Blame SOURCES/bind-dyndb-ldap-template-attribute-defaults.patch

c96fbb
From 88096745d1ef1798854e0c8319b5ae015f045fe3 Mon Sep 17 00:00:00 2001
c96fbb
From: Alexander Bokovoy <abokovoy@redhat.com>
c96fbb
Date: Wed, 1 May 2019 09:24:24 +0300
c96fbb
Subject: [PATCH] Move recognition of a templated attribute to
c96fbb
 ldap_attribute_to_rdatatype
c96fbb
c96fbb
When substitution of a templated entry attribute fails, we need to fall
c96fbb
back to a static definition of the attribute from the same entry. This
c96fbb
means, however, that ldap_attribute_to_rdatatype() will attempt to parse
c96fbb
an attribute value anyway and will be confused by the templating prefix,
c96fbb
thus reporting in named's logs:
c96fbb
c96fbb
unsupported operation: object class in resource record template DN
c96fbb
'idnsname=$NAME,idnsname=$ZONE.,cn=dns,$BASEDN' changed:
c96fbb
rndc reload might be necessary
c96fbb
c96fbb
Move recognition of a template attribute name to
c96fbb
ldap_attribute_to_rdatatype() so that a proper attribute class is
c96fbb
correctly derived and ignore templated attribute in the fallback code
c96fbb
if case that template expansion is failed.
c96fbb
c96fbb
Resolves: rhbz#1705072
c96fbb
---
c96fbb
 src/ldap_convert.c | 33 +++++++++++++++++++++++++--------
c96fbb
 src/ldap_convert.h |  2 ++
c96fbb
 src/ldap_helper.c  | 21 ++++++++++++++-------
c96fbb
 3 files changed, 41 insertions(+), 15 deletions(-)
