installer_base.lib.php 140 KB
Newer Older
latham's avatar
latham committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php

/*
Copyright (c) 2007-2010, Till Brehm, projektfarm Gmbh
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
    * Neither the name of ISPConfig nor the names of its contributors
      may be used to endorse or promote products derived from this software without
      specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

class installer_base {

	var $wb = array();
	var $language = 'en';
	var $db;
	public $conf;
	public $install_ispconfig_interface = true;
	public $is_update = false; // true if it is an update, falsi if it is a new install
39
	public $min_php = '5.3.3'; // minimal php-version for update / install
40
	protected $mailman_group = 'list';
latham's avatar
latham committed
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57


	public function __construct() {
		global $conf; //TODO: maybe $conf  should be passed to constructor
		//$this->conf = $conf;
	}

	//: TODO  Implement the translation function and language files for the installer.
	public function lng($text) {
		return $text;
	}

	public function error($msg) {
		die('ERROR: '.$msg."\n");
	}

	public function warning($msg) {
58
		echo 'WARNING: '.$msg."\n";
latham's avatar
latham committed
59
	}
maddinxx's avatar
maddinxx committed
60

Till Brehm's avatar
Till Brehm committed
61
	public function simple_query($query, $answers, $default, $name = '') {
62
		global $autoinstall, $autoupdate;
latham's avatar
latham committed
63
64
		$finished = false;
		do {
Till Brehm's avatar
Till Brehm committed
65
66
67
68
69
70
			if($name != '' && $autoinstall[$name] != '') {
				if($autoinstall[$name] == 'default') {
					$input = $default;
				} else {
					$input = $autoinstall[$name];
				}
71
72
73
74
75
76
			} elseif($name != '' && $autoupdate[$name] != '') {
				if($autoupdate[$name] == 'default') {
					$input = $default;
				} else {
					$input = $autoupdate[$name];
				}
Till Brehm's avatar
Till Brehm committed
77
78
79
80
81
			} else {
				$answers_str = implode(',', $answers);
				swrite($this->lng($query).' ('.$answers_str.') ['.$default.']: ');
				$input = sread();
			}
latham's avatar
latham committed
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

			//* Stop the installation
			if($input == 'quit') {
				swriteln($this->lng("Installation terminated by user.\n"));
				die();
			}

			//* Select the default
			if($input == '') {
				$answer = $default;
				$finished = true;
			}

			//* Set answer id valid
			if(in_array($input, $answers)) {
				$answer = $input;
				$finished = true;
			}

		} while ($finished == false);
		swriteln();
		return $answer;
	}

Till Brehm's avatar
Till Brehm committed
106
	public function free_query($query, $default, $name = '') {
107
		global $autoinstall, $autoupdate;
Till Brehm's avatar
Till Brehm committed
108
109
110
111
112
113
		if($name != '' && $autoinstall[$name] != '') {
			if($autoinstall[$name] == 'default') {
				$input = $default;
			} else {
				$input = $autoinstall[$name];
			}
114
115
116
117
118
119
		} elseif($name != '' && $autoupdate[$name] != '') {
			if($autoupdate[$name] == 'default') {
				$input = $default;
			} else {
				$input = $autoupdate[$name];
			}
Till Brehm's avatar
Till Brehm committed
120
121
122
123
		} else {
			swrite($this->lng($query).' ['.$default.']: ');
			$input = sread();
		}
latham's avatar
latham committed
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138

		//* Stop the installation
		if($input == 'quit') {
			swriteln($this->lng("Installation terminated by user.\n"));
			die();
		}

		$answer =  ($input == '') ? $default : $input;
		swriteln();
		return $answer;
	}

	/*
	// TODO: this function is not used atmo I think - pedro
	function request_language(){
maddinxx's avatar
maddinxx committed
139

latham's avatar
latham committed
140
141
		swriteln(lng('Enter your language'));
		swriteln(lng('de, en'));
maddinxx's avatar
maddinxx committed
142

latham's avatar
latham committed
143
144
145
	}
	*/

146
147
	//** Detect PHP-Version
	public function get_php_version() {
148
149
		if(version_compare(PHP_VERSION, $this->min_php, '<')) return false;
		else return true;
150
151
	}

latham's avatar
latham committed
152
153
154
155
156
157
	//** Detect installed applications
	public function find_installed_apps() {
		global $conf;

		if(is_installed('mysql') || is_installed('mysqld')) $conf['mysql']['installed'] = true;
		if(is_installed('postfix')) $conf['postfix']['installed'] = true;
Dominik's avatar
Dominik committed
158
		if(is_installed('postgrey')) $conf['postgrey']['installed'] = true;
159
		if(is_installed('mailman') || is_installed('mmsitepass')) $conf['mailman']['installed'] = true;
Michele's avatar
Michele committed
160
		if(is_installed('mlmmj') || is_installed('mlmmj-make-ml')) $conf['mlmmj']['installed'] = true;
161
		if(is_installed('apache') || is_installed('apache2') || is_installed('httpd') || is_installed('httpd2')) $conf['apache']['installed'] = true;
latham's avatar
latham committed
162
		if(is_installed('getmail')) $conf['getmail']['installed'] = true;
163
		if(is_installed('courierlogger')) $conf['courier']['installed'] = true;
latham's avatar
latham committed
164
		if(is_installed('dovecot')) $conf['dovecot']['installed'] = true;
165
		if(is_installed('saslauthd')) $conf['saslauthd']['installed'] = true;
tbrehm's avatar
tbrehm committed
166
		if(is_installed('amavisd-new') || is_installed('amavisd')) $conf['amavis']['installed'] = true;
latham's avatar
latham committed
167
168
169
170
171
172
		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;
		if(is_installed('jk_chrootsh')) $conf['jailkit']['installed'] = true;
		if(is_installed('pdns_server') || is_installed('pdns_control')) $conf['powerdns']['installed'] = true;
		if(is_installed('named') || is_installed('bind') || is_installed('bind9')) $conf['bind']['installed'] = true;
173
174
		if(is_installed('squid')) $conf['squid']['installed'] = true;
		if(is_installed('nginx')) $conf['nginx']['installed'] = true;
175
176
177
178
179
		if(is_installed('iptables') && is_installed('ufw')) {
			$conf['ufw']['installed'] = true;
		} elseif(is_installed('iptables')) {
			$conf['firewall']['installed'] = true;
		}
180
		if(is_installed('fail2ban-server')) $conf['fail2ban']['installed'] = true;
tbrehm's avatar
tbrehm committed
181
		if(is_installed('vzctl')) $conf['openvz']['installed'] = true;
182
		if(is_installed('metronome') && is_installed('metronomectl')) $conf['xmpp']['installed'] = true;
183
		if(is_installed('spamassassin')) $conf['spamassassin']['installed'] = true;
184
185
186
187
		// if(is_installed('vlogger')) $conf['vlogger']['installed'] = true;
		// ISPConfig ships with vlogger, so it is always installed.
		$conf['vlogger']['installed'] = true;
		if(is_installed('cron') || is_installed('anacron')) $conf['cron']['installed'] = true;
maddinxx's avatar
maddinxx committed
188

189
		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;
latham's avatar
latham committed
190
191
	}

