[Freeipa-devel] [PATCH 0111] Automatically reload invalid zone after each change in zone data

2013-02-12 Thread Petr Spacek

Hello,

Automatically reload invalid zone after each change in zone data.

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


How to test:

# create a invalid zone, e.g. zone without A records for names in NS records

ipa dnszone-add zone.test --admin-email=blah.nonsense 
--name-server=ns.zone.test. --force


# now dig ns.zone.test. should return SERVFAIL because zone doesn't have 
proper NS+A/ records


dig ns.zone.test.

# addition of arbitrary record should not crash the server

ipa dnsrecord-add zone.test ns --txt-rec=blah

# after this modification some error message should appear in log and dig 
ns.zone.test. should still return SERVFAIL


dig ns.zone.test.

# addition of valid A record should fix the problem

ipa dnsrecord-add zone.test ns --a-rec=127.0.0.1

# now dig -t ANY ns.zone.test. should return NOERROR and zone should work
# TXT and also A record should be visible

dig -t ANY ns.zone.test.

--
Petr^2 Spacek
From de083cd61471384ccdcc0f02303390d92928a506 Mon Sep 17 00:00:00 2001
From: Petr Spacek 
Date: Tue, 12 Feb 2013 12:42:29 +0100
Subject: [PATCH] Automatically reload invalid zone after each change in zone
 data.

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

Signed-off-by: Petr Spacek 
---
 NEWS  |  3 +++
 src/ldap_helper.c | 38 --
 2 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index 9f50db12de760ccaa7f4adb5cc03534ae72c47be..6dd09c118c86c4f5daf44bfbc5978600092b3d7f 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,6 @@
+[1] Automatically reload invalid zone after each change in zone data.
+https://fedorahosted.org/bind-dyndb-ldap/ticket/102
+
 2.5
 =
 [1] Fix crash during per-zone cache flush.
diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index 71b96ce5eef2a249f7d16c448c70e2c2068d271d..491817813229f988161f3cedc6c83055040ad3ae 100644
--- a/src/ldap_helper.c
+++ b/src/ldap_helper.c
@@ -3411,8 +3411,11 @@ update_record(isc_task_t *task, isc_event_t *event)
 	ldap_psearchevent_t *pevent = (ldap_psearchevent_t *)event;
 	isc_result_t result;
 	ldap_instance_t *inst = NULL;
-	ldap_cache_t *cache = NULL;
+	ldap_cache_t *cache;
 	isc_mem_t *mctx;
+	dns_zone_t *zone_ptr = NULL;
+	isc_boolean_t zone_found = ISC_FALSE;
+	isc_boolean_t zone_reloaded = ISC_FALSE;
 	mctx = pevent->mctx;
 
 	UNUSED(task);
@@ -3431,13 +3434,16 @@ update_record(isc_task_t *task, isc_event_t *event)
 	dns_name_init(&prevname, NULL);
 	dns_name_init(&prevorigin, NULL);
 	CHECK(dn_to_dnsname(mctx, pevent->dn, &name, &origin));
+	zone_found = ISC_TRUE;
 
+update_restart:
 	if (PSEARCH_DEL(pevent->chgtype) || PSEARCH_MODDN(pevent->chgtype)) {
 		log_debug(5, "psearch_update: removing name from cache, dn: '%s'",
 		  pevent->dn);
 	}
 
 	/* Get cache instance & clean old record */
+	cache = NULL;
 	CHECK(zr_get_zone_cache(inst->zone_register, &name, &cache));
 	CHECK(discard_from_cache(cache, &name));
 
@@ -3486,11 +3492,39 @@ update_record(isc_task_t *task, isc_event_t *event)
 	if (inst->serial_autoincrement && PSEARCH_ANY(pevent->chgtype)) {
 		CHECK(soa_serial_increment(mctx, inst, &origin));
 	}
+
 cleanup:
