The Samba-Bugzilla – Attachment 10244 Details for
Bug 10749
Support for DNS_TYPE_TOMBSTONE records
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patches for v4-0-test
tmp40.diff (text/plain), 112.72 KB, created by
Stefan Metzmacher
on 2014-09-01 10:28:28 UTC
(
hide
)
Description:
Patches for v4-0-test
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2014-09-01 10:28:28 UTC
Size:
112.72 KB
patch
obsolete
>From 015acf69bae1ae746b5d315ced62fd691f8be735 Mon Sep 17 00:00:00 2001 >From: Stefan Gohmann <gohmann@univention.de> >Date: Fri, 8 Mar 2013 20:57:31 +0100 >Subject: [PATCH 01/22] s4-dns: dlz_bind9: Check result to avoid segfault > >We saw this issue in a customer environment with many CNF objects. I >wasn't able to reproduce it, but I got the following core dump: > > (gdb) directory samba4-4.0.0~rc6/source4/dns_server/ > Source directories searched: /root/samba4-4.0.0~rc6/source4/dns_server:$cdir:$cwd > (gdb) bt > #0 0xb4b0bc13 in dlz_lookup_types (state=0x9648e48, zone=0xb659b9a8 "xxxxxx.xxxxx.de", name=0xb659bda8 "client9173", lookup=0xb6db7588, types=0x0) at ../source4/dns_server/dlz_bind9.c:830 > #1 0xb4b0bdb8 in dlz_lookup (zone=0xb659b9a8 "xxxxxx.xxxxx.de", name=0xb659bda8 "client9173", dbdata=0x9648e48, lookup=0xb6db7588) at ../source4/dns_server/dlz_bind9.c:875 > #2 0x080b43d8 in dlopen_dlz_lookup () > #3 0xb7701755 in findnode () from /usr/lib/libdns.so.81 > #4 0xb7701d22 in find () from /usr/lib/libdns.so.81 > #5 0xb7639e5f in dns_db_find () from /usr/lib/libdns.so.81 > #6 0x08075476 in query_find () > #7 0x0807acb9 in ns_query_start () > #8 0x08060712 in client_request () > #9 0xb743022b in run () from /usr/lib/libisc.so.81 > #10 0xb7216955 in start_thread () from /lib/i686/cmov/libpthread.so.0 > #11 0xb706c1de in clone () from /lib/i686/cmov/libc.so.6 > (gdb) f 0 > #0 0xb4b0bc13 in dlz_lookup_types (state=0x9648e48, zone=0xb659b9a8 "xxxxxx.xxxxx.de", name=0xb659bda8 "client9173", lookup=0xb6db7588, types=0x0) at ../source4/dns_server/dlz_bind9.c:830 > 830 el = ldb_msg_find_element(res->msgs[0], "dnsRecord"); > (gdb) p res->msgs > $1 = (struct ldb_message **) 0x0 > (gdb) p res->count > $2 = 0 > (gdb) > >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 666a5630ef3b03640089a0b6e81bf578b91b88ab) >--- > source4/dns_server/dlz_bind9.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c >index 689ed45..ac41dd0 100644 >--- a/source4/dns_server/dlz_bind9.c >+++ b/source4/dns_server/dlz_bind9.c >@@ -825,7 +825,7 @@ static isc_result_t dlz_lookup_types(struct dlz_bind9_data *state, > break; > } > } >- if (ret != LDB_SUCCESS) { >+ if (ret != LDB_SUCCESS || res->count == 0) { > talloc_free(tmp_ctx); > return ISC_R_NOTFOUND; > } >-- >1.9.1 > > >From 55da107ccfb6f3f02525f19deb6f1486eca7e28e Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 30 Jul 2014 17:55:57 +0200 >Subject: [PATCH 02/22] s4:dns_server: handle > WERR_DNS_ERROR_NAME_DOES_NOT_EXIST in werr_to_dns_err() > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit deb21a9afe77591743fda522355a5a9eb08fb27b) >--- > source4/dns_server/dns_utils.c | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/source4/dns_server/dns_utils.c b/source4/dns_server/dns_utils.c >index eea3dfd..052c626 100644 >--- a/source4/dns_server/dns_utils.c >+++ b/source4/dns_server/dns_utils.c >@@ -40,6 +40,8 @@ uint8_t werr_to_dns_err(WERROR werr) > return DNS_RCODE_SERVFAIL; > } else if (W_ERROR_EQUAL(DNS_ERR(NAME_ERROR), werr)) { > return DNS_RCODE_NXDOMAIN; >+ } else if (W_ERROR_EQUAL(WERR_DNS_ERROR_NAME_DOES_NOT_EXIST, werr)) { >+ return DNS_RCODE_NXDOMAIN; > } else if (W_ERROR_EQUAL(DNS_ERR(NOT_IMPLEMENTED), werr)) { > return DNS_RCODE_NOTIMP; > } else if (W_ERROR_EQUAL(DNS_ERR(REFUSED), werr)) { >-- >1.9.1 > > >From 2d3453e096bf2a048b62fb542d0e50c7c1653890 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 31 Jul 2014 08:19:50 +0200 >Subject: [PATCH 03/22] s4:dns_server: map LDB_ERR_NO_SUCH_OBJECT to > WERR_DNS_ERROR_NAME_DOES_NOT_EXIST > >This is the correct fix for commit 8b24c43b382740106474e26dec59e1419ba77306 >and Bug: https://bugzilla.samba.org/show_bug.cgi?id=9559 > >With this change we have a consistent behavior between internal server >and the bind dlz module. We keep a dangling LDAP object without >dnsRecord attribute arround forever. This will be fixed in the following >commits. > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit d0f424a23dc915d9fce625438d2bd63519757cba) >--- > source4/dns_server/dns_update.c | 21 ++++++++++++++++----- > source4/dns_server/dns_utils.c | 17 ++++++++--------- > 2 files changed, 24 insertions(+), 14 deletions(-) > >diff --git a/source4/dns_server/dns_update.c b/source4/dns_server/dns_update.c >index 8be3564..d2d90a5 100644 >--- a/source4/dns_server/dns_update.c >+++ b/source4/dns_server/dns_update.c >@@ -79,6 +79,9 @@ static WERROR check_one_prerequisite(struct dns_server *dns, > /* > */ > werror = dns_lookup_records(dns, mem_ctx, dn, &ans, &acount); >+ if (W_ERROR_EQUAL(werror, WERR_DNS_ERROR_NAME_DOES_NOT_EXIST)) { >+ return DNS_ERR(NAME_ERROR); >+ } > W_ERROR_NOT_OK_RETURN(werror); > > if (acount == 0) { >@@ -88,6 +91,9 @@ static WERROR check_one_prerequisite(struct dns_server *dns, > /* > */ > werror = dns_lookup_records(dns, mem_ctx, dn, &ans, &acount); >+ if (W_ERROR_EQUAL(werror, WERR_DNS_ERROR_NAME_DOES_NOT_EXIST)) { >+ return DNS_ERR(NXRRSET); >+ } > if (W_ERROR_EQUAL(werror, DNS_ERR(NAME_ERROR))) { > return DNS_ERR(NXRRSET); > } >@@ -128,10 +134,11 @@ static WERROR check_one_prerequisite(struct dns_server *dns, > /* > */ > werror = dns_lookup_records(dns, mem_ctx, dn, &ans, &acount); >+ if (W_ERROR_EQUAL(werror, WERR_DNS_ERROR_NAME_DOES_NOT_EXIST)) { >+ werror = WERR_OK; >+ } > if (W_ERROR_EQUAL(werror, DNS_ERR(NAME_ERROR))) { > werror = WERR_OK; >- ans = NULL; >- acount = 0; > } > > for (i = 0; i < acount; i++) { >@@ -160,6 +167,9 @@ static WERROR check_one_prerequisite(struct dns_server *dns, > *final_result = false; > > werror = dns_lookup_records(dns, mem_ctx, dn, &ans, &acount); >+ if (W_ERROR_EQUAL(werror, WERR_DNS_ERROR_NAME_DOES_NOT_EXIST)) { >+ return DNS_ERR(NXRRSET); >+ } > if (W_ERROR_EQUAL(werror, DNS_ERR(NAME_ERROR))) { > return DNS_ERR(NXRRSET); > } >@@ -418,12 +428,13 @@ static WERROR handle_one_update(struct dns_server *dns, > W_ERROR_NOT_OK_RETURN(werror); > > werror = dns_lookup_records(dns, mem_ctx, dn, &recs, &rcount); >- if (W_ERROR_EQUAL(werror, DNS_ERR(NAME_ERROR))) { >- recs = NULL; >- rcount = 0; >+ if (W_ERROR_EQUAL(werror, WERR_DNS_ERROR_NAME_DOES_NOT_EXIST)) { > needs_add = true; > werror = WERR_OK; > } >+ if (W_ERROR_EQUAL(werror, DNS_ERR(NAME_ERROR))) { >+ werror = WERR_OK; >+ } > W_ERROR_NOT_OK_RETURN(werror); > > if (update->rr_class == zone->question_class) { >diff --git a/source4/dns_server/dns_utils.c b/source4/dns_server/dns_utils.c >index 052c626..f8dd6d1 100644 >--- a/source4/dns_server/dns_utils.c >+++ b/source4/dns_server/dns_utils.c >@@ -191,8 +191,14 @@ WERROR dns_lookup_records(struct dns_server *dns, > struct ldb_message *msg = NULL; > struct dnsp_DnssrvRpcRecord *recs; > >+ *records = NULL; >+ *rec_count = 0; >+ > ret = dsdb_search_one(dns->samdb, mem_ctx, &msg, dn, > LDB_SCOPE_BASE, attrs, 0, "%s", "(objectClass=dnsNode)"); >+ if (ret == LDB_ERR_NO_SUCH_OBJECT) { >+ return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST; >+ } > if (ret != LDB_SUCCESS) { > /* TODO: we need to check if there's a glue record we need to > * create a referral to */ >@@ -201,8 +207,6 @@ WERROR dns_lookup_records(struct dns_server *dns, > > el = ldb_msg_find_element(msg, attrs[0]); > if (el == NULL) { >- *records = NULL; >- *rec_count = 0; > return DNS_ERR(NAME_ERROR); > } > >@@ -273,13 +277,8 @@ WERROR dns_replace_records(struct dns_server *dns, > if (needs_add) { > return WERR_OK; > } >- /* 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; >+ /* TODO: Delete object? */ >+ el->flags = LDB_FLAG_MOD_DELETE; > } > > if (needs_add) { >-- >1.9.1 > > >From e7024f6a93d4d51a103b2ade6daa9e64de8edb31 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 30 Jul 2014 08:01:11 +0200 >Subject: [PATCH 04/22] s4:dns_server: split out a private 'dnsserver_common' > library > >This will contain common code for the internal dns server, the dlz_bind9 module >and the rpc dns management server. > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(similar to commit 99d5a5ead4f33723c25e8716a79d34b53822521e) >--- > source4/dns_server/dns_server.h | 4 +-- > source4/dns_server/dns_utils.c | 33 ------------------ > source4/dns_server/dnsserver_common.c | 65 +++++++++++++++++++++++++++++++++++ > source4/dns_server/dnsserver_common.h | 28 +++++++++++++++ > source4/dns_server/wscript_build | 8 ++++- > 5 files changed, 102 insertions(+), 36 deletions(-) > create mode 100644 source4/dns_server/dnsserver_common.c > create mode 100644 source4/dns_server/dnsserver_common.h > >diff --git a/source4/dns_server/dns_server.h b/source4/dns_server/dns_server.h >index efe4db8..2459616 100644 >--- a/source4/dns_server/dns_server.h >+++ b/source4/dns_server/dns_server.h >@@ -86,7 +86,6 @@ WERROR dns_server_process_update(struct dns_server *dns, > struct dns_res_rec **updates, uint16_t *update_count, > struct dns_res_rec **additional, uint16_t *arcount); > >-uint8_t werr_to_dns_err(WERROR werror); > bool dns_name_match(const char *zone, const char *name, size_t *host_part_len); > bool dns_name_equal(const char *name1, const char *name2); > bool dns_records_match(struct dnsp_DnssrvRpcRecord *rec1, >@@ -124,5 +123,6 @@ WERROR dns_sign_tsig(struct dns_server *dns, > struct dns_name_packet *packet, > uint16_t error); > >-#define DNS_ERR(err_str) WERR_DNS_ERROR_RCODE_##err_str >+#include "source4/dns_server/dnsserver_common.h" >+ > #endif /* __DNS_SERVER_H__ */ >diff --git a/source4/dns_server/dns_utils.c b/source4/dns_server/dns_utils.c >index f8dd6d1..77c410b 100644 >--- a/source4/dns_server/dns_utils.c >+++ b/source4/dns_server/dns_utils.c >@@ -30,39 +30,6 @@ > #include "dsdb/common/util.h" > #include "dns_server/dns_server.h" > >-uint8_t werr_to_dns_err(WERROR werr) >-{ >- if (W_ERROR_EQUAL(WERR_OK, werr)) { >- return DNS_RCODE_OK; >- } else if (W_ERROR_EQUAL(DNS_ERR(FORMAT_ERROR), werr)) { >- return DNS_RCODE_FORMERR; >- } else if (W_ERROR_EQUAL(DNS_ERR(SERVER_FAILURE), werr)) { >- return DNS_RCODE_SERVFAIL; >- } else if (W_ERROR_EQUAL(DNS_ERR(NAME_ERROR), werr)) { >- return DNS_RCODE_NXDOMAIN; >- } else if (W_ERROR_EQUAL(WERR_DNS_ERROR_NAME_DOES_NOT_EXIST, werr)) { >- return DNS_RCODE_NXDOMAIN; >- } else if (W_ERROR_EQUAL(DNS_ERR(NOT_IMPLEMENTED), werr)) { >- return DNS_RCODE_NOTIMP; >- } else if (W_ERROR_EQUAL(DNS_ERR(REFUSED), werr)) { >- return DNS_RCODE_REFUSED; >- } else if (W_ERROR_EQUAL(DNS_ERR(YXDOMAIN), werr)) { >- return DNS_RCODE_YXDOMAIN; >- } else if (W_ERROR_EQUAL(DNS_ERR(YXRRSET), werr)) { >- return DNS_RCODE_YXRRSET; >- } else if (W_ERROR_EQUAL(DNS_ERR(NXRRSET), werr)) { >- return DNS_RCODE_NXRRSET; >- } else if (W_ERROR_EQUAL(DNS_ERR(NOTAUTH), werr)) { >- return DNS_RCODE_NOTAUTH; >- } else if (W_ERROR_EQUAL(DNS_ERR(NOTZONE), werr)) { >- return DNS_RCODE_NOTZONE; >- } else if (W_ERROR_EQUAL(DNS_ERR(BADKEY), werr)) { >- return DNS_RCODE_BADKEY; >- } >- DEBUG(5, ("No mapping exists for %s\n", win_errstr(werr))); >- return DNS_RCODE_SERVFAIL; >-} >- > bool dns_name_match(const char *zone, const char *name, size_t *host_part_len) > { > size_t zl = strlen(zone); >diff --git a/source4/dns_server/dnsserver_common.c b/source4/dns_server/dnsserver_common.c >new file mode 100644 >index 0000000..f5c1903 >--- /dev/null >+++ b/source4/dns_server/dnsserver_common.c >@@ -0,0 +1,65 @@ >+/* >+ Unix SMB/CIFS implementation. >+ >+ DNS server utils >+ >+ Copyright (C) 2010 Kai Blin >+ Copyright (C) 2014 Stefan Metzmacher >+ >+ 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; either version 3 of the License, or >+ (at your option) any later version. >+ >+ 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, see <http://www.gnu.org/licenses/>. >+*/ >+ >+#include "includes.h" >+#include "libcli/util/ntstatus.h" >+#include "libcli/util/werror.h" >+#include "librpc/ndr/libndr.h" >+#include "librpc/gen_ndr/ndr_dns.h" >+#include "librpc/gen_ndr/ndr_dnsp.h" >+#include <ldb.h> >+#include "dsdb/samdb/samdb.h" >+#include "dsdb/common/util.h" >+#include "dns_server/dnsserver_common.h" >+ >+uint8_t werr_to_dns_err(WERROR werr) >+{ >+ if (W_ERROR_EQUAL(WERR_OK, werr)) { >+ return DNS_RCODE_OK; >+ } else if (W_ERROR_EQUAL(DNS_ERR(FORMAT_ERROR), werr)) { >+ return DNS_RCODE_FORMERR; >+ } else if (W_ERROR_EQUAL(DNS_ERR(SERVER_FAILURE), werr)) { >+ return DNS_RCODE_SERVFAIL; >+ } else if (W_ERROR_EQUAL(DNS_ERR(NAME_ERROR), werr)) { >+ return DNS_RCODE_NXDOMAIN; >+ } else if (W_ERROR_EQUAL(WERR_DNS_ERROR_NAME_DOES_NOT_EXIST, werr)) { >+ return DNS_RCODE_NXDOMAIN; >+ } else if (W_ERROR_EQUAL(DNS_ERR(NOT_IMPLEMENTED), werr)) { >+ return DNS_RCODE_NOTIMP; >+ } else if (W_ERROR_EQUAL(DNS_ERR(REFUSED), werr)) { >+ return DNS_RCODE_REFUSED; >+ } else if (W_ERROR_EQUAL(DNS_ERR(YXDOMAIN), werr)) { >+ return DNS_RCODE_YXDOMAIN; >+ } else if (W_ERROR_EQUAL(DNS_ERR(YXRRSET), werr)) { >+ return DNS_RCODE_YXRRSET; >+ } else if (W_ERROR_EQUAL(DNS_ERR(NXRRSET), werr)) { >+ return DNS_RCODE_NXRRSET; >+ } else if (W_ERROR_EQUAL(DNS_ERR(NOTAUTH), werr)) { >+ return DNS_RCODE_NOTAUTH; >+ } else if (W_ERROR_EQUAL(DNS_ERR(NOTZONE), werr)) { >+ return DNS_RCODE_NOTZONE; >+ } else if (W_ERROR_EQUAL(DNS_ERR(BADKEY), werr)) { >+ return DNS_RCODE_BADKEY; >+ } >+ DEBUG(5, ("No mapping exists for %s\n", win_errstr(werr))); >+ return DNS_RCODE_SERVFAIL; >+} >diff --git a/source4/dns_server/dnsserver_common.h b/source4/dns_server/dnsserver_common.h >new file mode 100644 >index 0000000..41febe2 >--- /dev/null >+++ b/source4/dns_server/dnsserver_common.h >@@ -0,0 +1,28 @@ >+/* >+ Unix SMB/CIFS implementation. >+ >+ DNS server utils >+ >+ Copyright (C) 2014 Stefan Metzmacher >+ >+ 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; either version 3 of the License, or >+ (at your option) any later version. >+ >+ 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, see <http://www.gnu.org/licenses/>. >+*/ >+ >+#ifndef __DNSSERVER_COMMON_H__ >+#define __DNSSERVER_COMMON_H__ >+ >+uint8_t werr_to_dns_err(WERROR werr); >+#define DNS_ERR(err_str) WERR_DNS_ERROR_RCODE_##err_str >+ >+#endif /* __DNSSERVER_COMMON_H__ */ >diff --git a/source4/dns_server/wscript_build b/source4/dns_server/wscript_build >index 280f8de..66e6b72 100644 >--- a/source4/dns_server/wscript_build >+++ b/source4/dns_server/wscript_build >@@ -1,10 +1,16 @@ > #!/usr/bin/env python > >+bld.SAMBA_LIBRARY('dnsserver_common', >+ source='dnsserver_common.c', >+ deps='samba-util errors ldbsamba clidns', >+ private_library=True, >+ ) >+ > bld.SAMBA_MODULE('service_dns', > source='dns_server.c dns_query.c dns_update.c dns_utils.c dns_crypto.c', > subsystem='service', > init_function='server_service_dns_init', >- deps='samba-hostconfig LIBTSOCKET LIBSAMBA_TSOCKET ldbsamba clidns gensec auth samba_server_gensec', >+ deps='samba-hostconfig LIBTSOCKET LIBSAMBA_TSOCKET ldbsamba clidns gensec auth samba_server_gensec dnsserver_common', > local_include=False, > internal_module=False, > enabled=bld.AD_DC_BUILD_IS_ENABLED() >-- >1.9.1 > > >From 65126cbd73550f49aa797ee25b19580fe9d77045 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 30 Jul 2014 08:24:10 +0200 >Subject: [PATCH 05/22] s4:dns_server: split out dns_common_extract() and > dns_common_lookup() > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 342a087349f8a10833338a3fa49fbd4d4d29f3e5) >--- > source4/dns_server/dns_utils.c | 43 +------------------ > source4/dns_server/dnsserver_common.c | 78 +++++++++++++++++++++++++++++++++++ > source4/dns_server/dnsserver_common.h | 13 ++++++ > 3 files changed, 92 insertions(+), 42 deletions(-) > >diff --git a/source4/dns_server/dns_utils.c b/source4/dns_server/dns_utils.c >index 77c410b..69f9bd9 100644 >--- a/source4/dns_server/dns_utils.c >+++ b/source4/dns_server/dns_utils.c >@@ -151,48 +151,7 @@ WERROR dns_lookup_records(struct dns_server *dns, > struct dnsp_DnssrvRpcRecord **records, > uint16_t *rec_count) > { >- static const char * const attrs[] = { "dnsRecord", NULL}; >- struct ldb_message_element *el; >- uint16_t ri; >- int ret; >- struct ldb_message *msg = NULL; >- struct dnsp_DnssrvRpcRecord *recs; >- >- *records = NULL; >- *rec_count = 0; >- >- ret = dsdb_search_one(dns->samdb, mem_ctx, &msg, dn, >- LDB_SCOPE_BASE, attrs, 0, "%s", "(objectClass=dnsNode)"); >- if (ret == LDB_ERR_NO_SUCH_OBJECT) { >- return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST; >- } >- if (ret != LDB_SUCCESS) { >- /* TODO: we need to check if there's a glue record we need to >- * create a referral to */ >- return DNS_ERR(NAME_ERROR); >- } >- >- el = ldb_msg_find_element(msg, attrs[0]); >- if (el == NULL) { >- return DNS_ERR(NAME_ERROR); >- } >- >- recs = talloc_zero_array(mem_ctx, struct dnsp_DnssrvRpcRecord, el->num_values); >- W_ERROR_HAVE_NO_MEMORY(recs); >- for (ri = 0; ri < el->num_values; ri++) { >- struct ldb_val *v = &el->values[ri]; >- enum ndr_err_code ndr_err; >- >- ndr_err = ndr_pull_struct_blob(v, recs, &recs[ri], >- (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord); >- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >- DEBUG(0, ("Failed to grab dnsp_DnssrvRpcRecord\n")); >- return DNS_ERR(SERVER_FAILURE); >- } >- } >- *records = recs; >- *rec_count = el->num_values; >- return WERR_OK; >+ return dns_common_lookup(dns->samdb, mem_ctx, dn, records, rec_count); > } > > WERROR dns_replace_records(struct dns_server *dns, >diff --git a/source4/dns_server/dnsserver_common.c b/source4/dns_server/dnsserver_common.c >index f5c1903..5c3cafb 100644 >--- a/source4/dns_server/dnsserver_common.c >+++ b/source4/dns_server/dnsserver_common.c >@@ -63,3 +63,81 @@ uint8_t werr_to_dns_err(WERROR werr) > DEBUG(5, ("No mapping exists for %s\n", win_errstr(werr))); > return DNS_RCODE_SERVFAIL; > } >+ >+WERROR dns_common_extract(const struct ldb_message_element *el, >+ TALLOC_CTX *mem_ctx, >+ struct dnsp_DnssrvRpcRecord **records, >+ uint16_t *num_records) >+{ >+ uint16_t ri; >+ struct dnsp_DnssrvRpcRecord *recs; >+ >+ *records = NULL; >+ *num_records = 0; >+ >+ recs = talloc_zero_array(mem_ctx, struct dnsp_DnssrvRpcRecord, >+ el->num_values); >+ if (recs == NULL) { >+ return WERR_NOMEM; >+ } >+ for (ri = 0; ri < el->num_values; ri++) { >+ struct ldb_val *v = &el->values[ri]; >+ enum ndr_err_code ndr_err; >+ >+ ndr_err = ndr_pull_struct_blob(v, recs, &recs[ri], >+ (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord); >+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >+ TALLOC_FREE(recs); >+ DEBUG(0, ("Failed to grab dnsp_DnssrvRpcRecord\n")); >+ return DNS_ERR(SERVER_FAILURE); >+ } >+ } >+ *records = recs; >+ *num_records = el->num_values; >+ return WERR_OK; >+} >+ >+WERROR dns_common_lookup(struct ldb_context *samdb, >+ TALLOC_CTX *mem_ctx, >+ struct ldb_dn *dn, >+ struct dnsp_DnssrvRpcRecord **records, >+ uint16_t *num_records) >+{ >+ static const char * const attrs[] = { >+ "dnsRecord", >+ NULL >+ }; >+ int ret; >+ WERROR werr; >+ struct ldb_message *msg = NULL; >+ struct ldb_message_element *el; >+ >+ *records = NULL; >+ *num_records = 0; >+ >+ ret = dsdb_search_one(samdb, mem_ctx, &msg, dn, >+ LDB_SCOPE_BASE, attrs, 0, >+ "(objectClass=dnsNode)"); >+ if (ret == LDB_ERR_NO_SUCH_OBJECT) { >+ return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST; >+ } >+ if (ret != LDB_SUCCESS) { >+ /* TODO: we need to check if there's a glue record we need to >+ * create a referral to */ >+ return DNS_ERR(NAME_ERROR); >+ } >+ >+ el = ldb_msg_find_element(msg, "dnsRecord"); >+ if (el == NULL) { >+ TALLOC_FREE(msg); >+ return DNS_ERR(NAME_ERROR); >+ } >+ >+ werr = dns_common_extract(el, mem_ctx, records, num_records); >+ TALLOC_FREE(msg); >+ if (!W_ERROR_IS_OK(werr)) { >+ return werr; >+ } >+ >+ return WERR_OK; >+} >diff --git a/source4/dns_server/dnsserver_common.h b/source4/dns_server/dnsserver_common.h >index 41febe2..4731780 100644 >--- a/source4/dns_server/dnsserver_common.h >+++ b/source4/dns_server/dnsserver_common.h >@@ -25,4 +25,17 @@ > uint8_t werr_to_dns_err(WERROR werr); > #define DNS_ERR(err_str) WERR_DNS_ERROR_RCODE_##err_str > >+struct ldb_message_element; >+ >+WERROR dns_common_extract(const struct ldb_message_element *el, >+ TALLOC_CTX *mem_ctx, >+ struct dnsp_DnssrvRpcRecord **records, >+ uint16_t *num_records); >+ >+WERROR dns_common_lookup(struct ldb_context *samdb, >+ TALLOC_CTX *mem_ctx, >+ struct ldb_dn *dn, >+ struct dnsp_DnssrvRpcRecord **records, >+ uint16_t *num_records); >+ > #endif /* __DNSSERVER_COMMON_H__ */ >-- >1.9.1 > > >From ca09f113770c62b337e2d117790445547b3c4b21 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 31 Jul 2014 11:32:02 +0200 >Subject: [PATCH 06/22] s4:dns_server: remove const from dns_replace_records() > >All callers are find we the record array gets modified. > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 7e7df78bd7ae5575da7443b45c0e2e4167eebde2) >--- > source4/dns_server/dns_server.h | 2 +- > source4/dns_server/dns_utils.c | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > >diff --git a/source4/dns_server/dns_server.h b/source4/dns_server/dns_server.h >index 2459616..12ccc9b 100644 >--- a/source4/dns_server/dns_server.h >+++ b/source4/dns_server/dns_server.h >@@ -101,7 +101,7 @@ WERROR dns_replace_records(struct dns_server *dns, > TALLOC_CTX *mem_ctx, > struct ldb_dn *dn, > bool needs_add, >- const struct dnsp_DnssrvRpcRecord *records, >+ struct dnsp_DnssrvRpcRecord *records, > uint16_t rec_count); > WERROR dns_name2dn(struct dns_server *dns, > TALLOC_CTX *mem_ctx, >diff --git a/source4/dns_server/dns_utils.c b/source4/dns_server/dns_utils.c >index 69f9bd9..3882af4 100644 >--- a/source4/dns_server/dns_utils.c >+++ b/source4/dns_server/dns_utils.c >@@ -158,7 +158,7 @@ WERROR dns_replace_records(struct dns_server *dns, > TALLOC_CTX *mem_ctx, > struct ldb_dn *dn, > bool needs_add, >- const struct dnsp_DnssrvRpcRecord *records, >+ struct dnsp_DnssrvRpcRecord *records, > uint16_t rec_count) > { > struct ldb_message_element *el; >-- >1.9.1 > > >From 7a9adaaffe16b6fa3515540043aecf8fd28e3e46 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 30 Jul 2014 18:27:56 +0200 >Subject: [PATCH 07/22] s4:dns_server: split out dns_common_replace() > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 0689e795e073008d2ad539c0ef5ddbdc6d9efdac) >--- > source4/dns_server/dns_update.c | 2 - > source4/dns_server/dns_utils.c | 70 ++----------------------------- > source4/dns_server/dnsserver_common.c | 78 +++++++++++++++++++++++++++++++++++ > source4/dns_server/dnsserver_common.h | 8 ++++ > 4 files changed, 90 insertions(+), 68 deletions(-) > >diff --git a/source4/dns_server/dns_update.c b/source4/dns_server/dns_update.c >index d2d90a5..a82303b 100644 >--- a/source4/dns_server/dns_update.c >+++ b/source4/dns_server/dns_update.c >@@ -309,8 +309,6 @@ static WERROR dns_rr_to_dnsp(TALLOC_CTX *mem_ctx, > r->wType = rrec->rr_type; > r->dwTtlSeconds = rrec->ttl; > r->rank = DNS_RANK_ZONE; >- /* TODO: Autogenerate this somehow */ >- r->dwSerial = 110; > > /* If we get QCLASS_ANY, we're done here */ > if (rrec->rr_class == DNS_QCLASS_ANY) { >diff --git a/source4/dns_server/dns_utils.c b/source4/dns_server/dns_utils.c >index 3882af4..b966dec 100644 >--- a/source4/dns_server/dns_utils.c >+++ b/source4/dns_server/dns_utils.c >@@ -161,72 +161,10 @@ WERROR dns_replace_records(struct dns_server *dns, > struct dnsp_DnssrvRpcRecord *records, > uint16_t rec_count) > { >- struct ldb_message_element *el; >- uint16_t i; >- int ret; >- struct ldb_message *msg = NULL; >- >- msg = ldb_msg_new(mem_ctx); >- W_ERROR_HAVE_NO_MEMORY(msg); >- >- msg->dn = dn; >- >- ret = ldb_msg_add_empty(msg, "dnsRecord", LDB_FLAG_MOD_REPLACE, &el); >- if (ret != LDB_SUCCESS) { >- return DNS_ERR(SERVER_FAILURE); >- } >- >- el->values = talloc_zero_array(el, struct ldb_val, rec_count); >- if (rec_count > 0) { >- W_ERROR_HAVE_NO_MEMORY(el->values); >- } >- >- for (i = 0; i < rec_count; i++) { >- static const struct dnsp_DnssrvRpcRecord zero; >- struct ldb_val *v = &el->values[el->num_values]; >- enum ndr_err_code ndr_err; >- >- if (memcmp(&records[i], &zero, sizeof(zero)) == 0) { >- continue; >- } >- ndr_err = ndr_push_struct_blob(v, el->values, &records[i], >- (ndr_push_flags_fn_t)ndr_push_dnsp_DnssrvRpcRecord); >- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >- DEBUG(0, ("Failed to grab dnsp_DnssrvRpcRecord\n")); >- return DNS_ERR(SERVER_FAILURE); >- } >- el->num_values++; >- } >- >- >- if (el->num_values == 0) { >- if (needs_add) { >- return WERR_OK; >- } >- /* TODO: Delete object? */ >- el->flags = LDB_FLAG_MOD_DELETE; >- } >- >- if (needs_add) { >- ret = ldb_msg_add_string(msg, "objectClass", "dnsNode"); >- if (ret != LDB_SUCCESS) { >- return DNS_ERR(SERVER_FAILURE); >- } >- >- ret = ldb_add(dns->samdb, msg); >- if (ret != LDB_SUCCESS) { >- return DNS_ERR(SERVER_FAILURE); >- } >- >- return WERR_OK; >- } >- >- ret = ldb_modify(dns->samdb, msg); >- if (ret != LDB_SUCCESS) { >- return DNS_ERR(SERVER_FAILURE); >- } >- >- return WERR_OK; >+ /* TODO: Autogenerate this somehow */ >+ uint32_t dwSerial = 110; >+ return dns_common_replace(dns->samdb, mem_ctx, dn, >+ needs_add, dwSerial, records, rec_count); > } > > bool dns_authorative_for_zone(struct dns_server *dns, >diff --git a/source4/dns_server/dnsserver_common.c b/source4/dns_server/dnsserver_common.c >index 5c3cafb..c28fbc8 100644 >--- a/source4/dns_server/dnsserver_common.c >+++ b/source4/dns_server/dnsserver_common.c >@@ -141,3 +141,81 @@ WERROR dns_common_lookup(struct ldb_context *samdb, > > return WERR_OK; > } >+ >+WERROR dns_common_replace(struct ldb_context *samdb, >+ TALLOC_CTX *mem_ctx, >+ struct ldb_dn *dn, >+ bool needs_add, >+ uint32_t serial, >+ struct dnsp_DnssrvRpcRecord *records, >+ uint16_t rec_count) >+{ >+ struct ldb_message_element *el; >+ uint16_t i; >+ int ret; >+ struct ldb_message *msg = NULL; >+ >+ msg = ldb_msg_new(mem_ctx); >+ W_ERROR_HAVE_NO_MEMORY(msg); >+ >+ msg->dn = dn; >+ >+ ret = ldb_msg_add_empty(msg, "dnsRecord", LDB_FLAG_MOD_REPLACE, &el); >+ if (ret != LDB_SUCCESS) { >+ return DNS_ERR(SERVER_FAILURE); >+ } >+ >+ el->values = talloc_zero_array(el, struct ldb_val, rec_count); >+ if (rec_count > 0) { >+ W_ERROR_HAVE_NO_MEMORY(el->values); >+ } >+ >+ for (i = 0; i < rec_count; i++) { >+ static const struct dnsp_DnssrvRpcRecord zero; >+ struct ldb_val *v = &el->values[el->num_values]; >+ enum ndr_err_code ndr_err; >+ >+ if (memcmp(&records[i], &zero, sizeof(zero)) == 0) { >+ continue; >+ } >+ >+ records[i].dwSerial = serial; >+ ndr_err = ndr_push_struct_blob(v, el->values, &records[i], >+ (ndr_push_flags_fn_t)ndr_push_dnsp_DnssrvRpcRecord); >+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >+ DEBUG(0, ("Failed to push dnsp_DnssrvRpcRecord\n")); >+ return DNS_ERR(SERVER_FAILURE); >+ } >+ el->num_values++; >+ } >+ >+ if (needs_add) { >+ if (el->num_values == 0) { >+ return WERR_OK; >+ } >+ >+ ret = ldb_msg_add_string(msg, "objectClass", "dnsNode"); >+ if (ret != LDB_SUCCESS) { >+ return DNS_ERR(SERVER_FAILURE); >+ } >+ >+ ret = ldb_add(samdb, msg); >+ if (ret != LDB_SUCCESS) { >+ return DNS_ERR(SERVER_FAILURE); >+ } >+ >+ return WERR_OK; >+ } >+ >+ if (el->num_values == 0) { >+ el->flags = LDB_FLAG_MOD_DELETE; >+ } >+ >+ ret = ldb_modify(samdb, msg); >+ if (ret != LDB_SUCCESS) { >+ NTSTATUS nt = dsdb_ldb_err_to_ntstatus(ret); >+ return ntstatus_to_werror(nt); >+ } >+ >+ return WERR_OK; >+} >diff --git a/source4/dns_server/dnsserver_common.h b/source4/dns_server/dnsserver_common.h >index 4731780..1117ad1 100644 >--- a/source4/dns_server/dnsserver_common.h >+++ b/source4/dns_server/dnsserver_common.h >@@ -38,4 +38,12 @@ WERROR dns_common_lookup(struct ldb_context *samdb, > struct dnsp_DnssrvRpcRecord **records, > uint16_t *num_records); > >+WERROR dns_common_replace(struct ldb_context *samdb, >+ TALLOC_CTX *mem_ctx, >+ struct ldb_dn *dn, >+ bool needs_add, >+ uint32_t serial, >+ struct dnsp_DnssrvRpcRecord *records, >+ uint16_t rec_count); >+ > #endif /* __DNSSERVER_COMMON_H__ */ >-- >1.9.1 > > >From 985b3a63faa68d2c7593ffdcef1090c97af7f5ec Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 31 Jul 2014 09:32:00 +0200 >Subject: [PATCH 08/22] s4:dns_server: use .wType = DNS_TYPE_TOMBSTONE instead > of ZERO_STRUCT() > >The result is the same, but it is clearer. > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 3ff025a02cca3ff209668edd419d0e440e9865c6) >--- > source4/dns_server/dns_update.c | 20 +++++++++++++++----- > 1 file changed, 15 insertions(+), 5 deletions(-) > >diff --git a/source4/dns_server/dns_update.c b/source4/dns_server/dns_update.c >index a82303b..0906c2a 100644 >--- a/source4/dns_server/dns_update.c >+++ b/source4/dns_server/dns_update.c >@@ -518,7 +518,9 @@ static WERROR handle_one_update(struct dns_server *dns, > continue; > } > >- ZERO_STRUCT(recs[i]); >+ recs[i] = (struct dnsp_DnssrvRpcRecord) { >+ .wType = DNS_TYPE_TOMBSTONE, >+ }; > } > > werror = dns_replace_records(dns, mem_ctx, dn, >@@ -567,12 +569,16 @@ static WERROR handle_one_update(struct dns_server *dns, > continue; > } > >- ZERO_STRUCT(recs[i]); >+ recs[i] = (struct dnsp_DnssrvRpcRecord) { >+ .wType = DNS_TYPE_TOMBSTONE, >+ }; > } > > } else { > for (i = 0; i < rcount; i++) { >- ZERO_STRUCT(recs[i]); >+ recs[i] = (struct dnsp_DnssrvRpcRecord) { >+ .wType = DNS_TYPE_TOMBSTONE, >+ }; > } > } > >@@ -588,7 +594,9 @@ static WERROR handle_one_update(struct dns_server *dns, > } > for (i = 0; i < rcount; i++) { > if (recs[i].wType == update->rr_type) { >- ZERO_STRUCT(recs[i]); >+ recs[i] = (struct dnsp_DnssrvRpcRecord) { >+ .wType = DNS_TYPE_TOMBSTONE, >+ }; > } > } > >@@ -632,7 +640,9 @@ static WERROR handle_one_update(struct dns_server *dns, > > for (i = 0; i < rcount; i++) { > if (dns_records_match(del_rec, &recs[i])) { >- ZERO_STRUCT(recs[i]); >+ recs[i] = (struct dnsp_DnssrvRpcRecord) { >+ .wType = DNS_TYPE_TOMBSTONE, >+ }; > } > } > >-- >1.9.1 > > >From 202583cb07cfea82bb7c6374731f07f0661ae9f0 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 31 Jul 2014 08:54:17 +0200 >Subject: [PATCH 09/22] s4:dns_server: make sure dns_common_lookup() doesn't > return tombstones > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit a0a81ab01cb1d509b04f9af25177c8e0941b43aa) >--- > source4/dns_server/dns_utils.c | 3 +- > source4/dns_server/dnsserver_common.c | 53 ++++++++++++++++++++++++++++++++--- > source4/dns_server/dnsserver_common.h | 3 +- > 3 files changed, 53 insertions(+), 6 deletions(-) > >diff --git a/source4/dns_server/dns_utils.c b/source4/dns_server/dns_utils.c >index b966dec..768636c 100644 >--- a/source4/dns_server/dns_utils.c >+++ b/source4/dns_server/dns_utils.c >@@ -151,7 +151,8 @@ WERROR dns_lookup_records(struct dns_server *dns, > struct dnsp_DnssrvRpcRecord **records, > uint16_t *rec_count) > { >- return dns_common_lookup(dns->samdb, mem_ctx, dn, records, rec_count); >+ return dns_common_lookup(dns->samdb, mem_ctx, dn, >+ records, rec_count, NULL); > } > > WERROR dns_replace_records(struct dns_server *dns, >diff --git a/source4/dns_server/dnsserver_common.c b/source4/dns_server/dnsserver_common.c >index c28fbc8..6fc145b 100644 >--- a/source4/dns_server/dnsserver_common.c >+++ b/source4/dns_server/dnsserver_common.c >@@ -101,10 +101,12 @@ WERROR dns_common_lookup(struct ldb_context *samdb, > TALLOC_CTX *mem_ctx, > struct ldb_dn *dn, > struct dnsp_DnssrvRpcRecord **records, >- uint16_t *num_records) >+ uint16_t *num_records, >+ bool *tombstoned) > { > static const char * const attrs[] = { > "dnsRecord", >+ "dNSTombstoned", > NULL > }; > int ret; >@@ -115,9 +117,16 @@ WERROR dns_common_lookup(struct ldb_context *samdb, > *records = NULL; > *num_records = 0; > >- ret = dsdb_search_one(samdb, mem_ctx, &msg, dn, >- LDB_SCOPE_BASE, attrs, 0, >- "(objectClass=dnsNode)"); >+ if (tombstoned != NULL) { >+ *tombstoned = false; >+ ret = dsdb_search_one(samdb, mem_ctx, &msg, dn, >+ LDB_SCOPE_BASE, attrs, 0, >+ "(objectClass=dnsNode)"); >+ } else { >+ ret = dsdb_search_one(samdb, mem_ctx, &msg, dn, >+ LDB_SCOPE_BASE, attrs, 0, >+ "(&(objectClass=dnsNode)(!(dNSTombstoned=TRUE)))"); >+ } > if (ret == LDB_ERR_NO_SUCH_OBJECT) { > return WERR_DNS_ERROR_NAME_DOES_NOT_EXIST; > } >@@ -127,9 +136,45 @@ WERROR dns_common_lookup(struct ldb_context *samdb, > return DNS_ERR(NAME_ERROR); > } > >+ if (tombstoned != NULL) { >+ *tombstoned = ldb_msg_find_attr_as_bool(msg, >+ "dNSTombstoned", false); >+ } >+ > el = ldb_msg_find_element(msg, "dnsRecord"); > if (el == NULL) { > TALLOC_FREE(msg); >+ if (tombstoned != NULL) { >+ struct dnsp_DnssrvRpcRecord *recs; >+ /* >+ * records produced by older Samba releases >+ * keep dnsNode objects without dnsRecord and >+ * without setting dNSTombstoned=TRUE. >+ * >+ * We just pretend they're tombstones. >+ */ >+ recs = talloc_array(mem_ctx, >+ struct dnsp_DnssrvRpcRecord, >+ 1); >+ if (recs == NULL) { >+ return WERR_NOMEM; >+ } >+ recs[0] = (struct dnsp_DnssrvRpcRecord) { >+ .wType = DNS_TYPE_TOMBSTONE, >+ /* >+ * A value of timestamp != 0 >+ * indicated that the object was already >+ * a tombstone, this will be used >+ * in dns_common_replace() >+ */ >+ .data.timestamp = 1, >+ }; >+ >+ *tombstoned = true; >+ *records = recs; >+ *num_records = 1; >+ return WERR_OK; >+ } > return DNS_ERR(NAME_ERROR); > } > >diff --git a/source4/dns_server/dnsserver_common.h b/source4/dns_server/dnsserver_common.h >index 1117ad1..becd243 100644 >--- a/source4/dns_server/dnsserver_common.h >+++ b/source4/dns_server/dnsserver_common.h >@@ -36,7 +36,8 @@ WERROR dns_common_lookup(struct ldb_context *samdb, > TALLOC_CTX *mem_ctx, > struct ldb_dn *dn, > struct dnsp_DnssrvRpcRecord **records, >- uint16_t *num_records); >+ uint16_t *num_records, >+ bool *tombstoned); > > WERROR dns_common_replace(struct ldb_context *samdb, > TALLOC_CTX *mem_ctx, >-- >1.9.1 > > >From fdf161b099e0db55083cb7f96de98a8ebc305aef Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 31 Jul 2014 10:44:41 +0200 >Subject: [PATCH 10/22] s4:dns_server: add DNS_TYPE_TOMBSTONE support to > dns_common_replace() > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 > >Pair-Programmed-With: Michael Adam <obnox@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Signed-off-by: Michael Adam <obnox@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit bb3ca930cc57964487bd23a74f4caabd1616a8bf) >--- > source4/dns_server/dnsserver_common.c | 81 +++++++++++++++++++++++++++++++++-- > 1 file changed, 77 insertions(+), 4 deletions(-) > >diff --git a/source4/dns_server/dnsserver_common.c b/source4/dns_server/dnsserver_common.c >index 6fc145b..4f51fda 100644 >--- a/source4/dns_server/dnsserver_common.c >+++ b/source4/dns_server/dnsserver_common.c >@@ -187,6 +187,22 @@ WERROR dns_common_lookup(struct ldb_context *samdb, > return WERR_OK; > } > >+static int rec_cmp(const struct dnsp_DnssrvRpcRecord *r1, >+ const struct dnsp_DnssrvRpcRecord *r2) >+{ >+ if (r1->wType != r2->wType) { >+ /* >+ * The records are sorted with higher types first >+ */ >+ return r2->wType - r1->wType; >+ } >+ >+ /* >+ * Then we need to sort from the oldest to newest timestamp >+ */ >+ return r1->dwTimeStamp - r2->dwTimeStamp; >+} >+ > WERROR dns_common_replace(struct ldb_context *samdb, > TALLOC_CTX *mem_ctx, > struct ldb_dn *dn, >@@ -199,6 +215,8 @@ WERROR dns_common_replace(struct ldb_context *samdb, > uint16_t i; > int ret; > struct ldb_message *msg = NULL; >+ bool was_tombstoned = false; >+ bool become_tombstoned = false; > > msg = ldb_msg_new(mem_ctx); > W_ERROR_HAVE_NO_MEMORY(msg); >@@ -210,17 +228,30 @@ WERROR dns_common_replace(struct ldb_context *samdb, > return DNS_ERR(SERVER_FAILURE); > } > >- el->values = talloc_zero_array(el, struct ldb_val, rec_count); >+ /* >+ * we have at least one value, >+ * which might be used for the tombstone marker >+ */ >+ el->values = talloc_zero_array(el, struct ldb_val, MAX(1, rec_count)); > if (rec_count > 0) { > W_ERROR_HAVE_NO_MEMORY(el->values); >+ >+ /* >+ * We store a sorted list with the high wType values first >+ * that's what windows does. It also simplifies the >+ * filtering of DNS_TYPE_TOMBSTONE records >+ */ >+ TYPESAFE_QSORT(records, rec_count, rec_cmp); > } > > for (i = 0; i < rec_count; i++) { >- static const struct dnsp_DnssrvRpcRecord zero; > struct ldb_val *v = &el->values[el->num_values]; > enum ndr_err_code ndr_err; > >- if (memcmp(&records[i], &zero, sizeof(zero)) == 0) { >+ if (records[i].wType == DNS_TYPE_TOMBSTONE) { >+ if (records[i].data.timestamp != 0) { >+ was_tombstoned = true; >+ } > continue; > } > >@@ -253,7 +284,49 @@ WERROR dns_common_replace(struct ldb_context *samdb, > } > > if (el->num_values == 0) { >- el->flags = LDB_FLAG_MOD_DELETE; >+ struct dnsp_DnssrvRpcRecord tbs; >+ struct ldb_val *v = &el->values[el->num_values]; >+ enum ndr_err_code ndr_err; >+ struct timeval tv; >+ >+ if (was_tombstoned) { >+ /* >+ * This is already a tombstoned object. >+ * Just leave it instead of updating the time stamp. >+ */ >+ return WERR_OK; >+ } >+ >+ tv = timeval_current(); >+ tbs = (struct dnsp_DnssrvRpcRecord) { >+ .wType = DNS_TYPE_TOMBSTONE, >+ .dwSerial = serial, >+ .data.timestamp = timeval_to_nttime(&tv), >+ }; >+ >+ ndr_err = ndr_push_struct_blob(v, el->values, &tbs, >+ (ndr_push_flags_fn_t)ndr_push_dnsp_DnssrvRpcRecord); >+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >+ DEBUG(0, ("Failed to push dnsp_DnssrvRpcRecord\n")); >+ return DNS_ERR(SERVER_FAILURE); >+ } >+ el->num_values++; >+ >+ become_tombstoned = true; >+ } >+ >+ if (was_tombstoned || become_tombstoned) { >+ ret = ldb_msg_add_empty(msg, "dNSTombstoned", >+ LDB_FLAG_MOD_REPLACE, NULL); >+ if (ret != LDB_SUCCESS) { >+ return DNS_ERR(SERVER_FAILURE); >+ } >+ >+ ret = ldb_msg_add_fmt(msg, "dNSTombstoned", "%s", >+ become_tombstoned ? "TRUE" : "FALSE"); >+ if (ret != LDB_SUCCESS) { >+ return DNS_ERR(SERVER_FAILURE); >+ } > } > > ret = ldb_modify(samdb, msg); >-- >1.9.1 > > >From 870f33c0d2da2af984ba003df4541b0e38f20fb8 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 31 Jul 2014 09:35:26 +0200 >Subject: [PATCH 11/22] s4:dns_server: handle tombstones in handle_one_update() > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 491715399ff7e1ab788fec5e254581dc312e2cef) >--- > source4/dns_server/dns_update.c | 41 +++++++++++++++++++++++++---------------- > 1 file changed, 25 insertions(+), 16 deletions(-) > >diff --git a/source4/dns_server/dns_update.c b/source4/dns_server/dns_update.c >index 0906c2a..f96be0c 100644 >--- a/source4/dns_server/dns_update.c >+++ b/source4/dns_server/dns_update.c >@@ -397,7 +397,9 @@ static WERROR handle_one_update(struct dns_server *dns, > uint16_t rcount = 0; > struct ldb_dn *dn; > uint16_t i; >+ uint16_t first = 0; > WERROR werror; >+ bool tombstoned = false; > bool needs_add = false; > > DEBUG(2, ("Looking at record: \n")); >@@ -425,23 +427,29 @@ static WERROR handle_one_update(struct dns_server *dns, > werror = dns_name2dn(dns, mem_ctx, update->name, &dn); > W_ERROR_NOT_OK_RETURN(werror); > >- werror = dns_lookup_records(dns, mem_ctx, dn, &recs, &rcount); >+ werror = dns_common_lookup(dns->samdb, mem_ctx, dn, >+ &recs, &rcount, &tombstoned); > if (W_ERROR_EQUAL(werror, WERR_DNS_ERROR_NAME_DOES_NOT_EXIST)) { > needs_add = true; > werror = WERR_OK; > } >- if (W_ERROR_EQUAL(werror, DNS_ERR(NAME_ERROR))) { >- werror = WERR_OK; >- } > W_ERROR_NOT_OK_RETURN(werror); > >+ if (tombstoned) { >+ /* >+ * we need to keep the existing tombstone record >+ * and ignore it >+ */ >+ first = rcount; >+ } >+ > if (update->rr_class == zone->question_class) { > if (update->rr_type == DNS_QTYPE_CNAME) { > /* > * If there is a record in the directory > * that's not a CNAME, ignore update > */ >- for (i = 0; i < rcount; i++) { >+ for (i = first; i < rcount; i++) { > if (recs[i].wType != DNS_TYPE_CNAME) { > DEBUG(5, ("Skipping update\n")); > return WERR_OK; >@@ -454,13 +462,14 @@ static WERROR handle_one_update(struct dns_server *dns, > * per name, so replace everything with the new CNAME > */ > >- rcount = 1; >+ rcount = first; > recs = talloc_realloc(mem_ctx, recs, >- struct dnsp_DnssrvRpcRecord, rcount); >+ struct dnsp_DnssrvRpcRecord, rcount + 1); > W_ERROR_HAVE_NO_MEMORY(recs); > >- werror = dns_rr_to_dnsp(recs, update, &recs[0]); >+ werror = dns_rr_to_dnsp(recs, update, &recs[rcount]); > W_ERROR_NOT_OK_RETURN(werror); >+ rcount += 1; > > werror = dns_replace_records(dns, mem_ctx, dn, > needs_add, recs, rcount); >@@ -472,7 +481,7 @@ static WERROR handle_one_update(struct dns_server *dns, > * If there is a CNAME record for this name, > * ignore update > */ >- for (i = 0; i < rcount; i++) { >+ for (i = first; i < rcount; i++) { > if (recs[i].wType == DNS_TYPE_CNAME) { > DEBUG(5, ("Skipping update\n")); > return WERR_OK; >@@ -487,7 +496,7 @@ static WERROR handle_one_update(struct dns_server *dns, > * serial number is smaller than existing SOA's, > * ignore update > */ >- for (i = 0; i < rcount; i++) { >+ for (i = first; i < rcount; i++) { > if (recs[i].wType == DNS_TYPE_SOA) { > uint16_t n, o; > >@@ -537,7 +546,7 @@ static WERROR handle_one_update(struct dns_server *dns, > werror = dns_rr_to_dnsp(recs, update, &recs[rcount]); > W_ERROR_NOT_OK_RETURN(werror); > >- for (i = 0; i < rcount; i++) { >+ for (i = first; i < rcount; i++) { > if (!dns_records_match(&recs[i], &recs[rcount])) { > continue; > } >@@ -559,7 +568,7 @@ static WERROR handle_one_update(struct dns_server *dns, > } else if (update->rr_class == DNS_QCLASS_ANY) { > if (update->rr_type == DNS_QTYPE_ALL) { > if (dns_name_equal(update->name, zone->name)) { >- for (i = 0; i < rcount; i++) { >+ for (i = first; i < rcount; i++) { > > if (recs[i].wType == DNS_TYPE_SOA) { > continue; >@@ -575,7 +584,7 @@ static WERROR handle_one_update(struct dns_server *dns, > } > > } else { >- for (i = 0; i < rcount; i++) { >+ for (i = first; i < rcount; i++) { > recs[i] = (struct dnsp_DnssrvRpcRecord) { > .wType = DNS_TYPE_TOMBSTONE, > }; >@@ -592,7 +601,7 @@ static WERROR handle_one_update(struct dns_server *dns, > return WERR_OK; > } > } >- for (i = 0; i < rcount; i++) { >+ for (i = first; i < rcount; i++) { > if (recs[i].wType == update->rr_type) { > recs[i] = (struct dnsp_DnssrvRpcRecord) { > .wType = DNS_TYPE_TOMBSTONE, >@@ -621,7 +630,7 @@ static WERROR handle_one_update(struct dns_server *dns, > werror = dns_rr_to_dnsp(ns_rec, update, ns_rec); > W_ERROR_NOT_OK_RETURN(werror); > >- for (i = 0; i < rcount; i++) { >+ for (i = first; i < rcount; i++) { > if (dns_records_match(ns_rec, &recs[i])) { > found = true; > break; >@@ -638,7 +647,7 @@ static WERROR handle_one_update(struct dns_server *dns, > werror = dns_rr_to_dnsp(del_rec, update, del_rec); > W_ERROR_NOT_OK_RETURN(werror); > >- for (i = 0; i < rcount; i++) { >+ for (i = first; i < rcount; i++) { > if (dns_records_match(del_rec, &recs[i])) { > recs[i] = (struct dnsp_DnssrvRpcRecord) { > .wType = DNS_TYPE_TOMBSTONE, >-- >1.9.1 > > >From f857dbbb42e1c5a32f40ab1751084cacb22c9075 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 27 Feb 2014 09:59:51 +0100 >Subject: [PATCH 12/22] s4:dlz_bind9: avoid some compiler warnings > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit fbebe7e756e4ccd0684e94e9b1e787f98f399ccc) >--- > source4/dns_server/dlz_bind9.c | 6 +++--- > source4/dns_server/dlz_minimal.h | 2 +- > source4/torture/dns/dlz_bind9.c | 7 ++++--- > 3 files changed, 8 insertions(+), 7 deletions(-) > >diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c >index ac41dd0..8d5a208 100644 >--- a/source4/dns_server/dlz_bind9.c >+++ b/source4/dns_server/dlz_bind9.c >@@ -459,7 +459,7 @@ static isc_result_t b9_putnamedrr(struct dlz_bind9_data *state, > parse options > */ > static isc_result_t parse_options(struct dlz_bind9_data *state, >- unsigned int argc, char *argv[], >+ unsigned int argc, const char **argv, > struct b9_options *options) > { > int opt; >@@ -470,7 +470,7 @@ static isc_result_t parse_options(struct dlz_bind9_data *state, > { NULL } > }; > >- pc = poptGetContext("dlz_bind9", argc, (const char **)argv, long_options, >+ pc = poptGetContext("dlz_bind9", argc, argv, long_options, > POPT_CONTEXT_KEEP_FIRST); > while ((opt = poptGetNextOpt(pc)) != -1) { > switch (opt) { >@@ -564,7 +564,7 @@ static int dlz_state_debug_unregister(struct dlz_bind9_data *state) > called to initialise the driver > */ > _PUBLIC_ isc_result_t dlz_create(const char *dlzname, >- unsigned int argc, char *argv[], >+ unsigned int argc, const char **argv, > void **dbdata, ...) > { > struct dlz_bind9_data *state; >diff --git a/source4/dns_server/dlz_minimal.h b/source4/dns_server/dlz_minimal.h >index 5262cbd..98fb34e 100644 >--- a/source4/dns_server/dlz_minimal.h >+++ b/source4/dns_server/dlz_minimal.h >@@ -100,7 +100,7 @@ int dlz_version(unsigned int *flags); > /* > * dlz_create() is required for all DLZ external drivers. > */ >-isc_result_t dlz_create(const char *dlzname, unsigned int argc, char *argv[], void **dbdata, ...); >+isc_result_t dlz_create(const char *dlzname, unsigned int argc, const char **argv, void **dbdata, ...); > > /* > * dlz_destroy() is optional, and will be called when the driver is >diff --git a/source4/torture/dns/dlz_bind9.c b/source4/torture/dns/dlz_bind9.c >index d7d1736..88ca27c 100644 >--- a/source4/torture/dns/dlz_bind9.c >+++ b/source4/torture/dns/dlz_bind9.c >@@ -61,7 +61,7 @@ static bool test_dlz_bind9_create(struct torture_context *tctx) > NULL > }; > tctx_static = tctx; >- torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, discard_const_p(char *, argv), &dbdata, >+ torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata, > "log", dlz_bind9_log_wrapper, NULL), ISC_R_SUCCESS, > "Failed to create samba_dlz"); > >@@ -109,7 +109,7 @@ static bool test_dlz_bind9_configure(struct torture_context *tctx) > NULL > }; > tctx_static = tctx; >- torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, discard_const_p(char *, argv), &dbdata, >+ torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata, > "log", dlz_bind9_log_wrapper, > "writeable_zone", dlz_bind9_writeable_zone_hook, NULL), > ISC_R_SUCCESS, >@@ -144,7 +144,7 @@ static bool test_dlz_bind9_gensec(struct torture_context *tctx, const char *mech > NULL > }; > tctx_static = tctx; >- torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, discard_const_p(char *, argv), &dbdata, >+ torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata, > "log", dlz_bind9_log_wrapper, > "writeable_zone", dlz_bind9_writeable_zone_hook, NULL), > ISC_R_SUCCESS, >@@ -216,6 +216,7 @@ static struct torture_suite *dlz_bind9_suite(TALLOC_CTX *ctx) > /** > * DNS torture module initialization > */ >+NTSTATUS torture_bind_dns_init(void); > NTSTATUS torture_bind_dns_init(void) > { > struct torture_suite *suite; >-- >1.9.1 > > >From ada4e057cfd8e2fe857a795f8653a6750adb05e6 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 30 Jul 2014 17:57:13 +0200 >Subject: [PATCH 13/22] s4:dlz_bind9: do an early talloc_free(el_ctx) in > dlz_allnodes() > >We don't have to keep everything arround while walking the whole zone. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 5d397c8198bcd2cdccc3deda57377d4696e6abd1) >--- > source4/dns_server/dlz_bind9.c | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c >index 8d5a208..9f144a4 100644 >--- a/source4/dns_server/dlz_bind9.c >+++ b/source4/dns_server/dlz_bind9.c >@@ -980,6 +980,8 @@ _PUBLIC_ isc_result_t dlz_allnodes(const char *zone, void *dbdata, > continue; > } > } >+ >+ talloc_free(el_ctx); > } > > talloc_free(tmp_ctx); >-- >1.9.1 > > >From 5e66708cbfe2e87757d043082e0b8a34368323dc Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 26 Aug 2014 13:48:21 +0200 >Subject: [PATCH 14/22] s4:torture:dlz_bind9: fix spnego tests > >The dlz_bind9 module uses the special dns-${NETBIOSNAME} account, >and this is only available under the dns/hostname.domain SPN, not >host/hostname. > >Also the dlz_ssumatch() function returns isc_boolean_t instead >of isc_result_t. As ISC_R_SUCCESS and ISC_FALSE have the same value >we didn't notice this problem. > >Change-Id: I48539c3f48f5dde9eaa2fff6da0f3be2f9f66311 >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 76943bf0ac259fb8855bd123fe4bc85a103ba418) >--- > source4/torture/dns/dlz_bind9.c | 14 ++++++++++++-- > 1 file changed, 12 insertions(+), 2 deletions(-) > >diff --git a/source4/torture/dns/dlz_bind9.c b/source4/torture/dns/dlz_bind9.c >index 88ca27c..0c5b153 100644 >--- a/source4/torture/dns/dlz_bind9.c >+++ b/source4/torture/dns/dlz_bind9.c >@@ -158,9 +158,19 @@ static bool test_dlz_bind9_gensec(struct torture_context *tctx, const char *mech > lpcfg_gensec_settings(tctx, tctx->lp_ctx)); > torture_assert_ntstatus_ok(tctx, status, "gensec_client_start (client) failed"); > >- status = gensec_set_target_hostname(gensec_client_context, torture_setting_string(tctx, "host", NULL)); >+ /* >+ * dlz_bind9 use the special dns/host.domain account >+ */ >+ status = gensec_set_target_hostname(gensec_client_context, >+ talloc_asprintf(tctx, >+ "%s.%s", >+ torture_setting_string(tctx, "host", NULL), >+ lpcfg_dnsdomain(tctx->lp_ctx))); > torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_hostname (client) failed"); > >+ status = gensec_set_target_service(gensec_client_context, "dns"); >+ torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_service failed"); >+ > status = gensec_set_credentials(gensec_client_context, cmdline_credentials); > torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (client) failed"); > >@@ -181,7 +191,7 @@ static bool test_dlz_bind9_gensec(struct torture_context *tctx, const char *mech > client_to_server.length, > client_to_server.data, > dbdata), >- ISC_R_SUCCESS, >+ ISC_TRUE, > "Failed to check key for update rights samba_dlz"); > > dlz_destroy(dbdata); >-- >1.9.1 > > >From db50123099c384eef35caa9ebaaf160c2299dcad Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 26 Aug 2014 10:24:27 +1200 >Subject: [PATCH 15/22] torture-dns: Add test for dlz_bind9 lookups > >Change-Id: I3b9d1b56e3aa873fb8540b98e196b713b82332ca >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 2189470c2f55afe29e9e8dad1d2659a7eb2d06f9) >--- > source4/torture/dns/dlz_bind9.c | 224 ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 224 insertions(+) > >diff --git a/source4/torture/dns/dlz_bind9.c b/source4/torture/dns/dlz_bind9.c >index 0c5b153..327eb84 100644 >--- a/source4/torture/dns/dlz_bind9.c >+++ b/source4/torture/dns/dlz_bind9.c >@@ -209,6 +209,229 @@ static bool test_dlz_bind9_spnego(struct torture_context *tctx) > return test_dlz_bind9_gensec(tctx, "GSS-SPNEGO"); > } > >+struct test_expected_record { >+ const char *name; >+ const char *type; >+ const char *data; >+ int ttl; >+ bool printed; >+}; >+ >+struct test_expected_rr { >+ struct torture_context *tctx; >+ const char *query_name; >+ size_t num_records; >+ struct test_expected_record *records; >+ size_t num_rr; >+}; >+ >+static bool dlz_bind9_putnamedrr_torture_hook(struct test_expected_rr *expected, >+ const char *name, >+ const char *type, >+ dns_ttl_t ttl, >+ const char *data) >+{ >+ size_t i; >+ >+ torture_assert(expected->tctx, name != NULL, >+ talloc_asprintf(expected->tctx, >+ "Got unnamed record type[%s] data[%s]\n", >+ type, data)); >+ >+ expected->num_rr++; >+ torture_comment(expected->tctx, "%u: name[%s] type[%s] ttl[%u] data[%s]\n", >+ (unsigned)expected->num_rr, name, type, (unsigned)ttl, data); >+ >+ for (i = 0; i < expected->num_records; i++) { >+ if (expected->records[i].name != NULL) { >+ if (strcmp(name, expected->records[i].name) != 0) { >+ continue; >+ } >+ } >+ >+ if (strcmp(type, expected->records[i].type) != 0) { >+ continue; >+ } >+ >+ if (expected->records[i].data != NULL) { >+ if (strcmp(data, expected->records[i].data) != 0) { >+ continue; >+ } >+ } >+ >+ torture_assert_int_equal(expected->tctx, ttl, >+ expected->records[i].ttl, >+ talloc_asprintf(expected->tctx, >+ "TTL did not match expectations for type %s", >+ type)); >+ >+ expected->records[i].printed = true; >+ } >+ >+ return true; >+} >+ >+static isc_result_t dlz_bind9_putrr_hook(dns_sdlzlookup_t *lookup, >+ const char *type, >+ dns_ttl_t ttl, >+ const char *data) >+{ >+ struct test_expected_rr *expected = >+ talloc_get_type_abort(lookup, struct test_expected_rr); >+ bool ok; >+ >+ ok = dlz_bind9_putnamedrr_torture_hook(expected, expected->query_name, >+ type, ttl, data); >+ if (!ok) { >+ return ISC_R_FAILURE; >+ } >+ >+ return ISC_R_SUCCESS; >+} >+ >+static isc_result_t dlz_bind9_putnamedrr_hook(dns_sdlzallnodes_t *allnodes, >+ const char *name, >+ const char *type, >+ dns_ttl_t ttl, >+ const char *data) >+{ >+ struct test_expected_rr *expected = >+ talloc_get_type_abort(allnodes, struct test_expected_rr); >+ bool ok; >+ >+ ok = dlz_bind9_putnamedrr_torture_hook(expected, name, type, ttl, data); >+ if (!ok) { >+ return ISC_R_FAILURE; >+ } >+ >+ return ISC_R_SUCCESS; >+} >+ >+/* >+ * Tests some lookups >+ */ >+static bool test_dlz_bind9_lookup(struct torture_context *tctx) >+{ >+ size_t i; >+ void *dbdata; >+ const char *argv[] = { >+ "samba_dlz", >+ "-H", >+ lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"), >+ NULL >+ }; >+ struct test_expected_rr *expected1 = NULL; >+ struct test_expected_rr *expected2 = NULL; >+ >+ tctx_static = tctx; >+ torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata, >+ "log", dlz_bind9_log_wrapper, >+ "writeable_zone", dlz_bind9_writeable_zone_hook, >+ "putrr", dlz_bind9_putrr_hook, >+ "putnamedrr", dlz_bind9_putnamedrr_hook, >+ NULL), >+ ISC_R_SUCCESS, >+ "Failed to create samba_dlz"); >+ >+ torture_assert_int_equal(tctx, dlz_configure((void*)tctx, dbdata), >+ ISC_R_SUCCESS, >+ "Failed to configure samba_dlz"); >+ >+ expected1 = talloc_zero(tctx, struct test_expected_rr); >+ torture_assert(tctx, expected1 != NULL, "talloc failed"); >+ expected1->tctx = tctx; >+ >+ expected1->query_name = "@"; >+ >+ expected1->num_records = 4; >+ expected1->records = talloc_zero_array(expected1, >+ struct test_expected_record, >+ expected1->num_records); >+ torture_assert(tctx, expected1->records != NULL, "talloc failed"); >+ >+ expected1->records[0].name = expected1->query_name; >+ expected1->records[0].type = "soa"; >+ expected1->records[0].ttl = 3600; >+ expected1->records[0].data = talloc_asprintf(expected1->records, >+ "%s.%s hostmaster.%s 1 900 600 86400 3600", >+ torture_setting_string(tctx, "host", NULL), >+ lpcfg_dnsdomain(tctx->lp_ctx), >+ lpcfg_dnsdomain(tctx->lp_ctx)); >+ torture_assert(tctx, expected1->records[0].data != NULL, "talloc failed"); >+ >+ expected1->records[1].name = expected1->query_name; >+ expected1->records[1].type = "ns"; >+ expected1->records[1].ttl = 900; >+ expected1->records[1].data = talloc_asprintf(expected1->records, "%s.%s", >+ torture_setting_string(tctx, "host", NULL), >+ lpcfg_dnsdomain(tctx->lp_ctx)); >+ torture_assert(tctx, expected1->records[1].data != NULL, "talloc failed"); >+ >+ expected1->records[2].name = expected1->query_name; >+ expected1->records[2].type = "aaaa"; >+ expected1->records[2].ttl = 900; >+ >+ expected1->records[3].name = expected1->query_name; >+ expected1->records[3].type = "a"; >+ expected1->records[3].ttl = 900; >+ >+ torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), >+ expected1->query_name, dbdata, >+ (dns_sdlzlookup_t *)expected1), >+ ISC_R_SUCCESS, >+ "Failed to lookup @"); >+ for (i = 0; i < expected1->num_records; i++) { >+ torture_assert(tctx, expected1->records[i].printed, >+ talloc_asprintf(tctx, >+ "Failed to have putrr callback run for type %s", >+ expected1->records[i].type)); >+ } >+ torture_assert_int_equal(tctx, expected1->num_rr, >+ expected1->num_records, >+ "Got too much data"); >+ >+ expected2 = talloc_zero(tctx, struct test_expected_rr); >+ torture_assert(tctx, expected2 != NULL, "talloc failed"); >+ expected2->tctx = tctx; >+ >+ expected2->query_name = torture_setting_string(tctx, "host", NULL); >+ torture_assert(tctx, expected2->query_name != NULL, "unknown host"); >+ >+ expected2->num_records = 2; >+ expected2->records = talloc_zero_array(expected2, >+ struct test_expected_record, >+ expected2->num_records); >+ torture_assert(tctx, expected2->records != NULL, "talloc failed"); >+ >+ expected2->records[0].name = expected2->query_name; >+ expected2->records[0].type = "aaaa"; >+ expected2->records[0].ttl = 900; >+ >+ expected2->records[1].name = expected2->query_name; >+ expected2->records[1].type = "a"; >+ expected2->records[1].ttl = 900; >+ >+ torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), >+ expected2->query_name, dbdata, >+ (dns_sdlzlookup_t *)expected2), >+ ISC_R_SUCCESS, >+ "Failed to lookup hostname"); >+ for (i = 0; i < expected2->num_records; i++) { >+ torture_assert(tctx, expected2->records[i].printed, >+ talloc_asprintf(tctx, >+ "Failed to have putrr callback run name[%s] for type %s", >+ expected2->records[i].name, >+ expected2->records[i].type)); >+ } >+ torture_assert_int_equal(tctx, expected2->num_rr, >+ expected2->num_records, >+ "Got too much data"); >+ >+ dlz_destroy(dbdata); >+ >+ return true; >+} >+ > static struct torture_suite *dlz_bind9_suite(TALLOC_CTX *ctx) > { > struct torture_suite *suite = torture_suite_create(ctx, "dlz_bind9"); >@@ -220,6 +443,7 @@ static struct torture_suite *dlz_bind9_suite(TALLOC_CTX *ctx) > torture_suite_add_simple_test(suite, "configure", test_dlz_bind9_configure); > torture_suite_add_simple_test(suite, "gssapi", test_dlz_bind9_gssapi); > torture_suite_add_simple_test(suite, "spnego", test_dlz_bind9_spnego); >+ torture_suite_add_simple_test(suite, "lookup", test_dlz_bind9_lookup); > return suite; > } > >-- >1.9.1 > > >From e2d258afd112f872ee0a83235bdb1617cf321405 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 26 Aug 2014 10:34:17 +0200 >Subject: [PATCH 16/22] torture-dns: Add test for dlz_bind9 zonedumps > >Change-Id: I074b3e4cdad1a0b69c085dcaa44d6f48e68e863b >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit e23621e9dab67c8997d24b2ac7e4fd181fc5907c) >--- > source4/torture/dns/dlz_bind9.c | 106 ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 106 insertions(+) > >diff --git a/source4/torture/dns/dlz_bind9.c b/source4/torture/dns/dlz_bind9.c >index 327eb84..e98db44 100644 >--- a/source4/torture/dns/dlz_bind9.c >+++ b/source4/torture/dns/dlz_bind9.c >@@ -432,6 +432,111 @@ static bool test_dlz_bind9_lookup(struct torture_context *tctx) > return true; > } > >+/* >+ * Test some zone dumps >+ */ >+static bool test_dlz_bind9_zonedump(struct torture_context *tctx) >+{ >+ size_t i; >+ void *dbdata; >+ const char *argv[] = { >+ "samba_dlz", >+ "-H", >+ lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"), >+ NULL >+ }; >+ struct test_expected_rr *expected1 = NULL; >+ >+ tctx_static = tctx; >+ torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata, >+ "log", dlz_bind9_log_wrapper, >+ "writeable_zone", dlz_bind9_writeable_zone_hook, >+ "putrr", dlz_bind9_putrr_hook, >+ "putnamedrr", dlz_bind9_putnamedrr_hook, >+ NULL), >+ ISC_R_SUCCESS, >+ "Failed to create samba_dlz"); >+ >+ torture_assert_int_equal(tctx, dlz_configure((void*)tctx, dbdata), >+ ISC_R_SUCCESS, >+ "Failed to configure samba_dlz"); >+ >+ expected1 = talloc_zero(tctx, struct test_expected_rr); >+ torture_assert(tctx, expected1 != NULL, "talloc failed"); >+ expected1->tctx = tctx; >+ >+ expected1->num_records = 7; >+ expected1->records = talloc_zero_array(expected1, >+ struct test_expected_record, >+ expected1->num_records); >+ torture_assert(tctx, expected1->records != NULL, "talloc failed"); >+ >+ expected1->records[0].name = lpcfg_dnsdomain(tctx->lp_ctx); >+ expected1->records[0].type = "soa"; >+ expected1->records[0].ttl = 3600; >+ expected1->records[0].data = talloc_asprintf(expected1->records, >+ "%s.%s hostmaster.%s 1 900 600 86400 3600", >+ torture_setting_string(tctx, "host", NULL), >+ lpcfg_dnsdomain(tctx->lp_ctx), >+ lpcfg_dnsdomain(tctx->lp_ctx)); >+ torture_assert(tctx, expected1->records[0].data != NULL, "talloc failed"); >+ >+ expected1->records[1].name = lpcfg_dnsdomain(tctx->lp_ctx); >+ expected1->records[1].type = "ns"; >+ expected1->records[1].ttl = 900; >+ expected1->records[1].data = talloc_asprintf(expected1->records, "%s.%s", >+ torture_setting_string(tctx, "host", NULL), >+ lpcfg_dnsdomain(tctx->lp_ctx)); >+ torture_assert(tctx, expected1->records[1].data != NULL, "talloc failed"); >+ >+ expected1->records[2].name = lpcfg_dnsdomain(tctx->lp_ctx); >+ expected1->records[2].type = "aaaa"; >+ expected1->records[2].ttl = 900; >+ >+ expected1->records[3].name = lpcfg_dnsdomain(tctx->lp_ctx); >+ expected1->records[3].type = "a"; >+ expected1->records[3].ttl = 900; >+ >+ expected1->records[4].name = talloc_asprintf(expected1->records, "%s.%s", >+ torture_setting_string(tctx, "host", NULL), >+ lpcfg_dnsdomain(tctx->lp_ctx)); >+ torture_assert(tctx, expected1->records[4].name != NULL, "unknown host"); >+ expected1->records[4].type = "aaaa"; >+ expected1->records[4].ttl = 900; >+ >+ expected1->records[5].name = talloc_asprintf(expected1->records, "%s.%s", >+ torture_setting_string(tctx, "host", NULL), >+ lpcfg_dnsdomain(tctx->lp_ctx)); >+ torture_assert(tctx, expected1->records[5].name != NULL, "unknown host"); >+ expected1->records[5].type = "a"; >+ expected1->records[5].ttl = 900; >+ >+ /* >+ * We expect multiple srv records >+ */ >+ expected1->records[6].name = NULL; >+ expected1->records[6].type = "srv"; >+ expected1->records[6].ttl = 900; >+ >+ torture_assert_int_equal(tctx, dlz_allnodes(lpcfg_dnsdomain(tctx->lp_ctx), >+ dbdata, (dns_sdlzallnodes_t *)expected1), >+ ISC_R_SUCCESS, >+ "Failed to configure samba_dlz"); >+ for (i = 0; i < expected1->num_records; i++) { >+ torture_assert(tctx, expected1->records[i].printed, >+ talloc_asprintf(tctx, >+ "Failed to have putrr callback run name[%s] for type %s", >+ expected1->records[i].name, >+ expected1->records[i].type)); >+ } >+ torture_assert_int_equal(tctx, expected1->num_rr, 24, >+ "Got wrong record count"); >+ >+ dlz_destroy(dbdata); >+ >+ return true; >+} >+ > static struct torture_suite *dlz_bind9_suite(TALLOC_CTX *ctx) > { > struct torture_suite *suite = torture_suite_create(ctx, "dlz_bind9"); >@@ -444,6 +549,7 @@ static struct torture_suite *dlz_bind9_suite(TALLOC_CTX *ctx) > torture_suite_add_simple_test(suite, "gssapi", test_dlz_bind9_gssapi); > torture_suite_add_simple_test(suite, "spnego", test_dlz_bind9_spnego); > torture_suite_add_simple_test(suite, "lookup", test_dlz_bind9_lookup); >+ torture_suite_add_simple_test(suite, "zonedump", test_dlz_bind9_zonedump); > return suite; > } > >-- >1.9.1 > > >From bd0bb96c397d84104894f42654d01e2884f45d7f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 26 Aug 2014 12:04:59 +0200 >Subject: [PATCH 17/22] torture-dns: Add test for dlz_bind9 updates > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(similar to commit 914a3667471ced3199f51db8bc1d4a6d3fbc4e8f) >--- > source4/torture/dns/dlz_bind9.c | 517 ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 517 insertions(+) > >diff --git a/source4/torture/dns/dlz_bind9.c b/source4/torture/dns/dlz_bind9.c >index e98db44..fa6967d 100644 >--- a/source4/torture/dns/dlz_bind9.c >+++ b/source4/torture/dns/dlz_bind9.c >@@ -537,6 +537,522 @@ static bool test_dlz_bind9_zonedump(struct torture_context *tctx) > return true; > } > >+/* >+ * Test some updates >+ */ >+static bool test_dlz_bind9_update01(struct torture_context *tctx) >+{ >+ NTSTATUS status; >+ struct gensec_security *gensec_client_context; >+ DATA_BLOB client_to_server, server_to_client; >+ void *dbdata; >+ void *version = NULL; >+ const char *argv[] = { >+ "samba_dlz", >+ "-H", >+ lpcfg_private_path(tctx, tctx->lp_ctx, "dns/sam.ldb"), >+ NULL >+ }; >+ struct test_expected_rr *expected1 = NULL; >+ char *name = NULL; >+ char *data0 = NULL; >+ char *data1 = NULL; >+ char *data2 = NULL; >+ bool ret = false; >+ >+ tctx_static = tctx; >+ torture_assert_int_equal(tctx, dlz_create("samba_dlz", 3, argv, &dbdata, >+ "log", dlz_bind9_log_wrapper, >+ "writeable_zone", dlz_bind9_writeable_zone_hook, >+ "putrr", dlz_bind9_putrr_hook, >+ "putnamedrr", dlz_bind9_putnamedrr_hook, >+ NULL), >+ ISC_R_SUCCESS, >+ "Failed to create samba_dlz"); >+ >+ torture_assert_int_equal(tctx, dlz_configure((void*)tctx, dbdata), >+ ISC_R_SUCCESS, >+ "Failed to configure samba_dlz"); >+ >+ expected1 = talloc_zero(tctx, struct test_expected_rr); >+ torture_assert(tctx, expected1 != NULL, "talloc failed"); >+ expected1->tctx = tctx; >+ >+ expected1->query_name = __func__; >+ >+ name = talloc_asprintf(expected1, "%s.%s", >+ expected1->query_name, >+ lpcfg_dnsdomain(tctx->lp_ctx)); >+ torture_assert(tctx, name != NULL, "talloc failed"); >+ >+ expected1->num_records = 2; >+ expected1->records = talloc_zero_array(expected1, >+ struct test_expected_record, >+ expected1->num_records); >+ torture_assert(tctx, expected1->records != NULL, "talloc failed"); >+ >+ expected1->records[0].name = expected1->query_name; >+ expected1->records[0].type = "a"; >+ expected1->records[0].ttl = 3600; >+ expected1->records[0].data = "127.1.2.3"; >+ expected1->records[0].printed = false; >+ >+ data0 = talloc_asprintf(expected1, >+ "%s.\t" "%u\t" "%s\t" "%s\t" "%s", >+ name, >+ (unsigned)expected1->records[0].ttl, >+ "in", >+ expected1->records[0].type, >+ expected1->records[0].data); >+ torture_assert(tctx, data0 != NULL, "talloc failed"); >+ >+ expected1->records[1].name = expected1->query_name; >+ expected1->records[1].type = "a"; >+ expected1->records[1].ttl = 3600; >+ expected1->records[1].data = "127.3.2.1"; >+ expected1->records[1].printed = false; >+ >+ data1 = talloc_asprintf(expected1, >+ "%s.\t" "%u\t" "%s\t" "%s\t" "%s", >+ name, >+ (unsigned)expected1->records[1].ttl, >+ "in", >+ expected1->records[1].type, >+ expected1->records[1].data); >+ torture_assert(tctx, data1 != NULL, "talloc failed"); >+ >+ data2 = talloc_asprintf(expected1, >+ "%s.\t" "0\t" "in\t" "a\t" "127.3.3.3", >+ name); >+ torture_assert(tctx, data2 != NULL, "talloc failed"); >+ >+ /* >+ * Prepare session info >+ */ >+ status = gensec_client_start(tctx, &gensec_client_context, >+ lpcfg_gensec_settings(tctx, tctx->lp_ctx)); >+ torture_assert_ntstatus_ok(tctx, status, "gensec_client_start (client) failed"); >+ >+ /* >+ * dlz_bind9 use the special dns/host.domain account >+ */ >+ status = gensec_set_target_hostname(gensec_client_context, >+ talloc_asprintf(tctx, >+ "%s.%s", >+ torture_setting_string(tctx, "host", NULL), >+ lpcfg_dnsdomain(tctx->lp_ctx))); >+ torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_hostname (client) failed"); >+ >+ status = gensec_set_target_service(gensec_client_context, "dns"); >+ torture_assert_ntstatus_ok(tctx, status, "gensec_set_target_service failed"); >+ >+ status = gensec_set_credentials(gensec_client_context, cmdline_credentials); >+ torture_assert_ntstatus_ok(tctx, status, "gensec_set_credentials (client) failed"); >+ >+ status = gensec_start_mech_by_sasl_name(gensec_client_context, "GSS-SPNEGO"); >+ torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (client) failed"); >+ >+ server_to_client = data_blob(NULL, 0); >+ >+ /* Do one step of the client-server update dance */ >+ status = gensec_update(gensec_client_context, tctx, tctx->ev, server_to_client, &client_to_server); >+ if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {; >+ torture_assert_ntstatus_ok(tctx, status, "gensec_update (client) failed"); >+ } >+ >+ torture_assert_int_equal(tctx, dlz_ssumatch(cli_credentials_get_username(cmdline_credentials), >+ name, >+ "127.0.0.1", >+ expected1->records[0].type, >+ "key", >+ client_to_server.length, >+ client_to_server.data, >+ dbdata), >+ ISC_TRUE, >+ "Failed to check key for update rights samba_dlz"); >+ >+ /* >+ * We test the following: >+ * >+ * 1. lookup the records => NOT_FOUND >+ * 2. delete all records => NOT_FOUND >+ * 3. delete 1st record => NOT_FOUND >+ * 4. create 1st record => SUCCESS >+ * 5. lookup the records => found 1st >+ * 6. create 2nd record => SUCCESS >+ * 7. lookup the records => found 1st and 2nd >+ * 8. delete unknown record => NOT_FOUND >+ * 9. lookup the records => found 1st and 2nd >+ * 10. delete 1st record => SUCCESS >+ * 11. lookup the records => found 2nd >+ * 12. delete 2nd record => SUCCESS >+ * 13. lookup the records => NOT_FOUND >+ * 14. create 1st record => SUCCESS >+ * 15. lookup the records => found 1st >+ * 16. create 2nd record => SUCCESS >+ * 17. lookup the records => found 1st and 2nd >+ * 18. update 1st record => SUCCESS >+ * 19. lookup the records => found 1st and 2nd >+ * 20. delete all unknown type records => NOT_FOUND >+ * 21. lookup the records => found 1st and 2nd >+ * 22. delete all records => SUCCESS >+ * 23. lookup the records => NOT_FOUND >+ */ >+ >+ /* Step 1. */ >+ expected1->num_rr = 0; >+ expected1->records[0].printed = false; >+ expected1->records[1].printed = false; >+ torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), >+ expected1->query_name, dbdata, >+ (dns_sdlzlookup_t *)expected1), >+ ISC_R_NOTFOUND, >+ "Found hostname"); >+ torture_assert_int_equal(tctx, expected1->num_rr, 0, >+ "Got wrong record count"); >+ >+ /* Step 2. */ >+ torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), >+ dbdata, &version), >+ ISC_R_SUCCESS, >+ "Failed to start transaction"); >+ torture_assert_int_equal_goto(tctx, >+ dlz_delrdataset(name, >+ expected1->records[0].type, >+ dbdata, version), >+ ISC_R_NOTFOUND, ret, cancel_version, >+ talloc_asprintf(tctx, "Deleted name[%s] type[%s]\n", >+ name, expected1->records[0].type)); >+ dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), false, dbdata, &version); >+ >+ /* Step 3. */ >+ torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), >+ dbdata, &version), >+ ISC_R_SUCCESS, >+ "Failed to start transaction"); >+ torture_assert_int_equal_goto(tctx, >+ dlz_subrdataset(name, data0, dbdata, version), >+ ISC_R_NOTFOUND, ret, cancel_version, >+ talloc_asprintf(tctx, "Deleted name[%s] data[%s]\n", >+ name, data0)); >+ dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), false, dbdata, &version); >+ >+ /* Step 4. */ >+ torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), >+ dbdata, &version), >+ ISC_R_SUCCESS, >+ "Failed to start transaction"); >+ torture_assert_int_equal_goto(tctx, >+ dlz_addrdataset(name, data0, dbdata, version), >+ ISC_R_SUCCESS, ret, cancel_version, >+ talloc_asprintf(tctx, "Failed to add name[%s] data[%s]\n", >+ name, data0)); >+ dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version); >+ >+ /* Step 5. */ >+ expected1->num_rr = 0; >+ expected1->records[0].printed = false; >+ expected1->records[1].printed = false; >+ torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), >+ expected1->query_name, dbdata, >+ (dns_sdlzlookup_t *)expected1), >+ ISC_R_SUCCESS, >+ "Not found hostname"); >+ torture_assert(tctx, expected1->records[0].printed, >+ talloc_asprintf(tctx, >+ "Failed to have putrr callback run name[%s] for type %s", >+ expected1->records[0].name, >+ expected1->records[0].type)); >+ torture_assert_int_equal(tctx, expected1->num_rr, 1, >+ "Got wrong record count"); >+ >+ /* Step 6. */ >+ torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), >+ dbdata, &version), >+ ISC_R_SUCCESS, >+ "Failed to start transaction"); >+ torture_assert_int_equal_goto(tctx, >+ dlz_addrdataset(name, data1, dbdata, version), >+ ISC_R_SUCCESS, ret, cancel_version, >+ talloc_asprintf(tctx, "Failed to add name[%s] data[%s]\n", >+ name, data1)); >+ dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version); >+ >+ /* Step 7. */ >+ expected1->num_rr = 0; >+ expected1->records[0].printed = false; >+ expected1->records[1].printed = false; >+ torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), >+ expected1->query_name, dbdata, >+ (dns_sdlzlookup_t *)expected1), >+ ISC_R_SUCCESS, >+ "Not found hostname"); >+ torture_assert(tctx, expected1->records[0].printed, >+ talloc_asprintf(tctx, >+ "Failed to have putrr callback run name[%s] for type %s", >+ expected1->records[0].name, >+ expected1->records[0].type)); >+ torture_assert(tctx, expected1->records[1].printed, >+ talloc_asprintf(tctx, >+ "Failed to have putrr callback run name[%s] for type %s", >+ expected1->records[1].name, >+ expected1->records[1].type)); >+ torture_assert_int_equal(tctx, expected1->num_rr, 2, >+ "Got wrong record count"); >+ >+ /* Step 8. */ >+ torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), >+ dbdata, &version), >+ ISC_R_SUCCESS, >+ "Failed to start transaction"); >+ torture_assert_int_equal_goto(tctx, >+ dlz_subrdataset(name, data2, dbdata, version), >+ ISC_R_NOTFOUND, ret, cancel_version, >+ talloc_asprintf(tctx, "Deleted name[%s] data[%s]\n", >+ name, data2)); >+ dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version); >+ >+ /* Step 9. */ >+ expected1->num_rr = 0; >+ expected1->records[0].printed = false; >+ expected1->records[1].printed = false; >+ torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), >+ expected1->query_name, dbdata, >+ (dns_sdlzlookup_t *)expected1), >+ ISC_R_SUCCESS, >+ "Not found hostname"); >+ torture_assert(tctx, expected1->records[0].printed, >+ talloc_asprintf(tctx, >+ "Failed to have putrr callback run name[%s] for type %s", >+ expected1->records[0].name, >+ expected1->records[0].type)); >+ torture_assert(tctx, expected1->records[1].printed, >+ talloc_asprintf(tctx, >+ "Failed to have putrr callback run name[%s] for type %s", >+ expected1->records[1].name, >+ expected1->records[1].type)); >+ torture_assert_int_equal(tctx, expected1->num_rr, 2, >+ "Got wrong record count"); >+ >+ /* Step 10. */ >+ torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), >+ dbdata, &version), >+ ISC_R_SUCCESS, >+ "Failed to start transaction"); >+ torture_assert_int_equal_goto(tctx, >+ dlz_subrdataset(name, data0, dbdata, version), >+ ISC_R_SUCCESS, ret, cancel_version, >+ talloc_asprintf(tctx, "Failed to delete name[%s] data[%s]\n", >+ name, data0)); >+ dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version); >+ >+ /* Step 11. */ >+ expected1->num_rr = 0; >+ expected1->records[0].printed = false; >+ expected1->records[1].printed = false; >+ torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), >+ expected1->query_name, dbdata, >+ (dns_sdlzlookup_t *)expected1), >+ ISC_R_SUCCESS, >+ "Not found hostname"); >+ torture_assert(tctx, expected1->records[1].printed, >+ talloc_asprintf(tctx, >+ "Failed to have putrr callback run name[%s] for type %s", >+ expected1->records[1].name, >+ expected1->records[1].type)); >+ torture_assert_int_equal(tctx, expected1->num_rr, 1, >+ "Got wrong record count"); >+ >+ /* Step 12. */ >+ torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), >+ dbdata, &version), >+ ISC_R_SUCCESS, >+ "Failed to start transaction"); >+ torture_assert_int_equal_goto(tctx, >+ dlz_subrdataset(name, data1, dbdata, version), >+ ISC_R_SUCCESS, ret, cancel_version, >+ talloc_asprintf(tctx, "Failed to delete name[%s] data[%s]\n", >+ name, data1)); >+ dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version); >+ >+ /* Step 13. */ >+ expected1->num_rr = 0; >+ expected1->records[0].printed = false; >+ expected1->records[1].printed = false; >+ torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), >+ expected1->query_name, dbdata, >+ (dns_sdlzlookup_t *)expected1), >+ ISC_R_NOTFOUND, >+ "Found hostname"); >+ torture_assert_int_equal(tctx, expected1->num_rr, 0, >+ "Got wrong record count"); >+ >+ /* Step 14. */ >+ torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), >+ dbdata, &version), >+ ISC_R_SUCCESS, >+ "Failed to start transaction"); >+ torture_assert_int_equal_goto(tctx, >+ dlz_addrdataset(name, data0, dbdata, version), >+ ISC_R_SUCCESS, ret, cancel_version, >+ talloc_asprintf(tctx, "Failed to add name[%s] data[%s]\n", >+ name, data0)); >+ dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version); >+ >+ /* Step 15. */ >+ expected1->num_rr = 0; >+ expected1->records[0].printed = false; >+ expected1->records[1].printed = false; >+ torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), >+ expected1->query_name, dbdata, >+ (dns_sdlzlookup_t *)expected1), >+ ISC_R_SUCCESS, >+ "Not found hostname"); >+ torture_assert(tctx, expected1->records[0].printed, >+ talloc_asprintf(tctx, >+ "Failed to have putrr callback run name[%s] for type %s", >+ expected1->records[0].name, >+ expected1->records[0].type)); >+ torture_assert_int_equal(tctx, expected1->num_rr, 1, >+ "Got wrong record count"); >+ >+ /* Step 16. */ >+ torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), >+ dbdata, &version), >+ ISC_R_SUCCESS, >+ "Failed to start transaction"); >+ torture_assert_int_equal_goto(tctx, >+ dlz_addrdataset(name, data1, dbdata, version), >+ ISC_R_SUCCESS, ret, cancel_version, >+ talloc_asprintf(tctx, "Failed to add name[%s] data[%s]\n", >+ name, data1)); >+ dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version); >+ >+ /* Step 17. */ >+ expected1->num_rr = 0; >+ expected1->records[0].printed = false; >+ expected1->records[1].printed = false; >+ torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), >+ expected1->query_name, dbdata, >+ (dns_sdlzlookup_t *)expected1), >+ ISC_R_SUCCESS, >+ "Not found hostname"); >+ torture_assert(tctx, expected1->records[0].printed, >+ talloc_asprintf(tctx, >+ "Failed to have putrr callback run name[%s] for type %s", >+ expected1->records[0].name, >+ expected1->records[0].type)); >+ torture_assert(tctx, expected1->records[1].printed, >+ talloc_asprintf(tctx, >+ "Failed to have putrr callback run name[%s] for type %s", >+ expected1->records[1].name, >+ expected1->records[1].type)); >+ torture_assert_int_equal(tctx, expected1->num_rr, 2, >+ "Got wrong record count"); >+ >+ /* Step 18. */ >+ torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), >+ dbdata, &version), >+ ISC_R_SUCCESS, >+ "Failed to start transaction"); >+ torture_assert_int_equal_goto(tctx, >+ dlz_addrdataset(name, data0, dbdata, version), >+ ISC_R_SUCCESS, ret, cancel_version, >+ talloc_asprintf(tctx, "Failed to update name[%s] data[%s]\n", >+ name, data0)); >+ dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version); >+ >+ /* Step 19. */ >+ expected1->num_rr = 0; >+ expected1->records[0].printed = false; >+ expected1->records[1].printed = false; >+ torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), >+ expected1->query_name, dbdata, >+ (dns_sdlzlookup_t *)expected1), >+ ISC_R_SUCCESS, >+ "Not found hostname"); >+ torture_assert(tctx, expected1->records[0].printed, >+ talloc_asprintf(tctx, >+ "Failed to have putrr callback run name[%s] for type %s", >+ expected1->records[0].name, >+ expected1->records[0].type)); >+ torture_assert(tctx, expected1->records[1].printed, >+ talloc_asprintf(tctx, >+ "Failed to have putrr callback run name[%s] for type %s", >+ expected1->records[1].name, >+ expected1->records[1].type)); >+ torture_assert_int_equal(tctx, expected1->num_rr, 2, >+ "Got wrong record count"); >+ >+ /* Step 20. */ >+ torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), >+ dbdata, &version), >+ ISC_R_SUCCESS, >+ "Failed to start transaction"); >+ torture_assert_int_equal_goto(tctx, >+ dlz_delrdataset(name, "txt", dbdata, version), >+ ISC_R_FAILURE, ret, cancel_version, >+ talloc_asprintf(tctx, "Deleted name[%s] type[%s]\n", >+ name, "txt")); >+ dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), false, dbdata, &version); >+ >+ /* Step 21. */ >+ expected1->num_rr = 0; >+ expected1->records[0].printed = false; >+ expected1->records[1].printed = false; >+ torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), >+ expected1->query_name, dbdata, >+ (dns_sdlzlookup_t *)expected1), >+ ISC_R_SUCCESS, >+ "Not found hostname"); >+ torture_assert(tctx, expected1->records[0].printed, >+ talloc_asprintf(tctx, >+ "Failed to have putrr callback run name[%s] for type %s", >+ expected1->records[0].name, >+ expected1->records[0].type)); >+ torture_assert(tctx, expected1->records[1].printed, >+ talloc_asprintf(tctx, >+ "Failed to have putrr callback run name[%s] for type %s", >+ expected1->records[1].name, >+ expected1->records[1].type)); >+ torture_assert_int_equal(tctx, expected1->num_rr, 2, >+ "Got wrong record count"); >+ >+ /* Step 22. */ >+ torture_assert_int_equal(tctx, dlz_newversion(lpcfg_dnsdomain(tctx->lp_ctx), >+ dbdata, &version), >+ ISC_R_SUCCESS, >+ "Failed to start transaction"); >+ torture_assert_int_equal_goto(tctx, >+ dlz_delrdataset(name, >+ expected1->records[0].type, >+ dbdata, version), >+ ISC_R_SUCCESS, ret, cancel_version, >+ talloc_asprintf(tctx, "Failed to delete name[%s] type[%s]\n", >+ name, expected1->records[0].type)); >+ dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), true, dbdata, &version); >+ >+ /* Step 23. */ >+ expected1->num_rr = 0; >+ expected1->records[0].printed = false; >+ expected1->records[1].printed = false; >+ torture_assert_int_equal(tctx, dlz_lookup(lpcfg_dnsdomain(tctx->lp_ctx), >+ expected1->query_name, dbdata, >+ (dns_sdlzlookup_t *)expected1), >+ ISC_R_NOTFOUND, >+ "Found hostname"); >+ torture_assert_int_equal(tctx, expected1->num_rr, 0, >+ "Got wrong record count"); >+ >+ dlz_destroy(dbdata); >+ >+ return true; >+ >+cancel_version: >+ dlz_closeversion(lpcfg_dnsdomain(tctx->lp_ctx), false, dbdata, &version); >+ return ret; >+} >+ > static struct torture_suite *dlz_bind9_suite(TALLOC_CTX *ctx) > { > struct torture_suite *suite = torture_suite_create(ctx, "dlz_bind9"); >@@ -550,6 +1066,7 @@ static struct torture_suite *dlz_bind9_suite(TALLOC_CTX *ctx) > torture_suite_add_simple_test(suite, "spnego", test_dlz_bind9_spnego); > torture_suite_add_simple_test(suite, "lookup", test_dlz_bind9_lookup); > torture_suite_add_simple_test(suite, "zonedump", test_dlz_bind9_zonedump); >+ torture_suite_add_simple_test(suite, "update01", test_dlz_bind9_update01); > return suite; > } > >-- >1.9.1 > > >From 28ccdbcc5a22a50995e145a91d807a87011194ea Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 30 Jul 2014 08:40:32 +0200 >Subject: [PATCH 18/22] s4:dlz_bind9: let dlz_bind9 use dns_common_lookup() for > name lookup > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 > >Change-Id: I2632fa0ce120a978f6f400fa5cbf18a7fbbd64a3 >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 96dcebe8c20b9aa954a96a4deabe16957576be2c) >--- > source4/dns_server/dlz_bind9.c | 68 +++++++++++----------------------------- > source4/dns_server/wscript_build | 6 ++-- > 2 files changed, 21 insertions(+), 53 deletions(-) > >diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c >index 9f144a4..4479883 100644 >--- a/source4/dns_server/dlz_bind9.c >+++ b/source4/dns_server/dlz_bind9.c >@@ -37,7 +37,7 @@ > #include "messaging/messaging.h" > #include "lib/cmdline/popt_common.h" > #include "dlz_minimal.h" >- >+#include "dns_server/dnsserver_common.h" > > struct b9_options { > const char *url; >@@ -801,11 +801,10 @@ static isc_result_t dlz_lookup_types(struct dlz_bind9_data *state, > const char **types) > { > TALLOC_CTX *tmp_ctx = talloc_new(state); >- const char *attrs[] = { "dnsRecord", NULL }; >- int ret = LDB_SUCCESS, i; >- struct ldb_result *res; >- struct ldb_message_element *el; > struct ldb_dn *dn; >+ WERROR werr = WERR_DNS_ERROR_NAME_DOES_NOT_EXIST; >+ struct dnsp_DnssrvRpcRecord *records = NULL; >+ uint16_t num_records = 0, i; > > for (i=0; zone_prefixes[i]; i++) { > dn = ldb_dn_copy(tmp_ctx, ldb_get_default_basedn(state->samdb)); >@@ -819,38 +818,21 @@ static isc_result_t dlz_lookup_types(struct dlz_bind9_data *state, > return ISC_R_NOMEMORY; > } > >- ret = ldb_search(state->samdb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, >- attrs, "objectClass=dnsNode"); >- if (ret == LDB_SUCCESS) { >+ werr = dns_common_lookup(state->samdb, tmp_ctx, dn, >+ &records, &num_records, NULL); >+ if (W_ERROR_IS_OK(werr)) { > break; > } > } >- if (ret != LDB_SUCCESS || res->count == 0) { >+ if (!W_ERROR_IS_OK(werr)) { > talloc_free(tmp_ctx); > return ISC_R_NOTFOUND; > } > >- el = ldb_msg_find_element(res->msgs[0], "dnsRecord"); >- if (el == NULL || el->num_values == 0) { >- talloc_free(tmp_ctx); >- return ISC_R_NOTFOUND; >- } >- >- for (i=0; i<el->num_values; i++) { >- struct dnsp_DnssrvRpcRecord rec; >- enum ndr_err_code ndr_err; >+ for (i=0; i < num_records; i++) { > isc_result_t result; > >- ndr_err = ndr_pull_struct_blob(&el->values[i], tmp_ctx, &rec, >- (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord); >- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >- state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s", >- ldb_dn_get_linearized(dn)); >- talloc_free(tmp_ctx); >- return ISC_R_FAILURE; >- } >- >- result = b9_putrr(state, lookup, &rec, types); >+ result = b9_putrr(state, lookup, &records[i], types); > if (result != ISC_R_SUCCESS) { > talloc_free(tmp_ctx); > return result; >@@ -1059,39 +1041,25 @@ _PUBLIC_ void dlz_closeversion(const char *zone, isc_boolean_t commit, > */ > static bool b9_has_soa(struct dlz_bind9_data *state, struct ldb_dn *dn, const char *zone) > { >- const char *attrs[] = { "dnsRecord", NULL }; >- struct ldb_result *res; >- struct ldb_message_element *el; > TALLOC_CTX *tmp_ctx = talloc_new(state); >- int ret, i; >+ WERROR werr; >+ struct dnsp_DnssrvRpcRecord *records = NULL; >+ uint16_t num_records = 0, i; > > if (!ldb_dn_add_child_fmt(dn, "DC=@,DC=%s", zone)) { > talloc_free(tmp_ctx); > return false; > } > >- ret = ldb_search(state->samdb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, >- attrs, "objectClass=dnsNode"); >- if (ret != LDB_SUCCESS) { >- talloc_free(tmp_ctx); >- return false; >- } >- >- el = ldb_msg_find_element(res->msgs[0], "dnsRecord"); >- if (el == NULL) { >+ werr = dns_common_lookup(state->samdb, tmp_ctx, dn, >+ &records, &num_records, NULL); >+ if (!W_ERROR_IS_OK(werr)) { > talloc_free(tmp_ctx); > return false; > } >- for (i=0; i<el->num_values; i++) { >- struct dnsp_DnssrvRpcRecord rec; >- enum ndr_err_code ndr_err; > >- ndr_err = ndr_pull_struct_blob(&el->values[i], tmp_ctx, &rec, >- (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord); >- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >- continue; >- } >- if (rec.wType == DNS_TYPE_SOA) { >+ for (i=0; i < num_records; i++) { >+ if (records[i].wType == DNS_TYPE_SOA) { > talloc_free(tmp_ctx); > return true; > } >diff --git a/source4/dns_server/wscript_build b/source4/dns_server/wscript_build >index 66e6b72..a92ab67 100644 >--- a/source4/dns_server/wscript_build >+++ b/source4/dns_server/wscript_build >@@ -24,7 +24,7 @@ bld.SAMBA_LIBRARY('dlz_bind9', > link_name='modules/bind9/dlz_bind9.so', > realname='dlz_bind9.so', > install_path='${MODULESDIR}/bind9', >- deps='samba-hostconfig samdb-common gensec popt', >+ deps='samba-hostconfig samdb-common gensec popt dnsserver_common', > enabled=bld.AD_DC_BUILD_IS_ENABLED()) > > bld.SAMBA_LIBRARY('dlz_bind9_9', >@@ -34,12 +34,12 @@ bld.SAMBA_LIBRARY('dlz_bind9_9', > link_name='modules/bind9/dlz_bind9_9.so', > realname='dlz_bind9_9.so', > install_path='${MODULESDIR}/bind9', >- deps='samba-hostconfig samdb-common gensec popt', >+ deps='samba-hostconfig samdb-common gensec popt dnsserver_common', > enabled=bld.AD_DC_BUILD_IS_ENABLED()) > > bld.SAMBA_LIBRARY('dlz_bind9_for_torture', > source='dlz_bind9.c', > cflags='-DBIND_VERSION_9_8', > private_library=True, >- deps='samba-hostconfig samdb-common gensec popt', >+ deps='samba-hostconfig samdb-common gensec popt dnsserver_common', > enabled=bld.AD_DC_BUILD_IS_ENABLED()) >-- >1.9.1 > > >From a5baab4e1183a3be6bca69d4d5f4e9be37ac7f58 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 30 Jul 2014 17:59:08 +0200 >Subject: [PATCH 19/22] s4:dlz_bind9: let dlz_bind9 use dns_common_extract() > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 > >Change-Id: I7c661964a3da1a1981f022a06b9bef25bbd33479 >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit dedcf30fd12821c272002e3b4cbfda4ca38650fd) >--- > source4/dns_server/dlz_bind9.c | 118 +++++++++++++++++++++-------------------- > 1 file changed, 61 insertions(+), 57 deletions(-) > >diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c >index 4479883..7942e77 100644 >--- a/source4/dns_server/dlz_bind9.c >+++ b/source4/dns_server/dlz_bind9.c >@@ -911,6 +911,9 @@ _PUBLIC_ isc_result_t dlz_allnodes(const char *zone, void *dbdata, > TALLOC_CTX *el_ctx = talloc_new(tmp_ctx); > const char *rdn, *name; > const struct ldb_val *v; >+ WERROR werr; >+ struct dnsp_DnssrvRpcRecord *recs = NULL; >+ uint16_t num_recs = 0; > > el = ldb_msg_find_element(res->msgs[i], "dnsRecord"); > if (el == NULL || el->num_values == 0) { >@@ -944,20 +947,18 @@ _PUBLIC_ isc_result_t dlz_allnodes(const char *zone, void *dbdata, > return ISC_R_NOMEMORY; > } > >- for (j=0; j<el->num_values; j++) { >- struct dnsp_DnssrvRpcRecord rec; >- enum ndr_err_code ndr_err; >- isc_result_t result; >+ werr = dns_common_extract(el, el_ctx, &recs, &num_recs); >+ if (!W_ERROR_IS_OK(werr)) { >+ state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s, %s", >+ ldb_dn_get_linearized(dn), win_errstr(werr)); >+ talloc_free(el_ctx); >+ continue; >+ } > >- ndr_err = ndr_pull_struct_blob(&el->values[j], el_ctx, &rec, >- (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord); >- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >- state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s", >- ldb_dn_get_linearized(dn)); >- continue; >- } >+ for (j=0; j < num_recs; j++) { >+ isc_result_t result; > >- result = b9_putnamedrr(state, allnodes, name, &rec); >+ result = b9_putnamedrr(state, allnodes, name, &recs[j]); > if (result != ISC_R_SUCCESS) { > continue; > } >@@ -1462,8 +1463,11 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo > const char *attrs[] = { "dnsRecord", NULL }; > int ret, i; > struct ldb_message_element *el; >+ struct dnsp_DnssrvRpcRecord *recs = NULL; >+ uint16_t num_recs = 0; > enum ndr_err_code ndr_err; > NTTIME t; >+ WERROR werr; > > if (state->transaction_token != (void*)version) { > state->log(ISC_LOG_INFO, "samba_dlz: bad transaction version"); >@@ -1523,22 +1527,19 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo > } > } > >+ werr = dns_common_extract(el, rec, &recs, &num_recs); >+ if (!W_ERROR_IS_OK(werr)) { >+ state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s, %s", >+ ldb_dn_get_linearized(dn), win_errstr(werr)); >+ talloc_free(rec); >+ return ISC_R_FAILURE; >+ } >+ > /* there are existing records. We need to see if this will > * replace a record or add to it > */ >- for (i=0; i<el->num_values; i++) { >- struct dnsp_DnssrvRpcRecord rec2; >- >- ndr_err = ndr_pull_struct_blob(&el->values[i], rec, &rec2, >- (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord); >- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >- state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s", >- ldb_dn_get_linearized(dn)); >- talloc_free(rec); >- return ISC_R_FAILURE; >- } >- >- if (b9_record_match(state, rec, &rec2)) { >+ for (i=0; i < num_recs; i++) { >+ if (b9_record_match(state, rec, &recs[i])) { > break; > } > } >@@ -1597,7 +1598,9 @@ _PUBLIC_ isc_result_t dlz_subrdataset(const char *name, const char *rdatastr, vo > const char *attrs[] = { "dnsRecord", NULL }; > int ret, i; > struct ldb_message_element *el; >- enum ndr_err_code ndr_err; >+ struct dnsp_DnssrvRpcRecord *recs = NULL; >+ uint16_t num_recs = 0; >+ WERROR werr; > > if (state->transaction_token != (void*)version) { > state->log(ISC_LOG_ERROR, "samba_dlz: bad transaction version"); >@@ -1639,19 +1642,16 @@ _PUBLIC_ isc_result_t dlz_subrdataset(const char *name, const char *rdatastr, vo > return ISC_R_FAILURE; > } > >- for (i=0; i<el->num_values; i++) { >- struct dnsp_DnssrvRpcRecord rec2; >- >- ndr_err = ndr_pull_struct_blob(&el->values[i], rec, &rec2, >- (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord); >- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >- state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s", >- ldb_dn_get_linearized(dn)); >- talloc_free(rec); >- return ISC_R_FAILURE; >- } >+ werr = dns_common_extract(el, rec, &recs, &num_recs); >+ if (!W_ERROR_IS_OK(werr)) { >+ state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s, %s", >+ ldb_dn_get_linearized(dn), win_errstr(werr)); >+ talloc_free(rec); >+ return ISC_R_FAILURE; >+ } > >- if (b9_record_match(state, rec, &rec2)) { >+ for (i=0; i < num_recs; i++) { >+ if (b9_record_match(state, rec, &recs[i])) { > break; > } > } >@@ -1703,11 +1703,15 @@ _PUBLIC_ isc_result_t dlz_delrdataset(const char *name, const char *type, void * > isc_result_t result; > struct ldb_result *res; > const char *attrs[] = { "dnsRecord", NULL }; >- int ret, i; >+ int ret; > struct ldb_message_element *el; >- enum ndr_err_code ndr_err; >+ int vi = 0; > enum dns_record_type dns_type; > bool found = false; >+ struct dnsp_DnssrvRpcRecord *recs = NULL; >+ uint16_t num_recs = 0; >+ uint16_t ri = 0; >+ WERROR werr; > > if (state->transaction_token != (void*)version) { > state->log(ISC_LOG_ERROR, "samba_dlz: bad transaction version"); >@@ -1743,27 +1747,27 @@ _PUBLIC_ isc_result_t dlz_delrdataset(const char *name, const char *type, void * > return ISC_R_NOTFOUND; > } > >- for (i=0; i<el->num_values; i++) { >- struct dnsp_DnssrvRpcRecord rec2; >+ werr = dns_common_extract(el, tmp_ctx, &recs, &num_recs); >+ if (!W_ERROR_IS_OK(werr)) { >+ state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s, %s", >+ ldb_dn_get_linearized(dn), win_errstr(werr)); >+ talloc_free(tmp_ctx); >+ return ISC_R_FAILURE; >+ } > >- ndr_err = ndr_pull_struct_blob(&el->values[i], tmp_ctx, &rec2, >- (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord); >- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >- state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s", >- ldb_dn_get_linearized(dn)); >- talloc_free(tmp_ctx); >- return ISC_R_FAILURE; >+ for (ri=0; ri < num_recs; ri++) { >+ if (dns_type != recs[ri].wType) { >+ vi += 1; >+ continue; > } > >- if (dns_type == rec2.wType) { >- if (i < el->num_values-1) { >- memmove(&el->values[i], &el->values[i+1], >- sizeof(el->values[0])*((el->num_values-1)-i)); >- } >- el->num_values--; >- i--; >- found = true; >+ found = true; >+ >+ if (vi < el->num_values-1) { >+ memmove(&el->values[vi], &el->values[vi+1], >+ sizeof(el->values[0])*((el->num_values-1)-vi)); > } >+ el->num_values--; > } > > if (!found) { >-- >1.9.1 > > >From afeb1969c1c30f3dc91f313481505ab041170698 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 30 Jul 2014 18:51:39 +0200 >Subject: [PATCH 20/22] s4:dlz_bind9: let dlz_bind9 use dns_common_replace() > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 > >Change-Id: I2fd2503230cbf89445594e49f39ac321769ff06e >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit fd952bf814835c4860ab10794225fbd583ee3ad5) >--- > source4/dns_server/dlz_bind9.c | 127 ++++++++++++++++------------------------- > 1 file changed, 50 insertions(+), 77 deletions(-) > >diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c >index 7942e77..082759d 100644 >--- a/source4/dns_server/dlz_bind9.c >+++ b/source4/dns_server/dlz_bind9.c >@@ -1300,32 +1300,15 @@ static isc_result_t b9_add_record(struct dlz_bind9_data *state, const char *name > struct ldb_dn *dn, > struct dnsp_DnssrvRpcRecord *rec) > { >- struct ldb_message *msg; >- enum ndr_err_code ndr_err; >- struct ldb_val v; >- int ret; >- >- msg = ldb_msg_new(rec); >- if (msg == NULL) { >- return ISC_R_NOMEMORY; >- } >- msg->dn = dn; >- ret = ldb_msg_add_string(msg, "objectClass", "dnsNode"); >- if (ret != LDB_SUCCESS) { >- return ISC_R_FAILURE; >- } >- >- ndr_err = ndr_push_struct_blob(&v, rec, rec, (ndr_push_flags_fn_t)ndr_push_dnsp_DnssrvRpcRecord); >- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >- return ISC_R_FAILURE; >- } >- ret = ldb_msg_add_value(msg, "dnsRecord", &v, NULL); >- if (ret != LDB_SUCCESS) { >- return ISC_R_FAILURE; >- } >+ WERROR werr; > >- ret = ldb_add(state->samdb, msg); >- if (ret != LDB_SUCCESS) { >+ werr = dns_common_replace(state->samdb, rec, dn, >+ true,/* needs_add */ >+ state->soa_serial, >+ rec, 1); >+ if (!W_ERROR_IS_OK(werr)) { >+ state->log(ISC_LOG_ERROR, "samba_dlz: failed to add %s - %s", >+ ldb_dn_get_linearized(dn), win_errstr(werr)); > return ISC_R_FAILURE; > } > >@@ -1465,7 +1448,6 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo > struct ldb_message_element *el; > struct dnsp_DnssrvRpcRecord *recs = NULL; > uint16_t num_recs = 0; >- enum ndr_err_code ndr_err; > NTTIME t; > WERROR werr; > >@@ -1484,7 +1466,6 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo > t /= 3600; /* convert to hours */ > > rec->rank = DNS_RANK_ZONE; >- rec->dwSerial = state->soa_serial; > rec->dwTimeStamp = (uint32_t)t; > > if (!b9_parse(state, rdatastr, rec)) { >@@ -1543,25 +1524,26 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo > break; > } > } >- if (i == el->num_values) { >+ if (i == UINT16_MAX) { >+ state->log(ISC_LOG_ERROR, "samba_dlz: failed to already %u dnsRecord values for %s", >+ i, ldb_dn_get_linearized(dn)); >+ talloc_free(rec); >+ return ISC_R_FAILURE; >+ } >+ >+ if (i == num_recs) { > /* adding a new value */ >- el->values = talloc_realloc(el, el->values, struct ldb_val, el->num_values+1); >- if (el->values == NULL) { >+ recs = talloc_realloc(rec, recs, >+ struct dnsp_DnssrvRpcRecord, >+ num_recs + 1); >+ if (recs == NULL) { > talloc_free(rec); > return ISC_R_NOMEMORY; > } >- el->num_values++; >- } >- >- ndr_err = ndr_push_struct_blob(&el->values[i], rec, rec, >- (ndr_push_flags_fn_t)ndr_push_dnsp_DnssrvRpcRecord); >- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >- state->log(ISC_LOG_ERROR, "samba_dlz: failed to push dnsRecord for %s", >- ldb_dn_get_linearized(dn)); >- talloc_free(rec); >- return ISC_R_FAILURE; >+ num_recs++; > } > >+ recs[i] = *rec; > > if (!b9_set_session_info(state, name)) { > talloc_free(rec); >@@ -1569,12 +1551,14 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo > } > > /* modify the record */ >- el->flags = LDB_FLAG_MOD_REPLACE; >- ret = ldb_modify(state->samdb, res->msgs[0]); >+ werr = dns_common_replace(state->samdb, rec, dn, >+ false,/* needs_add */ >+ state->soa_serial, >+ recs, num_recs); > b9_reset_session_info(state); >- if (ret != LDB_SUCCESS) { >+ if (!W_ERROR_IS_OK(werr)) { > state->log(ISC_LOG_ERROR, "samba_dlz: failed to modify %s - %s", >- ldb_dn_get_linearized(dn), ldb_errstring(state->samdb)); >+ ldb_dn_get_linearized(dn), win_errstr(werr)); > talloc_free(rec); > return ISC_R_FAILURE; > } >@@ -1652,35 +1636,31 @@ _PUBLIC_ isc_result_t dlz_subrdataset(const char *name, const char *rdatastr, vo > > for (i=0; i < num_recs; i++) { > if (b9_record_match(state, rec, &recs[i])) { >+ recs[i] = (struct dnsp_DnssrvRpcRecord) { >+ .wType = DNS_TYPE_TOMBSTONE, >+ }; > break; > } > } >- if (i == el->num_values) { >+ if (i == num_recs) { > talloc_free(rec); > return ISC_R_NOTFOUND; > } > >- if (i < el->num_values-1) { >- memmove(&el->values[i], &el->values[i+1], sizeof(el->values[0])*((el->num_values-1)-i)); >- } >- el->num_values--; >- > if (!b9_set_session_info(state, name)) { > talloc_free(rec); > return ISC_R_FAILURE; > } > >- if (el->num_values == 0) { >- el->flags = LDB_FLAG_MOD_DELETE; >- } else { >- el->flags = LDB_FLAG_MOD_REPLACE; >- } >- ret = ldb_modify(state->samdb, res->msgs[0]); >- >+ /* modify the record */ >+ werr = dns_common_replace(state->samdb, rec, dn, >+ false,/* needs_add */ >+ state->soa_serial, >+ recs, num_recs); > b9_reset_session_info(state); >- if (ret != LDB_SUCCESS) { >+ if (!W_ERROR_IS_OK(werr)) { > state->log(ISC_LOG_ERROR, "samba_dlz: failed to modify %s - %s", >- ldb_dn_get_linearized(dn), ldb_errstring(state->samdb)); >+ ldb_dn_get_linearized(dn), win_errstr(werr)); > talloc_free(rec); > return ISC_R_FAILURE; > } >@@ -1705,7 +1685,6 @@ _PUBLIC_ isc_result_t dlz_delrdataset(const char *name, const char *type, void * > const char *attrs[] = { "dnsRecord", NULL }; > int ret; > struct ldb_message_element *el; >- int vi = 0; > enum dns_record_type dns_type; > bool found = false; > struct dnsp_DnssrvRpcRecord *recs = NULL; >@@ -1757,17 +1736,13 @@ _PUBLIC_ isc_result_t dlz_delrdataset(const char *name, const char *type, void * > > for (ri=0; ri < num_recs; ri++) { > if (dns_type != recs[ri].wType) { >- vi += 1; > continue; > } > > found = true; >- >- if (vi < el->num_values-1) { >- memmove(&el->values[vi], &el->values[vi+1], >- sizeof(el->values[0])*((el->num_values-1)-vi)); >- } >- el->num_values--; >+ recs[ri] = (struct dnsp_DnssrvRpcRecord) { >+ .wType = DNS_TYPE_TOMBSTONE, >+ }; > } > > if (!found) { >@@ -1780,17 +1755,15 @@ _PUBLIC_ isc_result_t dlz_delrdataset(const char *name, const char *type, void * > return ISC_R_FAILURE; > } > >- if (el->num_values == 0) { >- el->flags = LDB_FLAG_MOD_DELETE; >- } else { >- el->flags = LDB_FLAG_MOD_REPLACE; >- } >- ret = ldb_modify(state->samdb, res->msgs[0]); >- >+ /* modify the record */ >+ werr = dns_common_replace(state->samdb, tmp_ctx, dn, >+ false,/* needs_add */ >+ state->soa_serial, >+ recs, num_recs); > b9_reset_session_info(state); >- if (ret != LDB_SUCCESS) { >- state->log(ISC_LOG_ERROR, "samba_dlz: failed to delete type %s in %s - %s", >- type, ldb_dn_get_linearized(dn), ldb_errstring(state->samdb)); >+ if (!W_ERROR_IS_OK(werr)) { >+ state->log(ISC_LOG_ERROR, "samba_dlz: failed to modify %s - %s", >+ ldb_dn_get_linearized(dn), win_errstr(werr)); > talloc_free(tmp_ctx); > return ISC_R_FAILURE; > } >-- >1.9.1 > > >From 07677f756a96c37f85e6479c3754aebca9f42155 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 30 Jul 2014 20:12:08 +0200 >Subject: [PATCH 21/22] s4:dlz_bind9: let dlz_bind9 use dns_common_lookup() > before removing records > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 11bbfd932c113b3222bc93d59702271a3777b6f3) >--- > source4/dns_server/dlz_bind9.c | 53 ++++++------------------------------------ > 1 file changed, 7 insertions(+), 46 deletions(-) > >diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c >index 082759d..d15545e 100644 >--- a/source4/dns_server/dlz_bind9.c >+++ b/source4/dns_server/dlz_bind9.c >@@ -1578,12 +1578,9 @@ _PUBLIC_ isc_result_t dlz_subrdataset(const char *name, const char *rdatastr, vo > struct dnsp_DnssrvRpcRecord *rec; > struct ldb_dn *dn; > isc_result_t result; >- struct ldb_result *res; >- const char *attrs[] = { "dnsRecord", NULL }; >- int ret, i; >- struct ldb_message_element *el; > struct dnsp_DnssrvRpcRecord *recs = NULL; > uint16_t num_recs = 0; >+ uint16_t i; > WERROR werr; > > if (state->transaction_token != (void*)version) { >@@ -1610,28 +1607,11 @@ _PUBLIC_ isc_result_t dlz_subrdataset(const char *name, const char *rdatastr, vo > } > > /* get the existing records */ >- ret = ldb_search(state->samdb, rec, &res, dn, LDB_SCOPE_BASE, attrs, "objectClass=dnsNode"); >- if (ret == LDB_ERR_NO_SUCH_OBJECT) { >- talloc_free(rec); >- return ISC_R_NOTFOUND; >- } >- >- /* there are existing records. We need to see if any match >- */ >- el = ldb_msg_find_element(res->msgs[0], "dnsRecord"); >- if (el == NULL || el->num_values == 0) { >- state->log(ISC_LOG_ERROR, "samba_dlz: no dnsRecord attribute for %s", >- ldb_dn_get_linearized(dn)); >- talloc_free(rec); >- return ISC_R_FAILURE; >- } >- >- werr = dns_common_extract(el, rec, &recs, &num_recs); >+ werr = dns_common_lookup(state->samdb, rec, dn, >+ &recs, &num_recs, NULL); > if (!W_ERROR_IS_OK(werr)) { >- state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s, %s", >- ldb_dn_get_linearized(dn), win_errstr(werr)); > talloc_free(rec); >- return ISC_R_FAILURE; >+ return ISC_R_NOTFOUND; > } > > for (i=0; i < num_recs; i++) { >@@ -1681,10 +1661,6 @@ _PUBLIC_ isc_result_t dlz_delrdataset(const char *name, const char *type, void * > TALLOC_CTX *tmp_ctx; > struct ldb_dn *dn; > isc_result_t result; >- struct ldb_result *res; >- const char *attrs[] = { "dnsRecord", NULL }; >- int ret; >- struct ldb_message_element *el; > enum dns_record_type dns_type; > bool found = false; > struct dnsp_DnssrvRpcRecord *recs = NULL; >@@ -1712,26 +1688,11 @@ _PUBLIC_ isc_result_t dlz_delrdataset(const char *name, const char *type, void * > } > > /* get the existing records */ >- ret = ldb_search(state->samdb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, attrs, "objectClass=dnsNode"); >- if (ret == LDB_ERR_NO_SUCH_OBJECT) { >- talloc_free(tmp_ctx); >- return ISC_R_NOTFOUND; >- } >- >- /* there are existing records. We need to see if any match the type >- */ >- el = ldb_msg_find_element(res->msgs[0], "dnsRecord"); >- if (el == NULL || el->num_values == 0) { >- talloc_free(tmp_ctx); >- return ISC_R_NOTFOUND; >- } >- >- werr = dns_common_extract(el, tmp_ctx, &recs, &num_recs); >+ werr = dns_common_lookup(state->samdb, tmp_ctx, dn, >+ &recs, &num_recs, NULL); > if (!W_ERROR_IS_OK(werr)) { >- state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s, %s", >- ldb_dn_get_linearized(dn), win_errstr(werr)); > talloc_free(tmp_ctx); >- return ISC_R_FAILURE; >+ return ISC_R_NOTFOUND; > } > > for (ri=0; ri < num_recs; ri++) { >-- >1.9.1 > > >From 02266fd52e6f751ede65018c0c8a683096f6d9ff Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 31 Jul 2014 09:30:16 +0200 >Subject: [PATCH 22/22] s4:dlz_bind9: let dlz_bind9 use dns_common_lookup() > before add/modify > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Wed Aug 27 15:21:19 CEST 2014 on sn-devel-104 > >(cherry picked from commit d68a2ebecd244181b1238635ee54dadd05835525) >--- > source4/dns_server/dlz_bind9.c | 77 ++++++++++++------------------------------ > 1 file changed, 21 insertions(+), 56 deletions(-) > >diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c >index d15545e..db0993c 100644 >--- a/source4/dns_server/dlz_bind9.c >+++ b/source4/dns_server/dlz_bind9.c >@@ -1292,29 +1292,6 @@ _PUBLIC_ isc_boolean_t dlz_ssumatch(const char *signer, const char *name, const > return ISC_TRUE; > } > >- >-/* >- add a new record >- */ >-static isc_result_t b9_add_record(struct dlz_bind9_data *state, const char *name, >- struct ldb_dn *dn, >- struct dnsp_DnssrvRpcRecord *rec) >-{ >- WERROR werr; >- >- werr = dns_common_replace(state->samdb, rec, dn, >- true,/* needs_add */ >- state->soa_serial, >- rec, 1); >- if (!W_ERROR_IS_OK(werr)) { >- state->log(ISC_LOG_ERROR, "samba_dlz: failed to add %s - %s", >- ldb_dn_get_linearized(dn), win_errstr(werr)); >- return ISC_R_FAILURE; >- } >- >- return ISC_R_SUCCESS; >-} >- > /* > see if two DNS names are the same > */ >@@ -1442,12 +1419,12 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo > struct dnsp_DnssrvRpcRecord *rec; > struct ldb_dn *dn; > isc_result_t result; >- struct ldb_result *res; >- const char *attrs[] = { "dnsRecord", NULL }; >- int ret, i; >- struct ldb_message_element *el; >+ bool tombstoned = false; >+ bool needs_add = false; > struct dnsp_DnssrvRpcRecord *recs = NULL; > uint16_t num_recs = 0; >+ uint16_t first = 0; >+ uint16_t i; > NTTIME t; > WERROR werr; > >@@ -1482,33 +1459,12 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo > } > > /* get any existing records */ >- ret = ldb_search(state->samdb, rec, &res, dn, LDB_SCOPE_BASE, attrs, "objectClass=dnsNode"); >- if (ret == LDB_ERR_NO_SUCH_OBJECT) { >- if (!b9_set_session_info(state, name)) { >- talloc_free(rec); >- return ISC_R_FAILURE; >- } >- result = b9_add_record(state, name, dn, rec); >- b9_reset_session_info(state); >- talloc_free(rec); >- if (result == ISC_R_SUCCESS) { >- state->log(ISC_LOG_INFO, "samba_dlz: added %s %s", name, rdatastr); >- } >- return result; >- } >- >- el = ldb_msg_find_element(res->msgs[0], "dnsRecord"); >- if (el == NULL) { >- ret = ldb_msg_add_empty(res->msgs[0], "dnsRecord", LDB_FLAG_MOD_ADD, &el); >- if (ret != LDB_SUCCESS) { >- state->log(ISC_LOG_ERROR, "samba_dlz: failed to add dnsRecord for %s", >- ldb_dn_get_linearized(dn)); >- talloc_free(rec); >- return ISC_R_FAILURE; >- } >+ werr = dns_common_lookup(state->samdb, rec, dn, >+ &recs, &num_recs, &tombstoned); >+ if (W_ERROR_EQUAL(werr, WERR_DNS_ERROR_NAME_DOES_NOT_EXIST)) { >+ needs_add = true; >+ werr = WERR_OK; > } >- >- werr = dns_common_extract(el, rec, &recs, &num_recs); > if (!W_ERROR_IS_OK(werr)) { > state->log(ISC_LOG_ERROR, "samba_dlz: failed to parse dnsRecord for %s, %s", > ldb_dn_get_linearized(dn), win_errstr(werr)); >@@ -1516,10 +1472,18 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo > return ISC_R_FAILURE; > } > >+ if (tombstoned) { >+ /* >+ * we need to keep the existing tombstone record >+ * and ignore it >+ */ >+ first = num_recs; >+ } >+ > /* there are existing records. We need to see if this will > * replace a record or add to it > */ >- for (i=0; i < num_recs; i++) { >+ for (i=first; i < num_recs; i++) { > if (b9_record_match(state, rec, &recs[i])) { > break; > } >@@ -1552,12 +1516,13 @@ _PUBLIC_ isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, vo > > /* modify the record */ > werr = dns_common_replace(state->samdb, rec, dn, >- false,/* needs_add */ >+ needs_add, > state->soa_serial, > recs, num_recs); > b9_reset_session_info(state); > if (!W_ERROR_IS_OK(werr)) { >- state->log(ISC_LOG_ERROR, "samba_dlz: failed to modify %s - %s", >+ state->log(ISC_LOG_ERROR, "samba_dlz: failed to %s %s - %s", >+ needs_add ? "add" : "modify", > ldb_dn_get_linearized(dn), win_errstr(werr)); > talloc_free(rec); > return ISC_R_FAILURE; >-- >1.9.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 10749
:
10184
|
10202
|
10242
|
10243
|
10244
|
10248
|
10251
|
10252
|
10253
|
10255