diff options
Diffstat (limited to 'bin/named/server.c')
-rw-r--r-- | bin/named/server.c | 143 |
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); |