-	if (result != ISC_R_SUCCESS)
+	if (result != ISC_R_SUCCESS && zone_found && !zone_reloaded &&
+	   (result == DNS_R_NOTLOADED || result == DNS_R_BADZONE)) {
+		log_debug(1, "reloading invalid zone after a change; "
+			 "reload triggered by change in '%s'",
+			 pevent->dn);
+
+		result = zr_get_zone_ptr(inst->zone_register, &origin, &zone_ptr);
+		if (result == ISC_R_SUCCESS)
+			result = dns_zone_load(zone_ptr);
+		if (zone_ptr != NULL)
+			dns_zone_detach(&zone_ptr);
+
+		if (result == ISC_R_SUCCESS || result == DNS_R_UPTODATE ||
+		result == DNS_R_DYNAMIC || result == DNS_R_CONTINUE) {
+			/* zone reload succeeded, fire current event again */
+			log_debug(1, "restarting update_record after zone reload "
+ "caused by change in '%s'", pevent->dn);
+			zone_reloaded = ISC_TRUE;
+			goto update_restart;
+		} else {
+			log_error_r("unable to reload invalid zone; "
+"reload triggered by change in '%s'",
+pevent->dn);
+		}
+
+	} else if (result != ISC_R_SUCCESS) {
+		/* error other than invalid zone */
 		log_error_r("update_record (psearch) failed, dn '%s' change type 0x%x. "
 			  "Records can be outdated, run `rndc reload`",
 			  pevent->dn, pevent->chgtype);
+	}
 
 	if (dns_name_dynamic(&name))
 		dns_name_free(&name, inst->mctx);
-- 
1.7.11.7

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

Re: [Freeipa-devel] [PATCH 0111] Automatically reload invalid zone after each change in zone data

2013-03-04 Thread Adam Tkac
On Tue, Feb 12, 2013 at 12:57:44PM +0100, Petr Spacek wrote:
> Hello,
> 
> Automatically reload invalid zone after each change in zone data.
> 
> https://fedorahosted.org/bind-dyndb-ldap/ticket/102

Ack

> How to test:
> 
> # create a invalid zone, e.g. zone without A records for names in NS records
> 
> ipa dnszone-add zone.test --admin-email=blah.nonsense
> --name-server=ns.zone.test. --force
> 
> # now dig ns.zone.test. should return SERVFAIL because zone doesn't
> have proper NS+A/ records
> 
> dig ns.zone.test.
> 
> # addition of arbitrary record should not crash the server
> 
> ipa dnsrecord-add zone.test ns --txt-rec=blah
> 
> # after this modification some error message should appear in log
> and dig ns.zone.test. should still return SERVFAIL
> 
> dig ns.zone.test.
> 
> # addition of valid A record should fix the problem
> 
> ipa dnsrecord-add zone.test ns --a-rec=127.0.0.1
> 
> # now dig -t ANY ns.zone.test. should return NOERROR and zone should work
> # TXT and also A record should be visible
> 
> dig -t ANY ns.zone.test.
> 
> -- 
> Petr^2 Spacek

