gentoo.lib.php 46.6 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

335
        // Append the configuration for amavisd to the master.cf file
wyrie's avatar
wyrie committed
336
		$content = rf($conf['postfix']['config_dir'].'/master.cf');
337
		// Only add the content if we had not addded it before
338
		if(!preg_match('/^amavis\s+/m', $content)) {
339
			unset($content);
wyrie's avatar
wyrie committed
340 341
			$content = $this->get_template_file('master_cf_amavis', true);
			af($conf['postfix']['config_dir'].'/master.cf', $content);
342 343
			$content = rf($conf['postfix']['config_dir'].'/master.cf');
		}
344
		if(!preg_match('/^127.0.0.1:10025\s+/m', $content)) {
345 346 347 348 349
 			unset($content);
            $content = $this->get_template_file('master_cf_amavis10025', true);
			af($conf['postfix']['config_dir'].'/master.cf', $content);
			$content = rf($conf['postfix']['config_dir'].'/master.cf');
		}
350
		if(!preg_match('/^127.0.0.1:10027\s+/m', $content)) {
351 352 353
			unset($content);
			$content = $this->get_template_file('master_cf_amavis10027', true);
			af($conf['postfix']['config_dir'].'/master.cf', $content);
354 355
		}
		unset($content);
356

wyrie's avatar
wyrie committed
357
		//* Add the clamav user to the amavis group
358
		exec('usermod -a -G amavis clamav');
359 360 361 362
	}

	public function configure_pureftpd()
	{
363
		global $conf;
364

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

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

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

374 375
		$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);
376

wyrie's avatar
wyrie committed
377 378
		//* Logging defaults to syslog's ftp facility. Override this behaviour for better compatibility with debian/ubuntu
		//* and specify the format.
379 380 381 382
		$logdir = '/var/log/pure-ftpd';
		if (!is_dir($logdir)) {
			mkdir($logdir, 0755, true);
		}
383

wyrie's avatar
wyrie committed
384
		/**
385 386 387 388 389 390
		 * @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)
391
		 * -D displaydotfiles
wyrie's avatar
wyrie committed
392
		 * -H dontresolve
393
		 */
394 395


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

wyrie's avatar
wyrie committed
398
		$this->write_config_file($conf['pureftpd']['config_file'], $content);
399 400 401
	}

	public function configure_powerdns()
402 403
	{
		global $conf;
404

405 406 407 408
		//* 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'].'.');
		}
409

410
		//* Create the ISPConfig database user in the local database
411
		$query = 'GRANT ALL ON `'.$conf['powerdns']['database'].'` . * TO \''.$conf['mysql']['ispconfig_user'].'\'@\'localhost\';';
412 413 414
		if(!$this->db->query($query)) {
			$this->error('Unable to create user for powerdns database Error: '.$this->db->errorMessage);
		}
415

416 417
		//* Reload database privelages
		$this->db->query('FLUSH PRIVILEGES;');
418

419 420
		//* load the powerdns databse dump
		if($conf['mysql']['admin_password'] == '') {
421 422
			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');
423
		} else {
424 425
			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');
426
		}
427

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

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

wyrie's avatar
wyrie committed
434
		//* Create symlink to init script to start the correct config file
435 436 437 438
		if( !is_link($conf['init_scripts'].'/'.$conf['powerdns']['init_script']) ) {
			symlink($conf['init_scripts'].'/pdns', $conf['init_scripts'].'/'.$conf['powerdns']['init_script']);
		}
	}
439

wyrie's avatar
wyrie committed
440 441 442
	public function configure_bind() {
		global $conf;

443 444 445 446
		//* 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
447
		}
448

wyrie's avatar
wyrie committed
449 450
		//* 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']);
451
		if (stripos($named_conf, 'include "'.$conf['bind']['named_conf_local_path'].'";') === false)
wyrie's avatar
wyrie committed
452 453 454 455 456 457
		{
			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);
				}
458

wyrie's avatar
wyrie committed
459 460 461 462 463 464 465
				wf($conf['bind']['named_conf_path'], $named_conf);
			}
			else {
				af($conf['bind']['named_conf_path'], 'include "'.$conf['bind']['named_conf_local_path'].'";');
			}
		}
	}
466

467
	public function configure_apache()
