Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • ispconfig/ispconfig3
  • RealOpty/ispconfig3
  • Horfic/ispconfig3
  • kingcody/ispconfig3
  • mbethke/ispconfig3
  • harkman/ispconfig3
  • stefanheinen/ispconfig3
  • JanKraljic/ispconfig3
  • pulsweb/ispconfig3
  • kayyy/ispconfig3
  • mwacht/ispconfig3
  • schuetzm/ispconfig3
  • gbg/ispconfig3
  • jproxx/ispconfig3
  • Nilpo/ispconfig3
  • Cambra/ispconfig3
  • crackerizer/ispconfig3
  • simonswine/ispconfig3
  • zbuzanic/ispconfig3
  • alexalouit/ispconfig3
  • guilhermefilippo/ispconfig3
  • kotishe/ispconfig3
  • Rescue9/ispconfig3
  • DmitriyLyalyuev/ispconfig3
  • simon.levesque/ispconfig3
  • Viktor/ispconfig3
  • Dr4c0/ispconfig3
  • stefanmcds-mnt/ispconfig3
  • Konflikted/ispconfig3
  • Schoene/ispconfig3
  • stefan.eertwegh/ispconfig3
  • Quest/ispconfig3
  • bst2002/ispconfig3
  • jphustman/ispconfig3
  • lepirlouit/ispconfig3
  • lolo888/ispconfig3
  • Quetzal/ispconfig3
  • kolorafa/ispconfig3
  • jdsn/ispconfig3
  • mk/ispconfig3
  • jnorell/ispconfig3
  • madalin/ispconfig3
  • edspiner/ispconfig3
  • blu3bird/ispconfig3
  • ITManager/ispconfig3
  • virtualweb/ispconfig3
  • dirkd/ispconfig3
  • jcdirks/ispconfig3
  • bvbmedia/ispconfig3
  • CSoellinger/ispconfig3
  • lutacon/ispconfig3
  • armsby/ispconfig3
  • psantos/ispconfig3
  • pkdevbox_y/ispconfig3
  • tlanger/ispconfig3
  • Krauser/ispconfig3
  • ochorocho/ispconfig3
  • aisfrond/ispconfig3
  • ldrrp/ispconfig3
  • steglicd/ispconfig3
  • darkalex/ispconfig3
  • b.dokimakis/ispconfig3
  • MarioSteinitz/ispconfig3
  • bweston/ispconfig3
  • bob/ispconfig3
  • HHGAG/ispconfig3
  • ark74/ispconfig3
  • fuerni/ispconfig3
  • hexblot/ispconfig3
  • maxxer/ispconfig3
  • JustDevZero/ispconfig3
  • habeggerl/ispconfig3
  • phpexpert/ispconfig3
  • Questler/ispconfig3
  • JanThiel/ispconfig3
  • joni_1993/ispconfig3
  • MePha/ispconfig3
  • flies/ispconfig3
  • macjohnny/ispconfig3
  • csegarra/ispconfig3
  • Tibius/ispconfig3
  • wairuru/ispconfig3
  • pdreissen/ispconfig3
  • mgiworx/ispconfig3
  • michielp/ispconfig3
  • ZarToK/ispconfig3
  • x-f/ispconfig3
  • tomlankhorst/ispconfig3
  • olivier.br/ispconfig3
  • hajti/ispconfig3
  • JaviSabalete/ispconfig3
  • dharman/ispconfig3
  • Martin-enavn/ispconfig3
  • Fr3k4Life/ispconfig3
  • Caldeira/ispconfig3
  • enavn/ispconfig3
  • cybernet2u/ispconfig3
  • Denny/ispconfig3
  • jbbr/ispconfig3
  • kakohari/ispconfig3
  • almere/ispconfig3
  • Kyokata/ispconfig3
  • burn/ispconfig3
  • feldsam/ispconfig3
  • woutervddn/ispconfig3
  • tm/ispconfig3
  • blount/ispconfig3
  • pravdomil/ispconfig3
  • manyk/ispconfig3
  • Poppabear/ispconfig3
  • t1st3/ispconfig3
  • scrat14/ispconfig3
  • ncomputers.org/ispconfig3
  • wlisik/ispconfig3
  • CupOfTea696/ispconfig3
  • ogmelch/ispconfig3
  • techwolf12/ispconfig3
  • timo.boldt/ispconfig3
  • DemoFreak/ispconfig3
  • EndelWar/ispconfig3
  • maanus/ispconfig3
  • ms217/ispconfig3
  • luisvivasb/ispconfig3
  • Ismir/ispconfig3
  • truongld/ispconfig3
  • nhutphan/ispconfig3
  • ram/ispconfig3
  • josemorenoasix/ispconfig3
  • onestepp/ispconfig3
  • gguglielmetti/ispconfig3
  • andre/ispconfig3
  • omig/ispconfig3
  • liane/ispconfig3
  • PVasileff/ispconfig3
  • mattanja/ispconfig3
  • dnl-jst/ispconfig3
  • jkalousek/ispconfig3
  • lgg42/ispconfig3
  • ispcomm/ispconfig3
  • moglgasy/ispconfig3
  • natanfelles/ispconfig3
  • cristiandeluxe/ispconfig3
  • pete/ispconfig3
  • Sosha/ispconfig3
  • shr3k/ispconfig3
  • niceit/ispconfig3
  • dani/ispconfig3
  • Ongaro/ispconfig3
  • Djidel/ispconfig3
  • andre.ballensiefen/ispconfig3
  • qroac/ispconfig3
  • magenbrot/ispconfig3
  • doekia/ispconfig3
  • edersonmora/ispconfig3
  • zucha.imz/ispconfig3
  • ckc/ispconfig3
  • Sroka/ispconfig3
  • batgau/ispconfig3
  • isp/ispconfig3
  • oboumati/ispconfig3
  • mscholz/ispconfig3
  • katiak/ispconfig3
  • jamiroph/ispconfig3
  • buhlerax/ispconfig3
  • johan/ispconfig3
  • KordianBruck/ispconfig3
  • trs997/ispconfig3
  • Funclineal/ispconfig3
  • xals/ispconfig3
  • sververda/ispconfig3
  • presure/ispconfig3
  • vojtech.myslivec/ispconfig3
  • helmo/ispconfig3
  • brody/ispconfig3
  • GameO7er/ispconfig3
  • webslice/ispconfig3
  • ufoonline/ispconfig3
  • alwin/ispconfig3
  • t.heller/ispconfig3
  • philipp/ispconfig3
  • andrzejs/ispconfig3
  • pixcept/ispconfig3
  • tgmedia/ispconfig3
  • Nardol/ispconfig3
  • m42e/ispconfig3
  • condless/ispconfig3
  • alesak/ispconfig3
  • MasonChase/ispconfig3
  • brt/ispconfig3
  • Rusek/ispconfig3
  • credz/ispconfig3
  • fiftyz/ispconfig3
  • dciancu/ispconfig3
  • thom/ispconfig3
  • florian030/ispconfig3
  • Mixasik/ispconfig3
  • SimonSparks/ispconfig3
  • eurodomenii/ispconfig3
  • vitex/ispconfig3
  • mitho/ispconfig3
  • CaptainStarbuck/ispconfig3
  • renky/ispconfig3
  • d--j/ispconfig3
  • inetspec/ispconfig3
  • Christian/ispconfig3
  • lukav/ispconfig3
  • galgenjunge/ispconfig3
  • gody/ispconfig3
  • kpendic/ispconfig3
  • diciannove/ispconfig3
  • tbasler/ispconfig3
  • logifech/ispconfig3
  • maximaweb/ispconfig3
  • tommaso-perondi/ispconfig3
  • francoisPE/ispconfig3
  • elgeorge2k/ispconfig3
  • francoisgrizzlydev/ispconfig3
  • Chris_UK/ispconfig3
  • mrutkowski/ispconfig3
  • mladen074/ispconfig3
  • trogper/ispconfig3
  • Lokutos/ispconfig3
  • manoaratefy/ispconfig3
  • GwynethLlewelyn/ispconfig3
  • tim427/ispconfig3
  • mapreri/ispconfig3
  • gsubiron/ispconfig3
  • eriam/ispconfig3
  • Steveorevo/ispconfig3
  • Jens/ispconfig3
  • ebela/ispconfig3
  • typoworx/ispconfig3
  • teuto.net/ispconfig3
  • sonority/ispconfig3
  • element/ispconfig3
  • Petar/ispconfig3
  • ewsp/ispconfig3
  • bicisteadm/ispconfig3
  • ivmm/ispconfig3
  • blinkenbox/ispconfig3
  • Samgarr/ispconfig3
  • B.Richard/ispconfig3
  • ahrasis/ispconfig3
  • nephi.aust/ispconfig3
  • beastycoding/ispconfig3
  • luttje/ispconfig3
  • hairy/ispconfig3
  • styxtdo/ispconfig3
  • SGr33n/ispconfig3
  • mepstein/ispconfig3
  • kobuki/ispconfig3
  • dachris/ispconfig3
  • mina/ispconfig3
