Re: [Freeipa-devel] [PATCH] 0025-0028 Implement SOA serial number increments for external changes

2012-07-13 Thread Petr Spacek

On 07/13/2012 03:42 PM, Adam Tkac wrote:

On Tue, Jul 10, 2012 at 03:57:24PM +0200, Petr Spacek wrote:

Hello,

these patches provides SOA serial auto-increment feature for external changes.
Related ticket: https://fedorahosted.org/bind-dyndb-ldap/ticket/67

It is necessary to set "psearch" AND "serial_autoincrement" to "yes"
in /etc/named.conf to enable this feature.

In replicated environment idnsSOAserial attribute has to be declared
as non-replicated. It is done by mkosek's patch 281 for 389 DS &
FreeIPA.

For testing purposes it is enough to add "idnsSOAserial" to end of
exclude list in nsDS5ReplicatedAttributeList attribute for each
replication agreement located in cn=mapping tree,cn=config subtree.


My patch 28 contains "trick" necessary for replicated environments
with 389 DS. 389 sends entry change notification (ECN) in cases when
non-replicated attribute idnsSOAserial was changed on *other side*.
In that case no change is visible in DNS attributes, but ECN is sent
by 389. (Attribute modifyTimestamp is changed also.)

Patch 28 computes digest/hash from all resource records in idnsZone
object and compares old and new digest after each received ECN. This
approach eliminates "false changes".

Each patch depends on all preceding patches, but each patch
implements visible (and testable) part of functionality.


Hello Peter,

please check my comments below.

Regards, Adam


Hello,

I did all changes except this one:


+unsigned int
+rdatalist_length(const dns_rdatalist_t *rdlist)


There is no reason to have this function exported, please mark it as static (and
probably also as inline).


rdatalist_length() is used from rdlist.c and ldap_driver.c.

Rebased patches were pushed to master:
https://fedorahosted.org/bind-dyndb-ldap/changeset/99663b6d65cf5dc166b3cb6f83be1878b8de3163
https://fedorahosted.org/bind-dyndb-ldap/changeset/cd37fba03c5c86a766d1a9f893036ac3540e8b7c
https://fedorahosted.org/bind-dyndb-ldap/changeset/9a3f29c12db99597222ffa2bf0713d0b00cb4699
https://fedorahosted.org/bind-dyndb-ldap/changeset/c379d81508fbfa00ecb5da727ff7b097ebb29a3d
https://fedorahosted.org/bind-dyndb-ldap/changeset/93ae7491a80ba8c4789f8770e14c053b67176de4

Petr^2 Spacek

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


Re: [Freeipa-devel] [PATCH] 0025-0028 Implement SOA serial number increments for external changes

2012-07-13 Thread Adam Tkac
On Tue, Jul 10, 2012 at 03:57:24PM +0200, Petr Spacek wrote:
> Hello,
> 
> these patches provides SOA serial auto-increment feature for external changes.
> Related ticket: https://fedorahosted.org/bind-dyndb-ldap/ticket/67
> 
> It is necessary to set "psearch" AND "serial_autoincrement" to "yes"
> in /etc/named.conf to enable this feature.
> 
> In replicated environment idnsSOAserial attribute has to be declared
> as non-replicated. It is done by mkosek's patch 281 for 389 DS &
> FreeIPA.
> 
> For testing purposes it is enough to add "idnsSOAserial" to end of
> exclude list in nsDS5ReplicatedAttributeList attribute for each
> replication agreement located in cn=mapping tree,cn=config subtree.
> 
> 
> My patch 28 contains "trick" necessary for replicated environments
> with 389 DS. 389 sends entry change notification (ECN) in cases when
> non-replicated attribute idnsSOAserial was changed on *other side*.
> In that case no change is visible in DNS attributes, but ECN is sent
> by 389. (Attribute modifyTimestamp is changed also.)
> 
> Patch 28 computes digest/hash from all resource records in idnsZone
> object and compares old and new digest after each received ECN. This
> approach eliminates "false changes".
> 
> Each patch depends on all preceding patches, but each patch
> implements visible (and testable) part of functionality.

Hello Peter,

please check my comments below.

Regards, Adam

