installer_base.lib.php 76.7 KB
Newer Older
1
2
3
<?php

/*
vogelor's avatar
vogelor committed
4
Copyright (c) 2007-2010, Till Brehm, projektfarm Gmbh
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
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 {
32

33
34
35
36
37
38
39
40
	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


41
42
43
44
45
46
47
	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) {
48
49
		return $text;
	}
50
51

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

	public function simple_query($query, $answers, $default) {
56
57
58
59
60
		$finished = false;
		do {
			$answers_str = implode(',', $answers);
			swrite($this->lng($query).' ('.$answers_str.') ['.$default.']: ');
			$input = sread();
61

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

68
69
70
71
72
			//* Select the default
			if($input == '') {
				$answer = $default;
				$finished = true;
			}
73
74

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

80
81
82
83
		} while ($finished == false);
		swriteln();
		return $answer;
	}
84
85

	public function free_query($query,$default) {
86
87
		swrite($this->lng($query).' ['.$default.']: ');
		$input = sread();
88

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

		$answer =  ($input == '') ? $default : $input;
96
97
98
		swriteln();
		return $answer;
	}
99

100
101
102
103
104
105
106
107
108
	/*
	// TODO: this function is not used atmo I think - pedro
	function request_language(){
		
		swriteln(lng('Enter your language'));
		swriteln(lng('de, en'));
		
	}
	*/
109

110
111
112
	//** Detect installed applications
	public function find_installed_apps() {
		global $conf;
113

114
115
116
117
118
		if(is_installed('mysql') || is_installed('mysqld')) $conf['mysql']['installed'] = true;
		if(is_installed('postfix')) $conf['postfix']['installed'] = true;
		if(is_installed('apache') || is_installed('apache2') || is_installed('httpd')) $conf['apache']['installed'] = true;
		if(is_installed('getmail')) $conf['getmail']['installed'] = true;
		if(is_installed('couriertcpd')) $conf['courier']['installed'] = true;
119
		if(is_installed('dovecot')) $conf['dovecot']['installed'] = true;
120
121
122
123
124
125
		if(is_installed('saslsauthd')) $conf['saslauthd']['installed'] = true;
		if(is_installed('amavisd-new')) $conf['amavis']['installed'] = true;
		if(is_installed('clamdscan')) $conf['clamav']['installed'] = true;
		if(is_installed('pure-ftpd') || is_installed('pure-ftpd-wrapper')) $conf['pureftpd']['installed'] = true;
		if(is_installed('mydns') || is_installed('mydns-ng')) $conf['mydns']['installed'] = true;
		if(is_installed('jk_chrootsh')) $conf['jailkit']['installed'] = true;
126
		if(is_installed('pdns_server') || is_installed('pdns_control')) $conf['powerdns']['installed'] = true;
127
		if(is_installed('named') || is_installed('bind') || is_installed('bind9')) $conf['bind']['installed'] = true;
128

129
	}
130
131

	/** Create the database for ISPConfig */
132
133
	public function configure_database() {
		global $conf;
134

135
136
137
138
		//** Create the database
		if(!$this->db->query('CREATE DATABASE IF NOT EXISTS '.$conf['mysql']['database'].' DEFAULT CHARACTER SET '.$conf['mysql']['charset'])) {
			$this->error('Unable to create MySQL database: '.$conf['mysql']['database'].'.');
		}
139

140
141
		//* Set the database name in the DB library
		$this->db->dbName = $conf['mysql']['database'];
142

143
144
145
146
147
148
		//* 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'] == '') {
149
150
				caselog("mysql --default-character-set=".$conf['mysql']['charset']." -h '".$conf['mysql']['host']."' -u '".$conf['mysql']['admin_user']."' '".$conf['mysql']['database']."' < '".ISPC_INSTALL_ROOT."/install/sql/ispconfig3.sql' &> /dev/null",
						__FILE__, __LINE__, 'read in ispconfig3.sql', 'could not read in ispconfig3.sql');
151
			} else {
vogelor's avatar
vogelor committed
152
				caselog("mysql --default-character-set=".$conf['mysql']['charset']." -h '".$conf['mysql']['host']."' -u '".$conf['mysql']['admin_user']."' -p'".$conf['mysql']['admin_password']."' '".$conf['mysql']['database']."' < '".ISPC_INSTALL_ROOT."/install/sql/ispconfig3.sql' &> /dev/null",
153
						__FILE__, __LINE__, 'read in ispconfig3.sql', 'could not read in ispconfig3.sql');
154
155
156
157
158
			}
			$db_tables = $this->db->getTables();
			if(count($db_tables) == 0) {
				$this->error('Unable to load SQL-Dump into database table.');
			}