192
    public function force_configure_app($service, $enable_force=true) {
193
		$force = false;
194
		if(AUTOINSTALL == true) return false;
195
196
197
198
199
		if($enable_force == true) {
			swriteln("[WARN] autodetect for $service failed");
		} else {
			swriteln("[INFO] service $service not detected");
		}
200
201
202
203
204
		if($enable_force) {
	        if(strtolower($this->simple_query("Force configure $service", array('y', 'n'), 'n') ) == 'y') {
	            $force = true;
			} else swriteln("Skipping $service\n");
		}
205
206
207
		return $force;
    }

208
209
210
211
212
213
214
215
216
217
218
219
220
	public function reconfigure_app($service, $reconfigure_services_answer) {
		$reconfigure = false;
		if ($reconfigure_services_answer != 'selected') {
			$reconfigure = true;
		} else {
			if(strtolower($this->simple_query("Reconfigure $service", array('y', 'n'), 'y') ) == 'y') {
				$reconfigure = true;
			} else {
				swriteln("Skip reconfigure $service\n");
			}
		}
		return $reconfigure;
	}
221

latham's avatar
latham committed
222
	/** Create the database for ISPConfig */
223
224


latham's avatar
latham committed
225
226
227
	public function configure_database() {
		global $conf;

root's avatar
root committed
228
229
		//* ensure no modes with errors for ENGINE=MyISAM
		$this->db->query("SET sql_mode = ''");
230

231
		$unwanted_sql_plugins = array('validate_password');		
Florian Schaal's avatar
Florian Schaal committed
232
		$sql_plugins = $this->db->queryAllRecords("SELECT plugin_name FROM information_schema.plugins WHERE plugin_status='ACTIVE' AND plugin_name IN ?", $unwanted_sql_plugins);
233
234
235
236
237
		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();
		}

latham's avatar
latham committed
238
		//** Create the database
239
		if(!$this->db->query('CREATE DATABASE IF NOT EXISTS ?? DEFAULT CHARACTER SET ?', $conf['mysql']['database'], $conf['mysql']['charset'])) {
latham's avatar
latham committed
240
241
242
243
			$this->error('Unable to create MySQL database: '.$conf['mysql']['database'].'.');
		}

		//* Set the database name in the DB library
244
		$this->db->setDBName($conf['mysql']['database']);
latham's avatar
latham committed
245
246
247
248
249
250
251

		//* Load the database dump into the database, if database contains no tables
		$db_tables = $this->db->getTables();
		if(count($db_tables) > 0) {
			$this->error('Stopped: Database already contains some tables.');
		} else {
			if($conf['mysql']['admin_password'] == '') {
252
				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",
253
					__FILE__, __LINE__, 'read in ispconfig3.sql', 'could not read in ispconfig3.sql');
latham's avatar
latham committed
254
			} else {
255
				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",
256
					__FILE__, __LINE__, 'read in ispconfig3.sql', 'could not read in ispconfig3.sql');
latham's avatar
latham committed
257
258
259
260
261
262
263
			}
			$db_tables = $this->db->getTables();
			if(count($db_tables) == 0) {
				$this->error('Unable to load SQL-Dump into database table.');
			}

			//* Load system.ini into the sys_ini table
264
265
			$system_ini = rf('tpl/system.ini.master');
			$this->db->query("UPDATE sys_ini SET config = ? WHERE sysini_id = 1", $system_ini);
latham's avatar
latham committed
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281

		}
	}

	//** Create the server record in the database
	public function add_database_server_record() {

		global $conf;

		if($conf['mysql']['host'] == 'localhost') {
			$from_host = 'localhost';
		} else {
			$from_host = $conf['hostname'];
		}

		// Delete ISPConfig user in the local database, in case that it exists
Florian Schaal's avatar
Florian Schaal committed
282
		$this->db->query("DROP USER ?@?", $conf['mysql']['ispconfig_user'], $from_host);
283
		$this->db->query("DROP DATABASE IF EXISTS ?", $conf['mysql']['database']);
latham's avatar
latham committed
284
285

		//* Create the ISPConfig database user in the local database
286
287
		$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'])) {
latham's avatar
latham committed
288
289
290
291
			$this->error('Unable to create database user: '.$conf['mysql']['ispconfig_user'].' Error: '.$this->db->errorMessage);
		}

		//* Set the database name in the DB library
292
		$this->db->setDBName($conf['mysql']['database']);
latham's avatar
latham committed
293
294
295
296
297
298
299
300
301
302

		$tpl_ini_array = ini_to_array(rf('tpl/server.ini.master'));

		//* Update further distribution specific parameters for server config here
		//* HINT: Every line added here has to be added in update.lib.php too!!
		$tpl_ini_array['web']['vhost_conf_dir'] = $conf['apache']['vhost_conf_dir'];
		$tpl_ini_array['web']['vhost_conf_enabled_dir'] = $conf['apache']['vhost_conf_enabled_dir'];
		$tpl_ini_array['jailkit']['jailkit_chroot_app_programs'] = $conf['jailkit']['jailkit_chroot_app_programs'];
		$tpl_ini_array['fastcgi']['fastcgi_phpini_path'] = $conf['fastcgi']['fastcgi_phpini_path'];
		$tpl_ini_array['fastcgi']['fastcgi_starter_path'] = $conf['fastcgi']['fastcgi_starter_path'];
303
		$tpl_ini_array['fastcgi']['fastcgi_bin'] = $conf['fastcgi']['fastcgi_bin'];
latham's avatar
latham committed
304
305
		$tpl_ini_array['server']['hostname'] = $conf['hostname'];
		$tpl_ini_array['server']['ip_address'] = @gethostbyname($conf['hostname']);
306
		$tpl_ini_array['server']['firewall'] = ($conf['ufw']['installed'] == true)?'ufw':'bastille';
