Skip to content
installer_base.lib.php 178 KiB
Newer Older

			$out = "";
			$reading_service = false;

			while ( !feof( $cf ) ) {
				$line = fgets( $cf );

				$quoted_regex = '^'.preg_quote($service, '/').'\s+'.preg_quote($type, '/');
				if ( $reading_service ) {
					# regex matches a new service or "empty" (whitespace) line
					if ( preg_match( '/^([^\s#]+.*|\s*)$/', $line ) &&
					   ! preg_match( "/$quoted_regex/", $line ) ) {
						$out .= $line;
						$reading_service = false;
					}

					# $skipped_lines .= $line;

				# regex matches definition matching service to be removed
				} else if ( preg_match( "/$quoted_regex/", $line ) ) {

					$reading_service = true;
					# $skipped_lines .= $line;

				} else {
					$out .= $line;
				}
			}
			fclose( $cf );

			$out = preg_replace( '/(\r?\n){3,}/', '$1$1', $out ); # reduce 3 or more newlines to 2

			return wf( $conf['postfix']['config_dir'].'/master.cf', $out );
		}

		return true;
	}

latham's avatar
latham committed
	public function configure_postfix($options = '') {
		global $conf,$autoinstall;
latham's avatar
latham committed
		$cf = $conf['postfix'];
		$config_dir = $cf['config_dir'];

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

Jesse Norell's avatar
Jesse Norell committed
		exec('postconf -d mail_version 2>&1', $out);
		$postfix_version = preg_replace('/.*=\s*/', '', $out[0]);
		unset($out);

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

		// test if lmtp if available
		$configure_lmtp = $this->get_postfix_service('lmtp','unix');

		$filename='tag_as_originating.re';
		$full_file_name=$config_dir.'/'.$filename;
Florian Schaal's avatar
Florian Schaal committed
		if(is_file($full_file_name)) copy($full_file_name, $full_file_name.'~');
		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/postfix-'.$filename.'.master', 'tpl/postfix-'.$filename.'.master');
		if($configure_lmtp) {
			$content = preg_replace('/amavis:/', 'lmtp:', $content);
		}
		wf($full_file_name, $content);
		$filename='tag_as_foreign.re';
		$full_file_name=$config_dir.'/'.$filename;
Florian Schaal's avatar
Florian Schaal committed
		if(is_file($full_file_name)) copy($full_file_name, $full_file_name.'~');
		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/postfix-'.$filename.'.master', 'tpl/postfix-'.$filename.'.master');
		if($configure_lmtp) {
			$content = preg_replace('/amavis:/', 'lmtp:', $content);
		}
		wf($full_file_name, $content);
latham's avatar
latham committed
		//* Creating virtual mail user and group
		$command = 'groupadd -g '.$cf['vmail_groupid'].' '.$cf['vmail_groupname'];
		if(!is_group($cf['vmail_groupname'])) caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");

		$command = 'useradd -g '.$cf['vmail_groupname'].' -u '.$cf['vmail_userid'].' '.$cf['vmail_username'].' -d '.$cf['vmail_mailbox_base'].' -m';
		if(!is_user($cf['vmail_username'])) caselog("$command &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		//* These postconf commands will be executed on installation and update
		$server_ini_rec = $this->db->queryOneRecord("SELECT config FROM ?? WHERE server_id = ?", $conf["mysql"]["database"] . '.server', $conf['server_id']);
		$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);
Dominik's avatar
Dominik committed
		//* 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 = '';
		$reject_authenticated_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_sender_login_mismatch,';
			$reject_authenticated_sender_login_mismatch = 'reject_authenticated_sender_login_mismatch, ';

		# placeholder includes comment char
		$stress_adaptive_placeholder = '#{stress_adaptive}';
		$stress_adaptive = (isset($server_ini_array['mail']['stress_adaptive']) && ($server_ini_array['mail']['stress_adaptive'] == 'y')) ? '' : $stress_adaptive_placeholder;

		$reject_unknown_client_hostname='';
		if (isset($server_ini_array['mail']['reject_unknown']) && ($server_ini_array['mail']['reject_unknown'] == 'client' || $server_ini_array['mail']['reject_unknown'] == 'client_helo')) {
			$reject_unknown_client_hostname=',reject_unknown_client_hostname';
		}
		$reject_unknown_helo_hostname='';
		if ((!isset($server_ini_array['mail']['reject_unknown'])) || $server_ini_array['mail']['reject_unknown'] == 'helo' || $server_ini_array['mail']['reject_unknown'] == 'client_helo') {
			$reject_unknown_helo_hostname=',reject_unknown_helo_hostname';
		}

		unset($server_ini_array);
		$myhostname = str_replace('.','\.',$conf['hostname']);
		$postconf_placeholders = array('{config_dir}' => $config_dir,
			'{vmail_mailbox_base}' => $cf['vmail_mailbox_base'],
			'{vmail_userid}' => $cf['vmail_userid'],
			'{vmail_groupid}' => $cf['vmail_groupid'],
Dominik's avatar
Dominik committed
			'{rbl_list}' => $rbl_list,
			'{greylisting}' => $greylisting,
			'{reject_slm}' => $reject_sender_login_mismatch,
			'{reject_aslm}' => $reject_authenticated_sender_login_mismatch,
			'{myhostname}' => $myhostname,
			$stress_adaptive_placeholder => $stress_adaptive,
			'{reject_unknown_client_hostname}' => $reject_unknown_client_hostname,
			'{reject_unknown_helo_hostname}' => $reject_unknown_helo_hostname,
Dominik's avatar
Dominik committed
		);

		$postconf_tpl = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/debian_postfix.conf.master', 'tpl/debian_postfix.conf.master');
		$postconf_tpl = strtr($postconf_tpl, $postconf_placeholders);
		$postconf_commands = array_filter(explode("\n", $postconf_tpl)); // read and remove empty lines
		//* Merge version-specific postfix config
		if(version_compare($postfix_version , '2.5', '>=')) {
		    $configfile = 'postfix_2-5.conf';
		    $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master');
		    $content = strtr($content, $postconf_placeholders);
		    $postconf_commands = array_merge($postconf_commands, array_filter(explode("\n", $content)));
		}
		if(version_compare($postfix_version , '2.10', '>=')) {
		    $configfile = 'postfix_2-10.conf';
		    $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master');
		    $content = strtr($content, $postconf_placeholders);
		    $postconf_commands = array_merge($postconf_commands, array_filter(explode("\n", $content)));
		}
		if(version_compare($postfix_version , '3.0', '>=')) {
		    $configfile = 'postfix_3-0.conf';
		    $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master');
		    $content = strtr($content, $postconf_placeholders);
		    $postconf_commands = array_merge($postconf_commands, array_filter(explode("\n", $content)));
		}
		if(version_compare($postfix_version , '3.3', '>=')) {
		    $configfile = 'postfix_3-3.conf';
		    $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master');
		    $content = strtr($content, $postconf_placeholders);
		    $postconf_commands = array_merge($postconf_commands, array_filter(explode("\n", $content)));
		}
Thom's avatar
Thom committed
		$configfile = 'postfix_custom.conf';
		if(file_exists($conf['ispconfig_install_dir'].'/server/conf-custom/install/' . $configfile . '.master')) {
			$content = file_get_contents($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master');
			$content = strtr($content, $postconf_placeholders);
			$postconf_commands = array_merge($postconf_commands, array_filter(explode("\n", $content)));
		// Remove comment lines, these would give fatal errors when passed to postconf.
		$postconf_commands = array_filter($postconf_commands, function($line) { return preg_match('/^[^#]/', $line); });

		//* These postconf commands will be executed on installation only
		if($this->is_update == false) {
			$postconf_commands = array_merge($postconf_commands, array(
					'myhostname = '.$conf['hostname'],
					'mydestination = '.$conf['hostname'].', localhost, localhost.localdomain',
					'mynetworks = 127.0.0.0/8 [::1]/128'
				));
latham's avatar
latham committed

		//* Create the header and body check files
		touch($config_dir.'/header_checks');
		touch($config_dir.'/mime_header_checks');
		touch($config_dir.'/nested_header_checks');
		touch($config_dir.'/body_checks');
		touch($config_dir.'/sasl_passwd');
latham's avatar
latham committed
		//* Create the mailman files
		if(!is_dir('/var/lib/mailman/data')) exec('mkdir -p /var/lib/mailman/data');
		if(!is_file('/var/lib/mailman/data/aliases')) touch('/var/lib/mailman/data/aliases');
		exec('postalias /var/lib/mailman/data/aliases');
		if(!is_file('/var/lib/mailman/data/virtual-mailman')) touch('/var/lib/mailman/data/virtual-mailman');
		exec('postmap /var/lib/mailman/data/virtual-mailman');
		if(!is_file('/var/lib/mailman/data/transport-mailman')) touch('/var/lib/mailman/data/transport-mailman');
		exec('/usr/sbin/postmap /var/lib/mailman/data/transport-mailman');
		//* Create auxillary postfix conf files
		$configfile = 'helo_access';
		if(is_file($config_dir.'/'.$configfile)) {
			copy($config_dir.'/'.$configfile, $config_dir.'/'.$configfile.'~');
			chmod($config_dir.'/'.$configfile.'~', 0400);
		}
		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master');
		$content = strtr($content, $postconf_placeholders);
		# todo: look up this server's ip addrs and loop through each
		# todo: look up domains hosted on this server and loop through each
		wf($config_dir.'/'.$configfile, $content);

		$configfile = 'blacklist_helo';
		if(is_file($config_dir.'/'.$configfile)) {
			copy($config_dir.'/'.$configfile, $config_dir.'/'.$configfile.'~');
			chmod($config_dir.'/'.$configfile.'~', 0400);
		}
		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master');
		$content = strtr($content, $postconf_placeholders);
		wf($config_dir.'/'.$configfile, $content);

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

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

		if(!stristr($options, 'dont-create-certs')) {
latham's avatar
latham committed
			//* Create the SSL certificate
			if(AUTOINSTALL){
				$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";
			} else {
				$command = 'cd '.$config_dir.'; '
					.'openssl req -new -outform PEM -out smtpd.cert -newkey rsa:4096 -nodes -keyout smtpd.key -keyform PEM -days 3650 -x509';
			}
latham's avatar
latham committed
			exec($command);

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

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

		//* Check maildrop service in posfix master.cf
		$quoted_regex = '^maildrop   unix.*pipe flags=DRhu user=vmail '.preg_quote('argv=/usr/bin/maildrop -d '.$cf['vmail_username'].' ${extension} ${recipient} ${user} ${nexthop} ${sender}', '/');
		$configfile = $config_dir.'/master.cf';
		if($this->get_postfix_service('maildrop', 'unix')) {
			exec ("postconf -M maildrop.unix 2> /dev/null", $out, $ret);
			$change_maildrop_flags = @(preg_match("/$quoted_regex/", $out[0]) && $out[0] !='')?false:true;
			$change_maildrop_flags = @(preg_match("/$quoted_regex/", $configfile))?false:true;
		if ($change_maildrop_flags) {
			//* Change maildrop service in posfix master.cf
			if(is_file($config_dir.'/master.cf')) {
				copy($config_dir.'/master.cf', $config_dir.'/master.cf~');
			}
			if(is_file($config_dir.'/master.cf~')) {
				chmod($config_dir.'/master.cf~', 0400);
 			}
			$configfile = $config_dir.'/master.cf';
			$content = rf($configfile);
			$content =	str_replace('flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}',
						'flags=DRhu user='.$cf['vmail_username'].' argv=/usr/bin/maildrop -d '.$cf['vmail_username'].' ${extension} ${recipient} ${user} ${nexthop} ${sender}',
						$content);
			wf($configfile, $content);
latham's avatar
latham committed
		}

		//* Writing the Maildrop mailfilter file
		$configfile = 'mailfilter';
		if(is_file($cf['vmail_mailbox_base'].'/.'.$configfile)) {
			copy($cf['vmail_mailbox_base'].'/.'.$configfile, $cf['vmail_mailbox_base'].'/.'.$configfile.'~');
		}
		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master');
latham's avatar
latham committed
		$content = str_replace('{dist_postfix_vmail_mailbox_base}', $cf['vmail_mailbox_base'], $content);
		wf($cf['vmail_mailbox_base'].'/.'.$configfile, $content);

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

		//* Chmod and chown the .mailfilter file
		$command = 'chown '.$cf['vmail_username'].':'.$cf['vmail_groupname'].' '.$cf['vmail_mailbox_base'].'/.mailfilter';
latham's avatar
latham committed
		caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");

		$command = 'chmod 600 '.$cf['vmail_mailbox_base'].'/.mailfilter';
latham's avatar
latham committed
		caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");

	}
latham's avatar
latham committed
	public function configure_saslauthd() {
		global $conf;
		//* Get saslsauthd version
		exec('saslauthd -v 2>&1', $out);
		$parts = explode(' ', $out[0]);
		$saslversion = $parts[1];
		unset($parts);
		unset($out);
		if(version_compare($saslversion , '2.1.23', '<=')) {
			//* Configfile for saslauthd versions up to 2.1.23
			$configfile = 'sasl_smtpd.conf';
		} else {
			//* Configfile for saslauthd versions 2.1.24 and newer
			$configfile = 'sasl_smtpd2.conf';
		if(is_file($conf['postfix']['config_dir'].'/sasl/smtpd.conf')) copy($conf['postfix']['config_dir'].'/sasl/smtpd.conf', $conf['postfix']['config_dir'].'/sasl/smtpd.conf~');
latham's avatar
latham committed
		if(is_file($conf['postfix']['config_dir'].'/sasl/smtpd.conf~')) chmod($conf['postfix']['config_dir'].'/sasl/smtpd.conf~', 0400);
		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master');
		$content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content);
		$content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content);
		$content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content);
		$content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content);
		wf($conf['postfix']['config_dir'].'/sasl/smtpd.conf', $content);
latham's avatar
latham committed

		// TODO: Chmod and chown on the config file


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

		// Edit the file /etc/default/saslauthd
		$configfile = $conf['saslauthd']['config'];
		if(is_file($configfile)) copy($configfile, $configfile.'~');
latham's avatar
latham committed
		if(is_file($configfile.'~')) chmod($configfile.'~', 0400);
		$content = rf($configfile);
		$content = str_replace('START=no', 'START=yes', $content);
latham's avatar
latham committed
		// Debian
		$content = str_replace('OPTIONS="-c"', 'OPTIONS="-m /var/spool/postfix/var/run/saslauthd -r"', $content);
latham's avatar
latham committed
		// Ubuntu
		$content = str_replace('OPTIONS="-c -m /var/run/saslauthd"', 'OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd -r"', $content);
		wf($configfile, $content);
latham's avatar
latham committed

		// Edit the file /etc/init.d/saslauthd
		$configfile = $conf['init_scripts'].'/'.$conf['saslauthd']['init_script'];
		$content = rf($configfile);
		$content = str_replace('PIDFILE=$RUN_DIR/saslauthd.pid', 'PIDFILE="/var/spool/postfix/var/run/${NAME}/saslauthd.pid"', $content);
		wf($configfile, $content);
latham's avatar
latham committed

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


	}

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

		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master');
latham's avatar
latham committed
		$content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content);
		$content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content);
		$content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content);
		$content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content);
		wf($pam.'/smtp', $content);
		// On some OSes smtp is world readable which allows for reading database information.  Removing world readable rights should have no effect.
		if(is_file($pam.'/smtp'))    exec("chmod o= $pam/smtp");
		chmod($pam.'/smtp', 0660);
		chown($pam.'/smtp', 'daemon');
		chgrp($pam.'/smtp', 'daemon');

	}

	public function configure_courier() {
		global $conf;
		$config_dir = $conf['courier']['config_dir'];
		//* authmysqlrc
		$configfile = 'authmysqlrc';
		if(is_file($config_dir.'/'.$configfile)) {
			copy($config_dir.'/'.$configfile, $config_dir.'/'.$configfile.'~');
		}
		chmod($config_dir.'/'.$configfile.'~', 0400);
		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master');
		$content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content);
		$content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content);
		$content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content);
		$content = str_replace('{mysql_server_host}', $conf['mysql']['host'], $content);
		$content = str_replace('{mysql_server_port}', $conf['mysql']['port'], $content);
