Hello,

Make ldap_parse_rrentry() idempotent.

Now, a call to ldap_parse_rrentry() resets the internal entry
interators in ldap_entry_t so the results are always correct.

Without this patch, a second call returned empty ldapdb_rdatalist_t
because all iterators were at the end of internal lists.

This patch should go to branches v3 and master.

--
Petr^2 Spacek

From f1f1a8c9273ec9bf2f921e7ab534e0104bb84734 Mon Sep 17 00:00:00 2001
From: Petr Spacek <pspa...@redhat.com>
Date: Thu, 12 Dec 2013 10:01:34 +0100
Subject: [PATCH] Make ldap_parse_rrentry() idempotent.

Now, a call to ldap_parse_rrentry() resets the internal entry
interators in ldap_entry_t so the results are always correct.

Without this patch, a second call returned empty ldapdb_rdatalist_t
because all iterators were at the end of internal lists.

Signed-off-by: Petr Spacek <pspa...@redhat.com>
---
 src/ldap_entry.c  | 34 +++++++++++++++++++++++++++++-----
 src/ldap_entry.h  |  9 ++++++++-
 src/ldap_helper.c | 12 +++++++++---
 3 files changed, 46 insertions(+), 9 deletions(-)

diff --git a/src/ldap_entry.c b/src/ldap_entry.c
index c91eb4bacd4c2261e46337ce4e2f310e900bbc5e..2c3d4cf119ad6207401191cbf9fe8bfce263ac1b 100644
--- a/src/ldap_entry.c
+++ b/src/ldap_entry.c
@@ -321,6 +321,16 @@ ldap_entry_nextattr(ldap_entry_t *entry)
 }
 
 isc_result_t
+ldap_entry_firstrdtype(ldap_entry_t *entry, ldap_attribute_t **attrp,
+		       dns_rdatatype_t *rdtype)
+{
+	REQUIRE(entry != NULL);
+
+	entry->lastattr = NULL;
+	return ldap_entry_nextrdtype(entry, attrp, rdtype);
+}
+
+isc_result_t
 ldap_entry_nextrdtype(ldap_entry_t *entry, ldap_attribute_t **attrp,
 		      dns_rdatatype_t *rdtype)
 {
@@ -338,8 +348,10 @@ ldap_entry_nextrdtype(ldap_entry_t *entry, ldap_attribute_t **attrp,
 
 	if (result == ISC_R_SUCCESS)
 		*attrp = attr;
-	else if (result == ISC_R_NOTFOUND)
+	else {
+		result = ISC_R_NOMORE;
 		*attrp = NULL;
+	}
 
 	return result;
 }
@@ -455,9 +467,20 @@ ldap_entry_getclass(ldap_entry_t *entry, ldap_entryclass_t *class)
 #endif
 }
 
-ld_string_t*
+isc_result_t
+ldap_attr_firstvalue(ldap_attribute_t *attr, ld_string_t *str)
+{
+	REQUIRE(attr != NULL);
+	REQUIRE(str != NULL);
+
+	attr->lastval = NULL;
+	return ldap_attr_nextvalue(attr, str);
+}
+
+isc_result_t
 ldap_attr_nextvalue(ldap_attribute_t *attr, ld_string_t *str)
 {
+	isc_result_t result;
 	ldap_value_t *value;
 
 	REQUIRE(attr != NULL);
@@ -473,11 +496,12 @@ ldap_attr_nextvalue(ldap_attribute_t *attr, ld_string_t *str)
 	if (value != NULL)
 		attr->lastval = value;
 	else
-		return NULL;
+		return ISC_R_NOMORE;
 
-	str_init_char(str, value->value);
+	CHECK(str_init_char(str, value->value));
 
-	return str;
+cleanup:
+	return result;
 }
 
 #define DEFAULT_TTL 86400
diff --git a/src/ldap_entry.h b/src/ldap_entry.h
index 3279c2c50f3323633688221a1076bd2e796c72a9..2ea5f89cd3938da61aedfe4b5682762cd87a41f9 100644
--- a/src/ldap_entry.h
+++ b/src/ldap_entry.h
@@ -115,6 +115,10 @@ ldap_attribute_t*
 ldap_entry_nextattr(ldap_entry_t *entry) ATTR_NONNULLS;
 
 isc_result_t
+ldap_entry_firstrdtype(ldap_entry_t *entry, ldap_attribute_t **attrp,
+		       dns_rdatatype_t *rdtype);
+
+isc_result_t
 ldap_entry_nextrdtype(ldap_entry_t *entry, ldap_attribute_t **attrp,
 		      dns_rdatatype_t *rdtype) ATTR_NONNULLS;
 
@@ -131,13 +135,16 @@ ldap_entry_getfakesoa(ldap_entry_t *entry, const char *fake_mname,
 isc_result_t
 ldap_entry_getclass(ldap_entry_t *entry, ldap_entryclass_t *class) ATTR_NONNULLS;
 
+isc_result_t
+ldap_attr_firstvalue(ldap_attribute_t *attr, ld_string_t *str) ATTR_NONNULLS;
+
 /*
  * ldap_attr_nextvalue
  *
  * Returns pointer to value in case of success, NULL if no other val is
  * available
  */
-ld_string_t*
+isc_result_t
 ldap_attr_nextvalue(ldap_attribute_t *attr, ld_string_t *value) ATTR_NONNULLS;
 
 dns_ttl_t
diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index c107b06b3c628d35666c0d4f8f0019064aa7cc85..55cadbf0cff4efad33fb900f51583313563aeb92 100644
--- a/src/ldap_helper.c
+++ b/src/ldap_helper.c
@@ -1668,23 +1668,29 @@ ldap_parse_rrentry(isc_mem_t *mctx, ldap_entry_t *entry, dns_name_t *origin,
 	rdclass = ldap_entry_getrdclass(entry);
 	ttl = ldap_entry_getttl(entry);
 
-	for (result = ldap_entry_nextrdtype(entry, &attr, &rdtype);
+	for (result = ldap_entry_firstrdtype(entry, &attr, &rdtype);
 	     result == ISC_R_SUCCESS;
 	     result = ldap_entry_nextrdtype(entry, &attr, &rdtype)) {
 
 		CHECK(findrdatatype_or_create(mctx, rdatalist, rdclass,
 					      rdtype, ttl, &rdlist));
-		while (ldap_attr_nextvalue(attr, data_buf) != NULL) {
+		for (result = ldap_attr_firstvalue(attr, data_buf);
+		     result == ISC_R_SUCCESS;
+		     result = ldap_attr_nextvalue(attr, data_buf)) {
 			CHECK(parse_rdata(mctx, entry, rdclass,
 					  rdtype, origin,
 					  str_buf(data_buf), &rdata));
 			APPEND(rdlist->rdata, rdata, link);
 			rdata = NULL;
 		}
+		if (result != ISC_R_NOMORE)
+			goto cleanup;
 		rdlist = NULL;
 	}
-	str_destroy(&data_buf);
+	if (result != ISC_R_NOMORE)
+		goto cleanup;
 
+	str_destroy(&data_buf);
 	return ISC_R_SUCCESS;
 
 cleanup:
-- 
1.8.3.1

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

Reply via email to