The Samba-Bugzilla – Attachment 10243 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-1-test
tmp41.diff (text/plain), 110.45 KB, created by
Stefan Metzmacher
on 2014-09-01 09:32:21 UTC
(
hide
)
Description:
Patches for v4-1-test
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2014-09-01 09:32:21 UTC
Size:
110.45 KB
patch
obsolete
>From 80801df8b4e57e8899047491a0de7ba02dbefb4e Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 30 Jul 2014 17:55:57 +0200 >Subject: [PATCH 01/21] 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 72782cf..86f7e7c 100644 >--- a/source4/dns_server/dns_utils.c >+++ b/source4/dns_server/dns_utils.c >@@ -43,6 +43,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 28aa4a4b5345544b7772f5b989c8bab5f40bb7ed Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 31 Jul 2014 08:19:50 +0200 >Subject: [PATCH 02/21] 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 9edc40b..c439d8d 100644 >--- a/source4/dns_server/dns_update.c >+++ b/source4/dns_server/dns_update.c >@@ -82,6 +82,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) { >@@ -91,6 +94,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); > } >@@ -131,10 +137,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++) { >@@ -163,6 +170,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); > } >@@ -421,12 +431,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 86f7e7c..14ca2f4 100644 >--- a/source4/dns_server/dns_utils.c >+++ b/source4/dns_server/dns_utils.c >@@ -194,8 +194,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 */ >@@ -204,8 +210,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); > } > >@@ -278,13 +282,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 d22ce39f7629fb696d617b99e49519771994cf61 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 30 Jul 2014 08:01:11 +0200 >Subject: [PATCH 03/21] 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> >(cherry picked from commit 99d5a5ead4f33723c25e8716a79d34b53822521e) >--- > source4/dns_server/dns_server.h | 4 +-- > source4/dns_server/dns_utils.c | 33 ----------------- > source4/dns_server/dnsserver_common.c | 68 +++++++++++++++++++++++++++++++++++ > source4/dns_server/dnsserver_common.h | 28 +++++++++++++++ > source4/dns_server/wscript_build | 8 ++++- > 5 files changed, 105 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 14ca2f4..461e58d 100644 >--- a/source4/dns_server/dns_utils.c >+++ b/source4/dns_server/dns_utils.c >@@ -33,39 +33,6 @@ > #undef DBGC_CLASS > #define DBGC_CLASS DBGC_DNS > >-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..997ce03 >--- /dev/null >+++ b/source4/dns_server/dnsserver_common.c >@@ -0,0 +1,68 @@ >+/* >+ 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" >+ >+#undef DBGC_CLASS >+#define DBGC_CLASS DBGC_DNS >+ >+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 5e79a6370a613884f68de504580505cf120f6187 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 30 Jul 2014 08:24:10 +0200 >Subject: [PATCH 04/21] 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 | 45 +------------------- > source4/dns_server/dnsserver_common.c | 78 +++++++++++++++++++++++++++++++++++ > source4/dns_server/dnsserver_common.h | 13 ++++++ > 3 files changed, 92 insertions(+), 44 deletions(-) > >diff --git a/source4/dns_server/dns_utils.c b/source4/dns_server/dns_utils.c >index 461e58d..3bfa98b 100644 >--- a/source4/dns_server/dns_utils.c >+++ b/source4/dns_server/dns_utils.c >@@ -154,50 +154,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); >- 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)) { >- 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 997ce03..c1d08b2 100644 >--- a/source4/dns_server/dnsserver_common.c >+++ b/source4/dns_server/dnsserver_common.c >@@ -66,3 +66,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 af3fdc179ea07ce9ee9c7d5bdf5ba87c560c9965 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 31 Jul 2014 11:32:02 +0200 >Subject: [PATCH 05/21] 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 3bfa98b..cf1adcc 100644 >--- a/source4/dns_server/dns_utils.c >+++ b/source4/dns_server/dns_utils.c >@@ -161,7 +161,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 564b13b1972c9c7dc4e663a2bfddb3e4f3e76083 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 30 Jul 2014 18:27:56 +0200 >Subject: [PATCH 06/21] 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 c439d8d..a589d63 100644 >--- a/source4/dns_server/dns_update.c >+++ b/source4/dns_server/dns_update.c >@@ -312,8 +312,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 cf1adcc..c3a27fe 100644 >--- a/source4/dns_server/dns_utils.c >+++ b/source4/dns_server/dns_utils.c >@@ -164,72 +164,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 c1d08b2..3a777e5 100644 >--- a/source4/dns_server/dnsserver_common.c >+++ b/source4/dns_server/dnsserver_common.c >@@ -144,3 +144,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 201c6577a384b39f995c6b5ff7a6cf97c566f21f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 31 Jul 2014 09:32:00 +0200 >Subject: [PATCH 07/21] 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 a589d63..4ff82b4 100644 >--- a/source4/dns_server/dns_update.c >+++ b/source4/dns_server/dns_update.c >@@ -521,7 +521,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, >@@ -570,12 +572,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, >+ }; > } > } > >@@ -591,7 +597,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, >+ }; > } > } > >@@ -635,7 +643,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 bc041119ca8c9096bd860d5618cb7cc8752c02f6 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 31 Jul 2014 08:54:17 +0200 >Subject: [PATCH 08/21] 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 c3a27fe..c757c15 100644 >--- a/source4/dns_server/dns_utils.c >+++ b/source4/dns_server/dns_utils.c >@@ -154,7 +154,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 3a777e5..2866734 100644 >--- a/source4/dns_server/dnsserver_common.c >+++ b/source4/dns_server/dnsserver_common.c >@@ -104,10 +104,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; >@@ -118,9 +120,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; > } >@@ -130,9 +139,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 c505e8ba3bb87540d608862f5b2d0dfb64584e90 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 31 Jul 2014 10:44:41 +0200 >Subject: [PATCH 09/21] 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 2866734..c49d6ec 100644 >--- a/source4/dns_server/dnsserver_common.c >+++ b/source4/dns_server/dnsserver_common.c >@@ -190,6 +190,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, >@@ -202,6 +218,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); >@@ -213,17 +231,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; > } > >@@ -256,7 +287,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 f25fb80441c2d9431f7b1a1de15e54ba3bb0ca75 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 31 Jul 2014 09:35:26 +0200 >Subject: [PATCH 10/21] 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 4ff82b4..04e7d9a 100644 >--- a/source4/dns_server/dns_update.c >+++ b/source4/dns_server/dns_update.c >@@ -400,7 +400,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")); >@@ -428,23 +430,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; >@@ -457,13 +465,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); >@@ -475,7 +484,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; >@@ -490,7 +499,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; > >@@ -540,7 +549,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; > } >@@ -562,7 +571,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; >@@ -578,7 +587,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, > }; >@@ -595,7 +604,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, >@@ -624,7 +633,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; >@@ -641,7 +650,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 0892920d39377058d940958bf9d5feaf502b4694 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 27 Feb 2014 09:59:51 +0100 >Subject: [PATCH 11/21] 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 c0ed8e1..46c586e 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 cf5f86b405ebebed09cb661835d23bc5551c9ce9 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 30 Jul 2014 17:57:13 +0200 >Subject: [PATCH 12/21] 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 46c586e..01700a5 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 80416846b27f426d8b7f4482acdc45f08a3cde78 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 26 Aug 2014 13:48:21 +0200 >Subject: [PATCH 13/21] 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 2f50d70caae59ec440b2113530ad64383a2cc9d1 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 26 Aug 2014 10:24:27 +1200 >Subject: [PATCH 14/21] 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 5d3763adba2103478acbd1a01509079cac852b07 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 26 Aug 2014 10:34:17 +0200 >Subject: [PATCH 15/21] 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 81375301b92467f05c02b4cdca02f1e1bbc26c3a Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 26 Aug 2014 12:04:59 +0200 >Subject: [PATCH 16/21] torture-dns: Add test for dlz_bind9 updates > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from 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..1021f2c 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, 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 aabc52657877b6f08245bd59f79f45366d14b817 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 30 Jul 2014 08:40:32 +0200 >Subject: [PATCH 17/21] 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 01700a5..5cb9428 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 fce69fd0848a57e9bdb15a777bfd6b27fc0235fa Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 30 Jul 2014 17:59:08 +0200 >Subject: [PATCH 18/21] 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 5cb9428..a433acc 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 df8810d7fc4814f6fb301cdbf27cd506e6913905 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 30 Jul 2014 18:51:39 +0200 >Subject: [PATCH 19/21] 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 a433acc..b65545c 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 1fe31cfae8c3a32868a0fd7566276022213e6e5b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 30 Jul 2014 20:12:08 +0200 >Subject: [PATCH 20/21] 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 b65545c..460976e 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 1b338845869fe817830682c952d9899140a302fc Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 31 Jul 2014 09:30:16 +0200 >Subject: [PATCH 21/21] 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 460976e..38b765a 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
Flags:
abartlet
:
review+
Actions:
View
Attachments on
bug 10749
:
10184
|
10202
|
10242
|
10243
|
10244
|
10248
|
10251
|
10252
|
10253
|
10255