latham's avatar
latham committed
		wf($config_dir.'/'.$configfile, $content);

		chmod($config_dir.'/'.$configfile, 0660);
		chown($config_dir.'/'.$configfile, 'daemon');
		chgrp($config_dir.'/'.$configfile, 'daemon');

		//* authdaemonrc
		$configfile = $config_dir.'/authdaemonrc';
		if(is_file($configfile)) {
			copy($configfile, $configfile.'~');
		}
		if(is_file($configfile.'~')) {
			chmod($configfile.'~', 0400);
		}
		$content = rf($configfile);
		$content = str_replace('authmodulelist="authpam"', 'authmodulelist="authmysql"', $content);
		wf($configfile, $content);
	}

	public function configure_dovecot() {
		global $conf;
		$virtual_transport = 'dovecot';

		// use lmtp if installed
		if($configure_lmtp = (is_file('/usr/lib/dovecot/lmtp') || is_file('/usr/libexec/dovecot/lmtp'))) {
			$virtual_transport = 'lmtp:unix:private/dovecot-lmtp';
		}

		// check if virtual_transport must be changed
		if ($this->is_update) {
			$tmp = $this->db->queryOneRecord("SELECT * FROM ?? WHERE server_id = ?", $conf["mysql"]["database"] . ".server", $conf['server_id']);
			$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';
		$config_dir = $conf['postfix']['config_dir'];
		$quoted_config_dir = preg_quote($config_dir, '|');
		$postfix_version = `postconf -d mail_version 2>/dev/null`;
		$postfix_version = preg_replace( '/mail_version\s*=\s*(.*)\s*/', '$1', $postfix_version );
latham's avatar
latham committed
		//* Configure master.cf and add a line for deliver
		if(!$this->get_postfix_service('dovecot', 'unix')) {
 			//* 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($config_dir.'/master.cf');
			$deliver_content = 'dovecot   unix  -       n       n       -       -       pipe'."\n".'  flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${user}@${nexthop}'."\n";
			af($config_dir.'/master.cf', $deliver_content);
			unset($content);
			unset($deliver_content);
latham's avatar
latham committed
		}

		//* Reconfigure postfix to use dovecot authentication
		// Adding the amavisd commands to the postfix configuration
		$postconf_commands = array (
			'dovecot_destination_recipient_limit = 1',
			'virtual_transport = '.$virtual_transport,
			'smtpd_sasl_type = dovecot',
			'smtpd_sasl_path = private/auth'
latham's avatar
latham committed
		);

		// Make a backup copy of the main.cf file
		copy($config_dir.'/main.cf', $config_dir.'/main.cf~3');

		$options = preg_split("/,\s*/", exec("postconf -h smtpd_recipient_restrictions"));
		$new_options = array();
		foreach ($options as $value) {
			$value = trim($value);
			if ($value == '') continue;
			if (preg_match("|check_recipient_access\s+proxy:mysql:${quoted_config_dir}/mysql-verify_recipients.cf|", $value)) {
				continue;
			}
			$new_options[] = $value;
		}
		if ($configure_lmtp && $conf['mail']['content_filter'] === 'amavisd') {
			for ($i = 0; isset($new_options[$i]); $i++) {
				if ($new_options[$i] == 'reject_unlisted_recipient') {
					array_splice($new_options, $i+1, 0, array("check_recipient_access proxy:mysql:${config_dir}/mysql-verify_recipients.cf"));
					break;
				}
			}
			# postfix < 3.3 needs this when using reject_unverified_recipient:
			if(version_compare($postfix_version, 3.3, '<')) {
				$postconf_commands[] = "enable_original_recipient = yes";
			}
		}
		$postconf_commands[] = "smtpd_recipient_restrictions = ".implode(", ", $new_options);
latham's avatar
latham committed

		// Executing the postconf commands
		foreach($postconf_commands as $cmd) {
			$command = "postconf -e '$cmd'";
			caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		}

		//* backup dovecot.conf
		$config_dir = $conf['dovecot']['config_dir'];
latham's avatar
latham committed
		$configfile = 'dovecot.conf';
		if(is_file($config_dir.'/'.$configfile)) {
			copy($config_dir.'/'.$configfile, $config_dir.'/'.$configfile.'~');
		}
		//* Get the dovecot version
		exec('dovecot --version', $tmp);
		//* Copy dovecot configuration file
		if(version_compare($dovecot_version,1, '<=')) {	//* Dovecot 1.x
			if(is_file($conf['ispconfig_install_dir'].'/server/conf-custom/install/debian_dovecot.conf.master')) {
				copy($conf['ispconfig_install_dir'].'/server/conf-custom/install/debian_dovecot.conf.master', $config_dir.'/'.$configfile);
			} else {
				copy('tpl/debian_dovecot.conf.master', $config_dir.'/'.$configfile);
			}
		} else {	//* Dovecot 2.x
			if(is_file($conf['ispconfig_install_dir'].'/server/conf-custom/install/debian_dovecot2.conf.master')) {
				copy($conf['ispconfig_install_dir'].'/server/conf-custom/install/debian_dovecot2.conf.master', $config_dir.'/'.$configfile);
			} else {
				copy('tpl/debian_dovecot2.conf.master', $config_dir.'/'.$configfile);
			}
			// Copy custom config file
			if(is_file($conf['ispconfig_install_dir'].'/server/conf-custom/install/dovecot_custom.conf.master')) {
				copy($conf['ispconfig_install_dir'].'/server/conf-custom/install/dovecot_custom.conf.master', $config_dir.'/conf.d/99-ispconfig-custom-config.conf');
			}
			replaceLine($config_dir.'/'.$configfile, 'postmaster_address = postmaster@example.com', 'postmaster_address = postmaster@'.$conf['hostname'], 1, 0);
			replaceLine($config_dir.'/'.$configfile, 'postmaster_address = webmaster@localhost', 'postmaster_address = postmaster@'.$conf['hostname'], 1, 0);
			if(version_compare($dovecot_version, 2.1, '<')) {
				removeLine($config_dir.'/'.$configfile, 'ssl_protocols =');
			}
			if(version_compare($dovecot_version,2.2) >= 0) {
				// Dovecot > 2.2 does not recognize !SSLv2 anymore on Debian 9
				$content = file_get_contents($config_dir.'/'.$configfile);
				$content = str_replace('!SSLv2','',$content);
				file_put_contents($config_dir.'/'.$configfile,$content);
				unset($content);
			if(version_compare($dovecot_version,2.3) >= 0) {
				// Remove deprecated setting(s)
				removeLine($config_dir.'/'.$configfile, 'ssl_protocols =');
				// Check if we have a dhparams file and if not, create it
				if(!file_exists('/etc/dovecot/dh.pem')) {
					swriteln('Creating new DHParams file, this takes several minutes. Do not interrupt the script.');
					if(file_exists('/var/lib/dovecot/ssl-parameters.dat')) {
						// convert existing ssl parameters file
						$command = 'dd if=/var/lib/dovecot/ssl-parameters.dat bs=1 skip=88 | openssl dhparam -inform der > /etc/dovecot/dh.pem';
						caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
					} else {
						/*
						   Create a new dhparams file. We use 2048 bit only as it simply takes too long
						   on smaller systems to generate a 4096 bit dh file (> 30 minutes). If you need
						   a 4096 bit file, create it manually before you install ISPConfig
						*/
						$command = 'openssl dhparam -out /etc/dovecot/dh.pem 2048';
						caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
					}
				}
				//remove #2.3+ comment
				$content = file_get_contents($config_dir.'/'.$configfile);
				$content = str_replace('#2.3+ ','',$content);
				file_put_contents($config_dir.'/'.$configfile,$content);
				unset($content);
			} else {
				// remove settings which are not supported in Dovecot < 2.3
				removeLine($config_dir.'/'.$configfile, 'ssl_min_protocol =');
				removeLine($config_dir.'/'.$configfile, 'ssl_dh =');
			}
		$dovecot_protocols = 'imap pop3';
			$dovecot_protocols .= ' lmtp';
		}

		//* dovecot-managesieved
		if(is_file('/usr/lib/dovecot/managesieve') || is_file('/usr/libexec/dovecot/managesieve')) {
			$dovecot_protocols .= ' sieve';
		replaceLine($config_dir.'/'.$configfile, 'protocols = imap pop3', "protocols = $dovecot_protocols", 1, 0);

latham's avatar
latham committed
		//* dovecot-sql.conf
		$configfile = 'dovecot-sql.conf';
		if(is_file($config_dir.'/'.$configfile)) {
			copy($config_dir.'/'.$configfile, $config_dir.'/'.$configfile.'~');
		}
		if(is_file($config_dir.'/'.$configfile.'~')) chmod($config_dir.'/'.$configfile.'~', 0400);
		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/debian_dovecot-sql.conf.master', 'tpl/debian_dovecot-sql.conf.master');
		$content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content);
		$content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content);
		$content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content);
		$content = str_replace('{mysql_server_host}', $conf['mysql']['host'], $content);
		$content = str_replace('{mysql_server_port}', $conf['mysql']['port'], $content);
		$content = str_replace('{server_id}', $conf['server_id'], $content);
Till Brehm's avatar
Till Brehm committed
		# enable iterate_query for dovecot2
		if(version_compare($dovecot_version,2, '>=')) {
			$content = str_replace('# iterate_query', 'iterate_query', $content);
		}
latham's avatar
latham committed
		wf($config_dir.'/'.$configfile, $content);

		chmod($config_dir.'/'.$configfile, 0600);
		chown($config_dir.'/'.$configfile, 'root');
		chgrp($config_dir.'/'.$configfile, 'root');
		// Dovecot shall ignore mounts in website directory
Till Brehm's avatar
Till Brehm committed
		if(is_installed('doveadm')) exec("doveadm mount add '/var/www/*' ignore > /dev/null 2> /dev/null");
latham's avatar
latham committed

	}

	public function configure_amavis() {
		global $conf;

		// amavisd user config file
		$configfile = 'amavisd_user_config';
		if(is_file($conf['amavis']['config_dir'].'/conf.d/50-user')) copy($conf['amavis']['config_dir'].'/conf.d/50-user', $conf['amavis']['config_dir'].'/50-user~');
		if(is_file($conf['amavis']['config_dir'].'/conf.d/50-user~')) chmod($conf['amavis']['config_dir'].'/50-user~', 0400);
		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master');
		$content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content);
		$content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content);
		$content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content);
		$content = str_replace('{mysql_server_port}', $conf['mysql']['port'], $content);
		$content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content);
		wf($conf['amavis']['config_dir'].'/conf.d/50-user', $content);
		chmod($conf['amavis']['config_dir'].'/conf.d/50-user', 0640);
