From c55a1da4fc1188afe88264f97c1b705e188ae1fe Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Thu, 21 May 2015 23:04:29 -0700 Subject: [PATCH] [master] log parsing errors from default config or addzone/modzone 4124. [func] Log errors or warnings encountered when parsing the internal default configuration. Clarify the logging of errors and warnings encountered in rndc addzone or modzone parameters. [RT #39440] --- CHANGES | 5 +++++ bin/named/config.c | 29 +++++++++++++++-------------- bin/named/server.c | 20 ++++++++++++++++---- bin/tests/system/addzone/tests.sh | 16 ++++++++++++++++ lib/isccfg/include/isccfg/cfg.h | 7 +++++++ lib/isccfg/include/isccfg/grammar.h | 6 ++++++ lib/isccfg/parser.c | 26 +++++++++++++++++++++++--- 7 files changed, 88 insertions(+), 21 deletions(-) diff --git a/CHANGES b/CHANGES index 0e07b43e23..3fe38e28dd 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +4124. [func] Log errors or warnings encountered when parsing the + internal default configuration. Clarify the logging + of errors and warnings encountered in rndc + addzone or modzone parameters. [RT #39440] + 4123. [port] Added %z (size_t) format options to the portable internal printf/sprintf implementation. [RT #39586] diff --git a/bin/named/config.c b/bin/named/config.c index d4a1f21560..d0f2b745ad 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -62,13 +62,13 @@ options {\n\ "# session-keyfile \"" NS_LOCALSTATEDIR "/run/named/session.key\";\n\ session-keyname local-ddns;\n\ session-keyalg hmac-sha256;\n\ - deallocate-on-exit true;\n\ +# deallocate-on-exit ;\n\ # directory \n\ dump-file \"named_dump.db\";\n\ - fake-iquery no;\n\ - has-old-clients false;\n\ +# fake-iquery ;\n\ +# has-old-clients ;\n\ heartbeat-interval 60;\n\ - host-statistics no;\n\ +# host-statistics ;\n\ interface-interval 60;\n\ # keep-response-order {none;};\n\ listen-on {any;};\n\ @@ -76,7 +76,7 @@ options {\n\ match-mapped-addresses no;\n\ max-rsa-exponent-size 0; /* no limit */\n\ memstatistics-file \"named.memstats\";\n\ - multiple-cnames no;\n\ +# multiple-cnames ;\n\ # named-xfer ;\n\ nta-lifetime 3600;\n\ nta-recheck 300;\n\ @@ -97,12 +97,12 @@ options {\n\ recursive-clients 1000;\n\ resolver-query-timeout 10;\n\ rrset-order { order random; };\n\ - serial-queries 20;\n\ +# serial-queries ;\n\ serial-query-rate 20;\n\ server-id none;\n\ startup-notify-rate 20;\n\ statistics-file \"named.stats\";\n\ - statistics-interval 60;\n\ +# statistics-interval ;\n\ tcp-clients 150;\n\ tcp-listen-queue 10;\n\ # tkey-dhkey \n\ @@ -111,8 +111,8 @@ options {\n\ transfers-per-ns 2;\n\ transfers-in 10;\n\ transfers-out 10;\n\ - treat-cr-as-space true;\n\ - use-id-pool true;\n\ +# treat-cr-as-space ;\n\ +# use-id-pool ;\n\ use-ixfr true;\n\ edns-udp-size 4096;\n\ max-udp-size 4096;\n\ @@ -146,8 +146,8 @@ options {\n\ provide-ixfr true;\n\ request-ixfr true;\n\ request-expire true;\n\ - fetch-glue no;\n\ - rfc2308-type1 no;\n\ +# fetch-glue ;\n\ +# rfc2308-type1 ;\n\ additional-from-auth true;\n\ additional-from-cache true;\n\ query-source address *;\n\ @@ -155,7 +155,7 @@ options {\n\ notify-source *;\n\ notify-source-v6 *;\n\ cleaning-interval 0; /* now meaningless */\n\ - min-roots 2;\n\ +# min-roots ;\n\ lame-ttl 600;\n\ servfail-ttl 10;\n\ max-ncache-ttl 10800; /* 3 hours */\n\ @@ -205,7 +205,7 @@ options {\n\ dialup no;\n\ # forward \n\ # forwarders \n\ - maintain-ixfr-base no;\n\ +# maintain-ixfr-base ;\n\ # max-ixfr-log-size \n\ transfer-source *;\n\ transfer-source-v6 *;\n\ @@ -299,7 +299,8 @@ ns_config_parsedefaults(cfg_parser_t *parser, cfg_obj_t **conf) { isc_buffer_init(&b, defaultconf, sizeof(defaultconf) - 1); isc_buffer_add(&b, sizeof(defaultconf) - 1); - return (cfg_parse_buffer(parser, &b, &cfg_type_namedconf, conf)); + return (cfg_parse_buffer2(parser, &b, __FILE__, + &cfg_type_namedconf, conf)); } isc_result_t diff --git a/bin/named/server.c b/bin/named/server.c index d5340133ec..b3685957c3 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -5523,7 +5523,11 @@ load_configuration(const char *filename, ns_server_t *server, * Parse the global default pseudo-config file. */ if (first_time) { - CHECK(ns_config_parsedefaults(ns_g_parser, &ns_g_config)); + result = ns_config_parsedefaults(ns_g_parser, &ns_g_config); + if (result != ISC_R_SUCCESS) + ns_main_earlyfatal("unable to load " + "internal defaults: %s", + isc_result_totext(result)); RUNTIME_CHECK(cfg_map_get(ns_g_config, "options", &ns_g_defaults) == ISC_R_SUCCESS); } @@ -6701,10 +6705,10 @@ run_server(isc_task_t *task, isc_event_t *event) { server, &server->pps_timer), "creating pps timer"); - CHECKFATAL(cfg_parser_create(ns_g_mctx, NULL, &ns_g_parser), + CHECKFATAL(cfg_parser_create(ns_g_mctx, ns_g_lctx, &ns_g_parser), "creating default configuration parser"); - CHECKFATAL(cfg_parser_create(ns_g_mctx, NULL, &ns_g_addparser), + CHECKFATAL(cfg_parser_create(ns_g_mctx, ns_g_lctx, &ns_g_addparser), "creating additional configuration parser"); if (ns_g_lwresdonly) @@ -9239,6 +9243,7 @@ newzone_parse(ns_server_t *server, char *args, dns_view_t **viewp, const char *viewname = NULL; dns_rdataclass_t rdclass; dns_view_t *view = NULL; + const char *bn; REQUIRE(viewp != NULL && *viewp == NULL); @@ -9246,6 +9251,13 @@ newzone_parse(ns_server_t *server, char *args, dns_view_t **viewp, isc_buffer_init(&argbuf, args, (unsigned int) strlen(args)); isc_buffer_add(&argbuf, strlen(args)); + if (strncasecmp(args, "add", 3) == 0) + bn = "addzone"; + else if (strncasecmp(args, "mod", 3) == 0) + bn = "modzone"; + else + INSIST(0); + /* * Convert the "addzone" or "modzone" to just "zone", for * the benefit of the parser @@ -9253,7 +9265,7 @@ newzone_parse(ns_server_t *server, char *args, dns_view_t **viewp, isc_buffer_forward(&argbuf, 3); cfg_parser_reset(ns_g_addparser); - CHECK(cfg_parse_buffer(ns_g_addparser, &argbuf, + CHECK(cfg_parse_buffer2(ns_g_addparser, &argbuf, bn, &cfg_type_addzoneconf, &zoneconf)); CHECK(cfg_map_get(zoneconf, "zone", &zlist)); if (! cfg_obj_islist(zlist)) diff --git a/bin/tests/system/addzone/tests.sh b/bin/tests/system/addzone/tests.sh index 8e7587e114..849376624e 100755 --- a/bin/tests/system/addzone/tests.sh +++ b/bin/tests/system/addzone/tests.sh @@ -51,6 +51,22 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +echo "I:checking addzone errors are logged correctly" +ret=0 +$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 addzone bad.example '{ type mister; };' 2>&1 | grep 'unexpected token' > /dev/null 2>&1 || ret=1 +grep "addzone: 'mister' unexpected" ns2/named.run >/dev/null 2>&1 || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking modzone errors are logged correctly" +ret=0 +$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 modzone added.example '{ type mister; };' 2>&1 | grep 'unexpected token' > /dev/null 2>&1 || ret=1 +grep "modzone: 'mister' unexpected" ns2/named.run >/dev/null 2>&1 || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + echo "I:adding a zone that requires quotes ($n)" ret=0 $RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 addzone '"32/1.0.0.127-in-addr.added.example" { check-names ignore; type master; file "added.db"; };' 2>&1 | sed 's/^/I:ns2 /' diff --git a/lib/isccfg/include/isccfg/cfg.h b/lib/isccfg/include/isccfg/cfg.h index 5f5997aef0..1114256c36 100644 --- a/lib/isccfg/include/isccfg/cfg.h +++ b/lib/isccfg/include/isccfg/cfg.h @@ -120,6 +120,10 @@ cfg_parse_file(cfg_parser_t *pctx, const char *filename, isc_result_t cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, const cfg_type_t *type, cfg_obj_t **ret); +isc_result_t +cfg_parse_buffer2(cfg_parser_t *pctx, isc_buffer_t *buffer, + const char *bufname, const cfg_type_t *type, + cfg_obj_t **ret); /*%< * Read a configuration containing data of type 'type' * and make '*ret' point to its parse tree. @@ -128,6 +132,9 @@ cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, * (isc_parse_file()) or the buffer 'buffer' * (isc_parse_buffer()). * + * If 'bufname' is not NULL, it is a name for the buffer that + * can be reported when logging errors. + * * Returns an error if the file does not parse correctly. * * Requires: diff --git a/lib/isccfg/include/isccfg/grammar.h b/lib/isccfg/include/isccfg/grammar.h index c1dc495a90..9d27699908 100644 --- a/lib/isccfg/include/isccfg/grammar.h +++ b/lib/isccfg/include/isccfg/grammar.h @@ -211,6 +211,12 @@ struct cfg_parser { */ cfg_obj_t * closed_files; + /*% + * Name of a buffer being parsed; used only for + * logging. + */ + char const * buf_name; + /*% * Current line number. We maintain our own * copy of this so that it is available even diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index 497ab377e4..e1c9fe71bf 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -15,8 +15,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ - /*! \file */ #include @@ -427,6 +425,7 @@ cfg_parser_create(isc_mem_t *mctx, isc_log_t *lctx, cfg_parser_t **ret) { pctx->callbackarg = NULL; pctx->token.type = isc_tokentype_unknown; pctx->flags = 0; + pctx->buf_name = NULL; memset(specials, 0, sizeof(specials)); specials['{'] = 1; @@ -544,11 +543,20 @@ cfg_parse_file(cfg_parser_t *pctx, const char *filename, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; + cfg_listelt_t *elt; REQUIRE(filename != NULL); CHECK(parser_openfile(pctx, filename)); - CHECK(parse2(pctx, type, ret)); + + result = parse2(pctx, type, ret); + + /* Clean up the opened file */ + elt = ISC_LIST_TAIL(pctx->open_files->value.list); + INSIST(elt != NULL); + ISC_LIST_UNLINK(pctx->open_files->value.list, elt, link); + ISC_LIST_APPEND(pctx->closed_files->value.list, elt, link); + cleanup: return (result); } @@ -557,13 +565,23 @@ cfg_parse_file(cfg_parser_t *pctx, const char *filename, isc_result_t cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, const cfg_type_t *type, cfg_obj_t **ret) +{ + return (cfg_parse_buffer2(pctx, buffer, NULL, type, ret)); +} + +isc_result_t +cfg_parse_buffer2(cfg_parser_t *pctx, isc_buffer_t *buffer, + const char *bufname, const cfg_type_t *type, + cfg_obj_t **ret) { isc_result_t result; REQUIRE(buffer != NULL); CHECK(isc_lex_openbuffer(pctx->lexer, buffer)); + pctx->buf_name = bufname; CHECK(parse2(pctx, type, ret)); + pctx->buf_name = NULL; cleanup: return (result); @@ -2449,6 +2467,8 @@ parser_complain(cfg_parser_t *pctx, isc_boolean_t is_warning, if (have_current_file(pctx)) snprintf(where, sizeof(where), "%s:%u: ", current_file(pctx), pctx->line); + else if (pctx->buf_name != NULL) + snprintf(where, sizeof(where), "%s: ", pctx->buf_name); len = vsnprintf(message, sizeof(message), format, args); if (len >= sizeof(message))