gentoo.lib.php 47.5 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
		{
Till Brehm's avatar
Till Brehm committed
122 123 124 125 126 127 128
			if(AUTOINSTALL){
				$command = 'cd '.$config_dir.'; '
					."openssl req -new -subj '/C=".$autoinstall['ssl_cert_country']."/ST=".$autoinstall['ssl_cert_state']."/L=".$autoinstall['ssl_cert_locality']."/O=".$autoinstall['ssl_cert_organisation']."/OU=".$autoinstall['ssl_cert_organisation_unit']."/CN=".$autoinstall['ssl_cert_common_name']."' -outform PEM -out smtpd.cert -newkey rsa:4096 -nodes -keyout smtpd.key -keyform PEM -days 3650 -x509";
			} else {
				$command = 'cd '.$config_dir.'; '
					."openssl req -new -subj '/C=".escapeshellcmd($autoinstall['ssl_cert_country'])."/ST=".escapeshellcmd($autoinstall['ssl_cert_state'])."/L=".escapeshellcmd($autoinstall['ssl_cert_locality'])."/O=".escapeshellcmd($autoinstall['ssl_cert_organisation'])."/OU=".escapeshellcmd($autoinstall['ssl_cert_organisation_unit'])."/CN=".escapeshellcmd($autoinstall['ssl_cert_common_name'])."' -outform PEM -out smtpd.cert -newkey rsa:4096 -nodes -keyout smtpd.key -keyform PEM -days 3650 -x509";
			}
129

130 131 132
			$command = 'chmod o= '.$config_dir.'/smtpd.key';
			caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command);
		}
133

wyrie's avatar
wyrie committed
134 135 136 137 138
		//* 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);
		}
139

wyrie's avatar
wyrie committed
140
		//* Changing maildrop lines in posfix master.cf
141 142 143
		$configfile = $config_dir.'/master.cf';
		$content = rf($configfile);

144 145 146 147 148
		$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);

149
		$this->write_config_file($configfile, $content);
150

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

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

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

wyrie's avatar
wyrie committed
164
		//* Chmod and chown the .mailfilter file
165 166
		$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");
167

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

171
	}
172 173

	public function configure_saslauthd()
174 175
	{
		global $conf;
176

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

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

wyrie's avatar
wyrie committed
184
		$this->write_config_file($conf['saslauthd']['config_file'], $content);
185
	}
186

187
	public function configure_courier()
188 189 190
	{
		global $conf;

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

wyrie's avatar
wyrie committed
195
		//* authdaemonrc
196 197 198 199 200
		$configfile = $conf['courier']['config_dir'].'/authdaemonrc';

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

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

wyrie's avatar
wyrie committed
206
		$command = 'mkpop3dcert';
207
		caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
208 209 210 211 212 213 214 215 216 217 218
	}

	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
219 220 221 222 223
			copy($configfile, $configfile.'~2');
		}
		if(is_file($configfile.'~2')) {
			chmod($configfile.'~2', 0400);
		}
224 225

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

		if(!stristr($content, 'dovecot/deliver')) {
229
			$deliver_content = 'dovecot   unix  -       n       n       -       -       pipe'."\n".'  flags=DROhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}';
230
			af($conf['postfix']['config_dir'].'/master.cf', $deliver_content);
wyrie's avatar
wyrie committed
231 232 233 234
		}
		unset($content);
		unset($deliver_content);
		unset($configfile);
235

wyrie's avatar
wyrie committed
236 237
		//* Reconfigure postfix to use dovecot authentication
		$postconf_commands = array (
238 239 240 241
			'dovecot_destination_recipient_limit = 1',
			'virtual_transport = dovecot',
			'smtpd_sasl_type = dovecot',
			'smtpd_sasl_path = private/auth'
wyrie's avatar
wyrie committed
242
		);
243

wyrie's avatar
wyrie committed
244
		//* Make a backup copy of the main.cf file
245 246 247 248
		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
249 250 251 252
		{
			$command = "postconf -e '$cmd'";
			caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		}
253

