summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Tkac <atkac@redhat.com>2009-03-13 22:34:10 +0100
committerMartin Nagy <mnagy@redhat.com>2009-03-16 17:59:52 +0100
commitcf520c2637bc08a0185b93f041bc3504d3053f9e (patch)
tree5ca6dc534d403591fed26a000abea9a83ce243f6
parenteb177ee306596112f87c258edfe8ab98491ead03 (diff)
downloadldap_driver_testing-cf520c2637bc08a0185b93f041bc3504d3053f9e.tar.gz
ldap_driver_testing-cf520c2637bc08a0185b93f041bc3504d3053f9e.tar.xz
ldap_driver_testing-cf520c2637bc08a0185b93f041bc3504d3053f9e.zip
Implement subtractrdataset function.
-rw-r--r--ldap_driver.c106
1 files changed, 85 insertions, 21 deletions
diff --git a/ldap_driver.c b/ldap_driver.c
index dfb7852..75b4942 100644
--- a/ldap_driver.c
+++ b/ldap_driver.c
@@ -71,6 +71,7 @@ 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
write_to_ldap(dns_name_t *owner, ldapdb_t *ldapdb, dns_rdatalist_t *rdlist)
@@ -653,20 +654,19 @@ rdatalist_removedups(dns_rdatalist_t *rdlist1, dns_rdatalist_t *rdlist2,
while (rdata1 != NULL) {
rdata2 = HEAD(rdlist2->rdata);
while (rdata2 != NULL) {
- if (dns_rdata_compare(rdata1, rdata2) == 0) {
- /* same rdata has been found */
- if (rm_from1) {
- APPEND(diff->rdata, rdata1, link);
- ISC_LIST_UNLINK(rdlist1->rdata, rdata1,
- link);
- } else {
- APPEND(diff->rdata, rdata2, link);
- ISC_LIST_UNLINK(rdlist2->rdata, rdata2,
- link);
- }
- break;
+ if (dns_rdata_compare(rdata1, rdata2) != 0) {
+ rdata2 = NEXT(rdata2, link);
+ continue;
}
- rdata2 = NEXT(rdata2, link);
+ /* 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);
}
@@ -769,21 +769,85 @@ cleanup:
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)
{
- UNUSED(db);
- UNUSED(node);
- UNUSED(version);
- UNUSED(rdataset);
- UNUSED(options);
- UNUSED(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("subtractrdataset" == NULL);
+ REQUIRE(version == ldapdb_version);
- return ISC_R_NOTIMPLEMENTED;
+ 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;
+ }
+
+ result = remove_from_ldap(&ldapdbnode->owner, ldapdb, &diff);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ 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