diff options
-rw-r--r-- | src/cache.c | 3 | ||||
-rw-r--r-- | src/cache.h | 3 | ||||
-rw-r--r-- | src/ldap_driver.c | 30 | ||||
-rw-r--r-- | src/ldap_helper.c | 43 | ||||
-rw-r--r-- | src/ldap_helper.h | 10 | ||||
-rw-r--r-- | src/zone_manager.c | 87 | ||||
-rw-r--r-- | src/zone_manager.h | 7 |
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_ */ |