diff options
-rwxr-xr-x | config/postfix/postfix.inc | 285 | ||||
-rw-r--r-- | config/postfix/postfix.php | 307 | ||||
-rw-r--r-- | config/postfix/postfix_sync.xml | 198 | ||||
-rw-r--r-- | pkg_config.10.xml | 4 | ||||
-rw-r--r-- | pkg_config.8.xml | 4 | ||||
-rw-r--r-- | pkg_config.8.xml.amd64 | 4 |
6 files changed, 425 insertions, 377 deletions
diff --git a/config/postfix/postfix.inc b/config/postfix/postfix.inc index 0629c187..9db7e5a1 100755 --- a/config/postfix/postfix.inc +++ b/config/postfix/postfix.inc @@ -1,16 +1,16 @@ <?php /* postfix.inc - part of the Postfix package for pfSense + part of pfSense (https://www.pfSense.org/) Copyright (C) 2010 Erik Fonnesbeck Copyright (C) 2011-2014 Marcello Coutinho - + Copyright (C) 2015 ESF, LLC All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 1. Redistributions of source code MUST retain the above copyright notice, + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright @@ -27,7 +27,6 @@ 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. - */ $shortcut_section = "postfix"; require_once("util.inc"); @@ -689,8 +688,15 @@ MASTEREOF2; //check postfix etc dir on 2.2 $pfs_version = substr(trim(file_get_contents("/etc/version")),0,3); $postfix_etc_lnk="/usr/local/etc/postfix"; - if ($pfs_version == 2.2 && !is_dir($postfix_etc_lnk)) + if ($pfs_version == 2.2 && !is_dir($postfix_etc_lnk)) { @symlink(POSTFIX_LOCALBASE.'/etc/postfix',$postfix_etc_lnk); + } + + // Fixup library path so postfix can find its libraries + // XXX: Bug #4420 + if (POSTFIX_LOCALBASE != '/usr/local') { + mwexec("/sbin/ldconfig -m " . POSTFIX_LOCALBASE . "/local/lib/"); + } log_error("Writing out configuration"); file_put_contents(POSTFIX_LOCALBASE."/etc/postfix/main.cf", $postfix_main, LOCK_EX); @@ -737,6 +743,12 @@ MASTEREOF2; function postfix_start(){ global $config; $pf_dir=POSTFIX_LOCALBASE; + if (POSTFIX_LOCALBASE != '/usr/local') { + $pf_libdir = POSTFIX_LOCALBASE . "/local/lib"; + $pf_start_cmd = "LD_LIBRARY_PATH={$pf_libdir} {$pf_dir}/sbin/postfix start"; + } else { + $pf_start_cmd = "{$pf_dir}/sbin/postfix start"; + } $start=<<<EOF sysctl kern.ipc.nmbclusters=65536 @@ -744,7 +756,7 @@ function postfix_start(){ sysctl kern.maxfiles=131072 sysctl kern.maxfilesperproc=104856 sysctl kern.threads.max_threads_per_proc=4096 - {$pf_dir}/sbin/postfix start + {$pf_start_cmd} EOF; $stop = POSTFIX_LOCALBASE."/sbin/postfix stop\n"; @@ -813,163 +825,166 @@ function postfix_php_deinstall_command() { /* 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']; + 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){ + switch ($synconchanges) { case "manual": - if (is_array($postfix_sync[row])){ - $rs=$postfix_sync[row]; - } - else{ - log_error("[postfix] xmlrpc sync is enabled but there is no hosts to push postfix config."); + 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['installedpackages']['carpsettings']) && is_array($config['installedpackages']['carpsettings']['config'])){ - $system_carp=$config['installedpackages']['carpsettings']['config'][0]; - $rs[0]['ipaddress']=$system_carp['synchronizetoip']; - $rs[0]['username']=$system_carp['username']; - $rs[0]['password']=$system_carp['password']; - $rs[0]['enabless']=true; - $rs[0]['sync_type']="xmlrpc"; - if (! is_ipaddr($system_carp['synchronizetoip'])){ - log_error("[postfix] xmlrpc sync is enabled but there is no system backup hosts to push postfix config."); - return; - } + 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'; } - else{ - log_error("[postfix] xmlrpc sync is enabled but there is no system backup hosts to push postfix config."); + 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; + break; } - if (is_array($rs)){ - log_error("[postfix] xmlrpc sync is starting."); - foreach($rs as $sh){ - $sync_to_ip = $sh['ipaddress']; - if($sh['username']) - $username = $sh['username']; - else - $username = 'admin'; - if($sh['password'] && $sh['ipaddress'] && $sh['enabless']) - postfix_do_xmlrpc_sync($sh['ipaddress'], $username, $sh['password'],$sh['sync_type'],$synctimeout); + 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 is ending."); } - } + log_error("[postfix] XMLRPC sync completed."); + } + } } /* Do the actual XMLRPC sync */ -function postfix_do_xmlrpc_sync($sync_to_ip,$username,$password,$sync_type,$synctimeout) { +function postfix_do_xmlrpc_sync($sync_to_ip, $port, $protocol, $username, $password, $synctimeout) { global $config, $g; - if(!$username) - $username="admin"; - - if(!$password) + 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; + } - if(!$sync_to_ip) - return; + // Take care of IPv6 literal address + if (is_ipaddrv6($sync_to_ip)) { + $sync_to_ip = "[{$sync_to_ip}]"; + } - if(!$synctimeout) - $synctimeout=120; - - $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; + $url = "{$protocol}://{$sync_to_ip}"; - /* xml will hold the sections to sync */ + /* XML will hold the sections to sync. */ $xml = array(); - $sync_xml=$config['installedpackages']['postfixsync']['config'][0]['synconchanges']; - $sync_db=$config['installedpackages']['postfixsync']['config'][0]['rsync']; - if ($sync_xml && preg_match("/xmlrpc/",$sync_type)){ - log_error("Include postfix xmls"); - $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']; - } - if (count($xml) > 0){ - /* 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($username, $password); - if($g['debug']) - $cli->setDebug(1); - /* send our XMLRPC message and timeout after $sync_timeout seconds */ + $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); - 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, $synctimeout); - $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}."); - } + $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); + /* 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); - 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, $synctimeout); - $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)."); - } + $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)."); } } diff --git a/config/postfix/postfix.php b/config/postfix/postfix.php index 4cf85033..4c444ab8 100644 --- a/config/postfix/postfix.php +++ b/config/postfix/postfix.php @@ -1,15 +1,15 @@ <?php /* postfix.php - part of pfSense (https://www.pfsense.org/) + part of pfSense (https://www.pfSense.org/) Copyright (C) 2011-2014 Marcello Coutinho <marcellocoutinho@gmail.com> - based on varnish_view_config. + Copyright (C) 2015 ESF, LLC All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - 1. Redistributions of source code MUST retain the above copyright notice, + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright @@ -33,110 +33,140 @@ require_once("/etc/inc/pkg-utils.inc"); require_once("/etc/inc/globals.inc"); require_once("/usr/local/pkg/postfix.inc"); -$uname=posix_uname(); -if ($uname['machine']=='amd64') +$uname = posix_uname(); +if ($uname['machine'] == 'amd64') { ini_set('memory_limit', '250M'); +} -function get_remote_log(){ - global $config,$g,$postfix_dir; +function get_remote_log() { + global $config, $g, $postfix_dir; $curr_time = time(); - $log_time=date('YmdHis',$curr_time); - #get protocol - if($config['system']['webgui']['protocol'] != "") - $synchronizetoip = $config['system']['webgui']['protocol']. "://"; - #get port - $port = $config['system']['webgui']['port']; - #if port is empty lets rely on the protocol selection - if($port == "") - $port =($config['system']['webgui']['protocol'] == "http"?"80":"443"); - $synchronizetoip .= $sync_to_ip; - if (is_array($config['installedpackages']['postfixsync'])) - foreach($config['installedpackages']['postfixsync']['config'][0]['row'] as $sh){ - $sync_to_ip = $sh['ipaddress']; - $sync_type = $sh['sync_type']; - $password = $sh['password']; - $file= '/var/db/postfix/'.$server.'.sql'; - #get remote data - if ($sync_type=='fetch'){ - $url= $synchronizetoip . $sync_to_ip; - print "$sync_to_ip $url, $port\n"; - $method = 'pfsense.exec_php'; - $execcmd = "require_once('/usr/local/www/postfix.php');\n"; - $execcmd .= '$toreturn=get_sql('.$log_time.');'; - /* assemble xmlrpc payload */ - $params = array(XML_RPC_encode($password), - XML_RPC_encode($execcmd)); - log_error("postfix get sql data from {$sync_to_ip}."); - $msg = new XML_RPC_Message($method, $params); - $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port); - $cli->setCredentials('admin', $password); - #$cli->setDebug(1); - $resp = $cli->send($msg, "250"); - $a=$resp->value(); - $errors=0; - #var_dump($sql); - foreach($a as $b) - foreach ($b as $c) - foreach ($c as $d) - foreach ($d as $e){ - $update=unserialize($e['string']); - print $update['day']."\n"; - if ($update['day'] != ""){ - create_db($update['day'].".db"); - if ($debug=true) - print $update['day'] ." writing from remote system to db..."; - $dbhandle = sqlite_open($postfix_dir.'/'.$update['day'].".db", 0666, $error); - #file_put_contents("/tmp/".$key.'-'.$update['day'].".sql",gzuncompress(base64_decode($update['sql'])), LOCK_EX); - $ok = sqlite_exec($dbhandle, gzuncompress(base64_decode($update['sql'])), $error); - if (!$ok){ - $errors++; - die ("Cannot execute query. $error\n".$update['sql']."\n"); - } - else{ - if ($debug=true) - print "ok\n"; - } - sqlite_close($dbhandle); - } - } - if ($errors ==0){ + $log_time = date('YmdHis', $curr_time); + + if (is_array($config['installedpackages']['postfixsync'])) { + $synctimeout = $config['installedpackages']['postfixsync']['config'][0]['synctimeout'] ?: '250'; + foreach ($config['installedpackages']['postfixsync']['config'][0]['row'] as $sh) { + // Get remote data for enabled fetch hosts + if ($sh['enabless'] && $sh['sync_type'] == 'fetch') { + $sync_to_ip = $sh['ipaddress']; + $port = $sh['syncport']; + $username = $sh['username'] ?: 'admin'; + $password = $sh['password']; + $protocol = $sh['syncprotocol']; + $file = '/var/db/postfix/' . $server . '.sql'; + + $error = ''; + $valid = TRUE; + + if ($password == "") { + $error = "Password parameter is empty. "; + $valid = FALSE; + } + if ($protocol == "") { + $error = "Protocol 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) { + // Take care of IPv6 literal address + if (is_ipaddrv6($sync_to_ip)) { + $sync_to_ip = "[{$sync_to_ip}]"; + } + $url = "{$protocol}://{$sync_to_ip}"; + + print "{$sync_to_ip} {$url}, {$port}\n"; $method = 'pfsense.exec_php'; $execcmd = "require_once('/usr/local/www/postfix.php');\n"; - $execcmd .= 'flush_sql('.$log_time.');'; - /* assemble xmlrpc payload */ - $params = array(XML_RPC_encode($password), - XML_RPC_encode($execcmd)); - log_error("postfix flush sql buffer file from {$sync_to_ip}."); + $execcmd .= '$toreturn = get_sql('.$log_time.');'; + + /* Assemble XMLRPC payload. */ + $params = array(XML_RPC_encode($password), XML_RPC_encode($execcmd)); + log_error("[postfix] Fetching sql data from {$sync_to_ip}."); $msg = new XML_RPC_Message($method, $params); $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port); - $cli->setCredentials('admin', $password); - #$cli->setDebug(1); - $resp = $cli->send($msg, "250"); + $cli->setCredentials($username, $password); + //$cli->setDebug(1); + $resp = $cli->send($msg, $synctimeout); + $a = $resp->value(); + $errors = 0; + //var_dump($sql); + foreach($a as $b) { + foreach ($b as $c) { + foreach ($c as $d) { + foreach ($d as $e) { + $update = unserialize($e['string']); + print $update['day'] . "\n"; + if ($update['day'] != "") { + create_db($update['day'] . ".db"); + if ($debug) { + print $update['day'] . " writing from remote system to db..."; + } + $dbhandle = sqlite_open($postfix_dir . '/' . $update['day'] . ".db", 0666, $error); + //file_put_contents("/tmp/" . $key . '-' . $update['day'] . ".sql", gzuncompress(base64_decode($update['sql'])), LOCK_EX); + $ok = sqlite_exec($dbhandle, gzuncompress(base64_decode($update['sql'])), $error); + if (!$ok) { + $errors++; + die ("Cannot execute query. $error\n".$update['sql']."\n"); + } elseif ($debug) { + print "ok\n"; + } + sqlite_close($dbhandle); + } + } + } + } + } + if ($errors == 0) { + $method = 'pfsense.exec_php'; + $execcmd = "require_once('/usr/local/www/postfix.php');\n"; + $execcmd .= 'flush_sql('.$log_time.');'; + /* Assemble XMLRPC payload. */ + $params = array(XML_RPC_encode($password), XML_RPC_encode($execcmd)); + log_error("[postfix] Flushing sql buffer file from {$sync_to_ip}."); + $msg = new XML_RPC_Message($method, $params); + $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port); + $cli->setCredentials($username, $password); + //$cli->setDebug(1); + $resp = $cli->send($msg, $synctimeout); } + } else { + log_error("[postfix] Fetch sql database from '{$sync_to_ip}' aborted due to the following error(s): {$error}"); } + } } + log_error("[postfix] Fetch sql database completed."); + } } -function get_sql($log_time){ - global $config,$xmlrpc_g; - $server=$_SERVER['REMOTE_ADDR']; - if (is_array($config['installedpackages']['postfixsync'])) - foreach($config['installedpackages']['postfixsync']['config'][0]['row'] as $sh){ +function get_sql($log_time) { + global $config, $xmlrpc_g; + $server = $_SERVER['REMOTE_ADDR']; + + if (is_array($config['installedpackages']['postfixsync'])) { + foreach($config['installedpackages']['postfixsync']['config'][0]['row'] as $sh) { $sync_to_ip = $sh['ipaddress']; $sync_type = $sh['sync_type']; - $password = $sh['password']; - $file= '/var/db/postfix/'.$server.'.sql'; - if ($sync_to_ip==$server && $sync_type=='share' && file_exists($file)){ - rename($file,$file.".$log_time"); - return (file($file.".$log_time")); - } + $file = '/var/db/postfix/' . $server . '.sql'; + if ($sync_to_ip == "{$server}" && $sync_type == "share" && file_exists($file)) { + rename($file, $file . ".$log_time"); + return (file($file . ".$log_time")); + } } return ""; + } } -function flush_sql($log_time){ - if (preg_match("/\d+\.\d+\.\d+\.\d+/",$_SERVER['REMOTE_ADDR'])) - unlink_if_exists('/var/db/postfix/'.$_SERVER['REMOTE_ADDR'].".sql.$log_time"); +function flush_sql($log_time) { + if (preg_match("/\d+\.\d+\.\d+\.\d+/", $_SERVER['REMOTE_ADDR'])) { + unlink_if_exists('/var/db/postfix/' . $_SERVER['REMOTE_ADDR'] . ".sql.{$log_time}"); + } } function grep_log(){ @@ -296,73 +326,60 @@ function grep_log(){ } } - $config=parse_xml_config("{$g['conf_path']}/config.xml", $g['xml_rootobj']); - //print count($config['installedpackages']); - #start db replication if configured - if ($config['installedpackages']['postfixsync']['config'][0]['rsync']) - foreach ($config['installedpackages']['postfixsync']['config'] as $rs ) - foreach($rs['row'] as $sh){ - $sync_to_ip = $sh['ipaddress']; - $sync_type = $sh['sync_type']; - $password = $sh['password']; - print "checking replication to $sync_to_ip..."; - if ($password && $sync_to_ip && preg_match("/(both|database)/",$sync_type)) - postfix_do_xmlrpc_sync($sync_to_ip, $password,$sync_type); - print "ok\n"; - } - } -function write_db($stm,$table,$days){ - global $postfix_dir,$config,$g; +function write_db($stm, $table, $days) { + global $postfix_dir, $config, $g; conf_mount_rw(); - $do_sync=array(); + $do_sync = array(); print "writing to database..."; - foreach ($days as $day) - if (strlen($stm[$day]) > 10){ - if ($config['installedpackages']['postfixsync']['config'][0]) - foreach ($config['installedpackages']['postfixsync']['config'] as $rs ) - foreach($rs['row'] as $sh){ + foreach ($days as $day) { + if ((strlen($stm[$day]) > 10) && (is_array($config['installedpackages']['postfixsync']['config']))) { + foreach ($config['installedpackages']['postfixsync']['config'] as $rs) { + foreach($rs['row'] as $sh) { $sync_to_ip = $sh['ipaddress']; $sync_type = $sh['sync_type']; $password = $sh['password']; - $sql_file='/var/db/postfix/'.$sync_to_ip.'.sql'; - ${$sync_to_ip}=""; - if (file_exists($sql_file)) - ${$sync_to_ip}=file_get_contents($sql_file); - if ($sync_to_ip && $sync_type=="share"){ - ${$sync_to_ip}.=serialize(array('day'=> $day,'sql'=> base64_encode(gzcompress($stm[$day]."COMMIT;",9))))."\n"; - if (! in_array($sync_to_ip,$do_sync)) - $do_sync[]=$sync_to_ip; + $sql_file = '/var/db/postfix/' . $sync_to_ip . '.sql'; + ${$sync_to_ip} = ""; + if (file_exists($sql_file)) { + ${$sync_to_ip} = file_get_contents($sql_file); + } + if ($sync_to_ip && $sync_type == "share") { + ${$sync_to_ip} .= serialize(array('day' => $day, 'sql' => base64_encode(gzcompress($stm[$day] . "COMMIT;", 9)))) . "\n"; + if (!in_array($sync_to_ip, $do_sync)) { + $do_sync[] = $sync_to_ip; } } - #write local db file - create_db($day.".db"); - if ($debug=true) - print " writing to local db $day..."; - $dbhandle = sqlite_open($postfix_dir.$day.".db", 0666, $error); - if (!$dbhandle) die ($error); - #file_put_contents("/tmp/".$key.'-'.$update['day'].".sql",gzuncompress(base64_decode($update['sql'])), LOCK_EX); - $ok = sqlite_exec($dbhandle, $stm[$day]."COMMIT;", $error); - if (!$ok){ - if ($debug=true) - print ("Cannot execute query. $error\n".$stm[$day]."COMMIT;\n"); - } - else{ - if ($debug=true) - print "ok\n"; } - sqlite_close($dbhandle); } - #write update sql files - if (count ($do_sync) > 0 ){ - - foreach($do_sync as $ip) - file_put_contents('/var/db/postfix/'.$ip.'.sql',${$ip},LOCK_EX); - conf_mount_ro(); + /* Write local db file */ + create_db($day . ".db"); + if ($debug) { + print "writing to local db $day..."; + } + $dbhandle = sqlite_open($postfix_dir.$day.".db", 0666, $error); + if (!$dbhandle) { + die ($error); + } + //file_put_contents("/tmp/" . $key . '-' . $update['day'] . ".sql", gzuncompress(base64_decode($update['sql'])), LOCK_EX); + $ok = sqlite_exec($dbhandle, $stm[$day] . "COMMIT;", $error); + if (!$ok) { + print ("Cannot execute query. $error\n" . $stm[$day] . "COMMIT;\n"); + } elseif ($debug) { + print "ok\n"; + } + sqlite_close($dbhandle); + } } - #write local file - + /* Write updated sql files */ + if (count($do_sync) > 0 ) { + foreach ($do_sync as $ip) { + file_put_contents('/var/db/postfix/' . $ip . '.sql', ${$ip}, LOCK_EX); + } + } + conf_mount_ro(); + /* Write local file */ } function create_db($postfix_db){ @@ -748,4 +765,4 @@ if ($_REQUEST['files']!= ""){ print '</table>'; } } -?>
\ No newline at end of file +?> diff --git a/config/postfix/postfix_sync.xml b/config/postfix/postfix_sync.xml index 727305ff..eb3ab27b 100644 --- a/config/postfix/postfix_sync.xml +++ b/config/postfix/postfix_sync.xml @@ -5,44 +5,44 @@ <copyright> <![CDATA[ /* $Id$ */ -/* ========================================================================== */ +/* ====================================================================================== */ /* - postfix_sync.xml - part of the Postfix package for pfSense - Copyright (C) 2011-2014 Marcello Coutinho - All rights reserved. - */ -/* ========================================================================== */ + postfix_sync.xml + part of pfSense (https://www.pfSense.org/) + Copyright (C) 2011-2014 Marcello Coutinho + Copyright (C) 2015 ESF, LLC + All rights reserved. +*/ +/* ====================================================================================== */ /* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. 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. + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. - THIS SOFTWARE IS PROVIDED ``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 - AUTHOR 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. - */ -/* ========================================================================== */ + 2. 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. + + + THIS SOFTWARE IS PROVIDED ``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 + AUTHOR 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. +*/ +/* ====================================================================================== */ ]]> </copyright> - <description>Describe your package here</description> - <requirements>Describe your package requirements here</requirements> - <faq>Currently there are no FAQ items provided.</faq> - <name>postfix_sync</name> - <version>1.0</version> + <name>postfixsync</name> + <version>2.4.5</version> <title>Services: Postfix relay and antispam</title> <include_file>/usr/local/pkg/postfix.inc</include_file> <menu> @@ -100,12 +100,12 @@ <type>listtopic</type> </field> <field> - <fielddescr>Sync method</fielddescr> + <fielddescr>Sync Method</fielddescr> <fieldname>synconchanges</fieldname> <description>Automatically sync postfix configuration changes.</description> <type>select</type> <required/> - <default_value>auto</default_value> + <default_value>disabled</default_value> <options> <option><name>Sync to configured system backup server</name><value>auto</value></option> <option><name>Sync to host(s) defined below</name><value>manual</value></option> @@ -113,7 +113,7 @@ </options> </field> <field> - <fielddescr>Sync timeout</fielddescr> + <fielddescr>Sync Timeout</fielddescr> <fieldname>synctimeout</fieldname> <description>Select sync max wait time</description> <type>select</type> @@ -128,73 +128,89 @@ </options> </field> <field> - <fielddescr><![CDATA[Remote Server]]></fielddescr> + <fielddescr>Remote Server</fielddescr> <fieldname>none</fieldname> <type>rowhelper</type> <dontdisplayname/> <usecolspan2/> <rowhelper> - <rowhelperfield> - <fielddescr>Enable</fielddescr> - <fieldname>enabless</fieldname> - <type>checkbox</type> - </rowhelperfield> - <rowhelperfield> - <fielddescr>Sync Type </fielddescr> - <fieldname>sync_type</fieldname> - <type>select</type> - <options> - <option><name>XMLRPC Sync</name><value>xmlrpc</value></option> - <option><name>Share Database To</name><value>share</value></option> - <option><name>Fetch Database From</name><value>fetch</value></option> - <option><name>Disabled</name><value>disabled</value></option> - </options> - </rowhelperfield> - <rowhelperfield> - <fielddescr>Remote Server IP</fielddescr> - <fieldname>ipaddress</fieldname> - <description>IP Address of remote server</description> - <type>input</type> - <size>10</size> - </rowhelperfield> - <rowhelperfield> - <fielddescr>Username</fielddescr> - <fieldname>username</fieldname> - <description>Username for remote server.</description> - <type>input</type> - <size>10</size> - </rowhelperfield> - <rowhelperfield> - <fielddescr>Password</fielddescr> - <fieldname>password</fieldname> - <description>Password for remote server.</description> - <type>password</type> - <size>10</size> - </rowhelperfield> - <rowhelperfield> - <fielddescr>Description</fielddescr> - <fieldname>description</fieldname> - <type>input</type> - <size>27</size> - </rowhelperfield> + <rowhelperfield> + <fielddescr>Enable</fielddescr> + <fieldname>enabless</fieldname> + <type>checkbox</type> + </rowhelperfield> + <rowhelperfield> + <fielddescr>Sync Type</fielddescr> + <fieldname>sync_type</fieldname> + <type>select</type> + <options> + <option><name>XMLRPC Sync</name><value>xmlrpc</value></option> + <option><name>Share Database To</name><value>share</value></option> + <option><name>Fetch Database From</name><value>fetch</value></option> + <option><name>Disabled</name><value>disabled</value></option> + </options> + </rowhelperfield> + <rowhelperfield> + <fielddescr>Protocol</fielddescr> + <fieldname>syncprotocol</fieldname> + <description>Choose the protocol used to sync with the destination host (HTTP or HTTPS).</description> + <type>select</type> + <default_value>HTTP</default_value> + <options> + <option><name>HTTP</name><value>http</value></option> + <option><name>HTTPS</name><value>https</value></option> + </options> + </rowhelperfield> + <rowhelperfield> + <fielddescr>Remote Server IP/Hostname</fielddescr> + <fieldname>ipaddress</fieldname> + <description>IP address or hostname of remote server</description> + <type>input</type> + <size>30</size> + </rowhelperfield> + <rowhelperfield> + <fielddescr>Port</fielddescr> + <fieldname>syncport</fieldname> + <description>Choose the sync port of the remote server.</description> + <type>input</type> + <size>5</size> + </rowhelperfield> + <rowhelperfield> + <fielddescr>Username</fielddescr> + <fieldname>username</fieldname> + <description>Username for remote server.</description> + <type>input</type> + <size>20</size> + </rowhelperfield> + <rowhelperfield> + <fielddescr>Password</fielddescr> + <fieldname>password</fieldname> + <description>Password for remote server.</description> + <type>password</type> + <size>20</size> + </rowhelperfield> + <rowhelperfield> + <fielddescr>Description</fielddescr> + <fieldname>description</fieldname> + <type>input</type> + <size>30</size> + </rowhelperfield> </rowhelper> - <description><![CDATA[<br>Sync types Description:<br><br> - <strong>XMLRPC Sync</strong> - Forward postfix settings to other pfsense boxes. Remote password required<br> - <strong>Share Database To</strong> - Allow other pfsense boxes to fetch maillog data via xml. Remote password NOT required.<br> - <strong>Fetch Database From</strong> - Merge logs from other pfsense boxes to this local database. Remote password required.<br> - <strong>Disabled</strong> - Ignore this host while sync.<br><br> - While sharing databases works only when you select 'Sync to host(s) defined below' on sync method and you must setup 'Share Database To' in source box and 'Fetch Database From' on destination box.]]></description> + <description> + <![CDATA[ + <br/>Sync types Description:<br/><br/> + <strong>XMLRPC Sync</strong> - Forward postfix settings to other pfSense boxes. Remote password required.<br/> + <strong>Share Database To</strong> - Allow other pfSense boxes to fetch maillog data via XMLRPC. Remote password NOT required.<br/> + <strong>Fetch Database From</strong> - Merge logs from other pfSense boxes to this local database. Remote password required.<br/> + <strong>Disabled</strong> - Ignore this host while syncing.<br/><br/> + Sharing databases works only when you select 'Sync to host(s) defined below' sync method; you must setup 'Share Database To' in source box and 'Fetch Database From' on destination box. + ]]> + </description> </field> </fields> - <custom_php_install_command> - postfix_php_install_command(); - </custom_php_install_command> - <custom_php_deinstall_command> - postfix_php_deinstall_command(); - </custom_php_deinstall_command> <custom_php_validation_command> postfix_validate_input($_POST, $input_errors); - </custom_php_validation_command> + </custom_php_validation_command> <custom_php_resync_config_command> sync_package_postfix(); </custom_php_resync_config_command> diff --git a/pkg_config.10.xml b/pkg_config.10.xml index 06fddae7..6ef74ef7 100644 --- a/pkg_config.10.xml +++ b/pkg_config.10.xml @@ -460,14 +460,14 @@ <descr><![CDATA[ Postfix mail forwarder acts as a relay server for your domain.<br /> It can do first and second line antispam combat before sending incoming mail to local mail servers.<br /> - Postfix can also detect zombies, check RBLS, SPF, search ldap for valid recipients and use third part antispam engines like policyd and mailscanner for better antispam solution. + Postfix can also detect zombies, check RBLS, SPF, search LDAP for valid recipients and use third part antispam engines like policyd and mailscanner for better antispam solution. ]]> </descr> <category>Services</category> <pkginfolink>https://forum.pfsense.org/index.php/topic,40622.0.html</pkginfolink> <config_file>https://packages.pfsense.org/packages/config/postfix/postfix.xml</config_file> <depends_on_package_pbi>postfix-2.11.3_2-##ARCH##.pbi</depends_on_package_pbi> - <version>2.4.4</version> + <version>2.4.5</version> <status>Release</status> <required_version>2.2</required_version> <configurationfile>postfix.xml</configurationfile> diff --git a/pkg_config.8.xml b/pkg_config.8.xml index d4032e66..45c5fdd3 100644 --- a/pkg_config.8.xml +++ b/pkg_config.8.xml @@ -508,7 +508,7 @@ <website>http://www.postfix.org/</website> <descr><![CDATA[Postfix mail forwarder acts as a relay server for your domain.<br /> It can do first and second line antispam combat before sending incoming mail to local mail servers.<br /> - Postfix can also detect zombies, check RBLS, SPF, seach ldap for valid recipients and use third part antispam engines like policyd and mailscanner for better antispam solution.]]></descr> + Postfix can also detect zombies, check RBLS, SPF, seach LDAP for valid recipients and use third part antispam engines like policyd and mailscanner for better antispam solution.]]></descr> <category>Services</category> <pkginfolink>https://forum.pfsense.org/index.php/topic,40622.0.html</pkginfolink> <config_file>https://packages.pfsense.org/packages/config/postfix/postfix.xml</config_file> @@ -516,7 +516,7 @@ <depends_on_package>postfix-2.10.2,1.tbz</depends_on_package> <depends_on_package>perl5-5.16.3_4.tbz</depends_on_package> <depends_on_package_pbi>postfix-2.10.2-i386.pbi</depends_on_package_pbi> - <version>2.10.2 pkg v.2.4.4</version> + <version>2.10.2 pkg v2.4.5</version> <status>Release</status> <required_version>2.1</required_version> <configurationfile>postfix.xml</configurationfile> diff --git a/pkg_config.8.xml.amd64 b/pkg_config.8.xml.amd64 index 76bff1ec..0edb2cb5 100644 --- a/pkg_config.8.xml.amd64 +++ b/pkg_config.8.xml.amd64 @@ -495,7 +495,7 @@ <website>http://www.postfix.org/</website> <descr><![CDATA[Postfix mail forwarder acts as a relay server for your domain.<br /> It can do first and second line antispam combat before sending incoming mail to local mail servers.<br /> - Postfix can also detect zombies, check RBLS, SPF, seach ldap for valid recipients and use third part antispam engines like policyd and mailscanner for better antispam solution.]]></descr> + Postfix can also detect zombies, check RBLS, SPF, seach LDAP for valid recipients and use third part antispam engines like policyd and mailscanner for better antispam solution.]]></descr> <category>Services</category> <pkginfolink>https://forum.pfsense.org/index.php/topic,40622.0.html</pkginfolink> <config_file>https://packages.pfsense.org/packages/config/postfix/postfix.xml</config_file> @@ -503,7 +503,7 @@ <depends_on_package>postfix-2.10.2,1.tbz</depends_on_package> <depends_on_package>perl5-5.16.3_4.tbz</depends_on_package> <depends_on_package_pbi>postfix-2.10.2-amd64.pbi</depends_on_package_pbi> - <version>2.10.2 pkg v.2.4.4</version> + <version>2.10.2 pkg v2.4.5</version> <status>Release</status> <required_version>2.1</required_version> <configurationfile>postfix.xml</configurationfile> |