From 9f0f90921e481c79d284a56e6bad27e23afc2a22 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Sat, 1 Jun 2013 10:18:25 +0200 Subject: [PATCH] dns: Delete dnsNode objects when they are empty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If an update leaves the dnsNode without any entries, the dnsNode object should be deleted. Thanks to Günter Kukkukk for his excellent debugging work on this one. This should fix bug #9559 Signed-off-by: Kai Blin --- python/samba/tests/dns.py | 117 +++++++++++++++++++++++++++++++++++++++++ source4/dns_server/dns_utils.c | 8 ++- 2 files changed, 124 insertions(+), 1 deletion(-) diff --git a/python/samba/tests/dns.py b/python/samba/tests/dns.py index a29025d..629d3fe 100644 --- a/python/samba/tests/dns.py +++ b/python/samba/tests/dns.py @@ -510,6 +510,123 @@ class TestDNSUpdates(DNSTest): response = self.dns_transaction_udp(p) self.assert_dns_rcode_equals(response, dns.DNS_RCODE_NXDOMAIN) + def test_readd_record(self): + "Test if adding, deleting and then readding a records works" + + NAME = "readdrec.%s" % self.get_dns_domain() + + # Create the record + p = self.make_name_packet(dns.DNS_OPCODE_UPDATE) + updates = [] + + name = self.get_dns_domain() + + u = self.make_name_question(name, dns.DNS_QTYPE_SOA, dns.DNS_QCLASS_IN) + updates.append(u) + self.finish_name_packet(p, updates) + + updates = [] + r = dns.res_rec() + r.name = NAME + r.rr_type = dns.DNS_QTYPE_TXT + r.rr_class = dns.DNS_QCLASS_IN + r.ttl = 900 + r.length = 0xffff + rdata = dns.txt_record() + rdata.txt = '"This is a test"' + r.rdata = rdata + updates.append(r) + p.nscount = len(updates) + p.nsrecs = updates + + response = self.dns_transaction_udp(p) + self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) + + # Now check the record is around + p = self.make_name_packet(dns.DNS_OPCODE_QUERY) + questions = [] + q = self.make_name_question(NAME, dns.DNS_QTYPE_TXT, dns.DNS_QCLASS_IN) + questions.append(q) + + self.finish_name_packet(p, questions) + response = self.dns_transaction_udp(p) + self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) + + # Now delete the record + p = self.make_name_packet(dns.DNS_OPCODE_UPDATE) + updates = [] + + name = self.get_dns_domain() + + u = self.make_name_question(name, dns.DNS_QTYPE_SOA, dns.DNS_QCLASS_IN) + updates.append(u) + self.finish_name_packet(p, updates) + + updates = [] + r = dns.res_rec() + r.name = NAME + r.rr_type = dns.DNS_QTYPE_TXT + r.rr_class = dns.DNS_QCLASS_NONE + r.ttl = 0 + r.length = 0xffff + rdata = dns.txt_record() + rdata.txt = '"This is a test"' + r.rdata = rdata + updates.append(r) + p.nscount = len(updates) + p.nsrecs = updates + + response = self.dns_transaction_udp(p) + self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) + + # check it's gone + p = self.make_name_packet(dns.DNS_OPCODE_QUERY) + questions = [] + + q = self.make_name_question(NAME, dns.DNS_QTYPE_TXT, dns.DNS_QCLASS_IN) + questions.append(q) + + self.finish_name_packet(p, questions) + response = self.dns_transaction_udp(p) + self.assert_dns_rcode_equals(response, dns.DNS_RCODE_NXDOMAIN) + + # recreate the record + p = self.make_name_packet(dns.DNS_OPCODE_UPDATE) + updates = [] + + name = self.get_dns_domain() + + u = self.make_name_question(name, dns.DNS_QTYPE_SOA, dns.DNS_QCLASS_IN) + updates.append(u) + self.finish_name_packet(p, updates) + + updates = [] + r = dns.res_rec() + r.name = NAME + r.rr_type = dns.DNS_QTYPE_TXT + r.rr_class = dns.DNS_QCLASS_IN + r.ttl = 900 + r.length = 0xffff + rdata = dns.txt_record() + rdata.txt = '"This is a test"' + r.rdata = rdata + updates.append(r) + p.nscount = len(updates) + p.nsrecs = updates + + response = self.dns_transaction_udp(p) + self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) + + # Now check the record is around + p = self.make_name_packet(dns.DNS_OPCODE_QUERY) + questions = [] + q = self.make_name_question(NAME, dns.DNS_QTYPE_TXT, dns.DNS_QCLASS_IN) + questions.append(q) + + self.finish_name_packet(p, questions) + response = self.dns_transaction_udp(p) + self.assert_dns_rcode_equals(response, dns.DNS_RCODE_OK) + def test_update_add_mx_record(self): "test adding MX records works" p = self.make_name_packet(dns.DNS_OPCODE_UPDATE) diff --git a/source4/dns_server/dns_utils.c b/source4/dns_server/dns_utils.c index 74f7a29..eea3dfd 100644 --- a/source4/dns_server/dns_utils.c +++ b/source4/dns_server/dns_utils.c @@ -271,7 +271,13 @@ WERROR dns_replace_records(struct dns_server *dns, if (needs_add) { return WERR_OK; } - /* TODO: Delete object? */ + /* No entries left, delete the dnsNode object */ + ret = ldb_delete(dns->samdb, msg->dn); + if (ret != LDB_SUCCESS) { + DEBUG(0, ("Deleting record failed; %d\n", ret)); + return DNS_ERR(SERVER_FAILURE); + } + return WERR_OK; } if (needs_add) { -- 1.8.1.2