diff options
-rw-r--r-- | ldap_driver.c | 59 | ||||
-rw-r--r-- | ldap_helper.c | 27 | ||||
-rw-r--r-- | ldap_helper.h | 7 |
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); |