wyrie's avatar
wyrie committed
254 255 256 257
		//* copy dovecot.conf
		$configfile = $config_dir.'/dovecot.conf';
		$content = $this->get_template_file('dovecot.conf', true);
		$this->write_config_file($configfile, $content);
258

wyrie's avatar
wyrie committed
259 260 261 262
		//* 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);
263 264
	}

265
	public function configure_spamassassin()
266
	{
267
		return true;
268 269
	}

270
	public function configure_getmail()
271
	{
272
		global $conf;
273

274
		$config_dir = $conf['getmail']['config_dir'];
275

276
		if (!is_dir($config_dir)) {
wyrie's avatar
wyrie committed
277
			exec('mkdir -p '.escapeshellcmd($config_dir));
278 279 280 281 282 283
		}

		$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");
		}
284

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

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

wyrie's avatar
wyrie committed
291
		//* Getmail will be run from cron. In order to have access to cron the getmail user needs to be part of the cron group.
292 293 294
		$command = "gpasswd -a getmail " . $conf['cron']['group'];
		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
	}
295 296 297

	public function configure_amavis()
	{
298
		global $conf;
299

wyrie's avatar
wyrie committed
300
		//* Amavisd-new user config file
301 302
		$conf_file = 'amavisd-ispconfig.conf';
		$conf_path = dirname($conf['amavis']['config_file']) . '/' . $conf_file;
303

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

wyrie's avatar
wyrie committed
307
		//* Activate config directory in default file
308
		$amavis_conf = rf($conf['amavis']['config_file']);
309
		if (stripos($amavis_conf, $conf_path) === false)
310
		{
wyrie's avatar
wyrie committed
311
			$amavis_conf = preg_replace('/^(1;.*)$/m', "include_config_files('$conf_path');\n$1", $amavis_conf);
312 313
			$this->write_config_file($conf['amavis']['config_file'], $amavis_conf);
		}
314

wyrie's avatar
wyrie committed
315
		//* Adding the amavisd commands to the postfix configuration
316 317 318 319
		$postconf_commands = array (
			'content_filter = amavis:[127.0.0.1]:10024',
			'receive_override_options = no_address_mappings'
		);
320 321

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

wyrie's avatar
wyrie committed
326 327
		//* Append the configuration for amavisd to the master.cf file
		$content = rf($conf['postfix']['config_dir'].'/master.cf');
328 329 330

		if(!stristr($content, '127.0.0.1:10025')) //* Only add the content if we had not addded it before
			{
331
			unset($content);
wyrie's avatar
wyrie committed
332 333
			$content = $this->get_template_file('master_cf_amavis', true);
			af($conf['postfix']['config_dir'].'/master.cf', $content);
334 335
		}
		unset($content);
336

wyrie's avatar
wyrie committed
337
		//* Add the clamav user to the amavis group
338
		exec('usermod -a -G amavis clamav');
339 340 341 342
	}

	public function configure_pureftpd()
	{
343
		global $conf;
344

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

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

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

354 355
		$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);
356

wyrie's avatar
wyrie committed
357 358
		//* Logging defaults to syslog's ftp facility. Override this behaviour for better compatibility with debian/ubuntu
		//* and specify the format.
359 360 361 362
		$logdir = '/var/log/pure-ftpd';
		if (!is_dir($logdir)) {
			mkdir($logdir, 0755, true);
		}
363

wyrie's avatar
wyrie committed
364
		/**
365 366 367 368 369 370
		 * @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)
371
		 * -D displaydotfiles
wyrie's avatar
wyrie committed
372
		 * -H dontresolve
373
		 */
374 375


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

wyrie's avatar
wyrie committed
378
		$this->write_config_file($conf['pureftpd']['config_file'], $content);
379 380 381
	}

	public function configure_powerdns()
382 383
	{
		global $conf;
384

385 386 387 388
		//* 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'].'.');
		}
389

390
		//* Create the ISPConfig database user in the local database
391
		$query = 'GRANT ALL ON `'.$conf['powerdns']['database'].'` . * TO \''.$conf['mysql']['ispconfig_user'].'\'@\'localhost\';';