> From 0ed1d3dd4910e1c94617b0209420b1c6598de68e Mon Sep 17 00:00:00 2001
> From: Petr Spacek 
> Date: Wed, 27 Jun 2012 10:36:26 +0200
> Subject: [PATCH] Increment SOA serial for each ordinary record received
>  through psearch
> 
> Signed-off-by: Petr Spacek 
> ---
>  src/ldap_helper.c |   98 
> -
>  1 files changed, 97 insertions(+), 1 deletions(-)
> 
> diff --git a/src/ldap_helper.c b/src/ldap_helper.c
> index 
> 7f0a6f4b37171a6fa4db79cd32fdd8bc62288e0f..5c509443dfb176607d8ee4714d196efaa4afa66b
>  100644
> --- a/src/ldap_helper.c
> +++ b/src/ldap_helper.c
> @@ -34,6 +34,8 @@
>  #include 
>  #include 
>  #include 
> +#include 
> +#include 
>  
>  #include 
>  #include 
> @@ -172,6 +174,7 @@ struct ldap_instance {
>   isc_boolean_t   exiting;
>   isc_boolean_t   sync_ptr;
>   isc_boolean_t   dyn_update;
> + isc_boolean_t   serial_autoincrement;
>  };
>  
>  struct ldap_pool {
> @@ -343,6 +346,7 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
>   { "ldap_hostname", default_string("")   },
>   { "sync_ptr",default_boolean(ISC_FALSE) },
>   { "dyn_update",  default_boolean(ISC_FALSE) },
> + { "serial_autoincrement",default_boolean(ISC_FALSE) },
>   end_of_settings
>   };
>  
> @@ -401,6 +405,7 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
>   ldap_settings[i++].target = ldap_inst->ldap_hostname;
>   ldap_settings[i++].target = &ldap_inst->sync_ptr;
>   ldap_settings[i++].target = &ldap_inst->dyn_update;
> + ldap_settings[i++].target = &ldap_inst->serial_autoincrement;
>   CHECK(set_settings(ldap_settings, argv));
>  
>   /* Set timer for deadlock detection inside semaphore_wait_timed . */
> @@ -463,6 +468,13 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
> "increasing limit");
>   ldap_inst->connections = 3;
>   }
> + if (ldap_inst->serial_autoincrement == ISC_TRUE
> + && ldap_inst->psearch != ISC_TRUE) {
> + log_error("SOA serial number auto-increment feature requires "
> + "persistent search");
> + result = ISC_R_FAILURE;
> + goto cleanup;
> + }
>  
>   CHECK(new_ldap_cache(mctx, argv, &ldap_inst->cache, 
> ldap_inst->psearch));
>   CHECK(ldap_pool_create(mctx, ldap_inst->connections, &ldap_inst->pool));
> @@ -2741,6 +2753,86 @@ ldap_pscontrol_destroy(isc_mem_t *mctx, LDAPControl 
> **ctrlp)
>   *ctrlp = NULL;
>  }
>  
> +isc_result_t

Better is "static inline isc_result_t"

> +soa_serial_get(ldap_instance_t *inst, dns_name_t *zone_name,
> + isc_uint32_t *serial) {
> + isc_result_t result;
> + dns_zone_t *zone = NULL;
> +
> + REQUIRE(inst != NULL);
> + REQUIRE(zone_name != NULL);
> + REQUIRE(serial != NULL);

All those REQUIREs are redundant, please remove them. The "inst" parameter is
checked before function call in soa_serial_increment and last two params are
checked by functions below.

> +
> + CHECK(zr_get_zone_ptr(inst->zone_register, zone_name, &zone));
> + CHECK(dns_zone_getserial2(zone, serial));
> + dns_zone_detach(&zone);
> +
> +cleanup:
> + return result;
> +}
> +
> +isc_result_t
> +soa_serial_increment(isc_mem_t *mctx, ldap_instance_t *inst,
> + dns_name_t *zone_name) {
> + isc_result_t result = ISC_R_FAILURE;
> + ldap_connection_t * conn = NULL;
> +

[Freeipa-devel] [PATCH] 0025-0028 Implement SOA serial number increments for external changes

2012-07-10 Thread Petr Spacek

Hello,

these patches provides SOA serial auto-increment feature for external changes.
Related ticket: https://fedorahosted.org/bind-dyndb-ldap/ticket/67

It is necessary to set "psearch" AND "serial_autoincrement" to "yes" in 
/etc/named.conf to enable this feature.


In replicated environment idnsSOAserial attribute has to be declared as 
non-replicated. It is done by mkosek's patch 281 for 389 DS & FreeIPA.


For testing purposes it is enough to add "idnsSOAserial" to end of exclude 
list in nsDS5ReplicatedAttributeList attribute for each replication agreement 
located in cn=mapping tree,cn=config subtree.



My patch 28 contains "trick" necessary for replicated environments with 389 
DS. 389 sends entry change notification (ECN) in cases when non-replicated 
attribute idnsSOAserial was changed on *other side*. In that case no change is 
visible in DNS attributes, but ECN is sent by 389. (Attribute modifyTimestamp 
is changed also.)


Patch 28 computes digest/hash from all resource records in idnsZone object and 
compares old and new digest after each received ECN. This approach eliminates 
"false changes".


Each patch depends on all preceding patches, but each patch implements visible 
(and testable) part of functionality.


Petr^2 Spacek
From 0ed1d3dd4910e1c94617b0209420b1c6598de68e Mon Sep 17 00:00:00 2001
From: Petr Spacek 
Date: Wed, 27 Jun 2012 10:36:26 +0200
Subject: [PATCH] Increment SOA serial for each ordinary record received
 through psearch

Signed-off-by: Petr Spacek 
---
 src/ldap_helper.c |   98 -
 1 files changed, 97 insertions(+), 1 deletions(-)

diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index 7f0a6f4b37171a6fa4db79cd32fdd8bc62288e0f..5c509443dfb176607d8ee4714d196efaa4afa66b 100644
--- a/src/ldap_helper.c
+++ b/src/ldap_helper.c
@@ -34,6 +34,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -172,6 +174,7 @@ struct ldap_instance {
 	isc_boolean_t		exiting;
 	isc_boolean_t		sync_ptr;
 	isc_boolean_t		dyn_update;
+	isc_boolean_t		serial_autoincrement;
 };
 
 struct ldap_pool {
@@ -343,6 +346,7 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
 		{ "ldap_hostname", default_string("")		},
 		{ "sync_ptr",	 default_boolean(ISC_FALSE) },
 		{ "dyn_update",	 default_boolean(ISC_FALSE) },
+		{ "serial_autoincrement",	 default_boolean(ISC_FALSE) },
 		end_of_settings
 	};
 
@@ -401,6 +405,7 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
 	ldap_settings[i++].target = ldap_inst->ldap_hostname;
 	ldap_settings[i++].target = &ldap_inst->sync_ptr;
 	ldap_settings[i++].target = &ldap_inst->dyn_update;
+	ldap_settings[i++].target = &ldap_inst->serial_autoincrement;
 	CHECK(set_settings(ldap_settings, argv));
 
 	/* Set timer for deadlock detection inside semaphore_wait_timed . */
@@ -463,6 +468,13 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
 			  "increasing limit");
 		ldap_inst->connections = 3;
 	}
