From 6c81b497dfe929498432b1c116d0b6849344dffc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 30 Jul 2014 17:55:57 +0200 Subject: [PATCH 01/19] 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 --- 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 72c6e258d30f4c7b560ba54b2223f07e36bbd44b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 31 Jul 2014 08:19:50 +0200 Subject: [PATCH 02/19] 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 --- 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 add49b1b23c76cf35c3103389cd1886b42134a4a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 30 Jul 2014 08:01:11 +0200 Subject: [PATCH 03/19] 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 --- 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..6b15d94 --- /dev/null +++ b/source4/dns_server/dnsserver_common.c @@ -0,0 +1,68 @@ +/* + 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 . +*/ + +#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 +#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 . +*/ + +#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 59fab6314ac24e9153201af7b0aef7ded2196923 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 30 Jul 2014 08:24:10 +0200 Subject: [PATCH 04/19] 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 --- source4/dns_server/dns_utils.c | 45 +------------------- source4/dns_server/dnsserver_common.c | 77 +++++++++++++++++++++++++++++++++++ source4/dns_server/dnsserver_common.h | 13 ++++++ 3 files changed, 91 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 6b15d94..2130e41 100644 --- a/source4/dns_server/dnsserver_common.c +++ b/source4/dns_server/dnsserver_common.c @@ -66,3 +66,80 @@ uint8_t werr_to_dns_err(WERROR 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 7254f99b643d68d513b36c4fcf294ddcb4c46d13 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 31 Jul 2014 11:32:02 +0200 Subject: [PATCH 05/19] 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 --- 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 3556a692653e286ae1615dda58271eecc392f5b4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 30 Jul 2014 18:27:56 +0200 Subject: [PATCH 06/19] s4:dns_server: split out dns_common_replace() Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 Signed-off-by: Stefan Metzmacher --- 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 2130e41..3c69ae3e 100644 --- a/source4/dns_server/dnsserver_common.c +++ b/source4/dns_server/dnsserver_common.c @@ -143,3 +143,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 871b875c80b21501573d05b3916517ea04540f62 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 31 Jul 2014 09:32:00 +0200 Subject: [PATCH 07/19] 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 --- 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 29610f93fd296dec63067a6e4fae1f235a64bcc4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 31 Jul 2014 08:54:17 +0200 Subject: [PATCH 08/19] 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 --- 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 3c69ae3e..0881c84 100644 --- a/source4/dns_server/dnsserver_common.c +++ b/source4/dns_server/dnsserver_common.c @@ -103,10 +103,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; @@ -117,9 +119,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; } @@ -129,9 +138,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 a86e72dc39315ee70a7e9d34a7b07c1d91960a0b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 31 Jul 2014 10:44:41 +0200 Subject: [PATCH 09/19] s4:dns_server: add DNS_TYPE_TOMBSTONE support to dns_common_replace() Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 Signed-off-by: Stefan Metzmacher --- source4/dns_server/dnsserver_common.c | 74 +++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/source4/dns_server/dnsserver_common.c b/source4/dns_server/dnsserver_common.c index 0881c84..613608e 100644 --- a/source4/dns_server/dnsserver_common.c +++ b/source4/dns_server/dnsserver_common.c @@ -189,6 +189,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 -1; + } + + /* + * 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, @@ -201,6 +217,8 @@ WERROR dns_common_replace(struct ldb_context *samdb, uint16_t i; int ret; struct ldb_message *msg = NULL; + bool need_tombstoned = false; + bool is_tombstoned = false; msg = ldb_msg_new(mem_ctx); W_ERROR_HAVE_NO_MEMORY(msg); @@ -212,17 +230,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) { + need_tombstoned = true; + } continue; } @@ -255,7 +286,42 @@ 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; + + 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++; + + need_tombstoned = true; + is_tombstoned = true; + } + + if (need_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", + is_tombstoned ? "TRUE" : "FALSE"); + if (ret != LDB_SUCCESS) { + return DNS_ERR(SERVER_FAILURE); + } } ret = ldb_modify(samdb, msg); -- 1.9.1 From 8bda0ffe389595edd8618df6d922e589abf2e287 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 31 Jul 2014 09:35:26 +0200 Subject: [PATCH 10/19] s4:dns_server: handle tombstones in handle_one_update() Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 Signed-off-by: Stefan Metzmacher --- 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 5a6840f3e8fab65a604d00447c1b0f6c927f3059 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 27 Feb 2014 09:59:51 +0100 Subject: [PATCH 11/19] TODO/TEST: s4:dlz_bind9: avoid some compiler warnings Signed-off-by: Stefan Metzmacher --- 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 3ffb06b..092f255 100644 --- a/source4/dns_server/dlz_bind9.c +++ b/source4/dns_server/dlz_bind9.c @@ -466,7 +466,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; @@ -477,7 +477,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) { @@ -571,7 +571,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 b7d6957..0ee2f19 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 410646e5331f5cd52891b090d21e6840e4289d91 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 30 Jul 2014 17:57:13 +0200 Subject: [PATCH 12/19] TODO/TEST: 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 --- 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 092f255..83b6070 100644 --- a/source4/dns_server/dlz_bind9.c +++ b/source4/dns_server/dlz_bind9.c @@ -987,6 +987,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 89e3bc0c1879c85838503f67252ebb93f9ab3d26 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 30 Jul 2014 08:40:32 +0200 Subject: [PATCH 13/19] TODO/TEST: s4:dlz_bind9: let dlz_bind9 use dns_common_lookup() for name lookup Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 Signed-off-by: Stefan Metzmacher --- 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 83b6070..402de15 100644 --- a/source4/dns_server/dlz_bind9.c +++ b/source4/dns_server/dlz_bind9.c @@ -38,7 +38,7 @@ #include "lib/cmdline/popt_common.h" #include "lib/util/dlinklist.h" #include "dlz_minimal.h" - +#include "dns_server/dnsserver_common.h" struct b9_options { const char *url; @@ -808,11 +808,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)); @@ -826,38 +825,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; inum_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; @@ -1066,39 +1048,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; inum_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 1953b48d5e2a724371effa47737441e2f91d5aef Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 30 Jul 2014 17:59:08 +0200 Subject: [PATCH 14/19] TODO/TEST: s4:dlz_bind9: let dlz_bind9 use dns_common_extract() Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 Signed-off-by: Stefan Metzmacher --- 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 402de15..0431307 100644 --- a/source4/dns_server/dlz_bind9.c +++ b/source4/dns_server/dlz_bind9.c @@ -918,6 +918,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) { @@ -951,20 +954,18 @@ _PUBLIC_ isc_result_t dlz_allnodes(const char *zone, void *dbdata, return ISC_R_NOMEMORY; } - for (j=0; jnum_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[i]); if (result != ISC_R_SUCCESS) { continue; } @@ -1521,8 +1522,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"); @@ -1582,22 +1586,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; inum_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; } } @@ -1656,7 +1657,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"); @@ -1698,19 +1701,16 @@ _PUBLIC_ isc_result_t dlz_subrdataset(const char *name, const char *rdatastr, vo return ISC_R_FAILURE; } - for (i=0; inum_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; } } @@ -1762,11 +1762,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"); @@ -1802,27 +1806,27 @@ _PUBLIC_ isc_result_t dlz_delrdataset(const char *name, const char *type, void * return ISC_R_NOTFOUND; } - for (i=0; inum_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 5648b384318b7db3275d64abc447121379d59841 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 30 Jul 2014 18:51:39 +0200 Subject: [PATCH 15/19] TODO/TEST: s4:dlz_bind9: let dlz_bind9 use dns_common_replace() Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 Signed-off-by: Stefan Metzmacher --- source4/dns_server/dlz_bind9.c | 129 ++++++++++++++++------------------------- 1 file changed, 49 insertions(+), 80 deletions(-) diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c index 0431307..a4f2228 100644 --- a/source4/dns_server/dlz_bind9.c +++ b/source4/dns_server/dlz_bind9.c @@ -1355,32 +1355,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; } @@ -1524,7 +1507,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; @@ -1543,7 +1525,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)) { @@ -1602,25 +1583,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); @@ -1628,12 +1610,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; } @@ -1711,35 +1695,27 @@ _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) { - 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; } @@ -1764,7 +1740,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; @@ -1816,17 +1791,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) { @@ -1839,17 +1810,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 a2846d5cba8a2b96290c87a5212da499c3ecc9c7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 30 Jul 2014 20:12:08 +0200 Subject: [PATCH 16/19] TODO/TEST: 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 --- 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 a4f2228..a0c42d1 100644 --- a/source4/dns_server/dlz_bind9.c +++ b/source4/dns_server/dlz_bind9.c @@ -1637,12 +1637,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) { @@ -1669,28 +1666,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++) { @@ -1736,10 +1716,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; @@ -1767,26 +1743,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 d517056d2596c1433ef8462b7d745e5b15e3b881 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 31 Jul 2014 09:30:16 +0200 Subject: [PATCH 17/19] TODO/TEST: 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 --- source4/dns_server/dlz_bind9.c | 66 +++++++----------------------------------- 1 file changed, 11 insertions(+), 55 deletions(-) diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c index a0c42d1..ac184b5 100644 --- a/source4/dns_server/dlz_bind9.c +++ b/source4/dns_server/dlz_bind9.c @@ -1347,29 +1347,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 */ @@ -1501,12 +1478,11 @@ _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 tomstoned = false; + bool needs_add = false; struct dnsp_DnssrvRpcRecord *recs = NULL; uint16_t num_recs = 0; + uint16_t i; NTTIME t; WERROR werr; @@ -1541,33 +1517,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, &tomstoned); + 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)); @@ -1611,12 +1566,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 From 85eac3f2f6a42068cd50f6e2d1caeb607bd3caa8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 2 Aug 2014 16:23:37 +0200 Subject: [PATCH 18/19] TODO dns_cleanup Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 --- source4/dns_server/dns_cleanup.c | 251 +++++++++++++++++++++++++++++++++++++++ source4/dns_server/wscript_build | 10 ++ 2 files changed, 261 insertions(+) create mode 100644 source4/dns_server/dns_cleanup.c diff --git a/source4/dns_server/dns_cleanup.c b/source4/dns_server/dns_cleanup.c new file mode 100644 index 0000000..93e3420 --- /dev/null +++ b/source4/dns_server/dns_cleanup.c @@ -0,0 +1,251 @@ +/* + Unix SMB/CIFS implementation. + + DNS server cleanup + + 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 . +*/ + +#include "includes.h" +#include "smbd/service_task.h" +#include "smbd/service.h" +#include "lib/events/events.h" +#include "libcli/util/ntstatus.h" +#include "param/param.h" +#include "librpc/gen_ndr/dnsp.h" +#include +#include "dsdb/samdb/samdb.h" +#include "dsdb/common/util.h" +#include "auth/session.h" +#include "lib/util/dlinklist.h" +#include "dns_server/dnsserver_common.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_DNS + +struct dns_cleanup { + struct task_server *task; + struct ldb_context *samdb; + + struct timeval next_event; + struct tevent_timer *te; +}; + +static void dns_cleanup_run_partition(struct dns_cleanup *dns, + struct ldb_dn *base_dn, + NTTIME expire_time) +{ + TALLOC_CTX *frame = talloc_stackframe(); + TALLOC_CTX *last = NULL; + int ret; + struct ldb_result *res = NULL; + int i; + static const char * const attrs[] = { + "dnsRecord", + NULL, + }; + + ret = ldb_search(dns->samdb, frame, &res, base_dn, + LDB_SCOPE_SUBTREE, attrs, + "(&(objectClass=dnsNode)" + "(|(dNSTombstoned=TRUE)(!(dnsRecord=*)))" + ")"); + if (ret != LDB_SUCCESS) { + TALLOC_FREE(frame); + return; + } + + for (i=0; icount; i++) { + struct ldb_message *msg; + struct ldb_message_element *el; + WERROR werr; + struct dnsp_DnssrvRpcRecord *recs = NULL; + uint16_t num_recs = 0; + bool tombstoned = false; + NTTIME tbs_time = 0; + + TALLOC_FREE(last); + msg = res->msgs[i]; + res->msgs[i] = NULL; + last = msg; + + el = ldb_msg_find_element(msg, "dnsRecord"); + if (el != NULL) { + werr = dns_common_extract(el, msg->elements, &recs, &num_recs); + if (!W_ERROR_IS_OK(werr)) { + continue; + } + + if (num_recs >= 1 && recs[0].wType == DNS_TYPE_TOMBSTONE) { + tbs_time = recs[0].data.timestamp; + } + } + + if (tbs_time > expire_time) { + continue; + } + + msg->num_elements = 0; + TALLOC_FREE(msg->elements); + + /* + * It's very likely that we will delete this object, + * so check again under a transaction + */ + ret = ldb_transaction_start(dns->samdb); + if (ret != LDB_SUCCESS) { + continue; + } + + werr = dns_common_lookup(dns->samdb, msg, msg->dn, + &recs, &num_recs, &tombstoned); + if (!W_ERROR_IS_OK(werr)) { + ldb_transaction_cancel(dns->samdb); + continue; + } + + if (!tombstoned) { + ldb_transaction_cancel(dns->samdb); + continue; + } + + ret = ldb_delete(dns->samdb, msg->dn); + if (ret != LDB_SUCCESS) { + ldb_transaction_cancel(dns->samdb); + continue; + } + + ret = ldb_transaction_commit(dns->samdb); + if (ret != LDB_SUCCESS) { + continue; + } + } + + TALLOC_FREE(frame); +} + +static void dns_cleanup_run(struct dns_cleanup *dns) +{ + struct ldb_dn *default_dn = ldb_get_default_basedn(dns->samdb); + struct ldb_dn *root_dn = ldb_get_root_basedn(dns->samdb); + struct ldb_dn *base_dns[3]; + TALLOC_CTX *frame = talloc_stackframe(); + size_t i; + NTTIME expire_time; + time_t t; + + base_dns[0] = ldb_dn_copy(frame, default_dn); + ldb_dn_add_child_fmt(base_dns[0], "CN=MicrosoftDNS,CN=System"); + base_dns[1] = ldb_dn_copy(frame, default_dn); + ldb_dn_add_child_fmt(base_dns[1], "CN=MicrosoftDNS,DC=DomainDnsZones"); + base_dns[2] = ldb_dn_copy(frame, root_dn); + ldb_dn_add_child_fmt(base_dns[2], "CN=MicrosoftDNS,DC=ForestDnsZones"); + + t = time(NULL); + + t -= (60*60*24*14); + unix_to_nt_time(&expire_time, t); + + for (i=0; i < 3; i++) { + dns_cleanup_run_partition(dns, base_dns[i], expire_time); + } + + TALLOC_FREE(frame); +} + +static void dns_cleanup_timer(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval current_time, + void *private_data) +{ + struct dns_cleanup *dns = + talloc_get_type_abort(private_data, + struct dns_cleanup); + + dns->next_event = timeval_current_ofs(600, 0); + dns->te = tevent_add_timer(dns->task->event_ctx, dns, + dns->next_event, + dns_cleanup_timer, + dns); + if (dns->te == NULL) { + task_server_terminate(dns->task, + "dns_cleanup: tevent_add_time failed", true); + return; + } + + dns_cleanup_run(dns); +} + +static void dns_cleanup_task_init(struct task_server *task) +{ + struct dns_cleanup *dns; + bool is_rodc = false; + + switch (lpcfg_server_role(task->lp_ctx)) { + case ROLE_STANDALONE: + task_server_terminate(task, "dns_cleanup: no DNS required in standalone configuration", false); + return; + case ROLE_DOMAIN_MEMBER: + task_server_terminate(task, "dns_cleanup: no DNS required in member server configuration", false); + return; + case ROLE_ACTIVE_DIRECTORY_DC: + /* Yes, we want a DNS */ + break; + } + + task_server_set_title(task, "task[dns_cleanup]"); + + dns = talloc_zero(task, struct dns_cleanup); + if (dns == NULL) { + task_server_terminate(task, "dns_cleanup: out of memory", true); + return; + } + + dns->task = task; + dns->samdb = samdb_connect(dns, dns->task->event_ctx, dns->task->lp_ctx, + system_session(dns->task->lp_ctx), 0); + if (dns->samdb == NULL) { + task_server_terminate(task, "dns_cleanup: samdb_connect failed", true); + return; + } + + if (samdb_rodc(dns->samdb, &is_rodc) != LDB_SUCCESS) { + task_server_terminate(task, "dns_cleanup: samdb_rodc failed", true); + return; + } + + if (is_rodc) { + task_server_terminate(task, "dns_cleanup: not required on a RODC", false); + return; + } + + dns->next_event = timeval_current_ofs(600, 0); + dns->te = tevent_add_timer(dns->task->event_ctx, dns, + dns->next_event, + dns_cleanup_timer, + dns); + if (dns->te == NULL) { + task_server_terminate(dns->task, + "dns_cleanup: tevent_add_time failed", true); + return; + } +} + +NTSTATUS server_service_dns_cleanup_init(void); +NTSTATUS server_service_dns_cleanup_init(void) +{ + return register_server_service("dns_cleanup", dns_cleanup_task_init); +} diff --git a/source4/dns_server/wscript_build b/source4/dns_server/wscript_build index a92ab67..c4974f7 100644 --- a/source4/dns_server/wscript_build +++ b/source4/dns_server/wscript_build @@ -16,6 +16,16 @@ bld.SAMBA_MODULE('service_dns', enabled=bld.AD_DC_BUILD_IS_ENABLED() ) +bld.SAMBA_MODULE('service_dns_cleanup', + source='dns_cleanup.c', + subsystem='service', + init_function='server_service_dns_cleanup_init', + deps='samba-hostconfig ldbsamba clidns dnsserver_common', + local_include=False, + internal_module=False, + enabled=bld.AD_DC_BUILD_IS_ENABLED() + ) + # a bind9 dlz module giving access to the Samba DNS SAM bld.SAMBA_LIBRARY('dlz_bind9', source='dlz_bind9.c', -- 1.9.1 From 867772e2b2f869c45cb41f412bc34e27ae42e1dd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 2 Aug 2014 22:32:04 +0200 Subject: [PATCH 19/19] TODO start dns_cleanup Bug: https://bugzilla.samba.org/show_bug.cgi?id=10749 --- docs-xml/smbdotconf/base/serverservices.xml | 2 +- lib/param/loadparm.c | 2 +- source3/param/loadparm.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs-xml/smbdotconf/base/serverservices.xml b/docs-xml/smbdotconf/base/serverservices.xml index e02e29d..4f592be 100644 --- a/docs-xml/smbdotconf/base/serverservices.xml +++ b/docs-xml/smbdotconf/base/serverservices.xml @@ -13,6 +13,6 @@ -. -s3fs, rpc, nbt, wrepl, ldap, cldap, kdc, drepl, winbindd, ntp_signd, kcc, dnsupdate, dns +s3fs, rpc, nbt, wrepl, ldap, cldap, kdc, drepl, winbindd, ntp_signd, kcc, dnsupdate, dns, dns_cleanup -s3fs, +smb diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 4154260..ad453b5 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2431,7 +2431,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "max connections", "0"); lpcfg_do_global_parameter(lp_ctx, "dcerpc endpoint servers", "epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver"); - lpcfg_do_global_parameter(lp_ctx, "server services", "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns"); + lpcfg_do_global_parameter(lp_ctx, "server services", "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns dns_cleanup"); lpcfg_do_global_parameter(lp_ctx, "kccsrv:samba_kcc", "true"); /* the winbind method for domain controllers is for both RODC auth forwarding and for trusted domains */ diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index c428c23..67a896e 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -854,7 +854,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) string_set(Globals.ctx, &Globals.ncalrpc_dir, get_dyn_NCALRPCDIR()); - Globals.server_services = (const char **)str_list_make_v3(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns", NULL); + Globals.server_services = (const char **)str_list_make_v3(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns dns_cleanup", NULL); Globals.dcerpc_endpoint_servers = (const char **)str_list_make_v3(NULL, "epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL); -- 1.9.1