159

160
161
162
			//* Load system.ini into the sys_ini table
			$system_ini = $this->db->quote(rf('tpl/system.ini.master'));
			$this->db->query("UPDATE sys_ini SET config = '$system_ini' WHERE sysini_id = 1");
163

164
165
		}
	}
166

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

170
		global $conf;
171

172
173
174
175
176
		if($conf['mysql']['host'] == 'localhost') {
			$from_host = 'localhost';
		} else {
			$from_host = $conf['hostname'];
		}
177

178
179
180
181
		// Delete ISPConfig user in the local database, in case that it exists
		$this->db->query("DELETE FROM mysql.user WHERE User = '".$conf['mysql']['ispconfig_user']."' AND Host = '".$from_host."';");
		$this->db->query("DELETE FROM mysql.db WHERE Db = '".$conf['mysql']['database']."' AND Host = '".$from_host."';");
		$this->db->query('FLUSH PRIVILEGES;');
182

183
		//* Create the ISPConfig database user in the local database
184
185
186
		$query = 'GRANT SELECT, INSERT, UPDATE, DELETE ON '.$conf['mysql']['database'].".* "
				."TO '".$conf['mysql']['ispconfig_user']."'@'".$from_host."' "
				."IDENTIFIED BY '".$conf['mysql']['ispconfig_password']."';";
187
188
189
		if(!$this->db->query($query)) {
			$this->error('Unable to create database user: '.$conf['mysql']['ispconfig_user'].' Error: '.$this->db->errorMessage);
		}
190

191
192
		//* Reload database privelages
		$this->db->query('FLUSH PRIVILEGES;');
193

194
195
		//* Set the database name in the DB library
		$this->db->dbName = $conf['mysql']['database'];
196

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

199
200
		//* Update further distribution specific parameters for server config here
		//* HINT: Every line added here has to be added in update.lib.php too!!
201
202
203
204
205
206
207
208
209
210
		$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'];
		$tpl_ini_array['server']['hostname'] = $conf['hostname'];
		$tpl_ini_array['server']['ip_address'] = @gethostbyname($conf['hostname']);
		$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'];
211
		$tpl_ini_array['cron']['crontab_dir'] = $conf['cron']['crontab_dir'];
tbrehm's avatar
tbrehm committed
212
		$tpl_ini_array['web']['security_level'] = 20;
213
214
		$tpl_ini_array['web']['user'] = $conf['apache']['user'];
		$tpl_ini_array['web']['group'] = $conf['apache']['group'];
215
216
		$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'];
217
218
		$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';
tbrehm's avatar
tbrehm committed
219
220
221
222
223
		$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'];
224

225
226
		$server_ini_content = array_to_ini($tpl_ini_array);
		$server_ini_content = mysql_real_escape_string($server_ini_content);
227

228
229
230
231
232
233
		$mail_server_enabled = ($conf['services']['mail'])?1:0;
		$web_server_enabled = ($conf['services']['web'])?1:0;
		$dns_server_enabled = ($conf['services']['dns'])?1:0;
		$file_server_enabled = ($conf['services']['file'])?1:0;
		$db_server_enabled = ($conf['services']['db'])?1:0;
		$vserver_server_enabled = ($conf['services']['vserver'])?1:0;
234
235
236
237
238
239
240
241
242
243
244
245
246
		
		//** Get the database version number based on the patchfiles
		$found = true;
		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);
247
248


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

251
			//* Insert the server record in master DB
252
			$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`) VALUES (1, 1, 'riud', 'riud', 'r', '".$conf['hostname']."', '$mail_server_enabled', '$web_server_enabled', '$dns_server_enabled', '$file_server_enabled', '$db_server_enabled', '$vserver_server_enabled', '$server_ini_content', 0, 1, $current_db_version);";
253
254
255
			$this->dbmaster->query($sql);
			$conf['server_id'] = $this->dbmaster->insertID();
			$conf['server_id'] = $conf['server_id'];
256

257
			//* Insert the same record in the local DB
258
			$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`) VALUES ('".$conf['server_id']."',1, 1, 'riud', 'riud', 'r', '".$conf['hostname']."', '$mail_server_enabled', '$web_server_enabled', '$dns_server_enabled', '$file_server_enabled', '$db_server_enabled', '$vserver_server_enabled', '$server_ini_content', 0, 1, $current_db_version);";
