summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Nagy <mnagy@redhat.com>2009-07-31 14:33:56 +0200
committerMartin Nagy <mnagy@redhat.com>2009-08-04 16:50:54 +0200
commit2d1ffcf060eb873a76d462725195dbac6f114c1f (patch)
treed94c925778aedac5fedd1a5a5d66ceabf8b65bc3 /src
parentc81addd0760ab5d6f692358dc771432ec0cd91be (diff)
downloadldap_driver-2d1ffcf060eb873a76d462725195dbac6f114c1f.tar.gz
ldap_driver-2d1ffcf060eb873a76d462725195dbac6f114c1f.tar.xz
ldap_driver-2d1ffcf060eb873a76d462725195dbac6f114c1f.zip
Use the zone register for internal storage of zones
Moving the zone registration into a separate file will make the code more modular and easier to read and change. Also, we are preparing the refresh_zones_from_ldap() function for it's intended purpose of being able to add zones and later modify them if something has changed. Unfortunately, we will only be able to change some of the zone attributes (for now the update policy). We will not be able to create new zones as they are added to LDAP because that requires a reload of the name server.
Diffstat (limited to 'src')
-rw-r--r--src/ldap_convert.c8
-rw-r--r--src/ldap_convert.h4
-rw-r--r--src/ldap_helper.c294
-rw-r--r--src/ldap_helper.h8
4 files changed, 132 insertions, 182 deletions
diff --git a/src/ldap_convert.c b/src/ldap_convert.c
index e25fe42..c7f9fa4 100644
--- a/src/ldap_convert.c
+++ b/src/ldap_convert.c
@@ -34,9 +34,9 @@
#include "str.h"
#include "ldap_convert.h"
-#include "ldap_helper.h"
#include "log.h"
#include "util.h"
+#include "zone_register.h"
/*
* Consistency must be preserved in these tables.
@@ -190,13 +190,13 @@ explode_rdn(const char *rdn, char ***explodedp, int notypes)
}
isc_result_t
-dnsname_to_dn(ldap_instance_t *ldap_inst, dns_name_t *name, ld_string_t *target)
+dnsname_to_dn(zone_register_t *zr, dns_name_t *name, ld_string_t *target)
{
isc_result_t result;
int label_count;
const char *zone_dn = NULL;
- REQUIRE(ldap_inst != NULL);
+ REQUIRE(zr != NULL);
REQUIRE(name != NULL);
REQUIRE(target != NULL);
@@ -208,7 +208,7 @@ dnsname_to_dn(ldap_instance_t *ldap_inst, dns_name_t *name, ld_string_t *target)
INIT_BUFFERED_NAME(zone);
- CHECK(get_zone_dn(ldap_inst, name, &zone_dn, &zone));
+ CHECK(zr_get_zone_dn(zr, name, &zone_dn, &zone));
dns_name_fullcompare(name, &zone, &dummy, &common_labels);
label_count = dns_name_countlabels(name) - common_labels;
diff --git a/src/ldap_convert.h b/src/ldap_convert.h
index 58113e5..cca2330 100644
--- a/src/ldap_convert.h
+++ b/src/ldap_convert.h
@@ -23,7 +23,7 @@
#include <dns/types.h>
#include "str.h"
-#include "ldap_helper.h"
+#include "zone_register.h"
/*
* Convert LDAP DN 'dn', to dns_name_t 'target'. 'target' needs to be
@@ -33,7 +33,7 @@
isc_result_t dn_to_dnsname(isc_mem_t *mctx, const char *dn,
dns_name_t *target);
-isc_result_t dnsname_to_dn(ldap_instance_t *ldap_inst, dns_name_t *name,
+isc_result_t dnsname_to_dn(zone_register_t *zr, dns_name_t *name,
ld_string_t *target);
isc_result_t ldap_attribute_to_rdatatype(const char *ldap_record,
diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index ba774ff..b2ee99b 100644
--- a/src/ldap_helper.c
+++ b/src/ldap_helper.c
@@ -55,6 +55,7 @@
#include "settings.h"
#include "str.h"
#include "util.h"
+#include "zone_register.h"
#define DEFAULT_TTL 86400
@@ -108,8 +109,7 @@ struct ldap_instance {
LIST(ldap_connection_t) conn_list;
/* Our own list of zones. */
- isc_rwlock_t zone_rwlock;
- dns_rbt_t *zone_names;
+ zone_register_t *zone_register;
/* krb5 kinit mutex */
isc_mutex_t kinit_lock;
@@ -199,13 +199,9 @@ const ldap_auth_pair_t supported_ldap_auth[] = {
*/
/* TODO: reorganize this stuff & clean it up. */
-void string_deleter(void *arg1, void *arg2);
static isc_result_t new_ldap_connection(ldap_instance_t *ldap_inst,
ldap_connection_t **ldap_connp);
static void destroy_ldap_connection(ldap_connection_t **ldap_connp);
-static isc_result_t add_or_modify_zone(ldap_instance_t *ldap_inst, const char *dn,
- const char *db_name, const char *update_str,
- dns_zonemgr_t *zmgr);
static isc_result_t findrdatatype_or_create(isc_mem_t *mctx,
ldapdb_rdatalist_t *rdatalist, ldap_entry_t *entry,
@@ -312,8 +308,7 @@ new_ldap_instance(isc_mem_t *mctx, dns_view_t *view, ldap_instance_t **ldap_inst
INIT_LIST(ldap_inst->conn_list);
- CHECK(isc_rwlock_init(&ldap_inst->zone_rwlock, 0, 0));
- CHECK(dns_rbt_create(mctx, string_deleter, mctx, &ldap_inst->zone_names));
+ CHECK(zr_create(mctx, &ldap_inst->zone_register));
CHECK(isc_mutex_init(&ldap_inst->kinit_lock));
@@ -430,8 +425,7 @@ destroy_ldap_instance(ldap_instance_t **ldap_instp)
DESTROYLOCK(&ldap_inst->kinit_lock);
- dns_rbt_destroy(&ldap_inst->zone_names);
- isc_rwlock_destroy(&ldap_inst->zone_rwlock);
+ zr_destroy(&ldap_inst->zone_register);
isc_mem_putanddetach(&ldap_inst->mctx, ldap_inst, sizeof(ldap_instance_t));
@@ -503,9 +497,88 @@ destroy_ldap_connection(ldap_connection_t **ldap_connp)
*ldap_connp = NULL;
}
-/* TODO: Delete old zones. */
+/*
+ * Create a new zone with origin 'name'. The zone will be added to the
+ * view set in 'ldap_inst'.
+ */
+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)
+{
+ isc_result_t result;
+ dns_zone_t *zone = NULL;
+ const char *argv[2];
+
+ 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;
+
+ result = dns_view_findzone(ldap_inst->view, name, &zone);
+ if (result == ISC_R_SUCCESS) {
+ result = ISC_R_EXISTS;
+ log_error_r("failed to create new zone");
+ goto cleanup;
+ } else if (result != ISC_R_NOTFOUND) {
+ log_error_r("dns_view_findzone() failed");
+ goto cleanup;
+ }
+
+ CHECK(dns_zone_create(&zone, ldap_inst->mctx));
+ dns_zone_setview(zone, ldap_inst->view);
+ CHECK(dns_zone_setorigin(zone, 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_view_addzone(ldap_inst->view, zone));
+
+ *zonep = zone;
+ return ISC_R_SUCCESS;
+
+cleanup:
+ if (zone != NULL)
+ dns_zone_detach(&zone);
+
+ return result;
+}
+
+static isc_result_t
+modify_zone(dns_zone_t *zone, const char *update_str)
+{
+ REQUIRE(zone != NULL);
+
+ /*
+ * This is meant only for debugging.
+ * DANGEROUS: Do not leave uncommented!
+ */
+#if 0
+ {
+ dns_acl_t *any;
+ dns_acl_any(dns_zone_getmctx(zone), &any);
+ dns_zone_setupdateacl(zone, any);
+ dns_acl_detach(&any);
+ }
+
+ return ISC_R_SUCCESS;
+#endif
+
+ /* Set simple update table. */
+ return acl_configure_zone_ssutable(update_str, zone);
+}
+
+/*
+ * Search in LDAP for zones. If 'zmgr' is not NULL, add 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 *name,
+refresh_zones_from_ldap(ldap_instance_t *ldap_inst, const char *db_name,
dns_zonemgr_t *zmgr)
{
isc_result_t result = ISC_R_SUCCESS;
@@ -516,14 +589,14 @@ refresh_zones_from_ldap(ldap_instance_t *ldap_inst, const char *name,
};
REQUIRE(ldap_inst != NULL);
- REQUIRE(name != NULL);
+ REQUIRE(db_name != NULL);
- log_debug(2, "refreshing list of zones");
+ log_debug(2, "refreshing list of zones for %s", db_name);
ldap_conn = get_connection(ldap_inst);
- CHECK(ldap_query(ldap_conn, str_buf(ldap_inst->base), LDAP_SCOPE_SUBTREE,
- attrs, 0,
+ CHECK(ldap_query(ldap_conn, str_buf(ldap_inst->base),
+ LDAP_SCOPE_SUBTREE, attrs, 0,
"(&(objectClass=idnsZone)(idnsZoneActive=True))"));
CHECK(cache_query_results(ldap_conn));
@@ -531,25 +604,48 @@ refresh_zones_from_ldap(ldap_instance_t *ldap_inst, const char *name,
entry != NULL;
entry = NEXT(entry, link)) {
const char *dn;
- const char *update_str = NULL;
ldap_value_list_t values;
+ dns_name_t name;
+ dns_zone_t *zone;
+ zone = NULL;
+ dns_name_init(&name, NULL);
+
+ /* Derive the dns name of the zone from the DN. */
dn = get_dn(ldap_conn, entry);
+ CHECK_NEXT(dn_to_dnsname(ldap_inst->mctx, dn, &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));
+ CHECK_NEXT(zr_add_zone(ldap_inst->zone_register, zone,
+ dn));
+ log_error("created zone %p: %s", zone, dn);
+ } else {
+ CHECK_NEXT(zr_get_zone_ptr(ldap_inst->zone_register,
+ &name, &zone));
+ }
- /* Look if there's an update policy. */
+ log_error("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)
- update_str = HEAD(values)->value;
-
- result = add_or_modify_zone(ldap_inst, dn, name, update_str,
- zmgr);
-
- /* TODO: move this to the add_or_modify_zone() */
- if (result != ISC_R_SUCCESS)
- log_error("failed to add/modify zone %s", dn);
+ modify_zone(zone, HEAD(values)->value);
+ else
+ modify_zone(zone, NULL);
+
+next:
+ if (dns_name_dynamic(&name))
+ dns_name_free(&name, ldap_inst->mctx);
+ if (zone != NULL)
+ dns_zone_detach(&zone);
}
cleanup:
+ /* XXX: Cleanup here */
put_connection(ldap_conn);
log_debug(2, "finished refreshing list of zones");
@@ -587,148 +683,6 @@ get_dn(ldap_connection_t *inst)
}
#endif
-void
-string_deleter(void *arg1, void *arg2)
-{
- char *string = arg1;
- isc_mem_t *mctx = arg2;
-
- REQUIRE(string != NULL);
- REQUIRE(mctx != NULL);
-
- isc_mem_free(mctx, string);
-}
-
-isc_result_t
-get_zone_dn(ldap_instance_t *ldap_inst, dns_name_t *name, const char **dn,
- dns_name_t *matched_name)
-{
- isc_result_t result;
- dns_rbt_t *rbt;
- void *data = NULL;
-
- REQUIRE(ldap_inst != NULL);
- REQUIRE(name != NULL);
- REQUIRE(dn != NULL && *dn == NULL);
- REQUIRE(matched_name != NULL);
-
- RWLOCK(&ldap_inst->zone_rwlock, isc_rwlocktype_read);
- rbt = ldap_inst->zone_names;
-
- result = dns_rbt_findname(rbt, name, 0, matched_name, &data);
- if (result == DNS_R_PARTIALMATCH)
- result = ISC_R_SUCCESS;
- if (result == ISC_R_SUCCESS) {
- INSIST(data != NULL);
- *dn = data;
- }
-
- RWUNLOCK(&ldap_inst->zone_rwlock, isc_rwlocktype_read);
-
- return result;
-}
-
-static isc_result_t
-add_zone_dn(ldap_instance_t *ldap_inst, dns_name_t *name, const char *dn)
-{
- isc_result_t result;
- dns_rbt_t *rbt;
- void *data = NULL;
- char *new_dn = NULL;
-
- REQUIRE(ldap_inst != NULL);
- REQUIRE(name != NULL);
- REQUIRE(dn != NULL);
-
- RWLOCK(&ldap_inst->zone_rwlock, isc_rwlocktype_write);
- rbt = ldap_inst->zone_names;
-
- CHECKED_MEM_STRDUP(ldap_inst->mctx, dn, new_dn);
-
- /* First make sure the node doesn't exist. */
- result = dns_rbt_findname(rbt, name, 0, NULL, &data);
- if (result == ISC_R_SUCCESS)
- CHECK(dns_rbt_deletename(rbt, name, ISC_FALSE));
- else if (result != ISC_R_NOTFOUND && result != DNS_R_PARTIALMATCH)
- goto cleanup;
-
- /* Now add it. */
- CHECK(dns_rbt_addname(rbt, name, (void *)new_dn));
-
-cleanup:
- RWUNLOCK(&ldap_inst->zone_rwlock, isc_rwlocktype_write);
-
- if (result != ISC_R_SUCCESS && new_dn != NULL)
- isc_mem_free(ldap_inst->mctx, new_dn);
-
- return result;
-}
-
-/* FIXME: Better error handling. */
-static isc_result_t
-add_or_modify_zone(ldap_instance_t *ldap_inst, const char *dn, const char *db_name,
- const char *update_str, dns_zonemgr_t *zmgr)
-{
- isc_result_t result;
- dns_zone_t *zone;
- dns_name_t name;
- const char *argv[2];
-
- REQUIRE(ldap_inst != NULL);
- REQUIRE(dn != NULL);
- REQUIRE(db_name != NULL);
-
- argv[0] = ldapdb_impname;
- argv[1] = db_name;
-
- zone = NULL;
- dns_name_init(&name, NULL);
-
- CHECK(dn_to_dnsname(ldap_inst->mctx, dn, &name));
-
- /* If the zone doesn't exist, create it. */
- result = dns_view_findzone(ldap_inst->view, &name, &zone);
- if (result == ISC_R_NOTFOUND) {
- CHECK(dns_zone_create(&zone, ldap_inst->mctx));
- dns_zone_setview(zone, ldap_inst->view);
- CHECK(dns_zone_setorigin(zone, &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_view_addzone(ldap_inst->view, zone));
- CHECK(add_zone_dn(ldap_inst, &name, dn));
- } else if (result != ISC_R_SUCCESS) {
- goto cleanup;
- }
-
- /* Set simple update table. */
- CHECK(acl_configure_zone_ssutable(update_str, zone));
-
- /*
- * ACLs:
- * dns_zone_setqueryacl()
- * dns_zone_setqueryonacl()
- * dns_zone_setupdateacl()
- * dns_zone_setforwardacl()
- * dns_zone_setxfracl()
- */
-
- /*
- * maybe?
- * dns_zone_setnotifytype()
- * dns_zone_setalsonotify()
- */
-
-cleanup:
- if (dns_name_dynamic(&name))
- dns_name_free(&name, ldap_inst->mctx);
- if (zone != NULL)
- dns_zone_detach(&zone);
-
- return result;
-}
-
static isc_result_t
findrdatatype_or_create(isc_mem_t *mctx, ldapdb_rdatalist_t *rdatalist,
ldap_entry_t *entry, dns_rdatatype_t rdtype,
@@ -853,7 +807,7 @@ ldapdb_rdatalist_get(isc_mem_t *mctx, ldap_instance_t *ldap_inst, dns_name_t *na
INIT_LIST(*rdatalist);
CHECK(str_new(mctx, &string));
- CHECK(dnsname_to_dn(ldap_inst, name, string));
+ CHECK(dnsname_to_dn(ldap_inst->zone_register, name, string));
CHECK(ldap_query(ldap_conn, str_buf(string), LDAP_SCOPE_BASE, NULL, 0,
"(objectClass=idnsRecord)"));
@@ -1983,7 +1937,7 @@ modify_ldap_common(dns_name_t *owner, ldap_instance_t *ldap_inst,
ldap_conn = get_connection(ldap_inst);
CHECK(str_new(mctx, &owner_dn));
- CHECK(dnsname_to_dn(ldap_inst, owner, owner_dn));
+ CHECK(dnsname_to_dn(ldap_inst->zone_register, owner, owner_dn));
if (rdlist->type == dns_rdatatype_soa) {
result = modify_soa_record(ldap_conn, str_buf(owner_dn),
diff --git a/src/ldap_helper.h b/src/ldap_helper.h
index 019938c..d353ff2 100644
--- a/src/ldap_helper.h
+++ b/src/ldap_helper.h
@@ -86,12 +86,8 @@ isc_result_t ldapdb_rdatalist_get(isc_mem_t *mctx, ldap_instance_t *ldap_inst,
isc_result_t new_ldap_instance(isc_mem_t *mctx, dns_view_t *view, ldap_instance_t **ldap_instp,
const char * const *argv);
void destroy_ldap_instance(ldap_instance_t **ldap_inst);
-isc_result_t refresh_zones_from_ldap(ldap_instance_t *ldap_inst, const char *name,
- dns_zonemgr_t *zmgr);
-
-isc_result_t
-get_zone_dn(ldap_instance_t *ldap_inst, dns_name_t *name, const char **dn,
- dns_name_t *matched_name);
+isc_result_t refresh_zones_from_ldap(ldap_instance_t *ldap_inst,
+ const char *db_name, dns_zonemgr_t *zmgr);
/* Functions for writing to LDAP. */
isc_result_t write_to_ldap(dns_name_t *owner, ldap_instance_t *ldap_inst,