On 10/09/2012 03:49 PM, Petr Spacek wrote:
On 10/09/2012 01:21 PM, Adam Tkac wrote:
On Mon, Oct 08, 2012 at 04:46:54PM +0200, Petr Spacek wrote:
Hello,

     Use automatic connection management in LDAP modification code to
     prevent potential deadlock.

     Without this patch the plugin will deadlock when modify_ldap_common()
     is called with PTR synchronization enabled and only single
     connection is available in the connection pool.

Nack

If I read the patch correctly, it leaves unused ldap_conn parameters in
ldap_modify_do() and modify_soa_record() functions.

Those params are always NULL so they can be safely removed. Please also remove
the "autoconn" variable from ldap_modify_do()

My intent was to keep the same connection management abilities as are in
ldap_query(): You can avoid repetitive ldap_pool_get/putconnection() calls by
passing connection via parameter.

I can remove it if it isn't worth. (Actually *_modify_*() functions do not use
this capability now.)

I forgot to send the patch after our discussion on IRC. Attached patch removes unused parameters.

Petr^2 Spacek

From 7924717aab7d1dc343f21f6f459c1b4f21b373e1 Mon Sep 17 00:00:00 2001
From: Petr Spacek <pspa...@redhat.com>
Date: Mon, 8 Oct 2012 16:41:40 +0200
Subject: [PATCH] Use automatic connection management in LDAP modification
 code to prevent potential deadlock.

Without this patch the plugin will deadlock when modify_ldap_common()
is called with PTR synchronization enabled and only single
connection is available in the connection pool.

Signed-off-by: Petr Spacek <pspa...@redhat.com>
---
 src/ldap_helper.c | 34 ++++++++++++++--------------------
 1 file changed, 14 insertions(+), 20 deletions(-)

diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index f8df1b29871c28a1eeecfa93d5d91edd1aee3944..c91aea44aab845854818373b8b9dd91fb0e059c9 100644
--- a/src/ldap_helper.c
+++ b/src/ldap_helper.c
@@ -306,8 +306,7 @@ static void ldap_query_free(isc_boolean_t prepare_reuse, ldap_qresult_t **ldap_q
 
 /* Functions for writing to LDAP. */
 static isc_result_t ldap_modify_do(ldap_instance_t *ldap_inst,
-		ldap_connection_t *ldap_conn, const char *dn, LDAPMod **mods,
-		isc_boolean_t delete_node);
+		const char *dn, LDAPMod **mods,	isc_boolean_t delete_node);
 static isc_result_t ldap_rdttl_to_ldapmod(isc_mem_t *mctx,
 		dns_rdatalist_t *rdlist, LDAPMod **changep);
 static isc_result_t ldap_rdatalist_to_ldapmod(isc_mem_t *mctx,
@@ -2278,21 +2277,20 @@ reconnect:
 }
 
 static isc_result_t
