gentoo.lib.php 46 KB
Newer Older
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
<?php

/*
Copyright (c) 2007, 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.
*/

31
class installer extends installer_base
32 33
{
	public function configure_jailkit()
34 35 36
	{
		global $conf;

37 38
		if (is_dir($conf['jailkit']['config_dir']))
		{
wyrie's avatar
wyrie committed
39
			$jkinit_content = $this->get_template_file($conf['jailkit']['jk_init'], true); //* get contents
40
			$this->write_config_file($conf['jailkit']['config_dir'] . '/' . $conf['jailkit']['jk_init'], $jkinit_content);
41

wyrie's avatar
wyrie committed
42
			$jkchroot_content = $this->get_template_file($conf['jailkit']['jk_chrootsh'], true); //* get contents
43 44
			$this->write_config_file($conf['jailkit']['config_dir'] . '/' . $conf['jailkit']['jk_chrootsh'], $jkchroot_content);
		}
45

wyrie's avatar
wyrie committed
46 47
		$command = 'chown root:root /var/www';
		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
48 49
	}

50
	public function configure_postfix($options = '')
51 52 53 54
	{
		global $conf;

		$cf = $conf['postfix'];
55
		$config_dir = $cf['config_dir'];
56

57
		if(!is_dir($config_dir)){
58 59 60 61 62 63 64 65
			$this->error("The postfix configuration directory '$config_dir' does not exist.");
		}

		//* Install virtual mappings
		foreach (glob('tpl/mysql-virtual_*.master') as $filename) {
			$this->process_postfix_config( basename($filename, '.master') );
		}

wyrie's avatar
wyrie committed
66
		//* Changing mode and group of the new created config files.
67
		caselog('chmod o= '.$config_dir.'/mysql-virtual_*.cf* &> /dev/null',
68 69 70 71
			__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');

wyrie's avatar
wyrie committed
72
		//* Creating virtual mail user and group
73 74 75 76
		$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");
		}
77

78 79
		$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'])) {
80
			caselog("$command &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
81
		}
82

83
		//* These postconf commands will be executed on installation and update
84 85 86 87 88 89 90 91 92 93
		$postconf_placeholders = array('{config_dir}' => $config_dir,
			'{vmail_mailbox_base}' => $cf['vmail_mailbox_base'],
			'{vmail_userid}' => $cf['vmail_userid'],
			'{vmail_groupid}' => $cf['vmail_groupid'],
			'{rbl_list}' => $rbl_list);

		$postconf_tpl = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/gentoo_postfix.conf.master', 'tpl/gentoo_postfix.conf.master');
		$postconf_tpl = strtr($postconf_tpl, $postconf_placeholders);
		$postconf_commands = array_filter(explode("\n", $postconf_tpl)); // read and remove empty lines

94 95
		//* These postconf commands will be executed on installation only
		if($this->is_update == false) {
96 97 98 99 100
			$postconf_commands = array_merge($postconf_commands, array(
					'myhostname = '.$conf['hostname'],
					'mydestination = '.$conf['hostname'].', localhost, localhost.localdomain',
					'mynetworks = 127.0.0.0/8 [::1]/128'
				));
101
		}
102

wyrie's avatar
wyrie committed
103
		//* Create the header and body check files
104 105 106 107
		touch($config_dir.'/header_checks');
		touch($config_dir.'/mime_header_checks');
		touch($config_dir.'/nested_header_checks');
		touch($config_dir.'/body_checks');
108 109


wyrie's avatar
wyrie committed
110
		//* Make a backup copy of the main.cf file
111
		copy($config_dir.'/main.cf', $config_dir.'/main.cf~');
112

wyrie's avatar
wyrie committed
113
		//* Executing the postconf commands
114 115
		foreach($postconf_commands as $cmd) {
			$command = "postconf -e '$cmd'";
wyrie's avatar
wyrie committed
116
			caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command);
117
		}
118

wyrie's avatar
wyrie committed
119
		//* Create the SSL certificate
120
		if (!stristr($options, 'dont-create-certs'))
121 122
		{
			$command = 'cd '.$config_dir.'; '
123
				.'openssl req -new -outform PEM -out smtpd.cert -newkey rsa:2048 -nodes -keyout smtpd.key -keyform PEM -days 365 -x509';
124
			exec($command);
125

126 127 128
			$command = 'chmod o= '.$config_dir.'/smtpd.key';
			caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command);
		}
129

wyrie's avatar
wyrie committed
130 131 132 133 134
		//* We have to change the permissions of the courier authdaemon directory to make it accessible for maildrop.
		$command = 'chmod 755  /var/lib/courier/authdaemon/';
		if (is_dir('/var/lib/courier/authdaemon')) {
			caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command);
		}
135

wyrie's avatar
wyrie committed
136
		//* Changing maildrop lines in posfix master.cf
137 138 139
		$configfile = $config_dir.'/master.cf';
		$content = rf($configfile);

140 141 142 143 144
		$content = preg_replace('/^#?maildrop/m', 'maildrop', $content);
		$content = preg_replace('/^#?(\s+)flags=DRhu user=vmail argv=\/usr\/bin\/maildrop -d/m',
			'$1flags=DRhu user=vmail argv=/usr/bin/maildrop -d vmail \${extension} \${recipient} \${user} \${nexthop} \${sender}',
			$content);

