Hello,

Do not load invalid zones.

Without this patch, it was possible to load an invalid zone without
proper SOA or NS records because the fake SOA and NS records allowed
checks in dns_zone_load() to pass.

With this patch, no fake SOA or NS records are created and
dns_zone_load() is not called before end of the initial synchronization.

See the function ldapdb_associate() in ldap_driver.c and it's comments.

--
Petr^2 Spacek
From bd2f1f3d3c13d3efe5833146eb5bcb2bbf76b8d3 Mon Sep 17 00:00:00 2001
From: Petr Spacek <pspa...@redhat.com>
Date: Wed, 27 Nov 2013 16:25:30 +0100
Subject: [PATCH] Do not load invalid zones.

Without this patch, it was possible to load an invalid zone without
proper SOA or NS records because the fake SOA and NS records allowed
checks in dns_zone_load() to pass.

With this patch, no fake SOA or NS records are created and
dns_zone_load() is not called before end of the initial synchronization.

See the function ldapdb_associate() in ldap_driver.c and it's comments.

Signed-off-by: Petr Spacek <pspa...@redhat.com>
---
 src/ldap_driver.c   | 124 ++++++++++++++++++++--------------------------------
 src/ldap_driver.h   |  16 ++++++-
 src/ldap_helper.c   | 110 ++++++++++++++++++++++++++++++++--------------
 src/ldap_helper.h   |   9 ++--
 src/syncrepl.c      |   2 +-
 src/types.h         |   3 ++
 src/zone_register.c |  15 +++++--
 src/zone_register.h |   2 -
 8 files changed, 161 insertions(+), 120 deletions(-)

diff --git a/src/ldap_driver.c b/src/ldap_driver.c
index 11ade10a12edc89c4bd0e713788cc56b8afee83d..105c8a23dd42157f51eafdddb4f44f02335fb71e 100644
--- a/src/ldap_driver.c
+++ b/src/ldap_driver.c
@@ -66,7 +66,7 @@
 #define VALID_LDAPDB(ldapdb) \
 	((ldapdb) != NULL && (ldapdb)->common.impmagic == LDAPDB_MAGIC)
 
-typedef struct {
+struct ldapdb {
 	dns_db_t			common;
 	isc_refcount_t			refs;
 	ldap_instance_t			*ldap_inst;
@@ -92,7 +92,7 @@ typedef struct {
 	 * The purpose is to detect moment when the new version is closed.
 	 * That is the right time for unlocking newversion_lock. */
 	dns_dbversion_t			*newversion;
-} ldapdb_t;
+};
 
 dns_db_t * ATTR_NONNULLS
 ldapdb_get_rbtdb(dns_db_t *db) {
@@ -909,83 +909,57 @@ dns_ns_buildrdata(dns_name_t *origin, dns_name_t *ns_name,
 				      &ns, &rdatabuf));
 }
 
-/*
- * Create an SOA record for a newly-created zone
+/**
+ * Associate a pre-existing LDAP DB instance with a new DNS zone.
+ *
+ * @warning This is a hack.
+ *
+ * Normally, an empty database is created by dns_db_create() call during
+ * dns_zone_load().
+ *
+ * In our case, we need to create and populate databases on-the-fly
+ * as we process data from LDAP.
+ * We create an empty LDAP DB (which encapsulates internal RBT DB)
+ * for each zone when the zone is being added to zone_register.
+ *
+ * The database in zone register is modified on-the-fly and subsequent
+ * dns_db_create() call associates this populated database with the DNS zone.
+ *
+ * This allows us to call dns_zone_load() later when all the data are in place,
+ * so dns_zone_load() can be postponed until synchronization state sync_finish
+ * is reached.
+ *
+ * @param[in] argv [0] is database instance name
  */
