Hello all,

this series adds support for loading newly-added zones from LDAP.
Currently you must set `arg "zone_refresh <seconds>";` in your
named.conf to enable this feature because by default the plugin doesn't
check for new zones. "rndc reload" is no longer needed to pick new zones.

Note when you delete zone from LDAP, plugin still doesn't recognize it.

Regards, Adam
>From 61a73c696f7d77e73f5b705c7364adf1f5b53d72 Mon Sep 17 00:00:00 2001
From: Adam Tkac <at...@redhat.com>
Date: Tue, 17 May 2011 13:59:06 +0200
Subject: [PATCH 11/13] Freeze server when changing zones and don't hold
 instance_list_lock.

Signed-off-by: Adam Tkac <at...@redhat.com>
---
 src/ldap_helper.c  |   12 +++++++++++-
 src/ldap_helper.h  |    3 ++-
 src/zone_manager.c |   12 ++++--------
 3 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index 8f19d31..983dc05 100644
--- a/src/ldap_helper.c
+++ b/src/ldap_helper.c
@@ -36,6 +36,7 @@
 #include <isc/mutex.h>
 #include <isc/region.h>
 #include <isc/rwlock.h>
+#include <isc/task.h>
 #include <isc/time.h>
 #include <isc/util.h>
 
@@ -656,7 +657,8 @@ configure_zone_ssutable(dns_zone_t *zone, const char 
*update_str)
  * Returns ISC_R_FAILURE otherwise.
  */
 isc_result_t
-refresh_zones_from_ldap(ldap_instance_t *ldap_inst, isc_boolean_t create)
+refresh_zones_from_ldap(isc_task_t *task, ldap_instance_t *ldap_inst,
+                       isc_boolean_t create)
 {
        isc_result_t result = ISC_R_SUCCESS;
        ldap_connection_t *ldap_conn;
@@ -697,11 +699,17 @@ refresh_zones_from_ldap(ldap_instance_t *ldap_inst, 
isc_boolean_t create)
                 * otherwise we will just search for it in our zone register
                 * and modify the zone we found. */
                if (create) {
+                       /* Configuration phase, make sure we are running 
exclusively */
+                       RUNTIME_CHECK(isc_task_beginexclusive(task) == 
ISC_R_LOCKBUSY);
+
                        CHECK_NEXT(create_zone(ldap_inst, &name, &zone));
                        CHECK_NEXT(zr_add_zone(ldap_inst->zone_register, zone,
                                               dn));
                        log_debug(2, "created zone %p: %s", zone, dn);
                } else {
+                       /* Run exclusively */
+                       RUNTIME_CHECK(isc_task_beginexclusive(task) == 
ISC_R_SUCCESS);
+
                        CHECK_NEXT(zr_get_zone_ptr(ldap_inst->zone_register,
                                                   &name, &zone));
                }
@@ -737,6 +745,8 @@ refresh_zones_from_ldap(ldap_instance_t *ldap_inst, 
isc_boolean_t create)
 
                zone_count++;
 next:
+               if (!create)
+                       isc_task_endexclusive(task);
                if (dns_name_dynamic(&name))
                        dns_name_free(&name, ldap_inst->mctx);
                if (zone != NULL)
diff --git a/src/ldap_helper.h b/src/ldap_helper.h
index 887a059..1423e3c 100644
--- a/src/ldap_helper.h
+++ b/src/ldap_helper.h
@@ -99,7 +99,8 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
                  ldap_instance_t **ldap_instp);
 void destroy_ldap_instance(ldap_instance_t **ldap_inst);
 isc_result_t