145
		$this->write_config_file($configfile, $content);
146

wyrie's avatar
wyrie committed
147
		//* Writing the Maildrop mailfilter file
148
		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/mailfilter.master', 'tpl/mailfilter.master');
149
		$content = str_replace('{dist_postfix_vmail_mailbox_base}', $cf['vmail_mailbox_base'], $content);
150

151
		$this->write_config_file($cf['vmail_mailbox_base'].'/.mailfilter', $content);
152

wyrie's avatar
wyrie committed
153
		//* Create the directory for the custom mailfilters
154
		if (!is_dir($cf['vmail_mailbox_base'].'/mailfilters'))
155 156
		{
			$command = 'mkdir '.$cf['vmail_mailbox_base'].'/mailfilters';
wyrie's avatar
wyrie committed
157
			caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
158
		}
159 160 161 162 163

		//* postfix-dkim
		$full_file_name=$config_dir.'/tag_as_originating.re';
		if(is_file($full_file_name)) {
			copy($full_file_name, $config_dir.$configfile.'~');
164 165 166 167 168 169 170 171 172
		}
		$this->write_config_file($full_file_name, '/^/ FILTER amavis:[127.0.0.1]:10026');

		$full_file_name=$config_dir.'/tag_as_foreign.re';
		if(is_file($full_file_name)) {
			copy($full_file_name, $config_dir.$configfile.'~');
		}
		$this->write_config_file($full_file_name, '/^/ FILTER amavis:[127.0.0.1]:10024');

wyrie's avatar
wyrie committed
173
		//* Chmod and chown the .mailfilter file
174 175
		$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");
176

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

180
	}
181 182

	public function configure_saslauthd()
183 184
	{
		global $conf;
185

wyrie's avatar
wyrie committed
186
		$content = $this->get_template_file('sasl_smtpd.conf', true, true); //* get contents & insert db cred
187
		$this->write_config_file($conf['saslauthd']['config_dir'].'/smtpd.conf', $content);
188

wyrie's avatar
wyrie committed
189 190
		//* Edit the file saslauthd config file
		$content = rf($conf['saslauthd']['config_file']);
191
		$content = preg_replace('/(?<=\n)SASLAUTHD_OPTS="\$\{SASLAUTHD_OPTS\}[^"]+"/', 'SASLAUTHD_OPTS="${SASLAUTHD_OPTS} -a pam -r -c -s 128 -t 30 -n 5"', $content);
192

wyrie's avatar
wyrie committed
193
		$this->write_config_file($conf['saslauthd']['config_file'], $content);
194
	}
195

196
	public function configure_courier()
197 198 199
	{
		global $conf;

wyrie's avatar
wyrie committed
200 201
		//* authmysqlrc
		$content = $this->get_template_file('authmysqlrc', true, true); //* get contents & insert db cred
202
		$this->write_config_file($conf['courier']['config_dir'].'/authmysqlrc', $content);
203

wyrie's avatar
wyrie committed
204
		//* authdaemonrc
205 206 207 208 209
		$configfile = $conf['courier']['config_dir'].'/authdaemonrc';

		$content = rf($configfile);
		$content = preg_replace('/(?<=\n)authmodulelist="[^"]+"/', "authmodulelist=\"authmysql\"", $content);
		$this->write_config_file($configfile, $content);
210

wyrie's avatar
wyrie committed
211 212 213
		//* create certificates
		$command = 'mkimapdcert';
		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
214

wyrie's avatar
wyrie committed
215
		$command = 'mkpop3dcert';
216
		caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
217 218 219 220 221 222 223 224 225 226 227
	}

	public function configure_dovecot()
	{
		global $conf;

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

		$configfile = $conf['postfix']['config_dir'].'/master.cf';

		if(is_file($configfile)) {
wyrie's avatar
wyrie committed
228 229 230 231 232
			copy($configfile, $configfile.'~2');
		}
		if(is_file($configfile.'~2')) {
			chmod($configfile.'~2', 0400);
		}
233 234

		//* Configure master.cf and add a line for deliver
wyrie's avatar
wyrie committed
235
		$content = rf($configfile);
236 237

		if(!stristr($content, 'dovecot/deliver')) {
238
			$deliver_content = 'dovecot   unix  -       n       n       -       -       pipe'."\n".'  flags=DROhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}';
239
			af($conf['postfix']['config_dir'].'/master.cf', $deliver_content);
wyrie's avatar
wyrie committed
240 241 242 243
		}
		unset($content);
		unset($deliver_content);
		unset($configfile);
244

wyrie's avatar
wyrie committed
245 246
		//* Reconfigure postfix to use dovecot authentication
		$postconf_commands = array (
247
			'dovecot_destination_recipient_limit = 1',
248
			'virtual_transport = lmtp:unix:private/dovecot-lmtp',
249 250
			'smtpd_sasl_type = dovecot',
			'smtpd_sasl_path = private/auth'
wyrie's avatar
wyrie committed
251
		);
252

wyrie's avatar
wyrie committed
253
		//* Make a backup copy of the main.cf file
254 255 256 257
		copy($conf['postfix']['config_dir'].'/main.cf', $conf['postfix']['config_dir'].'/main.cf~3');

		//* Executing the postconf commands
		foreach($postconf_commands as $cmd)
wyrie's avatar
wyrie committed
258 259 260 261
		{
			$command = "postconf -e '$cmd'";
			caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		}
262

wyrie's avatar
wyrie committed
263 264 265 266
		//* copy dovecot.conf
		$configfile = $config_dir.'/dovecot.conf';
		$content = $this->get_template_file('dovecot.conf', true);
		$this->write_config_file($configfile, $content);
267

wyrie's avatar
wyrie committed
268 269 270 271
		//* dovecot-sql.conf
		$configfile = $config_dir.'/dovecot-sql.conf';
		$content = $this->get_template_file('debian_dovecot-sql.conf', true, true);
		$this->write_config_file($configfile, $content);
272 273
	}

