summaryrefslogtreecommitdiff
path: root/bin/named/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'bin/named/server.c')
-rw-r--r--bin/named/server.c143
1 files changed, 86 insertions, 57 deletions
diff --git a/bin/named/server.c b/bin/named/server.c
index f29321e510601..a01e5e79cfe3a 100644
--- a/bin/named/server.c
+++ b/bin/named/server.c
@@ -1,8 +1,8 @@
/*
- * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
@@ -15,11 +15,12 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: server.c,v 1.339.2.15.2.70 2006/05/24 04:30:24 marka Exp $ */
+/* $Id: server.c,v 1.339.2.15.2.78 2008/01/17 23:45:27 tbox Exp $ */
#include <config.h>
#include <stdlib.h>
+#include <unistd.h>
#include <isc/app.h>
#include <isc/base64.h>
@@ -290,6 +291,13 @@ configure_view_dnsseckey(const cfg_obj_t *vconfig, const cfg_obj_t *key,
keystruct.datalen = r.length;
keystruct.data = r.base;
+ if ((keystruct.algorithm == DST_ALG_RSASHA1 ||
+ keystruct.algorithm == DST_ALG_RSAMD5) &&
+ r.length > 1 && r.base[0] == 1 && r.base[1] == 3)
+ cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING,
+ "trusted key '%s' has a weak exponent",
+ keynamestr);
+
CHECK(dns_rdata_fromstruct(NULL,
keystruct.common.rdclass,
keystruct.common.rdtype,
@@ -375,7 +383,7 @@ configure_view_dnsseckeys(const cfg_obj_t *vconfig, const cfg_obj_t *config,
*target = keytable; /* Transfer ownership. */
keytable = NULL;
result = ISC_R_SUCCESS;
-
+
cleanup:
return (result);
}
@@ -391,7 +399,7 @@ mustbesecure(const cfg_obj_t *mbs, dns_resolver_t *resolver)
isc_boolean_t value;
isc_result_t result;
isc_buffer_t b;
-
+
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
for (element = cfg_list_first(mbs);
@@ -409,7 +417,7 @@ mustbesecure(const cfg_obj_t *mbs, dns_resolver_t *resolver)
}
result = ISC_R_SUCCESS;
-
+
cleanup:
return (result);
}
@@ -538,7 +546,7 @@ configure_order(dns_order_t *order, const cfg_obj_t *ent) {
return (result);
obj = cfg_tuple_get(ent, "name");
- if (cfg_obj_isstring(obj))
+ if (cfg_obj_isstring(obj))
str = cfg_obj_asstring(obj);
else
str = "*";
@@ -931,7 +939,7 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
if (lame_ttl > 1800)
lame_ttl = 1800;
dns_resolver_setlamettl(view->resolver, lame_ttl);
-
+
/*
* Set the resolver's EDNS UDP size.
*/
@@ -944,7 +952,7 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
if (udpsize > 4096)
udpsize = 4096;
dns_resolver_setudpsize(view->resolver, (isc_uint16_t)udpsize);
-
+
/*
* Set supported DNSSEC algorithms.
*/
@@ -968,7 +976,7 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
(void)ns_config_get(maps, "forward", &forwardtype);
(void)ns_config_get(maps, "forwarders", &forwarders);
if (forwarders != NULL)
- CHECK(configure_forward(config, view, dns_rootname,
+ CHECK(configure_forward(config, view, dns_rootname,
forwarders, forwardtype));
/*
@@ -988,7 +996,7 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
/*
* If we still have no hints, this is a non-IN view with no
* "hints zone" configured. Issue a warning, except if this
- * is a root server. Root servers never need to consult
+ * is a root server. Root servers never need to consult
* their hints, so it's no point requiring users to configure
* them.
*/
@@ -1111,7 +1119,7 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
view->transfer_format = dns_one_answer;
else
INSIST(0);
-
+
/*
* Set sources where additional data and CNAME/DNAME
* targets for authoritative answers may be found.
@@ -1179,7 +1187,7 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
result = ns_config_get(maps, "provide-ixfr", &obj);
INSIST(result == ISC_R_SUCCESS);
view->provideixfr = cfg_obj_asboolean(obj);
-
+
obj = NULL;
result = ns_config_get(maps, "dnssec-enable", &obj);
INSIST(result == ISC_R_SUCCESS);
@@ -1608,7 +1616,7 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
"name"));
else
vname = "<default view>";
-
+
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
"zone '%s': wrong class for view '%s'",
@@ -1968,7 +1976,7 @@ adjust_interfaces(ns_server_t *server, isc_mem_t *mctx) {
}
ns_interfacemgr_adjust(server->interfacemgr, list, ISC_TRUE);
-
+
clean:
ns_listenlist_detach(&list);
return;
@@ -2042,7 +2050,7 @@ setstring(ns_server_t *server, char **field, const char *value) {
*field = copy;
return (ISC_R_SUCCESS);
-}
+}
/*
* Replace the current value of '*field', a dynamically allocated
@@ -2084,7 +2092,7 @@ set_limit(const cfg_obj_t **maps, const char *configname,
result = isc_resource_setlimit(resourceid, value);
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
result == ISC_R_SUCCESS ?
- ISC_LOG_DEBUG(3) : ISC_LOG_WARNING,
+ ISC_LOG_DEBUG(3) : ISC_LOG_WARNING,
"set maximum %s to %" ISC_PRINT_QUADFORMAT "d: %s",
description, value, isc_result_totext(result));
}
@@ -2113,7 +2121,7 @@ portlist_fromconf(dns_portlist_t *portlist, unsigned int family,
element = cfg_list_next(element)) {
const cfg_obj_t *obj = cfg_listelt_value(element);
in_port_t port = (in_port_t)cfg_obj_asuint32(obj);
-
+
result = dns_portlist_add(portlist, family, port);
if (result != ISC_R_SUCCESS)
break;
@@ -2151,7 +2159,7 @@ load_configuration(const char *filename, ns_server_t *server,
/* Ensure exclusive access to configuration data. */
result = isc_task_beginexclusive(server->task);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
/*
* Parse the global default pseudo-config file.
@@ -2204,6 +2212,15 @@ load_configuration(const char *filename, ns_server_t *server,
CHECK(result);
/*
+ * Check that the working directory is writable.
+ */
+ if (access(".", W_OK) != 0) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "the working directory is not writable");
+ }
+
+ /*
* Check the validity of the configuration.
*/
CHECK(bind9_check_namedconf(config, ns_g_lctx, ns_g_mctx));
@@ -2664,7 +2681,7 @@ load_configuration(const char *filename, ns_server_t *server,
ns_os_writepidfile(lwresd_g_defaultpidfile, first_time);
else
ns_os_writepidfile(ns_g_defaultpidfile, first_time);
-
+
obj = NULL;
if (options != NULL &&
cfg_map_get(options, "memstatistics-file", &obj) == ISC_R_SUCCESS)
@@ -2798,7 +2815,7 @@ load_zones(ns_server_t *server, isc_boolean_t stop) {
*/
CHECK(dns_zonemgr_forcemaint(server->zonemgr));
cleanup:
- isc_task_endexclusive(server->task);
+ isc_task_endexclusive(server->task);
return (result);
}
@@ -2826,7 +2843,7 @@ load_new_zones(ns_server_t *server, isc_boolean_t stop) {
*/
dns_zonemgr_resumexfrs(server->zonemgr);
cleanup:
- isc_task_endexclusive(server->task);
+ isc_task_endexclusive(server->task);
return (result);
}
@@ -2880,7 +2897,7 @@ run_server(isc_task_t *task, isc_event_t *event) {
ISC_LOG_NOTICE, "running");
}
-void
+void
ns_server_flushonshutdown(ns_server_t *server, isc_boolean_t flush) {
REQUIRE(NS_SERVER_VALID(server));
@@ -3012,7 +3029,7 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
server->interface_timer = NULL;
server->heartbeat_timer = NULL;
-
+
server->interface_interval = 0;
server->heartbeat_interval = 0;
@@ -3035,7 +3052,7 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
server->hostname_set = ISC_FALSE;
server->hostname = NULL;
- server->version_set = ISC_FALSE;
+ server->version_set = ISC_FALSE;
server->version = NULL;
server->server_usehostname = ISC_FALSE;
server->server_id = NULL;
@@ -3191,7 +3208,7 @@ ns_add_reserved_dispatch(ns_server_t *server, const isc_sockaddr_t *addr) {
result = dns_dispatch_getudp(ns_g_dispatchmgr, ns_g_socketmgr,
ns_g_taskmgr, &dispatch->addr, 4096,
1000, 32768, 16411, 16433,
- attrs, attrmask, &dispatch->dispatch);
+ attrs, attrmask, &dispatch->dispatch);
if (result != ISC_R_SUCCESS)
goto cleanup;
@@ -3294,7 +3311,7 @@ next_token(char **stringp, const char *delim) {
break;
} while (*res == '\0');
return (res);
-}
+}
/*
* Find the zone specified in the control channel command 'args',
@@ -3352,14 +3369,14 @@ zone_from_args(ns_server_t *server, char *args, dns_zone_t **zonep) {
} else {
rdclass = dns_rdataclass_in;
}
-
+
if (viewtxt == NULL)
viewtxt = "_default";
result = dns_viewlist_find(&server->viewlist, viewtxt,
rdclass, &view);
if (result != ISC_R_SUCCESS)
goto fail1;
-
+
result = dns_zt_find(view->zonetable, dns_fixedname_name(&name),
0, NULL, zonep);
/* Partial match? */
@@ -3378,7 +3395,7 @@ ns_server_retransfercommand(ns_server_t *server, char *args) {
isc_result_t result;
dns_zone_t *zone = NULL;
dns_zonetype_t type;
-
+
result = zone_from_args(server, args, &zone);
if (result != ISC_R_SUCCESS)
return (result);
@@ -3391,7 +3408,7 @@ ns_server_retransfercommand(ns_server_t *server, char *args) {
result = ISC_R_NOTFOUND;
dns_zone_detach(&zone);
return (result);
-}
+}
/*
* Act on a "reload" command from the command channel.
@@ -3402,7 +3419,7 @@ ns_server_reloadcommand(ns_server_t *server, char *args, isc_buffer_t *text) {
dns_zone_t *zone = NULL;
dns_zonetype_t type;
const char *msg = NULL;
-
+
result = zone_from_args(server, args, &zone);
if (result != ISC_R_SUCCESS)
return (result);
@@ -3414,11 +3431,12 @@ ns_server_reloadcommand(ns_server_t *server, char *args, isc_buffer_t *text) {
type = dns_zone_gettype(zone);
if (type == dns_zone_slave || type == dns_zone_stub) {
dns_zone_refresh(zone);
+ dns_zone_detach(&zone);
msg = "zone refresh queued";
} else {
result = dns_zone_load(zone);
dns_zone_detach(&zone);
- switch (result) {
+ switch (result) {
case ISC_R_SUCCESS:
msg = "zone reload successful";
break;
@@ -3440,7 +3458,7 @@ ns_server_reloadcommand(ns_server_t *server, char *args, isc_buffer_t *text) {
isc_buffer_putmem(text, (const unsigned char *)msg,
strlen(msg) + 1);
return (result);
-}
+}
/*
* Act on a "reconfig" command from the command channel.
@@ -3478,17 +3496,17 @@ ns_server_refreshcommand(ns_server_t *server, char *args, isc_buffer_t *text) {
isc_buffer_putmem(text, msg1, sizeof(msg1));
return (ISC_R_SUCCESS);
}
-
+
dns_zone_detach(&zone);
if (sizeof(msg2) <= isc_buffer_availablelength(text))
isc_buffer_putmem(text, msg2, sizeof(msg2));
return (ISC_R_FAILURE);
-}
+}
isc_result_t
ns_server_togglequerylog(ns_server_t *server) {
server->log_queries = server->log_queries ? ISC_FALSE : ISC_TRUE;
-
+
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
"query logging is now %s",
@@ -3592,15 +3610,15 @@ ns_server_dumpstats(ns_server_t *server) {
CHECKMF(isc_stdio_open(server->statsfile, "a", &fp),
"could not open statistics dump file", server->statsfile);
-
+
ncounters = DNS_STATS_NCOUNTERS;
fprintf(fp, "+++ Statistics Dump +++ (%lu)\n", (unsigned long)now);
-
+
for (i = 0; i < ncounters; i++)
fprintf(fp, "%s %" ISC_PRINT_QUADFORMAT "u\n",
dns_statscounter_names[i],
server->querystats[i]);
-
+
zone = NULL;
for (result = dns_zone_first(server->zonemgr, &zone);
result == ISC_R_SUCCESS;
@@ -3611,7 +3629,7 @@ ns_server_dumpstats(ns_server_t *server) {
char zonename[DNS_NAME_FORMATSIZE];
dns_view_t *view;
char *viewname;
-
+
dns_name_format(dns_zone_getorigin(zone),
zonename, sizeof(zonename));
view = dns_zone_getview(zone);
@@ -3631,7 +3649,7 @@ ns_server_dumpstats(ns_server_t *server) {
if (result == ISC_R_NOMORE)
result = ISC_R_SUCCESS;
CHECK(result);
-
+
fprintf(fp, "--- Statistics Dump --- (%lu)\n", (unsigned long)now);
cleanup:
@@ -3659,7 +3677,7 @@ static isc_result_t
add_view_tolist(struct dumpcontext *dctx, dns_view_t *view) {
struct viewlistentry *vle;
isc_result_t result = ISC_R_SUCCESS;
-
+
/*
* Prevent duplicate views.
*/
@@ -3722,7 +3740,7 @@ dumpdone(void *arg, isc_result_t result) {
struct dumpcontext *dctx = arg;
char buf[1024+32];
const dns_master_style_t *style;
-
+
if (result != ISC_R_SUCCESS)
goto cleanup;
if (dctx->mdctx != NULL)
@@ -3879,7 +3897,7 @@ ns_server_dumpdb(ns_server_t *server, char *args) {
dctx->dumpzones = ISC_TRUE;
dctx->dumpcache = ISC_FALSE;
ptr = next_token(&args, " \t");
- }
+ }
nextview:
for (view = ISC_LIST_HEAD(server->viewlist);
@@ -3954,7 +3972,8 @@ isc_result_t
ns_server_flushcache(ns_server_t *server, char *args) {
char *ptr, *viewname;
dns_view_t *view;
- isc_boolean_t flushed = ISC_FALSE;
+ isc_boolean_t flushed;
+ isc_boolean_t found;
isc_result_t result;
/* Skip the command name. */
@@ -3967,23 +3986,28 @@ ns_server_flushcache(ns_server_t *server, char *args) {
result = isc_task_beginexclusive(server->task);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ flushed = ISC_TRUE;
+ found = ISC_FALSE;
for (view = ISC_LIST_HEAD(server->viewlist);
view != NULL;
view = ISC_LIST_NEXT(view, link))
{
if (viewname != NULL && strcasecmp(viewname, view->name) != 0)
continue;
+ found = ISC_TRUE;
result = dns_view_flushcache(view);
if (result != ISC_R_SUCCESS)
- goto out;
- flushed = ISC_TRUE;
+ flushed = ISC_FALSE;
}
- if (flushed)
+ if (flushed && found) {
result = ISC_R_SUCCESS;
- else
- result = ISC_R_FAILURE;
- out:
- isc_task_endexclusive(server->task);
+ } else {
+ if (!found)
+ result = ISC_R_NOTFOUND;
+ else
+ result = ISC_R_FAILURE;
+ }
+ isc_task_endexclusive(server->task);
return (result);
}
@@ -3991,7 +4015,8 @@ isc_result_t
ns_server_flushname(ns_server_t *server, char *args) {
char *ptr, *target, *viewname;
dns_view_t *view;
- isc_boolean_t flushed = ISC_FALSE;
+ isc_boolean_t flushed;
+ isc_boolean_t found;
isc_result_t result;
isc_buffer_t b;
dns_fixedname_t fixed;
@@ -4021,21 +4046,25 @@ ns_server_flushname(ns_server_t *server, char *args) {
result = isc_task_beginexclusive(server->task);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
flushed = ISC_TRUE;
+ found = ISC_FALSE;
for (view = ISC_LIST_HEAD(server->viewlist);
view != NULL;
view = ISC_LIST_NEXT(view, link))
{
if (viewname != NULL && strcasecmp(viewname, view->name) != 0)
continue;
+ found = ISC_TRUE;
result = dns_view_flushname(view, name);
if (result != ISC_R_SUCCESS)
flushed = ISC_FALSE;
}
- if (flushed)
+ if (flushed && found)
result = ISC_R_SUCCESS;
+ else if (!found)
+ result = ISC_R_NOTFOUND;
else
result = ISC_R_FAILURE;
- isc_task_endexclusive(server->task);
+ isc_task_endexclusive(server->task);
return (result);
}
@@ -4086,7 +4115,7 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args) {
char *journal;
const char *vname, *sep;
isc_boolean_t frozen;
-
+
result = zone_from_args(server, args, &zone);
if (result != ISC_R_SUCCESS)
return (result);