gentoo.lib.php 54.7 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
		global $conf,$autoinstall;
53 54

		$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
Dominik's avatar
Dominik committed
84
		$server_ini_rec = $this->db->queryOneRecord("SELECT config FROM ?? WHERE server_id = ?", $conf["mysql"]["database"].'.server', $conf['server_id']);
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
		$server_ini_array = ini_to_array(stripslashes($server_ini_rec['config']));
		unset($server_ini_rec);

		//* If there are RBL's defined, format the list and add them to smtp_recipient_restrictions to prevent removeal after an update
		$rbl_list = '';
		if (@isset($server_ini_array['mail']['realtime_blackhole_list']) && $server_ini_array['mail']['realtime_blackhole_list'] != '') {
			$rbl_hosts = explode(",", str_replace(" ", "", $server_ini_array['mail']['realtime_blackhole_list']));
			foreach ($rbl_hosts as $key => $value) {
				$rbl_list .= ", reject_rbl_client ". $value;
			}
		}
		unset($rbl_hosts);

		//* If Postgrey is installed, configure it
		$greylisting = '';
		if($conf['postgrey']['installed'] == true) {
			$greylisting = ', check_recipient_access mysql:/etc/postfix/mysql-virtual_policy_greylist.cf';
		}
		
		$reject_sender_login_mismatch = '';
		if(isset($server_ini_array['mail']['reject_sender_login_mismatch']) && ($server_ini_array['mail']['reject_sender_login_mismatch'] == 'y')) {
			$reject_sender_login_mismatch = ', reject_authenticated_sender_login_mismatch';
		}
		unset($server_ini_array);
		
110 111 112 113
		$postconf_placeholders = array('{config_dir}' => $config_dir,
			'{vmail_mailbox_base}' => $cf['vmail_mailbox_base'],
			'{vmail_userid}' => $cf['vmail_userid'],
			'{vmail_groupid}' => $cf['vmail_groupid'],
114 115 116 117
			'{rbl_list}' => $rbl_list,
			'{greylisting}' => $greylisting,
			'{reject_slm}' => $reject_sender_login_mismatch,
		);
118 119 120 121 122

		$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

123 124
		//* These postconf commands will be executed on installation only
		if($this->is_update == false) {
125 126 127 128 129
			$postconf_commands = array_merge($postconf_commands, array(
					'myhostname = '.$conf['hostname'],
					'mydestination = '.$conf['hostname'].', localhost, localhost.localdomain',
					'mynetworks = 127.0.0.0/8 [::1]/128'
				));
130
		}
131

wyrie's avatar
wyrie committed
132
		//* Create the header and body check files
133 134 135 136
		touch($config_dir.'/header_checks');
		touch($config_dir.'/mime_header_checks');
		touch($config_dir.'/nested_header_checks');
		touch($config_dir.'/body_checks');
137 138


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

wyrie's avatar
wyrie committed
142
		//* Executing the postconf commands
143 144
		foreach($postconf_commands as $cmd) {
			$command = "postconf -e '$cmd'";
wyrie's avatar
wyrie committed
145
			caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command);
146
		}
147

wyrie's avatar
wyrie committed
148
		//* Create the SSL certificate
149
		if (!stristr($options, 'dont-create-certs'))
150
		{
Till Brehm's avatar
Till Brehm committed
151 152
			if(AUTOINSTALL){
				$command = 'cd '.$config_dir.'; '
153
					."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";
Till Brehm's avatar
Till Brehm committed
154 155
			} else {
				$command = 'cd '.$config_dir.'; '
156
					.'openssl req -new -outform PEM -out smtpd.cert -newkey rsa:4096 -nodes -keyout smtpd.key -keyform PEM -days 3650 -x509';
Till Brehm's avatar
Till Brehm committed
157
			}
158
			exec($command);
159

160 161 162
			$command = 'chmod o= '.$config_dir.'/smtpd.key';
			caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command);
		}
163

wyrie's avatar
wyrie committed
164 165 166 167 168
		//* 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);
		}
169

wyrie's avatar
wyrie committed
170
		//* Changing maildrop lines in posfix master.cf
171 172 173
		$configfile = $config_dir.'/master.cf';
		$content = rf($configfile);

174 175 176 177 178
		$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);

179
		$this->write_config_file($configfile, $content);
180

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

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

wyrie's avatar
wyrie committed
187
		//* Create the directory for the custom mailfilters
188
		if (!is_dir($cf['vmail_mailbox_base'].'/mailfilters'))
189 190
		{
			$command = 'mkdir '.$cf['vmail_mailbox_base'].'/mailfilters';
wyrie's avatar
wyrie committed
191
			caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
192
		}
