From 97dd67315784b5c7126372a1fea6f9ceb2e102d8 Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Wed, 2 Oct 2013 17:28:45 +1000 Subject: s4-dns: Ignore duplicate dns zones from multiple locations in dlz_bind9 BIND DLZ module currently loads DNS zones from DNS partitions and domain partitions using following prefixes: CN=MicrosoftDNS,DC=DomainDnsZones CN=MicrosoftDNS,DC=ForestDNSZones CN=MicrosoftDNS,CN=System Windows supports DNS zones duplicated in DNS partitions and domain partition and updates both of them simultaneously. BIND DLZ module can handle DNS zones stored either in DNS partitions or domain partition, but not both. This patch ignores duplicate zones from domain partition and allows BIND9 to work with AD with duplicate DNS zones. Signed-off-by: Amitay Isaacs Reviewed-by: Kai Blin --- source4/dns_server/dlz_bind9.c | 55 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'source4/dns_server') diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c index ac41dd02aa5..ea00cfd8b76 100644 --- a/source4/dns_server/dlz_bind9.c +++ b/source4/dns_server/dlz_bind9.c @@ -36,6 +36,7 @@ #include "gen_ndr/server_id.h" #include "messaging/messaging.h" #include "lib/cmdline/popt_common.h" +#include "lib/util/dlinklist.h" #include "dlz_minimal.h" @@ -44,6 +45,11 @@ struct b9_options { const char *debug; }; +struct b9_zone { + char *name; + struct b9_zone *prev, *next; +}; + struct dlz_bind9_data { struct b9_options options; struct ldb_context *samdb; @@ -51,6 +57,7 @@ struct dlz_bind9_data { struct loadparm_context *lp; int *transaction_token; uint32_t soa_serial; + struct b9_zone *zonelist; /* Used for dynamic update */ struct smb_krb5_context *smb_krb5_ctx; @@ -1099,6 +1106,42 @@ static bool b9_has_soa(struct dlz_bind9_data *state, struct ldb_dn *dn, const ch return false; } +static bool b9_zone_add(struct dlz_bind9_data *state, const char *name) +{ + struct b9_zone *zone; + + zone = talloc_zero(state, struct b9_zone); + if (zone == NULL) { + return false; + } + + zone->name = talloc_strdup(zone, name); + if (zone->name == NULL) { + talloc_free(zone); + return false; + } + + DLIST_ADD(state->zonelist, zone); + return true; +} + +static bool b9_zone_exists(struct dlz_bind9_data *state, const char *name) +{ + struct b9_zone *zone = state->zonelist; + bool found = false; + + while (zone != NULL) { + if (strcasecmp(name, zone->name) == 0) { + found = true; + break; + } + zone = zone->next; + } + + return found; +} + + /* configure a writeable zone */ @@ -1161,6 +1204,18 @@ _PUBLIC_ isc_result_t dlz_configure(dns_view_t *view, void *dbdata) if (!b9_has_soa(state, zone_dn, zone)) { continue; } + + if (b9_zone_exists(state, zone)) { + state->log(ISC_LOG_WARNING, "samba_dlz: Ignoring duplicate zone '%s' from '%s'", + zone, ldb_dn_get_linearized(zone_dn)); + continue; + } + + if (!b9_zone_add(state, zone)) { + talloc_free(tmp_ctx); + return ISC_R_NOMEMORY; + } + result = state->writeable_zone(view, zone); if (result != ISC_R_SUCCESS) { state->log(ISC_LOG_ERROR, "samba_dlz: Failed to configure zone '%s'", -- cgit