From f6365a36db7d26d5b0f2aa32a7ceec7d365fd914 Mon Sep 17 00:00:00 2001
From: phpipam <miha.petkovsek@telemach.si>
Date: Mon, 18 Dec 2023 15:08:31 +0100
Subject: [PATCH] Added support for redundant PowerDNS databases (#3981)

---
 app/admin/powerDNS/index.php         |  7 ++++-
 app/admin/powerDNS/settings-save.php |  2 +-
 app/admin/powerDNS/settings.php      | 43 ++++++++++++++++++++++++++--
 app/tools/powerDNS/index.php         | 14 ++++++++-
 functions/classes/class.PowerDNS.php | 31 ++++++++++++++++++--
 misc/CHANGELOG                       | 14 ++++++---
 6 files changed, 99 insertions(+), 12 deletions(-)

diff --git a/app/admin/powerDNS/index.php b/app/admin/powerDNS/index.php
index 0bde6133..9d15272a 100644
--- a/app/admin/powerDNS/index.php
+++ b/app/admin/powerDNS/index.php
@@ -34,7 +34,12 @@ if ($test!==false) {
         $Result->show("warning", "Please set <a href='".create_link("administration", "powerDNS", "defaults")."'>default powerDNS values</a>!", false);
     }
 }
-
+// errors
+if(isset($PowerDNS->db_check_error)) {
+	foreach ($PowerDNS->db_check_error as $err) {
+		$Result->show("warning", $err);
+	}
+}
 ?>
 <!-- tabs -->
 <ul class="nav nav-tabs">
