summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Nagy <mnagy@redhat.com>2009-08-03 09:55:14 +0200
committerMartin Nagy <mnagy@redhat.com>2009-08-04 16:50:54 +0200
commitfdd7b1de1f1a82ebfc8483fe5264717b502243a2 (patch)
tree44058fd841c7984eb0584b65fd569f6749ab40c0
parent2d1ffcf060eb873a76d462725195dbac6f114c1f (diff)
downloadldap_driver-fdd7b1de1f1a82ebfc8483fe5264717b502243a2.tar.gz
ldap_driver-fdd7b1de1f1a82ebfc8483fe5264717b502243a2.tar.xz
ldap_driver-fdd7b1de1f1a82ebfc8483fe5264717b502243a2.zip
Periodically refresh zone settings
The original intent was to add and remove zones periodically, based on changes in the LDAP database. It seems, however, that this is not possible with the way BIND views are working. Each view can have zones added during the configuration phase, but not after that. Luckily, we can at least change their SSU table without the need to reload named. This commit also has some changes to the function interfaces and makes the whole thing a lot simpler. Creation of the ldap instances and cache instances is now left on the zone manager. Additionally, we now put view and zonemgr pointers right into into the ldap instance. This makes the API for refresh_zones_from_ldap() and create_zone() much more simpler.
-rw-r--r--src/cache.c3
-rw-r--r--src/cache.h3
-rw-r--r--src/ldap_driver.c30
-rw-r--r--src/ldap_helper.c43
-rw-r--r--src/ldap_helper.h10
-rw-r--r--src/zone_manager.c87
-rw-r--r--src/zone_manager.h7
7 files changed, 94 insertions, 89 deletions
diff --git a/src/cache.c b/src/cache.c
index de99ad9..f6dcfcc 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -101,8 +101,7 @@ cleanup:
}
isc_result_t
-new_ldap_cache(isc_mem_t *mctx, ldap_cache_t **cachep,
- const char * const *argv)
+new_ldap_cache(isc_mem_t *mctx, const char *const *argv, ldap_cache_t **cachep)
{
isc_result_t result;
ldap_cache_t *cache = NULL;
diff --git a/src/cache.h b/src/cache.h
index 1089e74..5543aec 100644
--- a/src/cache.h
+++ b/src/cache.h
@@ -28,8 +28,7 @@ typedef struct ldap_cache ldap_cache_t;
* Create a new cache.
*/
isc_result_t
-new_ldap_cache(isc_mem_t *mctx, ldap_cache_t **cachep,
- const char * const *argv);
+new_ldap_cache(isc_mem_t *mctx, const char * const *argv, ldap_cache_t **cachep);
/*
* Free all resources used up by the cache.
diff --git a/src/ldap_driver.c b/src/ldap_driver.c
index 1839025..f67ef5e 100644
--- a/src/ldap_driver.c
+++ b/src/ldap_driver.c
@@ -1021,10 +1021,6 @@ dynamic_driver_init(isc_mem_t *mctx, const char *name, const char * const *argv,
dns_dyndb_arguments_t *dyndb_args)
{
isc_result_t result;
- ldap_instance_t *ldap_inst = NULL;
- ldap_cache_t *ldap_cache = NULL;
- dns_view_t *view;
- dns_zonemgr_t *zmgr;
REQUIRE(mctx != NULL);
REQUIRE(name != NULL);
@@ -1033,9 +1029,6 @@ dynamic_driver_init(isc_mem_t *mctx, const char *name, const char * const *argv,
log_debug(2, "registering dynamic ldap driver for %s.", name);
- view = dns_dyndb_get_view(dyndb_args);
- zmgr = dns_dyndb_get_zonemgr(dyndb_args);
-
/*
* We need to discover what rdataset methods does
* dns_rdatalist_tordataset use. We then make a copy for ourselves
@@ -1060,27 +1053,8 @@ dynamic_driver_init(isc_mem_t *mctx, const char *name, const char * const *argv,
if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS)
return result;
- CHECK(new_ldap_instance(mctx, view, &ldap_inst, argv));
- CHECK(new_ldap_cache(mctx, &ldap_cache, argv));
- CHECK(manager_add_db_instance(mctx, name, ldap_inst, ldap_cache, zmgr));
-
- /*
- * TODO: now fetch all zones and initialize ldap zone manager
- * (periodically check for new zones)
- * - manager has to share server zonemgr (ns_g_server->zonemgr)
- *
- * zone has to be bind-ed to specified view:
- * - dns_view_findzone (check if zone already exists)
- * - dns_view_addzone
- */
-
- return ISC_R_SUCCESS;
-
-cleanup:
- if (ldap_inst != NULL)
- destroy_ldap_instance(&ldap_inst);
- if (ldap_cache != NULL)
- destroy_ldap_cache(&ldap_cache);
+ /* Finally, create the instance. */
+ result = manager_create_db_instance(mctx, name, argv, dyndb_args);
return result;
}
diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index b2ee99b..cbf6c25 100644
--- a/src/ldap_helper.c
+++ b/src/ldap_helper.c
@@ -18,6 +18,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <dns/dynamic_db.h>
#include <dns/rbt.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
@@ -102,7 +103,11 @@ struct ldap_auth_pair {
/* These are typedefed in ldap_helper.h */
struct ldap_instance {
isc_mem_t *mctx;
+
+ /* These are needed for zone creation. */
+ const char * db_name;
dns_view_t *view;
+ dns_zonemgr_t *zmgr;
/* List of LDAP connections. */
semaphore_t conn_semaphore;
@@ -268,8 +273,9 @@ static isc_result_t modify_ldap_common(dns_name_t *owner, ldap_instance_t *ldap_
dns_rdatalist_t *rdlist, int mod_op);
isc_result_t
-new_ldap_instance(isc_mem_t *mctx, dns_view_t *view, ldap_instance_t **ldap_instp,
- const char * const *argv)
+new_ldap_instance(isc_mem_t *mctx, const char *db_name,
+ const char * const *argv, dns_dyndb_arguments_t *dyndb_args,
+ ldap_instance_t **ldap_instp)
{
unsigned int i;
isc_result_t result;
@@ -292,7 +298,6 @@ new_ldap_instance(isc_mem_t *mctx, dns_view_t *view, ldap_instance_t **ldap_inst
};
REQUIRE(mctx != NULL);
- REQUIRE(view != NULL);
REQUIRE(ldap_instp != NULL && *ldap_instp == NULL);
ldap_inst = isc_mem_get(mctx, sizeof(ldap_instance_t));
@@ -302,7 +307,9 @@ new_ldap_instance(isc_mem_t *mctx, dns_view_t *view, ldap_instance_t **ldap_inst
ZERO_PTR(ldap_inst);
isc_mem_attach(mctx, &ldap_inst->mctx);
- ldap_inst->view = view;
+ ldap_inst->db_name = db_name;
+ ldap_inst->view = dns_dyndb_get_view(dyndb_args);
+ ldap_inst->zmgr = dns_dyndb_get_zonemgr(dyndb_args);
/* commented out for now, cause named to hang */
//dns_view_attach(view, &ldap_inst->view);
@@ -499,11 +506,10 @@ destroy_ldap_connection(ldap_connection_t **ldap_connp)
/*
* Create a new zone with origin 'name'. The zone will be added to the
- * view set in 'ldap_inst'.
+ * ldap_inst->view.
*/
static isc_result_t
-create_zone(ldap_instance_t *ldap_inst, dns_name_t *name, const char *db_name,
- dns_zonemgr_t *zmgr, dns_zone_t **zonep)
+create_zone(ldap_instance_t *ldap_inst, dns_name_t *name, dns_zone_t **zonep)
{
isc_result_t result;
dns_zone_t *zone = NULL;
@@ -511,12 +517,10 @@ create_zone(ldap_instance_t *ldap_inst, dns_name_t *name, const char *db_name,
REQUIRE(ldap_inst != NULL);
REQUIRE(name != NULL);
- REQUIRE(db_name != NULL);
- REQUIRE(zmgr != NULL);
REQUIRE(zonep != NULL && *zonep == NULL);
argv[0] = ldapdb_impname;
- argv[1] = db_name;
+ argv[1] = ldap_inst->db_name;
result = dns_view_findzone(ldap_inst->view, name, &zone);
if (result == ISC_R_SUCCESS) {
@@ -534,7 +538,7 @@ create_zone(ldap_instance_t *ldap_inst, dns_name_t *name, const char *db_name,
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(zmgr, zone));
+ CHECK(dns_zonemgr_managezone(ldap_inst->zmgr, zone));
CHECK(dns_view_addzone(ldap_inst->view, zone));
*zonep = zone;
@@ -572,14 +576,13 @@ modify_zone(dns_zone_t *zone, const char *update_str)
}
/*
- * Search in LDAP for zones. If 'zmgr' is not NULL, add the zones. Otherwise,
+ * Search in LDAP for zones. If 'create' is true, create the zones. Otherwise,
* we assume that we are past the configuration phase and no new zones can be
* added. In that case, only modify the zone's properties, like the update
* policy.
*/
isc_result_t
-refresh_zones_from_ldap(ldap_instance_t *ldap_inst, const char *db_name,
- dns_zonemgr_t *zmgr)
+refresh_zones_from_ldap(ldap_instance_t *ldap_inst, isc_boolean_t create)
{
isc_result_t result = ISC_R_SUCCESS;
ldap_connection_t *ldap_conn;
@@ -589,9 +592,8 @@ refresh_zones_from_ldap(ldap_instance_t *ldap_inst, const char *db_name,
};
REQUIRE(ldap_inst != NULL);
- REQUIRE(db_name != NULL);
- log_debug(2, "refreshing list of zones for %s", db_name);
+ log_debug(2, "refreshing list of zones for %s", ldap_inst->db_name);
ldap_conn = get_connection(ldap_inst);
@@ -618,18 +620,17 @@ refresh_zones_from_ldap(ldap_instance_t *ldap_inst, const char *db_name,
/* If we are in the configuration phase, create the zone,
* otherwise we will just search for it in our zone register
* and modify the zone we found. */
- if (zmgr != NULL) {
- CHECK_NEXT(create_zone(ldap_inst, &name, db_name, zmgr,
- &zone));
+ if (create) {
+ CHECK_NEXT(create_zone(ldap_inst, &name, &zone));
CHECK_NEXT(zr_add_zone(ldap_inst->zone_register, zone,
dn));
- log_error("created zone %p: %s", zone, dn);
+ log_debug(2, "created zone %p: %s", zone, dn);
} else {
CHECK_NEXT(zr_get_zone_ptr(ldap_inst->zone_register,
&name, &zone));
}
- log_error("modifying zone %p: %s", zone, dn);
+ log_debug(2, "modifying zone %p: %s", zone, dn);
/* Get the update policy and update the zone with it. */
result = get_values(entry, "idnsUpdatePolicy", &values);
if (result == ISC_R_SUCCESS)
diff --git a/src/ldap_helper.h b/src/ldap_helper.h
index d353ff2..0b019eb 100644
--- a/src/ldap_helper.h
+++ b/src/ldap_helper.h
@@ -83,11 +83,13 @@ isc_result_t ldapdb_rdatalist_get(isc_mem_t *mctx, ldap_instance_t *ldap_inst,
* DNS_R_PARTIALMATCH
*/
-isc_result_t new_ldap_instance(isc_mem_t *mctx, dns_view_t *view, ldap_instance_t **ldap_instp,
- const char * const *argv);
+isc_result_t
+new_ldap_instance(isc_mem_t *mctx, const char *db_name,
+ const char * const *argv, dns_dyndb_arguments_t *dyndb_args,
+ 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,
- const char *db_name, dns_zonemgr_t *zmgr);
+isc_result_t
+refresh_zones_from_ldap(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 50f39a9..ab9e740 100644
--- a/src/zone_manager.c
+++ b/src/zone_manager.c
@@ -20,8 +20,11 @@
#include <isc/mem.h>
#include <isc/once.h>
#include <isc/result.h>
+#include <isc/task.h>
+#include <isc/timer.h>
#include <isc/util.h>
+#include <dns/dynamic_db.h>
#include <dns/view.h>
#include <dns/zone.h>
@@ -30,6 +33,7 @@
#include "ldap_convert.h"
#include "ldap_helper.h"
#include "log.h"
+#include "settings.h"
#include "util.h"
#include "zone_manager.h"
@@ -38,7 +42,7 @@ struct db_instance {
char *name;
ldap_instance_t *ldap_inst;
ldap_cache_t *ldap_cache;
- dns_zonemgr_t *dns_zone_manager;
+ isc_timer_t *timer;
LINK(db_instance_t) link;
};
@@ -86,8 +90,12 @@ destroy_db_instance(db_instance_t **db_instp)
db_inst = *db_instp;
- destroy_ldap_instance(&db_inst->ldap_inst);
- destroy_ldap_cache(&db_inst->ldap_cache);
+ if (db_inst->timer != NULL)
+ isc_timer_detach(&db_inst->timer);
+ if (db_inst->ldap_inst != NULL)
+ destroy_ldap_instance(&db_inst->ldap_inst);
+ if (db_inst->ldap_cache != NULL)
+ destroy_ldap_cache(&db_inst->ldap_cache);
if (db_inst->name != NULL)
isc_mem_free(db_inst->mctx, db_inst->name);
@@ -96,23 +104,27 @@ destroy_db_instance(db_instance_t **db_instp)
*db_instp = NULL;
}
+static void refresh_zones_action(isc_task_t *task, isc_event_t *event);
+
isc_result_t
-manager_add_db_instance(isc_mem_t *mctx, const char *name, ldap_instance_t *ldap_inst,
- ldap_cache_t *ldap_cache, dns_zonemgr_t *zmgr)
+manager_create_db_instance(isc_mem_t *mctx, const char *name,
+ const char * const *argv,
+ dns_dyndb_arguments_t *dyndb_args)
{
isc_result_t result;
- db_instance_t *db_inst;
+ db_instance_t *db_inst = NULL;
+ unsigned int zone_refresh;
+ setting_t manager_settings[] = {
+ { "zone_refresh", default_uint(0) },
+ end_of_settings
+ };
REQUIRE(mctx != NULL);
REQUIRE(name != NULL);
- REQUIRE(ldap_inst != NULL);
- REQUIRE(ldap_cache != NULL);
- REQUIRE(zmgr != NULL);
+ REQUIRE(dyndb_args != NULL);
isc_once_do(&initialize_once, initialize_manager);
- db_inst = NULL;
-
result = find_db_instance(name, &db_inst);
if (result == ISC_R_SUCCESS) {
db_inst = NULL;
@@ -123,20 +135,39 @@ manager_add_db_instance(isc_mem_t *mctx, const char *name, ldap_instance_t *ldap
result = ISC_R_SUCCESS;
}
+ /* Parse settings. */
+ manager_settings[0].target = &zone_refresh;
+ CHECK(set_settings(manager_settings, argv));
+
CHECKED_MEM_GET_PTR(mctx, db_inst);
- CHECKED_MEM_STRDUP(mctx, name, db_inst->name);
- db_inst->mctx = NULL;
+ ZERO_PTR(db_inst);
+
isc_mem_attach(mctx, &db_inst->mctx);
- db_inst->ldap_inst = ldap_inst;
- db_inst->ldap_cache = ldap_cache;
- db_inst->dns_zone_manager = zmgr;
+ CHECKED_MEM_STRDUP(mctx, name, db_inst->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));
+
+ refresh_zones_from_ldap(db_inst->ldap_inst, ISC_TRUE);
+
+ /* 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);
+
+ CHECK(isc_timer_create(timer_mgr, isc_timertype_ticker, NULL,
+ &interval, task, refresh_zones_action,
+ db_inst, &db_inst->timer));
+ }
LOCK(&instance_list_lock);
APPEND(instance_list, db_inst, link);
UNLOCK(&instance_list_lock);
- refresh_zones_from_ldap(ldap_inst, name, zmgr);
-
return ISC_R_SUCCESS;
cleanup:
@@ -146,25 +177,23 @@ cleanup:
return result;
}
-void
-manager_refresh_zones(void)
+static void
+refresh_zones_action(isc_task_t *task, isc_event_t *event)
{
- db_instance_t *db_inst;
+ db_instance_t *db_inst = event->ev_arg;
- LOCK(&instance_list_lock);
- db_inst = HEAD(instance_list);
- while (db_inst != NULL) {
- refresh_zones_from_ldap(db_inst->ldap_inst, db_inst->name,
- db_inst->dns_zone_manager);
- db_inst = NEXT(db_inst, link);
- }
+ UNUSED(task);
+ LOCK(&instance_list_lock);
+ refresh_zones_from_ldap(db_inst->ldap_inst, ISC_FALSE);
UNLOCK(&instance_list_lock);
+
+ isc_event_free(&event);
}
isc_result_t
manager_get_ldap_instance_and_cache(const char *name, ldap_instance_t **ldap_inst,
- ldap_cache_t **ldap_cache)
+ ldap_cache_t **ldap_cache)
{
isc_result_t result;
db_instance_t *db_inst;
diff --git a/src/zone_manager.h b/src/zone_manager.h
index b7d15bf..b685f76 100644
--- a/src/zone_manager.h
+++ b/src/zone_manager.h
@@ -30,11 +30,12 @@ typedef struct db_instance db_instance_t;
void destroy_manager(void);
isc_result_t
-manager_add_db_instance(isc_mem_t *mctx, const char *name, ldap_instance_t *ldap_inst,
- ldap_cache_t *ldap_cache, dns_zonemgr_t *zmgr);
+manager_create_db_instance(isc_mem_t *mctx, const char *name,
+ const char * const *argv,
+ dns_dyndb_arguments_t *dyndb_args);
isc_result_t
manager_get_ldap_instance_and_cache(const char *name, ldap_instance_t **ldap_inst,
- ldap_cache_t **ldap_cache);
+ ldap_cache_t **ldap_cache);
#endif /* !_LD_ZONE_MANAGER_H_ */