latham's avatar
latham committed
307
308
309
310
311
312
313
314
315
316
317
		$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'];
		$tpl_ini_array['cron']['crontab_dir'] = $conf['cron']['crontab_dir'];
		$tpl_ini_array['web']['security_level'] = 20;
		$tpl_ini_array['web']['user'] = $conf['apache']['user'];
		$tpl_ini_array['web']['group'] = $conf['apache']['group'];
		$tpl_ini_array['web']['php_ini_path_apache'] = $conf['apache']['php_ini_path_apache'];
		$tpl_ini_array['web']['php_ini_path_cgi'] = $conf['apache']['php_ini_path_cgi'];
		$tpl_ini_array['mail']['pop3_imap_daemon'] = ($conf['dovecot']['installed'] == true)?'dovecot':'courier';
		$tpl_ini_array['mail']['mail_filter_syntax'] = ($conf['dovecot']['installed'] == true)?'sieve':'maildrop';
318
		$tpl_ini_array['mail']['mailinglist_manager'] = ($conf['mlmmj']['installed'] == true)?'mlmmj':'mailman';
latham's avatar
latham committed
319
320
321
322
323
		$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'];
		$tpl_ini_array['dns']['named_conf_path'] = $conf['bind']['named_conf_path'];
		$tpl_ini_array['dns']['named_conf_local_path'] = $conf['bind']['named_conf_local_path'];
maddinxx's avatar
maddinxx committed
324

325
326
327
328
329
330
331
332
333
334
		$tpl_ini_array['web']['nginx_vhost_conf_dir'] = $conf['nginx']['vhost_conf_dir'];
		$tpl_ini_array['web']['nginx_vhost_conf_enabled_dir'] = $conf['nginx']['vhost_conf_enabled_dir'];
		$tpl_ini_array['web']['nginx_user'] = $conf['nginx']['user'];
		$tpl_ini_array['web']['nginx_group'] = $conf['nginx']['group'];
		$tpl_ini_array['web']['nginx_cgi_socket'] = $conf['nginx']['cgi_socket'];
		$tpl_ini_array['web']['php_fpm_init_script'] = $conf['nginx']['php_fpm_init_script'];
		$tpl_ini_array['web']['php_fpm_ini_path'] = $conf['nginx']['php_fpm_ini_path'];
		$tpl_ini_array['web']['php_fpm_pool_dir'] = $conf['nginx']['php_fpm_pool_dir'];
		$tpl_ini_array['web']['php_fpm_start_port'] = $conf['nginx']['php_fpm_start_port'];
		$tpl_ini_array['web']['php_fpm_socket_dir'] = $conf['nginx']['php_fpm_socket_dir'];
maddinxx's avatar
maddinxx committed
335

336
		if ($conf['nginx']['installed'] == true) {
337
338
			$tpl_ini_array['web']['server_type'] = 'nginx';
			$tpl_ini_array['global']['webserver'] = 'nginx';
339
		}
maddinxx's avatar
maddinxx committed
340

latham's avatar
latham committed
341
342
343
344
345
346
347
		if (array_key_exists('awstats', $conf)) {
			foreach ($conf['awstats'] as $aw_sett => $aw_value) {
				$tpl_ini_array['web']['awstats_'.$aw_sett] = $aw_value;
			}
		}

		$server_ini_content = array_to_ini($tpl_ini_array);
Marius Cramer's avatar
Marius Cramer committed
348
		
latham's avatar
latham committed
349
350
351
352
353
		$mail_server_enabled = ($conf['services']['mail'])?1:0;
		$web_server_enabled = ($conf['services']['web'])?1:0;
		$dns_server_enabled = ($conf['services']['dns'])?1:0;
		$file_server_enabled = ($conf['services']['file'])?1:0;
		$db_server_enabled = ($conf['services']['db'])?1:0;
tbrehm's avatar
tbrehm committed
354
		$vserver_server_enabled = ($conf['openvz']['installed'])?1:0;
355
356
		$proxy_server_enabled = (isset($conf['services']['proxy']) && $conf['services']['proxy'])?1:0;
		$firewall_server_enabled = (isset($conf['services']['firewall']) && $conf['services']['firewall'])?1:0;
maddinxx's avatar
maddinxx committed
357

latham's avatar
latham committed
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
		//** Get the database version number based on the patchfiles
		$found = true;
		$current_db_version = 1;
		while($found == true) {
			$next_db_version = intval($current_db_version + 1);
			$patch_filename = realpath(dirname(__FILE__).'/../').'/sql/incremental/upd_'.str_pad($next_db_version, 4, '0', STR_PAD_LEFT).'.sql';
			if(is_file($patch_filename)) {
				$current_db_version = $next_db_version;
			} else {
				$found = false;
			}
		}
		$current_db_version = intval($current_db_version);


		if($conf['mysql']['master_slave_setup'] == 'y') {

			//* Insert the server record in master DB
376
377
			$sql = "INSERT INTO `server` (`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_name`, `mail_server`, `web_server`, `dns_server`, `file_server`, `db_server`, `vserver_server`, `config`, `updated`, `active`, `dbversion`,`firewall_server`,`proxy_server`) VALUES (1, 1, 'riud', 'riud', 'r', ?, ?, ?, ?, ?, ?, ?, ?, 0, 1, ?, ?, ?);";
			$this->dbmaster->query($sql, $conf['hostname'], $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $vserver_server_enabled, $server_ini_content, $current_db_version, $proxy_server_enabled, $firewall_server_enabled);
latham's avatar
latham committed
378
379
380
381
			$conf['server_id'] = $this->dbmaster->insertID();
			$conf['server_id'] = $conf['server_id'];

			//* Insert the same record in the local DB
Florian Schaal's avatar
Florian Schaal committed
382
			$sql = "INSERT INTO `server` (`server_id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_name`, `mail_server`, `web_server`, `dns_server`, `file_server`, `db_server`, `vserver_server`, `config`, `updated`, `active`, `dbversion`,`firewall_server`,`proxy_server`) VALUES (?,1, 1, 'riud', 'riud', 'r', ?, ?, ?, ?, ?, ?, ?, ?, 0, 1, ?, ?, ?);";
383
			$this->db->query($sql, $conf['server_id'], $conf['hostname'], $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $vserver_server_enabled, $server_ini_content, $current_db_version, $proxy_server_enabled, $firewall_server_enabled);
latham's avatar
latham committed
384
385
386
387
388
389
390
391

			//* username for the ispconfig user
			$conf['mysql']['master_ispconfig_user'] = 'ispcsrv'.$conf['server_id'];

			$this->grant_master_database_rights();

		} else {
			//* Insert the server, if its not a mster / slave setup
392
393
			$sql = "INSERT INTO `server` (`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_name`, `mail_server`, `web_server`, `dns_server`, `file_server`, `db_server`, `vserver_server`, `config`, `updated`, `active`, `dbversion`,`firewall_server`,`proxy_server`) VALUES (1, 1, 'riud', 'riud', 'r', ?, ?, ?, ?, ?, ?, ?, ?, 0, 1, ?, ?, ?);";
			$this->db->query($sql, $conf['hostname'], $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $vserver_server_enabled, $server_ini_content, $current_db_version, $proxy_server_enabled, $firewall_server_enabled);
latham's avatar
latham committed
394
395
396
397
398
399
			$conf['server_id'] = $this->db->insertID();
			$conf['server_id'] = $conf['server_id'];
		}


	}
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
	
	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",
							"",
