[Freeipa-devel] [PATCH] Fix handling of ANY queries in bind-dyndb-ldap

Adam Tkac atkac at redhat.com
Tue Dec 21 17:58:49 UTC 2010


Hello all,

attached patches fix handling of ANY queries in bind-dyndb-ldap
backend.

The first patch implements dns_rdatasetiter interface which is needed by
allrdatasets() DB method (implemented in the second patch).
The allrdatasets() database method is used by the named daemon to handle
ANY queries.

The third patch fixes the find() DB method to correctly return the
complete database node for a certain DNS name. Details are below.

If there are no objections I will push the patches.

Details:

Consider following resource records stored in the LDAP:

idns2.example.com. IN A 1.1.1.1
idns2.example.com. IN AAAA ::1

Currently the response for the ANY question looks:

---
$ dig @127.0.0.1 idns2.example.com ANY

;; QUESTION SECTION:
;idns2.example.com.             IN      ANY

;; AUTHORITY SECTION:
example.com.            86400   IN      SOA     idns.example.com.
root.example.com. 2009083006 10800 900 604800 86400
---

which is obviously incorrect. With this patch series output looks
fine:

$ dig @127.0.0.1 idns2.example.com ANY
---
;; QUESTION SECTION:
;idns2.example.com.             IN      ANY

;; ANSWER SECTION:
idns2.example.com.      86400   IN      A       1.1.1.1
idns2.example.com.      86400   IN      AAAA    ::1

;; AUTHORITY SECTION:
example.com.            86400   IN      NS      idns2.example.com.
example.com.            86400   IN      NS      idns.example.com.
example.com.            86400   IN      NS      ns.example.com.

;; ADDITIONAL SECTION:
ns.example.com.         86400   IN      A       172.29.255.254
idns.example.com.       86400   IN      A       172.30.0.32
---

Regards, Adam

-- 
Adam Tkac, Red Hat, Inc.
-------------- next part --------------
>From 1d7f44970bca635b4ed5a9ccd8521a3da6ae31fc Mon Sep 17 00:00:00 2001
From: Adam Tkac <atkac at redhat.com>
Date: Tue, 21 Dec 2010 18:21:29 +0100
Subject: [PATCH 1/3] Implement dns_rdatasetiter interface.

Signed-off-by: Adam Tkac <atkac at redhat.com>
---
 src/ldap_driver.c |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 60 insertions(+), 0 deletions(-)

diff --git a/src/ldap_driver.c b/src/ldap_driver.c
index 925ae20..0b584a5 100644
--- a/src/ldap_driver.c
+++ b/src/ldap_driver.c
@@ -36,6 +36,7 @@
 #include <dns/rdataclass.h>
 #include <dns/rdatalist.h>
 #include <dns/rdataset.h>
+#include <dns/rdatasetiter.h>
 #include <dns/rdatatype.h>
 #include <dns/result.h>
 #include <dns/types.h>
@@ -75,12 +76,71 @@ typedef struct {
 	ldapdb_rdatalist_t		rdatalist;
 } ldapdbnode_t;
 
+typedef struct {
+	dns_rdatasetiter_t		common;
+	dns_rdatalist_t			*current;
+} ldapdb_rdatasetiter_t;
+
 static int dummy;
 static void *ldapdb_version = &dummy;
 
 static void free_ldapdb(ldapdb_t *ldapdb);
 static void detachnode(dns_db_t *db, dns_dbnode_t **targetp);
 static unsigned int rdatalist_length(const dns_rdatalist_t *rdlist);