-refresh_zones_from_ldap(ldap_instance_t *ldap_inst, isc_boolean_t create);
+refresh_zones_from_ldap(isc_task_t *task, ldap_instance_t *ldap_inst,
+                       isc_boolean_t create);
 
 /* Functions for writing to LDAP. */
 isc_result_t write_to_ldap(dns_name_t *owner, ldap_instance_t *ldap_inst,
diff --git a/src/zone_manager.c b/src/zone_manager.c
index fb4c000..d6b5437 100644
--- a/src/zone_manager.c
+++ b/src/zone_manager.c
@@ -115,6 +115,7 @@ manager_create_db_instance(isc_mem_t *mctx, const char 
*name,
        isc_result_t result;
        db_instance_t *db_inst = NULL;
        unsigned int zone_refresh;
+       isc_task_t *task;
        setting_t manager_settings[] = {
                { "zone_refresh", default_uint(0) },
                end_of_settings
@@ -148,7 +149,8 @@ manager_create_db_instance(isc_mem_t *mctx, const char 
*name,
        CHECK(new_ldap_instance(mctx, db_inst->name, argv, dyndb_args, 
&db_inst->ldap_inst));
        CHECK(new_ldap_cache(mctx, argv, &db_inst->ldap_cache));
 
-       result = refresh_zones_from_ldap(db_inst->ldap_inst, ISC_TRUE);
+       task = dns_dyndb_get_task(dyndb_args);
+       result = refresh_zones_from_ldap(task, db_inst->ldap_inst, ISC_TRUE);
        if (result != ISC_R_SUCCESS) {
                /* In case we don't find any zones, we at least return
                 * ISC_R_SUCCESS so BIND won't exit because of this. */
@@ -159,11 +161,9 @@ manager_create_db_instance(isc_mem_t *mctx, const char 
*name,
 
        /* Add a timer to periodically refresh the zones. */
        if (zone_refresh) {
-               isc_task_t *task;
                isc_timermgr_t *timer_mgr;
                isc_interval_t interval;
 
-               task = dns_dyndb_get_task(dyndb_args);
                timer_mgr = dns_dyndb_get_timermgr(dyndb_args);
                isc_interval_set(&interval, zone_refresh, 0);
 
@@ -190,11 +190,7 @@ refresh_zones_action(isc_task_t *task, isc_event_t *event)
 {
        db_instance_t *db_inst = event->ev_arg;
 
-       UNUSED(task);
-
-       LOCK(&instance_list_lock);
-       refresh_zones_from_ldap(db_inst->ldap_inst, ISC_FALSE);
-       UNLOCK(&instance_list_lock);
+       refresh_zones_from_ldap(task, db_inst->ldap_inst, ISC_FALSE);
 
        isc_event_free(&event);
 }
-- 
1.7.5.1

>From f54f17b7c875ea0039354a8fbc6efeb149ba892b Mon Sep 17 00:00:00 2001
From: Adam Tkac <at...@redhat.com>
Date: Tue, 17 May 2011 14:34:39 +0200
Subject: [PATCH 12/13] Publish zones only when all ACLs are set correctly.

Signed-off-by: Adam Tkac <at...@redhat.com>
---
 src/ldap_helper.c |   28 ++++++++++++++++++++++++++--
 1 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index 983dc05..b8f71cb 100644
--- a/src/ldap_helper.c
+++ b/src/ldap_helper.c
@@ -609,8 +609,6 @@ create_zone(ldap_instance_t *ldap_inst, dns_name_t *name, 
dns_zone_t **zonep)
        dns_zone_setclass(zone, dns_rdataclass_in);
        dns_zone_settype(zone, dns_zone_master);
        CHECK(dns_zone_setdbtype(zone, 2, argv));
-       CHECK(dns_zonemgr_managezone(ldap_inst->zmgr, zone));
-       CHECK(dns_view_addzone(ldap_inst->view, zone));
 
        *zonep = zone;
        return ISC_R_SUCCESS;
@@ -622,6 +620,27 @@ cleanup:
        return result;
 }
 
+static isc_result_t
+publish_zone(ldap_instance_t *ldap_inst, dns_zone_t *zone)
+{
+       isc_result_t result;
+
+       REQUIRE(ldap_inst != NULL);
+       REQUIRE(zone != NULL);
+
+       result = dns_zonemgr_managezone(ldap_inst->zmgr, zone);
+       if (result != ISC_R_SUCCESS)
+               return result;
+       CHECK(dns_view_addzone(ldap_inst->view, zone));
+
+       return ISC_R_SUCCESS;
+
+cleanup:
+       dns_zonemgr_releasezone(ldap_inst->zmgr, zone);
+
+       return result;
+}
+
 /* In BIND9 terminology "ssu" means "Simple Secure Update" */
 static isc_result_t
 configure_zone_ssutable(dns_zone_t *zone, const char *update_str)
@@ -743,6 +762,11 @@ refresh_zones_from_ldap(isc_task_t *task, ldap_instance_t 
*ldap_inst,
                } else
                        log_debug(2, "allow-transfer not set");
 
+               if (create) {
+                       /* Everything is set correctly, publish zone */
+                       CHECK_NEXT(publish_zone(ldap_inst, zone));
+               }
+
                zone_count++;
 next:
                if (!create)
-- 
1.7.5.1

>From 8926ffc9c54c95d798914bec936c608170c5a6a9 Mon Sep 17 00:00:00 2001
From: Adam Tkac <at...@redhat.com>
Date: Tue, 17 May 2011 14:36:44 +0200
Subject: [PATCH 13/13] Allow to load new zones from LDAP runtime.

Signed-off-by: Adam Tkac <at...@redhat.com>
---
 src/ldap_helper.c |   24 ++++++++++++++++++++----
 1 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index b8f71cb..b651b70 100644
--- a/src/ldap_helper.c
+++ b/src/ldap_helper.c
@@ -683,6 +683,7 @@ refresh_zones_from_ldap(isc_task_t *task, ldap_instance_t 
*ldap_inst,
        ldap_connection_t *ldap_conn;
        int zone_count = 0;
        ldap_entry_t *entry;
+       isc_boolean_t runtime_add = ISC_FALSE;
        char *attrs[] = {
                "idnsName", "idnsUpdatePolicy", "idnsAllowQuery",
                "idnsAllowTransfer", NULL
@@ -720,7 +721,7 @@ refresh_zones_from_ldap(isc_task_t *task, ldap_instance_t 
*ldap_inst,
                if (create) {
                        /* Configuration phase, make sure we are running 
exclusively */
                        RUNTIME_CHECK(isc_task_beginexclusive(task) == 
ISC_R_LOCKBUSY);
-
+newzone:
                        CHECK_NEXT(create_zone(ldap_inst, &name, &zone));
                        CHECK_NEXT(zr_add_zone(ldap_inst->zone_register, zone,
                                               dn));
@@ -729,8 +730,13 @@ refresh_zones_from_ldap(isc_task_t *task, ldap_instance_t 
*ldap_inst,
                        /* Run exclusively */
                        RUNTIME_CHECK(isc_task_beginexclusive(task) == 
ISC_R_SUCCESS);
 
-                       CHECK_NEXT(zr_get_zone_ptr(ldap_inst->zone_register,
-                                                  &name, &zone));
+                       result = zr_get_zone_ptr(ldap_inst->zone_register,
+                                                &name, &zone);
+                       if (result != ISC_R_SUCCESS) {
+                               dns_view_thaw(ldap_inst->view);
+                               runtime_add = ISC_TRUE;
+                               goto newzone;
+                       }
                }
 
                log_debug(2, "Setting SSU table for %p: %s", zone, dn);
@@ -762,13 +768,23 @@ refresh_zones_from_ldap(isc_task_t *task, ldap_instance_t 
*ldap_inst,
                } else
                        log_debug(2, "allow-transfer not set");
 
-               if (create) {
+               if (create || runtime_add) {
                        /* Everything is set correctly, publish zone */
                        CHECK_NEXT(publish_zone(ldap_inst, zone));
                }
 
                zone_count++;
 next:
+               if (runtime_add) {
+                       /*
+                        * Don't bother if load fails, server will return
+                        * SERVFAIL for queries beneath this zone. This is
+                        * admin's problem.
+                        */
+                       (void) dns_zone_load(zone);
+                       dns_view_freeze(ldap_inst->view);
+                       runtime_add = ISC_FALSE;
+               }
                if (!create)
                        isc_task_endexclusive(task);
                if (dns_name_dynamic(&name))
-- 
1.7.5.1

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

Reply via email to