-static isc_result_t ATTR_NONNULLS
-add_soa(isc_mem_t *mctx, dns_name_t *origin, dns_db_t *db) {
+isc_result_t
+ldapdb_associate(isc_mem_t *mctx, dns_name_t *name, dns_dbtype_t type,
+		 dns_rdataclass_t rdclass, unsigned int argc, char *argv[],
+		 void *driverarg, dns_db_t **dbp) {
+
 	isc_result_t result;
-	dns_rdata_t rdata_soa = DNS_RDATA_INIT;
-	dns_rdata_t rdata_ns = DNS_RDATA_INIT;
-	unsigned char buf_soa[DNS_SOA_BUFFERSIZE];
-	unsigned char buf_ns[DNS_SOA_BUFFERSIZE];
-	dns_fixedname_t ns_name;
-	dns_fixedname_t m_name;
-	dns_dbversion_t *ver = NULL;
-	dns_difftuple_t *tp_soa = NULL;
-	dns_difftuple_t *tp_ns = NULL;
-	dns_diff_t diff;
+	ldap_instance_t *ldap_inst = NULL;
+	zone_register_t *zr = NULL;
 
-	dns_diff_init(mctx, &diff);
-	result = dns_db_newversion(db, &ver);
-	if (result != ISC_R_SUCCESS) {
-		log_error_r("add_soa:dns_db_newversion");
-		goto failure;
-	}
+	UNUSED(driverarg); /* Currently we don't need any data */
 
-	/* Build SOA record */
-	dns_fixedname_init(&m_name);
-	dns_name_fromstring(dns_fixedname_name(&m_name), "pspacek.brq.redhat.com.", 0, mctx);
-	result = dns_soa_buildrdata(dns_fixedname_name(&m_name), dns_rootname, dns_rdataclass_in,
-				    0, 0, 0, 0, 0, buf_soa, &rdata_soa);
-	if (result != ISC_R_SUCCESS) {
-		log_error_r("add_soa:dns_soa_buildrdata");
-		goto failure;
-	}
+	REQUIRE(ISCAPI_MCTX_VALID(mctx));
+	REQUIRE(argc == LDAP_DB_ARGC);
+	REQUIRE(type == LDAP_DB_TYPE);
+	REQUIRE(rdclass == LDAP_DB_RDATACLASS);
+	REQUIRE(dbp != NULL && *dbp == NULL);
 
-	result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, origin, 3600,
-				      &rdata_soa, &tp_soa);
-	if (result != ISC_R_SUCCESS) {
-			log_error_r("add_soa:dns_difftuple_create");
-			goto failure;
-	}
-	dns_diff_append(&diff, &tp_soa);
+	CHECK(manager_get_ldap_instance(argv[0], &ldap_inst));
+	zr = ldap_instance_getzr(ldap_inst);
+	if (zr == NULL)
+		CLEANUP_WITH(ISC_R_NOTFOUND);
 
-	/* Build NS record */
-	dns_fixedname_init(&ns_name);
-	dns_name_fromstring(dns_fixedname_name(&ns_name), "localhost.", 0, mctx);
+	CHECK(zr_get_zone_dbs(zr, name, dbp, NULL));
 
-	result = dns_ns_buildrdata(origin, dns_fixedname_name(&ns_name),
-			dns_rdataclass_in,
-			buf_ns,
-			&rdata_ns);
-	if (result != ISC_R_SUCCESS) {
-			log_error_r("add_soa:dns_ns_buildrdata");
-			goto failure;
-	}
-	result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, origin, 3600,
-				      &rdata_ns, &tp_ns);
-	if (result != ISC_R_SUCCESS) {
-			log_error_r("add_soa:dns_difftuple_create");
-			goto failure;
-	}
-	dns_diff_append(&diff, &tp_ns);
-
-	result = dns_diff_apply(&diff, db, ver);
-	if (result != ISC_R_SUCCESS) {
-			log_error_r("add_soa:dns_difftuple_create");
-			goto failure;
-	}
-
-failure:
-	dns_diff_clear(&diff);
-	if (ver != NULL)
-		dns_db_closeversion(db, &ver, ISC_TF(result == ISC_R_SUCCESS));
-
-	return (result);
+cleanup:
+	return result;
 }
 
-static isc_result_t
+isc_result_t
 ldapdb_create(isc_mem_t *mctx, dns_name_t *name, dns_dbtype_t type,
 	      dns_rdataclass_t rdclass, unsigned int argc, char *argv[],
 	      void *driverarg, dns_db_t **dbp)