468
	{
469
		global $conf;
470

Falko Timme's avatar
Falko Timme committed
471
		if($conf['apache']['installed'] == false) return;
wyrie's avatar
wyrie committed
472 473 474
		//* Create the logging directory for the vhost logfiles
		if (!is_dir($conf['ispconfig_log_dir'].'/httpd')) {
			mkdir($conf['ispconfig_log_dir'].'/httpd', 0755, true);
475
		}
476 477

		if (is_file($conf['suphp']['config_file']))
478 479
		{
			$content = rf($conf['suphp']['config_file']);
480

wyrie's avatar
wyrie committed
481 482
			if (!preg_match('|^x-httpd-suphp=php:/usr/bin/php-cgi$|m', $content))
			{
483 484
				$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
485
			}
486

487 488
			$this->write_config_file($conf['suphp']['config_file'], $content);
		}
489

wyrie's avatar
wyrie committed
490
		//* Enable ISPConfig default vhost settings
491
		$default_vhost_path = $conf['apache']['vhost_conf_dir'].'/'.$conf['apache']['vhost_default'];
492
		if (is_file($default_vhost_path))
493 494
		{
			$content = rf($default_vhost_path);
495

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

499 500
			$this->write_config_file($default_vhost_path, $content);
		}
501

wyrie's avatar
wyrie committed
502
		//* Generate default ssl certificates
503 504 505
		if (!is_dir($conf['apache']['ssl_dir'])) {
			mkdir($conf['apache']['ssl_dir']);
		}
506 507

		if ($conf['services']['mail'] == true)
508 509 510 511 512 513 514 515 516 517
		{
			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");
			}
		}
518 519 520



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

524
		$records = $this->db->queryAllRecords("SELECT * FROM server_ip WHERE server_id = ".$conf["server_id"]." AND virtualhost = 'y'");
525
		if(is_array($records) && count($records) > 0)
526 527 528 529 530 531
		{
			foreach($records as $rec) {
				$content .= "NameVirtualHost ".$rec["ip_address"].":80\n";
				$content .= "NameVirtualHost ".$rec["ip_address"].":443\n";
			}
		}
532

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

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

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

wyrie's avatar
wyrie committed
543
		//* make sure that webalizer finds its config file when it is directly in /etc
544
		if(is_file('/etc/webalizer.conf') && !is_dir('/etc/webalizer'))
545 546 547 548
		{
			mkdir('/etc/webalizer', 0755);
			symlink('/etc/webalizer.conf', '/etc/webalizer/webalizer.conf');
		}
549 550 551 552 553 554

		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);
555
		}
556

wyrie's avatar
wyrie committed
557
		//* add a sshusers group
558
		if (!is_group('sshusers'))
559 560 561 562
		{
			$command = 'groupadd sshusers';
			caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		}
563 564 565
	}

	public function configure_apps_vhost()
566 567
	{
		global $conf;
568

569
		//* Create the ispconfig apps vhost user and group
570
		if($conf['apache']['installed'] == true){
Falko Timme's avatar
Falko Timme committed
571 572 573
			$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');
574

Falko Timme's avatar
Falko Timme committed
575 576 577 578
			$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");
			}
579

Falko Timme's avatar
Falko Timme committed
580 581 582 583
			$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");
			}
584

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

588
			if(!@is_dir($install_dir)){
Falko Timme's avatar
Falko Timme committed
589
				mkdir($install_dir, 0755, true);
590 591
			} else {
				chmod($install_dir, 0755);
Falko Timme's avatar
Falko Timme committed
592 593 594
			}
			chown($install_dir, $apps_vhost_user);
			chgrp($install_dir, $apps_vhost_group);
595

Falko Timme's avatar
Falko Timme committed
596 597 598 599
			//* 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'];
600

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

Falko Timme's avatar
Falko Timme committed
604 605 606 607 608
			$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);
609

Falko Timme's avatar
Falko Timme committed
610 611 612 613 614 615
			//* 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);
			}
616

Falko Timme's avatar
Falko Timme committed
617
			$this->write_config_file("$vhost_conf_dir/apps.vhost", $content);
618 619

			//if ( !is_file($conf['web']['website_basedir'].'/php-fcgi-scripts/apps/.php-fcgi-starter') )
620
			//{
621 622 623 624 625 626 627 628 629
			$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');

630
			//}
Falko Timme's avatar
Falko Timme committed
631
		}
