Blob Blame History Raw
From 584f9ceeef131145feb32a741a8f5dbc04b9a2cd Mon Sep 17 00:00:00 2001
From: Petr Spacek <pspacek@redhat.com>
Date: Tue, 25 Nov 2014 18:05:13 +0100
Subject: [PATCH] Fix crash caused by interaction between forward and master
 zones.

LDAP modifications made to idnsName=sub, idnsName=example.com, cn=dns object
were incorrectly processed using update_zone() in cases where forward zone
sub.example.com. existed in LDAP as object idnsName=sub.example.com, cn=dns.

https://fedorahosted.org/bind-dyndb-ldap/ticket/145
---
 src/fwd_register.h |  3 +++
 src/ldap_entry.c   | 26 ++++++++++++++++++++++++++
 src/ldap_entry.h   |  7 +++++++
 src/ldap_helper.c  | 14 ++++----------
 4 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/src/fwd_register.h b/src/fwd_register.h
index 02ca7092d35ffbd684a4b531ac4ffbd94addd765..f7182ea0942ec0df811898c6de914f3302a722e3 100644
--- a/src/fwd_register.h
+++ b/src/fwd_register.h
@@ -4,6 +4,9 @@
 #include <dns/rbt.h>
 #include <dns/result.h>
 
+#include "util.h"
+#include "rbt_helper.h"
+
 #define FORWARDING_SET_MARK ((void *)1)
 /*
 #if FORWARDING_SET_MARK == NULL
diff --git a/src/ldap_entry.c b/src/ldap_entry.c
index 9823fddfe6cb9805565152ccec9f130d01cc0f8f..18e6980f075f5f916826599a30abd9173ad583f7 100644
--- a/src/ldap_entry.c
+++ b/src/ldap_entry.c
@@ -476,6 +476,32 @@ ldap_entry_getclass(ldap_entry_t *entry, ldap_entryclass_t *class)
 	return ISC_R_SUCCESS;
 }
 
+/**
+ * Infer entry class from auxiliary information.
+ *
+ * This is a fallback method for cases where objectClass values
+ * are not available.
+ *
+ * TODO: Object class information should be stored in UUID database
+ * 	 (once we have it).
+ */
+isc_result_t
+ldap_entry_guessclass(dns_name_t *entry_name, isc_boolean_t iszone,
+		      fwd_register_t *fwd_register, ldap_entryclass_t *class) {
+	REQUIRE(class != NULL);
+
+	if (iszone == ISC_TRUE) {
+		if (fwdr_zone_ispresent(fwd_register, entry_name)
+		    == ISC_R_SUCCESS)
+			*class = LDAP_ENTRYCLASS_FORWARD;
+		else /* master zone */
+			*class = (LDAP_ENTRYCLASS_MASTER | LDAP_ENTRYCLASS_RR);
+	} else
+		*class = LDAP_ENTRYCLASS_RR;
+
+	return ISC_R_SUCCESS;
+}
+
 isc_result_t
 ldap_attr_firstvalue(ldap_attribute_t *attr, ld_string_t *str)
 {
diff --git a/src/ldap_entry.h b/src/ldap_entry.h
index 420fcde5c06b46c9dd11e98ef9744be5b2b9524c..76a958520b8eb1c9f039e399ac9f4e0f1b346414 100644
--- a/src/ldap_entry.h
+++ b/src/ldap_entry.h
@@ -26,6 +26,8 @@
 #include <isc/util.h>
 #include <dns/types.h>
 
+#include "fwd_register.h"
+#include "util.h"
 #include "str.h"
 
 #define LDAP_DEPRECATED 1
@@ -137,6 +139,11 @@ isc_result_t
 ldap_entry_getclass(ldap_entry_t *entry, ldap_entryclass_t *class) ATTR_NONNULLS ATTR_CHECKRESULT;
 
 isc_result_t
+ldap_entry_guessclass(dns_name_t *entry_name, isc_boolean_t iszone,
+		      fwd_register_t *fwd_register, ldap_entryclass_t *class)
+		      ATTR_NONNULLS ATTR_CHECKRESULT;
+
+isc_result_t
 ldap_attr_firstvalue(ldap_attribute_t *attr, ld_string_t *str) ATTR_NONNULLS ATTR_CHECKRESULT;
 
 /*
diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index cb1ada64635406552f6b231cdb19a888a0f92244..c69b0748b7531479e62bbccc2b4ef468969c5434 100644
--- a/src/ldap_helper.c
+++ b/src/ldap_helper.c
@@ -4794,7 +4794,7 @@ syncrepl_update(ldap_instance_t *inst, ldap_entry_t *entry, int chgtype)
 	CHECKED_MEM_STRDUP(mctx, entry->dn, dn);
 	CHECKED_MEM_STRDUP(mctx, inst->db_name, dbname);
 
-	/* TODO: handle config objects properly - via UUID database */
+	/* TODO: handle object class inference properly - via UUID database */
 	CHECK(setting_get_str("base", inst->local_settings, &ldap_base));
 	CHECK(ldap_dn_compare(ldap_base, entry->dn, &isbase));
 	if (isbase == ISC_TRUE) {
@@ -4812,15 +4812,9 @@ syncrepl_update(ldap_instance_t *inst, ldap_entry_t *entry, int chgtype)
 			/* deleted entry doesn't contain objectClass, so
 			 * we need to find if the entry is zone or not
 			 * in other way */
-			result = fwdr_zone_ispresent(inst->fwd_register,
-						     &entry_name);
-			if (result == ISC_R_SUCCESS)
-				class = LDAP_ENTRYCLASS_FORWARD;
-			else if (iszone == ISC_TRUE)
-				class = (LDAP_ENTRYCLASS_MASTER |
-					 LDAP_ENTRYCLASS_RR);
-			else
-				class = LDAP_ENTRYCLASS_RR;
+			CHECK(ldap_entry_guessclass(&entry_name, iszone,
+						    inst->fwd_register,
+						    &class));
 			break;
 		}
 	}
-- 
2.1.0