diff options
Diffstat (limited to 'ldap_driver.c')
-rw-r--r-- | ldap_driver.c | 1076 |
1 files changed, 0 insertions, 1076 deletions
diff --git a/ldap_driver.c b/ldap_driver.c deleted file mode 100644 index 8003c85..0000000 --- a/ldap_driver.c +++ /dev/null @@ -1,1076 +0,0 @@ -/* Authors: Martin Nagy <mnagy@redhat.com> - * Adam Tkac <atkac@redhat.com> - * - * Copyright (C) 2008, 2009 Red Hat - * see file 'COPYING' for use and warranty information - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2 only - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <isc/buffer.h> -#include <isc/mem.h> -#include <isc/refcount.h> -#include <isc/util.h> - -#include <dns/db.h> -#include <dns/rdata.h> -#include <dns/rdataclass.h> -#include <dns/rdatalist.h> -#include <dns/rdataset.h> -#include <dns/rdatatype.h> -#include <dns/result.h> -#include <dns/types.h> - -#include <string.h> /* For memcpy */ - -#include "cache.h" -#include "ldap_helper.h" -#include "log.h" -#include "rdlist.h" -#include "util.h" -#include "zone_manager.h" - -#define LDAPDB_MAGIC ISC_MAGIC('L', 'D', 'P', 'D') -#define VALID_LDAPDB(ldapdb) \ - ((ldapdb) != NULL && (ldapdb)->common.impmagic == LDAPDB_MAGIC) - -#define LDAPDBNODE_MAGIC ISC_MAGIC('L', 'D', 'P', 'N') -#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; - isc_mutex_t lock; /* convert to isc_rwlock_t ? */ - ldap_db_t *ldap_db; - ldap_cache_t *ldap_cache; -} ldapdb_t; - -typedef struct { - unsigned int magic; - isc_refcount_t refs; - dns_name_t owner; - ldapdb_rdatalist_t rdatalist; -} ldapdbnode_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); - -/* ldapdbnode_t functions */ -static isc_result_t -ldapdbnode_create(isc_mem_t *mctx, dns_name_t *owner, ldapdbnode_t **nodep) -{ - ldapdbnode_t *node = NULL; - isc_result_t result; - - REQUIRE(nodep != NULL && *nodep == NULL); - - CHECKED_MEM_GET_PTR(mctx, node); - CHECK(isc_refcount_init(&node->refs, 1)); - - dns_name_init(&node->owner, NULL); - CHECK(dns_name_dup(owner, mctx, &node->owner)); - - node->magic = LDAPDBNODE_MAGIC; - - ISC_LIST_INIT(node->rdatalist); - - *nodep = node; - - return ISC_R_SUCCESS; - -cleanup: - SAFE_MEM_PUT_PTR(mctx, node); - - return result; -} - -/* - * Clone rdlist and convert it into rdataset. - */ -static isc_result_t -clone_rdatalist_to_rdataset(isc_mem_t *mctx, dns_rdatalist_t *rdlist, - dns_rdataset_t *rdataset) -{ - isc_result_t result; - dns_rdatalist_t *new_rdlist = NULL; - - REQUIRE(mctx != NULL); - - CHECK(rdatalist_clone(mctx, rdlist, &new_rdlist)); - - 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) { - free_rdatalist(mctx, rdlist); - isc_mem_put(mctx, new_rdlist, sizeof(*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); - SAFE_MEM_PUT_PTR(mctx, rdlist); - - isc_mem_detach(&mctx); -} - -/* - * Functions. - * - * Most of them don't need db parameter but we are checking if it is valid. - * Invalid db parameter indicates bug in code. - */ - -static void -attach(dns_db_t *source, dns_db_t **targetp) -{ - ldapdb_t *ldapdb = (ldapdb_t *)source; - - REQUIRE(VALID_LDAPDB(ldapdb)); - - isc_refcount_increment(&ldapdb->refs, NULL); - *targetp = source; -} - -static void -detach(dns_db_t **dbp) -{ - ldapdb_t *ldapdb = (ldapdb_t *)(*dbp); - unsigned int refs; - - REQUIRE(VALID_LDAPDB(ldapdb)); - - isc_refcount_decrement(&ldapdb->refs, &refs); - - if (refs == 0) - free_ldapdb(ldapdb); - - *dbp = NULL; -} - -static void -free_ldapdb(ldapdb_t *ldapdb) -{ - DESTROYLOCK(&ldapdb->lock); - dns_name_free(&ldapdb->common.origin, ldapdb->common.mctx); - isc_mem_putanddetach(&ldapdb->common.mctx, ldapdb, sizeof(*ldapdb)); -} - -static isc_result_t -beginload(dns_db_t *db, dns_addrdatasetfunc_t *addp, dns_dbload_t **dbloadp) -{ - - UNUSED(db); - UNUSED(addp); - UNUSED(dbloadp); - - fatal_error("ldapdb: method beginload() should never be called"); - - /* Not reached */ - return ISC_R_SUCCESS; -} - -static isc_result_t -endload(dns_db_t *db, dns_dbload_t **dbloadp) -{ - - UNUSED(db); - UNUSED(dbloadp); - - fatal_error("ldapdb: method endload() should never be called"); - - /* Not reached */ - return ISC_R_SUCCESS; -} - -static isc_result_t -dump(dns_db_t *db, dns_dbversion_t *version, const char *filename, - dns_masterformat_t masterformat) -{ - - UNUSED(db); - UNUSED(version); - UNUSED(filename); - UNUSED(masterformat); - - fatal_error("ldapdb: method dump() should never be called"); - - /* Not reached */ - return ISC_R_SUCCESS; -} - -static void -currentversion(dns_db_t *db, dns_dbversion_t **versionp) -{ - ldapdb_t *ldapdb = (ldapdb_t *)db; - - REQUIRE(VALID_LDAPDB(ldapdb)); - REQUIRE(versionp != NULL && *versionp == NULL); - - *versionp = ldapdb_version; -} - -static isc_result_t -newversion(dns_db_t *db, dns_dbversion_t **versionp) -{ - ldapdb_t *ldapdb = (ldapdb_t *)db; - - REQUIRE(VALID_LDAPDB(ldapdb)); - REQUIRE(versionp != NULL && *versionp == NULL); - - *versionp = ldapdb_version; - return ISC_R_SUCCESS; -} - -static void -attachversion(dns_db_t *db, dns_dbversion_t *source, - dns_dbversion_t **targetp) -{ - ldapdb_t *ldapdb = (ldapdb_t *)db; - - REQUIRE(VALID_LDAPDB(ldapdb)); - REQUIRE(source == ldapdb_version); - REQUIRE(targetp != NULL && *targetp == NULL); - - *targetp = ldapdb_version; -} - -static void -closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) -{ - ldapdb_t *ldapdb = (ldapdb_t *)db; - - UNUSED(commit); - - REQUIRE(VALID_LDAPDB(ldapdb)); - REQUIRE(versionp != NULL && *versionp == ldapdb_version); - - *versionp = NULL; -} - -static isc_result_t -findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, - dns_dbnode_t **nodep) -{ - ldapdb_t *ldapdb = (ldapdb_t *) db; - isc_result_t result; - ldapdb_rdatalist_t rdatalist; - ldapdbnode_t *node = NULL; - - REQUIRE(VALID_LDAPDB(ldapdb)); - - result = cached_ldap_rdatalist_get(ldapdb->common.mctx, - ldapdb->ldap_cache, ldapdb->ldap_db, - name, &rdatalist); - - if (result == ISC_R_NOMEMORY) - return ISC_R_NOMEMORY; - - if (create == ISC_FALSE) { - /* No partial matches are allowed in this function */ - if (result == DNS_R_PARTIALMATCH) { - result = ISC_R_NOTFOUND; - goto cleanup; - } else if (result != ISC_R_SUCCESS) { - return result; - } - } - - CHECK(ldapdbnode_create(ldapdb->common.mctx, name, &node)); - - memcpy(&node->rdatalist, &rdatalist, sizeof(rdatalist)); - - *nodep = node; - - return ISC_R_SUCCESS; - -cleanup: - ldapdb_rdatalist_destroy(ldapdb->common.mctx, &rdatalist); - - return result; -} - -/* XXX add support for DNAME redirection */ -static isc_result_t -find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, - dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset) -{ - ldapdb_t *ldapdb = (ldapdb_t *) db; - isc_result_t result; - ldapdbnode_t *node = NULL; - dns_rdatalist_t *rdlist = NULL; - isc_boolean_t is_cname = ISC_FALSE; - ldapdb_rdatalist_t rdatalist; - - UNUSED(now); - UNUSED(options); - UNUSED(sigrdataset); - - REQUIRE(VALID_LDAPDB(ldapdb)); - REQUIRE(!(node != NULL && type == dns_rdatatype_any)); - //REQUIRE(!(node == NULL && rdataset != NULL)); - - if (version != NULL) { - REQUIRE(version == ldapdb_version); - } - - result = cached_ldap_rdatalist_get(ldapdb->common.mctx, - ldapdb->ldap_cache, ldapdb->ldap_db, - name, &rdatalist); - INSIST(result != DNS_R_PARTIALMATCH); /* XXX Not yet implemented */ - - if (result != ISC_R_SUCCESS && result != DNS_R_PARTIALMATCH) - return (result == ISC_R_NOTFOUND) ? DNS_R_NXDOMAIN : result; - - result = ldapdb_rdatalist_findrdatatype(&rdatalist, type, &rdlist); - if (result != ISC_R_SUCCESS) { - /* No exact rdtype match. Check CNAME */ - - rdlist = HEAD(rdatalist); - while (rdlist != NULL && rdlist->type != dns_rdatatype_cname) - rdlist = NEXT(rdlist, link); - - /* CNAME was found */ - if (rdlist != NULL) { - result = ISC_R_SUCCESS; - is_cname = ISC_TRUE; - } - } - - if (result != ISC_R_SUCCESS) { - result = DNS_R_NXRRSET; - goto cleanup; - } - - /* XXX currently we implemented only exact authoritative matches */ - CHECK(dns_name_copy(name, foundname, NULL)); - - if (rdataset != NULL && type != dns_rdatatype_any) { - /* dns_rdatalist_tordataset returns success only */ - CHECK(clone_rdatalist_to_rdataset(ldapdb->common.mctx, rdlist, - rdataset)); - } - - if (nodep != NULL) { - CHECK(ldapdbnode_create(ldapdb->common.mctx, name, &node)); - memcpy(&node->rdatalist, &rdatalist, sizeof(rdatalist)); - *nodep = node; - } else { - ldapdb_rdatalist_destroy(ldapdb->common.mctx, &rdatalist); - } - - return (is_cname == ISC_TRUE) ? DNS_R_CNAME : ISC_R_SUCCESS; - -cleanup: - ldapdb_rdatalist_destroy(ldapdb->common.mctx, &rdatalist); - return result; -} - -static isc_result_t -findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, - isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - UNUSED(db); - UNUSED(name); - UNUSED(options); - UNUSED(now); - UNUSED(nodep); - UNUSED(foundname); - UNUSED(rdataset); - UNUSED(sigrdataset); - - return ISC_R_NOTIMPLEMENTED; -} - -static void -attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) -{ - ldapdbnode_t *node = (ldapdbnode_t *) source; - - REQUIRE(VALID_LDAPDBNODE(node)); - - UNUSED(db); - - isc_refcount_increment(&node->refs, NULL); - *targetp = source; -} - -static void -detachnode(dns_db_t *db, dns_dbnode_t **targetp) -{ - ldapdbnode_t *node = (ldapdbnode_t *)(*targetp); - ldapdb_t *ldapdb = (ldapdb_t *) db; - unsigned int refs; - - /* - * Don't check for db and targetp validity, it's done in - * dns_db_detachnode - */ - - REQUIRE(VALID_LDAPDBNODE(node)); - isc_refcount_decrement(&node->refs, &refs); - if (refs == 0) { - ldapdb_rdatalist_destroy(ldapdb->common.mctx, &node->rdatalist); - dns_name_free(&node->owner, ldapdb->common.mctx); - SAFE_MEM_PUT_PTR(ldapdb->common.mctx, node); - } - - *targetp = NULL; -} - -static isc_result_t -expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) -{ - UNUSED(db); - UNUSED(node); - UNUSED(now); - - return ISC_R_NOTIMPLEMENTED; -} - -static void -printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) -{ - UNUSED(db); - UNUSED(node); - UNUSED(out); -} - -static isc_result_t -createiterator(dns_db_t *db, unsigned int options, - dns_dbiterator_t **iteratorp) -{ - UNUSED(db); - UNUSED(options); - UNUSED(iteratorp); - - return ISC_R_NOTIMPLEMENTED; -} - -static isc_result_t -findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - dns_rdatatype_t type, dns_rdatatype_t covers, isc_stdtime_t now, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) -{ - ldapdb_t *ldapdb = (ldapdb_t *) db; - ldapdbnode_t *ldapdbnode = (ldapdbnode_t *) node; - dns_rdatalist_t *rdlist = NULL; - isc_result_t result; - - UNUSED(db); - UNUSED(now); - UNUSED(sigrdataset); - - REQUIRE(covers == 0); /* Only meaningful with DNSSEC capable DB*/ - REQUIRE(VALID_LDAPDBNODE(ldapdbnode)); - - if (version != NULL) { - REQUIRE(version == ldapdb_version); - } - - result = ldapdb_rdatalist_findrdatatype(&ldapdbnode->rdatalist, type, - &rdlist); - if (result != ISC_R_SUCCESS) - return result; - - result = clone_rdatalist_to_rdataset(ldapdb->common.mctx, rdlist, - rdataset); - - return result; -} - -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); - - return ISC_R_NOTIMPLEMENTED; -} - -/* - * Remove duplicates between rdlists. If rm_from1 == true then remove rdata - * from the first rdatalist. same rdata are removed from rdlist1 or 2 and are - * returned in diff. - */ -static void -rdatalist_removedups(dns_rdatalist_t *rdlist1, dns_rdatalist_t *rdlist2, - isc_boolean_t rm_from1, - dns_rdatalist_t *diff) -{ - dns_rdata_t *rdata1, *rdata2; - - rdata1 = HEAD(rdlist1->rdata); - while (rdata1 != NULL) { - rdata2 = HEAD(rdlist2->rdata); - while (rdata2 != NULL) { - if (dns_rdata_compare(rdata1, rdata2) != 0) { - rdata2 = NEXT(rdata2, link); - continue; - } - /* same rdata has been found */ - if (rm_from1) { - ISC_LIST_UNLINK(rdlist1->rdata, rdata1, link); - APPEND(diff->rdata, rdata1, link); - } else { - ISC_LIST_UNLINK(rdlist2->rdata, rdata2, link); - APPEND(diff->rdata, rdata2, link); - } - break; - } - rdata1 = NEXT(rdata1, link); - } -} - -static isc_result_t -addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options, - dns_rdataset_t *addedrdataset) -{ - ldapdbnode_t *ldapdbnode = (ldapdbnode_t *) node; - ldapdb_t *ldapdb = (ldapdb_t *) db; - dns_rdatalist_t *rdlist = NULL, *new_rdlist = NULL; - dns_rdatalist_t *found_rdlist = NULL; - dns_rdatalist_t diff; - isc_result_t result; - isc_boolean_t rdatalist_exists = ISC_FALSE; - - UNUSED(now); - UNUSED(db); - UNUSED(addedrdataset); - - REQUIRE(VALID_LDAPDBNODE(ldapdbnode)); - /* version == NULL is valid only for cache databases */ - REQUIRE(version == ldapdb_version); - REQUIRE((options & DNS_DBADD_FORCE) == 0); - - dns_rdatalist_init(&diff); - - result = dns_rdatalist_fromrdataset(rdataset, &rdlist); - INSIST(result == ISC_R_SUCCESS); - INSIST(rdlist->rdclass == dns_rdataclass_in); - - CHECK(rdatalist_clone(ldapdb->common.mctx, rdlist, &new_rdlist)); - - result = ldapdb_rdatalist_findrdatatype(&ldapdbnode->rdatalist, - rdlist->type, &found_rdlist); - if (result == ISC_R_SUCCESS) { - rdatalist_exists = ISC_TRUE; - - if (rdlist->ttl != found_rdlist->ttl) { - /* - * TODO: support it. When supported handle - * DNS_DBADD_EXACTTTL option well. - */ - log_error("Multiple TTLs for one name are not " - "supported"); - result = ISC_R_NOTIMPLEMENTED; - goto cleanup; - } - - if ((options & DNS_DBADD_MERGE) != 0 || - (options & DNS_DBADD_EXACT) != 0) { - rdatalist_removedups(found_rdlist, new_rdlist, - ISC_FALSE, &diff); - - if ((options & DNS_DBADD_MERGE) != 0) - free_rdatalist(ldapdb->common.mctx, &diff); - else if (rdatalist_length(&diff) != 0) { - free_rdatalist(ldapdb->common.mctx, &diff); - result = DNS_R_NOTEXACT; - goto cleanup; - } - } else { - /* Replace existing rdataset */ - free_rdatalist(ldapdb->common.mctx, found_rdlist); - } - } - - CHECK(write_to_ldap(&ldapdbnode->owner, ldapdb->ldap_db, new_rdlist)); - CHECK(discard_from_cache(ldapdb->ldap_cache, &ldapdbnode->owner)); - - if (addedrdataset != NULL) { - result = dns_rdatalist_tordataset(new_rdlist, addedrdataset); - /* Use strong condition here, returns only SUCCESS */ - INSIST(result == ISC_R_SUCCESS); - } - - if (rdatalist_exists) { - ISC_LIST_APPENDLIST(found_rdlist->rdata, new_rdlist->rdata, - link); - SAFE_MEM_PUT_PTR(ldapdb->common.mctx, new_rdlist); - } else - APPEND(ldapdbnode->rdatalist, new_rdlist, link); - - - return ISC_R_SUCCESS; - -cleanup: - if (new_rdlist != NULL) { - free_rdatalist(ldapdb->common.mctx, new_rdlist); - SAFE_MEM_PUT_PTR(ldapdb->common.mctx, new_rdlist); - } - - return result; -} - -static unsigned int -rdatalist_length(const dns_rdatalist_t *rdlist) -{ - dns_rdata_t *ptr = HEAD(rdlist->rdata); - unsigned int length = 0; - - while (ptr != NULL) { - length++; - ptr = NEXT(ptr, link); - } - - return length; -} - -static isc_result_t -subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - dns_rdataset_t *rdataset, unsigned int options, - dns_rdataset_t *newrdataset) -{ - ldapdb_t *ldapdb = (ldapdb_t *) db; - ldapdbnode_t *ldapdbnode = (ldapdbnode_t *) node; - dns_rdatalist_t *found_rdlist = NULL; - dns_rdatalist_t *rdlist; - dns_rdatalist_t diff; - isc_result_t result; - - REQUIRE(version == ldapdb_version); - - result = dns_rdatalist_fromrdataset(rdataset, &rdlist); - /* Use strong condition here, no other value is returned */ - INSIST(result == ISC_R_SUCCESS); - - /* Do we want to use memcpy here? */ - dns_rdatalist_init(&diff); - diff.rdclass = rdlist->rdclass; - diff.type = rdlist->type; - diff.covers = rdlist->covers; - diff.ttl = rdlist->ttl; - - result = ldapdb_rdatalist_findrdatatype(&ldapdbnode->rdatalist, - rdlist->type, &found_rdlist); - - if (result == ISC_R_NOTFOUND) - return DNS_R_NXRRSET; - - /* We found correct type, remove maching rdata */ - rdatalist_removedups(rdlist, found_rdlist, ISC_FALSE, &diff); - - if ((options & DNS_DBSUB_EXACT) != 0 && - rdatalist_length(&diff) != rdatalist_length(rdlist)) { - /* Not exact match, rollback */ - result = DNS_R_NOTEXACT; - goto cleanup; - } - - if (rdatalist_length(&diff) == 0) { - result = DNS_R_UNCHANGED; - goto cleanup; - } - - CHECK(remove_from_ldap(&ldapdbnode->owner, ldapdb->ldap_db, &diff)); - - if (newrdataset != NULL) { - result = dns_rdatalist_tordataset(found_rdlist, newrdataset); - /* Use strong condition here, no other value is returned */ - INSIST(result == ISC_R_SUCCESS); - } - - free_rdatalist(ldapdb->common.mctx, &diff); - - return ISC_R_SUCCESS; - -cleanup: - /* Roll back changes */ - ISC_LIST_APPENDLIST(found_rdlist->rdata, diff.rdata, link); - - return result; -} - -static isc_result_t -deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - dns_rdatatype_t type, dns_rdatatype_t covers) -{ - UNUSED(db); - UNUSED(node); - UNUSED(version); - UNUSED(type); - UNUSED(covers); - - REQUIRE("deleterdataset" == NULL); - - return ISC_R_NOTIMPLEMENTED; -} - -static isc_boolean_t -issecure(dns_db_t *db) -{ - UNUSED(db); - - return ISC_FALSE; -} - -static unsigned int -nodecount(dns_db_t *db) -{ - UNUSED(db); - - return ISC_R_NOTIMPLEMENTED; -} - -static isc_boolean_t -ispersistent(dns_db_t *db) -{ - UNUSED(db); - - return ISC_R_NOTIMPLEMENTED; -} - -static void -overmem(dns_db_t *db, isc_boolean_t overmem) -{ - UNUSED(db); - UNUSED(overmem); -} - -static void -settask(dns_db_t *db, isc_task_t *task) -{ - UNUSED(db); - UNUSED(task); -} - -static isc_result_t -getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) -{ - ldapdb_t *ldapdb = (ldapdb_t *) db; - - return findnode(db, &ldapdb->common.origin, ISC_FALSE, nodep); -} - -static void -transfernode(dns_db_t *db, dns_dbnode_t **sourcep, dns_dbnode_t **targetp) -{ - UNUSED(db); - UNUSED(sourcep); - UNUSED(targetp); -} - -static isc_result_t -getnsec3parameters(dns_db_t *db, dns_dbversion_t *version, dns_hash_t *hash, - isc_uint8_t *flags, isc_uint16_t *iterations, - unsigned char *salt, size_t *salt_len) -{ - UNUSED(db); - UNUSED(version); - UNUSED(hash); - UNUSED(flags); - UNUSED(iterations); - UNUSED(salt); - UNUSED(salt_len); - - return ISC_R_NOTIMPLEMENTED; -} - -static isc_result_t -findnsec3node(dns_db_t *db, dns_name_t *name, isc_boolean_t create, - dns_dbnode_t **nodep) -{ - UNUSED(db); - UNUSED(name); - UNUSED(create); - UNUSED(nodep); - - return ISC_R_NOTIMPLEMENTED; -} - -static isc_result_t -setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, isc_stdtime_t resign) -{ - UNUSED(db); - UNUSED(rdataset); - UNUSED(resign); - - return ISC_R_NOTIMPLEMENTED; -} - -static isc_result_t -getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, dns_name_t *name) -{ - UNUSED(db); - UNUSED(rdataset); - UNUSED(name); - - return ISC_R_NOTIMPLEMENTED; -} - -static void -resigned(dns_db_t *db, dns_rdataset_t *rdataset, dns_dbversion_t *version) -{ - UNUSED(db); - UNUSED(rdataset); - UNUSED(version); -} - -static isc_boolean_t -isdnssec(dns_db_t *db) -{ - UNUSED(db); - - return ISC_R_NOTIMPLEMENTED; -} - -static dns_stats_t * -getrrsetstats(dns_db_t *db) -{ - UNUSED(db); - - return NULL; -} - -static dns_dbmethods_t ldapdb_methods = { - attach, - detach, - beginload, - endload, - dump, - currentversion, - newversion, - attachversion, - closeversion, - findnode, - find, - findzonecut, - attachnode, - detachnode, - expirenode, - printnode, - createiterator, - findrdataset, - allrdatasets, - addrdataset, - subtractrdataset, - deleterdataset, - issecure, - nodecount, - ispersistent, - overmem, - settask, - getoriginnode, - transfernode, - getnsec3parameters, - findnsec3node, - setsigningtime, - getsigningtime, - resigned, - isdnssec, - getrrsetstats -}; - -static isc_result_t -ldapdb_create(isc_mem_t *mctx, dns_name_t *name, dns_dbtype_t type, - dns_rdataclass_t rdclass, unsigned int argc, char *argv[], - void *driverarg, dns_db_t **dbp) -{ - ldapdb_t *ldapdb = NULL; - isc_result_t result; - int lock_is_initialized = 0; - - UNUSED(driverarg); /* Currently we don't need any data */ - - /* Database instance name. */ - REQUIRE(argc > 0); - - REQUIRE(type == dns_dbtype_zone); - REQUIRE(rdclass == dns_rdataclass_in); - REQUIRE(dbp != NULL && *dbp == NULL); - - CHECKED_MEM_GET_PTR(mctx, ldapdb); - ZERO_PTR(ldapdb); - - isc_mem_attach(mctx, &ldapdb->common.mctx); - - dns_name_init(&ldapdb->common.origin, NULL); - isc_ondestroy_init(&ldapdb->common.ondest); - - CHECK(isc_mutex_init(&ldapdb->lock)); - lock_is_initialized = 1; - - ldapdb->common.magic = DNS_DB_MAGIC; - ldapdb->common.impmagic = LDAPDB_MAGIC; - - ldapdb->common.methods = &ldapdb_methods; - ldapdb->common.attributes = 0; - ldapdb->common.rdclass = rdclass; - - CHECK(dns_name_dupwithoffsets(name, mctx, &ldapdb->common.origin)); - - CHECK(isc_refcount_init(&ldapdb->refs, 1)); - CHECK(manager_get_ldap_db_and_cache(argv[0], &ldapdb->ldap_db, - &ldapdb->ldap_cache)); - - *dbp = (dns_db_t *)ldapdb; - - return ISC_R_SUCCESS; - -cleanup: - if (ldapdb != NULL) { - if (lock_is_initialized) - DESTROYLOCK(&ldapdb->lock); - if (dns_name_dynamic(&ldapdb->common.origin)) - dns_name_free(&ldapdb->common.origin, mctx); - - isc_mem_putanddetach(&ldapdb->common.mctx, ldapdb, - sizeof(*ldapdb)); - } - - return result; -} - -static dns_dbimplementation_t *ldapdb_imp; -const char *ldapdb_impname = "dynamic-ldap"; - - -isc_result_t -dynamic_driver_init(isc_mem_t *mctx, const char *name, const char * const *argv, - dns_view_t *view, dns_zonemgr_t *zmgr) -{ - isc_result_t result; - ldap_db_t *ldap_db = NULL; - ldap_cache_t *ldap_cache = NULL; - - REQUIRE(mctx != NULL); - REQUIRE(name != NULL); - REQUIRE(argv != NULL); - REQUIRE(view != NULL); - - log_debug(2, "Registering dynamic ldap driver for %s.", name); - - /* Test argv. */ - int i = 0; - while (argv[i] != NULL) { - log_debug(2, "Arg: %s", argv[i]); - 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); - if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) - return result; - - CHECK(new_ldap_db(mctx, view, &ldap_db, argv)); - CHECK(new_ldap_cache(mctx, &ldap_cache, argv)); - CHECK(manager_add_db_instance(mctx, name, ldap_db, ldap_cache, zmgr)); - - /* - * XXX now fetch all zones and initialize ldap zone manager - * (periodically check for new zones) - * - manager has to share server zonemgr (ns_g_server->zonemgr) - * - * XXX manager has to this this for each zone: - * - dns_zone_create - * - dns_zone_setorigin - * - dns_zone_setview - * - dns_zone_setacache (probably not needed) - * - dns_zone_setclass - * - dns_zone_settype - * - dns_zone_setdbtype (note: pass all connection arguments etc here - - * will be used by ldapdb_create) - * - continue as in bin/server.c - ns_zone_configure() - * - dns_zonemgr_managezone - * - * zone has to be bind-ed to specified view: - * - dns_view_findzone (check if zone already exists) - * - dns_view_addzone - */ - - return ISC_R_SUCCESS; - -cleanup: - if (ldap_db != NULL) - destroy_ldap_db(&ldap_db); - if (ldap_cache != NULL) - destroy_ldap_cache(&ldap_cache); - - return result; -} - -void -dynamic_driver_destroy(void) -{ - dns_db_unregister(&ldapdb_imp); - destroy_manager(); -} |