274
	public function configure_spamassassin()
275
	{
276
		return true;
277 278
	}

279
	public function configure_getmail()
280
	{
281
		global $conf;
282

283
		$config_dir = $conf['getmail']['config_dir'];
284

285
		if (!is_dir($config_dir)) {
wyrie's avatar
wyrie committed
286
			exec('mkdir -p '.escapeshellcmd($config_dir));
287 288 289 290 291 292
		}

		$command = "useradd -d $config_dir ".$conf['getmail']['user'];
		if (!is_user('getmail')) {
			caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		}
293

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

297 298
		$command = "chmod -R 700 $config_dir";
		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
299

wyrie's avatar
wyrie committed
300
		//* Getmail will be run from cron. In order to have access to cron the getmail user needs to be part of the cron group.
301 302 303
		$command = "gpasswd -a getmail " . $conf['cron']['group'];
		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
	}
304 305 306

	public function configure_amavis()
	{
307
		global $conf;
308

wyrie's avatar
wyrie committed
309
		//* Amavisd-new user config file
310 311
		$conf_file = 'amavisd-ispconfig.conf';
		$conf_path = dirname($conf['amavis']['config_file']) . '/' . $conf_file;
312

wyrie's avatar
wyrie committed
313
		$content = $this->get_template_file($conf_file, true, true); //* get contents & insert db cred
314
		$this->write_config_file($conf_path, $content);
315

wyrie's avatar
wyrie committed
316
		//* Activate config directory in default file
317
		$amavis_conf = rf($conf['amavis']['config_file']);
318
		if (stripos($amavis_conf, $conf_path) === false)
319
		{
wyrie's avatar
wyrie committed
320
			$amavis_conf = preg_replace('/^(1;.*)$/m', "include_config_files('$conf_path');\n$1", $amavis_conf);
321 322
			$this->write_config_file($conf['amavis']['config_file'], $amavis_conf);
		}
323

wyrie's avatar
wyrie committed
324
		//* Adding the amavisd commands to the postfix configuration
325 326 327 328
		$postconf_commands = array (
			'content_filter = amavis:[127.0.0.1]:10024',
			'receive_override_options = no_address_mappings'
		);
329 330

		foreach($postconf_commands as $cmd) {
331
			$command = "postconf -e '$cmd'";
wyrie's avatar
wyrie committed
332
			caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
333
		}
334

wyrie's avatar
wyrie committed
335 336
		//* Append the configuration for amavisd to the master.cf file
		$content = rf($conf['postfix']['config_dir'].'/master.cf');
337 338 339

		if(!stristr($content, '127.0.0.1:10025')) //* Only add the content if we had not addded it before
			{
340
			unset($content);
wyrie's avatar
wyrie committed
341 342
			$content = $this->get_template_file('master_cf_amavis', true);
			af($conf['postfix']['config_dir'].'/master.cf', $content);
343 344
		}
		unset($content);
345

wyrie's avatar
wyrie committed
346
		//* Add the clamav user to the amavis group
347
		exec('usermod -a -G amavis clamav');
348 349 350 351
	}

	public function configure_pureftpd()
	{
352
		global $conf;
353

354
		//* configure pure-ftpd for MySQL authentication against the ispconfig database
wyrie's avatar
wyrie committed
355 356
		$content = $this->get_template_file('pureftpd_mysql.conf', true, true); //* get contents & insert db cred
		$content = str_replace('{server_id}', $conf['server_id'], $content);
357

358
		$this->write_config_file($conf['pureftpd']['mysql_config_file'], $content, 600, 'root', 'root');
359

wyrie's avatar
wyrie committed
360
		//* enable pure-ftpd and server settings
361
		$content = rf($conf["pureftpd"]["config_file"]);
362

363 364
		$content = preg_replace('/#?IS_CONFIGURED="(?:yes|no)"/', 'IS_CONFIGURED="yes"', $content);
		$content = str_replace('AUTH="-l unix"', 'AUTH="-l mysql:'.$conf['pureftpd']['mysql_config_file'].'"', $content);
365

wyrie's avatar
wyrie committed
366 367
		//* Logging defaults to syslog's ftp facility. Override this behaviour for better compatibility with debian/ubuntu
		//* and specify the format.
368 369 370 371
		$logdir = '/var/log/pure-ftpd';
		if (!is_dir($logdir)) {
			mkdir($logdir, 0755, true);
		}
372

wyrie's avatar
wyrie committed
373
		/**
374 375 376 377 378 379
		 * @link http://download.pureftpd.org/pub/pure-ftpd/doc/README
		 * -b brokenclientscompatibility
		 * -A chrooteveryone
		 * -E noanonymous
		 * -O altlog <format>:<log file>
		 * -Z customerproof (Add safe guards against common customer mistakes ie. like chmod 0 on their own files)
380
		 * -D displaydotfiles
wyrie's avatar
wyrie committed
381
		 * -H dontresolve
382
		 */
383 384


wyrie's avatar
wyrie committed
385
		$content = preg_replace('/MISC_OTHER="[^"]+"/', 'MISC_OTHER="-b -A -E -Z -D -H -O clf:'.$logdir.'/transfer.log"', $content);
386

wyrie's avatar
wyrie committed
387
		$this->write_config_file($conf['pureftpd']['config_file'], $content);
388 389 390
	}

	public function configure_powerdns()