429
							?,
430
							0,
431
432
							?,
							?,
433
434
							"y",
							"80,443"
435
						)', $conf['server_id'], $ip_type, $line);
436
437
438
439
440
441
						$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 (
442
							?,
443
444
445
446
447
							1,
							1,
							"riud",
							"riud",
							"",
448
							?,
449
							0,
450
451
							?,
							?,
452
453
							"y",
							"80,443"
454
						)', $server_ip_id, $conf['server_id'], $ip_type, $line);
455
456
457
458
459
460
461
462
463
464
465
					} 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",
							"",
466
							?,
467
							0,
468
469
							?,
							?,
470
471
							"y",
							"80,443"
472
						)', $conf['server_id'], $ip_type, $line);
473
474
475
476
477
					}
				}
			}
		}
	}
latham's avatar
latham committed
478

479
	public function grant_master_database_rights($verbose = false) {
latham's avatar
latham committed
480
481
482
483
484
485
486
487
488
489
490
		global $conf;

		/*
		 * The following code is a little bit tricky:
		 * * If we HAVE a master-slave - Setup then the client has to grant the rights for himself
		 *   at the master.
		 * * If we DO NOT have a master-slave - Setup then we have two possibilities
		 *   1) it is a single server
		 *   2) it is the MASTER of n clients
		*/
		$hosts = array();
maddinxx's avatar
maddinxx committed
491

latham's avatar
latham committed
492
493
494
495
496
497
498
499
		if($conf['mysql']['master_slave_setup'] == 'y') {
			/*
			 * it is a master-slave - Setup so the slave has to grant its rights in the master
			 * database
			 */

			//* insert the ispconfig user in the remote server
			$from_host = $conf['hostname'];
maddinxx's avatar
maddinxx committed
500

latham's avatar
latham committed
501
502
503
504
			$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'];

505
506
507
508
509
510
511
512
513
514
515
			$ip_list=array();
			$ip_rec=dns_get_record($conf['hostname'], DNS_A + DNS_AAAA);
			if(!empty($ip_rec)) foreach($ip_rec as $rec => $ip) $ip_list[]=@(isset($ip['ip']))?$ip['ip']:$ip['ipv6'];

			if(!empty($ip_list)) {
				foreach($ip_list 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'];
				}
			}
latham's avatar
latham committed
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
		} else{
			/*
			 * it is NOT a master-slave - Setup so we have to find out all clients and their
			 * host
			 */
			$query = "SELECT Host, User FROM mysql.user WHERE User like 'ispcsrv%' ORDER BY User, Host";
			$data = $this->dbmaster->queryAllRecords($query);
			if($data === false) {
				$this->error('Unable to get the user rights: '.$value['db'].' Error: '.$this->dbmaster->errorMessage);
			}
			foreach ($data as $item){
				$hosts[$item['Host']]['user'] = $item['User'];
				$hosts[$item['Host']]['db'] = $conf['mysql']['master_database'];
				$hosts[$item['Host']]['pwd'] = ''; // the user already exists, so we need no pwd!
			}
		}
maddinxx's avatar
maddinxx committed
532

latham's avatar
latham committed
533
		if(count($hosts) > 0) {
534
535
			foreach($hosts as $host => $value) {
				/*
latham's avatar
latham committed
536
537
538
			 * If a pwd exists, this means, we have to add the new user (and his pwd).
			 * if not, the user already exists and we do not need the pwd
			 */
539
				if ($value['pwd'] != ''){
540
					$query = "CREATE USER ?@? IDENTIFIED BY ?";
541
542
543
					if ($verbose){
						echo "\n\n" . $query ."\n";
					}
544
					$this->dbmaster->query($query, $value['user'], $host, $value['pwd']); // ignore the error
545
				}
latham's avatar
latham committed
546

547
				/*
latham's avatar
latham committed
548
549
550
			 *  Try to delete all rights of the user in case that it exists.
			 *  In Case that it will not exist, do nothing (ignore the error!)
			 */
551
				$query = "REVOKE ALL PRIVILEGES, GRANT OPTION FROM ?@?";
552
				if ($verbose){
553
					echo "\n\n" . $query ."\n";
554
				}
555
				$this->dbmaster->query($query, $value['user'], $host); // ignore the error
latham's avatar
latham committed
556

557
				//* Create the ISPConfig database user in the remote database
558
				$query = "GRANT SELECT ON ?? TO ?@?";
559
560
561
				if ($verbose){
					echo $query ."\n";
				}
562
				if(!$this->dbmaster->query($query, $value['db'] . '.server', $value['user'], $host)) {
563
564
					$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
				}
latham's avatar
latham committed
565

566
				$query = "GRANT SELECT, INSERT ON ?? TO ?@?";
567
568
569
				if ($verbose){
					echo $query ."\n";
				}
570
				if(!$this->dbmaster->query($query, $value['db'] . '.sys_log', $value['user'], $host)) {
571
572
					$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
				}
latham's avatar
latham committed
573

574
				$query = "GRANT SELECT, UPDATE(`status`, `error`) ON ?? TO ?@?";
575
576
577
				if ($verbose){
					echo $query ."\n";
				}
578
				if(!$this->dbmaster->query($query, $value['db'] . '.sys_datalog', $value['user'], $host)) {
579
580
					$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
				}
latham's avatar
latham committed
581

582
				$query = "GRANT SELECT, UPDATE(`status`) ON ?? TO ?@?";
583
584
585
				if ($verbose){
					echo $query ."\n";
				}
586
				if(!$this->dbmaster->query($query, $value['db'] . '.software_update_inst', $value['user'], $host)) {
587
588
					$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
				}
latham's avatar
latham committed
589

590
				$query = "GRANT SELECT, UPDATE(`updated`) ON ?? TO ?@?";
591
592
593
				if ($verbose){
					echo $query ."\n";
				}
594
				if(!$this->dbmaster->query($query, $value['db'] . '.server', $value['user'], $host)) {
595
596
					$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
				}
latham's avatar
latham committed
597

598
				$query = "GRANT SELECT, UPDATE (`ssl`, `ssl_letsencrypt`, `ssl_request`, `ssl_cert`, `ssl_action`, `ssl_key`) ON ?? TO ?@?";
599
600
601
				if ($verbose){
					echo $query ."\n";
				}
602
				if(!$this->dbmaster->query($query, $value['db'] . '.web_domain', $value['user'], $host)) {
603
604
					$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
				}
latham's avatar
latham committed
605

606
				$query = "GRANT SELECT ON ?? TO ?@?";
607
608
609
				if ($verbose){
					echo $query ."\n";
				}
610
				if(!$this->dbmaster->query($query, $value['db'] . '.sys_group', $value['user'], $host)) {
611
612
					$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
				}
latham's avatar
latham committed
613

614
				$query = "GRANT SELECT, UPDATE (`action_state`, `response`) ON ?? TO ?@?";
615
616
617
				if ($verbose){
					echo $query ."\n";
				}
618
				if(!$this->dbmaster->query($query, $value['db'] . '.sys_remoteaction', $value['user'], $host)) {
619
620
					$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
				}
latham's avatar
latham committed
621

622
				$query = "GRANT SELECT, INSERT , DELETE ON ?? TO ?@?";
623
624
625
				if ($verbose){
					echo $query ."\n";
				}
626
				if(!$this->dbmaster->query($query, $value['db'] . '.monitor_data', $value['user'], $host)) {
627
628
					$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
				}
latham's avatar
latham committed
629

630
				$query = "GRANT SELECT, INSERT, UPDATE ON ?? TO ?@?";
631
632
633
				if ($verbose){
					echo $query ."\n";
				}
634
				if(!$this->dbmaster->query($query, $value['db'] . '.mail_traffic', $value['user'], $host)) {
635
636
					$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
				}
latham's avatar
latham committed
637

638
				$query = "GRANT SELECT, INSERT, UPDATE ON ?? TO ?@?";
639
640
641
				if ($verbose){
					echo $query ."\n";
				}
642
				if(!$this->dbmaster->query($query, $value['db'] . '.web_traffic', $value['user'], $host)) {
643
644
					$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
				}
maddinxx's avatar
maddinxx committed
645

646
				$query = "GRANT SELECT, UPDATE, DELETE ON ?? TO ?@?";
647
648
649
				if ($verbose){
					echo $query ."\n";
				}
650
				if(!$this->dbmaster->query($query, $value['db'] . '.aps_instances', $value['user'], $host)) {
651
652
653
					$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
				}
				
654
				$query = "GRANT SELECT, DELETE ON ?? TO ?@?";
655
656
657
				if ($verbose){
					echo $query ."\n";
				}
658
				if(!$this->dbmaster->query($query, $value['db'] . '.aps_instances_settings', $value['user'], $host)) {
659
660
					$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
				}
maddinxx's avatar
maddinxx committed
661

662
				$query = "GRANT SELECT, INSERT, DELETE ON ?? TO ?@?";
663
664
665
				if ($verbose){
					echo $query ."\n";
				}
666
				if(!$this->dbmaster->query($query, $value['db'] . '.web_backup', $value['user'], $host)) {
667
668
					$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
				}
latham's avatar
latham committed
669

670
				$query = "GRANT SELECT, INSERT, DELETE ON ?? TO ?@?";
671
672
673
				if ($verbose){
					echo $query ."\n";
				}
674
				if(!$this->dbmaster->query($query, $value['db'] . '.mail_backup', $value['user'], $host)) {
675
					$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
A. Täffner's avatar
A. Täffner committed
676
677
				}
				
A. Täffner's avatar
A. Täffner committed
678
				$query = "GRANT SELECT, UPDATE(`dnssec_initialized`, `dnssec_info`, `dnssec_last_signed`) ON ?? TO ?@?";
A. Täffner's avatar
A. Täffner committed
679
680
681
682
683
684
				if ($verbose){
					echo $query ."\n";
				}
				if(!$this->dbmaster->query($query, $value['db'] . '.dns_soa', $value['user'], $host)) {
					$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
				}
685
686
687
688
689
690
691
692
				
				$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);
				}
A. Täffner's avatar
A. Täffner committed
693

694
695
			}

