[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