Commit 6b79e960 authored by Mark Andrews's avatar Mark Andrews

1913. [func] Automatic empty zone creation for D.F.IP6.ARPA and

                        friends.  Note: RFC 1918 zones are not yet covered by
                        this but are likely to be in a future release.

                        New options: empty-server, empty-contact,
                        empty-zones-enable and disable-empty-zone.
parent 5007fd0c
1913. [func] Automatic empty zone creation for D.F.IP6.ARPA and
friends. Note: RFC 1918 zones are not yet covered by
this but are likely to be in a future release.
New options: empty-server, empty-contact,
empty-zones-enable and disable-empty-zone.
1912. [func] ISC string copy API.
1911. [func] Attempt to make the amount of work performed in a
......
......@@ -15,11 +15,11 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: builtin.c,v 1.7 2005/04/29 00:22:26 marka Exp $ */
/* $Id: builtin.c,v 1.8 2005/08/18 00:57:26 marka Exp $ */
/*! \file
* \brief
* The built-in "version", "hostname", "id" and "authors" databases.
* The built-in "version", "hostname", "id", "authors" and "empty" databases.
*/
#include <config.h>
......@@ -27,12 +27,13 @@
#include <string.h>
#include <stdio.h>
#include <isc/mem.h>
#include <isc/print.h>
#include <isc/result.h>
#include <isc/util.h>
#include <dns/sdb.h>
#include <dns/result.h>
#include <dns/sdb.h>
#include <named/builtin.h>
#include <named/globals.h>
......@@ -45,6 +46,7 @@ static isc_result_t do_version_lookup(dns_sdblookup_t *lookup);
static isc_result_t do_hostname_lookup(dns_sdblookup_t *lookup);
static isc_result_t do_authors_lookup(dns_sdblookup_t *lookup);
static isc_result_t do_id_lookup(dns_sdblookup_t *lookup);
static isc_result_t do_empty_lookup(dns_sdblookup_t *lookup);
/*
* We can't use function pointers as the db_data directly
......@@ -54,12 +56,15 @@ static isc_result_t do_id_lookup(dns_sdblookup_t *lookup);
struct builtin {
isc_result_t (*do_lookup)(dns_sdblookup_t *lookup);
char *server;
char *contact;
};
static builtin_t version_builtin = { do_version_lookup };
static builtin_t hostname_builtin = { do_hostname_lookup };
static builtin_t authors_builtin = { do_authors_lookup };
static builtin_t id_builtin = { do_id_lookup };
static builtin_t version_builtin = { do_version_lookup, NULL, NULL };
static builtin_t hostname_builtin = { do_hostname_lookup, NULL, NULL };
static builtin_t authors_builtin = { do_authors_lookup, NULL, NULL };
static builtin_t id_builtin = { do_id_lookup, NULL, NULL };
static builtin_t empty_builtin = { do_empty_lookup, NULL, NULL };
static dns_sdbimplementation_t *builtin_impl;
......@@ -167,17 +172,38 @@ do_id_lookup(dns_sdblookup_t *lookup) {
return (put_txt(lookup, ns_g_server->server_id));
}
static isc_result_t
do_empty_lookup(dns_sdblookup_t *lookup) {
UNUSED(lookup);
return (ISC_R_SUCCESS);
}
static isc_result_t
builtin_authority(const char *zone, void *dbdata, dns_sdblookup_t *lookup) {
isc_result_t result;
const char *contact = "hostmaster";
const char *server = "@";
builtin_t *b = (builtin_t *) dbdata;
UNUSED(zone);
UNUSED(dbdata);
result = dns_sdb_putsoa(lookup, "@", "hostmaster", 0);
if (b == &empty_builtin) {
server = ".";
contact = ".";
} else {
if (b->server != NULL)
server = b->server;
if (b->contact != NULL)
contact = b->contact;
}
result = dns_sdb_putsoa(lookup, server, contact, 0);
if (result != ISC_R_SUCCESS)
return (ISC_R_FAILURE);
result = dns_sdb_putrr(lookup, "ns", 0, "@");
result = dns_sdb_putrr(lookup, "ns", 0, server);
if (result != ISC_R_SUCCESS)
return (ISC_R_FAILURE);
......@@ -190,8 +216,11 @@ builtin_create(const char *zone, int argc, char **argv,
{
UNUSED(zone);
UNUSED(driverdata);
if (argc != 1)
if ((argc != 1 && strcmp(argv[0], "empty") != 0) ||
argc != 3)
return (DNS_R_SYNTAX);
if (strcmp(argv[0], "version") == 0)
*dbdata = &version_builtin;
else if (strcmp(argv[0], "hostname") == 0)
......@@ -200,17 +229,62 @@ builtin_create(const char *zone, int argc, char **argv,
*dbdata = &authors_builtin;
else if (strcmp(argv[0], "id") == 0)
*dbdata = &id_builtin;
else
else if (strcmp(argv[0], "empty") == 0) {
builtin_t *empty;
char *server;
char *contact;
/*
* We don't want built-in zones to fail. Fallback to
* to the static configuration if memory allocation fails.
*/
empty = isc_mem_get(ns_g_mctx, sizeof(*empty));
server = isc_mem_strdup(ns_g_mctx, argv[1]);
contact = isc_mem_strdup(ns_g_mctx, argv[2]);
if (empty == NULL || server == NULL || contact == NULL) {
*dbdata = &empty_builtin;
if (server != NULL)
isc_mem_free(ns_g_mctx, server);
if (contact != NULL)
isc_mem_free(ns_g_mctx, contact);
if (empty != NULL)
isc_mem_put(ns_g_mctx, empty, sizeof (*empty));
} else {
memcpy(empty, &empty_builtin, sizeof (empty_builtin));
empty->server = server;
empty->contact = contact;
*dbdata = empty;
}
} else
return (ISC_R_NOTIMPLEMENTED);
return (ISC_R_SUCCESS);
}
static void
builtin_destroy(const char *zone, void *driverdata, void **dbdata) {
builtin_t *b = (builtin_t *) *dbdata;
UNUSED(zone);
UNUSED(driverdata);
/*
* Don't free the static versions.
*/
if (*dbdata == &version_builtin || *dbdata == &hostname_builtin ||
*dbdata == &authors_builtin || *dbdata == &id_builtin ||
*dbdata == &empty_builtin)
return;
isc_mem_free(ns_g_mctx, b->server);
isc_mem_free(ns_g_mctx, b->contact);
isc_mem_put(ns_g_mctx, b, sizeof (*b));
}
static dns_sdbmethods_t builtin_methods = {
builtin_lookup,
builtin_authority,
NULL, /* allnodes */
builtin_create,
NULL /* destroy */
builtin_destroy
};
isc_result_t
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: server.h,v 1.79 2005/08/15 01:21:05 marka Exp $ */
/* $Id: server.h,v 1.80 2005/08/18 00:57:27 marka Exp $ */
#ifndef NAMED_SERVER_H
#define NAMED_SERVER_H 1
......@@ -62,9 +62,6 @@ struct ns_server {
isc_boolean_t server_usehostname;
char * server_id; /*%< User-specified server id */
/*% Empty zone SOA ORIGIN and CONTACT */
char * empty_contact;
char * empty_server;
/*%
* Current ACL environment. This defines the
* current values of the localhost and localnets
......
......@@ -17,7 +17,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
<!-- $Id: named.conf.docbook,v 1.13 2005/06/27 00:15:41 marka Exp $ -->
<!-- $Id: named.conf.docbook,v 1.14 2005/08/18 00:57:26 marka Exp $ -->
<refentry>
<refentryinfo>
<date>Aug 13, 2004</date>
......@@ -261,6 +261,11 @@ options {
dnssec-lookaside <replaceable>string</replaceable> trust-anchor <replaceable>string</replaceable>;
dnssec-must-be-secure <replaceable>string</replaceable> <replaceable>boolean</replaceable>;
empty-server <replaceable>string</replaceable>;
empty-contact <replaceable>string</replaceable>;
empty-zones-enable <replaceable>boolean</replaceable>;
disable-empty-zone <replaceable>string</replaceable>;
dialup <replaceable>dialuptype</replaceable>;
ixfr-from-differences <replaceable>ixfrdiff</replaceable>;
......@@ -396,6 +401,12 @@ view <replaceable>string</replaceable> <replaceable>optional_class</replaceable>
dnssec-lookaside <replaceable>string</replaceable> trust-anchor <replaceable>string</replaceable>;
dnssec-must-be-secure <replaceable>string</replaceable> <replaceable>boolean</replaceable>;
empty-server <replaceable>string</replaceable>;
empty-contact <replaceable>string</replaceable>;
empty-zones-enable <replaceable>boolean</replaceable>;
disable-empty-zone <replaceable>string</replaceable>;
dialup <replaceable>dialuptype</replaceable>;
ixfr-from-differences <replaceable>ixfrdiff</replaceable>;
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: query.c,v 1.271 2005/08/11 04:45:38 marka Exp $ */
/* $Id: query.c,v 1.272 2005/08/18 00:57:26 marka Exp $ */
/*! \file */
......@@ -31,6 +31,7 @@
#include <dns/db.h>
#include <dns/events.h>
#include <dns/message.h>
#include <dns/ncache.h>
#include <dns/order.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
......@@ -2914,6 +2915,109 @@ answer_in_glue(ns_client_t *client, dns_rdatatype_t qtype) {
}
}
#define NS_NAME_INIT(A,B) \
{ \
DNS_NAME_MAGIC, \
A, sizeof(A), sizeof(B), \
DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, \
B, NULL, { (void *)-1, (void *)-1}, \
{NULL, NULL} \
}
static unsigned char inaddr10_offsets[] = { 0, 3, 11, 16 };
static unsigned char inaddr172_offsets[] = { 0, 3, 7, 15, 20 };
static unsigned char inaddr192_offsets[] = { 0, 4, 8, 16, 21 };
static unsigned char inaddr10[] = "\00210\007IN-ADDR\004ARPA";
static unsigned char inaddr16172[] = "\00216\003172\007IN-ADDR\004ARPA";
static unsigned char inaddr17172[] = "\00217\003172\007IN-ADDR\004ARPA";
static unsigned char inaddr18172[] = "\00218\003172\007IN-ADDR\004ARPA";
static unsigned char inaddr19172[] = "\00219\003172\007IN-ADDR\004ARPA";
static unsigned char inaddr20172[] = "\00220\003172\007IN-ADDR\004ARPA";
static unsigned char inaddr21172[] = "\00221\003172\007IN-ADDR\004ARPA";
static unsigned char inaddr22172[] = "\00222\003172\007IN-ADDR\004ARPA";
static unsigned char inaddr23172[] = "\00223\003172\007IN-ADDR\004ARPA";
static unsigned char inaddr24172[] = "\00224\003172\007IN-ADDR\004ARPA";
static unsigned char inaddr25172[] = "\00225\003172\007IN-ADDR\004ARPA";
static unsigned char inaddr26172[] = "\00226\003172\007IN-ADDR\004ARPA";
static unsigned char inaddr27172[] = "\00227\003172\007IN-ADDR\004ARPA";
static unsigned char inaddr28172[] = "\00228\003172\007IN-ADDR\004ARPA";
static unsigned char inaddr29172[] = "\00229\003172\007IN-ADDR\004ARPA";
static unsigned char inaddr30172[] = "\00230\003172\007IN-ADDR\004ARPA";
static unsigned char inaddr31172[] = "\00231\003172\007IN-ADDR\004ARPA";
static unsigned char inaddr168192[] = "\003168\003192\007IN-ADDR\004ARPA";
static dns_name_t rfc1918names[] = {
NS_NAME_INIT(inaddr10, inaddr10_offsets),
NS_NAME_INIT(inaddr16172, inaddr172_offsets),
NS_NAME_INIT(inaddr17172, inaddr172_offsets),
NS_NAME_INIT(inaddr18172, inaddr172_offsets),
NS_NAME_INIT(inaddr19172, inaddr172_offsets),
NS_NAME_INIT(inaddr20172, inaddr172_offsets),
NS_NAME_INIT(inaddr21172, inaddr172_offsets),
NS_NAME_INIT(inaddr22172, inaddr172_offsets),
NS_NAME_INIT(inaddr23172, inaddr172_offsets),
NS_NAME_INIT(inaddr24172, inaddr172_offsets),
NS_NAME_INIT(inaddr25172, inaddr172_offsets),
NS_NAME_INIT(inaddr26172, inaddr172_offsets),
NS_NAME_INIT(inaddr27172, inaddr172_offsets),
NS_NAME_INIT(inaddr28172, inaddr172_offsets),
NS_NAME_INIT(inaddr29172, inaddr172_offsets),
NS_NAME_INIT(inaddr30172, inaddr172_offsets),
NS_NAME_INIT(inaddr31172, inaddr172_offsets),
NS_NAME_INIT(inaddr168192, inaddr192_offsets)
};
static unsigned char prisoner_data[] = "\010prisoner\004iana\003org";
static unsigned char hostmaster_data[] = "\012hostmaster\014root-servers\003org";
static unsigned char prisoner_offsets[] = { 0, 9, 14, 18 };
static unsigned char hostmaster_offsets[] = { 0, 11, 24, 28 };
static dns_name_t prisoner = NS_NAME_INIT(prisoner_data, prisoner_offsets);
static dns_name_t hostmaster = NS_NAME_INIT(hostmaster_data, hostmaster_offsets);
static void
warn_rfc1918(ns_client_t *client, dns_name_t *fname, dns_rdataset_t *rdataset) {
unsigned int i;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_soa_t soa;
dns_rdataset_t found;
isc_result_t result;
for (i = 0; i < (sizeof(rfc1918names)/sizeof(*rfc1918names)); i++) {
if (dns_name_issubdomain(fname, &rfc1918names[i])) {
dns_rdataset_init(&found);
result = dns_ncache_getrdataset(rdataset,
&rfc1918names[i],
dns_rdatatype_soa,
&found);
if (result != ISC_R_SUCCESS)
return;
result = dns_rdataset_first(&found);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
dns_rdataset_current(&found, &rdata);
dns_rdata_tostruct(&rdata, &soa, NULL);
if (dns_name_equal(&soa.origin, &prisoner) &&
dns_name_equal(&soa.contact, &hostmaster)) {
char buf[DNS_NAME_FORMATSIZE];
dns_name_format(fname, buf, sizeof(buf));
ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_QUERY,
ISC_LOG_WARNING,
"RFC 1918 response from "
"Internet for %s", buf);
}
dns_rdataset_disassociate(&found);
return;
}
}
}
/*
* Do the bulk of query processing for the current query of 'client'.
* If 'event' is non-NULL, we are returning from recursion and 'qtype'
......@@ -3518,6 +3622,14 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
*/
if (result == DNS_R_NCACHENXDOMAIN)
client->message->rcode = dns_rcode_nxdomain;
/*
* Look for RFC 1918 leakage from Internet.
*/
if (result == DNS_R_NCACHENXDOMAIN &&
qtype == dns_rdatatype_ptr &&
client->message->rdclass == dns_rdataclass_in &&
dns_name_countlabels(fname) == 7)
warn_rfc1918(client, fname, rdataset);
/*
* We don't call query_addrrset() because we don't need any
* of its extra features (and things would probably break!).
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: server.c,v 1.447 2005/08/15 01:21:04 marka Exp $ */
/* $Id: server.c,v 1.448 2005/08/18 00:57:27 marka Exp $ */
/*! \file */
......@@ -164,6 +164,58 @@ struct zonelistentry {
ISC_LINK(struct zonelistentry) link;
};
/*
* These zones should not leak onto the Internet.
*/
static const struct {
const char *zone;
isc_boolean_t rfc1918;
} empty_zones[] = {
#ifdef notyet
/* RFC 1918 */
{ "10.IN-ADDR.ARPA", ISC_TRUE },
{ "16.172.IN-ADDR.ARPA", ISC_TRUE },
{ "17.172.IN-ADDR.ARPA", ISC_TRUE },
{ "18.172.IN-ADDR.ARPA", ISC_TRUE },
{ "19.172.IN-ADDR.ARPA", ISC_TRUE },
{ "20.172.IN-ADDR.ARPA", ISC_TRUE },
{ "21.172.IN-ADDR.ARPA", ISC_TRUE },
{ "22.172.IN-ADDR.ARPA", ISC_TRUE },
{ "23.172.IN-ADDR.ARPA", ISC_TRUE },
{ "24.172.IN-ADDR.ARPA", ISC_TRUE },
{ "25.172.IN-ADDR.ARPA", ISC_TRUE },
{ "26.172.IN-ADDR.ARPA", ISC_TRUE },
{ "27.172.IN-ADDR.ARPA", ISC_TRUE },
{ "28.172.IN-ADDR.ARPA", ISC_TRUE },
{ "29.172.IN-ADDR.ARPA", ISC_TRUE },
{ "30.172.IN-ADDR.ARPA", ISC_TRUE },
{ "31.172.IN-ADDR.ARPA", ISC_TRUE },
{ "168.192.IN-ADDR.ARPA", ISC_TRUE },
#endif
/* RFC 3330 */
{ "127.IN-ADDR.ARPA", ISC_FALSE }, /* LOOPBACK */
{ "254.169.IN-ADDR.ARPA", ISC_FALSE }, /* LINK LOCAL */
{ "2.0.192.IN-ADDR.ARPA", ISC_FALSE }, /* TEST NET */
{ "255.255.255.255.IN-ADDR.ARPA", ISC_FALSE }, /* BROADCAST */
/* Local IPv6 Unicast Addresses */
{ "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA", ISC_FALSE },
{ "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA", ISC_FALSE },
/* LOCALLY ASSIGNED LOCAL ADDRES S SCOPE */
{ "D.F.IP6.ARPA", ISC_FALSE },
{ "8.E.F.IP6.ARPA", ISC_FALSE }, /* LINK LOCAL */
{ "9.E.F.IP6.ARPA", ISC_FALSE }, /* LINK LOCAL */
{ "A.E.F.IP6.ARPA", ISC_FALSE }, /* LINK LOCAL */
{ "B.E.F.IP6.ARPA", ISC_FALSE }, /* LINK LOCAL */
{ NULL, ISC_FALSE }
};
static const char *empty_dbtype[] = { "_builtin", "empty", NULL, NULL };
static unsigned int empty_dbtypec =
(sizeof(empty_dbtype) / sizeof(empty_dbtype[0]));
static void
fatal(const char *msg, isc_result_t result);
......@@ -724,6 +776,36 @@ disable_algorithms(cfg_obj_t *disabled, dns_resolver_t *resolver) {
return (result);
}
static isc_boolean_t
on_disable_list(cfg_obj_t *disablelist, dns_name_t *zonename) {
cfg_listelt_t *element;
dns_fixedname_t fixed;
dns_name_t *name;
isc_result_t result;
cfg_obj_t *value;
const char *str;
isc_buffer_t b;
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
for (element = cfg_list_first(disablelist);
element != NULL;
element = cfg_list_next(element))
{
value = cfg_listelt_value(element);
str = cfg_obj_asstring(value);
isc_buffer_init(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
result = dns_name_fromtext(name, &b, dns_rootname,
ISC_TRUE, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
if (dns_name_equal(name, zonename))
return (ISC_TRUE);
}
return (ISC_FALSE);
}
/*
* Configure 'view' according to 'vconfig', taking defaults from 'config'
* where values are missing in 'vconfig'.
......@@ -765,7 +847,14 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
dns_order_t *order = NULL;
isc_uint32_t udpsize;
unsigned int check = 0;
dns_zone_t *zone = NULL;
isc_uint32_t max_clients_per_query;
const char *sep = ": view ";
const char *viewname = view->name;
const char *forview = " for view ";
isc_boolean_t rfc1918;
isc_boolean_t empty_zones_enable;
cfg_obj_t *disablelist = NULL;
REQUIRE(DNS_VIEW_VALID(view));
......@@ -791,6 +880,12 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
cfgmaps[i++] = config;
cfgmaps[i] = NULL;
if (!strcmp(viewname, "_default")) {
sep = "";
viewname = "";
forview = "";
}
/*
* Set the view's port number for outgoing queries.
*/
......@@ -1218,20 +1313,11 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
if (!view->recursion && view->recursionacl != NULL &&
(view->recursionacl->length != 1 ||
view->recursionacl->elements[0].type != dns_aclelementtype_any ||
view->recursionacl->elements[0].negative != ISC_TRUE)) {
const char *forview = " for view ";
const char *viewname = view->name;
if (!strcmp(view->name, "_bind") ||
!strcmp(view->name, "_default")) {
forview = "";
viewname = "";
}
view->recursionacl->elements[0].negative != ISC_TRUE))
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
"both \"recursion no;\" and \"allow-recursion\" "
"active%s%s", forview, viewname);
}
CHECK(configure_view_acl(vconfig, config, "sortlist",
actx, ns_g_mctx, &view->sortlist));
......@@ -1373,9 +1459,153 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
} else
dns_view_setrootdelonly(view, ISC_FALSE);
/*
* Setup automatic empty zones. If recursion is off then
* they are disabled by default.
*/
obj = NULL;
(void)ns_config_get(maps, "empty-zones-enable", &obj);
(void)ns_config_get(maps, "disable-empty-zone", &disablelist);
if (obj == NULL && disablelist == NULL &&
view->rdclass == dns_rdataclass_in) {
rfc1918 = ISC_FALSE;
empty_zones_enable = view->recursion;
} else if (view->rdclass == dns_rdataclass_in) {
rfc1918 = ISC_TRUE;
if (obj != NULL)
empty_zones_enable = cfg_obj_asboolean(obj);
else
empty_zones_enable = view->recursion;
} else {
rfc1918 = ISC_FALSE;
empty_zones_enable = ISC_FALSE;
}
if (empty_zones_enable) {
const char *empty;
int empty_zone = 0;
dns_fixedname_t fixed;
dns_name_t *name;
isc_buffer_t buffer;
char *str;
char server[DNS_NAME_FORMATSIZE + 1];
char contact[DNS_NAME_FORMATSIZE + 1];
isc_boolean_t logit;
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
obj = NULL;
result = ns_config_get(maps, "empty-server", &obj);
if (result == ISC_R_SUCCESS) {
str = cfg_obj_asstring(obj);
isc_buffer_init(&buffer, str, strlen(str));
isc_buffer_add(&buffer, strlen(str));
CHECK(dns_name_fromtext(name, &buffer, dns_rootname,
ISC_FALSE, NULL));
isc_buffer_init(&buffer, server, sizeof(server) - 1);
CHECK(dns_name_totext(name, ISC_FALSE, &buffer));
server[isc_buffer_usedlength(&buffer)] = 0;
empty_dbtype[2] = server;
} else
empty_dbtype[2] = "@";
obj = NULL;
result = ns_config_get(maps, "empty-contact", &obj);
if (result == ISC_R_SUCCESS) {
str = cfg_obj_asstring(obj);
isc_buffer_init(&buffer, str, strlen(str));
isc_buffer_add(&buffer, strlen(str));
CHECK(dns_name_fromtext(name, &buffer, dns_rootname,
ISC_FALSE, NULL));
isc_buffer_init(&buffer, contact, sizeof(contact) - 1);
CHECK(dns_name_totext(name, ISC_FALSE, &buffer));
contact[isc_buffer_usedlength(&buffer)] = 0;
empty_dbtype[3] = contact;
} else
empty_dbtype[3] = ".";
logit = ISC_TRUE;
for (empty = empty_zones[empty_zone].zone;
empty != NULL;
empty = empty_zones[++empty_zone].zone)
{
dns_forwarders_t *forwarders = NULL;
isc_buffer_init(&buffer, empty, strlen(empty));
isc_buffer_add(&buffer, strlen(empty));
/*
* Look for zone on drop list.
*/
CHECK(dns_name_fromtext(name, &buffer, dns_rootname,
ISC_FALSE, NULL));
if (disablelist != NULL &&
on_disable_list(disablelist, name))
continue;
/*
* This zone already exists.
*/
(void)dns_view_findzone(view, name, &zone);
if (zone != NULL) {
dns_zone_detach(&zone);
continue;
}
/*
* If we would forward this name don't add a
* empty zone for it.
*/
result = dns_fwdtable_find(view->fwdtable, name,
&forwarders);
if (result == ISC_R_SUCCESS &&
forwarders->fwdpolicy == dns_fwdpolicy_only)
continue;
if (!rfc1918 && empty_zones[empty_zone].rfc1918) {
if (logit) {
isc_log_write(ns_g_lctx,
NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER,
ISC_LOG_WARNING,
"Warning%s%s: "
"'empty-zones-enable/"