summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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_ */