"*", "hour" => "*", "mday" => "*", "month" => "*", "wday" => "*", "who" => "root", "command"=> $cron_cmd); switch ($matches[2]){ case m: $cron_postfix["month"]="*/".$matches[1]; break; case h: $cron_postfix["hour"]="*/".$matches[1]; break; case d: $cron_postfix["mday"]="*/".$matches[1]; break; default: $input_errors[] = "A valid number with a time reference is required for the field 'Frequency'"; } $relay_ldap_recipients=""; if ($via_cron == "gui"){ #running via pfsense gui, not time for ldap fetch. $ldap_recipients='/usr/local/etc/postfix/relay_ldap_recipients.txt'; if (!file_exists($ldap_recipients)) system('/usr/bin/touch '. $ldap_recipients); $relay_ldap_recipients=file_get_contents($ldap_recipients); } else{ #running via crontab, time to get ldap content. $ldap_temp=array(); foreach ($postfix_recipients_config['row'] as $postfix_ldap) { print "extracting from ".$postfix_ldap['dc']."..."; $filename="/usr/local/etc/postfix/relay_ldap_recipients.".$postfix_ldap['dc'].".txt"; exec($ad_export." ".$postfix_ldap['dc']." ".$postfix_ldap['cn']." ".$postfix_ldap['username']." ".$postfix_ldap['password'],$ldap_fetch,$status); if ($status == 0){ #write backup conf for ldap server $fp=fopen($filename,"w+"); foreach($ldap_fetch as $key => $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 != ""?$recipient." OK\n":""); #save ldap relay recipients file_put_contents("/usr/local/etc/postfix/relay_ldap_recipients.txt",$relay_ldap_recipients, LOCK_EX); } } } #check crontab $new_cron=array(); $cron_cmd_sqlite = ""; $cron_postfix_sqlite=""; #check crontab Sqlite databases if (is_array($config['installedpackages']['postfix']['config']) && $postfix_enabled=="on"){ $cron_sqlite_queue=$config['installedpackages']['postfix']['config'][0]['update_sqlite']; $cron_cmd_sqlite="/usr/local/bin/php -q /usr/local/www/postfix.php"; if ($cron_sqlite_queue != "" && $cron_sqlite_queue != "never"){ $cron_postfix_sqlite=array("minute" => "*", "hour" => "*", "mday" => "*", "month" => "*", "wday" => "*", "who" => "root", "command"=> ""); switch ($cron_sqlite_queue){ case '10min': $cron_postfix_sqlite["minute"]="*/10"; $cron_postfix_sqlite["command"] = $cron_cmd_sqlite ." 10min"; break; case '01hour': $cron_postfix_sqlite["minute"]="0"; $cron_postfix_sqlite["command"] = $cron_cmd_sqlite ." 01hour"; break; case '24hours': $cron_postfix_sqlite["minute"]="0"; $cron_postfix_sqlite["hour"]="0"; $cron_postfix_sqlite["command"] = $cron_cmd_sqlite ." 24hours"; break; } } } #check crontab relay recipients $cron_found=""; if (is_array($config['cron']['item'])){ #print "
"; foreach($config['cron']['item'] as $cron){ #check valid_recipients cron if ($cron["command"] == $cron_cmd){ #postfix cron cmd found if($postfix_enabled=="on") $cron_found=$cron; if($postfix_recipients_config['enable_ldap'] && $postfix_enabled=="on") #update cron schedule $new_cron['item'][]=$cron_postfix; } #check sqlite update queue else if(!preg_match("/.usr.local.www.postfix.php/",$cron["command"])){ #keep all non postfix cron cmds if not empty if ($cron["command"] != "") $new_cron['item'][]=$cron; } } $write_cron=1; # Check if crontab must be changed to valid recipients cmd if ($postfix_recipients_config['enable_ldap']){ if ($cron_found!=$cron_postfix){ #update postfix cron schedule if (! is_array($cron_found) && $postfix_enabled=="on") $new_cron['item'][]=$cron_postfix; $write_cron=1; } } else{ if (is_array($cron_found)){ #remove postfix cron cmd $write_cron=1; } } #check if cron must be changed to Sqlite cmd if($cron_sqlite_queue != "" && $cron_sqlite_queue != "never"){ $new_cron['item'][]=$cron_postfix_sqlite; $config['cron']=$new_cron; $write_cron=1; } } #call cron functions if ($write_cron==1){ $config['cron']=$new_cron; write_config(); configure_cron(); } #remove postfix old cron call $old_cron=0; $crontab = file('/etc/crontab'); $new_crontab=""; foreach ($crontab as $line){ if (preg_match("/php..usr.local.www.postfix_recipients.php/",$line)) $old_cron=1; else $new_crontab .= $line; } if ($old_cron==1) file_put_contents("/etc/crontab",$new_crontab, LOCK_EX); } #save all relay recipients and reload postfix file_put_contents("/usr/local/etc/postfix/relay_recipients",$relay_ldap_recipients."\n".$relay_recipients, LOCK_EX); exec("/usr/local/sbin/postmap /usr/local/etc/postfix/relay_recipients"); mwexec("/usr/local/sbin/postfix reload"); } if($relay_recipients !="" || $relay_ldap_recipients!="") return("relay_recipient_maps = hash:/usr/local/etc/postfix/relay_recipients\n"); } function sync_package_postfix() { global $config; $relay_domains = ""; $transport = ""; $postfix_config=$config['installedpackages']['postfix']['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_config['row'])) { foreach ($postfix_config['row'] as $postfix_row) { $relay_domains .= ' ' . $postfix_row['domain']; if (!empty($postfix_row['mailserverip'])) $transport .= $postfix_row['domain'] . " smtp:[" . $postfix_row['mailserverip'] . "]\n"; } } #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'; $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); #set syslog entry mail.* %/var/log/maillog when log_to = system if (preg_match ('/mail.(.|crit);/',$line) && $postfix_config['log_to'] =="maillog") $new_sys_log .= 'mail.*'."\t\t\t\t\t\t".'/var/log/maillog'."\n"; #remove syslog entry mail.* %/var/log/maillog when log_to != system if (preg_match ("/^mail/",$line)) $new_sys_log .=""; else $new_sys_log .= $new_line; } if (!file_exists('/root/system.inc.backup')) { copy ($sys_log_file,'/root/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 .=($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 - 1 smtpd\n\t-o user=postfix\n"; } } } $rbl2.=($rbl2 !=""?"\t\t\t\tpermit\n":"permit\n"); $postfix_main=preg_replace("/RBLRBLRBL/",$rbl2,$postfix_main); $postfix_master .= << "postfix.sh", "start" => $start, "stop" => $stop)); conf_mount_ro(); sleep(1); if ($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("/usr/local/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'); } } 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() { mwexec("/usr/local/etc/rc.d/postfix.sh stop"); sleep(1); conf_mount_rw(); unlink_if_exists("/usr/local/etc/rc.d/postfix.sh"); conf_mount_ro(); } /* Uses XMLRPC to synchronize the changes to a remote node */ function postfix_sync_on_changes() { global $config, $g; log_error("[postfix] postfix_xmlrpc_sync.php is starting."); $synconchanges = $config['installedpackages']['postfixsync']['config'][0]['synconchanges']; if(!$synconchanges) return; foreach ($config['installedpackages']['postfixsync']['config'] as $rs ){ foreach($rs['row'] as $sh){ $sync_to_ip = $sh['ipaddress']; $password = $sh['password']; if($password && $sync_to_ip) postfix_do_xmlrpc_sync($sync_to_ip, $password); } } log_error("[postfix] postfix_xmlrpc_sync.php is ending."); } /* Do the actual XMLRPC sync */ function postfix_do_xmlrpc_sync($sync_to_ip, $password) { global $config, $g; if(!$password) return; if(!$sync_to_ip) return; $xmlrpc_sync_neighbor = $sync_to_ip; if($config['system']['webgui']['protocol'] != "") { $synchronizetoip = $config['system']['webgui']['protocol']; $synchronizetoip .= "://"; } $port = $config['system']['webgui']['port']; /* if port is empty lets rely on the protocol selection */ if($port == "") { if($config['system']['webgui']['protocol'] == "http") $port = "80"; else $port = "443"; } $synchronizetoip .= $sync_to_ip; /* xml will hold the sections to sync */ $xml = array(); $xml['postfix'] = $config['installedpackages']['postfix']; $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 borrowed from filter.inc */ $url = $synchronizetoip; log_error("Beginning Postfix 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('admin', $password); if($g['debug']) $cli->setDebug(1); /* send our XMLRPC message and timeout after 250 seconds */ $resp = $cli->send($msg, "250"); if(!$resp) { $error = "A communications error occurred while attempting postfix XMLRPC sync with {$url}:{$port}."; log_error($error); file_notice("sync_settings", $error, "Postfix Settings Sync", ""); } elseif($resp->faultCode()) { $cli->setDebug(1); $resp = $cli->send($msg, "250"); $error = "An error code was received while attempting postfix XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString(); log_error($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();"; /* 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('admin', $password); $resp = $cli->send($msg, "250"); if(!$resp) { $error = "A communications error occurred while attempting postfix XMLRPC sync with {$url}:{$port} (pfsense.exec_php)."; log_error($error); file_notice("sync_settings", $error, "postfix Settings Sync", ""); } elseif($resp->faultCode()) { $cli->setDebug(1); $resp = $cli->send($msg, "250"); $error = "An error code was received while attempting postfix XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString(); log_error($error); file_notice("sync_settings", $error, "postfix Settings Sync", ""); } else { log_error("postfix XMLRPC reload data success with {$url}:{$port} (pfsense.exec_php)."); } } ?>