391 392
	{
		global $conf;
393

394 395 396 397
		//* Create the database
		if(!$this->db->query('CREATE DATABASE IF NOT EXISTS '.$conf['powerdns']['database'].' DEFAULT CHARACTER SET '.$conf['mysql']['charset'])) {
			$this->error('Unable to create MySQL database: '.$conf['powerdns']['database'].'.');
		}
398

399
		//* Create the ISPConfig database user in the local database
400
		$query = 'GRANT ALL ON `'.$conf['powerdns']['database'].'` . * TO \''.$conf['mysql']['ispconfig_user'].'\'@\'localhost\';';
401 402 403
		if(!$this->db->query($query)) {
			$this->error('Unable to create user for powerdns database Error: '.$this->db->errorMessage);
		}
404

405 406
		//* Reload database privelages
		$this->db->query('FLUSH PRIVILEGES;');
407

408 409
		//* load the powerdns databse dump
		if($conf['mysql']['admin_password'] == '') {
410 411
			caselog("mysql --default-character-set=".$conf['mysql']['charset']." -h '".$conf['mysql']['host']."' -u '".$conf['mysql']['admin_user']."' '".$conf['powerdns']['database']."' < '".ISPC_INSTALL_ROOT."/install/sql/powerdns.sql' &> /dev/null",
				__FILE__, __LINE__, 'read in ispconfig3.sql', 'could not read in powerdns.sql');
412
		} else {
413 414
			caselog("mysql --default-character-set=".$conf['mysql']['charset']." -h '".$conf['mysql']['host']."' -u '".$conf['mysql']['admin_user']."' -p'".$conf['mysql']['admin_password']."' '".$conf['powerdns']['database']."' < '".ISPC_INSTALL_ROOT."/install/sql/powerdns.sql' &> /dev/null",
				__FILE__, __LINE__, 'read in ispconfig3.sql', 'could not read in powerdns.sql');
415
		}
416

417
		//* Create the powerdns config file
wyrie's avatar
wyrie committed
418
		$content = $this->get_template_file('pdns.local', true, true); //* get contents & insert db cred
419
		$content = str_replace('{powerdns_database}', $conf['powerdns']['database'], $content);
420

421 422
		$this->write_config_file($conf["powerdns"]["config_dir"].'/'.$conf["powerdns"]["config_file"], $content, 600, 'root', 'root');

wyrie's avatar
wyrie committed
423
		//* Create symlink to init script to start the correct config file
424 425 426 427
		if( !is_link($conf['init_scripts'].'/'.$conf['powerdns']['init_script']) ) {
			symlink($conf['init_scripts'].'/pdns', $conf['init_scripts'].'/'.$conf['powerdns']['init_script']);
		}
	}
428

wyrie's avatar
wyrie committed
429 430 431
	public function configure_bind() {
		global $conf;

432 433 434 435
		//* Check if the zonefile directory has a slash at the end
		$content=$conf['bind']['bind_zonefiles_dir'];
		if(substr($content, -1, 1) != '/') {
			$content .= '/';
wyrie's avatar
wyrie committed
436
		}
437

wyrie's avatar
wyrie committed
438 439
		//* New default format of named.conf uses views. Check which version the system is using and include our zones file.
		$named_conf = rf($conf['bind']['named_conf_path']);
440
		if (stripos($named_conf, 'include "'.$conf['bind']['named_conf_local_path'].'";') === false)
wyrie's avatar
wyrie committed
441 442 443 444 445 446
		{
			preg_match_all("/(?<=\n)view \"(?:public|internal)\" in \{.*\n\};/Us", $named_conf, $views);
			if (count($views[0]) == 2) {
				foreach ($views[0] as $view) {
					$named_conf = str_replace($view, substr($view, 0, -2)."include \"{$conf['bind']['named_conf_local_path']}\";\n};", $named_conf);
				}
447

wyrie's avatar
wyrie committed
448 449 450 451 452 453 454
				wf($conf['bind']['named_conf_path'], $named_conf);
			}
			else {
				af($conf['bind']['named_conf_path'], 'include "'.$conf['bind']['named_conf_local_path'].'";');
			}
		}
	}
