#179 Move recognition of a templated attribute to ldap_attribute_to_rdatatype
Merged 4 years ago by abbra. Opened 4 years ago by abbra.
abbra/bind-dyndb-ldap locations-defaults-missing  into  master

file modified
+25 -8
@@ -372,23 +372,40 @@ 

  {

  	isc_result_t result;

  	unsigned len;

+ 	const char *attribute = NULL;

  	isc_consttextregion_t region;

  

  	len = strlen(ldap_attribute);

  	if (len <= LDAP_RDATATYPE_SUFFIX_LEN)

  		return ISC_R_UNEXPECTEDEND;

  

+ 

+ 	/* Before looking up rdtype, we need to see if rdtype is

+ 	 * an LDAP subtype (type;subtype) and if so, strip one of

+ 	 * the known prefixes. We also need to remove 'record' suffix

+ 	 * if it exists. The resulting rdtype text name should have no

+ 	 * 'extra' details: A, AAAA, CNAME, etc. */

+ 	attribute = ldap_attribute;

+ 

+ 	/* Does attribute name start with with TEMPLATE_PREFIX? */

+ 	if (strncasecmp(LDAP_RDATATYPE_TEMPLATE_PREFIX,

+ 			ldap_attribute,

+ 			LDAP_RDATATYPE_TEMPLATE_PREFIX_LEN) == 0) {

+ 		attribute = ldap_attribute + LDAP_RDATATYPE_TEMPLATE_PREFIX_LEN;

+ 		len -= LDAP_RDATATYPE_TEMPLATE_PREFIX_LEN;

+ 	/* Does attribute name start with with UNKNOWN_PREFIX? */

+ 	} else if (strncasecmp(LDAP_RDATATYPE_UNKNOWN_PREFIX,

+ 			       ldap_attribute,

+ 			       LDAP_RDATATYPE_UNKNOWN_PREFIX_LEN) == 0) {

+ 		attribute = ldap_attribute + LDAP_RDATATYPE_UNKNOWN_PREFIX_LEN;

+ 		len -= LDAP_RDATATYPE_UNKNOWN_PREFIX_LEN;

+ 	}

+ 

  	/* Does attribute name end with RECORD_SUFFIX? */

- 	if (strcasecmp(ldap_attribute + len - LDAP_RDATATYPE_SUFFIX_LEN,

+ 	if (strcasecmp(attribute + len - LDAP_RDATATYPE_SUFFIX_LEN,

  		       LDAP_RDATATYPE_SUFFIX) == 0) {

- 		region.base = ldap_attribute;

+ 		region.base = attribute;

  		region.length = len - LDAP_RDATATYPE_SUFFIX_LEN;

- 	/* Does attribute name start with with UNKNOWN_PREFIX? */

- 	} else if (strncasecmp(ldap_attribute,

- 			      LDAP_RDATATYPE_UNKNOWN_PREFIX,

- 			      LDAP_RDATATYPE_UNKNOWN_PREFIX_LEN) == 0) {

- 		region.base = ldap_attribute + LDAP_RDATATYPE_UNKNOWN_PREFIX_LEN;

- 		region.length = len - LDAP_RDATATYPE_UNKNOWN_PREFIX_LEN;

  	} else

  		return ISC_R_UNEXPECTED;

  

file modified
+2
@@ -17,6 +17,8 @@ 

  #define LDAP_RDATATYPE_SUFFIX_LEN	(sizeof(LDAP_RDATATYPE_SUFFIX) - 1)

  #define LDAP_RDATATYPE_UNKNOWN_PREFIX	"UnknownRecord;"

  #define LDAP_RDATATYPE_UNKNOWN_PREFIX_LEN	(sizeof(LDAP_RDATATYPE_UNKNOWN_PREFIX) - 1)

+ #define LDAP_RDATATYPE_TEMPLATE_PREFIX "idnsTemplateAttribute;"

+ #define LDAP_RDATATYPE_TEMPLATE_PREFIX_LEN	(sizeof(LDAP_RDATATYPE_TEMPLATE_PREFIX) - 1)

  

  /*

   * Convert LDAP DN 'dn', to dns_name_t 'target'. 'target' needs to be

file modified
+14 -7
@@ -2396,7 +2396,7 @@ 

  		result = setting_find(setting_name, set, isc_boolean_true,

  				      isc_boolean_true, &setting);

  		if (result != ISC_R_SUCCESS) {

- 			log_debug(3, "setting '%s' is not defined so it "

+ 			log_debug(5, "setting '%s' is not defined so it "

  				  "cannot be substituted into template '%s'",

  				  setting_name, str_buf(orig_val));

  			CLEANUP_WITH(ISC_R_IGNORE);
@@ -2459,23 +2459,22 @@ 

  	dns_rdatatype_t rdtype;

  	dns_rdatalist_t *rdlist = NULL;

  	isc_boolean_t did_something = ISC_FALSE;

- 	static const char prefix[] = "idnsTemplateAttribute;";

- 	static const char prefix_len = sizeof(prefix) - 1;

  

  	CHECK(str_new(mctx, &orig_val));

  	rdclass = ldap_entry_getrdclass(entry);

  	ttl = ldap_entry_getttl(entry, settings);

  

  	while ((attr = ldap_entry_nextattr(entry)) != NULL) {

- 		if (strncasecmp(prefix, attr->name, prefix_len) != 0)

+ 		if (strncasecmp(LDAP_RDATATYPE_TEMPLATE_PREFIX,

+ 				attr->name,

+ 				LDAP_RDATATYPE_TEMPLATE_PREFIX_LEN) != 0)

  			continue;

  

- 		result = ldap_attribute_to_rdatatype(attr->name + prefix_len,

- 						     &rdtype);

+ 		result = ldap_attribute_to_rdatatype(attr->name, &rdtype);

  		if (result != ISC_R_SUCCESS) {

  			log_bug("%s: substitution into '%s' is not supported",

  				ldap_entry_logname(entry),

- 				attr->name + prefix_len);

+ 				attr->name + LDAP_RDATATYPE_TEMPLATE_PREFIX_LEN);

  			continue;

  		}

  
@@ -2559,6 +2558,14 @@ 

  	for (result = ldap_entry_firstrdtype(entry, &attr, &rdtype);

  	     result == ISC_R_SUCCESS;

  	     result = ldap_entry_nextrdtype(entry, &attr, &rdtype)) {

+ 		/* If we reached this point and found a template attribute,

+ 		 * skip it because it was not translated above due to missing

+ 		 * defaults or some other errors. */

+ 		if (((entry->class & LDAP_ENTRYCLASS_TEMPLATE) != 0) &&

+ 		    strncasecmp(LDAP_RDATATYPE_TEMPLATE_PREFIX,

+ 				attr->name,

+ 				LDAP_RDATATYPE_TEMPLATE_PREFIX_LEN) == 0)

+ 			continue;

  

  		CHECK(findrdatatype_or_create(mctx, rdatalist, rdclass,

  					      rdtype, ttl, &rdlist));

When substitution of a templated entry attribute fails, we need to fall
back to a static definition of the attribute from the same entry. This
means, however, that ldap_attribute_to_rdatatype() will attempt to parse
an attribute value anyway and will be confused by the templating prefix,
thus reporting in named's logs:

unsupported operation: object class in resource record template DN
'idnsname=$NAME,idnsname=$ZONE.,cn=dns,$BASEDN' changed:
rndc reload might be necessary

Move recognition of a template attribute name to
ldap_attribute_to_rdatatype() so that a proper attribute class is
correctly derived and ignore templated attribute in the fallback code
if case that template expansion is failed.

Resolves: rhbz#1553512

rebased onto 88096745d1ef1798854e0c8319b5ae015f045fe3

4 years ago

rebased onto f542870

4 years ago

Pull-Request has been merged by abbra

4 years ago