diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c index 88da4f7745..7fcfcdc6df 100644 --- a/bin/named/zoneconf.c +++ b/bin/named/zoneconf.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: zoneconf.c,v 1.47 2000/07/25 20:26:11 bwelling Exp $ */ +/* $Id: zoneconf.c,v 1.48 2000/07/26 18:47:34 mws Exp $ */ #include @@ -272,10 +272,15 @@ dns_zone_configure(dns_c_ctx_t *cctx, dns_c_view_t *cview, iplist = NULL; result = dns_c_zone_getmasterips(czone, &iplist); if (result == ISC_R_SUCCESS) +#ifndef NOMINUM_PUBLIC result = dns_zone_setmasterswithkeys(zone, iplist->ips, iplist->keys, iplist->nextidx); +#else /* NOMINUM_PUBLIC */ + result = dns_zone_setmasters(zone, iplist->ips, + iplist->nextidx); +#endif /* NOMINUM_PUBLIC */ else result = dns_zone_setmasters(zone, NULL, 0); RETERR(result); diff --git a/lib/dns/config/Makefile.in b/lib/dns/config/Makefile.in index b47278d3ab..caabdba7be 100644 --- a/lib/dns/config/Makefile.in +++ b/lib/dns/config/Makefile.in @@ -13,13 +13,14 @@ # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS # SOFTWARE. -# $Id: Makefile.in,v 1.13 2000/06/22 21:55:00 tale Exp $ +# $Id: Makefile.in,v 1.14 2000/07/26 18:47:35 mws Exp $ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ YACC = @YACC@ +PERL = @PERL@ @BIND9_VERSION@ @@ -65,6 +66,14 @@ confparser.c: confparser.y chmod a-w confparser.c mv y.tab.h confparser_p.h +#ifndef NOMINUM_PUBLIC +## This rule is here only for Nominum internal use. The above "comment" +## will cause the sanitizer to remove it +confparser.y: confparser.y.dirty + ${PERL} ../../../util/sanitize.pl -i - < confparser.y.dirty \ + > confparser.y +#endif NOMINUM_PUBLIC + depend: confparser.c distclean:: diff --git a/lib/dns/config/confip.c b/lib/dns/config/confip.c index fbac6d7ded..d65f459131 100644 --- a/lib/dns/config/confip.c +++ b/lib/dns/config/confip.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: confip.c,v 1.28 2000/07/21 21:24:56 brister Exp $ */ +/* $Id: confip.c,v 1.29 2000/07/26 18:47:36 mws Exp $ */ #include @@ -775,8 +775,9 @@ isc_result_t dns_c_iplist_new(isc_mem_t *mem, int length, dns_c_iplist_t **newlist) { dns_c_iplist_t *list; size_t bytes; +#ifndef NOMINUM_PUBLIC int i; - +#endif /* NOMINUM_PUBLIC */ REQUIRE(mem != NULL); REQUIRE(length > 0); REQUIRE(newlist != NULL); @@ -796,6 +797,7 @@ dns_c_iplist_new(isc_mem_t *mem, int length, dns_c_iplist_t **newlist) { bytes = sizeof (dns_name_t *) * length; +#ifndef NOMINUM_PUBLIC list->keys = isc_mem_get(mem, bytes); if (list->keys == NULL) { isc_mem_put(mem, list->ips, sizeof (isc_sockaddr_t) * length); @@ -804,7 +806,7 @@ dns_c_iplist_new(isc_mem_t *mem, int length, dns_c_iplist_t **newlist) { } for (i = 0 ; i < length ; i++) list->keys[i] = NULL; - +#endif /* NOMINUM_PUBLIC */ list->magic = DNS_C_IPLIST_MAGIC; list->size = length; @@ -834,6 +836,7 @@ dns_c_iplist_detach(dns_c_iplist_t **list) { l->refcount--; if (l->refcount == 0) { +#ifndef NOMINUM_PUBLIC for (i = 0 ; i < l->size ; i++) { if (l->keys[i] != NULL) { dns_name_free(l->keys[i], l->mem); @@ -842,8 +845,8 @@ dns_c_iplist_detach(dns_c_iplist_t **list) { l->keys[i] = NULL; } } - isc_mem_put(l->mem, l->keys, sizeof (dns_name_t *) * l->size); +#endif /* NOMINUM_PUBLIC */ isc_mem_put(l->mem, l->ips, sizeof (isc_sockaddr_t) * l->size); isc_mem_put(l->mem, l, sizeof *l); } @@ -853,7 +856,7 @@ dns_c_iplist_detach(dns_c_iplist_t **list) { return (ISC_R_SUCCESS); } - +#ifndef NOMINUM_PUBLIC isc_boolean_t dns_c_iplist_haskeys(dns_c_iplist_t *list) { @@ -871,7 +874,7 @@ dns_c_iplist_haskeys(dns_c_iplist_t *list) return (ISC_FALSE); } - +#endif /* NOMINUM_PUBLIC */ void dns_c_iplist_attach(dns_c_iplist_t *source, dns_c_iplist_t **target) { @@ -898,6 +901,7 @@ dns_c_iplist_copy(isc_mem_t *mem, dns_c_iplist_t **dest, dns_c_iplist_t *src) { for (i = 0 ; i < src->nextidx ; i++) { newl->ips[i] = src->ips[i]; +#ifndef NOMINUM_PUBLIC if (src->keys[i] != NULL) { newl->keys[i] = isc_mem_get(mem, sizeof (dns_name_t)); if (newl->keys[i] == NULL) { @@ -912,6 +916,7 @@ dns_c_iplist_copy(isc_mem_t *mem, dns_c_iplist_t **dest, dns_c_iplist_t *src) { } } } +#endif /* NOMINUM_PUBLIC */ } newl->nextidx = src->nextidx; @@ -935,6 +940,7 @@ dns_c_iplist_equal(dns_c_iplist_t *list1, dns_c_iplist_t *list2) { if (!isc_sockaddr_equal(&list1->ips[i], &list2->ips[i])) return (ISC_FALSE); +#ifndef NOMINUM_PUBLIC if ((list1->keys[i] == NULL && list2->keys[i] != NULL) || (list1->keys[i] != NULL && list2->keys[i] == NULL)) return (ISC_FALSE); @@ -942,6 +948,7 @@ dns_c_iplist_equal(dns_c_iplist_t *list1, dns_c_iplist_t *list2) { if (list1->keys[i] != NULL && !dns_name_equal(list1->keys[i], list2->keys[i])) return (ISC_FALSE); +#endif /* NOMINUM_PUBLIC */ } return (ISC_TRUE); @@ -951,7 +958,9 @@ void dns_c_iplist_printfully(FILE *fp, int indent, isc_boolean_t porttoo, dns_c_iplist_t *list) { +#ifndef NOMINUM_PUBLIC isc_uint32_t i; +#endif /* NOMINUM_PUBLIC */ in_port_t port; in_port_t tmpport; isc_boolean_t athead = ISC_TRUE; @@ -991,11 +1000,13 @@ dns_c_iplist_printfully(FILE *fp, int indent, isc_boolean_t porttoo, fprintf(fp, " port %d", isc_sockaddr_getport(&list->ips[i])); } +#ifndef NOMINUM_PUBLIC if (list->keys[i] != NULL) { fprintf(fp, " key \""); dns_name_print(list->keys[i], fp); fprintf(fp, "\" "); } +#endif /* NOMINUM_PUBLIC */ fprintf(fp, ";\n"); } dns_c_printtabs(fp, indent - 1); @@ -1010,9 +1021,15 @@ dns_c_iplist_print(FILE *fp, int indent, dns_c_iplist_t *list) { dns_c_iplist_printfully(fp, indent, ISC_FALSE, list); } +#ifndef NOMINUM_PUBLIC isc_result_t dns_c_iplist_append(dns_c_iplist_t *list, isc_sockaddr_t newaddr, - const char *key) { + const char *key) +{ +#else /* NOMINUM_PUBLIC */ +isc_result_t +dns_c_iplist_append(dns_c_iplist_t *list, isc_sockaddr_t newaddr) { +#endif /* NOMINUM_PUBLIC */ isc_uint32_t i; isc_result_t res; @@ -1030,7 +1047,9 @@ dns_c_iplist_append(dns_c_iplist_t *list, isc_sockaddr_t newaddr, if (list->nextidx == list->size) { isc_sockaddr_t *newlist; +#ifndef NOMINUM_PUBLIC dns_name_t **newkeys; +#endif /* NOMINUM_PUBLIC */ size_t newbytes; size_t oldbytes = list->size * sizeof (list->ips[0]); size_t newsize = list->size + 10; @@ -1047,6 +1066,7 @@ dns_c_iplist_append(dns_c_iplist_t *list, isc_sockaddr_t newaddr, isc_mem_put(list->mem, list->ips, oldbytes); list->ips = newlist; +#ifndef NOMINUM_PUBLIC oldbytes = list->size * sizeof(list->keys[0]); newbytes = sizeof (list->ips[0]) * newsize; newkeys = isc_mem_get(list->mem, newbytes); @@ -1059,6 +1079,7 @@ dns_c_iplist_append(dns_c_iplist_t *list, isc_sockaddr_t newaddr, list->keys[i] = NULL; isc_mem_put(list->mem, list->keys, oldbytes); list->keys = newkeys; +#endif /* NOMINUM_PUBLIC */ i = list->size; list->size = newsize; @@ -1070,6 +1091,7 @@ dns_c_iplist_append(dns_c_iplist_t *list, isc_sockaddr_t newaddr, res = ISC_R_SUCCESS; +#ifndef NOMINUM_PUBLIC if (key != NULL) { if (list->keys[i] != NULL) { dns_name_free(list->keys[i], list->mem); @@ -1080,6 +1102,7 @@ dns_c_iplist_append(dns_c_iplist_t *list, isc_sockaddr_t newaddr, res = dns_c_charptoname(list->mem, key, &list->keys[i]); } +#endif /* NOMINUM_PUBLIC */ return (res); } @@ -1104,11 +1127,13 @@ dns_c_iplist_remove(dns_c_iplist_t *list, isc_sockaddr_t newaddr) { list->nextidx--; +#ifndef NOMINUM_PUBLIC if (list->keys[i] != NULL) { dns_name_reset(list->keys[i]); isc_mem_put(list->mem, list->keys[i], sizeof (dns_name_t)); } - +#endif /* NOMINUM_PUBLIC */ + for ( /* nothing */ ; i < list->nextidx ; i++) { list->ips[i] = list->ips[i + 1]; list->keys[i] = list->keys[i + 1]; diff --git a/lib/dns/config/confparser.y b/lib/dns/config/confparser.y index 6b75756975..c3811cda87 100644 --- a/lib/dns/config/confparser.y +++ b/lib/dns/config/confparser.y @@ -16,7 +16,7 @@ * SOFTWARE. */ -/* $Id: confparser.y,v 1.106 2000/07/25 17:55:39 brister Exp $ */ +/* $Id: confparser.y,v 1.107 2000/07/26 18:47:38 mws Exp $ */ #include @@ -1817,7 +1817,7 @@ ip_and_port_list: ip_and_port_element maybe_key L_EOS if ($3 != NULL) { isc_mem_free(memctx, $3); } - + $$ = $1; } ; diff --git a/lib/dns/config/confparser.y.dirty b/lib/dns/config/confparser.y.dirty new file mode 100644 index 0000000000..7698cdcba4 --- /dev/null +++ b/lib/dns/config/confparser.y.dirty @@ -0,0 +1,6161 @@ +%{ +/* + * Copyright (C) 1996-2000 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* $Id: confparser.y.dirty,v 1.1 2000/07/26 18:47:40 mws Exp $ */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Type keys for symtab lookup */ +#define KEYWORD_SYM_TYPE 0x1 +#define CLASS_SYM_TYPE 0x2 +#define ACL_SYM_TYPE 0x3 + + +/* used for holding a list of dns_rdatatype_t on the stack */ +struct confrdtype_s { + dns_rdatatype_t *types; + isc_uint32_t idx; +}; + +/* used for holding ssu data on the stack */ +struct confssu_s { + isc_boolean_t grant; + dns_name_t *ident; + unsigned int matchtype; + dns_name_t *name; + struct confrdtype_s rdatatypes; +}; + +struct keydetails_s { + char *algorithm; + char *secret; +}; + + +static isc_mutex_t yacc_mutex; + +/* All these statics are protected by the above yacc_mutex */ +static dns_c_ctx_t *currcfg; +static isc_mem_t *memctx; /* used for internal allocations */ +static isc_lex_t *mylexer; +static isc_symtab_t *keywords; +static dns_c_cbks_t *callbacks; +static isc_lexspecials_t specials; + + +/* + * XXXJAB The #define for the default OMAPI port is not available + * to us, so we make our own. + */ + +#define OMAPI_DEFAULT_PORT 953 + +#define CONF_MAX_IDENT 1024 + +/* This should be sufficient to permit multiple parsers and lexers if needed */ +#define yyparse dns__yyparse + +#define YYDEBUG 1 + +/* + * Specify a small parser stack size. This is needed when + * using bison the generate the parser, because it puts + * the parser stack in a local variable, and the default + * initial stack size of 200 is big enough to cause a + * thread stack overflow. Berkeley yacc does not suffer + * from this problem as it allocates the parser stack + * using malloc. + */ + +#define YYMAXDEPTH 200 +#define YYINITDEPTH 200 + + +static isc_result_t tmpres; +static in_port_t default_port; + +int yyparse(void); +static int yylex(void); +static void parser_error(isc_boolean_t lasttoken, + const char *fmt, ...); +static void parser_warning(isc_boolean_t lasttoken, + const char *fmt, ...); +static void parser_complain(isc_boolean_t is_warning, + isc_boolean_t last_token, + const char *format, va_list args); +static isc_result_t unit_to_uint32(char *in, isc_uint32_t *out); +static const char * token_to_keyword(int token); +static void yyerror(const char *); +static dns_peerlist_t *currentpeerlist(dns_c_ctx_t *cfg, + isc_boolean_t createIfNeeded); +static isc_boolean_t keydefinedinscope(dns_c_ctx_t *cfg, + const char *name); + + + +/* returns true if (base * mult) would be too big.*/ +static isc_boolean_t int_too_big(isc_uint32_t base, isc_uint32_t mult); + +/* + * #define global symbols that various versions of YACC export into our + * namespace. This won't work for all versions, but we hope to cover + * the popular ones. + */ + +/* + * All YACCs + */ +#define yychar dns__yychar +#define yydebug dns__yydebug +#define yylval dns__yylval +#define yynerrs dns__yynerrs +/* + * BYACC + */ +#define yyerrflag dns__yyerrflag +#define yyss dns__yyss +#define yyssp dns__yyssp +#define yyval dns__yyval +#define yyvs dns__yyvs +#define yyvsp dns__yyvsp +/* + * AIX + */ +#define yyps dns__yyps +#define yypv dns__yypv +#define yypvt dns__yypvt +#define yys dns__yys +#define yystate dns__yystate +#define yytmp dns__yytmp +#define yyv dns__yyv +#define yyval dns__yyval +#define yyact dns__yyact +#define yychk dns__yychk +#define yydef dns__yydef +#define yyexca dns__yyexca +#define yypact dns__yypact +#define yypgo dns__yypgo +#define yyr1 dns__yyr1 +#define yyr2 dns__yyr2 +#define yyreds dns__yyreds +#define yytoks dns__yytoks + +%} + +%union { + char *text; + int number; + isc_int32_t l_int; + isc_uint32_t ul_int; + isc_uint16_t port_int; + dns_c_zonetype_t ztype; + struct in_addr ip4_addr; + struct in6_addr ip6_addr; + isc_sockaddr_t ipaddress; + + struct keydetails_s keydetails; + struct confssu_s ssu; + struct confrdtype_s rdatatypelist; + dns_rdatatype_t rdatatype; + dns_c_addata_t addata; + + isc_boolean_t boolean; + dns_rdataclass_t rrclass; + dns_severity_t severity; + dns_c_trans_t transport; + dns_transfer_format_t tformat; + dns_notifytype_t notifytype; + + dns_c_ipmatchelement_t *ime; + dns_c_ipmatchlist_t *iml; + + dns_c_forw_t forward; + dns_c_rrso_t *rrorder; + dns_c_rrsolist_t *rrolist; + dns_rdatatype_t ordertype; + dns_rdataclass_t orderclass; + dns_c_ordering_t ordering; + dns_c_iplist_t *iplist; + dns_c_kidlist_t *kidlist; +} + +/* Misc */ +%token L_STRING +%token L_QSTRING +%token L_INTEGER +%token L_IP4ADDR +%token L_IP6ADDR + +%token L_ACL +%token L_ADDITIONAL_DATA +%token L_ADDRESS +%token L_ALGID +%token L_ALLOW +%token L_ALLOW_QUERY +%token L_ALLOW_RECURSION +%token L_ALLOW_TRANSFER +%token L_ALLOW_UPDATE +%token L_ALLOW_UPDATE_FORWARDING +%token L_ALSO_NOTIFY +%token L_AUTH_NXDOMAIN +%token L_BANG +%token L_BLACKHOLE +%token L_BOGUS +%token L_MAX_CACHE_SIZE +%token L_CATEGORY +%token L_CHANNEL +%token L_CHECK_NAMES +%token L_CLASS +%token L_CLEAN_INTERVAL +%token L_CONTROLS +%token L_CORESIZE +%token L_DATASIZE +%token L_DATABASE +%token L_DEALLOC_ON_EXIT +%token L_DEBUG +%token L_DEFAULT +%token L_DENY +%token L_DIALUP +%token L_DIRECTORY +%token L_DUMP_FILE +%token L_DYNAMIC +%token L_ENABLE_ZONE +%token L_END_INCLUDE +%token L_EOS +%token L_EXPERT_MODE +%token L_FAIL +%token L_FAKE_IQUERY +%token L_FALSE +%token L_FETCH_GLUE +%token L_FILE +%token L_FILES +%token L_FILE_IXFR +%token L_FIRST +%token L_FORWARD +%token L_FORWARDERS +%token L_GLUE_FROM_AUTH +%token L_GLUE_FROM_CACHE +%token L_GRANT +%token L_GROUP +%token L_HAS_OLD_CLIENTS +%token L_HEARTBEAT +%token L_HINT +%token L_HOSTSTATS +%token L_IF_NO_ANSWER +%token L_IF_NO_DOMAIN +%token L_IGNORE +%token L_INCLUDE +%token L_INET +%token L_INTERFACE_INTERVAL +%token L_INTERNAL +%token L_IXFR_TMP +%token L_KEYS +%token L_LAME_TTL +%token L_LBRACE +%token L_LISTEN_ON +%token L_LISTEN_ON_V6 +%token L_LOGGING +%token L_MAINTAIN_IXFR_BASE +%token L_MANY_ANSWERS +%token L_MASTER +%token L_MASTERS +%token L_MATCH_CLIENTS +%token L_MAX_LOG_SIZE_IXFR +%token L_MAX_CACHE_TTL +%token L_MAX_NCACHE_TTL +%token L_MAX_TRANSFER_IDLE_IN +%token L_MAX_TRANSFER_IDLE_OUT +%token L_MAX_TRANSFER_TIME_IN +%token L_MAX_TRANSFER_TIME_OUT +%token L_MAXIMAL +%token L_MEMSTATS_FILE +%token L_MIN_ROOTS +%token L_MINIMAL +%token L_MULTIPLE_CNAMES +%token L_NAME +%token L_NAMED_XFER +%token L_NO +%token L_NOTIFY +%token L_NULL_OUTPUT +%token L_ONE_ANSWER +%token L_ONLY +%token L_OPTIONS +%token L_ORDER +%token L_OWNER +%token L_RANDOM_DEVICE +%token L_RANDOM_SEED_FILE +%token L_PERM +%token L_PIDFILE +%token L_PORT +%token L_PRINT_CATEGORY +%token L_PRINT_SEVERITY +%token L_PRINT_TIME +%token L_PROVIDE_IXFR +%token L_PUBKEY +%token L_QUERY_SOURCE +%token L_QUERY_SOURCE_V6 +%token L_RBRACE +%token L_RECURSION +%token L_RECURSIVE_CLIENTS +%token L_REQUEST_IXFR +%token L_RESPONSE +%token L_RFC2308_TYPE1 +%token L_RRSET_ORDER +%token L_SECRET +%token L_SEC_KEY +%token L_SELF +%token L_SERIAL_QUERIES +%token L_SERVER +%token L_SEVERITY +%token L_SIG_VALIDITY_INTERVAL +%token L_SIZE +%token L_SLASH +%token L_SLAVE +%token L_SORTLIST +%token L_STACKSIZE +%token L_STATS_FILE +%token L_STATS_INTERVAL +%token L_STDERR +%token L_STUB +%token L_SUBDOMAIN +%token L_SUPPORT_IXFR +%token L_SYSLOG +%token L_TCP_CLIENTS +%token L_TKEY_DHKEY +%token L_TKEY_DOMAIN +%token L_TOPOLOGY +%token L_TRANSFERS +%token L_TRANSFERS_IN +%token L_TRANSFERS_OUT +%token L_TRANSFERS_PER_NS +%token L_TRANSFER_FORMAT +%token L_TRANSFER_SOURCE +%token L_TRANSFER_SOURCE_V6 +%token L_TREAT_CR_AS_SPACE +%token L_TRUE +%token L_TRUSTED_KEYS +%token L_TYPE +%token L_UNIX +%token L_UNLIMITED +%token L_UPDATE_POLICY +%token L_USE_ID_POOL +%token L_USE_IXFR +%token L_VERSION +%token L_VERSIONS +%token L_VIEW +%token L_WARN +%token L_WILDCARD +%token L_YES +%token L_ZONE +%token L_EXPLICIT + + +%type additional_data +%type grantp +%type yea_or_nay +%type notify_setting +%type forward_opt +%type zone_forward_opt +%type address_match_element +%type address_match_simple +%type address_name +%type address_match_list +%type in_addr_elem +%type ip4_address +%type ip6_address +%type ip_address +%type maybe_wild_addr +%type maybe_wild_ip4_only_addr +%type maybe_wild_ip6_only_addr +%type query_source_v4 +%type query_source_v6 +%type ip_and_port_element +%type in_addr_list +%type opt_in_addr_list +%type opt_zone_forwarders_list +%type port_ip_list +%type ip_and_port_list +%type facility_name +%type maybe_syslog_facility +%type ordering_class +%type ordering_type +%type in_port +%type maybe_port +%type maybe_wild_port +%type maybe_zero_port +%type control_port +%type rdatatype +%type rdatatype_list +%type class_name +%type wild_class_name +%type optional_class +%type check_names_opt +%type key_definition +%type grant_stmt +%type algorithm_id +%type any_string +%type category_name +%type channel_name +%type domain_name +%type key_value +#ifndef NOMINUM_PUBLIC +%type maybe_key +#endif /* NOMINUM_PUBLIC */ +%type control_keys +%type keyid_list +%type ordering_name +%type secret +%type transfer_format +%type check_names_type; +%type grant_match_type +%type size_spec +%type zone_type + +/* Miscellaneous items (used in several places): */ + +%% + +config_file: /* nothing */ + | statement_list + ; + +statement_list: statement + | statement_list statement + ; + +statement: include_stmt + | options_stmt L_EOS + | controls_stmt L_EOS + | logging_stmt L_EOS + | server_stmt L_EOS + | zone_stmt L_EOS + | trusted_keys_stmt L_EOS + | acl_stmt L_EOS + | key_stmt L_EOS + | view_stmt L_EOS + | L_END_INCLUDE + ; + +/* + * Note that we must consume the semicolon ending the + * include statement before switching input streams. + */ +include_stmt: L_INCLUDE L_QSTRING L_EOS + { + tmpres = isc_lex_openfile(mylexer, $2); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "can't open file %s: %s", + $2, isc_result_totext(tmpres)); + YYABORT; + } + + isc_mem_free(memctx, $2); + } + ; + +options_stmt: L_OPTIONS + { + dns_c_options_t *options; + + if (currcfg->zlist != NULL || currcfg->views != NULL) { + parser_error(ISC_FALSE, + "options must come before all " + "zones and views"); + YYABORT; + } + + tmpres = dns_c_ctx_getoptions(currcfg, &options); + if (tmpres == ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "cannot redefine options"); + + /* + * Clean out options so rest of config won't fail + * or issue extra error messages + */ + dns_c_ctx_optionsdelete(&currcfg->options); + } + + tmpres = dns_c_ctx_optionsnew(currcfg->mem, &currcfg->options); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to create options structure: %s", + isc_result_totext(tmpres)); + YYABORT; + } + + } L_LBRACE options L_RBRACE { + if (callbacks != NULL && callbacks->optscbk != NULL) { + tmpres = callbacks->optscbk(currcfg, + callbacks->optscbkuap); + if (tmpres != ISC_R_SUCCESS) { + isc_log_write(dns_lctx, + DNS_LOGCATEGORY_CONFIG, + DNS_LOGMODULE_CONFIG, + ISC_LOG_ERROR, + "options configuration " + "failed: %s", + isc_result_totext(tmpres)); + YYABORT; + } + } + } + ; + + +options_list: option L_EOS + | options_list option L_EOS + ; + +options: /* nothin */ + | options_list + ; + + +option: /* Empty */ + | L_VERSION L_QSTRING + { + tmpres = dns_c_ctx_setversion(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine version"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "set version error %s: %s", + isc_result_totext(tmpres), $2); + YYABORT; + } + + isc_mem_free(memctx, $2); + } + | L_DIRECTORY L_QSTRING + { + tmpres = dns_c_ctx_setdirectory(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine directory"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "error setting directory: %s: %s", + isc_result_totext(tmpres), $2); + YYABORT; + } + + isc_mem_free(memctx, $2); + } + | L_NAMED_XFER L_QSTRING + { + tmpres = dns_c_ctx_setnamedxfer(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine named-xfer"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "set named-xfer error: %s: %s", + isc_result_totext(tmpres), $2); + YYABORT; + } + + isc_mem_free(memctx, $2); + } + | L_RANDOM_DEVICE L_QSTRING + { + tmpres = dns_c_ctx_setrandomdevice(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine random-device"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "error setting random-device: %s: %s", + isc_result_totext(tmpres), $2); + YYABORT; + } + + isc_mem_free(memctx, $2); + } + | L_RANDOM_SEED_FILE L_QSTRING + { + tmpres = dns_c_ctx_setrandomseedfile(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine random-seed-file"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "error setting random-seed-file: %s: %s", + isc_result_totext(tmpres), $2); + YYABORT; + } + + isc_mem_free(memctx, $2); + } + | L_TKEY_DOMAIN L_QSTRING + { + tmpres = dns_c_ctx_settkeydomain(currcfg, $2); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine tkey-domain"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "set tkey-domain error: %s: %s", + isc_result_totext(tmpres), $2); + YYABORT; + } + + isc_mem_free(memctx, $2); + } + | L_TKEY_DHKEY L_QSTRING L_INTEGER + { + tmpres = dns_c_ctx_settkeydhkey(currcfg, $2, $3); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine tkey-dhkey"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "set tkey-dhkey error: %s: %s", + isc_result_totext(tmpres), $2); + YYABORT; + } + + isc_mem_free(memctx, $2); + } + | L_PIDFILE L_QSTRING + { + tmpres = dns_c_ctx_setpidfilename(currcfg, $2); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine pid-file"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "set pidfile error %s: %s", + isc_result_totext(tmpres), $2); + YYABORT; + } + + isc_mem_free(memctx, $2); + } + | L_STATS_FILE L_QSTRING + { + tmpres = dns_c_ctx_setstatsfilename(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine statistics-file"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "set statsfile error %s: %s", + isc_result_totext(tmpres), $2); + YYABORT; + } + + isc_mem_free(memctx, $2); + } + | L_MEMSTATS_FILE L_QSTRING + { + tmpres = dns_c_ctx_setmemstatsfilename(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine memstatistics-file"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "set memstatsfile error %s: %s", + isc_result_totext(tmpres), $2); + YYABORT; + } + + isc_mem_free(memctx, $2); + } + | L_DUMP_FILE L_QSTRING + { + tmpres = dns_c_ctx_setdumpfilename(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine dump-file"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "set dumpfile error %s: %s", + isc_result_totext(tmpres), $2); + YYABORT; + } + + isc_mem_free(memctx, $2); + } + | L_EXPERT_MODE yea_or_nay + { + tmpres = dns_c_ctx_setexpertmode(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine expert-mode"); + YYABORT; + } + } + | L_FAKE_IQUERY yea_or_nay + { + tmpres = dns_c_ctx_setfakeiquery(currcfg, ISC_FALSE); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine fake-iquery"); + YYABORT; + } + } + | L_RECURSION yea_or_nay + { + tmpres = dns_c_ctx_setrecursion(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine recursion"); + YYABORT; + } + } + | L_FETCH_GLUE yea_or_nay + { + tmpres = dns_c_ctx_setfetchglue(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine fetch-glue"); + YYABORT; + } + } + | L_NOTIFY notify_setting + { + tmpres = dns_c_ctx_setnotify(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine notify"); + YYABORT; + } + } + | L_HOSTSTATS yea_or_nay + { + tmpres = dns_c_ctx_sethoststatistics(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine host-statistics"); + YYABORT; + } + } + | L_DEALLOC_ON_EXIT yea_or_nay + { + tmpres = dns_c_ctx_setdealloconexit(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine deallocate-on-exit"); + YYABORT; + } + } + | L_USE_IXFR yea_or_nay + { + tmpres = dns_c_ctx_setuseixfr(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine use-ixfr"); + YYABORT; + } + } + | L_MAINTAIN_IXFR_BASE yea_or_nay + { + /* + * Backwards compatibility, treated as + * equivalent to provide-ixfr. + */ + tmpres = dns_c_ctx_setprovideixfr(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine provide-ixfr"); + YYABORT; + } + } + | L_HAS_OLD_CLIENTS yea_or_nay + { + tmpres = dns_c_ctx_sethasoldclients(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine has-old-clients"); + YYABORT; + } + } + | L_AUTH_NXDOMAIN yea_or_nay + { + tmpres = dns_c_ctx_setauthnxdomain(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine auth-nxdomain"); + YYABORT; + } + } + | L_MULTIPLE_CNAMES yea_or_nay + { + tmpres = dns_c_ctx_setmultiplecnames(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine multiple-cnames"); + YYABORT; + } + } + | L_CHECK_NAMES check_names_type check_names_opt + { + tmpres = dns_c_ctx_setchecknames(currcfg, $2, $3); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine check-names"); + YYABORT; + } + } + | L_USE_ID_POOL yea_or_nay + { + tmpres = dns_c_ctx_setuseidpool(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine use-id-pool"); + YYABORT; + } + } + | L_RFC2308_TYPE1 yea_or_nay + { + tmpres = dns_c_ctx_setrfc2308type1(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine rfc2308-type"); + YYABORT; + } + } + | L_PROVIDE_IXFR yea_or_nay + { + tmpres = dns_c_ctx_setprovideixfr(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine provide-ixfr"); + YYABORT; + } + } + | L_REQUEST_IXFR yea_or_nay + { + tmpres = dns_c_ctx_setrequestixfr(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine request-ixfr"); + YYABORT; + } + } + | L_TREAT_CR_AS_SPACE yea_or_nay + { + tmpres = dns_c_ctx_settreatcrasspace(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine treat-cr-as-space"); + YYABORT; + } + } + | L_GLUE_FROM_CACHE yea_or_nay + { + tmpres = dns_c_ctx_setgluefromcache(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine glue-from-cache"); + YYABORT; + } + } + | L_GLUE_FROM_AUTH yea_or_nay + { + tmpres = dns_c_ctx_setgluefromauth(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine glue-from-auth"); + YYABORT; + } + } + | L_LISTEN_ON maybe_port L_LBRACE address_match_list L_RBRACE + { + if ($4 == NULL) { + parser_warning(ISC_FALSE, + "address-match-list empty implies" + "listen statement ignored"); + } else { + tmpres = dns_c_ctx_addlisten_on(currcfg, $2, $4, + ISC_FALSE); + + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to add listen statement"); + YYABORT; + } + } + } + | L_LISTEN_ON_V6 maybe_port L_LBRACE address_match_list L_RBRACE + { + if ($4 == NULL) { + parser_warning(ISC_FALSE, + "address-match-list empty implies" + "listen statement ignored"); + } else { + tmpres = dns_c_ctx_addv6listen_on(currcfg, $2, $4, + ISC_FALSE); + + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to add " + "v6listen statement"); + YYABORT; + } + } + } + | L_FORWARD forward_opt + { + tmpres = dns_c_ctx_setforward(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine forward"); + YYABORT; + } + } + | L_FORWARDERS { + dns_c_iplist_t *forwarders; + + tmpres = dns_c_ctx_getforwarders(currcfg, &forwarders); + if (tmpres != ISC_R_NOTFOUND) { + parser_warning(ISC_FALSE, + "cannot redefine options forwarders"); + dns_c_iplist_detach(&forwarders); + } + + tmpres = dns_c_iplist_new(currcfg->mem, 5, &forwarders); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to create forwarders list"); + YYABORT; + } + + tmpres = dns_c_ctx_setforwarders(currcfg, ISC_FALSE, + forwarders); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set forwarders list"); + YYABORT; + } + } L_LBRACE opt_forwarders_list L_RBRACE + | L_QUERY_SOURCE query_source_v4 + { + tmpres = dns_c_ctx_setquerysource(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine query-source"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set query-source"); + YYABORT; + } + } + | L_QUERY_SOURCE_V6 query_source_v6 + { + tmpres = dns_c_ctx_setquerysourcev6(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine query-source-v6"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set query-source-v6"); + YYABORT; + } + } + | L_TRANSFER_SOURCE maybe_wild_ip4_only_addr + { + tmpres = dns_c_ctx_settransfersource(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine transfer-source"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set transfer-source"); + YYABORT; + } + } + | L_TRANSFER_SOURCE_V6 maybe_wild_ip6_only_addr + { + tmpres = dns_c_ctx_settransfersourcev6(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine transfer-source-v6"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set transfer-source-v6"); + YYABORT; + } + } + | L_ALLOW_QUERY L_LBRACE address_match_list L_RBRACE + { + if ($3 == NULL) + YYABORT; + + tmpres = dns_c_ctx_setallowquery(currcfg, $3); + dns_c_ipmatchlist_detach(&$3); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine allow-query list"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "failed to set allow-query"); + YYABORT; + } + } + | L_ALLOW_TRANSFER L_LBRACE address_match_list L_RBRACE + { + tmpres = dns_c_ctx_setallowtransfer(currcfg, $3); + dns_c_ipmatchlist_detach(&$3); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine allow-transfer list"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set allow-transfer"); + YYABORT; + } + } + | L_ALLOW_RECURSION L_LBRACE address_match_list L_RBRACE + { + tmpres = dns_c_ctx_setallowrecursion(currcfg, $3); + dns_c_ipmatchlist_detach(&$3); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine allow-recursion list"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set allow-recursion"); + YYABORT; + } + } + | L_SORTLIST L_LBRACE address_match_list L_RBRACE + { + tmpres = dns_c_ctx_setsortlist(currcfg, $3); + dns_c_ipmatchlist_detach(&$3); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine sortlist"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "failed to set sortlist"); + YYABORT; + } + } + | L_ALSO_NOTIFY port_ip_list + { + tmpres = dns_c_ctx_setalsonotify(currcfg, $2); + dns_c_iplist_detach(&$2); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine also-notify"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "failed to set also-notify"); + YYABORT; + } + } + | L_BLACKHOLE L_LBRACE address_match_list L_RBRACE + { + tmpres = dns_c_ctx_setblackhole(currcfg, $3); + dns_c_ipmatchlist_detach(&$3); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine blackhole"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "failed to set blackhole"); + YYABORT; + } + } + | L_TOPOLOGY L_LBRACE address_match_list L_RBRACE + { + tmpres = dns_c_ctx_settopology(currcfg, $3); + dns_c_ipmatchlist_detach(&$3); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine topology"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "failed to set topology"); + YYABORT; + } + } + | size_clause + | transfer_clause + | L_TRANSFER_FORMAT transfer_format + { + tmpres = dns_c_ctx_settransferformat(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine transfer-format"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set transfer-format"); + YYABORT; + } + } + | L_MAX_TRANSFER_TIME_IN L_INTEGER + { + if ( int_too_big($2, 60) ) { + parser_error(ISC_FALSE, + "integer value too big: %u", $2); + YYABORT; + } + + tmpres = dns_c_ctx_setmaxtransfertimein(currcfg, $2 * 60); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine max-transfer-time-in"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set max-transfer-time-in"); + YYABORT; + } + } + | L_PORT in_port + { + tmpres = dns_c_ctx_setport(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine port"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set port"); + YYABORT; + } + default_port = $2; + } + | L_MAX_TRANSFER_TIME_OUT L_INTEGER + { + if ( int_too_big($2, 60) ) { + parser_error(ISC_FALSE, + "integer value too big: %u", $2); + YYABORT; + } + + tmpres = dns_c_ctx_setmaxtransfertimeout(currcfg, $2 * 60); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine max-transfer-time-out"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set max-transfer-time-out"); + YYABORT; + } + } + | L_MAX_TRANSFER_IDLE_IN L_INTEGER + { + if ( int_too_big($2, 60) ) { + parser_error(ISC_FALSE, + "integer value too big: %u", $2); + YYABORT; + } + + tmpres = dns_c_ctx_setmaxtransferidlein(currcfg, $2 * 60); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine max-transfer-idle-in"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set max-transfer-idle-in"); + YYABORT; + } + } + | L_MAX_TRANSFER_IDLE_OUT L_INTEGER + { + if ( int_too_big($2, 60) ) { + parser_error(ISC_FALSE, + "integer value too big: %u", $2); + YYABORT; + } + + tmpres = dns_c_ctx_setmaxtransferidleout(currcfg, $2 * 60); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine max-transfer-idle-out"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set max-transfer-idle-out"); + YYABORT; + } + } + | L_TCP_CLIENTS L_INTEGER + { + tmpres = dns_c_ctx_settcpclients(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine tcp-clients"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set tcp-clients"); + YYABORT; + } + } + | L_SIG_VALIDITY_INTERVAL L_INTEGER + { + tmpres = dns_c_ctx_setsigvalidityinterval(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine sig-validity-interval"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set sig-validity-interval"); + YYABORT; + } + } + | L_LAME_TTL L_INTEGER + { + tmpres = dns_c_ctx_setlamettl(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine lame-ttl"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "failed to set lame-ttl"); + YYABORT; + } + } + | L_RECURSIVE_CLIENTS L_INTEGER + { + tmpres = dns_c_ctx_setrecursiveclients(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine recursive-clients"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set recursive-clients"); + YYABORT; + } + } + | L_MIN_ROOTS L_INTEGER + { + tmpres = dns_c_ctx_setminroots(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine min-roots"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set min-roots"); + YYABORT; + } + } + | L_SERIAL_QUERIES L_INTEGER + { + tmpres = dns_c_ctx_setserialqueries(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine serial-queries"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set serial-queries"); + YYABORT; + } + } + | L_CLEAN_INTERVAL L_INTEGER + { + if ( int_too_big($2, 60) ) { + parser_error(ISC_FALSE, + "integer value too big: %u", $2); + YYABORT; + } + + tmpres = dns_c_ctx_setcleaninterval(currcfg, $2 * 60); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine cleaning-interval"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set cleaning-interval"); + YYABORT; + } + } + | L_INTERFACE_INTERVAL L_INTEGER + { + if ( int_too_big($2, 60) ) { + parser_error(ISC_FALSE, + "integer value too big: %u", $2); + YYABORT; + } + + tmpres = dns_c_ctx_setinterfaceinterval(currcfg, $2 * 60); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine interface-interval"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set interface-interval"); + YYABORT; + } + } + | L_STATS_INTERVAL L_INTEGER + { + if ( int_too_big($2, 60) ) { + parser_error(ISC_FALSE, + "integer value too big: %u", $2); + YYABORT; + } + + tmpres = dns_c_ctx_setstatsinterval(currcfg, $2 * 60); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine statistics-interval"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set statistics-interval"); + YYABORT; + } + } + | L_MAX_LOG_SIZE_IXFR L_INTEGER + { + tmpres = dns_c_ctx_setmaxlogsizeixfr(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine max-ixfr-log-size"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set max-ixfr-log-size"); + YYABORT; + } + } + | L_MAX_NCACHE_TTL L_INTEGER + { + tmpres = dns_c_ctx_setmaxncachettl(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine max-ncache-ttl"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set max-ncache-ttl"); + YYABORT; + } + } + | L_MAX_CACHE_TTL L_INTEGER + { + tmpres = dns_c_ctx_setmaxcachettl(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine max-cache-ttl"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set max-cache-ttl"); + YYABORT; + } + } + | L_HEARTBEAT L_INTEGER + { + if ( int_too_big($2, 60) ) { + parser_error(ISC_FALSE, + "integer value too big: %u", $2); + YYABORT; + } + + tmpres = dns_c_ctx_setheartbeatinterval(currcfg, $2 * 60); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine heartbeat-interval"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set heartbeat-interval"); + YYABORT; + } + } + | L_DIALUP yea_or_nay + { + tmpres = dns_c_ctx_setdialup(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine dialup"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "failed to set dialup"); + YYABORT; + } + } + | L_RRSET_ORDER + { + dns_c_rrsolist_t *ordering; + + tmpres = dns_c_ctx_getrrsetorderlist(currcfg, &ordering); + if (tmpres != ISC_R_NOTFOUND) { + parser_warning(ISC_FALSE, + "cannot redefine rrset-order list"); + dns_c_rrsolist_clear(ordering); + } else { + tmpres = dns_c_rrsolist_new(currcfg->mem, &ordering); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to create rrset-order " + "list"); + YYABORT; + } + tmpres = dns_c_ctx_setrrsetorderlist(currcfg, + ISC_FALSE, + ordering); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set rrset-order"); + YYABORT; + } + } + } L_LBRACE rrset_ordering_list L_RBRACE + | L_ALLOW_UPDATE_FORWARDING L_LBRACE address_match_list L_RBRACE + { + tmpres = dns_c_ctx_setallowupdateforwarding(currcfg, $3); + dns_c_ipmatchlist_detach(&$3); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine " + "allow-update-forwarding"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set allow-update-forwarding"); + YYABORT; + } + } + | L_ADDITIONAL_DATA additional_data + { + tmpres = dns_c_ctx_setadditionaldata(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine additional-data"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set additional-data"); + YYABORT; + } + } + ; + + +/* + * Controls. + */ +controls_stmt: L_CONTROLS + { + if (currcfg->controls != NULL) { + parser_warning(ISC_FALSE, "cannot redefine controls"); + dns_c_ctrllist_delete(&currcfg->controls); + } + + tmpres = dns_c_ctrllist_new(currcfg->mem, + &currcfg->controls); + if (tmpres != ISC_R_SUCCESS) { + YYABORT; + } + } L_LBRACE controls L_RBRACE + ; + +controls: control L_EOS + | controls control L_EOS + ; + +control: /* Empty */ + | L_INET maybe_wild_addr control_port + L_ALLOW L_LBRACE address_match_list L_RBRACE control_keys + { + dns_c_ctrl_t *control; + + tmpres = dns_c_ctrlinet_new(currcfg->mem, &control, + $2, $3, $6, $8, ISC_FALSE); + + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to build inet control structure"); + YYABORT; + } + + ISC_LIST_APPEND(currcfg->controls->elements, control, next); + } + | L_UNIX L_QSTRING L_PERM L_INTEGER L_OWNER L_INTEGER L_GROUP L_INTEGER + { + dns_c_ctrl_t *control; + + tmpres = dns_c_ctrlunix_new(currcfg->mem, &control, + $2, $4, $6, $8); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to build unix control structure"); + YYABORT; + } + + ISC_LIST_APPEND(currcfg->controls->elements, control, next); + + isc_mem_free(memctx, $2); + } + ; + + +control_keys: /* nothing */ + { + $$ = NULL; + } + | L_KEYS L_LBRACE keyid_list L_RBRACE + { + $$ = $3; + }; + + + +control_port: /* nothing */ + { + $$ = OMAPI_DEFAULT_PORT; + } + | L_PORT in_port + { + $$ = $2; + }; + + +rrset_ordering_list: rrset_ordering_element L_EOS + | rrset_ordering_list rrset_ordering_element L_EOS + ; + +ordering_class: /* nothing */ + { + $$ = dns_rdataclass_any; + } + | L_CLASS wild_class_name + { + $$ = $2; + } + ; + +ordering_type: /* nothing */ + { + $$ = dns_rdatatype_any; + } + | L_TYPE any_string + { + isc_textregion_t reg; + dns_rdatatype_t ty; + + if (strcmp($2, "*") == 0) { + ty = dns_rdatatype_any; + } else { + reg.base = $2; + reg.length = strlen($2); + + tmpres = dns_rdatatype_fromtext(&ty, ®); + if (tmpres != ISC_R_SUCCESS) { + parser_warning(ISC_TRUE, + "unknown type, assuming '*'"); + ty = dns_rdatatype_any; + } + } + + isc_mem_free(memctx, $2); + $$ = ty; + } + ; + + +ordering_name: /* nothing */ + { + $$ = isc_mem_strdup(memctx, "*"); + } + | L_NAME domain_name + { + if (strcmp($2, ".") == 0 || strcmp($2, "*.") == 0) { + $$ = isc_mem_strdup(memctx, "*"); + isc_mem_free(memctx, $2); + } else { + $$ = $2; + } + } + + +rrset_ordering_element: ordering_class ordering_type ordering_name + L_ORDER L_STRING + { + dns_c_rrso_t *orderelem; + dns_c_ordering_t o; + + tmpres = dns_c_string2ordering($5, &o); + if (tmpres != ISC_R_SUCCESS) { + parser_warning(ISC_FALSE, + "unknown ordering type '%s'" + " using default", $5); + o = DNS_DEFAULT_ORDERING; + } + + tmpres = dns_c_rrso_new(currcfg->mem, + &orderelem, $1, $2, $3, o); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to create rrset-order element"); + YYABORT; + } + + ISC_LIST_APPEND(currcfg->options->ordering->elements, + orderelem, next); + + isc_mem_free(memctx, $5); + isc_mem_free(memctx, $3); + } + + +transfer_format: L_ONE_ANSWER + { + $$ = dns_one_answer; + } + | L_MANY_ANSWERS + { + $$ = dns_many_answers; + } + ; + +#ifndef NOMINUM_PUBLIC + +maybe_key: /* nothing */ + { + $$ = NULL; + } + | L_SEC_KEY any_string + { + $$ = $2; + }; +#endif /* NOMINUM_PUBLIC */ + +maybe_wild_addr: ip4_address + | ip6_address + | L_STRING + { + isc_sockaddr_any(&$$); + + if (strcmp($1, "*") != 0) + parser_error(ISC_TRUE, + "bad IP address, using IPv4 '*'"); + + isc_mem_free(memctx, $1); + } + ; + +maybe_wild_ip4_only_addr: ip4_address + { + $$ = $1; + } + | ip6_address + { + parser_error(ISC_FALSE, + "cannot have an IPv6 address in this context"); + YYABORT; + } + | L_STRING + { + isc_sockaddr_any(&$$); + + if (strcmp($1, "*") != 0) + parser_error(ISC_TRUE, + "bad IPv4 address, using '*'"); + + isc_mem_free(memctx, $1); + } + ; + +maybe_wild_ip6_only_addr: ip6_address + { + $$ = $1; + } + | ip4_address + { + parser_error(ISC_FALSE, + "cannot have an IPv4 address in this context"); + YYABORT; + } + | L_STRING + { + isc_sockaddr_any6(&$$); + + if (strcmp($1, "*") != 0) + parser_error(ISC_TRUE, + "bad IPv6 address, using '*'"); + + isc_mem_free(memctx, $1); + } + ; + +maybe_wild_port: in_port + { + $$ = $1; + } + | L_STRING + { + $$ = 0; + + if (strcmp ($1, "*") != 0) { + parser_error(ISC_TRUE, + "bad port specification using '*'"); + } + + isc_mem_free(memctx, $1); + } + ; + + +port_ip_list: maybe_zero_port L_LBRACE ip_and_port_list L_RBRACE + { + in_port_t port = $1; + dns_c_iplist_t *list = $3; + unsigned int i; + + if (port == 0) + port = default_port; + + for (i = 0 ; i < list->nextidx ; i++) { + if (isc_sockaddr_getport(&list->ips[i]) == 0) { + isc_sockaddr_setport(&list->ips[i], port); + } + } + + $$ = list; + }; + + +ip_and_port_element: ip_address maybe_zero_port + { + isc_sockaddr_setport(&$1, $2); + $$ = $1; + }; + + +#ifndef NOMINUM_PUBLIC +ip_and_port_list: ip_and_port_element maybe_key L_EOS +#else /* NOMINUM_PUBLIC */ +ip_and_port_list: ip_and_port_element L_EOS +#endif /* NOMINUM_PUBLIC */ + { + dns_c_iplist_t *list; + + tmpres = dns_c_iplist_new(currcfg->mem, 5, &list); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_TRUE, + "failed to create new iplist"); + YYABORT; + } + +#ifndef NOMINUM_PUBLIC + tmpres = dns_c_iplist_append(list, $1, $2); +#else /* NOMINUM_PUBLIC */ + tmpres = dns_c_iplist_append(list, $1); +#endif /* NOMINUM_PUBLIC */ + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_TRUE, + "failed to append master address"); + YYABORT; + } + +#ifndef NOMINUM_PUBLIC + if ($2 != NULL) { + isc_mem_free(memctx, $2); + } +#endif /* NOMINUM_PUBLIC */ + + $$ = list; + } +#ifndef NOMINUM_PUBLIC + | ip_and_port_list ip_and_port_element maybe_key L_EOS +#else /* NOMINUM_PUBLIC */ + | ip_and_port_list ip_and_port_element L_EOS +#endif /* NOMINUM_PUBLIC */ + { +#ifndef NOMINUM_PUBLIC + tmpres = dns_c_iplist_append($1, $2, $3); +#else /* NOMINUM_PUBLIC */ + tmpres = dns_c_iplist_append($1, $2); +#endif /* NOMINUM_PUBLIC */ + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_TRUE, + "failed to append master address"); + YYABORT; + } + +#ifndef NOMINUM_PUBLIC + if ($3 != NULL) { + isc_mem_free(memctx, $3); + } +#endif /* NOMINUM_PUBLIC */ + + $$ = $1; + } + ; + + + +query_source_v6: L_ADDRESS maybe_wild_ip6_only_addr + { + isc_sockaddr_setport(&$2, 0); /* '0' is wild port */ + $$ = $2; + } + | L_ADDRESS maybe_wild_ip6_only_addr L_PORT maybe_wild_port + { + isc_sockaddr_setport(&$2, $4); + $$ = $2; + } + | L_PORT maybe_wild_port + { + isc_sockaddr_t addr; + isc_sockaddr_fromin6(&addr, &in6addr_any, $2); + $$ = addr; + } + | L_PORT maybe_wild_port L_ADDRESS maybe_wild_ip6_only_addr + { + isc_sockaddr_setport(&$4, $2); + $$ = $4; + } + ; + +query_source_v4: L_ADDRESS maybe_wild_ip4_only_addr + { + isc_sockaddr_setport(&$2, 0); /* '0' is wild port */ + $$ = $2; + } + | L_ADDRESS maybe_wild_ip4_only_addr L_PORT maybe_wild_port + { + isc_sockaddr_setport(&$2, $4); + $$ = $2; + } + | L_PORT maybe_wild_port + { + struct in_addr any; + isc_sockaddr_t addr; + + memset(&any, 0x0, sizeof any); + any.s_addr = htonl(INADDR_ANY); + isc_sockaddr_fromin(&addr, &any, $2); + $$ = addr; + } + | L_PORT maybe_wild_port L_ADDRESS maybe_wild_ip4_only_addr + { + isc_sockaddr_setport(&$4, $2); + $$ = $4; + } + ; + +maybe_port: /* nothing */ + { + $$ = default_port; + } + | L_PORT in_port + { + $$ = $2; + } + ; + +maybe_zero_port : /* nothing */ + { + $$ = 0; + } + | L_PORT in_port + { + $$ = $2; + } + ; + +additional_data: L_INTERNAL + { + $$ = dns_c_ad_internal; + } + | L_MINIMAL + { + $$ = dns_c_ad_minimal; + } + | L_MAXIMAL + { + $$ = dns_c_ad_maximal; + }; + +yea_or_nay: L_YES + { + $$ = isc_boolean_true; + } + | L_TRUE + { + $$ = isc_boolean_true; + } + | L_NO + { + $$ = isc_boolean_false; + } + | L_FALSE + { + $$ = isc_boolean_false; + } + | L_INTEGER + { + if ($1 == 1) { + $$ = isc_boolean_true; + } else if ($1 == 0) { + $$ = isc_boolean_false; + } else { + parser_warning(ISC_TRUE, + "number should be 0 or 1, assuming 1"); + $$ = isc_boolean_true; + } + } + +notify_setting: yea_or_nay + { + if ($1) + $$ = dns_notifytype_yes; + else + $$ = dns_notifytype_no; + + } + | L_EXPLICIT + { + $$ = dns_notifytype_explicit; + } + ; + +check_names_type: L_MASTER + { + $$ = dns_trans_primary; + } + | L_SLAVE + { + $$ = dns_trans_secondary; + } + | L_RESPONSE + { + $$ = dns_trans_response; + } + ; + +check_names_opt: L_WARN + { + $$ = dns_severity_warn; + } + | L_FAIL + { + $$ = dns_severity_fail; + } + | L_IGNORE + { + $$ = dns_severity_ignore; + } + ; + +forward_opt: L_ONLY + { + $$ = dns_c_forw_only; + } + | L_FIRST + { + $$ = dns_c_forw_first; + } + | L_IF_NO_ANSWER + { + $$ = dns_c_forw_noanswer; + } + | L_IF_NO_DOMAIN + { + $$ = dns_c_forw_nodomain; + } + ; + + + +size_clause: L_DATASIZE size_spec + { + tmpres = dns_c_ctx_setdatasize(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine datasize"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "failed to set datasize"); + YYABORT; + } + } + | L_STACKSIZE size_spec + { + tmpres = dns_c_ctx_setstacksize(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine stacksize"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "failed to set stacksize"); + YYABORT; + } + } + | L_CORESIZE size_spec + { + tmpres = dns_c_ctx_setcoresize(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine coresize"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "failed to set coresize"); + YYABORT; + } + } + | L_FILES size_spec + { + tmpres = dns_c_ctx_setfiles(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine files"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "failed to set files"); + YYABORT; + } + } + | L_MAX_CACHE_SIZE size_spec + { + if ($2 == DNS_C_SIZE_SPEC_DEFAULT) { + parser_error(ISC_FALSE, + "cannot specific 'default' for " + "'max-cache-size'"); + YYABORT; + } + + tmpres = dns_c_ctx_setmaxcachesize(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine max-cache-size"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set max-cache-size"); + YYABORT; + } + } + ; + + +size_spec: any_string + { + isc_uint32_t result; + + tmpres = unit_to_uint32($1, &result); + if (tmpres == ISC_R_SUCCESS) { + $$ = result; + } else if (tmpres == ISC_R_RANGE) { + $$ = DNS_C_SIZE_SPEC_UNLIM; + parser_warning(ISC_FALSE, + "invalid value %s: using 'unlimited'", + $1); + } else if (tmpres == ISC_R_FAILURE) { + parser_warning(ISC_FALSE, + "invalid unit string '%s', Using " + "'default'", $1); + $$ = DNS_C_SIZE_SPEC_DEFAULT; + } else { + parser_warning(ISC_FALSE, + "unknown result: %s: using 'default'", + isc_result_totext(tmpres)); + $$ = DNS_C_SIZE_SPEC_DEFAULT; + } + + isc_mem_free(memctx, $1); + } + | L_INTEGER + { + $$ = (isc_uint32_t)$1; + if ($$ == DNS_C_SIZE_SPEC_DEFAULT) { + isc_uint32_t newi = DNS_C_SIZE_SPEC_DEFAULT - 1; + parser_warning(ISC_FALSE, + "value (%lu) too big, Reducing to %lu", + (unsigned long) $$, + (unsigned long) newi); + $$ = newi; + } + } + | L_DEFAULT + { + $$ = DNS_C_SIZE_SPEC_DEFAULT; + } + | L_UNLIMITED + { + $$ = DNS_C_SIZE_SPEC_UNLIM; + } + ; + + + +transfer_clause: L_TRANSFERS_IN L_INTEGER + { + tmpres = dns_c_ctx_settransfersin(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine transfers-in"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "failed to set transfers-in"); + YYABORT; + } + } + | L_TRANSFERS_OUT L_INTEGER + { + tmpres = dns_c_ctx_settransfersout(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine transfers-out"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set transfers-out"); + YYABORT; + } + } + | L_TRANSFERS_PER_NS L_INTEGER + { + tmpres = dns_c_ctx_settransfersperns(currcfg, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine transfers-per-ns"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set transfers-per-ns"); + YYABORT; + } + } + ; + + +opt_forwarders_list: /* nothing */ { + } + | forwarders_in_addr_list + ; + +forwarders_in_addr_list: forwarders_in_addr L_EOS + | forwarders_in_addr_list forwarders_in_addr L_EOS + ; + +forwarders_in_addr: ip_address + { +#ifndef NOMINUM_PUBLIC + tmpres = dns_c_iplist_append(currcfg->options->forwarders, + $1, NULL); +#else /* NOMINUM_PUBLIC */ + tmpres = dns_c_iplist_append(currcfg->options->forwarders, + $1); +#endif /* NOMINUM_PUBLIC */ + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to add forwarders " + "address element"); + YYABORT; + } + } + ; + + +/* + * Logging + */ + +logging_stmt: L_LOGGING + { + /* initialized in logging_init() */ + INSIST(currcfg->logging != NULL); + } + L_LBRACE logging_opts_list L_RBRACE + ; + +logging_opts_list: logging_opt L_EOS + | logging_opts_list logging_opt L_EOS + ; + +logging_opt: category_stmt + | channel_stmt + ; + + +channel_stmt: + L_CHANNEL channel_name L_LBRACE L_FILE L_QSTRING { + dns_c_logchan_t *newc; + + tmpres = dns_c_ctx_addfile_channel(currcfg, + $2, &newc); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "redefing channel %s", $2); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to add new file channel"); + YYABORT; + } + + INSIST(newc != NULL); + + tmpres = dns_c_logchan_setpath(newc, $5); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to add file channel's path"); + YYABORT; + } + + isc_mem_free(memctx, $2); + isc_mem_free(memctx, $5); + } maybe_file_modifiers L_EOS optional_channel_opt_list L_RBRACE + | L_CHANNEL channel_name L_LBRACE L_SYSLOG maybe_syslog_facility { + dns_c_logchan_t *newc; + + tmpres = dns_c_ctx_addsyslogchannel(currcfg, + $2, &newc); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine channel %s", $2); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to add new syslog channel"); + YYABORT; + } + + tmpres = dns_c_logchan_setfacility(newc, $5); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "can't get set channel facility"); + YYABORT; + } + isc_mem_free(memctx, $2); + } L_EOS optional_channel_opt_list L_RBRACE + | L_CHANNEL channel_name L_LBRACE L_NULL_OUTPUT { + dns_c_logchan_t *newc; + + tmpres = dns_c_ctx_addnullchannel(currcfg, + $2, &newc); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine channel %s", $2); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to add new channel '%s'", $2); + YYABORT; + } + + isc_mem_free(memctx, $2); + } L_EOS optional_channel_opt_list L_RBRACE + | L_CHANNEL channel_name L_LBRACE L_STDERR { + dns_c_logchan_t *newc; + + tmpres = dns_c_ctx_addstderrchannel(currcfg, + $2, &newc); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine channel %s", $2); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to add new channel '%s'", $2); + YYABORT; + } + + isc_mem_free(memctx, $2); + } L_EOS optional_channel_opt_list L_RBRACE + | L_CHANNEL channel_name L_LBRACE logging_non_type_keywords { + parser_error(ISC_FALSE, + "first statment inside a channel definition " + "must be 'file' or 'syslog' or 'null'"); + YYABORT; + } + ; + + +logging_non_type_keywords: L_SEVERITY | L_PRINT_TIME | L_PRINT_CATEGORY | + L_PRINT_SEVERITY + ; + + +optional_channel_opt_list: /* empty */ + | channel_opt_list + ; + +category_stmt: L_CATEGORY category_name { + dns_c_logcat_t *cat; + + tmpres = dns_c_ctx_addcategory(currcfg, $2, &cat); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine category '%s'", $2); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to add new logging category"); + isc_mem_free(memctx, $2); + YYABORT; + } + isc_mem_free(memctx, $2); + } L_LBRACE channel_list L_RBRACE + ; + + +channel_severity: any_string + { + dns_c_logseverity_t severity; + dns_c_logchan_t *chan; + + tmpres = dns_c_string2logseverity($1, &severity); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "unknown severity '%s'", $1); + YYABORT; + } + + tmpres = dns_c_ctx_currchannel(currcfg, &chan); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "can't get current channel"); + YYABORT; + } + + tmpres = dns_c_logchan_setseverity(chan, severity); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine severity"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "can't get set channel severity"); + YYABORT; + } + + isc_mem_free(memctx, $1); + } + | L_DEBUG + { + dns_c_logchan_t *chan; + + tmpres = dns_c_ctx_currchannel(currcfg, &chan); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "can't get current channel"); + YYABORT; + } + + tmpres = dns_c_logchan_setseverity(chan, + dns_c_log_debug); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine severity"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "can't get set channel severity(debug)"); + YYABORT; + } + } + | L_DEBUG L_INTEGER + { + dns_c_logchan_t *chan; + + tmpres = dns_c_ctx_currchannel(currcfg, &chan); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "can't get current channel"); + YYABORT; + } + + tmpres = dns_c_logchan_setseverity(chan, + dns_c_log_debug); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine severity"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "can't get set channel " + "severity (debug)"); + YYABORT; + } + + tmpres = dns_c_logchan_setdebuglevel(chan, $2); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "can't get set channel " + "severity debug level"); + YYABORT; + } + } + | L_DYNAMIC + { + dns_c_logchan_t *chan; + + tmpres = dns_c_ctx_currchannel(currcfg, &chan); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "can't get current channel"); + YYABORT; + } + + tmpres = dns_c_logchan_setseverity(chan, + dns_c_log_dynamic); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine severity"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "can't get set channel " + "severity (dynamic)"); + YYABORT; + } + } + ; + +version_modifier: L_VERSIONS L_INTEGER + { + dns_c_logchan_t *chan; + + tmpres = dns_c_ctx_currchannel(currcfg, &chan); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "can't get current channel"); + YYABORT; + } + + tmpres = dns_c_logchan_setversions(chan, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine versions"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "can't get set channel versions"); + YYABORT; + } + } + | L_VERSIONS L_UNLIMITED + { + dns_c_logchan_t *chan; + + tmpres = dns_c_ctx_currchannel(currcfg, &chan); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "can't get current channel"); + YYABORT; + } + + tmpres = dns_c_logchan_setversions(chan, 0xffffffffU); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine versions"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "can't get set channel " + "versions (unlimited)"); + YYABORT; + } + } + ; + +size_modifier: L_SIZE size_spec + { + dns_c_logchan_t *chan; + + tmpres = dns_c_ctx_currchannel(currcfg, &chan); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "can't get current channel"); + YYABORT; + } + + tmpres = dns_c_logchan_setsize(chan, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine size"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "can't get set channel size"); + YYABORT; + } + } + ; + +maybe_file_modifiers: /* nothing */ + | version_modifier + | size_modifier + | version_modifier size_modifier + | size_modifier version_modifier + ; + +facility_name: any_string + { + tmpres = dns_c_string2facility($1, &$$); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_TRUE, "unknown syslog facility"); + $$ = LOG_DAEMON; + } + + isc_mem_free(memctx, $1); + } + | L_SYSLOG + { + $$ = LOG_SYSLOG; + } + ; + +maybe_syslog_facility: /* nothing */ + { + $$ = LOG_DAEMON; + } + | facility_name + { + $$ = $1; + } + ; + + +channel_opt_list: channel_opt L_EOS + | channel_opt_list channel_opt L_EOS + ; + + +channel_opt: L_SEVERITY channel_severity { /* nothing to do */ } + | L_PRINT_TIME yea_or_nay + { + dns_c_logchan_t *chan; + + tmpres = dns_c_ctx_currchannel(currcfg, &chan); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "can't get current channel"); + YYABORT; + } + + tmpres = dns_c_logchan_setprinttime(chan, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, "cannot redefine print-time"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "can't get set channel print-time"); + YYABORT; + } + } + | L_PRINT_CATEGORY yea_or_nay + { + dns_c_logchan_t *chan; + + tmpres = dns_c_ctx_currchannel(currcfg, &chan); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "can't get current channel"); + YYABORT; + } + + tmpres = dns_c_logchan_setprintcat(chan, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine print-category"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "can't get set channel print-category"); + YYABORT; + } + } + | L_PRINT_SEVERITY yea_or_nay + { + dns_c_logchan_t *chan; + + tmpres = dns_c_ctx_currchannel(currcfg, &chan); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "can't get current channel"); + YYABORT; + } + + tmpres = dns_c_logchan_setprintsev(chan, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine print-severity"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "can't get set channel print-severity"); + YYABORT; + } + } + ; + + +channel_name: any_string + | L_NULL_OUTPUT + { + $$ = isc_mem_strdup(memctx, "null"); + } + ; + + +channel: channel_name + { + dns_c_logcat_t *cat; + + /* + * XXX validate the channel name refers to a previously + * defined channel + */ + tmpres = dns_c_ctx_currcategory(currcfg, &cat); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "can't get current category"); + YYABORT; + } + + tmpres = dns_c_logcat_addname(cat, $1); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "can't add new name to category"); + YYABORT; + } + + isc_mem_free(memctx, $1); + } + ; + + +channel_list: channel L_EOS + | channel_list channel L_EOS + ; + + +category_name: any_string + { + $$ = $1; + } + | L_DEFAULT + { + const char *name = token_to_keyword(L_DEFAULT); + + REQUIRE(name != NULL); + + $$ = isc_mem_strdup(memctx, name); + } + | L_NOTIFY + { + const char *name = token_to_keyword(L_NOTIFY); + + REQUIRE(name != NULL); + + $$ = isc_mem_strdup(memctx, name); + } + ; + +/* + * Server Information + */ + +server_stmt: L_SERVER ip_address + { + isc_netaddr_t netaddr; + dns_peer_t *peer = NULL; + dns_peerlist_t *peers = currentpeerlist(currcfg, ISC_TRUE); + + isc_netaddr_fromsockaddr(&netaddr, &$2); + + /* + * Check that this IP hasn't already been used. + */ + tmpres = dns_peerlist_peerbyaddr(peers, &netaddr, &peer); + if (tmpres == ISC_R_SUCCESS) { + dns_peer_detach(&peer); + parser_error(ISC_TRUE, "cannot redefine peer"); + YYABORT; + } + + tmpres = dns_peer_new(currcfg->mem, &netaddr, &peer); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to create peer structure"); + YYABORT; + } + + dns_peerlist_addpeer(peers, peer); + dns_peerlist_detach(&peers); + dns_peer_detach(&peer); + } + L_LBRACE server_info_list L_RBRACE + ; + +server_info_list: server_info L_EOS + | server_info_list server_info L_EOS + ; + +server_info: L_BOGUS yea_or_nay + { + dns_peer_t *peer = NULL; + dns_peerlist_t *peerlist = currentpeerlist(currcfg, ISC_FALSE); + + REQUIRE(peerlist != NULL); + + dns_peerlist_currpeer(peerlist, &peer); + + INSIST(peer != NULL); + + tmpres = dns_peer_setbogus(peer, $2); + dns_peer_detach(&peer); + dns_peerlist_detach(&peerlist); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine server bogus value"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "error setting server bogus value"); + YYABORT; + } + + } + | L_SUPPORT_IXFR yea_or_nay + { + /* + * Backwards compatibility, equivalent to request-ixfr. + */ + dns_peer_t *peer = NULL; + dns_peerlist_t *peerlist = currentpeerlist(currcfg, ISC_FALSE); + + REQUIRE(peerlist != NULL); + + dns_peerlist_currpeer(peerlist, &peer); + + INSIST(peer != NULL); + + tmpres = dns_peer_setrequestixfr(peer, $2); + dns_peer_detach(&peer); + dns_peerlist_detach(&peerlist); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine peer " + "request-ixfr value"); + YYABORT; + } else if(tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "error setting peer " + "request-ixfr value"); + YYABORT; + } + } + | L_PROVIDE_IXFR yea_or_nay + { + dns_peer_t *peer = NULL; + dns_peerlist_t *peerlist = currentpeerlist(currcfg, ISC_FALSE); + + REQUIRE(peerlist != NULL); + + dns_peerlist_currpeer(peerlist, &peer); + + INSIST(peer != NULL); + + tmpres = dns_peer_setprovideixfr(peer, $2); + dns_peer_detach(&peer); + dns_peerlist_detach(&peerlist); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine peer " + "provide-ixfr value"); + YYABORT; + } else if(tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "error setting peer " + "provide-ixfr value"); + YYABORT; + } + } + | L_REQUEST_IXFR yea_or_nay + { + dns_peer_t *peer = NULL; + dns_peerlist_t *peerlist = currentpeerlist(currcfg, ISC_FALSE); + + REQUIRE(peerlist != NULL); + + dns_peerlist_currpeer(peerlist, &peer); + + INSIST(peer != NULL); + + tmpres = dns_peer_setrequestixfr(peer, $2); + dns_peer_detach(&peer); + dns_peerlist_detach(&peerlist); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine peer " + "request-ixfr value"); + YYABORT; + } else if(tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "error setting peer " + "request-ixfr value"); + YYABORT; + } + } + | L_TRANSFERS L_INTEGER + { + dns_peer_t *peer = NULL; + dns_peerlist_t *peerlist = currentpeerlist(currcfg, ISC_FALSE); + + REQUIRE(peerlist != NULL); + + dns_peerlist_currpeer(peerlist, &peer); + + INSIST(peer != NULL); + + tmpres = dns_peer_settransfers(peer, $2); + dns_peer_detach(&peer); + dns_peerlist_detach(&peerlist); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine peer transfers value"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "error setting peer transfers value"); + YYABORT; + } + } + | L_TRANSFER_FORMAT transfer_format + { + dns_peer_t *peer = NULL; + dns_peerlist_t *peerlist = currentpeerlist(currcfg, ISC_FALSE); + + REQUIRE(peerlist != NULL); + + dns_peerlist_currpeer(peerlist, &peer); + + INSIST(peer != NULL); + + tmpres = dns_peer_settransferformat(peer, $2); + dns_peer_detach(&peer); + dns_peerlist_detach(&peerlist); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine peer transfer-format " + "value"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "error setting peer transfer-format " + "value"); + YYABORT; + } + } + | L_KEYS key_value { + dns_name_t *name = NULL; + dns_peer_t *peer = NULL; + dns_peerlist_t *peerlist = currentpeerlist(currcfg, ISC_FALSE); + + REQUIRE(peerlist != NULL); + + dns_peerlist_currpeer(peerlist, &peer); + + INSIST(peer != NULL); + + if (!keydefinedinscope(currcfg, $2)) { + parser_error(ISC_FALSE, + "undefined key '%s' referenced", $2); + YYABORT; + } + + tmpres = dns_c_charptoname(peer->mem, $2, &name); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "error creating key name value"); + YYABORT; + } + + tmpres = dns_peer_setkey(peer, &name); + isc_mem_free(memctx, $2); + dns_peer_detach(&peer); + dns_peerlist_detach(&peerlist); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine peer key value"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "error setting peer key value"); + YYABORT; + } + } + ; + + +key_value: L_LBRACE any_string maybe_eos L_RBRACE + { + $$ = $2; + } + | any_string + { + $$ = $1; + }; + + +keyid_list: /* nothing */ + { + dns_c_kidlist_t *kidlist = NULL; + + tmpres = dns_c_kidlist_new(currcfg->mem, &kidlist); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "failed to create kidlist"); + YYABORT; + } + + $$ = kidlist; + } + | keyid_list any_string L_EOS + { + dns_c_kid_t *kid = NULL; + + tmpres = dns_c_kid_new($$->mem, $2, &kid); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "failed to create key id"); + dns_c_kidlist_delete(&$$); + $$ = NULL; + YYABORT; + } + + isc_mem_free(memctx, $2); + + dns_c_kidlist_append($$, kid); + }; + + +/* + * Address Matching + */ + +address_match_list: address_match_element L_EOS + { + dns_c_ipmatchlist_t *ml = 0; + + if ($1 != NULL) { + tmpres = dns_c_ipmatchlist_new(currcfg->mem, &ml); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "insufficient memory"); + dns_c_ipmatchelement_delete(currcfg->mem, + &$1); + YYABORT; + } + + ISC_LIST_APPEND(ml->elements, $1, next); + } + + $$ = ml; + } + | address_match_list address_match_element L_EOS + { + dns_c_ipmatchlist_t *ml = $1; + + if (ml == NULL && $2 != NULL) { + tmpres = dns_c_ipmatchlist_new(currcfg->mem, &ml); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "insufficient memory"); + dns_c_ipmatchelement_delete(currcfg->mem, + &$2); + YYABORT; + } + } + + if ($2 != NULL) { + ISC_LIST_APPEND(ml->elements, $2, next); + } + + $$ = ml; + } + ; + +address_match_element: address_match_simple + | L_BANG address_match_simple + { + if ($2 != NULL) { + dns_c_ipmatch_negate($2); + } + $$ = $2; + } + | L_SEC_KEY L_STRING + { + dns_c_ipmatchelement_t *ime = NULL; + + if (!keydefinedinscope(currcfg, $2)) { + parser_error(ISC_FALSE, + "address match key element (%s) " + "referenced before defined", $2); + YYABORT; + } else { + tmpres = dns_c_ipmatchkey_new(currcfg->mem, &ime, $2); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_TRUE, + "failed to create address match " + "key element for %s", $2); + YYABORT; + } + } + + isc_mem_free(memctx, $2); + $$ = ime; + } + ; + +address_match_simple: ip_address + { + dns_c_ipmatchelement_t *ime = NULL; + unsigned int prefixlen = 0; + + switch ($1.type.sa.sa_family) { + case AF_INET: + prefixlen = 32; + break; + case AF_INET6: + prefixlen = 128; + break; + default: + INSIST(0); + break; + } + tmpres = dns_c_ipmatchpattern_new(currcfg->mem, &ime, $1, + prefixlen); + switch (tmpres) { + case ISC_R_FAILURE: + parser_error(ISC_FALSE, "bad address match element"); + YYABORT; + break; + + case ISC_R_NOMEMORY: + parser_error(ISC_FALSE, + "insufficient memory available"); + YYABORT; + break; + + case ISC_R_SUCCESS: + break; + } + + $$ = ime; + } + | ip_address L_SLASH L_INTEGER + { + dns_c_ipmatchelement_t *ime = NULL; + + if ($3 < 0 || + ($1.type.sa.sa_family == AF_INET && $3 > 32) || + ($1.type.sa.sa_family == AF_INET6 && $3 > 128)) { + parser_warning(ISC_FALSE, + "mask bits (%d) out of range: " + "skipping", (int)$3); + $$ = NULL; + } else { + tmpres = dns_c_ipmatchpattern_new(currcfg->mem, &ime, + $1, $3); + switch (tmpres) { + case ISC_R_FAILURE: + parser_error(ISC_FALSE, + "bad address match element"); + YYABORT; + break; + + case ISC_R_NOMEMORY: + parser_error(ISC_FALSE, + "insufficient memory available"); + YYABORT; + break; + + case ISC_R_SUCCESS: + break; + } + } + + $$ = ime; + } + | L_INTEGER L_SLASH L_INTEGER + { + struct in_addr ia; + dns_c_ipmatchelement_t *ime = NULL; + isc_sockaddr_t address; + + if ($1 > 255) { + parser_error(ISC_FALSE, + "address out of range; skipping"); + YYABORT; + } else { + if ($3 < 0 || $3 > 32) { + parser_warning(ISC_FALSE, + "mask bits out of range; " + "skipping"); + $$ = NULL; + } else { + ia.s_addr = htonl(($1 & 0xff) << 24); + isc_sockaddr_fromin(&address, &ia, 0); + + tmpres = + dns_c_ipmatchpattern_new(currcfg->mem, + &ime, + address, + $3); + switch (tmpres) { + case ISC_R_FAILURE: + parser_error(ISC_FALSE, + "bad address match " + "element"); + YYABORT; + break; + + case ISC_R_NOMEMORY: + parser_error(ISC_FALSE, + "insufficient memory " + "available"); + YYABORT; + break; + + case ISC_R_SUCCESS: + break; + } + } + } + + $$ = ime; + } + | address_name + | L_LBRACE address_match_list L_RBRACE + { + dns_c_ipmatchelement_t *ime = NULL; + + if ($2 != NULL) { + tmpres = dns_c_ipmatchindirect_new(currcfg->mem, &ime, + $2, NULL); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to create indirect " + "ipmatch list"); + YYABORT; + } + } + + dns_c_ipmatchlist_detach(&$2); + + $$ = ime; + } + ; + +address_name: any_string + { + dns_c_ipmatchelement_t *elem; + dns_c_acl_t *acl; + + if (strcmp($1, "any") == 0) { + tmpres = dns_c_ipmatchany_new(currcfg->mem, &elem); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to create 'any'" + " ipmatch element"); + YYABORT; + } + } else if (strcmp($1, "none") == 0) { + tmpres = dns_c_ipmatchany_new(currcfg->mem, &elem); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to create 'none'" + " ipmatch element"); + YYABORT; + } + dns_c_ipmatch_negate(elem); + } else if (strcmp($1, "localhost") == 0) { + tmpres = dns_c_ipmatchlocalhost_new(currcfg->mem, + &elem); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to create 'localhost'" + " ipmatch element"); + YYABORT; + } + } else if (strcmp($1, "localnets") == 0) { + tmpres = dns_c_ipmatchlocalnets_new(currcfg->mem, + &elem); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to create 'localnets'" + " ipmatch element"); + YYABORT; + } + } else { + tmpres = dns_c_acltable_getacl(currcfg->acls, + $1, &acl); + if (tmpres == ISC_R_NOTFOUND) { + parser_warning(ISC_FALSE, + "undefined acl '%s' " + "referenced", $1); + elem = NULL; + } else { + tmpres = dns_c_ipmatch_aclnew(currcfg->mem, + &elem, $1); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to create " + "IPE-ACL"); + YYABORT; + } + } + } + + isc_mem_free(memctx, $1); + $$ = elem; + } + ; + +/* + * Keys + */ + + +key_stmt: L_SEC_KEY any_string L_LBRACE key_definition L_RBRACE + { + dns_c_kdef_t *keydef; + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + dns_c_kdeflist_t *list = NULL; + + if (view == NULL) { + tmpres = dns_c_ctx_getkdeflist(currcfg, &list); + } else { + tmpres = dns_c_view_getkeydefs(view, &list); + } + + if (tmpres == ISC_R_NOTFOUND) { + tmpres = dns_c_kdeflist_new(currcfg->mem, + &list); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to create keylist"); + isc_mem_free(memctx, $2); + isc_mem_free(memctx, $4.algorithm); + isc_mem_free(memctx, $4.secret); + + YYABORT; + } + + if (view == NULL) { + tmpres = dns_c_ctx_setkdeflist(currcfg, + list, + ISC_FALSE); + } else { + tmpres = dns_c_view_setkeydefs(view, list); + } + + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set keylist"); + dns_c_kdeflist_delete(&list); + isc_mem_free(memctx, $2); + isc_mem_free(memctx, $4.algorithm); + isc_mem_free(memctx, $4.secret); + + YYABORT; + } + } + + tmpres = dns_c_kdef_new(currcfg->mem, $2, &keydef); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "failed to create key"); + isc_mem_free(memctx, $2); + isc_mem_free(memctx, $4.algorithm); + isc_mem_free(memctx, $4.secret); + YYABORT; + } + + tmpres = dns_c_kdef_setalgorithm(keydef, $4.algorithm); + if (tmpres == ISC_R_SUCCESS) { + tmpres = dns_c_kdef_setsecret(keydef, $4.secret); + } + + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set key details"); + isc_mem_free(memctx, $2); + isc_mem_free(memctx, $4.algorithm); + isc_mem_free(memctx, $4.secret); + } + + dns_c_kdeflist_append(list, keydef, ISC_FALSE); + + isc_mem_free(memctx, $2); + isc_mem_free(memctx, $4.algorithm); + isc_mem_free(memctx, $4.secret); + } + ; + +key_definition: algorithm_id secret + { + $$.algorithm = $1; + $$.secret = $2; + } + | secret algorithm_id + { + $$.algorithm = $2; + $$.secret = $1; + } + ; + +algorithm_id: L_ALGID any_string L_EOS + { + $$ = $2; + } + ; + +secret: L_SECRET any_string L_EOS + { + $$ = $2; + } + ; + + +/* + * Views + */ + + +view_stmt: L_VIEW any_string optional_class L_LBRACE + { + dns_c_view_t *view; + + if (currcfg->views == NULL) { + tmpres = dns_c_viewtable_new(currcfg->mem, + &currcfg->views); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to create viewtable"); + YYABORT; + } + } + + tmpres = dns_c_view_new(currcfg->mem, $2, $3, &view); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to create view %s", $2); + YYABORT; + } + + dns_c_viewtable_addview(currcfg->views, view); + dns_c_ctx_setcurrview(currcfg, view); + + isc_mem_free(memctx, $2); + } optional_view_options_list L_RBRACE { + dns_c_ctx_setcurrview(currcfg, NULL); + }; + +optional_view_options_list: + | view_options_list + ; + +view_options_list: view_option L_EOS + | view_options_list view_option L_EOS; + + +view_option: L_FORWARD zone_forward_opt + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setforward(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view forward"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view forward"); + YYABORT; + } + } + | L_FORWARDERS L_LBRACE opt_in_addr_list L_RBRACE + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setforwarders(view, + $3, ISC_FALSE); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view forwarders"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view forwarders"); + YYABORT; + } + } + | L_ALLOW_QUERY L_LBRACE address_match_list L_RBRACE + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setallowquery(view, $3); + dns_c_ipmatchlist_detach(&$3); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view allow-query"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view allow-query"); + YYABORT; + } + } + | L_ALLOW_UPDATE_FORWARDING L_LBRACE address_match_list L_RBRACE + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setallowupdateforwarding(view, $3); + dns_c_ipmatchlist_detach(&$3); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view " + "allow-update-forwarding"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view " + "allow-update-forwarding"); + YYABORT; + } + } + | L_ALLOW_TRANSFER L_LBRACE address_match_list L_RBRACE + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_settransferacl(view, $3); + dns_c_ipmatchlist_detach(&$3); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view allow-transfer"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view allow-transfer"); + YYABORT; + } + } + | L_ALLOW_RECURSION L_LBRACE address_match_list L_RBRACE + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setrecursionacl(view, $3); + dns_c_ipmatchlist_detach(&$3); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view allow-recursion"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view allow-recursion"); + YYABORT; + } + } + | L_SORTLIST L_LBRACE address_match_list L_RBRACE + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setsortlist(view, $3); + dns_c_ipmatchlist_detach(&$3); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view sortlist"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view sortlist"); + YYABORT; + } + } + | L_TOPOLOGY L_LBRACE address_match_list L_RBRACE + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_settopology(view, $3); + dns_c_ipmatchlist_detach(&$3); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view topology"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view topology"); + YYABORT; + } + } + | L_MATCH_CLIENTS L_LBRACE address_match_list L_RBRACE + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setmatchclients(view, $3); + dns_c_ipmatchlist_detach(&$3); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view match-clients"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view match-clients"); + YYABORT; + } + } + | L_CHECK_NAMES check_names_type check_names_opt + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setchecknames(view, $2, $3); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view check-names"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view check-names"); + YYABORT; + } + } + | L_AUTH_NXDOMAIN yea_or_nay + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setauthnxdomain(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view auth-nxdomain"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view auth-nxdomain"); + YYABORT; + } + } + | L_RECURSION yea_or_nay + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setrecursion(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view recursion"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view recursion"); + YYABORT; + } + } + | L_PROVIDE_IXFR yea_or_nay + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setprovideixfr(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view provide-ixfr"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view provide-ixfr"); + YYABORT; + } + } + | L_REQUEST_IXFR yea_or_nay + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setrequestixfr(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view request-ixfr"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view request-ixfr"); + YYABORT; + } + } + | L_FETCH_GLUE yea_or_nay + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setfetchglue(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view fetch-glue"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view fetch-glue"); + YYABORT; + } + } + | L_NOTIFY notify_setting + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setnotify(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view notify"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view notify"); + YYABORT; + } + } + | L_RFC2308_TYPE1 yea_or_nay + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setrfc2308type1(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view rfc2308-type1"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view rfc2308-type1"); + YYABORT; + } + } + | L_GLUE_FROM_CACHE yea_or_nay + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setgluefromcache(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view glue-from-cache"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view glue-from-cache"); + YYABORT; + } + } + | L_GLUE_FROM_AUTH yea_or_nay + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setgluefromauth(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view glue-from-auth"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view glue-from-auth"); + YYABORT; + } + } + | L_QUERY_SOURCE query_source_v4 + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setquerysource(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view query-source"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view query-source"); + YYABORT; + } + } + | L_QUERY_SOURCE_V6 query_source_v6 + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setquerysourcev6(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view query-source-v6"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view query-source-v6"); + YYABORT; + } + } + | L_TRANSFER_SOURCE maybe_wild_ip4_only_addr + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_settransfersource(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view transfer-source"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view transfer-source"); + YYABORT; + } + } + | L_TRANSFER_SOURCE_V6 maybe_wild_ip6_only_addr + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_settransfersourcev6(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view " + "transfer-source-v6"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view transfer-source-v6"); + YYABORT; + } + } + | L_MAX_TRANSFER_TIME_OUT L_INTEGER + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + if ( int_too_big($2, 60) ) { + parser_error(ISC_FALSE, + "integer value too big: %u", $2); + YYABORT; + } + + tmpres = dns_c_view_setmaxtransfertimeout(view, $2 * 60); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view " + "max-transfer-time-out"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view " + "max-transfer-time-out"); + YYABORT; + } + } + | L_MAX_TRANSFER_IDLE_OUT L_INTEGER + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + if ( int_too_big($2, 60) ) { + parser_error(ISC_FALSE, + "integer value too big: %u", $2); + YYABORT; + } + + tmpres = dns_c_view_setmaxtransferidleout(view, $2 * 60); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view " + "max-transfer-idle-out"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view " + "max-transfer-idle-out"); + YYABORT; + } + } + | L_CLEAN_INTERVAL L_INTEGER + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + if ( int_too_big($2, 60) ) { + parser_error(ISC_FALSE, + "integer value too big: %u", $2); + YYABORT; + } + + tmpres = dns_c_view_setcleaninterval(view, $2 * 60); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view " + "cleaning-interval"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view cleaning-interval"); + YYABORT; + } + } + | L_MIN_ROOTS L_INTEGER + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setminroots(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view min-roots"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view min-roots"); + YYABORT; + } + } + | L_LAME_TTL L_INTEGER + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setlamettl(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view lame-ttl"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view lame-ttl"); + YYABORT; + } + } + | L_MAX_NCACHE_TTL L_INTEGER + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setmaxncachettl(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view max-ncache-ttl"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view max-ncache-ttl"); + YYABORT; + } + } + | L_MAX_CACHE_TTL L_INTEGER + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setmaxcachettl(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view max-cache-ttl"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view max-cache-ttl"); + YYABORT; + } + } + | L_SIG_VALIDITY_INTERVAL L_INTEGER + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setsigvalidityinterval(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view " + "sig-validity-interval"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view " + "sig-validity-interval"); + YYABORT; + } + } + | L_ADDITIONAL_DATA additional_data + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setadditionaldata(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view additional-data"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view additional-data"); + YYABORT; + } + } + | L_TRANSFER_FORMAT transfer_format + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_settransferformat(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view transfer-format"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view transfer-format"); + YYABORT; + } + } + | L_ALSO_NOTIFY port_ip_list + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + tmpres = dns_c_view_setalsonotify(view, $2); + dns_c_iplist_detach(&$2); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view also-notify"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view also-notify"); + YYABORT; + } + } + | L_MAX_CACHE_SIZE size_spec + { + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + INSIST(view != NULL); + + if ($2 == DNS_C_SIZE_SPEC_DEFAULT) { + parser_error(ISC_FALSE, + "cannot specific 'default' for " + "'max-cache-size'"); + YYABORT; + } + + tmpres = dns_c_view_setmaxcachesize(view, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine view max-cache-size"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set view max-cache-size"); + YYABORT; + } + } + | key_stmt + | zone_stmt + | server_stmt + | trusted_keys_stmt + ; + + +zone_update_policy: L_UPDATE_POLICY L_LBRACE { + + } zone_grant_stmt_list L_RBRACE; + +zone_grant_stmt_list: /* nothing */ | zone_grant_stmt_list zone_ssu_stmt L_EOS; + +zone_ssu_stmt: grant_stmt { + dns_ssutable_t *ssutable = NULL; + isc_boolean_t ok = ISC_TRUE; + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + REQUIRE(zone != NULL); + + switch(zone->ztype) { + case dns_c_zone_hint: + parser_error(ISC_FALSE, + "hint zones do not have grant/deny " + "statements"); + ok = ISC_FALSE; + break; + + case dns_c_zone_forward: + parser_error(ISC_FALSE, + "forward zones do not have grant/deny " + "statements"); + ok = ISC_FALSE; + break; + + default: + /* nothing */ + break; + } + + if (ok) { + tmpres = dns_c_zone_getssuauth(zone, &ssutable); + if (tmpres == ISC_R_NOTFOUND) { + REQUIRE(ssutable == NULL); + + tmpres = dns_ssutable_create(currcfg->mem, + &ssutable); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to create " + "ssutable"); + ok = ISC_FALSE; + } + } + + if (ok) { + dns_c_zone_setssuauth(zone, ssutable); + } + } + + tmpres = dns_ssutable_addrule(ssutable, $1.grant, + $1.ident, $1.matchtype, + $1.name, + $1.rdatatypes.idx, + $1.rdatatypes.types); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "error creating ssu " + "identity value"); + ok = ISC_FALSE; + } + + dns_name_free($1.ident, memctx); + dns_name_free($1.name, memctx); + + isc_mem_put(memctx, $1.rdatatypes.types, + sizeof ($1.rdatatypes.types[0]) * 256); + + isc_mem_put(memctx, $1.ident, sizeof (*$1.ident)); + isc_mem_put(memctx, $1.name, sizeof (*$1.name)); + + if (!ok) { + YYABORT; + } + }; + +grant_stmt: grantp any_string grant_match_type any_string rdatatype_list + { + dns_name_t *name = NULL; + dns_name_t *identity = NULL; + isc_boolean_t ok = ISC_TRUE; + + tmpres = dns_c_charptoname(memctx, $4, &name); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "error creating ssu name value"); + ok = ISC_FALSE; + } + + if (ok) { + tmpres = dns_c_charptoname(memctx, $2, &identity); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "error creating ssu " + "identity value"); + ok = ISC_FALSE; + } + } + + if (ok) { + if (!dns_name_isabsolute(identity)) { + parser_error(ISC_FALSE, + "identity (%s) must be an " + "absolute (not relative) name", + $2); + ok = ISC_FALSE; + } + + if (!dns_name_isabsolute(name)) { + parser_error(ISC_FALSE, + "name (%s) must be an " + "absolute (not relative) name", + $4); + ok = ISC_FALSE; + } + + if ($3 == DNS_SSUMATCHTYPE_WILDCARD && + !dns_name_iswildcard(name)) { + parser_error(ISC_FALSE, + "name (%s) has no wildcard " + "character ", + $4); + ok = ISC_FALSE; + } + } + + isc_mem_free(memctx, $2); + isc_mem_free(memctx, $4); + + if (ok) { + $$.grant = $1; + $$.ident = identity; + $$.matchtype = $3; + $$.name = name; + $$.rdatatypes = $5; + } else { + if (identity != NULL) { + dns_name_free(identity, memctx); + isc_mem_put(memctx, identity, + sizeof *identity); + } + + if (name != NULL) { + dns_name_free(name, memctx); + isc_mem_put(memctx, name, sizeof *name); + } + + REQUIRE($5.types != NULL); + + isc_mem_put(memctx, $5.types, + sizeof (dns_rdatatype_t) * 256); + + YYABORT; + } + }; + +grantp: L_GRANT { + $$ = ISC_TRUE; + } + | L_DENY { + $$ = ISC_FALSE; + }; + +grant_match_type: L_NAME { + $$ = DNS_SSUMATCHTYPE_NAME; + } + | L_SUBDOMAIN { + $$ = DNS_SSUMATCHTYPE_SUBDOMAIN; + } + | L_WILDCARD { + $$ = DNS_SSUMATCHTYPE_WILDCARD; + } + | L_SELF { + $$ = DNS_SSUMATCHTYPE_SELF; + }; + +rdatatype_list: /* nothing */ + { + $$.types = isc_mem_get(memctx, sizeof(dns_rdatatype_t) * 256); + $$.idx = 0; + } + | rdatatype_list rdatatype { + $1.types[$1.idx++] = $2; + $$ = $1; + }; + +rdatatype: any_string { + isc_textregion_t reg; + dns_rdatatype_t ty; + + reg.base = $1; + reg.length = strlen($1); + + tmpres = dns_rdatatype_fromtext(&ty, ®); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_TRUE, "unknown rdatatype"); + YYABORT; + } + + isc_mem_free(memctx, $1); + $$ = ty; + }; + + + +/* + * ACLs + */ + +acl_stmt: L_ACL any_string L_LBRACE address_match_list L_RBRACE + { + dns_c_acl_t *acl; + + INSIST(currcfg->acls != NULL); + + tmpres = dns_c_acl_new(currcfg->acls, + $2, ISC_FALSE, &acl); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to create acl %s", $2); + YYABORT; + } + + dns_c_acl_setipml(acl, $4, ISC_FALSE); + + isc_mem_free(memctx, $2); + } + ; + + +/* + * Zones + */ + +domain_name: L_QSTRING + { + $$ = $1; + } + ; + +/* + * 'type' is no longer optional and must be the first statement in the + * zone block. + */ +zone_stmt: L_ZONE domain_name optional_class L_LBRACE L_TYPE zone_type L_EOS + { + dns_c_zone_t *zone; + + if (currcfg->zlist == NULL) { + tmpres = dns_c_zonelist_new(currcfg->mem, + &currcfg->zlist); + if (tmpres != ISC_R_SUCCESS) { + isc_log_write(dns_lctx, + DNS_LOGCATEGORY_CONFIG, + DNS_LOGMODULE_CONFIG, + ISC_LOG_ERROR, + "Failed to create zone list"); + YYABORT; + } + } + + /* XXX internal name support needed! */ + tmpres = dns_c_zone_new(currcfg->mem, + $6, $3, $2, $2, &zone); + if (tmpres != ISC_R_SUCCESS) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG, + DNS_LOGMODULE_CONFIG, + ISC_LOG_ERROR, + "Error creating new zone"); + YYABORT; + } + + tmpres = dns_c_zonelist_addzone(currcfg->zlist, zone); + if (tmpres != ISC_R_SUCCESS) { + dns_c_zone_detach(&zone); + isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG, + DNS_LOGMODULE_CONFIG, + ISC_LOG_ERROR, + "Error adding new zone to list"); + YYABORT; + } + + dns_c_ctx_setcurrzone(currcfg, zone); + + isc_mem_free(memctx, $2); + } optional_zone_options_list L_RBRACE { + dns_c_zone_t *zone; + dns_c_view_t *view; + + zone = dns_c_ctx_getcurrzone(currcfg); + view = dns_c_ctx_getcurrview(currcfg); + + zone->view = view; + + if (view != NULL) { + dns_c_view_addzone(view, zone); + } + + dns_c_ctx_setcurrzone(currcfg, NULL); + + if (zone != NULL && + callbacks != NULL && callbacks->zonecbk != NULL) { + tmpres = dns_c_zone_validate(zone); + if (tmpres != ISC_R_SUCCESS) { + YYABORT; + } + + tmpres = callbacks->zonecbk(currcfg, + zone, + view, + callbacks->zonecbkuap); + if (tmpres != ISC_R_SUCCESS) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG, + DNS_LOGMODULE_CONFIG, + ISC_LOG_ERROR, + "zone configuration " + "for '%s' failed: %s", + zone->name, + isc_result_totext(tmpres)); + YYABORT; + } + + dns_c_zonelist_rmzone(currcfg->zlist, zone); + } + } + | L_ZONE domain_name optional_class L_LBRACE zone_non_type_keywords + { + parser_error(ISC_FALSE, + "first statement in a zone definition must " + "be 'type'"); + YYABORT; + } + | L_ZONE domain_name + { + parser_warning(ISC_FALSE, + "references to zones not implemented yet"); + } + ; + +optional_zone_options_list: /* Empty */ + | zone_option_list + ; + +class_name: any_string + { + isc_textregion_t reg; + dns_rdataclass_t cl; + + reg.base = $1; + reg.length = strlen($1); + + tmpres = dns_rdataclass_fromtext(&cl, ®); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_TRUE, "unknown class"); + YYABORT; + } + + isc_mem_free(memctx, $1); + $$ = cl; + } + +wild_class_name: any_string + { + isc_textregion_t reg; + dns_rdataclass_t cl; + + if (strcmp($1, "*") == 0) { + cl = dns_rdataclass_any; + } else { + reg.base = $1; + reg.length = strlen($1); + + tmpres = dns_rdataclass_fromtext(&cl, ®); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_TRUE, + "unknown class, assuming '*'"); + cl = dns_rdataclass_any; + } + } + + isc_mem_free(memctx, $1); + $$ = cl; + } + +optional_class: /* Empty */ + { + $$ = dns_rdataclass_in; + } + | class_name + ; + +zone_type: L_MASTER + { + $$ = dns_c_zone_master; + } + | L_SLAVE + { + $$ = dns_c_zone_slave; + } + | L_HINT + { + $$ = dns_c_zone_hint; + } + | L_STUB + { + $$ = dns_c_zone_stub; + } + | L_FORWARD + { + $$ = dns_c_zone_forward; + } + ; + + + +zone_option_list: zone_option L_EOS + | zone_option_list zone_option L_EOS + ; + + +/* + * This rule is used in enforcing the requirement that zone_type must be + * the first element in a zone statement + */ +zone_non_type_keywords: L_FILE | L_FILE_IXFR | L_IXFR_TMP | L_MASTERS | + L_TRANSFER_SOURCE | L_CHECK_NAMES | L_ALLOW_UPDATE | + L_ALLOW_UPDATE_FORWARDING | L_ALLOW_QUERY | + L_ALLOW_TRANSFER | L_FORWARD | L_FORWARDERS | L_MAX_TRANSFER_TIME_IN | + L_TCP_CLIENTS | L_RECURSIVE_CLIENTS | L_UPDATE_POLICY | L_DENY | + L_MAX_TRANSFER_TIME_OUT | L_MAX_TRANSFER_IDLE_IN | + L_MAX_TRANSFER_IDLE_OUT | L_MAX_LOG_SIZE_IXFR | L_NOTIFY | + L_MAINTAIN_IXFR_BASE | L_PUBKEY | L_ALSO_NOTIFY | L_DIALUP | + L_ENABLE_ZONE | L_DATABASE | L_PORT + ; + + +zone_option: L_FILE L_QSTRING + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + tmpres = dns_c_zone_setfile(zone, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone filename"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone file name"); + YYABORT; + } + isc_mem_free(memctx, $2); + } + | L_FILE_IXFR L_QSTRING + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + tmpres = dns_c_zone_setixfrbase(zone, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine ixfr-base"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone ixfr_base"); + YYABORT; + } + isc_mem_free(memctx, $2); + } + | L_IXFR_TMP L_QSTRING + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + tmpres = dns_c_zone_setixfrtmp(zone, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine ixfr-tmp-file"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone ixfr_tmp-file"); + YYABORT; + } + isc_mem_free(memctx, $2); + } + | L_MASTERS port_ip_list + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + tmpres = dns_c_zone_setmasterips(zone, $2, ISC_FALSE); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone masters ips"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone masters ips"); + YYABORT; + } + } + | L_TRANSFER_SOURCE maybe_wild_ip4_only_addr + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + tmpres = dns_c_zone_settransfersource(zone, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone transfer-source"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone transfer-source"); + YYABORT; + } + } + | L_TRANSFER_SOURCE_V6 maybe_wild_ip6_only_addr + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + tmpres = dns_c_zone_settransfersourcev6(zone, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone " + "transfer-source-v6"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone transfer-source-v6"); + YYABORT; + } + } + | L_CHECK_NAMES check_names_opt + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + tmpres = dns_c_zone_setchecknames(zone, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone check-names"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone check-names"); + YYABORT; + } + } + | L_ALLOW_UPDATE L_LBRACE address_match_list L_RBRACE + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + tmpres = dns_c_zone_setallowupd(zone, + $3, ISC_FALSE); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone allow-update"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone allow-update"); + YYABORT; + } + } + | L_ALLOW_UPDATE_FORWARDING L_LBRACE address_match_list L_RBRACE + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + tmpres = dns_c_zone_setallowupdateforwarding(zone, + $3, ISC_FALSE); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone " + "allow-update-forwarding"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone " + "allow-update-forwarding"); + YYABORT; + } + } + | L_ALLOW_QUERY L_LBRACE address_match_list L_RBRACE + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + tmpres = dns_c_zone_setallowquery(zone, + $3, ISC_FALSE); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone allow-query"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone allow-query"); + YYABORT; + } + } + | L_ALLOW_TRANSFER L_LBRACE address_match_list L_RBRACE + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + tmpres = dns_c_zone_setallowtransfer(zone, + $3, ISC_FALSE); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone allow-transfer"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone allow-transfer"); + YYABORT; + } + } + | L_FORWARD zone_forward_opt + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + tmpres = dns_c_zone_setforward(zone, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone forward"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone forward"); + YYABORT; + } + } + | L_FORWARDERS L_LBRACE opt_zone_forwarders_list L_RBRACE + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + dns_c_iplist_t *iplist; + + INSIST(zone != NULL); + + if ($3 == NULL) { /* user defined empty list */ + tmpres = dns_c_iplist_new(currcfg->mem, + 5, &iplist); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_TRUE, + "failed to create new zone " + "iplist"); + YYABORT; + } + } else { + iplist = $3; + } + + tmpres = dns_c_zone_setforwarders(zone, + iplist, ISC_FALSE); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone forwarders"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone forwarders"); + YYABORT; + } + } + | L_MAX_TRANSFER_TIME_IN L_INTEGER + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + if ( int_too_big($2, 60) ) { + parser_error(ISC_FALSE, + "integer value too big: %u", $2); + YYABORT; + } + + tmpres = dns_c_zone_setmaxtranstimein(zone, $2 * 60); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone " + "max-transfer-time-in"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone " + "max-transfer-time-in"); + YYABORT; + } + } + | L_MAX_TRANSFER_TIME_OUT L_INTEGER + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + if ( int_too_big($2, 60) ) { + parser_error(ISC_FALSE, + "integer value too big: %u", $2); + YYABORT; + } + + tmpres = dns_c_zone_setmaxtranstimeout(zone, $2 * 60); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone " + "max-transfer-time-out"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone " + "max-transfer-time-out"); + YYABORT; + } + } + | L_MAX_TRANSFER_IDLE_IN L_INTEGER + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + if ( int_too_big($2, 60) ) { + parser_error(ISC_FALSE, + "integer value too big: %u", $2); + YYABORT; + } + + tmpres = dns_c_zone_setmaxtransidlein(zone, $2 * 60); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone " + "max-transfer-idle-in"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone " + "max-transfer-idle-in"); + YYABORT; + } + } + | L_MAX_TRANSFER_IDLE_OUT L_INTEGER + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + if ( int_too_big($2, 60) ) { + parser_error(ISC_FALSE, + "integer value too big: %u", $2); + YYABORT; + } + + tmpres = dns_c_zone_setmaxtransidleout(zone, $2 * 60); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone " + "max-transfer-idle-out"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone " + "max-transfer-idle-out"); + YYABORT; + } + } + | L_SIG_VALIDITY_INTERVAL L_INTEGER + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + tmpres = dns_c_zone_setsigvalidityinterval(zone, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone " + "sig-validity-interval"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone " + "sig-validity-interval"); + YYABORT; + } + } + | L_MAX_LOG_SIZE_IXFR L_INTEGER + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + tmpres = dns_c_zone_setmaxixfrlog(zone, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone " + "max-ixfr-log-size"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone max-ixfr-log-size"); + YYABORT; + } + } + | L_NOTIFY notify_setting + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + tmpres = dns_c_zone_setnotify(zone, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone notify"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone notify"); + YYABORT; + } + } + | L_MAINTAIN_IXFR_BASE yea_or_nay + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + tmpres = dns_c_zone_setmaintixfrbase(zone, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone " + "maintain-ixfr-base"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone maintain-ixfr-base"); + YYABORT; + } + } + | L_PUBKEY L_INTEGER L_INTEGER L_INTEGER L_QSTRING + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + dns_c_pubkey_t *pubkey; + + INSIST(zone != NULL); + + tmpres = dns_c_pubkey_new(currcfg->mem, $2, + $3, $4, $5, &pubkey); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_TRUE, + "failed to create a zone pubkey"); + YYABORT; + } + + tmpres = dns_c_zone_addpubkey(zone, pubkey, + ISC_FALSE); + if (tmpres != ISC_R_SUCCESS) { + dns_c_pubkey_delete(&pubkey); + parser_error(ISC_FALSE, + "failed to add a zone pubkey"); + YYABORT; + } + + isc_mem_free(memctx, $5); + } + | L_ALSO_NOTIFY port_ip_list + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + tmpres = dns_c_zone_setalsonotify(zone, $2, ISC_FALSE); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone also-notify"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone also-notify"); + YYABORT; + } + } + | L_DIALUP yea_or_nay + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + tmpres = dns_c_zone_setdialup(zone, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone dialup"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone dialup"); + YYABORT; + } + } + | L_ENABLE_ZONE yea_or_nay + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + tmpres = dns_c_zone_setenabled(zone, $2); + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine enable-zone"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set enable-zone"); + YYABORT; + } + } + | L_DATABASE L_QSTRING + { + dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg); + + INSIST(zone != NULL); + + tmpres = dns_c_zone_setdatabase(zone, $2); + isc_mem_free(memctx, $2); + + if (tmpres == ISC_R_EXISTS) { + parser_error(ISC_FALSE, + "cannot redefine zone database"); + YYABORT; + } else if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, + "failed to set zone database"); + YYABORT; + } + + } + | zone_update_policy + ; + + +ip4_address: L_IP4ADDR + { + isc_sockaddr_fromin(&$$, &$1, 0); + } + ; + +ip6_address: L_IP6ADDR + { + isc_sockaddr_fromin6(&$$, &$1, 0); + }; + + +ip_address: ip4_address | ip6_address + ; + +in_addr_elem: ip_address + ; + +opt_in_addr_list: /* nothing */ + { + dns_c_iplist_t *list; + + tmpres = dns_c_iplist_new(currcfg->mem, 5, &list); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_TRUE, + "failed to create new iplist"); + YYABORT; + } + + $$ = list; + } + | in_addr_list + ; + +in_addr_list: in_addr_elem L_EOS + { + dns_c_iplist_t *list; + + tmpres = dns_c_iplist_new(currcfg->mem, 5, &list); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_TRUE, + "failed to create new iplist"); + YYABORT; + } + +#ifndef NOMINUM_PUBLIC + tmpres = dns_c_iplist_append(list, $1, NULL); +#else /* NOMINUM_PUBLIC */ + tmpres = dns_c_iplist_append(list, $1); +#endif /* NOMINUM_PUBLIC */ + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_TRUE, + "failed to append master address"); + YYABORT; + } + + $$ = list; + } + | in_addr_list in_addr_elem L_EOS + { +#ifndef NOMINUM_PUBLIC + tmpres = dns_c_iplist_append($1, $2, NULL); +#else /* NOMINUM_PUBLIC */ + tmpres = dns_c_iplist_append($1, $2, NULL); +#endif /* NOMINUM_PUBLIC */ + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_TRUE, + "failed to append master address"); + YYABORT; + } + + $$ = $1; + } + ; + +zone_forward_opt: L_ONLY + { + $$ = dns_c_forw_only; + } + | L_FIRST + { + $$ = dns_c_forw_first; + } + ; + +opt_zone_forwarders_list: opt_in_addr_list + ; + +/* + * Trusted Key statement + */ + +trusted_keys_stmt: L_TRUSTED_KEYS + { + dns_c_tkeylist_t *newlist; + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + + if (view == NULL) { + tmpres = dns_c_ctx_gettrustedkeys(currcfg, + &newlist); + } else { + tmpres = dns_c_view_gettrustedkeys(view, &newlist); + } + + if (tmpres == ISC_R_NOTFOUND) { + tmpres = dns_c_tkeylist_new(currcfg->mem, &newlist); + if (tmpres != ISC_R_SUCCESS) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG, + DNS_LOGMODULE_CONFIG, + ISC_LOG_ERROR, + "Failed to create trusted key" + " list"); + YYABORT; + } + + if (view == NULL) { + tmpres = dns_c_ctx_settrustedkeys(currcfg, + newlist, + ISC_FALSE); + } else { + tmpres = dns_c_view_settrustedkeys(view, + newlist, + ISC_FALSE); + } + + if (tmpres != ISC_R_SUCCESS) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG, + DNS_LOGMODULE_CONFIG, + ISC_LOG_ERROR, + "Failed to set trusted keys"); + YYABORT; + } + } + } L_LBRACE trusted_keys_list L_RBRACE + ; + +trusted_keys_list: trusted_key L_EOS + | trusted_keys_list trusted_key L_EOS + ; + + +trusted_key: any_string L_INTEGER L_INTEGER L_INTEGER L_QSTRING + { + dns_c_tkey_t *tkey; + dns_c_tkeylist_t *list; + dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + isc_mem_t *mem; + + if (view == NULL) { + tmpres = dns_c_ctx_gettrustedkeys(currcfg, &list); + mem = currcfg->mem; + } else { + tmpres = dns_c_view_gettrustedkeys(view, &list); + mem = view->mem; + } + + if (tmpres != ISC_R_SUCCESS) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG, + DNS_LOGMODULE_CONFIG, + ISC_LOG_ERROR, + "No trusted key list defined!"); + YYABORT; + } + + tmpres = dns_c_tkey_new(mem, $1, $2, $3, + $4, $5, &tkey); + if (tmpres != ISC_R_SUCCESS) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG, + DNS_LOGMODULE_CONFIG, + ISC_LOG_ERROR, + "Failed to create trusted key"); + YYABORT; + } + + tmpres = dns_c_tkeylist_append(list, + tkey, ISC_FALSE); + if (tmpres != ISC_R_SUCCESS) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG, + DNS_LOGMODULE_CONFIG, + ISC_LOG_ERROR, + "Failed to append trusted key"); + YYABORT; + } + + isc_mem_free(memctx, $1); + isc_mem_free(memctx, $5); + } + ; + + + +/* + * Misc. + */ + +in_port: L_INTEGER + { + if ($1 < 0 || $1 > 65535) { + parser_warning(ISC_TRUE, + "invalid IP port number '%d'; " + "setting port to 0", (int)$1); + $1 = 0; + } else { + $$ = $1; + } + } + ; + + +any_string: L_STRING + | L_QSTRING + ; + +maybe_eos: | L_EOS ; + +%% + +static int intuit_token(const char *string); + +static isc_boolean_t is_ip4addr(const char *string, struct in_addr *addr); +static isc_boolean_t is_ip6addr(const char *string, struct in6_addr *addr); +static isc_result_t keyword_init(void); +static char * token_to_text(int token, YYSTYPE lval); +static int token_value(isc_token_t *token, + isc_symtab_t *symtable); +static void init_action(void); + +static YYSTYPE lastyylval; +static int lasttoken; + + +/* + * Definition of all unique keyword tokens to be recognised by the + * lexer. All the 'L_' tokens defined in parser.y must be defined here too. + */ +struct token +{ + const char *token; + int yaccval; +}; + +static struct token keyword_tokens [] = { + { "{", L_LBRACE }, + { "}", L_RBRACE }, + { ";", L_EOS }, + { "/", L_SLASH }, + { "!", L_BANG }, + + { "acl", L_ACL }, + { "additional-data", L_ADDITIONAL_DATA }, + { "address", L_ADDRESS }, + { "algorithm", L_ALGID }, + { "allow", L_ALLOW }, + { "allow-query", L_ALLOW_QUERY }, + { "allow-recursion", L_ALLOW_RECURSION }, + { "allow-transfer", L_ALLOW_TRANSFER }, + { "allow-update", L_ALLOW_UPDATE }, + { "allow-update-forwarding", L_ALLOW_UPDATE_FORWARDING }, + { "also-notify", L_ALSO_NOTIFY }, + { "auth-nxdomain", L_AUTH_NXDOMAIN }, + { "blackhole", L_BLACKHOLE }, + { "bogus", L_BOGUS }, + { "category", L_CATEGORY }, + { "channel", L_CHANNEL }, + { "check-names", L_CHECK_NAMES }, + { "class", L_CLASS }, + { "cleaning-interval", L_CLEAN_INTERVAL }, + { "controls", L_CONTROLS }, + { "coresize", L_CORESIZE }, + { "database", L_DATABASE }, + { "datasize", L_DATASIZE }, + { "deallocate-on-exit", L_DEALLOC_ON_EXIT }, + { "debug", L_DEBUG }, + { "default", L_DEFAULT }, + { "deny", L_DENY }, + { "dialup", L_DIALUP }, + { "directory", L_DIRECTORY }, + { "dump-file", L_DUMP_FILE }, + { "dynamic", L_DYNAMIC }, + { "enable-zone", L_ENABLE_ZONE }, + { "expert-mode", L_EXPERT_MODE }, + { "explicit", L_EXPLICIT }, + { "fail", L_FAIL }, + { "fake-iquery", L_FAKE_IQUERY }, + { "false", L_FALSE }, + { "fetch-glue", L_FETCH_GLUE }, + { "file", L_FILE }, + { "files", L_FILES }, + { "first", L_FIRST }, + { "forward", L_FORWARD }, + { "forwarders", L_FORWARDERS }, + { "glue-from-auth", L_GLUE_FROM_AUTH }, + { "glue-from-cache", L_GLUE_FROM_CACHE }, + { "grant", L_GRANT }, + { "group", L_GROUP }, + { "has-old-clients", L_HAS_OLD_CLIENTS }, + { "heartbeat-interval", L_HEARTBEAT }, + { "hint", L_HINT }, + { "host-statistics", L_HOSTSTATS }, + { "if-no-answer", L_IF_NO_ANSWER }, + { "if-no-domain", L_IF_NO_DOMAIN }, + { "ignore", L_IGNORE }, + { "include", L_INCLUDE }, + { "inet", L_INET }, + { "interface-interval", L_INTERFACE_INTERVAL }, + { "internal", L_INTERNAL }, + { "ixfr-base", L_FILE_IXFR }, + { "ixfr-tmp-file", L_IXFR_TMP }, + { "key", L_SEC_KEY }, + { "keys", L_KEYS }, + { "lame-ttl", L_LAME_TTL }, + { "listen-on", L_LISTEN_ON }, + { "listen-on-v6", L_LISTEN_ON_V6 }, + { "logging", L_LOGGING }, + { "maintain-ixfr-base", L_MAINTAIN_IXFR_BASE }, + { "many-answers", L_MANY_ANSWERS }, + { "master", L_MASTER }, + { "masters", L_MASTERS }, + { "match-clients", L_MATCH_CLIENTS }, + { "max-cache-size", L_MAX_CACHE_SIZE }, + { "max-cache-ttl", L_MAX_CACHE_TTL }, + { "max-ixfr-log-size", L_MAX_LOG_SIZE_IXFR }, + { "max-ncache-ttl", L_MAX_NCACHE_TTL }, + { "max-transfer-idle-in", L_MAX_TRANSFER_IDLE_IN }, + { "max-transfer-idle-out", L_MAX_TRANSFER_IDLE_OUT }, + { "max-transfer-time-in", L_MAX_TRANSFER_TIME_IN }, + { "max-transfer-time-out", L_MAX_TRANSFER_TIME_OUT }, + { "maximal", L_MAXIMAL }, + { "memstatistics-file", L_MEMSTATS_FILE }, + { "min-roots", L_MIN_ROOTS }, + { "minimal", L_MINIMAL }, + { "multiple-cnames", L_MULTIPLE_CNAMES }, + { "name", L_NAME }, + { "named-xfer", L_NAMED_XFER }, + { "no", L_NO }, + { "notify", L_NOTIFY }, + { "null", L_NULL_OUTPUT }, + { "one-answer", L_ONE_ANSWER }, + { "only", L_ONLY }, + { "options", L_OPTIONS }, + { "order", L_ORDER }, + { "owner", L_OWNER }, + { "perm", L_PERM }, + { "pid-file", L_PIDFILE }, + { "port", L_PORT }, + { "print-category", L_PRINT_CATEGORY }, + { "print-severity", L_PRINT_SEVERITY }, + { "print-time", L_PRINT_TIME }, + { "provide-ixfr", L_PROVIDE_IXFR }, + { "pubkey", L_PUBKEY }, + { "query-source", L_QUERY_SOURCE }, + { "query-source-v6", L_QUERY_SOURCE_V6 }, + { "random-device", L_RANDOM_DEVICE }, + { "random-seed-file", L_RANDOM_SEED_FILE }, + { "recursion", L_RECURSION }, + { "recursive-clients", L_RECURSIVE_CLIENTS }, + { "request-ixfr", L_REQUEST_IXFR }, + { "response", L_RESPONSE }, + { "rfc2308-type1", L_RFC2308_TYPE1 }, + { "rrset-order", L_RRSET_ORDER }, + { "secret", L_SECRET }, + { "self", L_SELF }, + { "serial-queries", L_SERIAL_QUERIES }, + { "server", L_SERVER }, + { "severity", L_SEVERITY }, + { "sig-validity-interval", L_SIG_VALIDITY_INTERVAL }, + { "size", L_SIZE }, + { "slave", L_SLAVE }, + { "sortlist", L_SORTLIST }, + { "stacksize", L_STACKSIZE }, + { "statistics-file", L_STATS_FILE }, + { "statistics-interval", L_STATS_INTERVAL }, + { "stderr", L_STDERR }, + { "stub", L_STUB }, + { "subdomain", L_SUBDOMAIN }, + { "support-ixfr", L_SUPPORT_IXFR }, + { "syslog", L_SYSLOG }, + { "tcp-clients", L_TCP_CLIENTS }, + { "tkey-dhkey", L_TKEY_DHKEY }, + { "tkey-domain", L_TKEY_DOMAIN }, + { "topology", L_TOPOLOGY }, + { "transfer-format", L_TRANSFER_FORMAT }, + { "transfer-source", L_TRANSFER_SOURCE }, + { "transfer-source-v6", L_TRANSFER_SOURCE_V6 }, + { "transfers", L_TRANSFERS }, + { "transfers-in", L_TRANSFERS_IN }, + { "transfers-out", L_TRANSFERS_OUT }, + { "transfers-per-ns", L_TRANSFERS_PER_NS }, + { "treat-cr-as-space", L_TREAT_CR_AS_SPACE }, + { "true", L_TRUE }, + { "trusted-keys", L_TRUSTED_KEYS }, + { "type", L_TYPE }, + { "unix", L_UNIX }, + { "unlimited", L_UNLIMITED }, + { "update-policy", L_UPDATE_POLICY }, + { "use-id-pool", L_USE_ID_POOL }, + { "use-ixfr", L_USE_IXFR }, + { "version", L_VERSION }, + { "versions", L_VERSIONS }, + { "view", L_VIEW }, + { "warn", L_WARN }, + { "wildcard", L_WILDCARD }, + { "yes", L_YES }, + { "zone", L_ZONE }, + + { NULL, 0 } +}; + + +static struct token class_symbol_tokens[] = { + { "IN", dns_rdataclass_in }, +#if 0 /* XXX expand */ + { "CHAOS", dns_rdataclass_chaos }, + { "HS", dns_rdataclass_hs }, + { "HESIOD", dns_rdataclass_hs }, +#endif + { "ANY", dns_rdataclass_any }, + { "NONE", dns_rdataclass_none }, + { NULL, 0 } +}; + + +static isc_once_t once = ISC_ONCE_INIT; + + +static void +init_action(void) +{ + isc_mutex_init(&yacc_mutex); +} + + +/* + * XXX Need a parameter to specify where error messages should go (syslog, + * FILE, /dev/null etc.) Also some way to tell the function to obey logging + * statments as appropriate. + */ + +isc_result_t +dns_c_parse_namedconf(const char *filename, isc_mem_t *mem, + dns_c_ctx_t **configctx, dns_c_cbks_t *cbks) +{ + isc_result_t res; + const char *funcname = "dns_parse_namedconf"; + + RUNTIME_CHECK(isc_once_do(&once, init_action) == ISC_R_SUCCESS); + + /* Lock down whole parser. */ + if (isc_mutex_lock(&yacc_mutex) != ISC_R_SUCCESS) { + return (ISC_R_UNEXPECTED); + } + + REQUIRE(currcfg == NULL); + REQUIRE(filename != NULL); + REQUIRE(*filename != '\0'); + REQUIRE(configctx != NULL); + INSIST(mylexer == NULL); + INSIST(memctx == NULL); + INSIST(keywords == NULL); + INSIST(callbacks == NULL); + + specials['{'] = 1; + specials['}'] = 1; + specials[';'] = 1; + specials['/'] = 1; + specials['"'] = 1; + specials['!'] = 1; + + default_port = DNS_C_DEFAULTPORT; + + /* + * This memory context is only used by the lexer routines (and must + * stay that way). Any memory that must live past the return of + * yyparse() must be allocated via the 'mem' parameter to this + * function. + */ + res = isc_mem_create(0, 0, &memctx); + if (res != ISC_R_SUCCESS) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG, + DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL, + "%s: Error creating mem context", + funcname); + goto done; + } + + res = keyword_init(); + if (res != ISC_R_SUCCESS) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG, + DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL, + "%s: Error initializing keywords", + funcname); + goto done; + } + + res = dns_c_ctx_new(mem, &currcfg); + if (res != ISC_R_SUCCESS) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG, + DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL, + "%s: Error creating config context", + funcname); + goto done; + } + + res = isc_lex_create(memctx, CONF_MAX_IDENT, &mylexer); + if (res != ISC_R_SUCCESS) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG, + DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL, + "%s: Error creating lexer", + funcname); + goto done; + } + + isc_lex_setspecials(mylexer, specials); + isc_lex_setcomments(mylexer, (ISC_LEXCOMMENT_C | + ISC_LEXCOMMENT_CPLUSPLUS | + ISC_LEXCOMMENT_SHELL)); + + res = isc_lex_openfile(mylexer, filename); + if (res != ISC_R_SUCCESS) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG, + DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL, + "%s: open: %s", filename, + isc_result_totext(res)); + goto done; + } + + callbacks = cbks; + + if (yyparse() != 0) { + res = ISC_R_FAILURE; + + /* + * Syntax errors in the config file make it very difficult + * to clean up memory properly (which causes assertion + * failure when the memory manager is destroyed). + */ + isc_mem_setdestroycheck(memctx, ISC_FALSE); + + dns_c_ctx_delete(&currcfg); + currcfg = NULL; + } else { + res = ISC_R_SUCCESS; + } + + + done: + if (mylexer != NULL) + isc_lex_destroy(&mylexer); + + isc_symtab_destroy(&keywords); + + isc_mem_destroy(&memctx); + + if (res == ISC_R_SUCCESS) { + res = dns_c_checkconfig(currcfg); + if (res != ISC_R_SUCCESS) { + dns_c_ctx_delete(&currcfg); + } + } + + *configctx = currcfg; + + callbacks = NULL; + currcfg = NULL; + memctx = NULL; + mylexer = NULL; + + RUNTIME_CHECK(isc_mutex_unlock(&yacc_mutex) == ISC_R_SUCCESS); + + return (res); +} + + + +/*** + *** PRIVATE + ***/ + +static isc_result_t +keyword_init(void) +{ + struct token *tok; + isc_symvalue_t symval; + + RUNTIME_CHECK(isc_symtab_create(memctx, 97 /* prime < 100 */, + NULL, NULL, ISC_FALSE, + &keywords) == ISC_R_SUCCESS); + + + /* Stick all the keywords into the main symbol table. */ + for (tok = &keyword_tokens[0] ; tok->token != NULL ; tok++) { + symval.as_integer = tok->yaccval; + RUNTIME_CHECK(isc_symtab_define(keywords, tok->token, + KEYWORD_SYM_TYPE, symval, + isc_symexists_reject) == + ISC_R_SUCCESS); + } + + /* Now the class names */ + for (tok = &class_symbol_tokens[0] ; tok->token != NULL ; tok++) { + symval.as_integer = tok->yaccval; + RUNTIME_CHECK(isc_symtab_define(keywords, tok->token, + CLASS_SYM_TYPE, symval, + isc_symexists_reject) == + ISC_R_SUCCESS); + } + + return (ISC_R_SUCCESS); +} + + + +static int +yylex(void) +{ + isc_token_t token; + isc_result_t res; + int options = (ISC_LEXOPT_EOF | + ISC_LEXOPT_NUMBER | + ISC_LEXOPT_CNUMBER | + ISC_LEXOPT_QSTRING | + ISC_LEXOPT_NOMORE); + + INSIST(mylexer != NULL); + + res = isc_lex_gettoken(mylexer, options, &token); + + switch(res) { + case ISC_R_SUCCESS: + res = token_value(&token, keywords); /* modifies yylval */ + break; + + case ISC_R_EOF: + res = 0; + break; + + case ISC_R_UNBALANCED: + parser_error(ISC_TRUE, + "%s: %lu: unbalanced parentheses", + isc_lex_getsourcename(mylexer), + isc_lex_getsourceline(mylexer)); + res = -1; + break; + + case ISC_R_NOSPACE: + parser_error(ISC_TRUE, + "%s: %lu: token too big", + isc_lex_getsourcename(mylexer), + isc_lex_getsourceline(mylexer)); + res = -1; + break; + + case ISC_R_UNEXPECTEDEND: + parser_error(ISC_TRUE, + "%s: %lu: unexpected EOF", + isc_lex_getsourcename(mylexer), + isc_lex_getsourceline(mylexer)); + res = -1; + break; + + default: + parser_error(ISC_TRUE, + "%s: %lu unknown lexer error (%d)", + isc_lex_getsourcename(mylexer), + isc_lex_getsourceline(mylexer), + (int)res); + res = -1; + break; + } + + + lastyylval = yylval; + lasttoken = res; + + return (res); +} + + + +static char * +token_to_text(int token, YYSTYPE lval) { + static char buffer[1024]; + const char *tk; + + /* + * Yacc keeps token numbers above 128, it seems. + */ + if (token < 128) { + if (token == 0) + strncpy(buffer, "", sizeof buffer); + else + if ((unsigned int) sprintf(buffer, "'%c'", token) + >= sizeof buffer) { + abort(); + } + } else { + switch (token) { + case L_STRING: + if ((unsigned int) sprintf(buffer, "'%s'", + lval.text) >= + sizeof buffer) { + abort(); + } + break; + case L_QSTRING: + if ((unsigned int) sprintf(buffer, "\"%s\"", + lval.text) >= + sizeof buffer) { + abort(); + } + break; + case L_IP6ADDR: + strcpy(buffer, "UNAVAILABLE-IPV6-ADDRESS"); + inet_ntop(AF_INET6, lval.ip6_addr.s6_addr, + buffer, sizeof buffer); + break; + case L_IP4ADDR: + strcpy(buffer, "UNAVAILABLE-IPV4-ADDRESS"); + inet_ntop(AF_INET, &lval.ip4_addr.s_addr, + buffer, sizeof buffer); + break; + case L_INTEGER: + sprintf(buffer, "%lu", (unsigned long)lval.ul_int); + break; + case L_END_INCLUDE: + strcpy (buffer, ""); + break; + default: + tk = token_to_keyword(token); + if (tk == NULL) { + sprintf(buffer, "UNKNOWN-TOKEN-TYPE (%d)", + (int)token); + } else { + strncpy(buffer, tk, sizeof buffer - 1); + buffer[sizeof buffer - 1] = '\0'; + } + break; + } + } + + return (buffer); +} + +static const char * +token_to_keyword(int token) { + int i; + + for (i = 0 ; keyword_tokens[i].token != NULL ; i++) { + if (keyword_tokens[i].yaccval == token) { + break; + } + } + + return (keyword_tokens[i].token); +} + + + +static void +parser_complain(isc_boolean_t is_warning, isc_boolean_t print_last_token, + const char *format, va_list args) +{ + static char where[ISC_DIR_PATHMAX + 100]; + static char message[2048]; + int level = ISC_LOG_ERROR; + const char *filename = isc_lex_getsourcename(mylexer); + unsigned long lineno = isc_lex_getsourceline(mylexer); + + /* + * We can't get a trace of the include files we may be nested in + * (lex.c has the structures hidden). So we only report the current + * file. + */ + if (filename == NULL) { + filename = "(none)"; + } + + if (is_warning) { + level = ISC_LOG_WARNING; + } + + sprintf(where, "%s:%lu: ", filename, lineno); + if ((unsigned int)vsprintf(message, format, args) >= sizeof message) + FATAL_ERROR(__FILE__, __LINE__, + "error message would overflow"); + + if (print_last_token) { + if (dns_lctx != NULL) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG, + DNS_LOGMODULE_CONFIG, level, + "%s%s near '%s'", where, message, + token_to_text(lasttoken, lastyylval)); + } else { + fprintf(stderr, "%s%s near '%s'\n", where, message, + token_to_text(lasttoken, lastyylval)); + } + } else { + if (dns_lctx != NULL) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG, + DNS_LOGMODULE_CONFIG, level, + "%s%s", where, message); + } else { + fprintf(stderr, "%s%s\n", where, message); + } + } +} + + + + +/* + * For reporting items that are semantic, but not syntactic errors + */ +static void +parser_error(isc_boolean_t lasttoken, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + parser_complain(ISC_TRUE, lasttoken, fmt, args); + va_end(args); + + currcfg->errors++; +} + + +static void +parser_warning(isc_boolean_t lasttoken, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + parser_complain(ISC_FALSE, lasttoken, fmt, args); + va_end(args); + + currcfg->warnings++; +} + + +static isc_boolean_t +int_too_big(isc_uint32_t base, isc_uint32_t mult) { + isc_uint32_t max = UINT_MAX; + + if ((max / mult) < base) { + return ISC_TRUE; + } else { + return ISC_FALSE; + } +} + + +static void +yyerror(const char *string) +{ + parser_error(ISC_TRUE, string); +} + + + +static int +token_value(isc_token_t *token, isc_symtab_t *symtable) +{ + int res = -1; + const char *tokstring; + char tmpident [2]; + isc_symvalue_t keywordtok; + + switch (token->type) { + case isc_tokentype_unknown: + res = -1; + break; + + case isc_tokentype_special: + case isc_tokentype_string: + if (token->type == isc_tokentype_special) { + tmpident[0] = token->value.as_char; + tmpident[1] = '\0'; + tokstring = tmpident; + } else { + tokstring = token->value.as_textregion.base; + } + + res = isc_symtab_lookup(symtable, tokstring, + KEYWORD_SYM_TYPE, &keywordtok); + + if (res != ISC_R_SUCCESS) { + res = intuit_token(tokstring); + } else { + res = keywordtok.as_integer; + } + break; + + case isc_tokentype_number: + yylval.ul_int = (isc_uint32_t)token->value.as_ulong; + res = L_INTEGER; + break; + + case isc_tokentype_qstring: + yylval.text = isc_mem_strdup(memctx, + token->value.as_textregion.base); + if (yylval.text == NULL) { + res = -1; + } else { + res = L_QSTRING; + } + break; + + case isc_tokentype_eof: + res = isc_lex_close(mylexer); + INSIST(res == ISC_R_NOMORE || res == ISC_R_SUCCESS); + + if (isc_lex_getsourcename(mylexer) == NULL) { + /* the only way to tell that we + * closed the main file and not an included file + */ + res = 0; + } else { + res = L_END_INCLUDE; + } + break; + + case isc_tokentype_initialws: + res = -1; + break; + + case isc_tokentype_eol: + res = -1; + break; + + case isc_tokentype_nomore: + res = -1; + break; + } + + return (res); +} + + + + +static int +intuit_token(const char *string) +{ + int resval; + + if (is_ip4addr(string, &yylval.ip4_addr)) { + resval = L_IP4ADDR; + } else if (is_ip6addr(string, &yylval.ip6_addr)) { + resval = L_IP6ADDR; + } else { + yylval.text = isc_mem_strdup(memctx, string); + if (yylval.text == NULL) { + resval = -1; + } else { + resval = L_STRING; + } + } + + return (resval); +} + + +/* + * Conversion Routines + */ + +static isc_result_t +unit_to_uint32(char *in, isc_uint32_t *out) { + char *start = in; + int c, units_done = 0; + isc_uint32_t result = 0L; + isc_uint32_t maxK = 4194304; /* 2^32 / 1024 */ + isc_uint32_t maxM = 4096; /* 2^32 / (1024 * 1024) */ + isc_uint32_t maxG = 4; /* 2^32 / (1024 * 1024 * 1024) */ + + INSIST(in != NULL); + + for (; (c = *in) != '\0'; in++) { + if (units_done) + return (ISC_R_FAILURE); + if (isdigit((unsigned char)c)) { + result *= 10; + result += (c - '0'); + } else { + if (start == in) { + return (ISC_R_FAILURE); + } + switch (c) { + case 'k': + case 'K': + if (result > maxK) { + return (ISC_R_RANGE); + } + result *= 1024; + units_done = 1; + break; + case 'm': + case 'M': + if (result > maxM) { + return (ISC_R_RANGE); + } + result *= (1024*1024); + units_done = 1; + break; + case 'g': + case 'G': + if (result > maxG) { + return (ISC_R_RANGE); + } + result *= (1024*1024*1024); + units_done = 1; + break; + default: + return (ISC_R_FAILURE); + } + } + } + + *out = result; + return (ISC_R_SUCCESS); +} + + +static isc_boolean_t +is_ip6addr(const char *string, struct in6_addr *addr) +{ + if (inet_pton(AF_INET6, string, addr) != 1) { + return ISC_FALSE; + } + return ISC_TRUE; +} + + + +static isc_boolean_t +is_ip4addr(const char *string, struct in_addr *addr) +{ + char addrbuf[sizeof "xxx.xxx.xxx.xxx" + 1]; + const char *p = string; + int dots = 0; + char dot = '.'; + + while (*p) { + if (!isdigit(*p & 0xff) && *p != dot) { + return (ISC_FALSE); + } else if (!isdigit(*p & 0xff)) { + dots++; + } + p++; + } + + if (dots > 3) { + return (ISC_FALSE); + } else if (dots < 3) { + if (dots == 1) { + if (strlen(string) + 5 <= sizeof (addrbuf)) { + strcpy(addrbuf, string); + strcat(addrbuf, ".0.0"); + } else { + return (ISC_FALSE); + } + } else if (dots == 2) { + if (strlen(string) + 3 <= sizeof (addrbuf)) { + strcpy(addrbuf, string); + strcat(addrbuf, ".0"); + } else { + return (ISC_FALSE); + } + } + } else if (strlen(string) < sizeof addrbuf) { + strcpy (addrbuf, string); + } else { + return (ISC_FALSE); + } + + if (inet_pton(AF_INET, addrbuf, addr) != 1) { + return ISC_FALSE; + } + return ISC_TRUE; +} + + + +static dns_peerlist_t * +currentpeerlist(dns_c_ctx_t *cfg, isc_boolean_t createIfNeeded) +{ + dns_peerlist_t *peers = NULL; + dns_c_view_t *view = NULL; + isc_result_t result; + + view = dns_c_ctx_getcurrview(cfg); + + if (view == NULL) { + result = dns_c_ctx_getpeerlist(cfg, &peers); + } else { + result = dns_c_view_getpeerlist(view, &peers); + } + + if (result == ISC_R_NOTFOUND && createIfNeeded) { + result = dns_peerlist_new(currcfg->mem, &peers); + if (tmpres != ISC_R_SUCCESS) { + parser_error(ISC_FALSE, "failed to create peer list"); + return NULL; + } + + if (view == NULL) { + dns_c_ctx_setpeerlist(currcfg, peers); + } else { + dns_c_view_setpeerlist(view, peers); + } + } else if (result == ISC_R_NOTFOUND) { + /* nothing */ + } else if (result != ISC_R_SUCCESS) { + REQUIRE(result == ISC_R_SUCCESS); + } + + return peers; +} + + + +static isc_boolean_t +keydefinedinscope(dns_c_ctx_t *cfg, const char *name) +{ + dns_c_view_t *view = dns_c_ctx_getcurrview(cfg); + isc_boolean_t rval = ISC_FALSE; + + if (view != NULL) { + rval = dns_c_view_keydefinedp(view, name); + } + + if (!rval) { + rval = dns_c_ctx_keydefinedp(cfg, name); + } + + return (rval); +} + + + + diff --git a/lib/dns/include/dns/confip.h b/lib/dns/include/dns/confip.h index 4d6833f239..93b4aadfa7 100644 --- a/lib/dns/include/dns/confip.h +++ b/lib/dns/include/dns/confip.h @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: confip.h,v 1.23 2000/07/21 21:25:00 brister Exp $ */ +/* $Id: confip.h,v 1.24 2000/07/26 18:47:41 mws Exp $ */ #ifndef DNS_CONFIP_H #define DNS_CONFIP_H 1 @@ -95,7 +95,9 @@ struct dns_c_iplist { isc_mem_t *mem; int refcount; isc_sockaddr_t *ips; +#ifndef NOMINUM_PUBLIC dns_name_t **keys; +#endif /* NOMINUM_PUBLIC */ isc_uint32_t size; isc_uint32_t nextidx; }; @@ -227,12 +229,19 @@ isc_result_t dns_c_iplist_detach(dns_c_iplist_t **list); isc_result_t dns_c_iplist_copy(isc_mem_t *mem, dns_c_iplist_t **dest, dns_c_iplist_t *src); +#ifndef NOMINUM_PUBLIC isc_boolean_t dns_c_iplist_haskeys(dns_c_iplist_t *list); +#endif /* NOMINUM_PUBLIC */ void dns_c_iplist_attach(dns_c_iplist_t *source, dns_c_iplist_t **target); +#ifndef NOMINUM_PUBLIC isc_result_t dns_c_iplist_append(dns_c_iplist_t *list, isc_sockaddr_t newaddr, const char *key); +#else /* NOMINUM_PUBLIC */ +isc_result_t dns_c_iplist_append(dns_c_iplist_t *list, + isc_sockaddr_t newaddr, const char *key); +#endif /* NOMINUM_PUBLIC */ isc_result_t dns_c_iplist_remove(dns_c_iplist_t *list, isc_sockaddr_t newaddr); diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index e7d95216be..676032f983 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: zone.h,v 1.61 2000/07/24 22:59:44 explorer Exp $ */ +/* $Id: zone.h,v 1.62 2000/07/26 18:47:42 mws Exp $ */ #ifndef DNS_ZONE_H #define DNS_ZONE_H 1 @@ -351,9 +351,11 @@ dns_zone_maintenance(dns_zone_t *zone); isc_result_t dns_zone_setmasters(dns_zone_t *zone, isc_sockaddr_t *masters, isc_uint32_t count); +#ifndef NOMINUM_PUBLIC isc_result_t dns_zone_setmasterswithkeys(dns_zone_t *zone, isc_sockaddr_t *masters, dns_name_t **keynames, isc_uint32_t count); +#endif /* NOMINUM_PUBLIC */ /* * Set the list of master servers for the zone. * @@ -361,17 +363,21 @@ dns_zone_setmasterswithkeys(dns_zone_t *zone, isc_sockaddr_t *masters, * 'zone' to be a valid zone. * 'masters' array of isc_sockaddr_t with port set or NULL. * 'count' the number of masters. +#ifndef NOMINUM_PUBLIC * 'keynames' array of dns_name_t's for tsig keys or NULL. * * dns_zone_setmasters() is just a wrapper to setmasterswithkeys(), * passing NULL in the keynames field. +#endif NOMINUM_PUBLIC * * If 'masters' is NULL then 'count' must be zero. * * Returns: * ISC_R_SUCCESS * ISC_R_NOMEMORY +#ifndef NOMINUM_PUBLIC * Any result dns_name_dup() can return, if keynames!=NULL +#endif NOMINUM_PUBLIC */ isc_result_t diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 5f3a596bf0..788dbbdddc 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: zone.c,v 1.167 2000/07/25 19:29:00 mws Exp $ */ +/* $Id: zone.c,v 1.168 2000/07/26 18:47:32 mws Exp $ */ #include @@ -132,7 +132,9 @@ struct dns_zone { isc_uint32_t expire; isc_uint32_t minimum; isc_sockaddr_t *masters; +#ifndef NOMINUM_PUBLIC dns_name_t **masterkeynames; +#endif /* NOMINUM_PUBLIC */ unsigned int masterscnt; unsigned int curmaster; isc_sockaddr_t masteraddr; @@ -362,7 +364,9 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { zone->expire = 0; zone->minimum = 0; zone->masters = NULL; +#ifndef NOMINUM_PUBLIC zone->masterkeynames = NULL; +#endif /* NOMINUM_PUBLIC */ zone->masterscnt = 0; zone->curmaster = 0; zone->notify = NULL; @@ -439,7 +443,11 @@ zone_free(dns_zone_t *zone) { if (zone->db != NULL) dns_db_detach(&zone->db); dns_zone_cleardbargs(zone); +#ifndef NOMINUM_PUBLIC dns_zone_setmasterswithkeys(zone, NULL, NULL, 0); +#else /* NOMINUM_PUBLIC */ + dns_zone_setmasters(zone, NULL, 0); +#endif /* NOMINUM_PUBLIC */ dns_zone_setalsonotify(zone, NULL, 0); zone->check_names = dns_severity_ignore; if (zone->update_acl != NULL) @@ -1271,6 +1279,7 @@ dns_zone_setalsonotify(dns_zone_t *zone, isc_sockaddr_t *notify, return (ISC_R_SUCCESS); } +#ifndef NOMINUM_PUBLIC isc_result_t dns_zone_setmasters(dns_zone_t *zone, isc_sockaddr_t *masters, isc_uint32_t count) @@ -1284,24 +1293,34 @@ dns_zone_setmasters(dns_zone_t *zone, isc_sockaddr_t *masters, isc_result_t dns_zone_setmasterswithkeys(dns_zone_t *zone, isc_sockaddr_t *masters, dns_name_t **keynames, isc_uint32_t count) +#else /* NOMINUM_PUBLIC */ +isc_result_t +dns_zone_setmasters(dns_zone_t *zone, isc_sockaddr_t *masters, + isc_uint32_t count) +#endif /* NOMINUM_PUBLIC */ { isc_sockaddr_t *new; - dns_name_t **newname; isc_result_t result = ISC_R_SUCCESS; +#ifndef NOMINUM_PUBLIC + dns_name_t **newname; unsigned int i; +#endif /* NOMINUM_PUBLIC */ REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(count == 0 || masters != NULL); +#ifndef NOMINUM_PUBLIC if (keynames != NULL) { REQUIRE(count != 0); } - +#endif /* NOMINUM_PUBLIC */ + LOCK(&zone->lock); if (zone->masters != NULL) { isc_mem_put(zone->mctx, zone->masters, zone->masterscnt * sizeof *new); zone->masters = NULL; } +#ifndef NOMINUM_PUBLIC if (zone->masterkeynames != NULL) { for (i = 0; i < zone->masterscnt; i++) { if (zone->masterkeynames[i] != NULL) { @@ -1317,6 +1336,7 @@ dns_zone_setmasterswithkeys(dns_zone_t *zone, isc_sockaddr_t *masters, zone->masterscnt * sizeof(dns_name_t *)); zone->masterkeynames = NULL; } +#endif /* NOMINUM_PUBLIC */ zone->masterscnt = 0; /* * If count == 0, don't allocate any space for masters or keynames @@ -1339,6 +1359,7 @@ dns_zone_setmasterswithkeys(dns_zone_t *zone, isc_sockaddr_t *masters, zone->masterscnt = count; zone->flags &= ~DNS_ZONEFLG_NOMASTERS; +#ifndef NOMINUM_PUBLIC /* * if keynames is non-NULL, it must contain count elements! */ @@ -1379,6 +1400,7 @@ dns_zone_setmasterswithkeys(dns_zone_t *zone, isc_sockaddr_t *masters, } zone->masterkeynames = newname; } +#endif /* NOMINUM_PUBLIC */ unlock: UNLOCK(&zone->lock); return (result); @@ -4044,6 +4066,9 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) { /* * Determine if we should attempt to sign the request with TSIG. + */ +#ifndef NOMINUM_PUBLIC + /* * First, look for a tsig key in the master statement, then * try for a server key. */ @@ -4053,7 +4078,9 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) { keyname = zone->masterkeynames[zone->curmaster]; gotkey = ISC_TRUE; } - else if (peer != NULL && + else +#endif /* NOMINUM_PUBLIC */ + if (peer != NULL && dns_peer_getkey(peer, &keyname) == ISC_R_SUCCESS) { view = dns_zone_getview(zone); gotkey = ISC_TRUE; diff --git a/lib/dns/zoneconf.c b/lib/dns/zoneconf.c index 88da4f7745..7fcfcdc6df 100644 --- a/lib/dns/zoneconf.c +++ b/lib/dns/zoneconf.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: zoneconf.c,v 1.47 2000/07/25 20:26:11 bwelling Exp $ */ +/* $Id: zoneconf.c,v 1.48 2000/07/26 18:47:34 mws Exp $ */ #include @@ -272,10 +272,15 @@ dns_zone_configure(dns_c_ctx_t *cctx, dns_c_view_t *cview, iplist = NULL; result = dns_c_zone_getmasterips(czone, &iplist); if (result == ISC_R_SUCCESS) +#ifndef NOMINUM_PUBLIC result = dns_zone_setmasterswithkeys(zone, iplist->ips, iplist->keys, iplist->nextidx); +#else /* NOMINUM_PUBLIC */ + result = dns_zone_setmasters(zone, iplist->ips, + iplist->nextidx); +#endif /* NOMINUM_PUBLIC */ else result = dns_zone_setmasters(zone, NULL, 0); RETERR(result); diff --git a/util/sanitize.pl b/util/sanitize.pl new file mode 100644 index 0000000000..3fc9b3154e --- /dev/null +++ b/util/sanitize.pl @@ -0,0 +1,163 @@ +#!/usr/bin/perl +# +# Copyright (C) 1999, 2000 Internet Software Consortium. +# +# Permission to use, copy, modify, and 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. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS +# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE +# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +# SOFTWARE. + +# $Id: sanitize.pl,v 1.1 2000/07/26 18:47:43 mws Exp $ + +# Don't try and sanitize this file: NOMINUM_IGNORE + +# Go through the directory tree and make sure that all of the files are +# sanitized. +# +# In normal mode, check file, removing code between +# #ifndef NOMINUM_PUBLIC +# and the accompanying #else or #endif. Similarly, code in an #else +# clause after an #ifndef test will be removed. The #else or #endif's +# must appear as: +# #else /* NOMINUM_PUBLIC */ +# #endif /* NOMINUM_PUBLIC */ +# Balance is tested. +# Non-.c/.h files are tested for the existance of NOMINUM_PUBLIC anywhere +# in the file, and a warning is generated, unless the string +# NOMINUM_IGNORE appears before NOMINUM_PUBLIC. + +# Usage: +# ./sanitize.pl -c - Check syntax only, don't change anything +# ./sanitize.pl -i - Reverse sense of sanitize. +# ./sanitize.pl - - Work as a pipe, sanitizing stdin to stdout. +# ./sanitize.pl file - Sanitize the specified file. + +$makechange = 1; +$state = 0; +$showon = 1; +$debug = 0; + +# States: +# 0 - Outside of test, include code +# 1 - Inside NOMINUM_PUBLIC +# 2 - Inside !NOMINUM_PUBLIC + +foreach $arg (@ARGV) { + $_ = $arg; + if (/^-c$/i) { + $makechange = 0; + } + elsif (/^-i$/i) { + $showon = 2; + } + elsif (/^-$/i) { + &runfile("-","-"); + } +# elsif (/^-a$/i) { +# &rundir(); +# } + elsif (/^-d$/i) { + $debug = 1; + } + else { + &runfile($arg, $arg.".sanitize"); + } +} +exit(0); + + +sub runfile($) { + $state = 0; + open(INFILE, $_[0]) || die ("$_[0]"); + open(OUTFILE, ">$_[1]") || die ("$_[1]") + if ($makechange); + while () { + if (/NOMINUM_IGNORE/) { + close(INFILE); + close(OUTFILE); + unlink($_[1]); + break; + } + if (/\#ifdef.+NOMINUM_PUBLIC/) { + if ($state != 0) { + print(STDERR "*** ERROR in file $_[0]: ". + "Found #ifdef without matching ". + "#endif.\n"); + close(INFILE); + close(OUTFILE) if ($makechange); + unlink($_[1]); + break; + } + $state = 1; + } + elsif (/\#ifndef.+NOMINUM_PUBLIC/) { + if ($state != 0) { + print(STDERR "*** ERROR in file $_[0]: ". + "Found #ifndef without matching ". + "#endif.\n"); + close(INFILE); + close(OUTFILE) if ($makechange); + unlink($_[1]); + break; + } + $state = 2; + } + elsif (/\#else.+NOMINUM_PUBLIC/) { + if ($state == 0) { + print(STDERR "*** ERROR in file $_[0]: ". + "Found #else without matching ". + "#if[n]def.\n"); + close(INFILE); + close(OUTFILE) if ($makechange); + unlink($_[1]); + break; + } + if ($state == 1) { + $state = 2; + } else { + $state = 1; + } + } + elsif (/\#endif.+NOMINUM_PUBLIC/) { + if ($state == 0) { + print(STDERR "*** ERROR in file $_[0]: ". + "Found #else without matching ". + "#if[n]def.\n"); + close(INFILE); + close(OUTFILE) if ($makechange); + unlink($_[1]); + break; + } + $state = 0; + } + elsif (/NOMINUM_PUBLIC/) { + print(STDERR "*** WARNING in file $_[0]: ". + "Found NOMINUM_PUBLIC outside of ". + "#ifdef/#else/#endif.\n"); + } + else { + if (($state == 0) || ($state == $showon)) { + print(OUTFILE) if ($makechange); + } + } + } + if ($state != 0) { + print(STDERR "*** ERROR in file $_[0]: ". + "File ended with unterminated test.\n"); + } else { + close(INFILE); + close(OUTFILE) if ($makechange); + if (($_[0] ne "-") && ($makechange)) { + unlink($_[0]) || die "Unlink $_[0]:"; + rename($_[1], $_[0]) || die "Rename $_[1] to $_[0]:"; + } + } +} diff --git a/util/sanitize_all.sh b/util/sanitize_all.sh new file mode 100755 index 0000000000..55f385e5fe --- /dev/null +++ b/util/sanitize_all.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# +# Copyright (C) 2000 Internet Software Consortium. +# +# Permission to use, copy, modify, and 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. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS +# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE +# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +# SOFTWARE. + +# $Id: sanitize_all.sh,v 1.1 2000/07/26 18:47:43 mws Exp $ + +# Run this shell script from a CVS export'ed source tree, and it will +# sanitize all of the files in that tree. + +find . -name '*.[ch]' | xargs perl util/sanitize.pl $* +find . -name '*.in' | xargs perl util/sanitize.pl $* +for file in `find . -name '*.dirty'` +do + perl util/sanitize.pl - < $file > ${file/.dirty/} + rm $file +done +