259
			$this->db->query($sql);
260

261
262
			//* username for the ispconfig user
			$conf['mysql']['master_ispconfig_user'] = 'ispcsrv'.$conf['server_id'];
263
264
265

			$this->grant_master_database_rights();

266
267
		} else {
			//* Insert the server, if its not a mster / slave setup
268
			$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`) VALUES (1, 1, 'riud', 'riud', 'r', '".$conf['hostname']."', '$mail_server_enabled', '$web_server_enabled', '$dns_server_enabled', '$file_server_enabled', '$db_server_enabled', '$vserver_server_enabled', '$server_ini_content', 0, 1, $current_db_version);";
269
270
271
272
			$this->db->query($sql);
			$conf['server_id'] = $this->db->insertID();
			$conf['server_id'] = $conf['server_id'];
		}
273
274


275
	}
276
277
278
279

	public function grant_master_database_rights() {
		global $conf;

280
281
282
283
284
285
286
287
288
289
290
291
292
		/*
		 * 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
		*/
		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
			 */
293

294
295
296
297
298
299
			//* 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'];
300
			$hosts[$from_host]['pwd'] = $conf['mysql']['master_ispconfig_password'];
301
302
303

			$hosts[$from_ip]['user'] = $conf['mysql']['master_ispconfig_user'];
			$hosts[$from_ip]['db'] = $conf['mysql']['master_database'];
304
			$hosts[$from_ip]['pwd'] = $conf['mysql']['master_ispconfig_password'];
305
306
307
308
309
310
311
312
313
314
315
316
317
		} 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'];
318
				$hosts[$item['Host']]['pwd'] = ''; // the user already exists, so we need no pwd!
319
320
			}
		}
321
322
		
		if(is_array($hosts)) {
323
324
		foreach($hosts as $host => $value) {
			/*
325
326
			 * 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
327
			 */
328
329
330
			if ($value['pwd'] != ''){
				$query = "CREATE USER '".$value['user']."'@'".$host."' IDENTIFIED BY '" . $value['pwd'] . "'";
				$this->dbmaster->query($query); // ignore the error
331
			}
332

333
334
335
336
337
338
339
			/*
			 *  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!)
			 */
			$query = "REVOKE ALL PRIVILEGES, GRANT OPTION FROM '".$value['user']."'@'".$host."' ";
			$this->dbmaster->query($query); // ignore the error

340
			//* Create the ISPConfig database user in the remote database
341
			$query = "GRANT SELECT ON ".$value['db'].".`server` TO '".$value['user']."'@'".$host."' ";
342
			if(!$this->dbmaster->query($query)) {
343
				$this->error('Unable to set rights of user in master database: '.$value['db'].' Error: '.$this->dbmaster->errorMessage);
344
345
			}

346
			$query = "GRANT SELECT, INSERT ON ".$value['db'].".`sys_log` TO '".$value['user']."'@'".$host."' ";
347
			if(!$this->dbmaster->query($query)) {
348
				$this->error('Unable to set rights of user in master database: '.$value['db'].' Error: '.$this->dbmaster->errorMessage);
349
350
			}

351
			$query = "GRANT SELECT, UPDATE(`status`) ON ".$value['db'].".`sys_datalog` TO '".$value['user']."'@'".$host."' ";
352
			if(!$this->dbmaster->query($query)) {
353
				$this->error('Unable to set rights of user in master database: '.$value['db'].' Error: '.$this->dbmaster->errorMessage);
354
355
			}

356
			$query = "GRANT SELECT, UPDATE(`status`) ON ".$value['db'].".`software_update_inst` TO '".$value['user']."'@'".$host."' ";
357
			if(!$this->dbmaster->query($query)) {
358
				$this->error('Unable to set rights of user in master database: '.$value['db'].' Error: '.$this->dbmaster->errorMessage);
359
360
			}

361
			$query = "GRANT SELECT, UPDATE(`updated`) ON ".$value['db'].".`server` TO '".$value['user']."'@'".$host."' ";
362
			if(!$this->dbmaster->query($query)) {
363
				$this->error('Unable to set rights of user in master database: '.$value['db'].' Error: '.$this->dbmaster->errorMessage);
364
365
			}

366
			$query = "GRANT SELECT, UPDATE (`ssl_request`, `ssl_cert`, `ssl_action`) ON ".$value['db'].".`web_domain` TO '".$value['user']."'@'".$host."' ";
367
			if(!$this->dbmaster->query($query)) {
368
				$this->error('Unable to set rights of user in master database: '.$value['db'].' Error: '.$this->dbmaster->errorMessage);
369
370
			}

371
			$query = "GRANT SELECT ON ".$value['db'].".`sys_group` TO '".$value['user']."'@'".$host."' ";
372
			if(!$this->dbmaster->query($query)) {
373
				$this->error('Unable to set rights of user in master database: '.$value['db'].' Error: '.$this->dbmaster->errorMessage);
374
375
			}

376
			$query = "GRANT SELECT, UPDATE (`action_state`, `response`) ON ".$value['db'].".`sys_remoteaction` TO '".$value['user']."'@'".$host."' ";
377
			if(!$this->dbmaster->query($query)) {
378
				$this->error('Unable to set rights of user in master database: '.$value['db'].' Error: '.$this->dbmaster->errorMessage);
379
380
			}

381
			$query = "GRANT SELECT, INSERT , DELETE ON ".$value['db'].".`monitor_data` TO '".$value['user']."'@'".$host."' ";
382
			if(!$this->dbmaster->query($query)) {
383
				$this->error('Unable to set rights of user in master database: '.$value['db'].' Error: '.$this->dbmaster->errorMessage);
384
385
			}

386
			$query = "GRANT SELECT, INSERT, UPDATE ON ".$value['db'].".`mail_traffic` TO '".$value['user']."'@'".$host."' ";
387
			if(!$this->dbmaster->query($query)) {
388
				$this->error('Unable to set rights of user in master database: '.$value['db'].' Error: '.$this->dbmaster->errorMessage);
389
390
			}

391
			$query = "GRANT SELECT, INSERT, UPDATE ON ".$value['db'].".`web_traffic` TO '".$value['user']."'@'".$host."' ";
392
			if(!$this->dbmaster->query($query)) {
393
				$this->error('Unable to set rights of user in master database: '.$value['db'].' Error: '.$this->dbmaster->errorMessage);
394
395
396
			}
		}

397
398
399
400
		/*
		 * It is all done. Relod the rights...
		 */
		$this->dbmaster->query('FLUSH PRIVILEGES;');
401
		}
402

403
404
405
406
	}

	//** writes postfix configuration files
	public function process_postfix_config($configfile) {
407
		global $conf;
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426

		$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.'~');
		}
		$content = rf('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);
		wf($full_file_name, $content);
	}

	public function configure_jailkit() {
		global $conf;

427
428
429
430
		$cf = $conf['jailkit'];
		$config_dir = $cf['config_dir'];
		$jk_init = $cf['jk_init'];
		$jk_chrootsh = $cf['jk_chrootsh'];
431
432

		if (is_dir($config_dir)) {
433
			if(is_file($config_dir.'/'.$jk_init)) copy($config_dir.'/'.$jk_init, $config_dir.'/'.$jk_init.'~');
434
			if(is_file($config_dir.'/'.$jk_chrootsh.'.master')) copy($config_dir.'/'.$jk_chrootsh.'.master', $config_dir.'/'.$jk_chrootsh.'~');
435

436
437
			copy('tpl/'.$jk_init.'.master', $config_dir.'/'.$jk_init);
			copy('tpl/'.$jk_chrootsh.'.master', $config_dir.'/'.$jk_chrootsh);
438
		}
439
440
441
442
443

	}

	public function configure_postfix($options = '') {
		global $conf;
444
445
		$cf = $conf['postfix'];
		$config_dir = $cf['config_dir'];
446
447
448
449
450

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

451
		//* mysql-virtual_domains.cf
452
		$this->process_postfix_config('mysql-virtual_domains.cf');
453
454

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

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

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

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

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

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

		//* mysql-virtual_client.cf
473
474
		$this->process_postfix_config('mysql-virtual_client.cf');

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

478
		//* mysql-virtual_relayrecipientmaps.cf
479
		$this->process_postfix_config('mysql-virtual_relayrecipientmaps.cf');
480
481
482

		//* Changing mode and group of the new created config files.
		caselog('chmod o= '.$config_dir.'/mysql-virtual_*.cf* &> /dev/null',
483
484
485
486
				__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');

487
488
489
490
491
		//* 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';
492
		if(!is_user($cf['vmail_username'])) caselog("$command &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
493
494

		$postconf_commands = array (
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
				'myhostname = '.$conf['hostname'],
				'mydestination = '.$conf['hostname'].', localhost, localhost.localdomain',
				'mynetworks = 127.0.0.0/8 [::1]/128',
				'virtual_alias_domains =',
				'virtual_alias_maps = proxy:mysql:'.$config_dir.'/mysql-virtual_forwardings.cf, mysql:'.$config_dir.'/mysql-virtual_email2email.cf',
				'virtual_mailbox_domains = proxy:mysql:'.$config_dir.'/mysql-virtual_domains.cf',
				'virtual_mailbox_maps = proxy:mysql:'.$config_dir.'/mysql-virtual_mailboxes.cf',
				'virtual_mailbox_base = '.$cf['vmail_mailbox_base'],
				'virtual_uid_maps = static:'.$cf['vmail_userid'],
				'virtual_gid_maps = static:'.$cf['vmail_groupid'],
				'smtpd_sasl_auth_enable = yes',
				'broken_sasl_auth_clients = yes',
				'smtpd_sasl_authenticated_header = yes',
				'smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, check_recipient_access mysql:'.$config_dir.'/mysql-virtual_recipient.cf, reject_unauth_destination',
				'smtpd_use_tls = yes',
				'smtpd_tls_security_level = may',
				'smtpd_tls_cert_file = '.$config_dir.'/smtpd.cert',
				'smtpd_tls_key_file = '.$config_dir.'/smtpd.key',
				'transport_maps = proxy:mysql:'.$config_dir.'/mysql-virtual_transports.cf',
				'relay_domains = mysql:'.$config_dir.'/mysql-virtual_relaydomains.cf',
				'relay_recipient_maps = mysql:'.$config_dir.'/mysql-virtual_relayrecipientmaps.cf',
				'virtual_create_maildirsize = yes',
				'virtual_maildir_extended = yes',
				'virtual_mailbox_limit_maps = proxy:mysql:'.$config_dir.'/mysql-virtual_mailbox_limit_maps.cf',
				'virtual_mailbox_limit_override = yes',
				'virtual_maildir_limit_message = "The user you are trying to reach is over quota."',
				'virtual_overquota_bounce = yes',
				'proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $virtual_mailbox_limit_maps',
				'smtpd_sender_restrictions = check_sender_access mysql:'.$config_dir.'/mysql-virtual_sender.cf',
				'smtpd_client_restrictions = check_client_access mysql:'.$config_dir.'/mysql-virtual_client.cf',
				'maildrop_destination_concurrency_limit = 1',
				'maildrop_destination_recipient_limit   = 1',
				'virtual_transport = maildrop',
				'header_checks = regexp:'.$config_dir.'/header_checks',
				'mime_header_checks = regexp:'.$config_dir.'/mime_header_checks',
				'nested_header_checks = regexp:'.$config_dir.'/nested_header_checks',
				'body_checks = regexp:'.$config_dir.'/body_checks'
532
		);
533

534
535
536
537
538
		//* 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');
539
540


541
542
		//* Make a backup copy of the main.cf file
		copy($config_dir.'/main.cf', $config_dir.'/main.cf~');
543

544
545
546
547
548
		//* 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);
		}
549

550
551
552
		if(!stristr($options,'dont-create-certs')) {
			//* Create the SSL certificate
			$command = 'cd '.$config_dir.'; '
553
					.'openssl req -new -outform PEM -out smtpd.cert -newkey rsa:2048 -nodes -keyout smtpd.key -keyform PEM -days 365 -x509';
554
			exec($command);
555

556
557
558
			$command = 'chmod o= '.$config_dir.'/smtpd.key';
			caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command);
		}
559

560
561
		//** We have to change the permissions of the courier authdaemon directory to make it accessible for maildrop.
		$command = 'chmod 755  /var/run/courier/authdaemon/';
562
		if(is_file('/var/run/courier/authdaemon/')) caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command);
563

564
		//* Changing maildrop lines in posfix master.cf
565
566
567
568
		if(is_file($config_dir.'/master.cf')) {
			copy($config_dir.'/master.cf', $config_dir.'/master.cf~');
		}
		if(is_file($config_dir.'/master.cf~')) {
569
			chmod($config_dir.'/master.cf~', 0400);
570
		}
571
572
		$configfile = $config_dir.'/master.cf';
		$content = rf($configfile);
573
574
575
		$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);
576
		wf($configfile, $content);
577

578
579
		//* Writing the Maildrop mailfilter file
		$configfile = 'mailfilter';
580
581
582
		if(is_file($cf['vmail_mailbox_base'].'/.'.$configfile)) {
			copy($cf['vmail_mailbox_base'].'/.'.$configfile, $cf['vmail_mailbox_base'].'/.'.$configfile.'~');
		}
583
		$content = rf('tpl/'.$configfile.'.master');
584
585
		$content = str_replace('{dist_postfix_vmail_mailbox_base}', $cf['vmail_mailbox_base'], $content);
		wf($cf['vmail_mailbox_base'].'/.'.$configfile, $content);
586

587
588
589
590
591
		//* Create the directory for the custom mailfilters
		if(!is_dir($cf['vmail_mailbox_base'].'/mailfilters')) {
			$command = 'mkdir '.$cf['vmail_mailbox_base'].'/mailfilters';
			caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		}
592

593
594
595
		//* Chmod and chown the .mailfilter file
		$command = 'chown -R '.$cf['vmail_username'].':'.$cf['vmail_groupname'].' '.$cf['vmail_mailbox_base'].'/.mailfilter';
		caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
596

597
598
		$command = 'chmod -R 600 '.$cf['vmail_mailbox_base'].'/.mailfilter';
		caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
599

600
	}
601

602
603
	public function configure_saslauthd() {
		global $conf;
604
605


606
		$configfile = 'sasl_smtpd.conf';
607
608
609
		if(is_file($conf['postfix']['config_dir'].'/sasl/smtpd.conf')) copy($conf['postfix']['config_dir'].'/sasl/smtpd.conf',$conf['postfix']['config_dir'].'/sasl/smtpd.conf~');
		if(is_file($conf['postfix']['config_dir'].'/sasl/smtpd.conf~')) chmod($conf['postfix']['config_dir'].'/sasl/smtpd.conf~', 0400);
		$content = rf('tpl/'.$configfile.'.master');
610
611
612
613
		$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);
614
		wf($conf['postfix']['config_dir'].'/sasl/smtpd.conf',$content);
615

616
		// TODO: Chmod and chown on the config file
617
618


619
		// Recursively create the spool directory
620
		if(!@is_dir('/var/spool/postfix/var/run/saslauthd')) mkdir('/var/spool/postfix/var/run/saslauthd', 0755, true);
621

622
		// Edit the file /etc/default/saslauthd
623
		$configfile = $conf['saslauthd']['config'];
624
		if(is_file($configfile)) copy($configfile,$configfile.'~');
625
		if(is_file($configfile.'~')) chmod($configfile.'~', 0400);
626
627
628
629
630
631
632
		$content = rf($configfile);
		$content = str_replace('START=no','START=yes',$content);
		// Debian
		$content = str_replace('OPTIONS="-c"','OPTIONS="-m /var/spool/postfix/var/run/saslauthd -r"',$content);
		// Ubuntu
		$content = str_replace('OPTIONS="-c -m /var/run/saslauthd"','OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd -r"',$content);
		wf($configfile,$content);
633

634
		// Edit the file /etc/init.d/saslauthd
635
		$configfile = $conf['init_scripts'].'/'.$conf['saslauthd']['init_script'];
636
637
638
		$content = rf($configfile);
		$content = str_replace('PIDFILE=$RUN_DIR/saslauthd.pid','PIDFILE="/var/spool/postfix/var/run/${NAME}/saslauthd.pid"',$content);
		wf($configfile,$content);
639

640
		// add the postfix user to the sasl group (at least necessary for Ubuntu 8.04 and most likely Debian Lenny as well.
641
		exec('adduser postfix sasl');
642
643


644
	}
645
646

	public function configure_pam() {
647
648
649
650
		global $conf;
		$pam = $conf['pam'];
		//* configure pam for SMTP authentication agains the ispconfig database
		$configfile = 'pamd_smtp';
651
652
		if(is_file($pam.'/smtp'))    copy($pam.'/smtp', $pam.'/smtp~');
		if(is_file($pam.'/smtp~'))   chmod($pam.'/smtp~', 0400);
653

654
		$content = rf('tpl/'.$configfile.'.master');
655
656
657
658
		$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);
659
		wf($pam.'/smtp', $content);
660
		// On some OSes smtp is world readable which allows for reading database information.  Removing world readable rights should have no effect.
661
662
663
664
		if(is_file($pam.'/smtp'))    exec("chmod o= $pam/smtp");
		chmod($pam.'/smtp', 0660);
		chown($pam.'/smtp', 'daemon');
		chgrp($pam.'/smtp', 'daemon');
665

666
	}
667
668

	public function configure_courier() {
669
670
671
672
		global $conf;
		$config_dir = $conf['courier']['config_dir'];
		//* authmysqlrc
		$configfile = 'authmysqlrc';
673
674
		if(is_file($config_dir.'/'.$configfile)) {
			copy($config_dir.'/'.$configfile, $config_dir.'/'.$configfile.'~');
675
		}
676
677
		chmod($config_dir.'/'.$configfile.'~', 0400);
		$content = rf('tpl/'.$configfile.'.master');
678
679
680
681
		$content = str_replace('{mysql_server_ispconfig_user}',$conf['mysql']['ispconfig_user'],$content);
		$content = str_replace('{mysql_server_ispconfig_password}',$conf['mysql']['ispconfig_password'], $content);
		$content = str_replace('{mysql_server_database}',$conf['mysql']['database'],$content);
		$content = str_replace('{mysql_server_host}',$conf['mysql']['host'],$content);
682
		wf($config_dir.'/'.$configfile, $content);
683

684
685
686
		chmod($config_dir.'/'.$configfile, 0660);
		chown($config_dir.'/'.$configfile, 'daemon');
		chgrp($config_dir.'/'.$configfile, 'daemon');
687

688
		//* authdaemonrc
689
		$configfile = $config_dir.'/authdaemonrc';
690
691
692
693
		if(is_file($configfile)) {
			copy($configfile, $configfile.'~');
		}
		if(is_file($configfile.'~')) {
694
			chmod($configfile.'~', 0400);
695
		}
696
697
698
699
		$content = rf($configfile);
		$content = str_replace('authmodulelist="authpam"', 'authmodulelist="authmysql"', $content);
		wf($configfile, $content);
	}
700
701

	public function configure_dovecot() {
702
		global $conf;
703

704
		$config_dir = $conf['dovecot']['config_dir'];
705

706
		//* Configure master.cf and add a line for deliver
707
708
709
710
		if(is_file($config_dir.'/master.cf')) {
			copy($config_dir.'/master.cf', $config_dir.'/master.cf~2');
		}
		if(is_file($config_dir.'/master.cf~')) {
711
			chmod($config_dir.'/master.cf~2', 0400);
712
		}
713
		$content = rf($conf['postfix']['config_dir'].'/master.cf');
714
		// Only add the content if we had not addded it before
715
		if(!stristr($content,'dovecot/deliver')) {
716
			$deliver_content = 'dovecot   unix  -       n       n       -       -       pipe'."\n".'  flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${user}@${nexthop}';
717
			af($conf['postfix']['config_dir'].'/master.cf',$deliver_content);
718
719
720
		}
		unset($content);
		unset($deliver_content);
721
722


723
724
725
		//* Reconfigure postfix to use dovecot authentication
		// Adding the amavisd commands to the postfix configuration
		$postconf_commands = array (
726
727
728
729
				'dovecot_destination_recipient_limit = 1',
				'virtual_transport = dovecot',
				'smtpd_sasl_type = dovecot',
				'smtpd_sasl_path = private/auth'
730
		);
731

732
		// Make a backup copy of the main.cf file
733
		copy($conf['postfix']['config_dir'].'/main.cf',$conf['postfix']['config_dir'].'/main.cf~3');
734

735
736
737
738
739
		// 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");
		}
740

741
742
		//* copy dovecot.conf
		$configfile = 'dovecot.conf';
743
744
		if(is_file($config_dir.'/'.$configfile)) {
			copy($config_dir.'/'.$configfile, $config_dir.'/'.$configfile.'~');
745
		}
746
		copy('tpl/debian_dovecot.conf.master',$config_dir.'/'.$configfile);
747

748
749
		//* dovecot-sql.conf
		$configfile = 'dovecot-sql.conf';
750
751
		if(is_file($config_dir.'/'.$configfile)) {
			copy($config_dir.'/'.$configfile, $config_dir.'/'.$configfile.'~');
752
		}
753
754
		chmod($config_dir.'/'.$configfile.'~', 0400);
		$content = rf('tpl/debian_dovecot-sql.conf.master');
755
756
757
758
		$content = str_replace('{mysql_server_ispconfig_user}',$conf['mysql']['ispconfig_user'],$content);
		$content = str_replace('{mysql_server_ispconfig_password}',$conf['mysql']['ispconfig_password'], $content);
		$content = str_replace('{mysql_server_database}',$conf['mysql']['database'],$content);
		$content = str_replace('{mysql_server_host}',$conf['mysql']['host'],$content);
759
		wf($config_dir.'/'.$configfile, $content);
760

761
762
763
		chmod($config_dir.'/'.$configfile, 0600);
		chown($config_dir.'/'.$configfile, 'root');
		chgrp($config_dir.'/'.$configfile, 'root');
764
765

	}
766

767
768
	public function configure_amavis() {
		global $conf;
769

770
771
		// amavisd user config file
		$configfile = 'amavisd_user_config';
772
773
774
		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~');
		if(is_file($conf['amavis']['config_dir'].'/conf.d/50-user~')) chmod($conf['amavis']['config_dir'].'/conf.d/50-user~', 0400);
		$content = rf('tpl/'.$configfile.'.master');
775
776
777
		$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);
778
		$content = str_replace('{mysql_server_port}',$conf['mysql']['port'],$content);
779
		$content = str_replace('{mysql_server_ip}',$conf['mysql']['ip'],$content);
780
		wf($conf['amavis']['config_dir'].'/conf.d/50-user',$content);
781

782
		// TODO: chmod and chown on the config file
783
784


785
786
		// Adding the amavisd commands to the postfix configuration
		$postconf_commands = array (
787
788
				'content_filter = amavis:[127.0.0.1]:10024',
				'receive_override_options = no_address_mappings'
789
		);
790

791
		// Make a backup copy of the main.cf file
792
		copy($conf['postfix']['config_dir'].'/main.cf',$conf['postfix']['config_dir'].'/main.cf~2');
793

794
795
796
797
798
		// 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");
		}
799

800
		// Append the configuration for amavisd to the master.cf file
801
802
		if(is_file($conf['postfix']['config_dir'].'/master.cf')) copy($conf['postfix']['config_dir'].'/master.cf',$conf['postfix']['config_dir'].'/master.cf~');
		$content = rf($conf['postfix']['config_dir'].'/master.cf');
803
		// Only add the content if we had not addded it before
804
		if(!stristr($content,'127.0.0.1:10025')) {
805
			unset($content);
806
807
			$content = rf('tpl/master_cf_amavis.master');
			af($conf['postfix']['config_dir'].'/master.cf',$content);
808
809
		}
		unset($content);
810

811
812
		// Add the clamav user to the amavis group
		exec('adduser clamav amavis');
813
814


815
	}
816
817

	public function configure_spamassassin() {
818
		global $conf;
819

820
821
		//* Enable spamasasssin on debian and ubuntu
		$configfile = '/etc/default/spamassassin';
822
823
824
		if(is_file($configfile)) {
			copy($configfile, $configfile.'~');
		}
825
826
827
828
		$content = rf($configfile);
		$content = str_replace('ENABLED=0', 'ENABLED=1', $content);
		wf($configfile, $content);
	}
829
830

	public function configure_getmail() {
831
		global $conf;
832

833
		$config_dir = $conf['getmail']['config_dir'];
834

835
		if(!@is_dir($config_dir)) mkdir(escapeshellcmd($config_dir), 0700, true);
836

837
		$command = 'useradd -d '.$config_dir.' getmail';
838
		if(!is_user('getmail')) caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
839

840
841
		$command = "chown -R getmail $config_dir";
		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
842

843
844
845
		$command = "chmod -R 700 $config_dir";
		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
	}
846
847
848


	public function configure_pureftpd() {
849
		global $conf;
850

851
852
		$config_dir = $conf['pureftpd']['config_dir'];

853
		//* configure pure-ftpd for MySQL authentication against the ispconfig database
854
		$configfile = 'db/mysql.conf';
855
856
		if(is_file($config_dir.'/'.$configfile)) {
			copy($config_dir.'/'.$configfile, $config_dir.'/'.$configfile.'~');
857
		}
858
859
		if(is_file($config_dir.'/'.$configfile.'~')) {
			chmod($config_dir.'/'.$configfile.'~', 0400);
860
		}
861
		$content = rf('tpl/pureftpd_mysql.conf.master');
862
863
864
865
866
867
868
869
870
		$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($config_dir.'/'.$configfile, $content);
		chmod($config_dir.'/'.$configfile, 0600);
		chown($config_dir.'/'.$configfile, 'root');
		chgrp($config_dir.'/'.$configfile, 'root');
871
872
873
874
		// **enable chrooting
		//exec('mkdir -p '.$config_dir.'/conf/ChrootEveryone');
		exec('echo "yes" > '.$config_dir.'/conf/ChrootEveryone');
		exec('echo "yes" > '.$config_dir.'/conf/BrokenClientsCompatibility');