> From de083cd61471384ccdcc0f02303390d92928a506 Mon Sep 17 00:00:00 2001
> From: Petr Spacek 
> Date: Tue, 12 Feb 2013 12:42:29 +0100
> Subject: [PATCH] Automatically reload invalid zone after each change in zone
>  data.
> 
> https://fedorahosted.org/bind-dyndb-ldap/ticket/102
> 
> Signed-off-by: Petr Spacek 
> ---
>  NEWS  |  3 +++
>  src/ldap_helper.c | 38 --
>  2 files changed, 39 insertions(+), 2 deletions(-)
> 
> diff --git a/NEWS b/NEWS
> index 
> 9f50db12de760ccaa7f4adb5cc03534ae72c47be..6dd09c118c86c4f5daf44bfbc5978600092b3d7f
>  100644
> --- a/NEWS
> +++ b/NEWS
> @@ -1,3 +1,6 @@
> +[1] Automatically reload invalid zone after each change in zone data.
> +https://fedorahosted.org/bind-dyndb-ldap/ticket/102
> +
>  2.5
>  =
>  [1] Fix crash during per-zone cache flush.
> diff --git a/src/ldap_helper.c b/src/ldap_helper.c
> index 
> 71b96ce5eef2a249f7d16c448c70e2c2068d271d..491817813229f988161f3cedc6c83055040ad3ae
>  100644
> --- a/src/ldap_helper.c
> +++ b/src/ldap_helper.c
> @@ -3411,8 +3411,11 @@ update_record(isc_task_t *task, isc_event_t *event)
>   ldap_psearchevent_t *pevent = (ldap_psearchevent_t *)event;
>   isc_result_t result;
>   ldap_instance_t *inst = NULL;
> - ldap_cache_t *cache = NULL;
> + ldap_cache_t *cache;
>   isc_mem_t *mctx;
> + dns_zone_t *zone_ptr = NULL;
> + isc_boolean_t zone_found = ISC_FALSE;
> + isc_boolean_t zone_reloaded = ISC_FALSE;
>   mctx = pevent->mctx;
>  
>   UNUSED(task);
> @@ -3431,13 +3434,16 @@ update_record(isc_task_t *task, isc_event_t *event)
>   dns_name_init(&prevname, NULL);
>   dns_name_init(&prevorigin, NULL);
>   CHECK(dn_to_dnsname(mctx, pevent->dn, &name, &origin));
> + zone_found = ISC_TRUE;
>  
> +update_restart:
>   if (PSEARCH_DEL(pevent->chgtype) || PSEARCH_MODDN(pevent->chgtype)) {
>   log_debug(5, "psearch_update: removing name from cache, dn: 
> '%s'",
> pevent->dn);
>   }
>  
>   /* Get cache instance & clean old record */
> + cache = NULL;
>   CHECK(zr_get_zone_cache(inst->zone_register, &name, &cache));
>   CHECK(discard_from_cache(cache, &name));
>  
> @@ -3486,11 +3492,39 @@ update_record(isc_task_t *task, isc_event_t *event)
>   if (inst->serial_autoincrement && PSEARCH_ANY(pevent->chgtype)) {
>   CHECK(soa_serial_increment(mctx, inst, &origin));
>   }
> +
>  cleanup:
> - if (result != ISC_R_SUCCESS)
> + if (result != ISC_R_SUCCESS && zone_found && !zone_reloaded &&
> +(result == DNS_R_NOTLOADED || result == DNS_R_BADZONE)) {
> + log_debug(1, "reloading invalid zone after a change; "
> +  "reload triggered by change in '%s'",
> +  pevent->dn);
> +
> + result = zr_get_zone_ptr(inst->zone_register, &origin, 
> &zone_ptr);
> + if (result == ISC_R_SUCCESS)
> + result = dns_zone_load(zone_ptr);
> + if (zone_ptr != NULL)
> + dns_zone_detach(&zone_ptr);
> +
> + if (result == ISC_R_SUCCESS || result == DNS_R_UPTODATE ||
> + result == DNS_R_DYNAMIC || result == DNS_R_CONTINUE) {
> + /* zone reload succeeded, fire current event again */
> + log_debug(1, "restarting update_record after zone 
> reload "
> +  "caused by change in '%s'", pevent->dn);
> + zone_reloaded = ISC_TRUE;
> + goto update_restart;
> + } else {
> + log_error_r("unable to reload invalid zone; "
> + "reload triggered by change in '%s'",
> + pevent->dn);
> + }
> +
> + } else if (result != ISC_R_SUCCESS) {
> + /* e

Re: [Freeipa-devel] [PATCH 0111] Automatically reload invalid zone after each change in zone data

2013-03-05 Thread Petr Spacek

On 4.3.2013 15:45, Adam Tkac wrote:

On Tue, Feb 12, 2013 at 12:57:44PM +0100, Petr Spacek wrote:

>Hello,
>
> Automatically reload invalid zone after each change in zone data.
>
> https://fedorahosted.org/bind-dyndb-ldap/ticket/102

Ack


Pushed to master and v2: 655f9b4afa4255c738a228038164215f3f1b91a5

--
Petr^2 Spacek

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