193 194 195 196 197

		//* postfix-dkim
		$full_file_name=$config_dir.'/tag_as_originating.re';
		if(is_file($full_file_name)) {
			copy($full_file_name, $config_dir.$configfile.'~');
198 199 200 201 202 203 204 205 206
		}
		$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
207
		//* Chmod and chown the .mailfilter file
208 209
		$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");
210

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

214
	}
215 216

	public function configure_saslauthd()
217 218
	{
		global $conf;
219

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

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

wyrie's avatar
wyrie committed
227
		$this->write_config_file($conf['saslauthd']['config_file'], $content);
228
	}
229

230
	public function configure_courier()
231 232 233
	{
		global $conf;

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

wyrie's avatar
wyrie committed
238
		//* authdaemonrc
239 240 241 242 243
		$configfile = $conf['courier']['config_dir'].'/authdaemonrc';

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

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

wyrie's avatar
wyrie committed
249
		$command = 'mkpop3dcert';
250
		caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
251 252 253 254 255 256
	}

	public function configure_dovecot()
	{
		global $conf;

Dominik Müller's avatar
Dominik Müller committed
257
		$virtual_transport = 'dovecot';
258 259

		$configure_lmtp = false;
Dominik Müller's avatar
Dominik Müller committed
260 261 262
		
		// check if virtual_transport must be changed
		if ($this->is_update) {
263
			$tmp = $this->db->queryOneRecord("SELECT * FROM ?? WHERE server_id = ?", $conf["mysql"]["database"].".server", $conf['server_id']);
Dominik Müller's avatar
Dominik Müller committed
264 265 266 267 268
			$ini_array = ini_to_array(stripslashes($tmp['config']));
			// ini_array needs not to be checked, because already done in update.php -> updateDbAndIni()
			
			if(isset($ini_array['mail']['mailbox_virtual_uidgid_maps']) && $ini_array['mail']['mailbox_virtual_uidgid_maps'] == 'y') {
				$virtual_transport = 'lmtp:unix:private/dovecot-lmtp';
269
				$configure_lmtp = true;
Dominik Müller's avatar
Dominik Müller committed
270 271 272
			}
		}

273
		$config_dir = $conf['postfix']['config_dir'];
274

275
		//* Configure master.cf and add a line for deliver
276
		if(!$this->get_postfix_service('dovecot', 'unix')) {
277 278 279 280 281 282 283 284 285
			//* backup
			if(is_file($config_dir.'/master.cf')){
				copy($config_dir.'/master.cf', $config_dir.'/master.cf~2');
			}
			if(is_file($config_dir.'/master.cf~')){
				chmod($config_dir.'/master.cf~2', 0400);
			}
			//* Configure master.cf and add a line for deliver
			$content = rf($conf["postfix"]["config_dir"].'/master.cf');
286
			$deliver_content = 'dovecot   unix  -       n       n       -       -       pipe'."\n".'  flags=DROhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${user}@${nexthop}'."\n";
287
			af($config_dir.'/master.cf', $deliver_content);
288 289
			unset($content);
			unset($deliver_content);
wyrie's avatar
wyrie committed
290
		}
291

wyrie's avatar
wyrie committed
292 293
		//* Reconfigure postfix to use dovecot authentication
		$postconf_commands = array (
294
			'dovecot_destination_recipient_limit = 1',
Dominik Müller's avatar
Dominik Müller committed
295
			'virtual_transport = '.$virtual_transport,
296 297
			'smtpd_sasl_type = dovecot',
			'smtpd_sasl_path = private/auth'
wyrie's avatar
wyrie committed
298
		);
299

wyrie's avatar
wyrie committed
300
		//* Make a backup copy of the main.cf file
301 302 303 304
		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
305 306 307 308
		{
			$command = "postconf -e '$cmd'";
			caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		}
309

310
		$config_dir = $conf['dovecot']['config_dir'];
wyrie's avatar
wyrie committed
311 312 313 314
		//* copy dovecot.conf
		$configfile = $config_dir.'/dovecot.conf';
		$content = $this->get_template_file('dovecot.conf', true);
		$this->write_config_file($configfile, $content);
315

316 317 318 319 320
		//* dovecot-lmtpd
		if($configure_lmtp) {
			replaceLine($config_dir.'/'.$configfile, 'protocols = imap pop3', 'protocols = imap pop3 lmtp', 1, 0);
		}

wyrie's avatar
wyrie committed
321 322 323 324
		//* 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);
325 326
	}

327
	public function configure_spamassassin()
328
	{
329
		return true;
330 331
	}