392 393 394
		if(!$this->db->query($query)) {
			$this->error('Unable to create user for powerdns database Error: '.$this->db->errorMessage);
		}
395

396 397
		//* Reload database privelages
		$this->db->query('FLUSH PRIVILEGES;');
398

399 400
		//* load the powerdns databse dump
		if($conf['mysql']['admin_password'] == '') {
401 402
			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');
403
		} else {
404 405
			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');
406
		}
407

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

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

wyrie's avatar
wyrie committed
414
		//* Create symlink to init script to start the correct config file
415 416 417 418
		if( !is_link($conf['init_scripts'].'/'.$conf['powerdns']['init_script']) ) {
			symlink($conf['init_scripts'].'/pdns', $conf['init_scripts'].'/'.$conf['powerdns']['init_script']);
		}
	}
419

wyrie's avatar
wyrie committed
420 421 422
	public function configure_bind() {
		global $conf;

423 424 425 426
		//* 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
427
		}
428

wyrie's avatar
wyrie committed
429 430
		//* 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']);
431
		if (stripos($named_conf, 'include "'.$conf['bind']['named_conf_local_path'].'";') === false)
wyrie's avatar
wyrie committed
432 433 434 435 436 437
		{
			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);
				}
438

wyrie's avatar
wyrie committed
439 440 441 442 443 444 445
				wf($conf['bind']['named_conf_path'], $named_conf);
			}
			else {
				af($conf['bind']['named_conf_path'], 'include "'.$conf['bind']['named_conf_local_path'].'";');
			}
		}
	}
446

447
	public function configure_apache()
448
	{
449
		global $conf;
450

Falko Timme's avatar
Falko Timme committed
451
		if($conf['apache']['installed'] == false) return;
wyrie's avatar
wyrie committed
452 453 454
		//* Create the logging directory for the vhost logfiles
		if (!is_dir($conf['ispconfig_log_dir'].'/httpd')) {
			mkdir($conf['ispconfig_log_dir'].'/httpd', 0755, true);
455
		}
456 457

		if (is_file($conf['suphp']['config_file']))
458 459
		{
			$content = rf($conf['suphp']['config_file']);
460

wyrie's avatar
wyrie committed
461 462
			if (!preg_match('|^x-httpd-suphp=php:/usr/bin/php-cgi$|m', $content))
			{
463 464
				$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
465
			}
466

467 468
			$this->write_config_file($conf['suphp']['config_file'], $content);
		}
469

wyrie's avatar
wyrie committed
470
		//* Enable ISPConfig default vhost settings
471
		$default_vhost_path = $conf['apache']['vhost_conf_dir'].'/'.$conf['apache']['vhost_default'];
472
		if (is_file($default_vhost_path))
473 474
		{
			$content = rf($default_vhost_path);
475

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

479 480
			$this->write_config_file($default_vhost_path, $content);
		}
481

wyrie's avatar
wyrie committed
482
		//* Generate default ssl certificates
483 484 485
		if (!is_dir($conf['apache']['ssl_dir'])) {
			mkdir($conf['apache']['ssl_dir']);
		}
486 487

		if ($conf['services']['mail'] == true)
488 489 490 491 492 493 494 495 496 497
		{
			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");
			}
		}
498 499 500



wyrie's avatar
wyrie committed
501
		//* Copy the ISPConfig configuration include
