Hello,

this patch set enables bind-dyndb-ldap to automatically unload empty zone (see RFC 6303) if an explicit configuration for this zone is present in LDAP.

Please test it with idnsZone and also idnsForwardZone objectClasses.

--
Petr^2 Spacek
From aae527949cbe185b50160407631ada2d5266eabe Mon Sep 17 00:00:00 2001
From: Petr Spacek <pspa...@redhat.com>
Date: Thu, 16 May 2013 14:43:03 +0200
Subject: [PATCH] Separate generic zone removal code to function
 delete_bind_zone().

https://fedorahosted.org/bind-dyndb-ldap/ticket/119

Signed-off-by: Petr Spacek <pspa...@redhat.com>
---
 src/ldap_helper.c | 52 +++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 39 insertions(+), 13 deletions(-)

diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index fda733b961a05ec13cab62cfee2580dc96e0f36f..a4ce7fc5c7affc7b96f33728f216c24cec1083a9 100644
--- a/src/ldap_helper.c
+++ b/src/ldap_helper.c
@@ -683,6 +683,44 @@ destroy_ldap_connection(ldap_connection_t **ldap_connp)
 	MEM_PUT_AND_DETACH(*ldap_connp);
 }
 
+/**
+ * Delete a zone from plain BIND. LDAP zones require further steps for complete
+ * removal, like deletion from zone register etc.
+ *
+ * @pre A zone pointer has to be attached to *zonep.
+ *
+ * @returns Values returned by dns_zt_unmount().
+ */
+static isc_result_t
+delete_bind_zone(dns_zt_t *zt, dns_zone_t **zonep) {
+	dns_zone_t *zone;
+	dns_db_t *dbp = NULL;
+	dns_zonemgr_t *zmgr;
+	isc_result_t result;
+
+	REQUIRE (zonep != NULL && *zonep != NULL);
+
+	zone = *zonep;
+
+	/* Do not unload partially loaded zones, they have uninitialized
+	 * structures. */
+	if (dns_zone_getdb(zone, &dbp) == ISC_R_SUCCESS) {
+		dns_db_detach(&dbp); /* dns_zone_getdb() attaches DB implicitly */
+		dns_zone_unload(zone);
+		dns_zone_log(zone, ISC_LOG_INFO, "shutting down");
+	} else {
+		dns_zone_log(zone, ISC_LOG_DEBUG(1), "not loaded - unload skipped");
+	}
+
+	result = dns_zt_unmount(zt, zone);
+	zmgr = dns_zone_getmgr(zone);
+	if (zmgr != NULL)
+		dns_zonemgr_releasezone(zmgr, zone);
+	dns_zone_detach(zonep);
+
+	return result;
+}
+
 /*
  * Create a new zone with origin 'name'. The zone will be added to the
  * ldap_inst->view.
@@ -910,20 +948,8 @@ ldap_delete_zone2(ldap_instance_t *inst, dns_name_t *name, isc_boolean_t lock,
 		freeze = ISC_TRUE;
 	}
 
-	/* Do not unload partially loaded zones, they have incomplete structures. */
-	dns_db_t *dbp = NULL;
-	if (dns_zone_getdb(zone, &dbp) == ISC_R_SUCCESS) {
-		dns_db_detach(&dbp); /* dns_zone_getdb() attaches DB implicitly */
-		dns_zone_unload(zone);
-		dns_zone_log(zone, ISC_LOG_INFO, "shutting down");
-	} else {
-		log_debug(1, "zone '%s' not loaded - unload skipped", zone_name_char);
-	}
-
-	CHECK(dns_zt_unmount(inst->view->zonetable, zone));
+	CHECK(delete_bind_zone(inst->view->zonetable, &zone));
 	CHECK(zr_del_zone(inst->zone_register, name));
-	dns_zonemgr_releasezone(inst->zmgr, zone);
-	dns_zone_detach(&zone);
 
 cleanup:
 	if (freeze)
-- 
1.7.11.7

From c726ef95d33685d3a67edb44e0852a1d66be58ff Mon Sep 17 00:00:00 2001
From: Petr Spacek <pspa...@redhat.com>
Date: Thu, 16 May 2013 15:06:16 +0200
Subject: [PATCH] Automatically unload pre-defined empty zone if the real
 master zone is in LDAP.

BIND version 9.9 automatically loads all empty zones defined
in RFC 6303. This prevents bind-dyndb-ldap from loading real
master zone from LDAP.

https://fedorahosted.org/bind-dyndb-ldap/ticket/119

Signed-off-by: Petr Spacek <pspa...@redhat.com>
---
 src/ldap_helper.c | 47 ++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 42 insertions(+), 5 deletions(-)

diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index a4ce7fc5c7affc7b96f33728f216c24cec1083a9..dcb692bfc6a314f953b58199dcbdec5763ee6619 100644
--- a/src/ldap_helper.c
+++ b/src/ldap_helper.c
@@ -683,6 +683,27 @@ destroy_ldap_connection(ldap_connection_t **ldap_connp)
 	MEM_PUT_AND_DETACH(*ldap_connp);
 }
 