455

456
	public function configure_apache()
457
	{
458
		global $conf;
459

Falko Timme's avatar
Falko Timme committed
460
		if($conf['apache']['installed'] == false) return;
wyrie's avatar
wyrie committed
461 462 463
		//* Create the logging directory for the vhost logfiles
		if (!is_dir($conf['ispconfig_log_dir'].'/httpd')) {
			mkdir($conf['ispconfig_log_dir'].'/httpd', 0755, true);
464
		}
465 466

		if (is_file($conf['suphp']['config_file']))
467 468
		{
			$content = rf($conf['suphp']['config_file']);
469

wyrie's avatar
wyrie committed
470 471
			if (!preg_match('|^x-httpd-suphp=php:/usr/bin/php-cgi$|m', $content))
			{
472 473
				$content = preg_replace('/;Handler for php-scripts/', ";Handler for php-scripts\nx-httpd-suphp=php:/usr/bin/php-cgi", $content);
				$content = preg_replace('/;?umask=\d+/', 'umask=0022', $content);
wyrie's avatar
wyrie committed
474
			}
475

476 477
			$this->write_config_file($conf['suphp']['config_file'], $content);
		}
478

wyrie's avatar
wyrie committed
479
		//* Enable ISPConfig default vhost settings
480
		$default_vhost_path = $conf['apache']['vhost_conf_dir'].'/'.$conf['apache']['vhost_default'];
481
		if (is_file($default_vhost_path))
482 483
		{
			$content = rf($default_vhost_path);
484

485 486
			$content = preg_replace('/^#?\s*NameVirtualHost.*$/m', 'NameVirtualHost *:80', $content);
			$content = preg_replace('/<VirtualHost[^>]+>/', '<VirtualHost *:80>', $content);
487

488 489
			$this->write_config_file($default_vhost_path, $content);
		}
490

wyrie's avatar
wyrie committed
491
		//* Generate default ssl certificates
492 493 494
		if (!is_dir($conf['apache']['ssl_dir'])) {
			mkdir($conf['apache']['ssl_dir']);
		}
495 496

		if ($conf['services']['mail'] == true)
497 498 499 500 501 502 503 504 505 506
		{
			copy($conf['postfix']['config_dir']."/smtpd.key", $conf['apache']['ssl_dir']."/server.key");
			copy($conf['postfix']['config_dir']."/smtpd.cert", $conf['apache']['ssl_dir']."/server.crt");
		}
		else
		{
			if (!is_file($conf['apache']['ssl_dir'] . '/server.crt')) {
				exec("openssl req -new -outform PEM -out {$conf['apache']['ssl_dir']}/server.crt -newkey rsa:2048 -nodes -keyout {$conf['apache']['ssl_dir']}/server.key -keyform PEM -days 365 -x509");
			}
		}
507 508 509



wyrie's avatar
wyrie committed
510
		//* Copy the ISPConfig configuration include
511
		$content = $this->get_template_file('apache_ispconfig.conf', true);
512

513
		$records = $this->db->queryAllRecords("SELECT * FROM server_ip WHERE server_id = ".$conf["server_id"]." AND virtualhost = 'y'");
514
		if(is_array($records) && count($records) > 0)
515 516 517 518 519 520
		{
			foreach($records as $rec) {
				$content .= "NameVirtualHost ".$rec["ip_address"].":80\n";
				$content .= "NameVirtualHost ".$rec["ip_address"].":443\n";
			}
		}
521

522
		$this->write_config_file($conf['apache']['vhost_conf_dir'].'/000-ispconfig.conf', $content);
523

wyrie's avatar
wyrie committed
524
		//* Gentoo by default does not include .vhost files. Add include line to config file.
525 526
		$content = rf($conf['apache']['config_file']);
		if ( strpos($content, 'Include /etc/apache2/vhosts.d/*.vhost') === false ) {
527
			$content = preg_replace('|(Include /etc/apache2/vhosts.d/\*.conf)|', "$1\nInclude /etc/apache2/vhosts.d/*.vhost", $content);
528
		}
529

530
		$this->write_config_file($conf['apache']['config_file'], $content);
531

wyrie's avatar
wyrie committed
532
		//* make sure that webalizer finds its config file when it is directly in /etc
533
		if(is_file('/etc/webalizer.conf') && !is_dir('/etc/webalizer'))
534 535 536 537
		{
			mkdir('/etc/webalizer', 0755);
			symlink('/etc/webalizer.conf', '/etc/webalizer/webalizer.conf');
		}
538 539 540 541 542 543

		if(is_file('/etc/webalizer/webalizer.conf')) //* Change webalizer mode to incremental
			{
			replaceLine('/etc/webalizer/webalizer.conf', '#IncrementalName', 'IncrementalName webalizer.current', 0, 0);
			replaceLine('/etc/webalizer/webalizer.conf', '#Incremental', 'Incremental     yes', 0, 0);
			replaceLine('/etc/webalizer/webalizer.conf', '#HistoryName', 'HistoryName     webalizer.hist', 0, 0);
544
		}
545

wyrie's avatar
wyrie committed
546
		//* add a sshusers group
547
		if (!is_group('sshusers'))
548 549 550 551
		{
			$command = 'groupadd sshusers';
			caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		}
552 553 554
	}

	public function configure_apps_vhost()
