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