latham's avatar
latham committed

		// TODO: chmod and chown on the config file

		// test if lmtp if available
		$configure_lmtp = $this->get_postfix_service('lmtp','unix');
latham's avatar
latham committed

		// Adding the amavisd commands to the postfix configuration
		// Add array for no error in foreach and maybe future options
		$postconf_commands = array ();
		// Check for amavisd -> pure webserver with postfix for mailing without antispam
tbrehm's avatar
tbrehm committed
		if ($conf['amavis']['installed']) {
			$content_filter_service = ($configure_lmtp) ? 'lmtp' : 'amavis';
			$postconf_commands[] = "content_filter = ${content_filter_service}:[127.0.0.1]:10024";
			$postconf_commands[] = 'receive_override_options = no_address_mappings';
		}
latham's avatar
latham committed

		// Make a backup copy of the main.cf file
		copy($conf['postfix']['config_dir'].'/main.cf', $conf['postfix']['config_dir'].'/main.cf~2');
latham's avatar
latham committed

		// Executing the postconf commands
		foreach($postconf_commands as $cmd) {
			$command = "postconf -e '$cmd'";
			caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		}

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

		// Adding amavis-services to the master.cf file if the service does not already exists
//		$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');
		//*TODO: check templates against existing postfix-services to make sure we use the template
		// Or just remove the old service definitions and add them again?
		$add_amavis = $this->remove_postfix_service('amavis','unix');
		$add_amavis_10025 = $this->remove_postfix_service('127.0.0.1:10025','inet');
		$add_amavis_10027 = $this->remove_postfix_service('127.0.0.1:10027','inet');

		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);
    		}