332
	public function configure_getmail()
333
	{
334
		global $conf;
335

336
		$config_dir = $conf['getmail']['config_dir'];
337

338
		if (!is_dir($config_dir)) {
wyrie's avatar
wyrie committed
339
			exec('mkdir -p '.escapeshellcmd($config_dir));
340 341 342 343 344 345
		}

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

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

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

wyrie's avatar
wyrie committed
353
		//* Getmail will be run from cron. In order to have access to cron the getmail user needs to be part of the cron group.
354 355 356
		$command = "gpasswd -a getmail " . $conf['cron']['group'];
		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
	}
357 358 359

	public function configure_amavis()
	{
360
		global $conf;
361

wyrie's avatar
wyrie committed
362
		//* Amavisd-new user config file
363 364
		$conf_file = 'amavisd-ispconfig.conf';
		$conf_path = dirname($conf['amavis']['config_file']) . '/' . $conf_file;
365

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

wyrie's avatar
wyrie committed
369
		//* Activate config directory in default file
370
		$amavis_conf = rf($conf['amavis']['config_file']);
371
		if (stripos($amavis_conf, $conf_path) === false)
372
		{
wyrie's avatar
wyrie committed
373
			$amavis_conf = preg_replace('/^(1;.*)$/m', "include_config_files('$conf_path');\n$1", $amavis_conf);
374 375
			$this->write_config_file($conf['amavis']['config_file'], $amavis_conf);
		}
376

wyrie's avatar
wyrie committed
377
		//* Adding the amavisd commands to the postfix configuration
378 379 380 381
		$postconf_commands = array (
			'content_filter = amavis:[127.0.0.1]:10024',
			'receive_override_options = no_address_mappings'
		);
382 383

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

388 389 390
		$config_dir = $conf['postfix']['config_dir'];

		// Adding amavis-services to the master.cf file if the service does not already exists
391 392 393
		$add_amavis = !$this->get_postfix_service('amavis','unix');
		$add_amavis_10025 = !$this->get_postfix_service('127.0.0.1:10025','inet');
		$add_amavis_10027 = !$this->get_postfix_service('127.0.0.1:10027','inet');
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413

		if ($add_amavis || $add_amavis_10025 || $add_amavis_10027) {
			//* backup master.cf
			if(is_file($config_dir.'/master.cf')) copy($config_dir.'/master.cf', $config_dir.'/master.cf~');
			// adjust amavis-config
			if($add_amavis) {
				$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis.master', 'tpl/master_cf_amavis.master');
				af($config_dir.'/master.cf', $content);
				unset($content);
			}
			if ($add_amavis_10025) {
				$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10025.master', 'tpl/master_cf_amavis10025.master');
				af($config_dir.'/master.cf', $content);
				unset($content);
			}
			if ($add_amavis_10027) {
				$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10027.master', 'tpl/master_cf_amavis10027.master');
				af($config_dir.'/master.cf', $content);
				unset($content);
			}
414
		}
415

wyrie's avatar
wyrie committed
416
		//* Add the clamav user to the amavis group
417
		exec('usermod -a -G amavis clamav');
418 419 420 421
	}

	public function configure_pureftpd()
	{
422
		global $conf;
423

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

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

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

433 434
		$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);
435

wyrie's avatar
wyrie committed
436 437
		//* Logging defaults to syslog's ftp facility. Override this behaviour for better compatibility with debian/ubuntu
		//* and specify the format.
438 439 440 441
		$logdir = '/var/log/pure-ftpd';
		if (!is_dir($logdir)) {
			mkdir($logdir, 0755, true);
		}
442

wyrie's avatar
wyrie committed
443
		/**
444 445 446 447 448 449
		 * @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)
450
		 * -D displaydotfiles
wyrie's avatar
wyrie committed
451
		 * -H dontresolve
452
		 */
453 454


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

wyrie's avatar
wyrie committed
457
		$this->write_config_file($conf['pureftpd']['config_file'], $content);
458 459 460
	}

	public function configure_powerdns()
