From aca10608b64b161bc9e4b03f0f70b9a5f07ed08f Mon Sep 17 00:00:00 2001
From: Evan Hunt <each@isc.org>
Date: Fri, 27 Jan 2023 14:43:11 -0800
Subject: [PATCH] delay trust anchor management until zones are loaded

it was possible for a managed trust anchor needing to send a key
refresh query to be unable to do so because an authoritative zone
was not yet loaded. this has been corrected by delaying the
synchronization of managed-keys zones until after all zones are
loaded.

Conflict: NA
Reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/aca10608b64b161bc9e4b03f0f70b9a5f07ed08f

(cherry picked from commit bafbbd24653dc80a29ebd4e0569f77166123c3d1)
---
 bin/named/server.c | 23 +++++++++++++++++++++++
 lib/dns/zone.c     | 15 ++-------------
 2 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/bin/named/server.c b/bin/named/server.c
index ed0ee59552..a23c4ed107 100644
--- a/bin/named/server.c
+++ b/bin/named/server.c
@@ -9658,6 +9658,7 @@ view_loaded(void *arg) {
 	if (isc_refcount_decrement(&zl->refs) == 1) {
 		named_server_t *server = zl->server;
 		bool reconfig = zl->reconfig;
+		dns_view_t *view = NULL;
 
 		isc_refcount_destroy(&zl->refs);
 		isc_mem_put(server->mctx, zl, sizeof(*zl));
@@ -9678,6 +9679,28 @@ view_loaded(void *arg) {
 				      "all zones loaded");
 		}
 
+		for (view = ISC_LIST_HEAD(server->viewlist); view != NULL;
+		     view = ISC_LIST_NEXT(view, link))
+		{
+			if (view->managed_keys != NULL) {
+				result = dns_zone_synckeyzone(
+					view->managed_keys);
+				if (result != ISC_R_SUCCESS) {
+					isc_log_write(
+						named_g_lctx,
+						DNS_LOGCATEGORY_DNSSEC,
+						DNS_LOGMODULE_DNSSEC,
+						ISC_LOG_ERROR,
+						"failed to initialize "
+						"managed-keys for view %s "
+						"(%s): DNSSEC validation is "
+						"at risk",
+						view->name,
+						isc_result_totext(result));
+				}
+			}
+		}
+
 		CHECKFATAL(dns_zonemgr_forcemaint(server->zonemgr),
 			   "forcing zone maintenance");
 
diff --git a/lib/dns/zone.c b/lib/dns/zone.c
index c418be5da4..a2fe9f6d24 100644
--- a/lib/dns/zone.c
+++ b/lib/dns/zone.c
@@ -4730,8 +4730,7 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
 	}
 
 failure:
-	if (result != ISC_R_SUCCESS && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
-	{
+	if (result != ISC_R_SUCCESS) {
 		dnssec_log(zone, ISC_LOG_ERROR,
 			   "unable to synchronize managed keys: %s",
 			   dns_result_totext(result));
@@ -5196,10 +5195,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
 		break;
 
 	case dns_zone_key:
-		result = sync_keyzone(zone, db);
-		if (result != ISC_R_SUCCESS) {
-			goto cleanup;
-		}
+		/* Nothing needs to be done now */
 		break;
 
 	default:
@@ -5357,13 +5353,6 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
 	goto done;
 
 cleanup:
-	if (zone->type == dns_zone_key && result != ISC_R_SUCCESS) {
-		dnssec_log(zone, ISC_LOG_ERROR,
-			   "failed to initialize managed-keys (%s): "
-			   "DNSSEC validation is at risk",
-			   isc_result_totext(result));
-	}
-
 	if (result != ISC_R_SUCCESS) {
 		dns_zone_rpz_disable_db(zone, db);
 		dns_zone_catz_disable_db(zone, db);
-- 
2.23.0