latham's avatar
latham committed
		}

		// Add the clamav user to the amavis group
		exec('adduser clamav amavis');
tbrehm's avatar
tbrehm committed
		// get shell-group for amavis
		$amavis_group=exec('grep -o "^amavis:\|^vscan:" /etc/group');
		if(!empty($amavis_group)) {
			$amavis_group=rtrim($amavis_group, ":");
tbrehm's avatar
tbrehm committed
		}
		// get shell-user for amavis
		$amavis_user=exec('grep -o "^amavis:\|^vscan:" /etc/passwd');
		if(!empty($amavis_user)) {
			$amavis_user=rtrim($amavis_user, ":");
		}

		// Create the director for DKIM-Keys
		if(!is_dir('/var/lib/amavis')) mkdir('/var/lib/amavis', 0750, true);
		if(!empty($amavis_user)) exec('chown '.$amavis_user.' /var/lib/amavis');
		if(!empty($amavis_group)) exec('chgrp '.$amavis_group.' /var/lib/amavis');
		if(!is_dir('/var/lib/amavis/dkim')) mkdir('/var/lib/amavis/dkim', 0750);
		if(!empty($amavis_user)) exec('chown -R '.$amavis_user.' /var/lib/amavis/dkim');
		if(!empty($amavis_group)) exec('chgrp -R '.$amavis_group.' /var/lib/amavis/dkim');

	public function configure_rspamd() {
		global $conf;
		//* These postconf commands will be executed on installation and update
		$server_ini_rec = $this->db->queryOneRecord("SELECT config FROM ?? WHERE server_id = ?", $conf["mysql"]["database"] . '.server', $conf['server_id']);
		$server_ini_array = ini_to_array(stripslashes($server_ini_rec['config']));
		unset($server_ini_rec);
		$mail_config = $server_ini_array['mail'];
		if($mail_config['content_filter'] === 'rspamd') {
			exec("postconf -X 'receive_override_options'");
			exec("postconf -X 'content_filter'");

			exec("postconf -e 'smtpd_milters = inet:localhost:11332'");
			exec("postconf -e 'non_smtpd_milters = inet:localhost:11332'");
			exec("postconf -e 'milter_protocol = 6'");
			exec("postconf -e 'milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}'");
			exec("postconf -e 'milter_default_action = accept'");

			if(! isset($mail_config['reject_sender_login_mismatch'])) {
				$mail_config['reject_sender_login_mismatch'] = 'n';
			}
			$options = preg_split("/,\s*/", exec("postconf -h smtpd_sender_restrictions"));
			$new_options = array();
			foreach ($options as $key => $value) {
				$value = trim($value);
				if ($value == '') continue;
				if (preg_match('/tag_as_(originating|foreign)\.re/', $value)) {
					continue;
				}
				if (preg_match('/reject_(authenticated_)?sender_login_mismatch/', $value)) {
					continue;
				$new_options[] = $value;
			}
			if ($mail_config['reject_sender_login_mismatch'] == 'y') {
				// insert before permit_mynetworks
				for ($i = 0; isset($new_options[$i]); $i++) {
					if ($new_options[$i] == 'permit_mynetworks') {
						array_splice($new_options, $i, 0, array('reject_authenticated_sender_login_mismatch'));
						break;
					}
				}
				// insert before permit_sasl_authenticated
				for ($i = 0; isset($new_options[$i]); $i++) {
					if ($new_options[$i] == 'permit_sasl_authenticated') {
						array_splice($new_options, $i, 0, array('reject_sender_login_mismatch'));
			}
			exec("postconf -e 'smtpd_sender_restrictions = ".implode(", ", $new_options)."'");
			$options = preg_split("/,\s*/", exec("postconf -h smtpd_recipient_restrictions"));
			$new_options = array();
			foreach ($options as $value) {
				$value = trim($value);
				if ($value == '') continue;
				if (preg_match('/check_policy_service\s+inet:127.0.0.1:10023/', $value)) {
					continue;
				$new_options[] = $value;
			}
			exec("postconf -e 'smtpd_recipient_restrictions = ".implode(", ", $new_options)."'");
		if(is_user('_rspamd') && is_group('amavis')) {
			exec("usermod -a -G amavis _rspamd");
		} elseif(is_user('rspamd') && is_group('amavis')) {
			exec("usermod -a -G amavis rspamd");
		if(!is_dir('/etc/rspamd/local.d/')){
			mkdir('/etc/rspamd/local.d/', 0755, true);
		}

		if(!is_dir('/etc/rspamd/local.d/maps.d/')){
			mkdir('/etc/rspamd/local.d/maps.d/', 0755, true);
		}

		if(!is_dir('/etc/rspamd/override.d/')){
			mkdir('/etc/rspamd/override.d/', 0755, true);
		}
		if ( substr($mail_config['dkim_path'], strlen($mail_config['dkim_path'])-1) == '/' ) {
			$mail_config['dkim_path'] = substr($mail_config['dkim_path'], 0, strlen($mail_config['dkim_path'])-1);
		}
		$dkim_domains = $this->db->queryAllRecords('SELECT `dkim_selector`, `domain` FROM ?? WHERE `dkim` = ? ORDER BY `domain` ASC', $conf['mysql']['database'] . '.mail_domain', 'y');
		# should move maps to local.d/maps.d/ ?
		$fpp = fopen('/etc/rspamd/local.d/dkim_domains.map', 'w');
		$fps = fopen('/etc/rspamd/local.d/dkim_selectors.map', 'w');
		foreach($dkim_domains as $dkim_domain) {
			fwrite($fpp, $dkim_domain['domain'] . ' ' . $mail_config['dkim_path'] . '/' . $dkim_domain['domain'] . '.private' . "\n");
			fwrite($fps, $dkim_domain['domain'] . ' ' . $dkim_domain['dkim_selector'] . "\n");
		}
		fclose($fpp);
		fclose($fps);
		unset($dkim_domains);
		# local.d templates with template tags
		$tpl = new tpl();
		$tpl->newTemplate('rspamd_dkim_signing.conf.master');
		$tpl->setVar('dkim_path', $mail_config['dkim_path']);
		wf('/etc/rspamd/local.d/dkim_signing.conf', $tpl->grab());

		$tpl = new tpl();
		$tpl->newTemplate('rspamd_options.inc.master');
		$local_addrs = array();
		$ips = $this->db->queryAllRecords('SELECT `ip_address`, `ip_type` FROM ?? WHERE `server_id` = ?', $conf['mysql']['database'].'.server_ip', $conf['server_id']);
		if(is_array($ips) && !empty($ips)){
			foreach($ips as $ip){
				$local_addrs[] = array('quoted_ip' => "\"".$ip['ip_address']."\",\n");
		$tpl->setLoop('local_addrs', $local_addrs);
		wf('/etc/rspamd/local.d/options.inc', $tpl->grab());
		# local.d templates without template tags
		$local_d = array(
			'groups.conf',
			'antivirus.conf',
			'classifier-bayes.conf',
			'greylist.conf',
			'mx_check.conf',
			'redis.conf',
			'milter_headers.conf',
			'neural.conf',
			'neural_group.conf',
			'users.conf',
			'groups.conf',
		);
		foreach ($local_d as $f) {
			if(file_exists($conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_${f}.master")) {
				exec('cp '.$conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_${f}.master /etc/rspamd/local.d/${f}");
			} else {
				exec("cp tpl/rspamd_${f}.master /etc/rspamd/local.d/${f}");
			}
		# override.d templates without template tags
		$override_d = array(
			'rbl_group.conf',
			'surbl_group.conf',
		);
		foreach ($override_d as $f) {
			if(file_exists($conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_${f}.master")) {
				exec('cp '.$conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_${f}.master /etc/rspamd/override.d/${f}");
			} else {
				exec("cp tpl/rspamd_${f}.master /etc/rspamd/override.d/${f}");
		# local.d/maps.d templates without template tags
		$maps_d = array(
			'dkim_whitelist.inc.ispc',
			'dmarc_whitelist.inc.ispc',
			'spf_dkim_whitelist.inc.ispc',
			'spf_whitelist.inc.ispc',
		);
		foreach ($maps_d as $f) {
			if(file_exists($conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_${f}.master")) {
				exec('cp '.$conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_${f}.master /etc/rspamd/local.d/maps.d/${f}");
				exec("cp tpl/rspamd_${f}.master /etc/rspamd/local.d/maps.d/${f}");
		exec('chmod a+r /etc/rspamd/local.d/* /etc/rspamd/local.d/maps.d/* /etc/rspamd/override.d/*');
		# unneccesary, since this was done above?
		$command = 'usermod -a -G amavis _rspamd';
		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
		if(strpos(rf('/etc/rspamd/rspamd.conf'), '.include "$LOCAL_CONFDIR/local.d/users.conf"') === false){
			af('/etc/rspamd/rspamd.conf', '.include "$LOCAL_CONFDIR/local.d/users.conf"');
		}
		if(!isset($mail_config['rspamd_password']) || !$mail_config['rspamd_password']) {
			$mail_config['rspamd_password'] = str_shuffle(bin2hex(openssl_random_pseudo_bytes(12)));
			$server_ini_array['mail']['rspamd_password'] = $mail_config['rspamd_password'];
		}

		$server_ini_array['mail']['rspamd_available'] = 'y';
		$server_ini_string = array_to_ini($server_ini_array);
		if($this->dbmaster != $this->db) {
			$this->dbmaster->query('UPDATE `server` SET `config` = ? WHERE `server_id` = ?', $server_ini_string, $conf['server_id']);
		}
		$this->db->query('UPDATE `server` SET `config` = ? WHERE `server_id` = ?', $server_ini_string, $conf['server_id']);
		unset($server_ini_array);
		unset($server_ini_string);
		$tpl = new tpl();
		$tpl->newTemplate('rspamd_worker-controller.inc.master');
		$rspamd_password = $mail_config['rspamd_password'];
		$crypted_password = trim(exec('rspamadm pw -p ' . escapeshellarg($rspamd_password)));
		if($crypted_password) {
			$rspamd_password = $crypted_password;
		}
		$tpl->setVar('rspamd_password', $rspamd_password);
		wf('/etc/rspamd/local.d/worker-controller.inc', $tpl->grab());
		chmod('/etc/rspamd/local.d/worker-controller.inc', 0644);
latham's avatar
latham committed
	public function configure_spamassassin() {
		global $conf;

		//* Enable spamasasssin on debian and ubuntu
		$configfile = '/etc/default/spamassassin';
		if(is_file($configfile)) {
			copy($configfile, $configfile.'~');
		}
		$content = rf($configfile);
		$content = str_replace('ENABLED=0', 'ENABLED=1', $content);
		wf($configfile, $content);
	}

	public function configure_getmail() {
		global $conf;

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

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

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

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

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


	public function configure_pureftpd() {
		global $conf;

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

		//* configure pure-ftpd for MySQL authentication against the ispconfig database
		$configfile = 'db/mysql.conf';
		if(is_file($config_dir.'/'.$configfile)) {
			copy($config_dir.'/'.$configfile, $config_dir.'/'.$configfile.'~');
		}
		if(is_file($config_dir.'/'.$configfile.'~')) {
			chmod($config_dir.'/'.$configfile.'~', 0400);
		}
		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/pureftpd_mysql.conf.master', 'tpl/pureftpd_mysql.conf.master');
latham's avatar
latham committed
		$content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content);
		$content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content);
		$content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content);
		$content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content);
		$content = str_replace('{server_id}', $conf['server_id'], $content);
		wf($config_dir.'/'.$configfile, $content);
		chmod($config_dir.'/'.$configfile, 0600);
		chown($config_dir.'/'.$configfile, 'root');
		chgrp($config_dir.'/'.$configfile, 'root');
		// **enable chrooting
		//exec('mkdir -p '.$config_dir.'/conf/ChrootEveryone');
		exec('echo "yes" > '.$config_dir.'/conf/ChrootEveryone');
		exec('echo "yes" > '.$config_dir.'/conf/BrokenClientsCompatibility');
		exec('echo "yes" > '.$config_dir.'/conf/DisplayDotFiles');

		if(is_file('/etc/default/pure-ftpd-common')) {
			replaceLine('/etc/default/pure-ftpd-common', 'STANDALONE_OR_INETD=inetd', 'STANDALONE_OR_INETD=standalone', 1, 0);
			replaceLine('/etc/default/pure-ftpd-common', 'VIRTUALCHROOT=false', 'VIRTUALCHROOT=true', 1, 0);
latham's avatar
latham committed
		}

		if(is_file('/etc/inetd.conf')) {