latham's avatar
latham committed
696
697
698
699
700
701
702
703
704
705
706
707
708
709
		}

	}

	//** writes postfix configuration files
	public function process_postfix_config($configfile) {
		global $conf;

		$config_dir = $conf['postfix']['config_dir'].'/';
		$full_file_name = $config_dir.$configfile;
		//* Backup exiting file
		if(is_file($full_file_name)) {
			copy($full_file_name, $config_dir.$configfile.'~');
		}
710
		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master');
latham's avatar
latham committed
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
		$content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content);
		$content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content);
		$content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content);
		$content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content);
		$content = str_replace('{server_id}', $conf['server_id'], $content);
		wf($full_file_name, $content);
	}

	public function configure_jailkit() {
		global $conf;

		$cf = $conf['jailkit'];
		$config_dir = $cf['config_dir'];
		$jk_init = $cf['jk_init'];
		$jk_chrootsh = $cf['jk_chrootsh'];

		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.'~');
730
731
732
733
734
735
736
737
738
739
740

			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);
			} else {
				copy('tpl/'.$jk_init.'.master', $config_dir.'/'.$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);
			} else {
				copy('tpl/'.$jk_chrootsh.'.master', $config_dir.'/'.$jk_chrootsh);
			}
latham's avatar
latham committed
741
		}
maddinxx's avatar
maddinxx committed
742

743
744
745
		//* help jailkit fo find its ini files
		if(!is_link('/usr/jk_socketd.ini')) exec('ln -s /etc/jailkit/jk_socketd.ini /usr/jk_socketd.ini');
		if(!is_link('/usr/jk_init.ini')) exec('ln -s /etc/jailkit/jk_init.ini /usr/jk_init.ini');
latham's avatar
latham committed
746
747

	}
maddinxx's avatar
maddinxx committed
748