632
		if($conf['nginx']['installed'] == true){
Falko Timme's avatar
Falko Timme committed
633 634 635 636 637 638 639 640 641 642 643 644 645 646
			$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
647 648 649 650 651
			if(!@is_dir($install_dir)){
				mkdir($install_dir, 0755, true);
			} else {
				chmod($install_dir, 0755);
			}
Falko Timme's avatar
Falko Timme committed
652 653 654 655 656 657 658 659 660
			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
661
			$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/nginx_apps.vhost.master', 'tpl/nginx_apps.vhost.master');
662

Falko Timme's avatar
Falko Timme committed
663 664 665 666 667
			if($conf['web']['apps_vhost_ip'] == '_default_'){
				$apps_vhost_ip = '';
			} else {
				$apps_vhost_ip = $conf['web']['apps_vhost_ip'].':';
			}
668

669
			$socket_dir = escapeshellcmd($conf['nginx']['php_fpm_socket_dir']);
670
			if(substr($socket_dir, -1) != '/') $socket_dir .= '/';
671 672
			if(!is_dir($socket_dir)) exec('mkdir -p '.$socket_dir);
			$fpm_socket = $socket_dir.'apps.sock';
673
			$cgi_socket = escapeshellcmd($conf['nginx']['cgi_socket']);
Falko Timme's avatar
Falko Timme committed
674 675 676 677 678

			$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);
679 680
			//$content = str_replace('{fpm_port}', ($conf['nginx']['php_fpm_start_port']+1), $content);
			$content = str_replace('{fpm_socket}', $fpm_socket, $content);
681
			$content = str_replace('{cgi_socket}', $cgi_socket, $content);
Falko Timme's avatar
Falko Timme committed
682 683

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

Falko Timme's avatar
Falko Timme committed
685 686
			// PHP-FPM
			// Dont just copy over the php-fpm pool template but add some custom settings
687
			$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
688
			$content = str_replace('{fpm_pool}', 'apps', $content);
689 690
			//$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
691 692 693 694 695 696
			$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
697 698
			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')) {
699
				symlink($vhost_conf_dir.'/apps.vhost', $vhost_conf_enabled_dir.'/000-apps.vhost');
Falko Timme's avatar
Falko Timme committed
700
			}
701

702 703
		}
	}
704 705 706

	public function install_ispconfig()
	{
707
		global $conf;
708

709
		$install_dir = $conf['ispconfig_install_dir'];
710 711 712

		//* Create the ISPConfig installation directory
		if(!is_dir($install_dir))
713 714 715 716
		{
			$command = "mkdir $install_dir";
			caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		}
717

wyrie's avatar
wyrie committed
718
		//* Create a ISPConfig user and group
719
		if (!is_group('ispconfig'))
720 721 722 723
		{
			$command = 'groupadd ispconfig';
			caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		}
724 725

		if (!is_user('ispconfig'))
726 727 728 729
		{
			$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");
		}
730

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

wyrie's avatar
wyrie committed
735
		//* copy the ISPConfig server part
736 737
		$command = "cp -rf ../server $install_dir";
		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
738 739


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

744 745 746 747
		$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);
748

749 750 751
		$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);
752
		$content = str_replace('{timezone}', $conf['timezone'], $content);
cfoe's avatar
cfoe committed
753
		$content = str_replace('{theme}', $conf['theme'], $content);
754
		$content = str_replace('{language_file_import_enabled}', ($conf['language_file_import_enabled'] == true)?'true':'false', $content);
755

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

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

761 762
		//* 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
763 764
		if (!file_exists($install_dir.'/server/lib/remote_action.inc.php')) {
			$content = '<?php' . "\n" . '$maxid_remote_action = 0;' . "\n" . '?>';
765
			wf($install_dir.'/server/lib/remote_action.inc.php', $content);
wyrie's avatar
wyrie committed
766
		}
767 768

		// Enable the server modules and plugins.
769 770 771 772 773
		// 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) {
774 775 776
					if($file != '.' && $file != '..' && substr($file, -8, 8) == '.inc.php') {
						include_once $install_dir.'/server/mods-available/'.$file;
						$module_name = substr($file, 0, -8);
777 778
						$tmp = new $module_name;
						if($tmp->onInstall()) {
wyrie's avatar
wyrie committed
779 780 781 782
							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);
							}
783
							if (strpos($file, '_core_module') !== false) {
wyrie's avatar
wyrie committed
784 785 786 787
								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);
								}