[Freeipa-devel] [PATCH 0023] SOA serial number auto incrementation

Adam Tkac atkac at redhat.com
Wed Jun 27 15:51:11 UTC 2012


On Wed, Jun 27, 2012 at 04:07:38PM +0200, Petr Spacek wrote:
> Hello,
> 
> this patch is first proof-of-concept implementation of
> https://fedorahosted.org/bind-dyndb-ldap/ticket/67: Implement SOA
> serial number increments for external changes.
> 
> No optimizations are inside. SOA serial is bumped for each record
> after each restart, changes in root records are not handled and so
> on. It is really proof-of-concept.
> 
> It uses unix timestamp for "local" SOA serials to improve situation
> with local serials. Unix timestamps should not go to far future as
> YEAR-MONTH-DAY serials.
> 
> Please, let me know if you see some "principle" problems.

Hello Peter,

I'm fine with this approach.

Regards, Adam

> From c14eedd35682185702f58c3f6eaabb0237f38b15 Mon Sep 17 00:00:00 2001
> From: Petr Spacek <pspacek at redhat.com>
> Date: Wed, 27 Jun 2012 10:36:26 +0200
> Subject: [PATCH] SOA autoincrement feature Signed-off-by: Petr Spacek
>  <pspacek at redhat.com>
> 
> ---
>  src/ldap_helper.c |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 71 insertions(+), 1 deletions(-)
> 
> diff --git a/src/ldap_helper.c b/src/ldap_helper.c
> index 7f0a6f4b37171a6fa4db79cd32fdd8bc62288e0f..ff84ff7256a352f776b31dd221d291234eaabae7 100644
> --- a/src/ldap_helper.c
> +++ b/src/ldap_helper.c
> @@ -34,6 +34,7 @@
>  #include <dns/zt.h>
>  #include <dns/byaddr.h>
>  #include <dns/forward.h>
> +#include <dns/soa.h>
>  
>  #include <isc/buffer.h>
>  #include <isc/lex.h>
> @@ -172,6 +173,7 @@ struct ldap_instance {
>  	isc_boolean_t		exiting;
>  	isc_boolean_t		sync_ptr;
>  	isc_boolean_t		dyn_update;
> +	isc_boolean_t		soa_autoincrement;
>  };
>  
>  struct ldap_pool {
> @@ -343,6 +345,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 +404,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->soa_autoincrement;
>  	CHECK(set_settings(ldap_settings, argv));
>  
>  	/* Set timer for deadlock detection inside semaphore_wait_timed . */
> @@ -463,6 +467,13 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
>  			  "increasing limit");
>  		ldap_inst->connections = 3;
>  	}
> +	if (ldap_inst->soa_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 +2752,60 @@ ldap_pscontrol_destroy(isc_mem_t *mctx, LDAPControl **ctrlp)
>  	*ctrlp = NULL;
>  }
>  
> +isc_result_t
> +increment_soa_serial(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 actual SOA 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);
> +	old_serial = dns_soa_getserial(soa_rdata);
> +
> +	/* Compute the new SOA serial - use actual timestamp.
> +	 * If timestamp < oldSOAserial then increment old serial by one. */
> +	isc_time_now(&curr_time);
> +	new_serial = isc_time_seconds(&curr_time);
> +	if (new_serial <= old_serial) {
> +		/* RFC1982, from bind-9.8.2/bin/named/update.c */
> +		new_serial = (old_serial + 1) & 0xFFFFFFFF;
> +		if (new_serial == 0)
> +			new_serial = 1;
> +	}
> +	dns_soa_setserial(new_serial, soa_rdata);
> +
> +	/* write the new serial back to DB */
> +	CHECK(ldap_pool_getconnection(inst->pool, &conn));
> +	CHECK(modify_soa_record(conn, str_buf(zone_dn), soa_rdata));
> +
> +cleanup:
> +	if (result != ISC_R_SUCCESS)
> +		log_error("SOA serial number incrementation failed in zone '%s'",
> +					str_buf(zone_dn));
> +
> +	str_destroy(&zone_dn);
> +	ldap_pool_putconnection(inst->pool, &conn);
> +	ldapdb_rdatalist_destroy(mctx, &rdatalist);
> +	return result;
> +}
> +
>  /*
>   * update_action routine is processed asynchronously so it cannot assume
>   * anything about state of ldap_inst from where it was sent. The ldap_inst
> @@ -2892,7 +2957,7 @@ update_record(isc_task_t *task, isc_event_t *event)
>  	if (PSEARCH_DEL(pevent->chgtype)) {
>  		log_debug(5, "psearch_update: Removing item from cache (%s)", 
>  		          pevent->dn);
> -	} 
> +	}
>  
>  	/* Get cache instance & clean old record */
>  	cache = ldap_instance_getcache(inst);
> @@ -2916,6 +2981,11 @@ update_record(isc_task_t *task, isc_event_t *event)
>  		/* Destroy rdatalist, it is now in the cache. */
>  		ldapdb_rdatalist_destroy(mctx, &rdatalist);
>  	}
> +
> +	// !!!!!!!!!!!!!!! Don't forget to ZONE + RECORD in single object
> +	if (inst->soa_autoincrement) {
> +		CHECK(increment_soa_serial(mctx, inst, &origin));
> +	}
>  cleanup:
>  	if (result != ISC_R_SUCCESS)
>  		log_error("update_record (psearch) failed for %s. "
> -- 
> 1.7.7.6
> 


-- 
Adam Tkac, Red Hat, Inc.




More information about the Freeipa-devel mailing list