+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
* 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>
#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>
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
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;
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);
{
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)
*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
* 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
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
- 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>
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>;
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>;
* 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 */
#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>
}
}
+#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'
*/
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!).
* 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 */
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);
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'.
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));
cfgmaps[i++] = config;
cfgmaps[i] = NULL;
+ if (!strcmp(viewname, "_default")) {
+ sep = "";
+ viewname = "";
+ forview = "";
+ }
+
/*
* Set the view's port number for outgoing queries.
*/
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));
} 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/"
+ "disable-empty-zone' "
+ "not set: disabling "
+ "RFC 1918 empty zones",
+ sep, viewname);
+ logit = ISC_FALSE;
+ }
+ continue;
+ }
+
+ CHECK(dns_zone_create(&zone, mctx));
+ CHECK(dns_zone_setorigin(zone, name));
+ dns_zone_setview(zone, view);
+ CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone));
+ dns_zone_setclass(zone, view->rdclass);
+ dns_zone_settype(zone, dns_zone_master);
+ CHECK(dns_zone_setdbtype(zone, empty_dbtypec,
+ empty_dbtype));
+ if (view->queryacl != NULL)
+ dns_zone_setqueryacl(zone, view->queryacl);
+ dns_zone_setdialup(zone, dns_dialuptype_no);
+ dns_zone_setnotifytype(zone, dns_notifytype_no);
+ dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS,
+ ISC_TRUE);
+ CHECK(dns_view_addzone(view, zone));
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+ "automatic empty zone%s%s: %s",
+ sep, viewname, empty);
+ dns_zone_detach(&zone);
+ }
+ }
+
result = ISC_R_SUCCESS;
cleanup:
+ if (zone != NULL)
+ dns_zone_detach(&zone);
if (dispatch4 != NULL)
dns_dispatch_detach(&dispatch4);
if (dispatch6 != NULL)
} else if (result == ISC_R_SUCCESS) {
CHECKM(setoptstring(server, &server->server_id, obj), "strdup");
} else {
- result = setoptstring(server, &server->server_id, NULL);
+ result = setstring(server, &server->server_id, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
}
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- File: $Id: Bv9ARM-book.xml,v 1.276 2005/07/19 06:12:16 marka Exp $ -->
+<!-- File: $Id: Bv9ARM-book.xml,v 1.277 2005/08/18 00:57:28 marka Exp $ -->
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<title>BIND 9 Administrator Reference Manual</title>
<optional> clients-per-query <replaceable>number</replaceable> ; </optional>
<optional> max-clients-per-query <replaceable>number</replaceable> ; </optional>
<optional> masterfile-format (<constant>text</constant>|<constant>raw</constant>) ; </optional>
+ <optional> empty-server <replaceable>name</replaceable> ; </optional>
+ <optional> empty-contact <replaceable>name</replaceable> ; </optional>
+ <optional> empty-zones-enable <replaceable>yes_or_no</replaceable> ; </optional>
+ <optional> disable-empty-zone <replaceable>zone_name</replaceable> ; </optional>
};
</programlisting>
</sect3>
+ <sect3 id="empty">
+ <title>Built-in Empty Zones</title>
+ <para>
+ Named has some built-in empty zones (SOA and NS records only).
+ These are for zones that should normally be answered locally
+ and which queries should not be sent to the Internet's root
+ servers. The offical servers which cover these namespaces
+ return NXDOMAIN responses to these queries. In particular
+ these cover the reverse namespace for addresses from RFC 1918 and
+ RFC 3330. They also include the reverse namespace for IPv6 local
+ address (locally assigned), IPv6 link local addresses, the IPv6
+ loopback address and the IPv6 unknown addresss.
+ </para>
+ <para>
+ Named will attempt to determine if a built in zone already exists
+ or is active (covered by a forward-only forwarding declaration)
+ and will not not create a empty zone in that case.
+ </para>
+ <para>
+ The current list of empty zones is:
+ <itemizedlist>
+ <listitem>10.IN-ADDR.ARPA</listitem>
+ <listitem>127.IN-ADDR.ARPA</listitem>
+ <listitem>254.169.IN-ADDR.ARPA</listitem>
+ <listitem>16.172.IN-ADDR.ARPA</listitem>
+ <listitem>17.172.IN-ADDR.ARPA</listitem>
+ <listitem>18.172.IN-ADDR.ARPA</listitem>
+ <listitem>19.172.IN-ADDR.ARPA</listitem>
+ <listitem>20.172.IN-ADDR.ARPA</listitem>
+ <listitem>21.172.IN-ADDR.ARPA</listitem>
+ <listitem>22.172.IN-ADDR.ARPA</listitem>
+ <listitem>23.172.IN-ADDR.ARPA</listitem>
+ <listitem>24.172.IN-ADDR.ARPA</listitem>
+ <listitem>25.172.IN-ADDR.ARPA</listitem>
+ <listitem>26.172.IN-ADDR.ARPA</listitem>
+ <listitem>27.172.IN-ADDR.ARPA</listitem>
+ <listitem>28.172.IN-ADDR.ARPA</listitem>
+ <listitem>29.172.IN-ADDR.ARPA</listitem>
+ <listitem>30.172.IN-ADDR.ARPA</listitem>
+ <listitem>31.172.IN-ADDR.ARPA</listitem>
+ <listitem>168.192.IN-ADDR.ARPA</listitem>
+ <listitem>2.0.192.IN-ADDR.ARPA</listitem>
+ <listitem>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</listitem>
+ <listitem>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</listitem>
+ <listitem>D.F.IP6.ARPA</listitem>
+ <listitem>8.E.F.IP6.ARPA</listitem>
+ <listitem>9.E.F.IP6.ARPA</listitem>
+ <listitem>A.E.F.IP6.ARPA</listitem>
+ <listitem>B.E.F.IP6.ARPA</listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Empty zones are settable at the view level and only apply to
+ views of class IN. Disabled empty zones are only inherited
+ from options if there are no disabled empty zones specified
+ at the view level. To override the options list of disabled
+ zones you can disable the root zone at the view level
+ (disable-empty-zone ".";).
+ </para>
+ <para>
+ If you are using the address ranges covered here you should
+ already have reverse zones covering the addresses you use.
+ In practice this appears to not be the case with many queries
+ being made to the infrustucture servers for names in these
+ spaces. So many in fact that sacrificial servers were needed
+ to be deployed to channel the query load away from the
+ infrustucture servers.
+ </para>
+ <note>
+ The real parent servers for these zones should disable all
+ empty zone under the parent zone they serve. For the real
+ root servers this is all built in empty zones. This will
+ enable them to return referrals to deeper in the tree.
+ </note>
+ <variablelist>
+ <varlistentry>
+ <term><command>empty-server</command></term>
+ <listitem>
+ <para>
+ Specify what server name will appear in the returned
+ SOA record for empty zones. If none is specified then
+ the zone's name will be used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>empty-contact</command></term>
+ <listitem>
+ <para>
+ Specify what contact name will appear in the returned
+ SOA record for empty zones. If none is specified then
+ "." will be used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>empty-zones-enable</command></term>
+ <listitem>
+ <para>
+ Enable / disable all empty zones. By default they
+ are enabled.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>disable-empty-zone</command></term>
+ <listitem>
+ <para>
+ Disable a indiviual empty zones. By default none are
+ disabled. This option can be specified multiple times.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
<sect3 id="statsfile">
<title>The Statistics File</title>
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: check.c,v 1.61 2005/07/28 05:42:20 marka Exp $ */
+/* $Id: check.c,v 1.62 2005/08/18 00:57:28 marka Exp $ */
/*! \file */
cfg_obj_t *obj = NULL;
cfg_listelt_t *element;
isc_symtab_t *symtab = NULL;
+ dns_fixedname_t fixed;
+ const char *str;
+ dns_name_t *name;
+ isc_buffer_t b;
static intervaltable intervals[] = {
{ "cleaning-interval", 60, 28 * 24 * 60 }, /* 28 days */
}
}
+ dns_fixedname_init(&fixed);
+ name = dns_fixedname_name(&fixed);
+
/*
* Check the DLV zone name.
*/
element != NULL;
element = cfg_list_next(element))
{
- dns_fixedname_t fixedname;
- dns_name_t *name;
const char *dlv;
- isc_buffer_t b;
obj = cfg_listelt_value(element);
dlv = cfg_obj_asstring(cfg_tuple_get(obj, "domain"));
- dns_fixedname_init(&fixedname);
- name = dns_fixedname_name(&fixedname);
isc_buffer_init(&b, dlv, strlen(dlv));
isc_buffer_add(&b, strlen(dlv));
tresult = dns_name_fromtext(name, &b, dns_rootname,
}
dlv = cfg_obj_asstring(cfg_tuple_get(obj,
"trust-anchor"));
- dns_fixedname_init(&fixedname);
isc_buffer_init(&b, dlv, strlen(dlv));
isc_buffer_add(&b, strlen(dlv));
tresult = dns_name_fromtext(name, &b, dns_rootname,
isc_symtab_destroy(&symtab);
}
+ /*
+ * Check empty zone configuration.
+ */
+ obj = NULL;
+ (void)cfg_map_get(options, "empty-server", &obj);
+ if (obj != NULL) {
+ str = cfg_obj_asstring(obj);
+ isc_buffer_init(&b, str, strlen(str));
+ isc_buffer_add(&b, strlen(str));
+ tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
+ dns_rootname, ISC_FALSE, NULL);
+ if (tresult != ISC_R_SUCCESS) {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "empty-server: invalid name '%s'", str);
+ result = ISC_R_FAILURE;
+ }
+ }
+
+ obj = NULL;
+ (void)cfg_map_get(options, "empty-contact", &obj);
+ if (obj != NULL) {
+ str = cfg_obj_asstring(obj);
+ isc_buffer_init(&b, str, strlen(str));
+ isc_buffer_add(&b, strlen(str));
+ tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
+ dns_rootname, ISC_FALSE, NULL);
+ if (tresult != ISC_R_SUCCESS) {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "empty-contact: invalid name '%s'", str);
+ result = ISC_R_FAILURE;
+ }
+ }
+
+ obj = NULL;
+ (void)cfg_map_get(options, "disable-empty-zone", &obj);
+ for (element = cfg_list_first(obj);
+ element != NULL;
+ element = cfg_list_next(element))
+ {
+ obj = cfg_listelt_value(element);
+ str = cfg_obj_asstring(obj);
+ isc_buffer_init(&b, str, strlen(str));
+ isc_buffer_add(&b, strlen(str));
+ tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
+ dns_rootname, ISC_FALSE, NULL);
+ if (tresult != ISC_R_SUCCESS) {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "disable-empty-zone: invalid name '%s'",
+ str);
+ result = ISC_R_FAILURE;
+ }
+ }
+
return (result);
}
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone.h,v 1.135 2005/06/20 01:03:55 marka Exp $ */
+/* $Id: zone.h,v 1.136 2005/08/18 00:57:30 marka Exp $ */
#ifndef DNS_ZONE_H
#define DNS_ZONE_H 1
#define DNS_ZONEOPT_CHECKMX 0x00004000U /*%< check-mx */
#define DNS_ZONEOPT_CHECKMXFAIL 0x00008000U /*%< fatal check-mx failures */
#define DNS_ZONEOPT_INTEGRITYCHECK 0x00010000U /*%< perform integrity checks */
+#define DNS_ZONEOPT_NOCHECKNS 0x00020000U /*%< disable IN NS address checks */
#ifndef NOMINUM_PUBLIC
/*
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sdb.c,v 1.51 2005/07/12 01:00:16 marka Exp $ */
+/* $Id: sdb.c,v 1.52 2005/08/18 00:57:29 marka Exp $ */
/*! \file */
static inline unsigned int
initial_size(unsigned int len) {
unsigned int size;
- for (size = 64; size < (64 * 1024); size *= 2)
+
+ for (size = 1024; size < (64 * 1024); size *= 2)
if (len < size)
return (size);
- return (64 * 1024);
+ return (65535);
}
isc_result_t
if (result != ISC_R_SUCCESS)
goto failure;
+ if (size >= 65535)
+ size = 65535;
p = isc_mem_get(mctx, size);
if (p == NULL) {
result = ISC_R_NOMEMORY;
if (result != ISC_R_NOSPACE)
break;
+ /*
+ * Is the RR too big?
+ */
+ if (size >= 65535)
+ break;
isc_mem_put(mctx, p, size);
p = NULL;
size *= 2;
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone.c,v 1.443 2005/07/29 00:32:53 marka Exp $ */
+/* $Id: zone.c,v 1.444 2005/08/18 00:57:29 marka Exp $ */
/*! \file */
dns_name_t *foundname;
int level;
+ if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
+ return (ISC_TRUE);
+
if (zone->type == dns_zone_master)
level = ISC_LOG_ERROR;
else
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: namedconf.c,v 1.54 2005/07/18 05:59:01 marka Exp $ */
+/* $Id: namedconf.c,v 1.55 2005/08/18 00:57:31 marka Exp $ */
/*! \file */
static const char *zonetype_enums[] = {
"master", "slave", "stub", "hint", "forward", "delegation-only", NULL };
static cfg_type_t cfg_type_zonetype = {
- "zonetype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string,
- &zonetype_enums
+ "zonetype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
+ &cfg_rep_string, &zonetype_enums
};
static const char *loglevel_enums[] = {
{ "max-acache-size", &cfg_type_sizenodefault, 0 },
{ "clients-per-query", &cfg_type_uint32, 0 },
{ "max-clients-per-query", &cfg_type_uint32, 0 },
+ { "empty-server", &cfg_type_astring, 0 },
+ { "empty-contact", &cfg_type_astring, 0 },
+ { "empty-zones-enable", &cfg_type_boolean, 0 },
+ { "disable-empty-zone", &cfg_type_astring, CFG_CLAUSEFLAG_MULTI },
{ NULL, NULL, 0 }
};