diff --git a/app/admin/powerDNS/settings-save.php b/app/admin/powerDNS/settings-save.php
index 50385992..11dfb342 100644
--- a/app/admin/powerDNS/settings-save.php
+++ b/app/admin/powerDNS/settings-save.php
@@ -31,7 +31,7 @@ elseif (!is_numeric($_POST['port']))	{ $Result->show("danger", "Invalid port num
 // formulate json
 $values = new StdClass ();
 
-$values->host 		= $_POST['host'];
+$values->host 		= trim(str_replace(",", ";", $_POST['host']));
 $values->name 		= $_POST['name'];
 $values->username 	= $_POST['username'];
 $values->password 	= $_POST['password'];
diff --git a/app/admin/powerDNS/settings.php b/app/admin/powerDNS/settings.php
index cc8b7baa..19221e2c 100644
--- a/app/admin/powerDNS/settings.php
+++ b/app/admin/powerDNS/settings.php
@@ -9,6 +9,9 @@ $User->check_user_session();
 
 # create csrf token
 $csrf = $User->Crypto->csrf_cookie ("create", "pdns_settings");
+
+# if hostname is array implode to ; separated values
+if(is_array($pdns->host)) { $pdns->host = implode(";", $pdns->host); }
 ?>
 
 <script>
@@ -92,9 +95,43 @@ $(document).ready(function() {
 <div id="settingsEdit"></div>
 
 <!-- check -->
-<div class="check" style="height:60px;">
+<div class="check" style="height:60px;width:auto;position:absolute;">
+	<hr>
 	<?php
-	if ($test==false)		{ $Result->show("danger alert-absolute", "Failed to connect to database:<hr> ".$PowerDNS->error); }
-	else					{ $Result->show("success alert-absolute", "Database connection ok"); }
+	// multiple databases
+	if(strpos($pdns->host, ";")!==false) {
+		// multiple ?
+		if(isset($PowerDNS->db_check_error)) {
+			foreach ($PowerDNS->db_check_error as $err) {
+				$Result->show("warning", $err);
+			}
+			// none
+			if ($PowerDNS->active_db===false) {
+				$Result->show("danger", "All database connections failed", false);
+			}
+			// print active
+			else {
+				// set to array
+				$active_db = explode(";", $PowerDNS->db_settings->host);
+				// print
+				$Result->show("success ", "Database connection ok".". "._("Active database").": ".$active_db[$PowerDNS->active_db]);
+			}
+		}
+		// none selected
+		elseif ($PowerDNS->active_db===false) {
+			$Result->show("danger", "All database connections failed",false);
+		}
+		// else
+		else {
+			print "<div class='clearfix'></div>";
+			$Result->show("success ", "All database connections ok");
+		}
+	}
+	else {
+		// connection to selected database
+		if ($test==false)		{ $Result->show("danger ", "Failed to connect to database:<hr> ".$PowerDNS->error, false); }
+		else					{ $Result->show("success ", "Database connection ok"."."); }
+	}
+
 	?>
 </div>
\ No newline at end of file
diff --git a/app/tools/powerDNS/index.php b/app/tools/powerDNS/index.php
index 972fd791..0dc5dae2 100644
--- a/app/tools/powerDNS/index.php
+++ b/app/tools/powerDNS/index.php
@@ -31,7 +31,19 @@ if ($User->get_module_permissions ("pdns")>=User::ACCESS_R) {
                 $Result->show("warning", "Please set <a href='".create_link("administration", "powerDNS", "defaults")."'>default powerDNS values</a>!", false);
             }
         }
-
+        // check if TTL is set
+        if ($test!==false) {
+            $test_ttl = pf_json_decode($User->settings->powerDNS);
+            if ($test_ttl->ttl==NULL) {
+                $Result->show("warning", "Please set <a href='".create_link("administration", "powerDNS", "defaults")."'>default powerDNS values</a>!", false);
+            }
+        }
+        // errors
+        if(isset($PowerDNS->db_check_error)) {
+            foreach ($PowerDNS->db_check_error as $err) {
+                $Result->show("warning", $err);
+            }
+        }
         ?>
         <!-- tabs -->
         <ul class="nav nav-tabs">
diff --git a/functions/classes/class.PowerDNS.php b/functions/classes/class.PowerDNS.php
index db3ab4f5..287d3de4 100644
--- a/functions/classes/class.PowerDNS.php
+++ b/functions/classes/class.PowerDNS.php
@@ -168,8 +168,35 @@ class PowerDNS extends Common_functions {
     private function db_set () {
         // decode values form powerDNS
         $this->db_settings = strlen($this->settings->powerDNS)>10 ? pf_json_decode($this->settings->powerDNS) : pf_json_decode($this->db_set_db_settings ());
-        // set connection
-        $this->Database_pdns = new Database_PDO ($this->db_settings->username, $this->db_settings->password, $this->db_settings->host, $this->db_settings->port, $this->db_settings->name);
+
+        // if comma delimited host
+        if (strpos($this->db_settings->host, ";")!==false) {
+            // get all databases
+            $this->db_settings->host = explode(";", $this->db_settings->host);
+            // set active index
+            $this->active_db = false;
+            // check each, use first we are able to connect to
+            foreach ($this->db_settings->host as $key=>$host) {
+                // set connection
+                unset($this->Database_pdns);
+                $this->Database_pdns = new Database_PDO ($this->db_settings->username, $this->db_settings->password, $host, $this->db_settings->port, $this->db_settings->name);
+                // check connection, try untill it fails
+                if(!$this->db_check ()) {
+                    $this->db_check_error[] = $this->error." :: ".$host;
+                }
+                else {
+                    if($this->thisactive_db==false) {
+                        $this->active_db = $key;
+                    }
+                }
+            }
+            // connect to active
+            $this->Database_pdns = new Database_PDO ($this->db_settings->username, $this->db_settings->password, $this->db_settings->host[$active_db], $this->db_settings->port, $this->db_settings->name);
+        }
+        else {
+            // set connection
+            $this->Database_pdns = new Database_PDO ($this->db_settings->username, $this->db_settings->password, $this->db_settings->host, $this->db_settings->port, $this->db_settings->name);
+        }
     }
 
     /**
diff --git a/misc/CHANGELOG b/misc/CHANGELOG
index 1d5feb2b..2005ad75 100755
--- a/misc/CHANGELOG
+++ b/misc/CHANGELOG
@@ -6,8 +6,15 @@
 
     Bugfixes:
     ----------------------------
-    + Use UTF-16LE encoding for XLS sheet names, and UTF-8 as input encoding (#3977);
-    + Update login_form.php for installation inside subdir (#3954);
+    + Fixed Use UTF-16LE encoding for XLS sheet names, and UTF-8 as input encoding (#3977);
+    + Fixed Update login_form.php for installation inside subdir (#3954);
+    + Fixed php8 constructor fix for radius class (#3985);
+    + Fixed Force mac address update during status update scan (#3791);
+
+
+    Enhancements, changes:
+    ----------------------------
+    + Added support for redundant PowerDNS databases (#3981);
 
     Security Fixes:
     ----------------------------
@@ -17,9 +24,8 @@
 
     Enhancements, changes:
     ----------------------------
-    + php8.3 compatibility;
+    + php8.4 compatibility;;
     + MySQL 5.5.3+ is now required (support for utf8mb4);
-    + Reverse-proxy users should review the new config.php $trust_x_forwarded_headers setting;
 
     Security Fixes:
     ----------------------------
-- 
GitLab