555 556
	{
		global $conf;
557

558
		//* Create the ispconfig apps vhost user and group
559
		if($conf['apache']['installed'] == true){
Falko Timme's avatar
Falko Timme committed
560 561 562
			$apps_vhost_user = escapeshellcmd($conf['web']['apps_vhost_user']);
			$apps_vhost_group = escapeshellcmd($conf['web']['apps_vhost_group']);
			$install_dir = escapeshellcmd($conf['web']['website_basedir'].'/apps');
563

Falko Timme's avatar
Falko Timme committed
564 565 566 567
			$command = 'groupadd '.$apps_vhost_user;
			if ( !is_group($apps_vhost_group) ) {
				caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
			}
568

Falko Timme's avatar
Falko Timme committed
569 570 571 572
			$command = "useradd -g '$apps_vhost_group' -d $install_dir $apps_vhost_group";
			if ( !is_user($apps_vhost_user) ) {
				caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
			}
573

Falko Timme's avatar
Falko Timme committed
574 575
			$command = 'adduser '.$conf['apache']['user'].' '.$apps_vhost_group;
			caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
576

577
			if(!@is_dir($install_dir)){
Falko Timme's avatar
Falko Timme committed
578
				mkdir($install_dir, 0755, true);
579 580
			} else {
				chmod($install_dir, 0755);
Falko Timme's avatar
Falko Timme committed
581 582 583
			}
			chown($install_dir, $apps_vhost_user);
			chgrp($install_dir, $apps_vhost_group);
584

Falko Timme's avatar
Falko Timme committed
585 586 587 588
			//* Copy the apps vhost file
			$vhost_conf_dir = $conf['apache']['vhost_conf_dir'];
			$vhost_conf_enabled_dir = $conf['apache']['vhost_conf_enabled_dir'];
			$apps_vhost_servername = ($conf['web']['apps_vhost_servername'] == '') ? '' : 'ServerName '.$conf['web']['apps_vhost_servername'];
589

Falko Timme's avatar
Falko Timme committed
590 591
			//* Dont just copy over the virtualhost template but add some custom settings
			$content = $this->get_template_file('apache_apps.vhost', true);
592

Falko Timme's avatar
Falko Timme committed
593 594 595 596 597
			$content = str_replace('{apps_vhost_ip}', $conf['web']['apps_vhost_ip'], $content);
			$content = str_replace('{apps_vhost_port}', $conf['web']['apps_vhost_port'], $content);
			$content = str_replace('{apps_vhost_dir}', $conf['web']['website_basedir'].'/apps', $content);
			$content = str_replace('{website_basedir}', $conf['web']['website_basedir'], $content);
			$content = str_replace('{apps_vhost_servername}', $apps_vhost_servername, $content);
598

Falko Timme's avatar
Falko Timme committed
599 600 601 602 603 604
			//* comment out the listen directive if port is 80 or 443
			if($conf['web']['apps_vhost_ip'] == 80 or $conf['web']['apps_vhost_ip'] == 443) {
				$content = str_replace('{vhost_port_listen}', '#', $content);
			} else {
				$content = str_replace('{vhost_port_listen}', '', $content);
			}
605

Falko Timme's avatar
Falko Timme committed
606
			$this->write_config_file("$vhost_conf_dir/apps.vhost", $content);
607 608

			//if ( !is_file($conf['web']['website_basedir'].'/php-fcgi-scripts/apps/.php-fcgi-starter') )
609
			//{
610 611 612 613 614 615 616 617 618
			$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/apache_apps_fcgi_starter.master', 'tpl/apache_apps_fcgi_starter.master');
			$content = str_replace('{fastcgi_bin}', $conf['fastcgi']['fastcgi_bin'], $content);
			$content = str_replace('{fastcgi_phpini_path}', $conf['fastcgi']['fastcgi_phpini_path'], $content);
			mkdir($conf['web']['website_basedir'].'/php-fcgi-scripts/apps', 0755, true);
			//copy('tpl/apache_apps_fcgi_starter.master',$conf['web']['website_basedir'].'/php-fcgi-scripts/apps/.php-fcgi-starter');
			wf($conf['web']['website_basedir'].'/php-fcgi-scripts/apps/.php-fcgi-starter', $content);
			exec('chmod +x '.$conf['web']['website_basedir'].'/php-fcgi-scripts/apps/.php-fcgi-starter');
			exec('chown -R ispapps:ispapps '.$conf['web']['website_basedir'].'/php-fcgi-scripts/apps');

619
			//}
Falko Timme's avatar
Falko Timme committed
620
		}
621
		if($conf['nginx']['installed'] == true){
Falko Timme's avatar
Falko Timme committed
622 623 624 625 626 627 628 629 630 631 632 633 634 635
			$apps_vhost_user = escapeshellcmd($conf['web']['apps_vhost_user']);
			$apps_vhost_group = escapeshellcmd($conf['web']['apps_vhost_group']);
			$install_dir = escapeshellcmd($conf['web']['website_basedir'].'/apps');

			$command = 'groupadd '.$apps_vhost_user;
			if(!is_group($apps_vhost_group)) caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");

			$command = 'useradd -g '.$apps_vhost_group.' -d '.$install_dir.' '.$apps_vhost_group;
			if(!is_user($apps_vhost_user)) caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");


			$command = 'adduser '.$conf['nginx']['user'].' '.$apps_vhost_group;
			caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");

Falko Timme's avatar
Falko Timme committed
636 637 638 639 640
			if(!@is_dir($install_dir)){
				mkdir($install_dir, 0755, true);
			} else {
				chmod($install_dir, 0755);
			}
Falko Timme's avatar
Falko Timme committed
641 642 643 644 645 646 647 648 649
			chown($install_dir, $apps_vhost_user);
			chgrp($install_dir, $apps_vhost_group);

			//* Copy the apps vhost file
			$vhost_conf_dir = $conf['nginx']['vhost_conf_dir'];
			$vhost_conf_enabled_dir = $conf['nginx']['vhost_conf_enabled_dir'];
			$apps_vhost_servername = ($conf['web']['apps_vhost_servername'] == '')?'_':$conf['web']['apps_vhost_servername'];

			// Dont just copy over the virtualhost template but add some custom settings
650
			$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/nginx_apps.vhost.master', 'tpl/nginx_apps.vhost.master');
651

Falko Timme's avatar
Falko Timme committed
652 653 654 655 656
			if($conf['web']['apps_vhost_ip'] == '_default_'){
				$apps_vhost_ip = '';
			} else {
				$apps_vhost_ip = $conf['web']['apps_vhost_ip'].':';
			}
657

658
			$socket_dir = escapeshellcmd($conf['nginx']['php_fpm_socket_dir']);
659
			if(substr($socket_dir, -1) != '/') $socket_dir .= '/';
660 661
			if(!is_dir($socket_dir)) exec('mkdir -p '.$socket_dir);
			$fpm_socket = $socket_dir.'apps.sock';
662
			$cgi_socket = escapeshellcmd($conf['nginx']['cgi_socket']);
Falko Timme's avatar
Falko Timme committed
663 664 665 666 667

			$content = str_replace('{apps_vhost_ip}', $apps_vhost_ip, $content);
			$content = str_replace('{apps_vhost_port}', $conf['web']['apps_vhost_port'], $content);
			$content = str_replace('{apps_vhost_dir}', $conf['web']['website_basedir'].'/apps', $content);
			$content = str_replace('{apps_vhost_servername}', $apps_vhost_servername, $content);
668 669
			//$content = str_replace('{fpm_port}', ($conf['nginx']['php_fpm_start_port']+1), $content);
			$content = str_replace('{fpm_socket}', $fpm_socket, $content);
670
			$content = str_replace('{cgi_socket}', $cgi_socket, $content);
Falko Timme's avatar
Falko Timme committed
671 672

			wf($vhost_conf_dir.'/apps.vhost', $content);
673

Falko Timme's avatar
Falko Timme committed
674 675
			// PHP-FPM
			// Dont just copy over the php-fpm pool template but add some custom settings
676
			$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/apps_php_fpm_pool.conf.master', 'tpl/apps_php_fpm_pool.conf.master');
Falko Timme's avatar
Falko Timme committed
677
			$content = str_replace('{fpm_pool}', 'apps', $content);
678 679
			//$content = str_replace('{fpm_port}', ($conf['nginx']['php_fpm_start_port']+1), $content);
			$content = str_replace('{fpm_socket}', $fpm_socket, $content);
Falko Timme's avatar
Falko Timme committed
680 681 682 683 684 685
			$content = str_replace('{fpm_user}', $apps_vhost_user, $content);
			$content = str_replace('{fpm_group}', $apps_vhost_group, $content);
			wf($conf['nginx']['php_fpm_pool_dir'].'/apps.conf', $content);

			//copy('tpl/nginx_ispconfig.vhost.master', "$vhost_conf_dir/ispconfig.vhost");
			//* and create the symlink
Falko Timme's avatar
Falko Timme committed
686 687
			if(@is_link($vhost_conf_enabled_dir.'/apps.vhost')) unlink($vhost_conf_enabled_dir.'/apps.vhost');
			if(!@is_link($vhost_conf_enabled_dir.'/000-apps.vhost')) {
688
				symlink($vhost_conf_dir.'/apps.vhost', $vhost_conf_enabled_dir.'/000-apps.vhost');
Falko Timme's avatar
Falko Timme committed
689
			}
690

691 692
		}
	}