@@ -997,10 +971,9 @@ ldapdb_create(isc_mem_t *mctx, dns_name_t *name, dns_dbtype_t type,
 	UNUSED(driverarg); /* Currently we don't need any data */
 
 	/* Database instance name. */
-	REQUIRE(argc > 0);
-
-	REQUIRE(type == dns_dbtype_zone);
-	REQUIRE(rdclass == dns_rdataclass_in);
+	REQUIRE(argc == LDAP_DB_ARGC);
+	REQUIRE(type == LDAP_DB_TYPE);
+	REQUIRE(rdclass == LDAP_DB_RDATACLASS);
 	REQUIRE(dbp != NULL && *dbp == NULL);
 
 	CHECKED_MEM_GET_PTR(mctx, ldapdb);
@@ -1026,7 +999,6 @@ ldapdb_create(isc_mem_t *mctx, dns_name_t *name, dns_dbtype_t type,
 
 	CHECK(dns_db_create(mctx, "rbt", name, dns_dbtype_zone,
 			    dns_rdataclass_in, 0, NULL, &ldapdb->rbtdb));
-	CHECK(add_soa(mctx, name, ldapdb->rbtdb));
 
 	*dbp = (dns_db_t *)ldapdb;
 
@@ -1072,7 +1044,7 @@ dynamic_driver_init(isc_mem_t *mctx, const char *name, const char * const *argv,
 	 */
 
 	/* Register new DNS DB implementation. */
-	result = dns_db_register(ldapdb_impname, &ldapdb_create, NULL, mctx,
+	result = dns_db_register(ldapdb_impname, &ldapdb_associate, NULL, mctx,
 				 &ldapdb_imp_new);
 	if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS)
 		return result;
diff --git a/src/ldap_driver.h b/src/ldap_driver.h
index 8cd026c823324dd450c8e738891310a3445dbb2c..984eca14774371602ab2e31374f94942fc27b843 100644
--- a/src/ldap_driver.h
+++ b/src/ldap_driver.h
@@ -22,9 +22,23 @@
 #define LDAP_DRIVER_H_
 
 #include <dns/diff.h>
+#include <dns/types.h>
 
 #include "util.h"
 
-dns_db_t * ldapdb_get_rbtdb(dns_db_t *db) ATTR_NONNULLS;
+/* values shared by all LDAP database instances */
+#define LDAP_DB_TYPE		dns_dbtype_zone
+#define LDAP_DB_RDATACLASS	dns_rdataclass_in
+#define LDAP_DB_ARGC		1
+
+typedef struct ldapdb ldapdb_t;
+
+isc_result_t
+ldapdb_create(isc_mem_t *mctx, dns_name_t *name, dns_dbtype_t type,
+	      dns_rdataclass_t rdclass, unsigned int argc, char *argv[],
+	      void *driverarg, dns_db_t **dbp) ATTR_NONNULL(1,2,6,8);
+
+dns_db_t *
+ldapdb_get_rbtdb(dns_db_t *db) ATTR_NONNULLS;
 
 #endif /* LDAP_DRIVER_H_ */
diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index 700751eaefb5b312966d305686d65fb9cd398f04..ae1bead8e662bb2d0cbfe49b762a145a952870e8 100644
--- a/src/ldap_helper.c
+++ b/src/ldap_helper.c
@@ -842,6 +842,31 @@ cleanup:
 }
 
 static isc_result_t ATTR_NONNULLS
+load_zone(dns_zone_t *zone) {
+	isc_result_t result;
+	isc_boolean_t zone_dynamic;
+	isc_uint32_t serial;
+
+	result = dns_zone_load(zone);
+	if (result != ISC_R_SUCCESS && result != DNS_R_UPTODATE
+	    && result != DNS_R_DYNAMIC && result != DNS_R_CONTINUE)
+		goto cleanup;
+	zone_dynamic = (result == DNS_R_DYNAMIC);
+
+	CHECK(dns_zone_getserial2(zone, &serial));
+	dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u", serial);
+
+	if (zone_dynamic)
+		dns_zone_notify(zone);
+
+cleanup:
+	return result;
+}
+
+/**
+ * Add zone to the view defined in inst->view.
+ */
+static isc_result_t ATTR_NONNULLS
 publish_zone(ldap_instance_t *inst, dns_zone_t *zone)
 {
 	isc_result_t result;
@@ -865,8 +890,12 @@ cleanup:
 	return result;
 }
 
+/**
+ * Add all zones in zone register to DNS view specified in inst->view
+ * and load zones.
+ */
 isc_result_t
-publish_zones(ldap_instance_t *inst) {
+activate_zones(ldap_instance_t *inst) {
 	isc_result_t result;
 	rbt_iterator_t *iter = NULL;
 	dns_zone_t *zone = NULL;
@@ -879,6 +908,17 @@ publish_zones(ldap_instance_t *inst) {
 	do {
 		++total_cnt;
 		CHECK(zr_get_zone_ptr(inst->zone_register, &name, &zone));
+		/*
+		 * Don't bother if load fails, server will return
+		 * SERVFAIL for queries beneath this zone. This is
+		 * admin's problem.
+		 */
+		result = load_zone(zone);
+		if (result != ISC_R_SUCCESS)
+			dns_zone_log(zone, ISC_LOG_ERROR,
+				     "unable to load zone: %s",
+				     dns_result_totext(result));
+
 		result = publish_zone(inst, zone);
 		if (result != ISC_R_SUCCESS)
 			dns_zone_log(zone, ISC_LOG_ERROR,
@@ -1539,12 +1579,15 @@ diff_analyze_serial(dns_diff_t *diff, dns_difftuple_t **soa_latest,
 			} else if (t->op == DNS_DIFFOP_ADD ||
 				   t->op == DNS_DIFFOP_ADDRESIGN) {
 				/* add operation has to follow a delete */
-				INSIST(del_soa != NULL);
 				*soa_latest = t;
 
-				/* detect if fields other than serial
-				 * were changed (compute only if necessary) */
-				if (*data_changed == ISC_FALSE) {
+				/* we are adding SOA without preceding delete
+				 * -> we are initializing new empty zone */
+				if (del_soa == NULL) {
+					*data_changed = ISC_TRUE;
+				} else if (*data_changed == ISC_FALSE) {
+					/* detect if fields other than serial
+					 * were changed (compute only if necessary) */
 					CHECK(dns_difftuple_copy(t, &tmp_tuple));
 					dns_soa_setserial(dns_soa_getserial(del_soa),
 							  &tmp_tuple->rdata);
@@ -1647,12 +1690,11 @@ ldap_parse_master_zoneentry(ldap_entry_t *entry, ldap_instance_t *inst)
 	dns_zone_t *zone_raw = NULL;
 	isc_result_t result;
 	isc_boolean_t unlock = ISC_FALSE;
-	isc_boolean_t publish = ISC_FALSE;
+	isc_boolean_t new_zone = ISC_FALSE;
 	isc_boolean_t configured = ISC_FALSE;
 	isc_boolean_t ssu_changed;
 	isc_task_t *task = inst->task;
 	ldapdb_rdatalist_t rdatalist;
-	isc_boolean_t zone_dynamic = ISC_FALSE;
 	settings_set_t *zone_settings = NULL;
 	const char *fake_mname = NULL;
 	isc_boolean_t data_changed;
@@ -1716,7 +1758,7 @@ ldap_parse_master_zoneentry(ldap_entry_t *entry, ldap_instance_t *inst)
 		CHECK(create_zone(inst, &name, &zone));
 		CHECK(configure_paths(inst->mctx, inst, zone, ISC_FALSE));
 		CHECK(zr_add_zone(inst->zone_register, zone, dn));
-		publish = ISC_TRUE;
+		new_zone = ISC_TRUE;
 		log_debug(2, "created zone %p: %s", zone, dn);
 	} else if (result != ISC_R_SUCCESS)
 		goto cleanup;
@@ -1779,29 +1821,15 @@ ldap_parse_master_zoneentry(ldap_entry_t *entry, ldap_instance_t *inst)
 	}
 
 	sync_state_get(inst->sctx, &sync_state);
-	if (publish == ISC_TRUE && sync_state == sync_finished)
+	if (new_zone == ISC_TRUE && sync_state == sync_finished)
 		CHECK(publish_zone(inst, zone));
 	configured = ISC_TRUE;
 
-	/*
-	 * Don't bother if load fails, server will return
-	 * SERVFAIL for queries beneath this zone. This is
-	 * admin's problem.
-	 */
-
-	/* !!! We should parse existing zone records before dns_zone_load(). */
-	result = dns_zone_load(zone);
-	if (result != ISC_R_SUCCESS && result != DNS_R_UPTODATE
-		&& result != DNS_R_DYNAMIC && result != DNS_R_CONTINUE)
-		goto cleanup;
-	zone_dynamic = (result == DNS_R_DYNAMIC);
-
 	/* synchronize zone origin with LDAP */
 	CHECK(setting_get_str("fake_mname", inst->local_settings,
 			      &fake_mname));
 	CHECK(ldap_parse_rrentry(inst->mctx, entry, &name, fake_mname,
 				 &rdatalist));
-	CHECK(dns_zone_getserial2(zone, &curr_serial));
 
 	CHECK(zr_get_zone_dbs(inst->zone_register, &name, &ldapdb, &rbtdb));
 	CHECK(dns_db_newversion(ldapdb, &version));
@@ -1817,7 +1845,10 @@ ldap_parse_master_zoneentry(ldap_entry_t *entry, ldap_instance_t *inst)
 
 	dns_db_detachnode(rbtdb, &node);
 
-	/* Detect if SOA serial is affected by the update or not. */
+	/* Detect if SOA serial is affected by the update or not.
+	 * New zone doesn't have serial defined yet. */
+	if (new_zone == ISC_FALSE)
+		CHECK(dns_db_getsoaserial(rbtdb, version, &curr_serial));
 	CHECK(diff_analyze_serial(&diff, &soa_tuple, &data_changed));
 	if (data_changed == ISC_TRUE) {
 		if (soa_tuple == NULL) {
@@ -1833,8 +1864,9 @@ ldap_parse_master_zoneentry(ldap_entry_t *entry, ldap_instance_t *inst)
 			CHECK(update_soa_serial(dns_updatemethod_unixtime,
 						soa_tuple, &new_serial));
 			dns_diff_appendminimal(&diff, &soa_tuple);
-		} else if (isc_serial_le(dns_soa_getserial(&soa_tuple->rdata),
-					 curr_serial) || publish == ISC_TRUE) {
+		} else if (new_zone == ISC_TRUE ||
+			   isc_serial_le(dns_soa_getserial(&soa_tuple->rdata),
+					 curr_serial)) {
 			/* The diff tries to send SOA serial back!
 			 * => generate new serial and write it back to LDAP.
 			 * Force serial update if we are adding a new zone. */
@@ -1853,17 +1885,17 @@ ldap_parse_master_zoneentry(ldap_entry_t *entry, ldap_instance_t *inst)
 			/* The diff is empty => do nothing. */
 			INSIST(EMPTY(diff.tuples));
 		} else if (isc_serial_le(dns_soa_getserial(&soa_tuple->rdata),
-				       curr_serial)) {
+					 curr_serial)) {
 			/* Attempt to move serial backwards without any data
 			 * => ignore it. */
 			dns_diff_clear(&diff);
 		}/* else:
 		  * The diff contains new serial already
 		  * => do nothing. */
 	}
 
 	/* Allow write to LDAP if we are adding a new zone. */
-	if (publish == ISC_FALSE && sync_state != sync_finished)
+	if (new_zone == ISC_FALSE && sync_state != sync_finished)
 		ldap_writeback = ISC_FALSE;
 #if RBTDB_DEBUG >= 2
 	dns_diff_print(&diff, stdout);
@@ -1898,11 +1930,9 @@ ldap_parse_master_zoneentry(ldap_entry_t *entry, ldap_instance_t *inst)
 		dns_db_closeversion(ldapdb, &version, ISC_TRUE);
 	}
 
-	CHECK(dns_zone_getserial2(zone, &curr_serial));
-	if (publish)
-		dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u", curr_serial);
-	if (zone_dynamic)
-		dns_zone_notify(zone);
+	/* Do zone load only if the initial LDAP synchronization is done. */
+	if (sync_state == sync_finished && data_changed == ISC_TRUE)
+		CHECK(load_zone(zone));
 
 cleanup:
 	dns_diff_clear(&diff);
@@ -1920,7 +1950,7 @@ cleanup:
 		dns_journal_destroy(&journal);
 	if (ldapdb != NULL)
 		dns_db_detach(&ldapdb);
-	if (publish && !configured) { /* Failure in ACL parsing or so. */
+	if (new_zone && !configured) { /* Failure in ACL parsing or so. */
 		log_error_r("zone '%s': publishing failed, rolling back due to",
 			    entry->dn);
 		result = delete_forwarding_table(inst, &name, "zone", entry->dn);
@@ -4537,3 +4567,15 @@ ldap_instance_getsettings_local(ldap_instance_t *ldap_inst)
 {
 	return ldap_inst->local_settings;
 }
+
+const char *
+ldap_instance_getdbname(ldap_instance_t *ldap_inst)
+{
+	return ldap_inst->db_name;
+}
+
+zone_register_t *
+ldap_instance_getzr(ldap_instance_t *ldap_inst)
+{
+	return ldap_inst->zone_register;
+}
diff --git a/src/ldap_helper.h b/src/ldap_helper.h
index bab8bf556ef97612790b7fcddf28a0df7626e8d6..ceca74d8a5e3e1f3d23e3d60c6e4d23e9bdf23db 100644
--- a/src/ldap_helper.h
+++ b/src/ldap_helper.h
@@ -24,13 +24,12 @@
 
 #include "settings.h"
 #include "types.h"
+#include "zone_register.h"
 
 #include <isc/util.h>
 
 #define LDAPDB_EVENTCLASS 		ISC_EVENTCLASS(0xDDDD)
 
-typedef struct ldap_instance	ldap_instance_t;
-
 isc_result_t ldapdb_rdatalist_findrdatatype(ldapdb_rdatalist_t *rdatalist,
 					    dns_rdatatype_t rdtype,
 					    dns_rdatalist_t **rdlistp) ATTR_NONNULLS;
@@ -100,6 +99,10 @@ remove_entry_from_ldap(dns_name_t *owner, ldap_instance_t *ldap_inst) ATTR_NONNU
 
 settings_set_t * ldap_instance_getsettings_local(ldap_instance_t *ldap_inst) ATTR_NONNULLS;
 
-isc_result_t publish_zones(ldap_instance_t *inst);
+const char * ldap_instance_getdbname(ldap_instance_t *ldap_inst) ATTR_NONNULLS;
+
+zone_register_t * ldap_instance_getzr(ldap_instance_t *ldap_inst) ATTR_NONNULLS;
+
+isc_result_t activate_zones(ldap_instance_t *inst);
 
 #endif /* !_LD_LDAP_HELPER_H_ */
diff --git a/src/syncrepl.c b/src/syncrepl.c
index 04a896cc741df6819965aa82bbc5a3d6179fee78..15e9ffe0289daafb9d2ef9c5e8dd2d68bf213874 100644
--- a/src/syncrepl.c
+++ b/src/syncrepl.c
@@ -125,7 +125,7 @@ barrier_decrement(isc_task_t *task, isc_event_t *event) {
 			log_debug(1, "sync_barrier_wait(): barrier reached");
 			bev->sctx->state = sync_finished;
 			isc_condition_broadcast(&bev->sctx->cond);
-			publish_zones(inst);
+			activate_zones(inst);
 		}
 		UNLOCK(&bev->sctx->mutex);
 	}
diff --git a/src/types.h b/src/types.h
index c5053924be48385f4ac01f0ec95fc12cac49a128..1ca1411d1d29ce1e8475a3f9fa888519e08a730a 100644
--- a/src/types.h
+++ b/src/types.h
@@ -46,4 +46,7 @@ typedef struct enum_txt_assoc {
 	const char	*description;
 } enum_txt_assoc_t;
 
+typedef struct ldap_instance	ldap_instance_t;
+typedef struct zone_register	zone_register_t;
+
 #endif /* !_LD_TYPES_H_ */
diff --git a/src/zone_register.c b/src/zone_register.c
index a7d55c8d34bbef210c0ec676cd9a9635e8dfef71..f25c15b5d6581a7033345fb411a23f9c49937bcc 100644
--- a/src/zone_register.c
+++ b/src/zone_register.c
@@ -60,6 +60,7 @@ typedef struct {
 	dns_zone_t	*zone;
 	char		*dn;
 	settings_set_t	*settings;
+	dns_db_t	*ldapdb;
 } zone_info_t;
 
 /* Callback for dns_rbt_create(). */
@@ -231,12 +232,14 @@ cleanup:
 #define PRINT_BUFF_SIZE 255
 static isc_result_t ATTR_NONNULLS
 create_zone_info(isc_mem_t *mctx, dns_zone_t *zone, const char *dn,
-		settings_set_t *global_settings, zone_info_t **zinfop)
+		 settings_set_t *global_settings, const char *db_name,
+		 zone_info_t **zinfop)
 {
 	isc_result_t result;
 	zone_info_t *zinfo;
 	char settings_name[PRINT_BUFF_SIZE];
 	ld_string_t *zone_dir = NULL;
+	char *argv[1];
 
 	REQUIRE(zone != NULL);
 	REQUIRE(dn != NULL);
@@ -259,6 +262,11 @@ create_zone_info(isc_mem_t *mctx, dns_zone_t *zone, const char *dn,
 			       NULL, &zone_dir));
 	CHECK(fs_dir_create(str_buf(zone_dir)));
 
+	DE_CONST(db_name, argv[0]);
+	CHECK(ldapdb_create(mctx, dns_zone_getorigin(zone), LDAP_DB_TYPE,
+			    LDAP_DB_RDATACLASS, sizeof(argv)/sizeof(argv[0]),
+			    argv, NULL, &zinfo->ldapdb));
+
 cleanup:
 	if (result == ISC_R_SUCCESS)
 		*zinfop = zinfo;
@@ -285,6 +293,7 @@ delete_zone_info(void *arg1, void *arg2)
 	settings_set_free(&zinfo->settings);
 	isc_mem_free(mctx, zinfo->dn);
 	dns_zone_detach(&zinfo->zone);
+	dns_db_detach(&zinfo->ldapdb);
 	SAFE_MEM_PUT_PTR(mctx, zinfo);
 }
 
@@ -325,6 +334,7 @@ zr_add_zone(zone_register_t *zr, dns_zone_t *zone, const char *dn)
 	}
 
 	CHECK(create_zone_info(zr->mctx, zone, dn, zr->global_settings,
+			       ldap_instance_getdbname(zr->ldap_inst),
 			       &new_zinfo));
 	CHECK(dns_rbt_addname(zr->rbt, name, new_zinfo));
 
@@ -397,14 +407,13 @@ zr_get_zone_dbs(zone_register_t *zr, dns_name_t *name, dns_db_t **ldapdbp,
 	if (result == DNS_R_PARTIALMATCH)
 		result = ISC_R_SUCCESS;
 	if (result == ISC_R_SUCCESS) {
-		CHECK(dns_zone_getdb(((zone_info_t *)zinfo)->zone, &ldapdb));
+		dns_db_attach(((zone_info_t *)zinfo)->ldapdb, &ldapdb);
 		if (ldapdbp != NULL)
 			dns_db_attach(ldapdb, ldapdbp);
 		if (rbtdbp != NULL)
 			dns_db_attach(ldapdb_get_rbtdb(ldapdb), rbtdbp);
 	}
 
-cleanup:
 	RWUNLOCK(&zr->rwlock, isc_rwlocktype_read);
 	if (ldapdb)
 		dns_db_detach(&ldapdb);
diff --git a/src/zone_register.h b/src/zone_register.h
index 6ff184dc2935952f1d568d0694a6ebc874fda49e..21dc869b17d7779aa2e67796fb3c1a52490803a1 100644
--- a/src/zone_register.h
+++ b/src/zone_register.h
@@ -25,8 +25,6 @@
 #include "rbt_helper.h"
 #include "ldap_helper.h"
 
-typedef struct zone_register zone_register_t;
-
 isc_result_t
 zr_create(isc_mem_t *mctx, ldap_instance_t *ldap_inst,
 	  settings_set_t *glob_settings, zone_register_t **zrp) ATTR_NONNULLS;
-- 
1.8.3.1

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

Reply via email to