latham's avatar
latham committed
749
750
751
752
753
754
755
756
757
	public function configure_mailman($status = 'insert') {
		global $conf;

		$config_dir = $conf['mailman']['config_dir'].'/';
		$full_file_name = $config_dir.'mm_cfg.py';
		//* Backup exiting file
		if(is_file($full_file_name)) {
			copy($full_file_name, $config_dir.'mm_cfg.py~');
		}
maddinxx's avatar
maddinxx committed
758

latham's avatar
latham committed
759
		// load files
760
		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/mm_cfg.py.master', 'tpl/mm_cfg.py.master');
latham's avatar
latham committed
761
		$old_file = rf($full_file_name);
maddinxx's avatar
maddinxx committed
762

latham's avatar
latham committed
763
		$old_options = array();
maddinxx's avatar
maddinxx committed
764
		$lines = explode("\n", $old_file);
latham's avatar
latham committed
765
766
		foreach ($lines as $line)
		{
767
			if (trim($line) != '' && substr($line, 0, 1) != '#')
latham's avatar
latham committed
768
			{
769
				@list($key, $value) = @explode("=", $line);
770
				if (isset($value) && $value !== '')
latham's avatar
latham committed
771
772
773
774
775
776
				{
					$key = rtrim($key);
					$old_options[$key] = trim($value);
				}
			}
		}
maddinxx's avatar
maddinxx committed
777

latham's avatar
latham committed
778
779
780
781
782
		$virtual_domains = '';
		if($status == 'update')
		{
			// create virtual_domains list
			$domainAll = $this->db->queryAllRecords("SELECT domain FROM mail_mailinglist GROUP BY domain");
maddinxx's avatar
maddinxx committed
783

784
			if(is_array($domainAll)) {
785
786
787
788
789
790
791
				foreach($domainAll as $domain)
				{
					if ($domainAll[0]['domain'] == $domain['domain'])
						$virtual_domains .= "'".$domain['domain']."'";
					else
						$virtual_domains .= ", '".$domain['domain']."'";
				}
792
			}
latham's avatar
latham committed
793
794
795
		}
		else
			$virtual_domains = "' '";
maddinxx's avatar
maddinxx committed
796

latham's avatar
latham committed
797
		$content = str_replace('{hostname}', $conf['hostname'], $content);
798
		if(!isset($old_options['DEFAULT_SERVER_LANGUAGE']) || $old_options['DEFAULT_SERVER_LANGUAGE'] == '') $old_options['DEFAULT_SERVER_LANGUAGE'] = "'en'";
latham's avatar
latham committed
799
800
		$content = str_replace('{default_language}', $old_options['DEFAULT_SERVER_LANGUAGE'], $content);
		$content = str_replace('{virtual_domains}', $virtual_domains, $content);
801

latham's avatar
latham committed
802
		wf($full_file_name, $content);
803

804
805
806
		//* Write virtual_to_transport.sh script
		$config_dir = $conf['mailman']['config_dir'].'/';
		$full_file_name = $config_dir.'virtual_to_transport.sh';
807

808
809
810
811
		//* Backup exiting virtual_to_transport.sh script
		if(is_file($full_file_name)) {
			copy($full_file_name, $config_dir.'virtual_to_transport.sh~');
		}
812

813
		if(is_dir('/etc/mailman')) {
814
			if(is_file($conf['ispconfig_install_dir'].'/server/conf-custom/install/mailman-virtual_to_transport.sh')) {
815
816
817
818
				copy($conf['ispconfig_install_dir'].'/server/conf-custom/install/mailman-virtual_to_transport.sh', $full_file_name);
			} else {
				copy('tpl/mailman-virtual_to_transport.sh', $full_file_name);
			}
819
			chgrp($full_file_name, $this->mailman_group);
820
			chmod($full_file_name, 0755);
821
822
		}

823
		//* Create aliasaes
824
		if($status == 'install') exec('/usr/lib/mailman/bin/genaliases 2>/dev/null');
825

826
827
		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');
latham's avatar
latham committed
828
829
	}

Michele's avatar
Michele committed
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
	public function configure_mlmmj() {
		global $conf;

		$configDir = $conf['mlmmj']['config_dir'];
		@mkdir($configDir, 0755, true);

		$configFile = 'mlmmj.conf';

		//* Backup exiting file
		if(is_file("$configDir/$configFile")) {
			copy("$configDir/$configFile", "$configDir/$configFile~");
		}

		// load files
		if(is_file($conf['ispconfig_install_dir']."/server/conf-custom/install/$configFile.master")) {
			copy($conf['ispconfig_install_dir']."/server/conf-custom/install/$configFile.master", "$configDir/$configFile");
		} else {
			copy("tpl/$configFile.master", "$configDir/$configFile");
		}

		$mlConfig = @parse_ini_file("$configDir/$configFile");
		// Force PHP7 to use # to mark comments
		if(PHP_MAJOR_VERSION >= 7)
			$mlConfig = array_filter($mlConfig, function($v){return(substr($v,0,1)!=='#');}, ARRAY_FILTER_USE_KEY);

		$command = 'useradd --system mlmmj --home '.$mlConfig['spool_dir'].' --shell /usr/false';
		if(!is_user('mlmmj')) caselog("$command &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");

		@mkdir($mlConfig['spool_dir'], 0755, true);
		chown($mlConfig['spool_dir'], 'mlmmj');
		chgrp($mlConfig['spool_dir'], 'mlmmj');

		// Make a backup copy of master.cf and main.cf files
		copy($conf['postfix']['config_dir'].'/main.cf', $conf['postfix']['config_dir'].'/main.cf~mlmmj');

		//* Update postfix main.cf
		$content  = rf($conf['postfix']['config_dir'].'/main.cf');

		if(!preg_match("/^alias_maps = .*hash:\/etc\/mlmmj\/aliases.*/m", $content)) {
			$content = preg_replace("/^alias_maps = (.*)/m", "$0, hash:$configDir/aliases", $content);
		}

		if(!preg_match("/^alias_database = .*hash:\/etc\/mlmmj\/aliases.*/m", $content)) {
			$content = preg_replace("/^alias_database = (.*)/m", "$0, hash:$configDir/aliases", $content);
		}

		if(!preg_match("/^virtual_alias_maps = .*hash:\/etc\/mlmmj\/virtual.*/m", $content)) {
			$content = preg_replace("/^virtual_alias_maps = (.*)/m", "$0, hash:$configDir/virtual", $content);
		}

		if(!preg_match("/^transport_maps = .*hash:\/etc\/mlmmj\/transport.*/m", $content)) {
			$content = preg_replace("/transport_maps = (.*)/m", "$0, hash:$configDir/transport", $content);
		}

		if(!preg_match("/^mlmmj_destination_recipient_limit.*/m", $content)) {
			$content .= "\n# Only deliver one message to Mlmmj at a time\nmlmmj_destination_recipient_limit = 1\n";
		}

		wf($conf['postfix']['config_dir'].'/main.cf', $content);

		//* Update postfix master.cf
		$content  = rf($conf['postfix']['config_dir'].'/master.cf');
		if(!preg_match('/^mlmmj\s+unix\s+-\s+n\s+n\s+-\s+-\s+pipe\s*$/m', $content)) {
			copy($conf['postfix']['config_dir'].'/master.cf', $conf['postfix']['config_dir'].'/master.cf~mlmmj');
			$content .= "\n# mlmmj mailing lists\n";
			$content .= "mlmmj   unix  -       n       n       -       -       pipe\n";
Michele's avatar
Michele committed
896
			$content .= "  flags=ORhu user=mlmmj argv=/usr/bin/mlmmj-receive -F -L ";
Michele's avatar
Michele committed
897
			$content .= $mlConfig['spool_dir']."/\$nexthop\n\n";
Michele's avatar
Michele committed
898
899
900
901
902
903
904
905
906
907
			wf($conf['postfix']['config_dir'].'/master.cf', $content);
		}

		//* Create aliasaes
		touch("$configDir/aliases");
		exec("nohup /usr/sbin/postalias $configDir/aliases >/dev/null 2>&1");
		touch("$configDir/virtual");
		exec("nohup /usr/sbin/postmap $configDir/virtual >/dev/null 2>&1");
		touch("$configDir/transport");
		exec("nohup /usr/sbin/postmap $configDir/transport >/dev/null 2>&1");
Michele's avatar
Michele committed
908
909

		//* Create/update cron entry
Michele's avatar
Michele committed
910
		$cronEntry = '0 */2 * * * find /var'.$mlConfig['spool_dir'].'/ -mindepth 1 -maxdepth 1 -type d -exec /usr/bin/mlmmj-maintd -F -d {} \;';
Michele's avatar
Michele committed
911
		file_put_contents('/etc/cron.d/mlmmj', $cronEntry);
Michele's avatar
Michele committed
912
913
	}