502
		/*
503
		$content = $this->get_template_file('apache_ispconfig.conf', true);
504

505
		$records = $this->db->queryAllRecords("SELECT * FROM server_ip WHERE server_id = ".$conf["server_id"]." AND virtualhost = 'y'");
506
		if(is_array($records) && count($records) > 0)
507 508 509 510 511 512
		{
			foreach($records as $rec) {
				$content .= "NameVirtualHost ".$rec["ip_address"].":80\n";
				$content .= "NameVirtualHost ".$rec["ip_address"].":443\n";
			}
		}
513

514
		$this->write_config_file($conf['apache']['vhost_conf_dir'].'/000-ispconfig.conf', $content);
515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540
		*/
		
		$tpl = new tpl('apache_ispconfig.conf.master');
		$tpl->setVar('apache_version',getapacheversion());
		
		$records = $this->db->queryAllRecords('SELECT * FROM '.$conf['mysql']['master_database'].'.server_ip WHERE server_id = '.$conf['server_id']." AND virtualhost = 'y'");
		$ip_addresses = array();
		
		if(is_array($records) && count($records) > 0) {
			foreach($records as $rec) {
				if($rec['ip_type'] == 'IPv6') {
					$ip_address = '['.$rec['ip_address'].']';
				} else {
					$ip_address = $rec['ip_address'];
				}
				$ports = explode(',', $rec['virtualhost_port']);
				if(is_array($ports)) {
					foreach($ports as $port) {
						$port = intval($port);
						if($port > 0 && $port < 65536 && $ip_address != '') {
							$ip_addresses[] = array('ip_address' => $ip_address, 'port' => $port);
						}
					}
				}
			}
		}
541
		
Till Brehm's avatar
Till Brehm committed
542
		if(count($ip_addresses) > 0) $tpl->setLoop('ip_adresses',$ip_addresses);
543 544 545

		wf($conf['apache']['vhost_conf_dir'].'/000-ispconfig.conf', $tpl->grab());
		unset($tpl);
546

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

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

wyrie's avatar
wyrie committed
555
		//* make sure that webalizer finds its config file when it is directly in /etc
556
		if(is_file('/etc/webalizer.conf') && !is_dir('/etc/webalizer'))
557 558 559 560
		{
			mkdir('/etc/webalizer', 0755);
			symlink('/etc/webalizer.conf', '/etc/webalizer/webalizer.conf');
		}
561 562 563 564 565 566

		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);
567
		}
568

wyrie's avatar
wyrie committed
569
		//* add a sshusers group
570
		if (!is_group('sshusers'))
571 572 573 574
		{
			$command = 'groupadd sshusers';
			caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		}
575 576 577
	}

	public function configure_apps_vhost()
578 579
	{
		global $conf;
580

581
		//* Create the ispconfig apps vhost user and group
582
		if($conf['apache']['installed'] == true){
Falko Timme's avatar
Falko Timme committed
583 584 585
			$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');
586

Falko Timme's avatar
Falko Timme committed
587 588 589 590
			$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");
			}
591

Falko Timme's avatar
Falko Timme committed
592 593 594 595
			$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");
			}
596

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

600
			if(!@is_dir($install_dir)){
Falko Timme's avatar
Falko Timme committed
601
				mkdir($install_dir, 0755, true);
602 603
			} else {
				chmod($install_dir, 0755);
Falko Timme's avatar
Falko Timme committed
604 605 606
			}
			chown($install_dir, $apps_vhost_user);
			chgrp($install_dir, $apps_vhost_group);
607

Falko Timme's avatar
Falko Timme committed
608 609 610 611
			//* 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'];
612

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

Falko Timme's avatar
Falko Timme committed
616 617 618 619 620
			$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);
621

Falko Timme's avatar
Falko Timme committed
622 623 624 625 626 627
			//* 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);
			}
628

Falko Timme's avatar
Falko Timme committed
629
			$this->write_config_file("$vhost_conf_dir/apps.vhost", $content);
630 631

			//if ( !is_file($conf['web']['website_basedir'].'/php-fcgi-scripts/apps/.php-fcgi-starter') )
632
			//{
633 634 635 636 637 638 639 640 641
			$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');

642
			//}
Falko Timme's avatar
Falko Timme committed
643
		}
