From eff523095fbaa05a3c502551a0a60b6490dd2544 Mon Sep 17 00:00:00 2001
From: Herman van Rink <rink@initfour.nl>
Date: Wed, 14 Feb 2024 15:09:06 +0100
Subject: [PATCH] Avoid running checkzone for each rr when inserting/deleting a
 soa by deactivating the zone first, #6647

---
 interface/lib/classes/dns_wizard.inc.php     |  5 ++++-
 interface/web/dns/dns_import.php             |  5 ++++-
 interface/web/dns/dns_soa_del.php            |  2 ++
 server/plugins-available/bind_plugin.inc.php | 13 ++++++++++---
 4 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/interface/lib/classes/dns_wizard.inc.php b/interface/lib/classes/dns_wizard.inc.php
index 9b81748d23..c9c1af2e66 100644
--- a/interface/lib/classes/dns_wizard.inc.php
+++ b/interface/lib/classes/dns_wizard.inc.php
@@ -268,7 +268,7 @@ class dns_wizard
                 "expire" => $expire,
                 "minimum" => $minimum,
                 "ttl" => $ttl,
-                "active" => 'Y',
+                "active" => 'N', // Activated later when all DNS records are added.
                 "xfer" => $xfer,
                 "also_notify" => $also_notify,
                 "update_acl" => $update_acl,
@@ -301,6 +301,9 @@ class dns_wizard
                 }
             }
 
+            // Activate the DNS zone.
+            $app->db->datalogUpdate('dns_soa', array('active' => 'Y'), 'id', $dns_soa_id);
+
             return 'ok';
 
         } else {
diff --git a/interface/web/dns/dns_import.php b/interface/web/dns/dns_import.php
index d422983c0c..22a5367f6e 100644
--- a/interface/web/dns/dns_import.php
+++ b/interface/web/dns/dns_import.php
@@ -677,7 +677,7 @@ $error[] = print_r( $soa, true );
 			"expire" => $soa['expire'],
 			"minimum" => $soa['minimum'],
 			"ttl" => $soa['ttl'],
-			"active" => 'Y',
+			"active" => 'N', // Activated later when all DNS records are added.
 			"xfer" => $xfer
 		);
 		$dns_soa_id = $app->db->datalogInsert('dns_soa', $insert_data, 'id');
@@ -710,6 +710,9 @@ $error[] = print_r( $soa, true );
 				$dns_rr_id = $app->db->datalogInsert('dns_rr', $insert_data, 'id');
 			}
 
+			// Activate the DNS zone.
+			$app->db->datalogUpdate('dns_soa', array('active' => 'Y'), 'id', $dns_soa_id);
+
 			$msg[] = $wb['zone_file_successfully_imported_txt'];
 		} elseif (is_array($dns_rr)) {
 			$error[] = $wb['zone_file_import_fail'];
diff --git a/interface/web/dns/dns_soa_del.php b/interface/web/dns/dns_soa_del.php
index 2f2b3331c8..e04b11620d 100644
--- a/interface/web/dns/dns_soa_del.php
+++ b/interface/web/dns/dns_soa_del.php
@@ -55,6 +55,8 @@ class page_action extends tform_actions {
 
 		if($app->tform->checkPerm($this->id, 'd') == false) $app->error($app->lng('error_no_delete_permission'));
 
+               $app->db->datalogUpdate('dns_soa', array("active" => 'N'), 'id', $this->id);
+
 		// Delete all records that belong to this zone.
 		$records = $app->db->queryAllRecords("SELECT id FROM dns_rr WHERE zone = ?", $this->id);
 		foreach($records as $rec) {
diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php
index 99ae03ace8..9be9278269 100644
--- a/server/plugins-available/bind_plugin.inc.php
+++ b/server/plugins-available/bind_plugin.inc.php
@@ -352,7 +352,7 @@ class bind_plugin {
 				$loglevel = @($dns_config['disable_bind_log'] === 'y') ? LOGLEVEL_DEBUG : LOGLEVEL_WARN;
 				$app->log("Writing BIND domain file failed: ".$filename." ".implode(' ', $out), $loglevel);
 				if(is_array($out) && !empty($out)){
-                                       $app->log('Reason for Bind zone check failure: '.implode("\n", $out), $loglevel);
+					$app->log('Reason for Bind zone check failure: '.implode("\n", $out), $loglevel);
 					$app->dbmaster->datalogError(implode("\n", $out));
 				}
 				if ($old_zonefile != '') {
@@ -505,7 +505,10 @@ class bind_plugin {
 		$data["new"] = $tmp;
 		$data["old"] = $tmp;
 		$this->action = 'update';
-		$this->soa_update($event_name, $data);
+
+		if (isset($data['new']['active']) && $data['new']['active'] == 'Y') {
+			$this->soa_update($event_name, $data);
+		}
 
 	}
 
@@ -525,11 +528,15 @@ class bind_plugin {
 		global $app, $conf;
 
 		//* Get the data of the soa and call soa_update
+               //* In a singel server setup the record in dns_soa will already be gone ... so this will give an empty array.
 		$tmp = $app->db->queryOneRecord("SELECT * FROM dns_soa WHERE id = ?", $data['old']['zone']);
 		$data["new"] = $tmp;
 		$data["old"] = $tmp;
 		$this->action = 'update';
-		$this->soa_update($event_name, $data);
+
+		if (isset($data['new']['active']) && $data['new']['active'] == 'Y') {
+			$this->soa_update($event_name, $data);
+		}
 
 	}
 
-- 
GitLab