diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..7150a72ebc --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +; top-most EditorConfig file +root = true + +; Unix-style newlines +[*] +charset = utf-8 +end_of_line = LF +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = tab + +[*.{htm,html}] +indent_style = space +indent_size = 4 diff --git a/.gitignore b/.gitignore index c49a12edc1..d172db2d54 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,11 @@ .idea /nbproject/private/ .phplint-cache + +# Vim and patch specific excludes *.swp +*.orig +*.rej # macOS-specific things to exclude @@ -36,4 +40,30 @@ Temporary Items .apdisk # Configuration for the Nova editor -.nova \ No newline at end of file +.nova + +# VS Code files for those working on multiple tools +.vscode/* +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# Visual Studio IDE cache/options directory +.vs/ + +# do not version control generated config files +/server/lib/mysql_clientdb.conf +/server/lib/config.inc.php +/server/lib/config.inc.local.php +/interface/lib/config.inc.local.php +/install/existing_db.sql + +sync_config.jsonc \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3a4a7de71f..ee8e269b1c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,10 +3,13 @@ ISPConfig is a open source project and community contributions are very welcome. This document is under development and will be continuously improved. +Please do not refactor existing code and do not change the signature or the behaviour of central functions or libraries. Such changes may only be made by the core development team. We have had many bad experiences with such changes affecting the stability of ISPConfig, so we no longer accept submissions containing such changes. Merge requests containing such changes will be closed and not merged. + # Issues * Before opening a new issue, use the search function to check if there isn't a bug report / feature request already. * If you are reporting a bug, please share your OS and PHP (CLI) version. * If you want to report several bugs or request several features, open a separate issue for each one of them. +* Do note re-open issues that were closed by the core dev team unless something new and important that is not mentioned in the original issue needs to be added. Permanently re-opening issues that we commented on and closed will get your account banned. You may add comments to issues without re-opening them though. # Branches * If you are a new user, please send an email to: dev [at] ispconfig [dot] org to receive rights to fork the project. diff --git a/README.md b/README.md index 901cb2a7b9..156898ed2d 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,8 @@ Development branch: [![pipeline status](https://git.ispconfig.org/ispconfig/ispc [^1]: not actively tested ## Supported operating systems -- Debian 9 - 11, and testing -- Ubuntu 16.04 - 20.04 +- Debian 9 - 12, and testing +- Ubuntu 16.04 - 22.04 - CentOS 7 and 8 ## Auto-install script diff --git a/docs/autoinstall_samples/autoinstall.conf_sample.php b/docs/autoinstall_samples/autoinstall.conf_sample.php index c8bf209f9f..c8c374e4f0 100644 --- a/docs/autoinstall_samples/autoinstall.conf_sample.php +++ b/docs/autoinstall_samples/autoinstall.conf_sample.php @@ -61,7 +61,7 @@ $autoupdate['ispconfig_postfix_ssl_symlink'] = 'y'; $autoupdate['ispconfig_pureftpd_ssl_symlink'] = 'y'; -/* These are for service-detection (defaulting to old behaviour where alle changes were automatically accepted) */ +/* These are for service-detection (defaulting to old behaviour where all changes were automatically accepted) */ $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 diff --git a/docs/autoinstall_samples/autoinstall.ini.sample b/docs/autoinstall_samples/autoinstall.ini.sample index bf47122074..9251d1eef0 100644 --- a/docs/autoinstall_samples/autoinstall.ini.sample +++ b/docs/autoinstall_samples/autoinstall.ini.sample @@ -60,7 +60,7 @@ ignore_hostname_dns=n ispconfig_postfix_ssl_symlink=y ispconfig_pureftpd_ssl_symlink=y -; These are for service-detection (defaulting to old behaviour where alle changes were automatically accepted) +; These are for service-detection (defaulting to old behaviour where all changes were automatically accepted) svc_detect_change_mail_server=yes svc_detect_change_web_server=yes svc_detect_change_dns_server=yes diff --git a/server/plugins-available/bind_dlz_plugin.inc.php b/docs/old_server_plugins/bind_dlz_plugin.inc.php similarity index 100% rename from server/plugins-available/bind_dlz_plugin.inc.php rename to docs/old_server_plugins/bind_dlz_plugin.inc.php diff --git a/server/plugins-available/nginx_reverseproxy_plugin.inc.php b/docs/old_server_plugins/nginx_reverseproxy_plugin.inc.php similarity index 100% rename from server/plugins-available/nginx_reverseproxy_plugin.inc.php rename to docs/old_server_plugins/nginx_reverseproxy_plugin.inc.php diff --git a/extensions/empty.dir b/extensions/empty.dir new file mode 100644 index 0000000000..e69de29bb2 diff --git a/helper_scripts/import_langfile.php b/helper_scripts/import_langfile.php new file mode 100644 index 0000000000..f76822ec30 --- /dev/null +++ b/helper_scripts/import_langfile.php @@ -0,0 +1,185 @@ +') return $line; // don't treat empty lines as malicious + + $ok = preg_match('/^\s*\$wb\[(["\'])(.*?)\\1\]\s*=\s*(["\'])(.*?)\\3\s*;\s*$/', $line, $matches); + if(!$ok) return false; // this line has invalid form and could lead to malfunction + + $keyquote = $matches[1]; // ' or " + $key = $matches[2]; + if(strpos($key, '"') !== false || strpos($key, "'") !== false) return false; + + $textquote = $matches[3]; // ' or " + $text = $matches[4]; + + $new_line = '$wb[\''; + + // validate the language key + $key = normalize_string($key, $keyquote); + + $new_line .= $key . '\'] = \''; + + // validate this text to avoid code injection + $text = normalize_string($text, $textquote, true); + + $new_line .= $text . '\';'; + + return $new_line; +} + +$lines = file($lang_file); + +define('ISPC_ROOT_PATH', $ispconfig_path.'/interface'); +define('ISPC_LIB_PATH', ISPC_ROOT_PATH.'/lib'); +define('ISPC_WEB_PATH', ISPC_ROOT_PATH.'/web'); + +// initial check +$parts = explode('|', $lines[0]); +if($parts[0] == '---' && $parts[1] == 'ISPConfig Language File') { + unset($lines[0]); + + $buffer = ''; + $langfile_path = ''; + // all other lines + $ln = 1; + foreach($lines as $line) { + $ln++; + $parts = explode('|', $line); + if(is_array($parts) && count($parts) > 0 && $parts[0] == '--') { + // Write language file, if its not the first file + if($buffer != '' && $langfile_path != '') { + $buffer = trim($buffer)."\n"; + $msg .= "File written: $langfile_path\n"; + file_put_contents($langfile_path, $buffer); + } + // empty buffer and set variables + $buffer = ''; + $module_name = trim($parts[1]); + $selected_language = trim($parts[2]); + $file_name = trim($parts[3]); + if(!preg_match("/^[a-z]{2}$/i", $selected_language)) die("unallowed characters in selected language name: $selected_language"); + if(!preg_match("/^[a-z_]+$/i", $module_name)) die('unallowed characters in module name.'); + if(!preg_match("/^[a-z\._\-]+$/i", $file_name) || stristr($file_name, '..')) die("unallowed characters in language file name: '$file_name'"); + if($module_name == 'global') { + $langfile_path = trim(ISPC_LIB_PATH."/lang/".$selected_language.".lng"); + } else { + $langfile_path = trim(ISPC_WEB_PATH.'/'.$module_name.'/lib/lang/'.$file_name); + } + } elseif(is_array($parts) && count($parts) > 1 && $parts[0] == '---' && $parts[1] == 'EOF') { + // EOF line, ignore it. + } else { + $line = validate_line($line); + if($line === false) $error .= "Language file contains invalid language entry on line $ln.\n"; + else $buffer .= $line."\n"; + } + } +} + +echo $error; +echo $msg; +die("finished import.\n"); + +?> diff --git a/helper_scripts/multifile_add b/helper_scripts/multifile_add new file mode 100755 index 0000000000..d5e58937a6 --- /dev/null +++ b/helper_scripts/multifile_add @@ -0,0 +1,32 @@ +#!/bin/bash + +# Adding a new translation string to the files for all languages. +# If you already added the string to your current language, be sure to deduplicate. + +new=$(cat << 'EOD' +$wb['foo_txt'] = 'Some translation'; +EOD +) + +if [ -z "$1" ]; then + echo "Usage: $0 " + exit 1 +fi + +for f in $*; do + # Preserve a php close tag as the last line. + close='?>' + if [ "$(tail -n 1 $f)" == "$close" ]; then + ( + head -n -1 $f; + echo "$new"; + echo "?>"; + ) > ${f}.new + + mv ${f}.new $f + + + else + echo "$new" >> $f + fi +done diff --git a/install/dist/conf/centos70.conf.php b/install/dist/conf/centos70.conf.php index ec59c754cb..0ea6524c1b 100644 --- a/install/dist/conf/centos70.conf.php +++ b/install/dist/conf/centos70.conf.php @@ -186,7 +186,7 @@ //* Jailkit $conf['jailkit']['installed'] = false; // will be detected automatically during installation $conf['jailkit']['config_dir'] = '/etc/jailkit'; -$conf['jailkit']['jk_init'] = 'jk_init.ini'; +$conf['jailkit']['jk_init'] = 'jk_init_el.ini'; $conf['jailkit']['jk_chrootsh'] = 'jk_chrootsh.ini'; $conf['jailkit']['jailkit_chroot_app_programs'] = '/usr/bin/groups /usr/bin/id /usr/bin/dircolors /bin/basename /usr/bin/dirname /usr/bin/nano'; $conf['jailkit']['jailkit_chroot_cron_programs'] = '/usr/bin/php /usr/bin/perl /usr/share/perl /usr/share/php'; diff --git a/install/dist/conf/centos72.conf.php b/install/dist/conf/centos72.conf.php index d83ac2300b..51cd5b3332 100644 --- a/install/dist/conf/centos72.conf.php +++ b/install/dist/conf/centos72.conf.php @@ -189,7 +189,7 @@ //* Jailkit $conf['jailkit']['installed'] = false; // will be detected automatically during installation $conf['jailkit']['config_dir'] = '/etc/jailkit'; -$conf['jailkit']['jk_init'] = 'jk_init.ini'; +$conf['jailkit']['jk_init'] = 'jk_init_el.ini'; $conf['jailkit']['jk_chrootsh'] = 'jk_chrootsh.ini'; $conf['jailkit']['jailkit_chroot_app_programs'] = '/usr/bin/groups /usr/bin/id /usr/bin/dircolors /bin/basename /usr/bin/dirname /usr/bin/nano'; $conf['jailkit']['jailkit_chroot_cron_programs'] = '/usr/bin/php /usr/bin/perl /usr/share/perl /usr/share/php'; diff --git a/install/dist/conf/centos80.conf.php b/install/dist/conf/centos80.conf.php index dd2abc668a..bdba560c4f 100644 --- a/install/dist/conf/centos80.conf.php +++ b/install/dist/conf/centos80.conf.php @@ -189,7 +189,7 @@ //* Jailkit $conf['jailkit']['installed'] = false; // will be detected automatically during installation $conf['jailkit']['config_dir'] = '/etc/jailkit'; -$conf['jailkit']['jk_init'] = 'jk_init.ini'; +$conf['jailkit']['jk_init'] = 'jk_init_el.ini'; $conf['jailkit']['jk_chrootsh'] = 'jk_chrootsh.ini'; $conf['jailkit']['jailkit_chroot_app_programs'] = '/usr/bin/groups /usr/bin/id /usr/bin/dircolors /bin/basename /usr/bin/dirname /usr/bin/nano'; $conf['jailkit']['jailkit_chroot_cron_programs'] = '/usr/bin/php /usr/bin/perl /usr/share/perl /usr/share/php'; diff --git a/install/dist/conf/centos90.conf.php b/install/dist/conf/centos90.conf.php index 909418dc2e..f513d6b080 100644 --- a/install/dist/conf/centos90.conf.php +++ b/install/dist/conf/centos90.conf.php @@ -189,7 +189,7 @@ //* Jailkit $conf['jailkit']['installed'] = false; // will be detected automatically during installation $conf['jailkit']['config_dir'] = '/etc/jailkit'; -$conf['jailkit']['jk_init'] = 'jk_init.ini'; +$conf['jailkit']['jk_init'] = 'jk_init_el.ini'; $conf['jailkit']['jk_chrootsh'] = 'jk_chrootsh.ini'; $conf['jailkit']['jailkit_chroot_app_programs'] = '/usr/bin/groups /usr/bin/id /usr/bin/dircolors /bin/basename /usr/bin/dirname /usr/bin/nano'; $conf['jailkit']['jailkit_chroot_cron_programs'] = '/usr/bin/php /usr/bin/perl /usr/share/perl /usr/share/php'; diff --git a/install/dist/conf/debian120.conf.php b/install/dist/conf/debian120.conf.php new file mode 100644 index 0000000000..bd6773c623 --- /dev/null +++ b/install/dist/conf/debian120.conf.php @@ -0,0 +1,244 @@ + diff --git a/install/dist/conf/debiantesting.conf.php b/install/dist/conf/debiantesting.conf.php index e2fa04f8ab..145e213d0c 100644 --- a/install/dist/conf/debiantesting.conf.php +++ b/install/dist/conf/debiantesting.conf.php @@ -43,7 +43,7 @@ $conf['runlevel'] = '/etc'; $conf['shells'] = '/etc/shells'; $conf['pam'] = '/etc/pam.d'; -$conf['default_php'] = "8.1"; +$conf['default_php'] = "8.2"; //* Services provided by this server, this selection will be overridden by the expert mode $conf['services']['mail'] = true; @@ -85,8 +85,8 @@ $conf['apache']['vhost_conf_dir'] = '/etc/apache2/sites-available'; $conf['apache']['vhost_conf_enabled_dir'] = '/etc/apache2/sites-enabled'; $conf['apache']['vhost_port'] = '8080'; -$conf['apache']['php_ini_path_apache'] = '/etc/php/7.4/apache2/php.ini'; -$conf['apache']['php_ini_path_cgi'] = '/etc/php/7.4/cgi/php.ini'; +$conf['apache']['php_ini_path_apache'] = '/etc/php/8.2/apache2/php.ini'; +$conf['apache']['php_ini_path_cgi'] = '/etc/php/8.2/cgi/php.ini'; //* Website base settings $conf['web']['website_basedir'] = '/var/www'; @@ -101,7 +101,7 @@ $conf['web']['apps_vhost_group'] = 'ispapps'; //* Fastcgi -$conf['fastcgi']['fastcgi_phpini_path'] = '/etc/php/7.4/cgi/'; +$conf['fastcgi']['fastcgi_phpini_path'] = '/etc/php/8.2/cgi/'; $conf['fastcgi']['fastcgi_starter_path'] = '/var/www/php-fcgi-scripts/[system_user]/'; $conf['fastcgi']['fastcgi_bin'] = '/usr/bin/php-cgi'; @@ -212,11 +212,11 @@ $conf['nginx']['init_script'] = 'nginx'; $conf['nginx']['vhost_port'] = '8080'; $conf['nginx']['cgi_socket'] = '/var/run/fcgiwrap.socket'; -$conf['nginx']['php_fpm_init_script'] = 'php7.4-fpm'; -$conf['nginx']['php_fpm_ini_path'] = '/etc/php/7.4/fpm/php.ini'; -$conf['nginx']['php_fpm_pool_dir'] = '/etc/php/7.4/fpm/pool.d'; +$conf['nginx']['php_fpm_init_script'] = 'php8.2-fpm'; +$conf['nginx']['php_fpm_ini_path'] = '/etc/php/8.2/fpm/php.ini'; +$conf['nginx']['php_fpm_pool_dir'] = '/etc/php/8.2/fpm/pool.d'; $conf['nginx']['php_fpm_start_port'] = 9010; -$conf['nginx']['php_fpm_socket_dir'] = '/var/lib/php7.4-fpm'; +$conf['nginx']['php_fpm_socket_dir'] = '/var/lib/php8.2-fpm'; //* OpenVZ $conf['openvz']['installed'] = false; diff --git a/install/dist/conf/fedora9.conf.php b/install/dist/conf/fedora9.conf.php index 49802db9d6..1928489e5c 100644 --- a/install/dist/conf/fedora9.conf.php +++ b/install/dist/conf/fedora9.conf.php @@ -185,7 +185,7 @@ //* Jailkit $conf['jailkit']['installed'] = false; // will be detected automatically during installation $conf['jailkit']['config_dir'] = '/etc/jailkit'; -$conf['jailkit']['jk_init'] = 'jk_init.ini'; +$conf['jailkit']['jk_init'] = 'jk_init_el.ini'; $conf['jailkit']['jk_chrootsh'] = 'jk_chrootsh.ini'; $conf['jailkit']['jailkit_chroot_app_programs'] = '/usr/bin/groups /usr/bin/id /usr/bin/dircolors /bin/basename /usr/bin/dirname /usr/bin/nano'; $conf['jailkit']['jailkit_chroot_cron_programs'] = '/usr/bin/php /usr/bin/perl /usr/share/perl /usr/share/php'; diff --git a/install/dist/conf/gentoo.conf.php b/install/dist/conf/gentoo.conf.php index fbd169752a..6e746b4d9c 100644 --- a/install/dist/conf/gentoo.conf.php +++ b/install/dist/conf/gentoo.conf.php @@ -1,7 +1,7 @@ + diff --git a/install/dist/conf/ubuntu2404.conf.php b/install/dist/conf/ubuntu2404.conf.php new file mode 100644 index 0000000000..85c059d06d --- /dev/null +++ b/install/dist/conf/ubuntu2404.conf.php @@ -0,0 +1,240 @@ + \ No newline at end of file diff --git a/install/dist/lib/debian60.lib.php b/install/dist/lib/debian60.lib.php index 981e6cff92..cfb17b05b0 100644 --- a/install/dist/lib/debian60.lib.php +++ b/install/dist/lib/debian60.lib.php @@ -61,7 +61,7 @@ public function configure_dovecot() 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 @@ -209,14 +209,6 @@ public function configure_dovecot() } - public function configure_apache() { - global $conf; - - if(file_exists('/etc/apache2/mods-available/fcgid.conf')) replaceLine('/etc/apache2/mods-available/fcgid.conf', 'MaxRequestLen', 'MaxRequestLen 15728640', 0, 1); - - parent::configure_apache(); - } - public function configure_fail2ban() { /* copy('tpl/dovecot-pop3imap.conf.master',"/etc/fail2ban/filter.d/dovecot-pop3imap.conf"); diff --git a/install/dist/lib/fedora.lib.php b/install/dist/lib/fedora.lib.php index 71809ac81e..b1d1836ba1 100644 --- a/install/dist/lib/fedora.lib.php +++ b/install/dist/lib/fedora.lib.php @@ -144,7 +144,7 @@ public function configure_dovecot() 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 @@ -853,6 +853,10 @@ public function install_ispconfig() $command = 'chown -R ispconfig:ispconfig '.$install_dir.'/interface'; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); + //* chown the extensions directory to the ispconfig user and group + $command = 'chown ispconfig:ispconfig '.$install_dir.'/extensions'; + caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); + //* chown the server files to the root user and group $command = 'chown -R root:root '.$install_dir.'/server'; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); @@ -1076,6 +1080,12 @@ public function install_ispconfig() if(!is_link('/usr/local/bin/ispconfig_update_from_dev.sh')) exec('ln -s /usr/local/ispconfig/server/scripts/ispconfig_update.sh /usr/local/bin/ispconfig_update_from_dev.sh'); if(!is_link('/usr/local/bin/ispconfig_update.sh')) exec('ln -s /usr/local/ispconfig/server/scripts/ispconfig_update.sh /usr/local/bin/ispconfig_update.sh'); + // Install ISPConfig cli command + if(is_file('/usr/local/bin/ispc')) unlink('/usr/local/bin/ispc'); + chown($install_dir.'/server/cli/ispc', 'root'); + chmod($install_dir.'/server/cli/ispc', 0700); + symlink($install_dir.'/server/cli/ispc', '/usr/local/bin/ispc'); + // set the fast cgi starter script to executable // exec('chmod 755 '.$install_dir.'/interface/bin/php-fcgi'); @@ -1094,6 +1104,7 @@ public function install_ispconfig() if(!is_dir($conf['ispconfig_log_dir'])) mkdir($conf['ispconfig_log_dir']); if(!is_file($conf['ispconfig_log_dir'].'/ispconfig.log')) exec('touch '.$conf['ispconfig_log_dir'].'/ispconfig.log'); chmod($conf['ispconfig_log_dir'].'/ispconfig.log', 0600); + exec('chmod o-rw /var/log/ispconfig/*.gz /var/log/ispconfig/*.log'); if(is_user('getmail')) { exec('mv /usr/local/ispconfig/server/scripts/run-getmail.sh /usr/local/bin/run-getmail.sh'); diff --git a/install/dist/lib/gentoo.lib.php b/install/dist/lib/gentoo.lib.php index c98788e33c..56aee4a521 100644 --- a/install/dist/lib/gentoo.lib.php +++ b/install/dist/lib/gentoo.lib.php @@ -47,8 +47,7 @@ public function configure_jailkit() caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); } - public function configure_postfix($options = '') - { + public function configure_postfix($options = '') { global $conf,$autoinstall; $cf = $conf['postfix']; @@ -57,6 +56,11 @@ public function configure_postfix($options = '') if(!is_dir($config_dir)){ $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); //* Install virtual mappings foreach (glob('tpl/mysql-virtual_*.master') as $filename) { @@ -65,30 +69,48 @@ public function configure_postfix($options = '') //* mysql-verify_recipients.cf $this->process_postfix_config('mysql-verify_recipients.cf'); + + // test if lmtp if available + $configure_lmtp = $this->get_postfix_service('lmtp','unix'); + //* postfix-dkim + $filename='tag_as_originating.re'; + $full_file_name=$config_dir.'/'.$filename; + if(is_file($full_file_name)) copy($full_file_name, $full_file_name.'~'); + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/postfix-'.$filename.'.master', 'tpl/postfix-'.$filename.'.master'); + if($configure_lmtp) { + $content = preg_replace('/amavis:/', 'lmtp:', $content); + } + wf($full_file_name, $content); + + $filename='tag_as_foreign.re'; + $full_file_name=$config_dir.'/'.$filename; + if(is_file($full_file_name)) copy($full_file_name, $full_file_name.'~'); + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/postfix-'.$filename.'.master', 'tpl/postfix-'.$filename.'.master'); + if($configure_lmtp) { + $content = preg_replace('/amavis:/', 'lmtp:', $content); + } + wf($full_file_name, $content); + //* Changing mode and group of the new created config files. - caselog('chmod o= '.$config_dir.'/mysql-virtual_*.cf* &> /dev/null', + /*caselog('chmod o= '.$config_dir.'/mysql-virtual_*.cf* &> /dev/null', __FILE__, __LINE__, 'chmod on mysql-virtual_*.cf*', 'chmod on mysql-virtual_*.cf* failed'); caselog('chgrp '.$cf['group'].' '.$config_dir.'/mysql-virtual_*.cf* &> /dev/null', - __FILE__, __LINE__, 'chgrp on mysql-virtual_*.cf*', 'chgrp on mysql-virtual_*.cf* failed'); + __FILE__, __LINE__, 'chgrp on mysql-virtual_*.cf*', 'chgrp on mysql-virtual_*.cf* failed');*/ //* Creating virtual mail user and group $command = 'groupadd -g '.$cf['vmail_groupid'].' '.$cf['vmail_groupname']; - if (!is_group($cf['vmail_groupname'])) { - caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); - } + if(!is_group($cf['vmail_groupname'])) caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); $command = 'useradd -g '.$cf['vmail_groupname'].' -u '.$cf['vmail_userid'].' '.$cf['vmail_username'].' -d '.$cf['vmail_mailbox_base'].' -m'; - if (!is_user($cf['vmail_username'])) { - caselog("$command &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); - } + if(!is_user($cf['vmail_username'])) caselog("$command &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); //* These postconf commands will be executed on installation and update $server_ini_rec = $this->db->queryOneRecord("SELECT config FROM ?? WHERE server_id = ?", $conf["mysql"]["database"].'.server', $conf['server_id']); $server_ini_array = ini_to_array(stripslashes($server_ini_rec['config'])); unset($server_ini_rec); - //* If there are RBL's defined, format the list and add them to smtp_recipient_restrictions to prevent removeal after an update + //* If there are RBL's defined, format the list and add them to smtp_recipient_restrictions to prevent removal after an update $rbl_list = ''; if (@isset($server_ini_array['mail']['realtime_blackhole_list']) && $server_ini_array['mail']['realtime_blackhole_list'] != '') { $rbl_hosts = explode(",", str_replace(" ", "", $server_ini_array['mail']['realtime_blackhole_list'])); @@ -107,7 +129,7 @@ public function configure_postfix($options = '') $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')) { - $reject_sender_login_mismatch = ', reject_sender_login_mismatch'; + $reject_sender_login_mismatch = ',reject_sender_login_mismatch,'; $reject_authenticated_sender_login_mismatch = 'reject_authenticated_sender_login_mismatch, '; } @@ -145,7 +167,42 @@ public function configure_postfix($options = '') $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 - + + //* Merge version-specific postfix config + if(version_compare($postfix_version , '2.5', '>=')) { + $configfile = 'postfix_2-5.conf'; + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master'); + $content = strtr($content, $postconf_placeholders); + $postconf_commands = array_merge($postconf_commands, array_filter(explode("\n", $content))); + } + if(version_compare($postfix_version , '2.10', '>=')) { + $configfile = 'postfix_2-10.conf'; + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master'); + $content = strtr($content, $postconf_placeholders); + $postconf_commands = array_merge($postconf_commands, array_filter(explode("\n", $content))); + } + if(version_compare($postfix_version , '3.0', '>=')) { + $configfile = 'postfix_3-0.conf'; + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master'); + $content = strtr($content, $postconf_placeholders); + $postconf_commands = array_merge($postconf_commands, array_filter(explode("\n", $content))); + } + if(version_compare($postfix_version , '3.3', '>=')) { + $configfile = 'postfix_3-3.conf'; + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master'); + $content = strtr($content, $postconf_placeholders); + $postconf_commands = array_merge($postconf_commands, array_filter(explode("\n", $content))); + } + $configfile = 'postfix_custom.conf'; + if(file_exists($conf['ispconfig_install_dir'].'/server/conf-custom/install/' . $configfile . '.master')) { + $content = file_get_contents($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master'); + $content = strtr($content, $postconf_placeholders); + $postconf_commands = array_merge($postconf_commands, array_filter(explode("\n", $content))); + } + + // Remove comment lines, these would give fatal errors when passed to postconf. + $postconf_commands = array_filter($postconf_commands, function($line) { return preg_match('/^[^#]/', $line); }); + //* These postconf commands will be executed on installation only if($this->is_update == false) { $postconf_commands = array_merge($postconf_commands, array( @@ -161,6 +218,15 @@ public function configure_postfix($options = '') touch($config_dir.'/nested_header_checks'); touch($config_dir.'/body_checks'); touch($config_dir.'/sasl_passwd'); + + //* 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'; @@ -189,13 +255,13 @@ public function configure_postfix($options = '') //* Executing the postconf commands foreach($postconf_commands as $cmd) { $command = "postconf -e '$cmd'"; - caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command); + swriteln($command); + caselog($command." &> /dev/null", __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command); } - - //* Create the SSL certificate - if (!stristr($options, 'dont-create-certs')) - { - if(AUTOINSTALL){ + + 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 { @@ -208,58 +274,59 @@ public function configure_postfix($options = '') 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); - } + //** 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); - //* Changing maildrop lines in posfix master.cf + //* Check maildrop service in posfix master.cf + $quoted_regex = '^maildrop unix.*pipe flags=DRhu user=vmail '.preg_quote('argv=/usr/bin/maildrop -d '.$cf['vmail_username'].' ${extension} ${recipient} ${user} ${nexthop} ${sender}', '/'); $configfile = $config_dir.'/master.cf'; - $content = rf($configfile); - - $content = preg_replace('/^#?maildrop/m', 'maildrop', $content); - $content = preg_replace('/^#?(\s+)flags=DRhu user=vmail argv=\/usr\/bin\/maildrop -d/m', - '$1flags=DRhu user=vmail argv=/usr/bin/maildrop -d vmail \${extension} \${recipient} \${user} \${nexthop} \${sender}', - $content); - - $this->write_config_file($configfile, $content); - - //* Writing the Maildrop mailfilter file - $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/mailfilter.master', 'tpl/mailfilter.master'); + if($this->get_postfix_service('maildrop', 'unix')) { + exec ("postconf -M maildrop.unix 2> /dev/null", $out, $ret); + $change_maildrop_flags = @(preg_match("/$quoted_regex/", $out[0]) && $out[0] !='')?false:true; + } else { + $change_maildrop_flags = @(preg_match("/$quoted_regex/", $configfile))?false:true; + } + if ($change_maildrop_flags) { + //* Change maildrop service in posfix master.cf + if(is_file($config_dir.'/master.cf')) { + copy($config_dir.'/master.cf', $config_dir.'/master.cf~'); + } + if(is_file($config_dir.'/master.cf~')) { + chmod($config_dir.'/master.cf~', 0400); + } + $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); + wf($configfile, $content); + } + + //* Writing the Maildrop mailfilter file + $configfile = 'mailfilter'; + if(is_file($cf['vmail_mailbox_base'].'/.'.$configfile)) { + copy($cf['vmail_mailbox_base'].'/.'.$configfile, $cf['vmail_mailbox_base'].'/.'.$configfile.'~'); + } + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master'); $content = str_replace('{dist_postfix_vmail_mailbox_base}', $cf['vmail_mailbox_base'], $content); - - $this->write_config_file($cf['vmail_mailbox_base'].'/.mailfilter', $content); + wf($cf['vmail_mailbox_base'].'/.'.$configfile, $content); //* Create the directory for the custom mailfilters - if (!is_dir($cf['vmail_mailbox_base'].'/mailfilters')) - { + if(!is_dir($cf['vmail_mailbox_base'].'/mailfilters')) { $command = 'mkdir '.$cf['vmail_mailbox_base'].'/mailfilters'; - caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); - } - - //* postfix-dkim - $filename='tag_as_originating.re'; - $full_file_name=$config_dir.'/'.$filename; - if(is_file($full_file_name)) copy($full_file_name, $full_file_name.'~'); - $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/postfix-'.$filename.'.master', 'tpl/postfix-'.$filename.'.master'); - wf($full_file_name, $content); - - $filename='tag_as_foreign.re'; - $full_file_name=$config_dir.'/'.$filename; - if(is_file($full_file_name)) copy($full_file_name, $full_file_name.'~'); - $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/postfix-'.$filename.'.master', 'tpl/postfix-'.$filename.'.master'); - wf($full_file_name, $content); + caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); + } //* Chmod and chown the .mailfilter file - $command = 'chown -R '.$cf['vmail_username'].':'.$cf['vmail_groupname'].' '.$cf['vmail_mailbox_base'].'/.mailfilter'; + $command = 'chown '.$cf['vmail_username'].':'.$cf['vmail_groupname'].' '.$cf['vmail_mailbox_base'].'/.mailfilter'; caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); - $command = 'chmod -R 600 '.$cf['vmail_mailbox_base'].'/.mailfilter'; + $command = 'chmod 600 '.$cf['vmail_mailbox_base'].'/.mailfilter'; caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); } - + public function configure_saslauthd() { global $conf; @@ -297,17 +364,21 @@ public function configure_courier() caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); } - public function configure_dovecot() - { + public function configure_dovecot() { global $conf; $virtual_transport = 'dovecot'; $configure_lmtp = false; + // use lmtp if installed + if($configure_lmtp = (is_file('/usr/lib/dovecot/lmtp') || is_file('/usr/libexec/dovecot/lmtp'))) { + $virtual_transport = 'lmtp:unix:private/dovecot-lmtp'; + } + // check if virtual_transport must be changed if ($this->is_update) { - $tmp = $this->db->queryOneRecord("SELECT * FROM ?? WHERE server_id = ?", $conf["mysql"]["database"].".server", $conf['server_id']); + $tmp = $this->db->queryOneRecord("SELECT * FROM ?? WHERE server_id = ?", $conf["mysql"]["database"] . ".server", $conf['server_id']); $ini_array = ini_to_array(stripslashes($tmp['config'])); // ini_array needs not to be checked, because already done in update.php -> updateDbAndIni() @@ -318,25 +389,29 @@ public function configure_dovecot() } $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 ); //* Configure master.cf and add a line for deliver if(!$this->get_postfix_service('dovecot', 'unix')) { - //* backup + //* backup 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 - $content = rf($conf["postfix"]["config_dir"].'/master.cf'); - $deliver_content = 'dovecot unix - n n - - pipe'."\n".' flags=DROhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}'."\n"; + $content = rf($config_dir.'/master.cf'); + $deliver_content = 'dovecot unix - n n - - pipe'."\n".' flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${user}@${nexthop}'."\n"; af($config_dir.'/master.cf', $deliver_content); unset($content); unset($deliver_content); } //* Reconfigure postfix to use dovecot authentication + // Adding the amavisd commands to the postfix configuration $postconf_commands = array ( 'dovecot_destination_recipient_limit = 1', 'virtual_transport = '.$virtual_transport, @@ -344,25 +419,44 @@ public function configure_dovecot() 'smtpd_sasl_path = private/auth' ); - //* Make a backup copy of the main.cf file - copy($conf['postfix']['config_dir'].'/main.cf', $conf['postfix']['config_dir'].'/main.cf~3'); + // Make a backup copy of the main.cf file + copy($config_dir.'/main.cf', $config_dir.'/main.cf~3'); - //* Executing the postconf commands - foreach($postconf_commands as $cmd) - { + $options = preg_split("/,\s*/", exec("postconf -h smtpd_recipient_restrictions")); + $new_options = array(); + foreach ($options as $value) { + $value = trim($value); + if ($value == '') continue; + if (preg_match("|check_recipient_access\s+proxy:mysql:{$quoted_config_dir}/mysql-verify_recipients.cf|", $value)) { + continue; + } + $new_options[] = $value; + } + if ($configure_lmtp && (!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")); + break; + } + } + # postfix < 3.3 needs this when using reject_unverified_recipient: + if(version_compare($postfix_version, 3.3, '<')) { + $postconf_commands[] = "enable_original_recipient = yes"; + } + } + $postconf_commands[] = "smtpd_recipient_restrictions = ".implode(", ", $new_options); + + // Executing the postconf commands + foreach($postconf_commands as $cmd) { $command = "postconf -e '$cmd'"; - caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); + caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); } + //* backup dovecot.conf $config_dir = $conf['dovecot']['config_dir']; - //* copy dovecot.conf - $configfile = $config_dir.'/dovecot.conf'; - $content = $this->get_template_file('dovecot.conf', true); - $this->write_config_file($configfile, $content); - - //* dovecot-lmtpd - if($configure_lmtp) { - replaceLine($config_dir.'/'.$configfile, 'protocols = imap pop3', 'protocols = imap pop3 lmtp', 1, 0); + $configfile = 'dovecot.conf'; + if(is_file($config_dir.'/'.$configfile)) { + copy($config_dir.'/'.$configfile, $config_dir.'/'.$configfile.'~'); } //* Get the dovecot version @@ -370,15 +464,118 @@ public function configure_dovecot() $dovecot_version = $tmp[0]; unset($tmp); + //* Copy dovecot configuration file + if(version_compare($dovecot_version,1, '<=')) { //* Dovecot 1.x + if(is_file($conf['ispconfig_install_dir'].'/server/conf-custom/install/gentoo_dovecot.conf.master')) { + copy($conf['ispconfig_install_dir'].'/server/conf-custom/install/gentoo_dovecot.conf.master', $config_dir.'/'.$configfile); + } else { + copy('dist/tpl/gentoo/dovecot.conf.master', $config_dir.'/'.$configfile); + } + } else { //* Dovecot 2.x + if(is_file($conf['ispconfig_install_dir'].'/server/conf-custom/install/gentoo_dovecot2.conf.master')) { + copy($conf['ispconfig_install_dir'].'/server/conf-custom/install/gentoo_dovecot2.conf.master', $config_dir.'/'.$configfile); + } else { + copy('dist/tpl/gentoo/dovecot2.conf.master', $config_dir.'/'.$configfile); + } + // Copy custom config file + if(is_file($conf['ispconfig_install_dir'].'/server/conf-custom/install/dovecot_custom.conf.master')) { + if(!@is_dir($config_dir . '/conf.d')) { + mkdir($config_dir . '/conf.d'); + } + copy($conf['ispconfig_install_dir'].'/server/conf-custom/install/dovecot_custom.conf.master', $config_dir.'/conf.d/99-ispconfig-custom-config.conf'); + } + replaceLine($config_dir.'/'.$configfile, 'postmaster_address = postmaster@example.com', 'postmaster_address = postmaster@'.$conf['hostname'], 1, 0); + replaceLine($config_dir.'/'.$configfile, 'postmaster_address = webmaster@localhost', 'postmaster_address = postmaster@'.$conf['hostname'], 1, 0); + if(version_compare($dovecot_version, 2.1, '<')) { + removeLine($config_dir.'/'.$configfile, 'ssl_protocols ='); + } + if(version_compare($dovecot_version,2.2) >= 0) { + // Dovecot > 2.2 does not recognize !SSLv2 anymore on Debian 9 + $content = file_get_contents($config_dir.'/'.$configfile); + $content = str_replace('!SSLv2','',$content); + file_put_contents($config_dir.'/'.$configfile,$content); + unset($content); + } + if(version_compare($dovecot_version,2.3) >= 0) { + // Remove deprecated setting(s) + removeLine($config_dir.'/'.$configfile, 'ssl_protocols ='); + + // 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 + + $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); + $content = str_replace('#2.3+ ','',$content); + file_put_contents($config_dir.'/'.$configfile,$content); + unset($content); + + } else { + // remove settings which are not supported in Dovecot < 2.3 + removeLine($config_dir.'/'.$configfile, 'ssl_min_protocol ='); + removeLine($config_dir.'/'.$configfile, 'ssl_dh ='); + } + } + + $dovecot_protocols = 'imap pop3'; + + //* dovecot-lmtpd + if($configure_lmtp) { + $dovecot_protocols .= ' lmtp'; + } + + //* dovecot-managesieved + if(is_file('/usr/lib/dovecot/managesieve') || is_file('/usr/libexec/dovecot/managesieve')) { + $dovecot_protocols .= ' sieve'; + } + + replaceLine($config_dir.'/'.$configfile, 'protocols = imap pop3', "protocols = $dovecot_protocols", 1, 0); + //* dovecot-sql.conf - $configfile = $config_dir.'/dovecot-sql.conf'; - $content = $this->get_template_file('debian_dovecot-sql.conf', true, true); + $configfile = 'dovecot-sql.conf'; + if(is_file($config_dir.'/'.$configfile)) { + copy($config_dir.'/'.$configfile, $config_dir.'/'.$configfile.'~'); + } + if(is_file($config_dir.'/'.$configfile.'~')) chmod($config_dir.'/'.$configfile.'~', 0400); + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/debian_dovecot-sql.conf.master', 'tpl/debian_dovecot-sql.conf.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); + $content = str_replace('{server_id}', $conf['server_id'], $content); # enable iterate_query for dovecot2 if(version_compare($dovecot_version,2, '>=')) { $content = str_replace('# iterate_query', 'iterate_query', $content); } - $content = str_replace('{server_id}', $conf['server_id'], $content); - $this->write_config_file($configfile, $content); + wf($config_dir.'/'.$configfile, $content); + + chmod($config_dir.'/'.$configfile, 0600); + chown($config_dir.'/'.$configfile, 'root'); + chgrp($config_dir.'/'.$configfile, 'root'); + + // Dovecot shall ignore mounts in website directory + if(is_installed('doveadm')) exec("doveadm mount add '/var/www/*' ignore > /dev/null 2> /dev/null"); + } public function configure_spamassassin() @@ -515,6 +712,36 @@ public function configure_pureftpd() $content = preg_replace('/MISC_OTHER="[^"]+"/', 'MISC_OTHER="-b -A -E -Z -D -H -O clf:'.$logdir.'/transfer.log'.$enable_tls.'"', $content); $this->write_config_file($conf['pureftpd']['config_file'], $content); + + //* Since version 1.0.50: Configuration through /etc/conf.d/pure-ftpd is now deprecated! + exec("/usr/sbin/pure-ftpd --help | head -1",$out); + if(preg_match("#v([0-9\.]+)\s#",$out[0],$matches)){ + $pureftpd_version = $matches[1]; + + if(version_compare($pureftpd_version, '1.0.50', '>=')) { + $configfile = $conf['pureftpd']['main_config_file']; + if(is_file($configfile)) { + copy($configfile, $configfile.'~'); + } + + $content = rf($configfile); + $content = preg_replace('/BrokenClientsCompatibility\s+(yes|no)/', 'BrokenClientsCompatibility yes', $content); + $content = preg_replace('/ChrootEveryone\s+(yes|no)/', 'ChrootEveryone yes', $content); + $content = preg_replace('/NoAnonymous\s+(yes|no)/', 'NoAnonymous yes', $content); + $content = preg_replace('/#? AltLog\s+clf.*\s/', 'AltLog clf:/var/log/pureftpd.log', $content); + $content = preg_replace('/CustomerProof\s+(yes|no)/', 'CustomerProof yes', $content); + $content = preg_replace('/DisplayDotFiles\s+(yes|no)/', 'DisplayDotFiles yes', $content); + $content = preg_replace('/DontResolve\s+(yes|no)/', 'DontResolve yes', $content); + $content = preg_replace('/#? MySQLConfigFile\s+\/.*\s/', 'MySQLConfigFile ' . $conf['pureftpd']['mysql_config_file'], $content); + + if(file_exists('/etc/ssl/private/pure-ftpd.pem')) { + $content = preg_replace('/(#?) TLS\s+(0|1)/', 'TLS 1', $content); + } + + wf($configfile, $content); + } + } + } public function configure_powerdns() @@ -721,7 +948,8 @@ public function configure_apps_vhost() caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); } - $command = 'adduser '.$conf['apache']['user'].' '.$apps_vhost_group; + //$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"); if(!@is_dir($install_dir)){ @@ -781,7 +1009,8 @@ public function configure_apps_vhost() if(!is_user($apps_vhost_user)) caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); - $command = 'adduser '.$conf['nginx']['user'].' '.$apps_vhost_group; + //$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"); if(!@is_dir($install_dir)){ @@ -845,39 +1074,46 @@ public function configure_apps_vhost() } } + + public function get_host_ips() { + $out = array(); + exec("ip addr show | awk '/global/ { print $2 }' | cut -d '/' -f 1", $ret, $val); + if($val == 0) { + if(is_array($ret) && !empty($ret)){ + foreach($ret as $ip) { + $ip = trim($ip); + $out[] = $ip; + } + } + } - public function install_ispconfig() - { + return $out; + } + + public function install_ispconfig() { global $conf; $install_dir = $conf['ispconfig_install_dir']; //* Create the ISPConfig installation directory - if(!is_dir($install_dir)) - { + if(!@is_dir($install_dir)) { $command = "mkdir $install_dir"; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); } //* Create a ISPConfig user and group - if (!is_group('ispconfig')) - { - $command = 'groupadd ispconfig'; - caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); - } + $command = 'groupadd ispconfig'; + if(!is_group('ispconfig')) caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); - if (!is_user('ispconfig')) - { - $command = "useradd -g ispconfig -d $install_dir ispconfig"; - caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); - } + $command = 'useradd -g ispconfig -d '.$install_dir.' ispconfig'; + if(!is_user('ispconfig')) caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); //* copy the ISPConfig interface part - $command = "cp -rf ../interface $install_dir"; + $command = 'cp -rf ../interface '.$install_dir; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); //* copy the ISPConfig server part - $command = "cp -rf ../server $install_dir"; + $command = 'cp -rf ../server '.$install_dir; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); //* Make a backup of the security settings @@ -887,28 +1123,29 @@ public function install_ispconfig() $command = 'cp -rf ../security '.$install_dir; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); - //* Apply changed security_settings.ini values to new security_settings.ini file - if(is_file('/usr/local/ispconfig/security/security_settings.ini~')) { - $security_settings_old = ini_to_array(file_get_contents('/usr/local/ispconfig/security/security_settings.ini~')); - $security_settings_new = ini_to_array(file_get_contents('/usr/local/ispconfig/security/security_settings.ini')); - if(is_array($security_settings_new) && is_array($security_settings_old)) { - foreach($security_settings_new as $section => $sval) { - if(is_array($sval)) { - foreach($sval as $key => $val) { - if(isset($security_settings_old[$section]) && isset($security_settings_old[$section][$key])) { - $security_settings_new[$section][$key] = $security_settings_old[$section][$key]; - } - } - } - } - file_put_contents('/usr/local/ispconfig/security/security_settings.ini',array_to_ini($security_settings_new)); - } + $configfile = 'security_settings.ini'; + if(is_file($install_dir.'/security/'.$configfile)) { + copy($install_dir.'/security/'.$configfile, $install_dir.'/security/'.$configfile.'~'); } + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master'); + wf($install_dir.'/security/'.$configfile, $content); + //* Create a symlink, so ISPConfig is accessible via web + // Replaced by a separate vhost definition for port 8080 + // $command = "ln -s $install_dir/interface/web/ /var/www/ispconfig"; + // caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); //* Create the config file for ISPConfig interface $configfile = 'config.inc.php'; - $content = $this->get_template_file($configfile, true, true); //* get contents & insert db cred + if(is_file($install_dir.'/interface/lib/'.$configfile)) { + copy($install_dir.'/interface/lib/'.$configfile, $install_dir.'/interface/lib/'.$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); $content = str_replace('{mysql_master_server_ispconfig_user}', $conf['mysql']['master_ispconfig_user'], $content); $content = str_replace('{mysql_master_server_ispconfig_password}', $conf['mysql']['master_ispconfig_password'], $content); @@ -923,10 +1160,34 @@ public function install_ispconfig() $content = str_replace('{theme}', $conf['theme'], $content); $content = str_replace('{language_file_import_enabled}', ($conf['language_file_import_enabled'] == true)?'true':'false', $content); - $this->write_config_file("$install_dir/interface/lib/$configfile", $content); + wf($install_dir.'/interface/lib/'.$configfile, $content); //* Create the config file for ISPConfig server - $this->write_config_file("$install_dir/server/lib/$configfile", $content); + $configfile = 'config.inc.php'; + if(is_file($install_dir.'/server/lib/'.$configfile)) { + copy($install_dir.'/server/lib/'.$configfile, $install_dir.'/interface/lib/'.$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); + + $content = str_replace('{mysql_master_server_ispconfig_user}', $conf['mysql']['master_ispconfig_user'], $content); + $content = str_replace('{mysql_master_server_ispconfig_password}', $conf['mysql']['master_ispconfig_password'], $content); + $content = str_replace('{mysql_master_server_database}', $conf['mysql']['master_database'], $content); + $content = str_replace('{mysql_master_server_host}', $conf['mysql']['master_host'], $content); + $content = str_replace('{mysql_master_server_port}', $conf['mysql']['master_port'], $content); + + $content = str_replace('{server_id}', $conf['server_id'], $content); + $content = str_replace('{ispconfig_log_priority}', $conf['ispconfig_log_priority'], $content); + $content = str_replace('{language}', $conf['language'], $content); + $content = str_replace('{timezone}', $conf['timezone'], $content); + $content = str_replace('{theme}', $conf['theme'], $content); + $content = str_replace('{language_file_import_enabled}', ($conf['language_file_import_enabled'] == true)?'true':'false', $content); + + wf($install_dir.'/server/lib/'.$configfile, $content); //* Create the config file for remote-actions (but only, if it does not exist, because // the value is a autoinc-value and so changed by the remoteaction_core_module @@ -935,7 +1196,7 @@ public function install_ispconfig() wf($install_dir.'/server/lib/remote_action.inc.php', $content); } - // Enable the server modules and plugins. + //* Enable the server modules and plugins. // TODO: Implement a selector which modules and plugins shall be enabled. $dir = $install_dir.'/server/mods-available/'; if (is_dir($dir)) { @@ -977,10 +1238,12 @@ public function install_ispconfig() if(method_exists($tmp, 'onInstall') && $tmp->onInstall()) { if(!@is_link($install_dir.'/server/plugins-enabled/'.$file)) { @symlink($install_dir.'/server/plugins-available/'.$file, $install_dir.'/server/plugins-enabled/'.$file); + //@symlink($install_dir.'/server/plugins-available/'.$file, '../plugins-enabled/'.$file); } if (strpos($file, '_core_plugin') !== false) { if(!@is_link($install_dir.'/server/plugins-core/'.$file)) { @symlink($install_dir.'/server/plugins-available/'.$file, $install_dir.'/server/plugins-core/'.$file); + //@symlink($install_dir.'/server/plugins-available/'.$file, '../plugins-core/'.$file); } } } @@ -991,21 +1254,25 @@ public function install_ispconfig() } } - //* Update the server config + // Update the server config $mail_server_enabled = ($conf['services']['mail'])?1:0; $web_server_enabled = ($conf['services']['web'])?1:0; $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; + $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 = ?, web_server = ?, dns_server = ?, file_server = ?, db_server = ?, vserver_server = ? 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', xmpp_server = '$xmpp_server_enabled' 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, $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, $conf['server_id']); } + // chown install dir to root and chmod 755 $command = 'chown root:root '.$install_dir; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); @@ -1020,6 +1287,14 @@ public function install_ispconfig() $command = 'chown -R ispconfig:ispconfig '.$install_dir.'/interface'; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); + //* chown the extensions directory to the ispconfig user and group + $command = 'chown ispconfig:ispconfig '.$install_dir.'/extensions'; + caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); + + //* Chmod the files and directories in the acme dir + $command = 'chmod -R 755 '.$install_dir.'/interface/acme'; + caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); + //* chown the server files to the root user and group $command = 'chown -R root:root '.$install_dir.'/server'; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); @@ -1046,9 +1321,7 @@ public function install_ispconfig() exec("chmod -R 770 $install_dir/interface/lib/lang"); //* Make the temp directory for language file exports writable - if(is_dir($install_dir.'/interface/web/temp')) { - exec("chmod -R 770 $install_dir/interface/web/temp"); - } + if(is_dir($install_dir.'/interface/web/temp')) exec("chmod -R 770 $install_dir/interface/web/temp"); //* Make all interface language file directories group writable $handle = @opendir($install_dir.'/interface/web'); @@ -1104,15 +1377,15 @@ public function install_ispconfig() $command = 'usermod -a -G ispconfig '.$conf['apache']['user']; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); if(is_group('ispapps')){ - $command = 'usermod -a -G ispapps '.$conf['apache']['user']; + $command = 'usermod -a -G ispapps '.$conf['apache']['user']; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); } } if($conf['nginx']['installed'] == true){ - $command = 'usermod -a -G ispconfig '.$conf['nginx']['user']; + $command = 'usermod -a -G ispconfig '.$conf['nginx']['user']; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); if(is_group('ispapps')){ - $command = 'usermod -a -G ispapps '.$conf['nginx']['user']; + $command = 'usermod -a -G ispapps '.$conf['nginx']['user']; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); } } @@ -1128,43 +1401,62 @@ public function install_ispconfig() if($conf['apache']['installed'] == true && $this->install_ispconfig_interface == true){ //* Copy the ISPConfig vhost for the controlpanel - $content = $this->get_template_file("apache_ispconfig.vhost", true); - $content = str_replace('{vhost_port}', $conf['apache']['vhost_port'], $content); + $vhost_conf_dir = $conf['apache']['vhost_conf_dir']; + //$vhost_conf_enabled_dir = $conf['apache']['vhost_conf_enabled_dir']; - //* comment out the listen directive if port is 80 or 443 - if ($conf['apache']['vhost_port'] == 80 or $conf['apache']['vhost_port'] == 443) { - $content = str_replace('{vhost_port_listen}', '#', $content); + // Dont just copy over the virtualhost template but add some custom settings + $tpl = new tpl(); + if (file_exists($conf['ispconfig_install_dir']."/server/conf-custom/install/apache_ispconfig.vhost.master")) { + $tpl->newTemplate($conf['ispconfig_install_dir']."/server/conf-custom/install/apache_ispconfig.vhost.master"); + } else { + $tpl->newTemplate("dist/tpl/gentoo/apache_ispconfig.vhost.master"); + } + $tpl->setVar('vhost_port',$conf['apache']['vhost_port']); + + // comment out the listen directive if port is 80 or 443 + if($conf['apache']['vhost_port'] == 80 or $conf['apache']['vhost_port'] == 443) { + $tpl->setVar('vhost_port_listen','#'); } else { - $content = str_replace('{vhost_port_listen}', '', $content); + $tpl->setVar('vhost_port_listen',''); } if(is_file($install_dir.'/interface/ssl/ispserver.crt') && is_file($install_dir.'/interface/ssl/ispserver.key')) { - $content = str_replace('{ssl_comment}', '', $content); + $tpl->setVar('ssl_comment',''); } else { - $content = str_replace('{ssl_comment}', '#', $content); + $tpl->setVar('ssl_comment','#'); } if(is_file($install_dir.'/interface/ssl/ispserver.crt') && is_file($install_dir.'/interface/ssl/ispserver.key') && is_file($install_dir.'/interface/ssl/ispserver.bundle')) { - $content = str_replace('{ssl_bundle_comment}', '', $content); + $tpl->setVar('ssl_bundle_comment',''); } else { - $content = str_replace('{ssl_bundle_comment}', '#', $content); + $tpl->setVar('ssl_bundle_comment','#'); } - $vhost_path = $conf['apache']['vhost_conf_dir'].'/ispconfig.vhost'; - $this->write_config_file($vhost_path, $content); - - if(!is_file('/var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter')) { - $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/apache_ispconfig_fcgi_starter.master', 'tpl/apache_ispconfig_fcgi_starter.master'); - $content = str_replace('{fastcgi_bin}', $conf['fastcgi']['fastcgi_bin'], $content); - $content = str_replace('{fastcgi_phpini_path}', $conf['fastcgi']['fastcgi_phpini_path'], $content); - @mkdir('/var/www/php-fcgi-scripts/ispconfig', 0755, true); - $this->set_immutable('/var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter', false); - wf('/var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter', $content); - exec('chmod +x /var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter'); - chmod('/var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter', 0755); - @symlink($install_dir.'/interface/web', '/var/www/ispconfig'); - exec('chown -R ispconfig:ispconfig /var/www/php-fcgi-scripts/ispconfig'); - $this->set_immutable('/var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter', true); - } + $tpl->setVar('apache_version',getapacheversion()); + + wf($vhost_conf_dir.'/ispconfig.vhost', $tpl->grab()); + + //* and create the symlink + /*if($this->is_update == false) { + if(@is_link($vhost_conf_enabled_dir.'/ispconfig.vhost')) unlink($vhost_conf_enabled_dir.'/ispconfig.vhost'); + if(!@is_link($vhost_conf_enabled_dir.'/000-ispconfig.vhost')) { + symlink($vhost_conf_dir.'/ispconfig.vhost', $vhost_conf_enabled_dir.'/000-ispconfig.vhost'); + } + }*/ + //if(!is_file('/var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter')) { + $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/apache_ispconfig_fcgi_starter.master', 'tpl/apache_ispconfig_fcgi_starter.master'); + $content = str_replace('{fastcgi_bin}', $conf['fastcgi']['fastcgi_bin'], $content); + $content = str_replace('{fastcgi_phpini_path}', $conf['fastcgi']['fastcgi_phpini_path'], $content); + @mkdir('/var/www/php-fcgi-scripts/ispconfig', 0755, true); + $this->set_immutable('/var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter', false); + wf('/var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter', $content); + exec('chmod +x /var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter'); + @symlink($install_dir.'/interface/web', '/var/www/ispconfig'); + exec('chown -R ispconfig:ispconfig /var/www/php-fcgi-scripts/ispconfig'); + $this->set_immutable('/var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter', true); + //} + + // unlink acme vhost symlink + if(is_link($vhost_conf_dir . '/999-acme.conf') && file_exists($vhost_conf_dir . '/acme.conf')) unlink($vhost_conf_dir . '/999-acme.conf'); } if($conf['nginx']['installed'] == true && $this->install_ispconfig_interface == true){ @@ -1177,7 +1469,7 @@ public function install_ispconfig() $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}', 'ssl', $content); + $content = str_replace('{ssl_on}', 'ssl http2', $content); $content = str_replace('{ssl_comment}', '', $content); $content = str_replace('{fastcgi_ssl}', 'on', $content); } else { @@ -1219,44 +1511,47 @@ public function install_ispconfig() } //* Install the update script - if (is_file('/usr/local/bin/ispconfig_update_from_dev.sh')) { - unlink('/usr/local/bin/ispconfig_update_from_dev.sh'); - } - + if(is_file('/usr/local/bin/ispconfig_update_from_dev.sh')) unlink('/usr/local/bin/ispconfig_update_from_dev.sh'); chown($install_dir.'/server/scripts/update_from_dev.sh', 'root'); chmod($install_dir.'/server/scripts/update_from_dev.sh', 0700); - chown($install_dir.'/server/scripts/update_from_tgz.sh', 'root'); - chmod($install_dir.'/server/scripts/update_from_tgz.sh', 0700); +// chown($install_dir.'/server/scripts/update_from_tgz.sh', 'root'); +// chmod($install_dir.'/server/scripts/update_from_tgz.sh', 0700); chown($install_dir.'/server/scripts/ispconfig_update.sh', 'root'); chmod($install_dir.'/server/scripts/ispconfig_update.sh', 0700); - - if (!is_link('/usr/local/bin/ispconfig_update_from_dev.sh')) { - symlink($install_dir.'/server/scripts/ispconfig_update.sh', '/usr/local/bin/ispconfig_update_from_dev.sh'); - } - - if (!is_link('/usr/local/bin/ispconfig_update.sh')) { - symlink($install_dir.'/server/scripts/ispconfig_update.sh', '/usr/local/bin/ispconfig_update.sh'); - } + if(!is_link('/usr/local/bin/ispconfig_update_from_dev.sh')) symlink($install_dir.'/server/scripts/ispconfig_update.sh', '/usr/local/bin/ispconfig_update_from_dev.sh'); + if(!is_link('/usr/local/bin/ispconfig_update.sh')) symlink($install_dir.'/server/scripts/ispconfig_update.sh', '/usr/local/bin/ispconfig_update.sh'); + + // Install ISPConfig cli command + if(is_file('/usr/local/bin/ispc')) unlink('/usr/local/bin/ispc'); + chown($install_dir.'/server/cli/ispc', 'root'); + chmod($install_dir.'/server/cli/ispc', 0700); + symlink($install_dir.'/server/cli/ispc', '/usr/local/bin/ispc'); + + // Make executable then unlink and symlink letsencrypt pre, post and renew hook scripts + chown($install_dir.'/server/scripts/letsencrypt_pre_hook.sh', 'root'); + chown($install_dir.'/server/scripts/letsencrypt_post_hook.sh', 'root'); + chown($install_dir.'/server/scripts/letsencrypt_renew_hook.sh', 'root'); + chmod($install_dir.'/server/scripts/letsencrypt_pre_hook.sh', 0700); + chmod($install_dir.'/server/scripts/letsencrypt_post_hook.sh', 0700); + chmod($install_dir.'/server/scripts/letsencrypt_renew_hook.sh', 0700); + if(is_link('/usr/local/bin/letsencrypt_pre_hook.sh')) unlink('/usr/local/bin/letsencrypt_pre_hook.sh'); + if(is_link('/usr/local/bin/letsencrypt_post_hook.sh')) unlink('/usr/local/bin/letsencrypt_post_hook.sh'); + if(is_link('/usr/local/bin/letsencrypt_renew_hook.sh')) unlink('/usr/local/bin/letsencrypt_renew_hook.sh'); + symlink($install_dir.'/server/scripts/letsencrypt_pre_hook.sh', '/usr/local/bin/letsencrypt_pre_hook.sh'); + symlink($install_dir.'/server/scripts/letsencrypt_post_hook.sh', '/usr/local/bin/letsencrypt_post_hook.sh'); + symlink($install_dir.'/server/scripts/letsencrypt_renew_hook.sh', '/usr/local/bin/letsencrypt_renew_hook.sh'); //* Make the logs readable for the ispconfig user - if (is_file('/var/log/maillog')) { - exec('chmod +r /var/log/maillog'); - } - if (is_file('/var/log/messages')) { - exec('chmod +r /var/log/messages'); - } - if (is_file('/var/log/clamav/clamav.log')) { - exec('chmod +r /var/log/clamav/clamav.log'); - } - if (is_file('/var/log/clamav/freshclam.log')) { - exec('chmod +r /var/log/clamav/freshclam.log'); - } - - //* Create the ispconfig log directory - if (!is_dir($conf['ispconfig_log_dir'])) { - mkdir($conf['ispconfig_log_dir']); - } - if (!is_file($conf['ispconfig_log_dir'].'/ispconfig.log')) { + if(@is_file('/var/log/mail.log')) exec('chmod +r /var/log/mail.log'); + if(@is_file('/var/log/mail.warn')) exec('chmod +r /var/log/mail.warn'); + if(@is_file('/var/log/mail.err')) exec('chmod +r /var/log/mail.err'); + if(@is_file('/var/log/messages')) exec('chmod +r /var/log/messages'); + if(@is_file('/var/log/clamav/clamav.log')) exec('chmod +r /var/log/clamav/clamav.log'); + if(@is_file('/var/log/clamav/freshclam.log')) exec('chmod +r /var/log/clamav/freshclam.log'); + + //* Create the ispconfig log file and directory + if(!is_file($conf['ispconfig_log_dir'].'/ispconfig.log')) { + if(!is_dir($conf['ispconfig_log_dir'])) mkdir($conf['ispconfig_log_dir'], 0755); touch($conf['ispconfig_log_dir'].'/ispconfig.log'); } chmod($conf['ispconfig_log_dir'].'/ispconfig.log', 0600); @@ -1268,16 +1563,45 @@ public function install_ispconfig() exec('chown ispconfig:ispconfig '. $conf['ispconfig_log_dir'].'/auth.log'); exec('chmod 660 '. $conf['ispconfig_log_dir'].'/auth.log'); - rename($install_dir.'/server/scripts/run-getmail.sh', '/usr/local/bin/run-getmail.sh'); - - if (is_user('getmail')) { - chown('/usr/local/bin/run-getmail.sh', 'getmail'); + if(is_user('getmail')) { + rename($install_dir.'/server/scripts/run-getmail.sh', '/usr/local/bin/run-getmail.sh'); + if(is_user('getmail')) chown('/usr/local/bin/run-getmail.sh', 'getmail'); + chmod('/usr/local/bin/run-getmail.sh', 0744); + } + + //* Add Log-Rotation + if (is_dir('/etc/logrotate.d')) { + @unlink('/etc/logrotate.d/logispc3'); // ignore, if the file is not there + /* We rotate these logs in cron_daily.php + $fh = fopen('/etc/logrotate.d/logispc3', 'w'); + fwrite($fh, + "$conf['ispconfig_log_dir']/ispconfig.log { \n" . + " weekly \n" . + " missingok \n" . + " rotate 4 \n" . + " compress \n" . + " delaycompress \n" . + "} \n" . + "$conf['ispconfig_log_dir']/cron.log { \n" . + " weekly \n" . + " missingok \n" . + " rotate 4 \n" . + " compress \n" . + " delaycompress \n" . + "}"); + fclose($fh); + */ } - chmod('/usr/local/bin/run-getmail.sh', 0744); //* Remove Domain module as its functions are available in the client module now if(@is_dir('/usr/local/ispconfig/interface/web/domain')) exec('rm -rf /usr/local/ispconfig/interface/web/domain'); + //* Disable rkhunter run and update in debian cronjob as ispconfig is running and updating rkhunter + if(is_file('/etc/default/rkhunter')) { + replaceLine('/etc/default/rkhunter', 'CRON_DAILY_RUN="yes"', 'CRON_DAILY_RUN="no"', 1, 0); + replaceLine('/etc/default/rkhunter', 'CRON_DB_UPDATE="yes"', 'CRON_DB_UPDATE="no"', 1, 0); + } + // Add symlink for patch tool if(!is_link('/usr/local/bin/ispconfig_patch')) exec('ln -s /usr/local/ispconfig/server/scripts/ispconfig_patch /usr/local/bin/ispconfig_patch'); @@ -1286,9 +1610,9 @@ public function install_ispconfig() if(is_file($conf['amavis']['config_dir'].'/50-user~')) chmod($conf['amavis']['config_dir'].'/50-user~', 0400); if(is_file($conf['amavis']['config_dir'].'/amavisd.conf')) chmod($conf['amavis']['config_dir'].'/amavisd.conf', 0640); if(is_file($conf['amavis']['config_dir'].'/amavisd.conf~')) chmod($conf['amavis']['config_dir'].'/amavisd.conf~', 0400); - } } ?> + diff --git a/install/dist/lib/opensuse.lib.php b/install/dist/lib/opensuse.lib.php index 7cc368a14e..43407c5a56 100644 --- a/install/dist/lib/opensuse.lib.php +++ b/install/dist/lib/opensuse.lib.php @@ -383,7 +383,7 @@ public function configure_dovecot() 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 @@ -1072,6 +1072,10 @@ public function install_ispconfig() $command = 'chown -R ispconfig:ispconfig '.$install_dir.'/interface'; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); + //* chown the extensions directory to the ispconfig user and group + $command = 'chown ispconfig:ispconfig '.$install_dir.'/extensions'; + caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); + //* chown the server files to the root user and group $command = 'chown -R root:root '.$install_dir.'/server'; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); @@ -1325,6 +1329,7 @@ public function install_ispconfig() if(!is_dir($conf['ispconfig_log_dir'])) mkdir($conf['ispconfig_log_dir']); if(!is_file($conf['ispconfig_log_dir'].'/ispconfig.log')) exec('touch '.$conf['ispconfig_log_dir'].'/ispconfig.log'); chmod($conf['ispconfig_log_dir'].'/ispconfig.log', 0600); + exec('chmod o-rw /var/log/ispconfig/*.gz /var/log/ispconfig/*.log'); if(is_user('getmail')) { exec('mv /usr/local/ispconfig/server/scripts/run-getmail.sh /usr/local/bin/run-getmail.sh'); diff --git a/install/dist/tpl/gentoo/amavisd-ispconfig.conf.master b/install/dist/tpl/gentoo/amavisd-ispconfig.conf.master index c60b50e2fa..ba126c97bb 100644 --- a/install/dist/tpl/gentoo/amavisd-ispconfig.conf.master +++ b/install/dist/tpl/gentoo/amavisd-ispconfig.conf.master @@ -105,6 +105,9 @@ $policy_bank{'ORIGINATING'} = { originating => 1, smtpd_discard_ehlo_keywords => ['8BITMIME'], }; +$policy_bank{'MYNETS'} = { + originating => 1, +}; # IP-Addresses for internal networks => load policy MYNETS # - requires -o smtp_send_xforward_command=yes in postfix master.cf diff --git a/install/dist/tpl/gentoo/apache_ispconfig.vhost.master b/install/dist/tpl/gentoo/apache_ispconfig.vhost.master index e885b381bc..39d25ac906 100644 --- a/install/dist/tpl/gentoo/apache_ispconfig.vhost.master +++ b/install/dist/tpl/gentoo/apache_ispconfig.vhost.master @@ -4,41 +4,83 @@ # for the ISPConfig controlpanel ###################################################### -{vhost_port_listen} Listen {vhost_port} - - # NameVirtualHost *:{vhost_port} - + Listen +NameVirtualHost *: - +> ServerAdmin webmaster@localhost Alias /mail /var/www/ispconfig/mail + + + SetHandler None + + + + + SetHandler None + + + DocumentRoot /var/www/ispconfig/ SuexecUserGroup ispconfig ispconfig - Options +Indexes +FollowSymLinks +MultiViews +ExecCGI + Options -Indexes +FollowSymLinks +MultiViews +ExecCGI AllowOverride AuthConfig Indexes Limit Options FileInfo - + SetHandler fcgid-script FCGIWrapper /var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter .php + + Require all granted + Order allow,deny Allow from all + DirectoryIndex index.php + IPCCommTimeout 7200 + MaxRequestLen 15728640 + + + + DocumentRoot /usr/local/ispconfig/interface/web + SuexecUserGroup ispconfig ispconfig + DirectoryIndex index.php + + + Options -Indexes +FollowSymLinks +MultiViews +ExecCGI + AllowOverride AuthConfig Indexes Limit Options FileInfo + + Require all granted + + Order allow,deny + Allow from all + + + #SetHandler "proxy:unix:/var/lib/php5-fpm/ispconfig.sock|fcgi://localhost" + SetHandler "proxy:fcgi://127.0.0.1:9000" + + - + DocumentRoot /usr/local/ispconfig/interface/web/ + AssignUserId ispconfig ispconfig AddType application/x-httpd-php .php + # 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 + + php_value magic_quotes_gpc 0 @@ -51,20 +93,53 @@ # SSL Configuration - {ssl_comment}SSLEngine On - {ssl_comment}SSLCertificateFile /usr/local/ispconfig/interface/ssl/ispserver.crt - {ssl_comment}SSLCertificateKeyFile /usr/local/ispconfig/interface/ssl/ispserver.key + SSLEngine On + + SSLProtocol All -SSLv3 -TLSv1 -TLSv1.1 + + SSLProtocol All -SSLv2 -SSLv3 + + SSLCertificateFile /usr/local/ispconfig/interface/ssl/ispserver.crt + SSLCertificateKeyFile /usr/local/ispconfig/interface/ssl/ispserver.key + SSLCACertificateFile /usr/local/ispconfig/interface/ssl/ispserver.bundle - + SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 + SSLHonorCipherOrder On + + SSLCompression Off + + + SSLSessionTickets Off + - - AllowOverride None - Order Deny,Allow - Deny from all - + + # 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'" + 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" + Header always edit Set-Cookie (.*) "$1; Secure" + + = 2.4.7> + Header setifempty Strict-Transport-Security "max-age=15768000" + + + Header set Strict-Transport-Security "max-age=15768000" + + + RequestHeader unset Proxy early + + + + SSLUseStapling On + SSLStaplingResponderTimeout 5 + SSLStaplingReturnResponderErrors Off + + + # Redirect http to https + ErrorDocument 400 "

Error 400 - trying to redirect

" + +
- - AllowOverride None - Order Deny,Allow - Deny from all - diff --git a/install/dist/tpl/gentoo/dovecot2.conf.master b/install/dist/tpl/gentoo/dovecot2.conf.master new file mode 100644 index 0000000000..12288e2cde --- /dev/null +++ b/install/dist/tpl/gentoo/dovecot2.conf.master @@ -0,0 +1,115 @@ +# Do not change this file, as changes will be overwritten by any ISPConfig update. +# Put your custom settings in /usr/local/ispconfig/server/conf-custom/install/dovecot_custom.conf.master. +# To start using those changes, do a force upgrade and let it reconfigure your services. (ispconfig_update.sh --force) +listen = *,[::] +protocols = imap pop3 +auth_mechanisms = plain login +disable_plaintext_auth = no +log_timestamp = "%Y-%m-%d %H:%M:%S " +mail_privileged_group = vmail +postmaster_address = postmaster@example.com +ssl_cert = lng(' Tap in "quit" (without the quotes) to stop the installer.'."\n\n")); //** Check log file is writable (probably not root or sudo) -if(!is_writable(dirname(ISPC_LOG_FILE))){ - die("ERROR: Cannot write to the ".dirname(ISPC_LOG_FILE)." directory. Are you root or sudo ?\n\n"); +if(!is_writable(dirname($conf['ispconfig_log_dir']))){ + die("ERROR: Cannot write to the ".$conf['ispconfig_log_dir']." directory. Are you root or sudo ?\n\n"); } +if(!is_dir($conf['ispconfig_log_dir'])) { + mkdir($conf['ispconfig_log_dir'], 0755, true); +} +define('ISPC_LOG_FILE', $conf['ispconfig_log_dir'] . '/install.log'); + //** Check for ISPConfig 2.x versions if(is_dir('/root/ispconfig') || is_dir('/home/admispconfig')) { if(is_dir('/home/admispconfig')) { @@ -252,6 +255,9 @@ include_once 'lib/mysql.lib.php'; $inst->db = new db(); +//* Check MySQL version +$inst->check_mysql_version(); + //** Begin with standard or expert installation $conf['services']['mail'] = false; @@ -661,7 +667,7 @@ if($conf['bind']['installed'] == true && isset($conf['bind']['init_script']) && $conf['bind']['init_script'] != '') system($inst->getinitcommand($conf['bind']['init_script'], 'restart').' &> /dev/null'); //if($conf['squid']['installed'] == true && isset($conf['squid']['init_script']) && $conf['squid']['init_script'] != '' && is_file($conf['init_scripts'].'/'.$conf['squid']['init_script'])) system($conf['init_scripts'].'/'.$conf['squid']['init_script'].' restart &> /dev/null'); if($conf['nginx']['installed'] == true && isset($conf['nginx']['init_script']) && $conf['nginx']['init_script'] != '') system($inst->getinitcommand($conf['nginx']['init_script'], 'restart').' &> /dev/null'); -if($conf['ufw']['installed'] == true && isset($conf['ufw']['init_script']) && $conf['ufw']['init_script'] != '') system($inst->getinitcommand($conf['ufw']['init_script'], 'restart').' &> /dev/null'); +if(isset($conf['ufw']['installed']) && $conf['ufw']['installed'] == true && isset($conf['ufw']['init_script']) && $conf['ufw']['init_script'] != '') system($inst->getinitcommand($conf['ufw']['init_script'], 'restart').' &> /dev/null'); if($conf['xmpp']['installed'] == true && isset($conf['xmpp']['init_script']) && $conf['xmpp']['init_script'] != '') system($inst->getinitcommand($conf['xmpp']['init_script'], 'restart').' &> /dev/null'); diff --git a/install/lib/classes/tpl.inc.php b/install/lib/classes/tpl.inc.php index 2bea1e1fd5..12f2523a36 100644 --- a/install/lib/classes/tpl.inc.php +++ b/install/lib/classes/tpl.inc.php @@ -30,7 +30,7 @@ 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 | diff --git a/install/lib/install.lib.php b/install/lib/install.lib.php index 10de1d8fbf..e248d27a6f 100644 --- a/install/lib/install.lib.php +++ b/install/lib/install.lib.php @@ -85,7 +85,7 @@ function get_distname() { } $distname = 'Ubuntu'; - $distid = 'debian40'; + $distid = 'debian60'; $distbaseid = 'debian'; preg_match("/.*VERSION=\"(.*)\".*/ui", $os_release, $ver); @@ -98,6 +98,10 @@ function get_distname() { $mainver = current($mainver).'.'.next($mainver); } switch ($mainver){ + case "24.04": + $relname = "(Noble Numbat)"; + $distconfid = 'ubuntu2404'; + break; case "22.04": $relname = "(Jammy Jellyfish)"; $distconfid = 'ubuntu2204'; @@ -252,6 +256,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'; @@ -263,7 +274,7 @@ function get_distname() { $distname = 'Debian'; $distver = 'Unknown'; $distid = 'debian60'; - $distconfid = 'debian100'; + $distconfid = 'debian120'; $distbaseid = 'debian'; swriteln("Operating System: Debian or compatible, unknown version.\n"); } @@ -547,16 +558,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{ diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 3d49c23871..7c306d413e 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -28,7 +28,7 @@ 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 @@ private function install_acme() { } 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; @@ -247,21 +247,56 @@ public function find_installed_apps() { //** Check prerequisites public function check_prerequisites() { global $conf; - + $msg = ''; 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(), '7.0', '<')) $msg .= "PHP Version 7.0 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"; + if(!function_exists('openssl_pkey_get_details')) $msg .= "PHP OpenSSL fiúnctions are missing.\n"; 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; @@ -402,7 +437,7 @@ public function add_database_server_record() { $tpl_ini_array['fastcgi']['fastcgi_bin'] = $conf['fastcgi']['fastcgi_bin']; $tpl_ini_array['server']['hostname'] = $conf['hostname']; $tpl_ini_array['server']['ip_address'] = @gethostbyname($conf['hostname']); - $tpl_ini_array['server']['firewall'] = ($conf['ufw']['installed'] == true)?'ufw':'bastille'; + $tpl_ini_array['server']['firewall'] = (@$conf['ufw']['installed'] == true)?'ufw':'bastille'; $tpl_ini_array['web']['website_basedir'] = $conf['web']['website_basedir']; $tpl_ini_array['web']['website_path'] = $conf['web']['website_path']; $tpl_ini_array['web']['website_symlinks'] = $conf['web']['website_symlinks']; @@ -740,7 +775,7 @@ public function grant_master_database_rights($verbose = false) { $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 , DELETE ON ?? TO ?@?"; + $query = "GRANT SELECT, INSERT, UPDATE, DELETE ON ?? TO ?@?"; if ($verbose){ echo $query ."\n"; } @@ -812,6 +847,14 @@ public function grant_master_database_rights($verbose = false) { $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); + } + } } @@ -838,9 +881,9 @@ public function process_postfix_config($configfile) { $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 = "''"; } @@ -871,20 +914,22 @@ public function configure_jailkit() { $config_dir = $cf['config_dir']; $jk_init = $cf['jk_init']; $jk_chrootsh = $cf['jk_chrootsh']; + $dest_jk_init = 'jk_init.ini'; + $dest_jk_chrootsh = 'jk_chrootsh.ini'; 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_init)) copy($config_dir.'/'.$jk_init, $config_dir.'/'.$dest_jk_init.'~'); + if(is_file($config_dir.'/'.$jk_chrootsh)) copy($config_dir.'/'.$jk_chrootsh, $config_dir.'/'.$dest_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); + copy($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$jk_init.'.master', $config_dir.'/'.$dest_jk_init); } else { - copy('tpl/'.$jk_init.'.master', $config_dir.'/'.$jk_init); + copy('tpl/'.$jk_init.'.master', $config_dir.'/'.$dest_jk_init); } if(is_file($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$jk_chrootsh.'.master')) { - copy($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$jk_chrootsh.'.master', $config_dir.'/'.$jk_chrootsh); + copy($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$jk_chrootsh.'.master', $config_dir.'/'.$dest_jk_chrootsh); } else { - copy('tpl/'.$jk_chrootsh.'.master', $config_dir.'/'.$jk_chrootsh); + copy('tpl/'.$jk_chrootsh.'.master', $config_dir.'/'.$dest_jk_chrootsh); } } @@ -1027,6 +1072,7 @@ public function remove_postfix_service( $service, $type ) { # reduce 3 or more newlines to 2 $content = rf($conf['postfix']['config_dir'].'/master.cf'); + $content = preg_replace( '/^# Data returning from Amavis .*$/m', '', $content ); # Cleanup comment we generated $content = preg_replace( '/(\r?\n){3,}/', '$1$1', $content ); wf( $conf['postfix']['config_dir'].'/master.cf', $content ); @@ -1136,7 +1182,7 @@ public function configure_postfix($options = '') { //* 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; @@ -1146,13 +1192,13 @@ public function configure_postfix($options = '') { //* 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, '; } @@ -1162,11 +1208,11 @@ public function configure_postfix($options = '') { $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'; } @@ -1311,7 +1357,7 @@ public function configure_postfix($options = '') { $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~'); } @@ -1320,8 +1366,8 @@ public function configure_postfix($options = '') { } $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); } @@ -1497,7 +1543,7 @@ public function configure_dovecot() { 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 @@ -1525,7 +1571,7 @@ public function configure_dovecot() { 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; @@ -1533,7 +1579,7 @@ public function configure_dovecot() { 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; } } @@ -1712,7 +1758,7 @@ public function configure_amavis() { // 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'; @@ -1723,7 +1769,7 @@ public function configure_amavis() { 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; @@ -1731,7 +1777,7 @@ public function configure_amavis() { 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; } } @@ -1868,7 +1914,7 @@ public function configure_rspamd() { 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; @@ -1935,10 +1981,10 @@ public function configure_rspamd() { ); 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']); @@ -1950,7 +1996,7 @@ public function configure_rspamd() { $tpl->setLoop('local_addrs', $local_addrs); } - wf("/etc/rspamd/local.d/${f}", $tpl->grab()); + wf("/etc/rspamd/local.d/{$f}", $tpl->grab()); } @@ -1967,10 +2013,10 @@ public function configure_rspamd() { '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}"); } } @@ -1980,10 +2026,10 @@ public function configure_rspamd() { '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}"); } } @@ -1995,10 +2041,10 @@ public function configure_rspamd() { '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}"); } } @@ -2007,7 +2053,7 @@ public function configure_rspamd() { 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'); @@ -2018,8 +2064,10 @@ public function configure_rspamd() { } # 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"'); @@ -2054,6 +2102,18 @@ public function configure_rspamd() { $tpl->setVar('rspamd_password', $rspamd_password); wf('/etc/rspamd/local.d/worker-controller.inc', $tpl->grab()); chmod('/etc/rspamd/local.d/worker-controller.inc', 0644); + + // rspamd.local.lua + if(file_exists($conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd.local.lua.master")) { + exec('cp '.$conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd.local.lua.master /etc/rspamd/rspamd.local.lua"); + } else { + exec("cp tpl/rspamd.local.lua.master /etc/rspamd/rspamd.local.lua"); + } + if(file_exists('/etc/rspamd/rspamd.local.lua')) { + exec('chgrp _rspamd /etc/rspamd/rspamd.local.lua'); + exec('chmod 640 /etc/rspamd/rspamd.local.lua'); + } + } public function configure_spamassassin() { @@ -2352,13 +2412,17 @@ public function configure_apache() { 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')) { @@ -2555,17 +2619,20 @@ public function configure_bastille_firewall() { $row = $this->db->queryOneRecord('SELECT * FROM ?? WHERE server_id = ?', $conf["mysql"]["database"] . '.firewall', $conf['server_id']); - if(trim($row['tcp_port']) != '' || trim($row['udp_port']) != '') { - $tcp_public_services = trim(str_replace(',', ' ', $row['tcp_port'])); - $udp_public_services = trim(str_replace(',', ' ', $row['udp_port'])); - } else { - $tcp_public_services = '21 22 25 53 80 110 143 443 3306 8080 10000'; - $udp_public_services = '53'; - } + $tcp_public_services = '21 22 25 53 80 110 143 443 3306 8080 10000'; + $udp_public_services = '53'; + + if (!empty($row)) { + if(trim($row['tcp_port']) != '' || trim($row['udp_port']) != '') { + $tcp_public_services = trim(str_replace(',', ' ', $row['tcp_port'])); + $udp_public_services = trim(str_replace(',', ' ', $row['udp_port'])); + } + + if(!stristr($tcp_public_services, $conf['apache']['vhost_port'])) { + $tcp_public_services .= ' '.intval($conf['apache']['vhost_port']); + if($row['tcp_port'] != '') $this->db->query("UPDATE firewall SET tcp_port = tcp_port + ? WHERE server_id = ?", ',' . intval($conf['apache']['vhost_port']), $conf['server_id']); + } - if(!stristr($tcp_public_services, $conf['apache']['vhost_port'])) { - $tcp_public_services .= ' '.intval($conf['apache']['vhost_port']); - if($row['tcp_port'] != '') $this->db->query("UPDATE firewall SET tcp_port = tcp_port + ? WHERE server_id = ?", ',' . intval($conf['apache']['vhost_port']), $conf['server_id']); } $content = str_replace('{TCP_PUBLIC_SERVICES}', $tcp_public_services, $content); @@ -2640,7 +2707,7 @@ public function configure_apps_vhost() { //$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); @@ -2723,6 +2790,11 @@ public function configure_apps_vhost() { $apps_vhost_group = escapeshellcmd($conf['web']['apps_vhost_group']); $install_dir = escapeshellcmd($conf['web']['website_basedir'].'/apps'); + //* Get the apps vhost port + if($this->is_update == true) { + $conf['web']['apps_vhost_port'] = get_apps_vhost_port_number(); + } + $command = 'groupadd '.$apps_vhost_user; if(!is_group($apps_vhost_group)) caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); @@ -2732,7 +2804,7 @@ public function configure_apps_vhost() { //$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); @@ -2829,7 +2901,7 @@ public function configure_apps_vhost() { //copy('tpl/nginx_ispconfig.vhost.master', "$vhost_conf_dir/ispconfig.vhost"); //* and create the symlink if(@is_link($vhost_conf_enabled_dir.'/apps.vhost')) unlink($vhost_conf_enabled_dir.'/apps.vhost'); - if(!@is_link($vhost_conf_enabled_dir.'/000-apps.vhost')) { + if(file_exists($vhost_conf_dir.'/apps.vhost') && is_dir($vhost_conf_enabled_dir) && !@is_link($vhost_conf_enabled_dir.'/000-apps.vhost')) { symlink($vhost_conf_dir.'/apps.vhost', $vhost_conf_enabled_dir.'/000-apps.vhost'); } } @@ -2909,7 +2981,7 @@ public function make_acme_vhost($server = 'apache') { if(@is_link($vhost_conf_enabled_dir.'/' . $use_symlink)) { unlink($vhost_conf_enabled_dir.'/' . $use_symlink); } - if(!@is_file($vhost_conf_enabled_dir.'/' . $use_symlink)) { + if(file_exists($vhost_conf_dir.'/' . $use_name) && is_dir($vhost_conf_enabled_dir) && !@is_file($vhost_conf_enabled_dir.'/' . $use_symlink)) { symlink($vhost_conf_dir.'/' . $use_name, $vhost_conf_enabled_dir.'/' . $use_symlink); } } @@ -2936,33 +3008,33 @@ public function make_ispconfig_ssl_cert() { } } $dns_ips = array(); - if (checkdnsrr($hostname, 'A')) { - $dnsa=dns_get_record($hostname, DNS_A); + if(checkdnsrr($hostname, 'A')) { + $dnsa = dns_get_record($hostname, DNS_A); if($dnsa) { - foreach ($dnsa as $rec) { - $dns_ips[] = $rec['ip']; + foreach($dnsa as $rec) { + if(is_array($rec) && isset($rec['ip'])) $dns_ips[] = $rec['ip']; } } } - if (checkdnsrr($hostname, 'AAAA')) { - $dnsaaaa=dns_get_record($hostname, DNS_AAAA); + if(checkdnsrr($hostname, 'AAAA')) { + $dnsaaaa = dns_get_record($hostname, DNS_AAAA); if($dnsaaaa) { - foreach ($dnsaaaa as $rec) { - $dns_ips[] = $rec['ip']; + foreach($dnsaaaa as $rec) { + if(is_array($rec) && isset($rec['ip'])) $dns_ips[] = $rec['ip']; } } } //* Define and check ISPConfig SSL folder */ - $ssl_dir = $conf['ispconfig_install_dir'].'/interface/ssl'; + $ssl_dir = $conf['ispconfig_install_dir'] . '/interface/ssl'; if(!@is_dir($ssl_dir)) { mkdir($ssl_dir, 0755, true); } - $ssl_crt_file = $ssl_dir.'/ispserver.crt'; - $ssl_csr_file = $ssl_dir.'/ispserver.csr'; - $ssl_key_file = $ssl_dir.'/ispserver.key'; - $ssl_pem_file = $ssl_dir.'/ispserver.pem'; + $ssl_crt_file = $ssl_dir . '/ispserver.crt'; + $ssl_csr_file = $ssl_dir . '/ispserver.csr'; + $ssl_key_file = $ssl_dir . '/ispserver.key'; + $ssl_pem_file = $ssl_dir . '/ispserver.pem'; $date = new DateTime(); @@ -2970,17 +3042,100 @@ public function make_ispconfig_ssl_cert() { swriteln('Checking / creating certificate for ' . $hostname); - $acme_cert_dir = '/usr/local/ispconfig/server/scripts/' . $hostname; - $check_acme_file = $acme_cert_dir . '/' . $hostname . '.cer'; - if(!@is_dir($acme_cert_dir)) { - $acme_cert_dir = '/root/.acme.sh/' . $hostname; - $check_acme_file = $acme_cert_dir . '/' . $hostname . '.cer'; - if(!@is_dir($acme_cert_dir)) { + // Get the default LE client name and version + $which_certbot = shell_exec('which certbot /root/.local/share/letsencrypt/bin/letsencrypt /opt/eff.org/certbot/venv/bin/certbot letsencrypt'); + $certbot = explode("\n", $which_certbot ?: ''); + $certbot = reset($certbot); + $certbot_version = '0.0.0-unknown'; + if($certbot) { + $matches = []; + $output = shell_exec($certbot . ' --version 2>&1'); + if(preg_match('/^(\S+|\w+)\s+(\d+(\.\d+)+)$/', $output, $matches)) { + $certbot_version = $matches[2]; + swriteln('Discovered certbot version ' . $certbot_version . ' with certificate home /etc/letsencrypt'); + } else { + $certbot = ''; + } + } + + // Check for Neilpang acme.sh as well and install it when we did not find certbot + $which_acme = 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); + $acme_version = '0.0.0-unknown'; + + if(!$certbot && !$acme) { + $this->install_acme(); + $which_acme = shell_exec('which acme.sh /usr/local/ispconfig/server/scripts/acme.sh /root/.acme.sh/acme.sh'); + $acme = explode("\n", $which_acme ?: ''); + $acme = reset($acme); + } + if($acme) { + // always update acme.sh + $this->update_acme(); + $matches = []; + $output = shell_exec($acme . ' --version 2>&1') ?: ''; + if(preg_match('/^v(\d+(\.\d+)+)$/m', $output, $matches)) { + $acme_version = $matches[1]; + } else { + $acme = ''; + } + if($acme) { + $ret = 0; + $acme_cert_home = []; + exec(join(' ; ', [ + '_info() { :', + ' _info_stdout=$(' . escapeshellarg($acme) . ' --info 2>/dev/null)', + ' _info_ret=$?', + '}', + '_echo_home() { :', + ' eval "$_info_stdout"', + ' _info_ret=$?', + ' if [ $_info_ret -eq 0 ]; then :', + ' if [ -z "$CERT_HOME" ]', + ' then echo "$LE_CONFIG_HOME"', + ' else echo "$CERT_HOME"', + ' fi', + ' else :', + ' echo "Error eval-ing --info output (exit code $_info_ret). stdout was: $_info_stdout"', + ' exit 1', + ' fi', + '}', + '_info', + 'if [ $_info_ret -eq 0 ]; then :', + ' _echo_home', + 'else :', + ' echo "--info failed. stdout was: $_info_stdout"', + ' exit 1', + 'fi', + ]), $acme_cert_home, $ret); + $acme_cert_home = trim(implode("\n", $acme_cert_home)); + if($ret != 0 || empty($acme_cert_home) || !is_dir($acme_cert_home)) { + swriteln('Cannot find acme.sh certificate home: ' . $acme_cert_home); + $acme = ''; + } else { + swriteln('Discovered acme.sh version ' . $acme_version . ' with certificate home ' . $acme_cert_home); + } + } + } + + $acme_cert_dir = 'not found'; + $check_acme_file = ''; + if($certbot) { + if(version_compare($certbot_version, '2.0', '>=')) { + $acme_cert_dir = '/etc/letsencrypt/live/' . $hostname . '_ecc'; + } else { $acme_cert_dir = '/etc/letsencrypt/live/' . $hostname; - $check_acme_file = $acme_cert_dir . '/cert.pem'; } + $check_acme_file = $acme_cert_dir . '/cert.pem'; + swriteln('Using certificate path ' . $acme_cert_dir . ' / ' . $check_acme_file); + } elseif($acme) { + $acme_cert_dir = $acme_cert_home . '/' . $hostname . '_ecc'; // always use ECC since we updated acme.sh + $check_acme_file = $acme_cert_dir . '/' . $hostname . '.cer'; + swriteln('Using certificate path ' . $acme_cert_dir . ' / ' . $check_acme_file); + } else { + swriteln('Failed discovering certbot or acme.sh and installing acme.sh. Will not be able to issue certificate during install.'); } - swriteln('Using certificate path ' . $acme_cert_dir); if(!is_dir($conf['ispconfig_log_dir'])) { mkdir($conf['ispconfig_log_dir'], 0755, true); @@ -2989,8 +3144,8 @@ public function make_ispconfig_ssl_cert() { $ip_address_match = false; if(!(($svr_ip4 && in_array($svr_ip4, $dns_ips)) || ($svr_ip6 && in_array($svr_ip6, $dns_ips)))) { - swriteln('Server\'s public ip(s) (' . $svr_ip4 . ($svr_ip6 ? ', ' . $svr_ip6 : '') . ') not found in A/AAAA records for ' . $hostname . ': ' . implode(', ', $dns_ips)); - if(strtolower($this->simple_query('Ignore DNS check and continue to request certificate?', array('y', 'n') , 'n','ignore_hostname_dns')) == 'y') { + swriteln('Server\'s public ip(s) (' . implode(', ', array_filter([$svr_ip4, $svr_ip6])) . ') not found in A/AAAA records for ' . $hostname . ': ' . implode(', ', $dns_ips)); + if(strtolower($this->simple_query('Ignore DNS check and continue to request certificate?', array('y', 'n'), 'n', 'ignore_hostname_dns')) == 'y') { $ip_address_match = true; } } else { @@ -2998,12 +3153,31 @@ public function make_ispconfig_ssl_cert() { } // Get subject and issuer of ispserver.crt to check if it is self-signed cert - if (file_exists($ssl_crt_file)) { - $crt_subject = exec("openssl x509 -in ".escapeshellarg($ssl_crt_file)." -inform PEM -noout -subject"); - $crt_issuer = exec("openssl x509 -in ".escapeshellarg($ssl_crt_file)." -inform PEM -noout -issuer"); + $self_signed = false; + if(file_exists($ssl_crt_file)) { + $crt_subject = exec("openssl x509 -in " . escapeshellarg($ssl_crt_file) . " -inform PEM -noout -subject"); + $crt_issuer = exec("openssl x509 -in " . escapeshellarg($ssl_crt_file) . " -inform PEM -noout -issuer"); + // strip the subject= and issuer= prefix to check for equality + if(is_string($crt_subject) && strpos($crt_subject, 'subject=') !== false) { + $crt_subject = explode('=', $crt_subject, 2)[1]; + } + if(is_string($crt_issuer) && strpos($crt_issuer, 'issuer=') !== false) { + $crt_issuer = explode('=', $crt_issuer, 2)[1]; + } + $self_signed = $crt_subject == $crt_issuer; + if ($self_signed) { + swriteln('ISPConfig currently is using a self-signed certificate.'); + } } - 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) { + $issued_successfully = false; + + // if we have certbot or acme.sh, the required DNS records and our desired certificate is not the current one, try to get it + if( + ($acme || $certbot) && $ip_address_match + && ($self_signed || + (!@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))) + ) { // This script is needed earlier to check and open http port 80 or standalone might fail // Make executable and temporary symlink latest letsencrypt pre, post and renew hook script before install @@ -3032,48 +3206,19 @@ public function make_ispconfig_ssl_cert() { chmod('/usr/local/bin/letsencrypt_renew_hook.sh', 0700); } - // Check http port 80 status as it cannot be determined at post hook stage - $port80_status=exec('true &>/dev/null 0) print "open"; else print "close";}\''); - // Set pre-, post- and renew hook - $pre_hook = "--pre-hook \"letsencrypt_pre_hook.sh\""; - $renew_hook = " --renew-hook \"letsencrypt_renew_hook.sh\""; + // Set pre-, post- and renew hook (acme.sh and certbot use the same arguments) + $pre_hook = '--pre-hook "letsencrypt_pre_hook.sh"'; + $renew_hook = ' --renew-hook "letsencrypt_renew_hook.sh"'; if($port80_status == 'close') { - $post_hook = " --post-hook \"letsencrypt_post_hook.sh\""; + $post_hook = ' --post-hook "letsencrypt_post_hook.sh"'; $hook = $pre_hook . $post_hook . $renew_hook; } else { $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", $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", $which_acme ? $which_acme : ''); - $acme = reset($acme); - - if((!$acme || !is_executable($acme)) && (!$le_client || !is_executable($le_client))) { - $success = $this->install_acme(); - if(!$success) { - swriteln('Failed installing acme.sh. Will not be able to issue certificate during install.'); - } else { - $acme = explode("\n", shell_exec('which acme.sh /usr/local/ispconfig/server/scripts/acme.sh /root/.acme.sh/acme.sh')); - $acme = reset($acme); - if($acme && is_executable($acme)) { - swriteln('Installed acme.sh and using it for certificate creation during install.'); - - // we do this even on install to enable automatic updates - $this->update_acme(); - } else { - swriteln('Failed installing acme.sh. Will not be able to issue certificate during install.'); - } - } - } - $restore_conf_symlink = false; // we only need this for apache, so use fixed conf index @@ -3086,23 +3231,21 @@ public function make_ispconfig_ssl_cert() { $server = 'nginx'; } elseif($conf['apache']['installed'] == true) { swriteln('Using apache for certificate validation'); - if($this->is_update == false && @is_link($vhost_conf_enabled_dir.'/000-ispconfig.conf')) { + if($this->is_update == false && @is_link($vhost_conf_enabled_dir . '/000-ispconfig.conf')) { $restore_conf_symlink = true; - unlink($vhost_conf_enabled_dir.'/000-ispconfig.conf'); + unlink($vhost_conf_enabled_dir . '/000-ispconfig.conf'); } $server = 'apache'; } if($conf[$server]['installed'] == true && $conf[$server]['init_script'] != '') { if($this->is_update) { - system($this->getinitcommand($conf[$server]['init_script'], 'force-reload').' &> /dev/null || ' . $this->getinitcommand($conf[$server]['init_script'], 'restart').' &> /dev/null'); + system($this->getinitcommand($conf[$server]['init_script'], 'force-reload') . ' &> /dev/null || ' . $this->getinitcommand($conf[$server]['init_script'], 'restart') . ' &> /dev/null'); } else { - system($this->getinitcommand($conf[$server]['init_script'], 'restart').' &> /dev/null'); + system($this->getinitcommand($conf[$server]['init_script'], 'restart') . ' &> /dev/null'); } } - $issued_successfully = false; - // Backup existing ispserver ssl files // // We may find valid or broken symlinks or actual files here. @@ -3118,24 +3261,20 @@ public function make_ispconfig_ssl_cert() { // - actual file copied to tmp name. // if cert request is successful, rename tmp copy to perm rename; // if cert request fails, delete tmp copy - $cert_files = array( $ssl_crt_file, $ssl_key_file, $ssl_pem_file ); - foreach ($cert_files as $f) { - if (is_link($f) && ! file_exists($f)) { - rename($f, $f.'-'.$date->format('YmdHis').'.bak'); - } elseif (is_link($f)) { - rename($f, $f.'-temporary.bak'); - copy($f.'-temporary.bak', $f); + $cert_files = array($ssl_crt_file, $ssl_key_file, $ssl_pem_file); + foreach($cert_files as $f) { + if(is_link($f) && !file_exists($f)) { + rename($f, $f . '-' . $date->format('YmdHis') . '.bak'); + } elseif(is_link($f)) { + rename($f, $f . '-temporary.bak'); + copy($f . '-temporary.bak', $f); } elseif(file_exists($f)) { - copy($f, $f.'-temporary.bak'); + copy($f, $f . '-temporary.bak'); } } // Attempt to use Neilpang acme.sh first, as it is now the preferred LE client - if (is_executable($acme)) { - $acme_cert_dir = dirname($acme) . '/' . $hostname; - - swriteln('acme.sh is installed, overriding certificate path to use ' . $acme_cert_dir); - + if($acme) { # acme.sh does not set umask, resulting in incorrect permissions (ispconfig issue #6015) $old_umask = umask(0022); @@ -3145,13 +3284,11 @@ public function make_ispconfig_ssl_cert() { $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); - } - // 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 ec-256 --ecc --log $acme_log -w /usr/local/ispconfig/interface/acme -d " . escapeshellarg($hostname) . " $renew_hook", $out, $ret); + } else { // Else, it is not webserver, so we use standalone + exec("$acme --issue --keylength ec-256 --ecc --log $acme_log --standalone -d " . escapeshellarg($hostname) . " $hook", $out, $ret); } - + umask($old_umask); if($ret == 0 || ($ret == 2 && file_exists($check_acme_file))) { // acme.sh returns with 2 on issue for already existing certificate @@ -3161,111 +3298,83 @@ public function make_ispconfig_ssl_cert() { //$acme_cert = "--cert-file $acme_cert_dir/cert.pem"; $acme_key = "--key-file " . escapeshellarg($ssl_key_file); $acme_chain = "--fullchain-file " . escapeshellarg($ssl_crt_file); - exec("$acme --install-cert --log $acme_log -d " . escapeshellarg($hostname) . " $acme_key $acme_chain"); + exec("$acme --install-cert --log $acme_log -d " . escapeshellarg($hostname) . " --ecc $acme_key $acme_chain"); $issued_successfully = true; - umask($old_umask); - - // Make temporary backup of self-signed certs permanent - foreach ($cert_files as $f) { - if (is_link($f.'-temporary.bak')) { - unlink($f.'-temporary.bak'); - } elseif(file_exists($f.'-temporary.bak')) { - rename($f.'-temporary.bak', $f.'-'.$date->format('YmdHis').'.bak'); - } - } - } else { swriteln('Issuing certificate via acme.sh failed. Please check that your hostname can be verified by letsencrypt'); - - umask($old_umask); - - // Restore/cleanup temporary backup of self-signed certs - foreach ($cert_files as $f) { - if (is_link($f.'-temporary.bak')) { - @unlink($f); - rename($f.'-temporary.bak', $f); - } elseif(file_exists($f.'-temporary.bak')) { - unlink($f.'-temporary.bak'); - } - } } - // Else, we attempt to use the official LE certbot client certbot - } else { - // But only if it is otherwise available - if(is_executable($le_client)) { - $out = null; - $ret = null; - - // Get its version info due to be used for webroot arguement issues - $le_info = exec($le_client . ' --version 2>&1', $ret, $val); - if(preg_match('/^(\S+|\w+)\s+(\d+(\.\d+)+)$/', $le_info, $matches)) { - $le_version = $matches[2]; - } + // Else, we attempt to use the official LE certbot client certbot + } else { + $out = null; + $ret = null; - // Define certbot commands - $acme_version = '--server https://acme-v0' . (($le_version >=0.22) ? '2' : '1') . '.api.letsencrypt.org/directory'; + if(version_compare($certbot_version, '0.22', '>=')) { + $acme_version = '--server https://acme-v02.api.letsencrypt.org/directory'; + } else { + $acme_version = '--server https://acme-v01.api.letsencrypt.org/directory'; + } + if(version_compare($certbot_version, '2.0', '>=')) { + $certonly = 'certonly --agree-tos --non-interactive --expand --cert-name ' . escapeshellarg($hostname . '_ecc') . ' --elliptic-curve secp256r1'; + } elseif(version_compare($certbot_version, '0.30', '>=')) { + $certonly = 'certonly --agree-tos --non-interactive --expand --cert-name ' . escapeshellarg($hostname) . ' --rsa-key-size 4096'; + } else { $certonly = 'certonly --agree-tos --non-interactive --expand --rsa-key-size 4096'; + } - // If this is a webserver - if($conf['nginx']['installed'] == true || $conf['apache']['installed'] == true) { - exec("$le_client $certonly $acme_version --authenticator webroot --webroot-path /usr/local/ispconfig/interface/acme --email " . escapeshellarg('postmaster@' . $hostname) . " -d " . escapeshellarg($hostname) . " $renew_hook", $out, $ret); - } - // Else, it is not webserver, so we use standalone - else { - exec("$le_client $certonly $acme_version --standalone --email " . escapeshellarg('postmaster@' . $hostname) . " -d " . escapeshellarg($hostname) . " $hook", $out, $ret); - } - - if($ret == 0) { - // certbot returns with 0 on issue for already existing certificate - - $acme_cert_dir = '/etc/letsencrypt/live/' . $hostname; - foreach (array( $ssl_crt_file, $ssl_key_file) as $f) { - if (file_exists($f) && ! is_link($f)) { - unlink($f); - } - } - symlink($acme_cert_dir . '/fullchain.pem', $ssl_crt_file); - symlink($acme_cert_dir . '/privkey.pem', $ssl_key_file); - - $issued_successfully = true; + // If this is a webserver + if($conf['nginx']['installed'] == true || $conf['apache']['installed'] == true) { + exec("$certbot $certonly $acme_version --authenticator webroot --webroot-path /usr/local/ispconfig/interface/acme --email " . escapeshellarg('postmaster@' . $hostname) . " -d " . escapeshellarg($hostname) . " $renew_hook", $out, $ret); + } else { // Else, it is not webserver, so we use standalone + exec("$certbot $certonly $acme_version --standalone --email " . escapeshellarg('postmaster@' . $hostname) . " -d " . escapeshellarg($hostname) . " $hook", $out, $ret); + } - // Make temporary backup of self-signed certs permanent - foreach ($cert_files as $f) { - if (is_link($f.'-temporary.bak')) { - unlink($f.'-temporary.bak'); - } elseif(file_exists($f.'-temporary.bak')) { - rename($f.'-temporary.bak', $f.'-'.$date->format('YmdHis').'.bak'); - } - } + if($ret == 0 && is_dir($acme_cert_dir)) { + // certbot returns with 0 on issue for already existing certificate - } else { - swriteln('Issuing certificate via certbot failed. Please check log files and make sure that your hostname can be verified by letsencrypt'); - - // Restore/cleanup temporary backup of self-signed certs - foreach ($cert_files as $f) { - if (is_link($f.'-temporary.bak')) { - @unlink($f); - rename($f.'-temporary.bak', $f); - } elseif(file_exists($f.'-temporary.bak')) { - unlink($f.'-temporary.bak'); - } + foreach(array($ssl_crt_file, $ssl_key_file) as $f) { + if(file_exists($f) && !is_link($f)) { + unlink($f); } - } + symlink($acme_cert_dir . '/fullchain.pem', $ssl_crt_file); + symlink($acme_cert_dir . '/privkey.pem', $ssl_key_file); + + $issued_successfully = true; } else { - swriteln('Did not find any valid acme client (acme.sh or certbot)'); + swriteln('Issuing certificate via certbot failed. Please check log files and make sure that your hostname can be verified by letsencrypt'); } } if($restore_conf_symlink) { - if(!@is_link($vhost_conf_enabled_dir.'/000-ispconfig.conf')) { - symlink($vhost_conf_dir.'/ispconfig.conf', $vhost_conf_enabled_dir.'/000-ispconfig.conf'); + if(!@is_link($vhost_conf_enabled_dir . '/000-ispconfig.conf')) { + symlink($vhost_conf_dir . '/ispconfig.conf', $vhost_conf_enabled_dir . '/000-ispconfig.conf'); + } + } + + if($issued_successfully) { + // Make temporary backup of self-signed certs permanent + foreach($cert_files as $f) { + if(is_link($f . '-temporary.bak')) { + unlink($f . '-temporary.bak'); + } elseif(file_exists($f . '-temporary.bak')) { + rename($f . '-temporary.bak', $f . '-' . $date->format('YmdHis') . '.bak'); + } + } + } else { + // Restore/cleanup temporary backup of self-signed certs + foreach($cert_files as $f) { + if(is_link($f . '-temporary.bak')) { + @unlink($f); + rename($f . '-temporary.bak', $f); + } elseif(file_exists($f . '-temporary.bak')) { + unlink($f . '-temporary.bak'); + } } } } else { if($ip_address_match) { - // the directory already exists so we have to assume that it was created previously + // the directory already exists, so we have to assume that it was created previously $issued_successfully = true; } } @@ -3280,7 +3389,7 @@ public function make_ispconfig_ssl_cert() { // We can still use the old self-signed method $openssl_cmd = 'openssl req -nodes -newkey rsa:4096 -x509 -days 3650 -keyout ' . escapeshellarg($ssl_key_file) . ' -out ' . escapeshellarg($ssl_crt_file); - if(AUTOINSTALL){ + if(AUTOINSTALL) { $openssl_cmd .= ' -subj ' . escapeshellarg('/C=' . $autoinstall['ssl_cert_country'] . '/ST=' . $autoinstall['ssl_cert_state'] . '/L=' . $autoinstall['ssl_cert_locality'] . '/O=' . $autoinstall['ssl_cert_organisation'] . '/OU=' . $autoinstall['ssl_cert_organisation_unit'] . '/CN=' . $autoinstall['ssl_cert_common_name']); } exec($openssl_cmd); @@ -3291,18 +3400,18 @@ public function make_ispconfig_ssl_cert() { 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 SSL certs to Postfix?', array('y', 'n'), 'y','ispconfig_postfix_ssl_symlink')) == 'y') { + if($conf['postfix']['installed'] == true && strtolower($this->simple_query('Symlink ISPConfig SSL certs to Postfix?', array('y', 'n'), 'y', 'ispconfig_postfix_ssl_symlink')) == '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'; + $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'); + 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); @@ -3310,26 +3419,25 @@ public function make_ispconfig_ssl_cert() { } // Extend LE SSL certs to pureftpd - if ($conf['pureftpd']['installed'] == true && strtolower($this->simple_query('Symlink ISPConfig SSL certs to Pure-FTPd? Creating dhparam file may take some time.', array('y', 'n'), 'y','ispconfig_pureftpd_ssl_symlink')) == 'y') { + if($conf['pureftpd']['installed'] == true && strtolower($this->simple_query('Symlink ISPConfig SSL certs to Pure-FTPd? Creating dhparam file may take some time.', array('y', 'n'), 'y', 'ispconfig_pureftpd_ssl_symlink')) == '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'; + $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'); + 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")) - 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"); + if(!file_exists("$pureftpd_dir/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"); } } exec("chown -R root:root $ssl_dir"); - } public function install_ispconfig() { @@ -3529,6 +3637,10 @@ public function install_ispconfig() { $command = 'chown -R ispconfig:ispconfig '.$install_dir.'/interface'; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); + //* chown the extensions directory to the ispconfig user and group + $command = 'chown ispconfig:ispconfig '.$install_dir.'/extensions'; + caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); + //* Chmod the files and directories in the acme dir $command = 'chmod -R 755 '.$install_dir.'/interface/acme'; caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); @@ -3612,20 +3724,32 @@ public function install_ispconfig() { // 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 @@ -3751,6 +3875,12 @@ public function install_ispconfig() { if(!is_link('/usr/local/bin/ispconfig_update_from_dev.sh')) symlink($install_dir.'/server/scripts/ispconfig_update.sh', '/usr/local/bin/ispconfig_update_from_dev.sh'); if(!is_link('/usr/local/bin/ispconfig_update.sh')) symlink($install_dir.'/server/scripts/ispconfig_update.sh', '/usr/local/bin/ispconfig_update.sh'); + // Install ISPConfig cli command + if(is_file('/usr/local/bin/ispc')) unlink('/usr/local/bin/ispc'); + chown($install_dir.'/server/cli/ispc', 'root'); + chmod($install_dir.'/server/cli/ispc', 0700); + symlink($install_dir.'/server/cli/ispc', '/usr/local/bin/ispc'); + // Make executable then unlink and symlink letsencrypt pre, post and renew hook scripts chown($install_dir.'/server/scripts/letsencrypt_pre_hook.sh', 'root'); chown($install_dir.'/server/scripts/letsencrypt_post_hook.sh', 'root'); @@ -3779,6 +3909,7 @@ public function install_ispconfig() { touch($conf['ispconfig_log_dir'].'/ispconfig.log'); } chmod($conf['ispconfig_log_dir'].'/ispconfig.log', 0600); + exec('chmod o-rw /var/log/ispconfig/*.gz /var/log/ispconfig/*.log'); //* Create the ispconfig auth log file and set uid/gid if(!is_file($conf['ispconfig_log_dir'].'/auth.log')) { @@ -3867,7 +3998,7 @@ public function install_crontab() { $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 @@ -3884,10 +4015,6 @@ public function install_crontab() { $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"; @@ -3900,7 +4027,7 @@ public function install_crontab() { //* 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( diff --git a/install/patches/upd_0100.php b/install/patches/upd_0100.php new file mode 100644 index 0000000000..75ff4cc75c --- /dev/null +++ b/install/patches/upd_0100.php @@ -0,0 +1,17 @@ + 1, }; +$policy_bank{'MYNETS'} = { + originating => 1, +}; # IP-Addresses for internal networks => load policy MYNETS # - requires -o smtp_send_xforward_command=yes in postfix master.cf diff --git a/install/tpl/config.inc.php.master b/install/tpl/config.inc.php.master index aa9329fb7b..de174bbd20 100644 --- a/install/tpl/config.inc.php.master +++ b/install/tpl/config.inc.php.master @@ -139,6 +139,7 @@ $conf['demo_mode'] = false; //** Logging $conf['log_file'] = $conf['ispconfig_log_dir'].$conf['fs_div'].'ispconfig.log'; $conf['log_priority'] = {ispconfig_log_priority}; // 0 = Debug, 1 = Warning, 2 = Error +$conf['db_log_message_max_length'] = 32768; //** Themes @@ -158,6 +159,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 diff --git a/install/tpl/debian6_dovecot-sql.conf.master b/install/tpl/debian6_dovecot-sql.conf.master index d0b5269e13..370c2aa9cb 100644 --- a/install/tpl/debian6_dovecot-sql.conf.master +++ b/install/tpl/debian6_dovecot-sql.conf.master @@ -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 diff --git a/install/tpl/debian_dovecot-sql.conf.master b/install/tpl/debian_dovecot-sql.conf.master index d0b5269e13..370c2aa9cb 100644 --- a/install/tpl/debian_dovecot-sql.conf.master +++ b/install/tpl/debian_dovecot-sql.conf.master @@ -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 diff --git a/install/tpl/debian_postfix.conf.master b/install/tpl/debian_postfix.conf.master index 8bd34f6928..384559548d 100644 --- a/install/tpl/debian_postfix.conf.master +++ b/install/tpl/debian_postfix.conf.master @@ -26,15 +26,16 @@ relay_recipient_maps = proxy:mysql:{config_dir}/mysql-virtual_relayrecipientmaps smtpd_sender_login_maps = proxy:mysql:{config_dir}/mysql-virtual_sender_login_maps.cf proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $sender_bcc_maps $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $smtpd_sender_login_maps $virtual_uid_maps $virtual_gid_maps $smtpd_client_restrictions $smtpd_sender_restrictions $smtpd_recipient_restrictions $smtp_sasl_password_maps $sender_dependent_relayhost_maps smtpd_helo_required = yes -smtpd_helo_restrictions = permit_mynetworks, check_helo_access regexp:{config_dir}/helo_access, permit_sasl_authenticated, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, check_helo_access regexp:{config_dir}/blacklist_helo, {reject_unknown_helo_hostname}, permit +smtpd_helo_restrictions = permit_mynetworks, check_helo_access regexp:{config_dir}/helo_access, permit_sasl_authenticated, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, check_helo_access regexp:{config_dir}/blacklist_helo{reject_unknown_helo_hostname}, permit smtpd_sender_restrictions = check_sender_access proxy:mysql:{config_dir}/mysql-virtual_sender.cf, {reject_aslm} check_sender_access regexp:{config_dir}/tag_as_originating.re, permit_mynetworks{reject_slm}, permit_sasl_authenticated, reject_non_fqdn_sender, reject_unlisted_sender, check_sender_access regexp:{config_dir}/tag_as_foreign.re smtpd_reject_unlisted_sender = no -smtpd_client_restrictions = check_client_access proxy:mysql:{config_dir}/mysql-virtual_client.cf, permit_inet_interfaces, permit_mynetworks, permit_sasl_authenticated{rbl_list}, reject_unauth_pipelining {reject_unknown_client_hostname}, permit +smtpd_client_restrictions = check_client_access proxy:mysql:{config_dir}/mysql-virtual_client.cf, permit_inet_interfaces, permit_mynetworks, permit_sasl_authenticated{rbl_list}, reject_unauth_pipelining{reject_unknown_client_hostname}, permit smtpd_etrn_restrictions = permit_mynetworks, reject smtpd_data_restrictions = permit_mynetworks, reject_unauth_pipelining, reject_multi_recipient_bounce, permit smtpd_client_message_rate_limit = 100 -maildrop_destination_concurrency_limit = 1 -maildrop_destination_recipient_limit = 1 +# Needed for courier pop3/imap only +# maildrop_destination_concurrency_limit = 1 +# maildrop_destination_recipient_limit = 1 virtual_transport = maildrop header_checks = regexp:{config_dir}/header_checks mime_header_checks = regexp:{config_dir}/mime_header_checks @@ -60,4 +61,4 @@ smtp_sasl_auth_enable = yes smtp_sasl_security_options = noanonymous, noplaintext smtp_sasl_tls_security_options = noanonymous authorized_flush_users = -authorized_mailq_users = nagios, icinga +authorized_mailq_users = nagios, icinga, zabbix diff --git a/install/tpl/fedora_dovecot-sql.conf.master b/install/tpl/fedora_dovecot-sql.conf.master index d0b5269e13..370c2aa9cb 100644 --- a/install/tpl/fedora_dovecot-sql.conf.master +++ b/install/tpl/fedora_dovecot-sql.conf.master @@ -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 diff --git a/install/tpl/fedora_postfix.conf.master b/install/tpl/fedora_postfix.conf.master index 8d2b1a9dc2..59e35b9d9f 100644 --- a/install/tpl/fedora_postfix.conf.master +++ b/install/tpl/fedora_postfix.conf.master @@ -22,15 +22,16 @@ relay_recipient_maps = proxy:mysql:{config_dir}/mysql-virtual_relayrecipientmaps smtpd_sender_login_maps = proxy:mysql:{config_dir}/mysql-virtual_sender_login_maps.cf proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $sender_bcc_maps $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $smtpd_sender_login_maps $virtual_uid_maps $virtual_gid_maps $smtpd_client_restrictions $smtpd_sender_restrictions $smtpd_recipient_restrictions $smtp_sasl_password_maps $sender_dependent_relayhost_maps smtpd_helo_required = yes -smtpd_helo_restrictions = permit_mynetworks, check_helo_access regexp:{config_dir}/helo_access, permit_sasl_authenticated, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, check_helo_access regexp:{config_dir}/blacklist_helo, {reject_unknown_helo_hostname}, permit +smtpd_helo_restrictions = permit_mynetworks, check_helo_access regexp:{config_dir}/helo_access, permit_sasl_authenticated, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, check_helo_access regexp:{config_dir}/blacklist_helo{reject_unknown_helo_hostname}, permit smtpd_sender_restrictions = check_sender_access proxy:mysql:{config_dir}/mysql-virtual_sender.cf, {reject_aslm} check_sender_access regexp:{config_dir}/tag_as_originating.re, permit_mynetworks{reject_slm}, permit_sasl_authenticated, reject_non_fqdn_sender, reject_unlisted_sender, check_sender_access regexp:{config_dir}/tag_as_foreign.re smtpd_reject_unlisted_sender = no -smtpd_client_restrictions = check_client_access proxy:mysql:{config_dir}/mysql-virtual_client.cf, permit_inet_interfaces, permit_mynetworks, permit_sasl_authenticated{rbl_list}, reject_unauth_pipelining {reject_unknown_client_hostname}, permit +smtpd_client_restrictions = check_client_access proxy:mysql:{config_dir}/mysql-virtual_client.cf, permit_inet_interfaces, permit_mynetworks, permit_sasl_authenticated{rbl_list}, reject_unauth_pipelining{reject_unknown_client_hostname}, permit smtpd_etrn_restrictions = permit_mynetworks, reject smtpd_data_restrictions = permit_mynetworks, reject_unauth_pipelining, reject_multi_recipient_bounce, permit smtpd_client_message_rate_limit = 100 -maildrop_destination_concurrency_limit = 1 -maildrop_destination_recipient_limit = 1 +# Needed for courier pop3/imap only +# maildrop_destination_concurrency_limit = 1 +# maildrop_destination_recipient_limit = 1 virtual_transport = maildrop header_checks = regexp:{config_dir}/header_checks mime_header_checks = regexp:{config_dir}/mime_header_checks @@ -56,4 +57,4 @@ smtp_sasl_auth_enable = yes smtp_sasl_security_options = noanonymous, noplaintext smtp_sasl_tls_security_options = noanonymous authorized_flush_users = -authorized_mailq_users = nagios, icinga +authorized_mailq_users = nagios, icinga, zabbix diff --git a/install/tpl/gentoo_postfix.conf.master b/install/tpl/gentoo_postfix.conf.master index c6b1c2f9c5..4b9f4850f6 100644 --- a/install/tpl/gentoo_postfix.conf.master +++ b/install/tpl/gentoo_postfix.conf.master @@ -1,3 +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 = 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 @@ -24,18 +29,19 @@ smtpd_helo_required = yes smtpd_helo_restrictions = permit_mynetworks, check_helo_access regexp:{config_dir}/helo_access, permit_sasl_authenticated, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, check_helo_access regexp:{config_dir}/blacklist_helo, {reject_unknown_helo_hostname}, permit smtpd_sender_restrictions = check_sender_access proxy:mysql:{config_dir}/mysql-virtual_sender.cf, {reject_aslm} check_sender_access regexp:{config_dir}/tag_as_originating.re, permit_mynetworks{reject_slm}, permit_sasl_authenticated, reject_non_fqdn_sender, reject_unlisted_sender, check_sender_access regexp:{config_dir}/tag_as_foreign.re smtpd_reject_unlisted_sender = no -smtpd_client_restrictions = check_client_access proxy:mysql:{config_dir}/mysql-virtual_client.cf, permit_inet_interfaces, permit_mynetworks, permit_sasl_authenticated{rbl_list}, reject_unauth_pipelining {reject_unknown_client_hostname}, permit +smtpd_client_restrictions = check_client_access proxy:mysql:{config_dir}/mysql-virtual_client.cf, permit_inet_interfaces, permit_mynetworks, permit_sasl_authenticated{rbl_list}, reject_unauth_pipelining{reject_unknown_client_hostname}, permit smtpd_etrn_restrictions = permit_mynetworks, reject smtpd_data_restrictions = permit_mynetworks, reject_unauth_pipelining, reject_multi_recipient_bounce, permit smtpd_client_message_rate_limit = 100 -maildrop_destination_concurrency_limit = 1 -maildrop_destination_recipient_limit = 1 +# Needed for courier pop3/imap only +# maildrop_destination_concurrency_limit = 1 +# maildrop_destination_recipient_limit = 1 virtual_transport = maildrop 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 @@ -55,4 +61,4 @@ smtp_sasl_auth_enable = yes smtp_sasl_security_options = noanonymous, noplaintext smtp_sasl_tls_security_options = noanonymous authorized_flush_users = -authorized_mailq_users = nagios, icinga +authorized_mailq_users = nagios, icinga, zabbix diff --git a/install/tpl/jk_init.ini.master b/install/tpl/jk_init.ini.master index 0f9acb1ced..74356baa61 100644 --- a/install/tpl/jk_init.ini.master +++ b/install/tpl/jk_init.ini.master @@ -28,6 +28,10 @@ includesections = uidbasics, logbasics comment = alias for jk_lsh includesections = jk_lsh +[openssl] +comment = Generic openssl files (excluded: /etc/ssl/private, /usr/lib/ssl/private) +paths = /bin/openssl, /etc/ssl/openssl.cnf, /etc/ssl/certs, /usr/lib/ssl/cert.pem, /usr/lib/ssl/certs, /usr/lib/ssl/misc, /usr/lib/ssl/openssl.cnf, /usr/share/ca-certificates + [cvs] comment = Concurrent Versions System paths = cvs @@ -67,7 +71,7 @@ devices = /dev/null [basicshell] comment = bash based shell with several basic utilities -paths = /bin/sh, bash, ls, cat, chmod, mkdir, cp, cpio, date, dd, echo, egrep, false, fgrep, grep, gunzip, gzip, ln, ls, mkdir, mktemp, more, mv, pwd, rm, rmdir, sed, sh, sleep, sync, tar, touch, true, uncompress, zcat, /etc/motd, /etc/issue, /etc/bash.bashrc, /etc/bashrc, /etc/profile, /usr/lib/locale/en_US.utf8, uname, expr, xargs +paths = /bin/sh, bash, ls, cat, chmod, mkdir, cp, cpio, date, dd, echo, egrep, false, fgrep, grep, gunzip, gzip, ln, ls, mkdir, mktemp, more, mv, pwd, rm, rmdir, sed, sh, sleep, sync, tar, touch, true, uncompress, zcat, /etc/motd, /etc/issue, /etc/bash.bashrc, /etc/bashrc, /etc/profile, /usr/lib/locale/en_US.utf8, uname, expr, xargs, /etc/inputrc users = root groups = root includesections = uidbasics @@ -240,9 +244,27 @@ 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 + +[php8_3] +comment = php version 8.3 +paths = /usr/bin/php8.3, /usr/lib/php/8.3/, /usr/lib/php/20230831/, /usr/share/php/8.3/, /etc/php/8.3/cli/, /etc/php/8.3/mods-available/ +includesections = php_common + +[php8_4] +comment = php version 8.4 +paths = /usr/bin/php8.4, /usr/lib/php/8.4/, /usr/lib/php/20240924/, /usr/share/php/8.4/, /etc/php/8.4/cli/, /etc/php/8.4/mods-available/ includesections = php_common [imagemagick] comment = ImageMagick needed for php-imagemagick extension paths = /usr/share/ImageMagick-*, /etc/ImageMagick-*, /usr/lib/*/ImageMagick-* + +[java] +comment = Java (openjdk package) +paths = /usr/bin/java, /usr/share/java, /usr/lib/jvm/, /etc/ld.so.conf* + +[pdftk] +comment = pdftk +paths = /usr/bin/pdftk, /usr/share/pdftk/ \ No newline at end of file diff --git a/install/tpl/jk_init_el.ini.master b/install/tpl/jk_init_el.ini.master new file mode 100644 index 0000000000..d56247f7b6 --- /dev/null +++ b/install/tpl/jk_init_el.ini.master @@ -0,0 +1,272 @@ +# jk_init.ini: jailkit initialization config + +# Includes paths to handle Enterprise Linux systems like RHEL and its derivatives AlmaLinux, Rocky Linux et cetera +# if other paths are needed please create an issue with the details or even a merge request at: +# https://git.ispconfig.org/ispconfig/ispconfig3 + +[uidbasics] +comment = common files for all jails that need user/group information +paths = /lib*/libnsl.so.*, /lib*/libnss*.so.*, /lib/*/libnsl.so.*, /lib/*/libnss*.so.*, /etc/nsswitch.conf, /etc/ld.so.conf + +[netbasics] +comment = common files for all jails that need any internet connectivity +paths = /lib*/libnss_dns.so.*, /lib*/libnss_mdns*.so.*, /lib/*/libnss_dns.so.*, /lib/*/libnss_mdns*.so.*, /etc/resolv.conf, /etc/host.conf, /etc/hosts, /etc/protocols, /etc/services, /etc/ssl/certs/, /usr/lib/ssl/certs + +[logbasics] +comment = timezone information and log sockets +paths = /etc/localtime +need_logsocket = 1 + +[enterpriselinuxbasics] +comment = Various Enterprise Linux specific directories and programs +paths = /usr/lib/locale, /usr/share/modulefiles, /usr/share/Modules, /usr/share/tcl*, /usr/bin/lesspipe.sh, /usr/libexec/grepconf.sh, /usr/bin/tclsh, /usr/bin/tty +includesections = enterpriselinux_etc_env + +[enterpriselinux_etc_env] +comment = Enterprise Linux /etc specific environment related files +paths = /etc/profile, /etc/modulefiles, /etc/alternatives/modulecmd, /etc/DIR_COLORS*, /etc/sysconfig/bash-prompt-default, /etc/profile.d/bash_completion.sh, /etc/profile.d/color*, /etc/profile.d/lang*, /etc/profile.d/less*, /etc/profile.d/sh.local, /etc/profile.d/vim*, /etc/profile.d/composer*, /etc/profile.d/conda*, /etc/profile.d/guestfish.sh, /etc/locale.conf, /etc/inputrc +emptydirs = /etc/ssl, /etc/pki + +[jk_lsh] +comment = Jailkit limited shell +paths = /usr/sbin/jk_lsh, /etc/jailkit/jk_lsh.ini +users = root +groups = root +includesections = uidbasics, logbasics + +[limitedshell] +comment = alias for jk_lsh +includesections = jk_lsh + +[cvs] +comment = Concurrent Versions System +paths = cvs +devices = /dev/null + +[git] +comment = Fast Version Control System +paths = /usr/bin/git*, /usr/lib/git-core, /usr/share/git-core, pager +includesections = editors, perl, netbasics, basicshell, coreutils + +[scp] +comment = ssh secure copy +paths = scp +includesections = netbasics, uidbasics +devices = /dev/urandom, /dev/null + +[sftp] +comment = ssh secure ftp +paths = /usr/lib/sftp-server, /usr/libexec/openssh/sftp-server, /usr/lib/misc/sftp-server, /usr/libexec/sftp-server, /usr/lib/openssh/sftp-server +includesections = netbasics, uidbasics +devices = /dev/urandom, /dev/null + +[ssh] +comment = ssh secure shell +paths = ssh +includesections = netbasics, uidbasics +devices = /dev/urandom, /dev/tty, /dev/null + +[rsync] +paths = rsync +includesections = netbasics, uidbasics + +[procmail] +comment = procmail mail delivery +paths = procmail, /bin/sh +devices = /dev/null + +[basicshell] +comment = bash based shell with several basic utilities +paths = /bin/sh, bash, ls, cat, chmod, mkdir, cp, cpio, date, dd, echo, egrep, false, fgrep, grep, gunzip, gzip, ln, ls, mkdir, mktemp, more, mv, pwd, rm, rmdir, sed, sh, sleep, sync, tar, touch, true, uncompress, zcat, /etc/motd, /etc/issue, /etc/bash.bashrc, /etc/bashrc, /etc/profile, /usr/lib/locale/en_US.utf8, uname, expr, xargs +users = root +groups = root +includesections = uidbasics, enterpriselinuxbasics + +[interactiveshell] +comment = for ssh access to a full shell +includesections = uidbasics, basicshell, terminfo, editors, extendedshell + +[midnightcommander] +comment = Midnight Commander +paths = mc, mcedit, mcview, /usr/share/mc +includesections = basicshell, terminfo + +[extendedshell] +comment = bash shell including things like awk, bzip, tail, less +paths = awk, bzip2, bunzip2, ldd, less, clear, cut, du, find, head, less, md5sum, nice, sort, tac, tail, tr, sort, wc, watch, whoami +includesections = basicshell, midnightcommander, editors + +[terminfo] +comment = terminfo databases, required for example for ncurses or vim +paths = /etc/terminfo, /usr/share/terminfo, /lib/terminfo + +[editors] +comment = vim, joe and nano +includesections = terminfo +paths = joe, nano, vi, vim, /etc/vimrc, /etc/joe, /usr/share/vim + +[netutils] +comment = several internet utilities like curl, wget, ftp, rsync, scp, ssh +paths = curl, wget, lynx, ftp, host, rsync, smbclient +includesections = netbasics, ssh, sftp, scp + +[apacheutils] +comment = htpasswd utility +paths = htpasswd + +[extshellplusnet] +comment = alias for extendedshell + netutils + apacheutils +includesections = extendedshell, netutils, apacheutils + +[openvpn] +comment = jail for the openvpn daemon +paths = /usr/sbin/openvpn +users = root,nobody +groups = root,nogroup +devices = /dev/urandom, /dev/random, /dev/net/tun +includesections = netbasics, uidbasics +need_logsocket = 1 + +[apache] +comment = the apache webserver, very basic setup, probably too limited for you +paths = /usr/sbin/apache +users = root, www-data +groups = root, www-data +includesections = netbasics, uidbasics + +[perl] +comment = the perl interpreter and libraries +paths = perl, /usr/lib64/perl, /usr/lib64/perl5, /usr/share/perl, /usr/share/perl5 + +[xauth] +comment = getting X authentication to work +paths = /usr/bin/X11/xauth, /usr/X11R6/lib/X11/rgb.txt, /etc/ld.so.conf + +[xclients] +comment = minimal files for X clients +paths = /usr/X11R6/lib/X11/rgb.txt +includesections = xauth + +[vncserver] +comment = the VNC server program +paths = Xvnc, Xrealvnc, /usr/X11R6/lib/X11/fonts/ +includesections = xclients + +[ping] +comment = Ping program +paths_w_setuid = /bin/ping + +#[xterm] +#comment = xterm +#paths = /usr/bin/X11/xterm, /usr/share/terminfo, /etc/terminfo +#devices = /dev/pts/0, /dev/pts/1, /dev/pts/2, /dev/pts/3, /dev/pts/4, /dev/ptyb4, /dev/ptya4, /dev/tty, /dev/tty0, /dev/tty4 + +[coreutils] +comment = Progs from coreutils +paths = arch, b2sum, base32, base64, basename, cat, chcon, chgrp, chmod, chown, cksum, comm, cp, csplit, cut, date, dir, dircolors, dirname, du, echo, env, expand, expr, factor, false, fmt, fold, groups, head, hostid, id, install, join, link, ln, logname, ls, md5sum, mkdir, mkfifo, mknod, mktemp, mv, nice, nl, nohup, nproc, numfmt, od, paste, pathchk, pinky, pr, printenv, printf, ptx, pwd, readlink, realpath, rm, rmdir, runcon, seq, sha1sum, sha224sum, sha256sum, sha384sum, sha512sum, shred, shuf, sleep, sort, split, stat, stdbuf, stty, sum, tac, tail, tee, test, timeout, touch, tr, true, truncate, tsort, uname, unexpand, uniq, unlink, users, vdir, wc, who, whoami, yes + +[webutils] +comment = Collection of commonly used utils for webapps +paths = /usr/bin/gm, /usr/bin/convert, /usr/bin/identify, /usr/bin/composite, /usr/bin/combine, /usr/bin/cwebp, /usr/bin/pdf* + +[mysqlutils] +comment = MySQL client utils +paths = mysql, mysqldump, mysqlshow + +[composer] +comment = composer +paths = composer, /usr/local/bin/composer, /usr/share/doc/composer +includesections = php, uidbasics, netbasics + +[node] +comment = NodeJS +paths = npm, npx, node, nodejs, semver, /usr/lib/nodejs, /usr/share/nodejs, /usr/share/npm, /usr/share/node-mime, /usr/lib/node_modules, /usr/local/lib/nodejs, /usr/local/lib/node_modules, /etc/npmrc, /etc/npmignore, elmi-to-json, /usr/local/bin/elmi-to-json + +[env] +comment = /usr/bin/env for environment variables +paths = env + +[php] +comment = default php version and libraries +paths = /usr/bin/php +includesections = php_common + +[php_common] +comment = Common PHP directories and libraries +# notice: potential information leak +# do not add all of /etc/php/ or any of the fpm directories +# or the php config (which includes custom php snippets) from *all* +# sites which use fpm will be copied to *every* jailkit +paths = /usr/bin/php, /usr/bin/phar, /usr/lib64/php/, /usr/share/php/, /usr/share/zoneinfo/ +includesections = env, logbasics, netbasics, mysqlutils, webutils, imagemagick + +[php5_4] +comment = PHP 5.4 +paths = /opt/remi/php54/root/bin/php, /usr/bin/php54, /opt/remi/php54/root/bin/phar, /opt/remi/php54/root/usr/lib64/, /opt/remi/php54/root/usr/share/ +includesections = php_common + +[php5_5] +comment = PHP 5.5 +paths = /opt/remi/php55/root/bin/php, /usr/bin/php55, /opt/remi/php55/root/bin/phar, /opt/remi/php55/root/usr/lib64/, /opt/remi/php55/root/usr/share/ +includesections = php_common + +[php5_6] +comment = PHP 5.6 +paths = /opt/remi/php56/root/bin/php, /usr/bin/php56, /opt/remi/php56/root/bin/phar, /opt/remi/php56/root/usr/lib64/, /opt/remi/php56/root/usr/share/ +includesections = php_common + +[php7_0] +comment = PHP 7.0 +paths = /opt/remi/php70/root/bin/php, /usr/bin/php70, /opt/remi/php70/root/bin/phar, /opt/remi/php70/root/usr/lib64/, /opt/remi/php70/root/usr/share/ +includesections = php_common + +[php7_1] +comment = PHP 7.1 +paths = /opt/remi/php71/root/bin/php, /usr/bin/php71, /opt/remi/php71/root/bin/phar, /opt/remi/php71/root/usr/lib64/, /opt/remi/php71/root/usr/share/ +includesections = php_common + +[php7_2] +comment = PHP 7.2 +paths = /opt/remi/php72/root/bin/php, /usr/bin/php72, /opt/remi/php72/root/bin/phar, /opt/remi/php72/root/usr/lib64/, /opt/remi/php72/root/usr/share/ +includesections = php_common + +[php7_3] +comment = PHP 7.3 +paths = /opt/remi/php73/root/bin/php, /usr/bin/php73, /opt/remi/php73/root/bin/phar, /opt/remi/php73/root/usr/lib64/, /opt/remi/php73/root/usr/share/ +includesections = php_common + +[php7_4] +comment = PHP 7.4 +paths = /opt/remi/php74/root/bin/php, /usr/bin/php74, /opt/remi/php74/root/bin/phar, /opt/remi/php74/root/usr/lib64/, /opt/remi/php74/root/usr/share/ +includesections = php_common + +[php8_0] +comment = PHP 8.0 +paths = /opt/remi/php80/root/bin/php, /usr/bin/php80, /opt/remi/php80/root/bin/phar, /opt/remi/php80/root/usr/lib64/, /opt/remi/php80/root/usr/share/ +includesections = php_common + +[php8_1] +comment = PHP 8.1 +paths = /opt/remi/php81/root/bin/php, /usr/bin/php81, /opt/remi/php81/root/bin/phar, /opt/remi/php81/root/usr/lib64/, /opt/remi/php81/root/usr/share/ +includesections = php_common + +[php8_2] +comment = PHP 8.2 +paths = /opt/remi/php82/root/bin/php, /usr/bin/php82, /opt/remi/php82/root/bin/phar, /opt/remi/php82/root/usr/lib64/, /opt/remi/php82/root/usr/share/ +includesections = php_common + +[php8_3] +comment = PHP 8.3 +paths = /opt/remi/php83/root/bin/php, /usr/bin/php83, /opt/remi/php83/root/bin/phar, /opt/remi/php83/root/usr/lib64/, /opt/remi/php83/root/usr/share/ +includesections = php_common + +[php8_4] +comment = PHP 8.4 +paths = /opt/remi/php84/root/bin/php, /usr/bin/php84, /opt/remi/php84/root/bin/phar, /opt/remi/php84/root/usr/lib64/, /opt/remi/php84/root/usr/share/ +includesections = php_common + +[imagemagick] +comment = ImageMagick needed for php-imagemagick extension +paths = /usr/share/ImageMagick-*, /etc/ImageMagick-*, /usr/lib64/ImageMagick-* + + diff --git a/install/tpl/master_cf_amavis10025.master b/install/tpl/master_cf_amavis10025.master index 68d4561494..bac50f483f 100644 --- a/install/tpl/master_cf_amavis10025.master +++ b/install/tpl/master_cf_amavis10025.master @@ -1,4 +1,5 @@ +# Data returning from Amavis content filtering, defaults to incomming amavis port(10024) +1 127.0.0.1:10025 inet n - n - - smtpd -o content_filter= -o local_recipient_maps= diff --git a/install/tpl/master_cf_amavis10027.master b/install/tpl/master_cf_amavis10027.master index d3a07a8bce..5a7f5fd01c 100644 --- a/install/tpl/master_cf_amavis10027.master +++ b/install/tpl/master_cf_amavis10027.master @@ -1,4 +1,5 @@ +# Data returning from Amavis DKIM signing, defaults to incomming amavis port(10026) +1 127.0.0.1:10027 inet n - n - - smtpd -o content_filter= -o local_recipient_maps= diff --git a/install/tpl/mysql-virtual_domains.cf.master b/install/tpl/mysql-virtual_domains.cf.master index 11ccb046ef..0d8588f411 100644 --- a/install/tpl/mysql-virtual_domains.cf.master +++ b/install/tpl/mysql-virtual_domains.cf.master @@ -2,5 +2,5 @@ user = {mysql_server_ispconfig_user} password = {mysql_server_ispconfig_password} dbname = {mysql_server_database} hosts = {mysql_server_ip} -query = SELECT domain FROM mail_domain WHERE domain = '%s' AND active = 'y' AND server_id = {server_id} +query = SELECT domain FROM mail_domain WHERE domain = '%s' AND active = 'y' AND local_delivery = 'y' AND server_id = {server_id} AND NOT EXISTS (SELECT source FROM mail_forwarding WHERE source = '@%s' AND type = 'aliasdomain' AND active = 'y' AND server_id = {server_id}) diff --git a/install/tpl/opensuse_dovecot-sql.conf.master b/install/tpl/opensuse_dovecot-sql.conf.master index d0b5269e13..370c2aa9cb 100644 --- a/install/tpl/opensuse_dovecot-sql.conf.master +++ b/install/tpl/opensuse_dovecot-sql.conf.master @@ -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 diff --git a/install/tpl/opensuse_postfix.conf.master b/install/tpl/opensuse_postfix.conf.master index 03f134bb08..2e4d7deb07 100644 --- a/install/tpl/opensuse_postfix.conf.master +++ b/install/tpl/opensuse_postfix.conf.master @@ -24,15 +24,16 @@ relay_recipient_maps = proxy:mysql:{config_dir}/mysql-virtual_relayrecipientmaps smtpd_sender_login_maps = proxy:mysql:{config_dir}/mysql-virtual_sender_login_maps.cf proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $sender_bcc_maps $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $smtpd_sender_login_maps $virtual_uid_maps $virtual_gid_maps $smtpd_client_restrictions $smtpd_sender_restrictions $smtpd_recipient_restrictions $smtp_sasl_password_maps $sender_dependent_relayhost_maps smtpd_helo_required = yes -smtpd_helo_restrictions = permit_mynetworks, check_helo_access regexp:{config_dir}/helo_access, permit_sasl_authenticated, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, check_helo_access regexp:{config_dir}/blacklist_helo, {reject_unknown_helo_hostname}, permit +smtpd_helo_restrictions = permit_mynetworks, check_helo_access regexp:{config_dir}/helo_access, permit_sasl_authenticated, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, check_helo_access regexp:{config_dir}/blacklist_helo{reject_unknown_helo_hostname}, permit smtpd_sender_restrictions = check_sender_access proxy:mysql:{config_dir}/mysql-virtual_sender.cf, {reject_aslm} check_sender_access regexp:{config_dir}/tag_as_originating.re, permit_mynetworks{reject_slm}, permit_sasl_authenticated, reject_non_fqdn_sender, reject_unlisted_sender, check_sender_access regexp:{config_dir}/tag_as_foreign.re smtpd_reject_unlisted_sender = no -smtpd_client_restrictions = check_client_access proxy:mysql:{config_dir}/mysql-virtual_client.cf, permit_inet_interfaces, permit_mynetworks, permit_sasl_authenticated{rbl_list}, reject_unauth_pipelining {reject_unknown_client_hostname}, permit +smtpd_client_restrictions = check_client_access proxy:mysql:{config_dir}/mysql-virtual_client.cf, permit_inet_interfaces, permit_mynetworks, permit_sasl_authenticated{rbl_list}, reject_unauth_pipelining{reject_unknown_client_hostname}, permit smtpd_etrn_restrictions = permit_mynetworks, reject smtpd_data_restrictions = permit_mynetworks, reject_unauth_pipelining, reject_multi_recipient_bounce, permit smtpd_client_message_rate_limit = 100 -maildrop_destination_concurrency_limit = 1 -maildrop_destination_recipient_limit = 1 +# Needed for courier pop3/imap only +# maildrop_destination_concurrency_limit = 1 +# maildrop_destination_recipient_limit = 1 virtual_transport = maildrop header_checks = regexp:{config_dir}/header_checks mime_header_checks = regexp:{config_dir}/mime_header_checks @@ -58,4 +59,4 @@ smtp_sasl_auth_enable = yes smtp_sasl_security_options = noanonymous, noplaintext smtp_sasl_tls_security_options = noanonymous authorized_flush_users = -authorized_mailq_users = nagios, icinga +authorized_mailq_users = nagios, icinga, zabbix diff --git a/install/tpl/postfix_3-0.conf.master b/install/tpl/postfix_3-0.conf.master index ce4fc920ed..b0f831883e 100644 --- a/install/tpl/postfix_3-0.conf.master +++ b/install/tpl/postfix_3-0.conf.master @@ -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 diff --git a/install/tpl/rspamd.local.lua.master b/install/tpl/rspamd.local.lua.master new file mode 100644 index 0000000000..e0205b8ce6 --- /dev/null +++ b/install/tpl/rspamd.local.lua.master @@ -0,0 +1,7 @@ +rspamd_config.R_DUMMY = { + callback = function(task) + return true + end, + score = 0, + description = 'dummy symbol', +} \ No newline at end of file diff --git a/install/tpl/rspamd_antivirus.conf.master b/install/tpl/rspamd_antivirus.conf.master index aa3d2cc9f2..8cbf404bad 100644 --- a/install/tpl/rspamd_antivirus.conf.master +++ b/install/tpl/rspamd_antivirus.conf.master @@ -1,27 +1,36 @@ clamav { # If set force this action if any virus is found (default unset: no action is forced) #action = "reject"; + # Scan mime_parts separately - otherwise the complete mail will be transferred to AV Scanner scan_mime_parts = true; + # Scanning Text is suitable for some av scanner databases (e.g. Sanesecurity) scan_text_mime = true; scan_image_mime = 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 { @@ -32,6 +41,7 @@ clamav { # symbol_name = "pattern"; CLAM_PROTOCOL_ERROR = '^unhandled response'; } + # `whitelist` points to a map of IP addresses. Mail from these addresses is not scanned. whitelist = "/etc/rspamd/antivirus.wl"; } diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master index c9949c2793..a82a486c27 100644 --- a/install/tpl/server.ini.master +++ b/install/tpl/server.ini.master @@ -21,6 +21,7 @@ backup_dir_is_mount=n backup_mode=rootgz backup_time=0:00 backup_delete=n +sysbackup_copies=3 monit_url= monit_user= monit_password= @@ -56,9 +57,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 @@ -121,6 +122,7 @@ add_web_users_to_sshusers_group=y connect_userid_to_webid=n connect_userid_to_webid_start=10000 web_folder_protection=y +web_folder_permission=0710 php_ini_check_minutes=1 overtraffic_disable_web=y overquota_notify_threshold=90 @@ -136,12 +138,23 @@ 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 +le_signature_type=ECDSA +le_delete_on_site_remove=y +le_auto_cleanup=y +le_revoke_before_delete=y +le_auto_cleanup_denylist=[server_name] [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 diff --git a/install/tpl/system.ini.master b/install/tpl/system.ini.master index 07110c736f..418e578355 100644 --- a/install/tpl/system.ini.master +++ b/install/tpl/system.ini.master @@ -35,12 +35,12 @@ 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,php-fpm show_aps_menu=n client_protection=y ssh_authentication= le_caa_autocreate_options=y - +postgresql_database=n [tools] @@ -75,3 +75,4 @@ session_timeout=0 session_allow_endless=0 min_password_length=8 min_password_strength=3 +show_delete_on_forms=n diff --git a/install/update.php b/install/update.php index 37a0919999..c9874984f1 100644 --- a/install/update.php +++ b/install/update.php @@ -88,7 +88,6 @@ if(realpath(dirname(__FILE__)) != $cur_dir) die("Please run installation/update from _inside_ the install directory!\n"); //** Install logfile -define('ISPC_LOG_FILE', '/var/log/ispconfig_install.log'); define('ISPC_INSTALL_ROOT', realpath(dirname(__FILE__).'/../')); //** Include the templating lib @@ -112,6 +111,7 @@ include_once "/usr/local/ispconfig/server/lib/config.inc.php"; $conf_old = $conf; unset($conf); +define('ISPC_LOG_FILE', $conf_old['ispconfig_log_dir'] . '/update.log'); if($dist['id'] == '') die('Linux distribution or version not recognized.'); @@ -187,6 +187,8 @@ $conf['server_id'] = intval($conf_old["server_id"]); $conf['ispconfig_log_priority'] = $conf_old["log_priority"]; +$conf['db_log_message_max_length'] = (isset($conf_old['db_log_message_max_length'])) ? $conf_old['db_log_message_max_length'] : '32768'; + $inst = new installer(); $inst->is_update = true; @@ -274,6 +276,9 @@ $inst->db->setDBData($conf['mysql']["host"], $conf['mysql']["ispconfig_user"], $conf['mysql']["ispconfig_password"], $conf['mysql']["port"]); $inst->db->setDBName($conf['mysql']['database']); +//* Check MySQL version +$inst->check_mysql_version(); + //* initialize the master DB, if we have a multiserver setup if($conf['mysql']['master_slave_setup'] == 'y') { //** Get MySQL root credentials @@ -359,15 +364,47 @@ //** 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']); -$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['xmpp']['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']); + +if(isset($conf['postfix']['installed']) && $conf['postfix']['installed'] == true) { + $conf['services']['mail'] = check_service_config_state('mail_server', true); +} else { + $conf['services']['mail'] = check_service_config_state('mail_server', false); +} + +if(isset($conf['powerdns']['installed']) && $conf['powerdns']['installed'] == true || isset($conf['bind']['installed']) && $conf['bind']['installed'] == true || isset($conf['mydns']['installed']) && $conf['mydns']['installed'] == true) { + $conf['services']['dns'] = check_service_config_state('dns_server', true); +} else { + $conf['services']['dns'] = check_service_config_state('dns_server', false); +} + +if(isset($conf['apache']['installed']) && $conf['apache']['installed'] == true || isset($conf['nginx']['installed']) && $conf['nginx']['installed'] == true) { + $conf['services']['web'] = check_service_config_state('web_server', true); +} else { + $conf['services']['web'] = check_service_config_state('web_server', false); +} + +if(isset($conf['xmpp']['installed']) && $conf['xmpp']['installed'] == true) { + $conf['services']['xmpp'] = check_service_config_state('xmpp_server', true); +} else { + $conf['services']['xmpp'] = check_service_config_state('xmpp_server', false); +} + +if(isset($conf['ufw']['installed']) && $conf['ufw']['installed'] == true || isset($conf['firewall']['installed']) && $conf['firewall']['installed'] == true) { + $conf['services']['firewall'] = check_service_config_state('firewall_server', true); +} else { + $conf['services']['firewall'] = check_service_config_state('firewall_server', false); +} + +if(isset($conf['vserver']['installed']) && $conf['vserver']['installed'] == true) { + $conf['services']['vserver'] = check_service_config_state('vserver_server', true); +} else { + $conf['services']['vserver'] = check_service_config_state('vserver_server', false); +} + $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 = '{$conf['services']['firewall']}', xmpp_server = '{$conf['services']['xmpp']}' WHERE server_id = ?"; $inst->db->query($sql, $conf['mysql']['database'].'.server', $conf['server_id']); @@ -519,7 +556,7 @@ } if($conf['services']['firewall'] && $inst->reconfigure_app('Firewall', $reconfigure_services_answer)) { - if($conf['ufw']['installed'] == true) { + if(isset($conf['ufw']['installed']) && $conf['ufw']['installed'] == true) { //* Configure Ubuntu Firewall $conf['services']['firewall'] = true; swriteln('Configuring Ubuntu Firewall'); @@ -656,7 +693,7 @@ } if($conf['services']['firewall']) { - if($conf['ufw']['installed'] == true && isset($conf['ufw']['init_script']) && $conf['ufw']['init_script'] != '' && is_executable($conf['init_scripts'].'/'.$conf['ufw']['init_script'])) system($conf['init_scripts'].'/'.$conf['ufw']['init_script'].' restart &> /dev/null'); + if(isset($conf['ufw']['installed']) && $conf['ufw']['installed'] == true && isset($conf['ufw']['init_script']) && $conf['ufw']['init_script'] != '' && is_executable($conf['init_scripts'].'/'.$conf['ufw']['init_script'])) system($conf['init_scripts'].'/'.$conf['ufw']['init_script'].' restart &> /dev/null'); } } diff --git a/interface/lib/app.inc.php b/interface/lib/app.inc.php index 0350e28051..f023b98550 100644 --- a/interface/lib/app.inc.php +++ b/interface/lib/app.inc.php @@ -46,7 +46,7 @@ /* Application Class */ -class app { +class app extends stdClass { private $_language_inc = 0; private $_wb; @@ -214,8 +214,10 @@ public function log($msg, $priority = 0) { public function auth_log($msg) { $authlog_handle = fopen($this->_conf['ispconfig_log_dir'].'/auth.log', 'a'); - fwrite($authlog_handle, $msg . PHP_EOL); - fclose($authlog_handle); + if($authlog_handle) { + fwrite($authlog_handle, $msg . PHP_EOL); + fclose($authlog_handle); + } } /** Priority values are: 0 = DEBUG, 1 = WARNING, 2 = ERROR */ diff --git a/interface/lib/classes/auth.inc.php b/interface/lib/classes/auth.inc.php index 3a4cc1603c..5544cfe0db 100644 --- a/interface/lib/classes/auth.inc.php +++ b/interface/lib/classes/auth.inc.php @@ -44,7 +44,7 @@ public function is_admin() { return false; } } - + public function is_superadmin() { if($_SESSION['s']['user']['typ'] == 'admin' && $_SESSION['s']['user']['userid'] == 1) { return true; @@ -53,6 +53,13 @@ public function is_superadmin() { } } + public function is_reseller() { + if($this->has_clients($_SESSION['s']['user']['userid'])) { + return true; + } else { + return false; + } + } public function has_clients($userid) { global $app, $conf; @@ -64,11 +71,11 @@ public function has_clients($userid) { return false; } } - + // Function to check if a client belongs to a reseller public function is_client_of_reseller($userid = 0) { global $app, $conf; - + if($userid == 0) $userid = $_SESSION['s']['user']['userid']; $client = $app->db->queryOneRecord("SELECT client.sys_userid, client.sys_groupid FROM sys_user, client WHERE sys_user.userid = ? AND sys_user.client_id = client.client_id", $userid); @@ -91,7 +98,7 @@ public function add_group_to_user($userid, $groupid) { $groups = explode(',', $user['groups']); if(!in_array($groupid, $groups)) $groups[] = $groupid; $groups_string = implode(',', $groups); - $sql = "UPDATE sys_user SET groups = ? WHERE userid = ?"; + $sql = "UPDATE sys_user SET `groups` = ? WHERE userid = ?"; $app->db->query($sql, $groups_string, $userid); return true; } else { @@ -103,10 +110,10 @@ public function add_group_to_user($userid, $groupid) { public function get_client_limit($userid, $limitname) { global $app; - + $userid = $app->functions->intval($userid); if(!preg_match('/^[a-zA-Z0-9\-\_]{1,64}$/',$limitname)) $app->error('Invalid limit name '.$limitname); - + // simple query cache if($this->client_limits===null) $this->client_limits = $app->db->queryOneRecord("SELECT client.* FROM sys_user, client WHERE sys_user.userid = ? AND sys_user.client_id = client.client_id", $userid); @@ -133,7 +140,7 @@ public function remove_group_from_user($userid, $groupid) { $key = array_search($groupid, $groups); unset($groups[$key]); $groups_string = implode(',', $groups); - $sql = "UPDATE sys_user SET groups = ? WHERE userid = ?"; + $sql = "UPDATE sys_user SET `groups` = ? WHERE userid = ?"; $app->db->query($sql, $groups_string, $userid); return true; } else { @@ -181,11 +188,11 @@ public function check_module_permissions($module) { exit; } } - + public function check_security_permissions($permission) { - + global $app; - + $app->uses('getconf'); $security_config = $app->getconf->get_security_config('permissions'); @@ -195,7 +202,7 @@ public function check_security_permissions($permission) { if($security_check !== true) { $app->error($app->lng('security_check1_txt').' '.$permission.' '.$app->lng('security_check2_txt')); } - + } /** @@ -232,12 +239,12 @@ public function get_random_password($minLength = 8, $special = false) { if($minLength < 8) $minLength = 8; $maxLength = $minLength + 5; $length = random_int($minLength, $maxLength); - + $alphachars = "abcdefghijklmnopqrstuvwxyz"; $upperchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; $numchars = "1234567890"; $specialchars = "!@#_"; - + $num_special = 0; if($special == true) { $num_special = intval(random_int(0, round($length / 4))) + 1; @@ -247,23 +254,23 @@ public function get_random_password($minLength = 8, $special = false) { $upperlen = intval($alphalen / 2); $alphalen = $alphalen - $upperlen; $password = ''; - + for($i = 0; $i < $alphalen; $i++) { $password .= substr($alphachars, random_int(0, strlen($alphachars) - 1), 1); } - + for($i = 0; $i < $upperlen; $i++) { $password .= substr($upperchars, random_int(0, strlen($upperchars) - 1), 1); } - + for($i = 0; $i < $num_special; $i++) { $password .= substr($specialchars, random_int(0, strlen($specialchars) - 1), 1); } - + for($i = 0; $i < $numericlen; $i++) { $password .= substr($numchars, random_int(0, strlen($numchars) - 1), 1); } - + return str_shuffle($password); } @@ -271,7 +278,7 @@ public function crypt_password($cleartext_password, $charset = 'UTF-8') { if($charset != 'UTF-8') { $cleartext_password = mb_convert_encoding($cleartext_password, $charset, 'UTF-8'); } - + if(defined('CRYPT_SHA512') && CRYPT_SHA512 == 1) { $salt = '$6$rounds=5000$'; $salt_length = 16; @@ -282,7 +289,7 @@ public function crypt_password($cleartext_password, $charset = 'UTF-8') { $salt = '$1$'; $salt_length = 12; } - + if(function_exists('openssl_random_pseudo_bytes')) { $salt .= substr(bin2hex(openssl_random_pseudo_bytes($salt_length)), 0, $salt_length); } else { @@ -294,7 +301,7 @@ public function crypt_password($cleartext_password, $charset = 'UTF-8') { $salt .= "$"; return crypt($cleartext_password, $salt); } - + public function csrf_token_get($form_name) { /* CSRF PROTECTION */ // generate csrf protection id and key @@ -304,13 +311,13 @@ public function csrf_token_get($form_name) { if(!isset($_SESSION['_csrf_timeout'])) $_SESSION['_csrf_timeout'] = array(); $_SESSION['_csrf'][$_csrf_id] = $_csrf_key; $_SESSION['_csrf_timeout'][$_csrf_id] = time() + 3600; // timeout hash in 1 hour - + return array('csrf_id' => $_csrf_id,'csrf_key' => $_csrf_key); } - + public function csrf_token_check($method = 'POST') { global $app; - + if($method == 'POST') { $input_vars = $_POST; } elseif ($method == 'GET') { @@ -318,10 +325,10 @@ public function csrf_token_check($method = 'POST') { } else { $app->error('Unknown CSRF verification method.'); } - + //print_r($input_vars); //die(print_r($_SESSION['_csrf'])); - + if(isset($input_vars) && is_array($input_vars)) { $_csrf_valid = false; if(isset($input_vars['_csrf_id']) && isset($input_vars['_csrf_key'])) { @@ -339,7 +346,7 @@ public function csrf_token_check($method = 'POST') { $_SESSION['_csrf_timeout'][$_csrf_id] = null; unset($_SESSION['_csrf'][$_csrf_id]); unset($_SESSION['_csrf_timeout'][$_csrf_id]); - + if(isset($_SESSION['_csrf_timeout']) && is_array($_SESSION['_csrf_timeout'])) { $to_unset = array(); foreach($_SESSION['_csrf_timeout'] as $_csrf_id => $timeout) { diff --git a/interface/lib/classes/crypt.inc.php b/interface/lib/classes/crypt.inc.php new file mode 100644 index 0000000000..24d26a7a71 --- /dev/null +++ b/interface/lib/classes/crypt.inc.php @@ -0,0 +1,49 @@ +functions->intval($_SESSION["s"]["user"]["default_group"]); - $client = $app->db->queryOneRecord("SELECT default_dnsserver FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $client_group_id); - $sql = "SELECT server_id,server_name FROM server WHERE server_id = ?"; + $client = $app->db->queryOneRecord("SELECT dns_servers FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $client_group_id); + $sql = "SELECT server_id,server_name FROM server WHERE server_id in (?)"; } else { $sql = "SELECT server_id,server_name FROM server WHERE dns_server = 1 ORDER BY server_name AND mirror_server_id = 0"; } - $records = $app->db->queryAllRecords($sql, $client['default_dnsserver']); + $records = $app->db->queryAllRecords($sql, $client['dns_servers']); $records_new = array(); if(is_array($records)) { foreach($records as $rec) { diff --git a/interface/lib/classes/db_mysql.inc.php b/interface/lib/classes/db_mysql.inc.php index 78eee8c997..6cbbafe106 100644 --- a/interface/lib/classes/db_mysql.inc.php +++ b/interface/lib/classes/db_mysql.inc.php @@ -239,7 +239,7 @@ private function securityScan($string) { } } } - if($ok == true) { + if($ok) { return true; } else { if($ids_config['sql_scan_action'] == 'warn') { @@ -252,6 +252,8 @@ private function securityScan($string) { } } } + + return true; } private function _query($sQuery = '') { @@ -298,7 +300,9 @@ private function _query($sQuery = '') { } while($ok == false); $sQuery = call_user_func_array(array(&$this, '_build_query_string'), $aArgs); - $this->securityScan($sQuery); + if (!$this->securityScan($sQuery)) { + return false; + } $this->_iQueryId = mysqli_query($this->_iConnId, $sQuery); if (!$this->_iQueryId) { $this->_sqlerror('Falsche Anfrage / Wrong Query', 'SQL-Query = ' . $sQuery); @@ -590,6 +594,7 @@ public function unquote($formfield) { } public function toLower($record) { + $out = []; if(is_array($record)) { foreach($record as $key => $val) { $key = strtolower($key); @@ -668,7 +673,7 @@ public function getDatabaseSize($database_name) { $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; + $clientdb_flags = (isset($conf['db_flags']) && $conf['db_flags'] !== NULL) ? $conf['db_flags'] : NULL; require_once 'lib/mysql_clientdb.conf'; @@ -678,7 +683,7 @@ public function getDatabaseSize($database_name) { $result = $db->_query("SELECT SUM(data_length+index_length) FROM information_schema.TABLES WHERE table_schema='".$db->escape($database_name)."'"); if(!$result) { $db->_sqlerror('Unable to determine the size of database ' . $database_name); - return; + return 0; } $database_size = $result->getAsRow(); $result->free(); @@ -825,12 +830,13 @@ public function datalogDelete($tablename, $index_field, $index_value) { return true; } - //** Deletes a record and saves the changes into the datalog + // Updates a datalog record to store an error state. 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); - + 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; } @@ -844,7 +850,11 @@ public function datalogStatus($login = '') { $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); + $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 or sys_datalog.server_id = 0) AND sys_datalog.user = ? AND sys_datalog.datalog_id > server.updated AND server.active = 1 + 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']; @@ -1070,7 +1080,7 @@ function tableInfo($table_name) { } public function mapType($metaType, $typeValue) { - global $go_api; + global $app; $metaType = strtolower($metaType); switch ($metaType) { case 'int16': @@ -1102,6 +1112,8 @@ public function mapType($metaType, $typeValue) { return 'date'; break; } + $app->error('Unknown meta type: '.$metaType); + return false; } /** @@ -1143,36 +1155,173 @@ public function getDatabaseVersion($major_version_only = false) { * Get a mysql password hash * * @access public - * @param string cleartext password + * @param string $password cleartext password + * @param string $hash_type MySQL hash type to use. either mysql_native_password or caching_sha2_password * @return string Password hash */ - public function getPasswordHash($password) { + public function getPasswordHash($password, $hash_type = 'mysql_native_password') { + if($hash_type == 'caching_sha2_password') { + $password_hash = $this->mysqlSha256Crypt($password, $this->genSalt(20), 5000); + } else { + $password_hash = '*' . strtoupper(sha1(sha1($password, true))); + } - $password_type = 'password'; + return $password_hash; + } - /* Disabled until caching_sha2_password is implemented - if($this->getDatabaseType() == 'mysql' && $this->getDatabaseVersion(true) >= 8) { - // we are in MySQL 8 mode - $tmp = $this->queryOneRecord("show variables like 'default_authentication_plugin'"); - if($tmp['default_authentication_plugin'] == 'caching_sha2_password') { - $password_type = 'caching_sha2_password'; + /** + * @param $size int length of salt in bytes + * + * @return string + */ + private function genSalt($size) { + $salt = random_bytes($size); + if($salt === false) { + throw new Exception('Cannot generate salt.'); + } + for($i = 0; $i < $size; $i++) { + $ord = ord($salt[$i]) & 0x7f; + if($ord < 32) { + $ord += 32; + } + if($ord == 36 /* $ */) { + $ord += 1; } + $salt[$i] = chr($ord); } - */ - if($password_type == 'caching_sha2_password') { - /* - caching_sha2_password hashing needs to be implemented, have not - found valid PHP implementation for the new password hash type. - */ - } else { - $password_hash = '*'.strtoupper(sha1(sha1($password, true))); + return $salt; + } + + /** + * this is the SHA256 algorithm of the crypt unix call – the only difference is that we do not truncate the salt to 16 chars + * @see https://www.akkadia.org/drepper/SHA-crypt.txt + * @see https://github.com/mysql/mysql-server/blob/trunk/mysys/crypt_genhash_impl.cc + * + * @param string $plaintext the plain text password + * @param string $salt the raw salt (needs to be 20 bytes long) + * @param int $rounds number of rounds. MySQL default is 5000. Must be between 1000 and 4095000 (0xFFF * 1000) + * + * @return string hashed password in MySQL format + */ + private function mysqlSha256Crypt($plaintext, $salt, $rounds) { + $plaintext_len = strlen($plaintext); + $salt_len = strlen($salt); + + // 1 + $ctxA = hash_init('sha256'); + // 2 + hash_update($ctxA, $plaintext); + // 3 + hash_update($ctxA, $salt); + // 4 + $ctxB = hash_init('sha256'); + // 5 + hash_update($ctxB, $plaintext); + // 6 + hash_update($ctxB, $salt); + // 7 + hash_update($ctxB, $plaintext); + // 8 + $B = hash_final($ctxB, true); + // 9 + for($i = $plaintext_len; $i > 32; $i -= 32) { + hash_update($ctxA, $B); + } + // 10 + hash_update($ctxA, substr($B, 0, $i)); + // 11 + for($i = $plaintext_len; $i > 0; $i >>= 1) { + if(($i & 1) != 0) { + hash_update($ctxA, $B); + } else { + hash_update($ctxA, $plaintext); + } + } + // 12 + $A = hash_final($ctxA, true); + // 13 + $ctxDP = hash_init('sha256'); + // 14 + for($i = 0; $i < $plaintext_len; $i++) { + hash_update($ctxDP, $plaintext); + } + // 15 + $DP = hash_final($ctxDP, true); + // 16 + $P = ""; + for($i = $plaintext_len; $i > 32; $i -= 32) { + $P .= $DP; } + $P .= substr($DP, 0, $i); + // 17 + $ctxDS = hash_init('sha256'); + // 18 + for($i = 0; $i < 16 + ord($A[0]); $i++) { + hash_update($ctxDS, $salt); + } + // 19 + $DS = hash_final($ctxDS, true); + // 20 + $S = ""; + for($i = $salt_len; $i >= 32; $i -= 32) { + $S .= $DS; + } + $S .= substr($DS, 0, $i); + // 21 + $C = ""; + for($i = 0; $i < $rounds; $i++) { + $ctxC = hash_init('sha256'); + if(($i & 1) != 0) { + hash_update($ctxC, $P); + } else { + hash_update($ctxC, $i == 0 ? $A : $C); + } - return $password_hash; - } + if($i % 3 != 0) { + hash_update($ctxC, $S); + } + if($i % 7 != 0) { + hash_update($ctxC, $P); + } + + if(($i & 1) != 0) { + hash_update($ctxC, $i == 0 ? $A : $C); + } else { + hash_update($ctxC, $P); + } + $C = hash_final($ctxC, true); + } + + // 22 + $b64result = str_repeat(' ', 43); + $p = 0; + $b64_from_24bit = function($B2, $B1, $B0, $N) use (&$b64result, &$p) { + $b64_alphabet = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + $w = ($B2 << 16) | ($B1 << 8) | $B0; + $n = $N; + while(--$n >= 0) { + $b64result[$p++] = $b64_alphabet[$w & 0x3f]; + $w = $w >> 6; + } + }; + $b64_from_24bit(ord($C[0]), ord($C[10]), ord($C[20]), 4); + $b64_from_24bit(ord($C[21]), ord($C[1]), ord($C[11]), 4); + $b64_from_24bit(ord($C[12]), ord($C[22]), ord($C[2]), 4); + $b64_from_24bit(ord($C[3]), ord($C[13]), ord($C[23]), 4); + $b64_from_24bit(ord($C[24]), ord($C[4]), ord($C[14]), 4); + $b64_from_24bit(ord($C[15]), ord($C[25]), ord($C[5]), 4); + $b64_from_24bit(ord($C[6]), ord($C[16]), ord($C[26]), 4); + $b64_from_24bit(ord($C[27]), ord($C[7]), ord($C[17]), 4); + $b64_from_24bit(ord($C[18]), ord($C[28]), ord($C[8]), 4); + $b64_from_24bit(ord($C[9]), ord($C[19]), ord($C[29]), 4); + $b64_from_24bit(0, ord($C[31]), ord($C[30]), 3); + + // we do not truncate $salt to 16 chars since MySQL does not do that and uses 20 bytes salts + return sprintf('$A$%03x$%s%s', $rounds / 1000, $salt, $b64result); + } } @@ -1186,10 +1335,11 @@ class db_result { /** * - * + * @var mysqli_result|null * @access private */ private $_iResId = null; + /** @var mysqli|null */ private $_iConnection = null; @@ -1401,7 +1551,7 @@ public function getAsRow() { * * @access public * @param int $iStart offset to start read - * @param int iLength amount of datasets to read + * @param int $iLength amount of datasets to read */ public function limit_result($iStart, $iLength) { $this->aLimitedData = array_slice($this->aResultData, $iStart, $iLength, true); diff --git a/interface/lib/classes/dns_wizard.inc.php b/interface/lib/classes/dns_wizard.inc.php new file mode 100644 index 0000000000..c9c1af2e66 --- /dev/null +++ b/interface/lib/classes/dns_wizard.inc.php @@ -0,0 +1,314 @@ + +All rights reserved. + +Copyright (c) 2008, Till Brehm, projektfarm Gmbh +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +class dns_wizard +{ + function create(array $data) + { + global $app; + $app->uses('getconf'); + + // get system settings + $settings = $app->getconf->get_global_config(); + + $error = ''; + + // get the correct server_id + if (isset($data['server_id'])) { + $server_id = $app->functions->intval($data['server_id']); + $post_server_id = true; + } elseif (isset($data['server_id_value'])) { + $server_id = $app->functions->intval($data['server_id_value']); + $post_server_id = true; + } else { + $server_id = $app->functions->intval($settings['dns']['default_dnsserver']); + if(empty($server_id)) { + $tmp = $app->db->queryOneRecord('SELECT server_id FROM server WHERE dns_server = 1 LIMIT 0,1'); + if(!empty($tmp['server_id'])) { + $server_id = $tmp['server_id']; + } else { + $error .= $app->lng('error_no_server_id').'
'; + } + } + $post_server_id = false; + } + + if ($post_server_id) + { + $client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]); + $client = $app->db->queryOneRecord("SELECT dns_servers FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $client_group_id); + + $client['dns_servers_ids'] = explode(',', $client['dns_servers']); + + // Check if chosen server is in authorized servers for this client + if (!(is_array($client['dns_servers_ids']) && in_array($server_id, $client['dns_servers_ids'])) && $_SESSION["s"]["user"]["typ"] != 'admin') { + $error .= $app->lng('error_not_allowed_server_id').'
'; + } + } + /* + else + { + $error .= $app->lng('error_no_server_id').'
'; + } + */ + + // apply filters + if(isset($data['domain']) && $data['domain'] != ''){ + /* check if the domain module is used - and check if the selected domain can be used! */ + if ($settings['domains']['use_domain_module'] == 'y') { + // get domain_id for domain + $tmp = $app->db->queryOneRecord('SELECT domain_id from domain where domain = ?', $data['domain']); + $domain_id = $app->functions->intval( $tmp['domain_id']); + + if ($_SESSION["s"]["user"]["typ"] == 'admin' || $app->auth->has_clients($_SESSION['s']['user']['userid'])) { + $data['client_group_id'] = $app->tools_sites->getClientIdForDomain($domain_id); + } + $domain_check = $app->tools_sites->checkDomainModuleDomain($domain_id); + if($domain_check === false) { + // invalid domain selected + $data['domain'] = ''; + } else { + $data['domain'] = $domain_check; + } + } else { + $data['domain'] = $app->functions->idn_encode($data['domain']); + $data['domain'] = strtolower($data['domain']); + } + } + if(isset($data['ns1']) && $data['ns1'] != ''){ + $data['ns1'] = $app->functions->idn_encode($data['ns1']); + $data['ns1'] = strtolower($data['ns1']); + } + if(isset($data['ns2']) && $data['ns2'] != ''){ + $data['ns2'] = $app->functions->idn_encode($data['ns2']); + $data['ns2'] = strtolower($data['ns2']); + } + if(isset($data['email']) && $data['email'] != ''){ + $data['email'] = $app->functions->idn_encode($data['email']); + $data['email'] = strtolower($data['email']); + } + + + # fixme: this regex is pretty poor for domain validation + if(isset($data['domain']) && $data['domain'] == '') $error .= $app->lng('error_domain_empty').'
'; + elseif(isset($data['domain']) && !preg_match('/^[\w\.\-]{1,64}\.[a-zA-Z0-9\-]{2,63}$/', $data['domain'])) $error .= $app->lng('error_domain_regex').'
'; + + if(isset($data['ip']) && $data['ip'] == '') $error .= $app->lng('error_ip_empty').'
'; + + //if(isset($data['ipv6']) && $data['ipv6'] == '') $error .= $app->lng('error_ipv6_empty').'
'; + + # fixme: this regex is pretty poor for hostname validation + if(isset($data['ns1']) && $data['ns1'] == '') $error .= $app->lng('error_ns1_empty').'
'; + elseif(isset($data['ns1']) && !preg_match('/^[\w\.\-]{1,64}\.[a-zA-Z0-9]{2,63}$/', $data['ns1'])) $error .= $app->lng('error_ns1_regex').'
'; + + if(isset($data['ns2']) && $data['ns2'] == '') $error .= $app->lng('error_ns2_empty').'
'; + elseif(isset($data['ns2']) && !preg_match('/^[\w\.\-]{1,64}\.[a-zA-Z0-9]{2,63}$/', $data['ns2'])) $error .= $app->lng('error_ns2_regex').'
'; + + if(isset($data['email']) && $data['email'] == '') $error .= $app->lng('error_email_empty').'
'; + elseif(isset($data['email']) && filter_var($data['email'], FILTER_VALIDATE_EMAIL) === false) $error .= $app->lng('error_email_regex').'
'; + + // make sure that the record belongs to the client group and not the admin group when admin inserts it + if($_SESSION["s"]["user"]["typ"] == 'admin' && isset($data['client_group_id'])) { + $sys_groupid = $app->functions->intval($data['client_group_id']); + } elseif($app->auth->has_clients($_SESSION['s']['user']['userid']) && isset($data['client_group_id'])) { + $sys_groupid = $app->functions->intval($data['client_group_id']); + } else { + $sys_groupid = $_SESSION["s"]["user"]["default_group"]; + } + + $tform_def_file = "../../web/dns/form/dns_soa.tform.php"; + $app->uses('tform'); + $app->tform->loadFormDef($tform_def_file); + + if($_SESSION['s']['user']['typ'] != 'admin') { + if(!$app->tform->checkClientLimit('limit_dns_zone')) { + $error .= $app->tform->wordbook["limit_dns_zone_txt"]; + } + if(!$app->tform->checkResellerLimit('limit_dns_zone')) { + $error .= $app->tform->wordbook["limit_dns_zone_txt"]; + } + } + + + // replace template placeholders + $template_id = (isset($data['template_id']))?$app->functions->intval($data['template_id']):0; + $template_record = $app->db->queryOneRecord("SELECT * FROM dns_template WHERE template_id = ?", $template_id); + $tpl_content = $template_record['template']; + if($data['domain'] != '') $tpl_content = str_replace('{DOMAIN}', $data['domain'], $tpl_content); + if($data['ip'] != '') $tpl_content = str_replace('{IP}', $data['ip'], $tpl_content); + if($data['ipv6'] != '') $tpl_content = str_replace('{IPV6}',$data['ipv6'],$tpl_content); + if($data['ns1'] != '') $tpl_content = str_replace('{NS1}', $data['ns1'], $tpl_content); + if($data['ns2'] != '') $tpl_content = str_replace('{NS2}', $data['ns2'], $tpl_content); + if($data['email'] != '') $tpl_content = str_replace('{EMAIL}', $data['email'], $tpl_content); + // $enable_dnssec = (($data['dnssec'] == 'Y') ? 'Y' : 'N'); + // if(isset($data['dnssec'])) $vars['dnssec_wanted'] = 'Y'; + if(isset($data['dnssec'])) $tpl_content = str_replace('[ZONE]', '[ZONE]'."\n".'dnssec_wanted=Y', $tpl_content); + if(isset($data['dkim']) && preg_match('/^[\w\.\-\/]{1,255}\.[a-zA-Z0-9\-]{2,63}[\.]{0,1}$/', $data['domain'])) { + $sql = $app->db->queryOneRecord("SELECT dkim_public, dkim_selector FROM mail_domain WHERE domain = ? AND dkim = 'y' AND ".$app->tform->getAuthSQL('r'), $data['domain']); + $public_key = $sql['dkim_public']; + if ($public_key!='') { + if (empty($sql['dkim_selector'])) $sql['dkim_selector'] = 'default'; + $dns_record=str_replace(array("\r\n", "\n", "\r", "-----BEGIN PUBLIC KEY-----", "-----END PUBLIC KEY-----"), '', $public_key); + $tpl_content .= "\n".'TXT|'.$sql['dkim_selector'].'._domainkey.'.$data['domain'].'.|v=DKIM1; t=s; p='.$dns_record; + } + } + + // Parse the template + $tpl_rows = explode("\n", $tpl_content); + $section = ''; + $vars = array(); + $vars['xfer']=''; + $vars['dnssec_wanted']='N'; + $vars['dnssec_algo']='ECDSAP256SHA256'; + $dns_rr = array(); + foreach($tpl_rows as $row) { + $row = trim($row); + if(substr($row, 0, 1) == '[') { + if($row == '[ZONE]') { + $section = 'zone'; + } elseif($row == '[DNS_RECORDS]') { + $section = 'dns_records'; + } else { + die('Unknown section type'); + } + } else { + if($row != '') { + // Handle zone section + if($section == 'zone') { + $parts = explode('=', $row); + $key = trim($parts[0]); + $val = trim($parts[1]); + if($key != '') $vars[$key] = $val; + } + // Handle DNS Record rows + if($section == 'dns_records') { + $parts = explode('|', $row); + $dns_rr[] = array( + 'name' => $parts[1], + 'type' => $parts[0], + 'data' => $parts[2], + 'aux' => $parts[3], + 'ttl' => $parts[4] + ); + } + } + } + + } // end foreach + + if($vars['origin'] == '') $error .= $app->lng('error_origin_empty').'
'; + if($vars['ns'] == '') $error .= $app->lng('error_ns_empty').'
'; + if($vars['mbox'] == '') $error .= $app->lng('error_mbox_empty').'
'; + if($vars['refresh'] == '') $error .= $app->lng('error_refresh_empty').'
'; + if($vars['retry'] == '') $error .= $app->lng('error_retry_empty').'
'; + if($vars['expire'] == '') $error .= $app->lng('error_expire_empty').'
'; + if($vars['minimum'] == '') $error .= $app->lng('error_minimum_empty').'
'; + if($vars['ttl'] == '') $error .= $app->lng('error_ttl_empty').'
'; + + if($error == '') { + // Insert the soa record + $sys_userid = $_SESSION['s']['user']['userid']; + $origin = $vars['origin']; + $ns = $vars['ns']; + $mbox = str_replace('@', '.', $vars['mbox']); + $refresh = $vars['refresh']; + $retry = $vars['retry']; + $expire = $vars['expire']; + $minimum = $vars['minimum']; + $ttl = $vars['ttl']; + $xfer = $vars['xfer']; + $also_notify = $vars['also_notify']; + $update_acl = $vars['update_acl']; + $dnssec_wanted = $vars['dnssec_wanted']; + $dnssec_algo = $vars['dnssec_algo']; + $serial = $app->validate_dns->increase_serial(0); + + $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, + "origin" => $origin, + "ns" => $ns, + "mbox" => $mbox, + "serial" => $serial, + "refresh" => $refresh, + "retry" => $retry, + "expire" => $expire, + "minimum" => $minimum, + "ttl" => $ttl, + "active" => 'N', // Activated later when all DNS records are added. + "xfer" => $xfer, + "also_notify" => $also_notify, + "update_acl" => $update_acl, + "dnssec_wanted" => $dnssec_wanted, + "dnssec_algo" => $dnssec_algo + ); + + $dns_soa_id = $app->db->datalogInsert('dns_soa', $insert_data, 'id'); + if($dns_soa_id > 0) $app->plugin->raiseEvent('dns:wizard:on_after_insert', $dns_soa_id); + + // Insert the dns_rr records + if(is_array($dns_rr) && $dns_soa_id > 0) { + foreach($dns_rr as $rr) { + $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" => $rr['name'], + "type" => $rr['type'], + "data" => $rr['data'], + "aux" => $rr['aux'], + "ttl" => $rr['ttl'], + "active" => 'Y' + ); + $dns_rr_id = $app->db->datalogInsert('dns_rr', $insert_data, 'id'); + } + } + + // Activate the DNS zone. + $app->db->datalogUpdate('dns_soa', array('active' => 'Y'), 'id', $dns_soa_id); + + return 'ok'; + + } else { + return $error; + } + } + +} diff --git a/interface/lib/classes/extension_installer.inc.php b/interface/lib/classes/extension_installer.inc.php new file mode 100644 index 0000000000..ef55ac6c0a --- /dev/null +++ b/interface/lib/classes/extension_installer.inc.php @@ -0,0 +1,376 @@ +extension_basedir.'/devkey')) { + $devkey = trim(file_get_contents($this->extension_basedir.'/devkey')); + return $this->repo_list_url.'?devkey='.urlencode($devkey); + } + + return $this->repo_list_url; + } + + // add error + public function addError($error) { + $this->error[] = $error; + } + + // get errors + public function getErrors() { + return $this->error; + } + + // has errors + public function hasErrors() { + return count($this->error) > 0; + } + + /** + * Get the list of available extensions from the repository + * @return array + */ + public function getRepoExtensions() { + if(empty($this->repo_cache)) { + $response = file_get_contents($this->getRepoListUrl()); + if (empty($response)) { + return []; + } else { + $this->repo_cache = json_decode($response, true); + } + } + + return $this->repo_cache; + } + + public function getRepoExtension($name) { + $repo_extensions = $this->getRepoExtensions(); + + //$repo_extension = array_filter($repo_extensions, fn($ext) => $ext['name'] === $name); + $repo_extension = array_filter($repo_extensions, function($ext) use ($name) { + return $ext['name'] === $name; + }); + + if(!empty($repo_extension)) { + return reset($repo_extension); + } else { + return null; + } + } + + public function getInstalledExtensions($server_id = null) { + global $app, $conf; + + // get extensions from monitor_data table + if($server_id === null) { + $sql = 'SELECT * FROM `monitor_data` WHERE `type` = ?'; + $records = $app->db->queryAllRecords($sql, 'extensions'); + } else { + $sql = 'SELECT * FROM `monitor_data` WHERE `type` = ? and `server_id` = ?'; + $records = $app->db->queryAllRecords($sql, 'extensions', $server_id); + } + + // get repo extensions + $repo_extensions = $this->getRepoExtensions(); + + if(empty($records)) { + return []; + } else { + $extensions = []; + foreach($records as $record) { + $data_records = json_decode($record['data'], true); + if(!empty($data_records) && is_array($data_records)) { + foreach($data_records as $data) { + // get title by searching in repo extensions + $repo_extension = array_filter($repo_extensions, function($ext) use ($data) { + return $ext['name'] === $data['name']; + }); + if(!empty($repo_extension)) { + $repo_extension = reset($repo_extension); + $extensions[] = [ + 'name' => $data['name'], + 'version' => $data['version'], + 'license' => $data['license'], + 'title' => $repo_extension['title'], + 'active' => $data['active'], + 'server_id' => $record['server_id'] + ]; + } + } + } + } + return $extensions; + } + } + + public function getInstalledExtension($name, $server_id) { + global $app, $conf; + + // getInstalledExtensions + $extensions = $this->getInstalledExtensions($server_id); + + // search in extensions + $extension = array_filter($extensions, function($ext) use ($name) { + return $ext['name'] === $name; + }); + if(!empty($extension)) { + return reset($extension); + } else { + return null; + } + } + + public function installExtension($name, $server_id) { + global $app, $conf; + + // check if extension exists in repository + $repo_extension = $this->getRepoExtension($name); + if($repo_extension === null) { + $this->addError('Extension not found in repository'); + return false; + } + + // check if extension is already installed + $installed_extensions = $this->getInstalledExtensions($server_id); + $extension = array_filter($installed_extensions, function($ext) use ($name) { + return $ext['name'] === $name; + }); + if(!empty($extension)) { + $this->addError('Extension already installed'); + return false; + } + + // check server_id in server table + $sql = 'SELECT * FROM `server` WHERE `server_id` = ?'; + $record = $app->db->queryOneRecord($sql, $server_id); + if($record === null) { + $this->addError('Server not found'); + return false; + } + + // Install the extension + $sql = "INSERT INTO sys_remoteaction (server_id, tstamp, action_type, action_param, action_state, response) " . + "VALUES (?, UNIX_TIMESTAMP(), 'extension_install', ?, 'pending', '')"; + $app->db->query($sql, $server_id, $name); + + return true; + } + + public function updateExtension($name, $server_id) { + global $app, $conf; + + // check if extension exists in repository + $repo_extension = $this->getRepoExtension($name); + if($repo_extension === null) { + $this->addError('Extension not found in repository'); + return false; + } + + // check if extension is already installed + $installed_extensions = $this->getInstalledExtensions($server_id); + $extension = array_filter($installed_extensions, function($ext) use ($name) { + return $ext['name'] === $name; + }); + if(empty($extension)) { + $this->addError('Extension not installed'); + return false; + } + + // check server_id in server table + $sql = 'SELECT * FROM `server` WHERE `server_id` = ?'; + $record = $app->db->queryOneRecord($sql, $server_id); + if($record === null) { + $this->addError('Server not found'); + return false; + } + + // Update the extension + $sql = "INSERT INTO sys_remoteaction (server_id, tstamp, action_type, action_param, action_state, response) " . + "VALUES (?, UNIX_TIMESTAMP(), 'extension_update', ?, 'pending', '')"; + $app->db->query($sql, $server_id, $name); + + return true; + } + + public function deleteExtension($name, $server_id) { + global $app, $conf; + + // check if extension is already installed + $installed_extensions = $this->getInstalledExtensions($server_id); + $extension = array_filter($installed_extensions, function($ext) use ($name) { + return $ext['name'] === $name; + }); + if(empty($extension)) { + $this->addError('Extension not installed'); + return false; + } + + // check server_id in server table + $sql = 'SELECT * FROM `server` WHERE `server_id` = ?'; + $record = $app->db->queryOneRecord($sql, $server_id); + if($record === null) { + $this->addError('Server not found'); + return false; + } + + // Delete the extension + $sql = "INSERT INTO sys_remoteaction (server_id, tstamp, action_type, action_param, action_state, response) " . + "VALUES (?, UNIX_TIMESTAMP(), 'extension_uninstall', ?, 'pending', '')"; + $app->db->query($sql, $server_id, $name); + + return true; + } + + public function enableExtension($name, $server_id) { + global $app, $conf; + + // check if extension is already installed + $installed_extensions = $this->getInstalledExtensions($server_id); + $extension = array_filter($installed_extensions, function($ext) use ($name) { + return $ext['name'] === $name; + }); + if(empty($extension)) { + $this->addError('Extension not installed'); + return false; + } + + // check server_id in server table + $sql = 'SELECT * FROM `server` WHERE `server_id` = ?'; + $record = $app->db->queryOneRecord($sql, $server_id); + if($record === null) { + $this->addError('Server not found'); + return false; + } + + // Enable the extension + $sql = "INSERT INTO sys_remoteaction (server_id, tstamp, action_type, action_param, action_state, response) " . + "VALUES (?, UNIX_TIMESTAMP(), 'extension_enable', ?, 'pending', '')"; + $app->db->query($sql, $server_id, $name); + + return true; + } + + public function disableExtension($name, $server_id) { + global $app, $conf; + + // check if extension is already installed + $installed_extensions = $this->getInstalledExtensions($server_id); + $extension = array_filter($installed_extensions, function($ext) use ($name) { + return $ext['name'] === $name; + }); + if(empty($extension)) { + $this->addError('Extension not installed'); + return false; + } + + // check server_id in server table + $sql = 'SELECT * FROM `server` WHERE `server_id` = ?'; + $record = $app->db->queryOneRecord($sql, $server_id); + if($record === null) { + $this->addError('Server not found'); + return false; + } + + // Disable the extension + $sql = "INSERT INTO sys_remoteaction (server_id, tstamp, action_type, action_param, action_state, response) " . + "VALUES (?, UNIX_TIMESTAMP(), 'extension_disable', ?, 'pending', '')"; + $app->db->query($sql, $server_id, $name); + + return true; + } + + public function updateLicense($name, $server_id, $license) { + global $app, $conf; + + // check if extension is already installed + $installed_extensions = $this->getInstalledExtensions($server_id); + $extension = array_filter($installed_extensions, function($ext) use ($name) { + return $ext['name'] === $name; + }); + if(empty($extension)) { + $this->addError('Extension not installed'); + return false; + } + + // check server_id in server table + $sql = 'SELECT * FROM `server` WHERE `server_id` = ?'; + $record = $app->db->queryOneRecord($sql, $server_id); + if($record === null) { + $this->addError('Server not found'); + return false; + } + + // Update the license + $data = ['name' => $name, 'license' => $license]; + $sql = "INSERT INTO sys_remoteaction (server_id, tstamp, action_type, action_param, action_state, response) " . + "VALUES (?, UNIX_TIMESTAMP(), 'extension_license_update', ?, 'pending', '')"; + $app->db->query($sql, $server_id, json_encode($data)); + + return true; + } + + public function getServerName($server_id) { + global $app; + $sql = 'SELECT `server_name` FROM `server` WHERE `server_id` = ?'; + $record = $app->db->queryOneRecord($sql, $server_id); + if($record === null) { + return null; + } + return $record['server_name']; + } + + /** + * Get the list of pending extensions to install + * @return array + */ + public function getPendingInstalls() { + global $app; + $sql = 'SELECT * FROM `sys_remoteaction` WHERE `action_type` = ? and `action_state` = ?'; + $records = $app->db->queryAllRecords($sql, 'extension_install', 'pending'); + return $records; + } + +} diff --git a/interface/lib/classes/functions.inc.php b/interface/lib/classes/functions.inc.php index 629da2fb0e..b6e3ec158b 100644 --- a/interface/lib/classes/functions.inc.php +++ b/interface/lib/classes/functions.inc.php @@ -287,11 +287,33 @@ public function intval($string, $force_numeric = false) { * @return string - formated bytes */ public function formatBytes($size, $precision = 2) { + // 0 is a special as it would give NAN otehrwise. + if ($size == 0) { + return 0; + } + $base=log($size)/log(1024); $suffixes=array('', ' kB', ' MB', ' GB', ' TB'); return round(pow(1024, $base-floor($base)), $precision).$suffixes[floor($base)]; } + /** + * Function to change bytes to kB, MB, GB or TB or the translated string 'Unlimited' for -1 + * @param int $size - size in bytes + * @param int precicion - after-comma-numbers (default: 2) + * @return string - formated bytes + */ + public function formatBytesOrUnlimited($size, $precision = 2) { + global $app; + + if ($size == -1) { + return $app->lng('unlimited_txt'); + } + else { + return $this->formatBytes($size, $precision); + } + + } /** * Normalize a path and strip duplicate slashes from it @@ -650,7 +672,23 @@ public function func_client_cancel($client_id,$cancel) { $result = false; } return $result; - } + } + + /** + * Lookup a client's group + all groups he is reselling. + * + * @return string Comma separated list of groupid's + */ + function clientid_to_groups_list($client_id) { + global $app; + + if ($client_id != null) { + // Get the clients groupid, and in case it's a reseller the groupid's of its clients. + $group = $app->db->queryOneRecord("SELECT GROUP_CONCAT(groupid) AS `groups` FROM `sys_group` WHERE client_id IN (SELECT client_id FROM `client` WHERE client_id=? OR parent_client_id=?)", $client_id, $client_id); + return $group['groups']; + } + return null; + } } diff --git a/interface/lib/classes/ids.inc.php b/interface/lib/classes/ids.inc.php index ffa24a294e..fb5dde33e8 100644 --- a/interface/lib/classes/ids.inc.php +++ b/interface/lib/classes/ids.inc.php @@ -49,11 +49,14 @@ public function start() require_once(ISPC_CLASS_PATH.'/IDS/Report.php'); require_once(ISPC_CLASS_PATH.'/IDS/Event.php'); require_once(ISPC_CLASS_PATH.'/IDS/Converter.php'); + + $ispcookie = array(); + $ispcookie['ISPCSESS'] = $_COOKIE['ISPCSESS']; $ids_request = array( 'GET' => $_GET, 'POST' => $_POST, - 'COOKIE' => $_COOKIE + 'COOKIE' => $ispcookie ); $ids_init = IDS\Init::init(ISPC_CLASS_PATH.'/IDS/Config/Config.ini.php'); diff --git a/interface/lib/classes/ispcmail.inc.php b/interface/lib/classes/ispcmail.inc.php index f5aa359577..74dc137a7b 100644 --- a/interface/lib/classes/ispcmail.inc.php +++ b/interface/lib/classes/ispcmail.inc.php @@ -169,7 +169,7 @@ public function setOption($key, $value) { $this->smtp_host = $value; break; case 'smtp_port': - if(intval($value) > 0) $this->smtp_port = $value; + if(intval($value) > 0) $this->smtp_port = intval($value); break; case 'smtp_user': $this->smtp_user = $value; @@ -585,7 +585,7 @@ private function _encodeSubject($input, $charset = 'ISO-8859-1') { * @access private */ private function _smtp_login() { - $this->_smtp_conn = fsockopen(($this->smtp_crypt == 'ssl' ? 'tls://' : '') . $this->smtp_host, $this->smtp_port, $errno, $errstr, 30); + $this->_smtp_conn = fsockopen(($this->smtp_crypt == 'ssl' ? 'tls://' : '') . $this->smtp_host, (int)$this->smtp_port, $errno, $errstr, 30); if(empty($this->_smtp_conn)) return false; $response = fgets($this->_smtp_conn, 515); @@ -823,7 +823,7 @@ public function send($recipients) { $recipname = trim(str_replace('"', '', $recipname)); if($rec_string != '') $rec_string .= ', '; - if($recipname && !is_numeric($recipname)) $rec_string .= $recipname . '<' . $recip . '>'; + if($recipname && !is_numeric($recipname)) $rec_string .= '"' . $recipname . '"<' . $recip . '>'; else $rec_string .= $recip; } $to = $this->_encodeHeader($rec_string, $this->mail_charset); diff --git a/interface/lib/classes/listform_actions.inc.php b/interface/lib/classes/listform_actions.inc.php index 7ffc84c32b..dedbca8297 100644 --- a/interface/lib/classes/listform_actions.inc.php +++ b/interface/lib/classes/listform_actions.inc.php @@ -189,7 +189,7 @@ public function prepareDataRow($rec) //* substitute value for select fields if(is_array($app->listform->listDef['item']) && count($app->listform->listDef['item']) > 0) { foreach($app->listform->listDef['item'] as $field) { - if(isset($rec['active']) && $rec['active'] == 'n') $rec['warn_inactive'] = 'y'; + if(isset($rec['active']) && strtolower($rec['active']) == 'n') $rec['warn_inactive'] = 'y'; $key = $field['field']; if(isset($field['formtype']) && $field['formtype'] == 'SELECT') { if(strtolower($rec[$key]) == 'y' or strtolower($rec[$key]) == 'n') { @@ -226,7 +226,7 @@ public function getQueryString($no_limit = false) { } $sql_where = $app->listform->getSearchSQL($sql_where); - if(isset($app->listform->listDef['join_sql'])) $sql_where .= ' AND '.$app->listform->listDef['join_sql']; + if(isset($app->listform->listDef['join_sql']) && $app->listform->listDef['join_sql'] != '') $sql_where .= ' AND '.$app->listform->listDef['join_sql']; $app->tpl->setVar($app->listform->searchValues); $order_by_sql = $this->SQLOrderBy; diff --git a/interface/lib/classes/message.inc.php b/interface/lib/classes/message.inc.php new file mode 100644 index 0000000000..492e26aebc --- /dev/null +++ b/interface/lib/classes/message.inc.php @@ -0,0 +1,204 @@ +debug_log('Unknown message_state in message add function.'); + $message_date = date('Y-m-d H:i:s'); + $sql = "INSERT INTO `sys_message` (`sys_userid`,`sys_groupid`,`message_state`,`message_date`,`message`,`relation`) VALUES (?,?,?,?,?,?)"; + if(is_object($app->dbmaster)) { + // server + if(!$app->dbmaster->query($sql,(int)$sys_userid,(int)$sys_groupid,$message_state,$message_date,$message,$relation)) { + $app->debug_log('Adding '.$message_state.' message to sys_message failed.'); + } + } else { + // interface + if(!$app->db->query($sql,(int)$sys_userid,(int)$sys_groupid,$message_state,$message_date,$message,$relation)) { + $app->debug_log('Adding '.$message_state.' message to sys_message failed.'); + } + } + } + + /* + * This function is used to hide a message by message_id + */ + + public function hide_by_id($message_id) { + global $app, $conf; + $sql = "UPDATE `sys_message` SET `message_ack` = 'y' WHERE `message_id` = ?"; + if(is_object($app->dbmaster)) { + // server + if(!$app->dbmaster->query($sql,(int)$message_id)) { + $app->debug_log('Hiding message '.$message_id.' in sys_message failed.'); + } + } else { + // interface + if(!$app->db->query($sql,(int)$message_id)) { + $app->debug_log('Hiding message '.$message_id.' in sys_message failed.'); + } + } + } + + /* + * This function is used to hide a message by message_state + */ + + public function hide_by_message_state($message_state, $relation = '') { + global $app, $conf; + + if(!in_array($message_state,['info','warning','error'])) $app->debug_log('Unknown message_state in message add function.'); + + if(is_object($app->dbmaster)) { + // server + $sql = "UPDATE `sys_message` SET `message_ack` = 'y' WHERE `message_state` = ?"; + if(!empty($relation)) $sql .= " AND relation = ?"; + + if(!$app->dbmaster->query($sql, $message_state, $relation)) { + $app->debug_log('Hiding message by '.$message_state.' in sys_message failed.'); + } + } else { + // interface + $app->uses('tform_base'); + $sql = "UPDATE `sys_message` SET `message_ack` = 'y' WHERE `message_state` = ? AND ".$app->tform_base->getAuthSQL('r'); + if(!empty($relation)) $sql .= " AND relation = ?"; + + if(!$app->db->query($sql, $message_state, $relation)) { + $app->debug_log('Hiding message by '.$message_state.' in sys_message failed.'); + } + + // Do some cleanup + $this->cleanup(); + } + } + + /* + * This function is used to hide a message by relation + */ + + public function hide_by_message_relation($relation) { + global $app, $conf; + + if(is_object($app->dbmaster)) { + // server + $sql = "UPDATE `sys_message` SET `message_ack` = 'y' WHERE `relation` = ?"; + + if(!$app->dbmaster->query($sql, $relation)) { + $app->debug_log('Hiding message by '.$relation.' in sys_message failed.'); + } + } else { + // interface + $app->uses('tform_base'); + $sql = "UPDATE `sys_message` SET `message_ack` = 'y' WHERE `relation` = ? AND ".$app->tform_base->getAuthSQL('r'); + + if(!$app->db->query($sql, $relation)) { + $app->debug_log('Hiding message by '.$relation.' in sys_message failed.'); + } + + // Do some cleanup + $this->cleanup(); + } + } + + /* + * This function is used to delete a message by message_id + */ + + public function delete($message_id) { + global $app, $conf; + $sql = "DELETE FROM `sys_message` WHERE `message_id` = ?"; + + if(is_object($app->dbmaster)) { + // server + if(!$app->dbmaster->query($sql,(int)$message_id)) { + $app->debug_log('Deleting message '.$message_id.' from sys_message failed.'); + } + } else { + // interface + if(!$app->db->query($sql,(int)$message_id)) { + $app->debug_log('Deleting message '.$message_id.' from sys_message failed.'); + } + } + } + + /* + * This function is used to clean up old messages + */ + + private function cleanup() { + global $app, $conf; + $message_cleanup_date = date('Y-m-d H:i:s',strtotime('- 1 month')); + $sql = "DELETE FROM `sys_message` WHERE `message_ack` = 'y' and `message_date` < ?"; + if(!$app->db->query($sql,$message_cleanup_date)) { + $app->debug_log('Cleaning up messages from sys_message failed.'); + } + } + + /* + * This function returns an array with all not acknowledged messages + * for the currently logged-in user (use in interface only) + */ + + public function get_current_messages($relation = '') { + global $app, $conf; + + $app->uses('tform_base'); + if(!is_object($app->tform_base)) { + $app->debug_log('No tform_base object. Do not use this function in server part.'); + return false; + } + + if($relation != '') { + $sql = "SELECT * FROM `sys_message` WHERE `message_ack` = 'n' AND `relation` = ? AND ".$app->tform_base->getAuthSQL('r'); + } else { + $sql = "SELECT * FROM `sys_message` WHERE `message_ack` = 'n' AND ".$app->tform_base->getAuthSQL('r'); + } + $messages = $app->db->queryAllRecords($sql,$relation); + + // Translate messages + $app->load_language_file('web/dashboard/lib/lang/'.$_SESSION['s']['language'].'_message.lng'); + foreach($messages as $key => $msg) { + $messages[$key]['message'] = $app->lng($msg['message']); + } + + return $messages; + } +} \ No newline at end of file diff --git a/interface/lib/classes/quota_lib.inc.php b/interface/lib/classes/quota_lib.inc.php index b02cdea994..b8e5cbc06a 100644 --- a/interface/lib/classes/quota_lib.inc.php +++ b/interface/lib/classes/quota_lib.inc.php @@ -14,7 +14,10 @@ public function get_quota_data($clientid = null, $readable = true) { //print_r($monitor_data); // select all websites or websites belonging to client - $sites = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE active = 'y' AND type = 'vhost'".(($clientid != null)?" AND sys_groupid = (SELECT default_group FROM sys_user WHERE client_id=?)":'') . " ORDER BY domain", $clientid); + $q = "SELECT * FROM web_domain WHERE type = 'vhost' AND "; + $q .= $app->tform->getAuthSQL('r', '', '', $app->functions->clientid_to_groups_list($clientid)); + $q .= " ORDER BY domain"; + $sites = $app->db->queryAllRecords($q, $clientid); //print_r($sites); if(is_array($sites) && !empty($sites)){ @@ -36,9 +39,10 @@ public function get_quota_data($clientid = null, $readable = true) { if (!is_numeric($sites[$i]['hard'])) $sites[$i]['hard']=$sites[$i]['hard'][1]; if (!is_numeric($sites[$i]['files'])) $sites[$i]['files']=$sites[$i]['files'][1]; - $sites[$i]['used_raw'] = $sites[$i]['used']; - $sites[$i]['soft_raw'] = $sites[$i]['soft']; - $sites[$i]['hard_raw'] = $sites[$i]['hard']; + // Convert from kb to bytes, and use -1 for instead of 0 for Unlimited. + $sites[$i]['used_raw'] = $sites[$i]['used'] * 1024; + $sites[$i]['soft_raw'] = ($sites[$i]['soft'] > 0) ? $sites[$i]['soft'] * 1024 : -1; + $sites[$i]['hard_raw'] = ($sites[$i]['hard'] > 0) ? $sites[$i]['hard'] * 1024 : -1; $sites[$i]['files_raw'] = $sites[$i]['files']; $sites[$i]['used_percentage'] = ($sites[$i]['soft'] > 0 && $sites[$i]['used'] > 0 ? round($sites[$i]['used'] * 100 / $sites[$i]['soft']) : 0); @@ -53,29 +57,6 @@ public function get_quota_data($clientid = null, $readable = true) { if($used_ratio >= 0.8) $sites[$i]['display_colour'] = '#fd934f'; if($used_ratio >= 1) $sites[$i]['display_colour'] = '#cc0000'; - if($sites[$i]['used'] > 1024) { - $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, 1).' MB'; - } else { - $sites[$i]['soft'] .= ' KB'; - } - - if($sites[$i]['hard'] > 1024) { - $sites[$i]['hard'] = round($sites[$i]['hard'] / 1024, 1).' MB'; - } else { - $sites[$i]['hard'] .= ' KB'; - } - - if($sites[$i]['soft'] == " KB") $sites[$i]['soft'] = $app->lng('unlimited_txt'); - if($sites[$i]['hard'] == " KB") $sites[$i]['hard'] = $app->lng('unlimited_txt'); - - if($sites[$i]['soft'] == '0 B' || $sites[$i]['soft'] == '0 KB' || $sites[$i]['soft'] == '0') $sites[$i]['soft'] = $app->lng('unlimited_txt'); - if($sites[$i]['hard'] == '0 B' || $sites[$i]['hard'] == '0 KB' || $sites[$i]['hard'] == '0') $sites[$i]['hard'] = $app->lng('unlimited_txt'); /* if(!strstr($sites[$i]['used'],'M') && !strstr($sites[$i]['used'],'K')) $sites[$i]['used'].= ' B'; @@ -83,13 +64,7 @@ public function get_quota_data($clientid = null, $readable = true) { if(!strstr($sites[$i]['hard'],'M') && !strstr($sites[$i]['hard'],'K')) $sites[$i]['hard'].= ' B'; */ } - else { - if (empty($sites[$i]['soft'])) $sites[$i]['soft'] = -1; - if (empty($sites[$i]['hard'])) $sites[$i]['hard'] = -1; - if($sites[$i]['soft'] == '0 B' || $sites[$i]['soft'] == '0 KB' || $sites[$i]['soft'] == '0') $sites[$i]['soft'] = -1; - if($sites[$i]['hard'] == '0 B' || $sites[$i]['hard'] == '0 KB' || $sites[$i]['hard'] == '0') $sites[$i]['hard'] = -1; - } } } @@ -218,7 +193,7 @@ public function get_ftptrafficquota_data($clientid = null, $lastdays = 0) { return $traffic_data; } - public function get_mailquota_data($clientid = null, $readable = true) { + public function get_mailquota_data($clientid = null, $readable = true, $email = null) { global $app; $tmp_rec = $app->db->queryAllRecords("SELECT data from monitor_data WHERE type = 'email_quota' ORDER BY created DESC"); @@ -236,14 +211,32 @@ public function get_mailquota_data($clientid = null, $readable = true) { } //print_r($monitor_data); + if ($email !== null && !empty($email)) { + if(isset($monitor_data[$email])) { + return $monitor_data[$email]; + } else { + return ''; + } + + } // select all email accounts or email accounts belonging to client - $emails = $app->db->queryAllRecords("SELECT * FROM mail_user".(($clientid != null)? " WHERE sys_groupid = (SELECT default_group FROM sys_user WHERE client_id=?)" : '') . " ORDER BY email", $clientid); + $q = "SELECT * FROM mail_user WHERE"; + $q .= $app->tform->getAuthSQL('r', '', '', $app->functions->clientid_to_groups_list($clientid)); + $q .= " ORDER BY email"; + $emails = $app->db->queryAllRecords($q, $clientid); //print_r($emails); if(is_array($emails) && !empty($emails)) { for($i=0;$ilng('never_accessed_txt'); + } + else { + $emails[$i]['last_access'] = date($app->lng('conf_format_dateshort'), $emails[$i]['last_access']); + } + $emails[$i]['name'] = $app->functions->htmlentities($emails[$i]['name']); $emails[$i]['used'] = isset($monitor_data[$email]['used']) ? $monitor_data[$email]['used'] : array(1 => 0); @@ -265,17 +258,8 @@ public function get_mailquota_data($clientid = null, $readable = true) { if($used_ratio >= 0.8) $emails[$i]['display_colour'] = '#fd934f'; if($used_ratio >= 1) $emails[$i]['display_colour'] = '#cc0000'; - if($emails[$i]['quota'] == 0){ - $emails[$i]['quota'] = $app->lng('unlimited_txt'); - } else { - $emails[$i]['quota'] = round($emails[$i]['quota'] / 1048576, 1).' MB'; - } - - - if($emails[$i]['used'] < 1544000) { - $emails[$i]['used'] = round($emails[$i]['used'] / 1024, 1).' KB'; - } else { - $emails[$i]['used'] = round($emails[$i]['used'] / 1048576, 1).' MB'; + if($emails[$i]['quota'] == 0) { + $emails[$i]['quota'] = -1; } } } @@ -302,18 +286,21 @@ public function get_databasequota_data($clientid = null, $readable = true) { //print_r($monitor_data); // select all databases belonging to client - $databases = $app->db->queryAllRecords("SELECT * FROM web_database".(($clientid != null)? " WHERE sys_groupid = (SELECT default_group FROM sys_user WHERE client_id=?)" : '') . " ORDER BY database_name", $clientid); + $q = "SELECT * FROM web_database WHERE"; + $q .= $app->tform->getAuthSQL('r', '', '', $app->functions->clientid_to_groups_list($clientid)); + $q .= " ORDER BY database_name"; + $databases = $app->db->queryAllRecords($q); //print_r($databases); if(is_array($databases) && !empty($databases)){ for($i=0;$i 0) && ($databases[$i]['used'] > 0)) ? round($databases[$i]['used_raw'] * 100 / $databases[$i]['database_quota']) : 0; + $databases[$i]['database_quota_raw'] = ($databases[$i]['database_quota'] == -1) ? -1 : $databases[$i]['database_quota'] * 1000 * 1000; + $databases[$i]['used_raw'] = $size; // / 1024 / 1024; //* quota is stored as MB - calculated bytes + $databases[$i]['used_percentage'] = (($databases[$i]['database_quota'] > 0) && ($size > 0)) ? round($databases[$i]['used_raw'] * 100 / $databases[$i]['database_quota_raw']) : 0; if ($readable) { // colours @@ -326,18 +313,8 @@ public function get_databasequota_data($clientid = null, $readable = true) { if($used_ratio >= 0.8) $databases[$i]['display_colour'] = '#fd934f'; if($used_ratio >= 1) $databases[$i]['display_colour'] = '#cc0000'; - if($databases[$i]['database_quota'] == 0){ - $databases[$i]['database_quota'] = $app->lng('unlimited_txt'); - } else { - $databases[$i]['database_quota'] = $databases[$i]['database_quota'] . ' MB'; - } - if($databases[$i]['used'] < 1544000) { - $databases[$i]['used'] = round($databases[$i]['used'] / 1024, 1).' KB'; - } else { - $databases[$i]['used'] = round($databases[$i]['used'] / 1048576, 1).' MB'; - } } } } diff --git a/interface/lib/classes/remote.d/client.inc.php b/interface/lib/classes/remote.d/client.inc.php index b5a0b421d7..612e667f97 100644 --- a/interface/lib/classes/remote.d/client.inc.php +++ b/interface/lib/classes/remote.d/client.inc.php @@ -113,20 +113,20 @@ public function client_get_id($session_id, $sys_userid) } } - + //* Get the contact details to send a email like email address, name, etc. public function client_get_emailcontact($session_id, $client_id) { 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.'); return false; } - + $client_id = $app->functions->intval($client_id); $rec = $app->db->queryOneRecord("SELECT company_name,contact_name,gender,email,language FROM client WHERE client_id = ?", $client_id); - + if(is_array($rec)) { return $rec; } else { @@ -159,7 +159,7 @@ public function client_get_groupid($session_id, $client_id) public function client_add($session_id, $reseller_id, $params) { global $app; - + if (!$this->checkPerm($session_id, 'client_add')) { throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); @@ -198,7 +198,7 @@ public function client_update($session_id, $client_id, $reseller_id, $params) $app->uses('remoting_lib'); $app->remoting_lib->loadFormDef('../client/form/' . (isset($params['limit_client']) && $params['limit_client'] != 0 ? 'reseller' : 'client') . '.tform.php'); $old_rec = $app->remoting_lib->getDataRecord($client_id); - + //* merge old record with params, so only new values have to be set in $params $params = $app->functions->array_merge($old_rec,$params); @@ -218,7 +218,7 @@ public function client_update($session_id, $client_id, $reseller_id, $params) } } - // we need the previuos templates assigned here + // we need the previous templates assigned here $this->oldTemplatesAssigned = $app->db->queryAllRecords('SELECT * FROM `client_template_assigned` WHERE `client_id` = ?', $client_id); if(!is_array($this->oldTemplatesAssigned) || count($this->oldTemplatesAssigned) < 1) { // check previous type of storing templates @@ -243,7 +243,7 @@ public function client_update($session_id, $client_id, $reseller_id, $params) $affected_rows = $this->updateQuery('../client/form/' . (isset($params['limit_client']) && $params['limit_client'] != 0 ? 'reseller' : 'client') . '.tform.php', $reseller_id, $client_id, $params, 'client:' . ($reseller_id ? 'reseller' : 'client') . ':on_after_update'); $app->remoting_lib->ispconfig_sysuser_update($params, $client_id); - + // if canceled if ($params['canceled']) { $result = $app->functions->func_client_cancel($client_id, $params['canceled']); @@ -482,7 +482,7 @@ public function client_get_by_username($session_id, $username) { return false; } } - + public function client_get_by_customer_no($session_id, $customer_no) { global $app; if(!$this->checkPerm($session_id, 'client_get_by_customer_no')) { @@ -573,16 +573,16 @@ public function client_templates_get_all($session_id) { $result = $app->db->queryAllRecords($sql); return $result; } - + public function client_login_get($session_id,$username,$password,$remote_ip = '') { global $app; - + //* Check permissions if(!$this->checkPerm($session_id, 'client_get')) { throw new SoapFault('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.'); @@ -592,21 +592,21 @@ public function client_login_get($session_id,$username,$password,$remote_ip = '' throw new SoapFault('password_length_error', 'Invalid password length or no password provided.'); return false; } - + //* Check failed logins $sql = "SELECT * FROM `attempts_login` WHERE `ip`= ? AND `login_time` > (NOW() - INTERVAL 1 MINUTE) LIMIT 1"; $alreadyfailed = $app->db->queryOneRecord($sql, $remote_ip); - + //* too many failedlogins if($alreadyfailed['times'] > 5) { throw new SoapFault('error_user_too_many_logins', 'Too many failed logins.'); return false; } - - + + //*Set variables $returnval == false; - + if(strstr($username,'@')) { // Check against client table $sql = "SELECT * FROM client WHERE email = ?"; @@ -628,7 +628,7 @@ public function client_login_get($session_id,$username,$password,$remote_ip = '' } } } - + if(is_array($user)) { $returnval = array( 'username' => $user['username'], 'type' => 'user', @@ -636,7 +636,7 @@ public function client_login_get($session_id,$username,$password,$remote_ip = '' 'language' => $user['language'], 'country' => $user['country']); } - + } else { // Check against sys_user table $sql = "SELECT * FROM sys_user WHERE username = ?"; @@ -658,7 +658,7 @@ public function client_login_get($session_id,$username,$password,$remote_ip = '' } } } - + if(is_array($user)) { $returnval = array( 'username' => $user['username'], 'type' => $user['typ'], @@ -669,7 +669,7 @@ public function client_login_get($session_id,$username,$password,$remote_ip = '' throw new SoapFault('login_failed', 'Login failed.'); } } - + //* Log failed login attempts if($user === false) { if(!$alreadyfailed['times'] ) { @@ -682,10 +682,10 @@ public function client_login_get($session_id,$username,$password,$remote_ip = '' $app->db->query($sql, $remote_ip); } } - + return $returnval; } - + public function client_get_by_groupid($session_id, $group_id) { global $app; diff --git a/interface/lib/classes/remote.d/dns.inc.php b/interface/lib/classes/remote.d/dns.inc.php index 67b97e722d..00a3ce4b93 100644 --- a/interface/lib/classes/remote.d/dns.inc.php +++ b/interface/lib/classes/remote.d/dns.inc.php @@ -44,143 +44,41 @@ class remoting_dns extends remoting { //* Create Zone with Template public function dns_templatezone_add($session_id, $client_id, $template_id, $domain, $ip, $ns1, $ns2, $email, $ipv6 = '') { 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.'); } - $client = $app->db->queryOneRecord("SELECT default_dnsserver FROM client WHERE client_id = ?", $client_id); - $server_id = $client["default_dnsserver"]; - $template_record = $app->db->queryOneRecord("SELECT * FROM dns_template WHERE template_id = ?", $template_id); - $fields = explode(',', $template_record['fields']); - $tform_def_file = "../../web/dns/form/dns_soa.tform.php"; - $app->uses('tform'); - $app->tform->loadFormDef($tform_def_file); - $app->uses('tpl,validate_dns,remoting_lib'); + $client_id = $app->functions->intval($client_id); + // Get client group id + $rec = $app->db->queryOneRecord("SELECT groupid FROM sys_group WHERE client_id = ?", $client_id); + if(isset($rec['groupid'])) { + $client_group_id = $app->functions->intval($rec['groupid']); + } else { + throw new SoapFault('no_group_found', 'There is no group for this client ID.'); + return false; + } + + $app->uses('remoting_lib,dns_wizard'); $app->remoting_lib->loadUserProfile($client_id); - //* replace template placeholders - $tpl_content = $template_record['template']; - if($domain != '') $tpl_content = str_replace('{DOMAIN}', $domain, $tpl_content); - if($ip != '') $tpl_content = str_replace('{IP}', $ip, $tpl_content); - if($ipv6 != '') $tpl_content = str_replace('{IPV6}', $ipv6, $tpl_content); - if($ns1 != '') $tpl_content = str_replace('{NS1}', $ns1, $tpl_content); - if($ns2 != '') $tpl_content = str_replace('{NS2}', $ns2, $tpl_content); - if($email != '') $tpl_content = str_replace('{EMAIL}', $email, $tpl_content); - - //* Parse the template - $tpl_rows = explode("\n", $tpl_content); - $section = ''; - $vars = array(); - $dns_rr = array(); - foreach($tpl_rows as $row) { - $row = trim($row); - if(substr($row, 0, 1) == '[') { - if($row == '[ZONE]') { - $section = 'zone'; - } elseif($row == '[DNS_RECORDS]') { - $section = 'dns_records'; - } else { - die('Unknown section type'); - } - } else { - if($row != '') { - //* Handle zone section - if($section == 'zone') { - $parts = explode('=', $row); - $key = trim($parts[0]); - $val = trim($parts[1]); - if($key != '') $vars[$key] = $val; - } - //* Handle DNS Record rows - if($section == 'dns_records') { - $parts = explode('|', $row); - $dns_rr[] = array( - 'name' => $parts[1], - 'type' => $parts[0], - 'data' => $parts[2], - 'aux' => $parts[3], - 'ttl' => $parts[4] - ); - } - } - } - } // end foreach - - if($vars['origin'] == '') $error .= $app->lng('error_origin_empty').'
'; - if($vars['ns'] == '') $error .= $app->lng('error_ns_empty').'
'; - if($vars['mbox'] == '') $error .= $app->lng('error_mbox_empty').'
'; - if($vars['refresh'] == '') $error .= $app->lng('error_refresh_empty').'
'; - if($vars['retry'] == '') $error .= $app->lng('error_retry_empty').'
'; - if($vars['expire'] == '') $error .= $app->lng('error_expire_empty').'
'; - if($vars['minimum'] == '') $error .= $app->lng('error_minimum_empty').'
'; - if($vars['ttl'] == '') $error .= $app->lng('error_ttl_empty').'
'; - if(!isset($vars['xfer'])) $vars['xfer'] = ''; - - if($error == '') { - // Insert the soa record - $tmp = $app->db->queryOneRecord("SELECT userid,default_group FROM sys_user WHERE client_id = ?", $client_id); - $sys_userid = $tmp['userid']; - $sys_groupid = $tmp['default_group']; - unset($tmp); - $origin = $vars['origin']; - $ns = $vars['ns']; - $mbox = str_replace('@', '.', $vars['mbox']); - $refresh = $vars['refresh']; - $retry = $vars['retry']; - $expire = $vars['expire']; - $minimum = $vars['minimum']; - $ttl = $vars['ttl']; - $xfer = $vars['xfer']; - $also_notify = $vars['also_notify']; - $update_acl = $vars['update_acl']; - $serial = $app->validate_dns->increase_serial(0); - $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, - "origin" => $origin, - "ns" => $ns, - "mbox" => $mbox, - "serial" => $serial, - "refresh" => $refresh, - "retry" => $retry, - "expire" => $expire, - "minimum" => $minimum, - "ttl" => $ttl, - "active" => 'Y', - "xfer" => $xfer, - "also_notify" => $also_notify, - "update_acl" => $update_acl - ); - $dns_soa_id = $app->db->datalogInsert('dns_soa', $insert_data, 'id'); - // Insert the dns_rr records - if(is_array($dns_rr) && $dns_soa_id > 0) { - foreach($dns_rr as $rr) { - $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" => $rr['name'], - "type" => $rr['type'], - "data" => $rr['data'], - "aux" => $rr['aux'], - "ttl" => $rr['ttl'], - "active" => 'Y' - ); - $dns_rr_id = $app->db->datalogInsert('dns_rr', $insert_data, 'id'); - } - } - exit; + $create = $app->dns_wizard->create([ + 'client_group_id' => $client_group_id, + 'template_id' => $template_id, + 'domain' => $domain, + 'ip' => $ip, + 'ns1' => $ns1, + 'ns2' => $ns2, + 'email' => $email, + 'ipv6' => $ipv6, + ]); + + if ($create == 'ok') { + return true; } else { - throw new SoapFault('permission_denied', $error); + throw new SoapFault('dns_wizard_error', $create); + return false; } } @@ -254,7 +152,7 @@ public function dns_zone_get_id($session_id, $origin) { return false; } - $rec = $app->db->queryOneRecord("SELECT id FROM dns_soa WHERE origin like ?", $origin."%"); + $rec = $app->db->queryOneRecord("SELECT id FROM dns_soa WHERE origin = ? or origin = ?", $origin, $origin.'.'); if(isset($rec['id'])) { return $app->functions->intval($rec['id']); } else { @@ -320,10 +218,11 @@ private function dns_rr_add($session_id, $client_id, $params, $update_serial=fal if(!$this->checkPerm($session_id, 'dns_' . $rr_type . '_add')) { throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); } + $primary_id = $this->insertQuery('../dns/form/dns_' . $rr_type . '.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); + return $primary_id; } //* Update a record @@ -845,6 +744,39 @@ public function dns_zone_set_status($session_id, $primary_id, $status) { } } + /* + * Set DNSSec Algo and activate it if needed. + * + * @param int session id + * @param int client id + * @param string algorithm 'NSEC3RSASHA1', 'ECDSAP256SHA256' or 'NSEC3RSASHA1,ECDSAP256SHA256' string + * @param boolean update serial + * + * @author Tom Albers KovoKs B.V. 2023 + */ + + public function dns_zone_set_dnssec($session_id, $client_id, $primary_id, $algo, $update_serial=false) { + 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.'); + return false; + } + + if(!in_array($algo, ['NSEC3RSASHA1', 'ECDSAP256SHA256', 'NSEC3RSASHA1,ECDSAP256SHA256'])) { + throw new SoapFault('permission_denied', 'You are not using a valid algorithm for this function.'); + return false; + } + $params["dnssec_wanted"] = "Y"; + $params["dnssec_algo"] = $algo; + $affected_rows = $this->updateQuery('../dns/form/dns_soa.tform.php', $client_id, $primary_id, $params); + if($update_serial) { + $this->increase_serial($session_id, $client_id, ["zone" => $primary_id]); + + } + return $affected_rows; + } + + private function increase_serial($session_id, $client_id, $params) { global $app; if(!isset($params['zone']) && isset($params['dns_rr_id'])) { diff --git a/interface/lib/classes/remote.d/mail.inc.php b/interface/lib/classes/remote.d/mail.inc.php index 2d26b1969f..2cd0338a0c 100644 --- a/interface/lib/classes/remote.d/mail.inc.php +++ b/interface/lib/classes/remote.d/mail.inc.php @@ -60,6 +60,10 @@ public function mail_domain_add($session_id, $client_id, $params) throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); return false; } + + // set default value for dkim selector if not set in $params array + if(!isset($params['dkim_selector'])) $params['dkim_selector'] = 'default'; + $primary_id = $this->insertQuery('../mail/form/mail_domain.tform.php', $client_id, $params, 'mail:mail_domain:on_after_insert'); return $primary_id; } @@ -332,7 +336,7 @@ public function mail_user_filter_delete($session_id, $primary_id) return $affected_rows; } - // Mail backup list function by Dominik Müller, 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; @@ -355,7 +359,7 @@ public function mail_user_backup_list($session_id, $primary_id = null) return $result; } - // Mail backup restore/download functions by Dominik Müller, 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; diff --git a/interface/lib/classes/remote.d/sites.inc.php b/interface/lib/classes/remote.d/sites.inc.php index 10fc028e64..bbcc8be1d9 100644 --- a/interface/lib/classes/remote.d/sites.inc.php +++ b/interface/lib/classes/remote.d/sites.inc.php @@ -167,9 +167,8 @@ public function sites_database_update($session_id, $client_id, $primary_id, $par $retval = $this->updateQueryExecute($sql, $primary_id, $params); // set correct values for backup_interval and backup_copies - if(isset($params['backup_interval']) || isset($params['backup_copies']) || isset($params['backup_format_web']) || isset($params['backup_format_db'])){ + if(isset($params['backup_copies']) || isset($params['backup_format_web']) || isset($params['backup_format_db'])){ $sql_set = array(); - if(isset($params['backup_interval'])) $sql_set[] = "backup_interval = '".$app->db->quote($params['backup_interval'])."'"; if(isset($params['backup_copies'])) $sql_set[] = "backup_copies = ".$app->functions->intval($params['backup_copies']); if(isset($params['backup_format_web'])) $sql_set[] = "backup_format_web = ".$app->functions->intval($params['backup_format_web']); if(isset($params['backup_format_db'])) $sql_set[] = "backup_format_db = ".$app->functions->intval($params['backup_format_db']); @@ -434,10 +433,10 @@ public function sites_web_domain_add($session_id, $client_id, $params, $readonly if($params['log_retention'] == '') $params['log_retention'] = 30; //* Set a few defaults for nginx servers - if($params['pm_max_children'] == '') $params['pm_max_children'] = 1; - if($params['pm_start_servers'] == '') $params['pm_start_servers'] = 1; + if($params['pm_max_children'] == '') $params['pm_max_children'] = 10; + if($params['pm_start_servers'] == '') $params['pm_start_servers'] = 2; if($params['pm_min_spare_servers'] == '') $params['pm_min_spare_servers'] = 1; - if($params['pm_max_spare_servers'] == '') $params['pm_max_spare_servers'] = 1; + if($params['pm_max_spare_servers'] == '') $params['pm_max_spare_servers'] = 5; $domain_id = $this->insertQuery('../sites/form/web_vhost_domain.tform.php', $client_id, $params, 'sites:web_vhost_domain:on_after_insert'); if ($readonly === true) @@ -456,10 +455,10 @@ public function sites_web_domain_update($session_id, $client_id, $primary_id, $p if($params['log_retention'] == '') $params['log_retention'] = 30; //* Set a few defaults for nginx servers - if($params['pm_max_children'] == '') $params['pm_max_children'] = 1; - if($params['pm_start_servers'] == '') $params['pm_start_servers'] = 1; + if($params['pm_max_children'] == '') $params['pm_max_children'] = 10; + if($params['pm_start_servers'] == '') $params['pm_start_servers'] = 2; if($params['pm_min_spare_servers'] == '') $params['pm_min_spare_servers'] = 1; - if($params['pm_max_spare_servers'] == '') $params['pm_max_spare_servers'] = 1; + if($params['pm_max_spare_servers'] == '') $params['pm_max_spare_servers'] = 5; $affected_rows = $this->updateQuery('../sites/form/web_vhost_domain.tform.php', $client_id, $primary_id, $params); return $affected_rows; @@ -508,10 +507,10 @@ public function sites_web_vhost_aliasdomain_add($session_id, $client_id, $params if($params['log_retention'] == '') $params['log_retention'] = 30; //* Set a few defaults for nginx servers - if($params['pm_max_children'] == '') $params['pm_max_children'] = 1; - if($params['pm_start_servers'] == '') $params['pm_start_servers'] = 1; + if($params['pm_max_children'] == '') $params['pm_max_children'] = 10; + if($params['pm_start_servers'] == '') $params['pm_start_servers'] = 2; if($params['pm_min_spare_servers'] == '') $params['pm_min_spare_servers'] = 1; - if($params['pm_max_spare_servers'] == '') $params['pm_max_spare_servers'] = 1; + if($params['pm_max_spare_servers'] == '') $params['pm_max_spare_servers'] = 5; $domain_id = $this->insertQuery('../sites/form/web_vhost_domain.tform.php', $client_id, $params, 'sites:web_vhost_aliasdomain:on_after_insert'); return $domain_id; @@ -528,10 +527,10 @@ public function sites_web_vhost_aliasdomain_update($session_id, $client_id, $pri if($params['log_retention'] == '') $params['log_retention'] = 30; //* Set a few defaults for nginx servers - if($params['pm_max_children'] == '') $params['pm_max_children'] = 1; - if($params['pm_start_servers'] == '') $params['pm_start_servers'] = 1; + if($params['pm_max_children'] == '') $params['pm_max_children'] = 10; + if($params['pm_start_servers'] == '') $params['pm_start_servers'] = 2; if($params['pm_min_spare_servers'] == '') $params['pm_min_spare_servers'] = 1; - if($params['pm_max_spare_servers'] == '') $params['pm_max_spare_servers'] = 1; + if($params['pm_max_spare_servers'] == '') $params['pm_max_spare_servers'] = 5; $affected_rows = $this->updateQuery('../sites/form/web_vhost_domain.tform.php', $client_id, $primary_id, $params, 'sites:web_vhost_aliasdomain:on_after_insert'); return $affected_rows; @@ -580,10 +579,10 @@ public function sites_web_vhost_subdomain_add($session_id, $client_id, $params) if($params['log_retention'] == '') $params['log_retention'] = 30; //* Set a few defaults for nginx servers - if($params['pm_max_children'] == '') $params['pm_max_children'] = 1; - if($params['pm_start_servers'] == '') $params['pm_start_servers'] = 1; + if($params['pm_max_children'] == '') $params['pm_max_children'] = 10; + if($params['pm_start_servers'] == '') $params['pm_start_servers'] = 2; if($params['pm_min_spare_servers'] == '') $params['pm_min_spare_servers'] = 1; - if($params['pm_max_spare_servers'] == '') $params['pm_max_spare_servers'] = 1; + if($params['pm_max_spare_servers'] == '') $params['pm_max_spare_servers'] = 5; $domain_id = $this->insertQuery('../sites/form/web_vhost_domain.tform.php', $client_id, $params, 'sites:web_vhost_subdomain:on_after_insert'); return $domain_id; @@ -600,10 +599,10 @@ public function sites_web_vhost_subdomain_update($session_id, $client_id, $prima if($params['log_retention'] == '') $params['log_retention'] = 30; //* Set a few defaults for nginx servers - if($params['pm_max_children'] == '') $params['pm_max_children'] = 1; - if($params['pm_start_servers'] == '') $params['pm_start_servers'] = 1; + if($params['pm_max_children'] == '') $params['pm_max_children'] = 10; + if($params['pm_start_servers'] == '') $params['pm_start_servers'] = 2; if($params['pm_min_spare_servers'] == '') $params['pm_min_spare_servers'] = 1; - if($params['pm_max_spare_servers'] == '') $params['pm_max_spare_servers'] = 1; + if($params['pm_max_spare_servers'] == '') $params['pm_max_spare_servers'] = 5; $affected_rows = $this->updateQuery('../sites/form/web_vhost_domain.tform.php', $client_id, $primary_id, $params, 'sites:web_vhost_subdomain:on_after_insert'); return $affected_rows; diff --git a/interface/lib/classes/remoting_lib.inc.php b/interface/lib/classes/remoting_lib.inc.php index c496cb7e22..27b670065b 100644 --- a/interface/lib/classes/remoting_lib.inc.php +++ b/interface/lib/classes/remoting_lib.inc.php @@ -82,11 +82,22 @@ class remoting_lib extends tform_base { //* Load the form definition from file. - special version for remoting // module parameter is only for compatibility with base class function loadFormDef($file, $module = '') { - global $app, $conf; + global $app; include $file; + // Search for module name by path because $_SESSION['s']['module']['name'] + // isn't set in a remote call. + $module_path = array_reverse(explode('/', $file)); + $module_name = isset($module_path[2]) && $module_path[1] == 'form' && preg_match("/^[a-z]{2,20}$/i", $module_path[2]) ? $module_path[2] : ''; + + // Allow plugins to be loaded + if ($module_name) { + $app->plugin->raiseEvent($module_name.':'.$form['name'] . ':on_remote_before_formdef', $this); + } + $this->formDef = $form; + unset($this->formDef['tabs']); //* Copy all fields from all tabs into one form definition @@ -97,6 +108,11 @@ function loadFormDef($file, $module = '') { } unset($form); + // Allow plugins to be loaded + if ($module_name) { + $app->plugin->raiseEvent($module_name.':'.$this->formDef['name'] . ':on_remote_after_formdef', $this); + } + $this->dateformat = 'Y-m-d'; //$app->lng('conf_format_dateshort'); $this->datetimeformat = 'Y-m-d H:i:s'; //$app->lng('conf_format_datetime'); @@ -127,6 +143,10 @@ function loadUserProfile($client_id_param = 0) { $_SESSION["s"]["user"]["typ"] = 'admin'; } else { $user = $app->db->queryOneRecord("SELECT * FROM sys_user WHERE client_id = ?", $this->client_id); + if(empty($user)) { + throw new SoapFault('invalid_client_id', 'Invalid client_id '.$this->client_id); + return false; + } $this->sys_username = $user['username']; $this->sys_userid = $user['userid']; $this->sys_default_group = $user['default_group']; @@ -199,14 +219,14 @@ function encode($record, $tab = '', $dbencode = true) { function getSQL($record, $action = 'INSERT', $primary_id = 0, $sql_ext_where = '', $dummy = '') { global $app; - + // early usage. make sure _primary_id is sanitized if present. if ( isset($record['_primary_id']) && is_numeric($record['_primary_id'])) { $_primary_id = intval($record['_primary_id']); if ($_primary_id > 0) $this->primary_id_override = $_primary_id; } - + if(!is_array($this->formDef)) $app->error("Form definition not found."); $this->dataRecord = $record; @@ -277,6 +297,16 @@ function ispconfig_sysuser_add($params, $insert_id){ $modules = $conf['interface_modules_enabled']; } else { $modules = $params['modules']; + + // Check if modules are allowed and remove unknown modules + $allowed_modules = explode(',', $conf['interface_modules_enabled']); + $modules_array = explode(',', $modules); + foreach($modules_array as $key => $module) { + if(!in_array($module, $allowed_modules)) { + unset($modules_array[$key]); + } + } + $modules = implode(',', $modules_array); } if(isset($params['limit_client']) && $params['limit_client'] > 0) { $modules .= ',client'; @@ -286,7 +316,7 @@ function ispconfig_sysuser_add($params, $insert_id){ $startmodule = 'dashboard'; } else { $startmodule = $params["startmodule"]; - if(!preg_match('/'.$startmodule.'/', $modules)) { + if(!in_array($startmodule, explode(',', $modules))) { $_modules = explode(',', $modules); $startmodule=$_modules[0]; } @@ -305,13 +335,23 @@ function ispconfig_sysuser_add($params, $insert_id){ } function ispconfig_sysuser_update($params, $client_id){ - global $app; + global $app, $conf; $username = $params["username"]; $clear_password = $params["password"]; $language = $params['language']; $modules = $params['modules']; $client_id = $app->functions->intval($client_id); + // Check if modules are allowed and remove unknown modules + $allowed_modules = explode(',', $conf['interface_modules_enabled']); + $modules_array = explode(',', $modules); + foreach($modules_array as $key => $module) { + if(!in_array($module, $allowed_modules)) { + unset($modules_array[$key]); + } + } + $modules = implode(',', $modules_array); + 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); diff --git a/interface/lib/classes/sites_database_plugin.inc.php b/interface/lib/classes/sites_database_plugin.inc.php index 68421d6083..bc345f62ad 100644 --- a/interface/lib/classes/sites_database_plugin.inc.php +++ b/interface/lib/classes/sites_database_plugin.inc.php @@ -44,8 +44,7 @@ public function processDatabaseUpdate($form_page) { //* The Database user shall be owned by the same group then the website $sys_groupid = $app->functions->intval($web['sys_groupid']); - $backup_interval = $web['backup_interval']; - $backup_format_web = $web['backup_format_web']; + $backup_interval = $app->db->quote($form_page->dataRecord["backup_interval"]); $backup_format_db = $web['backup_format_db']; $backup_copies = $app->functions->intval($web['backup_copies']); diff --git a/interface/lib/classes/tform.inc.php b/interface/lib/classes/tform.inc.php index 920541cacc..b061c00f31 100644 --- a/interface/lib/classes/tform.inc.php +++ b/interface/lib/classes/tform.inc.php @@ -115,7 +115,7 @@ function getNextTab() { // Show the same tab again in case of an error $active_tab = $_SESSION["s"]["form"]["tab"]; } - + if(!preg_match('/^[a-zA-Z0-9_]{0,50}$/',$active_tab)) { die('Invalid next tab name.'); } @@ -132,7 +132,7 @@ function getCurrentTab() { 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. @@ -149,7 +149,7 @@ function isReadonlyTab($tab, $primary_id) { if($record['sys_userid'] != $_SESSION["s"]["user"]["userid"]) { return true; } else { - return false; + return false; } } else { return false; @@ -204,7 +204,7 @@ function checkResellerLimit($limit_name, $sql_where = '') { if($client['parent_client_id'] != 0) { //* first we need to know the groups of this reseller - $tmp = $app->db->queryOneRecord("SELECT userid, groups FROM sys_user WHERE client_id = ?", $client['parent_client_id']); + $tmp = $app->db->queryOneRecord("SELECT userid, `groups` FROM sys_user WHERE client_id = ?", $client['parent_client_id']); $reseller_groups = $tmp["groups"]; $reseller_userid = $tmp["userid"]; @@ -247,7 +247,7 @@ function getDiffRecord($record_old, $record_new) { return $diffrec; } - + /** * Generate HTML for DATE fields. * @@ -260,10 +260,10 @@ function _getDateHTML($form_element, $default_value) { $_date = ($default_value && $default_value != '0000-00-00' ? strtotime($default_value) : false); $_showdate = ($_date === false) ? false : true; - + $tmp_dt = strtr($this->dateformat,array('d' => 'dd', 'm' => 'mm', 'Y' => 'yyyy', 'y' => 'yy')); - - return ''; + + return ''; } @@ -285,12 +285,12 @@ function _getDateTimeHTML($form_element, $default_value, $display_seconds=false) if ($display_seconds === true) { $dselect[] = 'second'; } - + $tmp_dt = strtr($this->datetimeformat,array('d' => 'dd', 'm' => 'mm', 'Y' => 'yyyy', 'y' => 'yy', 'H' => 'hh', 'h' => 'HH', 'i' => 'ii')) . ($display_seconds ? ':ss' : ''); $out = ''; - - return ''; + + return ''; /* foreach ($dselect as $dt_element) { @@ -352,7 +352,7 @@ function _getDateTimeHTML($form_element, $default_value, $display_seconds=false) $selected_value = (int)floor(date('s', $_datetime)); break; } - + $out .= " $v\r\n"; - $out .= ""; + $out .= ""; if (isset($field['render_inline']) && $field['render_inline'] == 'n') { $out .= "
\r\n"; } @@ -617,11 +621,7 @@ function getHTML($record, $tab, $action = 'NEW') { break; default: - if(isset($record[$key])) { - $new_record[$key] = $app->functions->htmlentities($record[$key]); - } else { - $new_record[$key] = ''; - } + $new_record[$key] = $app->functions->htmlentities($val); } } } @@ -1183,7 +1183,7 @@ function validateField($field_name, $field_value, $validators) { if (count($sql_v6_explode) < count($explode_field_value) && isset($sql_v6['ip_address'])) { $errmsg = $validator['errmsg']; if(isset($this->wordbook[$errmsg])) { - $this->errorMessage .= $this->wordbook[$errmsg].$sql_v6[ip_address]."
\r\n"; + $this->errorMessage .= $this->wordbook[$errmsg].$sql_v6['ip_address']."
\r\n"; } else { $this->errorMessage .= $errmsg."
\r\n"; } @@ -1376,6 +1376,13 @@ protected function _getSQL($record, $tab, $action = 'INSERT', $primary_id = 0, $ } elseif (isset($field['encryption']) && $field['encryption'] == 'MYSQL') { $record[$key] = $app->db->getPasswordHash($record[$key]); $sql_insert_val .= "'".$app->db->quote($record[$key])."', "; + } elseif (isset($field['encryption']) && $field['encryption'] == 'MYSQLSHA2') { + $record[$key] = $app->db->getPasswordHash($record[$key], 'caching_sha2_password'); + $sql_insert_val .= "'".$app->db->quote($record[$key])."', "; + } elseif (isset($field['encryption']) && $field['encryption'] == 'POSTGRESHA256') { + $app->uses('crypt'); + $record[$key] = $app->crypt->postgres_scram_sha_256($record[$key]); + $sql_insert_val .= "'".$app->db->quote($record[$key])."', "; } else { $record[$key] = md5(stripslashes($record[$key])); $sql_insert_val .= "'".$app->db->quote($record[$key])."', "; @@ -1407,6 +1414,13 @@ protected function _getSQL($record, $tab, $action = 'INSERT', $primary_id = 0, $ } elseif (isset($field['encryption']) && $field['encryption'] == 'MYSQL') { $record[$key] = $app->db->getPasswordHash($record[$key]); $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', "; + } elseif (isset($field['encryption']) && $field['encryption'] == 'MYSQLSHA2') { + $record[$key] = $app->db->getPasswordHash($record[$key], 'caching_sha2_password'); + $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', "; + } elseif (isset($field['encryption']) && $field['encryption'] == 'POSTGRESHA256') { + $app->uses('crypt'); + $record[$key] = $app->crypt->postgres_scram_sha_256($record[$key]); + $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', "; } else { $record[$key] = md5(stripslashes($record[$key])); $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', "; @@ -1610,17 +1624,27 @@ function datalogSave($action, $primary_id, $record_old, $record_new) { return true; } - function getAuthSQL($perm, $table = '') { - if($_SESSION["s"]["user"]["typ"] == 'admin' || $_SESSION['s']['user']['mailuser_id'] > 0) { + function getAuthSQL($perm, $table = '', $userid = NULL, $groups = NULL) { + if(($_SESSION["s"]["user"]["typ"] == 'admin' || $_SESSION['s']['user']['mailuser_id'] > 0 ) && $userid == NULL && $groups == NULL) { return '1'; } else { if ($table != ''){ $table = ' ' . $table . '.'; } - $groups = ( $_SESSION["s"]["user"]["groups"] ) ? $_SESSION["s"]["user"]["groups"] : 0; $sql = '('; - $sql .= "(" . $table . "sys_userid = ".$_SESSION["s"]["user"]["userid"]." AND " . $table . "sys_perm_user like '%$perm%') OR "; - $sql .= "(" . $table . "sys_groupid IN (".$groups.") AND " . $table ."sys_perm_group like '%$perm%') OR "; + if ($userid === NULL) { + $userid = $_SESSION["s"]["user"]["userid"]; + } + if ($userid > 0) { + $sql .= "(" . $table . "sys_userid = ".$userid." AND " . $table . "sys_perm_user like '%$perm%') OR "; + } + + if ($groups === NULL) { + $groups = ( $_SESSION["s"]["user"]["groups"] ) ? $_SESSION["s"]["user"]["groups"] : 0; + } + if ($groups > 0) { + $sql .= "(" . $table . "sys_groupid IN (".$groups.") AND " . $table ."sys_perm_group like '%$perm%') OR "; + } $sql .= $table . "sys_perm_other like '%$perm%'"; $sql .= ')'; diff --git a/interface/lib/classes/tpl.inc.php b/interface/lib/classes/tpl.inc.php index 977ed0901d..e6a2cfdfb2 100644 --- a/interface/lib/classes/tpl.inc.php +++ b/interface/lib/classes/tpl.inc.php @@ -30,7 +30,7 @@ include_once ISPC_CLASS_PATH.'/tpl_error.inc.php'; include_once ISPC_CLASS_PATH.'/tpl_ini.inc.php'; - class tpl{ + class tpl extends stdClass{ /*-----------------------------------------------------------------------------\ | ATTENTION | @@ -233,7 +233,7 @@ public function newTemplate($tmplfile) public function setVar($k, $v = null, $encode = false) { global $app; - + if (is_array($k)) { foreach($k as $key => $value){ $key = ($this->OPTIONS['CASELESS']) ? strtolower(trim($key)) : trim($key); @@ -917,9 +917,17 @@ private function _fileSearch($file) $filename = basename($file); $filepath = dirname($file); - if(isset($_SESSION['s']['module']['name']) && isset($_SESSION['s']['theme'])) { - if(is_file(ISPC_THEMES_PATH.'/'.$_SESSION['s']['theme'].'/templates/'.$_SESSION['s']['module']['name'].'/'.$filename)) { - return ISPC_THEMES_PATH.'/'.$_SESSION['s']['theme'].'/templates/'.$_SESSION['s']['module']['name'].'/'.$filename; + $modulename = false; + + if(isset($_SESSION['s']['module']['name'])) { + $modulename = $_SESSION['s']['module']['name']; + } elseif(strpos($_SERVER['PHP_SELF'], '/login/') === 0) { + $modulename = 'login'; + } + + if($modulename && isset($_SESSION['s']['theme'])) { + if(is_file(ISPC_THEMES_PATH.'/'.$_SESSION['s']['theme'].'/templates/'.$modulename.'/'.$filename)) { + return ISPC_THEMES_PATH.'/'.$_SESSION['s']['theme'].'/templates/'.$modulename.'/'.$filename; } } @@ -1079,12 +1087,12 @@ private function _parseIf($varname, $value = null, $op = null, $namespace = null private function _parseHook ($name) { global $app; - + if(!$name) return false; - + $module = isset($_SESSION['s']['module']['name']) ? $_SESSION['s']['module']['name'] : ''; $form = isset($app->tform->formDef['name']) ? $app->tform->formDef['name'] : ''; - + $events = array(); if($module) { $events[] = $module . ':' . ($form ? $form : '') . ':' . $name; @@ -1093,9 +1101,9 @@ private function _parseHook ($name) $events[] = $name; $events[] = 'on_template_content'; } - + $events = array_unique($events); - + for($e = 0; $e < count($events); $e++) { $tmpresult = $app->plugin->raiseEvent($events[$e], array( 'name' => $name, @@ -1104,10 +1112,10 @@ private function _parseHook ($name) ), true); if(!$tmpresult) $tmpresult = ''; else $tmpresult = $this->_getData($tmpresult, false, true); - + $result .= $tmpresult; } - + return $result; } @@ -1225,7 +1233,7 @@ private function _parseTag ($args) $wholetag = $args[0]; $openclose = $args[1]; $tag = strtolower($args[2]); - + if ($tag == 'else') return ''; if ($tag == 'tmpl_include') return $wholetag; // ignore tmpl_include tags @@ -1303,10 +1311,10 @@ private function _parseTag ($args) if ($this->OPTIONS['ENABLE_PHPINCLUDE']) { return ''; } - + case 'hook': return $this->_parseHook(@$var); - + case 'include': return '_getData($this->_fileSearch(\''.$file.'\'), 1); ?>'; diff --git a/interface/lib/classes/validate_cron.inc.php b/interface/lib/classes/validate_cron.inc.php index 888fdd5cb7..983172b88c 100644 --- a/interface/lib/classes/validate_cron.inc.php +++ b/interface/lib/classes/validate_cron.inc.php @@ -45,15 +45,43 @@ function get_error($errmsg) { Validator function to check if a given cron command is in correct form (url only). */ function command_format($field_name, $field_value, $validator) { + global $app, $page; + if(preg_match("'^(\w+):\/\/'", $field_value, $matches)) { + //* Add the {DOMAIN} placeholder to the validation process + if(preg_match("/{DOMAIN}/", $field_value)) { + + if(isset($app->remoting_lib->primary_id)) { + $cronjob = $app->remoting_lib->dataRecord; + } else { + $cronjob = $page->dataRecord; + } + + if($cronjob['parent_domain_id'] > 0) { + $parent_domain = $app->db->queryOneRecord("SELECT `domain` FROM `web_domain` WHERE `domain_id` = ?", $cronjob['parent_domain_id']); + $trans = array( + '{DOMAIN}' => $parent_domain['domain'] + ); + } + + $field_value = strtr($field_value, $trans); + + } $parsed = parse_url($field_value); + if($parsed === false) return $this->get_error($validator['errmsg']); if($parsed["scheme"] != "http" && $parsed["scheme"] != "https") return $this->get_error($validator['errmsg']); + if(preg_match("'^([a-z0-9][a-z0-9\-]{0,62}\.)+([A-Za-z0-9\-]{2,63})$'i", $parsed["host"]) == false) return $this->get_error($validator['errmsg']); + + - if(preg_match("'^([a-z0-9][a-z0-9_\-]{0,62}\.)+([A-Za-z0-9\-]{2,63})$'i", $parsed["host"]) == false) return $this->get_error($validator['errmsg']); + if(strpos($field_value, '\\') !== false) { + return $this->get_error($validator['errmsg']); + } } + if(strpos($field_value, "\n") !== false || strpos($field_value, "\r") !== false || strpos($field_value, chr(0)) !== false) { return $this->get_error($validator['errmsg']); } diff --git a/interface/lib/classes/validate_database.inc.php b/interface/lib/classes/validate_database.inc.php index c789b6a1c4..d67c7d51e8 100644 --- a/interface/lib/classes/validate_database.inc.php +++ b/interface/lib/classes/validate_database.inc.php @@ -44,7 +44,8 @@ function valid_ip_list($field_name, $field_value, $validator) { $cur_value = trim($cur_value); $valid = true; if(function_exists('filter_var')) { - if(!filter_var($cur_value, FILTER_VALIDATE_IP)) { + // value must be either an IP address or hostname + if(!filter_var($cur_value, FILTER_VALIDATE_IP) && !filter_var($cur_value, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)) { $valid = false; } } else return "function filter_var missing
\r\n"; diff --git a/interface/lib/classes/validate_dns.inc.php b/interface/lib/classes/validate_dns.inc.php index 15d670d84a..1dca969629 100644 --- a/interface/lib/classes/validate_dns.inc.php +++ b/interface/lib/classes/validate_dns.inc.php @@ -292,7 +292,7 @@ function validate_ip($field_name, $field_value, $validator) { if($validator['allowempty'] != 'y') $validator['allowempty'] = 'n'; if($validator['allowempty'] == 'y' && $field_value == '') { //* Do nothing - } elseif ($field_value == 'any') { + } elseif ($field_value == 'any' && $field_name != "also_notify") { //* Do nothing } else { //* Check if its a IPv4 or IPv6 address/range diff --git a/interface/lib/classes/validate_domain.inc.php b/interface/lib/classes/validate_domain.inc.php index 3555135eae..0378b2ee20 100644 --- a/interface/lib/classes/validate_domain.inc.php +++ b/interface/lib/classes/validate_domain.inc.php @@ -278,5 +278,115 @@ function _wildcard_limit() { return true; // admin may always add wildcard domain } + /** + * Parses $expression to check if it is a valid shell glob pattern. + * Does not support extended glob matching syntax. + * + * @see https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html + * @param string $expression + * @param string $allowed_chars regexp of allowed characters in expression. ? and * are always allowed + * @param string|null $allowed_brace_chars regexp of allowed characters in brace ([...]). Dash is always allowed. If empty, then $allowed_chars will be used + * @return bool + */ + private function validate_glob($expression, $allowed_chars = '/^.$/u', $allowed_brace_chars = null) { + $escaping = false; + $in_brace = false; + $brace_content = []; + $chars = preg_split('//u', $expression, -1, PREG_SPLIT_NO_EMPTY); + foreach($chars as $i => $c) { + if($in_brace) { + // the first char after brace start can be a ]. + if(($c == ']' && empty($brace_content)) || $c != ']') { + $brace_content[] = $c; + } else { + $in_brace = false; + $last_is_dash = false; + foreach($brace_content as $bi => $bc) { + // dashes are always allowed + if($bc == '-') { + // ... but we consider consecutive dashes as invalid + if($last_is_dash) { + return false; + } + // ... and need to validate it as allowed char when it is first or last + if(($bi == 0 || $bi == count($brace_content) - 1) && !preg_match($allowed_brace_chars ?: $allowed_chars, '-')) { + return false; + } + $last_is_dash = true; + } else { + $last_is_dash = false; + // negate chars are always allowed + if($bi == 0 && ($bc == '^' || $bc == '!') && count($brace_content) > 1) { + continue; + } + if(!preg_match($allowed_brace_chars ?: $allowed_chars, $bc)) { + return false; + } + } + } + } + } else { + $peek = $i == count($chars) - 1 ? '' : $chars[$i + 1]; + if($c == '\\' && in_array($peek, ['[', ']', '*', '?'])) { + $escaping = true; + continue; + } elseif($c == '[' && !$escaping) { + $in_brace = true; + $brace_content = []; + } elseif($escaping || ($c != '?' && $c != '*')) { + if(!preg_match($allowed_chars, $c)) { + return false; + } + } + $escaping = false; + } + } + return !$in_brace && !$escaping; + } + + /** + * Validates that input is a comma separated list of domain globs. + * Can be used for fnmatch() as input. + */ + function domain_glob_list($field_name, $field_value, $validator) { + global $app; + $allowempty = $validator['allowempty'] ?: 'n'; + $exceptions = $validator['exceptions'] ?: []; + $allow_exception_as_substring = $validator['allow_exception_as_substring'] ?: 'y'; + if(!$field_value) { + if($allowempty == 'y') { + return ''; + } + return $this->get_error($validator['errmsg']); + } + $parts = explode(',', $field_value); + foreach($parts as $part) { + $part = trim($part); + // an empty part means there is a stray comma + if(empty($part)) { + return $this->get_error($validator['errmsg']); + } + // allow list placeholders that you will replace with real values at evaluation + if(in_array($part, $exceptions, true)) { + continue; + } + // optionally do not allow placeholders to be part of an expression + if($allow_exception_as_substring == 'n') { + foreach($exceptions as $exception) { + if(strpos($part, $exception) !== false) { + return $this->get_error($validator['errmsg']); + } + } + } + // A domain glob needs to: + // * be a valid glob with only a-z0-9._- as characters + // * have at least one dot in it + // * not have two consecutive dots + if(!$this->validate_glob($part, '/^[a-z0-9._-]$/ui') || strpos($part, '.') === false || strpos($part, '..') !== false) { + return $this->get_error($validator['errmsg']); + } + } + return ''; + } } diff --git a/interface/lib/classes/validate_mail_transport.inc.php b/interface/lib/classes/validate_mail_transport.inc.php index 6b47d95303..3396df65cf 100644 --- a/interface/lib/classes/validate_mail_transport.inc.php +++ b/interface/lib/classes/validate_mail_transport.inc.php @@ -41,6 +41,40 @@ function get_error($errmsg) { } } + /* Validator function for checking that the 'domain' is not already set as mail_domain */ + function validate_isnot_maildomain($field_name, $field_value, $validator) { + global $app, $conf; + + if(isset($app->remoting_lib->primary_id)) { + $id = $app->remoting_lib->primary_id; + } else { + $id = $app->tform->primary_id; + } + + $sql = "SELECT domain_id, domain FROM mail_domain WHERE domain = ? AND domain_id != ?"; + $domain_check = $app->db->queryOneRecord($sql, $field_value, $id); + + if($domain_check) return $this->get_error('domain_is_maildomain'); + + } + + /* Validator function for checking that the 'domain' is not already set as mail_transport */ + function validate_isnot_mailtransport($field_name, $field_value, $validator) { + global $app, $conf; + + if(isset($app->remoting_lib->primary_id)) { + $id = $app->remoting_lib->primary_id; + } else { + $id = $app->tform->primary_id; + } + + $sql = "SELECT transport_id, domain FROM mail_transport WHERE domain = ? AND transport_id != ?"; + $domain_check = $app->db->queryOneRecord($sql, $field_value, $id); + + if($domain_check) return $this->get_error('domain_is_transport'); + + } + /* Validator function for checking the 'domain' of a mail transport */ function validate_domain($field_name, $field_value, $validator) { global $app, $conf; @@ -52,8 +86,8 @@ function validate_domain($field_name, $field_value, $validator) { } // mail_transport.domain (could also be an email address) must be unique per server - $sql = "SELECT transport_id, domain FROM mail_transport WHERE domain = ? AND server_id = ? AND transport_id != ?"; - $domain_check = $app->db->queryOneRecord($sql, $field_value, $app->tform_actions->dataRecord['server_id'], $id); + $sql = "SELECT transport_id, domain FROM mail_transport WHERE domain = ? AND transport_id != ?"; + $domain_check = $app->db->queryOneRecord($sql, $field_value, $id); if($domain_check) return $this->get_error('domain_error_unique'); } diff --git a/interface/lib/lang/ar.lng b/interface/lib/lang/ar.lng index 4aa87ee5aa..7f98a2bbcf 100644 --- a/interface/lib/lang/ar.lng +++ b/interface/lib/lang/ar.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Close'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/bg.lng b/interface/lib/lang/bg.lng index 67c2b67b6f..58cac857df 100644 --- a/interface/lib/lang/bg.lng +++ b/interface/lib/lang/bg.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Close'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/br.lng b/interface/lib/lang/br.lng index 02f4697dee..8b4d04cbd0 100644 --- a/interface/lib/lang/br.lng +++ b/interface/lib/lang/br.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Por favor, selecione um servidor válido. O ID d $wb['datalog_changes_close_txt'] = 'Fechar'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/ca.lng b/interface/lib/lang/ca.lng index 0aa69997e5..aba877aa5c 100644 --- a/interface/lib/lang/ca.lng +++ b/interface/lib/lang/ca.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Close'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/cn.lng b/interface/lib/lang/cn.lng new file mode 100644 index 0000000000..fcb5439bad --- /dev/null +++ b/interface/lib/lang/cn.lng @@ -0,0 +1,192 @@ + diff --git a/interface/lib/lang/cz.lng b/interface/lib/lang/cz.lng index 1eccd3c8e5..480e75b197 100644 --- a/interface/lib/lang/cz.lng +++ b/interface/lib/lang/cz.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Close'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/de.lng b/interface/lib/lang/de.lng index d6cef498d3..78ca844ec9 100644 --- a/interface/lib/lang/de.lng +++ b/interface/lib/lang/de.lng @@ -37,7 +37,7 @@ $wb['top_menu_dns'] = 'DNS'; $wb['top_menu_tools'] = 'Einstellungen'; $wb['top_menu_help'] = 'Support'; $wb['top_menu_billing'] = 'Fakturierung'; -$wb['top_menu_mailuser'] = 'E-Mail Benutzer'; +$wb['top_menu_mailuser'] = 'E-Mail-Benutzer'; $wb['top_menu_domain'] = 'Domains'; $wb['top_menu_dashboard'] = 'Übersicht'; $wb['latest_news_txt'] = 'Neuigkeiten'; @@ -86,46 +86,46 @@ $wb['datalog_changes_end_txt'] = 'Die Übernahme der Änderungen kann bis zu 1 M $wb['datalog_status_i_web_database'] = 'Neue Datenbank anlegen'; $wb['datalog_status_u_web_database'] = 'Datenbank ändern'; $wb['datalog_status_d_web_database'] = 'Datenbank löschen'; -$wb['datalog_status_i_web_database_user'] = 'Datenbank Benutzer für Datenbank anlegen'; -$wb['datalog_status_u_web_database_user'] = 'Datenbank Benutzer ändern'; -$wb['datalog_status_d_web_database_user'] = 'Datenbank Benutzer löschen'; +$wb['datalog_status_i_web_database_user'] = 'Datenbank-Benutzer für Datenbank anlegen'; +$wb['datalog_status_u_web_database_user'] = 'Datenbank-Benutzer ändern'; +$wb['datalog_status_d_web_database_user'] = 'Datenbank-Benutzer löschen'; $wb['datalog_status_i_web_domain'] = 'Neue Webseite anlegen'; $wb['datalog_status_u_web_domain'] = 'Webseiten Einstellungen ändern'; $wb['datalog_status_d_web_domain'] = 'Webseite löschen'; -$wb['datalog_status_i_ftp_user'] = 'FTP Benutzer anlegen'; -$wb['datalog_status_u_ftp_user'] = 'FTP Benutzer ändern'; -$wb['datalog_status_d_ftp_user'] = 'FTP Benutzer löschen'; -$wb['datalog_status_i_mail_domain'] = 'Neue E-Mail Domain anlegen'; -$wb['datalog_status_u_mail_domain'] = 'E-Mail Domain ändern'; -$wb['datalog_status_d_mail_domain'] = 'E-Mail Domain löschen'; -$wb['datalog_status_i_mail_user'] = 'Neues E-Mail Konto anlegen'; -$wb['datalog_status_u_mail_user'] = 'E-Mail Konto ändern'; -$wb['datalog_status_d_mail_user'] = 'E-Mail Konto löschen'; -$wb['datalog_status_i_spamfilter_users'] = 'Spamfilter Einstellungen anlegen'; -$wb['datalog_status_u_spamfilter_users'] = 'Spamfilter Einstellungen ändern'; -$wb['datalog_status_d_spamfilter_users'] = 'Spamfilter Einstellungen löschen'; -$wb['datalog_status_i_mail_forwarding'] = 'Neue E-Mail Adresse anlegen'; -$wb['datalog_status_u_mail_forwarding'] = 'E-Mail Adresse ändern'; -$wb['datalog_status_d_mail_forwarding'] = 'E-Mail Adresse löschen'; -$wb['datalog_status_i_dns_rr'] = 'DNS Eintrag anlegen'; -$wb['datalog_status_u_dns_rr'] = 'DNS Eintrag ändern'; -$wb['datalog_status_d_dns_rr'] = 'DNS Eintrag löschen'; -$wb['datalog_status_i_dns_soa'] = 'DNS Zone anlegen'; -$wb['datalog_status_u_dns_soa'] = 'DNS Zone ändern'; -$wb['datalog_status_d_dns_soa'] = 'DNS Zone löschen'; -$wb['datalog_status_i_dns_slave'] = 'Create new secondary DNS zone'; -$wb['datalog_status_u_dns_slave'] = 'Update secondary DNS zone'; -$wb['datalog_status_d_dns_slave'] = 'Delete secondary DNS zone'; -$wb['datalog_status_i_firewall'] = 'Create new firewall rule'; -$wb['datalog_status_u_firewall'] = 'Update firewall rule'; -$wb['datalog_status_d_firewall'] = 'Delete firewall rule'; -$wb['datalog_status_u_server'] = 'Update server settings'; -$wb['datalog_status_d_server'] = 'Delete server'; +$wb['datalog_status_i_ftp_user'] = 'FTP-Benutzer anlegen'; +$wb['datalog_status_u_ftp_user'] = 'FTP-Benutzer ändern'; +$wb['datalog_status_d_ftp_user'] = 'FTP-Benutzer löschen'; +$wb['datalog_status_i_mail_domain'] = 'Neue E-Mail-Domain anlegen'; +$wb['datalog_status_u_mail_domain'] = 'E-Mail-Domain ändern'; +$wb['datalog_status_d_mail_domain'] = 'E-Mail-Domain löschen'; +$wb['datalog_status_i_mail_user'] = 'Neues E-Mail-Konto anlegen'; +$wb['datalog_status_u_mail_user'] = 'E-Mail-Konto ändern'; +$wb['datalog_status_d_mail_user'] = 'E-Mail-Konto löschen'; +$wb['datalog_status_i_spamfilter_users'] = 'Spamfilter-Einstellungen anlegen'; +$wb['datalog_status_u_spamfilter_users'] = 'Spamfilter-Einstellungen ändern'; +$wb['datalog_status_d_spamfilter_users'] = 'Spamfilter-Einstellungen löschen'; +$wb['datalog_status_i_mail_forwarding'] = 'Neue E-Mail-Adresse anlegen'; +$wb['datalog_status_u_mail_forwarding'] = 'E-Mail-Adresse ändern'; +$wb['datalog_status_d_mail_forwarding'] = 'E-Mail-Adresse löschen'; +$wb['datalog_status_i_dns_rr'] = 'DNS-Eintrag anlegen'; +$wb['datalog_status_u_dns_rr'] = 'DNS-Eintrag ändern'; +$wb['datalog_status_d_dns_rr'] = 'DNS-Eintrag löschen'; +$wb['datalog_status_i_dns_soa'] = 'Neue Primäre-DNS-Zone anlegen'; +$wb['datalog_status_u_dns_soa'] = 'Primäre-DNS-Zone aktualisieren'; +$wb['datalog_status_d_dns_soa'] = 'Primäre-DNS-Zone löschen'; +$wb['datalog_status_i_dns_slave'] = 'Neue Sekundäre-DNS-Zone anlegen'; +$wb['datalog_status_u_dns_slave'] = 'Sekundäre-DNS-Zone aktualisieren'; +$wb['datalog_status_d_dns_slave'] = 'Sekundäre-DNS-Zone löschen'; +$wb['datalog_status_i_firewall'] = 'Neue Firewall-Regel erstellen'; +$wb['datalog_status_u_firewall'] = 'Firewall-Regel ändern'; +$wb['datalog_status_d_firewall'] = 'Firewall-Regel löschen'; +$wb['datalog_status_u_server'] = 'Server-Einstellungen ändern'; +$wb['datalog_status_d_server'] = 'Server löschen'; $wb['datalog_status_i_cron'] = 'Cronjob anlegen'; $wb['datalog_status_u_cron'] = 'Cronjob ändern'; -$wb['datalog_status_i_server_ip'] = 'Add server IP'; -$wb['datalog_status_u_server_ip'] = 'Update server IP'; -$wb['datalog_status_d_server_ip'] = 'Delete server IP'; +$wb['datalog_status_i_server_ip'] = 'Server-IP anlegen'; +$wb['datalog_status_u_server_ip'] = 'Server-IP ändern'; +$wb['datalog_status_d_server_ip'] = 'Server-IP löschen'; $wb['datalog_status_d_cron'] = 'Cronjob löschen'; $wb['datalog_status_i_mail_get'] = 'E-Mailabruf anlegen'; $wb['datalog_status_u_mail_get'] = 'E-Mailabruf ändern'; @@ -133,21 +133,21 @@ $wb['datalog_status_d_mail_get'] = 'E-Mailabruf löschen'; $wb['datalog_status_i_mail_mailinglist'] = 'Mailingliste anlegen'; $wb['datalog_status_u_mail_mailinglist'] = 'Mailingliste ändern'; $wb['datalog_status_d_mail_mailinglist'] = 'Mailingliste löschen'; -$wb['datalog_status_i_shell_user'] = 'Shell Benutzer anlegen'; -$wb['datalog_status_u_shell_user'] = 'Shell Benutzer ändern'; -$wb['datalog_status_d_shell_user'] = 'Shell Benutzer löschen'; +$wb['datalog_status_i_shell_user'] = 'SSH/SFTP-Benutzer anlegen'; +$wb['datalog_status_u_shell_user'] = 'SSH/SFTP-Benutzer ändern'; +$wb['datalog_status_d_shell_user'] = 'SSH/SFTP-Benutzer löschen'; $wb['datalog_status_i_web_folder'] = 'Verzeichnisschutz anlegen'; $wb['datalog_status_u_web_folder'] = 'Verzeichnisschutz ändern'; $wb['datalog_status_d_web_folder'] = 'Verzeichnisschutz löschen'; -$wb['datalog_status_i_web_folder_user'] = 'Verzeichnisschutz Benutzer anlegen'; -$wb['datalog_status_u_web_folder_user'] = 'Verzeichnisschutz Benutzer ändern'; -$wb['datalog_status_d_web_folder_user'] = 'Verzeichnisschutz Benutzer löschen'; -$wb['datalog_status_i_xmpp_domain'] = 'XMPP Domain erstellen'; -$wb['datalog_status_u_xmpp_domain'] = 'XMPP Domain ändern'; -$wb['datalog_status_d_xmpp_domain'] = 'XMPP Domain löschen'; -$wb['datalog_status_i_xmpp_user'] = 'XMPP Benutzer erstellen'; -$wb['datalog_status_u_xmpp_user'] = 'XMPP Benutzer ändern'; -$wb['datalog_status_d_xmpp_user'] = 'XMPP Benutzer löschen'; +$wb['datalog_status_i_web_folder_user'] = 'Verzeichnisschutz-Benutzer anlegen'; +$wb['datalog_status_u_web_folder_user'] = 'Verzeichnisschutz-Benutzer ändern'; +$wb['datalog_status_d_web_folder_user'] = 'Verzeichnisschutz-Benutzer löschen'; +$wb['datalog_status_i_xmpp_domain'] = 'XMPP-Domain erstellen'; +$wb['datalog_status_u_xmpp_domain'] = 'XMPP-Domain ändern'; +$wb['datalog_status_d_xmpp_domain'] = 'XMPP-Domain löschen'; +$wb['datalog_status_i_xmpp_user'] = 'XMPP-Benutzer erstellen'; +$wb['datalog_status_u_xmpp_user'] = 'XMPP-Benutzer ändern'; +$wb['datalog_status_d_xmpp_user'] = 'XMPP-Benutzer löschen'; $wb['login_as_txt'] = 'Anmelden als'; $wb['no_domain_perm'] = 'Sie haben keine Berechtigung für diese Domain.'; $wb['no_destination_perm'] = 'Sie haben keine Berechtigung für dieses Ziel.'; @@ -167,11 +167,25 @@ $wb['weak_password_txt'] = 'Das gewählte Passwort erfüllt die Sicherheitsanfor $wb['weak_password_length_txt'] = 'Das gewählte Passwort erfüllt die Sicherheitsanforderungen nicht. Es muss mindestens {chars} Zeichen lang sein.'; $wb['security_check1_txt'] = 'Sicherheitsüberprüfung für:'; $wb['security_check2_txt'] = 'fehlgeschlagen.'; -$wb['select_directive_snippet_txt'] = 'Direktiven Schnipsel'; -$wb['select_master_directive_snippet_txt'] = 'Master Direktiven Schnipsel'; +$wb['select_directive_snippet_txt'] = 'Direktiven-Schnipsel'; +$wb['select_master_directive_snippet_txt'] = 'Master-Direktiven-Schnipsel'; $wb['unlimited_txt'] = 'unlimitiert'; -$wb['server_id_0_error_txt'] = 'Bitte Server auswählen. Server ID muss > als 0 sein.'; -$wb['datalog_changes_close_txt'] = 'Close'; -$wb['non_admin_error'] = 'Requires administrator level permissions'; -$wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['server_id_0_error_txt'] = 'Bitte Server auswählen. Server-ID muss > als 0 sein.'; +$wb['datalog_changes_close_txt'] = 'Schließen'; +$wb['non_admin_error'] = 'Erfordert Administratorrechte'; +$wb['copy_to_clipboard_txt'] = 'In die Zwischenablage kopieren'; +$wb['datalog_status_i_client'] = 'Neuen Kunden erstellen'; +$wb['datalog_status_u_client'] = 'Kunden aktualisieren'; +$wb['datalog_status_d_client'] = 'Kunden löschen'; +$wb['datalog_status_i_domain'] = 'Neue Domain erstellen'; +$wb['datalog_status_u_domain'] = 'Domain aktualisieren'; +$wb['datalog_status_d_domain'] = 'Domain löschen'; +$wb['datalog_status_d_web_backup'] = 'Website-Backup löschen'; +$wb['datalog_status_i_dns_template'] = 'Neue DNS-Vorlage erstellen'; +$wb['datalog_status_u_dns_template'] = 'DNS-Vorlage aktualisieren'; +$wb['datalog_status_d_dns_template'] = 'DNS-Vorlage löschen'; +$wb['datalog_status_i_sys_group'] = 'Neue Gruppe für Kunde erstellen'; +$wb['datalog_status_u_sys_ini'] = 'Aktualisiere Hauptkonfiguration'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/dk.lng b/interface/lib/lang/dk.lng index 85cee58659..92e5e9d120 100644 --- a/interface/lib/lang/dk.lng +++ b/interface/lib/lang/dk.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Close'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/el.lng b/interface/lib/lang/el.lng index d5b980722a..a35e371384 100644 --- a/interface/lib/lang/el.lng +++ b/interface/lib/lang/el.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Close'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/en.lng b/interface/lib/lang/en.lng index 6024cc69a7..113aad9577 100644 --- a/interface/lib/lang/en.lng +++ b/interface/lib/lang/en.lng @@ -83,6 +83,12 @@ $wb['global_tabchange_discard_txt'] = 'You have unsaved changes in this tab. Cha $wb['datalog_changes_txt'] = 'The following changes are not yet populated to all servers:'; $wb['datalog_changes_end_txt'] = 'Storing updates can take up to one minute. Please be patient.'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; $wb['datalog_status_i_web_database'] = 'Create new database'; $wb['datalog_status_u_web_database'] = 'Update database'; $wb['datalog_status_d_web_database'] = 'Delete database'; @@ -175,4 +181,12 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Close'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/es.lng b/interface/lib/lang/es.lng index e3ba1d41e0..363fb995b6 100644 --- a/interface/lib/lang/es.lng +++ b/interface/lib/lang/es.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Cerrar'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/fi.lng b/interface/lib/lang/fi.lng index 87f2dc24ed..7c133ce794 100644 --- a/interface/lib/lang/fi.lng +++ b/interface/lib/lang/fi.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Close'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/fr.lng b/interface/lib/lang/fr.lng index 7f8413d11c..bac465fae9 100644 --- a/interface/lib/lang/fr.lng +++ b/interface/lib/lang/fr.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Close'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/hr.lng b/interface/lib/lang/hr.lng index 167073f837..0ff37913be 100644 --- a/interface/lib/lang/hr.lng +++ b/interface/lib/lang/hr.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Close'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/hu.lng b/interface/lib/lang/hu.lng index a07c6810ce..1f9c4d7979 100644 --- a/interface/lib/lang/hu.lng +++ b/interface/lib/lang/hu.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Close'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/id.lng b/interface/lib/lang/id.lng index 51e1fd6aef..99d2c0a029 100644 --- a/interface/lib/lang/id.lng +++ b/interface/lib/lang/id.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Close'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/it.lng b/interface/lib/lang/it.lng index a56224e6d5..1b4f8beee6 100644 --- a/interface/lib/lang/it.lng +++ b/interface/lib/lang/it.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Chiudi'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/ja.lng b/interface/lib/lang/ja.lng index 00db303170..cb9465208b 100644 --- a/interface/lib/lang/ja.lng +++ b/interface/lib/lang/ja.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Close'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/nl.lng b/interface/lib/lang/nl.lng index 582c5ffe53..d58654e7f9 100644 --- a/interface/lib/lang/nl.lng +++ b/interface/lib/lang/nl.lng @@ -163,15 +163,29 @@ $wb['security_check2_txt'] = 'failed.'; $wb['err_csrf_attempt_blocked'] = 'CSRF attempt blocked.'; $wb['select_directive_snippet_txt'] = 'Directive Snippets'; $wb['select_master_directive_snippet_txt'] = 'Master Directive Snippets'; -$wb['datalog_status_i_xmpp_domain'] = 'Create XMPP domain'; -$wb['datalog_status_u_xmpp_domain'] = 'Update XMPP domain'; -$wb['datalog_status_d_xmpp_domain'] = 'Delete XMPP domain'; -$wb['datalog_status_i_xmpp_user'] = 'Create XMPP user'; -$wb['datalog_status_u_xmpp_user'] = 'Update XMPP user'; -$wb['datalog_status_d_xmpp_user'] = 'Delete XMPP user'; +$wb['datalog_status_i_xmpp_domain'] = 'Aanmaken XMPP domain'; +$wb['datalog_status_u_xmpp_domain'] = 'Bijwerken XMPP domain'; +$wb['datalog_status_d_xmpp_domain'] = 'Verwijderen XMPP domain'; +$wb['datalog_status_i_xmpp_user'] = 'Aanmaken XMPP user'; +$wb['datalog_status_u_xmpp_user'] = 'Bijwerken XMPP user'; +$wb['datalog_status_d_xmpp_user'] = 'Verwijderen XMPP user'; +$wb['datalog_status_i_client'] = 'Aanmaken client'; +$wb['datalog_status_u_client'] = 'Bijwerken client'; +$wb['datalog_status_d_client'] = 'Verwijderen client'; +$wb['datalog_status_i_domain'] = 'Aanmaken domain'; +$wb['datalog_status_u_domain'] = 'Bijwerken domain'; +$wb['datalog_status_d_domain'] = 'Verwijderen domain'; $wb['unlimited_txt'] = 'Ongelimiteerd'; $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.'; $wb['datalog_changes_close_txt'] = 'Sluiten'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Kopieer naar klembord'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Laatst gebruikt'; +$wb['never_accessed_txt'] = 'Niet of onbekend'; ?> diff --git a/interface/lib/lang/pl.lng b/interface/lib/lang/pl.lng index d22b0d4850..e88b071ae9 100644 --- a/interface/lib/lang/pl.lng +++ b/interface/lib/lang/pl.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Close'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/pt.lng b/interface/lib/lang/pt.lng index 23b1cd2079..e175778603 100644 --- a/interface/lib/lang/pt.lng +++ b/interface/lib/lang/pt.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Close'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/ro.lng b/interface/lib/lang/ro.lng index b4da89bc12..afebb4d5f2 100644 --- a/interface/lib/lang/ro.lng +++ b/interface/lib/lang/ro.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Close'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/ru.lng b/interface/lib/lang/ru.lng index cfd805010b..6561aa7f95 100644 --- a/interface/lib/lang/ru.lng +++ b/interface/lib/lang/ru.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Close'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/se.lng b/interface/lib/lang/se.lng index 03d818ec56..2ef5b039de 100644 --- a/interface/lib/lang/se.lng +++ b/interface/lib/lang/se.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Close'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/sk.lng b/interface/lib/lang/sk.lng index dfad74552b..fa05605097 100644 --- a/interface/lib/lang/sk.lng +++ b/interface/lib/lang/sk.lng @@ -174,4 +174,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Close'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/lang/tr.lng b/interface/lib/lang/tr.lng index 5b7afc3afa..e997e36679 100644 --- a/interface/lib/lang/tr.lng +++ b/interface/lib/lang/tr.lng @@ -175,4 +175,18 @@ $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be $wb['datalog_changes_close_txt'] = 'Close'; $wb['non_admin_error'] = 'Requires administrator level permissions'; $wb['copy_to_clipboard_txt'] = 'Copy to clipboard'; +$wb['datalog_status_i_client'] = 'Create new client'; +$wb['datalog_status_u_client'] = 'Update client'; +$wb['datalog_status_d_client'] = 'Delete client'; +$wb['datalog_status_i_domain'] = 'Create new domain'; +$wb['datalog_status_u_domain'] = 'Update domain'; +$wb['datalog_status_d_domain'] = 'Delete domain'; +$wb['datalog_status_d_web_backup'] = 'Delete website backup'; +$wb['datalog_status_i_dns_template'] = 'Create DNS template'; +$wb['datalog_status_u_dns_template'] = 'Update DNS template'; +$wb['datalog_status_d_dns_template'] = 'Delete DNS template'; +$wb['datalog_status_i_sys_group'] = 'Create new client group'; +$wb['datalog_status_u_sys_ini'] = 'Update main config'; +$wb['last_accessed_txt'] = 'Last accessed'; +$wb['never_accessed_txt'] = 'Never or unknown'; ?> diff --git a/interface/lib/plugins/mail_mail_domain_plugin.inc.php b/interface/lib/plugins/mail_mail_domain_plugin.inc.php index 4ff756f44f..485307fc55 100644 --- a/interface/lib/plugins/mail_mail_domain_plugin.inc.php +++ b/interface/lib/plugins/mail_mail_domain_plugin.inc.php @@ -60,7 +60,7 @@ function mail_mail_domain_edit($event_name, $page_form) { } //** If the domain name or owner has been changed, change the domain and owner in all mailbox records - if($page_form->oldDataRecord && ($page_form->oldDataRecord['domain'] != $domain || + if($page_form->oldDataRecord && !empty($page_form->oldDataRecord['domain']) && ($page_form->oldDataRecord['domain'] != $domain || (isset($page_form->dataRecord['client_group_id']) && $page_form->oldDataRecord['sys_groupid'] != $page_form->dataRecord['client_group_id']))) { $app->uses('getconf'); $mail_config = $app->getconf->get_server_config($page_form->dataRecord["server_id"], 'mail'); @@ -255,7 +255,7 @@ function mail_mail_domain_edit($event_name, $page_form) { // If domain changes, update spamfilter_users // and fire spamfilter_wblist_update events so rspamd files are rewritten if ($old_domain != $domain) { - $tmp_users = $app->db->queryOneRecord("SELECT id,fullname FROM spamfilter_users WHERE email LIKE ?", '%@' . $old_domain); + $tmp_users = $app->db->queryAllRecords("SELECT id,fullname FROM spamfilter_users WHERE email LIKE ?", '%@' . $old_domain); if(is_array($tmp_users)) { foreach ($tmp_users as $tmp_old) { $tmp_new = $app->db->queryOneRecord("SELECT id,fullname FROM spamfilter_users WHERE email = ?", '@' . $domain); 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 ba28ca0641..0cfd871560 100644 --- a/interface/lib/plugins/system_config_dns_ca_plugin.inc.php +++ b/interface/lib/plugins/system_config_dns_ca_plugin.inc.php @@ -79,7 +79,7 @@ function web_vhost_domain_edit($event_name, $page_form) { if(is_array($caa) && is_array($soa)) { $records = array(); $records[] = $domain.'.';; - if($subdomain != '' && $subdomain != 'www') $records[] = $subdomain.'.'.$domain; + if($subdomain != '' && $subdomain != 'www' && $subdomain != 'none') $records[] = $subdomain.'.'.$domain; foreach($records as $record) { $new_rr = $app->db->queryOneRecord("SELECT * FROM dns_rr WHERE name = ?", $soa['origin']); unset($new_rr['id']); diff --git a/interface/web/admin/directive_snippets_del.php b/interface/web/admin/directive_snippets_del.php index 91dae44155..766a7fdcb1 100644 --- a/interface/web/admin/directive_snippets_del.php +++ b/interface/web/admin/directive_snippets_del.php @@ -44,6 +44,7 @@ //* Check permissions for module $app->auth->check_module_permissions('admin'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); $app->load("tform_actions"); diff --git a/interface/web/admin/directive_snippets_edit.php b/interface/web/admin/directive_snippets_edit.php index 14a2807f49..80b93b355c 100644 --- a/interface/web/admin/directive_snippets_edit.php +++ b/interface/web/admin/directive_snippets_edit.php @@ -43,6 +43,7 @@ //* Check permissions for module $app->auth->check_module_permissions('admin'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); // Loading classes $app->uses('tpl,tform,tform_actions'); diff --git a/interface/web/admin/directive_snippets_list.php b/interface/web/admin/directive_snippets_list.php index 97cdc449a7..a95ea4f367 100644 --- a/interface/web/admin/directive_snippets_list.php +++ b/interface/web/admin/directive_snippets_list.php @@ -43,6 +43,7 @@ //* Check permissions for module $app->auth->check_module_permissions('admin'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); $app->uses('listform_actions'); diff --git a/interface/web/admin/extension_edit.php b/interface/web/admin/extension_edit.php new file mode 100644 index 0000000000..54054e652d --- /dev/null +++ b/interface/web/admin/extension_edit.php @@ -0,0 +1,293 @@ +auth->check_module_permissions('admin'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); + +//* load language file +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_extension_install_list.lng'; +include $lng_file; + +//* This is only allowed for administrators +if(!$app->auth->is_admin()) die('Only allowed for administrators.'); + +$action = $_REQUEST['action']; +$name = $_REQUEST['name']; +$server_id = (isset($_REQUEST['server_id']) ? intval($_REQUEST['server_id']) : 0); + +// check name with regex +if(!preg_match('/^[a-z0-9_]+$/', $name)) show_message('invalid_extension_name_txt', 'admin/extension_repo_list.php'); + +// check action +if(!in_array($action, array('edit', 'install', 'delete', 'enable', 'disable', 'update'))) { + show_message('unknown_action_txt', 'admin/extension_repo_list.php'); +} + +$app->uses('extension_installer'); + +// handle form post +if(count($_POST) > 0) { + if($action == 'install') { + + // check if server exists + $sql = 'SELECT * FROM `server` WHERE `server_id` = ?'; + $record = $app->db->queryOneRecord($sql, $server_id); + if($record === null) { + show_message('server_not_found_txt', 'admin/extension_repo_list.php'); + } + + // check if extension is already installed + $extension = $app->extension_installer->getInstalledExtension($name, $server_id); + if(!empty($extension)) { + show_message('extension_already_installed', 'admin/extension_repo_list.php'); + } + + // install extension + if($app->extension_installer->installExtension($name, $server_id) === false ||$app->extension_installer->hasErrors()) { + $next_link = 'admin/extension_repo_list.php'; + show_message('install_failed', $next_link, true); + } else { + $next_link = 'admin/extension_install_list.php'; + $repo_extension = $app->extension_installer->getRepoExtension($name); + show_message('install_success', $next_link,false,$repo_extension['postinstall_info']); + } + + } + if($action == 'edit') { + // check if server exists + $sql = 'SELECT * FROM `server` WHERE `server_id` = ?'; + $record = $app->db->queryOneRecord($sql, $server_id); + if($record === null) { + show_message('server_not_found_txt', 'admin/extension_repo_list.php'); + } + + // check if extension is already installed + $extension = $app->extension_installer->getInstalledExtension($name, $server_id); + if(empty($extension)) { + show_message('extension_not_installed', 'admin/extension_repo_list.php'); + } + + $success = true; + + // if active state has changed + if(isset($_POST['active'])) { + if($extension['active'] != 1) { + if($app->extension_installer->enableExtension($name, $server_id) === false) { + $success = false; + } + } + } else { + if($extension['active'] == 1) { + if($app->extension_installer->disableExtension($name, $server_id) === false) { + $success = false; + } + } + } + + + // if license has changed + if($extension['license'] != $_POST['license']) { + // check license with regex + if(!empty($_POST['license']) && !preg_match('/^[a-zA-Z0-9\-]+$/', $_POST['license'])) { + show_message('invalid_license_txt', 'admin/extension_repo_list.php'); + $success = false; + } + if($app->extension_installer->updateLicense($name, $server_id, $_POST['license']) === false) { + $success = false; + } + } + + if($success) { + show_message('update_success', 'admin/extension_repo_list.php', false); + } else { + show_message('update_failed', 'admin/extension_repo_list.php', true); + } + + // update extension + /* + if($app->extension_installer->updateExtension($name, $server_id) === false) { + $next_link = 'admin/extension_install_list.php'; + show_message('update_failed', $next_link, true); + } else { + $next_link = 'admin/extension_install_list.php'; + show_message('update_success', $next_link, false); + } + */ + } +} + +$app->tpl->newTemplate('form.tpl.htm'); +$app->tpl->setVar('name', $name); + +switch($action) { + case 'edit': + $app->tpl->setInclude('content_tpl', 'templates/extension_edit.htm'); + $repo_extension = $app->extension_installer->getRepoExtension($name); + if($repo_extension === null) { + show_message('extension_not_found_txt', 'admin/extension_repo_list.php'); + } + $repo_extension['repo_license'] = $repo_extension['license']; + unset($repo_extension['license']); + $repo_extension['repo_version'] = $repo_extension['version']; + unset($repo_extension['version']); + $app->tpl->setVar($repo_extension); + $extension = $app->extension_installer->getInstalledExtension($name, $server_id); + if(empty($extension)) { + show_message('extension_not_installed', 'admin/extension_repo_list.php'); + } + $app->tpl->setVar($extension); + // get server name + $server_name = $app->extension_installer->getServerName($server_id); + $app->tpl->setVar('server_name', $server_name); + // show update button if versions differ + if($extension['version'] !== $repo_extension['repo_version']) { + $app->tpl->setVar('show_update', true); + } else { + $app->tpl->setVar('show_update', false); + } + // show postinstall_info + if(!empty($extension['postinstall_info'])) { + $app->tpl->setVar('postinstall_info', $extension['postinstall_info']); + } + // show free limits + if(!empty($extension['free_limits'])) { + $app->tpl->setVar('free_limits', $extension['free_limits']); + } + break; + case 'install': + $app->tpl->setInclude('content_tpl', 'templates/extension_install.htm'); + $repo_extension = $app->extension_installer->getRepoExtension($name); + if($repo_extension === null) { + show_message('extension_not_found_txt', 'admin/extension_repo_list.php'); + } + $app->tpl->setVar($repo_extension); + // get servers + $servers = $app->db->queryAllRecords('SELECT * FROM `server` WHERE `active` = 1'); + if(!empty($servers)) { + $server_list = ''; + foreach($servers as $server) { + $server_list .= ''; + } + $app->tpl->setVar('server_id', $server_list); + } + break; + case 'delete': + if($app->extension_installer->deleteExtension($name, $server_id) === false) { + show_message('delete_failed', 'admin/extension_install_list.php', true); + } else { + show_message('delete_success', 'admin/extension_install_list.php', false); + } + break; + case 'enable': + if($app->extension_installer->enableExtension($name, $server_id) === false) { + show_message('enable_failed', 'admin/extension_install_list.php', true); + } else { + show_message('enable_success', 'admin/extension_install_list.php', false); + } + break; + case 'disable': + if($app->extension_installer->disableExtension($name, $server_id) === false) { + show_message('disable_failed', 'admin/extension_install_list.php', true); + } else { + show_message('disable_success', 'admin/extension_install_list.php', false); + } + break; + case 'update': + if($app->extension_installer->updateExtension($name, $server_id) === false) { + show_message('update_failed', 'admin/extension_install_list.php', true); + } else { + show_message('update_success', 'admin/extension_install_list.php', false); + } + break; + default: + show_message('unknown_action_txt', 'admin/extension_repo_list.php'); + break; +} + +// set language file variables +$app->tpl->setVar($wb); + +$app->tpl_defaults(); +$app->tpl->pparse(); + +// ---------------------------------------------------------------------------------------- +function show_message($message, $next_link, $show_errors = false, $info_text = '') { + global $app; + + $app->tpl->newTemplate('form.tpl.htm'); + $app->tpl->setInclude('content_tpl', 'templates/extension_msg.htm'); + + //* load language file + $lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_extension_install_list.lng'; + include $lng_file; + $app->tpl->setVar($wb); + + $message_txt = $wb[$message]; + if($show_errors && $app->extension_installer->hasErrors()) { + $message_txt .= '
' . implode('
', $app->extension_installer->getErrors()); + } + + $app->tpl->setVar('message_txt', $message_txt); + $app->tpl->setVar('next_link', $next_link); + $app->tpl->setVar('info_text', $info_text); + + $app->tpl_defaults(); + $app->tpl->pparse(); + + die(); +} + +// ---------------------------------------------------------------------------------------- + +function show_form($template, $vars = array(), $error_message = '') { + global $app; + + $app->tpl->newTemplate('form.tpl.htm'); + $app->tpl->setInclude('content_tpl', 'templates/'.$template); + + //* load language file + $lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_wp_action.lng'; + include $lng_file; + $app->tpl->setVar($wb); + + $app->tpl->setVar('error', $wb[$error_message]); + + $app->tpl->setVar($vars); + $app->tpl_defaults(); + $app->tpl->pparse(); + + die(); +} + +// ---------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/interface/web/admin/extension_install_list.php b/interface/web/admin/extension_install_list.php new file mode 100644 index 0000000000..b3f7e1398e --- /dev/null +++ b/interface/web/admin/extension_install_list.php @@ -0,0 +1,72 @@ +auth->check_module_permissions('admin'); + +//* This is only allowed for administrators +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); + +$app->uses('tpl,extension_installer'); + +$app->tpl->newTemplate('form.tpl.htm'); +$app->tpl->setInclude('content_tpl', 'templates/extension_install_list.htm'); + +// get extensions from monitor_data table +$records = $app->extension_installer->getInstalledExtensions(); +$records_out = []; +if(!empty($records)) { + foreach($records as $record) { + $record['active'] = $record['active'] == true ? 'Yes' : 'No'; + // resolve server name + $record['server_name'] = $app->extension_installer->getServerName($record['server_id']); + $records_out[] = $record; + } +} +unset($records); + +$app->tpl->setLoop('records', $records_out); +$app->tpl->setVar('has_records', !empty($records_out)); + +//* load language file +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_extension_install_list.lng'; +include $lng_file; +$app->tpl->setVar($wb); + +// Check if there are any pending installs in sys_remoteaction +$pending_installs = $app->extension_installer->getPendingInstalls(); + +$app->tpl->setVar('has_pending_installs', !empty($pending_installs)); + +$app->tpl_defaults(); +$app->tpl->pparse(); \ No newline at end of file diff --git a/server/lib/classes/cron.d/600-purge_mailboxes.inc.php b/interface/web/admin/extension_repo_list.php similarity index 58% rename from server/lib/classes/cron.d/600-purge_mailboxes.inc.php rename to interface/web/admin/extension_repo_list.php index 451eb56642..6086c4b3d1 100644 --- a/server/lib/classes/cron.d/600-purge_mailboxes.inc.php +++ b/interface/web/admin/extension_repo_list.php @@ -1,7 +1,7 @@ auth->check_module_permissions('admin'); - /* this function is optional if it contains no custom code */ - public function onPrepare() { - global $app; +//* This is only allowed for administrators +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); - parent::onPrepare(); - } +$app->uses('tpl,extension_installer'); - /* this function is optional if it contains no custom code */ - public function onBeforeRun() { - global $app; +$app->tpl->newTemplate('form.tpl.htm'); +$app->tpl->setInclude('content_tpl', 'templates/extension_repo_list.htm'); - return parent::onBeforeRun(); - } - - public function onRunJob() { - global $app, $conf; - - $sql = "SELECT email FROM mail_user WHERE maildir_format = 'mdbox' AND server_id = ?"; - $records = $app->db->queryAllRecords($sql, $server_id); - - if(is_array($records)) { - foreach($records as $rec){ - $app->system->exec_safe("su -c ?", 'doveadm purge -u "' . $rec["email"] . '"'); - } - } - - parent::onRunJob(); - } - - /* this function is optional if it contains no custom code */ - public function onAfterRun() { - global $app; - - parent::onAfterRun(); - } +// Get available extensions from repo API server in json format +$extensions = $app->extension_installer->getRepoExtensions(); +if(empty($extensions)) { + $extensions = []; } +$app->tpl->setLoop('records', $extensions); +$app->tpl->setVar('show_extensions', !empty($extensions)); + +//* load language file +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_extension_install_list.lng'; +include $lng_file; +$app->tpl->setVar($wb); -?> +$app->tpl_defaults(); +$app->tpl->pparse(); diff --git a/interface/web/admin/firewall_del.php b/interface/web/admin/firewall_del.php index 3fc23fe708..edc3247672 100644 --- a/interface/web/admin/firewall_del.php +++ b/interface/web/admin/firewall_del.php @@ -46,6 +46,8 @@ $app->auth->check_module_permissions('admin'); $app->auth->check_security_permissions('admin_allow_firewall_config'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); + $app->uses("tform_actions"); $app->tform_actions->onDelete(); diff --git a/interface/web/admin/firewall_edit.php b/interface/web/admin/firewall_edit.php index 01cad2b815..cef875dd72 100644 --- a/interface/web/admin/firewall_edit.php +++ b/interface/web/admin/firewall_edit.php @@ -45,6 +45,8 @@ $app->auth->check_module_permissions('admin'); $app->auth->check_security_permissions('admin_allow_firewall_config'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); + // Loading classes $app->uses('tpl,tform,tform_actions'); $app->load('tform_actions'); diff --git a/interface/web/admin/firewall_list.php b/interface/web/admin/firewall_list.php index 3d390504e2..557093fd61 100644 --- a/interface/web/admin/firewall_list.php +++ b/interface/web/admin/firewall_list.php @@ -43,6 +43,7 @@ //* Check permissions for module $app->auth->check_module_permissions('admin'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); $app->uses('listform_actions'); diff --git a/interface/web/admin/form/server.tform.php b/interface/web/admin/form/server.tform.php index f205758a8d..6961385631 100644 --- a/interface/web/admin/form/server.tform.php +++ b/interface/web/admin/form/server.tform.php @@ -67,10 +67,15 @@ 1 => array( 'event' => 'SAVE', 'type' => 'STRIPNL') ), + 'validators' => array( + 0 => array( 'type' => 'REGEX', + 'regex' => '/^[a-zA-Z0-9\s\-\._()]+$/', + 'errmsg' => 'server_name_error_regex') + ), 'default' => '', 'value' => '', 'width' => '30', - 'maxlength' => '255' + 'maxlength' => '60' ), 'mail_server' => array ( 'datatype' => 'INTEGER', diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php index 679ebb2b7f..b6f21239d2 100644 --- a/interface/web/admin/form/server_config.tform.php +++ b/interface/web/admin/form/server_config.tform.php @@ -321,6 +321,20 @@ 'default' => 'y', 'value' => array(0 => 'n', 1 => 'y') ), + 'sysbackup_copies' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => '3', + 'validators' => array( 0 => array('type' => 'NOTEMPTY', + 'errmsg' => 'sysbackup_copies_error_empty'), + 1 => array ( 'type' => 'REGEX', + 'regex' => "/^[0-9]{1,3}$/", + 'errmsg'=> 'sysbackup_copies_error_regex'), + ), + 'value' => '', + 'width' => '40', + 'maxlength' => '255' + ), 'monit_url' => array( 'datatype' => 'VARCHAR', 'formtype' => 'TEXT', @@ -560,15 +574,6 @@ 'default' => '2048', 'value' => array('1024' => 'weak (1024)', '2048' => 'normal (2048)', '4096' => 'strong (4096)') ), - 'relayhost_password' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'default' => '', - 'value' => '', - 'width' => '40', - 'maxlength' => '255' - ), - 'pop3_imap_daemon' => array( 'datatype' => 'VARCHAR', 'formtype' => 'SELECT', @@ -736,9 +741,17 @@ ), 'mailbox_soft_delete' => array ( 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', + 'formtype' => 'SELECT', 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') + 'value' => array( + 0 => 'soft_delete_directly_txt', + -1 => 'soft_delete_keep_indefinitely_txt', + 1 => 'soft_delete_keep_1_txt', + 7 => 'soft_delete_keep_7_txt', + 30 => 'soft_delete_keep_30_txt', + 90 => 'soft_delete_keep_90_txt', + 365 => 'soft_delete_keep_365_txt', + ) ), 'mailbox_quota_stats' => array ( 'datatype' => 'VARCHAR', @@ -926,10 +939,24 @@ ), 'vhost_proxy_protocol_enabled' => array ( 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', + 'formtype' => 'SELECT', 'default' => 'n', - 'value' => array(0 => 'n',1 => 'y') + 'value' => array( + 'n' => 'Disabled', + 'y' => 'Enabled (per site)', + 'all' => 'Enabled (all sites)' + ) ), + 'vhost_proxy_protocol_protocols' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'value' => array( + 'ipv4' => 'IPv4', + 'ipv6' => 'IPv6', + 'ipv4,ipv6' => 'IPv4 + IPv6' + ), + 'default' => 'ipv4' + ), 'vhost_proxy_protocol_http_port' => array( 'datatype' => 'VARCHAR', 'formtype' => 'TEXT', @@ -1052,6 +1079,16 @@ 'default' => 'n', 'value' => array(0 => 'n', 1 => 'y') ), + 'web_folder_permission' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'default' => '0710', + 'maxlength' => '4', + 'value' => array('0710' => '0710', '0711' => '0711', '0750' => '0750', '0751' => '0751'), + 'validators' => array( 0 => array ('type' => 'REGEX', + 'regex' => '/^0[0-7]{3}$/', + 'errmsg'=> 'incorrect_permissions_regex')), + ), 'web_folder_protection' => array( 'datatype' => 'VARCHAR', 'formtype' => 'CHECKBOX', @@ -1596,6 +1633,49 @@ 'width' => '40', 'maxlength' => '255' ), + 'le_signature_type' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'default' => 'ECDSA', + 'value' => array('RSA' => 'RSA (RSA encryption with SHA-256)', 'ECDSA' => 'ECDSA (Elliptic Curve Digital Signature Algorithm)') + ), + 'le_delete_on_site_remove' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'y', + 'value' => array(0 => 'n', 1 => 'y') + ), + 'le_auto_cleanup' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'y', + 'value' => array(0 => 'n', 1 => 'y') + ), + 'le_auto_cleanup_denylist' => array( + 'validators' => array( + array ( + 'type' => 'CUSTOM', + 'class' => 'validate_domain', + 'function' => 'domain_glob_list', + 'allowempty' => 'y', + 'exceptions' => array('[server_name]'), + 'allow_exception_as_substring' => 'n', + 'errmsg'=> 'le_auto_cleanup_denylist_error_custom' + ), + ), + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => '[server_name]', + 'value' => '', + 'width' => '40', + 'maxlength' => '255' + ), + 'le_revoke_before_delete' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'y', + 'value' => array(0 => 'n', 1 => 'y') + ), //################################# // END Datatable fields //################################# @@ -1666,6 +1746,30 @@ 'width' => '40', 'maxlength' => '255' ), + 'bind_zonefiles_masterprefix' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => '', + 'validators' => array( 0 => array ( 'type' => 'REGEX', + 'regex' => '/^[a-zA-Z0-9\.\-\_\/]{0,128}$/', + 'errmsg'=> 'bind_zonefiles_masterprefix_error_regex'), + ), + 'value' => '', + 'width' => '40', + 'maxlength' => '255' + ), + 'bind_zonefiles_slaveprefix' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => '', + 'validators' => array( 0 => array ( 'type' => 'REGEX', + 'regex' => '/^[a-zA-Z0-9\.\-\_\/]{0,128}$/', + 'errmsg'=> 'bind_zonefiles_slaveprefix_error_regex'), + ), + 'value' => '', + 'width' => '40', + 'maxlength' => '255' + ), 'named_conf_path' => array( 'datatype' => 'VARCHAR', 'formtype' => 'TEXT', diff --git a/interface/web/admin/form/server_php.tform.php b/interface/web/admin/form/server_php.tform.php index 2a37a1e6d1..01ded2cc61 100644 --- a/interface/web/admin/form/server_php.tform.php +++ b/interface/web/admin/form/server_php.tform.php @@ -62,6 +62,7 @@ $form["title"] = "Additional PHP Versions"; //$form["description"] = "Form to edit additional PHP versions"; $form["name"] = "server_php"; +$form["record_name_field"] = "name"; $form["action"] = "server_php_edit.php"; $form["db_table"] = "server_php"; $form["db_table_idx"] = "server_php_id"; @@ -248,4 +249,67 @@ //################################# ) ); +$form["tabs"]['php_cli'] = array ( + 'title' => "PHP-CLI settings", + 'width' => 80, + 'template' => "templates/server_php_cli_edit.htm", + 'fields' => array( + //################################# + // Begin Datatable fields + //################################# + 'php_cli_binary' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'validators' => array( + 0 => array('type' => 'NOTEMPTY', + 'errmsg' => 'php_cli_binary_empty' + ), + 1 => array ( + 'type' => 'REGEX', + 'regex' => '/^\/[a-zA-Z0-9\/\-\_\.\s]*$/', + 'errmsg'=> 'php_cli_binary_error_regex' + ), + ), + 'default' => '', + 'value' => '', + 'width' => '40', + 'maxlength' => '255' + ), + 'php_jk_section' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => '', + 'validators' => array( + 0 => array('type' => 'NOTEMPTY', + 'errmsg' => 'php_cli_jk_section_empty' + ), + 1 => array ( + 'type' => 'REGEX', + 'regex' => '/^[a-zA-Z0-9\-\_]*$/', + 'errmsg'=> 'php_cli_jk_section_error_regex' + ), + ), + 'value' => '', + 'width' => '40', + 'maxlength' => '255' + ), + ) + ); + +$form["tabs"]['php_sort'] = array ( + 'title' => "PHP Sort Priority", + 'width' => 80, + 'template' => "templates/server_php_sort_edit.htm", + 'fields' => array( + 'sortprio' => array ( + 'datatype' => 'INTEGER', + 'formtype' => 'TEXT', + 'default' => '100', + 'value' => '', + 'separator' => '', + 'width' => '10', + 'maxlength' => '20' + ), + ) +); ?> diff --git a/interface/web/admin/form/system_config.tform.php b/interface/web/admin/form/system_config.tform.php index 22212b8b74..40e5877f9f 100644 --- a/interface/web/admin/form/system_config.tform.php +++ b/interface/web/admin/form/system_config.tform.php @@ -252,7 +252,16 @@ 'formtype' => 'CHECKBOX', 'default' => 'y', 'value' => array(0 => 'n', 1 => 'y') - ), + ), + 'postgresql_database' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'n', + 'value' => array ( + 0 => 'n', + 1 => 'y' + ) + ), //################################# // END Datatable fields //################################# @@ -303,6 +312,12 @@ 'default' => 'y', 'value' => array(0 => 'n', 1 => 'y') ), + 'mailbox_show_last_access' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'n', + 'value' => array(0 => 'n', 1 => 'y') + ), 'mailboxlist_webmail_link' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'CHECKBOX', @@ -487,6 +502,18 @@ 'value' => '', 'name' => 'default_slave_dnsserver' ), + 'dns_external_slave_fqdn' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'filters' => array( + 0 => array( 'event' => 'SAVE', + 'type' => 'STRIPTAGS'), + 1 => array( 'event' => 'SAVE', + 'type' => 'STRIPNL') + ), + 'default' => '', + 'value' => '' + ), 'dns_show_zoneexport' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'CHECKBOX', @@ -661,6 +688,12 @@ 'default' => 'y', 'value' => array(0 => 'n', 1 => 'y') ), + 'show_delete_on_forms' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'n', + 'value' => array(0 => 'n', 1 => 'y') + ), 'maintenance_mode' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'CHECKBOX', diff --git a/interface/web/admin/groups_del.php b/interface/web/admin/groups_del.php index 42eed9507b..c8b3aaaa0c 100644 --- a/interface/web/admin/groups_del.php +++ b/interface/web/admin/groups_del.php @@ -46,6 +46,8 @@ $app->auth->check_module_permissions('admin'); $app->auth->check_security_permissions('admin_allow_cpuser_group'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); + $app->uses("tform_actions"); $app->tform_actions->onDelete(); diff --git a/interface/web/admin/groups_edit.php b/interface/web/admin/groups_edit.php index 0000003616..b25fe1b39a 100644 --- a/interface/web/admin/groups_edit.php +++ b/interface/web/admin/groups_edit.php @@ -45,6 +45,8 @@ $app->auth->check_module_permissions('admin'); $app->auth->check_security_permissions('admin_allow_cpuser_group'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); + // Loading classes $app->uses('tpl,tform,tform_actions'); diff --git a/interface/web/admin/groups_list.php b/interface/web/admin/groups_list.php index aa2c37c664..1f59610a5d 100644 --- a/interface/web/admin/groups_list.php +++ b/interface/web/admin/groups_list.php @@ -43,6 +43,7 @@ //* Check permissions for module $app->auth->check_module_permissions('admin'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); $app->uses('listform_actions'); $app->listform_actions->onLoad(); diff --git a/interface/web/admin/iptables_del.php b/interface/web/admin/iptables_del.php index 55371d6cb4..219370f916 100644 --- a/interface/web/admin/iptables_del.php +++ b/interface/web/admin/iptables_del.php @@ -44,6 +44,7 @@ //* Check permissions for module $app->auth->check_module_permissions('admin'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); $app->uses("tform_actions"); $app->tform_actions->onDelete(); diff --git a/interface/web/admin/iptables_edit.php b/interface/web/admin/iptables_edit.php index 77c2ae7e57..3f40f18223 100644 --- a/interface/web/admin/iptables_edit.php +++ b/interface/web/admin/iptables_edit.php @@ -44,6 +44,7 @@ //* Check permissions for module $app->auth->check_module_permissions('admin'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); // Loading classes $app->uses('tpl,tform,tform_actions'); diff --git a/interface/web/admin/iptables_list.php b/interface/web/admin/iptables_list.php index 06141b669b..1fd38ae30b 100644 --- a/interface/web/admin/iptables_list.php +++ b/interface/web/admin/iptables_list.php @@ -44,6 +44,7 @@ //* Check permissions for module $app->auth->check_module_permissions('admin'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); $app->uses('listform_actions'); diff --git a/interface/web/admin/language_add.php b/interface/web/admin/language_add.php index f36fd946d2..8056c9d05f 100644 --- a/interface/web/admin/language_add.php +++ b/interface/web/admin/language_add.php @@ -35,7 +35,7 @@ $app->auth->check_security_permissions('admin_allow_langedit'); //* This is only allowed for administrators -if(!$app->auth->is_admin()) die('only allowed for administrators.'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); if($conf['demo_mode'] == true) $app->error('This function is disabled in demo mode.'); $app->uses('tpl'); diff --git a/interface/web/admin/language_complete.php b/interface/web/admin/language_complete.php index 234685498d..72cb28c4e2 100644 --- a/interface/web/admin/language_complete.php +++ b/interface/web/admin/language_complete.php @@ -36,7 +36,7 @@ if($conf['demo_mode'] == true) $app->error('This function is disabled in demo mode.'); //* This is only allowed for administrators -if(!$app->auth->is_admin()) die('only allowed for administrators.'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); $app->uses('tpl'); @@ -81,22 +81,30 @@ if ($file != '.' && $file != '..') { if(@is_dir(ISPC_WEB_PATH.'/'.$file.'/lib/lang')) { $handle2 = opendir(ISPC_WEB_PATH.'/'.$file.'/lib/lang'); - while ($lang_file = @readdir($handle2)) { - if ($lang_file != '.' && $lang_file != '..' && substr($lang_file, 0, 2) == 'en') { - $target_lang_file = $selected_language.substr($lang_file, 2); - merge_langfile(ISPC_WEB_PATH.'/'.$file.'/lib/lang/'.$target_lang_file, ISPC_WEB_PATH.'/'.$file.'/lib/lang/'.$lang_file); + if($handle2) { + while ($lang_file = @readdir($handle2)) { + if ($lang_file != '.' && $lang_file != '..' && substr($lang_file, 0, 2) == 'en') { + $target_lang_file = $selected_language.substr($lang_file, 2); + merge_langfile(ISPC_WEB_PATH.'/'.$file.'/lib/lang/'.$target_lang_file, ISPC_WEB_PATH.'/'.$file.'/lib/lang/'.$lang_file); + } } + closedir($handle2); } + $handle2 = opendir(ISPC_WEB_PATH.'/'.$file.'/lib/lang'); - while ($lang_file = @readdir($handle2)) { - if ($lang_file != '.' && $lang_file != '..' && substr($lang_file, 0, 2) == $selected_language) { - $master_lang_file=ISPC_WEB_PATH.'/'.$file.'/lib/lang/en'.substr($lang_file, 2); - $target_lang_file=ISPC_WEB_PATH.'/'.$file.'/lib/lang/'.$lang_file; - if(!file_exists($master_lang_file)){ - unlink($target_lang_file); - $msg.="File $target_lang_file removed because does not exist in master language
"; + if($handle2) { + while ($lang_file = @readdir($handle2)) { + if ($lang_file != '.' && $lang_file != '..' && substr($lang_file, 0, 2) == $selected_language) { + $master_lang_file=ISPC_WEB_PATH.'/'.$file.'/lib/lang/en'.substr($lang_file, 2); + $target_lang_file=ISPC_WEB_PATH.'/'.$file.'/lib/lang/'.$lang_file; + if(!file_exists($master_lang_file)){ + if(@unlink($target_lang_file)) { + $msg.="File $target_lang_file removed because does not exist in master language
"; + } + } } } + closedir($handle2); }//Finish of remove the files how not exists in master language } } @@ -141,9 +149,11 @@ function merge_langfile($langfile, $masterfile) { $file_content = " $val) { - $val = str_replace("'", "\\'", $val); - $val = str_replace('"', '\"', $val); - $file_content .= '$wb['."'$key'".'] = '."'$val';\n"; + // Validate key: only allow letters, numbers, underscores, and spaces + if(!preg_match("/^[a-zA-Z0-9_ ]+$/", $key)) continue; + $safe_key = var_export($key, true); + $safe_val = var_export($val, true); + $file_content .= "\$wb[{$safe_key}] = {$safe_val};\n"; } $file_content .= "?>\n"; @@ -172,6 +182,3 @@ function merge_langfile($langfile, $masterfile) { $app->tpl_defaults(); $app->tpl->pparse(); - - -?> diff --git a/interface/web/admin/language_edit.php b/interface/web/admin/language_edit.php index 39baec55e3..78d618fcdb 100644 --- a/interface/web/admin/language_edit.php +++ b/interface/web/admin/language_edit.php @@ -35,7 +35,7 @@ $app->auth->check_security_permissions('admin_allow_langedit'); //* This is only allowed for administrators -if(!$app->auth->is_admin()) die('only allowed for administrators.'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); if($conf['demo_mode'] == true) $app->error('This function is disabled in demo mode.'); $app->uses('tpl'); @@ -62,9 +62,10 @@ $file_content = " $val) { $val = stripslashes($val); - $val = preg_replace('/(^|[^\\\\])((\\\\\\\\)*)"/', '$1$2\\"', $val); - $val = str_replace('$', '', $val); - $file_content .= '$wb['."'$key'".'] = "'.$val.'";'."\n"; + // Use var_export for secure escaping - handles all edge cases including consecutive quotes + $escaped_val = var_export($val, true); + if(!preg_match("/^[a-z0-9_]+$/", $key)) die('Invalid language file key.'); + $file_content .= '$wb['."'$key'".'] = '.$escaped_val.';'."\n"; $msg = 'File saved.'; } $file_content .= "?>\n"; diff --git a/interface/web/admin/language_export.php b/interface/web/admin/language_export.php index 3f54e53af8..8dfd53e653 100644 --- a/interface/web/admin/language_export.php +++ b/interface/web/admin/language_export.php @@ -35,7 +35,7 @@ $app->auth->check_security_permissions('admin_allow_langedit'); //* This is only allowed for administrators -if(!$app->auth->is_admin()) die('only allowed for administrators.'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); if($conf['demo_mode'] == true) $app->error('This function is disabled in demo mode.'); $app->uses('tpl'); diff --git a/interface/web/admin/language_import.php b/interface/web/admin/language_import.php index 6a2d0b5ba6..c3f754a7f3 100644 --- a/interface/web/admin/language_import.php +++ b/interface/web/admin/language_import.php @@ -31,10 +31,11 @@ require_once '../../lib/app.inc.php'; function normalize_string($string, $quote, $allow_special = false) { + // First, handle quote concatenation by extracting content between quotes + $content = ''; $escaped = false; - $in_string = true; - $new_string = ''; - + $in_string = ($quote !== null); + for($c = 0; $c < mb_strlen($string); $c++) { $char = mb_substr($string, $c, 1); @@ -51,34 +52,32 @@ function normalize_string($string, $quote, $allow_special = false) { } } - if($char === '"' && $escaped === true && $quote === '"') { - // unescape this - $new_string .= $char; - $escaped = false; - continue; - } elseif($char === "'" && $escaped === false && $quote === '"') { - // escape this - $new_string .= '\\' . $char; - continue; - } - if($escaped === true) { - // the next character is the escaped one. + // Handle escaped characters properly if($allow_special === true && ($char === 'n' || $char === 'r' || $char === 't')) { - $new_string .= '\' . "\\' . $char . '" . \''; + // Convert escape sequences to actual characters for special cases + if($char === 'n') $content .= "\n"; + elseif($char === 'r') $content .= "\r"; + elseif($char === 't') $content .= "\t"; } else { - $new_string .= '\\' . $char; + $content .= $char; // Add the escaped character without the backslash } $escaped = false; } else { if($char === '\\') { $escaped = true; } else { - $new_string .= $char; + $content .= $char; } } } - return $new_string; + + // Use var_export for secure escaping - this handles all edge cases correctly + // Remove outer quotes since we'll add our own + $safe_content = var_export($content, true); + // var_export returns single-quoted strings, so we can return as-is for single quotes + // or convert to double quotes if needed, but we'll standardize on single quotes + return substr($safe_content, 1, -1); // Remove the outer quotes added by var_export } function validate_line($line) { @@ -95,17 +94,17 @@ function validate_line($line) { $textquote = $matches[3]; // ' or " $text = $matches[4]; - $new_line = '$wb[\''; - - // validate the language key - $key = normalize_string($key, $keyquote); - - $new_line .= $key . '\'] = \''; + // Validate and normalize the language key using secure escaping + $normalized_key = normalize_string($key, $keyquote); + + // Validate and normalize the text value using secure escaping + $normalized_text = normalize_string($text, $textquote, true); - // validate this text to avoid code injection - $text = normalize_string($text, $textquote, true); + // Use var_export for final secure output generation + $safe_key = var_export($normalized_key, true); + $safe_text = var_export($normalized_text, true); - $new_line .= $text . '\';'; + $new_line = '$wb[' . $safe_key . '] = ' . $safe_text . ';'; return $new_line; } @@ -115,7 +114,7 @@ function validate_line($line) { $app->auth->check_security_permissions('admin_allow_langedit'); //* This is only allowed for administrators -if(!$app->auth->is_admin()) die('only allowed for administrators.'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); if($conf['demo_mode'] == true) $app->error('This function is disabled in demo mode.'); if(!$conf['language_file_import_enabled']) $app->error('Languge import function is disabled in the interface config.inc.php file.'); diff --git a/interface/web/admin/language_list.php b/interface/web/admin/language_list.php index b935bddd95..88cda998fd 100644 --- a/interface/web/admin/language_list.php +++ b/interface/web/admin/language_list.php @@ -34,7 +34,7 @@ $app->auth->check_module_permissions('admin'); //* This is only allowed for administrators -if(!$app->auth->is_admin()) die('only allowed for administrators.'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); $app->uses('tpl'); diff --git a/interface/web/admin/lib/lang/ar.lng b/interface/web/admin/lib/lang/ar.lng index ca5ffcc8e7..42f162c71d 100644 --- a/interface/web/admin/lib/lang/ar.lng +++ b/interface/web/admin/lib/lang/ar.lng @@ -49,4 +49,8 @@ $wb['Do ISPConfig-Update'] = 'Do ISPConfig-Update'; $wb['Directive Snippets'] = 'Directive Snippets'; $wb['Sites'] = 'Sites'; $wb['DNS'] = 'DNS'; + +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Available Extensions'; +$wb['Installed Extensions'] = 'Installed Extensions'; ?> diff --git a/interface/web/admin/lib/lang/ar_extension_install_list.lng b/interface/web/admin/lib/lang/ar_extension_install_list.lng new file mode 100644 index 0000000000..6e49501cbf --- /dev/null +++ b/interface/web/admin/lib/lang/ar_extension_install_list.lng @@ -0,0 +1,48 @@ + diff --git a/interface/web/admin/lib/lang/ar_remote_action.lng b/interface/web/admin/lib/lang/ar_remote_action.lng index dfe56b616d..aeb7a78537 100644 --- a/interface/web/admin/lib/lang/ar_remote_action.lng +++ b/interface/web/admin/lib/lang/ar_remote_action.lng @@ -8,5 +8,5 @@ $wb['do_ispcupdate_desc'] = 'This action does a ISPConfig3 update at your select $wb['action_scheduled'] = 'The action is scheduled for execution'; $wb['select_all_server'] = 'All server'; $wb['ispconfig_update_title'] = 'ISPConfig update instructions'; -$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; +$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; ?> diff --git a/interface/web/admin/lib/lang/ar_server.lng b/interface/web/admin/lib/lang/ar_server.lng index 6b63109f98..6c8a5a5754 100644 --- a/interface/web/admin/lib/lang/ar_server.lng +++ b/interface/web/admin/lib/lang/ar_server.lng @@ -13,4 +13,5 @@ $wb['- None -'] = '- None -'; $wb['proxy_server_txt'] = 'Proxy-Server'; $wb['firewall_server_txt'] = 'Firewall-Server'; $wb['xmpp_server_txt'] = 'XMPP Server'; +$wb['server_name_error_regex'] = 'Invalid server name. Only letters, numbers, spaces, hyphens, dots, underscores and parentheses are allowed.'; ?> diff --git a/interface/web/admin/lib/lang/ar_server_config.lng b/interface/web/admin/lib/lang/ar_server_config.lng index a58dbaaf44..b2a9a0c5cc 100644 --- a/interface/web/admin/lib/lang/ar_server_config.lng +++ b/interface/web/admin/lib/lang/ar_server_config.lng @@ -168,6 +168,7 @@ $wb['rescue_description_txt'] = 'Information: If you want to shut down my $wb['enable_sni_txt'] = 'Enable SNI'; $wb['do_not_try_rescue_httpd_txt'] = 'Disable HTTPD monitoring'; $wb['set_folder_permissions_on_update_txt'] = 'Set folder permissions on update'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Add web users to -sshusers- group'; $wb['connect_userid_to_webid_txt'] = 'Connect Linux userid to webid'; $wb['connect_userid_to_webid_start_txt'] = 'Start ID for userid/webid connect'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -342,5 +344,30 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Número de copias de seguridad del sistema'; +$wb['sysbackup_copies_error_empty'] = 'El número de copias de seguridad del sistema no debe estar vacío'; +$wb['sysbackup_copies_error_regex'] = 'El número de copias de seguridad del sistema debe ser un número entre 1 y 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = desactivado)'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/ar_server_php.lng b/interface/web/admin/lib/lang/ar_server_php.lng index 491be1aae2..1a7420fb21 100644 --- a/interface/web/admin/lib/lang/ar_server_php.lng +++ b/interface/web/admin/lib/lang/ar_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Active'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/ar_server_php_list.lng b/interface/web/admin/lib/lang/ar_server_php_list.lng index 291302cbb7..d5e6ad3c7f 100644 --- a/interface/web/admin/lib/lang/ar_server_php_list.lng +++ b/interface/web/admin/lib/lang/ar_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Client'; $wb['name_txt'] = 'PHP Name'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/ar_system_config.lng b/interface/web/admin/lib/lang/ar_system_config.lng index 4ae8ad3416..8840918613 100644 --- a/interface/web/admin/lib/lang/ar_system_config.lng +++ b/interface/web/admin/lib/lang/ar_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/bg.lng b/interface/web/admin/lib/lang/bg.lng index 9d90e56583..c79650bc7b 100644 --- a/interface/web/admin/lib/lang/bg.lng +++ b/interface/web/admin/lib/lang/bg.lng @@ -49,4 +49,8 @@ $wb['Misc'] = 'Misc'; $wb['Directive Snippets'] = 'Directive Snippets'; $wb['Sites'] = 'Sites'; $wb['DNS'] = 'DNS'; + +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Available Extensions'; +$wb['Installed Extensions'] = 'Installed Extensions'; ?> diff --git a/interface/web/admin/lib/lang/bg_extension_install_list.lng b/interface/web/admin/lib/lang/bg_extension_install_list.lng new file mode 100644 index 0000000000..3924f9a813 --- /dev/null +++ b/interface/web/admin/lib/lang/bg_extension_install_list.lng @@ -0,0 +1,48 @@ + diff --git a/interface/web/admin/lib/lang/bg_remote_action.lng b/interface/web/admin/lib/lang/bg_remote_action.lng index 8d6e441d85..79a08a9973 100644 --- a/interface/web/admin/lib/lang/bg_remote_action.lng +++ b/interface/web/admin/lib/lang/bg_remote_action.lng @@ -8,5 +8,5 @@ $wb['do_ispcupdate_desc'] = 'Това дейÑтвие прави ISPConfig 3 о $wb['action_scheduled'] = 'Това дейÑтвие е наÑрочено за изпълнение'; $wb['select_all_server'] = 'Ð¦ÐµÐ»Ð¸Ñ Ñървър'; $wb['ispconfig_update_title'] = 'ISPConfig ъпдейт инÑтрукции'; -$wb['ispconfig_update_text'] = 'Логнете Ñе като root потребител през шелла на вашиÑÑ‚ Ñървър използвайте командата

ispconfig_update.sh

за да Ñтартирате ISPConfig обновÑване.

Click here for detailed update instructions'; +$wb['ispconfig_update_text'] = 'Логнете Ñе като root потребител през шелла на вашиÑÑ‚ Ñървър използвайте командата

ispconfig_update.sh

за да Ñтартирате ISPConfig обновÑване.

Click here for detailed update instructions'; ?> diff --git a/interface/web/admin/lib/lang/bg_server.lng b/interface/web/admin/lib/lang/bg_server.lng index 448ec572b7..4aab92375b 100644 --- a/interface/web/admin/lib/lang/bg_server.lng +++ b/interface/web/admin/lib/lang/bg_server.lng @@ -13,4 +13,5 @@ $wb['- None -'] = '- Ðищо -'; $wb['proxy_server_txt'] = 'Proxy-Server'; $wb['firewall_server_txt'] = 'Firewall-Server'; $wb['xmpp_server_txt'] = 'XMPP Server'; +$wb['server_name_error_regex'] = 'Ðевалидно име на Ñървър. Разрешени Ñа Ñамо букви, цифри, интервали, тирета, точки, долни черти и Ñкоби.'; ?> diff --git a/interface/web/admin/lib/lang/bg_server_config.lng b/interface/web/admin/lib/lang/bg_server_config.lng index c856e7640f..4ef352b482 100644 --- a/interface/web/admin/lib/lang/bg_server_config.lng +++ b/interface/web/admin/lib/lang/bg_server_config.lng @@ -168,6 +168,7 @@ $wb['rescue_description_txt'] = 'ИÐФОРМÐЦИЯ: Ðко иÑкат $wb['enable_sni_txt'] = 'Enable SNI'; $wb['do_not_try_rescue_httpd_txt'] = 'Disable HTTPD monitoring'; $wb['set_folder_permissions_on_update_txt'] = 'Set folder permissions on update'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Add web users to -sshusers- group'; $wb['connect_userid_to_webid_txt'] = 'Connect Linux userid to webid'; $wb['connect_userid_to_webid_start_txt'] = 'Start ID for userid/webid connect'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -342,5 +344,30 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Number of ISPConfig backups'; +$wb['sysbackup_copies_error_empty'] = 'Number of ISPConfig backups must not be empty'; +$wb['sysbackup_copies_error_regex'] = 'Number of ISPConfig backups must be a number between 1 and 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = off)'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/bg_server_php.lng b/interface/web/admin/lib/lang/bg_server_php.lng index 491be1aae2..1a7420fb21 100644 --- a/interface/web/admin/lib/lang/bg_server_php.lng +++ b/interface/web/admin/lib/lang/bg_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Active'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/bg_server_php_list.lng b/interface/web/admin/lib/lang/bg_server_php_list.lng index 291302cbb7..d5e6ad3c7f 100644 --- a/interface/web/admin/lib/lang/bg_server_php_list.lng +++ b/interface/web/admin/lib/lang/bg_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Client'; $wb['name_txt'] = 'PHP Name'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/bg_system_config.lng b/interface/web/admin/lib/lang/bg_system_config.lng index 2029f38ed2..006703bb33 100644 --- a/interface/web/admin/lib/lang/bg_system_config.lng +++ b/interface/web/admin/lib/lang/bg_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/br.lng b/interface/web/admin/lib/lang/br.lng index 12db8395a4..0288fa595c 100644 --- a/interface/web/admin/lib/lang/br.lng +++ b/interface/web/admin/lib/lang/br.lng @@ -50,3 +50,7 @@ $wb['Import'] = 'Importar'; $wb['Remote Actions'] = 'Ações remotas'; $wb['Do OS-Update'] = 'Atualizar sistema operacional'; $wb['Do ISPConfig-Update'] = 'Atualizar o ISPConfig'; + +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Available Extensions'; +$wb['Installed Extensions'] = 'Installed Extensions'; diff --git a/interface/web/admin/lib/lang/br_extension_install_list.lng b/interface/web/admin/lib/lang/br_extension_install_list.lng new file mode 100644 index 0000000000..ce5d628ea3 --- /dev/null +++ b/interface/web/admin/lib/lang/br_extension_install_list.lng @@ -0,0 +1,48 @@ + diff --git a/interface/web/admin/lib/lang/br_remote_action.lng b/interface/web/admin/lib/lang/br_remote_action.lng index 84e928dbd9..623c2254b8 100644 --- a/interface/web/admin/lib/lang/br_remote_action.lng +++ b/interface/web/admin/lib/lang/br_remote_action.lng @@ -8,4 +8,4 @@ $wb['do_ispcupdate_desc'] = 'Esta ação atualizará o ISPConfig3 no servidor se $wb['action_scheduled'] = 'A ação foi agendada.'; $wb['select_all_server'] = 'Todos os servidores'; $wb['ispconfig_update_title'] = 'Instruções de atualização do ISPConfig'; -$wb['ispconfig_update_text'] = 'Acesse com o usuário root no shell do servidor e execute o comando

ispconfig_update.sh

para iniciar a atualização do ISPConfig.

Clique aqui para instruções detalhadas'; +$wb['ispconfig_update_text'] = 'Acesse com o usuário root no shell do servidor e execute o comando

ispconfig_update.sh

para iniciar a atualização do ISPConfig.

Clique aqui para instruções detalhadas'; diff --git a/interface/web/admin/lib/lang/br_server.lng b/interface/web/admin/lib/lang/br_server.lng index 20a2eddbb6..aa78b35c52 100644 --- a/interface/web/admin/lib/lang/br_server.lng +++ b/interface/web/admin/lib/lang/br_server.lng @@ -13,3 +13,5 @@ $wb['active_txt'] = 'Ativo'; $wb['mirror_server_id_txt'] = 'É um espelho de servidor'; $wb['- None -'] = '-Nenhum-'; $wb['xmpp_server_txt'] = 'Servidor XMPP'; +$wb['server_name_error_regex'] = 'Nome de servidor inválido. Apenas letras, números, espaços, hífens, pontos, sublinhados e parênteses são permitidos.'; +?> diff --git a/interface/web/admin/lib/lang/br_server_config.lng b/interface/web/admin/lib/lang/br_server_config.lng index 1041676ceb..3b42c65db7 100644 --- a/interface/web/admin/lib/lang/br_server_config.lng +++ b/interface/web/admin/lib/lang/br_server_config.lng @@ -182,6 +182,7 @@ $wb['do_not_try_rescue_mail_txt'] = 'Desabilitar monitoramento do servidor de em $wb['rescue_description_txt'] = 'Informação: Se o serviço MySQL for desligado e estiver selecionado "Desabilitar monitoramento do MySQL" aguarde entre 2 e 3 minutos sem abandonar a aba.
Se não aguardar o sistema de recuperação de falhas tentará reiniciar o MySQL!'; $wb['enable_sni_txt'] = 'Habilitar SNI'; $wb['set_folder_permissions_on_update_txt'] = 'Configurar permissões de pasta quando atualizar'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Adicionar novos usuários Web para o grupo SSH'; $wb['connect_userid_to_webid_txt'] = 'Conectar o UID do usuário no sistema para webID'; $wb['connect_userid_to_webid_start_txt'] = 'Conexão do ID inicial do usuário com o webID'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Habilitar protocolo PROXY'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'Porta HTTP protocolo PROXY'; $wb['vhost_proxy_protocol_https_port_txt'] = 'Porta HTTPS protocolo PROXY'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Gabarito authorized_keys Jailkit'; @@ -342,5 +344,30 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Usar links físicos é inseguro, mas eco $wb['jailkit_hardlinks_allow_txt'] = 'Permitir links físicos enjaulados'; $wb['jailkit_hardlinks_no_txt'] = 'Não, remover arquivos de links físicos'; $wb['jailkit_hardlinks_yes_txt'] = 'Sim, usar links físicos quando possível'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Número de copias de seguridad do sistema'; +$wb['sysbackup_copies_error_empty'] = 'O número de copias de seguridad do sistema não pode estar vazio'; +$wb['sysbackup_copies_error_regex'] = 'O número de copias de seguridad do sistema deve ser um número entre 1 e 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = desativado)'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/br_server_php.lng b/interface/web/admin/lib/lang/br_server_php.lng index d0a1015833..fe93fecab9 100644 --- a/interface/web/admin/lib/lang/br_server_php.lng +++ b/interface/web/admin/lib/lang/br_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Ativo'; $wb['php_in_use_error'] = 'Esta versão PHP está em uso.'; $wb['php_name_in_use_error'] = 'O nome não pode ser modificado.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/br_system_config.lng b/interface/web/admin/lib/lang/br_system_config.lng index 1128081d2d..d3ad7d08ce 100644 --- a/interface/web/admin/lib/lang/br_system_config.lng +++ b/interface/web/admin/lib/lang/br_system_config.lng @@ -108,3 +108,7 @@ $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['monitor_key_txt'] = 'Senha do Monitor'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/ca.lng b/interface/web/admin/lib/lang/ca.lng index d136825687..d747a6ba14 100644 --- a/interface/web/admin/lib/lang/ca.lng +++ b/interface/web/admin/lib/lang/ca.lng @@ -49,4 +49,8 @@ $wb['Import'] = 'Import'; $wb['Remote Actions'] = 'Remote Actions'; $wb['Do OS-Update'] = 'Do OS-Update'; $wb['Do ISPConfig-Update'] = 'Do ISPConfig-Update'; + +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Available Extensions'; +$wb['Installed Extensions'] = 'Installed Extensions'; ?> diff --git a/interface/web/admin/lib/lang/ca_extension_install_list.lng b/interface/web/admin/lib/lang/ca_extension_install_list.lng new file mode 100644 index 0000000000..2863ed3aa5 --- /dev/null +++ b/interface/web/admin/lib/lang/ca_extension_install_list.lng @@ -0,0 +1,48 @@ + diff --git a/interface/web/admin/lib/lang/ca_remote_action.lng b/interface/web/admin/lib/lang/ca_remote_action.lng index 667f382fbb..2883a475ab 100644 --- a/interface/web/admin/lib/lang/ca_remote_action.lng +++ b/interface/web/admin/lib/lang/ca_remote_action.lng @@ -8,5 +8,5 @@ $wb['do_ispcupdate_desc'] = 'This action does a ISPConfig3 update at your select $wb['action_scheduled'] = 'The action is scheduled for execution'; $wb['select_all_server'] = 'All servers'; $wb['ispconfig_update_title'] = 'ISPConfig update instructions'; -$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; +$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; ?> diff --git a/interface/web/admin/lib/lang/ca_server.lng b/interface/web/admin/lib/lang/ca_server.lng index 35cbfd891c..8d46e0a051 100644 --- a/interface/web/admin/lib/lang/ca_server.lng +++ b/interface/web/admin/lib/lang/ca_server.lng @@ -13,4 +13,5 @@ $wb['active_txt'] = 'Active'; $wb['mirror_server_id_txt'] = 'Is mirror of Server'; $wb['- None -'] = '- None -'; $wb['xmpp_server_txt'] = 'XMPP Server'; +$wb['server_name_error_regex'] = 'Nom de servidor no vàlid. Només es permeten lletres, números, espais, guions, punts, guions baixos i parèntesis.'; ?> diff --git a/interface/web/admin/lib/lang/ca_server_config.lng b/interface/web/admin/lib/lang/ca_server_config.lng index 3d4ad3a70c..1f53817449 100644 --- a/interface/web/admin/lib/lang/ca_server_config.lng +++ b/interface/web/admin/lib/lang/ca_server_config.lng @@ -178,6 +178,7 @@ $wb['do_not_try_rescue_mail_txt'] = 'Disable Email monitoring'; $wb['rescue_description_txt'] = 'Information: If you want to shut down mysql you have to select the \\"Disable MySQL monitor\\" checkbox and then wait 2-3 minutes.
If you do not wait 2-3 minutes, rescue will try to restart mysql!'; $wb['enable_sni_txt'] = 'Enable SNI'; $wb['set_folder_permissions_on_update_txt'] = 'Set folder permissions on update'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Add web users to -sshusers- group'; $wb['connect_userid_to_webid_txt'] = 'Connect Linux userid to webid'; $wb['connect_userid_to_webid_start_txt'] = 'Start ID for userid/webid connect'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -342,5 +344,30 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Number of ISPConfig backups'; +$wb['sysbackup_copies_error_empty'] = 'Number of ISPConfig backups must not be empty'; +$wb['sysbackup_copies_error_regex'] = 'Number of ISPConfig backups must be a number between 1 and 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = off)'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/ca_server_php.lng b/interface/web/admin/lib/lang/ca_server_php.lng index 491be1aae2..1a7420fb21 100644 --- a/interface/web/admin/lib/lang/ca_server_php.lng +++ b/interface/web/admin/lib/lang/ca_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Active'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/ca_server_php_list.lng b/interface/web/admin/lib/lang/ca_server_php_list.lng index 291302cbb7..d5e6ad3c7f 100644 --- a/interface/web/admin/lib/lang/ca_server_php_list.lng +++ b/interface/web/admin/lib/lang/ca_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Client'; $wb['name_txt'] = 'PHP Name'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/ca_system_config.lng b/interface/web/admin/lib/lang/ca_system_config.lng index 0c02530608..a8d57456ae 100644 --- a/interface/web/admin/lib/lang/ca_system_config.lng +++ b/interface/web/admin/lib/lang/ca_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/cn.lng b/interface/web/admin/lib/lang/cn.lng new file mode 100644 index 0000000000..74bda03042 --- /dev/null +++ b/interface/web/admin/lib/lang/cn.lng @@ -0,0 +1,64 @@ + diff --git a/interface/web/admin/lib/lang/cn_directive_snippets.lng b/interface/web/admin/lib/lang/cn_directive_snippets.lng new file mode 100644 index 0000000000..e35b560bba --- /dev/null +++ b/interface/web/admin/lib/lang/cn_directive_snippets.lng @@ -0,0 +1,15 @@ + diff --git a/interface/web/admin/lib/lang/cn_extension_install_list.lng b/interface/web/admin/lib/lang/cn_extension_install_list.lng new file mode 100644 index 0000000000..a72c3456ef --- /dev/null +++ b/interface/web/admin/lib/lang/cn_extension_install_list.lng @@ -0,0 +1,48 @@ + diff --git a/interface/web/admin/lib/lang/cn_firewall.lng b/interface/web/admin/lib/lang/cn_firewall.lng new file mode 100644 index 0000000000..d9d95c22d3 --- /dev/null +++ b/interface/web/admin/lib/lang/cn_firewall.lng @@ -0,0 +1,11 @@ + diff --git a/interface/web/admin/lib/lang/cn_firewall_list.lng b/interface/web/admin/lib/lang/cn_firewall_list.lng new file mode 100644 index 0000000000..8145ea0f7f --- /dev/null +++ b/interface/web/admin/lib/lang/cn_firewall_list.lng @@ -0,0 +1,8 @@ + diff --git a/interface/web/admin/lib/lang/cn_groups.lng b/interface/web/admin/lib/lang/cn_groups.lng new file mode 100644 index 0000000000..9ca6eb8de0 --- /dev/null +++ b/interface/web/admin/lib/lang/cn_groups.lng @@ -0,0 +1,5 @@ + diff --git a/interface/web/admin/lib/lang/cn_groups_list.lng b/interface/web/admin/lib/lang/cn_groups_list.lng new file mode 100644 index 0000000000..3ae2f8f458 --- /dev/null +++ b/interface/web/admin/lib/lang/cn_groups_list.lng @@ -0,0 +1,7 @@ +警告:请勿在此处编辑或修改任何用户设置。请改用客户端模å—中的客户端和ç»é”€å•†è®¾ç½®ã€‚在此处修改用户或组å¯èƒ½ä¼šå¯¼è‡´æ•°æ®ä¸¢å¤±ï¼'; +?> diff --git a/interface/web/admin/lib/lang/cn_iptables.lng b/interface/web/admin/lib/lang/cn_iptables.lng new file mode 100644 index 0000000000..f788bb9599 --- /dev/null +++ b/interface/web/admin/lib/lang/cn_iptables.lng @@ -0,0 +1,15 @@ + diff --git a/interface/web/admin/lib/lang/cn_iptables_list.lng b/interface/web/admin/lib/lang/cn_iptables_list.lng new file mode 100644 index 0000000000..512500b649 --- /dev/null +++ b/interface/web/admin/lib/lang/cn_iptables_list.lng @@ -0,0 +1,17 @@ + diff --git a/interface/web/admin/lib/lang/cn_language_add.lng b/interface/web/admin/lib/lang/cn_language_add.lng new file mode 100644 index 0000000000..717c411941 --- /dev/null +++ b/interface/web/admin/lib/lang/cn_language_add.lng @@ -0,0 +1,8 @@ + diff --git a/interface/web/admin/lib/lang/cn_language_complete.lng b/interface/web/admin/lib/lang/cn_language_complete.lng new file mode 100644 index 0000000000..b78431d3f9 --- /dev/null +++ b/interface/web/admin/lib/lang/cn_language_complete.lng @@ -0,0 +1,7 @@ +这将把英文主语言文件中缺失的字符串添加到所选语言文件中。'; +$wb['language_select_txt'] = '选择语言'; +$wb['btn_save_txt'] = 'ç«‹å³åˆå¹¶æ–‡ä»¶'; +$wb['btn_cancel_txt'] = '返回'; +?> diff --git a/interface/web/admin/lib/lang/cn_language_edit.lng b/interface/web/admin/lib/lang/cn_language_edit.lng new file mode 100644 index 0000000000..b4a0c104ec --- /dev/null +++ b/interface/web/admin/lib/lang/cn_language_edit.lng @@ -0,0 +1,8 @@ + diff --git a/interface/web/admin/lib/lang/cn_language_export.lng b/interface/web/admin/lib/lang/cn_language_export.lng new file mode 100644 index 0000000000..bbb3e7aee7 --- /dev/null +++ b/interface/web/admin/lib/lang/cn_language_export.lng @@ -0,0 +1,6 @@ + diff --git a/interface/web/admin/lib/lang/cn_language_import.lng b/interface/web/admin/lib/lang/cn_language_import.lng new file mode 100644 index 0000000000..a9a2ff908d --- /dev/null +++ b/interface/web/admin/lib/lang/cn_language_import.lng @@ -0,0 +1,9 @@ + diff --git a/interface/web/admin/lib/lang/cn_language_list.lng b/interface/web/admin/lib/lang/cn_language_list.lng new file mode 100644 index 0000000000..0a33f825db --- /dev/null +++ b/interface/web/admin/lib/lang/cn_language_list.lng @@ -0,0 +1,7 @@ + diff --git a/interface/web/admin/lib/lang/cn_package_install.lng b/interface/web/admin/lib/lang/cn_package_install.lng new file mode 100644 index 0000000000..744bc8c839 --- /dev/null +++ b/interface/web/admin/lib/lang/cn_package_install.lng @@ -0,0 +1,7 @@ + diff --git a/interface/web/admin/lib/lang/cn_remote_action.lng b/interface/web/admin/lib/lang/cn_remote_action.lng new file mode 100644 index 0000000000..65a75fa6f1 --- /dev/null +++ b/interface/web/admin/lib/lang/cn_remote_action.lng @@ -0,0 +1,12 @@ +
请自行承担风险ï¼'; +$wb['do_ispcupdate_caption'] = '在远程æœåŠ¡å™¨ä¸Šæ‰§è¡Œ ISPConfig 3 æ›´æ–°'; +$wb['do_ispcupdate_desc'] = 'æ­¤æ“作将在所选æœåŠ¡å™¨ä¸Šæ‰§è¡Œ ISPConfig3 更新。

请自行承担风险ï¼'; +$wb['action_scheduled'] = 'æ“作已安排执行'; +$wb['select_all_server'] = '所有æœåС噍'; +$wb['ispconfig_update_title'] = 'ISPConfig 更新说明'; +$wb['ispconfig_update_text'] = '以 root 用户身份登录æœåС噍 shell,执行命令

ispconfig_update.sh

以开始 ISPConfig 更新。

å•击此处获å–详细的更新说明'; +?> diff --git a/interface/web/admin/lib/lang/cn_remote_user.lng b/interface/web/admin/lib/lang/cn_remote_user.lng new file mode 100644 index 0000000000..66552727d4 --- /dev/null +++ b/interface/web/admin/lib/lang/cn_remote_user.lng @@ -0,0 +1,52 @@ + diff --git a/interface/web/admin/lib/lang/cn_remote_user_list.lng b/interface/web/admin/lib/lang/cn_remote_user_list.lng new file mode 100644 index 0000000000..7b90e136d0 --- /dev/null +++ b/interface/web/admin/lib/lang/cn_remote_user_list.lng @@ -0,0 +1,7 @@ + diff --git a/interface/web/admin/lib/lang/cn_server.lng b/interface/web/admin/lib/lang/cn_server.lng new file mode 100644 index 0000000000..c72037e94c --- /dev/null +++ b/interface/web/admin/lib/lang/cn_server.lng @@ -0,0 +1,17 @@ + diff --git a/interface/web/admin/lib/lang/cn_server_config.lng b/interface/web/admin/lib/lang/cn_server_config.lng new file mode 100644 index 0000000000..a082def28f --- /dev/null +++ b/interface/web/admin/lib/lang/cn_server_config.lng @@ -0,0 +1,373 @@ += 2000。'; +$wb['mailuser_gid_error_range'] = 'Mailuser GID å¿…é¡» >= 2000。'; +$wb['getmail_config_dir_error_regex'] = '无效的 getmail é…置目录。'; +$wb['website_basedir_error_regex'] = '无效的网站基础目录路径,最å°é•¿åº¦ä¸º 5 个字符。'; +$wb['website_symlinks_error_regex'] = '无效的网站符å·é“¾æŽ¥ã€‚'; +$wb['vhost_conf_dir_error_regex'] = '无效的虚拟主机é…置目录。'; +$wb['vhost_conf_enabled_dir_error_regex'] = '无效的虚拟主机å¯ç”¨é…置目录。'; +$wb['nginx_vhost_conf_dir_error_regex'] = '无效的 Nginx é…置目录。'; +$wb['nginx_vhost_conf_enabled_dir_error_regex'] = '无效的 Nginx å¯ç”¨é…置目录。'; +$wb['ca_path_error_regex'] = '无效的 CA 路径。'; +$wb['invalid_nginx_user_txt'] = '无效的 Nginx 用户。'; +$wb['invalid_nginx_group_txt'] = '无效的 Nginx 组。'; +$wb['php_ini_path_apache_error_regex'] = '无效的 Apache php.ini 路径。'; +$wb['php_ini_path_cgi_error_regex'] = '无效的 CGI php.ini 路径。'; +$wb['php_fpm_init_script_error_regex'] = '无效的 PHP-FPM init 脚本。'; +$wb['php_fpm_ini_path_error_regex'] = '无效的 PHP-FPM ini 路径。'; +$wb['php_fpm_pool_dir_error_regex'] = '无效的 PHP-FPM 池目录。'; +$wb['php_fpm_socket_dir_error_regex'] = '无效的 PHP-FPM socket 目录。'; +$wb['php_open_basedir_error_regex'] = '无效的 PHP open_basedir。'; +$wb['awstats_data_dir_empty'] = 'awstats æ•°æ®ç›®å½•为空'; +$wb['awstats_data_dir_error_regex'] = '无效的 awstats æ•°æ®ç›®å½•。'; +$wb['awstats_pl_empty'] = 'awstats.pl设置为空。'; +$wb['awstats_pl_error_regex'] = '无效的awstats.pl路径。'; +$wb['awstats_buildstaticpages_pl_empty'] = 'awstats_buildstaticpages.pl为空。'; +$wb['awstats_buildstaticpages_pl_error_regex'] = '无效的awstats_buildstaticpages.pl路径。'; +$wb['invalid_bind_user_txt'] = '无效的BIND用户。'; +$wb['invalid_bind_group_txt'] = '无效的BIND用户组。'; +$wb['bind_zonefiles_dir_error_regex'] = '无效的BIND区域文件目录。'; +$wb['bind_keyfiles_dir_error_regex'] = '无效的BIND密钥文件目录。'; +$wb['named_conf_path_error_regex'] = '无效的named.conf路径。'; +$wb['named_conf_local_path_error_regex'] = '无效的named.conf.local路径。'; +$wb['fastcgi_starter_path_error_regex'] = '无效的FastCGIå¯åŠ¨å™¨è·¯å¾„ã€‚'; +$wb['fastcgi_starter_script_error_regex'] = '无效的FastCGIå¯åŠ¨å™¨è„šæœ¬ã€‚'; +$wb['fastcgi_alias_error_regex'] = '无效的FastCGI别å。'; +$wb['fastcgi_phpini_path_error_regex'] = '无效的FastCGI php.ini路径。'; +$wb['fastcgi_bin_error_regex'] = '无效的FastCGI bin路径。'; +$wb['jailkit_chroot_home_error_regex'] = '无效的Jailkit chroot home路径。'; +$wb['jailkit_chroot_app_sections_error_regex'] = '无效的Jailkit chroot应用程åºsections。'; +$wb['jailkit_chroot_app_programs_error_regex'] = '无效的Jailkit chroot应用程åºã€‚'; +$wb['jailkit_chroot_cron_programs_error_regex'] = '无效的Jailkit chroot计划任务程åºã€‚'; +$wb['jailkit_chroot_authorized_keys_template_error_regex'] = '无效的 jaikit chroot authorized_keys æ¨¡æ¿æ–‡ä»¶ã€‚'; +$wb['vlogger_config_dir_error_regex'] = '无效的 vlogger é…置目录。'; +$wb['cron_init_script_error_regex'] = '无效的 cron åˆå§‹åŒ–脚本。'; +$wb['crontab_dir_error_regex'] = '无效的 crontab 目录。'; +$wb['cron_wget_error_regex'] = '无效的 cron wget 路径。'; +$wb['network_filesystem_txt'] = '网络文件系统'; +$wb['php_ini_check_minutes_txt'] = 'æ¯ X 分钟检查 php.ini æ˜¯å¦æ›´æ”¹'; +$wb['php_ini_check_minutes_error_empty'] = '请指定检查 php.ini 更改的频率。'; +$wb['php_ini_check_minutes_info_txt'] = '0 = 无需检查'; +$wb['web_settings_txt'] = 'Web æœåС噍'; +$wb['xmpp_server_txt'] = 'XMPP æœåС噍'; +$wb['xmpp_use_ipv6_txt'] = '使用 IPv6'; +$wb['xmpp_bosh_max_inactivity_txt'] = '最大 BOSH 䏿´»åŠ¨æ—¶é—´'; +$wb['xmpp_bosh_timeout_range_wrong'] = '请输入 BOSH 超时范围介于 15-360 之间'; +$wb['xmpp_module_saslauth'] = 'saslauth'; +$wb['xmpp_server_admins_txt'] = 'æœåŠ¡å™¨ç®¡ç†å‘˜ (JIDs)'; +$wb['xmpp_modules_enabled_txt'] = '全局å¯ç”¨çš„æ’ä»¶ï¼ˆæ¯è¡Œä¸€ä¸ªï¼‰'; +$wb['xmpp_ports_txt'] = '组件端å£'; +$wb['xmpp_port_http_txt'] = 'HTTP'; +$wb['xmpp_port_https_txt'] = 'HTTPS'; +$wb['xmpp_port_pastebin_txt'] = 'Pastebin'; +$wb['xmpp_port_bosh_txt'] = 'BOSH'; +$wb['disable_bind_log_txt'] = 'ç¦ç”¨bind9消æ¯ä»¥è¿›è¡Œæ—¥å¿—级别WARN'; +$wb['apps_vhost_enabled_txt'] = 'å¯ç”¨Apps-vhost'; +$wb['skip_le_check_txt'] = '跳过Let\'s Encrypt检查'; +$wb['migration_mode_txt'] = 'æœåС噍è¿ç§»æ¨¡å¼'; +$wb['nginx_enable_pagespeed_txt'] = 'å¯ç”¨Pagespeed'; +$wb['logging_txt'] = '存储网站访问和错误日志'; +$wb['logging_desc_txt'] = '使用工具>釿–°åŒæ­¥å°†æ›´æ”¹åº”用于现有站点。对于Apache,访问和错误日志å¯ä»¥åŒ¿å化。对于nginx,仅访问日志会被匿å化,错误日志将包å«IP地å€ã€‚'; +$wb['log_retention_txt'] = '日志ä¿ç•™æœŸï¼ˆå¤©ï¼‰'; +$wb['log_retention_error_ispositive'] = '日志ä¿ç•™æ—¶é—´å¿…须是大于0的数字'; +$wb['php_default_hide_txt'] = '在选择框中éšè—默认的PHP版本'; +$wb['php_default_name_txt'] = '默认PHP版本的æè¿°'; +$wb['php_default_name_error_empty'] = '默认PHP版本的æè¿°ä¸èƒ½ä¸ºç©º'; +$wb['error_mailbox_message_size_txt'] = '邮箱大å°å¿…须大于等于邮件大å°'; +$wb['php_fpm_reload_mode_txt'] = 'PHP-FPM釿–°åŠ è½½æ¨¡å¼'; +$wb['content_filter_txt'] = '内容过滤器'; +$wb['rspamd_url_txt'] = 'Rspamd URL'; +$wb['rspamd_user_txt'] = 'Rspamd 用户å'; +$wb['rspamd_password_txt'] = 'Rspamd 密ç '; +$wb['rspamd_redis_servers_txt'] = 'RedisæœåС噍'; +$wb['tooltip_rspamd_redis_servers_txt'] = 'Rspamd将使用的RedisæœåŠ¡å™¨ã€‚ä¾‹å¦‚: , 或。'; +$wb['rspamd_redis_password_txt'] = 'Redis密ç '; +$wb['tooltip_rspamd_redis_password_txt'] = 'RedisæœåŠ¡å™¨çš„å¯†ç (如果未使用,请留空)。'; +$wb['rspamd_redis_bayes_servers_txt'] = 'Bayesçš„RedisæœåС噍'; +$wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Rspamd将用于Bayesçš„RedisæœåŠ¡å™¨ï¼ˆå¦åˆ™è¯·ç•™ç©ºï¼‰ã€‚例如: 或。'; +$wb['rspamd_redis_bayes_password_txt'] = 'Bayes Redis密ç '; +$wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Bayes RedisæœåŠ¡å™¨çš„å¯†ç (如果未使用,请留空)。'; +$wb['vhost_proxy_protocol_enabled_txt'] = 'å¯ç”¨PROXYåè®®'; +$wb['vhost_proxy_protocol_http_port_txt'] = 'PROXYåè®®HTTP端å£'; +$wb['vhost_proxy_protocol_https_port_txt'] = 'PROXYåè®®HTTPS端å£'; +$wb['jailkit_hardlinks_txt'] = 'Jailkit chroot中的硬链接'; +$wb['tooltip_jailkit_hardlinks_txt'] = '使用硬链接ä¸å®‰å…¨ï¼Œä½†å¯ä»¥èŠ‚çœç£ç›˜ç©ºé—´ã€‚'; +$wb['jailkit_hardlinks_allow_txt'] = 'å…许狱中硬链接'; +$wb['jailkit_hardlinks_no_txt'] = 'ä¸ï¼Œåˆ é™¤ç¡¬é“¾æŽ¥æ–‡ä»¶'; +$wb['jailkit_hardlinks_yes_txt'] = '是的,如果å¯èƒ½ï¼Œä½¿ç”¨ç¡¬é“¾æŽ¥'; +$wb['mailbox_soft_delete_txt'] = '邮箱软删除'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Number of ISPConfig backups'; +$wb['sysbackup_copies_error_empty'] = 'Number of ISPConfig backups must not be empty'; +$wb['sysbackup_copies_error_regex'] = 'Number of ISPConfig backups must be a number between 1 and 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = off)'; +$wb['dkim_path_txt'] = 'DKIM Path'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/cn_server_config_list.lng b/interface/web/admin/lib/lang/cn_server_config_list.lng new file mode 100644 index 0000000000..4e4694c4e1 --- /dev/null +++ b/interface/web/admin/lib/lang/cn_server_config_list.lng @@ -0,0 +1,4 @@ + diff --git a/interface/web/admin/lib/lang/cn_server_ip.lng b/interface/web/admin/lib/lang/cn_server_ip.lng new file mode 100644 index 0000000000..c7b1593515 --- /dev/null +++ b/interface/web/admin/lib/lang/cn_server_ip.lng @@ -0,0 +1,13 @@ + diff --git a/interface/web/admin/lib/lang/cn_server_ip_list.lng b/interface/web/admin/lib/lang/cn_server_ip_list.lng new file mode 100644 index 0000000000..49d1f0a4f0 --- /dev/null +++ b/interface/web/admin/lib/lang/cn_server_ip_list.lng @@ -0,0 +1,10 @@ + diff --git a/interface/web/admin/lib/lang/cn_server_ip_map.lng b/interface/web/admin/lib/lang/cn_server_ip_map.lng new file mode 100644 index 0000000000..ff3ed0b27b --- /dev/null +++ b/interface/web/admin/lib/lang/cn_server_ip_map.lng @@ -0,0 +1,14 @@ + diff --git a/interface/web/admin/lib/lang/cn_server_ip_map_list.lng b/interface/web/admin/lib/lang/cn_server_ip_map_list.lng new file mode 100644 index 0000000000..1e28d08a77 --- /dev/null +++ b/interface/web/admin/lib/lang/cn_server_ip_map_list.lng @@ -0,0 +1,7 @@ + diff --git a/interface/web/admin/lib/lang/cn_server_list.lng b/interface/web/admin/lib/lang/cn_server_list.lng new file mode 100644 index 0000000000..1edbc95a83 --- /dev/null +++ b/interface/web/admin/lib/lang/cn_server_list.lng @@ -0,0 +1,14 @@ + diff --git a/interface/web/admin/lib/lang/cn_server_php.lng b/interface/web/admin/lib/lang/cn_server_php.lng new file mode 100644 index 0000000000..4ad0473169 --- /dev/null +++ b/interface/web/admin/lib/lang/cn_server_php.lng @@ -0,0 +1,32 @@ +Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; +?> diff --git a/interface/web/admin/lib/lang/cn_server_php_list.lng b/interface/web/admin/lib/lang/cn_server_php_list.lng new file mode 100644 index 0000000000..94711361bf --- /dev/null +++ b/interface/web/admin/lib/lang/cn_server_php_list.lng @@ -0,0 +1,9 @@ + diff --git a/interface/web/admin/lib/lang/cn_system_config.lng b/interface/web/admin/lib/lang/cn_system_config.lng new file mode 100644 index 0000000000..cc28ab154d --- /dev/null +++ b/interface/web/admin/lib/lang/cn_system_config.lng @@ -0,0 +1,112 @@ + diff --git a/interface/web/admin/lib/lang/cn_users.lng b/interface/web/admin/lib/lang/cn_users.lng new file mode 100644 index 0000000000..ccb6eb12cd --- /dev/null +++ b/interface/web/admin/lib/lang/cn_users.lng @@ -0,0 +1,42 @@ + diff --git a/interface/web/admin/lib/lang/cn_users_list.lng b/interface/web/admin/lib/lang/cn_users_list.lng new file mode 100644 index 0000000000..c85047fb63 --- /dev/null +++ b/interface/web/admin/lib/lang/cn_users_list.lng @@ -0,0 +1,9 @@ +警告:ä¸è¦åœ¨æ­¤å¤„编辑或修改任何客户端用户设置。请改用客户端模å—中的客户端和ç»é”€å•†è®¾ç½®ã€‚在此修改或更改客户端用户或组å¯èƒ½ä¼šå¯¼è‡´æ•°æ®ä¸¢å¤±ï¼'; +?> diff --git a/interface/web/admin/lib/lang/cz.lng b/interface/web/admin/lib/lang/cz.lng index 71ed4372d3..a25c948b3c 100644 --- a/interface/web/admin/lib/lang/cz.lng +++ b/interface/web/admin/lib/lang/cz.lng @@ -51,3 +51,7 @@ $wb['Sites'] = 'Stránky'; $wb['DNS'] = 'DNS'; $wb['2'] = 'Uživatelské jméno nebo heslo je prázdné.'; $wb['3'] = 'Uživatelské jméno nebo heslo je nesprávné.'; + +$wb['Extension Installer'] = 'Instalátor rozšíření'; +$wb['Available Extensions'] = 'Dostupná rozšíření'; +$wb['Installed Extensions'] = 'Nainstalovaná rozšíření'; diff --git a/interface/web/admin/lib/lang/cz_extension_install_list.lng b/interface/web/admin/lib/lang/cz_extension_install_list.lng new file mode 100644 index 0000000000..d217b50d23 --- /dev/null +++ b/interface/web/admin/lib/lang/cz_extension_install_list.lng @@ -0,0 +1,48 @@ + diff --git a/interface/web/admin/lib/lang/cz_remote_action.lng b/interface/web/admin/lib/lang/cz_remote_action.lng index 5f7fb604fc..1ce30b73b4 100644 --- a/interface/web/admin/lib/lang/cz_remote_action.lng +++ b/interface/web/admin/lib/lang/cz_remote_action.lng @@ -8,4 +8,4 @@ $wb['do_ispcupdate_desc'] = 'Tato akce provede \"ISPConfig 3\" aktualizaci na va $wb['action_scheduled'] = 'Akce je naplánována na provedení'; $wb['select_all_server'] = 'VÅ¡echny servery'; $wb['ispconfig_update_title'] = 'ISPConfig pokyny k aktualizaci'; -$wb['ispconfig_update_text'] = 'PÅ™ihlaste se jako uživatel root na terminal (shell) serveru a proveÄte příkaz

ispconfig_update.sh

spustí se ISPConfig aktualizace.

KliknÄ›te zde pro podrobnÄ›jší informace o provedení aktualizace'; +$wb['ispconfig_update_text'] = 'PÅ™ihlaste se jako uživatel root na terminal (shell) serveru a proveÄte příkaz

ispconfig_update.sh

spustí se ISPConfig aktualizace.

KliknÄ›te zde pro podrobnÄ›jší informace o provedení aktualizace'; diff --git a/interface/web/admin/lib/lang/cz_server.lng b/interface/web/admin/lib/lang/cz_server.lng index e213853198..61268a2d8e 100644 --- a/interface/web/admin/lib/lang/cz_server.lng +++ b/interface/web/admin/lib/lang/cz_server.lng @@ -13,3 +13,5 @@ $wb['- None -'] = '- Žádný -'; $wb['proxy_server_txt'] = 'Proxy-Server'; $wb['firewall_server_txt'] = 'Firewall-Server'; $wb['xmpp_server_txt'] = 'XMPP Server'; +$wb['server_name_error_regex'] = 'Neplatný název serveru. Povoleny jsou pouze písmena, Äísla, mezery, pomlÄky, teÄky, podtržítka a závorky.'; +?> diff --git a/interface/web/admin/lib/lang/cz_server_config.lng b/interface/web/admin/lib/lang/cz_server_config.lng index bdc1152cbc..7d00bc03d8 100644 --- a/interface/web/admin/lib/lang/cz_server_config.lng +++ b/interface/web/admin/lib/lang/cz_server_config.lng @@ -150,10 +150,11 @@ $wb['php_fpm_socket_dir_error_empty'] = 'PHP-FPM adresář pro socket je prázdn $wb['try_rescue_txt'] = 'Povolit monitorování služeb a restartovat pÅ™i selhání'; $wb['do_not_try_rescue_mysql_txt'] = 'Zakázat MySQL monitorování'; $wb['do_not_try_rescue_mail_txt'] = 'Zakázat E-mail monitorování'; -$wb['rescue_description_txt'] = 'Informace: Pokud chcete napÅ™. vypnout MySQL službu zatrhnÄ›te políÄko \"Zakázat MySQL monitorování\" zmÄ›na se provede do 2-3 minut.
Pokud nepoÄkáte 2-3 minuty, monitorování nastartuje službu MySQL automaticky znovu !'; +$wb['rescue_description_txt'] = 'Informace: Pokud chcete napÅ™. vypnout MySQL službu zatrhnÄ›te políÄko "Zakázat MySQL monitorování" zmÄ›na se provede do 2-3 minut.
Pokud nepoÄkáte 2-3 minuty, monitorování nastartuje službu MySQL automaticky znovu !'; $wb['enable_sni_txt'] = 'Aktivovat SNI (Server Name Indication)'; $wb['do_not_try_rescue_httpd_txt'] = 'Zakázat HTTPD monitorování'; $wb['set_folder_permissions_on_update_txt'] = 'Nastavení oprávnÄ›ní složky pÅ™i aktualizaci'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Add web users to -sshusers- group'; $wb['connect_userid_to_webid_txt'] = 'Connect Linux userid to webid'; $wb['connect_userid_to_webid_start_txt'] = 'Start ID for userid/webid connect'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -342,5 +344,30 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'Ne, odstranit soubory s pevným odkazem'; $wb['jailkit_hardlinks_yes_txt'] = 'Ano, pokud je to možné, použijte pevné odkazy'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Number of ISPConfig backups'; +$wb['sysbackup_copies_error_empty'] = 'Number of ISPConfig backups must not be empty'; +$wb['sysbackup_copies_error_regex'] = 'Number of ISPConfig backups must be a number between 1 and 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = off)'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/cz_server_php.lng b/interface/web/admin/lib/lang/cz_server_php.lng index c1c67f05ef..28de8c3472 100644 --- a/interface/web/admin/lib/lang/cz_server_php.lng +++ b/interface/web/admin/lib/lang/cz_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Aktivní'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/cz_system_config.lng b/interface/web/admin/lib/lang/cz_system_config.lng index fb0e65d5e7..aecf6c5fbe 100644 --- a/interface/web/admin/lib/lang/cz_system_config.lng +++ b/interface/web/admin/lib/lang/cz_system_config.lng @@ -108,3 +108,7 @@ $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['monitor_key_txt'] = 'Monitor keyword'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/de.lng b/interface/web/admin/lib/lang/de.lng index 92b370b19a..60ba7257b0 100644 --- a/interface/web/admin/lib/lang/de.lng +++ b/interface/web/admin/lib/lang/de.lng @@ -49,4 +49,8 @@ $wb['Do OS-Update'] = 'Betriebssystem Update'; $wb['Do ISPConfig-Update'] = 'ISPConfig Update'; $wb['Sites'] = 'Sites'; $wb['DNS'] = 'DNS'; + +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Verfügbare Erweiterungen'; +$wb['Installed Extensions'] = 'Installierte Erweiterungen'; ?> diff --git a/interface/web/admin/lib/lang/de_extension_install_list.lng b/interface/web/admin/lib/lang/de_extension_install_list.lng new file mode 100644 index 0000000000..218413674a --- /dev/null +++ b/interface/web/admin/lib/lang/de_extension_install_list.lng @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/interface/web/admin/lib/lang/de_remote_action.lng b/interface/web/admin/lib/lang/de_remote_action.lng index 324c183311..b0011d662c 100644 --- a/interface/web/admin/lib/lang/de_remote_action.lng +++ b/interface/web/admin/lib/lang/de_remote_action.lng @@ -8,5 +8,5 @@ $wb['do_ispcupdate_desc'] = 'Diese Aktion wird ein Update des ISPConfig 3 System $wb['action_scheduled'] = 'Die Aktion wurde zur Ausführung vorgemerkt'; $wb['select_all_server'] = 'Alle Server'; $wb['ispconfig_update_title'] = 'ISPConfig 3 Update Anweisungen'; -$wb['ispconfig_update_text'] = 'Melden Sie sich auf Ihrem Server als root an und führen Sie folgendes Kommando auf der Shell aus

ispconfig_update.sh

um das ISPConfig Update zu starten.

Klicken Sie hier um eine detailierte Beschreibung zu erhalten'; +$wb['ispconfig_update_text'] = 'Melden Sie sich auf Ihrem Server als root an und führen Sie folgendes Kommando auf der Shell aus

ispconfig_update.sh

um das ISPConfig Update zu starten.

Klicken Sie hier um eine detailierte Beschreibung zu erhalten'; ?> diff --git a/interface/web/admin/lib/lang/de_server.lng b/interface/web/admin/lib/lang/de_server.lng index b32a67bdfc..2397de5483 100644 --- a/interface/web/admin/lib/lang/de_server.lng +++ b/interface/web/admin/lib/lang/de_server.lng @@ -13,4 +13,5 @@ $wb['- None -'] = '- Nichts ausgewählt -'; $wb['proxy_server_txt'] = 'Proxy Server'; $wb['firewall_server_txt'] = 'Firewall Server'; $wb['xmpp_server_txt'] = 'XMPP Server'; +$wb['server_name_error_regex'] = 'Ungültiger Servername. Nur Buchstaben, Zahlen, Leerzeichen, Bindestriche, Punkte, Unterstriche und Klammern sind erlaubt.'; ?> diff --git a/interface/web/admin/lib/lang/de_server_config.lng b/interface/web/admin/lib/lang/de_server_config.lng index 42046a2e44..5986a84b78 100644 --- a/interface/web/admin/lib/lang/de_server_config.lng +++ b/interface/web/admin/lib/lang/de_server_config.lng @@ -175,6 +175,7 @@ $wb['do_not_try_rescue_mail_txt'] = 'Deaktiviere E-Mail Monitoring'; $wb['rescue_description_txt'] = 'Information: Falls Sie MySQL stoppen möchten, wählen Sie die Funktion \'Deaktiviere MySQL Monitoring\' und warten Sie 2 bis 3 Minuten. Wenn Sie nicht 2 bis 3 Minuten warten wird ISPConfig versuchen MySQL wieder zu starten.'; $wb['enable_sni_txt'] = 'Aktiviere SNI'; $wb['set_folder_permissions_on_update_txt'] = 'Verzeichnisberechtigungen beim Update setzen'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Webbenutzer zur -sshusers- hinzufügen'; $wb['connect_userid_to_webid_txt'] = 'Linux Userid mit webid verknüpfen'; $wb['connect_userid_to_webid_start_txt'] = 'Start ID für userid/webid Verknüpfung'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys Template'; @@ -343,4 +345,29 @@ $wb['jailkit_hardlinks_allow_txt'] = 'Erlaube hardlinks innerhalb des Jails'; $wb['jailkit_hardlinks_no_txt'] = 'Nein, entferne hardgelinkte Dateien'; $wb['jailkit_hardlinks_yes_txt'] = 'Ja, benutze hardlinks wenn möglich'; $wb['mailbox_soft_delete_txt'] = 'Postfach Soft-Löschung'; -$wb['mailbox_soft_delete_info_txt'] = 'wird standardmäßig nach 7 Tagen gelöscht.'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Datenbank'; +$wb['sysbackup_copies_txt'] = 'Anzahl der ISPConfig Sicherungen (0 = aus)'; +$wb['sysbackup_copies_error_empty'] = 'Anzahl der ISPConfig Sicherungen darf nicht leer sein'; +$wb['sysbackup_copies_error_regex'] = 'Anzahl der ISPConfig Sicherungen muss eine Zahl zwischen 1 und 3 sein'; +$wb['sysbackup_copies_note_txt'] = '(0 = aus)'; +$wb['le_signature_type_txt'] = 'Zertifikat Signaturtyp'; +$wb['le_auto_cleanup_txt'] = 'Entferne unbenutzte Let\'s Encrypt Zertifikate automatisch'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains die nie entfernt werden sollen'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Komma-separierte Liste von Domain-Globs, die niemals entfernt werden sollen.
Z.B. mail.*, externally-managed.example.com
Platzhalter:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Domain-Glob Liste ungültig'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/de_server_php.lng b/interface/web/admin/lib/lang/de_server_php.lng index b3ad5d9913..1bb5e069db 100644 --- a/interface/web/admin/lib/lang/de_server_php.lng +++ b/interface/web/admin/lib/lang/de_server_php.lng @@ -5,8 +5,8 @@ $wb['name_txt'] = 'PHP Name'; $wb['Name'] = 'Name'; $wb['FastCGI Settings'] = 'FastCGI Einstellungen'; $wb['PHP-FPM Settings'] = 'PHP-FPM Einstellungen'; -$wb['Additional PHP Versions'] = 'Zusätzliche PHP Versionen'; -$wb['Form to edit additional PHP versions'] = 'Formular, um zusätzliche PHP Versionen hinzuzufügen'; +$wb['Additional PHP Versions'] = 'Zusätzliche PHP-Versionen'; +$wb['Form to edit additional PHP versions'] = 'Formular, um zusätzliche PHP-Versionen hinzuzufügen'; $wb['server_php_name_error_empty'] = 'Das Name Feld darf nicht leer sein.'; $wb['php_fastcgi_binary_txt'] = 'Pfad zum PHP FastCGI Binary'; $wb['php_fastcgi_ini_dir_txt'] = 'Pfad zum php.ini Verzeichnis'; @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Aktiv'; $wb['php_in_use_error'] = 'Diese PHP-Version wird noch benutzt.'; $wb['php_name_in_use_error'] = 'Der Name kann nicht geändert werden.'; +$wb['PHP Sort Priority'] = 'Priorität'; +$wb['sortprio_txt'] = 'Sortieren Priorität'; +$wb['sortprio_long_txt'] = 'Priorität der PHP-Version im Auswahlfeld für die PHP-Version
Standardmäßig hat PHP die Priorität 0, wenn es aktiviert ist
Ein kleinerer Wert bedeutet eine höhere Priorität'; +$wb['PHP-CLI settings'] = 'PHP-CLI-Einstellungen'; +$wb['php_cli_binary_txt'] = 'Pfad zur PHP-CLI Binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Vollständiger Pfad zur PHP-CLI Binary (inkl. Dateinamen)'; +$wb['php_jk_section_txt'] = 'PHP Jailkit Sektion'; +$wb['tooltip_php_jk_section_txt'] = 'Bezeichner der PHP-Version in der jk_init.ini (Angabe ohne eckige Klammern)'; +$wb['php_cli_jk_section_error_regex'] = 'Ungültige Jaikit chroot-Sektion'; +$wb['php_cli_binary_error_regex'] = 'Ungültiger Pfad zur PHP-CLI-Binary'; +$wb['php_cli_binary_empty'] = 'Das Feld PHP-CLI-Binary darf nicht leer sein.'; +$wb['php_cli_jk_section_empty'] = 'Das Feld PHP Jailkit-Sektion darf nicht leer sein.'; ?> 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 f9da54d84c..6b0a084746 100644 --- a/interface/web/admin/lib/lang/de_server_php_list.lng +++ b/interface/web/admin/lib/lang/de_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Kunde'; $wb['name_txt'] = 'PHP Name'; $wb['active_txt'] = 'Aktiv'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/de_system_config.lng b/interface/web/admin/lib/lang/de_system_config.lng index ed4c26f61d..39e5d57287 100644 --- a/interface/web/admin/lib/lang/de_system_config.lng +++ b/interface/web/admin/lib/lang/de_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Automatische Erstellung des CAA-Records bei LE Ausstellung aktivieren'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Datenbank'; diff --git a/interface/web/admin/lib/lang/dk.lng b/interface/web/admin/lib/lang/dk.lng index 2e07b64fb0..92b1493e7c 100644 --- a/interface/web/admin/lib/lang/dk.lng +++ b/interface/web/admin/lib/lang/dk.lng @@ -49,4 +49,8 @@ $wb['Do OS-Update'] = 'Udfør OS-Opdatering'; $wb['Do ISPConfig-Update'] = 'Udfør ISPConfig-Opdatering'; $wb['Sites'] = 'Sites'; $wb['DNS'] = 'DNS'; + +$wb['Extension Installer'] = 'Instalátor rozšíření'; +$wb['Available Extensions'] = 'Dostupná rozšíření'; +$wb['Installed Extensions'] = 'Nainstalovaná rozšíření'; ?> diff --git a/interface/web/admin/lib/lang/dk_extension_install_list.lng b/interface/web/admin/lib/lang/dk_extension_install_list.lng new file mode 100644 index 0000000000..274ae208fe --- /dev/null +++ b/interface/web/admin/lib/lang/dk_extension_install_list.lng @@ -0,0 +1,48 @@ + diff --git a/interface/web/admin/lib/lang/dk_remote_action.lng b/interface/web/admin/lib/lang/dk_remote_action.lng index 53c12f6adf..4725ae3c7a 100644 --- a/interface/web/admin/lib/lang/dk_remote_action.lng +++ b/interface/web/admin/lib/lang/dk_remote_action.lng @@ -8,5 +8,5 @@ $wb['do_ispcupdate_desc'] = 'Denne Handling udfør en ISPConfig 3 opdatering på $wb['action_scheduled'] = 'Handlingen er planlagt til udførelse'; $wb['select_all_server'] = 'Alle servere'; $wb['ispconfig_update_title'] = 'ISPConfig opdateringsinstruktioner'; -$wb['ispconfig_update_text'] = 'Log ind som root-bruger på Shell af din server og udføre kommandoen

ispconfig_update.sh

for at starte ISPConfig opdateringen.

Klik her for detaljerede opdateringsinstruktioner'; +$wb['ispconfig_update_text'] = 'Log ind som root-bruger på Shell af din server og udføre kommandoen

ispconfig_update.sh

for at starte ISPConfig opdateringen.

Klik her for detaljerede opdateringsinstruktioner'; ?> diff --git a/interface/web/admin/lib/lang/dk_server.lng b/interface/web/admin/lib/lang/dk_server.lng index 63145e8b7e..ce2db731c8 100644 --- a/interface/web/admin/lib/lang/dk_server.lng +++ b/interface/web/admin/lib/lang/dk_server.lng @@ -13,4 +13,5 @@ $wb['active_txt'] = 'Aktiv'; $wb['mirror_server_id_txt'] = 'Er spejl af Server'; $wb['- None -'] = '- Ingen -'; $wb['xmpp_server_txt'] = 'XMPP Server'; +$wb['server_name_error_regex'] = 'Ugyldigt servernavn. Kun bogstaver, tal, mellemrum, bindestreger, punkter, understreger og parenteser er tilladt.'; ?> diff --git a/interface/web/admin/lib/lang/dk_server_config.lng b/interface/web/admin/lib/lang/dk_server_config.lng index d7b081150d..88f1b4d995 100644 --- a/interface/web/admin/lib/lang/dk_server_config.lng +++ b/interface/web/admin/lib/lang/dk_server_config.lng @@ -164,6 +164,7 @@ $wb['do_not_try_rescue_mail_txt'] = 'Deaktiver E-mail monitoring'; $wb['rescue_description_txt'] = 'Information: Hvis du ønsker nedlukning af mysql skal du vælge \\"Deaktiver MySQL monitor\\" afkrydsningsfeltet og derefter vente 2-3 minutter.
Hvis du ikke vente 2-3 minutter, vil redning forsøge at genstarte mysql!'; $wb['enable_sni_txt'] = 'Enable SNI'; $wb['set_folder_permissions_on_update_txt'] = 'Indstil mappe tilladelser ved opdatering'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Tilføj web-brugere til -sshusers- gruppe'; $wb['connect_userid_to_webid_txt'] = 'Forbinde Linux brugerid til webid'; $wb['connect_userid_to_webid_start_txt'] = 'Start ID for brugerid/webid forbinde'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -342,5 +344,30 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Number of ISPConfig backups'; +$wb['sysbackup_copies_error_empty'] = 'Number of ISPConfig backups must not be empty'; +$wb['sysbackup_copies_error_regex'] = 'Number of ISPConfig backups must be a number between 1 and 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = off)'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/dk_server_php.lng b/interface/web/admin/lib/lang/dk_server_php.lng index db6ef1f98a..29f6ae085c 100644 --- a/interface/web/admin/lib/lang/dk_server_php.lng +++ b/interface/web/admin/lib/lang/dk_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Active'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/dk_server_php_list.lng b/interface/web/admin/lib/lang/dk_server_php_list.lng index 65869ce2ed..4be3b3446b 100644 --- a/interface/web/admin/lib/lang/dk_server_php_list.lng +++ b/interface/web/admin/lib/lang/dk_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Kunde'; $wb['name_txt'] = 'PHP Navn'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/dk_system_config.lng b/interface/web/admin/lib/lang/dk_system_config.lng index 971253aae7..682264475b 100644 --- a/interface/web/admin/lib/lang/dk_system_config.lng +++ b/interface/web/admin/lib/lang/dk_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/el.lng b/interface/web/admin/lib/lang/el.lng index 0f26e0fbe9..c7e8691cd0 100644 --- a/interface/web/admin/lib/lang/el.lng +++ b/interface/web/admin/lib/lang/el.lng @@ -49,4 +49,8 @@ $wb['Do ISPConfig-Update'] = 'Αναβάθμιση ISPConfig'; $wb['Directive Snippets'] = 'Directive Snippets'; $wb['Sites'] = 'Sites'; $wb['DNS'] = 'DNS'; + +$wb['Extension Installer'] = 'Instalátor rozšíření'; +$wb['Available Extensions'] = 'Dostupná rozšíření'; +$wb['Installed Extensions'] = 'Nainstalovaná rozšíření'; ?> diff --git a/interface/web/admin/lib/lang/el_extension_install_list.lng b/interface/web/admin/lib/lang/el_extension_install_list.lng new file mode 100644 index 0000000000..f5a7270fce --- /dev/null +++ b/interface/web/admin/lib/lang/el_extension_install_list.lng @@ -0,0 +1,55 @@ + \ No newline at end of file diff --git a/interface/web/admin/lib/lang/el_server.lng b/interface/web/admin/lib/lang/el_server.lng index 560765e15b..21c2f1439c 100644 --- a/interface/web/admin/lib/lang/el_server.lng +++ b/interface/web/admin/lib/lang/el_server.lng @@ -13,4 +13,5 @@ $wb['- None -'] = '- Κανενός -'; $wb['proxy_server_txt'] = 'Proxy-Server'; $wb['firewall_server_txt'] = 'Firewall-Server'; $wb['xmpp_server_txt'] = 'XMPP Server'; +$wb['server_name_error_regex'] = 'Μη έγκυÏο όνομα διακομιστή. ΕπιτÏέπονται μόνο γÏάμματα, αÏιθμοί, κενά, παÏλες, τελείες, κάτω παÏλες και παÏενθέσεις.'; ?> diff --git a/interface/web/admin/lib/lang/el_server_config.lng b/interface/web/admin/lib/lang/el_server_config.lng index 40af42057f..30a412e545 100644 --- a/interface/web/admin/lib/lang/el_server_config.lng +++ b/interface/web/admin/lib/lang/el_server_config.lng @@ -168,6 +168,7 @@ $wb['rescue_description_txt'] = 'ΠληÏοφοÏία: Αν θέλετε $wb['enable_sni_txt'] = 'ΕνεÏγοποίηση SNI'; $wb['do_not_try_rescue_httpd_txt'] = 'ΑπενεÏγοποίηση εποπτείας HTTPD'; $wb['set_folder_permissions_on_update_txt'] = 'Set folder permissions on update'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Add web users to -sshusers- group'; $wb['connect_userid_to_webid_txt'] = 'Connect Linux userid to webid'; $wb['connect_userid_to_webid_start_txt'] = 'Start ID for userid/webid connect'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -342,5 +344,30 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Number of ISPConfig backups'; +$wb['sysbackup_copies_error_empty'] = 'Number of ISPConfig backups must not be empty'; +$wb['sysbackup_copies_error_regex'] = 'Number of ISPConfig backups must be a number between 1 and 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = off)'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/el_server_php.lng b/interface/web/admin/lib/lang/el_server_php.lng index 491be1aae2..1a7420fb21 100644 --- a/interface/web/admin/lib/lang/el_server_php.lng +++ b/interface/web/admin/lib/lang/el_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Active'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/el_server_php_list.lng b/interface/web/admin/lib/lang/el_server_php_list.lng index 291302cbb7..d5e6ad3c7f 100644 --- a/interface/web/admin/lib/lang/el_server_php_list.lng +++ b/interface/web/admin/lib/lang/el_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Client'; $wb['name_txt'] = 'PHP Name'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/el_system_config.lng b/interface/web/admin/lib/lang/el_system_config.lng index 8bfe8012de..87bd0267e6 100644 --- a/interface/web/admin/lib/lang/el_system_config.lng +++ b/interface/web/admin/lib/lang/el_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/en.lng b/interface/web/admin/lib/lang/en.lng index 6d145dd5d4..74d2c8dea8 100644 --- a/interface/web/admin/lib/lang/en.lng +++ b/interface/web/admin/lib/lang/en.lng @@ -61,4 +61,8 @@ $wb['Import'] = 'Import'; $wb['Remote Actions'] = 'Remote Actions'; $wb['Do OS-Update'] = 'Do OS-Update'; $wb['Do ISPConfig-Update'] = 'Do ISPConfig-Update'; + +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Available Extensions'; +$wb['Installed Extensions'] = 'Installed Extensions'; ?> diff --git a/interface/web/admin/lib/lang/en_extension_install_list.lng b/interface/web/admin/lib/lang/en_extension_install_list.lng new file mode 100644 index 0000000000..f5a7270fce --- /dev/null +++ b/interface/web/admin/lib/lang/en_extension_install_list.lng @@ -0,0 +1,55 @@ + \ No newline at end of file diff --git a/interface/web/admin/lib/lang/en_server.lng b/interface/web/admin/lib/lang/en_server.lng index d85a16d3a9..820a10f0ec 100644 --- a/interface/web/admin/lib/lang/en_server.lng +++ b/interface/web/admin/lib/lang/en_server.lng @@ -14,4 +14,5 @@ $wb['mirror_server_id_txt'] = 'Is mirror of Server'; $wb['- None -'] = '- None -'; // New for XMPP $wb['xmpp_server_txt'] = 'XMPP Server'; +$wb['server_name_error_regex'] = 'Invalid server name. Only letters, numbers, spaces, hyphens, dots, underscores and parentheses are allowed.'; ?> \ 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 363f528fba..2e35c78baa 100644 --- a/interface/web/admin/lib/lang/en_server_config.lng +++ b/interface/web/admin/lib/lang/en_server_config.lng @@ -91,6 +91,8 @@ $wb['apps_vhost_servername_txt'] = 'Apps-vhost Domain'; $wb['bind_user_txt'] = 'BIND User'; $wb['bind_group_txt'] = 'BIND Group'; $wb['bind_zonefiles_dir_txt'] = 'BIND zonefiles directory'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; $wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; $wb['named_conf_path_txt'] = 'BIND named.conf path'; $wb['bind_user_error_empty'] = 'BIND user is empty.'; @@ -190,6 +192,7 @@ $wb['do_not_try_rescue_mail_txt'] = 'Disable Email monitoring'; $wb['rescue_description_txt'] = 'If you want to shut down MySQL you have to select the "Disable MySQL monitor" checkbox and then wait 2-3 minutes. If you do not wait 2-3 minutes, rescue will try to restart MySQL!'; $wb['enable_sni_txt'] = 'Enable SNI'; $wb['set_folder_permissions_on_update_txt'] = 'Set folder permissions on update'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Add web users to -sshusers- group'; $wb['connect_userid_to_webid_txt'] = 'Connect Linux userid to webid'; $wb['connect_userid_to_webid_start_txt'] = 'Start ID for userid/webid connect'; @@ -206,6 +209,7 @@ $wb['firewall_txt'] = 'Firewall'; $wb['mailbox_quota_stats_txt'] = 'Mailbox quota statistics'; $wb['enable_ip_wildcard_txt'] = 'Enable IP wildcard (*)'; $wb['web_folder_protection_txt'] = 'Make web folders immutable (extended attributes)'; +$wb['web_folder_permission_txt'] = 'Default permission for the web folder'; $wb['overtraffic_notify_admin_txt'] = 'Send overtraffic notification to admin'; $wb['overtraffic_notify_reseller_txt'] = 'Send overtraffic notification to reseller'; $wb['overtraffic_notify_client_txt'] = 'Send overtraffic notification to client'; @@ -283,6 +287,8 @@ $wb['awstats_buildstaticpages_pl_error_regex'] = 'Invalid awstats_buildstaticpag $wb['invalid_bind_user_txt'] = 'Invalid BIND user.'; $wb['invalid_bind_group_txt'] = 'Invalid BIND group.'; $wb['bind_zonefiles_dir_error_regex'] = 'Invalid BIND zonefiles directory.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; $wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['named_conf_path_error_regex'] = 'Invalid named.conf path.'; $wb['named_conf_local_path_error_regex'] = 'Invalid named.conf.local path.'; @@ -344,6 +350,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot'; @@ -352,4 +359,22 @@ $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Number of ISPConfig backups'; +$wb['sysbackup_copies_error_empty'] = 'Number of ISPConfig backups must not be empty'; +$wb['sysbackup_copies_error_regex'] = 'Number of ISPConfig backups must be a number between 1 and 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = off)'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/en_server_php.lng b/interface/web/admin/lib/lang/en_server_php.lng index 491be1aae2..1a7420fb21 100644 --- a/interface/web/admin/lib/lang/en_server_php.lng +++ b/interface/web/admin/lib/lang/en_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Active'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> 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 291302cbb7..d5e6ad3c7f 100644 --- a/interface/web/admin/lib/lang/en_server_php_list.lng +++ b/interface/web/admin/lib/lang/en_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Client'; $wb['name_txt'] = 'PHP Name'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/en_system_config.lng b/interface/web/admin/lib/lang/en_system_config.lng index 9cf04103bb..7a63da9fea 100644 --- a/interface/web/admin/lib/lang/en_system_config.lng +++ b/interface/web/admin/lib/lang/en_system_config.lng @@ -108,4 +108,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/es.lng b/interface/web/admin/lib/lang/es.lng index efce31d6db..79024ee5fa 100644 --- a/interface/web/admin/lib/lang/es.lng +++ b/interface/web/admin/lib/lang/es.lng @@ -49,4 +49,8 @@ $wb['System'] = 'Sistema'; $wb['Updates'] = 'Actualizaciones'; $wb['User Management'] = 'Administrador de usuarios'; $wb['Web'] = 'Web'; + +$wb['Extension Installer'] = 'Instalador de extensiones'; +$wb['Available Extensions'] = 'Extensiones disponibles'; +$wb['Installed Extensions'] = 'Extensiones instaladas'; ?> diff --git a/interface/web/admin/lib/lang/es_extension_install_list.lng b/interface/web/admin/lib/lang/es_extension_install_list.lng new file mode 100644 index 0000000000..18422133e1 --- /dev/null +++ b/interface/web/admin/lib/lang/es_extension_install_list.lng @@ -0,0 +1,48 @@ + diff --git a/interface/web/admin/lib/lang/es_remote_action.lng b/interface/web/admin/lib/lang/es_remote_action.lng index 0e7997d049..a0e31a6870 100644 --- a/interface/web/admin/lib/lang/es_remote_action.lng +++ b/interface/web/admin/lib/lang/es_remote_action.lng @@ -5,7 +5,7 @@ $wb['do_ispcupdate_caption'] = 'Realizar actualización de ISPConfig 3 en el ser $wb['do_ispcupdate_desc'] = 'Esta acción realizará una actualización de ISPConfig 3 en el servidor seleccionado.

¡USE ESTO BAJO SU PROPIA RESPONSABILIDAD!'; $wb['do_osupdate_caption'] = 'Ejecutar actualización de S.O. al servidor remoto'; $wb['do_osupdate_desc'] = 'Esta acción realizará un \'apt -y upgrade\' en el servidor seleccionado.

¡USE ESTO BAJO SU PROPIA RESPONSABILIDAD!'; -$wb['ispconfig_update_text'] = 'Inicie sesión como root en el shell de su servidor y ejecute el comando

ispconfig_update.sh

para iniciar la actualización de ISPConfig.

Pulse aquí para ver una descripción detallada de cómo actualizar'; +$wb['ispconfig_update_text'] = 'Inicie sesión como root en el shell de su servidor y ejecute el comando

ispconfig_update.sh

para iniciar la actualización de ISPConfig.

Pulse aquí para ver una descripción detallada de cómo actualizar'; $wb['ispconfig_update_title'] = 'Instrucciones de actualización de ISPConfig'; $wb['select_all_server'] = 'Todos los servidores'; $wb['select_server_txt'] = 'Seleccione un servidor'; diff --git a/interface/web/admin/lib/lang/es_server.lng b/interface/web/admin/lib/lang/es_server.lng index 844357878a..229fc4bdab 100644 --- a/interface/web/admin/lib/lang/es_server.lng +++ b/interface/web/admin/lib/lang/es_server.lng @@ -13,4 +13,5 @@ $wb['server_name_txt'] = 'Nombre del servidor'; $wb['vserver_server_txt'] = 'Servidor VServer'; $wb['web_server_txt'] = 'Servidor web'; $wb['xmpp_server_txt'] = 'Servidor XMPP'; +$wb['server_name_error_regex'] = 'Nombre de servidor inválido. Solo se permiten letras, números, espacios, guiones, puntos, guiones bajos y paréntesis.'; ?> diff --git a/interface/web/admin/lib/lang/es_server_config.lng b/interface/web/admin/lib/lang/es_server_config.lng index 528dfe36af..17b5ac567e 100644 --- a/interface/web/admin/lib/lang/es_server_config.lng +++ b/interface/web/admin/lib/lang/es_server_config.lng @@ -255,6 +255,7 @@ $wb['rescue_description_txt'] = 'Información: Si desea detener el servic $wb['security_level_txt'] = 'Nivel de seguridad'; $wb['server_type_txt'] = 'Tipo de servidor'; $wb['set_folder_permissions_on_update_txt'] = 'Establecer permisos de carpetas al actualizar'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['ssl_settings_txt'] = 'Opciones de SSL'; $wb['try_rescue_txt'] = 'Habilitar monitorización y reinicio en caso de fallo'; $wb['ufw_default_application_policy_txt'] = 'Directiva predeterminada de aplicación'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -342,5 +344,30 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Número de copias de seguridad del sistema'; +$wb['sysbackup_copies_error_empty'] = 'El número de copias de seguridad del sistema no debe estar vacío'; +$wb['sysbackup_copies_error_regex'] = 'El número de copias de seguridad del sistema debe ser un número entre 1 y 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = desactivado)'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/es_server_php.lng b/interface/web/admin/lib/lang/es_server_php.lng index df2f0778f4..60f4be0c1d 100644 --- a/interface/web/admin/lib/lang/es_server_php.lng +++ b/interface/web/admin/lib/lang/es_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Active'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/es_server_php_list.lng b/interface/web/admin/lib/lang/es_server_php_list.lng index 8d62ee8919..1efd239d31 100644 --- a/interface/web/admin/lib/lang/es_server_php_list.lng +++ b/interface/web/admin/lib/lang/es_server_php_list.lng @@ -6,4 +6,5 @@ $wb['name_txt'] = 'Versión de PHP'; $wb['server_id_txt'] = 'Servidor'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/es_system_config.lng b/interface/web/admin/lib/lang/es_system_config.lng index 844c19db58..b62e52b774 100644 --- a/interface/web/admin/lib/lang/es_system_config.lng +++ b/interface/web/admin/lib/lang/es_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/fi.lng b/interface/web/admin/lib/lang/fi.lng index 5037b98314..b0aab544ec 100644 --- a/interface/web/admin/lib/lang/fi.lng +++ b/interface/web/admin/lib/lang/fi.lng @@ -49,4 +49,8 @@ $wb['Do ISPConfig-Update'] = 'Do ISPConfig-Update'; $wb['Directive Snippets'] = 'Directive Snippets'; $wb['Sites'] = 'Sites'; $wb['DNS'] = 'DNS'; + +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Available Extensions'; +$wb['Installed Extensions'] = 'Installed Extensions'; ?> diff --git a/interface/web/admin/lib/lang/fi_remote_action.lng b/interface/web/admin/lib/lang/fi_remote_action.lng index dfe56b616d..aeb7a78537 100644 --- a/interface/web/admin/lib/lang/fi_remote_action.lng +++ b/interface/web/admin/lib/lang/fi_remote_action.lng @@ -8,5 +8,5 @@ $wb['do_ispcupdate_desc'] = 'This action does a ISPConfig3 update at your select $wb['action_scheduled'] = 'The action is scheduled for execution'; $wb['select_all_server'] = 'All server'; $wb['ispconfig_update_title'] = 'ISPConfig update instructions'; -$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; +$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; ?> diff --git a/interface/web/admin/lib/lang/fi_server.lng b/interface/web/admin/lib/lang/fi_server.lng index e1110bdf74..400c3f2c5b 100644 --- a/interface/web/admin/lib/lang/fi_server.lng +++ b/interface/web/admin/lib/lang/fi_server.lng @@ -13,4 +13,5 @@ $wb['- None -'] = '- Ei mikään -'; $wb['proxy_server_txt'] = 'Proxy-Server'; $wb['firewall_server_txt'] = 'Firewall-Server'; $wb['xmpp_server_txt'] = 'XMPP Server'; +$wb['server_name_error_regex'] = 'Virheellinen palvelimen nimi. Vain kirjaimet, numerot, välilyönnit, viivat, pisteet, alaviivat ja sulkeet ovat sallittuja.'; ?> diff --git a/interface/web/admin/lib/lang/fi_server_config.lng b/interface/web/admin/lib/lang/fi_server_config.lng index 906013f785..6751e66a89 100644 --- a/interface/web/admin/lib/lang/fi_server_config.lng +++ b/interface/web/admin/lib/lang/fi_server_config.lng @@ -168,6 +168,7 @@ $wb['rescue_description_txt'] = 'Information: If you want to shut down my $wb['enable_sni_txt'] = 'Enable SNI'; $wb['do_not_try_rescue_httpd_txt'] = 'Disable HTTPD monitoring'; $wb['set_folder_permissions_on_update_txt'] = 'Set folder permissions on update'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Add web users to -sshusers- group'; $wb['connect_userid_to_webid_txt'] = 'Connect Linux userid to webid'; $wb['connect_userid_to_webid_start_txt'] = 'Start ID for userid/webid connect'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -342,5 +344,30 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Number of ISPConfig backups'; +$wb['sysbackup_copies_error_empty'] = 'Number of ISPConfig backups must not be empty'; +$wb['sysbackup_copies_error_regex'] = 'Number of ISPConfig backups must be a number between 1 and 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = off)'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/fi_server_php.lng b/interface/web/admin/lib/lang/fi_server_php.lng index 491be1aae2..1a7420fb21 100644 --- a/interface/web/admin/lib/lang/fi_server_php.lng +++ b/interface/web/admin/lib/lang/fi_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Active'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/fi_server_php_list.lng b/interface/web/admin/lib/lang/fi_server_php_list.lng index 291302cbb7..d5e6ad3c7f 100644 --- a/interface/web/admin/lib/lang/fi_server_php_list.lng +++ b/interface/web/admin/lib/lang/fi_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Client'; $wb['name_txt'] = 'PHP Name'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/fi_system_config.lng b/interface/web/admin/lib/lang/fi_system_config.lng index 4b4bf32cc0..cde97192b4 100644 --- a/interface/web/admin/lib/lang/fi_system_config.lng +++ b/interface/web/admin/lib/lang/fi_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/fr.lng b/interface/web/admin/lib/lang/fr.lng index 7743f5d0e9..93dec8bfa4 100644 --- a/interface/web/admin/lib/lang/fr.lng +++ b/interface/web/admin/lib/lang/fr.lng @@ -49,4 +49,7 @@ $wb['Do ISPConfig-Update'] = 'Mise à jour ISPConfig'; $wb['Directive Snippets'] = 'Directive Snippets'; $wb['Sites'] = 'Sites'; $wb['DNS'] = 'DNS'; +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Available Extensions'; +$wb['Installed Extensions'] = 'Installed Extensions'; ?> diff --git a/interface/web/admin/lib/lang/fr_extension_install_list.lng b/interface/web/admin/lib/lang/fr_extension_install_list.lng new file mode 100644 index 0000000000..b6b2554dbb --- /dev/null +++ b/interface/web/admin/lib/lang/fr_extension_install_list.lng @@ -0,0 +1,48 @@ + diff --git a/interface/web/admin/lib/lang/fr_remote_action.lng b/interface/web/admin/lib/lang/fr_remote_action.lng index ca4dc85ddd..9656e1e586 100644 --- a/interface/web/admin/lib/lang/fr_remote_action.lng +++ b/interface/web/admin/lib/lang/fr_remote_action.lng @@ -8,5 +8,5 @@ $wb['do_ispcupdate_desc'] = 'Cette action met à jour ISPConfig3 sur le serveur $wb['action_scheduled'] = 'L’action est marquée pour exécution'; $wb['select_all_server'] = 'Tout serveur'; $wb['ispconfig_update_title'] = 'ISPConfig update instructions'; -$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; +$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; ?> diff --git a/interface/web/admin/lib/lang/fr_server.lng b/interface/web/admin/lib/lang/fr_server.lng index fe7f4a4aab..a79a80cfba 100644 --- a/interface/web/admin/lib/lang/fr_server.lng +++ b/interface/web/admin/lib/lang/fr_server.lng @@ -13,4 +13,5 @@ $wb['- None -'] = '- Aucun -'; $wb['proxy_server_txt'] = 'Proxy-Server'; $wb['firewall_server_txt'] = 'Firewall-Server'; $wb['xmpp_server_txt'] = 'XMPP Server'; +$wb['server_name_error_regex'] = 'Nom de serveur invalide. Seules les lettres, chiffres, espaces, tirets, points, underscores et parenthèses sont autorisés.'; ?> diff --git a/interface/web/admin/lib/lang/fr_server_config.lng b/interface/web/admin/lib/lang/fr_server_config.lng index 274c2b6804..119ac9e395 100644 --- a/interface/web/admin/lib/lang/fr_server_config.lng +++ b/interface/web/admin/lib/lang/fr_server_config.lng @@ -156,6 +156,7 @@ $wb['rescue_description_txt'] = 'Information: If you want to shut down my $wb['enable_sni_txt'] = 'Enable SNI'; $wb['do_not_try_rescue_httpd_txt'] = 'Disable HTTPD monitoring'; $wb['set_folder_permissions_on_update_txt'] = 'Set folder permissions on update'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Add web users to -sshusers- group'; $wb['connect_userid_to_webid_txt'] = 'Connect Linux userid to webid'; $wb['connect_userid_to_webid_start_txt'] = 'Start ID for userid/webid connect'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -342,5 +344,30 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Nombre de sauvegardes système'; +$wb['sysbackup_copies_error_empty'] = 'Le nombre de sauvegardes système ne doit pas être vide'; +$wb['sysbackup_copies_error_regex'] = 'Le nombre de sauvegardes système doit être un nombre entre 1 et 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = désactivé)'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/fr_server_php.lng b/interface/web/admin/lib/lang/fr_server_php.lng index 491be1aae2..1a7420fb21 100644 --- a/interface/web/admin/lib/lang/fr_server_php.lng +++ b/interface/web/admin/lib/lang/fr_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Active'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/fr_server_php_list.lng b/interface/web/admin/lib/lang/fr_server_php_list.lng index 291302cbb7..d5e6ad3c7f 100644 --- a/interface/web/admin/lib/lang/fr_server_php_list.lng +++ b/interface/web/admin/lib/lang/fr_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Client'; $wb['name_txt'] = 'PHP Name'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/fr_system_config.lng b/interface/web/admin/lib/lang/fr_system_config.lng index 801c27b5df..c4faa624ce 100644 --- a/interface/web/admin/lib/lang/fr_system_config.lng +++ b/interface/web/admin/lib/lang/fr_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/hr.lng b/interface/web/admin/lib/lang/hr.lng index f105e1f5e9..3e3dff6a77 100644 --- a/interface/web/admin/lib/lang/hr.lng +++ b/interface/web/admin/lib/lang/hr.lng @@ -49,4 +49,7 @@ $wb['Do ISPConfig-Update'] = 'Nadogradnja control panela'; $wb['Directive Snippets'] = 'Direktive'; $wb['Sites'] = 'Sites'; $wb['DNS'] = 'DNS'; +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Available Extensions'; +$wb['Installed Extensions'] = 'Installed Extensions'; ?> diff --git a/interface/web/admin/lib/lang/hr_extension_install_list.lng b/interface/web/admin/lib/lang/hr_extension_install_list.lng new file mode 100644 index 0000000000..f5a7270fce --- /dev/null +++ b/interface/web/admin/lib/lang/hr_extension_install_list.lng @@ -0,0 +1,55 @@ + \ No newline at end of file diff --git a/interface/web/admin/lib/lang/hr_remote_action.lng b/interface/web/admin/lib/lang/hr_remote_action.lng index d36e61de86..7710b954c7 100644 --- a/interface/web/admin/lib/lang/hr_remote_action.lng +++ b/interface/web/admin/lib/lang/hr_remote_action.lng @@ -8,5 +8,5 @@ $wb['do_ispcupdate_desc'] = 'Ovime pokrećete nadogradnju ISPConfig3-a na izabra $wb['action_scheduled'] = 'Nadogradnja je dodana u planer poslova'; $wb['select_all_server'] = 'Svi serveri'; $wb['ispconfig_update_title'] = 'Upute za ISPConfig nadogradnju'; -$wb['ispconfig_update_text'] = 'Logiraj se kao root korisnik na server (SSH) i pokreni:

ispconfig_update.sh

Pogledaj detaljne upute ovdje'; +$wb['ispconfig_update_text'] = 'Logiraj se kao root korisnik na server (SSH) i pokreni:

ispconfig_update.sh

Pogledaj detaljne upute ovdje'; ?> diff --git a/interface/web/admin/lib/lang/hr_server_config.lng b/interface/web/admin/lib/lang/hr_server_config.lng index 5d35d0d33f..70aad61dd3 100644 --- a/interface/web/admin/lib/lang/hr_server_config.lng +++ b/interface/web/admin/lib/lang/hr_server_config.lng @@ -168,6 +168,7 @@ $wb['rescue_description_txt'] = 'Informacija: Ako želite ugasiti mysql m $wb['enable_sni_txt'] = 'Omogući SNI'; $wb['do_not_try_rescue_httpd_txt'] = 'IskljuÄi HTTPD monitoriranje'; $wb['set_folder_permissions_on_update_txt'] = 'Postavi dozvole pri svakoj nadogradnji ISPConfiga'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Dodaj web korisnikeu -sshusers- grupu'; $wb['connect_userid_to_webid_txt'] = 'Spoji Linux userid u webid'; $wb['connect_userid_to_webid_start_txt'] = 'PoÄetni ID za spajanje userid/webid-a'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -342,5 +344,30 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Number of ISPConfig backups'; +$wb['sysbackup_copies_error_empty'] = 'Number of ISPConfig backups must not be empty'; +$wb['sysbackup_copies_error_regex'] = 'Number of ISPConfig backups must be a number between 1 and 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = off)'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/hr_server_php.lng b/interface/web/admin/lib/lang/hr_server_php.lng index 15ec1b30f5..b47ad3d8f9 100644 --- a/interface/web/admin/lib/lang/hr_server_php.lng +++ b/interface/web/admin/lib/lang/hr_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Active'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/hr_server_php_list.lng b/interface/web/admin/lib/lang/hr_server_php_list.lng index 1851ac8395..4e5381c1f3 100644 --- a/interface/web/admin/lib/lang/hr_server_php_list.lng +++ b/interface/web/admin/lib/lang/hr_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Klijent'; $wb['name_txt'] = 'PHP Name'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/hr_system_config.lng b/interface/web/admin/lib/lang/hr_system_config.lng index 87fcfff645..ccbc203a66 100644 --- a/interface/web/admin/lib/lang/hr_system_config.lng +++ b/interface/web/admin/lib/lang/hr_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/hu.lng b/interface/web/admin/lib/lang/hu.lng index 3864c43861..fdebfd5b23 100644 --- a/interface/web/admin/lib/lang/hu.lng +++ b/interface/web/admin/lib/lang/hu.lng @@ -49,4 +49,7 @@ $wb['Do ISPConfig-Update'] = 'ISPConfig-Frissítés'; $wb['Directive Snippets'] = 'Directive Snippets'; $wb['Sites'] = 'Sites'; $wb['DNS'] = 'DNS'; +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Available Extensions'; +$wb['Installed Extensions'] = 'Installed Extensions'; ?> diff --git a/interface/web/admin/lib/lang/hu_extension_install_list.lng b/interface/web/admin/lib/lang/hu_extension_install_list.lng new file mode 100644 index 0000000000..f5a7270fce --- /dev/null +++ b/interface/web/admin/lib/lang/hu_extension_install_list.lng @@ -0,0 +1,55 @@ + \ No newline at end of file diff --git a/interface/web/admin/lib/lang/hu_remote_action.lng b/interface/web/admin/lib/lang/hu_remote_action.lng index 03d94116b9..81c58928d9 100644 --- a/interface/web/admin/lib/lang/hu_remote_action.lng +++ b/interface/web/admin/lib/lang/hu_remote_action.lng @@ -8,5 +8,5 @@ $wb['do_ispcupdate_desc'] = 'This action does a ISPConfig3 update at your select $wb['action_scheduled'] = 'The action is scheduled for execution'; $wb['select_all_server'] = 'Összes szerver'; $wb['ispconfig_update_title'] = 'ISPConfig update instructions'; -$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; +$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; ?> diff --git a/interface/web/admin/lib/lang/hu_server_config.lng b/interface/web/admin/lib/lang/hu_server_config.lng index 74a5b15701..0fb2e37587 100644 --- a/interface/web/admin/lib/lang/hu_server_config.lng +++ b/interface/web/admin/lib/lang/hu_server_config.lng @@ -168,6 +168,7 @@ $wb['rescue_description_txt'] = 'Information: If you want to shut down my $wb['enable_sni_txt'] = 'Enable SNI'; $wb['do_not_try_rescue_httpd_txt'] = 'Disable HTTPD monitoring'; $wb['set_folder_permissions_on_update_txt'] = 'Set folder permissions on update'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Add web users to -sshusers- group'; $wb['connect_userid_to_webid_txt'] = 'Connect Linux userid to webid'; $wb['connect_userid_to_webid_start_txt'] = 'Start ID for userid/webid connect'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -342,5 +344,30 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Number of ISPConfig backups'; +$wb['sysbackup_copies_error_empty'] = 'Number of ISPConfig backups must not be empty'; +$wb['sysbackup_copies_error_regex'] = 'Number of ISPConfig backups must be a number between 1 and 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = off)'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/hu_server_php.lng b/interface/web/admin/lib/lang/hu_server_php.lng index 491be1aae2..1a7420fb21 100644 --- a/interface/web/admin/lib/lang/hu_server_php.lng +++ b/interface/web/admin/lib/lang/hu_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Active'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/hu_server_php_list.lng b/interface/web/admin/lib/lang/hu_server_php_list.lng index 291302cbb7..d5e6ad3c7f 100644 --- a/interface/web/admin/lib/lang/hu_server_php_list.lng +++ b/interface/web/admin/lib/lang/hu_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Client'; $wb['name_txt'] = 'PHP Name'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/hu_system_config.lng b/interface/web/admin/lib/lang/hu_system_config.lng index cdb3113662..648cf2beef 100644 --- a/interface/web/admin/lib/lang/hu_system_config.lng +++ b/interface/web/admin/lib/lang/hu_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/id.lng b/interface/web/admin/lib/lang/id.lng index 69201b41b1..4abc5ab4a8 100644 --- a/interface/web/admin/lib/lang/id.lng +++ b/interface/web/admin/lib/lang/id.lng @@ -49,4 +49,7 @@ $wb['Do ISPConfig-Update'] = 'Lakukan Pemutakhiran ISPConfig'; $wb['Directive Snippets'] = 'Directive Snippets'; $wb['Sites'] = 'Sites'; $wb['DNS'] = 'DNS'; +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Available Extensions'; +$wb['Installed Extensions'] = 'Installed Extensions'; ?> diff --git a/interface/web/admin/lib/lang/id_extension_install_list.lng b/interface/web/admin/lib/lang/id_extension_install_list.lng new file mode 100644 index 0000000000..f5a7270fce --- /dev/null +++ b/interface/web/admin/lib/lang/id_extension_install_list.lng @@ -0,0 +1,55 @@ + \ No newline at end of file diff --git a/interface/web/admin/lib/lang/id_remote_action.lng b/interface/web/admin/lib/lang/id_remote_action.lng index 2ddc957f63..52708365b0 100644 --- a/interface/web/admin/lib/lang/id_remote_action.lng +++ b/interface/web/admin/lib/lang/id_remote_action.lng @@ -8,5 +8,5 @@ $wb['do_ispcupdate_desc'] = 'Tindakan ini melakukan pemutakhiran ISPConfig3 di s $wb['action_scheduled'] = 'Tindakan dijadwalkan untuk dijalankan'; $wb['select_all_server'] = 'Semua server'; $wb['ispconfig_update_title'] = 'ISPConfig update instructions'; -$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; +$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; ?> diff --git a/interface/web/admin/lib/lang/id_server_config.lng b/interface/web/admin/lib/lang/id_server_config.lng index 2419ee63f1..1ec2900250 100644 --- a/interface/web/admin/lib/lang/id_server_config.lng +++ b/interface/web/admin/lib/lang/id_server_config.lng @@ -168,6 +168,7 @@ $wb['rescue_description_txt'] = 'Information: If you want to shut down my $wb['enable_sni_txt'] = 'Enable SNI'; $wb['do_not_try_rescue_httpd_txt'] = 'Disable HTTPD monitoring'; $wb['set_folder_permissions_on_update_txt'] = 'Set folder permissions on update'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Add web users to -sshusers- group'; $wb['connect_userid_to_webid_txt'] = 'Connect Linux userid to webid'; $wb['connect_userid_to_webid_start_txt'] = 'Start ID for userid/webid connect'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -342,5 +344,30 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Number of ISPConfig backups'; +$wb['sysbackup_copies_error_empty'] = 'Number of ISPConfig backups must not be empty'; +$wb['sysbackup_copies_error_regex'] = 'Number of ISPConfig backups must be a number between 1 and 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = off)'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/id_server_php.lng b/interface/web/admin/lib/lang/id_server_php.lng index 491be1aae2..1a7420fb21 100644 --- a/interface/web/admin/lib/lang/id_server_php.lng +++ b/interface/web/admin/lib/lang/id_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Active'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/id_server_php_list.lng b/interface/web/admin/lib/lang/id_server_php_list.lng index 291302cbb7..d5e6ad3c7f 100644 --- a/interface/web/admin/lib/lang/id_server_php_list.lng +++ b/interface/web/admin/lib/lang/id_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Client'; $wb['name_txt'] = 'PHP Name'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/id_system_config.lng b/interface/web/admin/lib/lang/id_system_config.lng index f9b3f87a00..be99b10113 100644 --- a/interface/web/admin/lib/lang/id_system_config.lng +++ b/interface/web/admin/lib/lang/id_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/it.lng b/interface/web/admin/lib/lang/it.lng index 5b6644cc71..71837c26e5 100644 --- a/interface/web/admin/lib/lang/it.lng +++ b/interface/web/admin/lib/lang/it.lng @@ -49,4 +49,7 @@ $wb['Do ISPConfig-Update'] = 'Aggiorna ISPconfig'; $wb['Directive Snippets'] = 'Directive Snippets'; $wb['Sites'] = 'Sites'; $wb['DNS'] = 'DNS'; +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Available Extensions'; +$wb['Installed Extensions'] = 'Installed Extensions'; ?> diff --git a/interface/web/admin/lib/lang/it_extension_install_list.lng b/interface/web/admin/lib/lang/it_extension_install_list.lng new file mode 100644 index 0000000000..5306ffa0fb --- /dev/null +++ b/interface/web/admin/lib/lang/it_extension_install_list.lng @@ -0,0 +1,45 @@ + diff --git a/interface/web/admin/lib/lang/it_remote_action.lng b/interface/web/admin/lib/lang/it_remote_action.lng index 9f43cb45fc..9100c3380b 100644 --- a/interface/web/admin/lib/lang/it_remote_action.lng +++ b/interface/web/admin/lib/lang/it_remote_action.lng @@ -8,5 +8,5 @@ $wb['do_ispcupdate_desc'] = 'Questa operazione esegue un aggiornamento a ISPConf $wb['action_scheduled'] = 'L\'azione è programmata per la sua esecuzione'; $wb['select_all_server'] = 'Tutti i server'; $wb['ispconfig_update_title'] = 'Istruzioni per l\'aggiornamento di ISPConfig'; -$wb['ispconfig_update_text'] = 'Collegati alla shell del server come root ed esegui il comando

ispconfig_update.sh

per iniziare il processo di aggiornamento.

Clicca qui per le istruzioni dettagliate di aggiornamento (in inglese)'; +$wb['ispconfig_update_text'] = 'Collegati alla shell del server come root ed esegui il comando

ispconfig_update.sh

per iniziare il processo di aggiornamento.

Clicca qui per le istruzioni dettagliate di aggiornamento (in inglese)'; ?> diff --git a/interface/web/admin/lib/lang/it_server.lng b/interface/web/admin/lib/lang/it_server.lng index fc82b6cc68..3f4d9577e6 100644 --- a/interface/web/admin/lib/lang/it_server.lng +++ b/interface/web/admin/lib/lang/it_server.lng @@ -13,4 +13,5 @@ $wb['- None -'] = '- Nessuno -'; $wb['proxy_server_txt'] = 'Proxy-Server'; $wb['firewall_server_txt'] = 'Firewall-Server'; $wb['xmpp_server_txt'] = 'XMPP Server'; +$wb['server_name_error_regex'] = 'Nome server non valido. Sono consentiti solo lettere, numeri, spazi, trattini, punti, underscore e parentesi.'; ?> diff --git a/interface/web/admin/lib/lang/it_server_config.lng b/interface/web/admin/lib/lang/it_server_config.lng index 4d01d70b22..f650fb726e 100644 --- a/interface/web/admin/lib/lang/it_server_config.lng +++ b/interface/web/admin/lib/lang/it_server_config.lng @@ -156,6 +156,7 @@ $wb['do_not_try_rescue_mail_txt'] = 'Disabilita monitoraggio Email'; $wb['rescue_description_txt'] = 'Informazione: Se desideri fermare MySQL devi selezionare la spunta per Disabilitare monitor MySQL ed attendere 2-3 minuti.
Se non attendi 2-3 minuti, il sistema tenterà di riavviare MySQL!'; $wb['enable_sni_txt'] = 'Abilita SNI'; $wb['set_folder_permissions_on_update_txt'] = 'Imposta permessi cartella ad aggiornamento'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Aggiungi utente sito web a gruppo utenti -ssh-'; $wb['connect_userid_to_webid_txt'] = 'Collega userid Linux a webid'; $wb['connect_userid_to_webid_start_txt'] = 'Avvia ID per collegamento userid/webid'; @@ -332,6 +333,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) che Rspamd user $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password per Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password per Bayes Redis Server (lasciare vuoto se non usato).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Abilita protocollo PROXY'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'Porta HHTP per il protocollo PROXY'; $wb['vhost_proxy_protocol_https_port_txt'] = 'Porta HHTPS per il protocollo PROXY'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'modello Jailkit authorized_keys'; @@ -341,5 +343,31 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'L\'uso di hardlinks è meno sicuro però $wb['jailkit_hardlinks_allow_txt'] = 'Consenti hardlinks all\'interno di jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, rimuovi i file con hardlink'; $wb['jailkit_hardlinks_yes_txt'] = 'Si, usa hardlinks se possibile'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Numero di backup di sistema'; +$wb['sysbackup_copies_error_empty'] = 'Il numero di backup di sistema non deve essere vuoto'; +$wb['sysbackup_copies_error_regex'] = 'Il numero di backup di sistema deve essere un numero compreso tra 1 e 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = disattivato)'; +$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/it_server_php.lng b/interface/web/admin/lib/lang/it_server_php.lng index 7569ba9b52..288d140b84 100644 --- a/interface/web/admin/lib/lang/it_server_php.lng +++ b/interface/web/admin/lib/lang/it_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Attivo'; $wb['php_in_use_error'] = 'Questa versione PHP è in uso.'; $wb['php_name_in_use_error'] = 'Il nome non può essere cambiato.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/it_server_php_list.lng b/interface/web/admin/lib/lang/it_server_php_list.lng index 5ff1ebe314..ca117bf38a 100644 --- a/interface/web/admin/lib/lang/it_server_php_list.lng +++ b/interface/web/admin/lib/lang/it_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Cliente'; $wb['name_txt'] = 'Nome PHP'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/it_system_config.lng b/interface/web/admin/lib/lang/it_system_config.lng index 2f8950d7a3..e503221ffa 100644 --- a/interface/web/admin/lib/lang/it_system_config.lng +++ b/interface/web/admin/lib/lang/it_system_config.lng @@ -105,7 +105,9 @@ $wb['show_support_messages_txt'] = 'Mostra la funzione messaggio nel modulo Help $wb['show_aps_menu_txt'] = 'Mostra menu APS'; $wb['show_aps_menu_note_txt'] = 'APS saranno rimosse dal pannello in un prossimo futuro.'; $wb['show_aps_menu_note_url_txt'] = 'Clicca qui per maggiori informazioni.'; -$wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/ja.lng b/interface/web/admin/lib/lang/ja.lng index b39e9f3085..18e9cbee5f 100644 --- a/interface/web/admin/lib/lang/ja.lng +++ b/interface/web/admin/lib/lang/ja.lng @@ -49,4 +49,7 @@ $wb['Do ISPConfig-Update'] = 'Do ISPConfig-Update'; $wb['Directive Snippets'] = 'Directive Snippets'; $wb['Sites'] = 'Sites'; $wb['DNS'] = 'DNS'; +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Available Extensions'; +$wb['Installed Extensions'] = 'Installed Extensions'; ?> diff --git a/interface/web/admin/lib/lang/ja_extension_install_list.lng b/interface/web/admin/lib/lang/ja_extension_install_list.lng new file mode 100644 index 0000000000..f5a7270fce --- /dev/null +++ b/interface/web/admin/lib/lang/ja_extension_install_list.lng @@ -0,0 +1,55 @@ + \ No newline at end of file diff --git a/interface/web/admin/lib/lang/ja_remote_action.lng b/interface/web/admin/lib/lang/ja_remote_action.lng index dfe56b616d..aeb7a78537 100644 --- a/interface/web/admin/lib/lang/ja_remote_action.lng +++ b/interface/web/admin/lib/lang/ja_remote_action.lng @@ -8,5 +8,5 @@ $wb['do_ispcupdate_desc'] = 'This action does a ISPConfig3 update at your select $wb['action_scheduled'] = 'The action is scheduled for execution'; $wb['select_all_server'] = 'All server'; $wb['ispconfig_update_title'] = 'ISPConfig update instructions'; -$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; +$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; ?> diff --git a/interface/web/admin/lib/lang/ja_server.lng b/interface/web/admin/lib/lang/ja_server.lng index 1450c387f4..bb99dd4fc0 100644 --- a/interface/web/admin/lib/lang/ja_server.lng +++ b/interface/web/admin/lib/lang/ja_server.lng @@ -13,4 +13,5 @@ $wb['- None -'] = '- None -'; $wb['proxy_server_txt'] = 'Proxy-Server'; $wb['firewall_server_txt'] = 'Firewall-Server'; $wb['xmpp_server_txt'] = 'XMPP Server'; +$wb['server_name_error_regex'] = '無効ãªã‚µãƒ¼ãƒãƒ¼åã§ã™ã€‚æ–‡å­—ã€æ•°å­—ã€ã‚¹ãƒšãƒ¼ã‚¹ã€ãƒã‚¤ãƒ•ンã€ãƒ”リオドã€ã‚¢ãƒ³ãƒ€ãƒ¼ã‚¹ã‚³ã‚¢ã€æ‹¬å¼§ã®ã¿ä½¿ç”¨ã§ãã¾ã™ã€‚'; ?> diff --git a/interface/web/admin/lib/lang/ja_server_config.lng b/interface/web/admin/lib/lang/ja_server_config.lng index 66d505562b..88b1015b40 100644 --- a/interface/web/admin/lib/lang/ja_server_config.lng +++ b/interface/web/admin/lib/lang/ja_server_config.lng @@ -168,6 +168,7 @@ $wb['rescue_description_txt'] = 'Information: If you want to shut down my $wb['enable_sni_txt'] = 'Enable SNI'; $wb['do_not_try_rescue_httpd_txt'] = 'Disable HTTPD monitoring'; $wb['set_folder_permissions_on_update_txt'] = 'Set folder permissions on update'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Add web users to -sshusers- group'; $wb['connect_userid_to_webid_txt'] = 'Connect Linux userid to webid'; $wb['connect_userid_to_webid_start_txt'] = 'Start ID for userid/webid connect'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -342,5 +344,30 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Number of ISPConfig backups'; +$wb['sysbackup_copies_error_empty'] = 'Number of ISPConfig backups must not be empty'; +$wb['sysbackup_copies_error_regex'] = 'Number of ISPConfig backups must be a number between 1 and 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = off)'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/ja_server_php.lng b/interface/web/admin/lib/lang/ja_server_php.lng index 491be1aae2..1a7420fb21 100644 --- a/interface/web/admin/lib/lang/ja_server_php.lng +++ b/interface/web/admin/lib/lang/ja_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Active'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/ja_server_php_list.lng b/interface/web/admin/lib/lang/ja_server_php_list.lng index 291302cbb7..d5e6ad3c7f 100644 --- a/interface/web/admin/lib/lang/ja_server_php_list.lng +++ b/interface/web/admin/lib/lang/ja_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Client'; $wb['name_txt'] = 'PHP Name'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/ja_system_config.lng b/interface/web/admin/lib/lang/ja_system_config.lng index 744d83a705..68169d9f28 100644 --- a/interface/web/admin/lib/lang/ja_system_config.lng +++ b/interface/web/admin/lib/lang/ja_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/nl.lng b/interface/web/admin/lib/lang/nl.lng index 99a4b53da1..bbb4dc25b8 100644 --- a/interface/web/admin/lib/lang/nl.lng +++ b/interface/web/admin/lib/lang/nl.lng @@ -49,4 +49,7 @@ $wb['Do ISPConfig-Update'] = 'Voer een ISPConfig-update uit'; $wb['Directive Snippets'] = 'Directive Snippets'; $wb['Sites'] = 'Sites'; $wb['DNS'] = 'DNS'; +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Available Extensions'; +$wb['Installed Extensions'] = 'Installed Extensions'; ?> diff --git a/interface/web/admin/lib/lang/nl_extension_install_list.lng b/interface/web/admin/lib/lang/nl_extension_install_list.lng new file mode 100644 index 0000000000..148b8dce90 --- /dev/null +++ b/interface/web/admin/lib/lang/nl_extension_install_list.lng @@ -0,0 +1,45 @@ + diff --git a/interface/web/admin/lib/lang/nl_remote_action.lng b/interface/web/admin/lib/lang/nl_remote_action.lng index 146bbc6bfb..b1d5bc7517 100644 --- a/interface/web/admin/lib/lang/nl_remote_action.lng +++ b/interface/web/admin/lib/lang/nl_remote_action.lng @@ -8,5 +8,5 @@ $wb['do_ispcupdate_desc'] = 'Deze actie voert een ISPConfig3 update uit op de so $wb['action_scheduled'] = 'Deze actie is ingepland om uitgevoerd te worden'; $wb['select_all_server'] = 'Alle servers'; $wb['ispconfig_update_title'] = 'ISPConfig update instructions'; -$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; +$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; ?> diff --git a/interface/web/admin/lib/lang/nl_server.lng b/interface/web/admin/lib/lang/nl_server.lng index 7aed707e15..0829b655ab 100644 --- a/interface/web/admin/lib/lang/nl_server.lng +++ b/interface/web/admin/lib/lang/nl_server.lng @@ -13,4 +13,5 @@ $wb['- None -'] = '- Geen enkele -'; $wb['proxy_server_txt'] = 'Proxy-Server'; $wb['firewall_server_txt'] = 'Firewall-Server'; $wb['xmpp_server_txt'] = 'XMPP Server'; +$wb['server_name_error_regex'] = 'Ongeldige servernaam. Alleen letters, cijfers, spaties, koppeltekens, punten, underscores en haakjes zijn toegestaan.'; ?> diff --git a/interface/web/admin/lib/lang/nl_server_config.lng b/interface/web/admin/lib/lang/nl_server_config.lng index 8ea60a21a8..dd38781075 100644 --- a/interface/web/admin/lib/lang/nl_server_config.lng +++ b/interface/web/admin/lib/lang/nl_server_config.lng @@ -168,6 +168,7 @@ $wb['rescue_description_txt'] = 'Information: If you want to shut down my $wb['enable_sni_txt'] = 'Enable SNI'; $wb['do_not_try_rescue_httpd_txt'] = 'Disable HTTPD monitoring'; $wb['set_folder_permissions_on_update_txt'] = 'Set folder permissions on update'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Add web users to -sshusers- group'; $wb['connect_userid_to_webid_txt'] = 'Connect Linux userid to webid'; $wb['connect_userid_to_webid_start_txt'] = 'Start ID for userid/webid connect'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -342,5 +344,30 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Aantal systeemback-ups'; +$wb['sysbackup_copies_error_empty'] = 'Aantal systeemback-ups mag niet leeg zijn'; +$wb['sysbackup_copies_error_regex'] = 'Aantal systeemback-ups moet een getal tussen 1 en 3 zijn'; +$wb['sysbackup_copies_note_txt'] = '(0 = uit)'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/nl_server_php.lng b/interface/web/admin/lib/lang/nl_server_php.lng index 491be1aae2..1a7420fb21 100644 --- a/interface/web/admin/lib/lang/nl_server_php.lng +++ b/interface/web/admin/lib/lang/nl_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Active'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/nl_server_php_list.lng b/interface/web/admin/lib/lang/nl_server_php_list.lng index 291302cbb7..d5e6ad3c7f 100644 --- a/interface/web/admin/lib/lang/nl_server_php_list.lng +++ b/interface/web/admin/lib/lang/nl_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Client'; $wb['name_txt'] = 'PHP Name'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/nl_system_config.lng b/interface/web/admin/lib/lang/nl_system_config.lng index b40ce96285..6812c67d34 100644 --- a/interface/web/admin/lib/lang/nl_system_config.lng +++ b/interface/web/admin/lib/lang/nl_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/pl.lng b/interface/web/admin/lib/lang/pl.lng index a24e4357c0..9bde236afe 100644 --- a/interface/web/admin/lib/lang/pl.lng +++ b/interface/web/admin/lib/lang/pl.lng @@ -49,4 +49,7 @@ $wb['Domains'] = 'Domeny'; $wb['Misc'] = 'Różne'; $wb['Sites'] = 'Sites'; $wb['DNS'] = 'DNS'; +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Available Extensions'; +$wb['Installed Extensions'] = 'Installed Extensions'; ?> diff --git a/interface/web/admin/lib/lang/pl_extension_install_list.lng b/interface/web/admin/lib/lang/pl_extension_install_list.lng new file mode 100644 index 0000000000..f5a7270fce --- /dev/null +++ b/interface/web/admin/lib/lang/pl_extension_install_list.lng @@ -0,0 +1,55 @@ + \ No newline at end of file diff --git a/interface/web/admin/lib/lang/pl_remote_action.lng b/interface/web/admin/lib/lang/pl_remote_action.lng index 884b2047d5..bedba87e3a 100644 --- a/interface/web/admin/lib/lang/pl_remote_action.lng +++ b/interface/web/admin/lib/lang/pl_remote_action.lng @@ -8,5 +8,5 @@ $wb['do_ispcupdate_desc'] = 'Ta akcja przeprowadzi aktualizację ISPConfig3 na w $wb['action_scheduled'] = 'Akcja zaplanowana do wykonania'; $wb['select_all_server'] = 'Wszystkie serwery'; $wb['ispconfig_update_title'] = 'ISPConfig update instructions'; -$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; +$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; ?> diff --git a/interface/web/admin/lib/lang/pl_server.lng b/interface/web/admin/lib/lang/pl_server.lng index 1fe0171ff1..a137d4ec5e 100644 --- a/interface/web/admin/lib/lang/pl_server.lng +++ b/interface/web/admin/lib/lang/pl_server.lng @@ -13,4 +13,5 @@ $wb['- None -'] = '- Żaden -'; $wb['proxy_server_txt'] = 'Proxy-Server'; $wb['firewall_server_txt'] = 'Firewall-Server'; $wb['xmpp_server_txt'] = 'XMPP Server'; +$wb['server_name_error_regex'] = 'Nieprawidłowa nazwa serwera. Dozwolone są tylko litery, cyfry, spacje, myślniki, kropki, podkreślenia i nawiasy.'; ?> diff --git a/interface/web/admin/lib/lang/pl_server_config.lng b/interface/web/admin/lib/lang/pl_server_config.lng index c186f5d2a6..16907a6abe 100644 --- a/interface/web/admin/lib/lang/pl_server_config.lng +++ b/interface/web/admin/lib/lang/pl_server_config.lng @@ -168,6 +168,7 @@ $wb['rescue_description_txt'] = 'Information: If you want to shut down my $wb['enable_sni_txt'] = 'Włącz SNI'; $wb['do_not_try_rescue_httpd_txt'] = 'Disable HTTPD monitoring'; $wb['set_folder_permissions_on_update_txt'] = 'Set folder permissions on update'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Add web users to -sshusers- group'; $wb['connect_userid_to_webid_txt'] = 'Connect Linux userid to webid'; $wb['connect_userid_to_webid_start_txt'] = 'Start ID for userid/webid connect'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -342,5 +344,30 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Number of ISPConfig backups'; +$wb['sysbackup_copies_error_empty'] = 'Number of ISPConfig backups must not be empty'; +$wb['sysbackup_copies_error_regex'] = 'Number of ISPConfig backups must be a number between 1 and 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = off)'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/pl_server_php.lng b/interface/web/admin/lib/lang/pl_server_php.lng index de4ce60ac1..6e2a7be786 100644 --- a/interface/web/admin/lib/lang/pl_server_php.lng +++ b/interface/web/admin/lib/lang/pl_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Active'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/pl_server_php_list.lng b/interface/web/admin/lib/lang/pl_server_php_list.lng index 291302cbb7..d5e6ad3c7f 100644 --- a/interface/web/admin/lib/lang/pl_server_php_list.lng +++ b/interface/web/admin/lib/lang/pl_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Client'; $wb['name_txt'] = 'PHP Name'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/pl_system_config.lng b/interface/web/admin/lib/lang/pl_system_config.lng index 5431213977..edc15d68c1 100644 --- a/interface/web/admin/lib/lang/pl_system_config.lng +++ b/interface/web/admin/lib/lang/pl_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/pt.lng b/interface/web/admin/lib/lang/pt.lng index 6aaddc02ae..bce47d571f 100644 --- a/interface/web/admin/lib/lang/pt.lng +++ b/interface/web/admin/lib/lang/pt.lng @@ -49,4 +49,7 @@ $wb['Do ISPConfig-Update'] = 'Do ISPConfig-Update'; $wb['Directive Snippets'] = 'Directive Snippets'; $wb['Sites'] = 'Sites'; $wb['DNS'] = 'DNS'; +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Available Extensions'; +$wb['Installed Extensions'] = 'Installed Extensions'; ?> diff --git a/interface/web/admin/lib/lang/pt_extension_install_list.lng b/interface/web/admin/lib/lang/pt_extension_install_list.lng new file mode 100644 index 0000000000..74079d832e --- /dev/null +++ b/interface/web/admin/lib/lang/pt_extension_install_list.lng @@ -0,0 +1,45 @@ + diff --git a/interface/web/admin/lib/lang/pt_remote_action.lng b/interface/web/admin/lib/lang/pt_remote_action.lng index dfe56b616d..aeb7a78537 100644 --- a/interface/web/admin/lib/lang/pt_remote_action.lng +++ b/interface/web/admin/lib/lang/pt_remote_action.lng @@ -8,5 +8,5 @@ $wb['do_ispcupdate_desc'] = 'This action does a ISPConfig3 update at your select $wb['action_scheduled'] = 'The action is scheduled for execution'; $wb['select_all_server'] = 'All server'; $wb['ispconfig_update_title'] = 'ISPConfig update instructions'; -$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; +$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; ?> diff --git a/interface/web/admin/lib/lang/pt_server.lng b/interface/web/admin/lib/lang/pt_server.lng index 13f60a3f97..e32b29fdd7 100644 --- a/interface/web/admin/lib/lang/pt_server.lng +++ b/interface/web/admin/lib/lang/pt_server.lng @@ -13,4 +13,5 @@ $wb['- None -'] = '- Não -'; $wb['proxy_server_txt'] = 'Proxy-Server'; $wb['firewall_server_txt'] = 'Firewall-Server'; $wb['xmpp_server_txt'] = 'XMPP Server'; +$wb['server_name_error_regex'] = 'Nome de servidor inválido. Apenas letras, números, espaços, hífens, pontos, sublinhados e parênteses são permitidos.'; ?> diff --git a/interface/web/admin/lib/lang/pt_server_config.lng b/interface/web/admin/lib/lang/pt_server_config.lng index 2e398500db..97918b7af5 100644 --- a/interface/web/admin/lib/lang/pt_server_config.lng +++ b/interface/web/admin/lib/lang/pt_server_config.lng @@ -168,6 +168,7 @@ $wb['rescue_description_txt'] = 'Information: If you want to shut down my $wb['enable_sni_txt'] = 'Enable SNI'; $wb['do_not_try_rescue_httpd_txt'] = 'Disable HTTPD monitoring'; $wb['set_folder_permissions_on_update_txt'] = 'Set folder permissions on update'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Add web users to -sshusers- group'; $wb['connect_userid_to_webid_txt'] = 'Connect Linux userid to webid'; $wb['connect_userid_to_webid_start_txt'] = 'Start ID for userid/webid connect'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -342,5 +344,30 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Number of ISPConfig backups'; +$wb['sysbackup_copies_error_empty'] = 'Number of ISPConfig backups must not be empty'; +$wb['sysbackup_copies_error_regex'] = 'Number of ISPConfig backups must be a number between 1 and 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = off)'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/pt_server_php.lng b/interface/web/admin/lib/lang/pt_server_php.lng index 491be1aae2..1a7420fb21 100644 --- a/interface/web/admin/lib/lang/pt_server_php.lng +++ b/interface/web/admin/lib/lang/pt_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Active'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/pt_server_php_list.lng b/interface/web/admin/lib/lang/pt_server_php_list.lng index 291302cbb7..d5e6ad3c7f 100644 --- a/interface/web/admin/lib/lang/pt_server_php_list.lng +++ b/interface/web/admin/lib/lang/pt_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Client'; $wb['name_txt'] = 'PHP Name'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/pt_system_config.lng b/interface/web/admin/lib/lang/pt_system_config.lng index 8c995047b4..17374d12ae 100644 --- a/interface/web/admin/lib/lang/pt_system_config.lng +++ b/interface/web/admin/lib/lang/pt_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/ro.lng b/interface/web/admin/lib/lang/ro.lng index dedbaef51f..52db89fe10 100644 --- a/interface/web/admin/lib/lang/ro.lng +++ b/interface/web/admin/lib/lang/ro.lng @@ -49,4 +49,7 @@ $wb['Do ISPConfig-Update'] = 'Do ISPConfig-Update'; $wb['Directive Snippets'] = 'Directive Snippets'; $wb['Sites'] = 'Sites'; $wb['DNS'] = 'DNS'; +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Available Extensions'; +$wb['Installed Extensions'] = 'Installed Extensions'; ?> diff --git a/interface/web/admin/lib/lang/ro_remote_action.lng b/interface/web/admin/lib/lang/ro_remote_action.lng index dfe56b616d..aeb7a78537 100644 --- a/interface/web/admin/lib/lang/ro_remote_action.lng +++ b/interface/web/admin/lib/lang/ro_remote_action.lng @@ -8,5 +8,5 @@ $wb['do_ispcupdate_desc'] = 'This action does a ISPConfig3 update at your select $wb['action_scheduled'] = 'The action is scheduled for execution'; $wb['select_all_server'] = 'All server'; $wb['ispconfig_update_title'] = 'ISPConfig update instructions'; -$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; +$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; ?> diff --git a/interface/web/admin/lib/lang/ro_server.lng b/interface/web/admin/lib/lang/ro_server.lng index 6b63109f98..a6fd6be8f8 100644 --- a/interface/web/admin/lib/lang/ro_server.lng +++ b/interface/web/admin/lib/lang/ro_server.lng @@ -13,4 +13,5 @@ $wb['- None -'] = '- None -'; $wb['proxy_server_txt'] = 'Proxy-Server'; $wb['firewall_server_txt'] = 'Firewall-Server'; $wb['xmpp_server_txt'] = 'XMPP Server'; +$wb['server_name_error_regex'] = 'Nume de server invalid. Sunt permise doar litere, cifre, spații, liniuțe, puncte, underscore și paranteze.'; ?> diff --git a/interface/web/admin/lib/lang/ro_server_config.lng b/interface/web/admin/lib/lang/ro_server_config.lng index 2756ae7acd..805acc106e 100644 --- a/interface/web/admin/lib/lang/ro_server_config.lng +++ b/interface/web/admin/lib/lang/ro_server_config.lng @@ -168,6 +168,7 @@ $wb['rescue_description_txt'] = 'Information: If you want to shut down my $wb['enable_sni_txt'] = 'Enable SNI'; $wb['do_not_try_rescue_httpd_txt'] = 'Disable HTTPD monitoring'; $wb['set_folder_permissions_on_update_txt'] = 'Set folder permissions on update'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Add web users to -sshusers- group'; $wb['connect_userid_to_webid_txt'] = 'Connect Linux userid to webid'; $wb['connect_userid_to_webid_start_txt'] = 'Start ID for userid/webid connect'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -342,5 +344,30 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Number of ISPConfig backups'; +$wb['sysbackup_copies_error_empty'] = 'Number of ISPConfig backups must not be empty'; +$wb['sysbackup_copies_error_regex'] = 'Number of ISPConfig backups must be a number between 1 and 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = off)'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/ro_server_php.lng b/interface/web/admin/lib/lang/ro_server_php.lng index 491be1aae2..1a7420fb21 100644 --- a/interface/web/admin/lib/lang/ro_server_php.lng +++ b/interface/web/admin/lib/lang/ro_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Active'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/ro_server_php_list.lng b/interface/web/admin/lib/lang/ro_server_php_list.lng index 291302cbb7..d5e6ad3c7f 100644 --- a/interface/web/admin/lib/lang/ro_server_php_list.lng +++ b/interface/web/admin/lib/lang/ro_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Client'; $wb['name_txt'] = 'PHP Name'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/ro_system_config.lng b/interface/web/admin/lib/lang/ro_system_config.lng index 9fd8e4d587..f31a8dbaeb 100644 --- a/interface/web/admin/lib/lang/ro_system_config.lng +++ b/interface/web/admin/lib/lang/ro_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/ru.lng b/interface/web/admin/lib/lang/ru.lng index ef7216ae5a..18308a599d 100644 --- a/interface/web/admin/lib/lang/ru.lng +++ b/interface/web/admin/lib/lang/ru.lng @@ -49,4 +49,7 @@ $wb['Do ISPConfig-Update'] = 'Обновление ISPConfig'; $wb['Directive Snippets'] = 'Заготовки директив'; $wb['Sites'] = 'Сайты'; $wb['DNS'] = 'DNS'; +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Available Extensions'; +$wb['Installed Extensions'] = 'Installed Extensions'; ?> diff --git a/interface/web/admin/lib/lang/ru_extension_install_list.lng b/interface/web/admin/lib/lang/ru_extension_install_list.lng new file mode 100644 index 0000000000..16d9996c9b --- /dev/null +++ b/interface/web/admin/lib/lang/ru_extension_install_list.lng @@ -0,0 +1,45 @@ + diff --git a/interface/web/admin/lib/lang/ru_remote_action.lng b/interface/web/admin/lib/lang/ru_remote_action.lng index f9d10afc53..055cd5e3ab 100644 --- a/interface/web/admin/lib/lang/ru_remote_action.lng +++ b/interface/web/admin/lib/lang/ru_remote_action.lng @@ -8,5 +8,5 @@ $wb['do_ispcupdate_desc'] = 'Это дейÑтвие выполнит обнов $wb['action_scheduled'] = 'ДейÑтвие запланировано на выполнение'; $wb['select_all_server'] = 'Ð’Ñе Ñервера'; $wb['ispconfig_update_title'] = 'ИнÑтрукции по обновлению ISPConfig'; -$wb['ispconfig_update_text'] = 'Войдите в ÑиÑтему вашего Ñервера как корневой пользователь Shell и выполнить команду

ispconfig_update.sh

чтобы начать обновление ISPConfig.

Ðажмите здеÑÑŒ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ñ‹Ñ… инÑтрукций по обновлению'; +$wb['ispconfig_update_text'] = 'Войдите в ÑиÑтему вашего Ñервера как корневой пользователь Shell и выполнить команду

ispconfig_update.sh

чтобы начать обновление ISPConfig.

Ðажмите здеÑÑŒ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ñ‹Ñ… инÑтрукций по обновлению'; ?> diff --git a/interface/web/admin/lib/lang/ru_server.lng b/interface/web/admin/lib/lang/ru_server.lng index f4b870300d..0a51370d32 100644 --- a/interface/web/admin/lib/lang/ru_server.lng +++ b/interface/web/admin/lib/lang/ru_server.lng @@ -13,4 +13,5 @@ $wb['- None -'] = '- нет -'; $wb['proxy_server_txt'] = 'ПрокÑи-Ñервер'; $wb['firewall_server_txt'] = 'БрандмауÑÑ€-Ñервер'; $wb['xmpp_server_txt'] = 'XMPP-Ñервер'; +$wb['server_name_error_regex'] = 'ÐедопуÑтимое Ð¸Ð¼Ñ Ñервера. Разрешены только буквы, цифры, пробелы, дефиÑÑ‹, точки, Ð¿Ð¾Ð´Ñ‡ÐµÑ€ÐºÐ¸Ð²Ð°Ð½Ð¸Ñ Ð¸ Ñкобки.'; ?> diff --git a/interface/web/admin/lib/lang/ru_server_config.lng b/interface/web/admin/lib/lang/ru_server_config.lng index 2fbf9cf7d6..6028a06605 100644 --- a/interface/web/admin/lib/lang/ru_server_config.lng +++ b/interface/web/admin/lib/lang/ru_server_config.lng @@ -168,6 +168,7 @@ $wb['rescue_description_txt'] = 'ИнформациÑ: ЕÑли вы хо $wb['enable_sni_txt'] = 'Включить SNI'; $wb['do_not_try_rescue_httpd_txt'] = 'Отключить мониторинг HTTPD'; $wb['set_folder_permissions_on_update_txt'] = 'УÑтановить Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¿Ð°Ð¿ÐºÐ¸ на обновлениÑ'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Добавить веб-пользователей в группу -sshusers-'; $wb['connect_userid_to_webid_txt'] = 'СвÑзать ID Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Linux (UserID/) Ñ Ð²ÐµÐ±-идентификатором WebID'; $wb['connect_userid_to_webid_start_txt'] = 'Ðачальный ID Ð´Ð»Ñ ÑвÑзки UserID/WebID'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -342,5 +344,30 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['sysbackup_copies_txt'] = 'Number of ISPConfig backups'; +$wb['sysbackup_copies_error_empty'] = 'Number of ISPConfig backups must not be empty'; +$wb['sysbackup_copies_error_regex'] = 'Number of ISPConfig backups must be a number between 1 and 3'; +$wb['sysbackup_copies_note_txt'] = '(0 = off)'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/ru_server_php.lng b/interface/web/admin/lib/lang/ru_server_php.lng index c5c4942b8e..5392117cd9 100644 --- a/interface/web/admin/lib/lang/ru_server_php.lng +++ b/interface/web/admin/lib/lang/ru_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Active'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/ru_server_php_list.lng b/interface/web/admin/lib/lang/ru_server_php_list.lng index 5be582f23d..1a2068057f 100644 --- a/interface/web/admin/lib/lang/ru_server_php_list.lng +++ b/interface/web/admin/lib/lang/ru_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'ID Клиента'; $wb['name_txt'] = 'Ð˜Ð¼Ñ PHP'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/ru_system_config.lng b/interface/web/admin/lib/lang/ru_system_config.lng index 55c8731515..29f7bc4251 100644 --- a/interface/web/admin/lib/lang/ru_system_config.lng +++ b/interface/web/admin/lib/lang/ru_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/se.lng b/interface/web/admin/lib/lang/se.lng index 198c338c3d..9e96492fba 100644 --- a/interface/web/admin/lib/lang/se.lng +++ b/interface/web/admin/lib/lang/se.lng @@ -49,4 +49,7 @@ $wb['Do ISPConfig-Update'] = 'Utför ISPConfig-uppdatering'; $wb['Directive Snippets'] = 'Directive Snippets'; $wb['Sites'] = 'Sites'; $wb['DNS'] = 'DNS'; +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Available Extensions'; +$wb['Installed Extensions'] = 'Installed Extensions'; ?> diff --git a/interface/web/admin/lib/lang/se_extension_install_list.lng b/interface/web/admin/lib/lang/se_extension_install_list.lng new file mode 100644 index 0000000000..f5a7270fce --- /dev/null +++ b/interface/web/admin/lib/lang/se_extension_install_list.lng @@ -0,0 +1,55 @@ + \ No newline at end of file diff --git a/interface/web/admin/lib/lang/se_remote_action.lng b/interface/web/admin/lib/lang/se_remote_action.lng index 9aeb7d9ba3..2e2a637469 100644 --- a/interface/web/admin/lib/lang/se_remote_action.lng +++ b/interface/web/admin/lib/lang/se_remote_action.lng @@ -8,5 +8,5 @@ $wb['do_ispcupdate_desc'] = 'This action does a ISPConfig3 update at your select $wb['action_scheduled'] = 'Handlingen är schemalagd att utföras'; $wb['select_all_server'] = 'Alla servrar'; $wb['ispconfig_update_title'] = 'ISPConfig uppdateringsinstruktioner'; -$wb['ispconfig_update_text'] = 'Logga in som root pÃ¥ din server och kör kommandot

ispconfig_update.sh

för att påbörja ISPConfig-uppdateringen.

Klicka här för detaljerade instruktioner'; +$wb['ispconfig_update_text'] = 'Logga in som root på din server och kör kommandot

ispconfig_update.sh

för att påbörja ISPConfig-uppdateringen.

Klicka här för detaljerade instruktioner'; ?> diff --git a/interface/web/admin/lib/lang/se_server.lng b/interface/web/admin/lib/lang/se_server.lng index 11806c81bc..90ec2a5ed8 100644 --- a/interface/web/admin/lib/lang/se_server.lng +++ b/interface/web/admin/lib/lang/se_server.lng @@ -13,4 +13,5 @@ $wb['- None -'] = '- Ingen'; $wb['proxy_server_txt'] = 'Proxy-server'; $wb['firewall_server_txt'] = 'Brandväggsserver'; $wb['xmpp_server_txt'] = 'XMPP Server'; +$wb['server_name_error_regex'] = 'Ogiltigt servernamn. Endast bokstäver, siffror, mellanslag, bindestreck, punkter, understreck och parenteser är tillåtna.'; ?> diff --git a/interface/web/admin/lib/lang/se_server_config.lng b/interface/web/admin/lib/lang/se_server_config.lng index e21017769c..3badfe4a9f 100644 --- a/interface/web/admin/lib/lang/se_server_config.lng +++ b/interface/web/admin/lib/lang/se_server_config.lng @@ -168,6 +168,7 @@ $wb['rescue_description_txt'] = 'Information: If you want to shut down my $wb['enable_sni_txt'] = 'Enable SNI'; $wb['do_not_try_rescue_httpd_txt'] = 'Disable HTTPD monitoring'; $wb['set_folder_permissions_on_update_txt'] = 'Set folder permissions on update'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Add web users to -sshusers- group'; $wb['connect_userid_to_webid_txt'] = 'Connect Linux userid to webid'; $wb['connect_userid_to_webid_start_txt'] = 'Start ID for userid/webid connect'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -342,5 +344,26 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/se_server_php.lng b/interface/web/admin/lib/lang/se_server_php.lng index 491be1aae2..1a7420fb21 100644 --- a/interface/web/admin/lib/lang/se_server_php.lng +++ b/interface/web/admin/lib/lang/se_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Active'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/se_server_php_list.lng b/interface/web/admin/lib/lang/se_server_php_list.lng index b2f8b55112..86adb0f2a6 100644 --- a/interface/web/admin/lib/lang/se_server_php_list.lng +++ b/interface/web/admin/lib/lang/se_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Kund'; $wb['name_txt'] = 'PHP-namn'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/se_system_config.lng b/interface/web/admin/lib/lang/se_system_config.lng index d3de89aa55..a4a417f4f6 100644 --- a/interface/web/admin/lib/lang/se_system_config.lng +++ b/interface/web/admin/lib/lang/se_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/sk.lng b/interface/web/admin/lib/lang/sk.lng index 6c85afe688..137b4234e0 100644 --- a/interface/web/admin/lib/lang/sk.lng +++ b/interface/web/admin/lib/lang/sk.lng @@ -49,4 +49,7 @@ $wb['Do ISPConfig-Update'] = 'Do ISPConfig-Update'; $wb['Directive Snippets'] = 'Directive Snippets'; $wb['Sites'] = 'Sites'; $wb['DNS'] = 'DNS'; +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Available Extensions'; +$wb['Installed Extensions'] = 'Installed Extensions'; ?> diff --git a/interface/web/admin/lib/lang/sk_extension_install_list.lng b/interface/web/admin/lib/lang/sk_extension_install_list.lng new file mode 100644 index 0000000000..f5a7270fce --- /dev/null +++ b/interface/web/admin/lib/lang/sk_extension_install_list.lng @@ -0,0 +1,55 @@ + \ No newline at end of file diff --git a/interface/web/admin/lib/lang/sk_remote_action.lng b/interface/web/admin/lib/lang/sk_remote_action.lng index dfe56b616d..aeb7a78537 100644 --- a/interface/web/admin/lib/lang/sk_remote_action.lng +++ b/interface/web/admin/lib/lang/sk_remote_action.lng @@ -8,5 +8,5 @@ $wb['do_ispcupdate_desc'] = 'This action does a ISPConfig3 update at your select $wb['action_scheduled'] = 'The action is scheduled for execution'; $wb['select_all_server'] = 'All server'; $wb['ispconfig_update_title'] = 'ISPConfig update instructions'; -$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; +$wb['ispconfig_update_text'] = 'Login as root user on the shell of your server and execute the command

ispconfig_update.sh

to start the ISPConfig update.

Click here for detailed update instructions'; ?> diff --git a/interface/web/admin/lib/lang/sk_server.lng b/interface/web/admin/lib/lang/sk_server.lng index 3d35c3f20d..8c92123652 100644 --- a/interface/web/admin/lib/lang/sk_server.lng +++ b/interface/web/admin/lib/lang/sk_server.lng @@ -13,4 +13,5 @@ $wb['- None -'] = '- None -'; $wb['proxy_server_txt'] = 'Proxy-Server'; $wb['firewall_server_txt'] = 'Firewall-Server'; $wb['xmpp_server_txt'] = 'XMPP Server'; +$wb['server_name_error_regex'] = 'Neplatné meno servera. Povolené sÄ… len písmená, Äísla, medzery, pomlÄky, bodky, podÄiarkovníky a zátvorky.'; ?> diff --git a/interface/web/admin/lib/lang/sk_server_config.lng b/interface/web/admin/lib/lang/sk_server_config.lng index 9ec5367be5..2746f6c7c7 100644 --- a/interface/web/admin/lib/lang/sk_server_config.lng +++ b/interface/web/admin/lib/lang/sk_server_config.lng @@ -168,6 +168,7 @@ $wb['rescue_description_txt'] = 'Information: If you want to shut down my $wb['enable_sni_txt'] = 'Enable SNI'; $wb['do_not_try_rescue_httpd_txt'] = 'Disable HTTPD monitoring'; $wb['set_folder_permissions_on_update_txt'] = 'Set folder permissions on update'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Add web users to -sshusers- group'; $wb['connect_userid_to_webid_txt'] = 'Connect Linux userid to webid'; $wb['connect_userid_to_webid_start_txt'] = 'Start ID for userid/webid connect'; @@ -333,6 +334,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -342,5 +344,26 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/sk_server_php.lng b/interface/web/admin/lib/lang/sk_server_php.lng index 491be1aae2..1a7420fb21 100644 --- a/interface/web/admin/lib/lang/sk_server_php.lng +++ b/interface/web/admin/lib/lang/sk_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Active'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/sk_server_php_list.lng b/interface/web/admin/lib/lang/sk_server_php_list.lng index 291302cbb7..d5e6ad3c7f 100644 --- a/interface/web/admin/lib/lang/sk_server_php_list.lng +++ b/interface/web/admin/lib/lang/sk_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Client'; $wb['name_txt'] = 'PHP Name'; $wb['active_txt'] = 'Active'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/sk_system_config.lng b/interface/web/admin/lib/lang/sk_system_config.lng index 1e85adca8c..ef25b1982a 100644 --- a/interface/web/admin/lib/lang/sk_system_config.lng +++ b/interface/web/admin/lib/lang/sk_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/lang/ti_extension_install_list.lng b/interface/web/admin/lib/lang/ti_extension_install_list.lng new file mode 100644 index 0000000000..f5a7270fce --- /dev/null +++ b/interface/web/admin/lib/lang/ti_extension_install_list.lng @@ -0,0 +1,55 @@ + \ No newline at end of file diff --git a/interface/web/admin/lib/lang/tr.lng b/interface/web/admin/lib/lang/tr.lng index 9b0dfc59ec..f3c1446ae2 100644 --- a/interface/web/admin/lib/lang/tr.lng +++ b/interface/web/admin/lib/lang/tr.lng @@ -59,4 +59,7 @@ $wb['Import'] = 'Dil Yükleme'; $wb['Remote Actions'] = 'Uzak İşlemler'; $wb['Do OS-Update'] = 'İşletim Sistemi Güncelleme'; $wb['Do ISPConfig-Update'] = 'ISPConfig Güncelleme'; +$wb['Extension Installer'] = 'Extension Installer'; +$wb['Available Extensions'] = 'Available Extensions'; +$wb['Installed Extensions'] = 'Installed Extensions'; ?> diff --git a/interface/web/admin/lib/lang/tr_extension_install_list.lng b/interface/web/admin/lib/lang/tr_extension_install_list.lng new file mode 100644 index 0000000000..f5a7270fce --- /dev/null +++ b/interface/web/admin/lib/lang/tr_extension_install_list.lng @@ -0,0 +1,55 @@ + \ No newline at end of file diff --git a/interface/web/admin/lib/lang/tr_remote_action.lng b/interface/web/admin/lib/lang/tr_remote_action.lng index b2ed0a6da7..b8919eb2ef 100644 --- a/interface/web/admin/lib/lang/tr_remote_action.lng +++ b/interface/web/admin/lib/lang/tr_remote_action.lng @@ -8,5 +8,5 @@ $wb['do_ispcupdate_desc'] = 'Bu işlem seçilmiş sunucuda ISPConfig3 güncellem $wb['action_scheduled'] = 'İşlem yürütülmek üzere zamanlandı'; $wb['select_all_server'] = 'Tüm Sunucularda'; $wb['ispconfig_update_title'] = 'ISPConfig güncelleme yönergeleri'; -$wb['ispconfig_update_text'] = 'Sunucunuzda root kullanıcısı ile bir kabuk oturumu açın ve ISPConfig güncellemesini başlatmak için

ispconfig_update.sh

komutunu yürütün.

Ayrıntılı güncelleme bilgilerine bakmak için buraya tıklayın'; +$wb['ispconfig_update_text'] = 'Sunucunuzda root kullanıcısı ile bir kabuk oturumu açın ve ISPConfig güncellemesini başlatmak için

ispconfig_update.sh

komutunu yürütün.

Ayrıntılı güncelleme bilgilerine bakmak için buraya tıklayın' ?> diff --git a/interface/web/admin/lib/lang/tr_server.lng b/interface/web/admin/lib/lang/tr_server.lng index bdc70761e1..d959603cd2 100644 --- a/interface/web/admin/lib/lang/tr_server.lng +++ b/interface/web/admin/lib/lang/tr_server.lng @@ -13,4 +13,5 @@ $wb['active_txt'] = 'Etkin'; $wb['mirror_server_id_txt'] = 'Sunucunun Yansısı'; $wb['- None -'] = '- Hiçbiri -'; $wb['xmpp_server_txt'] = 'XMPP Sunucusu'; +$wb['server_name_error_regex'] = 'Geçersiz sunucu adı. Sadece harfler, rakamlar, boşluklar, tire, nokta, alt çizgi ve parantez kullanılabilir.'; ?> diff --git a/interface/web/admin/lib/lang/tr_server_config.lng b/interface/web/admin/lib/lang/tr_server_config.lng index 29ccbe6129..c880e4779e 100644 --- a/interface/web/admin/lib/lang/tr_server_config.lng +++ b/interface/web/admin/lib/lang/tr_server_config.lng @@ -182,6 +182,7 @@ $wb['do_not_try_rescue_mail_txt'] = 'E-posta İzlenmesin'; $wb['rescue_description_txt'] = 'Uyarı: mysql sunucusunu kapatmak istiyorsanız "MySQL İzlenmesin" seçeneğini etkinleştirip 2-3 dakika bekleyin.
2-3 dakika beklemezseniz, kurtarma işlemi mysql sunucusunu yeniden başlatmaya çalışır!'; $wb['enable_sni_txt'] = 'SNI Kullanılsın'; $wb['set_folder_permissions_on_update_txt'] = 'Güncellenirken klasör izinleri ayarlansın'; +$wb['incorrect_permissions_regex'] = 'Incorrect permissions string'; $wb['add_web_users_to_sshusers_group_txt'] = 'Web kullanıcıları -sshusers- grubuna eklensin'; $wb['connect_userid_to_webid_txt'] = 'Linux kullanıcıkodu webkoduna bağlansın'; $wb['connect_userid_to_webid_start_txt'] = 'Bağlanacak kullanıcıkodu/webkodu için başlangıç kodu'; @@ -233,12 +234,11 @@ $wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level'; $wb['overquota_db_notify_admin_txt'] = 'Veritabanı Kotası Bildirimleri Yöneticiye Gönderilsin'; $wb['overquota_db_notify_reseller_txt'] = 'Send DB quota warnings to reseller'; $wb['overquota_db_notify_client_txt'] = 'Veritabanı Kotası Bildirimleri Müşteriye Gönderilsin'; -$wb['monitor_system_updates_txt'] = 'Linux Güncellemeleri Denetlensin'; +$wb['monitor_system_updates_txt'] = 'Linux Güncelleme Denetimi'; $wb['php_handler_txt'] = 'Varsayılan PHP İşleyici'; $wb['php_fpm_default_chroot_txt'] = 'Default chrooted PHP-FPM'; $wb['disabled_txt'] = 'Devre Dışı'; $wb['dkim_strength_txt'] = 'DKIM zorluğu'; -$wb['monitor_system_updates_txt'] = 'Linux Güncelleme Denetimi'; $wb['invalid_apache_user_txt'] = 'Apache kullanıcısı geçersiz.'; $wb['invalid_apache_group_txt'] = 'Apache grubu geçersiz.'; $wb['backup_dir_error_regex'] = 'Yedek klasörü geçersiz.'; @@ -330,6 +330,7 @@ $wb['tooltip_rspamd_redis_bayes_servers_txt'] = 'Redis server(s) which Rspamd wi $wb['rspamd_redis_bayes_password_txt'] = 'Redis Password for Bayes'; $wb['tooltip_rspamd_redis_bayes_password_txt'] = 'Password for Bayes Redis Server (leave blank if unused).'; $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol'; +$wb['vhost_proxy_protocol_protocols_txt'] = 'Use PROXY Protocol on'; $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port'; $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port'; $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template'; @@ -339,5 +340,30 @@ $wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves d $wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail'; $wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files'; $wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible'; +$wb['bind_zonefiles_masterprefix_txt'] = 'BIND master zonefiles prefix'; +$wb['bind_zonefiles_slaveprefix_txt'] = 'BIND slave zonefiles prefix'; +$wb['bind_keyfiles_dir_txt'] = 'BIND keyfiles directory'; +$wb['bind_keyfiles_dir_error_empty'] = 'BIND keyfiles directory is empty.'; +$wb['bind_zonefiles_masterprefix_error_regex'] = 'Invalid BIND zonefiles master prefix.'; +$wb['bind_zonefiles_slaveprefix_error_regex'] = 'Invalid BIND zonefiles slave prefix.'; +$wb['bind_keyfiles_dir_error_regex'] = 'Invalid BIND keyfiles directory.'; $wb['mailbox_soft_delete_txt'] = 'Mailbox soft delete'; -$wb['mailbox_soft_delete_info_txt'] = 'by default cleaned up after 7 days.'; +$wb['soft_delete_directly_txt'] = 'Delete instantly'; +$wb['soft_delete_keep_indefinitely_txt'] = 'Rename but don\'t delete (manual cleanup)'; +$wb['soft_delete_keep_1_txt'] = 'Purge after 1 day'; +$wb['soft_delete_keep_7_txt'] = 'Purge after 7 days'; +$wb['soft_delete_keep_30_txt'] = 'Purge after 30 days'; +$wb['soft_delete_keep_90_txt'] = 'Purge after 90 days'; +$wb['soft_delete_keep_365_txt'] = 'Purge after 365 days'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; +$wb['php_fpm_incron_reload_txt'] = 'Install incron trigger file to reload PHP-FPM'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; +$wb['php_fpm_reload_mode_txt'] = 'PHP-FPM reload mode'; +$wb['content_filter_txt'] = 'Content Filter'; +$wb['le_signature_type_txt'] = 'Certificate signature type'; +$wb['le_auto_cleanup_txt'] = 'Automatically purge unused Let\'s Encrypt certificates'; +$wb['le_auto_cleanup_denylist_txt'] = 'Domains that should never be purged'; +$wb['le_auto_cleanup_denylist_note_txt'] = 'Comma separated list of domain globs that should not be purged.
E.g. mail.*, externally-managed.example.com
Placeholders:'; +$wb['le_auto_cleanup_denylist_error_custom'] = 'Invalid list of domain globs'; +$wb['le_delete_on_site_remove_txt'] = 'Delete Let\'s Encrypt certificate on website removal'; +$wb['le_revoke_before_delete_txt'] = 'Revoke a certificate before deleting it (prevents Let\'s Encrypt renewal warnings)'; diff --git a/interface/web/admin/lib/lang/tr_server_php.lng b/interface/web/admin/lib/lang/tr_server_php.lng index 71b130e3d2..b0abcb8623 100644 --- a/interface/web/admin/lib/lang/tr_server_php.lng +++ b/interface/web/admin/lib/lang/tr_server_php.lng @@ -17,4 +17,16 @@ $wb['php_fpm_socket_dir_txt'] = 'PHP-FPM socket directory'; $wb['active_txt'] = 'Etkin'; $wb['php_in_use_error'] = 'This PHP-Version is in use.'; $wb['php_name_in_use_error'] = 'The name can not be changed.'; +$wb['PHP Sort Priority'] = 'Priority'; +$wb['sortprio_txt'] = 'Priority'; +$wb['sortprio_long_txt'] = 'Priority of PHP version in the PHP version select box
Default PHP has prio 0 if enabled
Lower value is higher priority'; +$wb['PHP-CLI settings'] = 'PHP-CLI settings'; +$wb['php_cli_binary_txt'] = 'Path to the PHP CLI binary'; +$wb['tooltip_php_cli_binary_txt'] = 'Path to the PHP CLI binary including the filename'; +$wb['php_jk_section_txt'] = 'PHP Jailkit section'; +$wb['tooltip_php_jk_section_txt'] = 'Identifier of the PHP version in your jk_init.ini (without square brackets).'; +$wb['php_cli_jk_section_error_regex'] = 'Invalid Jaikit chroot section'; +$wb['php_cli_binary_error_regex'] = 'Invalid path to PHP cli binary'; +$wb['php_cli_binary_empty'] = 'PHP CLI binary field must not be empty'; +$wb['php_cli_jk_section_empty'] = 'PHP Jailkit section field must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/tr_server_php_list.lng b/interface/web/admin/lib/lang/tr_server_php_list.lng index 4468e7ead9..82fb3cc32e 100644 --- a/interface/web/admin/lib/lang/tr_server_php_list.lng +++ b/interface/web/admin/lib/lang/tr_server_php_list.lng @@ -6,4 +6,5 @@ $wb['client_id_txt'] = 'Müşteri'; $wb['name_txt'] = 'PHP Adı'; $wb['active_txt'] = 'Etkin'; $wb['usage_txt'] = 'Usage count'; +$wb['sortprio_txt'] = 'Priority'; ?> diff --git a/interface/web/admin/lib/lang/tr_system_config.lng b/interface/web/admin/lib/lang/tr_system_config.lng index 6054bebc88..9181932af0 100644 --- a/interface/web/admin/lib/lang/tr_system_config.lng +++ b/interface/web/admin/lib/lang/tr_system_config.lng @@ -107,4 +107,7 @@ $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.'; $wb['dns_show_zoneexport_txt'] = 'Show zone export.'; $wb['le_caa_autocreate_options_txt'] = 'Enable automatic creation of CAA record on issuing LE'; -?> +$wb['show_delete_on_forms_txt'] = 'Show delete button on edit forms'; +$wb['dns_external_slave_server_txt'] = 'External DNS servers (comma separated)'; +$wb['mailbox_show_last_access_txt'] = 'Show last access time for mail accounts'; +$wb['postgresql_database_txt'] = 'PostgreSQL Database'; diff --git a/interface/web/admin/lib/module.conf.php b/interface/web/admin/lib/module.conf.php index 59b2e1ffc1..faa10eda31 100644 --- a/interface/web/admin/lib/module.conf.php +++ b/interface/web/admin/lib/module.conf.php @@ -8,6 +8,7 @@ $module['startpage'] = 'admin/server_list.php'; $module['tab_width'] = '60'; $module['order'] = '90'; +$module['icon'] = 'icon icon-admin'; $items[] = array( 'title' => 'CP Users', @@ -92,6 +93,24 @@ 'items' => $items); +// cleanup +unset($items); + +$items[] = array( 'title' => 'Available Extensions', + 'target' => 'content', + 'link' => 'admin/extension_repo_list.php', + 'html_id' => 'extension_repo_list'); + +$items[] = array( 'title' => 'Installed Extensions', + 'target' => 'content', + 'link' => 'admin/extension_install_list.php', + 'html_id' => 'extension_install_list'); + +$module['nav'][] = array( 'title' => 'Extension Installer', + 'open' => "1", + 'items' => $items); + + // cleanup unset($items); diff --git a/interface/web/admin/list/firewall.list.php b/interface/web/admin/list/firewall.list.php index 884779110a..4835cb9d4a 100644 --- a/interface/web/admin/list/firewall.list.php +++ b/interface/web/admin/list/firewall.list.php @@ -57,11 +57,11 @@ 'value' => array('y' => $app->lng('yes_txt'), 'n' => $app->lng('no_txt'))); $liste["item"][] = array( 'field' => "server_id", - 'datatype' => "VARCHAR", + 'datatype' => "INTEGER", 'formtype' => "SELECT", - 'op' => "like", - 'prefix' => "%", - 'suffix' => "%", + 'op' => "=", + 'prefix' => "", + 'suffix' => "", 'datasource' => array ( 'type' => 'SQL', 'querystring' => 'SELECT server_id,server_name FROM server WHERE {AUTHSQL} ORDER BY server_name', 'keyfield'=> 'server_id', diff --git a/interface/web/admin/list/remote_user.list.php b/interface/web/admin/list/remote_user.list.php index 7dc0fbf430..de11f0d9a1 100644 --- a/interface/web/admin/list/remote_user.list.php +++ b/interface/web/admin/list/remote_user.list.php @@ -35,7 +35,7 @@ $liste['item'][] = array( 'field' => 'remote_userid', - 'datatype' => 'VARCHAR', + 'datatype' => 'INTEGER', 'formtype' => 'SELECT', 'op' => '=', 'prefix' => '', diff --git a/interface/web/admin/list/server_php.list.php b/interface/web/admin/list/server_php.list.php index a4a38901ab..4ea40bdae1 100644 --- a/interface/web/admin/list/server_php.list.php +++ b/interface/web/admin/list/server_php.list.php @@ -39,6 +39,9 @@ //* Enable auth $liste['auth'] = 'no'; +// mark columns for php sorting (no real mySQL columns) +$liste["phpsort"] = array('usage'); + /***************************************************** * Suchfelder diff --git a/interface/web/admin/remote_action_ispcupdate.php b/interface/web/admin/remote_action_ispcupdate.php index 938f25a1a3..d7c50e79f6 100644 --- a/interface/web/admin/remote_action_ispcupdate.php +++ b/interface/web/admin/remote_action_ispcupdate.php @@ -36,7 +36,7 @@ $app->auth->check_module_permissions('admin'); //* This is only allowed for administrators -if(!$app->auth->is_admin()) die('only allowed for administrators.'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); $app->uses('tpl'); diff --git a/interface/web/admin/remote_action_osupdate.php b/interface/web/admin/remote_action_osupdate.php index e39cf0eedf..87f8ee8c2b 100644 --- a/interface/web/admin/remote_action_osupdate.php +++ b/interface/web/admin/remote_action_osupdate.php @@ -35,7 +35,7 @@ $app->auth->check_security_permissions('admin_allow_osupdate'); //* This is only allowed for administrators -if(!$app->auth->is_admin()) die('only allowed for administrators.'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); $app->uses('tpl'); diff --git a/interface/web/admin/remote_user_del.php b/interface/web/admin/remote_user_del.php index b23336cab3..28534db38d 100644 --- a/interface/web/admin/remote_user_del.php +++ b/interface/web/admin/remote_user_del.php @@ -46,6 +46,8 @@ $app->auth->check_module_permissions('admin'); $app->auth->check_security_permissions('admin_allow_remote_users'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); + $app->uses('tpl,tform'); $app->load('tform_actions'); diff --git a/interface/web/admin/remote_user_edit.php b/interface/web/admin/remote_user_edit.php index efc4f72a38..66903c80f1 100644 --- a/interface/web/admin/remote_user_edit.php +++ b/interface/web/admin/remote_user_edit.php @@ -16,6 +16,8 @@ $app->auth->check_module_permissions('admin'); $app->auth->check_security_permissions('admin_allow_remote_users'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); + // Disable this function in demo mode if($conf['demo_mode'] == true) $app->error('This function is disabled in demo mode.'); diff --git a/interface/web/admin/remote_user_list.php b/interface/web/admin/remote_user_list.php index 1830ba562f..086236de93 100644 --- a/interface/web/admin/remote_user_list.php +++ b/interface/web/admin/remote_user_list.php @@ -12,6 +12,8 @@ die(); } +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); + // Loading the class $app->uses('listform_actions'); diff --git a/interface/web/admin/server_config_del.php b/interface/web/admin/server_config_del.php index 3a332edd12..4487063c58 100644 --- a/interface/web/admin/server_config_del.php +++ b/interface/web/admin/server_config_del.php @@ -45,6 +45,9 @@ //* Check permissions for module $app->auth->check_module_permissions('admin'); $app->auth->check_security_permissions('admin_allow_server_config'); + +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); + if($conf['demo_mode'] == true) $app->error('This function is disabled in demo mode.'); $app->uses("tform_actions"); diff --git a/interface/web/admin/server_config_edit.php b/interface/web/admin/server_config_edit.php index 32aa270893..863e537d8d 100644 --- a/interface/web/admin/server_config_edit.php +++ b/interface/web/admin/server_config_edit.php @@ -45,6 +45,7 @@ $app->auth->check_module_permissions('admin'); $app->auth->check_security_permissions('admin_allow_server_config'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); // Loading classes $app->uses('tpl,tform,tform_actions'); @@ -125,7 +126,7 @@ function onShowEdit() { function onShowEnd() { global $app; - $tmp = $app->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = ? AND ((SELECT COUNT(*) FROM server) > 1)", $this->id); + $tmp = $app->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = ? AND ((SELECT COUNT(*) FROM server) >= 1)", $this->id); $app->tpl->setVar('server_name', $app->functions->htmlentities($tmp['server_name'])); unset($tmp); diff --git a/interface/web/admin/server_config_list.php b/interface/web/admin/server_config_list.php index 5a1d61517b..293ec95ffe 100644 --- a/interface/web/admin/server_config_list.php +++ b/interface/web/admin/server_config_list.php @@ -43,6 +43,7 @@ //* Check permissions for module $app->auth->check_module_permissions('admin'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); $app->uses('listform_actions'); //$app->listform_actions->SQLExtWhere = "wb = 'W'"; diff --git a/interface/web/admin/server_del.php b/interface/web/admin/server_del.php index f90bfa7f86..4bce6ac623 100644 --- a/interface/web/admin/server_del.php +++ b/interface/web/admin/server_del.php @@ -47,6 +47,8 @@ $app->auth->check_security_permissions('admin_allow_server_services'); if($conf['demo_mode'] == true) $app->error('This function is disabled in demo mode.'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); + $app->uses("tform_actions"); $app->tform_actions->onDelete(); diff --git a/interface/web/admin/server_edit.php b/interface/web/admin/server_edit.php index b146d8f295..11a7a7fbe5 100644 --- a/interface/web/admin/server_edit.php +++ b/interface/web/admin/server_edit.php @@ -45,6 +45,8 @@ $app->auth->check_module_permissions('admin'); $app->auth->check_security_permissions('admin_allow_server_services'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); + // Loading classes $app->uses('tpl,tform,tform_actions'); $app->load('tform_actions'); diff --git a/interface/web/admin/server_ip_del.php b/interface/web/admin/server_ip_del.php index 61252c31c0..49474847e1 100644 --- a/interface/web/admin/server_ip_del.php +++ b/interface/web/admin/server_ip_del.php @@ -46,6 +46,8 @@ $app->auth->check_module_permissions('admin'); $app->auth->check_security_permissions('admin_allow_server_ip'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); + $app->uses("tform_actions"); $app->tform_actions->onDelete(); diff --git a/interface/web/admin/server_ip_edit.php b/interface/web/admin/server_ip_edit.php index f7872f4438..68338b7f90 100644 --- a/interface/web/admin/server_ip_edit.php +++ b/interface/web/admin/server_ip_edit.php @@ -45,6 +45,8 @@ $app->auth->check_module_permissions('admin'); $app->auth->check_security_permissions('admin_allow_server_ip'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); + // Loading classes $app->uses('tpl,tform,tform_actions'); $app->load('tform_actions'); diff --git a/interface/web/admin/server_ip_list.php b/interface/web/admin/server_ip_list.php index 29622428aa..c8b7d098fa 100644 --- a/interface/web/admin/server_ip_list.php +++ b/interface/web/admin/server_ip_list.php @@ -43,6 +43,7 @@ //* Check permissions for module $app->auth->check_module_permissions('admin'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); $app->uses('listform_actions'); diff --git a/interface/web/admin/server_ip_map_del.php b/interface/web/admin/server_ip_map_del.php index a861b46ccb..a7cf42d0f1 100644 --- a/interface/web/admin/server_ip_map_del.php +++ b/interface/web/admin/server_ip_map_del.php @@ -38,6 +38,8 @@ $app->auth->check_module_permissions('admin'); $app->auth->check_security_permissions('admin_allow_server_ip'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); + $app->uses("tform_actions"); $app->tform_actions->onDelete(); diff --git a/interface/web/admin/server_ip_map_edit.php b/interface/web/admin/server_ip_map_edit.php index b518867309..88a8068cb0 100644 --- a/interface/web/admin/server_ip_map_edit.php +++ b/interface/web/admin/server_ip_map_edit.php @@ -36,6 +36,8 @@ $app->auth->check_module_permissions('admin'); $app->auth->check_security_permissions('admin_allow_server_ip'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); + // Loading classes $app->uses('tpl,tform,tform_actions'); $app->load('tform_actions'); diff --git a/interface/web/admin/server_ip_map_list.php b/interface/web/admin/server_ip_map_list.php index 04a9a4e506..df52c85b70 100644 --- a/interface/web/admin/server_ip_map_list.php +++ b/interface/web/admin/server_ip_map_list.php @@ -35,6 +35,7 @@ //* Check permissions for module $app->auth->check_module_permissions('admin'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); $app->uses('listform_actions'); diff --git a/interface/web/admin/server_list.php b/interface/web/admin/server_list.php index 30ba12373a..1adc573b1f 100644 --- a/interface/web/admin/server_list.php +++ b/interface/web/admin/server_list.php @@ -43,6 +43,7 @@ //* Check permissions for module $app->auth->check_module_permissions('admin'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); $app->uses('listform_actions'); $app->listform_actions->onLoad(); diff --git a/interface/web/admin/server_php_del.php b/interface/web/admin/server_php_del.php index 82b4c8a17d..1a28edb27a 100644 --- a/interface/web/admin/server_php_del.php +++ b/interface/web/admin/server_php_del.php @@ -46,6 +46,8 @@ $app->auth->check_module_permissions('admin'); $app->auth->check_security_permissions('admin_allow_server_php'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); + $app->uses('tpl,tform,tform_actions'); $app->load('tform_actions'); diff --git a/interface/web/admin/server_php_edit.php b/interface/web/admin/server_php_edit.php index a9e7b38bbb..e6b8e0daec 100644 --- a/interface/web/admin/server_php_edit.php +++ b/interface/web/admin/server_php_edit.php @@ -45,6 +45,8 @@ $app->auth->check_module_permissions('admin'); $app->auth->check_security_permissions('admin_allow_server_php'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); + // Loading classes $app->uses('tpl,tform,tform_actions'); $app->load('tform_actions'); @@ -54,7 +56,13 @@ function onSubmit() { parent::onSubmit(); } function onBeforeUpdate() { - global $app; + + global $app; + + //check if Prio tab got update/save if yes disable datalog update - not needed + if(isset($this->dataRecord["sortprio"])) { + $app->tform->formDef['db_history'] = 'no'; + } //* 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 diff --git a/interface/web/admin/server_php_list.php b/interface/web/admin/server_php_list.php index 11ef881792..de96174f6c 100644 --- a/interface/web/admin/server_php_list.php +++ b/interface/web/admin/server_php_list.php @@ -43,6 +43,7 @@ //* Check permissions for module $app->auth->check_module_permissions('admin'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); $app->uses('listform_actions'); diff --git a/interface/web/admin/system_config_edit.php b/interface/web/admin/system_config_edit.php index 941f6e0bbe..b75ce628fc 100644 --- a/interface/web/admin/system_config_edit.php +++ b/interface/web/admin/system_config_edit.php @@ -45,6 +45,8 @@ $app->auth->check_module_permissions('admin'); $app->auth->check_security_permissions('admin_allow_system_config'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); + // Loading classes $app->uses('tpl,tform,tform_actions'); $app->load('tform_actions'); diff --git a/interface/web/admin/templates/extension_edit.htm b/interface/web/admin/templates/extension_edit.htm new file mode 100644 index 0000000000..c4376c9f18 --- /dev/null +++ b/interface/web/admin/templates/extension_edit.htm @@ -0,0 +1,115 @@ + + + + +
+
+ +
+
+ +
+
+
    + +
+
+
+
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ + +
+
+ +
+ +
+ + +
+
+ +
+ +
+ +
+
+ +
{tmpl_var name='repo_version_txt'}:
+
+
+
+ + + +
+
+ + + +
+
+ + +
+ +
+ +
+
+
+ +
+ +
+ +
+
+ + +
+ +
+

{tmpl_var name='free_limits'}

+
+
+
+ + +
+ +
+

{tmpl_var name='postinstall_info'}

+
+
+
+ + + +
+
+ + +
+
+
+
diff --git a/interface/web/admin/templates/extension_install.htm b/interface/web/admin/templates/extension_install.htm new file mode 100644 index 0000000000..fac50bc7dc --- /dev/null +++ b/interface/web/admin/templates/extension_install.htm @@ -0,0 +1,81 @@ + + +

+ +

+ + +
+
+ +
+
+ +
+
+
    + +
+
+
+
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ + +
+
+ +
+ +
+ +
+
+ + + + + + + +
+
+ + +
+
+
+
diff --git a/interface/web/admin/templates/extension_install_list.htm b/interface/web/admin/templates/extension_install_list.htm new file mode 100644 index 0000000000..7bb64d534d --- /dev/null +++ b/interface/web/admin/templates/extension_install_list.htm @@ -0,0 +1,51 @@ + + + +

{tmpl_var name="toolsarea_head_txt"}

+ +

+ + +
+ +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{tmpl_var name='search_limit'}
{tmpl_var name="active"}{tmpl_var name="server_name"}{tmpl_var name="name"}{tmpl_var name="version"}{tmpl_var name="title"} + +
+
+ + \ No newline at end of file diff --git a/interface/web/admin/templates/extension_msg.htm b/interface/web/admin/templates/extension_msg.htm new file mode 100644 index 0000000000..1d6f3a152f --- /dev/null +++ b/interface/web/admin/templates/extension_msg.htm @@ -0,0 +1,17 @@ + + + + +

+ {tmpl_var name='message_txt'} +

+{tmpl_if name='info_text'} +

+ {tmpl_var name='info_text'} +

+{/tmpl_if} +

+ {tmpl_var name='btn_next_txt'} > +

\ No newline at end of file diff --git a/interface/web/admin/templates/extension_repo_list.htm b/interface/web/admin/templates/extension_repo_list.htm new file mode 100644 index 0000000000..4252e8d9fd --- /dev/null +++ b/interface/web/admin/templates/extension_repo_list.htm @@ -0,0 +1,59 @@ + + +

+

{tmpl_var name="toolsarea_head_txt"}

+ +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{tmpl_var name='search_limit'}
{tmpl_var name="name"}{tmpl_var name="version"}{tmpl_var name="date"}{tmpl_var name="title"} + +
{tmpl_var name='globalsearch_noresults_text_txt'}
+
+ + \ 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 dcc7328e2c..9a157ce4a7 100644 --- a/interface/web/admin/templates/server_config_dns_edit.htm +++ b/interface/web/admin/templates/server_config_dns_edit.htm @@ -14,6 +14,12 @@
+
+ +
+
+ +
diff --git a/interface/web/admin/templates/server_config_mail_edit.htm b/interface/web/admin/templates/server_config_mail_edit.htm index 84683191c8..485f94b740 100644 --- a/interface/web/admin/templates/server_config_mail_edit.htm +++ b/interface/web/admin/templates/server_config_mail_edit.htm @@ -143,7 +143,9 @@
- {tmpl_var name='mailbox_soft_delete'} {tmpl_var name='mailbox_soft_delete_info_txt'} +
diff --git a/interface/web/admin/templates/server_config_server_edit.htm b/interface/web/admin/templates/server_config_server_edit.htm index 1898f2bc55..61ca6d73b5 100644 --- a/interface/web/admin/templates/server_config_server_edit.htm +++ b/interface/web/admin/templates/server_config_server_edit.htm @@ -80,6 +80,11 @@
{tmpl_var name='backup_delete'}
+
+
+ +
+
{tmpl_var name='sysbackup_copies_note_txt'}
diff --git a/interface/web/admin/templates/server_config_web_edit.htm b/interface/web/admin/templates/server_config_web_edit.htm index 2161907cb5..956fd3039a 100644 --- a/interface/web/admin/templates/server_config_web_edit.htm +++ b/interface/web/admin/templates/server_config_web_edit.htm @@ -54,7 +54,17 @@

- {tmpl_var name='vhost_proxy_protocol_enabled'} + +
+
+
+ +
+
@@ -238,6 +248,28 @@

+
+ +
+
+
+
+
+
+
+
+
+
+
+
+ +
+ +
{tmpl_var name='le_auto_cleanup_denylist_note_txt'} [server_name] +
+

@@ -253,7 +285,15 @@

-
+
+ +
+ +
+
+
{tmpl_var name='set_folder_permissions_on_update'} diff --git a/interface/web/admin/templates/server_list.htm b/interface/web/admin/templates/server_list.htm index 313fad7ff1..ca2600b491 100644 --- a/interface/web/admin/templates/server_list.htm +++ b/interface/web/admin/templates/server_list.htm @@ -51,16 +51,16 @@

- {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/admin/templates/server_php_cli_edit.htm b/interface/web/admin/templates/server_php_cli_edit.htm new file mode 100644 index 0000000000..bc641ee827 --- /dev/null +++ b/interface/web/admin/templates/server_php_cli_edit.htm @@ -0,0 +1,15 @@ +
+ +
+
+ +
+ + + +
+ + +
+ + diff --git a/interface/web/admin/templates/server_php_list.htm b/interface/web/admin/templates/server_php_list.htm index a2595a8474..2f9a3f922e 100644 --- a/interface/web/admin/templates/server_php_list.htm +++ b/interface/web/admin/templates/server_php_list.htm @@ -4,12 +4,12 @@

{tmpl_var name="toolsarea_head_txt"}

- + - - - + + +

@@ -19,6 +19,7 @@

+ @@ -27,7 +28,7 @@

- + @@ -40,7 +41,8 @@

- + + @@ -48,16 +50,16 @@

- + - +
{tmpl_var name='search_limit'}
{tmpl_var name="server_id"} {tmpl_var name="client_id"} {tmpl_var name="name"}{tmpl_var name="usage"}{tmpl_var name="sortprio"}{tmpl_var name="usage"}
{tmpl_var name='globalsearch_noresults_text_txt'}{tmpl_var name='globalsearch_noresults_text_txt'}
- - + + diff --git a/interface/web/admin/templates/server_php_sort_edit.htm b/interface/web/admin/templates/server_php_sort_edit.htm new file mode 100644 index 0000000000..c7ca24adfa --- /dev/null +++ b/interface/web/admin/templates/server_php_sort_edit.htm @@ -0,0 +1,11 @@ +
+ +
+
+ + + +
+ + +
diff --git a/interface/web/admin/templates/system_config_dns_edit.htm b/interface/web/admin/templates/system_config_dns_edit.htm index 9636b4a261..0395c5b17d 100644 --- a/interface/web/admin/templates/system_config_dns_edit.htm +++ b/interface/web/admin/templates/system_config_dns_edit.htm @@ -12,6 +12,13 @@

+
+ +
+ +
+
+
diff --git a/interface/web/admin/templates/system_config_mail_edit.htm b/interface/web/admin/templates/system_config_mail_edit.htm index ac9271a9cf..4731240bd2 100644 --- a/interface/web/admin/templates/system_config_mail_edit.htm +++ b/interface/web/admin/templates/system_config_mail_edit.htm @@ -34,6 +34,12 @@ {tmpl_var name='mailbox_show_custom_rules_tab'}
+
+ +
+ {tmpl_var name='mailbox_show_last_access'} +
+
diff --git a/interface/web/admin/templates/system_config_misc_edit.htm b/interface/web/admin/templates/system_config_misc_edit.htm index 5c57eeb9a6..30d893bc10 100644 --- a/interface/web/admin/templates/system_config_misc_edit.htm +++ b/interface/web/admin/templates/system_config_misc_edit.htm @@ -90,6 +90,12 @@ {tmpl_var name='show_support_messages'}
+
+ +
+ {tmpl_var name='show_delete_on_forms'} +
+
diff --git a/interface/web/admin/templates/system_config_sites_edit.htm b/interface/web/admin/templates/system_config_sites_edit.htm index 9a36e3275e..944fba5ec5 100644 --- a/interface/web/admin/templates/system_config_sites_edit.htm +++ b/interface/web/admin/templates/system_config_sites_edit.htm @@ -109,6 +109,12 @@ {tmpl_var name='le_caa_autocreate_options'}
+
+ +
+ {tmpl_var name='postgresql_database'} +
+
diff --git a/interface/web/admin/users_del.php b/interface/web/admin/users_del.php index ce413b60f4..afd2c01fdb 100644 --- a/interface/web/admin/users_del.php +++ b/interface/web/admin/users_del.php @@ -47,6 +47,8 @@ $app->auth->check_security_permissions('admin_allow_del_cpuser'); if($conf['demo_mode'] == true && $_REQUEST['id'] <= 3) $app->error('This function is disabled in demo mode.'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); + $app->uses("tform_actions"); $app->tform_actions->onDelete(); diff --git a/interface/web/admin/users_edit.php b/interface/web/admin/users_edit.php index 7f0c691c42..1165580567 100644 --- a/interface/web/admin/users_edit.php +++ b/interface/web/admin/users_edit.php @@ -43,6 +43,7 @@ //* Check permissions for module $app->auth->check_module_permissions('admin'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); // Loading classes $app->uses('tpl,tform,tform_actions'); @@ -54,7 +55,7 @@ function onBeforeInsert() { global $app, $conf; //* Security settings check - if(isset($this->dataRecord['typ']) && $this->dataRecord['typ'][0] == 'admin') { + if(isset($this->dataRecord['typ']) && in_array('admin', $this->dataRecord['typ'])) { $app->auth->check_security_permissions('admin_allow_new_admin'); } @@ -63,7 +64,7 @@ function onBeforeInsert() { } //* Do not add users here - if(isset($this->dataRecord['typ']) && $this->dataRecord['typ'][0] == 'user') { + if(isset($this->dataRecord['typ']) && in_array('user', $this->dataRecord['typ'])) { $app->tform->errorMessage .= $app->tform->wordbook['no_user_insert']; } @@ -75,7 +76,7 @@ function onBeforeUpdate() { if($conf['demo_mode'] == true && $_REQUEST['id'] <= 3) $app->error('This function is disabled in demo mode.'); //* Security settings check - if(isset($this->dataRecord['typ']) && $this->dataRecord['typ'][0] == 'admin') { + if(isset($this->dataRecord['typ']) && in_array('admin', $this->dataRecord['typ'])) { $app->auth->check_security_permissions('admin_allow_new_admin'); } @@ -86,12 +87,12 @@ function onBeforeUpdate() { $this->oldDataRecord = $app->tform->getDataRecord($this->id); //* A user that belongs to a client record (client or reseller) may not have typ admin - if(isset($this->dataRecord['typ']) && $this->dataRecord['typ'][0] == 'admin' && $this->oldDataRecord['client_id'] > 0) { + if(isset($this->dataRecord['typ']) && in_array('admin', $this->dataRecord['typ']) && $this->oldDataRecord['client_id'] > 0) { $app->tform->errorMessage .= $app->tform->wordbook['client_not_admin_err']; } //* Users have to belong to clients - if(isset($this->dataRecord['typ']) && $this->dataRecord['typ'][0] == 'user' && $this->oldDataRecord['client_id'] == 0) { + if(isset($this->dataRecord['typ']) && in_array('user', $this->dataRecord['typ']) && $this->oldDataRecord['client_id'] == 0) { $app->tform->errorMessage .= $app->tform->wordbook['no_user_insert']; } diff --git a/interface/web/admin/users_list.php b/interface/web/admin/users_list.php index 1f83258929..e74d128577 100644 --- a/interface/web/admin/users_list.php +++ b/interface/web/admin/users_list.php @@ -43,6 +43,7 @@ //* Check permissions for module $app->auth->check_module_permissions('admin'); +if(!$app->auth->is_admin()) die('Allowed for administrators only.'); $app->uses('listform_actions'); $app->listform_actions->SQLOrderBy = 'ORDER BY sys_user.username'; diff --git a/interface/web/capp.php b/interface/web/capp.php index 71d3d9ba35..462f775f76 100644 --- a/interface/web/capp.php +++ b/interface/web/capp.php @@ -45,7 +45,7 @@ } if (!preg_match("/^[a-z]{2,20}$/i", $mod)) die('module name contains unallowed chars.'); -if ($redirect != '' && !preg_match("/^[a-z0-9]+\/[a-z0-9_\.\-]+\?id=[0-9]{1,9}(\&type=[a-z0-9_\.\-]+)?$/i", $redirect)) die('redirect contains unallowed chars.'); +if ($redirect != '' && !preg_match("/^[a-z0-9]+\/[a-z0-9_\.\-]+\?id=[0-9]{1,9}(\&type=[a-z0-9_\.\-]+)?(\&next_tab=[a-z0-9_\.\-]+)?$/i", $redirect)) die('redirect contains unallowed chars.'); //* Check if user may use the module. $user_modules = explode(",", $_SESSION["s"]["user"]["modules"]); diff --git a/interface/web/client/client_edit.php b/interface/web/client/client_edit.php index e0b74595fc..0947307304 100644 --- a/interface/web/client/client_edit.php +++ b/interface/web/client/client_edit.php @@ -70,9 +70,50 @@ function onShowNew() { } } + // Hide the info tab when creating a new client. + unset($app->tform->formDef["tabs"]['info']); + $app->tform->formDef["tab_default"] = "address"; + parent::onShowNew(); } + function onShowEdit() { + global $app, $conf; + chdir('../dashboard'); + + $dashlet_list = array(); + $dashlets = array('quota.php', 'databasequota.php', 'mailquota.php', 'limits.php'); + $current_client_id = $this->id; + + foreach ($dashlets as $file) { + if ($file != '.' && $file != '..' && !is_dir(ISPC_WEB_PATH.'/dashboard/dashlets/'.$file)) { + $dashlet_name = substr($file, 0, -4); + $dashlet_class = 'dashlet_'.$dashlet_name; + include_once ISPC_WEB_PATH.'/dashboard/dashlets/'.$file; + $dashlet_list[$dashlet_name] = new $dashlet_class; + $dashlets_html .= $dashlet_list[$dashlet_name]->show($current_client_id); + } + } + $app->tpl->setVar('dashlets', $dashlets_html); + + chdir('../client'); + + $tmp = $app->db->queryOneRecord("SELECT company_name, contact_firstname, contact_name, email FROM client WHERE client_id = ?", $current_client_id); + $app->tpl->setVar('company_name', $tmp['company_name']); + $app->tpl->setVar('contact_name', $tmp['contact_name']); + $app->tpl->setVar('email', $tmp['email']); + + $app->uses('getconf,system'); + $web_config = $app->getconf->get_global_config('sites'); + if($web_config['postgresql_database'] == 'y') { + $app->tpl->setVar('show_postgresql', true); + } else { + $app->tpl->setVar('show_postgresql', false); + } + + parent::onShowEdit(); + } + function onSubmit() { global $app, $conf; @@ -435,13 +476,13 @@ function onAfterUpdate() { } // lock and cancel - if(!isset($this->dataRecord['locked'])) $this->dataRecord['locked'] = 'n'; - if(isset($conf['demo_mode']) && $conf['demo_mode'] != true && $this->dataRecord["locked"] != $this->oldDataRecord['locked']) + if(!isset($this->dataRecord['locked']) && isset($this->dataRecord['username'])) $this->dataRecord['locked'] = 'n'; + if(isset($conf['demo_mode']) && $conf['demo_mode'] != true && $this->dataRecord["locked"] != $this->oldDataRecord['locked']) { $lock = $app->functions->func_client_lock($this->id,$this->dataRecord["locked"]); } - if(!isset($this->dataRecord['canceled'])) $this->dataRecord['canceled'] = 'n'; + if(!isset($this->dataRecord['canceled']) && isset($this->dataRecord['username'])) $this->dataRecord['canceled'] = 'n'; if(isset($conf['demo_mode']) && $conf['demo_mode'] != true && $this->dataRecord["canceled"] != $this->oldDataRecord['canceled']) { $cancel = $app->functions->func_client_cancel($this->id,$this->dataRecord["canceled"]); } diff --git a/interface/web/client/client_template_edit.php b/interface/web/client/client_template_edit.php index 7cc3ab5ff9..b004ec9de3 100644 --- a/interface/web/client/client_template_edit.php +++ b/interface/web/client/client_template_edit.php @@ -80,6 +80,15 @@ function onShowEnd() { } else { $app->tpl->setVar("show_aps_menu", 0); } + + $app->uses('getconf,system'); + $web_config = $app->getconf->get_global_config('sites'); + if($web_config['postgresql_database'] == 'y') { + $app->tpl->setVar('show_postgresql', true); + } else { + $app->tpl->setVar('show_postgresql', false); + } + parent::onShowEnd(); } diff --git a/interface/web/client/domain_edit.php b/interface/web/client/domain_edit.php index af7b900b91..78b7d53de7 100644 --- a/interface/web/client/domain_edit.php +++ b/interface/web/client/domain_edit.php @@ -130,6 +130,13 @@ function onShowEnd() { $app->tpl->setVar($wb); + $csrf_token = $app->auth->csrf_token_get('_domain_del'); + $app->tpl->setVar('_csrf_id', $csrf_token['csrf_id']); + $app->tpl->setVar('_csrf_key', $csrf_token['csrf_key']); + + $global_config = $app->getconf->get_global_config(); + $app->tpl->setVar('show_delete_on_forms', $global_config['misc']['show_delete_on_forms']); + parent::onShowEnd(); } diff --git a/interface/web/client/form/client.tform.php b/interface/web/client/form/client.tform.php index c6d05f9eb3..59d2190f75 100644 --- a/interface/web/client/form/client.tform.php +++ b/interface/web/client/form/client.tform.php @@ -41,11 +41,12 @@ $form["title"] = "Client"; $form["description"] = ""; $form["name"] = "client"; +$form["record_name_field"] = "username"; $form["action"] = "client_edit.php"; $form["db_table"] = "client"; $form["db_table_idx"] = "client_id"; $form["db_history"] = "yes"; -$form["tab_default"] = "address"; +$form["tab_default"] = "info"; $form["list_default"] = "client_list.php"; $form["auth"] = 'yes'; @@ -80,6 +81,12 @@ } } +$form["tabs"]['info'] = array ( + 'title' => "Info", + 'width' => 100, + 'template' => "templates/client_edit_info.htm", + 'fields' => array () +); $form["tabs"]['address'] = array ( 'title' => "Address", 'width' => 100, @@ -224,6 +231,9 @@ 'language' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'SELECT', + 'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY', + 'errmsg'=> 'language_error_empty'), + ), 'default' => $conf["language"], 'value' => $language_list, 'separator' => '', @@ -422,6 +432,7 @@ 'cols' => '', 'searchable' => 2 ), + // Deprecated 'icq' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'TEXT', @@ -1455,6 +1466,20 @@ 'rows' => '', 'cols' => '' ), + 'limit_database_postgresql' => array ( + 'datatype' => 'INTEGER', + 'formtype' => 'TEXT', + 'validators' => array ( 0 => array ( 'type' => 'ISINT', + 'errmsg'=> 'limit_database_error_notint'), + ), + 'default' => '-1', + 'value' => '', + 'separator' => '', + 'width' => '10', + 'maxlength' => '10', + 'rows' => '', + 'cols' => '' + ), 'limit_cron' => array ( 'datatype' => 'INTEGER', 'formtype' => 'TEXT', diff --git a/interface/web/client/form/client_circle.tform.php b/interface/web/client/form/client_circle.tform.php index 64eee542d7..6916c2248b 100644 --- a/interface/web/client/form/client_circle.tform.php +++ b/interface/web/client/form/client_circle.tform.php @@ -112,10 +112,11 @@ 'default' => '', 'separator' => ',', 'datasource' => array ( 'type' => 'SQL', - 'querystring' => 'SELECT client_id,contact_name FROM client WHERE {AUTHSQL} ORDER BY contact_name', + 'querystring' => 'SELECT client_id,CONCAT(company_name, " (",contact_firstname, " ", contact_name, ")") as contact_label FROM client WHERE {AUTHSQL} ORDER BY contact_label', 'keyfield'=> 'client_id', - 'valuefield'=> 'contact_name' + 'valuefield'=> 'contact_label' ), + 'render_inline' => 'n', 'value' => '' ), 'description' => array ( diff --git a/interface/web/client/form/client_template.tform.php b/interface/web/client/form/client_template.tform.php index adf72670f8..3dda317492 100644 --- a/interface/web/client/form/client_template.tform.php +++ b/interface/web/client/form/client_template.tform.php @@ -860,6 +860,20 @@ 'rows' => '', 'cols' => '' ), + 'limit_database_postgresql' => array ( + 'datatype' => 'INTEGER', + 'formtype' => 'TEXT', + 'validators' => array ( 0 => array ( 'type' => 'ISINT', + 'errmsg'=> 'limit_database_error_notint'), + ), + 'default' => '-1', + 'value' => '', + 'separator' => '', + 'width' => '10', + 'maxlength' => '10', + 'rows' => '', + 'cols' => '' + ), 'limit_cron' => array ( 'datatype' => 'INTEGER', 'formtype' => 'TEXT', diff --git a/interface/web/client/form/domain.tform.php b/interface/web/client/form/domain.tform.php index f521a55b2d..0e8d3ffa1c 100644 --- a/interface/web/client/form/domain.tform.php +++ b/interface/web/client/form/domain.tform.php @@ -63,6 +63,7 @@ $form["title"] = "Domain"; $form["description"] = ""; $form["name"] = "domain"; +$form["record_name_field"] = "domain"; $form["action"] = "domain_edit.php"; $form["db_table"] = "domain"; $form["db_table_idx"] = "domain_id"; @@ -106,7 +107,8 @@ 'default' => '', 'value' => '', 'width' => '30', - 'maxlength' => '255' + 'maxlength' => '255', + 'searchable' => 1, ), //################################# // END Datatable fields diff --git a/interface/web/client/form/reseller.tform.php b/interface/web/client/form/reseller.tform.php index d48dea6229..35cb511bcd 100644 --- a/interface/web/client/form/reseller.tform.php +++ b/interface/web/client/form/reseller.tform.php @@ -41,11 +41,12 @@ $form["title"] = "Reseller"; $form["description"] = ""; $form["name"] = "reseller"; +$form["record_name_field"] = "username"; $form["action"] = "reseller_edit.php"; $form["db_table"] = "client"; $form["db_table_idx"] = "client_id"; $form["db_history"] = "yes"; -$form["tab_default"] = "address"; +$form["tab_default"] = "info"; $form["list_default"] = "reseller_list.php"; $form["auth"] = 'yes'; @@ -80,6 +81,12 @@ } } +$form["tabs"]['info'] = array( + 'title' => "Info", + 'width' => 100, + 'template' => "templates/reseller_edit_info.htm", + 'fields' => array() +); $form["tabs"]['address'] = array ( 'title' => "Address", 'width' => 100, @@ -1434,6 +1441,20 @@ 'rows' => '', 'cols' => '' ), + 'limit_database_postgresql' => array ( + 'datatype' => 'INTEGER', + 'formtype' => 'TEXT', + 'validators' => array ( 0 => array ( 'type' => 'ISINT', + 'errmsg'=> 'limit_database_error_notint'), + ), + 'default' => '-1', + 'value' => '', + 'separator' => '', + 'width' => '10', + 'maxlength' => '10', + 'rows' => '', + 'cols' => '' + ), 'limit_cron' => array ( 'datatype' => 'INTEGER', 'formtype' => 'TEXT', diff --git a/interface/web/client/lib/lang/ar_client.lng b/interface/web/client/lib/lang/ar_client.lng index 8b6ff765c9..9f881f7c17 100644 --- a/interface/web/client/lib/lang/ar_client.lng +++ b/interface/web/client/lib/lang/ar_client.lng @@ -206,3 +206,4 @@ $wb['password_click_to_set_txt'] = 'Click to set'; $wb['limit_dns_record_error_notint'] = 'The dns record limit must be a number.'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Limits'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/ar_domain.lng b/interface/web/client/lib/lang/ar_domain.lng index a66a2258af..50dc79323a 100644 --- a/interface/web/client/lib/lang/ar_domain.lng +++ b/interface/web/client/lib/lang/ar_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'The domain-name is empty'; $wb['domain_error_unique'] = 'The domain already exists'; $wb['domain_error_regex'] = 'This domain-name is not allowed'; $wb['Domain'] = 'Domain'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/bg_client.lng b/interface/web/client/lib/lang/bg_client.lng index 233a7c9b27..d44884b1a9 100644 --- a/interface/web/client/lib/lang/bg_client.lng +++ b/interface/web/client/lib/lang/bg_client.lng @@ -206,3 +206,4 @@ $wb['password_click_to_set_txt'] = 'Click to set'; $wb['limit_dns_record_error_notint'] = 'The dns record limit must be a number.'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Limits'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/bg_domain.lng b/interface/web/client/lib/lang/bg_domain.lng index c60ae56045..fdffdcd26a 100644 --- a/interface/web/client/lib/lang/bg_domain.lng +++ b/interface/web/client/lib/lang/bg_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'Името на домейна е празно'; $wb['domain_error_unique'] = 'Домейна ÑъщеÑтвува'; $wb['domain_error_regex'] = 'Това име на домейн не е разрешен.'; $wb['Domain'] = 'Домейн'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/br_client.lng b/interface/web/client/lib/lang/br_client.lng index 58557a3a00..9f7e4eb642 100644 --- a/interface/web/client/lib/lang/br_client.lng +++ b/interface/web/client/lib/lang/br_client.lng @@ -206,3 +206,4 @@ $wb['email_error_empty'] = 'O email está vazio'; $wb['limit_directive_snippets_txt'] = 'Exibir configurações de seleção do servidor Web'; $wb['Address'] = 'Cliente'; $wb['Limits'] = 'Limites'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/br_domain.lng b/interface/web/client/lib/lang/br_domain.lng index 0ebd82d63c..cafdc79358 100644 --- a/interface/web/client/lib/lang/br_domain.lng +++ b/interface/web/client/lib/lang/br_domain.lng @@ -3,3 +3,4 @@ $wb['domain_error_empty'] = 'O domínio está vazio.'; $wb['domain_error_unique'] = 'O domínio já existe.'; $wb['domain_error_regex'] = 'O nome do domínio não é permitido.'; $wb['Domain'] = 'Domínio'; +$wb['domain_txt'] = 'Domain'; diff --git a/interface/web/client/lib/lang/ca_client.lng b/interface/web/client/lib/lang/ca_client.lng index 4482b8f241..99fd5bafb7 100644 --- a/interface/web/client/lib/lang/ca_client.lng +++ b/interface/web/client/lib/lang/ca_client.lng @@ -206,3 +206,4 @@ $wb['password_click_to_set_txt'] = 'Click to set'; $wb['limit_dns_record_error_notint'] = 'The dns record limit must be a number.'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Limits'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/ca_domain.lng b/interface/web/client/lib/lang/ca_domain.lng index f94d21bbe5..7ca7e894a1 100644 --- a/interface/web/client/lib/lang/ca_domain.lng +++ b/interface/web/client/lib/lang/ca_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'Le nom de domaine est vide'; $wb['domain_error_unique'] = 'Ce nom de domaine existe déjà'; $wb['domain_error_regex'] = 'Ce nom de domaine n\'est pas autorisé'; $wb['Domain'] = 'Domaine'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/cn.lng b/interface/web/client/lib/lang/cn.lng new file mode 100644 index 0000000000..cefa8508e9 --- /dev/null +++ b/interface/web/client/lib/lang/cn.lng @@ -0,0 +1,31 @@ + diff --git a/interface/web/client/lib/lang/cn_client.lng b/interface/web/client/lib/lang/cn_client.lng new file mode 100644 index 0000000000..1c1e578019 --- /dev/null +++ b/interface/web/client/lib/lang/cn_client.lng @@ -0,0 +1,211 @@ + diff --git a/interface/web/client/lib/lang/cn_client_circle_list.lng b/interface/web/client/lib/lang/cn_client_circle_list.lng new file mode 100644 index 0000000000..2fbf762682 --- /dev/null +++ b/interface/web/client/lib/lang/cn_client_circle_list.lng @@ -0,0 +1,10 @@ + diff --git a/interface/web/client/lib/lang/cn_client_del.lng b/interface/web/client/lib/lang/cn_client_del.lng new file mode 100644 index 0000000000..5598db2e34 --- /dev/null +++ b/interface/web/client/lib/lang/cn_client_del.lng @@ -0,0 +1,10 @@ + diff --git a/interface/web/client/lib/lang/cn_client_message.lng b/interface/web/client/lib/lang/cn_client_message.lng new file mode 100644 index 0000000000..080ca70cdd --- /dev/null +++ b/interface/web/client/lib/lang/cn_client_message.lng @@ -0,0 +1,20 @@ + diff --git a/interface/web/client/lib/lang/cn_client_message_template.lng b/interface/web/client/lib/lang/cn_client_message_template.lng new file mode 100644 index 0000000000..7ec95daad1 --- /dev/null +++ b/interface/web/client/lib/lang/cn_client_message_template.lng @@ -0,0 +1,13 @@ + diff --git a/interface/web/client/lib/lang/cn_client_message_template_list.lng b/interface/web/client/lib/lang/cn_client_message_template_list.lng new file mode 100644 index 0000000000..8e6fbaf90e --- /dev/null +++ b/interface/web/client/lib/lang/cn_client_message_template_list.lng @@ -0,0 +1,5 @@ + diff --git a/interface/web/client/lib/lang/cn_client_template.lng b/interface/web/client/lib/lang/cn_client_template.lng new file mode 100644 index 0000000000..1e4eace66f --- /dev/null +++ b/interface/web/client/lib/lang/cn_client_template.lng @@ -0,0 +1,131 @@ + diff --git a/interface/web/client/lib/lang/cn_clients_list.lng b/interface/web/client/lib/lang/cn_clients_list.lng new file mode 100644 index 0000000000..c12c0f7009 --- /dev/null +++ b/interface/web/client/lib/lang/cn_clients_list.lng @@ -0,0 +1,14 @@ + diff --git a/interface/web/client/lib/lang/cn_domain.lng b/interface/web/client/lib/lang/cn_domain.lng new file mode 100644 index 0000000000..022feb4ba4 --- /dev/null +++ b/interface/web/client/lib/lang/cn_domain.lng @@ -0,0 +1,7 @@ + diff --git a/interface/web/client/lib/lang/cn_domain_list.lng b/interface/web/client/lib/lang/cn_domain_list.lng new file mode 100644 index 0000000000..8eed884ad9 --- /dev/null +++ b/interface/web/client/lib/lang/cn_domain_list.lng @@ -0,0 +1,6 @@ + diff --git a/interface/web/client/lib/lang/cn_reseller.lng b/interface/web/client/lib/lang/cn_reseller.lng new file mode 100644 index 0000000000..0f002ddc2d --- /dev/null +++ b/interface/web/client/lib/lang/cn_reseller.lng @@ -0,0 +1,216 @@ + 0或-1(无é™åˆ¶ï¼‰'; +$wb['limit_web_quota_txt'] = 'Webé…é¢'; +$wb['limit_traffic_quota_txt'] = 'æµé‡é…é¢'; +$wb['limit_trafficquota_error_notint'] = 'æµé‡é…é¢å¿…须是数字。'; +$wb['customer_no_txt'] = '客户编å·'; +$wb['vat_id_txt'] = '增值税编å·'; +$wb['required_fields_txt'] = '*必填字段'; +$wb['limit_openvz_vm_txt'] = '最大虚拟æœåŠ¡å™¨æ•°'; +$wb['limit_openvz_vm_template_id_txt'] = '强制虚拟æœåŠ¡å™¨æ¨¡æ¿'; +$wb['limit_openvz_vm_error_notint'] = '虚拟æœåС噍é™åˆ¶å¿…须是数字。'; +$wb['web_php_options_notempty'] = '未选择PHP选项。请选择至少一个PHP选项。'; +$wb['ssh_chroot_notempty'] = '未选择SSH chroot选项。请选择至少一个选项。'; +$wb['username_error_collision'] = '用户åä¸èƒ½ä»¥-web-或-web-åŽè·Ÿæ•°å­—开头。'; +$wb['web_limits_txt'] = 'Webé™åˆ¶'; +$wb['email_limits_txt'] = '电å­é‚®ä»¶é™åˆ¶'; +$wb['database_limits_txt'] = 'æ•°æ®åº“é™åˆ¶'; +$wb['cron_job_limits_txt'] = '计划任务é™åˆ¶'; +$wb['dns_limits_txt'] = 'DNSé™åˆ¶'; +$wb['virtualization_limits_txt'] = '虚拟化é™åˆ¶'; +$wb['generate_password_txt'] = '生æˆå¯†ç '; +$wb['repeat_password_txt'] = 'é‡å¤å¯†ç '; +$wb['password_mismatch_txt'] = '密ç ä¸åŒ¹é…。'; +$wb['password_match_txt'] = '密ç åŒ¹é…。'; +$wb['email_error_isemail'] = '请输入有效的电å­é‚®ä»¶åœ°å€ã€‚'; +$wb['customer_no_error_unique'] = '客户编å·å¿…须唯一(或为空)。'; +$wb['paypal_email_error_isemail'] = '请输入有效的PayPal电å­é‚®ä»¶åœ°å€ã€‚'; +$wb['paypal_email_txt'] = 'PayPal电å­é‚®ä»¶'; +$wb['company_id_txt'] = 'å…¬å¸/ä¼ä¸šID'; +$wb['bank_account_number_txt'] = '银行账å·'; +$wb['bank_account_owner_txt'] = '银行账户所有者'; +$wb['bank_code_txt'] = '银行代ç '; +$wb['bank_name_txt'] = '银行åç§°'; +$wb['bank_account_iban_txt'] = 'IBAN'; +$wb['bank_account_swift_txt'] = 'BIC/Swift'; +$wb['aps_limits_txt'] = 'APS安装器é™åˆ¶'; +$wb['limit_aps_txt'] = '最大APS实例数'; +$wb['limit_aps_error_notint'] = 'APS实例é™åˆ¶å¿…须是数字。'; +$wb['default_slave_dnsserver_txt'] = '默认次è¦DNSæœåС噍'; +$wb['locked_txt'] = 'å·²é”定'; +$wb['canceled_txt'] = '已喿¶ˆ'; +$wb['gender_m_txt'] = '先生'; +$wb['gender_f_txt'] = '女士'; +$wb['gender_txt'] = '称呼'; +$wb['web_servers_txt'] = 'WebæœåС噍'; +$wb['web_servers_placeholder'] = '选择WebæœåС噍'; +$wb['no_web_server_error'] = '至少必须选择一个WebæœåŠ¡å™¨ã€‚'; +$wb['web_servers_used'] = '您正在å°è¯•从此客户端中删除的æœåŠ¡å™¨ç”¨ä½œWebæœåŠ¡å™¨ã€‚è¯·ç¡®ä¿åœ¨åˆ é™¤ä¹‹å‰ï¼Œæ­¤æœåŠ¡å™¨æœªè¢«æ­¤å®¢æˆ·ç«¯ä½¿ç”¨ã€‚'; +$wb['dns_servers_txt'] = 'DNSæœåС噍'; +$wb['dns_servers_placeholder'] = '选择DNSæœåС噍'; +$wb['no_dns_server_error'] = '至少必须选择一个DNSæœåŠ¡å™¨ã€‚'; +$wb['dns_servers_used'] = '您正在å°è¯•从此客户端中删除的æœåŠ¡å™¨ç”¨ä½œDNSæœåŠ¡å™¨ã€‚è¯·ç¡®ä¿åœ¨åˆ é™¤ä¹‹å‰ï¼Œæ­¤æœåŠ¡å™¨æœªè¢«æ­¤å®¢æˆ·ç«¯ä½¿ç”¨ã€‚'; +$wb['db_servers_txt'] = 'æ•°æ®åº“æœåС噍'; +$wb['db_servers_placeholder'] = '选择数æ®åº“æœåС噍'; +$wb['no_db_server_error'] = '至少必须选择一个数æ®åº“æœåŠ¡å™¨ã€‚'; +$wb['db_servers_used'] = '您正在å°è¯•从此客户端中删除的æœåŠ¡å™¨ç”¨ä½œæ•°æ®åº“æœåŠ¡å™¨ã€‚è¯·ç¡®ä¿åœ¨åˆ é™¤ä¹‹å‰ï¼Œæ­¤æœåŠ¡å™¨æœªè¢«æ­¤å®¢æˆ·ç«¯ä½¿ç”¨ã€‚'; +$wb['mail_servers_txt'] = '邮件æœåС噍'; +$wb['mail_servers_placeholder'] = '选择邮件æœåС噍'; +$wb['no_mail_server_error'] = '至少必须选择一个邮件æœåŠ¡å™¨ã€‚'; +$wb['mail_servers_used'] = '您å°è¯•从此客户端中删除的æœåŠ¡å™¨æ­£åœ¨ç”¨ä½œé‚®ä»¶æœåŠ¡å™¨ã€‚è¯·ç¡®ä¿åœ¨åˆ é™¤ä¹‹å‰æ­¤æœåŠ¡å™¨æœªè¢«æ­¤å®¢æˆ·ç«¯ä½¿ç”¨ã€‚'; +$wb['customer_no_template_txt'] = 'å®¢æˆ·ç¼–å·æ¨¡æ¿'; +$wb['customer_no_template_error_regex_txt'] = 'å®¢æˆ·ç¼–å·æ¨¡æ¿åŒ…嫿— æ•ˆå­—符。'; +$wb['customer_no_start_txt'] = '客户编å·èµ·å§‹å€¼'; +$wb['customer_no_counter_txt'] = '客户编å·è®¡æ•°å™¨'; + +$wb['xmpp_limits_txt'] = 'XMPP é™åˆ¶'; +$wb['xmpp_servers_txt'] = 'XMPP æœåС噍'; +$wb['xmpp_servers_placeholder'] = '选择 XMPP æœåС噍'; +$wb['no_xmpp_server_error'] = '必须选择至少一个 XMPP æœåŠ¡å™¨ã€‚'; +$wb['xmpp_servers_used'] = '您正在å°è¯•从此客户端中删除的æœåŠ¡å™¨è¢«ç”¨ä½œ XMPP æœåŠ¡å™¨ã€‚åœ¨åˆ é™¤ä¹‹å‰ï¼Œè¯·ç¡®ä¿è¯¥æœåŠ¡å™¨æœªè¢«æ­¤å®¢æˆ·ç«¯ä½¿ç”¨ã€‚'; +$wb['limit_xmpp_domain_error_notint'] = 'XMPP 域é™åˆ¶å¿…须为数字。'; +$wb['limit_xmpp_user_error_notint'] = 'XMPP 用户é™åˆ¶å¿…须为数字。'; +$wb['limit_xmpp_domain_txt'] = 'XMPP 域最大数é‡'; +$wb['limit_xmpp_user_txt'] = 'XMPP 叿ˆ·æœ€å¤§æ•°é‡'; +$wb['limit_xmpp_muc_txt'] = '支æŒå¤šç”¨æˆ·èŠå¤©'; +$wb['limit_xmpp_pastebin_txt'] = 'æ”¯æŒ MUC çš„ Pastebin'; +$wb['limit_xmpp_httparchive_txt'] = 'æ”¯æŒ MUC çš„ HTTP 存档'; +$wb['limit_xmpp_anon_txt'] = '匿å主机å¯ç”¨'; +$wb['limit_xmpp_vjud_txt'] = 'VJUD 用户目录å¯ç”¨'; +$wb['limit_xmpp_proxy_txt'] = 'Bytestream 代ç†å¯ç”¨'; +$wb['limit_xmpp_status_txt'] = '状æ€ä¸»æœºå¯ç”¨'; +$wb['added_by_txt'] = '添加人'; +$wb['added_date_txt'] = '添加日期'; +$wb['limit_domainmodule_error_notint'] = '域模å—é™åˆ¶å¿…须为数字。'; +$wb['limit_domainmodule_txt'] = '域模å—é™åˆ¶'; +$wb['client_limits_txt'] = '客户端é™åˆ¶'; +$wb['err_msg_master_tpl_set'] = '如果选择了除 "自定义" 之外的任何主模æ¿ï¼Œåˆ™å¿½ç•¥æ‰€æœ‰è‡ªå®šä¹‰é™åˆ¶è®¾ç½®ã€‚'; +$wb['invalid_vat_id'] = '无效的增值税å·ã€‚'; +$wb['btn_save_txt'] = 'ä¿å­˜'; +$wb['btn_cancel_txt'] = 'å–æ¶ˆ'; +$wb['email_error_empty'] = '电å­é‚®ä»¶ä¸ºç©º'; +$wb['limit_directive_snippets_txt'] = '显示WebæœåС噍é…置选项'; +$wb['limit_database_user_txt'] = '最大数æ®åº“用户数'; +$wb['limit_database_user_error_notint'] = 'æ•°æ®åº“用户é™åˆ¶å¿…须为数字。'; +$wb['limit_database_quota_txt'] = 'æ•°æ®åº“é…é¢'; +$wb['limit_database_quota_error_notint'] = 'æ•°æ®åº“é…é¢é™åˆ¶å¿…须为数字。'; +$wb['Reseller'] = 'ç»é”€å•†'; +$wb['Address'] = '地å€'; +$wb['Limits'] = 'é™åˆ¶'; diff --git a/interface/web/client/lib/lang/cn_resellers_list.lng b/interface/web/client/lib/lang/cn_resellers_list.lng new file mode 100644 index 0000000000..b8768e3224 --- /dev/null +++ b/interface/web/client/lib/lang/cn_resellers_list.lng @@ -0,0 +1,11 @@ + diff --git a/interface/web/client/lib/lang/cz_client.lng b/interface/web/client/lib/lang/cz_client.lng index 691bac508a..2217ca1958 100644 --- a/interface/web/client/lib/lang/cz_client.lng +++ b/interface/web/client/lib/lang/cz_client.lng @@ -206,3 +206,4 @@ $wb['password_click_to_set_txt'] = 'Pro nastavení klikni zde'; $wb['limit_dns_record_error_notint'] = 'Limit DNS záznamů musí být Äíslo.'; $wb['Address'] = 'Adresa'; $wb['Limits'] = 'Limity'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/cz_domain.lng b/interface/web/client/lib/lang/cz_domain.lng index 33d634d8e3..c40ae34ce2 100644 --- a/interface/web/client/lib/lang/cz_domain.lng +++ b/interface/web/client/lib/lang/cz_domain.lng @@ -3,3 +3,4 @@ $wb['domain_error_empty'] = 'Doménové jméno je prázdné'; $wb['domain_error_unique'] = 'Doména již existuje'; $wb['domain_error_regex'] = 'Toto doménové jméno je zakázáno'; $wb['Domain'] = 'Doména'; +$wb['domain_txt'] = 'Domain'; diff --git a/interface/web/client/lib/lang/de_client.lng b/interface/web/client/lib/lang/de_client.lng index 34328a17f8..3774319404 100644 --- a/interface/web/client/lib/lang/de_client.lng +++ b/interface/web/client/lib/lang/de_client.lng @@ -206,3 +206,4 @@ $wb['password_click_to_set_txt'] = 'Click to set'; $wb['limit_dns_record_error_notint'] = 'The dns record limit must be a number.'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Limits'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/de_domain.lng b/interface/web/client/lib/lang/de_domain.lng index eb4276a3f8..3b0ab87a4b 100644 --- a/interface/web/client/lib/lang/de_domain.lng +++ b/interface/web/client/lib/lang/de_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'Der Domain Name darf nicht leer sein'; $wb['domain_error_unique'] = 'Die Domain existiert bereits'; $wb['domain_error_regex'] = 'Dieser Domain Name ist nicht gültig'; $wb['Domain'] = 'Domain'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/dk_client.lng b/interface/web/client/lib/lang/dk_client.lng index c5154dac5d..43c00f9c01 100644 --- a/interface/web/client/lib/lang/dk_client.lng +++ b/interface/web/client/lib/lang/dk_client.lng @@ -206,3 +206,4 @@ $wb['limit_directive_snippets_txt'] = 'Show web server config selection'; $wb['limit_dns_record_error_notint'] = 'The dns record limit must be a number.'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Limits'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/dk_domain.lng b/interface/web/client/lib/lang/dk_domain.lng index cd9c60de58..240c9e9f29 100644 --- a/interface/web/client/lib/lang/dk_domain.lng +++ b/interface/web/client/lib/lang/dk_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'Domæne-navn er tomt'; $wb['domain_error_unique'] = 'Domænet findes allerede'; $wb['domain_error_regex'] = 'Dette domæne-navn er ikke tilladt'; $wb['Domain'] = 'Domæne'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/el_client.lng b/interface/web/client/lib/lang/el_client.lng index 373c751a52..151b2ed4f5 100644 --- a/interface/web/client/lib/lang/el_client.lng +++ b/interface/web/client/lib/lang/el_client.lng @@ -206,3 +206,4 @@ $wb['password_click_to_set_txt'] = 'Click to set'; $wb['limit_dns_record_error_notint'] = 'The dns record limit must be a number.'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Limits'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/el_domain.lng b/interface/web/client/lib/lang/el_domain.lng index 696d10da42..624c72cd1d 100644 --- a/interface/web/client/lib/lang/el_domain.lng +++ b/interface/web/client/lib/lang/el_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'Το όνομα domain δεν έχει οÏιστε $wb['domain_error_unique'] = 'Το όνομα domain υπάÏχει'; $wb['domain_error_regex'] = 'Το όνομα domain δεν επιτÏέπεται'; $wb['Domain'] = 'Domain'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/en_client.lng b/interface/web/client/lib/lang/en_client.lng index acaafeb390..467424a6ca 100644 --- a/interface/web/client/lib/lang/en_client.lng +++ b/interface/web/client/lib/lang/en_client.lng @@ -208,3 +208,4 @@ $wb['email_error_empty'] = 'Email is empty'; $wb['limit_directive_snippets_txt'] = 'Show web server config selection'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Limits'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/en_domain.lng b/interface/web/client/lib/lang/en_domain.lng index a66a2258af..50dc79323a 100644 --- a/interface/web/client/lib/lang/en_domain.lng +++ b/interface/web/client/lib/lang/en_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'The domain-name is empty'; $wb['domain_error_unique'] = 'The domain already exists'; $wb['domain_error_regex'] = 'This domain-name is not allowed'; $wb['Domain'] = 'Domain'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/es_client.lng b/interface/web/client/lib/lang/es_client.lng index d9210b8ec3..b55abb52e2 100644 --- a/interface/web/client/lib/lang/es_client.lng +++ b/interface/web/client/lib/lang/es_client.lng @@ -206,3 +206,4 @@ $wb['password_click_to_set_txt'] = 'Click to set'; $wb['limit_dns_record_error_notint'] = 'The dns record limit must be a number.'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Limits'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/es_domain.lng b/interface/web/client/lib/lang/es_domain.lng index 95ccf9ae23..525eee7a87 100644 --- a/interface/web/client/lib/lang/es_domain.lng +++ b/interface/web/client/lib/lang/es_domain.lng @@ -3,4 +3,5 @@ $wb['Domain'] = 'Dominio'; $wb['domain_error_empty'] = 'El nombre de dominio está vacío'; $wb['domain_error_regex'] = 'Este nombre de dominio no esta permitido'; $wb['domain_error_unique'] = 'El dominio ya existe'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/fi_client.lng b/interface/web/client/lib/lang/fi_client.lng index 68058e1ab5..e55a5e9bfb 100644 --- a/interface/web/client/lib/lang/fi_client.lng +++ b/interface/web/client/lib/lang/fi_client.lng @@ -206,3 +206,4 @@ $wb['password_click_to_set_txt'] = 'Click to set'; $wb['limit_dns_record_error_notint'] = 'The dns record limit must be a number.'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Limits'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/fi_domain.lng b/interface/web/client/lib/lang/fi_domain.lng index a66a2258af..50dc79323a 100644 --- a/interface/web/client/lib/lang/fi_domain.lng +++ b/interface/web/client/lib/lang/fi_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'The domain-name is empty'; $wb['domain_error_unique'] = 'The domain already exists'; $wb['domain_error_regex'] = 'This domain-name is not allowed'; $wb['Domain'] = 'Domain'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/fr_client.lng b/interface/web/client/lib/lang/fr_client.lng index fc96c0d319..98a3907fb7 100644 --- a/interface/web/client/lib/lang/fr_client.lng +++ b/interface/web/client/lib/lang/fr_client.lng @@ -206,3 +206,4 @@ $wb['password_click_to_set_txt'] = 'Click to set'; $wb['limit_dns_record_error_notint'] = 'The dns record limit must be a number.'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Limits'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/fr_domain.lng b/interface/web/client/lib/lang/fr_domain.lng index 03b7c14c28..d0b489518f 100644 --- a/interface/web/client/lib/lang/fr_domain.lng +++ b/interface/web/client/lib/lang/fr_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'Le nom de domaine est vide'; $wb['domain_error_unique'] = 'Ce nom de domaine existe déjà'; $wb['domain_error_regex'] = 'Ce nom de domaine n’est pas autorisé'; $wb['Domain'] = 'Domaine'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/hr_client.lng b/interface/web/client/lib/lang/hr_client.lng index ed00a5c520..709b20c793 100644 --- a/interface/web/client/lib/lang/hr_client.lng +++ b/interface/web/client/lib/lang/hr_client.lng @@ -206,3 +206,4 @@ $wb['password_click_to_set_txt'] = 'Click to set'; $wb['limit_dns_record_error_notint'] = 'The dns record limit must be a number.'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Limits'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/hr_domain.lng b/interface/web/client/lib/lang/hr_domain.lng index 784ccc63b7..d557bfa631 100644 --- a/interface/web/client/lib/lang/hr_domain.lng +++ b/interface/web/client/lib/lang/hr_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'Ime domene je prazno'; $wb['domain_error_unique'] = 'Domena već postoji'; $wb['domain_error_regex'] = 'Ovo ime domene ne možete upotrijebiti'; $wb['Domain'] = 'Domain'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/hu_client.lng b/interface/web/client/lib/lang/hu_client.lng index 9e6ad94a7b..98c0d2ceb9 100644 --- a/interface/web/client/lib/lang/hu_client.lng +++ b/interface/web/client/lib/lang/hu_client.lng @@ -206,3 +206,4 @@ $wb['password_click_to_set_txt'] = 'Click to set'; $wb['limit_dns_record_error_notint'] = 'The dns record limit must be a number.'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Limits'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/hu_domain.lng b/interface/web/client/lib/lang/hu_domain.lng index a66a2258af..50dc79323a 100644 --- a/interface/web/client/lib/lang/hu_domain.lng +++ b/interface/web/client/lib/lang/hu_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'The domain-name is empty'; $wb['domain_error_unique'] = 'The domain already exists'; $wb['domain_error_regex'] = 'This domain-name is not allowed'; $wb['Domain'] = 'Domain'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/id_client.lng b/interface/web/client/lib/lang/id_client.lng index 47f8971b1f..4e2a526c74 100644 --- a/interface/web/client/lib/lang/id_client.lng +++ b/interface/web/client/lib/lang/id_client.lng @@ -206,3 +206,4 @@ $wb['password_click_to_set_txt'] = 'Click to set'; $wb['limit_dns_record_error_notint'] = 'The dns record limit must be a number.'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Limits'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/id_domain.lng b/interface/web/client/lib/lang/id_domain.lng index 2091e872f9..73ea445c79 100644 --- a/interface/web/client/lib/lang/id_domain.lng +++ b/interface/web/client/lib/lang/id_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'Nama Domain kosong'; $wb['domain_error_unique'] = 'Domain sudah ada'; $wb['domain_error_regex'] = 'Nama Domain ini tidak diperbolehkan'; $wb['Domain'] = 'Domain'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/it_client.lng b/interface/web/client/lib/lang/it_client.lng index 9b2e6492cf..520bcd37de 100644 --- a/interface/web/client/lib/lang/it_client.lng +++ b/interface/web/client/lib/lang/it_client.lng @@ -206,3 +206,4 @@ $wb['password_click_to_set_txt'] = 'Clicca per impostare'; $wb['limit_dns_record_error_notint'] = 'Il limite di record DNS deve essere un numero.'; $wb['Address'] = 'Indirizzo'; $wb['Limits'] = 'Limiti'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/it_domain.lng b/interface/web/client/lib/lang/it_domain.lng index dba372981a..bb7c9e6640 100644 --- a/interface/web/client/lib/lang/it_domain.lng +++ b/interface/web/client/lib/lang/it_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'Nome dominio è vuoto'; $wb['domain_error_unique'] = 'Dominio già esistente'; $wb['domain_error_regex'] = 'Questo nome di dominio non è permesso'; $wb['Domain'] = 'Dominio'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/ja_client.lng b/interface/web/client/lib/lang/ja_client.lng index 4639125717..10caa99603 100644 --- a/interface/web/client/lib/lang/ja_client.lng +++ b/interface/web/client/lib/lang/ja_client.lng @@ -206,3 +206,4 @@ $wb['password_click_to_set_txt'] = 'Click to set'; $wb['limit_dns_record_error_notint'] = 'The dns record limit must be a number.'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Limits'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/ja_domain.lng b/interface/web/client/lib/lang/ja_domain.lng index a66a2258af..50dc79323a 100644 --- a/interface/web/client/lib/lang/ja_domain.lng +++ b/interface/web/client/lib/lang/ja_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'The domain-name is empty'; $wb['domain_error_unique'] = 'The domain already exists'; $wb['domain_error_regex'] = 'This domain-name is not allowed'; $wb['Domain'] = 'Domain'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/nl_client.lng b/interface/web/client/lib/lang/nl_client.lng index 593d5dbdff..b247947c76 100644 --- a/interface/web/client/lib/lang/nl_client.lng +++ b/interface/web/client/lib/lang/nl_client.lng @@ -206,3 +206,4 @@ $wb['limit_directive_snippets_txt'] = 'Show web server config selection'; $wb['limit_dns_record_error_notint'] = 'The dns record limit must be a number.'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Limits'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/nl_domain.lng b/interface/web/client/lib/lang/nl_domain.lng index c1da1b741d..78c728bc47 100644 --- a/interface/web/client/lib/lang/nl_domain.lng +++ b/interface/web/client/lib/lang/nl_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'De domein naam is niet ingevuld'; $wb['domain_error_unique'] = 'Het domein bestaat reeds'; $wb['domain_error_regex'] = 'Deze domein naam is niet toegestaan'; $wb['Domain'] = 'Domein'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/pl_client.lng b/interface/web/client/lib/lang/pl_client.lng index 6943deef95..662d04e447 100644 --- a/interface/web/client/lib/lang/pl_client.lng +++ b/interface/web/client/lib/lang/pl_client.lng @@ -206,3 +206,4 @@ $wb['password_click_to_set_txt'] = 'Click to set'; $wb['limit_dns_record_error_notint'] = 'The dns record limit must be a number.'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Limits'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/pl_domain.lng b/interface/web/client/lib/lang/pl_domain.lng index 9f3e80ff64..f80dea959f 100644 --- a/interface/web/client/lib/lang/pl_domain.lng +++ b/interface/web/client/lib/lang/pl_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'Nazwa domeny jest pusta'; $wb['domain_error_unique'] = 'Domena o podanej nazwie już istnieje'; $wb['domain_error_regex'] = 'Nazwa domeny jest niedopuszczalna'; $wb['Domain'] = 'Domena'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/pt_client.lng b/interface/web/client/lib/lang/pt_client.lng index 2b90c823ca..96fd1dd4e0 100644 --- a/interface/web/client/lib/lang/pt_client.lng +++ b/interface/web/client/lib/lang/pt_client.lng @@ -206,3 +206,4 @@ $wb['password_click_to_set_txt'] = 'Click to set'; $wb['limit_dns_record_error_notint'] = 'The dns record limit must be a number.'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Limits'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/pt_domain.lng b/interface/web/client/lib/lang/pt_domain.lng index a66a2258af..50dc79323a 100644 --- a/interface/web/client/lib/lang/pt_domain.lng +++ b/interface/web/client/lib/lang/pt_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'The domain-name is empty'; $wb['domain_error_unique'] = 'The domain already exists'; $wb['domain_error_regex'] = 'This domain-name is not allowed'; $wb['Domain'] = 'Domain'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/ro_client.lng b/interface/web/client/lib/lang/ro_client.lng index 70407714a8..79dcc4fc50 100644 --- a/interface/web/client/lib/lang/ro_client.lng +++ b/interface/web/client/lib/lang/ro_client.lng @@ -206,3 +206,4 @@ $wb['password_click_to_set_txt'] = 'Click to set'; $wb['limit_dns_record_error_notint'] = 'The dns record limit must be a number.'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Limits'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/ro_domain.lng b/interface/web/client/lib/lang/ro_domain.lng index a66a2258af..50dc79323a 100644 --- a/interface/web/client/lib/lang/ro_domain.lng +++ b/interface/web/client/lib/lang/ro_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'The domain-name is empty'; $wb['domain_error_unique'] = 'The domain already exists'; $wb['domain_error_regex'] = 'This domain-name is not allowed'; $wb['Domain'] = 'Domain'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/ru_client.lng b/interface/web/client/lib/lang/ru_client.lng index d8cd5e4788..936463e3e8 100644 --- a/interface/web/client/lib/lang/ru_client.lng +++ b/interface/web/client/lib/lang/ru_client.lng @@ -206,3 +206,4 @@ $wb['password_click_to_set_txt'] = 'Клик Ð´Ð»Ñ ÑƒÑтановки'; $wb['limit_dns_record_error_notint'] = 'Лимит вторичных DNS-зон должен быть чиÑлом.'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Лимиты'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/ru_domain.lng b/interface/web/client/lib/lang/ru_domain.lng index 50f0d3f2fc..a387fb970e 100644 --- a/interface/web/client/lib/lang/ru_domain.lng +++ b/interface/web/client/lib/lang/ru_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'Домен пуÑтой.'; $wb['domain_error_unique'] = 'Ð˜Ð¼Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ быть уникальным.'; $wb['domain_error_regex'] = 'Ðекорректное Ð¸Ð¼Ñ Ð´Ð¾Ð¼ÐµÐ½Ð°.'; $wb['Domain'] = 'Домен'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/se_client.lng b/interface/web/client/lib/lang/se_client.lng index 41aca6a6bb..c1a921d750 100644 --- a/interface/web/client/lib/lang/se_client.lng +++ b/interface/web/client/lib/lang/se_client.lng @@ -206,3 +206,4 @@ $wb['password_click_to_set_txt'] = 'Click to set'; $wb['limit_dns_record_error_notint'] = 'The dns record limit must be a number.'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Limits'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/se_domain.lng b/interface/web/client/lib/lang/se_domain.lng index df60bbeca2..b300fb890a 100644 --- a/interface/web/client/lib/lang/se_domain.lng +++ b/interface/web/client/lib/lang/se_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'Domännamnet är tomt'; $wb['domain_error_unique'] = 'Domänen finns redan'; $wb['domain_error_regex'] = 'Denna domän är ogiltig'; $wb['Domain'] = 'Domän'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/sk_client.lng b/interface/web/client/lib/lang/sk_client.lng index 5ca58b5b0e..87c92c7184 100644 --- a/interface/web/client/lib/lang/sk_client.lng +++ b/interface/web/client/lib/lang/sk_client.lng @@ -206,3 +206,4 @@ $wb['password_click_to_set_txt'] = 'Click to set'; $wb['limit_dns_record_error_notint'] = 'The dns record limit must be a number.'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Limits'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/sk_domain.lng b/interface/web/client/lib/lang/sk_domain.lng index a66a2258af..50dc79323a 100644 --- a/interface/web/client/lib/lang/sk_domain.lng +++ b/interface/web/client/lib/lang/sk_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'The domain-name is empty'; $wb['domain_error_unique'] = 'The domain already exists'; $wb['domain_error_regex'] = 'This domain-name is not allowed'; $wb['Domain'] = 'Domain'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/lang/tr_client.lng b/interface/web/client/lib/lang/tr_client.lng index ca1e2f7429..25d28da1fc 100644 --- a/interface/web/client/lib/lang/tr_client.lng +++ b/interface/web/client/lib/lang/tr_client.lng @@ -208,3 +208,4 @@ $wb['email_error_empty'] = 'E-posta boÅŸ olamaz.'; $wb['limit_directive_snippets_txt'] = 'Web Sunucu Yapılandırma Seçimi Görüntülensin'; $wb['Address'] = 'Address'; $wb['Limits'] = 'Sınırlar'; +$wb['language_error_empty'] = 'Language is empty.'; diff --git a/interface/web/client/lib/lang/tr_domain.lng b/interface/web/client/lib/lang/tr_domain.lng index d0b4e228da..3f7312bf8a 100644 --- a/interface/web/client/lib/lang/tr_domain.lng +++ b/interface/web/client/lib/lang/tr_domain.lng @@ -3,4 +3,5 @@ $wb['domain_error_empty'] = 'Etki alanı boÅŸ olamaz'; $wb['domain_error_unique'] = 'Aynı etki alanı zaten var'; $wb['domain_error_regex'] = 'Bu etki alanına izin verilmiyor'; $wb['Domain'] = 'Etki Alanı'; +$wb['domain_txt'] = 'Domain'; ?> diff --git a/interface/web/client/lib/menu.d/empty.dir b/interface/web/client/lib/menu.d/empty.dir new file mode 100644 index 0000000000..e69de29bb2 diff --git a/interface/web/client/lib/module.conf.php b/interface/web/client/lib/module.conf.php index 2203571381..deebfd6a78 100644 --- a/interface/web/client/lib/module.conf.php +++ b/interface/web/client/lib/module.conf.php @@ -6,7 +6,7 @@ $module["startpage"] = "client/client_list.php"; $module["tab_width"] = ''; $module['order'] = '20'; - +$module['icon'] = 'icon icon-client'; $items[] = array( 'title' => "Edit Client", 'target' => 'content', diff --git a/interface/web/client/list/domain.list.php b/interface/web/client/list/domain.list.php index 8fc81eeef9..c156d857c3 100644 --- a/interface/web/client/list/domain.list.php +++ b/interface/web/client/list/domain.list.php @@ -86,7 +86,7 @@ 'value' => ""); $liste["item"][] = array( 'field' => "sys_groupid", - 'datatype' => "VARCHAR", + 'datatype' => "INTEGER", 'formtype' => "SELECT", 'op' => "=", 'prefix' => "", diff --git a/interface/web/client/reseller_edit.php b/interface/web/client/reseller_edit.php index 10da3b78e1..7600dcd62d 100644 --- a/interface/web/client/reseller_edit.php +++ b/interface/web/client/reseller_edit.php @@ -72,10 +72,53 @@ function onShowNew() { } } + // Hide the info tab when creating a new client. + unset($app->tform->formDef["tabs"]['info']); + $app->tform->formDef["tab_default"] = "address"; + parent::onShowNew(); } + function onShowEdit() { + global $app, $conf; + chdir('../dashboard'); + + $dashlet_list = array(); + $dashlets = array('quota.php', 'databasequota.php', 'mailquota.php', 'limits.php'); + $current_client_id = $this->id; + + foreach ($dashlets as $file) { + if ($file != '.' && $file != '..' && !is_dir(ISPC_WEB_PATH.'/dashboard/dashlets/'.$file)) { + $dashlet_name = substr($file, 0, -4); + $dashlet_class = 'dashlet_'.$dashlet_name; + include_once ISPC_WEB_PATH.'/dashboard/dashlets/'.$file; + $dashlet_list[$dashlet_name] = new $dashlet_class; + $dashlets_html .= $dashlet_list[$dashlet_name]->show($current_client_id); + } + } + $app->tpl->setVar('dashlets', $dashlets_html); + + chdir('../client'); + + $tmp = $app->db->queryOneRecord("SELECT company_name, contact_firstname, contact_name, email FROM client WHERE client_id = ?", $current_client_id); + + $app->tpl->setVar('company_name', $tmp['company_name']); + $app->tpl->setVar('contact_name', $tmp['contact_name']); + $app->tpl->setVar('email', $tmp['email']); + + $app->uses('getconf,system'); + $web_config = $app->getconf->get_global_config('sites'); + if($web_config['postgresql_database'] == 'y') { + $app->tpl->setVar('show_postgresql', true); + } else { + $app->tpl->setVar('show_postgresql', false); + } + + parent::onShowEdit(); + } + + function onSubmit() { global $app, $conf; @@ -291,8 +334,8 @@ function onAfterInsert() { $subject = str_replace('{password}', $this->dataRecord['password'], $subject); break; case 'gender': - $message = str_replace('{salutation}', $wb['gender_'.$val.'_txt'], $message); - $subject = str_replace('{salutation}', $wb['gender_'.$val.'_txt'], $subject); + $message = str_replace('{salutation}', $app->lng('gender_'.$val.'_txt'), $message); + $subject = str_replace('{salutation}', $app->lng('gender_'.$val.'_txt'), $subject); break; default: $message = str_replace('{'.$key.'}', $val, $message); diff --git a/interface/web/client/templates/client_circle_edit.htm b/interface/web/client/templates/client_circle_edit.htm index 0bdf2f49a0..b497fd9509 100644 --- a/interface/web/client/templates/client_circle_edit.htm +++ b/interface/web/client/templates/client_circle_edit.htm @@ -9,12 +9,6 @@

-
- -
- {tmpl_var name='client_ids'} -
-
@@ -25,6 +19,13 @@

{tmpl_var name='active'}
+
+
+ +
+ {tmpl_var name='client_ids'} +
+
{tmpl_var name='required_fields_txt'} @@ -33,4 +34,4 @@

-
\ No newline at end of file + diff --git a/interface/web/client/templates/client_edit_address.htm b/interface/web/client/templates/client_edit_address.htm index 835b264400..0333b93958 100644 --- a/interface/web/client/templates/client_edit_address.htm +++ b/interface/web/client/templates/client_edit_address.htm @@ -48,6 +48,9 @@ +
+ +
-
- -
-
- -
diff --git a/interface/web/client/templates/client_edit_info.htm b/interface/web/client/templates/client_edit_info.htm new file mode 100644 index 0000000000..2b89fa18ea --- /dev/null +++ b/interface/web/client/templates/client_edit_info.htm @@ -0,0 +1,23 @@ + + + diff --git a/interface/web/client/templates/client_edit_limits.htm b/interface/web/client/templates/client_edit_limits.htm index 9a2578b697..b8183a3585 100644 --- a/interface/web/client/templates/client_edit_limits.htm +++ b/interface/web/client/templates/client_edit_limits.htm @@ -342,8 +342,15 @@

- +
+ +
+ +
+ + +
diff --git a/interface/web/client/templates/client_template_edit_limits.htm b/interface/web/client/templates/client_template_edit_limits.htm index ef15d18358..1f13fcaf82 100644 --- a/interface/web/client/templates/client_template_edit_limits.htm +++ b/interface/web/client/templates/client_template_edit_limits.htm @@ -299,9 +299,16 @@

- +
-
+ +
+ +
+ + +
+
diff --git a/interface/web/client/templates/domain_edit.htm b/interface/web/client/templates/domain_edit.htm index 97fefc85e0..8d2da4d03f 100644 --- a/interface/web/client/templates/domain_edit.htm +++ b/interface/web/client/templates/domain_edit.htm @@ -19,7 +19,11 @@ -
+
+ + + +
\ No newline at end of file diff --git a/interface/web/client/templates/reseller_edit_info.htm b/interface/web/client/templates/reseller_edit_info.htm new file mode 100644 index 0000000000..26e9258d6d --- /dev/null +++ b/interface/web/client/templates/reseller_edit_info.htm @@ -0,0 +1,24 @@ + + + + diff --git a/interface/web/client/templates/reseller_edit_limits.htm b/interface/web/client/templates/reseller_edit_limits.htm index eee685ac51..4ca8ab14a9 100644 --- a/interface/web/client/templates/reseller_edit_limits.htm +++ b/interface/web/client/templates/reseller_edit_limits.htm @@ -343,9 +343,16 @@

- +
-
+ +
+ +
+ + +
+
diff --git a/interface/web/dashboard/ajax_get_json.php b/interface/web/dashboard/ajax_get_json.php index 76f284352b..0bd587ce01 100644 --- a/interface/web/dashboard/ajax_get_json.php +++ b/interface/web/dashboard/ajax_get_json.php @@ -54,6 +54,9 @@ // resellers $result[] = _search('client', 'reseller', "AND limit_client != 0"); + // client domains + $result[] = _search('client', 'domain'); + // web sites $result[] = _search('sites', 'web_vhost_domain', "AND type = 'vhost'"); @@ -109,7 +112,7 @@ $result[] = _search('mail', 'mail_get'); // dns zones - $result[] = _search('dns', 'dns_soa'); + $result[] = _search('dns', 'dns_soa', '', 'next_tab=dns_records'); // secondary dns zones $result[] = _search('dns', 'dns_slave'); diff --git a/interface/web/dashboard/dashboard.php b/interface/web/dashboard/dashboard.php index d8adccd15e..796b88a8d1 100644 --- a/interface/web/dashboard/dashboard.php +++ b/interface/web/dashboard/dashboard.php @@ -153,7 +153,20 @@ } } -$app->tpl->setloop('info', $info); +// Load messages from sys_message +$app->uses('message'); +$messages = $app->message->get_current_messages(); +if(!empty($messages)) { + foreach($messages as $message) { + if($message['message_state'] == 'info') $info[] = array('info_msg' => '

'.$message['message'].'

'); + if($message['message_state'] == 'warning') $warning[] = array('warning_msg' => '

'.$message['message'].'

'); + if($message['message_state'] == 'error') $error[] = array('error_msg' => '

'.$message['message'].'

'); + } +} + +if(!empty($info)) $app->tpl->setloop('info', $info); +if(!empty($warning)) $app->tpl->setloop('warning', $warning); +if(!empty($error)) $app->tpl->setloop('error', $error); /* Load the dashlets*/ $dashlet_list = array(); @@ -174,7 +187,7 @@ /* Which dashlets in which column */ /******************************************************************************/ -$default_leftcol_dashlets = array('modules', 'invoices', 'quota', 'mailquota', 'databasequota'); +$default_leftcol_dashlets = array('modules', 'metrics', 'invoices', 'quota', 'mailquota', 'databasequota'); $default_rightcol_dashlets = array('customer', 'products', 'shop', 'limits'); $app->uses('getconf'); @@ -214,12 +227,18 @@ } } +if ($app->auth->is_admin() || $app->auth->is_reseller()) { + $limit_to_client_id = null; +} +else { + $limit_to_client_id = $_SESSION['s']['user']['client_id']; +} /* Fill the left column */ $leftcol = array(); foreach($leftcol_dashlets as $name) { if(isset($dashlet_list[$name])) { - $leftcol[]['content'] = $dashlet_list[$name]->show(); + $leftcol[]['content'] = $dashlet_list[$name]->show($limit_to_client_id); } } $app->tpl->setloop('leftcol', $leftcol); @@ -228,7 +247,7 @@ $rightcol = array(); foreach($rightcol_dashlets as $name) { if(isset($dashlet_list[$name])) { - $rightcol[]['content'] = $dashlet_list[$name]->show(); + $rightcol[]['content'] = $dashlet_list[$name]->show($limit_to_client_id); } } $app->tpl->setloop('rightcol', $rightcol); diff --git a/interface/web/dashboard/dashlets/databasequota.php b/interface/web/dashboard/dashlets/databasequota.php index 4b06599d1c..2c488e37a6 100644 --- a/interface/web/dashboard/dashlets/databasequota.php +++ b/interface/web/dashboard/dashlets/databasequota.php @@ -2,7 +2,7 @@ class dashlet_databasequota { - function show() { + function show($limit_to_client_id = null) { global $app; //* Loading Template @@ -24,27 +24,22 @@ function show() { if(is_file($lng_file)) include $lng_file; $tpl->setVar($wb); - $databases = $app->quota_lib->get_databasequota_data( ($_SESSION["s"]["user"]["typ"] != 'admin') ? $_SESSION['s']['user']['client_id'] : null); + $databases = $app->quota_lib->get_databasequota_data($limit_to_client_id); //print_r($databases); - $has_databasequota = false; + $total_used = 0; if(is_array($databases) && !empty($databases)){ + foreach ($databases as &$db) { + $db['used'] = $app->functions->formatBytes($db['used_raw'], 0); + $db['database_quota'] = $app->functions->formatBytesOrUnlimited($db['database_quota_raw'], 0); + + $total_used += $db['used_raw']; + } $databases = $app->functions->htmlentities($databases); $tpl->setloop('databasequota', $databases); - $has_databasequota = isset($databases[0]['used']); + $tpl->setVar('total_used', $app->functions->formatBytes($total_used, 0)); + + return $tpl->grab(); } - $tpl->setVar('has_databasequota', $has_databasequota); - - return $tpl->grab(); } - } - - - - - - - - -?> diff --git a/interface/web/dashboard/dashlets/limits.php b/interface/web/dashboard/dashlets/limits.php index 50bcad9122..a1fa802869 100644 --- a/interface/web/dashboard/dashlets/limits.php +++ b/interface/web/dashboard/dashlets/limits.php @@ -2,14 +2,14 @@ class dashlet_limits { - public function show() + public function show($limit_to_client_id = 0) { global $app, $conf; $limits = array(); /* Limits to be shown*/ - + $limits[] = array('field' => 'limit_mailquota', 'db_table' => 'mail_user', 'db_where' => 'quota > 0', /* Count only posive value of quota, negative value -1 is unlimited */ @@ -75,7 +75,7 @@ public function show() 'db_table' => 'web_domain', 'db_where' => 'hd_quota > 0', /* Count only posive value of quota, negative value -1 is unlimited */ 'q_type' => 'hd_quota'); - + $limits[] = array('field' => 'limit_web_domain', 'db_table' => 'web_domain', 'db_where' => "type = 'vhost'"); @@ -112,7 +112,7 @@ public function show() 'db_table' => 'web_database', 'db_where' => 'database_quota > 0', /* Count only posive value of quota, negative value -1 is unlimited */ 'q_type' => 'database_quota'); - + $limits[] = array('field' => 'limit_database', 'db_table' => 'web_database', 'db_where' => ""); @@ -147,36 +147,35 @@ public function show() } $tpl->setVar($wb); - if ($app->auth->is_admin()) { - $user_is_admin = true; - } else { - $user_is_admin = false; + if ($limit_to_client_id != null) { + $client_id = $limit_to_client_id; } - $tpl->setVar('is_admin', $user_is_admin); - - if ($user_is_admin == false) { - $client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]); - $client = $app->db->queryOneRecord("SELECT * FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $client_group_id); + elseif ($limit_to_client_id == null && $app->auth->is_reseller()) { + $client_id = $_SESSION['s']['user']['client_id']; } + $client = $app->db->queryOneRecord("SELECT * FROM client WHERE client_id = ?", $client_id); $rows = array(); foreach ($limits as $limit) { $field = $limit['field']; - if ($user_is_admin) { - $value = $wb['unlimited_txt']; + $value = $client[$field]; + if ($app->auth->is_admin() && $limit_to_client_id == 0) { + $value = -1; } else { $value = $client[$field]; } + if ($value != 0 || $value == $wb['unlimited_txt']) { - $value_formatted = ($value == '-1')?$wb['unlimited_txt']:$value; + $suffix = ''; if (isset($limit['q_type']) && $limit['q_type'] != '') { - $usage = $this->_get_assigned_quota($limit) . " MB"; - $value_formatted = ($value == '-1')?$wb['unlimited_txt']:$value . " MB"; + $usage = $this->_get_assigned_quota($limit, $client_id); + $suffix = ' MB'; } else { - $usage = $this->_get_limit_usage($limit); + $usage = $this->_get_limit_usage($limit, $client_id); } $percentage = ($value == '-1' || intval($value) == 0 || trim($value) == '' ? -1 : round(100 * (int)$usage / (int)$value)); $progressbar = $percentage > 100 ? 100 : $percentage; + $value_formatted = ($value == '-1') ? $wb['unlimited_txt'] : ($value . $suffix); $rows[] = array('field' => $field, 'field_txt' => $wb[$field.'_txt'], 'value' => $value_formatted, @@ -195,7 +194,7 @@ public function show() return $tpl->grab(); } - public function _get_limit_usage($limit) + public function _get_limit_usage($limit, $limit_to_client_id) { global $app; @@ -203,12 +202,13 @@ public function _get_limit_usage($limit) if ($limit['db_where'] != '') { $sql .= $limit['db_where']." AND "; } - $sql .= $app->tform->getAuthSQL('r'); + $sql .= $app->tform->getAuthSQL('r', '', '', $app->functions->clientid_to_groups_list($limit_to_client_id)); + $rec = $app->db->queryOneRecord($sql, $limit['db_table']); return $rec['number']; } - - public function _get_assigned_quota($limit) + + public function _get_assigned_quota($limit, $limit_to_client_id) { global $app; @@ -216,14 +216,14 @@ public function _get_assigned_quota($limit) if ($limit['db_where'] != '') { $sql .= $limit['db_where']." AND "; } - $sql .= $app->tform->getAuthSQL('r'); + $sql .= $app->tform->getAuthSQL('r', '', '', $app->functions->clientid_to_groups_list($limit_to_client_id)); $rec = $app->db->queryOneRecord($sql, $limit['q_type'], $limit['db_table']); - if ($limit['db_table']=='mail_user') { + if ($limit['db_table'] == 'mail_user') { $quotaMB = $rec['number'] / 1048576; } // Mail quota is in bytes, must be converted to MB else { - $quotaMB = $rec['number']; - } - return $quotaMB; + $quotaMB = $app->functions->intval($rec['number']); + } + return $quotaMB; } } diff --git a/interface/web/dashboard/dashlets/mailquota.php b/interface/web/dashboard/dashlets/mailquota.php index a9434e58ea..8e238f6b6d 100644 --- a/interface/web/dashboard/dashlets/mailquota.php +++ b/interface/web/dashboard/dashlets/mailquota.php @@ -2,7 +2,7 @@ class dashlet_mailquota { - function show() { + function show($limit_to_client_id = null) { global $app; //* Loading Template @@ -14,34 +14,37 @@ function show() { $wb = array(); $lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_dashlet_mailquota.lng'; if(is_file($lng_file)) include $lng_file; + $wb['last_accessed_txt'] = $app->lng('last_accessed_txt'); $tpl->setVar($wb); - $emails = $app->quota_lib->get_mailquota_data( ($_SESSION["s"]["user"]["typ"] != 'admin') ? $_SESSION['s']['user']['client_id'] : null); - //print_r($emails); + $app->uses('getconf'); + $mail_config = $app->getconf->get_global_config('mail'); + $tpl->setVar('mailbox_show_last_access', $mail_config['mailbox_show_last_access']); + + $emails = $app->quota_lib->get_mailquota_data($limit_to_client_id); $has_mailquota = false; + $total_used = 0; if(is_array($emails) && !empty($emails)){ foreach($emails as &$email) { $email['email'] = $app->functions->idn_decode($email['email']); + $email['used'] = $app->functions->formatBytes($email['used_raw'], 0); + // Mail is the exception with 0 == unlimited, instead of -1 + if ($email['quota_raw'] == 0) { + $email['quota_raw'] = -1; + } + + $email['quota'] = $app->functions->formatBytesOrUnlimited($email['quota_raw'], 0); + $total_used += $email['used_raw']; } unset($email); - // email username is quoted in quota.lib already, so no htmlentities here to prevent double encoding - //$emails = $app->functions->htmlentities($emails); $tpl->setloop('mailquota', $emails); $has_mailquota = isset($emails[0]['used']); - } - $tpl->setVar('has_mailquota', $has_mailquota); - return $tpl->grab(); - } + $tpl->setVar('has_mailquota', $has_mailquota); + $tpl->setVar('total_used', $app->functions->formatBytes($total_used, 0)); + return $tpl->grab(); + } + } } - - - - - - - - -?> diff --git a/interface/web/dashboard/dashlets/metrics.php b/interface/web/dashboard/dashlets/metrics.php new file mode 100644 index 0000000000..ca290cbe7f --- /dev/null +++ b/interface/web/dashboard/dashlets/metrics.php @@ -0,0 +1,75 @@ +uses('tpl'); + + $tpl = new tpl; + $tpl->newTemplate("dashlets/templates/metrics.htm"); + + $wb = array(); + $lng_file = 'lib/lang/' . $_SESSION['s']['language'] . '_dashlet_metrics.lng'; + if (is_file($lng_file)) { + include $lng_file; + } elseif (is_file('lib/lang/en_dashlet_metrics.lng')) { + include 'lib/lang/en_dashlet_metrics.lng'; + } + $tpl->setVar($wb); + + // Get monitor data + $rec = $app->db->queryOneRecord("SELECT `data`FROM `monitor_data` WHERE `type` = 'sys_usage' ORDER BY `created` DESC LIMIT 0,1"); + $data = unserialize($rec['data']); + + if(isset($data['load']) && is_array($data['load'])) { + $tpl->setVar('loadchart_data', implode(', ',$data['load'])); + } + + if(isset($data['mem']) && is_array($data['mem'])) { + $tpl->setVar('memchart_data', implode(', ',$data['mem'])); + } + + $label = []; + $n = 1; + if(isset($data['net']) && is_array($data['net'])) { + $rx = []; + $tx = []; + foreach($data['net'] as $val) { + $rx[] = $val['rx']; + $tx[] = $val['tx']; + $label[] = $n; + $n++; + } + $tpl->setVar('rxchart_data', implode(', ',$rx)); + $tpl->setVar('txchart_data', implode(', ',$tx)); + } + //$tpl->setVar('label', implode(', ',$label)); + + if(isset($data['time']) && is_array($data['time'])) { + foreach($data['time'] as $key => $val) { + $data['time'][$key] = "'".$val."'"; + } + $tpl->setVar('label', implode(', ',$data['time'])); + } + + $tpl->setVar('tablelayout', $_SESSION['s']['user']['table_layout']); + + $tpl->setVar('loadchart_label',$wb['loadchart_label']); + $tpl->setVar('memchart_label',$wb['memchart_label']); + $tpl->setVar('rxchart_label',$wb['rxchart_label']); + $tpl->setVar('txchart_label',$wb['txchart_label']); + $tpl->setvar('label_chart_title',$wb['label_chart_title']); + + return $tpl->grab(); + } + +} diff --git a/interface/web/dashboard/dashlets/modules.php b/interface/web/dashboard/dashlets/modules.php index f5f96a82ac..c855733b73 100644 --- a/interface/web/dashboard/dashlets/modules.php +++ b/interface/web/dashboard/dashlets/modules.php @@ -25,6 +25,7 @@ function show() { foreach($modules as $mt) { if(is_file('../' . $mt . '/lib/module.conf.php')) { if(!preg_match("/^[a-z]{2,20}$/i", $mt)) die('module name contains unallowed chars.'); + if(isset($module)) unset($module); include_once '../' . $mt.'/lib/module.conf.php'; /* We don't want to show the dashboard */ if ($mt != 'dashboard') { @@ -52,9 +53,12 @@ function show() { } else { if(strlen($module_title) > 8) $module_title = substr($module_title, 0, 7).'..'; } + $icon = isset($module['icon']) ? $module['icon'] : 'icon icon-'. $module['name']; $mod[$module['order'].'-'.$module['name']] = array( 'modules_title' => $module_title, 'modules_startpage' => $module['startpage'], - 'modules_name' => $module['name']); + 'modules_name' => $module['name'], + 'modules_icon' => $icon, + ); } } } diff --git a/interface/web/dashboard/dashlets/quota.php b/interface/web/dashboard/dashlets/quota.php index d0b1be998f..ce8ee91c75 100644 --- a/interface/web/dashboard/dashlets/quota.php +++ b/interface/web/dashboard/dashlets/quota.php @@ -2,7 +2,7 @@ class dashlet_quota { - function show() { + function show($limit_to_client_id = null) { global $app; //* Loading Template @@ -24,35 +24,28 @@ function show() { if(is_file($lng_file)) include $lng_file; $tpl->setVar($wb); - $sites = $app->quota_lib->get_quota_data( ($_SESSION["s"]["user"]["typ"] != 'admin') ? $_SESSION['s']['user']['client_id'] : null); - //print_r($sites); + $sites = $app->quota_lib->get_quota_data($limit_to_client_id); $has_quota = false; if(is_array($sites) && !empty($sites)){ foreach($sites as &$site) { $site['domain'] = $app->functions->idn_decode($site['domain']); $site['progressbar'] = $site['hd_quota']; + $site['used'] = $app->functions->formatBytes($site['used_raw'], 0); + $site['hard'] = $app->functions->formatBytesOrUnlimited($site['hard_raw'], 0); + $site['soft'] = $app->functions->formatBytesOrUnlimited($site['soft_raw'], 0); + $total_used += $site['used_raw']; } unset($site); $sites = $app->functions->htmlentities($sites); $tpl->setloop('quota', $sites); $has_quota = isset($sites[0]['used']); - } - $tpl->setVar('has_quota', $has_quota); - - return $tpl->grab(); + $tpl->setVar('has_quota', $has_quota); + $tpl->setVar('total_used', $app->functions->formatBytes($total_used, 0)); + return $tpl->grab(); + } } - } - - - - - - - - -?> diff --git a/interface/web/dashboard/dashlets/templates/databasequota.htm b/interface/web/dashboard/dashlets/templates/databasequota.htm index 082dd1f8c0..5874c4b20a 100644 --- a/interface/web/dashboard/dashlets/templates/databasequota.htm +++ b/interface/web/dashboard/dashlets/templates/databasequota.htm @@ -11,10 +11,10 @@ - {tmpl_var name='database_name'} + {tmpl_var name='database_name'} {tmpl_var name='used'} {tmpl_var name='database_quota'} - {tmpl_if name="quota_raw" op="!=" value="0"} + {tmpl_if name="database_quota_raw" op="!=" value="-1"}
{tmpl_var name="used_percentage"}% {tmpl_var name='used'} {tmpl_var name='of_txt'} {tmpl_var name='database_quota'} @@ -24,5 +24,12 @@ - -
+ + + {tmpl_var name='total_txt'} + {tmpl_var name='total_used'} + + + + +
diff --git a/interface/web/dashboard/dashlets/templates/mailquota.htm b/interface/web/dashboard/dashlets/templates/mailquota.htm index 9013c7ac3b..c24b2e608a 100644 --- a/interface/web/dashboard/dashlets/templates/mailquota.htm +++ b/interface/web/dashboard/dashlets/templates/mailquota.htm @@ -6,6 +6,7 @@ {tmpl_var name='email_txt'} {tmpl_var name='name_txt'} {tmpl_var name='used_txt'} + {tmpl_var name='last_accessed_txt'} {tmpl_var name='quota_txt'} @@ -15,8 +16,9 @@ {tmpl_var name='email'} {tmpl_var name='name'} {tmpl_var name='used'} + {tmpl_var name='last_access'} {tmpl_var name='quota'} - {tmpl_if name="quota_raw" op="!=" value="0"} + {tmpl_if name="quota_raw" op="!=" value="-1"}
{tmpl_var name="used_percentage"}% {tmpl_var name='used'} {tmpl_var name='of_txt'} {tmpl_var name='quota'} @@ -26,5 +28,14 @@ + + + + {tmpl_var name='total_txt'} + {tmpl_var name='total_used'} + + + + -
+
diff --git a/interface/web/dashboard/dashlets/templates/metrics.htm b/interface/web/dashboard/dashlets/templates/metrics.htm new file mode 100644 index 0000000000..2084ef2a43 --- /dev/null +++ b/interface/web/dashboard/dashlets/templates/metrics.htm @@ -0,0 +1,69 @@ + +
+

{tmpl_var name="label_chart_title"}

+
+
+
+
+
+ + \ No newline at end of file diff --git a/interface/web/dashboard/dashlets/templates/modules.htm b/interface/web/dashboard/dashlets/templates/modules.htm index 0c7322b954..8e018f85e3 100644 --- a/interface/web/dashboard/dashlets/templates/modules.htm +++ b/interface/web/dashboard/dashlets/templates/modules.htm @@ -4,7 +4,7 @@

{tmpl_var name='available_modules_txt'}

  • -
    +
    {tmpl_var name='modules_title'}
    diff --git a/interface/web/dashboard/dashlets/templates/quota.htm b/interface/web/dashboard/dashlets/templates/quota.htm index fe006c2087..7fab69413b 100644 --- a/interface/web/dashboard/dashlets/templates/quota.htm +++ b/interface/web/dashboard/dashlets/templates/quota.htm @@ -12,7 +12,7 @@ - {tmpl_var name='domain'} + {tmpl_var name='domain'} {tmpl_var name='used'} {tmpl_var name='soft'} {tmpl_var name='hard'} @@ -29,6 +29,13 @@ {tmpl_else}{/tmpl_if} - + + + + {tmpl_var name='total_txt'} + {tmpl_var name='total_used'} + + + -
    \ No newline at end of file +
  • diff --git a/interface/web/dashboard/lib/lang/ar_dashlet_metrics.lng b/interface/web/dashboard/lib/lang/ar_dashlet_metrics.lng new file mode 100644 index 0000000000..7bbb3f2b06 --- /dev/null +++ b/interface/web/dashboard/lib/lang/ar_dashlet_metrics.lng @@ -0,0 +1,7 @@ + diff --git a/interface/web/dashboard/lib/lang/cn_dashlet_customer.lng b/interface/web/dashboard/lib/lang/cn_dashlet_customer.lng new file mode 100644 index 0000000000..3cc1389c37 --- /dev/null +++ b/interface/web/dashboard/lib/lang/cn_dashlet_customer.lng @@ -0,0 +1,4 @@ + diff --git a/interface/web/dashboard/lib/lang/cn_dashlet_databasequota.lng b/interface/web/dashboard/lib/lang/cn_dashlet_databasequota.lng new file mode 100644 index 0000000000..b03712a821 --- /dev/null +++ b/interface/web/dashboard/lib/lang/cn_dashlet_databasequota.lng @@ -0,0 +1,7 @@ + diff --git a/interface/web/dashboard/lib/lang/cn_dashlet_donate.lng b/interface/web/dashboard/lib/lang/cn_dashlet_donate.lng new file mode 100644 index 0000000000..f12fe56696 --- /dev/null +++ b/interface/web/dashboard/lib/lang/cn_dashlet_donate.lng @@ -0,0 +1,7 @@ + diff --git a/interface/web/dashboard/lib/lang/cn_dashlet_invoice_client_settings.lng b/interface/web/dashboard/lib/lang/cn_dashlet_invoice_client_settings.lng new file mode 100644 index 0000000000..338c8910d2 --- /dev/null +++ b/interface/web/dashboard/lib/lang/cn_dashlet_invoice_client_settings.lng @@ -0,0 +1,4 @@ + diff --git a/interface/web/dashboard/lib/lang/cn_dashlet_invoices.lng b/interface/web/dashboard/lib/lang/cn_dashlet_invoices.lng new file mode 100644 index 0000000000..50bbf57294 --- /dev/null +++ b/interface/web/dashboard/lib/lang/cn_dashlet_invoices.lng @@ -0,0 +1,18 @@ + diff --git a/interface/web/dashboard/lib/lang/cn_dashlet_limits.lng b/interface/web/dashboard/lib/lang/cn_dashlet_limits.lng new file mode 100644 index 0000000000..29adaf9ad8 --- /dev/null +++ b/interface/web/dashboard/lib/lang/cn_dashlet_limits.lng @@ -0,0 +1,34 @@ + diff --git a/interface/web/dashboard/lib/lang/cn_dashlet_mailquota.lng b/interface/web/dashboard/lib/lang/cn_dashlet_mailquota.lng new file mode 100644 index 0000000000..4e7361a9f9 --- /dev/null +++ b/interface/web/dashboard/lib/lang/cn_dashlet_mailquota.lng @@ -0,0 +1,8 @@ + diff --git a/interface/web/dashboard/lib/lang/cn_dashlet_metrics.lng b/interface/web/dashboard/lib/lang/cn_dashlet_metrics.lng new file mode 100644 index 0000000000..d9c051a551 --- /dev/null +++ b/interface/web/dashboard/lib/lang/cn_dashlet_metrics.lng @@ -0,0 +1,7 @@ + diff --git a/interface/web/dashboard/lib/lang/cn_dashlet_products.lng b/interface/web/dashboard/lib/lang/cn_dashlet_products.lng new file mode 100644 index 0000000000..f9c161934e --- /dev/null +++ b/interface/web/dashboard/lib/lang/cn_dashlet_products.lng @@ -0,0 +1,9 @@ + diff --git a/interface/web/dashboard/lib/lang/cn_dashlet_quota.lng b/interface/web/dashboard/lib/lang/cn_dashlet_quota.lng new file mode 100644 index 0000000000..123ffc314a --- /dev/null +++ b/interface/web/dashboard/lib/lang/cn_dashlet_quota.lng @@ -0,0 +1,8 @@ + diff --git a/interface/web/dashboard/lib/lang/cn_dashlet_shop.lng b/interface/web/dashboard/lib/lang/cn_dashlet_shop.lng new file mode 100644 index 0000000000..e5977b2586 --- /dev/null +++ b/interface/web/dashboard/lib/lang/cn_dashlet_shop.lng @@ -0,0 +1,8 @@ + diff --git a/interface/web/dashboard/lib/lang/cz_dashlet_metrics.lng b/interface/web/dashboard/lib/lang/cz_dashlet_metrics.lng new file mode 100644 index 0000000000..9589f9cd4d --- /dev/null +++ b/interface/web/dashboard/lib/lang/cz_dashlet_metrics.lng @@ -0,0 +1,7 @@ + 'Dashboard 1', -// 'target' => 'content', -// 'link' => 'dashboard/dashboard.php'); -// -//$module['nav'][] = array( 'title' => 'Dashboard 2', -// 'open' => 1, -// 'items' => $items); - - - -?> diff --git a/interface/web/dashboard/message_ack.php b/interface/web/dashboard/message_ack.php new file mode 100644 index 0000000000..ac3880acd9 --- /dev/null +++ b/interface/web/dashboard/message_ack.php @@ -0,0 +1,45 @@ +auth->check_module_permissions('dashboard'); + +$app->uses('message'); + +if(!empty($_GET['message_state'])) { + $app->message->hide_by_message_state($_GET['message_state']); +} +if(!empty($_GET['relation'])) { + $app->message->hide_by_message_relation($_GET['relation']); +} + +?> \ No newline at end of file diff --git a/interface/web/dashboard/templates/dashboard.htm b/interface/web/dashboard/templates/dashboard.htm index 7c8b46e2a2..0cfea9ab10 100644 --- a/interface/web/dashboard/templates/dashboard.htm +++ b/interface/web/dashboard/templates/dashboard.htm @@ -3,21 +3,24 @@

    {tmpl_var name='welcome_user'}

    -
    + -
    + -
    +