644
		if($conf['nginx']['installed'] == true){
Falko Timme's avatar
Falko Timme committed
645 646 647 648 649 650 651 652 653 654 655 656 657 658
			$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
659 660 661 662 663
			if(!@is_dir($install_dir)){
				mkdir($install_dir, 0755, true);
			} else {
				chmod($install_dir, 0755);
			}
Falko Timme's avatar
Falko Timme committed
664 665 666 667 668 669 670 671 672
			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
673
			$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/nginx_apps.vhost.master', 'tpl/nginx_apps.vhost.master');
674

Falko Timme's avatar
Falko Timme committed
675 676 677 678 679
			if($conf['web']['apps_vhost_ip'] == '_default_'){
				$apps_vhost_ip = '';
			} else {
				$apps_vhost_ip = $conf['web']['apps_vhost_ip'].':';
			}
680

681
			$socket_dir = escapeshellcmd($conf['nginx']['php_fpm_socket_dir']);
682
			if(substr($socket_dir, -1) != '/') $socket_dir .= '/';
683 684
			if(!is_dir($socket_dir)) exec('mkdir -p '.$socket_dir);
			$fpm_socket = $socket_dir.'apps.sock';
685
			$cgi_socket = escapeshellcmd($conf['nginx']['cgi_socket']);
Falko Timme's avatar
Falko Timme committed
686 687 688 689 690

			$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);
691 692
			//$content = str_replace('{fpm_port}', ($conf['nginx']['php_fpm_start_port']+1), $content);
			$content = str_replace('{fpm_socket}', $fpm_socket, $content);
693
			$content = str_replace('{cgi_socket}', $cgi_socket, $content);
Falko Timme's avatar
Falko Timme committed
694 695

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

Falko Timme's avatar
Falko Timme committed
697 698
			// PHP-FPM
			// Dont just copy over the php-fpm pool template but add some custom settings
699
			$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
700
			$content = str_replace('{fpm_pool}', 'apps', $content);
701 702
			//$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
703 704 705 706 707 708
			$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
709 710
			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')) {
711
				symlink($vhost_conf_dir.'/apps.vhost', $vhost_conf_enabled_dir.'/000-apps.vhost');
Falko Timme's avatar
Falko Timme committed
712
			}
713

714 715
		}
	}
716 717 718

	public function install_ispconfig()
	{
719
		global $conf;
720

721
		$install_dir = $conf['ispconfig_install_dir'];
722 723 724

		//* Create the ISPConfig installation directory
		if(!is_dir($install_dir))
725 726 727 728
		{
			$command = "mkdir $install_dir";
			caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		}
729

wyrie's avatar
wyrie committed
730
		//* Create a ISPConfig user and group
731
		if (!is_group('ispconfig'))
732 733 734 735
		{
			$command = 'groupadd ispconfig';
			caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		}
736 737

		if (!is_user('ispconfig'))
738 739 740 741
		{
			$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");
		}
742

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

wyrie's avatar
wyrie committed
747
		//* copy the ISPConfig server part
748 749
		$command = "cp -rf ../server $install_dir";
		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
750 751


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

756 757 758 759
		$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);
760

761 762 763
		$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);
764
		$content = str_replace('{timezone}', $conf['timezone'], $content);
cfoe's avatar
cfoe committed
765
		$content = str_replace('{theme}', $conf['theme'], $content);
766
		$content = str_replace('{language_file_import_enabled}', ($conf['language_file_import_enabled'] == true)?'true':'false', $content);
767

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

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

773 774
		//* 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
775 776
		if (!file_exists($install_dir.'/server/lib/remote_action.inc.php')) {
			$content = '<?php' . "\n" . '$maxid_remote_action = 0;' . "\n" . '?>';
777
			wf($install_dir.'/server/lib/remote_action.inc.php', $content);
wyrie's avatar
wyrie committed
778
		}
779 780

		// Enable the server modules and plugins.
781 782 783 784 785
		// 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) {
786 787 788
					if($file != '.' && $file != '..' && substr($file, -8, 8) == '.inc.php') {
						include_once $install_dir.'/server/mods-available/'.$file;
						$module_name = substr($file, 0, -8);
789 790
						$tmp = new $module_name;
						if($tmp->onInstall()) {
wyrie's avatar
wyrie committed
791 792 793 794
							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);
							}
795
							if (strpos($file, '_core_module') !== false) {
wyrie's avatar
wyrie committed
796 797 798 799
								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);
								}
800 801 802 803 804 805 806 807
							}
						}
						unset($tmp);
					}
				}
				closedir($dh);
			}
		}
wyrie's avatar
wyrie committed
808

wyrie's avatar