Hello,

Add basic support for inline-signing.

Inline-signing is enabled for zones with idnsSecInlineSigning attribute = TRUE.

Limitations:
- Signing configuration is hardcoded in create_zone() as magic constants
- idnsSecInlineSigning attribute cannot be changed at run-time
- DNS updates are not supported
- Signing keys have to be pre-generated and stored in
  <dyndb-ldap working directory>/<ldap intance name>/<zone name>/keys
  directory before named is started

https://fedorahosted.org/bind-dyndb-ldap/ticket/56

--
Petr^2 Spacek
From 8d9542dd2efc45e98aacbdd9c6432627caa6d6fc Mon Sep 17 00:00:00 2001
From: Petr Spacek <[email protected]>
Date: Fri, 18 Apr 2014 14:43:04 +0200
Subject: [PATCH] Separate raw and secure zones in Zone Register.

https://fedorahosted.org/bind-dyndb-ldap/ticket/56

Signed-off-by: Petr Spacek <[email protected]>
---
 src/ldap_helper.c   | 67 ++++++++++++++++++++++++++++++++------------------
 src/zone_register.c | 70 ++++++++++++++++++++++++++++++++++-------------------
 src/zone_register.h |  7 ++++--
 3 files changed, 93 insertions(+), 51 deletions(-)

diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index a3eadaa022942fb81fde9b2f6a54b811a0d33e1f..f40d7e78dbd122c5499f5995713721793f481b07 100644
--- a/src/ldap_helper.c
+++ b/src/ldap_helper.c
@@ -815,15 +815,18 @@ static isc_result_t ATTR_CHECKRESULT
 cleanup_files(ldap_instance_t *inst) {
 	isc_result_t result;
 	rbt_iterator_t *iter = NULL;
-	dns_zone_t *zone = NULL;
+	dns_zone_t *raw = NULL;
+	dns_zone_t *secure = NULL;
 	DECLARE_BUFFERED_NAME(name);
 
 	INIT_BUFFERED_NAME(name);
 	CHECK(zr_rbt_iter_init(inst->zone_register, &iter, &name));
 	do {
-		CHECK(zr_get_zone_ptr(inst->zone_register, &name, &zone));
-		cleanup_zone_files(zone);
-		dns_zone_detach(&zone);
+		CHECK(zr_get_zone_ptr(inst->zone_register, &name, &raw, &secure));
+		cleanup_zone_files(raw);
+		cleanup_zone_files(secure);
+		dns_zone_detach(&raw);
+		dns_zone_detach(&secure);
 
 		INIT_BUFFERED_NAME(name);
 		CHECK(rbt_iter_next(&iter, &name));
@@ -1022,36 +1025,43 @@ activate_zones(isc_task_t *task, ldap_instance_t *inst) {
 	isc_result_t result;
 	isc_boolean_t loaded;
 	rbt_iterator_t *iter = NULL;
-	dns_zone_t *zone = NULL;
+	dns_zone_t *raw = NULL;
+	dns_zone_t *secure = NULL;
+	dns_zone_t *toview = NULL;
 	DECLARE_BUFFERED_NAME(name);
 	unsigned int published_cnt = 0;
 	unsigned int total_cnt = 0;
 
 	INIT_BUFFERED_NAME(name);
 	CHECK(zr_rbt_iter_init(inst->zone_register, &iter, &name));
 	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);
+		CHECK(zr_get_zone_ptr(inst->zone_register, &name, &raw, &secure));
+		/* Load only "secure" zone if inline-signing is active.
+		 * It will not work if raw zone is loaded explicitly. */
+		toview = (secure != NULL) ? secure : raw;
+		result = load_zone(toview);
 		loaded = (result == ISC_R_SUCCESS);
 		if (loaded == ISC_FALSE)
-			dns_zone_log(zone, ISC_LOG_ERROR,
+			dns_zone_log(raw, ISC_LOG_ERROR,
 				     "unable to load zone: %s",
 				     dns_result_totext(result));
 
-		result = publish_zone(task, inst, zone);
+		/*
+		 * Don't bother if load fails, server will return
+		 * SERVFAIL for queries beneath this zone. This is
+		 * admin's problem.
+		 */
+		result = publish_zone(task, inst, toview);
 		if (result != ISC_R_SUCCESS)
-			dns_zone_log(zone, ISC_LOG_ERROR,
+			dns_zone_log(toview, ISC_LOG_ERROR,
 				     "cannot add zone to view: %s",
 				     dns_result_totext(result));
 		else if (loaded == ISC_TRUE)
 			++published_cnt;
-		dns_zone_detach(&zone);
+		dns_zone_detach(&raw);
+		if (secure != NULL)
+			dns_zone_detach(&secure);
 
 		INIT_BUFFERED_NAME(name);
 		CHECK(rbt_iter_next(&iter, &name));
@@ -1170,7 +1180,8 @@ ldap_delete_zone2(ldap_instance_t *inst, dns_name_t *name, isc_boolean_t lock,
 	isc_result_t isforward = ISC_R_NOTFOUND;
 	isc_boolean_t unlock = ISC_FALSE;
 	isc_boolean_t freeze = ISC_FALSE;
-	dns_zone_t *zone = NULL;
+	dns_zone_t *raw = NULL;
+	dns_zone_t *secure = NULL;
 	dns_zone_t *foundzone = NULL;
 	char zone_name_char[DNS_NAME_FORMATSIZE];
 
@@ -1192,7 +1203,7 @@ ldap_delete_zone2(ldap_instance_t *inst, dns_name_t *name, isc_boolean_t lock,
 			CHECK(fwdr_del_zone(inst->fwd_register, name));
 	}
 
-	result = zr_get_zone_ptr(inst->zone_register, name, &zone);
+	result = zr_get_zone_ptr(inst->zone_register, name, &raw, &secure);
 	if (result == ISC_R_NOTFOUND || result == DNS_R_PARTIALMATCH) {
 		if (isforward == ISC_R_SUCCESS)
 			log_info("forward zone '%s': shutting down", zone_name_char);
@@ -1205,16 +1216,21 @@ ldap_delete_zone2(ldap_instance_t *inst, dns_name_t *name, isc_boolean_t lock,
 	result = dns_view_findzone(inst->view, name, &foundzone);
 	if (result == ISC_R_SUCCESS) {
 		/* foundzone != zone indicates a bug */
-		RUNTIME_CHECK(foundzone == zone);
+		if (secure != NULL)
+			RUNTIME_CHECK(foundzone == secure);
+		else
+			RUNTIME_CHECK(foundzone == raw);
 		dns_zone_detach(&foundzone);
 
 		if (lock) {
 			dns_view_thaw(inst->view);
 			freeze = ISC_TRUE;
 		}
 	} /* else: zone wasn't in a view */
 
-	CHECK(delete_bind_zone(inst->view->zonetable, &zone));
+	if (secure != NULL)
+		CHECK(delete_bind_zone(inst->view->zonetable, &secure));
+	CHECK(delete_bind_zone(inst->view->zonetable, &raw));
 	CHECK(zr_del_zone(inst->zone_register, name));
 
 cleanup:
@@ -2023,6 +2039,7 @@ ldap_parse_master_zoneentry(ldap_entry_t *entry, ldap_instance_t *inst,
 	const char *dn;
 	dns_name_t name;
 	dns_zone_t *raw = NULL;
+	dns_zone_t *secure = NULL;
 	isc_result_t result;
 	isc_boolean_t unlock = ISC_FALSE;
 	isc_boolean_t new_zone = ISC_FALSE;
@@ -2075,11 +2092,11 @@ ldap_parse_master_zoneentry(ldap_entry_t *entry, ldap_instance_t *inst,
 	 * Load the zone. */
 
 	/* Check if we are already serving given zone */
-	result = zr_get_zone_ptr(inst->zone_register, &name, &raw);
+	result = zr_get_zone_ptr(inst->zone_register, &name, &raw, &secure);
 	if (result == ISC_R_NOTFOUND || result == DNS_R_PARTIALMATCH) {
 		CHECK(create_zone(inst, &name, &raw));
 		CHECK(configure_paths(inst->mctx, inst, raw, ISC_FALSE));
-		CHECK(zr_add_zone(inst->zone_register, raw, dn));
+		CHECK(zr_add_zone(inst->zone_register, raw, secure, dn));
 		new_zone = ISC_TRUE;
 		log_debug(2, "created zone %p: %s", raw, dn);
 	} else if (result != ISC_R_SUCCESS)
@@ -2157,6 +2174,8 @@ cleanup:
 		dns_name_free(&name, inst->mctx);
 	if (raw != NULL)
 		dns_zone_detach(&raw);
+	if (secure != NULL)
+		dns_zone_detach(&secure);
 
 	return result;
 }
@@ -4106,7 +4125,7 @@ update_record(isc_task_t *task, isc_event_t *event)
 
 	CHECK(manager_get_ldap_instance(pevent->dbname, &inst));
 	CHECK(dn_to_dnsname(mctx, pevent->dn, &name, &origin));
-	CHECK(zr_get_zone_ptr(inst->zone_register, &origin, &zone_ptr));
+	CHECK(zr_get_zone_ptr(inst->zone_register, &origin, &zone_ptr, NULL));
 	zone_found = ISC_TRUE;
 
 update_restart:
@@ -4412,7 +4431,7 @@ syncrepl_update(ldap_instance_t *inst, ldap_entry_t *entry, int chgtype)
 
 	if (class == LDAP_ENTRYCLASS_MASTER || class == LDAP_ENTRYCLASS_RR) {
 		result = zr_get_zone_ptr(inst->zone_register, &zone_name,
-					 &zone_ptr);
+					 &zone_ptr, NULL);
 		if (result == ISC_R_SUCCESS && dns_zone_getmgr(zone_ptr) != NULL)
 			dns_zone_gettask(zone_ptr, &task);
 		else {
diff --git a/src/zone_register.c b/src/zone_register.c
index e84664b3b5ea3a9306a592e82fa53f3dbc097de4..9e799f5ca276fc890084212f50827e879cb75914 100644
--- a/src/zone_register.c
+++ b/src/zone_register.c
@@ -57,7 +57,8 @@ struct zone_register {
 };
 
 typedef struct {
-	dns_zone_t	*zone;
+	dns_zone_t	*raw;
+	dns_zone_t	*secure;
 	char		*dn;
 	settings_set_t	*settings;
 	dns_db_t	*ldapdb;
@@ -226,44 +227,48 @@ cleanup:
 	return result;
 }
 
-/*
+/**
  * Create a new zone info structure.
  */
 #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,
+create_zone_info(isc_mem_t * const mctx, dns_zone_t * const raw,
+		dns_zone_t * const secure, const char * const dn,
 		 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(raw != NULL);
 	REQUIRE(dn != NULL);
 	REQUIRE(zinfop != NULL && *zinfop == NULL);
 
 	CHECKED_MEM_GET_PTR(mctx, zinfo);
 	ZERO_PTR(zinfo);
 	CHECKED_MEM_STRDUP(mctx, dn, zinfo->dn);
-	dns_zone_attach(zone, &zinfo->zone);
+	dns_zone_attach(raw, &zinfo->raw);
+	if (secure != NULL)
+		dns_zone_attach(secure, &zinfo->secure);
+
 	zinfo->settings = NULL;
 	isc_string_printf_truncate(settings_name, PRINT_BUFF_SIZE,
 				   SETTING_SET_NAME_ZONE " %s",
 				   dn);
 	CHECK(settings_set_create(mctx, zone_settings, sizeof(zone_settings),
 				  settings_name, global_settings,
 				  &zinfo->settings));
 
-	/* Prepare a directory for this zone */
-	CHECK(zr_get_zone_path(mctx, global_settings, dns_zone_getorigin(zone),
+	/* Prepare a directory for this maybesecure */
+	CHECK(zr_get_zone_path(mctx, global_settings, dns_zone_getorigin(raw),
 			       "keys/", &zone_dir));
 	CHECK(fs_dirs_create(str_buf(zone_dir)));
 
 	DE_CONST(db_name, argv[0]);
-	CHECK(ldapdb_create(mctx, dns_zone_getorigin(zone), LDAP_DB_TYPE,
+	CHECK(ldapdb_create(mctx, dns_zone_getorigin(raw), LDAP_DB_TYPE,
 			    LDAP_DB_RDATACLASS, sizeof(argv)/sizeof(argv[0]),
 			    argv, NULL, &zinfo->ldapdb));
 
@@ -293,8 +298,10 @@ delete_zone_info(void *arg1, void *arg2)
 	settings_set_free(&zinfo->settings);
 	if (zinfo->dn != NULL)
 		isc_mem_free(mctx, zinfo->dn);
-	if (zinfo->zone != NULL)
-		dns_zone_detach(&zinfo->zone);
+	if (zinfo->raw != NULL)
+		dns_zone_detach(&zinfo->raw);
+	if (zinfo->secure != NULL)
+		dns_zone_detach(&zinfo->secure);
 	if (zinfo->ldapdb != NULL)
 		dns_db_detach(&zinfo->ldapdb);
 	SAFE_MEM_PUT_PTR(mctx, zinfo);
@@ -305,18 +312,19 @@ delete_zone_info(void *arg1, void *arg2)
  * must be absolute and the zone cannot already be in the zone register.
  */
 isc_result_t
-zr_add_zone(zone_register_t *zr, dns_zone_t *zone, const char *dn)
+zr_add_zone(zone_register_t * const zr, dns_zone_t * const raw,
+	    dns_zone_t * const secure, const char * const dn)
 {
 	isc_result_t result;
 	dns_name_t *name;
 	zone_info_t *new_zinfo = NULL;
 	void *dummy = NULL;
 
 	REQUIRE(zr != NULL);
-	REQUIRE(zone != NULL);
+	REQUIRE(raw != NULL);
 	REQUIRE(dn != NULL);
 
-	name = dns_zone_getorigin(zone);
+	name = dns_zone_getorigin(raw);
 	if (!dns_name_isabsolute(name)) {
 		log_bug("zone with bad origin");
 		return ISC_R_FAILURE;
@@ -336,7 +344,7 @@ zr_add_zone(zone_register_t *zr, dns_zone_t *zone, const char *dn)
 		goto cleanup;
 	}
 
-	CHECK(create_zone_info(zr->mctx, zone, dn, zr->global_settings,
+	CHECK(create_zone_info(zr->mctx, raw, secure, dn, zr->global_settings,
 			       ldap_instance_getdbname(zr->ldap_inst),
 			       &new_zinfo));
 	CHECK(dns_rbt_addname(zr->rbt, name, new_zinfo));
@@ -462,32 +470,44 @@ zr_get_zone_dn(zone_register_t *zr, dns_name_t *name, const char **dn,
 	return result;
 }
 
-/*
- * Find a zone with origin 'name' within in the zone register 'zr'. If an
- * exact match is found, the pointer to the zone is returned through 'zonep'.
- * Note that the function will attach the zone pointer and therefore the
- * caller has to detach it after use.
+/**
+ * Get zone pointers from zone register.
+ *
+ * @param[in]  name    Zone origin
+ * @param[out] rawp    Raw zone
+ * @param[out] securep Secure zone
+ *
+ * @pre At least one of rawp/securep has to be non-NULL.
+ *
+ * @remark Caller has to detach zone pointer after use.
  */
 isc_result_t
-zr_get_zone_ptr(zone_register_t *zr, dns_name_t *name, dns_zone_t **zonep)
+zr_get_zone_ptr(zone_register_t * const zr, dns_name_t * const name,
+		dns_zone_t ** const rawp, dns_zone_t ** const securep)
 {
 	isc_result_t result;
-	void *zinfo = NULL;
+	zone_info_t *zinfo = NULL;
 
 	REQUIRE(zr != NULL);
 	REQUIRE(name != NULL);
-	REQUIRE(zonep != NULL && *zonep == NULL);
+	REQUIRE(rawp != NULL || securep != NULL);
+	REQUIRE(rawp == NULL || *rawp == NULL);
+	REQUIRE(securep == NULL || *securep == NULL);
 
 	if (!dns_name_isabsolute(name)) {
 		log_bug("trying to find zone with a relative name");
 		return ISC_R_FAILURE;
 	}
 
 	RWLOCK(&zr->rwlock, isc_rwlocktype_read);
 
-	result = dns_rbt_findname(zr->rbt, name, 0, NULL, &zinfo);
-	if (result == ISC_R_SUCCESS)
-		dns_zone_attach(((zone_info_t *)zinfo)->zone, zonep);
+	result = dns_rbt_findname(zr->rbt, name, 0, NULL, (void *)&zinfo);
+	if (result == ISC_R_SUCCESS) {
+		if (rawp != NULL)
+			dns_zone_attach(zinfo->raw, rawp);
+		if (zinfo->secure != NULL && securep != NULL)
+			dns_zone_attach(zinfo->secure, securep);
+	}
 
 	RWUNLOCK(&zr->rwlock, isc_rwlocktype_read);
 
diff --git a/src/zone_register.h b/src/zone_register.h
index a8e37240fdf24693b6277c69762d181c194953ef..7f776358ca7bafa81ea1c2b3806fb428b7cac1ea 100644
--- a/src/zone_register.h
+++ b/src/zone_register.h
@@ -33,7 +33,8 @@ void
 zr_destroy(zone_register_t **zrp) ATTR_NONNULLS;
 
 isc_result_t
-zr_add_zone(zone_register_t *zr, dns_zone_t *zone, const char *dn) ATTR_NONNULLS ATTR_CHECKRESULT;
+zr_add_zone(zone_register_t * const zr, dns_zone_t * const raw,
+	    dns_zone_t * const secure, const char * const dn) ATTR_NONNULLS ATTR_CHECKRESULT;
 
 isc_result_t
 zr_del_zone(zone_register_t *zr, dns_name_t *origin) ATTR_NONNULLS ATTR_CHECKRESULT;
@@ -47,7 +48,9 @@ zr_get_zone_dn(zone_register_t *zr, dns_name_t *name, const char **dn,
 	       dns_name_t *matched_name) ATTR_NONNULLS ATTR_CHECKRESULT;
 
 isc_result_t
-zr_get_zone_ptr(zone_register_t *zr, dns_name_t *name, dns_zone_t **zonep) ATTR_NONNULLS ATTR_CHECKRESULT;
+zr_get_zone_ptr(zone_register_t * const zr, dns_name_t * const name,
+		dns_zone_t ** const rawp, dns_zone_t ** const securep)
+		ATTR_NONNULL(1,2,3) ATTR_CHECKRESULT;
 
 isc_result_t
 zr_get_zone_settings(zone_register_t *zr, dns_name_t *name, settings_set_t **set) ATTR_NONNULLS ATTR_CHECKRESULT;
-- 
1.9.0

From 70ff2597b9f977be5051761db6fbbe19aaae695c Mon Sep 17 00:00:00 2001
From: Petr Spacek <[email protected]>
Date: Fri, 18 Apr 2014 16:50:56 +0200
Subject: [PATCH] Add basic support for inline-signing.

Inline-signing is enabled for zones with idnsSecInlineSigning attribute = TRUE.

Limitations:
- Signing configuration is hardcoded in create_zone() as magic constants
- idnsSecInlineSigning attribute cannot be changed at run-time
- DNS updates are not supported
- Signing keys have to be pre-generated and stored in
  <dyndb-ldap working directory>/<ldap intance name>/<zone name>/keys
  directory before named is started

Signed-off-by: Petr Spacek <[email protected]>
---
 src/ldap_helper.c | 145 ++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 102 insertions(+), 43 deletions(-)

diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index f40d7e78dbd122c5499f5995713721793f481b07..b9afc792862ed6e14b29862ac4d527528aae8e87 100644
--- a/src/ldap_helper.c
+++ b/src/ldap_helper.c
@@ -874,54 +874,125 @@ cleanup:
 	return result;
 }
 
+static isc_result_t ATTR_NONNULLS ATTR_CHECKRESULT
+configure_paths(isc_mem_t *mctx, ldap_instance_t *inst, dns_zone_t *zone,
+		isc_boolean_t issecure) {
+	isc_result_t result;
+	ld_string_t *file_name = NULL;
+	ld_string_t *key_dir = NULL;
+
+	CHECK(zr_get_zone_path(mctx, ldap_instance_getsettings_local(inst),
+			       dns_zone_getorigin(zone),
+			       (issecure ? "signed" : "raw"), &file_name));
+	CHECK(dns_zone_setfile(zone, str_buf(file_name)));
+	if (issecure == ISC_TRUE) {
+		CHECK(zr_get_zone_path(mctx,
+				       ldap_instance_getsettings_local(inst),
+				       dns_zone_getorigin(zone), "keys/",
+				       &key_dir));
+		dns_zone_setkeydirectory(zone, str_buf(key_dir));
+	}
+	CHECK(fs_file_remove(dns_zone_getfile(zone)));
+	CHECK(fs_file_remove(dns_zone_getjournal(zone)));
+
+cleanup:
+	str_destroy(&file_name);
+	str_destroy(&key_dir);
+	return result;
+}
+
 /*
  * Create a new zone with origin 'name'. The zone will be added to the
  * ldap_inst->view.
  */
 static isc_result_t ATTR_NONNULLS ATTR_CHECKRESULT
-create_zone(ldap_instance_t *ldap_inst, dns_name_t *name, dns_zone_t **rawp)
+create_zone(ldap_instance_t * const inst, const char * const dn,
+	    dns_name_t * const name, const isc_boolean_t want_secure,
+	    dns_zone_t ** const rawp, dns_zone_t ** const securep)
 {
 	isc_result_t result;
 	dns_zone_t *raw = NULL;
-	const char *argv[2];
+	dns_zone_t *secure = NULL;
+	const char *ldap_argv[2];
+	const char *rbt_argv[1] = { "rbt" };
 	sync_state_t sync_state;
 	isc_task_t *task = NULL;
 	char zone_name[DNS_NAME_FORMATSIZE];
 
-	REQUIRE(ldap_inst != NULL);
+	REQUIRE(inst != NULL);
 	REQUIRE(name != NULL);
 	REQUIRE(rawp != NULL && *rawp == NULL);
 
-	argv[0] = ldapdb_impname;
-	argv[1] = ldap_inst->db_name;
+	ldap_argv[0] = ldapdb_impname;
+	ldap_argv[1] = inst->db_name;
 
-	result = zone_unload_ifempty(ldap_inst->view, name);
+	result = zone_unload_ifempty(inst->view, name);
 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
 		goto cleanup;
 
-	CHECK(dns_zone_create(&raw, ldap_inst->mctx));
+	CHECK(dns_zone_create(&raw, inst->mctx));
 	CHECK(dns_zone_setorigin(raw, name));
 	dns_zone_setclass(raw, dns_rdataclass_in);
 	dns_zone_settype(raw, dns_zone_master);
-	CHECK(dns_zone_setdbtype(raw, 2, argv));
-	CHECK(dns_zonemgr_managezone(ldap_inst->zmgr, raw));
-	sync_state_get(ldap_inst->sctx, &sync_state);
+	/* dns_zone_setview(raw, view); */
+	CHECK(dns_zone_setdbtype(raw, 2, ldap_argv));
+	CHECK(configure_paths(inst->mctx, inst, raw, ISC_FALSE));
+
+	if (want_secure == ISC_FALSE) {
+		CHECK(dns_zonemgr_managezone(inst->zmgr, raw));
+	} else {
+		CHECK(dns_zone_create(&secure, inst->mctx));
+		CHECK(dns_zone_setorigin(secure, name));
+		dns_zone_setclass(secure, dns_rdataclass_in);
+		dns_zone_settype(secure, dns_zone_master);
+		/* dns_zone_setview(secure, view); */
+		CHECK(dns_zone_setdbtype(secure, 1, rbt_argv));
+		CHECK(dns_zonemgr_managezone(inst->zmgr, secure));
+		CHECK(dns_zone_link(secure, raw));
+
+		/* Magic constants are taken from zoneconf.c */
+		dns_zone_setsigvalidityinterval(secure, 2592000); /* sig-validity-interval */
+		dns_zone_setsigresigninginterval(secure, 648000); /* re-sign */
+		dns_zone_setsignatures(secure, 10); /* sig-signing-signatures */
+		dns_zone_setnodes(secure, 10); /* sig-signing-nodes */
+		dns_zone_setprivatetype(secure, 65534); /* sig-signing-type */
+		dns_zone_setoption(secure, DNS_ZONEOPT_UPDATECHECKKSK,
+				   ISC_TRUE); /* update-check-ksk */
+		dns_zone_setrefreshkeyinterval(secure, 60); /* dnssec-loadkeys-interval */
+		/* auto-dnssec = maintain */
+		dns_zone_setkeyopt(secure, DNS_ZONEKEY_ALLOW, ISC_TRUE);
+		dns_zone_setkeyopt(secure, DNS_ZONEKEY_MAINTAIN, ISC_TRUE);
+
+		dns_zone_rekey(secure, ISC_TRUE);
+		CHECK(configure_paths(inst->mctx, inst, secure, ISC_TRUE));
+	}
+
+	sync_state_get(inst->sctx, &sync_state);
 	if (sync_state == sync_init) {
 		dns_zone_gettask(raw, &task);
-		CHECK(sync_task_add(ldap_inst->sctx, task));
+		CHECK(sync_task_add(inst->sctx, task));
 		isc_task_detach(&task);
+
+		if (secure != NULL) {
+			dns_zone_gettask(secure, &task);
+			CHECK(sync_task_add(inst->sctx, task));
+			isc_task_detach(&task);
+		}
 	}
 
+	CHECK(zr_add_zone(inst->zone_register, raw, secure, dn));
+
 	*rawp = raw;
+	*securep = secure;
 	return ISC_R_SUCCESS;
 
 cleanup:
 	dns_name_format(name, zone_name, DNS_NAME_FORMATSIZE);
 	log_error_r("failed to create new zone '%s'", zone_name);
 
 	if (raw != NULL) {
 		if (dns_zone_getmgr(raw) != NULL)
-			dns_zonemgr_releasezone(ldap_inst->zmgr, raw);
+			dns_zonemgr_releasezone(inst->zmgr, raw);
 		dns_zone_detach(&raw);
 	}
 	if (task != NULL)
@@ -1653,33 +1724,6 @@ cleanup:
 	return result;
 }
 
-static isc_result_t ATTR_NONNULLS ATTR_CHECKRESULT
-configure_paths(isc_mem_t *mctx, ldap_instance_t *inst, dns_zone_t *zone,
-		isc_boolean_t issecure) {
-	isc_result_t result;
-	ld_string_t *file_name = NULL;
-	ld_string_t *key_dir = NULL;
-
-	CHECK(zr_get_zone_path(mctx, ldap_instance_getsettings_local(inst),
-			       dns_zone_getorigin(zone),
-			       (issecure ? "signed" : "raw"), &file_name));
-	CHECK(dns_zone_setfile(zone, str_buf(file_name)));
-	if (issecure == ISC_TRUE) {
-		CHECK(zr_get_zone_path(mctx,
-				       ldap_instance_getsettings_local(inst),
-				       dns_zone_getorigin(zone), "keys/",
-				       &key_dir));
-		dns_zone_setkeydirectory(zone, str_buf(key_dir));
-	}
-	CHECK(fs_file_remove(dns_zone_getfile(zone)));
-	CHECK(fs_file_remove(dns_zone_getjournal(zone)));
-
-cleanup:
-	str_destroy(&file_name);
-	str_destroy(&key_dir);
-	return result;
-}
-
 /**
  * Process strictly minimal diff and detect if data were changed
  * and return latest SOA RR.
@@ -2037,12 +2081,14 @@ ldap_parse_master_zoneentry(ldap_entry_t *entry, ldap_instance_t *inst,
 			    isc_task_t *task)
 {
 	const char *dn;
+	ldap_valuelist_t values;
 	dns_name_t name;
 	dns_zone_t *raw = NULL;
 	dns_zone_t *secure = NULL;
 	isc_result_t result;
 	isc_boolean_t unlock = ISC_FALSE;
 	isc_boolean_t new_zone = ISC_FALSE;
+	isc_boolean_t want_secure = ISC_FALSE;
 	settings_set_t *zone_settings = NULL;
 	isc_boolean_t ldap_writeback;
 	isc_boolean_t data_changed;
@@ -2091,16 +2137,29 @@ ldap_parse_master_zoneentry(ldap_entry_t *entry, ldap_instance_t *inst,
 	/* No forwarders are used. Zone was removed from fwdtable.
 	 * Load the zone. */
 
+	result = ldap_entry_getvalues(entry, "idnsSecInlineSigning", &values);
+	if (result == ISC_R_NOTFOUND || HEAD(values) == NULL)
+		want_secure = ISC_FALSE;
+	else
+		want_secure = ISC_TF(strcasecmp(HEAD(values)->value, "TRUE")
+				     == 0);
+
 	/* Check if we are already serving given zone */
 	result = zr_get_zone_ptr(inst->zone_register, &name, &raw, &secure);
 	if (result == ISC_R_NOTFOUND || result == DNS_R_PARTIALMATCH) {
-		CHECK(create_zone(inst, &name, &raw));
-		CHECK(configure_paths(inst->mctx, inst, raw, ISC_FALSE));
-		CHECK(zr_add_zone(inst->zone_register, raw, secure, dn));
+		CHECK(create_zone(inst, dn, &name, want_secure, &raw, &secure));
 		new_zone = ISC_TRUE;
-		log_debug(2, "created zone %p: %s", raw, dn);
+		log_debug(2, "created zone %s: raw %p; secure %p", dn, raw,
+			  secure);
 	} else if (result != ISC_R_SUCCESS)
 		goto cleanup;
+	else {
+		if (want_secure != ISC_TF(secure != NULL)) {
+			log_error("zone '%s': inline-signing setting cannot "
+				  "be changed at run-time yet", dn);
+			CLEANUP_WITH(ISC_R_NOTIMPLEMENTED);
+		}
+	}
 
 	CHECK(zr_get_zone_settings(inst->zone_register, &name, &zone_settings));
 	CHECK(zone_master_reconfigure(entry, zone_settings, raw, task));
-- 
1.9.0

_______________________________________________
Freeipa-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to