c96fbb
c96fbb
diff --git a/src/ldap_convert.c b/src/ldap_convert.c
c96fbb
index 002a679..6e24c81 100644
c96fbb
--- a/src/ldap_convert.c
c96fbb
+++ b/src/ldap_convert.c
c96fbb
@@ -372,23 +372,40 @@ ldap_attribute_to_rdatatype(const char *ldap_attribute, dns_rdatatype_t *rdtype)
c96fbb
 {
c96fbb
 	isc_result_t result;
c96fbb
 	unsigned len;
c96fbb
+	const char *attribute = NULL;
c96fbb
 	isc_consttextregion_t region;
c96fbb
 
c96fbb
 	len = strlen(ldap_attribute);
c96fbb
 	if (len <= LDAP_RDATATYPE_SUFFIX_LEN)
c96fbb
 		return ISC_R_UNEXPECTEDEND;
c96fbb
 
c96fbb
+
c96fbb
+	/* Before looking up rdtype, we need to see if rdtype is
c96fbb
+	 * an LDAP subtype (type;subtype) and if so, strip one of
c96fbb
+	 * the known prefixes. We also need to remove 'record' suffix
c96fbb
+	 * if it exists. The resulting rdtype text name should have no
c96fbb
+	 * 'extra' details: A, AAAA, CNAME, etc. */
c96fbb
+	attribute = ldap_attribute;
c96fbb
+
c96fbb
+	/* Does attribute name start with with TEMPLATE_PREFIX? */
c96fbb
+	if (strncasecmp(LDAP_RDATATYPE_TEMPLATE_PREFIX,
c96fbb
+			ldap_attribute,
c96fbb
+			LDAP_RDATATYPE_TEMPLATE_PREFIX_LEN) == 0) {
c96fbb
+		attribute = ldap_attribute + LDAP_RDATATYPE_TEMPLATE_PREFIX_LEN;
c96fbb
+		len -= LDAP_RDATATYPE_TEMPLATE_PREFIX_LEN;
c96fbb
+	/* Does attribute name start with with UNKNOWN_PREFIX? */
c96fbb
+	} else if (strncasecmp(LDAP_RDATATYPE_UNKNOWN_PREFIX,
c96fbb
+			       ldap_attribute,
c96fbb
+			       LDAP_RDATATYPE_UNKNOWN_PREFIX_LEN) == 0) {
c96fbb
+		attribute = ldap_attribute + LDAP_RDATATYPE_UNKNOWN_PREFIX_LEN;
c96fbb
+		len -= LDAP_RDATATYPE_UNKNOWN_PREFIX_LEN;
c96fbb
+	}
c96fbb
+
c96fbb
 	/* Does attribute name end with RECORD_SUFFIX? */
c96fbb
-	if (strcasecmp(ldap_attribute + len - LDAP_RDATATYPE_SUFFIX_LEN,
c96fbb
+	if (strcasecmp(attribute + len - LDAP_RDATATYPE_SUFFIX_LEN,
c96fbb
 		       LDAP_RDATATYPE_SUFFIX) == 0) {
c96fbb
-		region.base = ldap_attribute;
c96fbb
+		region.base = attribute;
c96fbb
 		region.length = len - LDAP_RDATATYPE_SUFFIX_LEN;
c96fbb
-	/* Does attribute name start with with UNKNOWN_PREFIX? */
c96fbb
-	} else if (strncasecmp(ldap_attribute,
c96fbb
-			      LDAP_RDATATYPE_UNKNOWN_PREFIX,
c96fbb
-			      LDAP_RDATATYPE_UNKNOWN_PREFIX_LEN) == 0) {
c96fbb
-		region.base = ldap_attribute + LDAP_RDATATYPE_UNKNOWN_PREFIX_LEN;
c96fbb
-		region.length = len - LDAP_RDATATYPE_UNKNOWN_PREFIX_LEN;
c96fbb
 	} else
c96fbb
 		return ISC_R_UNEXPECTED;
c96fbb
 
c96fbb
diff --git a/src/ldap_convert.h b/src/ldap_convert.h
c96fbb
index 47ac947..fcd575b 100644
c96fbb
--- a/src/ldap_convert.h
c96fbb
+++ b/src/ldap_convert.h
c96fbb
@@ -17,6 +17,8 @@
c96fbb
 #define LDAP_RDATATYPE_SUFFIX_LEN	(sizeof(LDAP_RDATATYPE_SUFFIX) - 1)
c96fbb
 #define LDAP_RDATATYPE_UNKNOWN_PREFIX	"UnknownRecord;"
c96fbb
 #define LDAP_RDATATYPE_UNKNOWN_PREFIX_LEN	(sizeof(LDAP_RDATATYPE_UNKNOWN_PREFIX) - 1)
c96fbb
+#define LDAP_RDATATYPE_TEMPLATE_PREFIX "idnsTemplateAttribute;"
c96fbb
+#define LDAP_RDATATYPE_TEMPLATE_PREFIX_LEN	(sizeof(LDAP_RDATATYPE_TEMPLATE_PREFIX) - 1)
c96fbb
 
c96fbb
 /*
c96fbb
  * Convert LDAP DN 'dn', to dns_name_t 'target'. 'target' needs to be
c96fbb
diff --git a/src/ldap_helper.c b/src/ldap_helper.c
c96fbb
index 8b486ae..7f70ee3 100644
c96fbb
--- a/src/ldap_helper.c
c96fbb
+++ b/src/ldap_helper.c
c96fbb
@@ -2396,7 +2396,7 @@ ldap_substitute_rr_template(isc_mem_t *mctx, const settings_set_t * set,
c96fbb
 		result = setting_find(setting_name, set, isc_boolean_true,
c96fbb
 				      isc_boolean_true, &setting);
c96fbb
 		if (result != ISC_R_SUCCESS) {
c96fbb
-			log_debug(3, "setting '%s' is not defined so it "
c96fbb
+			log_debug(5, "setting '%s' is not defined so it "
c96fbb
 				  "cannot be substituted into template '%s'",
c96fbb
 				  setting_name, str_buf(orig_val));
c96fbb
 			CLEANUP_WITH(ISC_R_IGNORE);
c96fbb
@@ -2459,23 +2459,22 @@ ldap_parse_rrentry_template(isc_mem_t *mctx, ldap_entry_t *entry,
c96fbb
 	dns_rdatatype_t rdtype;
c96fbb
 	dns_rdatalist_t *rdlist = NULL;
c96fbb
 	isc_boolean_t did_something = ISC_FALSE;
c96fbb
-	static const char prefix[] = "idnsTemplateAttribute;";
c96fbb
-	static const char prefix_len = sizeof(prefix) - 1;
c96fbb
 
c96fbb
 	CHECK(str_new(mctx, &orig_val));
c96fbb
 	rdclass = ldap_entry_getrdclass(entry);
c96fbb
 	ttl = ldap_entry_getttl(entry, settings);
c96fbb
 
c96fbb
 	while ((attr = ldap_entry_nextattr(entry)) != NULL) {
c96fbb
-		if (strncasecmp(prefix, attr->name, prefix_len) != 0)
c96fbb
+		if (strncasecmp(LDAP_RDATATYPE_TEMPLATE_PREFIX,
c96fbb
+				attr->name,
c96fbb
+				LDAP_RDATATYPE_TEMPLATE_PREFIX_LEN) != 0)
c96fbb
 			continue;
c96fbb
 
c96fbb
-		result = ldap_attribute_to_rdatatype(attr->name + prefix_len,
c96fbb
-						     &rdtype);
c96fbb
+		result = ldap_attribute_to_rdatatype(attr->name, &rdtype);
c96fbb
 		if (result != ISC_R_SUCCESS) {
c96fbb
 			log_bug("%s: substitution into '%s' is not supported",
c96fbb
 				ldap_entry_logname(entry),
c96fbb
-				attr->name + prefix_len);
c96fbb
+				attr->name + LDAP_RDATATYPE_TEMPLATE_PREFIX_LEN);
c96fbb
 			continue;
c96fbb
 		}
c96fbb
 
c96fbb
@@ -2559,6 +2558,14 @@ ldap_parse_rrentry(isc_mem_t *mctx, ldap_entry_t *entry, dns_name_t *origin,
c96fbb
 	for (result = ldap_entry_firstrdtype(entry, &attr, &rdtype);
c96fbb
 	     result == ISC_R_SUCCESS;
c96fbb
 	     result = ldap_entry_nextrdtype(entry, &attr, &rdtype)) {
c96fbb
+		/* If we reached this point and found a template attribute,
c96fbb
+		 * skip it because it was not translated above due to missing
c96fbb
+		 * defaults or some other errors. */
c96fbb
+		if (((entry->class & LDAP_ENTRYCLASS_TEMPLATE) != 0) &&
c96fbb
+		    strncasecmp(LDAP_RDATATYPE_TEMPLATE_PREFIX,
c96fbb
+				attr->name,
c96fbb
+				LDAP_RDATATYPE_TEMPLATE_PREFIX_LEN) == 0)
c96fbb
+			continue;
c96fbb
 
c96fbb
 		CHECK(findrdatatype_or_create(mctx, rdatalist, rdclass,
c96fbb
 					      rdtype, ttl, &rdlist));
c96fbb
-- 
c96fbb
2.21.0
c96fbb