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 <pspa...@redhat.com>
> Date: Wed, 27 Jun 2012 10:36:26 +0200
> Subject: [PATCH] SOA autoincrement feature Signed-off-by: Petr Spacek
>  <pspa...@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.

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

Reply via email to