461 462
	{
		global $conf;
463

464
		//* Create the database
465
		if(!$this->db->query('CREATE DATABASE IF NOT EXISTS ?? DEFAULT CHARACTER SET ?', $conf['powerdns']['database'], $conf['mysql']['charset'])) {
466 467
			$this->error('Unable to create MySQL database: '.$conf['powerdns']['database'].'.');
		}
468

469
		//* Create the ISPConfig database user in the local database
470 471
		$query = 'GRANT ALL ON ??.* TO ?@?';
		if(!$this->db->query($query, $conf['powerdns']['database'], $conf['mysql']['ispconfig_user'], 'localhost')) {
472 473
			$this->error('Unable to create user for powerdns database Error: '.$this->db->errorMessage);
		}
474

475 476
		//* Reload database privelages
		$this->db->query('FLUSH PRIVILEGES;');
477

478 479
		//* load the powerdns databse dump
		if($conf['mysql']['admin_password'] == '') {
480 481
			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');
482
		} else {
483 484
			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');
485
		}
486

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

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

wyrie's avatar
wyrie committed
493
		//* Create symlink to init script to start the correct config file
494 495 496 497
		if( !is_link($conf['init_scripts'].'/'.$conf['powerdns']['init_script']) ) {
			symlink($conf['init_scripts'].'/pdns', $conf['init_scripts'].'/'.$conf['powerdns']['init_script']);
		}
	}
498

wyrie's avatar
wyrie committed
499 500 501
	public function configure_bind() {
		global $conf;

502 503 504 505
		//* 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
506
		}
507

wyrie's avatar
wyrie committed
508 509
		//* 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']);
510
		if (stripos($named_conf, 'include "'.$conf['bind']['named_conf_local_path'].'";') === false)
wyrie's avatar
wyrie committed
511 512 513 514 515 516
		{
			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);
				}
517

wyrie's avatar
wyrie committed
518 519 520 521 522 523 524
				wf($conf['bind']['named_conf_path'], $named_conf);
			}
			else {
				af($conf['bind']['named_conf_path'], 'include "'.$conf['bind']['named_conf_local_path'].'";');
			}
		}
	}
525

526
	public function configure_apache()
527
	{
528
		global $conf;
529

Falko Timme's avatar
Falko Timme committed
530
		if($conf['apache']['installed'] == false) return;
wyrie's avatar
wyrie committed
531 532 533
		//* Create the logging directory for the vhost logfiles
		if (!is_dir($conf['ispconfig_log_dir'].'/httpd')) {
			mkdir($conf['ispconfig_log_dir'].'/httpd', 0755, true);
534
		}
535 536

		if (is_file($conf['suphp']['config_file']))
537 538
		{
			$content = rf($conf['suphp']['config_file']);
539

wyrie's avatar
wyrie committed
540 541
			if (!preg_match('|^x-httpd-suphp=php:/usr/bin/php-cgi$|m', $content))
			{
542 543
				$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
544
			}
545

546 547
			$this->write_config_file($conf['suphp']['config_file'], $content);
		}
548

wyrie's avatar
wyrie committed
549
		//* Enable ISPConfig default vhost settings
550
		$default_vhost_path = $conf['apache']['vhost_conf_dir'].'/'.$conf['apache']['vhost_default'];
551
		if (is_file($default_vhost_path))
552 553
		{
			$content = rf($default_vhost_path);
554

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

558 559
			$this->write_config_file($default_vhost_path, $content);
		}
560

wyrie's avatar
wyrie committed
561
		//* Generate default ssl certificates
562 563 564
		if (!is_dir($conf['apache']['ssl_dir'])) {
			mkdir($conf['apache']['ssl_dir']);
		}
565 566

		if ($conf['services']['mail'] == true)
567 568 569 570 571 572 573 574 575 576
		{
			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");
			}
		}
577 578 579



wyrie's avatar
wyrie committed
580
		//* Copy the ISPConfig configuration include
581 582 583
		$tpl = new tpl('apache_ispconfig.conf.master');
		$tpl->setVar('apache_version',getapacheversion());
		
584
		$records = $this->db->queryAllRecords("SELECT * FROM ?? WHERE server_id = ? AND virtualhost = 'y'", $conf['mysql']['master_database'] . '.server_ip', $conf['server_id']);
585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604
		$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);
						}
					}
				}
			}
		}
605
		
Till Brehm's avatar
Till Brehm committed
606
		if(count($ip_addresses) > 0) $tpl->setLoop('ip_adresses',$ip_addresses);
607 608 609

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

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

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

wyrie's avatar
wyrie committed
619
		//* make sure that webalizer finds its config file when it is directly in /etc
620
		if(is_file('/etc/webalizer.conf') && !is_dir('/etc/webalizer'))
621 622 623 624
		{
			mkdir('/etc/webalizer', 0755);
			symlink('/etc/webalizer.conf', '/etc/webalizer/webalizer.conf');
		}
625 626 627 628 629 630

		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);
631
		}
632

wyrie's avatar
wyrie committed
633
		//* add a sshusers group
634
		if (!is_group('sshusers'))
635 636 637 638
		{
			$command = 'groupadd sshusers';
			caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		}
639 640 641
	}

	public function configure_apps_vhost()
