Adam Tkac 8b8546b
From f0d49c0eb816c958e4fa6bf4a073eb6ac592efad Mon Sep 17 00:00:00 2001
Adam Tkac 8b8546b
From: Adam Tkac <atkac@redhat.com>
Adam Tkac 8b8546b
Date: Thu, 26 Apr 2012 13:48:21 +0200
Adam Tkac 8b8546b
Subject: [PATCH 1/5] Link ldap.so with relro, now and noexecstack linker
Adam Tkac 8b8546b
 parameters.
Adam Tkac 8b8546b
Adam Tkac 8b8546b
Signed-off-by: Adam Tkac <atkac@redhat.com>
Adam Tkac 8b8546b
---
Adam Tkac 8b8546b
 src/Makefile.am |    2 +-
Adam Tkac 8b8546b
 1 file changed, 1 insertion(+), 1 deletion(-)
Adam Tkac 8b8546b
Adam Tkac 8b8546b
diff --git a/src/Makefile.am b/src/Makefile.am
Adam Tkac 8b8546b
index 84c774b..b7b4240 100644
Adam Tkac 8b8546b
--- a/src/Makefile.am
Adam Tkac 8b8546b
+++ b/src/Makefile.am
Adam Tkac 8b8546b
@@ -38,4 +38,4 @@ ldap_la_SOURCES =		\
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 ldap_la_CFLAGS = -Wall -Wextra -std=gnu99 -O2
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
-ldap_la_LDFLAGS = -module -avoid-version
Adam Tkac 8b8546b
+ldap_la_LDFLAGS = -module -avoid-version -Wl,-z,relro,-z,now,-z,noexecstack
Adam Tkac 8b8546b
-- 
Adam Tkac 8b8546b
1.7.10.2
Adam Tkac 8b8546b
Adam Tkac 8b8546b
Adam Tkac 8b8546b
From 481e350f5848cf01da6743f259a6f12419fc4177 Mon Sep 17 00:00:00 2001
Adam Tkac 8b8546b
From: Petr Spacek <pspacek@redhat.com>
Adam Tkac 8b8546b
Date: Tue, 24 Apr 2012 15:09:32 +0200
Adam Tkac 8b8546b
Subject: [PATCH 2/5] Add simple semaphore deadlock detection logic.
Adam Tkac 8b8546b
 Signed-off-by: Petr Spacek <pspacek@redhat.com>
Adam Tkac 8b8546b
Adam Tkac 8b8546b
---
Adam Tkac 8b8546b
 src/ldap_helper.c |   78 ++++++++++++++++++++++++++++++++---------------------
Adam Tkac 8b8546b
 src/semaphore.c   |   26 +++++++++++++++---
Adam Tkac 8b8546b
 src/semaphore.h   |    6 ++++-
Adam Tkac 8b8546b
 3 files changed, 74 insertions(+), 36 deletions(-)
Adam Tkac 8b8546b
Adam Tkac 8b8546b
diff --git a/src/ldap_helper.c b/src/ldap_helper.c
Adam Tkac 8b8546b
index 6ebe4c0..5965d30 100644
Adam Tkac 8b8546b
--- a/src/ldap_helper.c
Adam Tkac 8b8546b
+++ b/src/ldap_helper.c
Adam Tkac 8b8546b
@@ -295,9 +295,10 @@ ldap_delete_zone2(ldap_instance_t *inst, dns_name_t *name, isc_boolean_t lock);
Adam Tkac 8b8546b
 static isc_result_t ldap_pool_create(isc_mem_t *mctx, unsigned int connections,
Adam Tkac 8b8546b
 		ldap_pool_t **poolp);
Adam Tkac 8b8546b
 static void ldap_pool_destroy(ldap_pool_t **poolp);
Adam Tkac 8b8546b
-static ldap_connection_t * ldap_pool_getconnection(ldap_pool_t *pool);
Adam Tkac 8b8546b
+static isc_result_t ldap_pool_getconnection(ldap_pool_t *pool,
Adam Tkac 8b8546b
+		ldap_connection_t ** conn);
Adam Tkac 8b8546b
 static void ldap_pool_putconnection(ldap_pool_t *pool,
Adam Tkac 8b8546b
-		ldap_connection_t *ldap_conn);
Adam Tkac 8b8546b
+		ldap_connection_t ** conn);
Adam Tkac 8b8546b
 static isc_result_t ldap_pool_connect(ldap_pool_t *pool,
Adam Tkac 8b8546b
 		ldap_instance_t *ldap_inst);
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
@@ -401,6 +402,10 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
Adam Tkac 8b8546b
 	ldap_settings[i++].target = &ldap_inst->dyn_update;
Adam Tkac 8b8546b
 	CHECK(set_settings(ldap_settings, argv));
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
+	/* Set timer for deadlock detection inside semaphore_wait_timed . */
Adam Tkac 8b8546b
+	if (semaphore_wait_timeout.seconds < ldap_inst->timeout*SEM_WAIT_TIMEOUT_MUL)
Adam Tkac 8b8546b
+		semaphore_wait_timeout.seconds = ldap_inst->timeout*SEM_WAIT_TIMEOUT_MUL;
Adam Tkac 8b8546b
+
Adam Tkac 8b8546b
 	/* Validate and check settings. */
Adam Tkac 8b8546b
 	str_toupper(ldap_inst->sasl_mech);
