summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ldap_driver.c59
-rw-r--r--ldap_helper.c27
-rw-r--r--ldap_helper.h7
3 files changed, 75 insertions, 18 deletions
diff --git a/ldap_driver.c b/ldap_driver.c
index afc6d65..a7cac48 100644
--- a/ldap_driver.c
+++ b/ldap_driver.c
@@ -25,6 +25,7 @@
#include <dns/db.h>
#include <dns/rdata.h>
#include <dns/rdatalist.h>
+#include <dns/rdataset.h>
#include <dns/result.h>
#include <dns/types.h>
@@ -43,6 +44,8 @@
#define VALID_LDAPDBNODE(ldapdbnode) ISC_MAGIC_VALID(ldapdbnode, \
LDAPDBNODE_MAGIC)
+static dns_rdatasetmethods_t rdataset_methods;
+
typedef struct {
dns_db_t common;
isc_refcount_t refs;
@@ -63,7 +66,6 @@ static void *ldapdb_version = &dummy;
static void free_ldapdb(ldapdb_t *ldapdb);
static void detachnode(dns_db_t *db, dns_dbnode_t **targetp);
-
/* ldapdbnode_t functions */
static isc_result_t
ldapdbnode_create(isc_mem_t *mctx, dns_name_t *owner, ldapdbnode_t **nodep)
@@ -138,25 +140,47 @@ clone_rdatalist_to_rdataset(isc_mem_t *mctx, dns_rdatalist_t *rdlist,
APPEND(new_rdlist->rdata, new_rdata, link);
}
- result = dns_rdatalist_tordataset(new_rdlist, rdataset);
+ CHECK(dns_rdatalist_tordataset(new_rdlist, rdataset));
+ rdataset->methods = &rdataset_methods;
+ isc_mem_attach(mctx, (isc_mem_t **)&rdataset->private5);
return result;
cleanup:
if (new_rdlist != NULL) {
- for (rdata = HEAD(new_rdlist->rdata);
- rdata != NULL;
- rdata = NEXT(rdata, link)) {
- SAFE_MEM_PUT(mctx, rdata->data, rdata->length);
- SAFE_MEM_PUT_PTR(mctx, rdata);
- }
+ free_rdatalist(mctx, rdlist);
+ isc_mem_put(mctx, new_rdlist, sizeof(*new_rdlist));
}
- SAFE_MEM_PUT_PTR(mctx, new_rdlist);
return result;
}
/*
+ * Our own function for disassociating rdatasets. We will also free the
+ * rdatalist that we put inside from clone_rdatalist_to_rdataset.
+ */
+void
+ldapdb_rdataset_disassociate(dns_rdataset_t *rdataset)
+{
+ dns_rdatalist_t *rdlist;
+ isc_mem_t *mctx;
+
+ REQUIRE(rdataset != NULL);
+
+ rdlist = rdataset->private1;
+ mctx = rdataset->private5;
+ if (rdlist == NULL)
+ return;
+ rdataset->private1 = NULL;
+ rdataset->private5 = NULL;
+
+ free_rdatalist(mctx, rdlist);
+ isc_mem_put(mctx, rdlist, sizeof(*rdlist));
+
+ isc_mem_detach(&mctx);
+}
+
+/*
* Functions.
*
* Most of them don't need db parameter but we are checking if it is valid.
@@ -845,6 +869,23 @@ dynamic_driver_init(isc_mem_t *mctx, const char *name, const char * const *argv,
i++;
}
+ /*
+ * We need to discover what rdataset methods does
+ * dns_rdatalist_tordataset use. We then make a copy for ourselves
+ * with the exception that we modify the disassociate method to free
+ * the rdlist we allocate for it in clone_rdatalist_to_rdataset().
+ */
+ if (rdataset_methods.disassociate == NULL) {
+ dns_rdataset_t rdset;
+ dns_rdatalist_t rdatalist;
+
+ dns_rdataset_init(&rdset);
+ dns_rdatalist_tordataset(&rdatalist, &rdset);
+ memcpy(&rdataset_methods, rdset.methods,
+ sizeof(dns_rdatasetmethods_t));
+ rdataset_methods.disassociate = ldapdb_rdataset_disassociate;
+ }
+
/* Register new DNS DB implementation. */
result = dns_db_register(ldapdb_impname, &ldapdb_create, NULL, mctx,
&ldapdb_imp);
diff --git a/ldap_helper.c b/ldap_helper.c
index ac9be6e..18bfb5e 100644
--- a/ldap_helper.c
+++ b/ldap_helper.c
@@ -558,26 +558,35 @@ ldapdb_rdatalist_findrdatatype(ldapdb_rdatalist_t *rdatalist,
void
ldapdb_rdatalist_destroy(isc_mem_t *mctx, ldapdb_rdatalist_t *rdatalist)
{
- dns_rdata_t *rdata;
dns_rdatalist_t *rdlist;
- isc_region_t r;
REQUIRE(rdatalist != NULL);
while (!EMPTY(*rdatalist)) {
rdlist = HEAD(*rdatalist);
- while (!EMPTY(rdlist->rdata)) {
- rdata = HEAD(rdlist->rdata);
- UNLINK(rdlist->rdata, rdata, link);
- dns_rdata_toregion(rdata, &r);
- isc_mem_put(mctx, r.base, r.length);
- isc_mem_put(mctx, rdata, sizeof(*rdata));
- }
+ free_rdatalist(mctx, rdlist);
UNLINK(*rdatalist, rdlist, link);
isc_mem_put(mctx, rdlist, sizeof(*rdlist));
}
}
+void
+free_rdatalist(isc_mem_t *mctx, dns_rdatalist_t *rdlist)
+{
+ dns_rdata_t *rdata;
+ isc_region_t r;
+
+ REQUIRE(rdlist != NULL);
+
+ while (!EMPTY(rdlist->rdata)) {
+ rdata = HEAD(rdlist->rdata);
+ UNLINK(rdlist->rdata, rdata, link);
+ dns_rdata_toregion(rdata, &r);
+ isc_mem_put(mctx, r.base, r.length);
+ isc_mem_put(mctx, rdata, sizeof(*rdata));
+ }
+}
+
isc_result_t
ldapdb_rdatalist_get(isc_mem_t *mctx, ldap_db_t *ldap_db, dns_name_t *name,
ldapdb_rdatalist_t *rdatalist)
diff --git a/ldap_helper.h b/ldap_helper.h
index 8b25137..2c3c98b 100644
--- a/ldap_helper.h
+++ b/ldap_helper.h
@@ -59,6 +59,13 @@ void ldapdb_rdatalist_destroy(isc_mem_t *mctx, ldapdb_rdatalist_t *rdatalist);
* Free rdatalist list and free all associated rdata buffers.
*/
+void free_rdatalist(isc_mem_t *mctx, dns_rdatalist_t *rdlist);
+/*
+ * free_rdatalist
+ *
+ * Free all dynamically allocated memory inside rdlist.
+ */
+
isc_result_t ldapdb_rdatalist_get(isc_mem_t *mctx, ldap_db_t *ldap_db,
dns_name_t *name,
ldapdb_rdatalist_t *rdatalist);