642 643
	{
		global $conf;
644

645
		//* Create the ispconfig apps vhost user and group
646
		if($conf['apache']['installed'] == true){
Falko Timme's avatar
Falko Timme committed
647 648 649
			$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');
650

Falko Timme's avatar
Falko Timme committed
651 652 653 654
			$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");
			}
655

Falko Timme's avatar
Falko Timme committed
656 657 658 659
			$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");
			}
660

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

664
			if(!@is_dir($install_dir)){
Falko Timme's avatar
Falko Timme committed
665
				mkdir($install_dir, 0755, true);
666 667
			} else {
				chmod($install_dir, 0755);
Falko Timme's avatar
Falko Timme committed
668 669 670
			}
			chown($install_dir, $apps_vhost_user);
			chgrp($install_dir, $apps_vhost_group);
671

Falko Timme's avatar
Falko Timme committed
672 673 674 675
			//* 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'];
676

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

Falko Timme's avatar
Falko Timme committed
680 681 682 683 684
			$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);
685

Falko Timme's avatar
Falko Timme committed
686 687 688 689 690 691
			//* 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);
			}
692

Falko Timme's avatar
Falko Timme committed
693
			$this->write_config_file("$vhost_conf_dir/apps.vhost", $content);
694 695

			//if ( !is_file($conf['web']['website_basedir'].'/php-fcgi-scripts/apps/.php-fcgi-starter') )
696
			//{
697 698 699 700 701 702 703 704 705
			$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');

706
			//}
Falko Timme's avatar
Falko Timme committed
707
		}
708
		if($conf['nginx']['installed'] == true){
Falko Timme's avatar
Falko Timme committed
709 710 711 712 713 714 715 716 717 718 719 720 721 722
			$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
723 724 725 726 727
			if(!@is_dir($install_dir)){
				mkdir($install_dir, 0755, true);
			} else {
				chmod($install_dir, 0755);
			}
Falko Timme's avatar
Falko Timme committed
728 729 730 731 732 733 734 735 736
			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
737
			$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/nginx_apps.vhost.master', 'tpl/nginx_apps.vhost.master');
738

Falko Timme's avatar
Falko Timme committed
739 740 741 742 743
			if($conf['web']['apps_vhost_ip'] == '_default_'){
				$apps_vhost_ip = '';
			} else {
				$apps_vhost_ip = $conf['web']['apps_vhost_ip'].':';
			}
744

745
			$socket_dir = escapeshellcmd($conf['nginx']['php_fpm_socket_dir']);
746
			if(substr($socket_dir, -1) != '/') $socket_dir .= '/';
747 748
			if(!is_dir($socket_dir)) exec('mkdir -p '.$socket_dir);
			$fpm_socket = $socket_dir.'apps.sock';
749
			$cgi_socket = escapeshellcmd($conf['nginx']['cgi_socket']);
Falko Timme's avatar
Falko Timme committed
750 751 752 753 754

			$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);
755 756
			//$content = str_replace('{fpm_port}', ($conf['nginx']['php_fpm_start_port']+1), $content);
			$content = str_replace('{fpm_socket}', $fpm_socket, $content);
757
			$content = str_replace('{cgi_socket}', $cgi_socket, $content);
Till Brehm's avatar
Till Brehm committed
758 759 760 761 762
			
			// SSL in apps vhost is off by default. Might change later.
			$content = str_replace('{ssl_on}', 'off', $content);
			$content = str_replace('{ssl_comment}', '#', $content);
			
Falko Timme's avatar
Falko Timme committed
763
			wf($vhost_conf_dir.'/apps.vhost', $content);
764

Falko Timme's avatar
Falko Timme committed
765 766
			// PHP-FPM
			// Dont just copy over the php-fpm pool template but add some custom settings
767
			$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
768
			$content = str_replace('{fpm_pool}', 'apps', $content);
769 770
			//$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
771 772 773 774 775 776
			$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
777 778
			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')) {
779
				symlink($vhost_conf_dir.'/apps.vhost', $vhost_conf_enabled_dir.'/000-apps.vhost');
Falko Timme's avatar
Falko Timme committed
780
			}
781

782 783
		}
	}
784 785 786

	public function install_ispconfig()
	{
787
		global $conf;
788

789
		$install_dir = $conf['ispconfig_install_dir'];
790 791 792

		//* Create the ISPConfig installation directory
		if(!is_dir($install_dir))
793 794 795 796
		{
			$command = "mkdir $install_dir";
			caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		}
797

wyrie's avatar
wyrie committed
798
		//* Create a ISPConfig user and group
Marius Cramer's avatar