+/* Test if the existing zone is 'empty zone' per RFC 6303. */
+static isc_boolean_t
+zone_isempty(isc_mem_t *mctx, dns_zone_t *zone) {
+	char **argv = NULL;
+	isc_boolean_t result = ISC_FALSE;
+
+	if (dns_zone_getdbtype(zone, &argv, mctx) != ISC_R_SUCCESS)
+		CLEANUP_WITH(ISC_FALSE);
+
+	if (argv[0] != NULL && strcmp("_builtin", argv[0]) == 0 &&
+	    argv[1] != NULL && strcmp("empty", argv[1]) == 0) {
+		result = ISC_TRUE;
+	} else {
+		result = ISC_FALSE;
+	}
+	isc_mem_free(mctx, argv);
+
+cleanup:
+	return result;
+}
+
 /**
  * Delete a zone from plain BIND. LDAP zones require further steps for complete
  * removal, like deletion from zone register etc.
@@ -744,14 +765,30 @@ create_zone(ldap_instance_t *ldap_inst, dns_name_t *name, dns_zone_t **zonep)
 		char zone_name[DNS_NAME_FORMATSIZE];
 		dns_name_format(name, zone_name, DNS_NAME_FORMATSIZE);
 
-		if (result == ISC_R_SUCCESS) {
-			result = ISC_R_EXISTS;
-			log_error_r("failed to create new zone '%s'", zone_name);
-		} else {
+		if (result != ISC_R_SUCCESS) {
 			log_error_r("dns_view_findzone() failed while "
 				    "searching for zone '%s'", zone_name);
+		} else { /* zone already exists */
+			if (zone_isempty(ldap_inst->mctx, zone) == ISC_TRUE) {
+				result = delete_bind_zone(ldap_inst->view->zonetable,
+							  &zone);
+				if (result != ISC_R_SUCCESS)
+					log_error_r("failed to create new zone "
+						    "'%s': unable to unload "
+						    "automatic empty zone",
+						    zone_name);
+				else
+					log_info("automatic empty zone %s "
+						 "unloaded", zone_name);
+
+			} else {
+				result = ISC_R_EXISTS;
+				log_error_r("failed to create new zone '%s'",
+					    zone_name);
+			}
 		}
-		goto cleanup;
+		if (result != ISC_R_SUCCESS)
+			goto cleanup;
 	}
 
 	CHECK(dns_zone_create(&zone, ldap_inst->mctx));
-- 
1.7.11.7

From 17c55b8543c2b3f9da0302cf284d4c74cbebc1f1 Mon Sep 17 00:00:00 2001
From: Petr Spacek <pspa...@redhat.com>
Date: Mon, 27 May 2013 15:41:58 +0200
Subject: [PATCH] Automatically unload pre-defined empty zone if the forward
 zone is in LDAP.

BIND version 9.9 automatically loads all empty zones defined
in RFC 6303. Forwarding configuration is not honoured when it is
applied to a empty zone. This patch automatically unloads
empty zone if forwarding for this zone is configured in LDAP.

https://fedorahosted.org/bind-dyndb-ldap/ticket/119

Signed-off-by: Petr Spacek <pspa...@redhat.com>
---
 src/ldap_helper.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index dcb692bfc6a314f953b58199dcbdec5763ee6619..0de62025e67d466a5c656ce8a5d6b3042fadce67 100644
--- a/src/ldap_helper.c
+++ b/src/ldap_helper.c
@@ -1052,6 +1052,7 @@ configure_zone_forwarders(ldap_entry_t *entry, ldap_instance_t *inst,
 	isc_boolean_t fwdtbl_update_requested = ISC_FALSE;
 	dns_forwarders_t *old_setting = NULL;
 	dns_fixedname_t foundname;
+	dns_zone_t *zone = NULL;
 	const char *msg_use_global_fwds;
 	const char *msg_obj_type;
 	const char *msg_forwarders_not_def;
@@ -1184,6 +1185,24 @@ configure_zone_forwarders(ldap_entry_t *entry, ldap_instance_t *inst,
 	}
 
 	if (fwdtbl_update_requested) {
+		/* Shutdown automatic empty zone if it is present. */
+		result = dns_zt_find(inst->view->zonetable, name, 0, NULL,
+				     &zone);
+		if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
+			if (zone_isempty(inst->mctx, zone)) {
+				dns_zone_log(zone, ISC_LOG_INFO, "automatic "
+					     "empty zone will be shut down "
+					     "to enable forwarding");
+				result = delete_bind_zone(inst->view->zonetable,
+							  &zone);
+			} else {
+				dns_zone_detach(&zone);
+				result = ISC_R_SUCCESS;
+			}
+		}
+		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
+			goto cleanup;
+
 		/* Something was changed - set forward table up. */
 		CHECK(delete_forwarding_table(inst, name, msg_obj_type, dn));
 		result = dns_fwdtable_add(inst->view->fwdtable, name, &addrs, fwdpolicy);
-- 
1.7.11.7

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to