693 694 695

	public function install_ispconfig()
	{
696
		global $conf;
697

698
		$install_dir = $conf['ispconfig_install_dir'];
699 700 701

		//* Create the ISPConfig installation directory
		if(!is_dir($install_dir))
702 703 704 705
		{
			$command = "mkdir $install_dir";
			caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		}
706

wyrie's avatar
wyrie committed
707
		//* Create a ISPConfig user and group
708
		if (!is_group('ispconfig'))
709 710 711 712
		{
			$command = 'groupadd ispconfig';
			caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		}
713 714

		if (!is_user('ispconfig'))
715 716 717 718
		{
			$command = "useradd -g ispconfig -d $install_dir ispconfig";
			caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		}
719

wyrie's avatar
wyrie committed
720
		//* copy the ISPConfig interface part
721 722
		$command = "cp -rf ../interface $install_dir";
		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
723

wyrie's avatar
wyrie committed
724
		//* copy the ISPConfig server part
725 726
		$command = "cp -rf ../server $install_dir";
		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
727 728


wyrie's avatar
wyrie committed
729
		//* Create the config file for ISPConfig interface
730
		$configfile = 'config.inc.php';
wyrie's avatar
wyrie committed
731
		$content = $this->get_template_file($configfile, true, true); //* get contents & insert db cred
732

733 734 735 736
		$content = str_replace('{mysql_master_server_ispconfig_user}', $conf['mysql']['master_ispconfig_user'], $content);
		$content = str_replace('{mysql_master_server_ispconfig_password}', $conf['mysql']['master_ispconfig_password'], $content);
		$content = str_replace('{mysql_master_server_database}', $conf['mysql']['master_database'], $content);
		$content = str_replace('{mysql_master_server_host}', $conf['mysql']['master_host'], $content);
737

738 739 740
		$content = str_replace('{server_id}', $conf['server_id'], $content);
		$content = str_replace('{ispconfig_log_priority}', $conf['ispconfig_log_priority'], $content);
		$content = str_replace('{language}', $conf['language'], $content);
741
		$content = str_replace('{timezone}', $conf['timezone'], $content);
cfoe's avatar
cfoe committed
742
		$content = str_replace('{theme}', $conf['theme'], $content);
743
		$content = str_replace('{language_file_import_enabled}', ($conf['language_file_import_enabled'] == true)?'true':'false', $content);
744

745
		$this->write_config_file("$install_dir/interface/lib/$configfile", $content);
746

wyrie's avatar
wyrie committed
747
		//* Create the config file for ISPConfig server
748
		$this->write_config_file("$install_dir/server/lib/$configfile", $content);
749

750 751
		//* Create the config file for remote-actions (but only, if it does not exist, because
		//  the value is a autoinc-value and so changed by the remoteaction_core_module
wyrie's avatar
wyrie committed
752 753
		if (!file_exists($install_dir.'/server/lib/remote_action.inc.php')) {
			$content = '<?php' . "\n" . '$maxid_remote_action = 0;' . "\n" . '?>';
754
			wf($install_dir.'/server/lib/remote_action.inc.php', $content);
wyrie's avatar
wyrie committed
755
		}
756 757

		// Enable the server modules and plugins.
758 759 760 761 762
		// TODO: Implement a selector which modules and plugins shall be enabled.
		$dir = $install_dir.'/server/mods-available/';
		if (is_dir($dir)) {
			if ($dh = opendir($dir)) {
				while (($file = readdir($dh)) !== false) {
763 764 765
					if($file != '.' && $file != '..' && substr($file, -8, 8) == '.inc.php') {
						include_once $install_dir.'/server/mods-available/'.$file;
						$module_name = substr($file, 0, -8);
766 767
						$tmp = new $module_name;
						if($tmp->onInstall()) {
wyrie's avatar
wyrie committed
768 769 770 771
							if(!@is_link($install_dir.'/server/mods-enabled/'.$file)) {
								@symlink($install_dir.'/server/mods-available/'.$file, $install_dir.'/server/mods-enabled/'.$file);
								// @symlink($install_dir.'/server/mods-available/'.$file, '../mods-enabled/'.$file);
							}
772
							if (strpos($file, '_core_module') !== false) {
wyrie's avatar
wyrie committed
773 774 775 776
								if(!@is_link($install_dir.'/server/mods-core/'.$file)) {
									@symlink($install_dir.'/server/mods-available/'.$file, $install_dir.'/server/mods-core/'.$file);
									// @symlink($install_dir.'/server/mods-available/'.$file, '../mods-core/'.$file);
								}
777 778 779 780 781 782 783 784
							}
						}
						unset($tmp);
					}
				}
				closedir($dh);
			}
		}
wyrie's avatar
wyrie committed
785

786 787 788 789
		$dir = $install_dir.'/server/plugins-available/';
		if (is_dir($dir)) {
			if ($dh = opendir($dir)) {
				while (($file = readdir($dh)) !== false) {
Falko Timme's avatar
Falko Timme committed
790 791
					if($conf['apache']['installed'] == true && $file == 'nginx_plugin.inc.php') continue;
					if($conf['nginx']['installed'] == true && $file == 'apache2_plugin.inc.php') continue;
792 793 794
					if($file != '.' && $file != '..' && substr($file, -8, 8) == '.inc.php') {
						include_once $install_dir.'/server/plugins-available/'.$file;
						$plugin_name = substr($file, 0, -8);
795
						$tmp = new $plugin_name;