253 results
Show changes
Showing
with 3013 additions and 1280 deletions
......@@ -51,11 +51,12 @@ use strict;
$sql_select_policy =
'SELECT *,spamfilter_users.id'.
' FROM spamfilter_users LEFT JOIN spamfilter_policy ON spamfilter_users.policy_id=spamfilter_policy.id'.
' WHERE spamfilter_users.email IN (%k) ORDER BY spamfilter_users.priority DESC';
' WHERE spamfilter_users.email IN (%k) AND spamfilter_users.policy_id != 0'.
' ORDER BY spamfilter_users.priority DESC';
$sql_select_white_black_list = 'SELECT wb FROM spamfilter_wblist'.
' WHERE (spamfilter_wblist.rid=?) AND (spamfilter_wblist.email IN (%k))' .
' WHERE (spamfilter_wblist.rid=?) AND (spamfilter_wblist.email IN (%k)) AND (spamfilter_wblist.active="y")' .
' ORDER BY spamfilter_wblist.priority DESC';
#
......@@ -67,7 +68,7 @@ $final_spam_destiny = D_DISCARD;
$final_banned_destiny = D_BOUNCE;
$final_bad_header_destiny = D_PASS;
# Default settings, we st this very high to not filter aut emails accidently
# Default settings, we set this very high to not filter out emails accidentally
$sa_spam_subject_tag = '***SPAM*** ';
$sa_tag_level_deflt = 20.0; # add spam info headers if at, or above that level
$sa_tag2_level_deflt = 60.0; # add 'spam detected' headers at that level
......@@ -95,15 +96,18 @@ $log_level = 0; # (defaults to 0)
$inet_socket_port = [10024,10026];
# *:* = send to IP/HOST:incoming Port + 1
$forward_method = 'smtp:*:*';
$notify_method = 'smtp:*:*';
# :* = send to incoming Port + 1
$forward_method = 'smtp:127.0.0.1:*';
$notify_method = 'smtp:127.0.0.1:*';
$interface_policy{'10026'} = 'ORIGINATING';
$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
......@@ -112,9 +116,10 @@ $policy_bank{'ORIGINATING'} = {
# Allow SMTP access from IPs in @inet_acl to amvisd SMTP Port
@inet_acl = qw( 127.0.0.1 [::1] 192.168.0.0/16 );
$signed_header_fields{'received'} = 0; # turn off signing of Received
# DKIM
$enable_dkim_verification = 1;
$enable_dkim_signing = 1;
$enable_dkim_signing = 1; # load DKIM signing code
$signed_header_fields{'received'} = 0; # turn off signing of Received
@dkim_signature_options_bysender_maps = (
{ '.' => { ttl => 21*24*3600, c => 'relaxed/simple' } } );
......
......@@ -4,64 +4,142 @@
# for the ISPConfig controlpanel
######################################################
{vhost_port_listen} Listen {vhost_port}
NameVirtualHost *:{vhost_port}
<tmpl_var name="vhost_port_listen"> Listen <tmpl_var name="vhost_port">
NameVirtualHost *:<tmpl_var name="vhost_port">
<VirtualHost _default_:{vhost_port}>
<VirtualHost _default_:<tmpl_var name="vhost_port">>
ServerAdmin webmaster@localhost
Alias /mail /var/www/ispconfig/mail
<Directory /var/www/ispconfig/>
<FilesMatch "\.ph(p3?|tml)$">
SetHandler None
</FilesMatch>
</Directory>
<Directory /usr/local/ispconfig/interface/web/>
<FilesMatch "\.ph(p3?|tml)$">
SetHandler None
</FilesMatch>
</Directory>
<IfModule mod_fcgid.c>
DocumentRoot /var/www/ispconfig/
SuexecUserGroup ispconfig ispconfig
<Directory /var/www/ispconfig/>
Options +Indexes +FollowSymLinks +MultiViews +ExecCGI
Options -Indexes +FollowSymLinks +MultiViews +ExecCGI
AllowOverride AuthConfig Indexes Limit Options FileInfo
<FilesMatch "\.ph(p[3-5]?|tml)$">
<FilesMatch "\.php$">
SetHandler fcgid-script
</FilesMatch>
FCGIWrapper /var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter .php
<tmpl_if name='apache_version' op='>' value='2.2' format='version'>
Require all granted
<tmpl_else>
Order allow,deny
Allow from all
</tmpl_if>
</Directory>
DirectoryIndex index.php
IPCCommTimeout 7200
MaxRequestLen 15728640
</IfModule>
<IfModule mod_php5.c>
<IfModule mod_proxy_fcgi.c>
DocumentRoot /usr/local/ispconfig/interface/web
SuexecUserGroup ispconfig ispconfig
DirectoryIndex index.php
<Directory /usr/local/ispconfig/interface/web>
Options -Indexes +FollowSymLinks +MultiViews +ExecCGI
AllowOverride AuthConfig Indexes Limit Options FileInfo
<tmpl_if name='apache_version' op='>' value='2.2' format='version'>
Require all granted
<tmpl_else>
Order allow,deny
Allow from all
</tmpl_if>
<FilesMatch \.php$>
#SetHandler "proxy:unix:/var/lib/php5-fpm/ispconfig.sock|fcgi://localhost"
SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>
</Directory>
</IfModule>
<IfModule mpm_itk_module>
DocumentRoot /usr/local/ispconfig/interface/web/
AssignUserId ispconfig ispconfig
AddType application/x-httpd-php .php
<Directory /usr/local/ispconfig/interface/web>
# php_admin_value open_basedir "/usr/local/ispconfig/interface:/usr/share:/tmp"
Options +FollowSymLinks
AllowOverride None
<tmpl_if name='apache_version' op='>' value='2.2' format='version'>
Require all granted
<tmpl_else>
Order allow,deny
Allow from all
php_value magic_quotes_gpc 0
</tmpl_if>
php_value magic_quotes_gpc 0
</Directory>
</IfModule>
# ErrorLog /var/log/apache2/error.log
# CustomLog /var/log/apache2/access.log combined
ServerSignature Off
<IfModule mod_security2.c>
SecRuleEngine Off
</IfModule>
# 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
<tmpl_var name="ssl_comment">SSLEngine On
<tmpl_if name='apache_version' op='>=' value='2.3.16' format='version'>
<tmpl_var name="ssl_comment">SSLProtocol All -SSLv3 -TLSv1 -TLSv1.1
<tmpl_else>
<tmpl_var name="ssl_comment">SSLProtocol All -SSLv2 -SSLv3
</tmpl_if>
<tmpl_var name="ssl_comment">SSLCertificateFile /usr/local/ispconfig/interface/ssl/ispserver.crt
<tmpl_var name="ssl_comment">SSLCertificateKeyFile /usr/local/ispconfig/interface/ssl/ispserver.key
<tmpl_var name="ssl_bundle_comment">SSLCACertificateFile /usr/local/ispconfig/interface/ssl/ispserver.bundle
</VirtualHost>
<tmpl_var name="ssl_comment">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
<tmpl_var name="ssl_comment">SSLHonorCipherOrder On
<tmpl_if name='apache_version' op='>=' value='2.4.3' format='version'>
<tmpl_var name="ssl_comment">SSLCompression Off
</tmpl_if>
<tmpl_if name='apache_version' op='>=' value='2.4.11' format='version'>
<tmpl_var name="ssl_comment">SSLSessionTickets Off
</tmpl_if>
<Directory /var/www/php-cgi-scripts>
AllowOverride None
Order Deny,Allow
Deny from all
</Directory>
<IfModule mod_headers.c>
# 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'"
<tmpl_var name="ssl_comment">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"
<tmpl_var name="ssl_comment">Header always edit Set-Cookie (.*) "$1; Secure"
<IfModule mod_version.c>
<IfVersion >= 2.4.7>
Header setifempty Strict-Transport-Security "max-age=15768000"
</IfVersion>
<IfVersion < 2.4.7>
Header set Strict-Transport-Security "max-age=15768000"
</IfVersion>
</IfModule>
RequestHeader unset Proxy early
</IfModule>
<Directory /var/www/php-fcgi-scripts>
AllowOverride None
Order Deny,Allow
Deny from all
</Directory>
<tmpl_if name='apache_version' op='>=' value='2.3.3' format='version'>
<tmpl_var name="ssl_comment">SSLUseStapling On
<tmpl_var name="ssl_comment">SSLStaplingResponderTimeout 5
<tmpl_var name="ssl_comment">SSLStaplingReturnResponderErrors Off
</tmpl_if>
# Redirect http to https
ErrorDocument 400 "<script>document.location.href='https://'+location.hostname+':'+location.port';</script><h1>Error 400 - trying to redirect</h1>"
</VirtualHost>
# 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 = </etc/postfix/smtpd.cert
ssl_key = </etc/postfix/smtpd.key
ssl_dh = </etc/dovecot/dh.pem
ssl_min_protocol = TLSv1.2
ssl_cipher_list = 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
ssl_prefer_server_ciphers = no
mail_max_userip_connections = 100
mail_plugins = quota
passdb {
args = /etc/dovecot/dovecot-sql.conf
driver = sql
}
userdb {
driver = prefetch
}
userdb {
args = /etc/dovecot/dovecot-sql.conf
driver = sql
}
plugin {
quota = dict:user::file:/var/vmail/%d/%n/.quotausage
# no longer needed, as 'sieve' is in userdb extra fields:
sieve=/var/vmail/%d/%n/.sieve
sieve_before=/var/vmail/%d/%n/.ispconfig-before.sieve
sieve_after=/var/vmail/%d/%n/.ispconfig.sieve
sieve_max_script_size = 2M
sieve_max_actions = 100
sieve_max_redirects = 25
}
service auth {
unix_listener /var/spool/postfix/private/auth {
group = postfix
mode = 0660
user = postfix
}
unix_listener auth-userdb {
group = vmail
mode = 0600
user = vmail
}
user = root
}
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
group = postfix
mode = 0600
user = postfix
}
}
lmtp_rcpt_check_quota = yes
service imap-login {
client_limit = 1000
process_limit = 512
}
protocol imap {
mail_plugins = $mail_plugins quota imap_quota
auth_verbose = yes
}
protocol pop3 {
pop3_uidl_format = %08Xu%08Xv
mail_plugins = $mail_plugins quota
auth_verbose = yes
}
protocol lda {
postmaster_address = webmaster@localhost
mail_plugins = $mail_plugins sieve quota
}
protocol lmtp {
postmaster_address = webmaster@localhost
mail_plugins = $mail_plugins quota sieve
}
#2.3+ service stats {
#2.3+ unix_listener stats-reader {
#2.3+ user = vmail
#2.3+ group = vmail
#2.3+ mode = 0660
#2.3+ }
#2.3+
#2.3+ unix_listener stats-writer {
#2.3+ user = vmail
#2.3+ group = vmail
#2.3+ mode = 0660
#2.3+ }
#2.3+ }
service quota-status {
executable = quota-status -p postfix
unix_listener /var/spool/postfix/private/quota-status {
group = postfix
mode = 0660
user = postfix
}
client_limit = 1
}
plugin {
quota_status_success = DUNNO
quota_status_nouser = DUNNO
quota_status_overquota = "552 5.2.2 Mailbox is full"
}
!include_try conf.d/99-ispconfig-custom-config.conf
\ No newline at end of file
......@@ -96,9 +96,11 @@ regularfiles = /etc/vimrc
directories = /etc/joe, /etc/terminfo, /usr/share/vim, /usr/share/terminfo, /usr/lib/terminfo
[netutils]
comment = several internet utilities like wget, ftp, rsync, scp, ssh
executables = /usr/bin/wget, /usr/bin/lynx, /usr/bin/ftp, /usr/bin/host, /usr/bin/rsync, /usr/bin/smbclient
comment = several internet utilities like curl, wget, ftp, rsync, scp, ssh
executables = /usr/bin/curl /usr/bin/wget, /usr/bin/lynx, /usr/bin/ftp, /usr/bin/host, /usr/bin/rsync, /usr/bin/smbclient
includesections = netbasics, ssh, sftp, scp
directories = /etc/ssl/certs/
regularfiles = /usr/lib/ssl/certs
[apacheutils]
comment = htpasswd utility
......
......@@ -30,30 +30,30 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/*
ISPConfig 3 installer.
-------------------------------------------------------------------------------------
- Interactive install
-------------------------------------------------------------------------------------
run:
php install.php
-------------------------------------------------------------------------------------
- Noninteractive (autoinstall) mode
-------------------------------------------------------------------------------------
The autoinstall mode can read the installer questions from a .ini style file or from
a php config file. Examples for both file types are in the docs folder.
a php config file. Examples for both file types are in the docs folder.
See autoinstall.ini.sample and autoinstall.conf_sample.php.
run:
php install.php --autoinstall=autoinstall.ini
or
php install.php --autoinstall=autoinstall.conf.php
*/
error_reporting(E_ALL|E_STRICT);
......@@ -85,8 +85,6 @@ if(realpath(dirname(__FILE__)) != $cur_dir) {
chdir( realpath(dirname(__FILE__)) );
}
//** Install logfile
define('ISPC_LOG_FILE', '/var/log/ispconfig_install.log');
define('ISPC_INSTALL_ROOT', realpath(dirname(__FILE__).'/../'));
//** Include the templating lib
......@@ -97,6 +95,9 @@ require_once 'lib/classes/tpl.inc.php';
die('We will stop here. There is already a ISPConfig installation, use the update script to update this installation.');
}*/
// Patch is required to reapir latest amavis versions
if(is_installed('amavisd-new') && !is_installed('patch')) die('The patch command is missing. Install patch command and start installation again.');
//** Get distribution identifier
$dist = get_distname();
......@@ -114,7 +115,11 @@ if(isset($cmd_opt['autoinstall']) && is_file($cmd_opt['autoinstall'])) {
if($path_parts['extension'] == 'php') {
include_once $cmd_opt['autoinstall'];
} elseif($path_parts['extension'] == 'ini') {
$tmp = ini_to_array(file_get_contents('autoinstall.ini'));
if(is_file('autoinstall.ini')) {
$tmp = ini_to_array(file_get_contents('autoinstall.ini'));
} else {
$tmp = ini_to_array(file_get_contents($cmd_opt['autoinstall']));
}
if(!is_array($tmp['install'])) $tmp['install'] = array();
if(!is_array($tmp['ssl_cert'])) $tmp['ssl_cert'] = array();
if(!is_array($tmp['expert'])) $tmp['expert'] = array();
......@@ -133,27 +138,38 @@ if(isset($cmd_opt['autoinstall']) && is_file($cmd_opt['autoinstall'])) {
//** Include the distribution-specific installer class library and configuration
if(is_file('dist/lib/'.$dist['baseid'].'.lib.php')) include_once 'dist/lib/'.$dist['baseid'].'.lib.php';
include_once 'dist/lib/'.$dist['id'].'.lib.php';
include_once 'dist/conf/'.$dist['id'].'.conf.php';
include_once 'dist/conf/'.$dist['confid'].'.conf.php';
//****************************************************************************************************
//** Installer Interface
//****************************************************************************************************
$inst = new installer();
if (!$inst->get_php_version()) die('ISPConfig requieres PHP '.$inst->min_php."\n");
$retval=shell_exec("which which");
if (empty($retval)) die ("ISPConfig requieres which \n");
if (empty($retval)) die ("ISPConfig requires which \n");
$inst->check_prerequisites();
swriteln($inst->lng(' Following will be a few questions for primary configuration so be careful.'));
swriteln($inst->lng(' Default values are in [brackets] and can be accepted with <ENTER>.'));
swriteln($inst->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')) {
die('This software cannot be installed on a server wich runs ISPConfig 2.x.');
if(is_dir('/home/admispconfig')) {
die('This software cannot be installed on a server which runs ISPConfig 2.x.');
} else {
die('This software cannot be installed on a server which runs ISPConfig 2.x; the presence of the /root/ispconfig/ directory may indicate an ISPConfig 2.x installation, otherwise you can remove or rename it to continue.');
}
}
if(is_dir('/usr/local/ispconfig')) {
......@@ -163,6 +179,11 @@ if(is_dir('/usr/local/ispconfig')) {
//** Detect the installed applications
$inst->find_installed_apps();
//* crontab required by ISPConfig
if(!$conf['cron']['installed']) {
die("crontab not found; please install a compatible cron daemon before ISPConfig\n\n");
}
//** Select the language and set default timezone
$conf['language'] = $inst->simple_query('Select language', array('en', 'de'), 'en','language');
$conf['timezone'] = get_system_timezone();
......@@ -195,17 +216,17 @@ if(!function_exists('mysqli_connect')) die('No PHP MySQLi functions available. P
//** Get MySQL root credentials
$finished = false;
do {
$tmp_mysql_server_host = $inst->free_query('MySQL server hostname', $conf['mysql']['host'],'mysql_hostname');
$tmp_mysql_server_host = $inst->free_query('MySQL server hostname', $conf['mysql']['host'],'mysql_hostname');
$tmp_mysql_server_port = $inst->free_query('MySQL server port', $conf['mysql']['port'],'mysql_port');
$tmp_mysql_server_admin_user = $inst->free_query('MySQL root username', $conf['mysql']['admin_user'],'mysql_root_user');
$tmp_mysql_server_admin_password = $inst->free_query('MySQL root password', $conf['mysql']['admin_password'],'mysql_root_password');
$tmp_mysql_server_database = $inst->free_query('MySQL database to create', $conf['mysql']['database'],'mysql_database');
$tmp_mysql_server_admin_user = $inst->free_query('MySQL root username', $conf['mysql']['admin_user'],'mysql_root_user');
$tmp_mysql_server_admin_password = $inst->free_query('MySQL root password', $conf['mysql']['admin_password'],'mysql_root_password');
$tmp_mysql_server_database = $inst->free_query('MySQL database to create', $conf['mysql']['database'],'mysql_database');
$tmp_mysql_server_charset = $inst->free_query('MySQL charset', $conf['mysql']['charset'],'mysql_charset');
if($install_mode == 'expert') {
swriteln("The next two questions are about the internal ISPConfig database user and password.\nIt is recommended to accept the defaults which are 'ispconfig' as username and a random password.\nIf you use a different password, use only numbers and chars for the password.\n");
$conf['mysql']['ispconfig_user'] = $inst->free_query('ISPConfig mysql database username', $conf['mysql']['ispconfig_user'],'mysql_ispconfig_user');
$conf['mysql']['ispconfig_user'] = $inst->free_query('ISPConfig mysql database username', $conf['mysql']['ispconfig_user'],'mysql_ispconfig_user');
$conf['mysql']['ispconfig_password'] = $inst->free_query('ISPConfig mysql database password', $conf['mysql']['ispconfig_password'],'mysql_ispconfig_password');
}
......@@ -234,6 +255,9 @@ unset($tmp);
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;
......@@ -246,41 +270,99 @@ $conf['services']['firewall'] = false;
$conf['services']['proxy'] = false;
$conf['services']['xmpp'] = false;
if($install_mode == 'standard') {
//** Get Server ID
// $conf['server_id'] = $inst->free_query('Unique Numeric ID of the server','1');
// Server ID is an autoInc value of the mysql database now
if($install_mode == 'expert' && strtolower($inst->simple_query('Shall this server join an existing ISPConfig multiserver setup', array('y', 'n'), 'n','join_multiserver_setup')) == 'y') {
$conf['mysql']['master_slave_setup'] = 'y';
//** Get MySQL root credentials
$finished = false;
do {
$tmp_mysql_server_host = $inst->free_query('MySQL master server hostname', $conf['mysql']['master_host'],'mysql_master_hostname');
$tmp_mysql_server_port = $inst->free_query('MySQL master server port', $conf['mysql']['master_port'],'mysql_master_port');
$tmp_mysql_server_admin_user = $inst->free_query('MySQL master server root username', $conf['mysql']['master_admin_user'],'mysql_master_root_user');
$tmp_mysql_server_admin_password = $inst->free_query('MySQL master server root password', $conf['mysql']['master_admin_password'],'mysql_master_root_password');
$tmp_mysql_server_database = $inst->free_query('MySQL master server database name', $conf['mysql']['master_database'],'mysql_master_database');
//* Initialize the MySQL server connection
if(@mysqli_connect($tmp_mysql_server_host, $tmp_mysql_server_admin_user, $tmp_mysql_server_admin_password, $tmp_mysql_server_database, (int)$tmp_mysql_server_port)) {
$conf['mysql']['master_host'] = $tmp_mysql_server_host;
$conf['mysql']['master_port'] = $tmp_mysql_server_port;
$conf['mysql']['master_admin_user'] = $tmp_mysql_server_admin_user;
$conf['mysql']['master_admin_password'] = $tmp_mysql_server_admin_password;
$conf['mysql']['master_database'] = $tmp_mysql_server_database;
$finished = true;
} else {
swriteln($inst->lng('Unable to connect to mysql server').' '.mysqli_connect_error());
}
} while ($finished == false);
unset($finished);
// initialize the connection to the master database
$inst->dbmaster = new db();
if($inst->dbmaster->linkId) $inst->dbmaster->closeConn();
$inst->dbmaster->setDBData($conf['mysql']["master_host"], $conf['mysql']["master_admin_user"], $conf['mysql']["master_admin_password"], $conf['mysql']['master_port']);
$inst->dbmaster->setDBName($conf['mysql']["master_database"]);
} else {
// the master DB is the same then the slave DB
$inst->dbmaster = $inst->db;
//* Create the MySQL database
$inst->configure_database();
}
//* Create the mysql database
$inst->configure_database();
//* Insert the Server record into the database
$inst->add_database_server_record();
//* Check for Web-Server
if(!$conf['apache']['installed'] && !$conf['nginx']['installed']) {
$conf['apache']['installed'] = $inst->force_configure_app('Apache', ($install_mode == 'expert'));
$conf['nginx']['installed'] = $inst->force_configure_app('nginx', ($install_mode == 'expert'));
}
//* Configure Webserver - Apache or nginx
if($conf['apache']['installed'] == true && $conf['nginx']['installed'] == true) {
$http_server_to_use = $inst->simple_query('Apache and nginx detected. Select server to use for ISPConfig:', array('apache', 'nginx'), 'apache','http_server');
if($http_server_to_use == 'apache'){
$conf['nginx']['installed'] = false;
$conf['services']['file'] = true;
} else {
$conf['apache']['installed'] = false;
}
}
//* Insert the Server record into the database
if($install_mode == 'expert') {
swriteln('Adding ISPConfig server record to database.');
swriteln('');
}
$inst->add_database_server_record();
if($install_mode == 'standard' || strtolower($inst->simple_query('Configure Mail', array('y', 'n') , 'y','configure_mail') ) == 'y') {
//* Configure Postgrey
$force = @($conf['postgrey']['installed']) ? true : $inst->force_configure_app('Postgrey', false);
$force = @($conf['postgrey']['installed']) ? true : $inst->force_configure_app('Postgrey', ($install_mode == 'expert'));
if($force) swriteln('Configuring Postgrey');
//* Configure Postfix
$force = @($conf['postfix']['installed']) ? true : $inst->force_configure_app('Postfix', false);
$force = @($conf['postfix']['installed']) ? true : $inst->force_configure_app('Postfix', ($install_mode == 'expert'));
if($force) {
swriteln('Configuring Postfix');
$inst->configure_postfix();
$conf['services']['mail'] = true;
$inst->configure_postfix();
}
if($conf['services']['mail']) {
//* Configure Mailman
$force = @($conf['mailman']['installed']) ? true : $inst->force_configure_app('Mailman', false);
$force = @($conf['mailman']['installed']) ? true : $inst->force_configure_app('Mailman', ($install_mode == 'expert'));
if($force) {
swriteln('Configuring Mailman');
$inst->configure_mailman();
}
}
//* Check for Dovecot and Courier
if(!$conf['dovecot']['installed'] && !$conf['courier']['installed']) {
$conf['dovecot']['installed'] = $inst->force_configure_app('Dovecot', false);
$conf['courier']['installed'] = $inst->force_configure_app('Courier', false);
$conf['dovecot']['installed'] = $inst->force_configure_app('Dovecot', ($install_mode == 'expert'));
$conf['courier']['installed'] = $inst->force_configure_app('Courier', ($install_mode == 'expert'));
}
//* Configure Mailserver - Dovecot or Courier
if($conf['dovecot']['installed'] && $conf['courier']['installed']) {
......@@ -307,44 +389,65 @@ if($install_mode == 'standard') {
}
//* Configure Spamasassin
$force = @($conf['spamassassin']['installed']) ? true : $inst->force_configure_app('Spamassassin', false);
$force = @($conf['spamassassin']['installed']) ? true : $inst->force_configure_app('Spamassassin', ($install_mode == 'expert'));
if($force) {
swriteln('Configuring Spamassassin');
$inst->configure_spamassassin();
}
//* Configure Amavis
$force = @($conf['amavis']['installed']) ? true : $inst->force_configure_app('Amavisd', false);
$force = @($conf['amavis']['installed']) ? true : $inst->force_configure_app('Amavisd', ($install_mode == 'expert'));
if($force) {
swriteln('Configuring Amavisd');
$inst->configure_amavis();
}
//* Configure Getmail
$force = @($conf['getmail']['installed']) ? true : $inst->force_configure_app('Getmail', false);
//* Configure Rspamd
$force = @($conf['rspamd']['installed']) ? true : $inst->force_configure_app('Rspamd', ($install_mode == 'expert'));
if($force) {
swriteln('Configuring Rspamd');
$inst->configure_rspamd();
}
//* Configure Getmail
$force = @($conf['getmail']['installed']) ? true : $inst->force_configure_app('Getmail', ($install_mode == 'expert'));
if($force) {
swriteln('Configuring Getmail');
$inst->configure_getmail();
}
} else {
swriteln('[ERROR] Postfix not installed - skipping Mail');
}
}
} else swriteln('[ERROR] Postfix not installed - skipping Mail');
//* Configure Jailkit
$force = @($conf['jailkit']['installed']) ? true : $inst->force_configure_app('Jailkit', ($install_mode == 'expert'));
if($force) {
swriteln('Configuring Jailkit');
$inst->configure_jailkit();
}
//* Configure Pureftpd
$force = @($conf['pureftpd']['installed']) ? true : $inst->force_configure_app('pureftpd', ($install_mode == 'expert'));
if($force) {
swriteln('Configuring Pureftpd');
$inst->configure_pureftpd();
}
//** Configure DNS
if($install_mode == 'standard' || strtolower($inst->simple_query('Configure DNS Server', array('y', 'n'), 'y','configure_dns')) == 'y') {
//* Check for DNS
// if(!$conf['powerdns']['installed'] && !$conf['bind']['installed'] && !$conf['mydns']['installed']) {
if(!$conf['bind']['installed'] && !$conf['mydns']['installed']) {
// $conf['powerdns']['installed'] = $inst->force_configure_app('PowerDNS', false);
$conf['bind']['installed'] = $inst->force_configure_app('BIND', false);
$conf['mydns']['installed'] = $inst->force_configure_app('MyDNS', false);
if(!$conf['powerdns']['installed'] && !$conf['bind']['installed'] && !$conf['mydns']['installed']) {
if($install_mode == 'expert') $conf['powerdns']['installed'] = $inst->force_configure_app('PowerDNS', ($install_mode == 'expert'));
$conf['bind']['installed'] = $inst->force_configure_app('BIND', ($install_mode == 'expert'));
$conf['mydns']['installed'] = $inst->force_configure_app('MyDNS', ($install_mode == 'expert'));
}
//* Configure PowerDNS
/*
if($conf['powerdns']['installed']) {
if($install_mode == 'expert' && $conf['powerdns']['installed']) {
swriteln('Configuring PowerDNS');
$inst->configure_powerdns();
$conf['services']['dns'] = true;
}
*/
//* Configure Bind
if($conf['bind']['installed']) {
swriteln('Configuring BIND');
......@@ -361,36 +464,10 @@ if($install_mode == 'standard') {
$conf['services']['dns'] = true;
}
//* Configure Jailkit
$force = @($conf['jailkit']['installed']) ? true : $inst->force_configure_app('Jailkit', false);
if($force) {
swriteln('Configuring Jailkit');
$inst->configure_jailkit();
}
//* Configure Pureftpd
$force = @($conf['pureftpd']['installed']) ? true : $inst->force_configure_app('pureftpd', false);
if($force) {
swriteln('Configuring Pureftpd');
$inst->configure_pureftpd();
}
//* Check for Web-Server
if(!$conf['apache']['installed'] && !$conf['nginx']['installed']) {
$conf['apache']['installed'] = $inst->force_configure_app('Apache', false);
$conf['nginx']['installed'] = $inst->force_configure_app('nginx', false);
}
//* Configure Webserver - Apache or nginx
if($conf['apache']['installed'] && $conf['nginx']['installed']) {
$http_server_to_use = $inst->simple_query('Apache and nginx detected. Select server to use for ISPConfig:', array('apache', 'nginx'), 'apache','http_server');
if($http_server_to_use == 'apache'){
$conf['nginx']['installed'] = false;
} else {
$conf['apache']['installed'] = false;
}
}
}
if($install_mode == 'expert') swriteln('The Web Server option has to be enabled when you want run a web server or when this node shall host the ISPConfig interface.');
if($install_mode == 'standard' || strtolower($inst->simple_query('Configure Web Server', array('y', 'n'), 'y','configure_webserver')) == 'y') {
//* Configure Apache
if($conf['apache']['installed']){
swriteln('Configuring Apache');
......@@ -398,41 +475,51 @@ if($install_mode == 'standard') {
$conf['services']['web'] = true;
$conf['services']['file'] = true;
//* Configure Vlogger
$force = @($conf['vlogger']['installed']) ? true : $inst->force_configure_app('vlogger', false);
$force = @($conf['vlogger']['installed']) ? true : $inst->force_configure_app('vlogger', ($install_mode == 'expert'));
if($force) {
swriteln('Configuring vlogger');
$inst->configure_vlogger();
}
//* Configure squid
/*
$force = @($conf['squid']['installed']) ? true : $inst->force_configure_app('squid');
$force = @($conf['squid']['installed']) ? true : $inst->force_configure_app('squid', ($install_mode == 'expert'));
if($force) {
swriteln('Configuring Squid');
$inst->configure_squid();
$conf['services']['proxy'] = true;
if($conf['squid']['init_script'] != '' && is_executable($conf['init_scripts'].'/'.$conf['squid']['init_script']))system($conf['init_scripts'].'/'.$conf['squid']['init_script'].' restart &> /dev/null');
}
*/
}
//* Configure nginx
if($conf['nginx']['installed']){
swriteln('Configuring nginx');
$inst->configure_nginx();
$conf['services']['web'] = true;
}
}
//* Configure XMPP
$force = @($conf['xmpp']['installed']) ? true : $inst->force_configure_app('Metronome XMPP Server', false);
if($force) {
swriteln('Configuring Metronome XMPP Server');
$inst->configure_xmpp();
$conf['services']['xmpp'] = true;
}
//* Configure OpenVZ
$force = @($conf['openvz']['installed']) ? true : $inst->force_configure_app('OpenVZ', ($install_mode == 'expert'));
if($force) {
$conf['services']['vserver'] = true;
swriteln('Configuring OpenVZ');
}
// Configure AppArmor
if($conf['apparmor']['installed']){
swriteln('Configuring AppArmor');
$inst->configure_apparmor();
}
if($install_mode == 'standard' || strtolower($inst->simple_query('Configure Firewall Server', array('y', 'n'), 'y','configure_firewall')) == 'y') {
//* Check for Firewall
if(!isset($conf['firewall']['installed'])) {
$conf['firewall']['installed'] = false;
}
if(!$conf['ufw']['installed'] && !$conf['firewall']['installed']) {
$conf['ufw']['installed'] = $inst->force_configure_app('Ubuntu Firewall', false);
$conf['firewall']['installed'] = $inst->force_configure_app('Bastille Firewall', false);
$conf['ufw']['installed'] = $inst->force_configure_app('Ubuntu Firewall', ($install_mode == 'expert'));
$conf['firewall']['installed'] = $inst->force_configure_app('Bastille Firewall', ($install_mode == 'expert'));
}
//* Configure Firewall - Ubuntu or Bastille
if($conf['ufw']['installed'] && $conf['firewall']['installed']) {
......@@ -456,441 +543,133 @@ if($install_mode == 'standard') {
$conf['services']['firewall'] = true;
$conf['bastille']['installed'] = true;
}
}
//* Configure Fail2ban
$force = @($conf['fail2ban']['installed']) ? true : $inst->force_configure_app('Fail2ban', false);
if($force) {
swriteln('Configuring Fail2ban');
$inst->configure_fail2ban();
}
//* Configure XMPP
$force = @($conf['xmpp']['installed']) ? true : $inst->force_configure_app('Metronome XMPP Server', ($install_mode == 'expert'));
if($force) {
swriteln('Configuring Metronome XMPP Server');
$inst->configure_xmpp();
$conf['services']['xmpp'] = true;
}
//* Configure OpenVZ
$force = @($conf['openvz']['installed']) ? true : $inst->force_configure_app('OpenVZ', false);
if($force) {
$conf['services']['vserver'] = true;
swriteln('Configuring OpenVZ');
}
//* Configure Fail2ban
$force = @($conf['fail2ban']['installed']) ? true : $inst->force_configure_app('Fail2ban', ($install_mode == 'expert'));
if($force) {
swriteln('Configuring Fail2ban');
$inst->configure_fail2ban();
}
//** Configure apps vhost
swriteln('Configuring Apps vhost');
$inst->configure_apps_vhost();
// create acme vhost
if($conf['nginx']['installed'] == true) {
$inst->make_acme_vhost('nginx'); // we need this config file but we don't want nginx to be restarted at this point
}
if($conf['apache']['installed'] == true) {
$inst->make_acme_vhost('apache'); // we need this config file but we don't want apache to be restarted at this point
}
//* Configure ISPConfig
//** Configure ISPConfig :-)
$issue_asked = false;
$issue_tried = false;
$install_ispconfig_interface_default = ($conf['mysql']['master_slave_setup'] == 'y')?'n':'y';
if($install_mode == 'standard' || strtolower($inst->simple_query('Install ISPConfig Web Interface', array('y', 'n'), $install_ispconfig_interface_default,'install_ispconfig_web_interface')) == 'y') {
swriteln('Installing ISPConfig');
//** Customize the port ISPConfig runs on
//** Customise the port ISPConfig runs on
$ispconfig_vhost_port = $inst->free_query('ISPConfig Port', '8080','ispconfig_port');
$conf['interface_password'] = $inst->free_query('Admin password', 'admin');
if($conf['interface_password'] != 'admin') {
$temp_admin_password = str_shuffle(bin2hex(openssl_random_pseudo_bytes(4)));
$conf['interface_password'] = $inst->free_query('Admin password', $temp_admin_password, 'ispconfig_admin_password');
if($conf['interface_password'] != $temp_admin_password) {
$check = false;
do {
unset($temp_password);
$temp_password = $inst->free_query('Re-enter admin password', '');
$temp_password = $inst->free_query('Re-enter admin password', '','ispconfig_admin_password');
$check = @($temp_password == $conf['interface_password'])?true:false;
if(!$check) swriteln('Passwords do not match.');
} while (!$check);
}
unset($check);
unset($temp_password);
unset($temp_admin_password);
if($conf['apache']['installed'] == true) $conf['apache']['vhost_port'] = $ispconfig_vhost_port;
if($conf['nginx']['installed'] == true) $conf['nginx']['vhost_port'] = $ispconfig_vhost_port;
unset($ispconfig_vhost_port);
if(strtolower($inst->simple_query('Do you want a secure (SSL) connection to the ISPConfig web interface', array('y', 'n'), 'y','ispconfig_use_ssl')) == 'y') {
if(strtolower($inst->simple_query('Do you want a secure (SSL) connection to the ISPConfig web interface', array('y', 'n'), 'y','ispconfig_use_ssl')) == 'y') {
$inst->make_ispconfig_ssl_cert();
$issue_tried = true;
}
$issue_asked = true;
$inst->install_ispconfig_interface = true;
$inst->install_ispconfig();
//* Configure DBServer
swriteln('Configuring DBServer');
$inst->configure_dbserver();
//* Configure ISPConfig
if($conf['cron']['installed']) {
swriteln('Installing ISPConfig crontab');
$inst->install_crontab();
} else swriteln('[ERROR] Cron not found');
swriteln('Detect IP addresses');
$inst->detect_ips();
swriteln('Restarting services ...');
if($conf['mysql']['installed'] == true && $conf['mysql']['init_script'] != '') system($inst->getinitcommand($conf['mysql']['init_script'], 'restart').' >/dev/null 2>&1');
if($conf['postfix']['installed'] == true && $conf['postfix']['init_script'] != '') system($inst->getinitcommand($conf['postfix']['init_script'], 'restart'));
if($conf['saslauthd']['installed'] == true && $conf['saslauthd']['init_script'] != '') system($inst->getinitcommand($conf['saslauthd']['init_script'], 'restart'));
if($conf['amavis']['installed'] == true && $conf['amavis']['init_script'] != '') system($inst->getinitcommand($conf['amavis']['init_script'], 'restart'));
if($conf['clamav']['installed'] == true && $conf['clamav']['init_script'] != '') system($inst->getinitcommand($conf['clamav']['init_script'], 'restart'));
if($conf['courier']['installed'] == true){
if($conf['courier']['courier-authdaemon'] != '') system($inst->getinitcommand($conf['courier']['courier-authdaemon'], 'restart'));
if($conf['courier']['courier-imap'] != '') system($inst->getinitcommand($conf['courier']['courier-imap'], 'restart'));
if($conf['courier']['courier-imap-ssl'] != '') system($inst->getinitcommand($conf['courier']['courier-imap-ssl'], 'restart'));
if($conf['courier']['courier-pop'] != '') system($inst->getinitcommand($conf['courier']['courier-pop'], 'restart'));
if($conf['courier']['courier-pop-ssl'] != '') system($inst->getinitcommand($conf['courier']['courier-pop-ssl'], 'restart'));
}
if($conf['dovecot']['installed'] == true && $conf['dovecot']['init_script'] != '') system($inst->getinitcommand($conf['dovecot']['init_script'], 'restart'));
if($conf['mailman']['installed'] == true && $conf['mailman']['init_script'] != '') system('nohup '.$inst->getinitcommand($conf['mailman']['init_script'], 'restart').' >/dev/null 2>&1 &');
if($conf['apache']['installed'] == true && $conf['apache']['init_script'] != '') system($inst->getinitcommand($conf['apache']['init_script'], 'restart'));
//* Reload is enough for nginx
if($conf['nginx']['installed'] == true){
if($conf['nginx']['php_fpm_init_script'] != '') system($inst->getinitcommand($conf['nginx']['php_fpm_init_script'], 'reload'));
if($conf['nginx']['init_script'] != '') system($inst->getinitcommand($conf['nginx']['init_script'], 'reload'));
}
if($conf['pureftpd']['installed'] == true && $conf['pureftpd']['init_script'] != '') system($inst->getinitcommand($conf['pureftpd']['init_script'], 'restart'));
if($conf['mydns']['installed'] == true && $conf['mydns']['init_script'] != '') system($inst->getinitcommand($conf['mydns']['init_script'], 'restart').' &> /dev/null');
if($conf['powerdns']['installed'] == true && $conf['powerdns']['init_script'] != '') system($inst->getinitcommand($conf['powerdns']['init_script'], 'restart').' &> /dev/null');
if($conf['bind']['installed'] == true && $conf['bind']['init_script'] != '') system($inst->getinitcommand($conf['bind']['init_script'], 'restart').' &> /dev/null');
//if($conf['squid']['installed'] == true && $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 && $conf['nginx']['init_script'] != '') system($inst->getinitcommand($conf['nginx']['init_script'], 'restart').' &> /dev/null');
if($conf['ufw']['installed'] == true && $conf['ufw']['init_script'] != '') system($inst->getinitcommand($conf['ufw']['init_script'], 'restart').' &> /dev/null');
if($conf['xmpp']['installed'] == true && $conf['xmpp']['init_script'] != '') system($inst->getinitcommand($conf['xmpp']['init_script'], 'restart').' &> /dev/null');
} else { //* expert mode
//** Get Server ID
// $conf['server_id'] = $inst->free_query('Unique Numeric ID of the server','1');
// Server ID is an autoInc value of the mysql database now
if(strtolower($inst->simple_query('Shall this server join an existing ISPConfig multiserver setup', array('y', 'n'), 'n','join_multiserver_setup')) == 'y') {
$conf['mysql']['master_slave_setup'] = 'y';
//** Get MySQL root credentials
$finished = false;
do {
$tmp_mysql_server_host = $inst->free_query('MySQL master server hostname', $conf['mysql']['master_host'],'mysql_master_hostname');
$tmp_mysql_server_port = $inst->free_query('MySQL master server port', $conf['mysql']['master_port'],'mysql_master_port');
$tmp_mysql_server_admin_user = $inst->free_query('MySQL master server root username', $conf['mysql']['master_admin_user'],'mysql_master_root_user');
$tmp_mysql_server_admin_password = $inst->free_query('MySQL master server root password', $conf['mysql']['master_admin_password'],'mysql_master_root_password');
$tmp_mysql_server_database = $inst->free_query('MySQL master server database name', $conf['mysql']['master_database'],'mysql_master_database');
//* Initialize the MySQL server connection
if(@mysqli_connect($tmp_mysql_server_host, $tmp_mysql_server_admin_user, $tmp_mysql_server_admin_password, $tmp_mysql_server_database, (int)$tmp_mysql_server_port)) {
$conf['mysql']['master_host'] = $tmp_mysql_server_host;
$conf['mysql']['master_port'] = $tmp_mysql_server_port;
$conf['mysql']['master_admin_user'] = $tmp_mysql_server_admin_user;
$conf['mysql']['master_admin_password'] = $tmp_mysql_server_admin_password;
$conf['mysql']['master_database'] = $tmp_mysql_server_database;
$finished = true;
} else {
swriteln($inst->lng('Unable to connect to mysql server').' '.mysqli_connect_error());
}
} while ($finished == false);
unset($finished);
// initialize the connection to the master database
$inst->dbmaster = new db();
if($inst->dbmaster->linkId) $inst->dbmaster->closeConn();
$inst->dbmaster->setDBData($conf['mysql']["master_host"], $conf['mysql']["master_admin_user"], $conf['mysql']["master_admin_password"]);
$inst->dbmaster->setDBName($conf['mysql']["master_database"]);
} else {
// the master DB is the same then the slave DB
$inst->dbmaster = $inst->db;
}
//* Create the mysql database
$inst->configure_database();
//* Check for Web-Server
if($conf['apache']['installed'] != true && $conf['nginx']['installed'] != true) {
$conf['apache']['installed'] = $inst->force_configure_app('Apache');
$conf['nginx']['installed'] = $inst->force_configure_app('nginx');
}
//* Configure Webserver - Apache or nginx
if($conf['apache']['installed'] == true && $conf['nginx']['installed'] == true) {
$http_server_to_use = $inst->simple_query('Apache and nginx detected. Select server to use for ISPConfig:', array('apache', 'nginx'), 'apache','http_server');
if($http_server_to_use == 'apache'){
$conf['nginx']['installed'] = false;
$conf['services']['file'] = true;
} else {
$conf['apache']['installed'] = false;
}
}
//* Insert the Server record into the database
swriteln('Adding ISPConfig server record to database.');
swriteln('');
$inst->add_database_server_record();
if(strtolower($inst->simple_query('Configure Mail', array('y', 'n') , 'y','configure_mail') ) == 'y') {
$conf['services']['mail'] = true;
//* Configure Postgrey
$force = @($conf['postgrey']['installed']) ? true : $inst->force_configure_app('Postgrey');
if($force) swriteln('Configuring Postgrey');
//* Configure Postfix
$force = @($conf['postfix']['installed']) ? true : $inst->force_configure_app('Postfix');
if($force) {
swriteln('Configuring Postfix');
$inst->configure_postfix();
}
//* Configure Mailman
$force = @($conf['mailman']['installed']) ? true : $inst->force_configure_app('Mailman');
if($force) {
swriteln('Configuring Mailman');
$inst->configure_mailman();
}
//* Check for Dovecot and Courier
if(!$conf['dovecot']['installed'] && !$conf['courier']['installed']) {
$conf['dovecot']['installed'] = $inst->force_configure_app('Dovecot');
$conf['courier']['installed'] = $inst->force_configure_app('Courier');
}
//* Configure Mailserver - Dovecot or Courier
if($conf['dovecot']['installed'] && $conf['courier']['installed']) {
$mail_server_to_use = $inst->simple_query('Dovecot and Courier detected. Select server to use with ISPConfig:', array('dovecot', 'courier'), 'dovecot','mail_server');
if($mail_server_to_use == 'dovecot'){
$conf['courier']['installed'] = false;
} else {
$conf['dovecot']['installed'] = false;
}
}
//* Configure Dovecot
if($conf['dovecot']['installed']) {
swriteln('Configuring Dovecot');
$inst->configure_dovecot();
}
//* Configure Courier
if($conf['courier']['installed']) {
swriteln('Configuring Courier');
$inst->configure_courier();
swriteln('Configuring SASL');
$inst->configure_saslauthd();
swriteln('Configuring PAM');
$inst->configure_pam();
}
//* Configure Spamasassin
$force = @($conf['spamassassin']['installed']) ? true : $inst->force_configure_app('Spamassassin');
if($force) {
swriteln('Configuring Spamassassin');
$inst->configure_spamassassin();
}
//* Configure Amavis
$force = @($conf['amavis']['installed']) ? true : $inst->force_configure_app('Amavisd');
if($force) {
swriteln('Configuring Amavisd');
$inst->configure_amavis();
}
//* Configure Getmail
$force = @($conf['getmail']['installed']) ? true : $inst->force_configure_app('Getmail');
if($force) {
swriteln('Configuring Getmail');
$inst->configure_getmail();
}
if($conf['postfix']['installed'] == true && $conf['postfix']['init_script'] != '') system($inst->getinitcommand($conf['postfix']['init_script'], 'restart'));
if($conf['saslauthd']['installed'] == true && $conf['saslauthd']['init_script'] != '') system($inst->getinitcommand($conf['saslauthd']['init_script'], 'restart'));
if($conf['amavis']['installed'] == true && $conf['amavis']['init_script'] != '') system($inst->getinitcommand($conf['amavis']['init_script'], 'restart'));
if($conf['clamav']['installed'] == true && $conf['clamav']['init_script'] != '') system($inst->getinitcommand($conf['clamav']['init_script'], 'restart'));
if($conf['courier']['installed'] == true){
if($conf['courier']['courier-authdaemon'] != '') system($inst->getinitcommand($conf['courier']['courier-authdaemon'], 'restart'));
if($conf['courier']['courier-imap'] != '') system($inst->getinitcommand($conf['courier']['courier-imap'], 'restart'));
if($conf['courier']['courier-imap-ssl'] != '') system($inst->getinitcommand($conf['courier']['courier-imap-ssl'], 'restart'));
if($conf['courier']['courier-pop'] != '') system($inst->getinitcommand($conf['courier']['courier-pop'], 'restart'));
if($conf['courier']['courier-pop-ssl'] != '') system($inst->getinitcommand($conf['courier']['courier-pop-ssl'], 'restart'));
}
if($conf['dovecot']['installed'] == true && $conf['dovecot']['init_script'] != '') system($inst->getinitcommand($conf['dovecot']['init_script'], 'restart'));
if($conf['mailman']['installed'] == true && $conf['mailman']['init_script'] != '') system('nohup '.$inst->getinitcommand($conf['mailman']['init_script'], 'restart').' >/dev/null 2>&1 &');
}
//* Configure Jailkit
$force = @($conf['jailkit']['installed']) ? true : $inst->force_configure_app('Jailkit');
if($force) {
swriteln('Configuring Jailkit');
$inst->configure_jailkit();
}
//* Configure Pureftpd
$force = @($conf['pureftpd']['installed']) ? true : $inst->force_configure_app('pureftpd');
if($force) {
swriteln('Configuring Pureftpd');
$inst->configure_pureftpd();
}
//** Configure DNS
if(strtolower($inst->simple_query('Configure DNS Server', array('y', 'n'), 'y','configure_dns')) == 'y') {
$conf['services']['dns'] = true;
//* Check for DNS
if(!$conf['powerdns']['installed'] && !$conf['bind']['installed'] && !$conf['mydns']['installed']) {
$conf['powerdns']['installed'] = $inst->force_configure_app('PowerDNS');
$conf['bind']['installed'] = $inst->force_configure_app('BIND');
$conf['mydns']['installed'] = $inst->force_configure_app('MyDNS');
}
//* Configure PowerDNS
if($conf['powerdns']['installed']) {
swriteln('Configuring PowerDNS');
$inst->configure_powerdns();
$conf['services']['dns'] = true;
}
//* Configure Bind
if($conf['bind']['installed']) {
swriteln('Configuring BIND');
$inst->configure_bind();
$conf['services']['dns'] = true;
if(!is_installed('haveged')) {
swriteln("[INFO] haveged not detected - DNSSEC can fail");
}
}
//* Configure MyDNS
if($conf['mydns']['installed']) {
swriteln('Configuring MyDNS');
$inst->configure_mydns();
$conf['services']['dns'] = true;
}
}
if(strtolower($inst->simple_query('Configure Web Server', array('y', 'n'), 'y','configure_webserver')) == 'y') {
$conf['services']['web'] = true;
//* Configure Apache
if($conf['apache']['installed']){
swriteln('Configuring Apache');
$inst->configure_apache();
$conf['services']['file'] = true;
//* Configure Vlogger
$force = @($conf['vlogger']['installed']) ? true : $inst->force_configure_app('vlogger');
if($force) {
swriteln('Configuring vlogger');
$inst->configure_vlogger();
}
//* Configure squid
/*
$force = @($conf['squid']['installed']) ? true : $inst->force_configure_app('squid');
if($force) {
swriteln('Configuring Squid');
$inst->configure_squid();
$conf['services']['proxy'] = true;
if($conf['squid']['init_script'] != '' && is_executable($conf['init_scripts'].'/'.$conf['squid']['init_script']))system($conf['init_scripts'].'/'.$conf['squid']['init_script'].' restart &> /dev/null');
}
*/
}
//* Configure nginx
if($conf['nginx']['installed']){
swriteln('Configuring nginx');
$inst->configure_nginx();
}
}
//* Configure OpenVZ
$force = @($conf['openvz']['installed']) ? true : $inst->force_configure_app('OpenVZ');
if($force) {
$conf['services']['vserver'] = true;
swriteln('Configuring OpenVZ');
}
if(strtolower($inst->simple_query('Configure Firewall Server', array('y', 'n'), 'y','configure_firewall')) == 'y') {
//* Check for Firewall
if(!$conf['ufw']['installed'] && !$conf['firewall']['installed']) {
$conf['ufw']['installed'] = $inst->force_configure_app('Ubuntu Firewall');
$conf['firewall']['installed'] = $inst->force_configure_app('Bastille Firewall');
}
//* Configure Firewall - Ubuntu or Bastille
if($conf['ufw']['installed'] && $conf['firewall']['installed']) {
$firewall_to_use = $inst->simple_query('Ubuntu and Bastille Firewall detected. Select firewall to use with ISPConfig:', array('bastille', 'ubuntu'), 'bastille','firewall_server');
if($firewall_to_use == 'bastille'){
$conf['ufw']['installed'] = false;
} else {
$conf['firewall']['installed'] = false;
}
}
//* Configure Ubuntu Firewall
if($conf['ufw']['installed']){
swriteln('Configuring Ubuntu Firewall');
$inst->configure_ufw_firewall();
$conf['services']['firewall'] = true;
}
//* Configure Bastille Firewall
if($conf['firewall']['installed']){
swriteln('Configuring Bastille Firewall');
$inst->configure_bastille_firewall();
$conf['services']['firewall'] = true;
}
}
//* Configure XMPP
$force = @($conf['xmpp']['installed']) ? true : $inst->force_configure_app('Metronome XMPP Server');
if($force) {
swriteln('Configuring Metronome XMPP Server');
$inst->configure_xmpp();
$conf['services']['xmpp'] = true;
}
//** Configure ISPConfig :-)
$install_ispconfig_interface_default = ($conf['mysql']['master_slave_setup'] == 'y')?'n':'y';
if(strtolower($inst->simple_query('Install ISPConfig Web Interface', array('y', 'n'), $install_ispconfig_interface_default,'install_ispconfig_web_interface')) == 'y') {
swriteln('Installing ISPConfig');
//** We want to check if the server is a module or cgi based php enabled server
//** TODO: Don't always ask for this somehow ?
/*
$fast_cgi = $inst->simple_query('CGI PHP Enabled Server?', array('yes','no'),'no');
if($fast_cgi == 'yes') {
$alias = $inst->free_query('Script Alias', '/php/');
$path = $inst->free_query('Script Alias Path', '/path/to/cgi/bin');
$conf['apache']['vhost_cgi_alias'] = sprintf('ScriptAlias %s %s', $alias, $path);
} else {
$conf['apache']['vhost_cgi_alias'] = "";
}
*/
//** Customise the port ISPConfig runs on
$ispconfig_vhost_port = $inst->free_query('ISPConfig Port', '8080','ispconfig_port');
$conf['interface_password'] = $inst->free_query('Admin password', 'admin');
if($conf['interface_password'] != 'admin') {
$check = false;
do {
unset($temp_password);
$temp_password = $inst->free_query('Re-enter admin password', '');
$check = @($temp_password == $conf['interface_password'])?true:false;
if(!$check) swriteln('Passwords do not match.');
} while (!$check);
}
unset($check);
unset($temp_password);
if($conf['apache']['installed'] == true) $conf['apache']['vhost_port'] = $ispconfig_vhost_port;
if($conf['nginx']['installed'] == true) $conf['nginx']['vhost_port'] = $ispconfig_vhost_port;
unset($ispconfig_vhost_port);
if(strtolower($inst->simple_query('Enable SSL for the ISPConfig web interface', array('y', 'n'), 'y','ispconfig_use_ssl')) == 'y') {
$inst->make_ispconfig_ssl_cert();
}
$inst->install_ispconfig_interface = true;
} else {
$inst->install_ispconfig_interface = false;
}
$inst->install_ispconfig();
} else {
$inst->install_ispconfig_interface = false;
}
//* Configure DBServer
swriteln('Configuring DBServer');
$inst->configure_dbserver();
// Create SSL certs for non-webserver(s)?
if(!$issue_asked) {
if(!file_exists('/usr/local/ispconfig/interface/ssl/ispserver.crt')) {
if(!$issue_tried && strtolower($inst->simple_query('Do you want to create SSL certs for your server?', array('y', 'n'), 'y','create_ssl_server_certs')) == 'y') {
$inst->make_ispconfig_ssl_cert();
}
} else {
swriteln('Certificate exists. Not creating a new one.');
}
}
//* Configure ISPConfig
swriteln('Installing ISPConfig crontab');
$inst->install_crontab();
if($conf['apache']['installed'] == true && $conf['apache']['init_script'] != '') system($inst->getinitcommand($conf['apache']['init_script'], 'restart'));
//* Reload is enough for nginx
if($conf['nginx']['installed'] == true){
if($conf['nginx']['php_fpm_init_script'] != '') system($inst->getinitcommand($conf['nginx']['php_fpm_init_script'], 'reload'));
if($conf['nginx']['init_script'] != '') system($inst->getinitcommand($conf['nginx']['init_script'], 'reload'));
}
swriteln('Detect IP addresses');
$inst->detect_ips();
// update acme.sh if installed
$inst->update_acme();
if($conf['services']['web'] == true) {
//** Configure apps vhost
swriteln('Configuring Apps vhost');
$inst->configure_apps_vhost();
}
$inst->install_ispconfig();
//* Configure DBServer
swriteln('Configuring DBServer');
$inst->configure_dbserver();
//* Configure ISPConfig
swriteln('Installing ISPConfig crontab');
$inst->install_crontab();
swriteln('Detect IP addresses');
$inst->detect_ips();
swriteln('Restarting services ...');
if($conf['mysql']['installed'] == true && isset($conf['mysql']['init_script']) && $conf['mysql']['init_script'] != '') system($inst->getinitcommand($conf['mysql']['init_script'], 'restart').' >/dev/null 2>&1');
if($conf['postfix']['installed'] == true && isset($conf['postfix']['init_script']) && $conf['postfix']['init_script'] != '') system($inst->getinitcommand($conf['postfix']['init_script'], 'restart'));
if($conf['saslauthd']['installed'] == true && isset($conf['saslauthd']['init_script']) && $conf['saslauthd']['init_script'] != '') system($inst->getinitcommand($conf['saslauthd']['init_script'], 'restart'));
if($conf['amavis']['installed'] == true && isset($conf['amavis']['init_script']) && $conf['amavis']['init_script'] != '') system($inst->getinitcommand($conf['amavis']['init_script'], 'restart'));
if($conf['rspamd']['installed'] == true && isset($conf['rspamd']['init_script']) && $conf['rspamd']['init_script'] != '') system($inst->getinitcommand($conf['rspamd']['init_script'], 'restart'));
if($conf['clamav']['installed'] == true && isset($conf['clamav']['init_script']) && $conf['clamav']['init_script'] != '' && $conf['amavis']['installed'] == true) system($inst->getinitcommand($conf['clamav']['init_script'], 'restart'));
if($conf['courier']['installed'] == true){
if($conf['courier']['courier-authdaemon'] != '') system($inst->getinitcommand($conf['courier']['courier-authdaemon'], 'restart'));
if($conf['courier']['courier-imap'] != '') system($inst->getinitcommand($conf['courier']['courier-imap'], 'restart'));
if($conf['courier']['courier-imap-ssl'] != '') system($inst->getinitcommand($conf['courier']['courier-imap-ssl'], 'restart'));
if($conf['courier']['courier-pop'] != '') system($inst->getinitcommand($conf['courier']['courier-pop'], 'restart'));
if($conf['courier']['courier-pop-ssl'] != '') system($inst->getinitcommand($conf['courier']['courier-pop-ssl'], 'restart'));
}
if($conf['dovecot']['installed'] == true && isset($conf['dovecot']['init_script']) && $conf['dovecot']['init_script'] != '') system($inst->getinitcommand($conf['dovecot']['init_script'], 'restart'));
if($conf['mailman']['installed'] == true && isset($conf['mailman']['init_script']) && $conf['mailman']['init_script'] != '') system('nohup '.$inst->getinitcommand($conf['mailman']['init_script'], 'restart').' >/dev/null 2>&1 &');
if($conf['apache']['installed'] == true && isset($conf['apache']['init_script']) && $conf['apache']['init_script'] != '') system($inst->getinitcommand($conf['apache']['init_script'], 'restart'));
//* Reload is enough for nginx
if($conf['nginx']['installed'] == true){
if($conf['nginx']['php_fpm_init_script'] != '') system($inst->getinitcommand($conf['nginx']['php_fpm_init_script'], 'reload'));
if(isset($conf['nginx']['init_script']) && $conf['nginx']['init_script'] != '') system($inst->getinitcommand($conf['nginx']['init_script'], 'reload'));
}
if($conf['pureftpd']['installed'] == true && isset($conf['pureftpd']['init_script']) && $conf['pureftpd']['init_script'] != '') system($inst->getinitcommand($conf['pureftpd']['init_script'], 'restart'));
if($conf['mydns']['installed'] == true && isset($conf['mydns']['init_script']) && $conf['mydns']['init_script'] != '') system($inst->getinitcommand($conf['mydns']['init_script'], 'restart').' &> /dev/null');
if($conf['powerdns']['installed'] == true && isset($conf['powerdns']['init_script']) && $conf['powerdns']['init_script'] != '') system($inst->getinitcommand($conf['powerdns']['init_script'], 'restart').' &> /dev/null');
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(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');
} //* << $install_mode / 'Standard' or Genius
$inst->create_mount_script();
......
......@@ -30,7 +30,7 @@ if (!defined('vlibTemplateClassLoaded')) {
include_once ISPC_INSTALL_ROOT.'/install/lib/classes/tpl_error.inc.php';
include_once ISPC_INSTALL_ROOT.'/install/lib/classes/tpl_ini.inc.php';
class tpl{
class tpl extends stdClass{
/*-----------------------------------------------------------------------------\
| ATTENTION |
......@@ -357,147 +357,6 @@ if (!defined('vlibTemplateClassLoaded')) {
return true;
}
/**
* [** EXPERIMENTAL **]
* Function to create a loop from a Db result resource link.
* @param string $loopname to commit loop. If not set, will use last loopname set using newLoop()
* @param string $result link to a Db result resource
* @param string $db_type, type of db that the result resource belongs to.
* @return boolean true/false
* @access public
*/
public function setDbLoop($loopname, $result, $db_type = 'MYSQL')
{
/*
$db_type = strtoupper($db_type);
if (!in_array($db_type, $this->allowed_loop_dbs)) {
vlibTemplateError::raiseError('VT_WARNING_INVALID_LOOP_DB', WARNING, $db_type);
return false;
}
$loop_arr = array();
// TODO: Are all these necessary as were onyl using mysql and possible postgres ? - pedro
switch ($db_type) {
case 'MYSQL':
if (get_resource_type($result) != 'mysql result') {
vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type);
return false;
}
while($r = mysql_fetch_assoc($result)) {
$loop_arr[] = $r;
}
break;
case 'POSTGRESQL':
if (get_resource_type($result) != 'pgsql result') {
vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type);
return false;
}
$nr = (function_exists('pg_num_rows')) ? pg_num_rows($result) : pg_numrows($result);
for ($i=0; $i < $nr; $i++) {
$loop_arr[] = pg_fetch_array($result, $i, PGSQL_ASSOC);
}
break;
case 'INFORMIX':
if (!$result) {
vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type);
return false;
}
while($r = ifx_fetch_row($result, 'NEXT')) {
$loop_arr[] = $r;
}
break;
case 'INTERBASE':
if (get_resource_type($result) != 'interbase result') {
vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type);
return false;
}
while($r = ibase_fetch_row($result)) {
$loop_arr[] = $r;
}
break;
case 'INGRES':
if (!$result) {
vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type);
return false;
}
while($r = ingres_fetch_array(INGRES_ASSOC, $result)) {
$loop_arr[] = $r;
}
break;
case 'MSSQL':
if (get_resource_type($result) != 'mssql result') {
vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type);
return false;
}
while($r = mssql_fetch_array($result)) {
$loop_arr[] = $r;
}
break;
case 'MSQL':
if (get_resource_type($result) != 'msql result') {
vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type);
return false;
}
while($r = msql_fetch_array($result, MSQL_ASSOC)) {
$loop_arr[] = $r;
}
break;
case 'OCI8':
if (get_resource_type($result) != 'oci8 statement') {
vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type);
return false;
}
while(OCIFetchInto($result, &$r, OCI_ASSOC+OCI_RETURN_LOBS)) {
$loop_arr[] = $r;
}
break;
case 'ORACLE':
if (get_resource_type($result) != 'oracle Cursor') {
vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type);
return false;
}
while(ora_fetch_into($result, &$r, ORA_FETCHINTO_ASSOC)) {
$loop_arr[] = $r;
}
break;
case 'OVRIMOS':
if (!$result) {
vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type);
return false;
}
while(ovrimos_fetch_into($result, &$r, 'NEXT')) {
$loop_arr[] = $r;
}
break;
case 'SYBASE':
if (get_resource_type($result) != 'sybase-db result') {
vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type);
return false;
}
while($r = sybase_fetch_array($result)) {
$loop_arr[] = $r;
}
break;
}
$this->setLoop($loopname, $loop_arr);
return true;
*/
}
/**
* Sets the name for the curent loop in the 3 step loop process.
* @param string $name string to define loop name
......@@ -1072,7 +931,7 @@ if (!defined('vlibTemplateClassLoaded')) {
{
array_push($this->_namespace, $varname);
$tempvar = count($this->_namespace) - 1;
$retstr = "for (\$_".$tempvar."=0 ; \$_".$tempvar." < count(\$this->_arrvars";
$retstr = "for (\$_".$tempvar."=0 ; \$_".$tempvar." < \$this->_tpl_count(\$this->_arrvars";
for ($i=0; $i < count($this->_namespace); $i++) {
$retstr .= "['".$this->_namespace[$i]."']";
if ($this->_namespace[$i] != $varname) $retstr .= "[\$_".$i."]";
......@@ -1311,7 +1170,15 @@ if (!defined('vlibTemplateClassLoaded')) {
array_push($this->_currentincludedir, dirname($this->_tmplfilename));
$this->_includedepth++;
$success = @eval($this->_tmplfilep);
try {
$success = @eval($this->_tmplfilep);
} catch(Exception $ex) {
print $this->_tmplfilep;
throw $ex;
} catch(TypeError $ex) {
print $this->_tmplfilep;
throw $ex;
}
$this->_includedepth--;
array_pop($this->_currentincludedir);
......@@ -1409,6 +1276,27 @@ if (!defined('vlibTemplateClassLoaded')) {
return $return;
}
/**
* Used during in evaled code to replace PHP count function for PHP 8 compatibility
* @var variable to be counted
*/
private function _tpl_count($var)
{
$retvar = 0;
if(isset($var)) {
if(is_array($var)) {
$retvar = count($var);
} elseif(is_null($var)) {
$retvar = 0;
} else {
$retvar = 1;
}
} else {
$retvar = 0;
}
return $retvar;
}
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The following functions have no use and are included just so that if the user
is making use of vlibTemplateCache functions, this doesn't crash when changed to
......
<?php
/*
Copyright (c) 2021, Jesse Norell <jesse@kci.net>
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of ISPConfig nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* random_bytes can be dropped when php 5.6 support is dropped */
if (! function_exists('random_bytes')) {
function random_bytes($length) {
return openssl_random_pseudo_bytes($length);
}
}
/* random_int can be dropped when php 5.6 support is dropped */
if (! function_exists('random_int')) {
function random_int($min=null, $max=null) {
if (null === $min) {
$min = PHP_INT_MIN;
}
if (null === $max) {
$min = PHP_INT_MAX;
}
if (!is_int($min) || !is_int($max)) {
trigger_error('random_int: $min and $max must be integer values', E_USER_NOTICE);
$min = (int)$min;
$max = (int)$max;
}
if ($min > $max) {
trigger_error('random_int: $max can\'t be lesser than $min', E_USER_WARNING);
return null;
}
$range = $counter = $max - $min;
$bits = 1;
while ($counter >>= 1) {
++$bits;
}
$bytes = (int)max(ceil($bits/8), 1);
$bitmask = pow(2, $bits) - 1;
if ($bitmask >= PHP_INT_MAX) {
$bitmask = PHP_INT_MAX;
}
do {
$result = hexdec(bin2hex(random_bytes($bytes))) & $bitmask;
} while ($result > $range);
return $result + $min;
}
}
......@@ -26,32 +26,12 @@ 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.
*/
/*
This function returns a string that describes the installed
Linux distribution. e.g. debian40 for Debian GNU/Linux 4.0
*/
/*
Comments to completion forever ;-)
commandline arguments
$argv[1]
<?
echo "Total argument passed are : $argc \n";
for( $i = 0 ; $i <= $argc -1 ;$i++)
{
echo "Argument $i : $argv[$i] \n";
}
?>
*/
error_reporting(E_ALL|E_STRICT);
if(version_compare(phpversion(), '7.0', '<')) {
require_once 'compatibility.inc.php';
}
$FILE = realpath('../install.php');
......@@ -59,6 +39,10 @@ $FILE = realpath('../install.php');
//** IMPORTANT!
// This is the same code as in server/lib/classes/monitor_tools.inc.php
// So if you change it here, you also have to change it in there!
//
// This function returns a string that describes the installed
// Linux distribution. e.g. debian40 for Debian GNU/Linux 4.0
function get_distname() {
$distname = '';
......@@ -66,53 +50,85 @@ function get_distname() {
$distid = '';
$distbaseid = '';
//** Debian or Ubuntu
if (is_file('/etc/os-release') && stristr(file_get_contents('/etc/os-release'), 'Ubuntu')) {
$os_release = file_get_contents('/etc/os-release');
if (strstr(trim($os_release), 'LTS')) {
$lts = " LTS";
} else {
$lts = "";
}
preg_match("/.*VERSION=\"(.*)\".*/ui", $os_release, $ver);
$ver = str_replace("LTS", "", $ver[1]);
$ver = explode(" ", $ver, 2);
$relname = end($ver);
$relname = "(" . trim(trim($relname), "()") . ")";
$distname = 'Ubuntu';
$ver = reset($ver);
if($ver == "16.04") {
$distid = 'ubuntu1604';
} else {
$distid = 'debian40';
}
$distbaseid = 'debian';
$distver = $ver . $lts . " " . $relname;
swriteln("Operating System: " . $distver . "\n");
} //** Debian / Ubuntu
elseif(file_exists('/etc/debian_version')) {
if (strstr(trim(file_get_contents('/etc/issue')), 'Ubuntu')) {
if (strstr(trim(file_get_contents('/etc/issue')), 'LTS')) {
$lts=" LTS";
//** Debian or Ubuntu
if(file_exists('/etc/debian_version')) {
// Check if this is Ubuntu and not Debian
if (strstr(trim(file_get_contents('/etc/issue')), 'Ubuntu') || (is_file('/etc/os-release') && stristr(file_get_contents('/etc/os-release'), 'Ubuntu'))) {
$issue = file_get_contents('/etc/issue');
// Use content of /etc/issue file
if(strstr($issue,'Ubuntu')) {
if (strstr(trim($issue), 'LTS')) {
$lts=" LTS";
} else {
$lts="";
}
$distname = 'Ubuntu';
$distid = 'debian40';
$distbaseid = 'debian';
$ver = explode(' ', $issue);
$ver = array_filter($ver);
$ver = next($ver);
$mainver = explode('.', $ver);
$mainver = array_filter($mainver);
$mainver = current($mainver).'.'.next($mainver);
// Use content of /etc/os-release file
} else {
$lts="";
$os_release = file_get_contents('/etc/os-release');
if (strstr(trim($os_release), 'LTS')) {
$lts = " LTS";
} else {
$lts = "";
}
$distname = 'Ubuntu';
$distid = 'debian60';
$distbaseid = 'debian';
preg_match("/.*VERSION=\"(.*)\".*/ui", $os_release, $ver);
$ver = str_replace("LTS", "", $ver[1]);
$ver = explode(" ", $ver, 2);
$ver = reset($ver);
$mainver = $ver;
$mainver = explode('.', $ver);
$mainver = array_filter($mainver);
$mainver = current($mainver).'.'.next($mainver);
}
$issue=file_get_contents('/etc/issue');
$distname = 'Ubuntu';
$distid = 'debian40';
$distbaseid = 'debian';
$ver = explode(' ', $issue);
$ver = array_filter($ver);
$ver = next($ver);
$mainver = explode('.', $ver);
$mainver = array_filter($mainver);
$mainver = current($mainver).'.'.next($mainver);
switch ($mainver){
case "24.04":
$relname = "(Noble Numbat)";
$distconfid = 'ubuntu2404';
break;
case "22.04":
$relname = "(Jammy Jellyfish)";
$distconfid = 'ubuntu2204';
break;
case "20.04":
$relname = "(Focal Fossa)";
$distconfid = 'ubuntu2004';
break;
case "18.04":
$relname = "(Bionic Beaver)";
$distconfid = 'ubuntu1804';
break;
case "17.10":
$relname = "(Artful Aardvark)";
$distconfid = 'ubuntu1710';
break;
case "17.04":
$relname = "(Zesty Zapus)";
$distconfid = 'ubuntu1604';
break;
case "16.10":
$relname = "(Yakkety Yak)";
$distconfid = 'ubuntu1604';
break;
case "16.04":
$relname = "(Xenial Xerus)";
$distid = 'ubuntu1604';
$distconfid = 'ubuntu1604';
break;
case "15.10":
$relname = "(Wily Werewolf)";
......@@ -185,9 +201,10 @@ function get_distname() {
break;
default:
$relname = "UNKNOWN";
$distconfid = 'ubuntu2004';
}
$distver = $ver.$lts." ".$relname;
swriteln("Operating System: ".$distver."\n");
swriteln("Operating System: ".$distname.' '.$distver."\n");
} elseif(trim(file_get_contents('/etc/debian_version')) == '4.0') {
$distname = 'Debian';
$distver = '4.0';
......@@ -212,16 +229,52 @@ function get_distname() {
$distid = 'debian60';
$distbaseid = 'debian';
swriteln("Operating System: Debian 7.0 (Wheezy/Sid) or compatible\n");
} elseif(strstr(trim(file_get_contents('/etc/debian_version')), '8') || substr(trim(file_get_contents('/etc/debian_version')),0,1) == '8') {
} elseif(substr(trim(file_get_contents('/etc/debian_version')),0,1) == '8') {
$distname = 'Debian';
$distver = 'Jessie';
$distid = 'debian60';
$distbaseid = 'debian';
swriteln("Operating System: Debian 8.0 (Jessie) or compatible\n");
} elseif(substr(trim(file_get_contents('/etc/debian_version')),0,1) == '9') {
$distname = 'Debian';
$distver = 'Stretch';
$distconfid = 'debian90';
$distid = 'debian60';
$distbaseid = 'debian';
swriteln("Operating System: Debian 9.0 (Stretch) or compatible\n");
} elseif(substr(trim(file_get_contents('/etc/debian_version')),0,2) == '10') {
$distname = 'Debian';
$distver = 'Buster';
$distconfid = 'debian100';
$distid = 'debian60';
$distbaseid = 'debian';
swriteln("Operating System: Debian 10.0 (Buster) or compatible\n");
} elseif(substr(trim(file_get_contents('/etc/debian_version')),0,2) == '11') {
$distname = 'Debian';
$distver = 'Bullseye';
$distconfid = 'debian110';
$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';
$distid = 'debian60';
$distconfid = 'debiantesting';
$distbaseid = 'debian';
swriteln("Operating System: Debian Testing\n");
} else {
$distname = 'Debian';
$distver = 'Unknown';
$distid = 'debian40';
$distid = 'debian60';
$distconfid = 'debian120';
$distbaseid = 'debian';
swriteln("Operating System: Debian or compatible, unknown version.\n");
}
......@@ -256,72 +309,92 @@ function get_distname() {
}
}
//** Redhat
elseif(file_exists('/etc/redhat-release')) {
//** RHEL (including compatible clones) & Fedora
elseif(file_exists('/etc/redhat-release') && file_exists('/etc/os-release')) {
$content = file_get_contents('/etc/os-release');
preg_match('/(?<=PRETTY_NAME=\").+?(?=\")/', $content, $prettyname);
preg_match('/(?<=NAME=\").+?(?=\")/', $content, $name);
preg_match('/(?<=VERSION=\").+?(?=\")/', $content, $version);
preg_match('/(?<=VERSION_ID=\").+?(?=\")/', $content, $versionid);
if(stristr($prettyname[0], 'Fedora 32 (Thirty Two)')) {
$distname = 'Fedora';
$distver = '32';
$distid = 'fedora32';
$distbaseid = 'fedora';
swriteln("Operating System: Fedora 32 or compatible\n");
} elseif(stristr($prettyname[0], 'Fedora 33 (Thirty Three)')) {
$distname = 'Fedora';
$distver = '33';
$distid = 'fedora33';
$distbaseid = 'fedora';
swriteln("Operating System: Fedora 33 or compatible\n");
//** RHEL 7 and compatible clones
} elseif(preg_match('/^(?:7|7\.[0-9]{1,2})$/', $versionid[0])) {
preg_match_all('/([0-9]{1,2})\.?([0-9]{0,2})\.?([0-9]*)/', file_get_contents('/etc/redhat-release'), $centos7_version);
$distname = $name[0];
$distver = is_array($centos7_version)? implode('.', array_filter(array($centos7_version[1][0],$centos7_version[2][0],$centos7_version[3][0]),'strlen')) : $version[0];
$distid = 'centos72';
$distbaseid = 'fedora';
swriteln("Operating System: " . $distname . " " . $distver . "\n");
//** RHEL 8 and compatible clones
} elseif(preg_match('/^(?:8|8\.[0-9]{1,2})$/', $versionid[0])) {
$distname = $name[0];
$distver = $version[0];
$distid = 'centos80';
$distbaseid = 'fedora';
swriteln("Operating System: " . $prettyname[0] . "\n");
//** RHEL 9 and compatible clones
} elseif(preg_match('/^(?:9|9\.[0-9]{1,2})$/', $versionid[0])) {
$distname = $name[0];
$distver = $version[0];
$distid = 'centos90';
$distbaseid = 'fedora';
swriteln("Operating System: " . $prettyname[0] . "\n");
} else {
$distname = 'Redhat';
$distver = 'Unknown';
$distid = 'fedora9';
$distbaseid = 'fedora';
swriteln("Operating System: Redhat or compatible\n");
}
//** CentOS 6
} elseif(file_exists('/etc/redhat-release') && !file_exists('/etc/os-release') && !file_exists('/etc/els-release')) {
$content = file_get_contents('/etc/redhat-release');
if(stristr($content, 'Fedora release 9 (Sulphur)')) {
$distname = 'Fedora';
$distver = '9';
$distid = 'fedora9';
$distbaseid = 'fedora';
swriteln("Operating System: Fedora 9 or compatible\n");
} elseif(stristr($content, 'Fedora release 10 (Cambridge)')) {
$distname = 'Fedora';
$distver = '10';
$distid = 'fedora9';
$distbaseid = 'fedora';
swriteln("Operating System: Fedora 10 or compatible\n");
} elseif(stristr($content, 'Fedora release 10')) {
$distname = 'Fedora';
$distver = '11';
$distid = 'fedora9';
$distbaseid = 'fedora';
swriteln("Operating System: Fedora 11 or compatible\n");
} elseif(stristr($content, 'CentOS release 5.2 (Final)')) {
$distname = 'CentOS';
$distver = '5.2';
$distid = 'centos52';
$distbaseid = 'fedora';
swriteln("Operating System: CentOS 5.2 or compatible\n");
} elseif(stristr($content, 'CentOS release 5.3 (Final)')) {
$distname = 'CentOS';
$distver = '5.3';
if(stristr($content, 'CentOS Linux release 6') || stristr($content, 'CentOS release 6')) {
preg_match_all('/(6\.?([0-9]{0,2})\.?(\s)?([a-zA-Z()]+))$/', $content, $centos6_version);
$distname = 'CentOS Linux';
$distver = $centos6_version[0][0] ? $centos6_version[0][0] : '6';
$distid = 'centos53';
$distbaseid = 'fedora';
swriteln("Operating System: CentOS 5.3 or compatible\n");
} elseif(stristr($content, 'CentOS release 5')) {
$distname = 'CentOS';
swriteln("Operating System: " . $distname . " " . $distver . "\n");
} else {
$distname = 'Redhat';
$distver = 'Unknown';
$distid = 'centos53';
$distid = 'fedora9';
$distbaseid = 'fedora';
swriteln("Operating System: CentOS 5 or compatible\n");
} elseif(stristr($content, 'CentOS Linux release 6')) {
$distname = 'CentOS';
$distver = 'Unknown';
}
//** CentOS 6 Extended Lifecycle Support by CloudLinux
} elseif(file_exists('/etc/redhat-release') && file_exists('/etc/els-release') && !file_exists('/etc/os-release')) {
$content = file_get_contents('/etc/els-release');
if(stristr($content, 'CentOS Linux release 6') || stristr($content, 'CentOS release 6')) {
preg_match_all('/(6)\.?([0-9]{0,2})?\.?\s([a-zA-Z(), ]+)?$/', $content, $centos6_version);
$distname = 'CentOS Linux';
$distver = $centos6_version[0][0] ? $centos6_version[0][0] : '6';
$distid = 'centos53';
$distbaseid = 'fedora';
swriteln("Operating System: CentOS 6 or compatible\n");
} elseif(stristr($content, 'CentOS Linux release 7.2')) {
$distname = 'CentOS';
$distver = 'Unknown';
$distid = 'centos72';
$distbaseid = 'fedora';
swriteln("Operating System: CentOS 7.2\n");
} elseif(stristr($content, 'CentOS Linux release 7')) {
$distname = 'CentOS';
$distver = 'Unknown';
$distid = 'centos70';
$distbaseid = 'fedora';
swriteln("Operating System: CentOS 7 or compatible\n");
swriteln("Operating System: " . $distname . " " . $distver . "\n");
} else {
$distname = 'Redhat';
$distver = 'Unknown';
$distid = 'fedora9';
$distbaseid = 'fedora';
swriteln("Operating System: Redhat or compatible, unknown version.\n");
}
}
......@@ -340,8 +413,11 @@ function get_distname() {
} else {
die('Unrecognized GNU/Linux distribution');
}
// Set $distconfid to distid, if no different id for the config is defined
if(!isset($distconfid)) $distconfid = $distid;
return array('name' => $distname, 'version' => $distver, 'id' => $distid, 'baseid' => $distbaseid);
return array('name' => $distname, 'version' => $distver, 'id' => $distid, 'confid' => $distconfid, 'baseid' => $distbaseid);
}
function sread() {
......@@ -434,29 +510,38 @@ function rf($file){
}
function wf($file, $content){
mkdirs(dirname($file));
if(!$ret_val = mkdirs(dirname($file))) return false;
if(!$fp = fopen($file, 'wb')){
ilog('WARNING: could not open file '.$file);
// implicitly returned false because the following fwrite and fclose both fail,
// but to be explicit:
$ret_val = false;
}
fwrite($fp, $content);
fclose($fp);
fwrite($fp, $content) or $ret_val = false;
fclose($fp) or $ret_val = false;
return $ret_val;
}
function af($file, $content){
mkdirs(dirname($file));
if(!$ret_val = mkdirs(dirname($file))) return false;
if(!$fp = fopen($file, 'ab')){
ilog('WARNING: could not open file '.$file);
$ret_val = false;
}
fwrite($fp, $content);
fclose($fp);
fwrite($fp, $content) or $ret_val = false;
fclose($fp) or $ret_val = false;
return $ret_val;
}
function aftsl($file, $content){
$ret_val = true;
if(!$fp = fopen($file, 'ab')){
ilog('WARNING: could not open file '.$file);
$ret_val = false;
}
fwrite($fp, $content);
fclose($fp);
fwrite($fp, $content) or $ret_val = false;
fclose($fp) or $ret_val = false;
return $ret_val;
}
function unix_nl($input){
......@@ -473,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{
......@@ -621,7 +705,7 @@ function edit_xinetd_conf($service){
//* Converts a ini string to array
function ini_to_array($ini) {
$config = '';
$config = array();
$ini = str_replace("\r\n", "\n", $ini);
$lines = explode("\n", $ini);
foreach($lines as $line) {
......@@ -631,6 +715,7 @@ function ini_to_array($ini) {
$section = strtolower($matches[1]);
} elseif(preg_match("/^([\w\d_]+)=(.*)$/", $line, $matches) && $section != null) {
$item = trim($matches[1]);
if(!isset($config[$section])) $config[$section] = array();
$config[$section][$item] = trim($matches[2]);
}
}
......@@ -640,8 +725,7 @@ function ini_to_array($ini) {
//* Converts a config array to a string
function array_to_ini($config_array = '') {
if($config_array == '') $config_array = $this->config;
function array_to_ini($config_array) {
$content = '';
foreach($config_array as $section => $data) {
$content .= "[$section]\n";
......@@ -773,7 +857,7 @@ function is_installed($appname) {
function get_ispconfig_port_number() {
global $conf;
if($conf['nginx']['installed'] == true){
if(is_file($conf['nginx']['vhost_conf_dir'].'/ispconfig.vhost')) {
$ispconfig_vhost_file = $conf['nginx']['vhost_conf_dir'].'/ispconfig.vhost';
$regex = '/listen (\d+)/';
} else {
......@@ -799,7 +883,7 @@ function get_ispconfig_port_number() {
function get_apps_vhost_port_number() {
global $conf;
if($conf['nginx']['installed'] == true){
if(is_file($conf['nginx']['vhost_conf_dir'].'/apps.vhost')) {
$ispconfig_vhost_file = $conf['nginx']['vhost_conf_dir'].'/apps.vhost';
$regex = '/listen (\d+)/';
} else {
......@@ -820,9 +904,8 @@ function get_apps_vhost_port_number() {
}
/*
* Get the port number of the ISPConfig controlpanel vhost
*/
* Check if SSL is anabled in the ISPConfig controlpanel vhost.
*/
function is_ispconfig_ssl_enabled() {
global $conf;
$ispconfig_vhost_file = $conf['apache']['vhost_conf_dir'].'/ispconfig.vhost';
......@@ -837,6 +920,28 @@ function is_ispconfig_ssl_enabled() {
}
}
/*
* Is anonymization enabled in ispconfig.conf file
*/
function get_logging_state() {
global $conf;
$ispconfig_conf_file = $conf['apache']['vhost_conf_dir'].'/ispconfig.conf';
if(is_file($ispconfig_conf_file)) {
$tmp = file_get_contents($ispconfig_conf_file);
if(stristr($tmp, '/usr/local/ispconfig/server/scripts/vlogger -p -s access.log')) {
return 'anon';
} elseif(stristr($tmp, '/usr/local/ispconfig/server/scripts/vlogger -s access.log')) {
return 'yes';
} else {
return 'no';
}
} else {
return 'yes';
}
}
/**
Function to find the hash file for timezone detection
(c) 2012 Marius Cramer, pixcept KG, m.cramer@pixcept.de
......
<?php
/*
Copyright (c) 2007-2010, Till Brehm, projektfarm Gmbh
Copyright (c) 2007-2019, Till Brehm, projektfarm GmbH
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
......@@ -28,21 +28,42 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
class installer_base {
class installer_base extends stdClass {
var $wb = array();
var $language = 'en';
var $db;
public $conf;
public $install_ispconfig_interface = true;
public $is_update = false; // true if it is an update, falsi if it is a new install
public $min_php = '5.3.3'; // minimal php-version for update / install
public $is_update = false; // true if it is an update, false if it is a new install
protected $mailman_group = 'list';
public function __construct() {
global $conf; //TODO: maybe $conf should be passed to constructor
//$this->conf = $conf;
}
private function install_acme() {
$install_cmd = 'wget -O - https://get.acme.sh | sh';
$ret = null;
$val = 0;
exec($install_cmd . ' 2>&1', $ret, $val);
return ($val == 0 ? true : false);
}
public function update_acme() {
$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;
if($acme && is_executable($acme)) {
$cmd = $acme . ' --upgrade --auto-upgrade ; ' . $acme . ' --set-default-ca --server letsencrypt';
$ret = null;
$val = 0;
exec($cmd. ' 2>&1', $ret, $val);
}
return ($val == 0 ? true : false);
}
//: TODO Implement the translation function and language files for the installer.
......@@ -59,16 +80,16 @@ class installer_base {
}
public function simple_query($query, $answers, $default, $name = '') {
global $autoinstall;
global $autoinstall, $autoupdate;
$finished = false;
do {
if($name != '' && $autoinstall[$name] != '') {
if($name != '' && isset($autoinstall[$name]) && $autoinstall[$name] != '') {
if($autoinstall[$name] == 'default') {
$input = $default;
} else {
$input = $autoinstall[$name];
}
} elseif($name != '' && $autoupdate[$name] != '') {
} elseif($name != '' && isset($autoupdate[$name]) && $autoupdate[$name] != '') {
if($autoupdate[$name] == 'default') {
$input = $default;
} else {
......@@ -104,14 +125,14 @@ class installer_base {
}
public function free_query($query, $default, $name = '') {
global $autoinstall;
if($name != '' && $autoinstall[$name] != '') {
global $autoinstall, $autoupdate;
if($name != '' && isset($autoinstall[$name]) && $autoinstall[$name] != '') {
if($autoinstall[$name] == 'default') {
$input = $default;
} else {
$input = $autoinstall[$name];
}
} elseif($name != '' && $autoupdate[$name] != '') {
} elseif($name != '' && isset($autoupdate[$name]) && $autoupdate[$name] != '') {
if($autoupdate[$name] == 'default') {
$input = $default;
} else {
......@@ -143,10 +164,43 @@ class installer_base {
}
*/
//** Detect PHP-Version
public function get_php_version() {
if(version_compare(PHP_VERSION, $this->min_php, '<')) return false;
else return true;
public function set_immutable($path, $enable = true) {
if($path != '' && $path != '/' && strlen($path) > 6 && strpos($path, '..') === false && (is_file($path) || is_dir($path))) {
if($enable) {
exec('chattr +i ' . escapeshellarg($path));
} else {
exec('chattr -i ' . escapeshellarg($path));
}
}
}
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;
} elseif(defined('CRYPT_SHA256') && CRYPT_SHA256 == 1) {
$salt = '$5$rounds=5000$';
$salt_length = 16;
} else {
$salt = '$1$';
$salt_length = 12;
}
// todo: replace the below with password_hash() when we drop php5.4 support
if(function_exists('openssl_random_pseudo_bytes')) {
$salt .= substr(bin2hex(openssl_random_pseudo_bytes($salt_length)), 0, $salt_length);
} else {
$base64_alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./';
for($n = 0; $n < $salt_length; $n++) {
$salt .= $base64_alphabet[mt_rand(0, 63)];
}
}
$salt .= "$";
return crypt($cleartext_password, $salt);
}
//** Detect installed applications
......@@ -163,6 +217,7 @@ class installer_base {
if(is_installed('dovecot')) $conf['dovecot']['installed'] = true;
if(is_installed('saslauthd')) $conf['saslauthd']['installed'] = true;
if(is_installed('amavisd-new') || is_installed('amavisd')) $conf['amavis']['installed'] = true;
if(is_installed('rspamd')) $conf['rspamd']['installed'] = true;
if(is_installed('clamdscan')) $conf['clamav']['installed'] = true;
if(is_installed('pure-ftpd') || is_installed('pure-ftpd-wrapper')) $conf['pureftpd']['installed'] = true;
if(is_installed('mydns') || is_installed('mydns-ng')) $conf['mydns']['installed'] = true;
......@@ -171,20 +226,80 @@ class installer_base {
if(is_installed('named') || is_installed('bind') || is_installed('bind9')) $conf['bind']['installed'] = true;
if(is_installed('squid')) $conf['squid']['installed'] = true;
if(is_installed('nginx')) $conf['nginx']['installed'] = true;
if(is_installed('iptables') && is_installed('ufw')) $conf['ufw']['installed'] = true;
if(is_installed('iptables') && is_installed('bastille-netfilter')) $conf['firewall']['installed'] = true;
if(is_installed('apparmor_status')) $conf['apparmor']['installed'] = true;
if(is_installed('iptables') && is_installed('ufw')) {
$conf['ufw']['installed'] = true;
} elseif(is_installed('iptables')) {
$conf['firewall']['installed'] = true;
}
if(is_installed('fail2ban-server')) $conf['fail2ban']['installed'] = true;
if(is_installed('vzctl')) $conf['openvz']['installed'] = true;
if(is_installed('metronome') && is_installed('metronomectl')) $conf['xmpp']['installed'] = true;
if(is_installed('spamassassin')) $conf['spamassassin']['installed'] = true;
if(is_installed('vlogger')) $conf['vlogger']['installed'] = true;
if(is_installed('cron')) $conf['cron']['installed'] = true;
// if(is_installed('vlogger')) $conf['vlogger']['installed'] = true;
// ISPConfig ships with vlogger, so it is always installed.
$conf['vlogger']['installed'] = true;
if(is_installed('crontab')) $conf['cron']['installed'] = true;
if ($conf['services']['web'] && (($conf['apache']['installed'] && is_file($conf['apache']["vhost_conf_enabled_dir"]."/000-ispconfig.vhost")) || ($conf['nginx']['installed'] && is_file($conf['nginx']["vhost_conf_enabled_dir"]."/000-ispconfig.vhost")))) $this->ispconfig_interface_installed = true;
if (($conf['apache']['installed'] && is_file($conf['apache']["vhost_conf_enabled_dir"]."/000-ispconfig.vhost")) || ($conf['nginx']['installed'] && is_file($conf['nginx']["vhost_conf_enabled_dir"]."/000-ispconfig.vhost"))) $this->ispconfig_interface_installed = true;
}
//** 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(), '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;
if($enable_force == true) {
swriteln("[WARN] autodetect for $service failed");
} else {
......@@ -218,14 +333,27 @@ class installer_base {
public function configure_database() {
global $conf;
//* check sql-mode
$check_sql_mode = $this->db->queryOneRecord("SELECT @@sql_mode");
if ($check_sql_mode['@@sql_mode'] != '' && $check_sql_mode['@@sql_mode'] != 'NO_ENGINE_SUBSTITUTION') {
echo "Wrong SQL-mode. You should use NO_ENGINE_SUBSTITUTION. Add\n\n";
echo " sql-mode=\"NO_ENGINE_SUBSTITUTION\"\n\n";
echo"to the mysqld-section in /etc/mysql/my.cnf and restart mysqld afterwards\n";
die();
//** Check for unwanted plugins
if ($this->db->getDatabaseType() == 'mysql' && $this->db->getDatabaseVersion(true) >= 8) {
// component approach since MySQL 8.0
$unwanted_components = [
'file://component_validate_password',
];
$sql_components = $this->db->queryAllRecords("SELECT * FROM mysql.component where component_urn IN ?", $unwanted_components);
if(is_array($sql_components) && !empty($sql_components)) {
foreach ($sql_components as $component) {
$component_name = parse_url($component['component_urn'], PHP_URL_HOST);
echo "Login in to MySQL and disable '{$component_name}' with:\n\n UNINSTALL COMPONENT '{$component['component_urn']}';\n\n";
}
die();
}
} else {
$unwanted_sql_plugins = array('validate_password');
$sql_plugins = $this->db->queryAllRecords("SELECT plugin_name FROM information_schema.plugins WHERE plugin_status='ACTIVE' AND plugin_name IN ?", $unwanted_sql_plugins);
if(is_array($sql_plugins) && !empty($sql_plugins)) {
foreach ($sql_plugins as $plugin) echo "Login in to MySQL and disable $plugin[plugin_name] with:\n\n UNINSTALL PLUGIN $plugin[plugin_name];";
die();
}
}
//** Create the database
......@@ -242,10 +370,10 @@ class installer_base {
$this->error('Stopped: Database already contains some tables.');
} else {
if($conf['mysql']['admin_password'] == '') {
caselog("mysql --default-character-set=".escapeshellarg($conf['mysql']['charset'])." -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." ".escapeshellarg($conf['mysql']['database'])." < '".ISPC_INSTALL_ROOT."/install/sql/ispconfig3.sql' &> /dev/null",
caselog("mysql --default-character-set=".escapeshellarg($conf['mysql']['charset'])." -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." -P ".escapeshellarg($conf['mysql']['port'])." ".escapeshellarg($conf['mysql']['database'])." < '".ISPC_INSTALL_ROOT."/install/sql/ispconfig3.sql' &> /dev/null",
__FILE__, __LINE__, 'read in ispconfig3.sql', 'could not read in ispconfig3.sql');
} else {
caselog("mysql --default-character-set=".escapeshellarg($conf['mysql']['charset'])." -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." -p".escapeshellarg($conf['mysql']['admin_password'])." ".escapeshellarg($conf['mysql']['database'])." < '".ISPC_INSTALL_ROOT."/install/sql/ispconfig3.sql' &> /dev/null",
caselog("mysql --default-character-set=".escapeshellarg($conf['mysql']['charset'])." -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." -p".escapeshellarg($conf['mysql']['admin_password'])." -P ".escapeshellarg($conf['mysql']['port'])." ".escapeshellarg($conf['mysql']['database'])." < '".ISPC_INSTALL_ROOT."/install/sql/ispconfig3.sql' &> /dev/null",
__FILE__, __LINE__, 'read in ispconfig3.sql', 'could not read in ispconfig3.sql');
}
$db_tables = $this->db->getTables();
......@@ -275,11 +403,24 @@ class installer_base {
$this->db->query("DROP USER ?@?", $conf['mysql']['ispconfig_user'], $from_host);
$this->db->query("DROP DATABASE IF EXISTS ?", $conf['mysql']['database']);
//* Create the ISPConfig database user in the local database
$query = 'GRANT SELECT, INSERT, UPDATE, DELETE ON ?? TO ?@? IDENTIFIED BY ?';
if(!$this->db->query($query, $conf['mysql']['database'] . ".*", $conf['mysql']['ispconfig_user'], $from_host, $conf['mysql']['ispconfig_password'])) {
//* Create the ISPConfig database user and grant permissions in the local database
$query = 'CREATE USER ?@? IDENTIFIED BY ?';
if(!$this->db->query($query, $conf['mysql']['ispconfig_user'], $from_host, $conf['mysql']['ispconfig_password'])) {
$this->error('Unable to create database user: '.$conf['mysql']['ispconfig_user'].' Error: '.$this->db->errorMessage);
}
$query = 'GRANT SELECT, INSERT, UPDATE, DELETE ON ?? TO ?@?';
if(!$this->db->query($query, $conf['mysql']['database'] . ".*", $conf['mysql']['ispconfig_user'], $from_host)) {
$this->error('Unable to grant databse permissions to user: '.$conf['mysql']['ispconfig_user'].' Error: '.$this->db->errorMessage);
}
// add correct administrative rights to IPSConfig user (SUPER is deprecated and unnecessarily powerful)
if ($this->db->getDatabaseType() == 'mysql' && $this->db->getDatabaseVersion(true) >= 8) {
// there might be more needed on replicated db environments, this was not tested
$query = 'GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO ?@?';
if(!$this->db->query($query, $conf['mysql']['ispconfig_user'], $from_host)) {
$this->error('Unable to grant administrative permissions to user: '.$conf['mysql']['ispconfig_user'].' Error: '.$this->db->errorMessage);
}
}
//* Set the database name in the DB library
$this->db->setDBName($conf['mysql']['database']);
......@@ -296,6 +437,7 @@ class installer_base {
$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['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'];
......@@ -307,6 +449,8 @@ class installer_base {
$tpl_ini_array['web']['php_ini_path_cgi'] = $conf['apache']['php_ini_path_cgi'];
$tpl_ini_array['mail']['pop3_imap_daemon'] = ($conf['dovecot']['installed'] == true)?'dovecot':'courier';
$tpl_ini_array['mail']['mail_filter_syntax'] = ($conf['dovecot']['installed'] == true)?'sieve':'maildrop';
$tpl_ini_array['mail']['content_filter'] = @($conf['rspamd']['installed']) ? 'rspamd' : 'amavisd';
$tpl_ini_array['mail']['rspamd_available'] = @($conf['rspamd']['installed']) ? 'y' : 'n';
$tpl_ini_array['dns']['bind_user'] = $conf['bind']['bind_user'];
$tpl_ini_array['dns']['bind_group'] = $conf['bind']['bind_group'];
$tpl_ini_array['dns']['bind_zonefiles_dir'] = $conf['bind']['bind_zonefiles_dir'];
......@@ -335,8 +479,11 @@ class installer_base {
}
}
// preserve needed values in $conf (should just array_merge $tpl_ini_array into $conf?)
$conf['mail']['content_filter'] = $tpl_ini_array['mail']['content_filter'];
$server_ini_content = array_to_ini($tpl_ini_array);
$mail_server_enabled = ($conf['services']['mail'])?1:0;
$web_server_enabled = ($conf['services']['web'])?1:0;
$dns_server_enabled = ($conf['services']['dns'])?1:0;
......@@ -388,80 +535,92 @@ class installer_base {
}
public function get_host_ips() {
$out = array();
exec('hostname --all-ip-addresses', $ret, $val);
if($val == 0) {
if(is_array($ret) && !empty($ret)){
$temp = (explode(' ', $ret[0]));
foreach($temp as $ip) {
$out[] = $ip;
}
}
}
return $out;
}
public function detect_ips(){
global $conf;
exec("ip addr show | awk '/global/ { print $2 }' | cut -d '/' -f 1", $output, $retval);
if($retval == 0){
if(is_array($output) && !empty($output)){
foreach($output as $line){
$line = trim($line);
$ip_type = '';
if (filter_var($line, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
$ip_type = 'IPv4';
}
if (filter_var($line, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
$ip_type = 'IPv6';
}
if($ip_type == '') continue;
if($this->db->dbHost != $this->dbmaster->dbHost){
$this->dbmaster->query('INSERT INTO server_ip (
sys_userid, sys_groupid, sys_perm_user, sys_perm_group,
sys_perm_other, server_id, client_id, ip_type, ip_address,
virtualhost, virtualhost_port
) VALUES (
1,
1,
"riud",
"riud",
"",
?,
0,
?,
?,
"y",
"80,443"
)', $conf['server_id'], $ip_type, $line);
$server_ip_id = $this->dbmaster->insertID();
$this->db->query('INSERT INTO server_ip (
server_php_id, sys_userid, sys_groupid, sys_perm_user, sys_perm_group,
sys_perm_other, server_id, client_id, ip_type, ip_address,
virtualhost, virtualhost_port
) VALUES (
?,
1,
1,
"riud",
"riud",
"",
?,
0,
?,
?,
"y",
"80,443"
)', $server_ip_id, $conf['server_id'], $ip_type, $line);
} else {
$this->db->query('INSERT INTO server_ip (
sys_userid, sys_groupid, sys_perm_user, sys_perm_group,
sys_perm_other, server_id, client_id, ip_type, ip_address,
virtualhost, virtualhost_port
) VALUES (
1,
1,
"riud",
"riud",
"",
?,
0,
?,
?,
"y",
"80,443"
)', $conf['server_id'], $ip_type, $line);
}
$output = $this->get_host_ips();
if(is_array($output) && !empty($output)){
foreach($output as $line){
$ip_type = '';
if (filter_var($line, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
$ip_type = 'IPv4';
}
if (filter_var($line, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
$ip_type = 'IPv6';
}
if($ip_type == '') continue;
if($this->db->dbHost != $this->dbmaster->dbHost){
$this->dbmaster->query('INSERT INTO server_ip (
sys_userid, sys_groupid, sys_perm_user, sys_perm_group,
sys_perm_other, server_id, client_id, ip_type, ip_address,
virtualhost, virtualhost_port
) VALUES (
1,
1,
"riud",
"riud",
"",
?,
0,
?,
?,
"n",
"80,443"
)', $conf['server_id'], $ip_type, $line);
$server_ip_id = $this->dbmaster->insertID();
$this->db->query('INSERT INTO server_ip (
server_php_id, sys_userid, sys_groupid, sys_perm_user, sys_perm_group,
sys_perm_other, server_id, client_id, ip_type, ip_address,
virtualhost, virtualhost_port
) VALUES (
?,
1,
1,
"riud",
"riud",
"",
?,
0,
?,
?,
"n",
"80,443"
)', $server_ip_id, $conf['server_id'], $ip_type, $line);
} else {
$this->db->query('INSERT INTO server_ip (
sys_userid, sys_groupid, sys_perm_user, sys_perm_group,
sys_perm_other, server_id, client_id, ip_type, ip_address,
virtualhost, virtualhost_port
) VALUES (
1,
1,
"riud",
"riud",
"",
?,
0,
?,
?,
"n",
"80,443"
)', $conf['server_id'], $ip_type, $line);
}
}
}
......@@ -488,15 +647,23 @@ class installer_base {
//* insert the ispconfig user in the remote server
$from_host = $conf['hostname'];
$from_ip = gethostbyname($conf['hostname']);
$hosts[$from_host]['user'] = $conf['mysql']['master_ispconfig_user'];
$hosts[$from_host]['db'] = $conf['mysql']['master_database'];
$hosts[$from_host]['pwd'] = $conf['mysql']['master_ispconfig_password'];
$hosts[$from_ip]['user'] = $conf['mysql']['master_ispconfig_user'];
$hosts[$from_ip]['db'] = $conf['mysql']['master_database'];
$hosts[$from_ip]['pwd'] = $conf['mysql']['master_ispconfig_password'];
$host_ips = $this->get_host_ips();
if(is_array($host_ips) && !empty($host_ips)) {
foreach($host_ips as $ip) {
$hosts[$ip]['user'] = $conf['mysql']['master_ispconfig_user'];
$hosts[$ip]['db'] = $conf['mysql']['master_database'];
$hosts[$ip]['pwd'] = $conf['mysql']['master_ispconfig_password'];
}
} else {
$from_ip = gethostbyname($conf['hostname']);
$hosts[$from_ip]['user'] = $conf['mysql']['master_ispconfig_user'];
$hosts[$from_ip]['db'] = $conf['mysql']['master_database'];
$hosts[$from_ip]['pwd'] = $conf['mysql']['master_ispconfig_password'];
}
} else{
/*
* it is NOT a master-slave - Setup so we have to find out all clients and their
......@@ -567,9 +734,6 @@ class installer_base {
if ($verbose){
echo $query ."\n";
}
if(!$this->dbmaster->query($query, $value['db'] . '.software_update_inst', $value['user'], $host)) {
$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
}
$query = "GRANT SELECT, UPDATE(`updated`) ON ?? TO ?@?";
if ($verbose){
......@@ -579,7 +743,7 @@ class installer_base {
$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
}
$query = "GRANT SELECT, UPDATE (`ssl_request`, `ssl_cert`, `ssl_action`, `ssl_key`) ON ?? TO ?@?";
$query = "GRANT SELECT, UPDATE (`ssl`, `ssl_letsencrypt`, `ssl_request`, `ssl_cert`, `ssl_action`, `ssl_key`) ON ?? TO ?@?";
if ($verbose){
echo $query ."\n";
}
......@@ -587,6 +751,14 @@ class installer_base {
$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
}
$query = "GRANT SELECT ON ?? TO ?@?";
if ($verbose){
echo $query ."\n";
}
if(!$this->dbmaster->query($query, $value['db'] . '.web_database', $value['user'], $host)) {
$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
}
$query = "GRANT SELECT ON ?? TO ?@?";
if ($verbose){
echo $query ."\n";
......@@ -603,7 +775,7 @@ class installer_base {
$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
}
$query = "GRANT SELECT, INSERT , DELETE ON ?? TO ?@?";
$query = "GRANT SELECT, INSERT, UPDATE, DELETE ON ?? TO ?@?";
if ($verbose){
echo $query ."\n";
}
......@@ -634,7 +806,7 @@ class installer_base {
if(!$this->dbmaster->query($query, $value['db'] . '.aps_instances', $value['user'], $host)) {
$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
}
$query = "GRANT SELECT, DELETE ON ?? TO ?@?";
if ($verbose){
echo $query ."\n";
......@@ -658,8 +830,8 @@ class installer_base {
if(!$this->dbmaster->query($query, $value['db'] . '.mail_backup', $value['user'], $host)) {
$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
}
$query = "GRANT SELECT, UPDATE(`dnssec_initialized`, `dnssec_info`, `dnssec_last_signed`) ON ?? TO ?@?";
$query = "GRANT SELECT, UPDATE(`dnssec_initialized`, `dnssec_info`, `dnssec_last_signed`, `rendered_zone`) ON ?? TO ?@?";
if ($verbose){
echo $query ."\n";
}
......@@ -667,6 +839,22 @@ class installer_base {
$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
}
$query = "GRANT SELECT, INSERT, UPDATE ON ?? TO ?@?";
if ($verbose){
echo $query ."\n";
}
if(!$this->dbmaster->query($query, $value['db'] . '.ftp_traffic', $value['user'], $host)) {
$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
}
$query = "GRANT SELECT, 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);
}
}
}
......@@ -678,18 +866,45 @@ class installer_base {
global $conf;
$config_dir = $conf['postfix']['config_dir'].'/';
$postfix_group = $conf['postfix']['group'];
$full_file_name = $config_dir.$configfile;
//* Backup exiting file
if(is_file($full_file_name)) {
copy($full_file_name, $config_dir.$configfile.'~');
chmod($config_dir.$configfile.'~',0600);
}
exec('postconf -h recipient_delimiter 2>/dev/null', $out);
if (strlen($out[0]) > 0) {
// build string like: CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX('%u', '%%', 1), '+', 1), '@%d')
$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)";
}
$no_addr_extension = "CONCAT({$addr_cleanup}, '@%d')";
} else {
$no_addr_extension = "''";
}
unset($out);
//* Replace variables in config file template
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master');
$content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content);
$content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content);
$content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content);
$content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content);
$content = str_replace('{server_id}', $conf['server_id'], $content);
$content = str_replace('{address_without_extension}', $no_addr_extension, $content);
wf($full_file_name, $content);
//* Changing mode and group of the new created config file
caselog('chmod u=rw,g=r,o= '.escapeshellarg($full_file_name).' &> /dev/null',
__FILE__, __LINE__, 'chmod on '.$full_file_name, 'chmod on '.$full_file_name.' failed');
caselog('chgrp '.escapeshellarg($postfix_group).' '.escapeshellarg($full_file_name).' &> /dev/null',
__FILE__, __LINE__, 'chgrp on '.$full_file_name, 'chgrp on '.$full_file_name.' failed');
}
public function configure_jailkit() {
......@@ -699,20 +914,22 @@ class installer_base {
$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);
}
}
......@@ -725,6 +942,20 @@ class installer_base {
public function configure_mailman($status = 'insert') {
global $conf;
// Fix for #6314: bug on Debian 11 systems where Mailman3 is not available and broken routes exist in the Mailman config
$data_dir = '/var/lib/mailman';
if (($conf['mailman']['installed'] != true) && is_dir($data_dir)) {
rename($data_dir, $data_dir . '-bk');
//* 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('postmap /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('postmap /var/lib/mailman/data/transport-mailman');
}
$config_dir = $conf['mailman']['config_dir'].'/';
$full_file_name = $config_dir.'mm_cfg.py';
//* Backup exiting file
......@@ -771,7 +1002,7 @@ class installer_base {
$virtual_domains = "' '";
$content = str_replace('{hostname}', $conf['hostname'], $content);
if(!isset($old_options['DEFAULT_SERVER_LANGUAGE'])) $old_options['DEFAULT_SERVER_LANGUAGE'] = '';
if(!isset($old_options['DEFAULT_SERVER_LANGUAGE']) || $old_options['DEFAULT_SERVER_LANGUAGE'] == '') $old_options['DEFAULT_SERVER_LANGUAGE'] = "'en'";
$content = str_replace('{default_language}', $old_options['DEFAULT_SERVER_LANGUAGE'], $content);
$content = str_replace('{virtual_domains}', $virtual_domains, $content);
......@@ -797,7 +1028,7 @@ class installer_base {
}
//* Create aliasaes
exec('/usr/lib/mailman/bin/genaliases 2>/dev/null');
if($status == 'install') exec('/usr/lib/mailman/bin/genaliases 2>/dev/null');
if(!is_file('/var/lib/mailman/data/transport-mailman')) touch('/var/lib/mailman/data/transport-mailman');
exec('/usr/sbin/postmap /var/lib/mailman/data/transport-mailman');
......@@ -806,7 +1037,7 @@ class installer_base {
public function get_postfix_service($service, $type) {
global $conf;
exec("postconf -M", $out, $ret);
exec("postconf -M 2> /dev/null", $out, $ret);
if ($ret === 0) { //* with postfix >= 2.9 we can detect configured services with postconf
unset($out);
......@@ -815,77 +1046,127 @@ class installer_base {
exec ("postconf -M $service.$type 2> /dev/null", $out, $ret);
}
$postfix_service = @($out[0]=='')?false:true;
} else { //* fallback - Postfix < 2.9
rf($conf['postfix']['config_dir'].'/master.cf');
$regex = '/[^#]'.$service.'.*.'.$type.'.*/';
$postfix_service = @(!preg_match($regex, $content))?true:false;
} else { //* fallback - Postfix < 2.9
$content = rf($conf['postfix']['config_dir'].'/master.cf');
$quoted_regex = "^((?!#)".preg_quote($service, '/').".*".preg_quote($type, '/').".*)$";
$postfix_service = @(preg_match("/$quoted_regex/m", $content))?true:false;
}
return $postfix_service;
}
public function configure_postfix($options = '') {
global $conf,$autoinstall;
$cf = $conf['postfix'];
$config_dir = $cf['config_dir'];
public function remove_postfix_service( $service, $type ) {
global $conf;
if(!is_dir($config_dir)) {
$this->error("The postfix configuration directory '$config_dir' does not exist.");
// nothing to do if the service isn't even defined.
if (! $this->get_postfix_service( $service, $type ) ) {
return true;
}
//* mysql-virtual_domains.cf
$this->process_postfix_config('mysql-virtual_domains.cf');
$postfix_version = `postconf -d mail_version 2>/dev/null`;
$postfix_version = preg_replace( '/mail_version\s*=\s*(.*)\s*/', '$1', $postfix_version );
//* mysql-virtual_forwardings.cf
$this->process_postfix_config('mysql-virtual_forwardings.cf');
if ( version_compare( $postfix_version, '2.11', '>=' ) ) {
//* mysql-virtual_mailboxes.cf
$this->process_postfix_config('mysql-virtual_mailboxes.cf');
exec("postconf -X -M $service/$type 2> /dev/null", $out, $ret);
//* mysql-virtual_email2email.cf
$this->process_postfix_config('mysql-virtual_email2email.cf');
# 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 );
//* mysql-virtual_transports.cf
$this->process_postfix_config('mysql-virtual_transports.cf');
} else { //* fallback - Postfix < 2.11
//* mysql-virtual_recipient.cf
$this->process_postfix_config('mysql-virtual_recipient.cf');
if ( ! $cf = fopen( $conf['postfix']['config_dir'].'/master.cf', 'r' ) ) {
return false;
}
$out = "";
$reading_service = false;
//* mysql-virtual_sender.cf
$this->process_postfix_config('mysql-virtual_sender.cf');
while ( !feof( $cf ) ) {
$line = fgets( $cf );
//* mysql-virtual_sender_login_maps.cf
$this->process_postfix_config('mysql-virtual_sender_login_maps.cf');
$quoted_regex = '^'.preg_quote($service, '/').'\s+'.preg_quote($type, '/');
if ( $reading_service ) {
# regex matches a new service or "empty" (whitespace) line
if ( preg_match( '/^([^\s#]+.*|\s*)$/', $line ) &&
! preg_match( "/$quoted_regex/", $line ) ) {
$out .= $line;
$reading_service = false;
}
//* mysql-virtual_client.cf
$this->process_postfix_config('mysql-virtual_client.cf');
# $skipped_lines .= $line;
//* mysql-virtual_relaydomains.cf
$this->process_postfix_config('mysql-virtual_relaydomains.cf');
# regex matches definition matching service to be removed
} else if ( preg_match( "/$quoted_regex/", $line ) ) {
//* mysql-virtual_relayrecipientmaps.cf
$this->process_postfix_config('mysql-virtual_relayrecipientmaps.cf');
//* mysql-virtual_outgoing_bcc.cf
$this->process_postfix_config('mysql-virtual_outgoing_bcc.cf');
$reading_service = true;
# $skipped_lines .= $line;
//* mysql-virtual_policy_greylist.cf
$this->process_postfix_config('mysql-virtual_policy_greylist.cf');
} else {
$out .= $line;
}
}
fclose( $cf );
$out = preg_replace( '/(\r?\n){3,}/', '$1$1', $out ); # reduce 3 or more newlines to 2
return wf( $conf['postfix']['config_dir'].'/master.cf', $out );
}
return true;
}
public function get_postfix_version() {
//* Get postfix version
exec('postconf -d mail_version 2>&1', $out);
$postfix_version = preg_replace('/.*=\s*/', '', $out[0]);
unset($out);
return $postfix_version;
}
public function configure_postfix($options = '') {
global $conf,$autoinstall;
$cf = $conf['postfix'];
$config_dir = $cf['config_dir'];
if(!is_dir($config_dir)) {
$this->error("The postfix configuration directory '$config_dir' does not exist.");
}
$postfix_version = $this->get_postfix_version();
//* Install virtual mappings
foreach (glob('tpl/mysql-virtual_*.master') as $filename) {
$this->process_postfix_config( basename($filename, '.master') );
}
//* 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
$full_file_name=$config_dir.'/tag_as_originating.re';
$filename='tag_as_originating.re';
$full_file_name=$config_dir.'/'.$filename;
if(is_file($full_file_name)) copy($full_file_name, $full_file_name.'~');
wf($full_file_name, '/^/ FILTER amavis:[127.0.0.1]:10026');
$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);
$full_file_name=$config_dir.'/tag_as_foreign.re';
$filename='tag_as_foreign.re';
$full_file_name=$config_dir.'/'.$filename;
if(is_file($full_file_name)) copy($full_file_name, $full_file_name.'~');
wf($full_file_name, '/^/ FILTER amavis:[127.0.0.1]:10024');
//* Changing mode and group of the new created config files.
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');
$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);
//* Creating virtual mail user and group
$command = 'groupadd -g '.$cf['vmail_groupid'].' '.$cf['vmail_groupname'];
......@@ -899,9 +1180,9 @@ class installer_base {
$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'] != '') {
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;
......@@ -911,17 +1192,33 @@ class installer_base {
//* If Postgrey is installed, configure it
$greylisting = '';
if($conf['postgrey']['installed'] == true) {
if(isset($conf['postgrey']['installed']) && ($conf['postgrey']['installed'] == true)) {
$greylisting = ', check_recipient_access mysql:/etc/postfix/mysql-virtual_policy_greylist.cf';
}
$reject_sender_login_mismatch = '';
$reject_authenticated_sender_login_mismatch = '';
if(isset($server_ini_array['mail']['reject_sender_login_mismatch']) && ($server_ini_array['mail']['reject_sender_login_mismatch'] == 'y')) {
$reject_sender_login_mismatch = ', reject_authenticated_sender_login_mismatch';
$reject_sender_login_mismatch = ',reject_sender_login_mismatch,';
$reject_authenticated_sender_login_mismatch = 'reject_authenticated_sender_login_mismatch, ';
}
# placeholder includes comment char
$stress_adaptive_placeholder = '#{stress_adaptive}';
$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')) {
$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') {
$reject_unknown_helo_hostname=',reject_unknown_helo_hostname';
}
unset($server_ini_array);
$tmp = str_replace('.','\.',$conf['hostname']);
$myhostname = str_replace('.','\.',$conf['hostname']);
$postconf_placeholders = array('{config_dir}' => $config_dir,
'{vmail_mailbox_base}' => $cf['vmail_mailbox_base'],
......@@ -930,13 +1227,52 @@ class installer_base {
'{rbl_list}' => $rbl_list,
'{greylisting}' => $greylisting,
'{reject_slm}' => $reject_sender_login_mismatch,
'{myhostname}' => $tmp,
'{reject_aslm}' => $reject_authenticated_sender_login_mismatch,
'{myhostname}' => $myhostname,
$stress_adaptive_placeholder => $stress_adaptive,
'{reject_unknown_client_hostname}' => $reject_unknown_client_hostname,
'{reject_unknown_helo_hostname}' => $reject_unknown_helo_hostname,
);
$postconf_tpl = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/debian_postfix.conf.master', 'tpl/debian_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(
......@@ -951,6 +1287,7 @@ class installer_base {
touch($config_dir.'/mime_header_checks');
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');
......@@ -1011,16 +1348,16 @@ class installer_base {
if(is_file('/var/run/courier/authdaemon/')) caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command);
//* Check maildrop service in posfix master.cf
$regex = "/^maildrop unix.*pipe flags=DRhu user=vmail argv=\\/usr\\/bin\\/maildrop -d ".$cf['vmail_username']." \\$\{extension} \\$\{recipient} \\$\{user} \\$\{nexthop} \\$\{sender}/";
$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';
if($this->get_postfix_service('maildrop', 'unix')) {
exec ("postconf -M maildrop.unix &> /dev/null", $out, $ret);
$change_maildrop_flags = @(preg_match($regex, $out[0]) && $out[0] !='')?false:true;
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($regex, $configfile))?false:true;
$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~');
}
......@@ -1029,8 +1366,8 @@ class installer_base {
}
$configfile = $config_dir.'/master.cf';
$content = rf($configfile);
$content = str_replace('flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}',
'flags=DRhu user='.$cf['vmail_username'].' argv=/usr/bin/maildrop -d '.$cf['vmail_username'].' ${extension} ${recipient} ${user} ${nexthop} ${sender}',
$content = preg_replace('/flags=(DRX?hu) user=vmail argv=\/usr\/bin\/maildrop -d \${recipient}/',
'flags=$1 user='.$cf['vmail_username'].' argv=/usr/bin/maildrop -d '.$cf['vmail_username'].' \${extension} \${recipient} \${user} \${nexthop} \${sender}',
$content);
wf($configfile, $content);
}
......@@ -1058,7 +1395,7 @@ class installer_base {
caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
}
public function configure_saslauthd() {
global $conf;
......@@ -1174,17 +1511,22 @@ class installer_base {
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']);
$ini_array = ini_to_array(stripslashes($tmp['config']));
// ini_array needs not to be checked, because already done in update.php -> updateDbAndIni()
if(isset($ini_array['mail']['mailbox_virtual_uidgid_maps']) && $ini_array['mail']['mailbox_virtual_uidgid_maps'] == 'y') {
$virtual_transport = 'lmtp:unix:private/dovecot-lmtp';
$configure_lmtp = true;
......@@ -1192,6 +1534,8 @@ class installer_base {
}
$config_dir = $conf['postfix']['config_dir'];
$quoted_config_dir = preg_quote($config_dir, '|');
$postfix_version = $this->get_postfix_version();
//* Configure master.cf and add a line for deliver
if(!$this->get_postfix_service('dovecot', 'unix')) {
......@@ -1199,11 +1543,11 @@ class installer_base {
if(is_file($config_dir.'/master.cf')){
copy($config_dir.'/master.cf', $config_dir.'/master.cf~2');
}
if(is_file($config_dir.'/master.cf~')){
if(is_file($config_dir.'/master.cf~2')){
chmod($config_dir.'/master.cf~2', 0400);
}
//* Configure master.cf and add a line for deliver
$content = rf($conf["postfix"]["config_dir"].'/master.cf');
$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);
......@@ -1220,7 +1564,31 @@ class installer_base {
);
// Make a backup copy of the main.cf file
copy($conf['postfix']['config_dir'].'/main.cf', $conf['postfix']['config_dir'].'/main.cf~3');
copy($config_dir.'/main.cf', $config_dir.'/main.cf~3');
$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) {
......@@ -1253,17 +1621,77 @@ class installer_base {
} else {
copy('tpl/debian_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) {
replaceLine($config_dir.'/'.$configfile, 'protocols = imap pop3', 'protocols = imap pop3 lmtp', 1, 0);
$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 = 'dovecot-sql.conf';
if(is_file($config_dir.'/'.$configfile)) {
......@@ -1277,12 +1705,16 @@ class installer_base {
$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);
}
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");
......@@ -1291,6 +1723,12 @@ class installer_base {
public function configure_amavis() {
global $conf;
//* These postconf commands will be executed on installation and update
$server_ini_rec = $this->db->queryOneRecord("SELECT mail_server, config FROM ?? WHERE server_id = ?", $conf["mysql"]["database"] . '.server', $conf['server_id']);
$server_ini_array = ini_to_array(stripslashes($server_ini_rec['config']));
$mail_server = $conf['services']['mail'];
unset($server_ini_rec);
// amavisd user config file
$configfile = 'amavisd_user_config';
if(is_file($conf['amavis']['config_dir'].'/conf.d/50-user')) copy($conf['amavis']['config_dir'].'/conf.d/50-user', $conf['amavis']['config_dir'].'/50-user~');
......@@ -1303,74 +1741,379 @@ class installer_base {
$content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content);
wf($conf['amavis']['config_dir'].'/conf.d/50-user', $content);
chmod($conf['amavis']['config_dir'].'/conf.d/50-user', 0640);
chgrp($conf['amavis']['config_dir'].'/conf.d/50-user', 'amavis');
// TODO: chmod and chown on the config file
$config_dir = $conf['postfix']['config_dir'];
$quoted_config_dir = preg_quote($config_dir, '|');
$mail_config = $server_ini_array['mail'];
//* only change postfix config if amavisd is active filter
if($mail_server && $mail_config['content_filter'] === 'amavisd') {
// test if lmtp if available
$configure_lmtp = $this->get_postfix_service('lmtp','unix');
// Adding the amavisd commands to the postfix configuration
$postconf_commands = array ();
// 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[] = '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';
}
$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) {
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_version = $this->get_postfix_version();
# postfix < 3.3 needs this when using reject_unverified_recipient:
if(version_compare($postfix_version, 3.3, '<')) {
$postconf_commands[] = "enable_original_recipient = yes";
}
}
$postconf_commands[] = "smtpd_recipient_restrictions = ".implode(", ", $new_options);
// Adding the amavisd commands to the postfix configuration
// Add array for no error in foreach and maybe future options
$postconf_commands = array ();
// Make a backup copy of the main.cf file
copy($conf['postfix']['config_dir'].'/main.cf', $conf['postfix']['config_dir'].'/main.cf~2');
// Check for amavisd -> pure webserver with postfix for mailing without antispam
if ($conf['amavis']['installed']) {
$postconf_commands[] = 'content_filter = amavis:[127.0.0.1]:10024';
$postconf_commands[] = 'receive_override_options = no_address_mappings';
}
// 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");
}
// Make a backup copy of the main.cf file
copy($conf['postfix']['config_dir'].'/main.cf', $conf['postfix']['config_dir'].'/main.cf~2');
// Adding amavis-services to the master.cf file
// 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");
}
// backup master.cf
if(is_file($config_dir.'/master.cf')) copy($config_dir.'/master.cf', $config_dir.'/master.cf~');
$config_dir = $conf['postfix']['config_dir'];
// first remove the old service definitions
$this->remove_postfix_service('amavis','unix');
$this->remove_postfix_service('127.0.0.1:10025','inet');
$this->remove_postfix_service('127.0.0.1:10027','inet');
// Adding amavis-services to the master.cf file if the service does not already exists
$add_amavis = !$this->get_postfix_service('amavis','unix');
$add_amavis_10025 = !$this->get_postfix_service('127.0.0.1:10025','inet');
$add_amavis_10027 = !$this->get_postfix_service('127.0.0.1:10027','inet');
// then add them back
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis.master', 'tpl/master_cf_amavis.master');
af($config_dir.'/master.cf', $content);
unset($content);
if ($add_amavis || $add_amavis_10025 || $add_amavis_10027) {
//* backup master.cf
if(is_file($config_dir.'/master.cf')) copy($config_dir.'/master.cf', $config_dir.'/master.cf~');
// adjust amavis-config
if($add_amavis) {
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis.master', 'tpl/master_cf_amavis.master');
af($config_dir.'/master.cf', $content);
unset($content);
}
if ($add_amavis_10025) {
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10025.master', 'tpl/master_cf_amavis10025.master');
af($config_dir.'/master.cf', $content);
unset($content);
}
if ($add_amavis_10027) {
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10027.master', 'tpl/master_cf_amavis10027.master');
af($config_dir.'/master.cf', $content);
unset($content);
}
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10025.master', 'tpl/master_cf_amavis10025.master');
af($config_dir.'/master.cf', $content);
unset($content);
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10027.master', 'tpl/master_cf_amavis10027.master');
af($config_dir.'/master.cf', $content);
unset($content);
}
// Add the clamav user to the amavis group
exec('adduser clamav amavis');
// Create the director for DKIM-Keys
if(!is_dir('/var/lib/amavis/dkim')) mkdir('/var/lib/amavis/dkim', 0750, true);
// get shell-group for amavis
$amavis_group=exec('grep -o "^amavis:\|^vscan:" /etc/group');
if(!empty($amavis_group)) {
$amavis_group=rtrim($amavis_group, ":");
}
// get shell-user for amavis
$amavis_user=exec('grep -o "^amavis:\|^vscan:" /etc/passwd');
if(!empty($amavis_user)) {
$amavis_user=rtrim($amavis_user, ":");
exec('chown '.$amavis_user.' /var/lib/amavis/dkim');
}
// get shell-group for amavis
$amavis_group=exec('grep -o "^amavis:\|^vscan:" /etc/group');
if(!empty($amavis_group)) {
$amavis_group=rtrim($amavis_group, ":");
exec('chgrp '.$amavis_group.' /var/lib/amavis/dkim');
// Create the director for DKIM-Keys
if(!is_dir('/var/lib/amavis')) mkdir('/var/lib/amavis', 0750, true);
if(!empty($amavis_user)) exec('chown '.$amavis_user.' /var/lib/amavis');
if(!empty($amavis_group)) exec('chgrp '.$amavis_group.' /var/lib/amavis');
if(!is_dir('/var/lib/amavis/dkim')) mkdir('/var/lib/amavis/dkim', 0750);
if(!empty($amavis_user)) exec('chown -R '.$amavis_user.' /var/lib/amavis/dkim');
if(!empty($amavis_group)) exec('chgrp -R '.$amavis_group.' /var/lib/amavis/dkim');
}
public function configure_rspamd() {
global $conf;
//* These postconf commands will be executed on installation and update
$server_ini_rec = $this->db->queryOneRecord("SELECT mail_server, config FROM ?? WHERE server_id = ?", $conf["mysql"]["database"] . '.server', $conf['server_id']);
$server_ini_array = ini_to_array(stripslashes($server_ini_rec['config']));
$mail_server = $conf['services']['mail'];
unset($server_ini_rec);
$config_dir = $conf['postfix']['config_dir'];
$quoted_config_dir = preg_quote($config_dir, '|');
$mail_config = $server_ini_array['mail'];
//* only change postfix config if rspamd is active filter
if($mail_server && $mail_config['content_filter'] === 'rspamd') {
exec("postconf -X receive_override_options");
exec("postconf -X content_filter");
exec("postconf -X address_verify_virtual_transport");
exec("postconf -X address_verify_transport_maps");
exec("postconf -e 'smtpd_milters = inet:localhost:11332'");
exec("postconf -e 'non_smtpd_milters = inet:localhost:11332'");
exec("postconf -e 'milter_protocol = 6'");
exec("postconf -e 'milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}'");
exec("postconf -e 'milter_default_action = accept'");
if(! isset($mail_config['reject_sender_login_mismatch'])) {
$mail_config['reject_sender_login_mismatch'] = 'n';
}
$options = preg_split("/,\s*/", exec("postconf -h smtpd_sender_restrictions"));
$new_options = array();
foreach ($options as $key => $value) {
$value = trim($value);
if ($value == '') continue;
if (preg_match('/tag_as_(originating|foreign)\.re/', $value)) {
continue;
}
if (preg_match('/reject_(authenticated_)?sender_login_mismatch/', $value)) {
continue;
}
$new_options[] = $value;
}
if ($mail_config['reject_sender_login_mismatch'] == 'y') {
// insert before permit_mynetworks
for ($i = 0; isset($new_options[$i]); $i++) {
if ($new_options[$i] == 'permit_mynetworks') {
array_splice($new_options, $i, 0, array('reject_authenticated_sender_login_mismatch'));
break;
}
}
// insert before permit_sasl_authenticated
for ($i = 0; isset($new_options[$i]); $i++) {
if ($new_options[$i] == 'permit_sasl_authenticated') {
array_splice($new_options, $i, 0, array('reject_sender_login_mismatch'));
break;
}
}
}
exec("postconf -e 'smtpd_sender_restrictions = ".implode(", ", $new_options)."'");
$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_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)) {
continue;
}
$new_options[] = $value;
}
exec("postconf -e 'smtpd_recipient_restrictions = ".implode(", ", $new_options)."'");
}
if(is_user('_rspamd') && is_group('amavis')) {
exec("usermod -a -G amavis _rspamd");
} elseif(is_user('rspamd') && is_group('amavis')) {
exec("usermod -a -G amavis rspamd");
}
if(!is_dir('/etc/rspamd/local.d/')){
mkdir('/etc/rspamd/local.d/', 0755, true);
chmod('/etc/rspamd/local.d/', 0755);
}
if(!is_dir('/etc/rspamd/local.d/maps.d/')){
mkdir('/etc/rspamd/local.d/maps.d/', 0755, true);
chmod('/etc/rspamd/local.d/maps.d/', 0755);
}
if(!is_dir('/etc/rspamd/override.d/')){
mkdir('/etc/rspamd/override.d/', 0755, true);
chmod('/etc/rspamd/override.d/', 0755);
}
if ( substr($mail_config['dkim_path'], strlen($mail_config['dkim_path'])-1) == '/' ) {
$mail_config['dkim_path'] = substr($mail_config['dkim_path'], 0, strlen($mail_config['dkim_path'])-1);
}
$dkim_domains = $this->db->queryAllRecords('SELECT `dkim_selector`, `domain` FROM ?? WHERE `dkim` = ? ORDER BY `domain` ASC', $conf['mysql']['database'] . '.mail_domain', 'y');
# should move maps to local.d/maps.d/ ?
$fpp = fopen('/etc/rspamd/local.d/dkim_domains.map', 'w');
$fps = fopen('/etc/rspamd/local.d/dkim_selectors.map', 'w');
foreach($dkim_domains as $dkim_domain) {
fwrite($fpp, $dkim_domain['domain'] . ' ' . $mail_config['dkim_path'] . '/' . $dkim_domain['domain'] . '.private' . "\n");
fwrite($fps, $dkim_domain['domain'] . ' ' . $dkim_domain['dkim_selector'] . "\n");
}
fclose($fpp);
fclose($fps);
unset($dkim_domains);
# look up values for use in template tags
$local_addrs = array();
$ips = $this->db->queryAllRecords('SELECT `ip_address`, `ip_type` FROM ?? WHERE `server_id` = ?', $conf['mysql']['database'].'.server_ip', $conf['server_id']);
if(is_array($ips) && !empty($ips)){
foreach($ips as $ip){
$local_addrs[] = array(
'ip' => $ip['ip_address'],
'quoted_ip' => "\"".$ip['ip_address']."\",\n"
);
}
}
# local.d templates with template tags
# note: ensure these template files are in server/conf/ and symlinked in install/tpl/
$local_d = array(
'dkim_signing.conf', # dkim_signing.conf no longer uses template tags, could move below
'options.inc',
'redis.conf',
'classifier-bayes.conf',
);
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");
} else {
$tpl->newTemplate("rspamd_{$f}.master");
}
$tpl->setVar('dkim_path', $mail_config['dkim_path']);
$tpl->setVar('rspamd_redis_servers', (isset($mail_config['rspamd_redis_servers']) ? $mail_config['rspamd_redis_servers'] : ''));
$tpl->setVar('rspamd_redis_password', (isset($mail_config['rspamd_redis_password']) ? $mail_config['rspamd_redis_password'] : ''));
$tpl->setVar('rspamd_redis_bayes_servers', (isset($mail_config['rspamd_redis_bayes_servers']) ? $mail_config['rspamd_redis_bayes_servers'] : ''));
$tpl->setVar('rspamd_redis_bayes_password', (isset($mail_config['rspamd_redis_bayes_password']) ? $mail_config['rspamd_redis_bayes_password'] : ''));
if(count($local_addrs) > 0) {
$tpl->setLoop('local_addrs', $local_addrs);
}
wf("/etc/rspamd/local.d/{$f}", $tpl->grab());
}
# local.d templates without template tags
$local_d = array(
'groups.conf',
'antivirus.conf',
'mx_check.conf',
'milter_headers.conf',
'neural.conf',
'neural_group.conf',
'users.conf',
'groups.conf',
'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}");
} else {
exec("cp tpl/rspamd_{$f}.master /etc/rspamd/local.d/{$f}");
}
}
# override.d templates without template tags
$override_d = array(
'rbl_group.conf',
'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}");
} else {
exec("cp tpl/rspamd_{$f}.master /etc/rspamd/override.d/{$f}");
}
}
# local.d/maps.d templates without template tags
$maps_d = array(
'dkim_whitelist.inc.ispc',
'dmarc_whitelist.inc.ispc',
'spf_dkim_whitelist.inc.ispc',
'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}");
} else {
exec("cp tpl/rspamd_{$f}.master /etc/rspamd/local.d/maps.d/{$f}");
}
}
# rename rspamd templates we no longer use
if(file_exists("/etc/rspamd/local.d/greylist.conf")) {
rename("/etc/rspamd/local.d/greylist.conf", "/etc/rspamd/local.d/greylist.old");
}
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');
if(file_exists('/etc/rspamd/local.d/worker-controller.inc')) {
exec('chgrp _rspamd /etc/rspamd/local.d/worker-controller.inc');
exec('chmod 640 /etc/rspamd/local.d/worker-controller.inc');
}
# unneccesary, since this was done above?
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"');
}
if(!isset($mail_config['rspamd_password']) || !$mail_config['rspamd_password']) {
$mail_config['rspamd_password'] = str_shuffle(bin2hex(openssl_random_pseudo_bytes(12)));
$server_ini_array['mail']['rspamd_password'] = $mail_config['rspamd_password'];
}
$server_ini_array['mail']['rspamd_available'] = 'y';
$server_ini_string = array_to_ini($server_ini_array);
if($this->dbmaster != $this->db) {
$this->dbmaster->query('UPDATE `server` SET `config` = ? WHERE `server_id` = ?', $server_ini_string, $conf['server_id']);
}
$this->db->query('UPDATE `server` SET `config` = ? WHERE `server_id` = ?', $server_ini_string, $conf['server_id']);
unset($server_ini_array);
unset($server_ini_string);
$tpl = new tpl();
if (file_exists($conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_worker-controller.inc.master")) {
$tpl->newTemplate($conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_worker-controller.inc.master");
} else {
$tpl->newTemplate("rspamd_worker-controller.inc.master");
}
$rspamd_password = $mail_config['rspamd_password'];
$crypted_password = trim(exec('rspamadm pw -p ' . escapeshellarg($rspamd_password)));
if($crypted_password) {
$rspamd_password = $crypted_password;
}
$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() {
......@@ -1477,17 +2220,17 @@ class installer_base {
}
//* Create the ISPConfig database user in the local database
$query = "GRANT ALL ON ?? TO ?@'localhost'";
if(!$this->db->query($query, $conf['powerdns']['database'] . '.*', $conf['mysql']['ispconfig_user'])) {
$query = "GRANT ALL ON ??.* TO ?@?";
if(!$this->db->query($query, $conf['powerdns']['database'], $conf['mysql']['ispconfig_user'], 'localhost')) {
$this->error('Unable to create user for powerdns database Error: '.$this->db->errorMessage);
}
//* load the powerdns databse dump
if($conf['mysql']['admin_password'] == '') {
caselog("mysql --default-character-set=".$conf['mysql']['charset']." -h '".$conf['mysql']['host']."' -u '".$conf['mysql']['admin_user']."' '".$conf['powerdns']['database']."' < '".ISPC_INSTALL_ROOT."/install/sql/powerdns.sql' &> /dev/null",
caselog("mysql --default-character-set=".$conf['mysql']['charset']." -h '".$conf['mysql']['host']."' -u '".$conf['mysql']['admin_user']."' --force '".$conf['powerdns']['database']."' < '".ISPC_INSTALL_ROOT."/install/sql/powerdns.sql' &> /dev/null",
__FILE__, __LINE__, 'read in ispconfig3.sql', 'could not read in powerdns.sql');
} else {
caselog("mysql --default-character-set=".$conf['mysql']['charset']." -h '".$conf['mysql']['host']."' -u '".$conf['mysql']['admin_user']."' -p'".$conf['mysql']['admin_password']."' '".$conf['powerdns']['database']."' < '".ISPC_INSTALL_ROOT."/install/sql/powerdns.sql' &> /dev/null",
caselog("mysql --default-character-set=".$conf['mysql']['charset']." -h '".$conf['mysql']['host']."' -u '".$conf['mysql']['admin_user']."' -p'".$conf['mysql']['admin_password']."' --force '".$conf['powerdns']['database']."' < '".ISPC_INSTALL_ROOT."/install/sql/powerdns.sql' &> /dev/null",
__FILE__, __LINE__, 'read in ispconfig3.sql', 'could not read in powerdns.sql');
}
......@@ -1508,17 +2251,17 @@ class installer_base {
}
//** writes bind configuration files
public function process_bind_file($configfile, $target='/', $absolute=false) {
global $conf;
if ($absolute) $full_file_name = $target.$configfile;
else $full_file_name = $conf['ispconfig_install_dir'].$target.$configfile;
//* Backup exiting file
if(is_file($full_file_name)) {
copy($full_file_name, $config_dir.$configfile.'~');
copy($full_file_name, $full_file_name.'~');
}
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master');
$content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content);
......@@ -1547,7 +2290,7 @@ class installer_base {
chown($content, $conf['bind']['bind_user']);
chgrp($content, $conf['bind']['bind_group']);
chmod($content, 02770);
//* Install scripts for dnssec implementation
$this->process_bind_file('named.conf.options', '/etc/bind/', true); //TODO replace hardcoded path
}
......@@ -1583,6 +2326,7 @@ class installer_base {
// Copy isp libs
if(!@is_dir('/usr/lib/metronome/isp-modules')) mkdir('/usr/lib/metronome/isp-modules', 0755, true);
caselog('cp -rf apps/metronome_libs/* /usr/lib/metronome/isp-modules/', __FILE__, __LINE__);
caselog('chmod 755 /usr/lib/metronome/isp-modules/mod_auth_external/authenticate_isp.sh', __FILE__, __LINE__);
// Process db config
$full_file_name = '/usr/lib/metronome/isp-modules/mod_auth_external/db_conf.inc.php';
$content = rf($full_file_name);
......@@ -1595,13 +2339,14 @@ class installer_base {
if(!stristr($options, 'dont-create-certs')){
// Create SSL Certificate for localhost
echo "writing new private key to 'localhost.key'\n-----\n";
$ssl_country = $this->free_query('Country Name (2 letter code)', 'AU');
$ssl_locality = $this->free_query('Locality Name (eg, city)', '');
$ssl_organisation = $this->free_query('Organization Name (eg, company)', 'Internet Widgits Pty Ltd');
$ssl_organisation_unit = $this->free_query('Organizational Unit Name (eg, section)', '');
$ssl_domain = $this->free_query('Common Name (e.g. server FQDN or YOUR name)', $conf['hostname']);
$ssl_email = $this->free_query('Email Address', '');
// Ensure no line is left blank
echo "writing new private key to 'localhost.key'\n-----\n";
$ssl_country = $this->free_query('Country Name (2 letter code)', 'AU','ssl_cert_country');
$ssl_locality = $this->free_query('Locality Name (eg, city)', 'City Name','ssl_cert_locality');
$ssl_organisation = $this->free_query('Organization Name (eg, company)', 'Internet Widgits Pty Ltd','ssl_cert_organisation');
$ssl_organisation_unit = $this->free_query('Organizational Unit Name (eg, section)', 'Infrastructure','ssl_cert_organisation_unit');
$ssl_domain = $this->free_query('Common Name (e.g. server FQDN or YOUR name)', $conf['hostname'],'ssl_cert_common_name');
$ssl_email = $this->free_query('Email Address', 'hostmaster@'.$conf['hostname'],'ssl_cert_email');
$tpl = new tpl('metronome_conf_ssl.master');
$tpl->setVar('ssl_country',$ssl_country);
......@@ -1618,11 +2363,21 @@ class installer_base {
exec("(cd /etc/metronome/certs && make localhost.cert)");
exec('chmod 0400 /etc/metronome/certs/localhost.key');
exec('chown metronome /etc/metronome/certs/localhost.key');
echo "IMPORTANT:\n";
echo "Localhost Key, Csr and a self-signed Cert have been saved to /etc/metronome/certs\n";
echo "In order to work with all clients, the server must have a trusted certificate, so use the Csr\n";
echo "to get a trusted certificate from your CA or replace Key and Cert with already signed files for\n";
echo "your domain. Clients like Pidgin dont allow to use untrusted self-signed certificates.\n";
echo "\n";
}else{
echo "-----\n";
/*
echo "-----\n";
echo "Metronome XMPP SSL server certificate is not renewed. Run the following command manual as root to recreate it:\n";
echo "# (cd /etc/metronome/certs && make localhost.key && make localhost.csr && make localhost.cert && chmod 0400 localhost.key && chown metronome localhost.key)\n";
echo "-----\n";
*/
}
// Copy init script
......@@ -1631,45 +2386,6 @@ class installer_base {
caselog('update-rc.d metronome defaults', __FILE__, __LINE__);
exec($this->getinitcommand($conf['xmpp']['init_script'], 'restart'));
/*
writing new private key to 'smtpd.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:
* */
/*// Dont just copy over the virtualhost template but add some custom settings
$tpl = new tpl('apache_apps.vhost.master');
$tpl->setVar('apps_vhost_port',$conf['web']['apps_vhost_port']);
$tpl->setVar('apps_vhost_dir',$conf['web']['website_basedir'].'/apps');
$tpl->setVar('apps_vhost_basedir',$conf['web']['website_basedir']);
$tpl->setVar('apps_vhost_servername',$apps_vhost_servername);
$tpl->setVar('apache_version',getapacheversion());
// comment out the listen directive if port is 80 or 443
if($conf['web']['apps_vhost_ip'] == 80 or $conf['web']['apps_vhost_ip'] == 443) {
$tpl->setVar('vhost_port_listen','#');
} else {
$tpl->setVar('vhost_port_listen','');
}
wf($vhost_conf_dir.'/apps.vhost', $tpl->grab());
unset($tpl);*/
}
......@@ -1681,9 +2397,9 @@ Email Address []:
if(!@is_dir($conf['ispconfig_log_dir'].'/httpd')) mkdir($conf['ispconfig_log_dir'].'/httpd', 0755, true);
if(is_file('/etc/suphp/suphp.conf')) {
replaceLine('/etc/suphp/suphp.conf', 'php=php:/usr/bin', 'x-httpd-suphp="php:/usr/bin/php-cgi"', 0);
replaceLine('/etc/suphp/suphp.conf', 'php="php:/usr/bin', 'x-httpd-suphp="php:/usr/bin/php-cgi"', 0);
//replaceLine('/etc/suphp/suphp.conf','docroot=','docroot=/var/clients',0);
replaceLine('/etc/suphp/suphp.conf', 'umask=0077', 'umask=0022', 0);
replaceLine('/etc/suphp/suphp.conf', 'umask=00', 'umask=0022', 0);
}
if(is_file('/etc/apache2/sites-enabled/000-default')) {
......@@ -1694,15 +2410,19 @@ Email Address []:
if(is_file('/etc/apache2/ports.conf')) {
// add a line "Listen 443" to ports conf if line does not exist
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')) {
......@@ -1714,7 +2434,7 @@ Email Address []:
}
}
}
if(is_file('/etc/apache2/apache2.conf')) {
if(hasLine('/etc/apache2/apache2.conf', 'Include sites-enabled/', 1) == false && hasLine('/etc/apache2/apache2.conf', 'IncludeOptional sites-enabled/', 1) == false) {
if(hasLine('/etc/apache2/apache2.conf', 'Include sites-enabled/*.conf', 1) == true) {
......@@ -1731,10 +2451,16 @@ Email Address []:
$tpl = new tpl('apache_ispconfig.conf.master');
$tpl->setVar('apache_version',getapacheversion());
if($this->is_update == true) {
$tpl->setVar('logging',get_logging_state());
} else {
$tpl->setVar('logging','yes');
}
$records = $this->db->queryAllRecords("SELECT * FROM ?? WHERE server_id = ? AND virtualhost = 'y'", $conf['mysql']['master_database'] . '.server_ip', $conf['server_id']);
$ip_addresses = array();
if(is_array($records) && count($records) > 0) {
foreach($records as $rec) {
if($rec['ip_type'] == 'IPv6') {
......@@ -1753,9 +2479,9 @@ Email Address []:
}
}
}
if(count($ip_addresses) > 0) $tpl->setLoop('ip_adresses',$ip_addresses);
wf($vhost_conf_dir.'/ispconfig.conf', $tpl->grab());
unset($tpl);
......@@ -1815,6 +2541,17 @@ Email Address []:
//* add a sshusers group
$command = 'groupadd sshusers';
if(!is_group('sshusers')) caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
// add anonymized log option to nginxx.conf file
$nginx_conf_file = $conf['nginx']['config_dir'].'/nginx.conf';
if(is_file($nginx_conf_file)) {
$tmp = file_get_contents($nginx_conf_file);
if(!stristr($tmp, 'log_format anonymized')) {
copy($nginx_conf_file,$nginx_conf_file.'~');
replaceLine($nginx_conf_file, 'http {', "http {\n\n".file_get_contents('tpl/nginx_anonlog.master'), 0, 0);
}
}
}
public function configure_fail2ban() {
......@@ -1840,6 +2577,13 @@ Email Address []:
exec('chown root:root '.$conf["squid"]["config_dir"].'/'.$configfile);
}
public function configure_apparmor() {
$configfile = 'apparmor_usr.sbin.named';
if(is_file('/etc/apparmor.d/local/usr.sbin.named')) copy('/etc/apparmor.d/local/usr.sbin.named', '/etc/apparmor.d/local/usr.sbin.named~');
$content = rf("tpl/".$configfile.".master");
wf('/etc/apparmor.d/local/usr.sbin.named', $content);
}
public function configure_ufw_firewall()
{
if($this->is_update == false) {
......@@ -1875,17 +2619,20 @@ Email Address []:
$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);
......@@ -1960,7 +2707,7 @@ Email Address []:
//$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);
......@@ -1974,7 +2721,7 @@ Email Address []:
$vhost_conf_dir = $conf['apache']['vhost_conf_dir'];
$vhost_conf_enabled_dir = $conf['apache']['vhost_conf_enabled_dir'];
$apps_vhost_servername = ($conf['web']['apps_vhost_servername'] == '')?'':'ServerName '.$conf['web']['apps_vhost_servername'];
//* Get the apps vhost port
if($this->is_update == true) {
$conf['web']['apps_vhost_port'] = get_apps_vhost_port_number();
......@@ -1987,11 +2734,29 @@ Email Address []:
$tpl->setVar('apps_vhost_dir',$conf['web']['website_basedir'].'/apps');
$tpl->setVar('apps_vhost_basedir',$conf['web']['website_basedir']);
$tpl->setVar('apps_vhost_servername',$apps_vhost_servername);
if(is_file($conf['ispconfig_install_dir'].'/interface/ssl/ispserver.crt') && is_file($conf['ispconfig_install_dir'].'/interface/ssl/ispserver.key')) {
$tpl->setVar('ssl_comment','');
} else {
$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')) {
$tpl->setVar('ssl_bundle_comment','');
} else {
$tpl->setVar('ssl_bundle_comment','#');
}
$tpl->setVar('apache_version',getapacheversion());
if($this->is_update == true) {
$tpl->setVar('logging',get_logging_state());
} else {
$tpl->setVar('logging','yes');
}
if($conf['rspamd']['installed'] == true) {
$tpl->setVar('use_rspamd', 'yes');
}
// comment out the listen directive if port is 80 or 443
if($conf['web']['apps_vhost_ip'] == 80 or $conf['web']['apps_vhost_ip'] == 443) {
if($conf['web']['apps_vhost_port'] == 80 or $conf['web']['apps_vhost_port'] == 443) {
$tpl->setVar('vhost_port_listen','#');
} else {
$tpl->setVar('vhost_port_listen','');
......@@ -2003,8 +2768,8 @@ Email Address []:
//copy('tpl/apache_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')) {
symlink($vhost_conf_dir.'/apps.vhost', $vhost_conf_enabled_dir.'/000-apps.vhost');
if(!@is_link($vhost_conf_enabled_dir.'/000-apps.vhost') && @is_file($vhost_conf_dir.'/apps.vhost')) {
@symlink($vhost_conf_dir.'/apps.vhost', $vhost_conf_enabled_dir.'/000-apps.vhost');
}
if(!is_file($conf['web']['website_basedir'].'/php-fcgi-scripts/apps/.php-fcgi-starter')) {
......@@ -2012,11 +2777,12 @@ Email Address []:
$content = str_replace('{fastcgi_bin}', $conf['fastcgi']['fastcgi_bin'], $content);
$content = str_replace('{fastcgi_phpini_path}', $conf['fastcgi']['fastcgi_phpini_path'], $content);
mkdir($conf['web']['website_basedir'].'/php-fcgi-scripts/apps', 0755, true);
$this->set_immutable($conf['web']['website_basedir'].'/php-fcgi-scripts/apps/.php-fcgi-starter', false);
//copy('tpl/apache_apps_fcgi_starter.master',$conf['web']['website_basedir'].'/php-fcgi-scripts/apps/.php-fcgi-starter');
wf($conf['web']['website_basedir'].'/php-fcgi-scripts/apps/.php-fcgi-starter', $content);
exec('chmod +x '.$conf['web']['website_basedir'].'/php-fcgi-scripts/apps/.php-fcgi-starter');
exec('chown -R ispapps:ispapps '.$conf['web']['website_basedir'].'/php-fcgi-scripts/apps');
$this->set_immutable($conf['web']['website_basedir'].'/php-fcgi-scripts/apps/.php-fcgi-starter', true);
}
}
if($conf['nginx']['installed'] == true){
......@@ -2024,6 +2790,11 @@ Email Address []:
$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");
......@@ -2033,7 +2804,7 @@ Email Address []:
//$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);
......@@ -2051,12 +2822,27 @@ Email Address []:
// Dont just copy over the virtualhost template but add some custom settings
$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/nginx_apps.vhost.master', 'tpl/nginx_apps.vhost.master');
// Enable SSL if a cert is in place.
if(is_file($conf['ispconfig_install_dir'].'/interface/ssl/ispserver.crt') && is_file($conf['ispconfig_install_dir'].'/interface/ssl/ispserver.key')) {
$content = str_replace('{ssl_on}', 'ssl http2', $content);
$content = str_replace('{ssl_comment}', '', $content);
} else {
$content = str_replace('{ssl_on}', '', $content);
$content = str_replace('{ssl_comment}', '#', $content);
}
if($conf['web']['apps_vhost_ip'] == '_default_'){
$apps_vhost_ip = '';
} else {
$apps_vhost_ip = $conf['web']['apps_vhost_ip'].':';
}
if($conf['rspamd']['installed'] == true) {
$content = str_replace('{use_rspamd}', '', $content);
} else {
$content = str_replace('{use_rspamd}', '# ', $content);
}
$socket_dir = escapeshellcmd($conf['nginx']['php_fpm_socket_dir']);
if(substr($socket_dir, -1) != '/') $socket_dir .= '/';
if(!is_dir($socket_dir)) exec('mkdir -p '.$socket_dir);
......@@ -2071,7 +2857,13 @@ Email Address []:
$content = str_replace('{fpm_socket}', $fpm_socket, $content);
$content = str_replace('{cgi_socket}', $cgi_socket, $content);
if(file_exists('/var/run/php5-fpm.sock')){
if( file_exists('/var/run/php5-fpm.sock')
|| file_exists('/var/run/php/php7.0-fpm.sock')
|| file_exists('/var/run/php/php7.1-fpm.sock')
|| file_exists('/var/run/php/php7.2-fpm.sock')
|| file_exists('/var/run/php/php7.3-fpm.sock')
|| file_exists('/var/run/php/php7.4-fpm.sock')
){
$use_tcp = '#';
$use_socket = '';
} else {
......@@ -2080,10 +2872,19 @@ Email Address []:
}
$content = str_replace('{use_tcp}', $use_tcp, $content);
$content = str_replace('{use_socket}', $use_socket, $content);
// SSL in apps vhost is off by default. Might change later.
$content = str_replace('{ssl_on}', 'off', $content);
$content = str_replace('{ssl_comment}', '#', $content);
// Fix socket path on PHP 7 systems
if (file_exists('/var/run/php/php7.4-fpm.sock')) {
$content = str_replace('/var/run/php5-fpm.sock', '/var/run/php/php7.4-fpm.sock', $content);
} elseif(file_exists('/var/run/php/php7.3-fpm.sock')) {
$content = str_replace('/var/run/php5-fpm.sock', '/var/run/php/php7.3-fpm.sock', $content);
} elseif (file_exists('/var/run/php/php7.2-fpm.sock')) {
$content = str_replace('/var/run/php5-fpm.sock', '/var/run/php/php7.2-fpm.sock', $content);
} elseif (file_exists('/var/run/php/php7.1-fpm.sock')) {
$content = str_replace('/var/run/php5-fpm.sock', '/var/run/php/php7.1-fpm.sock', $content);
} elseif (file_exists('/var/run/php/php7.0-fpm.sock')) {
$content = str_replace('/var/run/php5-fpm.sock', '/var/run/php/php7.0-fpm.sock', $content);
}
wf($vhost_conf_dir.'/apps.vhost', $content);
......@@ -2103,35 +2904,540 @@ Email Address []:
if(!@is_link($vhost_conf_enabled_dir.'/000-apps.vhost')) {
symlink($vhost_conf_dir.'/apps.vhost', $vhost_conf_enabled_dir.'/000-apps.vhost');
}
}
}
private function curl_request($url, $use_ipv6 = false) {
$set_headers = [
'Connection: Close',
'User-Agent: ISPConfig/3',
'Accept: */*'
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_HTTPHEADER, $set_headers);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
if($use_ipv6) {
if(defined('CURLOPT_IPRESOLVE') && defined('CURL_IPRESOLVE_V6')) {
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6);
}
} else {
if(defined('CURLOPT_IPRESOLVE') && defined('CURL_IPRESOLVE_V4')) {
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
}
}
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
public function make_acme_vhost($server = 'apache') {
global $conf;
if($conf['hostname'] !== 'localhost' && $conf['hostname'] !== '') {
$server_name = $conf['hostname'];
} else {
$server_name = exec('hostname -f');
}
$use_template = 'apache_acme.conf.master';
$use_symlink = '999-acme.conf';
$use_name = 'acme.conf';
if($server === 'nginx') {
$use_template = 'nginx_acme.vhost.master';
$use_symlink = '999-acme.vhost';
$use_name = 'acme.vhost';
}
$vhost_conf_dir = $conf[$server]['vhost_conf_dir'];
$vhost_conf_enabled_dir = $conf[$server]['vhost_conf_enabled_dir'];
$tpl = new tpl($use_template);
$tpl->setVar('domain', $server_name);
if($server !== 'nginx') {
$tpl->setVar('apache_version',getapacheversion());
}
$acme_dir = $conf['ispconfig_install_dir'] . '/interface/acme';
//* Create the ISPConfig installation directory
if(!@is_dir($acme_dir)) {
$command = "mkdir -p $acme_dir";
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
}
wf($vhost_conf_dir.'/' . $use_name, $tpl->grab());
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)) {
symlink($vhost_conf_dir.'/' . $use_name, $vhost_conf_enabled_dir.'/' . $use_symlink);
}
}
public function make_ispconfig_ssl_cert() {
global $conf,$autoinstall;
global $conf, $autoinstall;
$install_dir = $conf['ispconfig_install_dir'];
//* Get hostname from user entry or shell command */
if($conf['hostname'] !== 'localhost' && $conf['hostname'] !== '') {
$hostname = $conf['hostname'];
} else {
$hostname = exec('hostname -f');
}
// Check dns a record exist and its ip equal to server public ip
$svr_ip4 = $this->curl_request('https://ispconfig.org/remoteip.php', false);
$svr_ip6 = $this->curl_request('https://ispconfig.org/remoteip.php', true);
if(function_exists('idn_to_ascii')) {
if(defined('IDNA_NONTRANSITIONAL_TO_ASCII') && defined('INTL_IDNA_VARIANT_UTS46') && constant('IDNA_NONTRANSITIONAL_TO_ASCII')) {
$hostname = idn_to_ascii($hostname, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
} else {
$hostname = idn_to_ascii($hostname);
}
}
$dns_ips = array();
if(checkdnsrr($hostname, 'A')) {
$dnsa = dns_get_record($hostname, DNS_A);
if($dnsa) {
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($dnsaaaa) {
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';
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';
$date = new DateTime();
// Request for certs if no LE SSL folder for server fqdn exist
swriteln('Checking / creating certificate for ' . $hostname);
// 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 = '';
}
}
$ssl_crt_file = $install_dir.'/interface/ssl/ispserver.crt';
$ssl_csr_file = $install_dir.'/interface/ssl/ispserver.csr';
$ssl_key_file = $install_dir.'/interface/ssl/ispserver.key';
// 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';
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.');
}
if(!@is_dir($install_dir.'/interface/ssl')) mkdir($install_dir.'/interface/ssl', 0755, true);
if(!is_dir($conf['ispconfig_log_dir'])) {
mkdir($conf['ispconfig_log_dir'], 0755, true);
}
$acme_log = $conf['ispconfig_log_dir'] . '/acme.log';
$ssl_pw = substr(md5(mt_rand()), 0, 6);
exec("openssl genrsa -des3 -passout pass:$ssl_pw -out $ssl_key_file 4096");
if(AUTOINSTALL){
exec("openssl req -new -passin pass:$ssl_pw -passout pass:$ssl_pw -subj '/C=".escapeshellcmd($autoinstall['ssl_cert_country'])."/ST=".escapeshellcmd($autoinstall['ssl_cert_state'])."/L=".escapeshellcmd($autoinstall['ssl_cert_locality'])."/O=".escapeshellcmd($autoinstall['ssl_cert_organisation'])."/OU=".escapeshellcmd($autoinstall['ssl_cert_organisation_unit'])."/CN=".escapeshellcmd($autoinstall['ssl_cert_common_name'])."' -key $ssl_key_file -out $ssl_csr_file");
$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) (' . 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 {
exec("openssl req -new -passin pass:$ssl_pw -passout pass:$ssl_pw -key $ssl_key_file -out $ssl_csr_file");
$ip_address_match = true;
}
exec("openssl req -x509 -passin pass:$ssl_pw -passout pass:$ssl_pw -key $ssl_key_file -in $ssl_csr_file -out $ssl_crt_file -days 3650");
exec("openssl rsa -passin pass:$ssl_pw -in $ssl_key_file -out $ssl_key_file.insecure");
rename($ssl_key_file, $ssl_key_file.'.secure');
rename($ssl_key_file.'.insecure', $ssl_key_file);
exec('chown -R root:root /usr/local/ispconfig/interface/ssl');
// Get subject and issuer of ispserver.crt to check if it is self-signed cert
$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.');
}
}
$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
if(file_exists(ISPC_INSTALL_ROOT . '/server/scripts/letsencrypt_pre_hook.sh') && !file_exists('/usr/local/bin/letsencrypt_pre_hook.sh')) {
if(is_link('/usr/local/bin/letsencrypt_pre_hook.sh')) {
unlink('/usr/local/bin/letsencrypt_pre_hook.sh');
}
symlink(ISPC_INSTALL_ROOT . '/server/scripts/letsencrypt_pre_hook.sh', '/usr/local/bin/letsencrypt_pre_hook.sh');
chown('/usr/local/bin/letsencrypt_pre_hook.sh', 'root');
chmod('/usr/local/bin/letsencrypt_pre_hook.sh', 0700);
}
if(file_exists(ISPC_INSTALL_ROOT . '/server/scripts/letsencrypt_post_hook.sh') && !file_exists('/usr/local/bin/letsencrypt_post_hook.sh')) {
if(is_link('/usr/local/bin/letsencrypt_post_hook.sh')) {
unlink('/usr/local/bin/letsencrypt_post_hook.sh');
}
symlink(ISPC_INSTALL_ROOT . '/server/scripts/letsencrypt_post_hook.sh', '/usr/local/bin/letsencrypt_post_hook.sh');
chown('/usr/local/bin/letsencrypt_post_hook.sh', 'root');
chmod('/usr/local/bin/letsencrypt_post_hook.sh', 0700);
}
if(file_exists(ISPC_INSTALL_ROOT . '/server/scripts/letsencrypt_renew_hook.sh') && !file_exists('/usr/local/bin/letsencrypt_renew_hook.sh')) {
if(is_link('/usr/local/bin/letsencrypt_renew_hook.sh')) {
unlink('/usr/local/bin/letsencrypt_renew_hook.sh');
}
symlink(ISPC_INSTALL_ROOT . '/server/scripts/letsencrypt_renew_hook.sh', '/usr/local/bin/letsencrypt_renew_hook.sh');
chown('/usr/local/bin/letsencrypt_renew_hook.sh', 'root');
chmod('/usr/local/bin/letsencrypt_renew_hook.sh', 0700);
}
// Check http port 80 status (open when any IP listens on port 80) as it cannot be determined at post hook stage
$port80_status = exec('netstat -tln | awk \'BEGIN{open=0} $6 == "LISTEN" && $4~/:80$/{open=1} END{if (open>0) print "open"; else print "close";}\'');
// 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"';
$hook = $pre_hook . $post_hook . $renew_hook;
} else {
$hook = $pre_hook . $renew_hook;
}
$restore_conf_symlink = false;
// we only need this for apache, so use fixed conf index
$vhost_conf_dir = $conf['apache']['vhost_conf_dir'];
$vhost_conf_enabled_dir = $conf['apache']['vhost_conf_enabled_dir'];
// first of all create the acme vhosts if not existing
if($conf['nginx']['installed'] == true) {
swriteln('Using nginx for certificate validation');
$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')) {
$restore_conf_symlink = true;
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');
} else {
system($this->getinitcommand($conf[$server]['init_script'], 'restart') . ' &> /dev/null');
}
}
// Backup existing ispserver ssl files
//
// We may find valid or broken symlinks or actual files here.
//
// - dangling links are broken and get perm renamed (should just delete?).
// possibly web server can't start because vhost file points to non-existing cert files,
// we're not trying to catch or fix that (and not making it worse)
//
// - link to valid file is tmp renamed, and file copied to original name.
// if cert request is successful, remove the old symlink;
// if cert request fails, remove file copy and rename symlink to original name
//
// - 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);
} elseif(file_exists($f)) {
copy($f, $f . '-temporary.bak');
}
}
// Attempt to use Neilpang acme.sh first, as it is now the preferred LE client
if($acme) {
# acme.sh does not set umask, resulting in incorrect permissions (ispconfig issue #6015)
$old_umask = umask(0022);
// Switch from zerossl to letsencrypt CA
exec("$acme --set-default-ca --server letsencrypt");
$out = null;
$ret = null;
if($conf['nginx']['installed'] == true || $conf['apache']['installed'] == true) {
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
$check_acme_file = $ssl_crt_file;
// Define LE certs name and path, then install them
//$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) . " --ecc $acme_key $acme_chain");
$issued_successfully = true;
} else {
swriteln('Issuing certificate via acme.sh failed. Please check that your hostname can be verified by letsencrypt');
}
// Else, we attempt to use the official LE certbot client certbot
} else {
$out = null;
$ret = null;
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("$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);
}
if($ret == 0 && is_dir($acme_cert_dir)) {
// certbot returns with 0 on issue for already existing certificate
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('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($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
$issued_successfully = true;
}
}
// If the LE SSL certs for this hostname exists
if(!is_dir($acme_cert_dir) || !file_exists($check_acme_file) || !$issued_successfully) {
if(!$issued_successfully) {
swriteln('Could not issue letsencrypt certificate, falling back to self-signed.');
} else {
swriteln('Issuing certificate seems to have succeeded but ' . $check_acme_file . ' seems to be missing. Falling back to self-signed.');
}
// 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) {
$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);
}
// Build ispserver.pem file and chmod it
if(file_exists($ssl_key_file)) {
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') {
// Define folder, file(s)
$cf = $conf['postfix'];
$postfix_dir = $cf['config_dir'];
if(!is_dir($postfix_dir)) $this->error("The Postfix configuration directory '$postfix_dir' does not exist.");
$smtpd_crt = $postfix_dir . '/smtpd.cert';
$smtpd_key = $postfix_dir . '/smtpd.key';
// Backup existing postfix ssl files
if(file_exists($smtpd_crt)) rename($smtpd_crt, $smtpd_crt . '-' . $date->format('YmdHis') . '.bak');
if(file_exists($smtpd_key)) rename($smtpd_key, $smtpd_key . '-' . $date->format('YmdHis') . '.bak');
// Create symlink to ISPConfig SSL files
symlink($ssl_crt_file, $smtpd_crt);
symlink($ssl_key_file, $smtpd_key);
}
// Extend LE SSL certs to pureftpd
if($conf['pureftpd']['installed'] == true && strtolower($this->simple_query('Symlink ISPConfig 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';
// Backup existing pureftpd ssl files
if(file_exists($pureftpd_pem)) rename($pureftpd_pem, $pureftpd_pem . '-' . $date->format('YmdHis') . '.bak');
// Create symlink to ISPConfig SSL files
symlink($ssl_pem_file, $pureftpd_pem);
if(!file_exists("$pureftpd_dir/pure-ftpd-dhparams.pem"))
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() {
......@@ -2159,31 +3465,20 @@ Email Address []:
//* copy the ISPConfig server part
$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
if(is_file('/usr/local/ispconfig/security/security_settings.ini')) copy('/usr/local/ispconfig/security/security_settings.ini','/usr/local/ispconfig/security/security_settings.ini~');
//* copy the ISPConfig security part
$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
......@@ -2318,9 +3613,9 @@ Email Address []:
$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;
$xmpp_server_enabled = ($conf['services']['xmpp'])?1:0;
$sql = "UPDATE `server` SET mail_server = '$mail_server_enabled', web_server = '$web_server_enabled', dns_server = '$dns_server_enabled', file_server = '$file_server_enabled', db_server = '$db_server_enabled', vserver_server = '$vserver_server_enabled', proxy_server = '$proxy_server_enabled', firewall_server = '$firewall_server_enabled', xmpp_server = '.$xmpp_server_enabled.' WHERE server_id = ?";
$sql = "UPDATE `server` SET mail_server = '$mail_server_enabled', web_server = '$web_server_enabled', dns_server = '$dns_server_enabled', file_server = '$file_server_enabled', db_server = '$db_server_enabled', vserver_server = '$vserver_server_enabled', proxy_server = '$proxy_server_enabled', firewall_server = '$firewall_server_enabled', xmpp_server = '$xmpp_server_enabled' WHERE server_id = ?";
$this->db->query($sql, $conf['server_id']);
if($conf['mysql']['master_slave_setup'] == 'y') {
......@@ -2341,15 +3636,19 @@ Email Address []:
//* chown the interface files to the ispconfig user and group
$command = 'chown -R ispconfig:ispconfig '.$install_dir.'/interface';
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");
//* chown the security files to the root user and group
$command = 'chown -R root:root '.$install_dir.'/security';
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
//* chown the security directory and security_settings.ini to root:ispconfig
$command = 'chown root:ispconfig '.$install_dir.'/security/security_settings.ini';
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
......@@ -2361,6 +3660,8 @@ Email Address []:
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
$command = 'chown root:ispconfig '.$install_dir.'/security/apache_directives.blacklist';
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
$command = 'chown root:ispconfig '.$install_dir.'/security/nginx_directives.blacklist';
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
//* Make the global language file directory group writable
exec("chmod -R 770 $install_dir/interface/lib/lang");
......@@ -2412,27 +3713,39 @@ Email Address []:
exec('chmod -R 770 '.escapeshellarg($install_dir.'/interface/invoices'));
exec('chown -R ispconfig:ispconfig '.escapeshellarg($install_dir.'/interface/invoices'));
}
exec('chown -R root:root /usr/local/ispconfig/interface/ssl');
// TODO: FIXME: add the www-data user to the ispconfig group. This is just for testing
// 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
......@@ -2440,8 +3753,8 @@ Email Address []:
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
if ($this->install_ispconfig_interface == true && isset($conf['interface_password']) && $conf['interface_password']!='admin') {
$sql = "UPDATE sys_user SET passwort = md5(?) WHERE username = 'admin';";
$this->db->query($sql, $conf['interface_password']);
$sql = "UPDATE sys_user SET passwort = ? WHERE username = 'admin';";
$this->db->query($sql, $this->crypt_password($conf['interface_password']));
}
if($conf['apache']['installed'] == true && $this->install_ispconfig_interface == true){
......@@ -2470,7 +3783,7 @@ Email Address []:
} else {
$tpl->setVar('ssl_bundle_comment','#');
}
$tpl->setVar('apache_version',getapacheversion());
wf($vhost_conf_dir.'/ispconfig.vhost', $tpl->grab());
......@@ -2487,10 +3800,12 @@ Email Address []:
$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);
//}
}
......@@ -2504,11 +3819,11 @@ Email Address []:
$content = str_replace('{vhost_port}', $conf['nginx']['vhost_port'], $content);
if(is_file($install_dir.'/interface/ssl/ispserver.crt') && is_file($install_dir.'/interface/ssl/ispserver.key')) {
$content = str_replace('{ssl_on}', 'on', $content);
$content = str_replace('{ssl_on}', 'ssl http2', $content);
$content = str_replace('{ssl_comment}', '', $content);
$content = str_replace('{fastcgi_ssl}', 'on', $content);
} else {
$content = str_replace('{ssl_on}', 'off', $content);
$content = str_replace('{ssl_on}', '', $content);
$content = str_replace('{ssl_comment}', '#', $content);
$content = str_replace('{fastcgi_ssl}', 'off', $content);
}
......@@ -2549,13 +3864,33 @@ Email Address []:
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');
// 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/mail.log')) exec('chmod +r /var/log/mail.log');
if(@is_file('/var/log/mail.warn')) exec('chmod +r /var/log/mail.warn');
......@@ -2569,6 +3904,7 @@ Email Address []:
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);
//* Create the ispconfig auth log file and set uid/gid
if(!is_file($conf['ispconfig_log_dir'].'/auth.log')) {
......@@ -2609,16 +3945,16 @@ Email Address []:
//* 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');
// Change mode of a few files from amavisd
if(is_file($conf['amavis']['config_dir'].'/conf.d/50-user')) chmod($conf['amavis']['config_dir'].'/conf.d/50-user', 0640);
if(is_file($conf['amavis']['config_dir'].'/50-user~')) chmod($conf['amavis']['config_dir'].'/50-user~', 0400);
......@@ -2657,7 +3993,7 @@ Email Address []:
$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
......@@ -2686,7 +4022,7 @@ Email Address []:
//* 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(
......@@ -2712,12 +4048,12 @@ Email Address []:
chmod($conf['ispconfig_log_dir'].'/cron.log', 0660);
}
public function create_mount_script(){
global $app, $conf;
$mount_script = '/usr/local/ispconfig/server/scripts/backup_dir_mount.sh';
$mount_command = '';
if(is_file($mount_script)) return;
if(is_file('/etc/rc.local')){
$rc_local = file('/etc/rc.local');
......@@ -2738,25 +4074,25 @@ Email Address []:
}
}
}
// This function is called at the end of the update process and contains code to clean up parts of old ISPCONfig releases
public function cleanup_ispconfig() {
global $app,$conf;
// Remove directories recursively
if(is_dir('/usr/local/ispconfig/interface/web/designer')) exec('rm -rf /usr/local/ispconfig/interface/web/designer');
if(is_dir('/usr/local/ispconfig/interface/web/themes/default-304')) exec('rm -rf /usr/local/ispconfig/interface/web/themes/default-304');
// Remove files
if(is_file('/usr/local/ispconfig/interface/lib/classes/db_firebird.inc.php')) unlink('/usr/local/ispconfig/interface/lib/classes/db_firebird.inc.php');
if(is_file('/usr/local/ispconfig/interface/lib/classes/form.inc.php')) unlink('/usr/local/ispconfig/interface/lib/classes/form.inc.php');
// Change mode of a few files from amavisd
if(is_file($conf['amavis']['config_dir'].'/conf.d/50-user')) chmod($conf['amavis']['config_dir'].'/conf.d/50-user', 0640);
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);
}
public function getinitcommand($servicename, $action, $init_script_directory = ''){
......@@ -2828,6 +4164,9 @@ Email Address []:
* @return bool
*/
protected function write_config_file($tConf, $tContents) {
$args = func_get_args();
// Backup config file before writing new contents and stat file
if ( is_file($tConf) ) {
$stat = exec('stat -c \'%a %U %G\' '.escapeshellarg($tConf), $output, $res);
......@@ -2841,10 +4180,9 @@ Email Address []:
}
wf($tConf, $tContents); // write file
if (func_num_args() >= 4) // override rights and/or ownership
{
$args = func_get_args();
$output = array_slice($args, 2);
switch (sizeof($output)) {
......@@ -2894,5 +4232,3 @@ Email Address []:
}
}
?>
......@@ -27,7 +27,7 @@
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
class db extends mysqli
class db
{
/**#@+
* @access private
......@@ -36,6 +36,7 @@ class db extends mysqli
private $_iConnId;
private $dbHost = ''; // hostname of the MySQL server
private $dbPort = ''; // port of the MySQL server
private $dbName = ''; // logical database name on that server
private $dbUser = ''; // database authorized user
private $dbPass = ''; // user's password
......@@ -63,26 +64,29 @@ class db extends mysqli
public function __destruct() {
if($this->_iConnId) mysqli_close($this->_iConnId);
}
private function do_connect() {
global $conf;
mysqli_report(MYSQLI_REPORT_OFF);
if($this->_iConnId) return true;
$this->dbHost = $conf["mysql"]["host"];
$this->dbHost = $conf['mysql']['host'];
$this->dbPort = $conf['mysql']['port'];
$this->dbName = false;//$conf["mysql"]["database"];
$this->dbUser = $conf["mysql"]["admin_user"];
$this->dbPass = $conf["mysql"]["admin_password"];
$this->dbCharset = $conf["mysql"]["charset"];
$this->dbNewLink = false;
$this->dbClientFlags = null;
$this->_iConnId = mysqli_connect($this->dbHost, $this->dbUser, $this->dbPass);
$this->_iConnId = mysqli_connect($this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort);
$try = 0;
while((!is_object($this->_iConnId) || mysqli_connect_error()) && $try < 5) {
if($try > 0) sleep(1);
$try++;
$this->_iConnId = mysqli_connect($this->dbHost, $this->dbUser, $this->dbPass);
$this->_iConnId = mysqli_connect($this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort);
}
if(!is_object($this->_iConnId) || mysqli_connect_error()) {
......@@ -90,28 +94,29 @@ class db extends mysqli
$this->_sqlerror('Zugriff auf Datenbankserver fehlgeschlagen! / Database server not accessible!');
return false;
}
if($this->dbName) $this->setDBName($this->dbName);
$this->_setCharset();
}
public function setDBData($host, $user, $password) {
public function setDBData($host, $user, $password, $port) {
$this->dbHost = $host;
$this->dbUser = $user;
$this->dbPass = $password;
$this->dbPort = $port;
}
public function setDBName($name) {
$this->dbName = $name;
$this->_iConnId = mysqli_connect($this->dbHost, $this->dbUser, $this->dbPass);
$this->_iConnId = mysqli_connect($this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort);
if(!((bool)mysqli_query( $this->_iConnId, 'USE `' . $this->dbName . '`'))) {
$this->close();
$this->_sqlerror('Datenbank nicht gefunden / Database not found');
return false;
}
}
public function close() {
if($this->_iConnId) mysqli_close($this->_iConnId);
$this->_iConnId = null;
......@@ -189,6 +194,8 @@ class db extends mysqli
}
private function _query($sQuery = '') {
$aArgs = func_get_args();
$this->do_connect();
if ($sQuery == '') {
......@@ -201,7 +208,7 @@ class db extends mysqli
$try++;
$ok = mysqli_ping($this->_iConnId);
if(!$ok) {
if(!mysqli_connect($this->dbHost, $this->dbUser, $this->dbPass, $this->dbName)) {
if(!mysqli_connect($this->dbHost, $this->dbUser, $this->dbPass, $this->dbName, (int)$this->dbPort)) {
if($this->errorNumber == '111') {
// server is not available
if($try > 9) {
......@@ -224,7 +231,6 @@ class db extends mysqli
}
} while($ok == false);
$aArgs = func_get_args();
$sQuery = call_user_func_array(array(&$this, '_build_query_string'), $aArgs);
$this->_iQueryId = mysqli_query($this->_iConnId, $sQuery);
......@@ -280,10 +286,17 @@ class db extends mysqli
* @return array result row or NULL if none found
*/
public function queryOneRecord($sQuery = '') {
if(!preg_match('/limit \d+\s*,\s*\d+$/i', $sQuery)) $sQuery .= ' LIMIT 0,1';
$aArgs = func_get_args();
$oResult = call_user_func_array(array(&$this, 'query'), $aArgs);
if(!empty($aArgs)) {
$sQuery = array_shift($aArgs);
if($sQuery && !preg_match('/limit \d+(\s*,\s*\d+)?$/i', $sQuery)) {
$sQuery .= ' LIMIT 0,1';
}
array_unshift($aArgs, $sQuery);
}
$oResult = call_user_func_array([&$this, 'query'], $aArgs);
if(!$oResult) return null;
$aReturn = $oResult->get();
......@@ -523,7 +536,7 @@ class db extends mysqli
if($debug == 1) echo "mySQL Error Message: ".$this->errorMessage;
}
}
/* TODO: rewrite SQL */
function update($tablename, $form, $bedingung, $debug = 0)
{
......@@ -751,6 +764,41 @@ class db extends mysqli
}
}
/**
* Get the database type (mariadb or mysql)
*
* @access public
* @return string 'mariadb' or string 'mysql'
*/
public function getDatabaseType() {
$tmp = $this->queryOneRecord('SELECT VERSION() as version');
if(stristr($tmp['version'],'mariadb')) {
return 'mariadb';
} else {
return 'mysql';
}
}
/**
* Get the database version
*
* @access public
* @param bool $major_version_only = true will return the major version only, e.g. 8 for MySQL 8
* @return string version number
*/
public function getDatabaseVersion($major_version_only = false) {
$tmp = $this->queryOneRecord('SELECT VERSION() as version');
$version = explode('-', $tmp['version']);
if($major_version_only == true) {
$version_parts = explode('.', $version[0]);
return $version_parts[0];
} else {
return $version[0];
}
}
}
/**
......@@ -953,7 +1001,7 @@ class fakedb_result {
if(!is_array($this->aLimitedData)) return $aItem;
if(list($vKey, $aItem) = each($this->aLimitedData)) {
foreach($this->aLimitedData as $vKey => $aItem) {
if(!$aItem) $aItem = null;
}
return $aItem;
......
......@@ -44,9 +44,9 @@ function prepareDBDump() {
//** load the pre update sql script do perform modifications on the database before the database is dumped
if(is_file(ISPC_INSTALL_ROOT."/install/sql/pre_update.sql")) {
if($conf['mysql']['admin_password'] == '') {
caselog("mysql --default-character-set=".escapeshellarg($conf['mysql']['charset'])." -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." ".escapeshellarg($conf['mysql']['database'])." < '".ISPC_INSTALL_ROOT."/install/sql/pre_update.sql' &> /dev/null", __FILE__, __LINE__, 'read in ispconfig3.sql', 'could not read in ispconfig3.sql');
caselog("mysql --default-character-set=".escapeshellarg($conf['mysql']['charset'])." -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." ".escapeshellarg($conf['mysql']['database'])." < '".ISPC_INSTALL_ROOT."/install/sql/pre_update.sql' &> /dev/null", __FILE__, __LINE__, 'read in pre_update.sql', 'could not read in pre_update.sql');
} else {
caselog("mysql --default-character-set=".escapeshellarg($conf['mysql']['charset'])." -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." -p".escapeshellarg($conf['mysql']['admin_password'])." ".escapeshellarg($conf['mysql']['database'])." < '".ISPC_INSTALL_ROOT."/install/sql/pre_update.sql' &> /dev/null", __FILE__, __LINE__, 'read in ispconfig3.sql', 'could not read in ispconfig3.sql');
caselog("mysql --default-character-set=".escapeshellarg($conf['mysql']['charset'])." -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." -p".escapeshellarg($conf['mysql']['admin_password'])." ".escapeshellarg($conf['mysql']['database'])." < '".ISPC_INSTALL_ROOT."/install/sql/pre_update.sql' &> /dev/null", __FILE__, __LINE__, 'read in pre_update.sql', 'could not read in pre_update.sql');
}
}
......@@ -59,6 +59,8 @@ function prepareDBDump() {
system("mysqldump -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." -c -t --add-drop-table --create-options --quick --result-file=existing_db.sql ".$conf['mysql']['database']);
}
chmod('existing_db.sql', 0400);
chown('existing_db.sql', 'root');
/*
* If we have a server with nothing in it except VE's then the database of thie server is empty.
......@@ -80,9 +82,9 @@ function prepareDBDump() {
if ($conf['powerdns']['installed']) {
//** export the current PowerDNS database data
if( !empty($conf["mysql"]["admin_password"]) ) {
system("mysqldump -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." -p".escapeshellarg($conf['mysql']['admin_password'])." -c -t --add-drop-table --create-options --quick --result-file=existing_powerdns_db.sql ".$conf['powerdns']['database']);
system("mysqldump -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." -p".escapeshellarg($conf['mysql']['admin_password'])." -P ".escapeshellarg($conf['mysql']['port'])." -c -t --add-drop-table --create-options --quick --result-file=existing_powerdns_db.sql ".$conf['powerdns']['database']);
} else {
system("mysqldump -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." -c -t --add-drop-table --create-options --quick --result-file=existing_powerdns_db.sql ".$conf['powerdns']['database']);
system("mysqldump -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." -P ".escapeshellarg($conf['mysql']['port'])." -c -t --add-drop-table --create-options --quick --result-file=existing_powerdns_db.sql ".$conf['powerdns']['database']);
}
// create a backup copy of the PowerDNS database in the root folder
......@@ -101,7 +103,7 @@ function checkDbHealth() {
$notok = array();
echo "Checking ISPConfig database .. ";
exec("mysqlcheck -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." -p".escapeshellarg($conf['mysql']['admin_password'])." -r ".escapeshellarg($conf["mysql"]["database"]), $result);
exec("mysqlcheck -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." -p".escapeshellarg($conf['mysql']['admin_password'])." -P ".escapeshellarg($conf['mysql']['port'])." --auto-repair ".escapeshellarg($conf["mysql"]["database"]), $result);
for( $i=0; $i<sizeof($result);$i++) {
if ( substr($result[$i], -2) != "OK" ) {
$notok[] = $result[$i];
......@@ -124,11 +126,19 @@ function updateDbAndIni() {
global $inst, $conf;
//* check sql-mode
/*
$check_sql_mode = $inst->db->queryOneRecord("SELECT @@sql_mode");
if ($check_sql_mode['@@sql_mode'] != '' && $check_sql_mode['@@sql_mode'] != 'NO_ENGINE_SUBSTITUTION') {
echo "Wrong SQL-mode. You should use NO_ENGINE_SUBSTITUTION. Add\n\n";
echo " sql-mode=\"NO_ENGINE_SUBSTITUTION\"\n\n";
echo"to the mysqld-section in /etc/mysql/my.cnf and restart mysqld afterwards\n";
echo"to the mysqld-section in your mysql-config on this server and restart mysqld afterwards\n";
die();
}*/
$unwanted_sql_plugins = array('validate_password');
$sql_plugins = $inst->db->queryAllRecords("SELECT plugin_name FROM information_schema.plugins WHERE plugin_status='ACTIVE' AND plugin_name IN ?", $unwanted_sql_plugins);
if(is_array($sql_plugins) && !empty($sql_plugins)) {
foreach ($sql_plugins as $plugin) echo "Login in to MySQL and disable $plugin[plugin_name] with:\n\n UNINSTALL PLUGIN $plugin[plugin_name];";
die();
}
......@@ -175,9 +185,9 @@ function updateDbAndIni() {
else $next_db_version = intval($current_db_version + 1);
$sql_patch_filename = realpath(dirname(__FILE__).'/../').'/sql/incremental/upd_'.str_pad($next_db_version, 4, '0', STR_PAD_LEFT).'.sql';
$php_patch_filename = realpath(dirname(__FILE__).'/../').'/patches/upd_'.str_pad($next_db_version, 4, '0', STR_PAD_LEFT).'.php';
// comma separated list of version numbers were a update has to be done silently
$silent_update_versions = 'dev_collection,75';
$silent_update_versions = 'dev_collection,75,91';
if(is_file($sql_patch_filename)) {
......@@ -200,14 +210,18 @@ function updateDbAndIni() {
//* Load patch file into database
if( !empty($conf["mysql"]["admin_password"]) ) {
$cmd = "mysql --default-character-set=".escapeshellarg($conf['mysql']['charset'])." --force -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." -p".escapeshellarg($conf['mysql']['admin_password'])." ".escapeshellarg($conf['mysql']['database'])." < ".$sql_patch_filename;
$cmd = "mysql --default-character-set=".escapeshellarg($conf['mysql']['charset'])." --force -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." -p".escapeshellarg($conf['mysql']['admin_password'])." -P ".escapeshellarg($conf['mysql']['port'])." ".escapeshellarg($conf['mysql']['database'])." < ".$sql_patch_filename;
} else {
$cmd = "mysql --default-character-set=".escapeshellarg($conf['mysql']['charset'])." --force -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." ".escapeshellarg($conf['mysql']['database'])." < ".$sql_patch_filename;
$cmd = "mysql --default-character-set=".escapeshellarg($conf['mysql']['charset'])." --force -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." -P ".escapeshellarg($conf['mysql']['port'])." ".escapeshellarg($conf['mysql']['database'])." < ".$sql_patch_filename;
}
if(in_array($next_db_version,explode(',',$silent_update_versions))) {
$cmd .= ' > /dev/null 2> /dev/null';
} else {
$cmd .= ' >> /var/log/ispconfig_install.log 2>> /var/log/ispconfig_install.log';
}
if(in_array($next_db_version,explode(',',$silent_update_versions))) $cmd .= ' > /dev/null 2> /dev/null';
system($cmd);
swriteln($inst->lng('Loading SQL patch file').': '.$sql_patch_filename);
//* Exec onAfterSQL function
......@@ -217,7 +231,7 @@ function updateDbAndIni() {
if($dev_patch == false) $current_db_version = $next_db_version;
else $found = false;
if(isset($php_patch)) unset($php_patch);
} elseif($dev_patch == false) {
$dev_patch = true;
......@@ -321,6 +335,9 @@ function updateDbAndIni() {
$tpl_ini_array['web']['php_ini_path_cgi'] = $conf['apache']['php_ini_path_cgi'];
$tpl_ini_array['mail']['pop3_imap_daemon'] = ($conf['dovecot']['installed'] == true)?'dovecot':'courier';
$tpl_ini_array['mail']['mail_filter_syntax'] = ($conf['dovecot']['installed'] == true)?'sieve':'maildrop';
// do not switch to rspamd automatically!
// $tpl_ini_array['mail']['content_filter'] = @($conf['rspamd']['installed']) ? 'rspamd' : 'amavisd';
$tpl_ini_array['mail']['rspamd_available'] = @($conf['rspamd']['installed']) ? 'y' : 'n';
$tpl_ini_array['dns']['bind_user'] = $conf['bind']['bind_user'];
$tpl_ini_array['dns']['bind_group'] = $conf['bind']['bind_group'];
$tpl_ini_array['dns']['bind_zonefiles_dir'] = $conf['bind']['bind_zonefiles_dir'];
......@@ -390,13 +407,16 @@ function updateDbAndIni() {
unset($old_ini_array);
unset($tpl_ini_array);
unset($new_ini);
// Truncate sys_session
$inst->db->query('TRUNCATE ??', $conf['mysql']['database'].'sys_session');
}
function setDefaultServers(){
global $inst, $conf;
// clients
$clients = $inst->db->queryAllRecords("SELECT * FROM ".$conf["mysql"]["database"].".client");
if(is_array($clients) && !empty($clients)){
......@@ -411,7 +431,92 @@ function setDefaultServers(){
if(trim($client['db_servers']) == '') $inst->db->query("UPDATE ?? SET db_servers = ? WHERE client_id = ?", $conf["mysql"]["database"].".client", trim($client['default_dbserver']), $client['client_id']);
}
}
}
/** Checks if a detected service differs from db setup and asks the user what to do
* @param $servicename string the name of the Database-Field in "servers" for this service
* @param $detected_value boolean The result of service detection
*/
function check_service_config_state($servicename, $detected_value) {
global $current_svc_config, $inst, $conf;
if ($current_svc_config[$servicename] == 1) $current_state = 1;
else $current_state = 0;
if ($detected_value) $detected_value = 1;
else $detected_value = 0;
if ($detected_value != $current_state) {
$answer = $inst->simple_query('Service \''.$servicename.'\' '.($detected_value ? 'has been' : 'has not been').' detected ('.($current_state ? 'strongly recommended, currently enabled' : 'currently disabled').') do you want to '.($detected_value ? 'enable and configure' : 'disable').' it? ', array('yes', 'no'), ($current_state ? 'yes' : 'no'), 'svc_detect_change_'.$servicename);
if ($answer == 'yes') return $detected_value;
else {
if ($servicename == 'web_server') echo "\033[0;33mWARNING: If ISPConfig-Interface (Webfrontend) is installed on this Server we will configure the Web Server anyways but will not enable it in ISPConfig.\033[0m\n\n";
return $current_state;
}
} else return $current_state;
}
/**
* Check for existing conf-custom templates and offer to rename them.
*/
function checkAndRenameCustomTemplates($default_prompt='no') {
global $inst;
$ret = true;
$default_prompt = ($default_prompt == 'yes') ? 'yes' : 'no';
$template_directories = array(
'/usr/local/ispconfig/server/conf-custom',
'/usr/local/ispconfig/server/conf-custom/install',
);
$override_templates = array(
'postfix_custom.conf.master',
'dovecot_custom.conf.master',
);
$found_templates = array();
$found_override_templates = array();
foreach ($template_directories as $dir) {
if (!is_dir($dir)) { continue; }
foreach (glob("$dir/*.master") as $f) {
if (is_file($f)) {
if (in_array( basename($f), $override_templates )) {
$found_override_templates[] = $f;
} else {
$found_templates[] = $f;
}
}
}
}
if (count($found_templates) > 0) {
echo "The following custom templates were found:\n\n";
echo implode("\n", $found_templates) . "\n\n";
$answer = $inst->simple_query('Do you want to rename these conf-custom templates now so the default templates are used?', array('yes', 'no'), $default_prompt, 'rename_custom_templates');
if (strtolower($answer) == 'yes') {
$date=date('-Y-m-d_H-i');
foreach ($found_templates as $f) {
if (!rename($f, $f.$date)) {
echo "Error renaming template $f\n";
$ret = false;
}
}
} else {
$ret = null;
}
}
if (count($found_override_templates) > 0) {
echo "The following local config override templates were found, be sure to incorporate upstream changes if needed:\n\n";
echo implode("\n", $found_override_templates) . "\n\n";
}
return $ret;
}
?>
<?php
if(!defined('INSTALLER_RUN')) die('Patch update file access violation.');
/*
Example installer patch update class. the classname must match
the php and the sql patch update filename. The php patches are
only executed when a corresponding sql patch exists.
*/
class upd_0085 extends installer_patch_update {
public function onAfterSQL() {
global $inst, $conf;
$cron_files = $conf['cron']['crontab_dir'] . '/ispc_*';
$check_suffix = '';
if (file_exists('/etc/gentoo-release')) {
$cron_files .= '.cron';
$check_suffix = '.cron';
}
$file_list = glob($cron_files);
if(is_array($file_list) && !empty($file_list)) {
for($f = 0; $f < count($file_list); $f++) {
$cron_file = $file_list[$f];
$fp = fopen($cron_file, 'r');
while($fp && !feof($fp)) {
$line = trim(fgets($fp));
if($line == '') continue;
elseif(substr($line, 0, 1) === '#') continue; // commented out
$fields = preg_split('/\s+/', $line);
if(trim($fields[0]) == '') {
// invalid line
swriteln($inst->lng('[INFO] Invalid cron line in file ' . $cron_file));
} elseif(preg_match('/^\w+=/', $line)) {
if(preg_match('/\s/', $line)) {
// warning line with env var and space!
swriteln($inst->lng("\n" . '[WARNING] Cron line in file ' . $cron_file . ' contains environment variable.' . "\n"));
}
} elseif(!isset($fields[5])) {
// invalid line (missing user)
swriteln($inst->lng("\n" . '[WARNING] Cron line in file ' . $cron_file . ' misses user field.' . "\n"));
} else {
$check_filename = trim($fields[5]) . $check_suffix;
if(substr($cron_file, -strlen($check_filename)) != $check_filename) {
// warning user not equal to file name
swriteln($inst->lng("\n" . '[WARNING] SUSPECT USER IN CRON FILE ' . $cron_file . '! CHECK CRON FILE FOR MALICIOUS ENTRIES!' . "\n"));
}
}
}
fclose($fp);
}
}
}
}
?>
<?php
if(!defined('INSTALLER_RUN')) die('Patch update file access violation.');
/*
Example installer patch update class. the classname must match
the php and the sql patch update filename. The php patches are
only executed when a corresponding sql patch exists.
*/
class upd_0086 extends installer_patch_update {
public function onAfterSQL() {
global $inst;
// delete all the files that were deleted on previous updates
$delete = array(
'interface/web/js/mail_domain_dkim.js',
'interface/web/mail/mail_domain_dkim_create.php'
);
$curpath = dirname(dirname(realpath(dirname(__FILE__))));
$c = 0;
$del_all = false;
foreach($delete as $file) {
if(strpos($file, '..') !== false) continue; // security!
if($del_all == false) {
$answer = $inst->simple_query('Delete obsolete file ' . $file . '?', array('y', 'n', 'a', 'all', 'none'), 'y');
if($answer == 'n') continue;
elseif($answer == 'a' || $answer == 'all') $del_all = true;
elseif($answer == 'none') break;
}
if(@is_file('/usr/local/ispconfig/' . $file) && !@is_file($curpath . '/' . $file)) {
// be sure this is not a file contained in installation!
@unlink('/usr/local/ispconfig/' . $file);
ilog('Deleted obsolete file /usr/local/ispconfig/' . $file);
$c++;
}
}
ilog($c . 'obsolete files deleted.');
}
}
?>
<?php
if(!defined('INSTALLER_RUN')) die('Patch update file access violation.');
/*
Example installer patch update class. the classname must match
the php and the sql patch update filename. The php patches are
only executed when a corresponding sql patch exists.
*/
class upd_0088 extends installer_patch_update {
public function onAfterSQL() {
global $inst;
// delete all the files that were deleted on previous updates
$delete = array(
'interface/web/mail/templates/spamfilter_taglevel_edit.htm',
'interface/web/mail/templates/spamfilter_quarantine_edit.htm',
'interface/web/mail/templates/spamfilter_other_edit.htm',
);
$curpath = dirname(dirname(realpath(dirname(__FILE__))));
$c = 0;
$del_all = false;
foreach($delete as $file) {
if(strpos($file, '..') !== false) continue; // security!
if($del_all == false) {
$answer = $inst->simple_query('Delete obsolete file ' . $file . '?', array('y', 'n', 'a', 'all', 'none'), 'y');
if($answer == 'n') continue;
elseif($answer == 'a' || $answer == 'all') $del_all = true;
elseif($answer == 'none') break;
}
if(@is_file('/usr/local/ispconfig/' . $file) && !@is_file($curpath . '/' . $file)) {
// be sure this is not a file contained in installation!
@unlink('/usr/local/ispconfig/' . $file);
ilog('Deleted obsolete file /usr/local/ispconfig/' . $file);
$c++;
}
}
ilog($c . 'obsolete files deleted.');
}
}
?>
<?php
if(!defined('INSTALLER_RUN')) die('Patch update file access violation.');
class upd_0094 extends installer_patch_update {
public function onBeforeSQL() {
global $inst;
// Remove any duplicate mail_forwardings prior to adding unique key
//$inst->db->query("DELETE FROM mail_forwarding WHERE forwarding_id NOT IN (SELECT MIN(forwarding_id) FROM mail_forwarding GROUP BY source)");
// Remove any duplicate mail_transports prior to adding unique key
$inst->db->query("DELETE FROM mail_transport WHERE transport_id NOT IN (SELECT MIN(transport_id) FROM mail_transport GROUP BY domain, server_id)");
}
}
<?php
if(!defined('INSTALLER_RUN')) die('Patch update file access violation.');
class upd_0100 extends installer_patch_update {
public function onAfterSQL() {
global $inst;
// Remove old server plugins, unless they are currently enabled
if(!is_link('/usr/local/ispconfig/server/plugins-enabled/nginx_reverseproxy_plugin.inc.php'))
unlink('/usr/local/ispconfig/server/plugins-available/nginx_reverseproxy_plugin.inc.php');
if(!is_link('/usr/local/ispconfig/server/plugins-enabled/bind_dlz_plugin.inc.php'))
unlink('/usr/local/ispconfig/server/plugins-available/bind_dlz_plugin.inc.php');
}
}
......@@ -9,18 +9,24 @@ then follow these steps:
1) Add the field or table in the ispconfig3.sql file. This file contains the
complete database dump which is used when ISPConfig gets installed.
2) Create a new file in the "incremental" subfolder wich contains the alter
table, or if it is a complete new table then the add table, statement(s) in
MySQL syntax which is/are required to modify the current ispconfig database
during update. The naming scheme of the sql patch update files is
upd_0001.sql, upd_0002.sql, upd_0003.sql etc. Ensure that the number that
you choose for the new file is a +1 increment of the number of the last
existing file and that the number is formatted with 4 digits.
2) Edit the file "incremental/upd_dev_collection.sql" which contains the SQL
statements (alter table, add table, update, etc.) in MySQL syntax which
are required to modify the current ispconfig database during update.
The upd_dev_collection.sql file contains all db schema modifications
for changes made since the last ISPConfig release. If SQL statements
are already present in the file when you make your additions, add yours
to the end of the file, and do not remove any existing statements.
When a new ISPConfig update is released, the contents of
upd_dev_collections.sql will move to an sql patch file, using the naming
scheme upd_0001.sql, upd_0002.sql, upd_0003.sql etc.
A patch file may contain one or more alter table statements. Every patch file
gets executed once in the database, so do not modify older (already released)
A patch file may contain one or more SQL modification statements. Every patch
file gets executed once in the database, so do not modify older (already released)
patch files, they will not get executed again if the update was already run
once on a system.
once on a system, and will result in missing updates on any system where they
have not run yet.
After a patch has been executed, the dbversion field in the server table gets
increeased to the version number of the last installed patch.
......
......@@ -5,4 +5,4 @@ CREATE TABLE IF NOT EXISTS `sys_session` (
`session_data` longtext,
PRIMARY KEY (`session_id`),
KEY `last_updated` (`last_updated`)
) ENGINE=MyISAM;
\ No newline at end of file
);
\ No newline at end of file
......@@ -11,7 +11,7 @@ CREATE TABLE `help_faq_sections` (
`sys_perm_group` varchar(5) DEFAULT NULL,
`sys_perm_other` varchar(5) DEFAULT NULL,
PRIMARY KEY (`hfs_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1;
) AUTO_INCREMENT=1;
INSERT INTO `help_faq_sections` VALUES (1,'General',0,NULL,NULL,NULL,NULL,NULL);
......@@ -27,7 +27,7 @@ CREATE TABLE `help_faq` (
`sys_perm_group` varchar(5) DEFAULT NULL,
`sys_perm_other` varchar(5) DEFAULT NULL,
PRIMARY KEY (`hf_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1;
) AUTO_INCREMENT=1;
INSERT INTO `help_faq` VALUES (1,1,0,'I\'d like to know ...','Yes, of course.',1,1,'riud','riud','r');
......@@ -14,6 +14,6 @@ CREATE TABLE IF NOT EXISTS `mail_mailinglist` (
`email` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
PRIMARY KEY (`mailinglist_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1;
) AUTO_INCREMENT=1;
DROP TABLE `mail_mailman_domain`;
\ No newline at end of file