diff options
Diffstat (limited to 'bin/named/server.c')
-rw-r--r-- | bin/named/server.c | 164 |
1 files changed, 119 insertions, 45 deletions
diff --git a/bin/named/server.c b/bin/named/server.c index 77a4e4406976..84e3ecf32108 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -130,6 +130,14 @@ if (result != ISC_R_SUCCESS) goto cleanup; \ } while (0) +#define TCHECK(op) \ + do { tresult = (op); \ + if (tresult != ISC_R_SUCCESS) { \ + isc_buffer_clear(text); \ + goto cleanup; \ + } \ + } while (0) + #define CHECKM(op, msg) \ do { result = (op); \ if (result != ISC_R_SUCCESS) { \ @@ -357,12 +365,12 @@ ns_server_reload(isc_task_t *task, isc_event_t *event); static isc_result_t ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, - isc_mem_t *mctx, ns_listenelt_t **target); + cfg_aclconfctx_t *actx, isc_mem_t *mctx, + isc_uint16_t family, ns_listenelt_t **target); static isc_result_t ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, - isc_mem_t *mctx, ns_listenlist_t **target); + cfg_aclconfctx_t *actx, isc_mem_t *mctx, + isc_uint16_t family, ns_listenlist_t **target); static isc_result_t configure_forward(const cfg_obj_t *config, dns_view_t *view, dns_name_t *origin, @@ -389,6 +397,9 @@ newzone_cfgctx_destroy(void **cfgp); static isc_result_t putstr(isc_buffer_t *b, const char *str); +static isc_result_t +putnull(isc_buffer_t *b); + isc_result_t add_comment(FILE *fp, const char *viewname); @@ -1338,10 +1349,8 @@ check_dbtype(dns_zone_t *zone, unsigned int dbtypec, const char **dbargv, * Check that all the arguments match. */ for (i = 0; i < dbtypec; i++) - if (argv[i] == NULL || strcmp(argv[i], dbargv[i]) != 0) { + if (argv[i] == NULL || strcmp(argv[i], dbargv[i]) != 0) CHECK(ISC_R_FAILURE); - break; - } /* * Check that there are not extra arguments. @@ -2321,9 +2330,9 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, obj = NULL; if (dlz != NULL) { - (void)cfg_map_get(cfg_tuple_get(dlz, "options"), - "database", &obj); + (void)cfg_map_get(dlz, "database", &obj); if (obj != NULL) { + const cfg_obj_t *name; char *s = isc_mem_strdup(mctx, cfg_obj_asstring(obj)); if (s == NULL) { result = ISC_R_NOMEMORY; @@ -2336,8 +2345,8 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, goto cleanup; } - obj = cfg_tuple_get(dlz, "name"); - result = dns_dlzcreate(mctx, cfg_obj_asstring(obj), + name = cfg_map_getname(dlz); + result = dns_dlzcreate(mctx, cfg_obj_asstring(name), dlzargv[0], dlzargc, dlzargv, &view->dlzdatabase); isc_mem_free(mctx, s); @@ -3073,6 +3082,14 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, } /* + * Ignore case when compressing responses to the specified + * clients. This causes case not always to be preserved, + * and is needed by some broken clients. + */ + CHECK(configure_view_acl(vconfig, config, "no-case-compress", NULL, + actx, ns_g_mctx, &view->nocasecompress)); + + /* * Filter setting on addresses in the answer section. */ CHECK(configure_view_acl(vconfig, config, "deny-answer-addresses", @@ -3141,6 +3158,16 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, cfg_obj_asuint32(obj), max_clients_per_query); + obj = NULL; + result = ns_config_get(maps, "max-recursion-depth", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_resolver_setmaxdepth(view->resolver, cfg_obj_asuint32(obj)); + + obj = NULL; + result = ns_config_get(maps, "max-recursion-queries", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_resolver_setmaxqueries(view->resolver, cfg_obj_asuint32(obj)); + #ifdef ALLOW_FILTER_AAAA_ON_V4 obj = NULL; result = ns_config_get(maps, "filter-aaaa-on-v4", &obj); @@ -3872,8 +3899,16 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig, (void)cfg_map_get(zoptions, "forward", &forwardtype); (void)cfg_map_get(zoptions, "forwarders", &forwarders); - result = configure_forward(config, view, origin, forwarders, - forwardtype); + CHECK(configure_forward(config, view, origin, forwarders, + forwardtype)); + + /* + * Forward zones may also set delegation only. + */ + only = NULL; + tresult = cfg_map_get(zoptions, "delegation-only", &only); + if (tresult == ISC_R_SUCCESS && cfg_obj_asboolean(only)) + CHECK(dns_view_adddelegationonly(view, origin)); goto cleanup; } @@ -4559,6 +4594,9 @@ removed(dns_zone_t *zone, void *uap) { case dns_zone_stub: type = "stub"; break; + case dns_zone_staticstub: + type = "static-stub"; + break; case dns_zone_redirect: type = "redirect"; break; @@ -4654,8 +4692,8 @@ generate_session_key(const char *filename, const char *keynamestr, (int) isc_buffer_usedlength(&key_txtbuffer), (char*) isc_buffer_base(&key_txtbuffer)); - RUNTIME_CHECK(isc_stdio_flush(fp) == ISC_R_SUCCESS); - RUNTIME_CHECK(isc_stdio_close(fp) == ISC_R_SUCCESS); + CHECK(isc_stdio_flush(fp)); + CHECK(isc_stdio_close(fp)); dst_key_free(&key); @@ -4668,6 +4706,11 @@ generate_session_key(const char *filename, const char *keynamestr, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, "failed to generate session key " "for dynamic DNS: %s", isc_result_totext(result)); + if (fp != NULL) { + if (isc_file_exists(filename)) + (void)isc_file_remove(filename); + (void)isc_stdio_close(fp); + } if (tsigkey != NULL) dns_tsigkey_detach(&tsigkey); if (key != NULL) @@ -5217,7 +5260,8 @@ load_configuration(const char *filename, ns_server_t *server, /* check return code? */ (void)ns_listenlist_fromconfig(clistenon, config, ns_g_aclconfctx, - ns_g_mctx, &listenon); + ns_g_mctx, AF_INET, + &listenon); } else if (!ns_g_lwresdonly) { /* * Not specified, use default. @@ -5244,7 +5288,8 @@ load_configuration(const char *filename, ns_server_t *server, /* check return code? */ (void)ns_listenlist_fromconfig(clistenon, config, ns_g_aclconfctx, - ns_g_mctx, &listenon); + ns_g_mctx, AF_INET6, + &listenon); } else if (!ns_g_lwresdonly) { isc_boolean_t enable; /* @@ -5759,7 +5804,7 @@ load_configuration(const char *filename, ns_server_t *server, } if (bindkeys_parser != NULL) { - if (bindkeys != NULL) + if (bindkeys != NULL) cfg_obj_destroy(bindkeys_parser, &bindkeys); cfg_parser_destroy(&bindkeys_parser); } @@ -6574,6 +6619,10 @@ zone_from_args(ns_server_t *server, char *args, const char *zonetxt, snprintf(problem, sizeof(problem), "no matching zone '%s' in any view", zonetxt); + else if (result == ISC_R_MULTIPLE) + snprintf(problem, sizeof(problem), + "zone '%s' was found in multiple views", + zonetxt); } else { result = dns_viewlist_find(&server->viewlist, viewtxt, rdclass, &view); @@ -6600,9 +6649,8 @@ zone_from_args(ns_server_t *server, char *args, const char *zonetxt, isc_result_t tresult; tresult = putstr(text, problem); - if (tresult == ISC_R_SUCCESS && - isc_buffer_availablelength(text) > 0U) - isc_buffer_putuint8(text, 0); + if (tresult == ISC_R_SUCCESS) + putnull(text); } cleanup: @@ -6805,8 +6853,8 @@ ns_server_togglequerylog(ns_server_t *server, char *args) { static isc_result_t ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, - isc_mem_t *mctx, ns_listenlist_t **target) + cfg_aclconfctx_t *actx, isc_mem_t *mctx, + isc_uint16_t family, ns_listenlist_t **target) { isc_result_t result; const cfg_listelt_t *element; @@ -6825,7 +6873,7 @@ ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config, ns_listenelt_t *delt = NULL; const cfg_obj_t *listener = cfg_listelt_value(element); result = ns_listenelt_fromconfig(listener, config, actx, - mctx, &delt); + mctx, family, &delt); if (result != ISC_R_SUCCESS) goto cleanup; ISC_LIST_APPEND(dlist->elts, delt, link); @@ -6844,8 +6892,8 @@ ns_listenlist_fromconfig(const cfg_obj_t *listenlist, const cfg_obj_t *config, */ static isc_result_t ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, - cfg_aclconfctx_t *actx, - isc_mem_t *mctx, ns_listenelt_t **target) + cfg_aclconfctx_t *actx, isc_mem_t *mctx, + isc_uint16_t family, ns_listenelt_t **target) { isc_result_t result; const cfg_obj_t *portobj; @@ -6876,9 +6924,9 @@ ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config, if (result != ISC_R_SUCCESS) return (result); - result = cfg_acl_fromconfig(cfg_tuple_get(listener, "acl"), - config, ns_g_lctx, actx, mctx, 0, - &delt->acl); + result = cfg_acl_fromconfig2(cfg_tuple_get(listener, "acl"), + config, ns_g_lctx, actx, mctx, 0, + family, &delt->acl); if (result != ISC_R_SUCCESS) { ns_listenelt_destroy(delt); return (result); @@ -8179,8 +8227,8 @@ add_comment(FILE *fp, const char *viewname) { * Act on an "addzone" command from the command channel. */ isc_result_t -ns_server_add_zone(ns_server_t *server, char *args) { - isc_result_t result; +ns_server_add_zone(ns_server_t *server, char *args, isc_buffer_t *text) { + isc_result_t result, tresult; isc_buffer_t argbuf; size_t arglen; cfg_parser_t *parser = NULL; @@ -8195,7 +8243,7 @@ ns_server_add_zone(ns_server_t *server, char *args) { const char *argp; const char *viewname = NULL; dns_rdataclass_t rdclass; - dns_view_t *view = 0; + dns_view_t *view = NULL; isc_buffer_t buf; dns_fixedname_t fname; dns_name_t *dnsname; @@ -8276,7 +8324,14 @@ ns_server_add_zone(ns_server_t *server, char *args) { } /* Open save file for write configuration */ - CHECK(isc_stdio_open(view->new_zone_file, "a", &fp)); + result = isc_stdio_open(view->new_zone_file, "a", &fp); + if (result != ISC_R_SUCCESS) { + TCHECK(putstr(text, "unable to open '")); + TCHECK(putstr(text, view->new_zone_file)); + TCHECK(putstr(text, "': ")); + TCHECK(putstr(text, isc_result_totext(result))); + goto cleanup; + } CHECK(isc_stdio_tell(fp, &offset)); if (offset == 0) CHECK(add_comment(fp, view->name)); @@ -8289,8 +8344,11 @@ ns_server_add_zone(ns_server_t *server, char *args) { server->mctx, view, cfg->actx, ISC_FALSE); dns_view_freeze(view); isc_task_endexclusive(server->task); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { + TCHECK(putstr(text, "configure_zone failed: ")); + TCHECK(putstr(text, isc_result_totext(result))); goto cleanup; + } /* Is it there yet? */ CHECK(dns_zt_find(view->zonetable, dnsname, 0, NULL, &zone)); @@ -8303,6 +8361,9 @@ ns_server_add_zone(ns_server_t *server, char *args) { if (result != ISC_R_SUCCESS) { dns_db_t *dbp = NULL; + TCHECK(putstr(text, "dns_zone_loadnew failed: ")); + TCHECK(putstr(text, isc_result_totext(result))); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_INFO, "addzone failed; reverting."); @@ -8324,7 +8385,7 @@ ns_server_add_zone(ns_server_t *server, char *args) { /* Emit the zone name, quoted and escaped */ isc_buffer_init(&buf, namebuf, sizeof(namebuf)); CHECK(dns_name_totext(dnsname, ISC_TRUE, &buf)); - isc_buffer_putuint8(&buf, 0); + putnull(&buf); CHECK(isc_stdio_write("zone \"", 6, 1, fp, NULL)); CHECK(isc_stdio_write(namebuf, strlen(namebuf), 1, fp, NULL)); CHECK(isc_stdio_write("\" ", 2, 1, fp, NULL)); @@ -8360,6 +8421,8 @@ ns_server_add_zone(ns_server_t *server, char *args) { result = ISC_R_SUCCESS; cleanup: + if (isc_buffer_usedlength(text) > 0) + putnull(text); if (fp != NULL) isc_stdio_close(fp); if (parser != NULL) { @@ -8538,6 +8601,8 @@ ns_server_del_zone(ns_server_t *server, char *args, isc_buffer_t *text) { result = ISC_R_SUCCESS; cleanup: + if (isc_buffer_usedlength(text) > 0) + putnull(text); if (ifp != NULL) isc_stdio_close(ifp); if (ofp != NULL) { @@ -8667,15 +8732,15 @@ ns_server_signing(ns_server_t *server, char *args, isc_buffer_t *text) { if (clear) { CHECK(dns_zone_keydone(zone, keystr)); - isc_buffer_putstr(text, "request queued"); - isc_buffer_putuint8(text, 0); + putstr(text, "request queued"); + putnull(text); } else if (chain) { CHECK(dns_zone_setnsec3param(zone, (isc_uint8_t)hash, (isc_uint8_t)flags, iter, (isc_uint8_t)saltlen, salt, ISC_TRUE)); - isc_buffer_putstr(text, "request queued"); - isc_buffer_putuint8(text, 0); + putstr(text, "request queued"); + putnull(text); } else if (list) { privatetype = dns_zone_getprivatetype(zone); origin = dns_zone_getorigin(zone); @@ -8687,8 +8752,8 @@ ns_server_signing(ns_server_t *server, char *args, isc_buffer_t *text) { dns_rdatatype_none, 0, &privset, NULL); if (result == ISC_R_NOTFOUND) { - isc_buffer_putstr(text, "No signing records found"); - isc_buffer_putuint8(text, 0); + putstr(text, "No signing records found"); + putnull(text); result = ISC_R_SUCCESS; goto cleanup; } @@ -8707,7 +8772,7 @@ ns_server_signing(ns_server_t *server, char *args, isc_buffer_t *text) { CHECK(dns_private_totext(&priv, &buf)); if (!first) - isc_buffer_putstr(text, "\n"); + putstr(text, "\n"); first = ISC_FALSE; n = snprintf((char *)isc_buffer_used(text), @@ -8718,8 +8783,8 @@ ns_server_signing(ns_server_t *server, char *args, isc_buffer_t *text) { isc_buffer_add(text, (unsigned int)n); } - if (!first && isc_buffer_availablelength(text) > 0) - isc_buffer_putuint8(text, 0); + if (!first) + putnull(text); if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; @@ -8742,7 +8807,7 @@ ns_server_signing(ns_server_t *server, char *args, isc_buffer_t *text) { static isc_result_t putstr(isc_buffer_t *b, const char *str) { - size_t l = strlen(str); + unsigned int l = strlen(str); /* * Use >= to leave space for NUL termination. @@ -8753,3 +8818,12 @@ putstr(isc_buffer_t *b, const char *str) { isc_buffer_putmem(b, (const unsigned char *)str, l); return (ISC_R_SUCCESS); } + +static isc_result_t +putnull(isc_buffer_t *b) { + if (isc_buffer_availablelength(b) == 0) + return (ISC_R_NOSPACE); + + isc_buffer_putuint8(b, 0); + return (ISC_R_SUCCESS); +} |