+	if (ldap_inst->serial_autoincrement == ISC_TRUE
+		&& ldap_inst->psearch != ISC_TRUE) {
+		log_error("SOA serial number auto-increment feature requires "
+"persistent search");
+		result = ISC_R_FAILURE;
+		goto cleanup;
+	}
 
 	CHECK(new_ldap_cache(mctx, argv, &ldap_inst->cache, ldap_inst->psearch));
 	CHECK(ldap_pool_create(mctx, ldap_inst->connections, &ldap_inst->pool));
@@ -2741,6 +2753,86 @@ ldap_pscontrol_destroy(isc_mem_t *mctx, LDAPControl **ctrlp)
 	*ctrlp = NULL;
 }
 
+isc_result_t
+soa_serial_get(ldap_instance_t *inst, dns_name_t *zone_name,
+isc_uint32_t *serial) {
+	isc_result_t result;
+	dns_zone_t *zone = NULL;
+
+	REQUIRE(inst != NULL);
+	REQUIRE(zone_name != NULL);
+	REQUIRE(serial != NULL);
+
+	CHECK(zr_get_zone_ptr(inst->zone_register, zone_name, &zone));
+	CHECK(dns_zone_getserial2(zone, serial));
+	dns_zone_detach(&zone);
+
+cleanup:
+	return result;
+}
+
+isc_result_t
+soa_serial_increment(isc_mem_t *mctx, ldap_instance_t *inst,
+		dns_name_t *zone_name) {
+	isc_result_t result = ISC_R_FAILURE;
+	ldap_connection_t * conn = NULL;
+	ld_string_t *zone_dn = NULL;
+	ldapdb_rdatalist_t rdatalist;
+	dns_rdatalist_t *rdlist = NULL;
+	dns_rdata_t *soa_rdata = NULL;
+	isc_uint32_t old_serial;
+	isc_uint32_t new_serial;
+	isc_time_t curr_time;
+
+	REQUIRE(inst != NULL);
+	REQUIRE(zone_name != NULL);
+
+	CHECK(str_new(mctx, &zone_dn));
+	CHECK(dnsname_to_dn(inst->zone_register, zone_name, zone_dn));
+	log_debug(5, "incrementing SOA serial number in zone '%s'",
+str_buf(zone_dn));
+
+	/* get original SOA rdata and serial value */
+	INIT_LIST(rdatalist);
+	CHECK(ldapdb_rdatalist_get(mctx, inst, zone_name, zone_name, &rdatalist));
+	CHECK(ldapdb_rdatalist_findrdatatype(&rdatalist, dns_rdatatype_soa, &rdlist));
+	soa_rdata = ISC_LIST_HEAD(rdlist->rdata);
+	CHECK(soa_serial_get(inst, zone_name, &old_serial));
+
+	/* Compute the new SOA serial - use actual timestamp.
+	 * If timestamp <= oldSOAserial then increment old serial by one. */
+	isc_time_now(&c