diff options
author | doktornotor <notordoktor@gmail.com> | 2015-11-03 19:00:14 +0100 |
---|---|---|
committer | doktornotor <notordoktor@gmail.com> | 2015-11-03 19:00:14 +0100 |
commit | dd855ad665f6a48590fd77c06e053d772d6f1b29 (patch) | |
tree | 9369947be5a99f43ba5298b0d2257ccc61c10c7c /config/postfix | |
parent | 993af612262ca577fac9858e5b9c2b509ef75f70 (diff) | |
download | pfsense-packages-dd855ad665f6a48590fd77c06e053d772d6f1b29.tar.gz pfsense-packages-dd855ad665f6a48590fd77c06e053d772d6f1b29.tar.bz2 pfsense-packages-dd855ad665f6a48590fd77c06e053d772d6f1b29.zip |
XMLRPC sync fixes
- CARP/HA (auto) option has never worked since pfSense 2.1 due to outdated system settings location being checked
- Fix CARP/HA protocol/port selection
- Add protocol/port selection for manually configured sync hosts
- Do some better validations (IP/hostname, port, password) before attempting to sync
- Handle IPv6 addresses for sync target
- Code style cleanup
Diffstat (limited to 'config/postfix')
-rwxr-xr-x | config/postfix/postfix.inc | 268 |
1 files changed, 135 insertions, 133 deletions
diff --git a/config/postfix/postfix.inc b/config/postfix/postfix.inc index 0629c187..4662feaa 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"); @@ -813,163 +812,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)."); } } |