From: Mark Andrews Date: Fri, 22 Aug 2014 06:18:49 +0000 (+1000) Subject: 3924. [bug] Improve 'rndc addzone' error reporting. RT #35187 X-Git-Tag: v9.8.8rc1~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=92c2986f634c2f75b6c983408ee11a2abaeaf2a4;p=thirdparty%2Fbind9.git 3924. [bug] Improve 'rndc addzone' error reporting. RT #35187 (cherry picked from commit d4859b0b2a0510d8c4f3c48c606a5568a3b0c1d8) --- diff --git a/CHANGES b/CHANGES index e9b1d932343..ddfa3841efe 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +3924. [bug] Improve 'rndc addzone' error reporting. RT #35187] + 3923. [bug] Sanity check the xml2-config output. [RT #22246] 3922. [bug] When resigning, dnssec-signzone was removing diff --git a/bin/named/control.c b/bin/named/control.c index c98c92f7bed..590bbd5731e 100644 --- a/bin/named/control.c +++ b/bin/named/control.c @@ -199,7 +199,7 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) { command_compare(command, NS_COMMAND_LOADKEYS)) { result = ns_server_rekey(ns_g_server, command, text); } else if (command_compare(command, NS_COMMAND_ADDZONE)) { - result = ns_server_add_zone(ns_g_server, command); + result = ns_server_add_zone(ns_g_server, command, text); } else if (command_compare(command, NS_COMMAND_DELZONE)) { result = ns_server_del_zone(ns_g_server, command, text); } else { diff --git a/bin/named/include/named/server.h b/bin/named/include/named/server.h index aa5a76b5472..1f8fb1180d9 100644 --- a/bin/named/include/named/server.h +++ b/bin/named/include/named/server.h @@ -329,7 +329,7 @@ ns_server_validation(ns_server_t *server, char *args); * Add a zone to a running process */ isc_result_t -ns_server_add_zone(ns_server_t *server, char *args); +ns_server_add_zone(ns_server_t *server, char *args, isc_buffer_t *text); /*% * Deletes a zone from a running process diff --git a/bin/named/server.c b/bin/named/server.c index 74d04f0afc6..b939906f077 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -123,6 +123,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) { \ @@ -375,6 +383,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); @@ -6303,9 +6314,8 @@ zone_from_args(ns_server_t *server, char *args, dns_zone_t **zonep, 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: @@ -7720,8 +7730,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; @@ -7736,7 +7746,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; @@ -7817,7 +7827,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)); @@ -7830,8 +7847,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)); @@ -7844,6 +7864,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."); @@ -7865,7 +7888,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)); @@ -7901,6 +7924,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) { @@ -8078,6 +8103,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) { @@ -8131,3 +8158,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); +}