$value) fwrite($fp,$value."\n"); fclose($fp); } else{ if (file_exists($filename)) { #LDAP fetch failed...read backup file. print "Restoring backup file for ".$postfix_ldap['dc']."..."; $ldap_fetch=file($filename); } else{ #we never got any info from this server. print "There is no backup file for ".$postfix_ldap['dc']."..."; $ldap_fetch=array(); } } $ldap_all = array_merge($ldap_temp,$ldap_fetch); $ldap_temp=$ldap_all; print "(".count($ldap_fetch).")\n"; $ldap_fetch=array(); } $ldap_unique=array_unique($ldap_all); print "Total ldap recipients:".count($ldap_all)."\tunique:".count($ldap_unique)."\n"; foreach($ldap_unique as $recipient) $relay_ldap_recipients.=($recipient != ""?preg_replace("/\s+/","",$recipient)." OK\n":""); #save ldap relay recipients file_put_contents(POSTFIX_LOCALBASE."/etc/postfix/relay_ldap_recipients.txt",$relay_ldap_recipients, LOCK_EX); } } } #save all relay recipients, remove duplicates and reload postfix $recipients_file=POSTFIX_LOCALBASE."/etc/postfix/relay_recipients"; file_put_contents($recipients_file.".unsort",$relay_ldap_recipients."\n".$relay_recipients, LOCK_EX); exec('/usr/bin/sort -u '.$recipients_file.'.unsort > '.$recipients_file); unlink_if_exists($recipients_file.'.unsort'); exec(POSTFIX_LOCALBASE."/sbin/postmap ".POSTFIX_LOCALBASE."/etc/postfix/relay_recipients"); mwexec("/usr/local/sbin/postfix reload"); } if($relay_recipients !="" || $relay_ldap_recipients!="") return("relay_recipient_maps = hash:".POSTFIX_LOCALBASE."/etc/postfix/relay_recipients\n"); } function check_cron(){ global $config, $g; $cron_postfix_sqlite = ""; $cron_cmd_sqlite = "/usr/local/bin/php -q /usr/local/www/postfix.php"; $cron_cmd_recipients = "/usr/local/bin/php -q /usr/local/www/postfix_recipients.php"; if (is_array($config['installedpackages']['postfix']['config'])) { $postfix_enabled = $config['installedpackages']['postfix']['config'][0]['enable_postfix']; } // check ldap update if (is_array($config['installedpackages']['postfixrecipients']['config'])) { $postfix_recipients_config = $config['installedpackages']['postfixrecipients']['config'][0]; } // check crontab relay recipients if (preg_match("/(\d+)(\w)/", $postfix_recipients_config['freq'], $matches)) { $r_minute = "*"; $r_hour = "*"; $r_mday = "*"; $r_month = "*"; $r_wday = "*"; $r_who = "root"; switch ($matches[2]) { case m: $r_minute = "*/" . $matches[1]; break; case h: $r_minute = "0"; $r_hour = "*/" . $matches[1]; break; case d: $r_minute = "0"; $r_hour = "0"; $r_mday = "*/" . $matches[1]; break; default: $input_errors[] = "A valid number with a time reference is required for the field 'Frequency'"; } } // check crontab Sqlite databases if (is_array($config['installedpackages']['postfix']['config'])) { $cron_sqlite_queue = $config['installedpackages']['postfix']['config'][0]['update_sqlite']; if ($cron_sqlite_queue != "" && $cron_sqlite_queue != "never") { $s_minute = "*"; $s_hour = "*"; $s_mday = "*"; $s_month = "*"; $s_wday = "*"; $s_who = "root"; switch ($cron_sqlite_queue) { case '01min': $cron_postfix_sqlite = $cron_cmd_sqlite . " 01min"; break; case '10min': $s_minute = "*/10"; $cron_postfix_sqlite = $cron_cmd_sqlite . " 10min"; break; case '01hour': $s_minute = "0"; $cron_postfix_sqlite = $cron_cmd_sqlite . " 01hour"; break; case '24hours': $s_minute = "0"; $s_hour = "0"; $cron_postfix_sqlite = $cron_cmd_sqlite . " 24hours"; break; } } } // update cron if ($postfix_enabled == "on") { if ($postfix_recipients_config['enable_ldap'] || $postfix_recipients_config['enable_url']) { install_cron_job("{$cron_cmd_recipients}", true, $r_minute, $r_hour, $r_mday, $r_month, $r_wday, $r_who); } else { install_cron_job("{$cron_cmd_recipients}", false); } if ($cron_sqlite_queue != "" && $cron_sqlite_queue != "never") { // First remove the previous schedule since the command was appended as well install_cron_job("{$cron_cmd_sqlite}", false); install_cron_job("{$cron_postfix_sqlite}", true, $s_minute, $s_hour, $s_mday, $s_month, $s_wday, $s_who); } else { install_cron_job("{$cron_cmd_sqlite}", false); } } else { install_cron_job("{$cron_cmd_recipients}", false); install_cron_job("{$cron_cmd_sqlite}", false); } } function sync_package_postfix($via_rpc="no") { global $g, $config; log_error("sync_package_postfix called with via_rpc={$via_rpc}"); # detect boot process if (is_array($_POST)) { if (function_exists("platform_booting")) { if (!platform_booting()) { unset($boot_process); } else { $boot_process="on"; } } elseif (!($g['booting'])) { unset($boot_process); } else { $boot_process="on"; } } if(is_process_running("master") && isset($boot_process) && $via_rpc=="no") return; #check patch in /etc/inc/config. $relay_domains = ""; $transport = ""; $postfix_config=$config['installedpackages']['postfix']['config'][0]; if (is_array($config['installedpackages']['postfixdomains'])) $postfix_domains=$config['installedpackages']['postfixdomains']['config'][0]; $message_size_limit=($postfix_config['message_size_limit']?$postfix_config['message_size_limit']:"10240000"); $process_limit=($postfix_config['process_limit']?$postfix_config['process_limit']:"100"); if (is_array($postfix_domains['row'])) { foreach ($postfix_domains['row'] as $postfix_row) { $relay_domains .= ' ' . $postfix_row['domain']; if (!empty($postfix_row['mailserverip'])) $transport .= $postfix_row['domain'] . " smtp:[" . $postfix_row['mailserverip'] . "]\n"; } } #check cron check_cron(); #check logging if ($postfix_config['log_to']){ switch($postfix_config['log_to']){ case 'maillog': system("/usr/bin/touch /var/log/maillog"); $mail_syslog="mail.crit;"; break; case 'none': $mail_syslog="mail.crit;"; break; default: $mail_syslog='mail.*;'; break; } #update /etc/inc/system.inc $sys_log_file='/etc/inc/system.inc'; $pfsense_version=preg_replace("/\s/","",file_get_contents("/etc/version")); $sys_log = file($sys_log_file); $new_sys_log=""; $found_mail=0; foreach ($sys_log as $line){ $new_line=preg_replace('/mail.(.|crit);/',$mail_syslog,$line); if (preg_match('/mail.*system.log/',$line) && $postfix_config['log_to'] =="maillog"){ $new_sys_log .= 'mail.*'."\t\t\t\t\t\t".'/var/log/maillog'."\n"; } if (preg_match('/maillog/',$line)){ $new_line =""; } $new_sys_log .= $new_line; } if (!file_exists('/root/'.$pfsense_version.'.system.inc.backup')) { copy ($sys_log_file,'/root/'.$pfsense_version.'.system.inc.backup'); } file_put_contents($sys_log_file,$new_sys_log, LOCK_EX); #mwexec('/usr/local/bin/php -q /usr/local/www/postfix_syslog.php'); #restart syslog daemon system_syslogd_start(); } #check_debug if($postfix_config['debug_list'] && $postfix_config['debug_list']!=""){ $check_debug ="\n#Debugging postfix\n"; $check_debug.="debug_peer_list = ".px_text_area_decode($postfix_config['debug_list'])."\n"; $check_debug.="debug_peer_level = ".$postfix_config['debug_level']."\n\n"; } #check relay recipients $all_relay_recipients=sync_relay_recipients('gui'); $copyright=<< $iface) { // $real_ifaces[] = px_get_real_interface_address($iface); // if($real_ifaces[$i][0]) { // $postfix_master .=$real_ifaces[$i][0].":25 inet n - n - 1 postscreen\n\t-o user=postfix\n"; $postfix_master = "smtp inet n - n - 1 postscreen\n\t-o user=postfix\n"; $postfix_master .=($antispam['soft_bounce'] == "postscreen"?"\t-o soft_bounce=yes\n":""); // } //} $postfix_master .= $postfix_inets.<< $iface) { $real_ifaces[] = px_get_real_interface_address($iface); if($real_ifaces[$i][0]) { $postfix_master .=$real_ifaces[$i][0].":25 inet n - n - - smtpd\n"; } } */ $postfix_master ="25 inet n - n - - smtpd\n"; } $rbl2.=($rbl2 !=""?"\t\t\t\tpermit\n":"permit\n"); $postfix_main=preg_replace("/RBLRBLRBL/",$rbl2,$postfix_main); #Header Maps $anvil_config=$config['installedpackages']['postfixantispam']['config'][0]['anvil']; if ($anvil_config =='enabled' || ($anvil_config =='postscreen' && $postscreen==1)) $anvil='anvil unix - - n - 1 anvil'; $postfix_master .= << "postfix.sh", "start" => $start, "stop" => $stop)); sleep(1); if (is_array($config['installedpackages']['postfix']) && $config['installedpackages']['postfix']['config'][0]['enable_postfix']){ log_error("Reloading/starting postfix"); system('/bin/chmod +x /usr/local/etc/rc.d/postfix.sh'); mwexec_bg(POSTFIX_LOCALBASE."/sbin/postfix reload || /usr/local/etc/rc.d/postfix.sh start"); log_error("Postfix setup completed"); } else{ log_error("Stopping postfix"); mwexec("/usr/local/etc/rc.d/postfix.sh stop"); system('/bin/chmod -x /usr/local/etc/rc.d/postfix.sh'); } conf_mount_ro(); } function postfix_validate_input($post, &$input_errors) { foreach ($post as $key => $value) { if (empty($value)) continue; if($key == "greet_time" && !preg_match("/(\d+),(\d+)(s|m|h|w)/",$value)) $input_errors[] = "Wrong greet time sintax."; if($key == "message_size_limit" && !is_numeric($value)) $input_errors[] = "Message size limit must be numeric."; if($key == "process_limit" && !is_numeric($value)) $input_errors[] = "Process limit must be numeric."; if($key == "freq" && (!preg_match("/^\d+(h|m|d)$/",$value) || $value == 0)) $input_errors[] = "A valid number with a time reference is required for the field 'Frequency'"; if (substr($key, 0, 2) == "dc" && !is_hostname($value)) $input_errors[] = "{$value} is not a valid host name."; if (substr($key, 0, 6) == "domain" && is_numeric(substr($key, 6))) { if (!is_domain($value)) $input_errors[] = "{$value} is not a valid domain name."; } else if (substr($key, 0, 12) == "mailserverip" && is_numeric(substr($key, 12))) { if (empty($post['domain' . substr($key, 12)])) $input_errors[] = "Domain for {$value} cannot be blank."; if (!is_ipaddr($value) && !is_hostname($value)) $input_errors[] = "{$value} is not a valid IP address or host name."; } } } function postfix_php_install_command() { sync_package_postfix(); } function postfix_php_deinstall_command() { global $config; #disable service if (is_array($config['installedpackages']['postfix'])) $config['installedpackages']['postfix']['config'][0]['enable_postfix']=""; write_config(); sync_package_postfix(); conf_mount_rw(); unlink_if_exists("/usr/local/etc/rc.d/postfix.sh"); unlink_if_exists("/etc/aliases"); conf_mount_ro(); } /* Uses XMLRPC to synchronize the changes to a remote node */ function postfix_sync_on_changes() { global $config, $g; if (is_array($config['installedpackages']['postfixsync']['config'])) { $postfix_sync = $config['installedpackages']['postfixsync']['config'][0]; $synctimeout = $postfix_sync['synctimeout'] ?: '250'; $synconchanges = $postfix_sync['synconchanges']; switch ($synconchanges) { case "manual": if (is_array($postfix_sync['row'])) { $rs = $postfix_sync['row']; } else { log_error("[postfix] XMLRPC sync is enabled but there are no hosts configured as replication targets."); return; } break; case "auto": if (is_array($config['hasync'])) { $system_carp = $config['hasync']; $rs[0]['ipaddress'] = $system_carp['synchronizetoip']; $rs[0]['username'] = $system_carp['username']; $rs[0]['password'] = $system_carp['password']; $rs[0]['sync_type'] = "xmlrpc"; $rs[0]['enabless'] = FALSE; // XMLRPC sync is currently only supported over connections using the same protocol and port as this system if ($config['system']['webgui']['protocol'] == "http") { $rs[0]['syncprotocol'] = "http"; $rs[0]['syncport'] = $config['system']['webgui']['port'] ?: '80'; } else { $rs[0]['syncprotocol'] = "https"; $rs[0]['syncport'] = $config['system']['webgui']['port'] ?: '443'; } if (!is_ipaddr($system_carp['synchronizetoip'])) { log_error("[postfix] XMLRPC CARP/HA sync is enabled but there are no system backup hosts configured as replication targets."); return; } else { $rs[0]['enabless'] = TRUE; } } else { log_error("[postfix] XMLRPC CARP/HA sync is enabled but there are no system backup hosts configured as replication targets."); return; } break; default: return; break; } if (is_array($rs)) { log_error("[postfix] XMLRPC sync is starting."); foreach($rs as $sh) { if ($sh['enabless'] && $sh['sync_type'] == 'xmlrpc') { $sync_to_ip = $sh['ipaddress']; $port = $sh['syncport']; $username = $sh['username'] ?: 'admin'; $password = $sh['password']; $protocol = $sh['syncprotocol']; $sync_type = $sh['sync_type']; $error = ''; $valid = TRUE; if ($password == "") { $error = "Password parameter is empty. "; $valid = FALSE; } if (!is_ipaddr($sync_to_ip) && !is_hostname($sync_to_ip) && !is_domain($sync_to_ip)) { $error .= "Misconfigured Replication Target IP Address or Hostname. "; $valid = FALSE; } if (!is_port($port)) { $error .= "Misconfigured Replication Target Port. "; $valid = FALSE; } if ($valid) { postfix_do_xmlrpc_sync($sync_to_ip, $port, $protocol, $username, $password, $synctimeout); } else { log_error("[postfix] XMLRPC sync with '{$sync_to_ip}' aborted due to the following error(s): {$error}"); } } } log_error("[postfix] XMLRPC sync completed."); } } } /* Do the actual XMLRPC sync */ function postfix_do_xmlrpc_sync($sync_to_ip, $port, $protocol, $username, $password, $synctimeout) { global $config, $g; if ($username == "" || $password == "" || $sync_to_ip == "" || $port == "" || $protocol == "") { log_error("[postfix] A required XMLRPC sync parameter (username, password, replication target, port or protocol) is empty ... aborting pkg sync"); return; } // Take care of IPv6 literal address if (is_ipaddrv6($sync_to_ip)) { $sync_to_ip = "[{$sync_to_ip}]"; } $url = "{$protocol}://{$sync_to_ip}"; /* XML will hold the sections to sync. */ $xml = array(); $xml['postfix'] = $config['installedpackages']['postfix']; $xml['postfixdomains'] = $config['installedpackages']['postfixdomains']; $xml['postfixacl'] = $config['installedpackages']['postfixacl']; $xml['postfixrecipients'] = $config['installedpackages']['postfixrecipients']; $xml['postfixantispam'] = $config['installedpackages']['postfixantispam']; /* Assemble XMLRPC payload. */ $params = array(XML_RPC_encode($password), XML_RPC_encode($xml)); /* Set a few variables needed for sync code */ log_error("[postfix] Beginning XMLRPC sync to {$url}:{$port}."); $method = 'pfsense.merge_installedpackages_section_xmlrpc'; $msg = new XML_RPC_Message($method, $params); $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port); $cli->setCredentials($username, $password); if ($g['debug']) { $cli->setDebug(1); } /* Send our XMLRPC message and timeout after defined sync timeout value */ $resp = $cli->send($msg, $synctimeout); if (!$resp) { $error = "A communications error occurred while attempting XMLRPC sync with {$url}:{$port}."; log_error("[postfix] {$error}"); file_notice("sync_settings", $error, "Postfix Settings Sync", ""); } elseif ($resp->faultCode()) { $cli->setDebug(1); $resp = $cli->send($msg, $synctimeout); $error = "An error code was received while attempting XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString(); log_error("[postfix] {$error}"); file_notice("sync_settings", $error, "Postfix Settings Sync", ""); } else { log_error("[postfix] XMLRPC sync successfully completed with {$url}:{$port}."); } /* Tell postfix to reload our settings on the destionation sync host. */ $method = 'pfsense.exec_php'; $execcmd = "require_once('/usr/local/pkg/postfix.inc');\n"; $execcmd .= "sync_package_postfix('yes');"; /* Assemble XMLRPC payload. */ $params = array(XML_RPC_encode($password), XML_RPC_encode($execcmd)); log_error("[postfix] XMLRPC reload data {$url}:{$port}."); $msg = new XML_RPC_Message($method, $params); $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port); $cli->setCredentials($username, $password); $resp = $cli->send($msg, $synctimeout); if(!$resp) { $error = "A communications error occurred while attempting XMLRPC sync with {$url}:{$port} (pfsense.exec_php)."; log_error("[postfix] {$error}"); file_notice("sync_settings", $error, "postfix Settings Sync", ""); } elseif($resp->faultCode()) { $cli->setDebug(1); $resp = $cli->send($msg, $synctimeout); $error = "An error code was received while attempting XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString(); log_error("[postfix] {$error}"); file_notice("sync_settings", $error, "postfix Settings Sync", ""); } else { log_error("[postfix] XMLRPC reload data success with {$url}:{$port} (pfsense.exec_php)."); } } ?>