Adam Tkac 8b8546b
 	if (ldap_inst->connections < 1) {
Adam Tkac 8b8546b
@@ -1088,7 +1093,7 @@ isc_result_t
Adam Tkac 8b8546b
 refresh_zones_from_ldap(ldap_instance_t *ldap_inst)
Adam Tkac 8b8546b
 {
Adam Tkac 8b8546b
 	isc_result_t result = ISC_R_SUCCESS;
Adam Tkac 8b8546b
-	ldap_connection_t *ldap_conn;
Adam Tkac 8b8546b
+	ldap_connection_t *ldap_conn = NULL;
Adam Tkac 8b8546b
 	int zone_count = 0;
Adam Tkac 8b8546b
 	ldap_entry_t *entry;
Adam Tkac 8b8546b
 	dns_rbt_t *rbt = NULL;
Adam Tkac 8b8546b
@@ -1113,7 +1118,7 @@ refresh_zones_from_ldap(ldap_instance_t *ldap_inst)
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	log_debug(2, "refreshing list of zones for %s", ldap_inst->db_name);
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
-	ldap_conn = ldap_pool_getconnection(ldap_inst->pool);
Adam Tkac 8b8546b
+	CHECK(ldap_pool_getconnection(ldap_inst->pool, &ldap_conn));
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	CHECK(ldap_query(ldap_inst, ldap_conn, str_buf(ldap_inst->base),
Adam Tkac 8b8546b
 			 LDAP_SCOPE_SUBTREE, config_attrs, 0,
Adam Tkac 8b8546b
@@ -1226,7 +1231,7 @@ cleanup:
Adam Tkac 8b8546b
 	if (invalidate_nodechain)
Adam Tkac 8b8546b
 		dns_rbtnodechain_invalidate(&chain);
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
-	ldap_pool_putconnection(ldap_inst->pool, ldap_conn);
Adam Tkac 8b8546b
+	ldap_pool_putconnection(ldap_inst->pool, &ldap_conn);
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	log_debug(2, "finished refreshing list of zones");
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
@@ -1380,7 +1385,7 @@ ldapdb_nodelist_get(isc_mem_t *mctx, ldap_instance_t *ldap_inst, dns_name_t *nam
Adam Tkac 8b8546b
 		     dns_name_t *origin, ldapdb_nodelist_t *nodelist)
Adam Tkac 8b8546b
 {
Adam Tkac 8b8546b
 	isc_result_t result;
Adam Tkac 8b8546b
-	ldap_connection_t *ldap_conn;
Adam Tkac 8b8546b
+	ldap_connection_t *ldap_conn = NULL;
Adam Tkac 8b8546b
 	ldap_entry_t *entry;
Adam Tkac 8b8546b
 	ld_string_t *string = NULL;
Adam Tkac 8b8546b
 	ldapdb_node_t *node;
Adam Tkac 8b8546b
@@ -1391,7 +1396,7 @@ ldapdb_nodelist_get(isc_mem_t *mctx, ldap_instance_t *ldap_inst, dns_name_t *nam
Adam Tkac 8b8546b
 	REQUIRE(nodelist != NULL);
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	/* RRs aren't in the cache, perform ordinary LDAP query */
Adam Tkac 8b8546b
-	ldap_conn = ldap_pool_getconnection(ldap_inst->pool);
Adam Tkac 8b8546b
+	CHECK(ldap_pool_getconnection(ldap_inst->pool, &ldap_conn));
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	INIT_LIST(*nodelist);
Adam Tkac 8b8546b
 	CHECK(str_new(mctx, &string));
Adam Tkac 8b8546b
@@ -1438,7 +1443,7 @@ ldapdb_nodelist_get(isc_mem_t *mctx, ldap_instance_t *ldap_inst, dns_name_t *nam
Adam Tkac 8b8546b
 	result = ISC_R_SUCCESS;
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 cleanup:
Adam Tkac 8b8546b
-	ldap_pool_putconnection(ldap_inst->pool, ldap_conn);
Adam Tkac 8b8546b
+	ldap_pool_putconnection(ldap_inst->pool, &ldap_conn);
Adam Tkac 8b8546b
 	str_destroy(&string);
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	return result;
Adam Tkac 8b8546b
@@ -1449,7 +1454,7 @@ ldapdb_rdatalist_get(isc_mem_t *mctx, ldap_instance_t *ldap_inst, dns_name_t *na
Adam Tkac 8b8546b
 		     dns_name_t *origin, ldapdb_rdatalist_t *rdatalist)
Adam Tkac 8b8546b
 {
Adam Tkac 8b8546b
 	isc_result_t result;
Adam Tkac 8b8546b
-	ldap_connection_t *ldap_conn;
Adam Tkac 8b8546b
+	ldap_connection_t *ldap_conn = NULL;
Adam Tkac 8b8546b
 	ldap_entry_t *entry;
Adam Tkac 8b8546b
 	ld_string_t *string = NULL;
Adam Tkac 8b8546b
 	ldap_cache_t *cache;
Adam Tkac 8b8546b
@@ -1467,12 +1472,11 @@ ldapdb_rdatalist_get(isc_mem_t *mctx, ldap_instance_t *ldap_inst, dns_name_t *na
Adam Tkac 8b8546b
 		return result;
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	/* RRs aren't in the cache, perform ordinary LDAP query */
Adam Tkac 8b8546b
-	ldap_conn = ldap_pool_getconnection(ldap_inst->pool);
Adam Tkac 8b8546b
-
Adam Tkac 8b8546b
 	INIT_LIST(*rdatalist);
Adam Tkac 8b8546b
 	CHECK(str_new(mctx, &string));
Adam Tkac 8b8546b
 	CHECK(dnsname_to_dn(ldap_inst->zone_register, name, string));
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
+	CHECK(ldap_pool_getconnection(ldap_inst->pool, &ldap_conn));
Adam Tkac 8b8546b
 	CHECK(ldap_query(ldap_inst, ldap_conn, str_buf(string),
Adam Tkac 8b8546b
 			 LDAP_SCOPE_BASE, NULL, 0, "(objectClass=idnsRecord)"));
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
@@ -1499,7 +1503,7 @@ ldapdb_rdatalist_get(isc_mem_t *mctx, ldap_instance_t *ldap_inst, dns_name_t *na
Adam Tkac 8b8546b
 		result = ISC_R_NOTFOUND;
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 cleanup:
Adam Tkac 8b8546b
-	ldap_pool_putconnection(ldap_inst->pool, ldap_conn);
Adam Tkac 8b8546b
+	ldap_pool_putconnection(ldap_inst->pool, &ldap_conn);
Adam Tkac 8b8546b
 	str_destroy(&string);
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	if (result != ISC_R_SUCCESS)
Adam Tkac 8b8546b
@@ -2258,7 +2262,7 @@ modify_ldap_common(dns_name_t *owner, ldap_instance_t *ldap_inst,
Adam Tkac 8b8546b
 		zone_dn += 1; /* skip whitespace */
Adam Tkac 8b8546b
 	}
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
-	ldap_conn = ldap_pool_getconnection(ldap_inst->pool);
Adam Tkac 8b8546b
+	CHECK(ldap_pool_getconnection(ldap_inst->pool, &ldap_conn));
Adam Tkac 8b8546b
 	CHECK(ldap_query(ldap_inst, ldap_conn, zone_dn,
Adam Tkac 8b8546b
 					 LDAP_SCOPE_BASE, attrs, 0,
Adam Tkac 8b8546b
 					 "(&(objectClass=idnsZone)(idnsZoneActive=TRUE))"));
Adam Tkac 8b8546b
@@ -2489,9 +2493,7 @@ modify_ldap_common(dns_name_t *owner, ldap_instance_t *ldap_inst,
Adam Tkac 8b8546b
 	}
Adam Tkac 8b8546b
 	
Adam Tkac 8b8546b
 cleanup:
Adam Tkac 8b8546b
-	if (ldap_conn != NULL)
Adam Tkac 8b8546b
-		ldap_pool_putconnection(ldap_inst->pool, ldap_conn);
Adam Tkac 8b8546b
-
Adam Tkac 8b8546b
+	ldap_pool_putconnection(ldap_inst->pool, &ldap_conn);
Adam Tkac 8b8546b
 	str_destroy(&owner_dn_ptr);
Adam Tkac 8b8546b
 	str_destroy(&owner_dn);
Adam Tkac 8b8546b
 	free_ldapmod(mctx, &change[0]);
Adam Tkac 8b8546b
@@ -2573,15 +2575,18 @@ ldap_pool_destroy(ldap_pool_t **poolp)
Adam Tkac 8b8546b
 	MEM_PUT_AND_DETACH(pool);
Adam Tkac 8b8546b
 }
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
-static ldap_connection_t *
Adam Tkac 8b8546b
-ldap_pool_getconnection(ldap_pool_t *pool)
Adam Tkac 8b8546b
+static isc_result_t
Adam Tkac 8b8546b
+ldap_pool_getconnection(ldap_pool_t *pool, ldap_connection_t ** conn)
Adam Tkac 8b8546b
 {
Adam Tkac 8b8546b
 	ldap_connection_t *ldap_conn = NULL;
Adam Tkac 8b8546b
 	unsigned int i;
Adam Tkac 8b8546b
+	isc_result_t result;
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	REQUIRE(pool != NULL);
Adam Tkac 8b8546b
+	REQUIRE(conn != NULL && *conn == NULL);
Adam Tkac 8b8546b
+	ldap_conn = *conn;
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
-	semaphore_wait(&pool->conn_semaphore);
Adam Tkac 8b8546b
+	CHECK(semaphore_wait_timed(&pool->conn_semaphore));
Adam Tkac 8b8546b
 	for (i = 0; i < pool->connections; i++) {
Adam Tkac 8b8546b
 		ldap_conn = pool->conns[i];
Adam Tkac 8b8546b
 		if (isc_mutex_trylock(&ldap_conn->lock) == ISC_R_SUCCESS)
Adam Tkac 8b8546b
@@ -2591,16 +2596,30 @@ ldap_pool_getconnection(ldap_pool_t *pool)
Adam Tkac 8b8546b
 	RUNTIME_CHECK(ldap_conn != NULL);
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	INIT_LIST(ldap_conn->ldap_entries);
Adam Tkac 8b8546b
+	*conn = ldap_conn;
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
-	return ldap_conn;
Adam Tkac 8b8546b
+cleanup:
Adam Tkac 8b8546b
+	if (result != ISC_R_SUCCESS) {
Adam Tkac 8b8546b
+		log_error("timeout in ldap_pool_getconnection(): try to raise "
Adam Tkac 8b8546b
+				"'connections' parameter; potential deadlock?");
Adam Tkac 8b8546b
+	}
Adam Tkac 8b8546b
+	return result;
Adam Tkac 8b8546b
 }
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 static void
Adam Tkac 8b8546b
-ldap_pool_putconnection(ldap_pool_t *pool, ldap_connection_t *ldap_conn)
Adam Tkac 8b8546b
+ldap_pool_putconnection(ldap_pool_t *pool, ldap_connection_t **conn)
Adam Tkac 8b8546b
 {
Adam Tkac 8b8546b
+	REQUIRE(conn != NULL);
Adam Tkac 8b8546b
+	ldap_connection_t *ldap_conn = *conn;
Adam Tkac 8b8546b
+
Adam Tkac 8b8546b
+	if (ldap_conn == NULL)
Adam Tkac 8b8546b
+		return;
Adam Tkac 8b8546b
+
Adam Tkac 8b8546b
 	ldap_query_free(ldap_conn);
Adam Tkac 8b8546b
 	UNLOCK(&ldap_conn->lock);
Adam Tkac 8b8546b
 	semaphore_signal(&pool->conn_semaphore);
Adam Tkac 8b8546b
+
Adam Tkac 8b8546b
+	*conn = NULL;
Adam Tkac 8b8546b
 }
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 static isc_result_t
Adam Tkac 8b8546b
@@ -2727,7 +2746,7 @@ update_action(isc_task_t *task, isc_event_t *event)
Adam Tkac 8b8546b
 	ldap_psearchevent_t *pevent = (ldap_psearchevent_t *)event;
Adam Tkac 8b8546b
 	isc_result_t result ;
Adam Tkac 8b8546b
 	ldap_instance_t *inst = NULL;
Adam Tkac 8b8546b
-	ldap_connection_t *conn;
Adam Tkac 8b8546b
+	ldap_connection_t *conn = NULL;
Adam Tkac 8b8546b
 	ldap_entry_t *entry;
Adam Tkac 8b8546b
 	isc_boolean_t delete = ISC_TRUE;
Adam Tkac 8b8546b
 	isc_mem_t *mctx;
Adam Tkac 8b8546b
@@ -2744,7 +2763,7 @@ update_action(isc_task_t *task, isc_event_t *event)
Adam Tkac 8b8546b
 	if (result != ISC_R_SUCCESS)
Adam Tkac 8b8546b
 		goto cleanup;
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
-	conn = ldap_pool_getconnection(inst->pool);
Adam Tkac 8b8546b
+	CHECK(ldap_pool_getconnection(inst->pool, &conn));
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	CHECK(ldap_query(inst, conn, pevent->dn,
Adam Tkac 8b8546b
 			 LDAP_SCOPE_BASE, attrs, 0,
Adam Tkac 8b8546b
@@ -2762,14 +2781,13 @@ update_action(isc_task_t *task, isc_event_t *event)
Adam Tkac 8b8546b
 	if (delete)
Adam Tkac 8b8546b
 		CHECK(ldap_delete_zone(inst, pevent->dn, ISC_TRUE));
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
-        ldap_pool_putconnection(inst->pool, conn);
Adam Tkac 8b8546b
-
Adam Tkac 8b8546b
 cleanup:
Adam Tkac 8b8546b
 	if (result != ISC_R_SUCCESS)
Adam Tkac 8b8546b
 		log_error("update_action (psearch) failed for %s. "
Adam Tkac 8b8546b
 			  "Zones can be outdated, run `rndc reload`",
Adam Tkac 8b8546b
 			  pevent->dn);
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
+	ldap_pool_putconnection(inst->pool, &conn;;
Adam Tkac 8b8546b
 	isc_mem_free(mctx, pevent->dbname);
Adam Tkac 8b8546b
 	isc_mem_free(mctx, pevent->dn);
Adam Tkac 8b8546b
 	isc_mem_detach(&mctx);
Adam Tkac 8b8546b
@@ -2798,7 +2816,7 @@ update_config(isc_task_t *task, isc_event_t *event)
Adam Tkac 8b8546b
 	if (result != ISC_R_SUCCESS)
Adam Tkac 8b8546b
 		goto cleanup;
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
-	conn = ldap_pool_getconnection(inst->pool);
Adam Tkac 8b8546b
+	CHECK(ldap_pool_getconnection(inst->pool, &conn));
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	CHECK(ldap_query(inst, conn, pevent->dn,
Adam Tkac 8b8546b
 			 LDAP_SCOPE_BASE, attrs, 0,
Adam Tkac 8b8546b
@@ -2817,14 +2835,12 @@ update_config(isc_task_t *task, isc_event_t *event)
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 cleanup:
Adam Tkac 8b8546b
-	if (conn != NULL)
Adam Tkac 8b8546b
-		ldap_pool_putconnection(inst->pool, conn);
Adam Tkac 8b8546b
-
Adam Tkac 8b8546b
 	if (result != ISC_R_SUCCESS)
Adam Tkac 8b8546b
 		log_error("update_config (psearch) failed for %s. "
Adam Tkac 8b8546b
 			  "Configuration can be outdated, run `rndc reload`",
Adam Tkac 8b8546b
 			  pevent->dn);
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
+	ldap_pool_putconnection(inst->pool, &conn;;
Adam Tkac 8b8546b
 	isc_mem_free(mctx, pevent->dbname);
Adam Tkac 8b8546b
 	isc_mem_free(mctx, pevent->dn);
Adam Tkac 8b8546b
 	isc_mem_detach(&mctx);
Adam Tkac 8b8546b
@@ -3087,7 +3103,7 @@ ldap_psearch_watcher(isc_threadarg_t arg)
Adam Tkac 8b8546b
 	tv.tv_usec = 0;
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	/* Pick connection, one is reserved purely for this thread */
Adam Tkac 8b8546b
-	conn = ldap_pool_getconnection(inst->pool);
Adam Tkac 8b8546b
+	CHECK(ldap_pool_getconnection(inst->pool, &conn));
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	/* Try to connect. */
Adam Tkac 8b8546b
 	while (conn->handle == NULL) {
Adam Tkac 8b8546b
@@ -3195,7 +3211,7 @@ soft_err:
Adam Tkac 8b8546b
 	log_debug(1, "Ending ldap_psearch_watcher");
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 cleanup:
Adam Tkac 8b8546b
-	ldap_pool_putconnection(inst->pool, conn);
Adam Tkac 8b8546b
+	ldap_pool_putconnection(inst->pool, &conn;;
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	return (isc_threadresult_t)0;
Adam Tkac 8b8546b
 }
Adam Tkac 8b8546b
diff --git a/src/semaphore.c b/src/semaphore.c
Adam Tkac 8b8546b
index 41d6a30..352219f 100644
Adam Tkac 8b8546b
--- a/src/semaphore.c
Adam Tkac 8b8546b
+++ b/src/semaphore.c
Adam Tkac 8b8546b
@@ -27,8 +27,19 @@
Adam Tkac 8b8546b
 #include <isc/condition.h>
Adam Tkac 8b8546b
 #include <isc/result.h>
Adam Tkac 8b8546b
 #include <isc/util.h>
Adam Tkac 8b8546b
+#include <isc/time.h>
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 #include "semaphore.h"
Adam Tkac 8b8546b
+#include "util.h"
Adam Tkac 8b8546b
+
Adam Tkac 8b8546b
+/*
Adam Tkac 8b8546b
+ * Timer setting for deadlock detection. Format: seconds, nanoseconds.
Adam Tkac 8b8546b
+ * These values will be overwriten during initialization
Adam Tkac 8b8546b
+ * from set_settings() with max(setting+SEM_WAIT_TIMEOUT_ADD, curr_value).
Adam Tkac 8b8546b
+ *
Adam Tkac 8b8546b
+ * Initial value can be useful in early phases of initialization.
Adam Tkac 8b8546b
+ */
Adam Tkac 8b8546b
+isc_interval_t semaphore_wait_timeout = { 3, 0 };
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 /*
Adam Tkac 8b8546b
  * Initialize a semaphore.
Adam Tkac 8b8546b
@@ -74,20 +85,27 @@ semaphore_destroy(semaphore_t *sem)
Adam Tkac 8b8546b
 /*
Adam Tkac 8b8546b
  * Wait on semaphore. This operation will try to acquire a lock on the
Adam Tkac 8b8546b
  * semaphore. If the semaphore is already acquired as many times at it allows,
Adam Tkac 8b8546b
- * the function will block until someone releases the lock.
Adam Tkac 8b8546b
+ * the function will block until someone releases the lock OR timeout expire.
Adam Tkac 8b8546b
+ *
Adam Tkac 8b8546b
+ * @return ISC_R_SUCCESS or ISC_R_TIMEDOUT or other errors from ISC libs
Adam Tkac 8b8546b
  */
Adam Tkac 8b8546b
-void
Adam Tkac 8b8546b
-semaphore_wait(semaphore_t *sem)
Adam Tkac 8b8546b
+isc_result_t
Adam Tkac 8b8546b
+semaphore_wait_timed(semaphore_t *sem)
Adam Tkac 8b8546b
 {
Adam Tkac 8b8546b
+	isc_result_t result;
Adam Tkac 8b8546b
+	isc_time_t abs_timeout;
Adam Tkac 8b8546b
 	REQUIRE(sem != NULL);
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
+	CHECK(isc_time_nowplusinterval(&abs_timeout, &semaphore_wait_timeout));
Adam Tkac 8b8546b
 	LOCK(&sem->mutex);
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	while (sem->value <= 0)
Adam Tkac 8b8546b
-		WAIT(&sem->cond, &sem->mutex);
Adam Tkac 8b8546b
+		CHECK(WAITUNTIL(&sem->cond, &sem->mutex, &abs_timeout));
Adam Tkac 8b8546b
 	sem->value--;
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
+cleanup:
Adam Tkac 8b8546b
 	UNLOCK(&sem->mutex);
Adam Tkac 8b8546b
+	return result;
Adam Tkac 8b8546b
 }
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 /*
Adam Tkac 8b8546b
diff --git a/src/semaphore.h b/src/semaphore.h
Adam Tkac 8b8546b
index 4ca4f65..1367747 100644
Adam Tkac 8b8546b
--- a/src/semaphore.h
Adam Tkac 8b8546b
+++ b/src/semaphore.h
Adam Tkac 8b8546b
@@ -24,6 +24,10 @@
Adam Tkac 8b8546b
 #include <isc/condition.h>
Adam Tkac 8b8546b
 #include <isc/mutex.h>
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
+/* Multiplier for to user-defined connection parameter 'timeout'. */
Adam Tkac 8b8546b
+#define SEM_WAIT_TIMEOUT_MUL 6 /* times */
Adam Tkac 8b8546b
+extern isc_interval_t semaphore_wait_timeout;
Adam Tkac 8b8546b
+
Adam Tkac 8b8546b
 /*
Adam Tkac 8b8546b
  * Semaphore can be "acquired" multiple times. However, it has a maximum
Adam Tkac 8b8546b
  * number of times someone can acquire him. If a semaphore is already acquired
Adam Tkac 8b8546b
@@ -40,7 +44,7 @@ typedef struct semaphore	semaphore_t;
Adam Tkac 8b8546b
 /* Public functions. */
Adam Tkac 8b8546b
 isc_result_t	semaphore_init(semaphore_t *sem, int value);
Adam Tkac 8b8546b
 void		semaphore_destroy(semaphore_t *sem);
Adam Tkac 8b8546b
-void		semaphore_wait(semaphore_t *sem);
Adam Tkac 8b8546b
+isc_result_t	semaphore_wait_timed(semaphore_t *sem);
Adam Tkac 8b8546b
 void		semaphore_signal(semaphore_t *sem);
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 #endif /* !_LD_SEMAPHORE_H_ */
Adam Tkac 8b8546b
-- 
Adam Tkac 8b8546b
1.7.10.2
Adam Tkac 8b8546b
Adam Tkac 8b8546b
Adam Tkac 8b8546b
From 3d43fd66aa68ef275855391a94e47e9d2f30309d Mon Sep 17 00:00:00 2001
Adam Tkac 8b8546b
From: Petr Spacek <pspacek@redhat.com>
Adam Tkac 8b8546b
Date: Mon, 23 Apr 2012 11:38:43 +0200
Adam Tkac 8b8546b
Subject: [PATCH 3/5] Add proper DN escaping before LDAP library calls.
Adam Tkac 8b8546b
 Signed-off-by: Petr Spacek <pspacek@redhat.com>
Adam Tkac 8b8546b
Adam Tkac 8b8546b
---
Adam Tkac 8b8546b
 src/ldap_convert.c  |  105 ++++++++++++++++++++++++++++++++++++++++++++++++---
Adam Tkac 8b8546b
 src/zone_register.c |    7 ++++
Adam Tkac 8b8546b
 src/zone_register.h |    3 ++
Adam Tkac 8b8546b
 3 files changed, 110 insertions(+), 5 deletions(-)
Adam Tkac 8b8546b
Adam Tkac 8b8546b
diff --git a/src/ldap_convert.c b/src/ldap_convert.c
Adam Tkac 8b8546b
index 6405a98..6b4e321 100644
Adam Tkac 8b8546b
--- a/src/ldap_convert.c
Adam Tkac 8b8546b
+++ b/src/ldap_convert.c
Adam Tkac 8b8546b
@@ -21,6 +21,7 @@
Adam Tkac 8b8546b
 #include <isc/buffer.h>
Adam Tkac 8b8546b
 #include <isc/mem.h>
Adam Tkac 8b8546b
 #include <isc/util.h>
Adam Tkac 8b8546b
+#include <isc/string.h>
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 #include <dns/name.h>
Adam Tkac 8b8546b
 #include <dns/rdatatype.h>
Adam Tkac 8b8546b
@@ -32,6 +33,7 @@
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 #include <errno.h>
Adam Tkac 8b8546b
 #include <strings.h>
Adam Tkac 8b8546b
+#include <ctype.h>
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 #include "str.h"
Adam Tkac 8b8546b
 #include "ldap_convert.h"
Adam Tkac 8b8546b
@@ -189,6 +191,92 @@ cleanup:
Adam Tkac 8b8546b
 	return result;
Adam Tkac 8b8546b
 }
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
+/**
Adam Tkac 8b8546b
+ * Convert a string from DNS escaping to LDAP escaping.
Adam Tkac 8b8546b
+ * The Input string dns_str is expected to be the result of dns_name_tostring().
Adam Tkac 8b8546b
+ * The DNS label can contain any binary data as described in
Adam Tkac 8b8546b
+ * http://tools.ietf.org/html/rfc2181#section-11 .
Adam Tkac 8b8546b
+ *
Adam Tkac 8b8546b
+ * DNS escaping uses form   "\123" = ASCII value 123 (decimal)
Adam Tkac 8b8546b
+ * LDAP escaping users form "\7b"  = ASCII value 7b (hexadecimal)
Adam Tkac 8b8546b
+ *
Adam Tkac 8b8546b
+ * Input (DNS escaped) example  : _aaa,bbb\255\000ccc.555.ddd-eee
Adam Tkac 8b8546b
+ * Output (LDAP escaped) example: _aaa\2cbbb\ff\00ccc.555.ddd-eee
Adam Tkac 8b8546b
+ *
Adam Tkac 8b8546b
+ * The DNS to text functions from ISC libraries do not convert certain
Adam Tkac 8b8546b
+ * characters (e.g. ","). This function converts \123 form to \7b form in all
Adam Tkac 8b8546b
+ * cases. Other characters (not escaped by ISC libraries) will be additionally
Adam Tkac 8b8546b
+ * converted to the LDAP escape form.
Adam Tkac 8b8546b
+ * Input characters [a-zA-Z0-9._-] are left in raw ASCII form.
Adam Tkac 8b8546b
+ *
Adam Tkac 8b8546b
+ * If dns_str consists only of the characters in the [a-zA-Z0-9._-] set, it
Adam Tkac 8b8546b
+ * will be checked & copied to the output buffer, without any additional escaping.
Adam Tkac 8b8546b
+ */
Adam Tkac 8b8546b
+isc_result_t
Adam Tkac 8b8546b
+dns_to_ldap_dn_escape(isc_mem_t *mctx, const char const * dns_str, char ** ldap_name) {
Adam Tkac 8b8546b
+	isc_result_t result = ISC_R_FAILURE;
Adam Tkac 8b8546b
+	char * esc_name = NULL;
Adam Tkac 8b8546b
+	int idx_symb_first = -1; /* index of first "nice" printable symbol in dns_str */
Adam Tkac 8b8546b
+	int dns_idx = 0;
Adam Tkac 8b8546b
+	int esc_idx = 0;
Adam Tkac 8b8546b
+
Adam Tkac 8b8546b
+	REQUIRE(dns_str != NULL);
Adam Tkac 8b8546b
+	REQUIRE(ldap_name != NULL && *ldap_name == NULL);
Adam Tkac 8b8546b
+
Adam Tkac 8b8546b
+	int dns_str_len = strlen(dns_str);
Adam Tkac 8b8546b
+
Adam Tkac 8b8546b
+	/**
Adam Tkac 8b8546b
+	 * In worst case each symbol from DNS dns_str will be represented
Adam Tkac 8b8546b
+	 * as "\xy" in ldap_name. (xy are hexadecimal digits)
Adam Tkac 8b8546b
+	 */
Adam Tkac 8b8546b
+	CHECKED_MEM_ALLOCATE(mctx, *ldap_name, 3 * dns_str_len + 1);
Adam Tkac 8b8546b
+	esc_name = *ldap_name;
Adam Tkac 8b8546b
+
Adam Tkac 8b8546b
+	for (dns_idx = 0; dns_idx < dns_str_len; dns_idx++) {
Adam Tkac 8b8546b
+		if (isalnum(dns_str[dns_idx]) || dns_str[dns_idx] == '.'
Adam Tkac 8b8546b
+				|| dns_str[dns_idx] == '-' || dns_str[dns_idx] == '_' ) {
Adam Tkac 8b8546b
+			if (idx_symb_first == -1)
Adam Tkac 8b8546b
+				idx_symb_first = dns_idx;
Adam Tkac 8b8546b
+			continue;
Adam Tkac 8b8546b
+		} else { /* some not very nice symbols */
Adam Tkac 8b8546b
+			int ascii_val;
Adam Tkac 8b8546b
+			if (idx_symb_first != -1) { /* copy previous nice part */
Adam Tkac 8b8546b
+				int length_ok = dns_idx - idx_symb_first;
Adam Tkac 8b8546b
+				memcpy(esc_name + esc_idx, dns_str + idx_symb_first, length_ok);
Adam Tkac 8b8546b
+				esc_idx += length_ok;
Adam Tkac 8b8546b
+				idx_symb_first = -1;
Adam Tkac 8b8546b
+			}
Adam Tkac 8b8546b
+			if (dns_str[dns_idx] != '\\') { /* not nice raw value, e.g. ',' */
Adam Tkac 8b8546b
+				ascii_val = dns_str[dns_idx];
Adam Tkac 8b8546b
+			} else { /* not nice value in DNS \123 decimal format */
Adam Tkac 8b8546b
+				/* check if input length <= expected size */
Adam Tkac 8b8546b
+				REQUIRE (dns_str_len > dns_idx + 3); /* this problem should never happen */
Adam Tkac 8b8546b
+				ascii_val = 100 * (dns_str[dns_idx + 1] - '0')
Adam Tkac 8b8546b
+						+ 10 * (dns_str[dns_idx + 2] - '0')
Adam Tkac 8b8546b
+						+ (dns_str[dns_idx + 3] - '0');
Adam Tkac 8b8546b
+				dns_idx += 3;
Adam Tkac 8b8546b
+			}
Adam Tkac 8b8546b
+			/* LDAP uses \xy escaping. "xy" represent two hexadecimal digits.*/
Adam Tkac 8b8546b
+			/* TODO: optimize to bit mask & rotate & dec->hex table? */
Adam Tkac 8b8546b
+			CHECK(isc_string_printf(esc_name + esc_idx, 4, "\\%02x", ascii_val));
Adam Tkac 8b8546b
+			esc_idx += 3; /* isc_string_printf wrote 4 bytes including '\0' */
Adam Tkac 8b8546b
+		}
Adam Tkac 8b8546b
+	}
Adam Tkac 8b8546b
+	if (idx_symb_first != -1) { /* copy last nice part */
Adam Tkac 8b8546b
+		int length_ok = dns_idx - idx_symb_first;
Adam Tkac 8b8546b
+		memcpy(esc_name + esc_idx, dns_str + idx_symb_first, dns_idx - idx_symb_first);
Adam Tkac 8b8546b
+		esc_idx += length_ok;
Adam Tkac 8b8546b
+		idx_symb_first = -1;
Adam Tkac 8b8546b
+	}
Adam Tkac 8b8546b
+	esc_name[esc_idx] = '\0';
Adam Tkac 8b8546b
+	return ISC_R_SUCCESS;
Adam Tkac 8b8546b
+
Adam Tkac 8b8546b
+cleanup:
Adam Tkac 8b8546b
+	if (*ldap_name)
Adam Tkac 8b8546b
+		isc_mem_free(mctx, *ldap_name);
Adam Tkac 8b8546b
+	return result;
Adam Tkac 8b8546b
+}
Adam Tkac 8b8546b
+
Adam Tkac 8b8546b
 static isc_result_t
Adam Tkac 8b8546b
 explode_dn(const char *dn, char ***explodedp, int notypes)
Adam Tkac 8b8546b
 {
Adam Tkac 8b8546b
@@ -243,11 +331,15 @@ dnsname_to_dn(zone_register_t *zr, dns_name_t *name, ld_string_t *target)
Adam Tkac 8b8546b
 	isc_result_t result;
Adam Tkac 8b8546b
 	int label_count;
Adam Tkac 8b8546b
 	const char *zone_dn = NULL;
Adam Tkac 8b8546b
+	char *dns_str = NULL;
Adam Tkac 8b8546b
+	char *escaped_name = NULL;
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	REQUIRE(zr != NULL);
Adam Tkac 8b8546b
 	REQUIRE(name != NULL);
Adam Tkac 8b8546b
 	REQUIRE(target != NULL);
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
+	isc_mem_t * mctx = zr_get_mctx(zr);
Adam Tkac 8b8546b
+
Adam Tkac 8b8546b
 	/* Find the DN of the zone we belong to. */
Adam Tkac 8b8546b
 	{
Adam Tkac 8b8546b
 		DECLARE_BUFFERED_NAME(zone);
Adam Tkac 8b8546b
@@ -264,17 +356,15 @@ dnsname_to_dn(zone_register_t *zr, dns_name_t *name, ld_string_t *target)
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	str_clear(target);
Adam Tkac 8b8546b
 	if (label_count > 0) {
Adam Tkac 8b8546b
-		DECLARE_BUFFER(buffer, DNS_NAME_MAXTEXT);
Adam Tkac 8b8546b
 		dns_name_t labels;
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
-		INIT_BUFFER(buffer);
Adam Tkac 8b8546b
 		dns_name_init(&labels, NULL);
Adam Tkac 8b8546b
-
Adam Tkac 8b8546b
 		dns_name_getlabelsequence(name, 0, label_count, &labels);
Adam Tkac 8b8546b
-		CHECK(dns_name_totext(&labels, ISC_TRUE, &buffer));
Adam Tkac 8b8546b
+		CHECK(dns_name_tostring(&labels, &dns_str, mctx));
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
+		CHECK(dns_to_ldap_dn_escape(mctx, dns_str, &escaped_name));
Adam Tkac 8b8546b
 		CHECK(str_cat_char(target, "idnsName="));
Adam Tkac 8b8546b
-		CHECK(str_cat_isc_buffer(target, &buffer));
Adam Tkac 8b8546b
+		CHECK(str_cat_char(target, escaped_name));
Adam Tkac 8b8546b
 		/* 
Adam Tkac 8b8546b
 		 * Modification of following line can affect modify_ldap_common().
Adam Tkac 8b8546b
 		 * See line with: char *zone_dn = strstr(str_buf(owner_dn),", ") + 1;  
Adam Tkac 8b8546b
@@ -284,6 +374,10 @@ dnsname_to_dn(zone_register_t *zr, dns_name_t *name, ld_string_t *target)
Adam Tkac 8b8546b
 	CHECK(str_cat_char(target, zone_dn));
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 cleanup:
Adam Tkac 8b8546b
+	if (dns_str)
Adam Tkac 8b8546b
+		isc_mem_free(mctx, dns_str);
Adam Tkac 8b8546b
+	if (escaped_name)
Adam Tkac 8b8546b
+		isc_mem_free(mctx, escaped_name);
Adam Tkac 8b8546b
 	return result;
Adam Tkac 8b8546b
 }
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
@@ -328,3 +422,4 @@ rdatatype_to_ldap_attribute(dns_rdatatype_t rdtype, const char **target)
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	return ISC_R_SUCCESS;
Adam Tkac 8b8546b
 }
Adam Tkac 8b8546b
+
Adam Tkac 8b8546b
diff --git a/src/zone_register.c b/src/zone_register.c
Adam Tkac 8b8546b
index fc6dc07..81d208f 100644
Adam Tkac 8b8546b
--- a/src/zone_register.c
Adam Tkac 8b8546b
+++ b/src/zone_register.c
Adam Tkac 8b8546b
@@ -61,6 +61,13 @@ zr_get_rbt(zone_register_t *zr)
Adam Tkac 8b8546b
 	return zr->rbt;
Adam Tkac 8b8546b
 }
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
+isc_mem_t *
Adam Tkac 8b8546b
+zr_get_mctx(zone_register_t *zr) {
Adam Tkac 8b8546b
+	REQUIRE(zr);
Adam Tkac 8b8546b
+
Adam Tkac 8b8546b
+	return zr->mctx;
Adam Tkac 8b8546b
+}
Adam Tkac 8b8546b
+
Adam Tkac 8b8546b
 /*
Adam Tkac 8b8546b
  * Create a new zone register.
Adam Tkac 8b8546b
  */
Adam Tkac 8b8546b
diff --git a/src/zone_register.h b/src/zone_register.h
Adam Tkac 8b8546b
index e2408cb..fa8ef25 100644
Adam Tkac 8b8546b
--- a/src/zone_register.h
Adam Tkac 8b8546b
+++ b/src/zone_register.h
Adam Tkac 8b8546b
@@ -45,4 +45,7 @@ zr_get_zone_ptr(zone_register_t *zr, dns_name_t *name, dns_zone_t **zonep);
Adam Tkac 8b8546b
 dns_rbt_t *
Adam Tkac 8b8546b
 zr_get_rbt(zone_register_t *zr);
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
+isc_mem_t *
Adam Tkac 8b8546b
+zr_get_mctx(zone_register_t *zr);
Adam Tkac 8b8546b
+
Adam Tkac 8b8546b
 #endif /* !_LD_ZONE_REGISTER_H_ */
Adam Tkac 8b8546b
-- 
Adam Tkac 8b8546b
1.7.10.2
Adam Tkac 8b8546b
Adam Tkac 8b8546b
Adam Tkac 8b8546b
From 0744209bc4461bf2f4d83b0a8e3f7051132ddef3 Mon Sep 17 00:00:00 2001
Adam Tkac 8b8546b
From: Petr Spacek <pspacek@redhat.com>
Adam Tkac 8b8546b
Date: Thu, 7 Jun 2012 14:42:40 +0200
Adam Tkac 8b8546b
Subject: [PATCH 4/5] Fix crash during BIND reload with persistent search
Adam Tkac 8b8546b
 enabled.
Adam Tkac 8b8546b
 https://fedorahosted.org/bind-dyndb-ldap/ticket/78
Adam Tkac 8b8546b
 Signed-off-by: Petr Spacek <pspacek@redhat.com>
Adam Tkac 8b8546b
Adam Tkac 8b8546b
Signed-off-by: Adam Tkac <atkac@redhat.com>
Adam Tkac 8b8546b
---
Adam Tkac 8b8546b
 src/ldap_helper.c |    2 +-
Adam Tkac 8b8546b
 1 file changed, 1 insertion(+), 1 deletion(-)
Adam Tkac 8b8546b
Adam Tkac 8b8546b
diff --git a/src/ldap_helper.c b/src/ldap_helper.c
Adam Tkac 8b8546b
index 5965d30..dc4fdf5 100644
Adam Tkac 8b8546b
--- a/src/ldap_helper.c
Adam Tkac 8b8546b
+++ b/src/ldap_helper.c
Adam Tkac 8b8546b
@@ -3078,7 +3078,7 @@ static isc_threadresult_t
Adam Tkac 8b8546b
 ldap_psearch_watcher(isc_threadarg_t arg)
Adam Tkac 8b8546b
 {
Adam Tkac 8b8546b
 	ldap_instance_t *inst = (ldap_instance_t *)arg;
Adam Tkac 8b8546b
-	ldap_connection_t *conn;
Adam Tkac 8b8546b
+	ldap_connection_t *conn = NULL;
Adam Tkac 8b8546b
 	struct timeval tv;
Adam Tkac 8b8546b
 	int ret, cnt;
Adam Tkac 8b8546b
 	isc_result_t result;
Adam Tkac 8b8546b
-- 
Adam Tkac 8b8546b
1.7.10.2
Adam Tkac 8b8546b
Adam Tkac 8b8546b
Adam Tkac 8b8546b
From 0dccccec9cede75bd254f723bc9a49592c24a44b Mon Sep 17 00:00:00 2001
Adam Tkac 8b8546b
From: Petr Spacek <pspacek@redhat.com>
Adam Tkac 8b8546b
Date: Thu, 7 Jun 2012 15:27:27 +0200
Adam Tkac 8b8546b
Subject: [PATCH 5/5] Fix crash during zone unload when NS is not resolvable.
Adam Tkac 8b8546b
 https://fedorahosted.org/bind-dyndb-ldap/ticket/77
Adam Tkac 8b8546b
 Signed-off-by: Petr Spacek <pspacek@redhat.com>
Adam Tkac 8b8546b
Adam Tkac 8b8546b
Signed-off-by: Adam Tkac <atkac@redhat.com>
Adam Tkac 8b8546b
---
Adam Tkac 8b8546b
 src/ldap_helper.c |   11 +++++++++--
Adam Tkac 8b8546b
 1 file changed, 9 insertions(+), 2 deletions(-)
Adam Tkac 8b8546b
Adam Tkac 8b8546b
diff --git a/src/ldap_helper.c b/src/ldap_helper.c
Adam Tkac 8b8546b
index dc4fdf5..09c1f7d 100644
Adam Tkac 8b8546b
--- a/src/ldap_helper.c
Adam Tkac 8b8546b
+++ b/src/ldap_helper.c
Adam Tkac 8b8546b
@@ -30,6 +30,7 @@
Adam Tkac 8b8546b
 #include <dns/ttl.h>
Adam Tkac 8b8546b
 #include <dns/view.h>
Adam Tkac 8b8546b
 #include <dns/zone.h>
Adam Tkac 8b8546b
+#include <dns/db.h>
Adam Tkac 8b8546b
 #include <dns/zt.h>
Adam Tkac 8b8546b
 #include <dns/byaddr.h>
Adam Tkac 8b8546b
 #include <dns/forward.h>
Adam Tkac 8b8546b
@@ -788,7 +789,12 @@ ldap_delete_zone2(ldap_instance_t *inst, dns_name_t *name, isc_boolean_t lock)
Adam Tkac 8b8546b
 		freeze = ISC_TRUE;
Adam Tkac 8b8546b
 	}
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
-	dns_zone_unload(zone);
Adam Tkac 8b8546b
+	/* Do not unload partially loaded zones, they have incomplete structures. */
Adam Tkac 8b8546b
+	dns_db_t *dbp = NULL;
Adam Tkac 8b8546b
+	if (dns_zone_getdb(zone, &dbp) != DNS_R_NOTLOADED) {
Adam Tkac 8b8546b
+		dns_db_detach(&dbp;; /* dns_zone_getdb() attaches DB implicitly */
Adam Tkac 8b8546b
+		dns_zone_unload(zone);
Adam Tkac 8b8546b
+	}
Adam Tkac 8b8546b
 	CHECK(dns_zt_unmount(inst->view->zonetable, zone));
Adam Tkac 8b8546b
 	CHECK(zr_del_zone(inst->zone_register, name));
Adam Tkac 8b8546b
 	dns_zonemgr_releasezone(inst->zmgr, zone);
Adam Tkac 8b8546b
@@ -1013,7 +1019,7 @@ ldap_parse_zoneentry(ldap_entry_t *entry, ldap_instance_t *inst)
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	/* Check if we are already serving given zone */
Adam Tkac 8b8546b
 	result = zr_get_zone_ptr(inst->zone_register, &name, &zone);
Adam Tkac 8b8546b
-	if (result != ISC_R_SUCCESS) {
Adam Tkac 8b8546b
+	if (result != ISC_R_SUCCESS) { /* TODO: What about other errors? */
Adam Tkac 8b8546b
 		CHECK(create_zone(inst, &name, &zone));
Adam Tkac 8b8546b
 		CHECK(zr_add_zone(inst->zone_register, zone, dn));
Adam Tkac 8b8546b
 		publish = ISC_TRUE;
Adam Tkac 8b8546b
@@ -2760,6 +2766,7 @@ update_action(isc_task_t *task, isc_event_t *event)
Adam Tkac 8b8546b
 	mctx = pevent->mctx;
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
 	result = manager_get_ldap_instance(pevent->dbname, &inst);
Adam Tkac 8b8546b
+	/* TODO: Can it happen? */
Adam Tkac 8b8546b
 	if (result != ISC_R_SUCCESS)
Adam Tkac 8b8546b
 		goto cleanup;
Adam Tkac 8b8546b
 
Adam Tkac 8b8546b
-- 
Adam Tkac 8b8546b
1.7.10.2
Adam Tkac 8b8546b