+static isc_result_t clone_rdatalist_to_rdataset(isc_mem_t *mctx,
+						dns_rdatalist_t *rdlist,
+						dns_rdataset_t *rdataset);
+
+/* ldapdb_rdatasetiter_t methods */
+static void
+rdatasetiter_destroy(dns_rdatasetiter_t **iterp)
+{
+	ldapdb_rdatasetiter_t *ldapdbiter = (ldapdb_rdatasetiter_t *)(*iterp);
+
+	detachnode(ldapdbiter->common.db, &ldapdbiter->common.node);
+	SAFE_MEM_PUT_PTR(ldapdbiter->common.db->mctx, ldapdbiter);
+	*iterp = NULL;
+}
+
+static isc_result_t
+rdatasetiter_first(dns_rdatasetiter_t *iter)
+{
+	ldapdb_rdatasetiter_t *ldapdbiter = (ldapdb_rdatasetiter_t *)iter;
+	ldapdbnode_t *node = (ldapdbnode_t *)iter->node;
+
+	if (EMPTY(node->rdatalist))
+		return ISC_R_NOMORE;
+
+	ldapdbiter->current = HEAD(node->rdatalist);
+	return ISC_R_SUCCESS;
+}
+
+static isc_result_t
+rdatasetiter_next(dns_rdatasetiter_t *iter)
+{
+	ldapdb_rdatasetiter_t *ldapdbiter = (ldapdb_rdatasetiter_t *)iter;
+
+	ldapdbiter->current = NEXT(ldapdbiter->current, link);
+	return (ldapdbiter->current == NULL) ? ISC_R_NOMORE : ISC_R_SUCCESS;
+}
+
+static void
+rdatasetiter_current(dns_rdatasetiter_t *iter, dns_rdataset_t *rdataset)
+{
+	ldapdb_rdatasetiter_t *ldapdbiter = (ldapdb_rdatasetiter_t *)iter;
+	isc_result_t result;
+
+	result = clone_rdatalist_to_rdataset(ldapdbiter->common.db->mctx,
+					     ldapdbiter->current, rdataset);
+	INSIST(result == ISC_R_SUCCESS);
+}
+
+static dns_rdatasetitermethods_t rdatasetiter_methods = {
+	rdatasetiter_destroy,
+	rdatasetiter_first,
+	rdatasetiter_next,
+	rdatasetiter_current
+};
 
 /* ldapdbnode_t functions */
 static isc_result_t
-- 
1.7.3.4

-------------- next part --------------
>From 2f750c435ab9af81ec88658a685d17f76d7dc2a7 Mon Sep 17 00:00:00 2001
From: Adam Tkac <atkac at redhat.com>
Date: Tue, 21 Dec 2010 18:26:31 +0100
Subject: [PATCH 2/3] Implement allrdatasets() DB method.

Signed-off-by: Adam Tkac <atkac at redhat.com>
---
 src/ldap_driver.c |   25 +++++++++++++++++++------
 1 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/src/ldap_driver.c b/src/ldap_driver.c
index 0b584a5..5787d6f 100644
--- a/src/ldap_driver.c
+++ b/src/ldap_driver.c
@@ -606,13 +606,26 @@ static isc_result_t
 allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
 	     isc_stdtime_t now, dns_rdatasetiter_t **iteratorp)
 {
-	UNUSED(db);
-	UNUSED(node);
-	UNUSED(version);
-	UNUSED(now);
-	UNUSED(iteratorp);
+	ldapdb_rdatasetiter_t *iter;
+	isc_result_t result;
 
-	return ISC_R_NOTIMPLEMENTED;
+	REQUIRE(version == NULL || version == &dummy);
+
+	CHECKED_MEM_GET_PTR(db->mctx, iter);
+	iter->common.magic = DNS_RDATASETITER_MAGIC;
+	iter->common.methods = &rdatasetiter_methods;
+	iter->common.db = db;
+	iter->common.node = NULL;
+	attachnode(db, node, &iter->common.node);
+	iter->common.version = version;
+	iter->common.now = now;
+
+	*iteratorp = (dns_rdatasetiter_t *)iter;
+
+	return ISC_R_SUCCESS;
+
+cleanup:
+	return result;
 }
 
 /*
-- 
1.7.3.4

-------------- next part --------------
>From 6aebf7e1162654dc3d15741de5fbfc35a27a44ee Mon Sep 17 00:00:00 2001
From: Adam Tkac <atkac at redhat.com>
Date: Tue, 21 Dec 2010 18:43:25 +0100
Subject: [PATCH 3/3] Fix ticket #2 - handling of DNS ANY questions.

Signed-off-by: Adam Tkac <atkac at redhat.com>
---
 src/ldap_driver.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/src/ldap_driver.c b/src/ldap_driver.c
index 5787d6f..965877c 100644
--- a/src/ldap_driver.c
+++ b/src/ldap_driver.c
@@ -435,6 +435,13 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
 	if (result != ISC_R_SUCCESS && result != DNS_R_PARTIALMATCH)
 		return (result == ISC_R_NOTFOUND) ? DNS_R_NXDOMAIN : result;
 
+	/*
+	 * ANY pseudotype indicates the whole node, skip routines
+	 * which attempts to find the exact RR type.
+	 */
+	if (type == dns_rdatatype_any)
+		goto anyfound;
+
 	result = ldapdb_rdatalist_findrdatatype(&rdatalist, type, &rdlist);
 	if (result != ISC_R_SUCCESS) {
 		/* No exact rdtype match. Check CNAME */
@@ -455,6 +462,7 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
 		goto cleanup;
 	}
 
+anyfound:
 	/* XXX currently we implemented only exact authoritative matches */
 	CHECK(dns_name_copy(name, foundname, NULL));
 
-- 
1.7.3.4



More information about the Freeipa-devel mailing list