914
915
916
	public function get_postfix_service($service, $type) {
		global $conf;

917
		exec("postconf -M 2> /dev/null", $out, $ret);
918
919
920
921
922
923
924
925
926

		if ($ret === 0) { //* with postfix >= 2.9 we can detect configured services with postconf
			unset($out);
			exec ("postconf -M $service/$type 2> /dev/null", $out, $ret); //* Postfix >= 2.11
			if (!isset($out[0])) { //* try Postfix 2.9
				exec ("postconf -M $service.$type 2> /dev/null", $out, $ret);
			}
			$postfix_service = @($out[0]=='')?false:true;
        } else { //* fallback - Postfix < 2.9
927
			$content = rf($conf['postfix']['config_dir'].'/master.cf');
928
929
			$regex = "/^((?!#)".$service.".*".$type.".*)$/m"; 
			$postfix_service = @(preg_match($regex, $content))?true:false;
930
931
932
		}

		return $postfix_service;
933
934
	}

latham's avatar
latham committed
935
	public function configure_postfix($options = '') {
Till Brehm's avatar
Till Brehm committed
936
		global $conf,$autoinstall;
latham's avatar
latham committed
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
		$cf = $conf['postfix'];
		$config_dir = $cf['config_dir'];

		if(!is_dir($config_dir)) {
			$this->error("The postfix configuration directory '$config_dir' does not exist.");
		}

		//* mysql-virtual_domains.cf
		$this->process_postfix_config('mysql-virtual_domains.cf');

		//* mysql-virtual_forwardings.cf
		$this->process_postfix_config('mysql-virtual_forwardings.cf');

		//* mysql-virtual_mailboxes.cf
		$this->process_postfix_config('mysql-virtual_mailboxes.cf');

		//* mysql-virtual_email2email.cf
		$this->process_postfix_config('mysql-virtual_email2email.cf');

		//* mysql-virtual_transports.cf
		$this->process_postfix_config('mysql-virtual_transports.cf');

		//* mysql-virtual_recipient.cf
		$this->process_postfix_config('mysql-virtual_recipient.cf');

		//* mysql-virtual_sender.cf
		$this->process_postfix_config('mysql-virtual_sender.cf');

965
966
967
		//* mysql-virtual_sender_login_maps.cf
		$this->process_postfix_config('mysql-virtual_sender_login_maps.cf');

latham's avatar
latham committed
968
969
970
971
972
973
974
975
		//* mysql-virtual_client.cf
		$this->process_postfix_config('mysql-virtual_client.cf');

		//* mysql-virtual_relaydomains.cf
		$this->process_postfix_config('mysql-virtual_relaydomains.cf');

		//* mysql-virtual_relayrecipientmaps.cf
		$this->process_postfix_config('mysql-virtual_relayrecipientmaps.cf');
Rescue9's avatar
Rescue9 committed
976
977
978
		
		//* mysql-virtual_outgoing_bcc.cf
		$this->process_postfix_config('mysql-virtual_outgoing_bcc.cf');
latham's avatar
latham committed
979

980
981
982
983
		//* mysql-virtual_policy_greylist.cf
		$this->process_postfix_config('mysql-virtual_policy_greylist.cf');

		//* mysql-virtual_gids.cf.master
Florian Schaal's avatar
Florian Schaal committed
984
		$this->process_postfix_config('mysql-virtual_gids.cf');
985
986

		//* mysql-virtual_uids.cf
Florian Schaal's avatar
Florian Schaal committed
987
		$this->process_postfix_config('mysql-virtual_uids.cf');
Dominik's avatar
Dominik committed
988

989
990
		//* postfix-dkim
		$full_file_name=$config_dir.'/tag_as_originating.re';
Florian Schaal's avatar
Florian Schaal committed
991
		if(is_file($full_file_name)) copy($full_file_name, $full_file_name.'~');
992
		wf($full_file_name, '/^/ FILTER amavis:[127.0.0.1]:10026');
993
994

		$full_file_name=$config_dir.'/tag_as_foreign.re';
Florian Schaal's avatar
Florian Schaal committed
995
		if(is_file($full_file_name)) copy($full_file_name, $full_file_name.'~');
996
		wf($full_file_name, '/^/ FILTER amavis:[127.0.0.1]:10024');
997

latham's avatar
latham committed
998
		//* Changing mode and group of the new created config files.
999
		caselog('chmod u=rw,g=r,o= '.$config_dir.'/mysql-virtual_*.cf* &> /dev/null',
1000
			__FILE__, __LINE__, 'chmod on mysql-virtual_*.cf*', 'chmod on mysql-virtual_*.cf* failed');
latham's avatar
latham committed
1001
		caselog('chgrp '.$cf['group'].' '.$config_dir.'/mysql-virtual_*.cf* &> /dev/null',
1002
			__FILE__, __LINE__, 'chgrp on mysql-virtual_*.cf*', 'chgrp on mysql-virtual_*.cf* failed');
latham's avatar
latham committed
1003
1004
1005
1006
1007
1008
1009

		//* Creating virtual mail user and group
		$command = 'groupadd -g '.$cf['vmail_groupid'].' '.$cf['vmail_groupname'];
		if(!is_group($cf['vmail_groupname'])) caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");

		$command = 'useradd -g '.$cf['vmail_groupname'].' -u '.$cf['vmail_userid'].' '.$cf['vmail_username'].' -d '.$cf['vmail_mailbox_base'].' -m';
		if(!is_user($cf['vmail_username'])) caselog("$command &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
maddinxx's avatar
maddinxx committed
1010

1011
		//* These postconf commands will be executed on installation and update
1012
		$server_ini_rec = $this->db->queryOneRecord("SELECT config FROM ?? WHERE server_id = ?", $conf["mysql"]["database"] . '.server', $conf['server_id']);
marknl's avatar
marknl committed
1013
1014
1015
1016
1017
		$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
		$rbl_list = '';
1018
		if (@isset($server_ini_array['mail']['realtime_blackhole_list']) && $server_ini_array['mail']['realtime_blackhole_list'] != '') {
1019
			$rbl_hosts = explode(",", str_replace(" ", "", $server_ini_array['mail']['realtime_blackhole_list']));
marknl's avatar
marknl committed
1020
1021
1022
1023
1024
			foreach ($rbl_hosts as $key => $value) {
				$rbl_list .= ", reject_rbl_client ". $value;
			}
		}
		unset($rbl_hosts);
1025

Dominik's avatar
Dominik committed
1026
1027
1028
		//* If Postgrey is installed, configure it
		$greylisting = '';
		if($conf['postgrey']['installed'] == true) {
1029
			$greylisting = ', check_recipient_access mysql:/etc/postfix/mysql-virtual_policy_greylist.cf';
Dominik's avatar
Dominik committed
1030
1031
		}
		
1032
1033
1034
		$reject_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';
Dominik's avatar
Dominik committed
1035
		}
1036
		unset($server_ini_array);
Dominik's avatar
Dominik committed
1037
		
1038
1039
		$tmp = str_replace('.','\.',$conf['hostname']);

1040
1041
1042
1043
		$postconf_placeholders = array('{config_dir}' => $config_dir,
			'{vmail_mailbox_base}' => $cf['vmail_mailbox_base'],
			'{vmail_userid}' => $cf['vmail_userid'],
			'{vmail_groupid}' => $cf['vmail_groupid'],
Dominik's avatar
Dominik committed
1044
1045
			'{rbl_list}' => $rbl_list,
			'{greylisting}' => $greylisting,
1046
			'{reject_slm}' => $reject_sender_login_mismatch,
1047
			'{myhostname}' => $tmp,
Dominik's avatar
Dominik committed
1048
		);
1049
1050
1051
1052

		$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
maddinxx's avatar
maddinxx committed
1053

1054
1055
		//* These postconf commands will be executed on installation only
		if($this->is_update == false) {
1056
1057
1058
1059
1060
			$postconf_commands = array_merge($postconf_commands, array(
					'myhostname = '.$conf['hostname'],
					'mydestination = '.$conf['hostname'].', localhost, localhost.localdomain',
					'mynetworks = 127.0.0.0/8 [::1]/128'
				));
1061
		}
latham's avatar
latham committed
1062
1063
1064
1065
1066
1067

		//* Create the header and body check files
		touch($config_dir.'/header_checks');
		touch($config_dir.'/mime_header_checks');
		touch($config_dir.'/nested_header_checks');
		touch($config_dir.'/body_checks');
maddinxx's avatar
maddinxx committed
1068

latham's avatar
latham committed
1069
		//* Create the mailman files
1070
		if(!is_dir('/var/lib/mailman/data')) exec('mkdir -p /var/lib/mailman/data');
1071
1072
1073
		if(!is_file('/var/lib/mailman/data/aliases')) touch('/var/lib/mailman/data/aliases');
		exec('postalias /var/lib/mailman/data/aliases');
		if(!is_file('/var/lib/mailman/data/virtual-mailman')) touch('/var/lib/mailman/data/virtual-mailman');
tbrehm's avatar
tbrehm committed
1074
		exec('postmap /var/lib/mailman/data/virtual-mailman');
1075
1076
		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');
latham's avatar
latham committed
1077

Jesse Norell's avatar
Jesse Norell committed
1078
1079
1080
1081
		//* Create auxillary postfix conf files
		$configfile = 'helo_access';
		if(is_file($config_dir.'/'.$configfile)) {
			copy($config_dir.'/'.$configfile, $config_dir.'/'.$configfile.'~');
1082
			chmod($config_dir.'/'.$configfile.'~', 0400);
Jesse Norell's avatar
Jesse Norell committed
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
		}
		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master');
		$content = strtr($content, $postconf_placeholders);
		# todo: look up this server's ip addrs and loop through each
		# todo: look up domains hosted on this server and loop through each
		wf($config_dir.'/'.$configfile, $content);

		$configfile = 'blacklist_helo';
		if(is_file($config_dir.'/'.$configfile)) {
			copy($config_dir.'/'.$configfile, $config_dir.'/'.$configfile.'~');
1093
			chmod($config_dir.'/'.$configfile.'~', 0400);
Jesse Norell's avatar
Jesse Norell committed
1094
1095
1096
1097
1098
		}
		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master');
		$content = strtr($content, $postconf_placeholders);
		wf($config_dir.'/'.$configfile, $content);

latham's avatar
latham committed
1099
1100
1101
1102
1103
1104
1105
1106
1107
		//* Make a backup copy of the main.cf file
		copy($config_dir.'/main.cf', $config_dir.'/main.cf~');

		//* 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);
		}

1108
		if(!stristr($options, 'dont-create-certs')) {
latham's avatar
latham committed
1109
			//* Create the SSL certificate
Till Brehm's avatar
Till Brehm committed
1110
			if(AUTOINSTALL){
1111
				$command = 'cd '.$config_dir.'; '
Till Brehm's avatar
Till Brehm committed
1112
					."openssl req -new -subj '/C=".escapeshellcmd($autoinstall['ssl_cert_country'])."/ST=".escapeshellcmd($autoinstall['ssl_cert_state'])."/L=".escapeshellcmd($autoinstall['ssl_cert_locality'])."/O=".escapeshellcmd($autoinstall['ssl_cert_organisation'])."/OU=".escapeshellcmd($autoinstall['ssl_cert_organisation_unit'])."/CN=".escapeshellcmd($autoinstall['ssl_cert_common_name'])."' -outform PEM -out smtpd.cert -newkey rsa:4096 -nodes -keyout smtpd.key -keyform PEM -days 3650 -x509";
1113
1114
1115
1116
			} else {
				$command = 'cd '.$config_dir.'; '
					.'openssl req -new -outform PEM -out smtpd.cert -newkey rsa:4096 -nodes -keyout smtpd.key -keyform PEM -days 3650 -x509';
			}