From 5bb4ceb2a67fd558962f8a786c93daedc148a599 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Tue, 9 Jan 2001 00:43:24 +0000 Subject: [PATCH] 668. [func] named-checkzone now reports multiple errors in master files. --- CHANGES | 3 + bin/check/named-checkzone.c | 3 +- lib/dns/include/dns/master.h | 3 +- lib/dns/include/dns/zone.h | 3 +- lib/dns/master.c | 184 ++++++++++++++++++++++++++++------- lib/dns/zone.c | 17 +++- 6 files changed, 174 insertions(+), 39 deletions(-) diff --git a/CHANGES b/CHANGES index 492f6f8d06..47ffd86746 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ + 668. [func] named-checkzone now reports multiple errors in master + files. + 667. [bug] On Linux, running named with the -u option and a non-world-readable configuration file didn't work. [RT #626] diff --git a/bin/check/named-checkzone.c b/bin/check/named-checkzone.c index 0fbc9ff9de..991bb05e77 100644 --- a/bin/check/named-checkzone.c +++ b/bin/check/named-checkzone.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named-checkzone.c,v 1.6 2000/12/21 22:11:03 gson Exp $ */ +/* $Id: named-checkzone.c,v 1.7 2001/01/09 00:43:18 marka Exp $ */ #include @@ -105,6 +105,7 @@ setup(char *zonename, char *filename, char *classname) { ERRRET(result, "dns_rdataclass_fromtext"); dns_zone_setclass(zone, rdclass); + dns_zone_setoption(zone, DNS_ZONEOPT_MANYERRORS, ISC_TRUE); result = dns_zone_load(zone); diff --git a/lib/dns/include/dns/master.h b/lib/dns/include/dns/master.h index 74694abaa2..fa125a5849 100644 --- a/lib/dns/include/dns/master.h +++ b/lib/dns/include/dns/master.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: master.h,v 1.27 2001/01/05 03:12:45 marka Exp $ */ +/* $Id: master.h,v 1.28 2001/01/09 00:43:23 marka Exp $ */ #ifndef DNS_MASTER_H #define DNS_MASTER_H 1 @@ -31,6 +31,7 @@ #include #define DNS_MASTER_AGETTL 0x01 /* Age the ttl based on $DATE. */ +#define DNS_MASTER_MANYERRORS 0x2 /* Continue processing on errors. */ ISC_LANG_BEGINDECLS diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index 7baf03124f..e445b40fe6 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.h,v 1.95 2000/12/28 01:29:08 marka Exp $ */ +/* $Id: zone.h,v 1.96 2001/01/09 00:43:24 marka Exp $ */ #ifndef DNS_ZONE_H #define DNS_ZONE_H 1 @@ -44,6 +44,7 @@ typedef enum { #define DNS_ZONEOPT_PARENTS 0x00000002U /* perform parent checks */ #define DNS_ZONEOPT_CHILDREN 0x00000004U /* perform child checks */ #define DNS_ZONEOPT_NOTIFY 0x00000008U /* perform NOTIFY */ +#define DNS_ZONEOPT_MANYERRORS 0x00000010U /* return many errors on load */ #ifndef NOMINUM_PUBLIC /* * Nominum specific options build down. diff --git a/lib/dns/master.c b/lib/dns/master.c index 93b6abffba..209494a485 100644 --- a/lib/dns/master.c +++ b/lib/dns/master.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: master.c,v 1.93 2001/01/08 23:52:52 marka Exp $ */ +/* $Id: master.c,v 1.94 2001/01/09 00:43:20 marka Exp $ */ #include @@ -125,6 +125,7 @@ struct dns_loadctx { isc_event_t event; isc_mutex_t lock; + isc_result_t result; /* locked by lock */ isc_uint32_t references; }; @@ -197,11 +198,23 @@ loadmgr_destroy(dns_loadmgr_t *mgr); case ISC_R_UNEXPECTED: \ goto insist_and_cleanup; \ default: \ - goto log_and_cleanup; \ + if (MANYERRS(ctx, result)) { \ + SETRESULT(ctx, result); \ + LOGIT(result); \ + read_till_eol = ISC_TRUE; \ + goto next_line; \ + } else \ + goto log_and_cleanup; \ } \ if ((token)->type == isc_tokentype_special) { \ result = DNS_R_SYNTAX; \ - goto log_and_cleanup; \ + if (MANYERRS(ctx, result)) { \ + SETRESULT(ctx, result); \ + LOGIT(result); \ + read_till_eol = ISC_TRUE; \ + goto next_line; \ + } else \ + goto log_and_cleanup; \ } \ } while (0) @@ -209,11 +222,17 @@ loadmgr_destroy(dns_loadmgr_t *mgr); do { \ result = commit(callbacks, ctx->lex, ¤t_list, \ ctx->current, ctx->top); \ - if (result != ISC_R_SUCCESS) \ + if (MANYERRS(ctx, result)) { \ + SETRESULT(ctx, result); \ + LOGIT(result); \ + } else if (result != ISC_R_SUCCESS) \ goto log_and_cleanup; \ result = commit(callbacks, ctx->lex, &glue_list, \ ctx->glue, ctx->top); \ - if (result != ISC_R_SUCCESS) \ + if (MANYERRS(ctx, result)) { \ + SETRESULT(ctx, result); \ + LOGIT(result); \ + } else if (result != ISC_R_SUCCESS) \ goto log_and_cleanup; \ rdcount = 0; \ rdlcount = 0; \ @@ -233,6 +252,25 @@ loadmgr_destroy(dns_loadmgr_t *mgr); #define CTX_COPYVAR(ctx, new, var) (new)->var = (ctx)->var +#define MANYERRS(ctx, result) \ + ((result != ISC_R_SUCCESS) && \ + ((ctx)->options & DNS_MASTER_MANYERRORS) != 0) +#define SETRESULT(ctx, r) \ + do { \ + if ((ctx)->result == ISC_R_SUCCESS) \ + (ctx)->result = r; \ + } while (0) +#define LOGIT(result) \ + if (result == ISC_R_NOMEMORY) \ + (*callbacks->error)(callbacks, "dns_master_load: %s", \ + dns_result_totext(result)); \ + else \ + (*callbacks->error)(callbacks, "%s: %s:%lu: %s", \ + "dns_master_load", \ + isc_lex_getsourcename(ctx->lex), \ + isc_lex_getsourceline(ctx->lex), \ + dns_result_totext(result)) + static inline isc_result_t gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *token, isc_boolean_t eol, dns_rdatacallbacks_t *callbacks) @@ -394,6 +432,7 @@ loadctx_create(isc_mem_t *mctx, unsigned int options, dns_name_t *top, ctx->options = options; ctx->seen_include = ISC_FALSE; ctx->zclass = zclass; + ctx->result = ISC_R_SUCCESS; dns_fixedname_init(&ctx->fixed_top); ctx->top = dns_fixedname_name(&ctx->fixed_top); @@ -770,6 +809,7 @@ load(dns_loadctx_t **ctxp) { CTX_COPYVAR(ctx, *ctxp, default_ttl); CTX_COPYVAR(ctx, *ctxp, warn_1035); CTX_COPYVAR(ctx, *ctxp, seen_include); + CTX_COPYVAR(ctx, *ctxp, result); dns_loadctx_detach(&ctx); ctx = *ctxp; continue; @@ -812,7 +852,10 @@ load(dns_loadctx_t **ctxp) { result = dns_ttl_fromtext(&token.value.as_textregion, &ctx->ttl); - if (result != ISC_R_SUCCESS) + if (MANYERRS(ctx, result)) { + SETRESULT(ctx, result); + ctx->ttl = 0; + } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; if (ctx->ttl > 0x7fffffffUL) { (callbacks->warn)(callbacks, @@ -865,7 +908,11 @@ load(dns_loadctx_t **ctxp) { result = pushfile(include_file, ctx->origin, ctxp); - if (result != ISC_R_SUCCESS) + if (MANYERRS(ctx, result)) { + SETRESULT(ctx, result); + LOGIT(result); + continue; + } else if (result != ISC_R_SUCCESS) goto log_and_cleanup; ctx = *ctxp; continue; @@ -885,7 +932,11 @@ load(dns_loadctx_t **ctxp) { isc_stdtime_get(¤t_time); result = dns_time64_fromtext(token.value. as_pointer, &dump_time64); - if (result != ISC_R_SUCCESS) + if (MANYERRS(ctx, result)) { + SETRESULT(ctx, result); + LOGIT(result); + dump_time64 = 0; + } else if (result != ISC_R_SUCCESS) goto log_and_cleanup; dump_time = (isc_stdtime_t)dump_time64; if (dump_time != dump_time64) { @@ -924,7 +975,11 @@ load(dns_loadctx_t **ctxp) { isc_lex_getsourcename(ctx->lex), isc_lex_getsourceline(ctx->lex)); result = DNS_R_NOTTL; - goto insist_and_cleanup; + if (MANYERRS(ctx, result)) { + SETRESULT(ctx, result); + ctx->ttl = 0; + } else if (result != ISC_R_SUCCESS) + goto insist_and_cleanup; } else if (ctx->default_ttl_known) { ctx->ttl = ctx->default_ttl; } @@ -972,7 +1027,9 @@ load(dns_loadctx_t **ctxp) { goto log_and_cleanup; } result = generate(ctx, range, lhs, gtype, rhs); - if (result != ISC_R_SUCCESS) + if (MANYERRS(ctx, result)) { + SETRESULT(ctx, result); + } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; read_till_eol = ISC_TRUE; continue; @@ -986,7 +1043,10 @@ load(dns_loadctx_t **ctxp) { isc_lex_getsourceline(ctx->lex), token.value.as_pointer); result = DNS_R_SYNTAX; - goto insist_and_cleanup; + if (MANYERRS(ctx, result)) { + SETRESULT(ctx, result); + } else if (result != ISC_R_SUCCESS) + goto insist_and_cleanup; } /* @@ -1007,7 +1067,11 @@ load(dns_loadctx_t **ctxp) { token.value.as_region.length); result = dns_name_fromtext(new_name, &buffer, ctx->origin, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) + if (MANYERRS(ctx, result)) { + SETRESULT(ctx, result); + read_till_eol = ISC_TRUE; + continue; + } else if (result != ISC_R_SUCCESS) goto insist_and_cleanup; /* @@ -1027,7 +1091,11 @@ load(dns_loadctx_t **ctxp) { finish_include = ISC_FALSE; result = pushfile(include_file, new_name, ctxp); - if (result != ISC_R_SUCCESS) + if (MANYERRS(ctx, result)) { + SETRESULT(ctx, result); + LOGIT(result); + continue; + } else if (result != ISC_R_SUCCESS) goto log_and_cleanup; ctx = *ctxp; continue; @@ -1048,7 +1116,10 @@ load(dns_loadctx_t **ctxp) { result = commit(callbacks, ctx->lex, &glue_list, ctx->glue, ctx->top); - if (result != ISC_R_SUCCESS) + if (MANYERRS(ctx, result)) { + SETRESULT(ctx, result); + LOGIT(result); + } else if (result != ISC_R_SUCCESS) goto log_and_cleanup; if (ctx->glue_in_use != -1) ctx->in_use[ctx->glue_in_use] = @@ -1083,7 +1154,10 @@ load(dns_loadctx_t **ctxp) { ¤t_list, ctx->current, ctx->top); - if (result != ISC_R_SUCCESS) + if (MANYERRS(ctx, result)) { + SETRESULT(ctx, result); + LOGIT(result); + } else if (result != ISC_R_SUCCESS) goto log_and_cleanup; rdcount = 0; rdlcount = 0; @@ -1107,7 +1181,12 @@ load(dns_loadctx_t **ctxp) { isc_lex_getsourceline(ctx->lex), token.type); result = ISC_R_UNEXPECTED; - goto insist_and_cleanup; + if (MANYERRS(ctx, result)) { + SETRESULT(ctx, result); + LOGIT(result); + continue; + } else if (result != ISC_R_SUCCESS) + goto insist_and_cleanup; } /* @@ -1144,7 +1223,12 @@ load(dns_loadctx_t **ctxp) { isc_lex_getsourcename(ctx->lex), isc_lex_getsourceline(ctx->lex)); result = DNS_R_NOOWNER; - goto insist_and_cleanup; + if (MANYERRS(ctx, result)) { + SETRESULT(ctx, result); + read_till_eol = ISC_TRUE; + continue; + } else if (result != ISC_R_SUCCESS) + goto insist_and_cleanup; } } @@ -1178,7 +1262,11 @@ load(dns_loadctx_t **ctxp) { isc_lex_getsourcename(ctx->lex), isc_lex_getsourceline(ctx->lex)); result = DNS_R_NOTTL; - goto insist_and_cleanup; + if (MANYERRS(ctx, result)) { + SETRESULT(ctx, result); + ctx->ttl = 0; + } else if (result != ISC_R_SUCCESS) + goto insist_and_cleanup; } else if (ctx->default_ttl_known) { ctx->ttl = ctx->default_ttl; } else if (ctx->warn_1035) { @@ -1195,7 +1283,12 @@ load(dns_loadctx_t **ctxp) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_lex_gettoken() returned unexpected token type"); result = ISC_R_UNEXPECTED; - goto insist_and_cleanup; + if (MANYERRS(ctx, result)) { + SETRESULT(ctx, result); + read_till_eol = ISC_TRUE; + continue; + } else if (result != ISC_R_SUCCESS) + goto insist_and_cleanup; } if (rdclass == 0 && @@ -1208,7 +1301,12 @@ load(dns_loadctx_t **ctxp) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_lex_gettoken() returned unexpected token type"); result = ISC_R_UNEXPECTED; - goto insist_and_cleanup; + if (MANYERRS(ctx, result)) { + SETRESULT(ctx, result); + read_till_eol = ISC_TRUE; + continue; + } else if (result != ISC_R_SUCCESS) + goto insist_and_cleanup; } result = dns_rdatatype_fromtext(&type, @@ -1221,7 +1319,12 @@ load(dns_loadctx_t **ctxp) { isc_lex_getsourceline(ctx->lex), token.value.as_textregion.length, token.value.as_textregion.base); - goto insist_and_cleanup; + if (MANYERRS(ctx, result)) { + SETRESULT(ctx, result); + read_till_eol = ISC_TRUE; + continue; + } else if (result != ISC_R_SUCCESS) + goto insist_and_cleanup; } /* @@ -1244,7 +1347,12 @@ load(dns_loadctx_t **ctxp) { isc_lex_getsourceline(ctx->lex), classname1, classname2); result = DNS_R_BADCLASS; - goto insist_and_cleanup; + if (MANYERRS(ctx, result)) { + SETRESULT(ctx, result); + read_till_eol = ISC_TRUE; + continue; + } else if (result != ISC_R_SUCCESS) + goto insist_and_cleanup; } if (type == dns_rdatatype_ns && ctx->glue == NULL) @@ -1286,8 +1394,12 @@ load(dns_loadctx_t **ctxp) { result = dns_rdata_fromtext(&rdata[rdcount], ctx->zclass, type, ctx->lex, ctx->origin, ISC_FALSE, ctx->mctx, &target, callbacks); - if (result != ISC_R_SUCCESS) - goto log_and_cleanup; + if (MANYERRS(ctx, result)) { + SETRESULT(ctx, result); + read_till_eol = ISC_TRUE; + continue; + } else if (result != ISC_R_SUCCESS) + goto insist_and_cleanup; if (type == dns_rdatatype_sig) covers = dns_rdata_covers(&rdata[rdcount]); else @@ -1357,6 +1469,7 @@ load(dns_loadctx_t **ctxp) { */ if ((target.length - target.used) < MINTSIZ) COMMITALL; + next_line: } while (!done && (ctx->loop_cnt == 0 || loop_cnt++ < ctx->loop_cnt)); /* @@ -1364,29 +1477,29 @@ load(dns_loadctx_t **ctxp) { */ result = commit(callbacks, ctx->lex, ¤t_list, ctx->current, ctx->top); - if (result != ISC_R_SUCCESS) + if (MANYERRS(ctx, result)) { + SETRESULT(ctx, result); + LOGIT(result); + } else if (result != ISC_R_SUCCESS) goto log_and_cleanup; result = commit(callbacks, ctx->lex, &glue_list, ctx->glue, ctx->top); - if (result != ISC_R_SUCCESS) + if (MANYERRS(ctx, result)) { + SETRESULT(ctx, result); + LOGIT(result); + } else if (result != ISC_R_SUCCESS) goto log_and_cleanup; if (!done) { INSIST(ctx->done != NULL && ctx->task != NULL); result = DNS_R_CONTINUE; + } else if (result == ISC_R_SUCCESS && ctx->result != ISC_R_SUCCESS) { + result = ctx->result; } else if (result == ISC_R_SUCCESS && ctx->seen_include) result = DNS_R_SEENINCLUDE; goto cleanup; log_and_cleanup: - if (result == ISC_R_NOMEMORY) - (*callbacks->error)(callbacks, "dns_master_load: %s", - dns_result_totext(result)); - else - (*callbacks->error)(callbacks, "%s: %s:%lu: %s", - "dns_master_load", - isc_lex_getsourcename(ctx->lex), - isc_lex_getsourceline(ctx->lex), - dns_result_totext(result)); + LOGIT(result); insist_and_cleanup: INSIST(result != ISC_R_SUCCESS); @@ -1459,6 +1572,7 @@ pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t **ctxp) { CTX_COPYVAR(ctx, new, default_ttl); CTX_COPYVAR(ctx, new, warn_1035); CTX_COPYVAR(ctx, new, seen_include); + CTX_COPYVAR(ctx, new, result); result = isc_lex_openfile(new->lex, master_file); if (result != ISC_R_SUCCESS) diff --git a/lib/dns/zone.c b/lib/dns/zone.c index ab001bb0cf..2d29f3eff3 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.291 2001/01/05 22:09:02 gson Exp $ */ +/* $Id: zone.c,v 1.292 2001/01/09 00:43:21 marka Exp $ */ #include @@ -1051,6 +1051,21 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { goto cleanup; } else result = DNS_R_CONTINUE; + } else if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) { + dns_rdatacallbacks_t callbacks; + + dns_rdatacallbacks_init(&callbacks); + result = dns_db_beginload(db, &callbacks.add, + &callbacks.add_private); + if (result != ISC_R_SUCCESS) + return (result); + result = dns_master_loadfile(zone->masterfile, &zone->origin, + &zone->origin, zone->rdclass, + DNS_MASTER_MANYERRORS, + &callbacks, zone->mctx); + tresult = dns_db_endload(db, &callbacks.add_private); + if (result == ISC_R_SUCCESS) + result = tresult; } else { result = dns_db_load(db, zone->masterfile); }