-ldap_modify_do(ldap_instance_t *ldap_inst, ldap_connection_t *ldap_conn,
-		const char *dn, LDAPMod **mods, isc_boolean_t delete_node)
+ldap_modify_do(ldap_instance_t *ldap_inst, const char *dn, LDAPMod **mods,
+	       isc_boolean_t delete_node)
 {
 	int ret;
 	int err_code;
 	const char *operation_str;
 	isc_result_t result;
-	isc_boolean_t autoconn = (ldap_conn == NULL);
+	ldap_connection_t *ldap_conn = NULL;
 
 	REQUIRE(dn != NULL);
 	REQUIRE(mods != NULL);
 	REQUIRE(ldap_inst != NULL);
 
-	if (autoconn)
-		CHECK(ldap_pool_getconnection(ldap_inst->pool, &ldap_conn));
+	CHECK(ldap_pool_getconnection(ldap_inst->pool, &ldap_conn));
 
 	if (ldap_conn->handle == NULL) {
 		/*
@@ -2375,8 +2373,7 @@ ldap_modify_do(ldap_instance_t *ldap_inst, ldap_connection_t *ldap_conn,
 		result = ISC_R_FAILURE;
 	}
 cleanup:
-	if (autoconn)
-		ldap_pool_putconnection(ldap_inst->pool, &ldap_conn);
+	ldap_pool_putconnection(ldap_inst->pool, &ldap_conn);
 
 	return result;
 }
@@ -2544,8 +2541,8 @@ cleanup:
  * refresh, retry, expire and minimum attributes for each SOA record.
  */
 static isc_result_t
-modify_soa_record(ldap_instance_t *ldap_inst, ldap_connection_t *ldap_conn,
-		const char *zone_dn, dns_rdata_t *rdata)
+modify_soa_record(ldap_instance_t *ldap_inst, const char *zone_dn,
+		  dns_rdata_t *rdata)
 {
 	isc_result_t result;
 	dns_rdata_soa_t soa;
@@ -2578,7 +2575,7 @@ modify_soa_record(ldap_instance_t *ldap_inst, ldap_connection_t *ldap_conn,
 
 	dns_rdata_freestruct((void *)&soa);
 
-	result = ldap_modify_do(ldap_inst, ldap_conn, zone_dn, changep, ISC_FALSE);
+	result = ldap_modify_do(ldap_inst, zone_dn, changep, ISC_FALSE);
 
 cleanup:
 	return result;
@@ -2593,7 +2590,6 @@ modify_ldap_common(dns_name_t *owner, ldap_instance_t *ldap_inst,
 {
 	isc_result_t result;
 	isc_mem_t *mctx = ldap_inst->mctx;
-	ldap_connection_t *ldap_conn = NULL;
 	ld_string_t *owner_dn = NULL;
 	LDAPMod *change[3] = { NULL };
 	LDAPMod *change_ptr = NULL;
@@ -2630,8 +2626,6 @@ modify_ldap_common(dns_name_t *owner, ldap_instance_t *ldap_inst,
 
 	CHECK(dn_to_dnsname(mctx, zone_dn, &zone_name, NULL));
 
-	CHECK(ldap_pool_getconnection(ldap_inst->pool, &ldap_conn));
-
 	result = zr_get_zone_settings(ldap_inst->zone_register, &zone_name,
 				      &zone_settings);
 	if (result != ISC_R_SUCCESS) {
@@ -2655,7 +2649,7 @@ modify_ldap_common(dns_name_t *owner, ldap_instance_t *ldap_inst,
 	CHECK(discard_from_cache(cache, owner));
 
 	if (rdlist->type == dns_rdatatype_soa) {
-		result = modify_soa_record(ldap_inst, ldap_conn, str_buf(owner_dn),
+		result = modify_soa_record(ldap_inst, str_buf(owner_dn),
 					   HEAD(rdlist->rdata));
 		goto cleanup;
 	}
@@ -2666,7 +2660,7 @@ modify_ldap_common(dns_name_t *owner, ldap_instance_t *ldap_inst,
 		CHECK(ldap_rdttl_to_ldapmod(mctx, rdlist, &change[1]));
 	}
 	
-	CHECK(ldap_modify_do(ldap_inst, ldap_conn, str_buf(owner_dn), change, delete_node));
+	CHECK(ldap_modify_do(ldap_inst, str_buf(owner_dn), change, delete_node));
 
 	/* Keep the PTR of corresponding A/AAAA record synchronized. */
 	if (rdlist->type == dns_rdatatype_a || rdlist->type == dns_rdatatype_aaaa) {
@@ -2824,13 +2818,13 @@ modify_ldap_common(dns_name_t *owner, ldap_instance_t *ldap_inst,
 		change_ptr = NULL;
 
 		/* Modify PTR record. */
-		CHECK(ldap_modify_do(ldap_inst, ldap_conn, str_buf(owner_dn_ptr), change, delete_node));
+		CHECK(ldap_modify_do(ldap_inst, str_buf(owner_dn_ptr),
+				     change, delete_node));
 		(void) discard_from_cache(ldap_instance_getcache(ldap_inst),
 					  dns_fixedname_name(&ptr_name));
 	}
 	
 cleanup:
-	ldap_pool_putconnection(ldap_inst->pool, &ldap_conn);
 	str_destroy(&owner_dn_ptr);
 	str_destroy(&owner_dn);
 	str_destroy(&str_ptr);
@@ -3111,7 +3105,7 @@ soa_serial_increment(isc_mem_t *mctx, ldap_instance_t *inst,
 	dns_soa_setserial(new_serial, soa_rdata);
 
 	/* write the new serial back to DB */
-	CHECK(modify_soa_record(inst, NULL, str_buf(zone_dn), soa_rdata));
+	CHECK(modify_soa_record(inst, str_buf(zone_dn), soa_rdata));
 	CHECK(discard_from_cache(ldap_instance_getcache(inst), zone_name));
 
 	/* put the new SOA to inst->cache and compare old and new serials */
-- 
1.7.11.4

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

Reply via email to