summaryrefslogtreecommitdiff
path: root/lib/dns/config
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dns/config')
-rw-r--r--lib/dns/config/.cvsignore3
-rw-r--r--lib/dns/config/Makefile.in67
-rw-r--r--lib/dns/config/confacl.c416
-rw-r--r--lib/dns/config/confcache.c48
-rw-r--r--lib/dns/config/confcommon.c553
-rw-r--r--lib/dns/config/confctl.c267
-rw-r--r--lib/dns/config/confctx.c4424
-rw-r--r--lib/dns/config/confip.c1044
-rw-r--r--lib/dns/config/confkeys.c1177
-rw-r--r--lib/dns/config/conflog.c1345
-rw-r--r--lib/dns/config/conflsn.c213
-rw-r--r--lib/dns/config/confparser.y4508
-rw-r--r--lib/dns/config/confpvt.h41
-rw-r--r--lib/dns/config/confresolv.c47
-rw-r--r--lib/dns/config/confrrset.c300
-rw-r--r--lib/dns/config/confserv.c414
-rw-r--r--lib/dns/config/confview.c1056
-rw-r--r--lib/dns/config/confzone.c3596
18 files changed, 19519 insertions, 0 deletions
diff --git a/lib/dns/config/.cvsignore b/lib/dns/config/.cvsignore
new file mode 100644
index 00000000..78fed989
--- /dev/null
+++ b/lib/dns/config/.cvsignore
@@ -0,0 +1,3 @@
+Makefile
+confparser_p.h
+confparser.c
diff --git a/lib/dns/config/Makefile.in b/lib/dns/config/Makefile.in
new file mode 100644
index 00000000..a3206271
--- /dev/null
+++ b/lib/dns/config/Makefile.in
@@ -0,0 +1,67 @@
+# Copyright (C) 1998, 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.
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+@BIND9_INCLUDES@
+
+CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES}
+
+CDEFINES =
+CWARNINGS =
+
+LIBS = @LIBS@
+
+# Alphabetically
+
+OBJS = confparser.@O@ confcommon.@O@ confacl.@O@ confcache.@O@ \
+ confctl.@O@ confctx.@O@ confip.@O@ confkeys.@O@ conflog.@O@ \
+ conflsn.@O@ confresolv.@O@ confrrset.@O@ confserv.@O@ \
+ confview.@O@ confzone.@O@
+
+SRCS = confparser.c confcommon.c confacl.c confcache.c \
+ confctl.c confctx.c confip.c confkeys.c conflog.c \
+ conflsn.c confresolv.c confrrset.c confserv.c \
+ confview.c confzone.c
+
+SUBDIRS =
+TARGETS = ${OBJS}
+
+@BIND9_MAKE_RULES@
+
+##confparser.c: confparser.y
+## ${YACC} -d ${srcdir}/confparser.y
+## rm -f confparser.c confparser_p.h
+## mv y.tab.c confparser.c
+## mv y.tab.h confparser_p.h
+
+## This rule is here during development to help debugging.
+## Remove and uncomment the rule above before release.
+confparser.c: confparser.y
+ ${YACC} -d ${srcdir}/confparser.y
+ rm -f confparser.c confparser_p.h
+ sed -e '/^\#line/d' < y.tab.c > confparser.c
+ rm -f y.tab.c
+ chmod a-w confparser.c
+ mv y.tab.h confparser_p.h
+
+depend: confparser.c
+
+distclean::
+ rm -f confparser.c confparser_p.h
diff --git a/lib/dns/config/confacl.c b/lib/dns/config/confacl.c
new file mode 100644
index 00000000..c7c522c8
--- /dev/null
+++ b/lib/dns/config/confacl.c
@@ -0,0 +1,416 @@
+/*
+ * 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.
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <isc/assertions.h>
+#include <isc/magic.h>
+
+#include <dns/log.h>
+#include <dns/confacl.h>
+#include <dns/confcommon.h>
+
+
+static isc_result_t acl_delete(dns_c_acl_t **aclptr);
+
+
+
+isc_result_t
+dns_c_acltable_new(isc_mem_t *mem, dns_c_acltable_t **newtable)
+{
+ dns_c_acltable_t *table;
+
+ REQUIRE(mem != NULL);
+ REQUIRE(newtable != NULL);
+
+ table = isc_mem_get(mem, sizeof *table);
+ if (table == NULL) {
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Out of memory");
+ return (ISC_R_NOMEMORY);
+ }
+
+ table->mem = mem;
+ table->magic = DNS_C_CONFACLTABLE_MAGIC;
+
+ ISC_LIST_INIT(table->acl_list);
+
+ *newtable = table;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_acltable_delete(dns_c_acltable_t **table)
+{
+ dns_c_acltable_t *acltable;
+ isc_mem_t *mem;
+
+ REQUIRE(table != NULL);
+ REQUIRE(*table != NULL);
+
+ acltable = *table;
+
+ REQUIRE(DNS_C_CONFACLTABLE_VALID(acltable));
+
+ dns_c_acltable_clear(acltable);
+
+ mem = acltable->mem;
+
+ acltable->magic = 0;
+ acltable->mem = NULL;
+
+
+ isc_mem_put(mem, acltable, sizeof *acltable);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+void
+dns_c_acltable_print(FILE *fp, int indent, dns_c_acltable_t *table)
+{
+ dns_c_acl_t *acl;
+ dns_c_acl_t *acltmp;
+
+ REQUIRE(fp != NULL);
+ REQUIRE(indent >= 0);
+
+ if (table == NULL) {
+ return;
+ }
+
+ REQUIRE(DNS_C_CONFACLTABLE_VALID(table));
+
+ acl = ISC_LIST_HEAD(table->acl_list);
+ while (acl != NULL) {
+ acltmp = ISC_LIST_NEXT(acl, next);
+
+ if (!acl->is_special) { /* don't print specials */
+ dns_c_acl_print(fp, indent, acl);
+ fprintf(fp, "\n");
+ }
+
+ acl = acltmp;
+ }
+}
+
+
+isc_result_t
+dns_c_acltable_clear(dns_c_acltable_t *table)
+{
+ dns_c_acl_t *elem;
+ dns_c_acl_t *tmpelem;
+ isc_result_t r;
+
+ REQUIRE(DNS_C_CONFACLTABLE_VALID(table));
+
+ elem = ISC_LIST_HEAD(table->acl_list);
+ while (elem != NULL) {
+ tmpelem = ISC_LIST_NEXT(elem, next);
+ ISC_LIST_UNLINK(table->acl_list, elem, next);
+
+ r = acl_delete(&elem);
+ if (r != ISC_R_SUCCESS) {
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG,
+ ISC_LOG_CRITICAL,
+ "Failed to delete acl element.");
+ return (r);
+ }
+
+ elem = tmpelem;
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_acltable_getacl(dns_c_acltable_t *table,
+ const char *aclname, dns_c_acl_t **retval)
+{
+ dns_c_acl_t *elem;
+
+ REQUIRE(DNS_C_CONFACLTABLE_VALID(table));
+ REQUIRE(retval != NULL);
+ REQUIRE(aclname != NULL);
+ REQUIRE(strlen(aclname) > 0);
+
+
+ elem = ISC_LIST_HEAD(table->acl_list);
+ while (elem != NULL) {
+ if (strcmp(aclname, elem->name) == 0) {
+ break;
+ }
+
+ elem = ISC_LIST_NEXT(elem, next);
+ }
+
+ if (elem != NULL) {
+ REQUIRE(DNS_C_CONFACL_VALID(elem));
+ *retval = elem;
+ }
+
+ return (elem == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_acltable_removeacl(dns_c_acltable_t *table, const char *aclname)
+{
+ dns_c_acl_t *acl;
+ dns_c_acl_t *tmpacl;
+
+ REQUIRE(DNS_C_CONFACLTABLE_VALID(table));
+ REQUIRE(aclname != NULL);
+
+ acl = ISC_LIST_HEAD(table->acl_list);
+ while (acl != NULL) {
+ tmpacl = ISC_LIST_NEXT(acl, next);
+ if (strcmp(aclname, acl->name) == 0) {
+ ISC_LIST_UNLINK(table->acl_list, acl, next);
+ acl_delete(&acl);
+ return (ISC_R_SUCCESS);
+ }
+
+ acl = tmpacl;
+ }
+
+ return (ISC_R_NOTFOUND);
+}
+
+
+isc_result_t
+dns_c_acl_new(dns_c_acltable_t *table, const char *aclname,
+ isc_boolean_t isspecial, dns_c_acl_t **newacl)
+{
+ dns_c_acl_t *acl;
+
+ REQUIRE(DNS_C_CONFACLTABLE_VALID(table));
+ REQUIRE(aclname != NULL);
+ REQUIRE(strlen(aclname) > 0);
+ REQUIRE(newacl != NULL);
+
+ acl = isc_mem_get(table->mem, sizeof *acl);
+ if (acl == NULL) {
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Not enough memory");
+ return (ISC_R_NOMEMORY);
+ }
+
+ acl->mytable = table;
+ acl->magic = DNS_C_CONFACL_MAGIC;
+ acl->name = NULL;
+ acl->ipml = NULL;
+ acl->is_special = isspecial;
+
+ acl->name = isc_mem_strdup(table->mem, aclname);
+ if (acl->name == NULL) {
+ isc_mem_put(table->mem, acl, sizeof *acl);
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Not enough memory");
+ return (ISC_R_NOMEMORY);
+ }
+
+ ISC_LIST_APPEND(table->acl_list, acl, next);
+
+ *newacl = acl;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+void
+dns_c_acl_print(FILE *fp, int indent, dns_c_acl_t *acl)
+{
+ REQUIRE(DNS_C_CONFACL_VALID(acl));
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "acl ");
+ if (acl->name == NULL) {
+ fprintf(fp, "anon-acl-%p ", acl);
+ } else {
+ fprintf(fp, "%s ", acl->name);
+ }
+
+ if (acl->ipml != NULL) {
+ dns_c_ipmatchlist_print(fp, indent + 1, acl->ipml);
+ } else {
+ fprintf(fp, "{\n");
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "}");
+ }
+ fprintf(fp, ";\n");
+}
+
+
+isc_result_t
+dns_c_acl_setipml(dns_c_acl_t *acl,
+ dns_c_ipmatchlist_t *ipml, isc_boolean_t deepcopy)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFACL_VALID(acl));
+ REQUIRE(ipml != NULL);
+
+ if (acl->ipml != NULL) {
+ dns_c_ipmatchlist_detach(&acl->ipml);
+ }
+
+ if (deepcopy) {
+ res = dns_c_ipmatchlist_copy(acl->mytable->mem,
+ &acl->ipml, ipml);
+ } else {
+ acl->ipml = ipml;
+ res = ISC_R_SUCCESS;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_acl_getipmlexpanded(isc_mem_t *mem, dns_c_acl_t *acl,
+ dns_c_ipmatchlist_t **retval)
+{
+ dns_c_ipmatchlist_t *newlist;
+ isc_result_t r;
+
+ REQUIRE(DNS_C_CONFACL_VALID(acl));
+
+ if (acl->ipml == NULL) {
+ newlist = NULL;
+ r = ISC_R_SUCCESS;
+ } else {
+ r = dns_c_ipmatchlist_copy(mem, &newlist, acl->ipml);
+ if (r != ISC_R_SUCCESS) {
+ return (r);
+ }
+
+ r = dns_c_acl_expandacls(acl->mytable, newlist);
+ }
+
+ *retval = newlist;
+
+ return (r);
+}
+
+
+
+/* XXX this should really be a function in the confip module */
+
+isc_result_t
+dns_c_acl_expandacls(dns_c_acltable_t *table,
+ dns_c_ipmatchlist_t *list)
+{
+ dns_c_ipmatchelement_t *elem;
+ dns_c_ipmatchelement_t *tmpelem;
+ dns_c_acl_t *acl;
+ isc_result_t r;
+ isc_boolean_t isneg;
+
+ REQUIRE(DNS_C_CONFACLTABLE_VALID(table));
+
+ if (list == NULL) {
+ return (ISC_R_SUCCESS);
+ }
+
+ elem = ISC_LIST_HEAD(list->elements);
+ while (elem != NULL) {
+ switch (elem->type) {
+ case dns_c_ipmatch_indirect:
+ dns_c_acl_expandacls(table,
+ elem->u.indirect.list);
+ break;
+
+ case dns_c_ipmatch_acl:
+ r = dns_c_acltable_getacl(table,
+ elem->u.aclname, &acl);
+ if (r != ISC_R_SUCCESS) {
+ return (ISC_R_FAILURE);
+ }
+
+ if (acl->ipml != NULL) {
+ isneg = dns_c_ipmatchelement_isneg(elem);
+
+ /* XXX I this should be inserted in place and
+ * not appended
+ */
+ dns_c_ipmatchlist_append(list,
+ acl->ipml, isneg);
+ }
+
+ default:
+ ; /* Do nothing */
+ }
+
+ tmpelem = ISC_LIST_NEXT(elem, next);
+
+ if (elem->type == dns_c_ipmatch_acl) {
+ ISC_LIST_UNLINK(list->elements, elem, next);
+ }
+
+ elem = tmpelem;
+ }
+
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+
+static isc_result_t
+acl_delete(dns_c_acl_t **aclptr)
+{
+ dns_c_acl_t *acl;
+ isc_result_t res;
+ isc_mem_t *mem;
+
+ REQUIRE(aclptr != NULL);
+ REQUIRE(*aclptr != NULL);
+
+ acl = *aclptr;
+
+ REQUIRE(DNS_C_CONFACL_VALID(acl));
+
+ mem = acl->mytable->mem;
+
+ acl->mytable = NULL;
+
+ isc_mem_free(mem, acl->name);
+
+ if (acl->ipml != NULL)
+ res = dns_c_ipmatchlist_detach(&acl->ipml);
+ else
+ res = ISC_R_SUCCESS;
+
+ acl->magic = 0;
+
+ isc_mem_put(mem, acl, sizeof *acl);
+
+ return (res);
+}
+
+
diff --git a/lib/dns/config/confcache.c b/lib/dns/config/confcache.c
new file mode 100644
index 00000000..5bdb7092
--- /dev/null
+++ b/lib/dns/config/confcache.c
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+#include <config.h>
+
+#include <dns/confcache.h>
+#include <dns/result.h>
+
+#include "confpvt.h"
+
+isc_result_t
+dns_c_cache_new(isc_mem_t *mem, dns_c_cache_t **cfgcache)
+{
+
+ (void) mem ; (void) cfgcache; /* lint */
+
+ /* XXX nothing yet */
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_cache_delete(dns_c_cache_t **cfgcache)
+{
+ (void) cfgcache ; /* lint */
+
+ /* XXX nothin yet */
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
diff --git a/lib/dns/config/confcommon.c b/lib/dns/config/confcommon.c
new file mode 100644
index 00000000..23235835
--- /dev/null
+++ b/lib/dns/config/confcommon.c
@@ -0,0 +1,553 @@
+/*
+ * 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.
+ */
+
+#include <config.h>
+
+#include <sys/types.h> /* XXXRTH */
+
+#include <limits.h>
+#include <syslog.h> /* XXXRTH */
+#include <ctype.h>
+#include <string.h>
+
+#include <isc/assertions.h>
+#include <isc/buffer.h>
+
+/* XXX this next include is needed by <dns/rdataclass.h> */
+#include <dns/result.h>
+
+#include <dns/rdataclass.h>
+#include <dns/rdatatype.h>
+
+#include <dns/confcommon.h>
+
+
+
+/***
+ *** TYPES
+ ***/
+
+#define ordering_nametable_size \
+ (sizeof (ordering_nametable) / sizeof (struct dns_c_pvt_ont))
+static struct dns_c_pvt_ont {
+ dns_c_ordering_t val;
+ const char *strval;
+} ordering_nametable[] = {
+ { dns_c_ordering_fixed, "fixed" },
+ { dns_c_ordering_random, "random" },
+ { dns_c_ordering_cyclic, "cyclic" }
+};
+
+
+#define log_severity_nametable_size \
+ (sizeof (log_severity_nametable) / sizeof (struct dns_c_pvt_lsnt))
+static struct dns_c_pvt_lsnt {
+ dns_c_logseverity_t val;
+ const char *strval;
+} log_severity_nametable[] = {
+ { dns_c_log_critical, "critical" },
+ { dns_c_log_error, "error" },
+ { dns_c_log_info, "info" },
+ { dns_c_log_notice, "notice" },
+ { dns_c_log_warn, "warning" },
+ { dns_c_log_debug, "debug" },
+ { dns_c_log_dynamic, "dynamic" }
+};
+
+
+static struct dsn_c_pvt_sfnt {
+ int val;
+ const char *strval;
+} syslog_facil_nametable[] = {
+ { LOG_KERN, "kern" },
+ { LOG_USER, "user" },
+ { LOG_MAIL, "mail" },
+ { LOG_DAEMON, "daemon" },
+ { LOG_AUTH, "auth" },
+ { LOG_SYSLOG, "syslog" },
+ { LOG_LPR, "lpr" },
+#ifdef LOG_NEWS
+ { LOG_NEWS, "news" },
+#endif
+#ifdef LOG_UUCP
+ { LOG_UUCP, "uucp" },
+#endif
+#ifdef LOG_CRON
+ { LOG_CRON, "cron" },
+#endif
+#ifdef LOG_AUTHPRIV
+ { LOG_AUTHPRIV, "authpriv" },
+#endif
+#ifdef LOG_FTP
+ { LOG_FTP, "ftp" },
+#endif
+ { LOG_LOCAL0, "local0"},
+ { LOG_LOCAL1, "local1"},
+ { LOG_LOCAL2, "local2"},
+ { LOG_LOCAL3, "local3"},
+ { LOG_LOCAL4, "local4"},
+ { LOG_LOCAL5, "local5"},
+ { LOG_LOCAL6, "local6"},
+ { LOG_LOCAL7, "local7"},
+ { 0, NULL }
+};
+
+
+#define category_nametable_size \
+ (sizeof (category_nametable) / sizeof(struct dns_c_pvt_cntable))
+static struct dns_c_pvt_cntable {
+ dns_c_category_t val;
+ const char *strval;
+} category_nametable[] = {
+ { dns_c_cat_default, "default" },
+ { dns_c_cat_config, "config" },
+ { dns_c_cat_parser, "parser" },
+ { dns_c_cat_queries, "queries" },
+ { dns_c_cat_lameservers, "lame-servers" },
+ { dns_c_cat_statistics, "statistics" },
+ { dns_c_cat_panic, "panic" },
+ { dns_c_cat_update, "update" },
+ { dns_c_cat_ncache, "ncache" },
+ { dns_c_cat_xferin, "xfer-in" },
+ { dns_c_cat_xferout, "xfer-out" },
+ { dns_c_cat_db, "db" },
+ { dns_c_cat_eventlib, "eventlib" },
+ { dns_c_cat_packet, "packet" },
+ { dns_c_cat_notify, "notify" },
+ { dns_c_cat_cname, "cname" },
+ { dns_c_cat_security, "security" },
+ { dns_c_cat_os, "os" },
+ { dns_c_cat_insist, "insist" },
+ { dns_c_cat_maint, "maintenance" },
+ { dns_c_cat_load, "load" },
+ { dns_c_cat_respchecks, "response-checks" },
+ { dns_c_cat_control, "control" }
+};
+
+
+
+/***
+ *** DATA
+ ***/
+
+isc_boolean_t debug_mem_print;
+FILE *debug_mem_print_stream;
+
+
+
+/***
+ *** FUNCTIONS
+ ***/
+
+#if 0 /* XXXJAB delete this code */
+static void default_cfgerror(isc_result_t result, const char *fmt,
+ va_list args);
+#endif
+
+
+
+void
+dns_c_printinunits(FILE *fp, isc_uint32_t val)
+{
+ isc_uint32_t one_gig = (1024 * 1024 * 1024);
+ isc_uint32_t one_meg = (1024 * 1024);
+ isc_uint32_t one_k = 1024;
+
+ if (val == DNS_C_SIZE_SPEC_DEFAULT)
+ fprintf(fp, "default");
+ else if (val == 0)
+ fprintf(fp, "0");
+ else if ((val % one_gig) == 0)
+ fprintf(fp, "%luG", (unsigned long) val / one_gig);
+ else if ((val % one_meg) == 0)
+ fprintf(fp, "%luM", (unsigned long) val / one_meg);
+ else if ((val % one_k) == 0)
+ fprintf(fp, "%luK", (unsigned long) val / one_k);
+ else if (val == DNS_C_SIZE_SPEC_UNLIM)
+ fprintf(fp, "unlimited");
+ else
+ fprintf(fp, "%lu", (unsigned long) val);
+}
+
+
+void
+dns_c_dataclass_tostream(FILE *fp, dns_rdataclass_t rclass)
+{
+ char buffer[64];
+ isc_buffer_t sourceb;
+
+ isc_buffer_init(&sourceb, buffer, sizeof buffer,
+ ISC_BUFFERTYPE_GENERIC);
+
+ if (dns_rdataclass_totext(rclass, &sourceb) == DNS_R_SUCCESS) {
+ INSIST(sourceb.used + 1 < sizeof buffer);
+ buffer[sourceb.used] = '\0';
+ fputs(buffer, fp);
+ } else {
+ fprintf(fp, "UNKNOWN-CLASS(%d)",(int) rclass);
+ }
+}
+
+
+void
+dns_c_datatype_tostream(FILE *fp, dns_rdatatype_t rtype)
+{
+ char buffer[64];
+ isc_buffer_t sourceb;
+
+ isc_buffer_init(&sourceb, buffer, sizeof buffer,
+ ISC_BUFFERTYPE_GENERIC);
+
+ if (dns_rdatatype_totext(rtype, &sourceb) == DNS_R_SUCCESS) {
+ INSIST(sourceb.used + 1 < sizeof buffer);
+ buffer[sourceb.used] = '\0';
+ fputs(buffer, fp);
+ } else {
+ fprintf(fp, "UNKNOWN-RDATATYPE(%d)",(int) rtype);
+ }
+}
+
+
+void
+dns_c_printtabs(FILE *fp, int count)
+{
+
+ while (count > 0) {
+ fputc('\t', fp);
+ count--;
+ }
+}
+
+
+
+isc_result_t
+dns_c_string2ordering(char *name, dns_c_ordering_t *ordering)
+{
+ unsigned int i;
+ isc_result_t rval = ISC_R_FAILURE;
+
+ for (i = 0 ; i < ordering_nametable_size ; i++) {
+ if (strcmp(ordering_nametable[i].strval, name) == 0) {
+ *ordering = ordering_nametable[i].val;
+ rval = ISC_R_SUCCESS;
+ break;
+ }
+ }
+
+ return (rval);
+}
+
+
+const char *
+dns_c_ordering2string(dns_c_ordering_t ordering,
+ isc_boolean_t printable)
+{
+ unsigned int i;
+ const char *rval = NULL;
+
+ for (i = 0 ; i < ordering_nametable_size ; i++) {
+ if (ordering_nametable[i].val == ordering) {
+ rval = ordering_nametable[i].strval;
+ break;
+ }
+ }
+
+ return (rval == NULL && printable ? "UNKNOWN_ORDERING" : rval);
+}
+
+
+const char *
+dns_c_logseverity2string(dns_c_logseverity_t severity,
+ isc_boolean_t printable)
+{
+ unsigned int i;
+ const char *rval = NULL;
+
+ for (i = 0 ; i < log_severity_nametable_size ; i++) {
+ if (log_severity_nametable[i].val == severity) {
+ rval = log_severity_nametable[i].strval;
+ break;
+ }
+ }
+
+ return (rval == NULL && printable ? "UNKNOWN_SEVERITY" : rval);
+}
+
+
+isc_result_t
+dns_c_string2logseverity(const char *string,
+ dns_c_logseverity_t *result)
+{
+ unsigned int i;
+ isc_result_t rval = ISC_R_FAILURE;
+
+ REQUIRE(result != NULL);
+
+ for (i = 0 ; i < log_severity_nametable_size ; i++) {
+ if (strcmp(log_severity_nametable[i].strval, string) == 0) {
+ *result = log_severity_nametable[i].val;
+ rval = ISC_R_SUCCESS;
+ break;
+ }
+ }
+
+ return rval;
+}
+
+
+const char *
+dns_c_category2string(dns_c_category_t cat,
+ isc_boolean_t printable)
+{
+ unsigned int i;
+ const char *rval = NULL;
+
+ for (i = 0 ; i < category_nametable_size ; i++) {
+ if (category_nametable[i].val == cat) {
+ rval = category_nametable[i].strval;
+ break;
+ }
+ }
+
+ return (rval == NULL && printable ? "UNKNOWN_CATEGORY" : rval);
+}
+
+
+isc_result_t
+dns_c_string2category(const char *string,
+ dns_c_category_t *category)
+{
+ unsigned int i;
+ isc_result_t rval = ISC_R_FAILURE;
+
+ REQUIRE (category != NULL);
+
+ for (i = 0 ; i < category_nametable_size ; i++) {
+ if (strcmp(category_nametable[i].strval, string) == 0) {
+ *category = category_nametable[i].val;
+ rval = ISC_R_SUCCESS;
+ break;
+ }
+ }
+
+ return (rval);
+}
+
+
+
+const char *
+dns_c_facility2string(int facility, isc_boolean_t printable)
+{
+ int i;
+ const char *rval = NULL;
+
+ for (i = 0 ; syslog_facil_nametable[i].strval != NULL ; i++) {
+ if (syslog_facil_nametable[i].val == facility) {
+ rval = syslog_facil_nametable[i].strval;
+ break;
+ }
+ }
+
+ return (rval == NULL && printable ? "UNKNOWN_FACILITY" : rval);
+}
+
+
+isc_result_t
+dns_c_string2facility(const char *string, int *result)
+{
+ int i;
+ isc_result_t rval = ISC_R_FAILURE;
+
+ for (i = 0 ; syslog_facil_nametable[i].strval != NULL ; i++) {
+ if (strcmp(syslog_facil_nametable[i].strval, string) == 0) {
+ *result = syslog_facil_nametable[i].val;
+ rval = ISC_R_SUCCESS;
+ break;
+ }
+ }
+
+ return rval;
+}
+
+
+const char *
+dns_c_transformat2string(dns_transfer_format_t tformat,
+ isc_boolean_t printable)
+{
+ const char *rval = NULL;
+
+ switch (tformat) {
+ case dns_one_answer:
+ rval = "one-answer";
+ break;
+
+ case dns_many_answers:
+ rval = "many-answers";
+ break;
+ }
+
+ return (rval == NULL && printable ? "UNKNOWN_TRANSFER_FORMAT" : rval);
+}
+
+
+
+
+const char *
+dns_c_transport2string(dns_c_trans_t transport,
+ isc_boolean_t printable)
+{
+ const char *rval = NULL;
+
+ switch (transport) {
+ case dns_trans_primary:
+ rval = "master";
+ break;
+
+ case dns_trans_secondary:
+ rval = "slave";
+ break;
+
+ case dns_trans_response:
+ rval = "response";
+ break;
+ }
+
+ return (rval == NULL && printable ? "UNKNOWN_TRANSPORT" : rval);
+}
+
+
+const char *
+dns_c_nameseverity2string(dns_severity_t severity,
+ isc_boolean_t printable)
+{
+ const char *rval = NULL;
+
+ switch (severity) {
+ case dns_severity_ignore:
+ rval = "ignore";
+ break;
+
+ case dns_severity_warn:
+ rval = "warn";
+ break;
+
+ case dns_severity_fail:
+ rval = "fail";
+ break;
+ }
+
+ return (rval == NULL && printable ? "UNKNOWN_NAME_SEVERITY" : rval);
+}
+
+
+const char *
+dns_c_forward2string(dns_c_forw_t forw,
+ isc_boolean_t printable)
+{
+ const char *rval = NULL;
+
+ switch (forw) {
+ case dns_c_forw_only:
+ rval = "only";
+ break;
+
+ case dns_c_forw_first:
+ rval = "first";
+ break;
+
+ case dns_c_forw_noanswer:
+ rval = "if-no-answer";
+ break;
+
+ case dns_c_forw_nodomain:
+ rval = "if-no-domain";
+ break;
+ }
+
+ return (rval == NULL && printable ? "UNKNOWN_FORWARDING" : rval);
+}
+
+
+
+int
+dns_c_isanyaddr(isc_sockaddr_t *inaddr)
+{
+ int result = 0;
+
+ if (inaddr->type.sa.sa_family == AF_INET) {
+ if (inaddr->type.sin.sin_addr.s_addr == htonl(INADDR_ANY)) {
+ result = 1;
+ }
+ } else {
+ if (memcmp(&inaddr->type.sin6.sin6_addr,
+ &in6addr_any, sizeof in6addr_any) == 0) {
+ result = 1;
+ }
+ }
+
+ return (result);
+}
+
+
+
+void
+dns_c_print_ipaddr(FILE *fp, isc_sockaddr_t *inaddr)
+{
+ const char *p;
+ char tmpaddrstr[64];
+ int family = inaddr->type.sa.sa_family;
+ void *addr;
+
+ if (dns_c_isanyaddr(inaddr)) {
+ if (family == AF_INET) {
+ fprintf(fp, "*");
+ } else {
+ fprintf(fp, "0::0");
+ }
+ } else {
+ addr = (family == AF_INET ?
+ (void *)&inaddr->type.sin.sin_addr :
+ (void *)&inaddr->type.sin6.sin6_addr);
+
+ p = inet_ntop(family, addr, tmpaddrstr, sizeof tmpaddrstr);
+ if (p == NULL) {
+ fprintf(fp, "BAD-IP-ADDRESS");
+ } else {
+ fprintf(fp, "%s", tmpaddrstr);
+ }
+ }
+}
+
+
+isc_boolean_t
+dns_c_need_quote(const char *string)
+{
+ isc_boolean_t rval = ISC_FALSE;
+
+ while (string != NULL && *string != '\0') {
+ if (!(isalnum(*string & 0xff) || *string == '_')) {
+ rval = ISC_TRUE;
+ break;
+ }
+ string++;
+ }
+
+ return rval;
+}
+
+
+
diff --git a/lib/dns/config/confctl.c b/lib/dns/config/confctl.c
new file mode 100644
index 00000000..5e8e7009
--- /dev/null
+++ b/lib/dns/config/confctl.c
@@ -0,0 +1,267 @@
+/*
+ * 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.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <isc/assertions.h>
+#include <isc/net.h>
+#include <isc/magic.h>
+
+#include <dns/confctl.h>
+#include <dns/confcommon.h>
+
+
+isc_result_t
+dns_c_ctrllist_new(isc_mem_t *mem, dns_c_ctrllist_t **newlist)
+{
+ dns_c_ctrllist_t *newl;
+
+ REQUIRE(mem != NULL);
+ REQUIRE (newlist != NULL);
+
+ newl = isc_mem_get(mem, sizeof *newl);
+ if (newl == NULL) {
+ /* XXXJAB logwrite */
+ return (ISC_R_NOMEMORY);
+ }
+
+ newl->mem = mem;
+ newl->magic = DNS_C_CONFCTLLIST_MAGIC;
+
+ ISC_LIST_INIT(newl->elements);
+
+ *newlist = newl;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+void
+dns_c_ctrllist_print(FILE *fp, int indent, dns_c_ctrllist_t *cl)
+{
+ dns_c_ctrl_t *ctl;
+
+ if (cl == NULL) {
+ return;
+ }
+
+ REQUIRE(DNS_C_CONFCTLLIST_VALID(cl));
+
+ fprintf(fp, "controls {\n");
+ ctl = ISC_LIST_HEAD(cl->elements);
+ if (ctl == NULL) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp,"/* empty list */\n");
+ } else {
+ while (ctl != NULL) {
+ dns_c_printtabs(fp, indent + 1);
+ dns_c_ctrl_print(fp, indent + 1, ctl);
+ ctl = ISC_LIST_NEXT(ctl, next);
+ }
+ }
+ fprintf(fp, "};\n");
+}
+
+
+
+isc_result_t
+dns_c_ctrllist_delete(dns_c_ctrllist_t **list)
+{
+ dns_c_ctrl_t *ctrl;
+ dns_c_ctrl_t *tmpctrl;
+ dns_c_ctrllist_t *clist;
+
+ REQUIRE(list != NULL);
+ REQUIRE(*list != NULL);
+
+ clist = *list;
+
+ REQUIRE(DNS_C_CONFCTLLIST_VALID(clist));
+
+ ctrl = ISC_LIST_HEAD(clist->elements);
+ while (ctrl != NULL) {
+ tmpctrl = ISC_LIST_NEXT(ctrl, next);
+ dns_c_ctrl_delete(&ctrl);
+ ctrl = tmpctrl;
+ }
+
+ clist->magic = 0;
+ isc_mem_put(clist->mem, clist, sizeof *clist);
+
+ *list = NULL;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctrlinet_new(isc_mem_t *mem, dns_c_ctrl_t **control,
+ isc_sockaddr_t addr, in_port_t port,
+ dns_c_ipmatchlist_t *iml, isc_boolean_t copy)
+{
+ dns_c_ctrl_t *ctrl;
+ isc_result_t res;
+
+ REQUIRE(mem != NULL);
+ REQUIRE(control != NULL);
+
+ ctrl = isc_mem_get(mem, sizeof *ctrl);
+ if (ctrl == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ ctrl->magic = DNS_C_CONFCTL_MAGIC;
+ ctrl->mem = mem;
+ ctrl->control_type = dns_c_inet_control;
+ ctrl->u.inet_v.addr = addr;
+ ctrl->u.inet_v.port = port;
+
+ if (copy) {
+ res = dns_c_ipmatchlist_copy(mem,
+ &ctrl->u.inet_v.matchlist, iml);
+ if (res != ISC_R_SUCCESS) {
+ isc_mem_put(mem, ctrl, sizeof *ctrl);
+ return (res);
+ }
+ } else {
+ ctrl->u.inet_v.matchlist = iml;
+ }
+
+ *control = ctrl;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctrlunix_new(isc_mem_t *mem, dns_c_ctrl_t **control,
+ const char *path, int perm, uid_t uid, gid_t gid)
+{
+ dns_c_ctrl_t *ctrl;
+
+ REQUIRE(mem != NULL);
+ REQUIRE(control != NULL);
+
+ ctrl = isc_mem_get(mem, sizeof *ctrl);
+ if (ctrl == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ ctrl->magic = DNS_C_CONFCTL_MAGIC;
+ ctrl->mem = mem;
+ ctrl->control_type = dns_c_unix_control;
+ ctrl->u.unix_v.pathname = isc_mem_strdup(mem, path);
+ if (ctrl->u.unix_v.pathname == NULL) {
+ isc_mem_put(mem, ctrl, sizeof *ctrl);
+ /* XXXJAB logwrite */
+ return (ISC_R_NOMEMORY);
+ }
+
+ ctrl->u.unix_v.perm = perm;
+ ctrl->u.unix_v.owner = uid;
+ ctrl->u.unix_v.group = gid;
+
+ *control = ctrl;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctrl_delete(dns_c_ctrl_t **control)
+{
+ isc_result_t res = ISC_R_SUCCESS;
+ isc_result_t rval;
+ isc_mem_t *mem;
+ dns_c_ctrl_t *ctrl;
+
+ REQUIRE(control != NULL);
+ REQUIRE(*control != NULL);
+
+ ctrl = *control;
+
+ REQUIRE(DNS_C_CONFCTL_VALID(ctrl));
+
+ mem = ctrl->mem;
+
+ switch (ctrl->control_type) {
+ case dns_c_inet_control:
+ if (ctrl->u.inet_v.matchlist != NULL)
+ res = dns_c_ipmatchlist_detach(&ctrl->u.inet_v.matchlist);
+ else
+ res = ISC_R_SUCCESS;
+ break;
+
+ case dns_c_unix_control:
+ isc_mem_free(mem, ctrl->u.unix_v.pathname);
+ res = ISC_R_SUCCESS;
+ break;
+ }
+
+ rval = res;
+
+ ctrl->magic = 0;
+
+ isc_mem_put(mem, ctrl, sizeof *ctrl);
+
+ *control = NULL;
+
+ return (res);
+}
+
+
+void
+dns_c_ctrl_print(FILE *fp, int indent, dns_c_ctrl_t *ctl)
+{
+ in_port_t port;
+ dns_c_ipmatchlist_t *iml;
+
+ REQUIRE(DNS_C_CONFCTL_VALID(ctl));
+
+ (void) indent;
+
+ if (ctl->control_type == dns_c_inet_control) {
+ port = ctl->u.inet_v.port;
+ iml = ctl->u.inet_v.matchlist;
+
+ fprintf(fp, "inet ");
+ dns_c_print_ipaddr(fp, &ctl->u.inet_v.addr);
+
+ if (port == 0) {
+ fprintf(fp, " port *\n");
+ } else {
+ fprintf(fp, " port %d\n", port);
+ }
+
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "allow ");
+ dns_c_ipmatchlist_print(fp, indent + 2, iml);
+ fprintf(fp, ";\n");
+ } else {
+ /* The "#" means force a leading zero */
+ fprintf(fp, "unix \"%s\" perm %#o owner %lu group %lu;\n",
+ ctl->u.unix_v.pathname,
+ ctl->u.unix_v.perm,
+ (unsigned long)ctl->u.unix_v.owner,
+ (unsigned long)ctl->u.unix_v.group);
+ }
+}
+
+
diff --git a/lib/dns/config/confctx.c b/lib/dns/config/confctx.c
new file mode 100644
index 00000000..9ed62fd7
--- /dev/null
+++ b/lib/dns/config/confctx.c
@@ -0,0 +1,4424 @@
+/*
+ * 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.
+ */
+
+#include <config.h>
+
+#include <syslog.h> /* XXXRTH */
+#include <string.h>
+
+#include <isc/assertions.h>
+#include <isc/error.h>
+#include <isc/magic.h>
+
+#include <dns/confctx.h>
+#include <dns/confcommon.h>
+#include <dns/log.h>
+
+#include "confpvt.h"
+
+
+
+/*
+ * Bit positions in the flags fields of the dns_c_options_t structure.
+ */
+#define MAX_NCACHE_TTL_BIT 0
+#define TRANSFERS_IN_BIT 1
+#define TRANSFERS_PER_NS_BIT 2
+#define TRANSFERS_OUT_BIT 3
+#define MAX_LOG_SIZE_IXFR_BIT 4
+#define CLEAN_INTERVAL_BIT 5
+#define INTERFACE_INTERVAL_BIT 6
+#define STATS_INTERVAL_BIT 7
+#define HEARTBEAT_INTERVAL_BIT 8
+#define MAX_TRANSFER_TIME_IN_BIT 9
+#define MAX_TRANSFER_TIME_OUT_BIT 10
+#define MAX_TRANSFER_IDLE_IN_BIT 11
+#define MAX_TRANSFER_IDLE_OUT_BIT 12
+#define DATA_SIZE_BIT 13
+#define STACK_SIZE_BIT 14
+#define CORE_SIZE_BIT 15
+#define FILES_BIT 16
+#define QUERY_SOURCE_ADDR_BIT 17
+#define QUERY_SOURCE_PORT_BIT 18
+#define FAKE_IQUERY_BIT 19
+#define RECURSION_BIT 20
+#define FETCH_GLUE_BIT 21
+#define NOTIFY_BIT 22
+#define HOST_STATISTICS_BIT 23
+#define DEALLOC_ON_EXIT_BIT 24
+#define USE_IXFR_BIT 25
+#define MAINTAIN_IXFR_BASE_BIT 26
+#define HAS_OLD_CLIENTS_BIT 27
+#define AUTH_NX_DOMAIN_BIT 28
+#define MULTIPLE_CNAMES_BIT 29
+#define USE_ID_POOL_BIT 30
+#define DIALUP_BIT 31
+#define CHECKNAME_PRIM_BIT 32
+#define CHECKNAME_SEC_BIT 33
+#define CHECKNAME_RESP_BIT 34
+#define OPTIONS_TRANSFER_FORMAT_BIT 35
+#define FORWARD_BIT 36
+#define EXPERT_MODE_BIT 37
+#define RFC2308_TYPE1_BIT 38
+#define TCP_CLIENTS_BIT 39
+#define RECURSIVE_CLIENTS_BIT 40
+#define TRANSFER_SOURCE_BIT 41
+
+
+static isc_result_t cfg_set_iplist(dns_c_options_t *options,
+ dns_c_iplist_t **fieldaddr,
+ dns_c_iplist_t *newval,
+ isc_boolean_t copy);
+static isc_result_t cfg_set_ipmatchlist(dns_c_options_t *options,
+ dns_c_ipmatchlist_t **fieldaddr,
+ dns_c_ipmatchlist_t *newval,
+ isc_boolean_t copy);
+static isc_result_t cfg_set_boolean(dns_c_options_t *options,
+ isc_boolean_t *fieldaddr,
+ isc_boolean_t newval,
+ dns_c_setbits_t *setfield,
+ isc_uint32_t bitnumber);
+static isc_result_t cfg_set_int32(dns_c_options_t *options,
+ isc_int32_t *fieldaddr,
+ isc_int32_t newval,
+ dns_c_setbits_t *setfield,
+ isc_uint32_t bitnumber);
+static isc_result_t cfg_set_uint32(dns_c_options_t *options,
+ isc_uint32_t *fieldaddr,
+ isc_uint32_t newval,
+ dns_c_setbits_t *setfield,
+ isc_uint32_t bitnumber);
+static isc_result_t cfg_set_string(dns_c_options_t *options,
+ char **field,
+ const char *newval);
+
+static isc_result_t cfg_get_uint32(dns_c_options_t *options,
+ isc_uint32_t *field,
+ isc_uint32_t *result,
+ dns_c_setbits_t *setfield,
+ isc_uint32_t bitnumber);
+static isc_result_t cfg_get_int32(dns_c_options_t *options,
+ isc_int32_t *field,
+ isc_int32_t *result,
+ dns_c_setbits_t *setfield,
+ isc_uint32_t bitnumber);
+static isc_result_t cfg_get_boolean(dns_c_options_t *options,
+ isc_boolean_t *field,
+ isc_boolean_t *result,
+ dns_c_setbits_t *setfield,
+ isc_uint32_t bitnumber);
+static isc_result_t cfg_get_ipmatchlist(dns_c_options_t *options,
+ dns_c_ipmatchlist_t *field,
+ dns_c_ipmatchlist_t **resval);
+static isc_result_t cfg_get_iplist(dns_c_options_t *options,
+ dns_c_iplist_t *field,
+ dns_c_iplist_t **resval);
+static isc_result_t acl_init(dns_c_ctx_t *cfg);
+static isc_result_t logging_init (dns_c_ctx_t *cfg);
+static isc_result_t make_options(dns_c_ctx_t *cfg);
+
+
+
+isc_result_t
+dns_c_checkconfig(dns_c_ctx_t *ctx)
+{
+ isc_boolean_t bval;
+ char *cpval;
+ dns_severity_t severity;
+ isc_int32_t intval;
+ dns_c_ipmatchlist_t *ipml;
+
+ if (dns_c_ctx_getnamedxfer(ctx, &cpval) != ISC_R_NOTFOUND) {
+ isc_log_write(dns_lctx,DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_WARNING,
+ "named-xfer is now obsolete");
+ }
+
+
+ if (dns_c_ctx_getdumpfilename(ctx, &cpval) != ISC_R_NOTFOUND) {
+ isc_log_write(dns_lctx,DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_WARNING,
+ "dump-file is not yet implemented.");
+ }
+
+
+ if (dns_c_ctx_getmemstatsfilename(ctx, &cpval) != ISC_R_NOTFOUND) {
+ isc_log_write(dns_lctx,DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_WARNING,
+ "memstatistics-file is not yet implemented.");
+ }
+
+
+ if ((dns_c_ctx_getauthnxdomain(ctx, &bval)) == ISC_R_NOTFOUND) {
+ isc_log_write(dns_lctx,DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_WARNING,
+ "the default for auth-nxdomain is now ``no''");
+ }
+
+
+ if (dns_c_ctx_getdealloconexit(ctx, &bval) != ISC_R_NOTFOUND) {
+ isc_log_write(dns_lctx,DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_WARNING,
+ "deallocate-on-exit is obsolete.");
+ }
+
+
+ if (dns_c_ctx_getfakeiquery(ctx, &bval) != ISC_R_NOTFOUND) {
+ isc_log_write(dns_lctx,DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_WARNING,
+ "fake-iquery is obsolete.");
+ }
+
+
+ if (dns_c_ctx_getfetchglue(ctx, &bval) != ISC_R_NOTFOUND) {
+ isc_log_write(dns_lctx,DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_WARNING,
+ "fetch-glue is not yet implemented.");
+ }
+
+
+ if (dns_c_ctx_gethasoldclients(ctx, &bval) != ISC_R_NOTFOUND) {
+ isc_log_write(dns_lctx,DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_WARNING,
+ "has-old-clients is obsolete.");
+ }
+
+
+ if (dns_c_ctx_gethoststatistics(ctx, &bval) != ISC_R_NOTFOUND) {
+ isc_log_write(dns_lctx,DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_WARNING,
+ "host-statistics is not yet implemented.");
+ }
+
+
+ if (dns_c_ctx_getmultiplecnames(ctx, &bval) != ISC_R_NOTFOUND) {
+ isc_log_write(dns_lctx,DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_WARNING,
+ "multiple-cnames is obsolete.");
+ }
+
+
+ if (dns_c_ctx_getuseidpool(ctx, &bval) != ISC_R_NOTFOUND) {
+ isc_log_write(dns_lctx,DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_WARNING,
+ "use-id-pool is obsolete.");
+ }
+
+
+ if ((dns_c_ctx_getchecknames(ctx, dns_trans_primary,
+ &severity) != ISC_R_NOTFOUND) ||
+ (dns_c_ctx_getchecknames(ctx, dns_trans_secondary,
+ &severity) != ISC_R_NOTFOUND) ||
+ (dns_c_ctx_getchecknames(ctx, dns_trans_response,
+ &severity) != ISC_R_NOTFOUND)) {
+ isc_log_write(dns_lctx,DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_WARNING,
+ "check-names are not yet implemented.");
+ }
+
+
+ if (dns_c_ctx_getmaxlogsizeixfr(ctx, &intval) != ISC_R_NOTFOUND) {
+ isc_log_write(dns_lctx,DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_WARNING,
+ "max-ixfr-log-size is not yet implemented.");
+ }
+
+
+ if (dns_c_ctx_getstatsinterval(ctx, &intval) != ISC_R_NOTFOUND) {
+ isc_log_write(dns_lctx,DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_WARNING,
+ "statistics-interval is not yet implemented.");
+ }
+
+
+ if (dns_c_ctx_gettopology(ctx, &ipml) != ISC_R_NOTFOUND) {
+ dns_c_ipmatchlist_detach(&ipml);
+ isc_log_write(dns_lctx,DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_WARNING,
+ "topology is not yet implemented.");
+ }
+
+ if (dns_c_ctx_getsortlist(ctx, &ipml) != ISC_R_NOTFOUND) {
+ dns_c_ipmatchlist_detach(&ipml);
+ isc_log_write(dns_lctx,DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_WARNING,
+ "sortlist is not yet implemented.");
+ }
+
+
+ if (dns_c_ctx_getrfc2308type1(ctx, &bval) != ISC_R_NOTFOUND) {
+ isc_log_write(dns_lctx,DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_WARNING,
+ "rfc2308-type-1 is not yet implemented.");
+ }
+
+
+
+ /*
+ named-xfer obsolete
+ dump-file not yet implemented
+ memstatistics-file not yet implemented
+ auth-nxdomain default changed (to "no")
+ deallocate-on-exit obsolete (always "yes")
+ fake-iquery obsolete (always "no")
+ fetch-glue not yet implemented (always "no")
+ has-old-clients obsolete (always "no")
+ host-statistics not yet implemented
+ multiple-cnames obsolete (always "no")
+ use-id-pool obosolete (always "yes")
+ maintain-ixfr-base obosolete (always "yes")
+ check-names not yet implemented
+ max-ixfr-log-size not yet implemented
+ statistics-interval not yet implemented
+ topology not yet implemented
+ sortlist not yet implemented
+ */
+
+
+ return (ISC_R_SUCCESS);
+}
+
+
+/* ************************************************************************ */
+
+isc_result_t
+dns_c_ctx_new(isc_mem_t *mem, dns_c_ctx_t **ctx)
+{
+ dns_c_ctx_t *cfg;
+ isc_result_t r;
+
+ REQUIRE(mem != NULL);
+
+ cfg = isc_mem_get(mem, sizeof *cfg);
+ if (cfg == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ cfg->magic = DNS_C_CONFIG_MAGIC;
+ cfg->mem = mem;
+ cfg->warnings = 0;
+ cfg->errors = 0;
+ cfg->acls = NULL;
+ cfg->options = NULL;
+ cfg->zlist = NULL;
+ cfg->servers = NULL;
+ cfg->acls = NULL;
+ cfg->keydefs = NULL;
+ cfg->trusted_keys = NULL;
+ cfg->logging = NULL;
+ cfg->resolver = NULL;
+ cfg->cache = NULL;
+ cfg->views = NULL;
+
+ cfg->currview = NULL;
+ cfg->currzone = NULL;
+
+ r = acl_init(cfg);
+ if (r != ISC_R_SUCCESS) {
+ return (r);
+ }
+
+ r = logging_init(cfg);
+ if (r != ISC_R_SUCCESS) {
+ return (r);
+ }
+
+
+#if 1 /* XXX brister */
+ cfg->controls = NULL;
+#else
+ r = dns_c_ctrllist_new(mem, &cfg->controls);
+ if (r != ISC_R_SUCCESS) {
+ dns_c_ctx_delete(&cfg);
+ return r;
+ }
+#endif
+
+ *ctx = cfg;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctx_delete(dns_c_ctx_t **cfg)
+{
+ dns_c_ctx_t *c;
+
+ REQUIRE(cfg != NULL);
+ REQUIRE(*cfg != NULL);
+ REQUIRE(DNS_C_CONFCTX_VALID(*cfg));
+
+ c = *cfg;
+
+ REQUIRE(c->mem != NULL);
+
+ if (c->options != NULL)
+ dns_c_ctx_optionsdelete(&c->options);
+
+ if (c->controls != NULL)
+ dns_c_ctrllist_delete(&c->controls);
+
+ if (c->servers != NULL)
+ dns_c_srvlist_delete(&c->servers);
+
+ if (c->acls != NULL)
+ dns_c_acltable_delete(&c->acls);
+
+ if (c->keydefs != NULL)
+ dns_c_kdeflist_delete(&c->keydefs);
+
+ if (c->zlist != NULL)
+ dns_c_zonelist_delete(&c->zlist);
+
+ if (c->trusted_keys != NULL)
+ dns_c_tkeylist_delete(&c->trusted_keys);
+
+ if (c->logging != NULL)
+ dns_c_logginglist_delete(&c->logging);
+
+ if (c->views != NULL)
+ dns_c_viewtable_delete(&c->views);
+
+ c->magic = 0;
+ isc_mem_put(c->mem, c, sizeof *c);
+ *cfg = NULL;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctx_setcontrols(dns_c_ctx_t *cfg, dns_c_ctrllist_t *ctrls)
+{
+ isc_boolean_t existed = ISC_FALSE;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(DNS_C_CONFCTLLIST_VALID(ctrls));
+
+ if (cfg->controls != NULL) {
+ existed = ISC_TRUE;
+ dns_c_ctrllist_delete(&cfg->controls);
+ }
+
+ cfg->controls = ctrls;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+isc_result_t
+dns_c_ctx_getcontrols(dns_c_ctx_t *cfg, dns_c_ctrllist_t **ctrls)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ *ctrls = cfg->controls;
+
+ return (cfg->controls != NULL ? ISC_R_SUCCESS : ISC_R_NOTFOUND);
+}
+
+
+
+
+isc_result_t
+dns_c_ctx_setcurrzone(dns_c_ctx_t *cfg, dns_c_zone_t *zone)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ cfg->currzone = zone; /* zone may be NULL */
+
+ /* XXX should we validate that the zone is in our table? */
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+dns_c_zone_t *
+dns_c_ctx_getcurrzone(dns_c_ctx_t *cfg)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ return (cfg->currzone);
+}
+
+
+
+isc_result_t
+dns_c_ctx_setcurrview(dns_c_ctx_t *cfg,
+ dns_c_view_t *view)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ cfg->currview = view;
+
+ /* XXX should we validate that the zone is in our table? */
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+dns_c_view_t *
+dns_c_ctx_getcurrview(dns_c_ctx_t *cfg)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ return (cfg->currview);
+}
+
+
+
+void
+dns_c_ctx_print(FILE *fp, int indent, dns_c_ctx_t *cfg)
+{
+ REQUIRE(fp != NULL);
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ if (cfg->logging != NULL) {
+ dns_c_logginglist_print(fp, indent,
+ cfg->logging, ISC_FALSE);
+ fprintf(fp,"\n");
+ }
+
+
+ if (cfg->keydefs != NULL) {
+ dns_c_kdeflist_print(fp, indent, cfg->keydefs);
+ fprintf(fp, "\n");
+ }
+
+
+ if (cfg->trusted_keys != NULL) {
+ dns_c_tkeylist_print(fp, indent, cfg->trusted_keys);
+ fprintf(fp, "\n");
+ }
+
+
+ if (cfg->acls != NULL) {
+ dns_c_acltable_print(fp, indent, cfg->acls);
+ fprintf(fp,"\n");
+ }
+
+
+ if (cfg->zlist != NULL) {
+ dns_c_zonelist_printpreopts(fp, indent, cfg->zlist);
+ fprintf(fp, "\n");
+ }
+
+
+ if (cfg->options != NULL) {
+ dns_c_ctx_optionsprint(fp, indent, cfg->options);
+ fprintf(fp,"\n");
+ }
+
+
+ if (cfg->views != NULL) {
+ dns_c_viewtable_print(fp, indent, cfg->views);
+ fprintf(fp, "\n");
+ }
+
+
+ if (cfg->zlist != NULL) {
+ dns_c_zonelist_printpostopts(fp, indent, cfg->zlist);
+ fprintf(fp, "\n");
+ }
+
+ if (cfg->controls != NULL) {
+ dns_c_ctrllist_print(fp, indent, cfg->controls);
+ fprintf(fp, "\n");
+ }
+
+
+ if (cfg->servers != NULL) {
+ dns_c_srvlist_print(fp, indent, cfg->servers);
+ fprintf(fp, "\n");
+ }
+}
+
+
+void
+dns_c_ctx_forwarderprint(FILE *fp, int indent, dns_c_options_t *options)
+{
+ REQUIRE(fp != NULL);
+ REQUIRE(indent >= 0);
+
+ if (options == NULL) {
+ return;
+ }
+
+ REQUIRE(DNS_C_CONFOPT_VALID(options));
+
+ if (DNS_C_CHECKBIT(FORWARD_BIT, &options->setflags1)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "forward %s;\n",
+ dns_c_forward2string(options->forward, ISC_TRUE));
+ }
+
+ if (options->forwarders != NULL) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "forwarders ");
+ dns_c_iplist_print(fp, indent + 1,
+ options->forwarders);
+ fprintf(fp, ";\n");
+ }
+}
+
+
+isc_result_t
+dns_c_ctx_getoptions(dns_c_ctx_t *cfg, dns_c_options_t **options)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(options != NULL);
+
+ if (cfg->options != NULL) {
+ REQUIRE(DNS_C_CONFOPT_VALID(cfg->options));
+ }
+
+ *options = cfg->options;
+
+ return (cfg->options == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+
+isc_result_t
+dns_c_ctx_getlogging(dns_c_ctx_t *cfg, dns_c_logginglist_t **retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ *retval = cfg->logging;
+
+ return (cfg->logging == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctx_setlogging(dns_c_ctx_t *cfg, dns_c_logginglist_t *newval,
+ isc_boolean_t deepcopy)
+{
+ dns_c_logginglist_t *ll;
+ isc_result_t res;
+ isc_boolean_t existed;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ existed = ISC_TF(cfg->logging != NULL);
+
+ if (deepcopy) {
+ res = dns_c_logginglist_copy(cfg->mem, &ll, newval);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ } else {
+ ll = newval;
+ }
+
+ cfg->logging = ll;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctx_getkdeflist(dns_c_ctx_t *cfg,
+ dns_c_kdeflist_t **retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ *retval = cfg->keydefs;
+
+ if (cfg->keydefs == NULL) {
+ return (ISC_R_NOTFOUND);
+ } else {
+ return (ISC_R_SUCCESS);
+ }
+}
+
+
+isc_result_t
+dns_c_ctx_setkdeflist(dns_c_ctx_t *cfg,
+ dns_c_kdeflist_t *newval, isc_boolean_t deepcopy)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ if (cfg->keydefs != NULL) {
+ dns_c_kdeflist_delete(&cfg->keydefs);
+ }
+
+ if (newval == NULL) {
+ cfg->keydefs = NULL;
+ res = ISC_R_SUCCESS;
+ } else if (deepcopy) {
+ res = dns_c_kdeflist_copy(cfg->mem,
+ &cfg->keydefs, newval);
+ } else {
+ cfg->keydefs = newval;
+ res = ISC_R_SUCCESS;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ctx_addfile_channel(dns_c_ctx_t *cfg, const char *name,
+ dns_c_logchan_t **chan)
+{
+ dns_c_logchan_t *newc;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(name != NULL);
+ REQUIRE(chan != NULL);
+ REQUIRE(cfg->logging != NULL);
+
+ res = dns_c_logchan_new(cfg->mem, name, dns_c_logchan_file,
+ &newc);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ res = dns_c_logginglist_addchannel(cfg->logging, newc,
+ ISC_FALSE);
+
+ *chan = newc;
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ctx_addsyslogchannel(dns_c_ctx_t *cfg, const char *name,
+ dns_c_logchan_t **chan)
+{
+ dns_c_logchan_t *newc;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(name != NULL);
+ REQUIRE(chan != NULL);
+ REQUIRE(cfg->logging != NULL);
+
+ res = dns_c_logchan_new(cfg->mem, name,
+ dns_c_logchan_syslog, &newc);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ res = dns_c_logginglist_addchannel(cfg->logging, newc,
+ ISC_FALSE);
+
+ *chan = newc;
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ctx_addnullchannel(dns_c_ctx_t *cfg, const char *name,
+ dns_c_logchan_t **chan)
+{
+ dns_c_logchan_t *newc;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(name != NULL);
+ REQUIRE(chan != NULL);
+ REQUIRE(cfg->logging != NULL);
+
+ res = dns_c_logchan_new(cfg->mem, name, dns_c_logchan_null,
+ &newc);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ res = dns_c_logginglist_addchannel(cfg->logging, newc,
+ ISC_FALSE);
+
+ *chan = newc;
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ctx_addcategory(dns_c_ctx_t *cfg, dns_c_category_t category,
+ dns_c_logcat_t **newcat)
+{
+ dns_c_logcat_t *newc;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(newcat != NULL);
+ REQUIRE(cfg->logging != NULL);
+
+ res = dns_c_logcat_new(cfg->mem, category, &newc);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ res = dns_c_logginglist_addcategory(cfg->logging, newc,
+ ISC_FALSE);
+
+ *newcat = newc;
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ctx_currchannel(dns_c_ctx_t *cfg, dns_c_logchan_t **channel)
+{
+ dns_c_logchan_t *newc;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(channel != NULL);
+ REQUIRE(cfg->logging != NULL);
+
+ newc = ISC_LIST_TAIL(cfg->logging->channels);
+
+ *channel = newc;
+
+ return (newc == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+isc_boolean_t
+dns_c_ctx_channeldefinedp(dns_c_ctx_t *cfg, const char *name)
+{
+ isc_result_t res;
+ dns_c_logchan_t *chan;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(name != NULL);
+ REQUIRE(strlen(name) > 0);
+
+ res = dns_c_logginglist_chanbyname(cfg->logging, name, &chan);
+
+ return (ISC_TF(res == ISC_R_SUCCESS));
+}
+
+
+
+isc_result_t
+dns_c_ctx_currcategory(dns_c_ctx_t *cfg, dns_c_logcat_t **category)
+{
+ dns_c_logcat_t *newc;
+ dns_c_logginglist_t *llist;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(category != NULL);
+
+ res = dns_c_ctx_getlogging(cfg, &llist);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ newc = ISC_LIST_TAIL(llist->categories);
+
+ *category = newc;
+
+ return (newc == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+/*
+ * Modifiers for options.
+ *
+ */
+
+
+isc_result_t
+dns_c_ctx_setdirectory(dns_c_ctx_t *cfg, const char *newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_string(cfg->options,
+ &cfg->options->directory,
+ newval));
+}
+
+
+isc_result_t
+dns_c_ctx_setversion(dns_c_ctx_t *cfg, const char *newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_string(cfg->options,
+ &cfg->options->version,
+ newval));
+}
+
+
+isc_result_t
+dns_c_ctx_setdumpfilename(dns_c_ctx_t *cfg, const char *newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_string(cfg->options,
+ &cfg->options->dump_filename,
+ newval));
+}
+
+
+isc_result_t
+dns_c_ctx_setpidfilename(dns_c_ctx_t *cfg, const char *newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_string(cfg->options,
+ &cfg->options->pid_filename,
+ newval));
+}
+
+
+isc_result_t
+dns_c_ctx_setstatsfilename(dns_c_ctx_t *cfg, const char *newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_string(cfg->options,
+ &cfg->options->stats_filename,
+ newval));
+}
+
+
+isc_result_t
+dns_c_ctx_setmemstatsfilename(dns_c_ctx_t *cfg, const char *newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_string(cfg->options,
+ &cfg->options->memstats_filename,
+ newval));
+}
+
+
+isc_result_t
+dns_c_ctx_setnamedxfer(dns_c_ctx_t *cfg, const char *newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_string(cfg->options,
+ &cfg->options->named_xfer,
+ newval));
+}
+
+
+isc_result_t
+dns_c_ctx_settkeydomain(dns_c_ctx_t *cfg, const char *newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_string(cfg->options,
+ &cfg->options->tkeydomain,
+ newval));
+}
+
+
+isc_result_t
+dns_c_ctx_settkeydhkey(dns_c_ctx_t *cfg,
+ const char *charval, isc_int32_t intval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ cfg->options->tkeydhkeyi = intval;
+ return (cfg_set_string(cfg->options,
+ &cfg->options->tkeydhkeycp,
+ charval));
+}
+
+
+isc_result_t
+dns_c_ctx_setmaxncachettl(dns_c_ctx_t *cfg, isc_uint32_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_uint32(cfg->options,
+ &cfg->options->max_ncache_ttl,
+ newval,
+ &cfg->options->setflags1,
+ MAX_NCACHE_TTL_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_settransfersin(dns_c_ctx_t *cfg, isc_int32_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_int32(cfg->options,
+ &cfg->options->transfers_in,
+ newval,
+ &cfg->options->setflags1,
+ TRANSFERS_IN_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_settransfersperns(dns_c_ctx_t *cfg, isc_int32_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_int32(cfg->options,
+ &cfg->options->transfers_per_ns,
+ newval,
+ &cfg->options->setflags1,
+ TRANSFERS_PER_NS_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_settransfersout(dns_c_ctx_t *cfg, isc_int32_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_int32(cfg->options,
+ &cfg->options->transfers_out,
+ newval,
+ &cfg->options->setflags1,
+ TRANSFERS_OUT_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setmaxlogsizeixfr(dns_c_ctx_t *cfg, isc_int32_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_int32(cfg->options,
+ &cfg->options->max_log_size_ixfr,
+ newval,
+ &cfg->options->setflags1,
+ MAX_LOG_SIZE_IXFR_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setcleaninterval(dns_c_ctx_t *cfg, isc_int32_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_int32(cfg->options,
+ &cfg->options->clean_interval,
+ newval,
+ &cfg->options->setflags1,
+ CLEAN_INTERVAL_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setinterfaceinterval(dns_c_ctx_t *cfg, isc_int32_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_int32(cfg->options,
+ &cfg->options->interface_interval,
+ newval,
+ &cfg->options->setflags1,
+ INTERFACE_INTERVAL_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setstatsinterval(dns_c_ctx_t *cfg, isc_int32_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_int32(cfg->options,
+ &cfg->options->stats_interval,
+ newval,
+ &cfg->options->setflags1,
+ STATS_INTERVAL_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setheartbeat_interval(dns_c_ctx_t *cfg, isc_int32_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_int32(cfg->options,
+ &cfg->options->heartbeat_interval,
+ newval,
+ &cfg->options->setflags1,
+ HEARTBEAT_INTERVAL_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setmaxtransfertimein(dns_c_ctx_t *cfg, isc_int32_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_int32(cfg->options,
+ &cfg->options->max_transfer_time_in,
+ newval,
+ &cfg->options->setflags1,
+ MAX_TRANSFER_TIME_IN_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setmaxtransfertimeout(dns_c_ctx_t *cfg, isc_int32_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_int32(cfg->options,
+ &cfg->options->max_transfer_time_out,
+ newval,
+ &cfg->options->setflags1,
+ MAX_TRANSFER_TIME_OUT_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setmaxtransferidlein(dns_c_ctx_t *cfg, isc_int32_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_int32(cfg->options,
+ &cfg->options->max_transfer_idle_in,
+ newval,
+ &cfg->options->setflags1,
+ MAX_TRANSFER_IDLE_IN_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setmaxtransferidleout(dns_c_ctx_t *cfg, isc_int32_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_int32(cfg->options,
+ &cfg->options->max_transfer_idle_out,
+ newval,
+ &cfg->options->setflags1,
+ MAX_TRANSFER_IDLE_OUT_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_settcpclients(dns_c_ctx_t *cfg, isc_int32_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_int32(cfg->options,
+ &cfg->options->tcp_clients,
+ newval,
+ &cfg->options->setflags1,
+ TCP_CLIENTS_BIT));
+}
+
+isc_result_t
+dns_c_ctx_setrecursiveclients(dns_c_ctx_t *cfg, isc_int32_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_int32(cfg->options,
+ &cfg->options->recursive_clients,
+ newval,
+ &cfg->options->setflags1,
+ RECURSIVE_CLIENTS_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setdatasize(dns_c_ctx_t *cfg, isc_uint32_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_uint32(cfg->options,
+ &cfg->options->data_size,
+ newval,
+ &cfg->options->setflags1,
+ DATA_SIZE_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setstacksize(dns_c_ctx_t *cfg, isc_uint32_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_uint32(cfg->options,
+ &cfg->options->stack_size,
+ newval,
+ &cfg->options->setflags1,
+ STACK_SIZE_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setcoresize(dns_c_ctx_t *cfg, isc_uint32_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_uint32(cfg->options,
+ &cfg->options->core_size,
+ newval,
+ &cfg->options->setflags1,
+ CORE_SIZE_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setfiles(dns_c_ctx_t *cfg, isc_uint32_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_uint32(cfg->options,
+ &cfg->options->files,
+ newval,
+ &cfg->options->setflags1,
+ FILES_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setexpertmode(dns_c_ctx_t *cfg, isc_boolean_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_boolean(cfg->options,
+ &cfg->options->expert_mode,
+ newval,
+ &cfg->options->setflags1,
+ EXPERT_MODE_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setfakeiquery(dns_c_ctx_t *cfg, isc_boolean_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_boolean(cfg->options,
+ &cfg->options->fake_iquery,
+ newval,
+ &cfg->options->setflags1,
+ FAKE_IQUERY_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setrecursion(dns_c_ctx_t *cfg, isc_boolean_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_boolean(cfg->options,
+ &cfg->options->recursion,
+ newval,
+ &cfg->options->setflags1,
+ RECURSION_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setfetchglue(dns_c_ctx_t *cfg, isc_boolean_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_boolean(cfg->options,
+ &cfg->options->fetch_glue,
+ newval,
+ &cfg->options->setflags1,
+ FETCH_GLUE_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setnotify(dns_c_ctx_t *cfg, isc_boolean_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_boolean(cfg->options,
+ &cfg->options->notify,
+ newval,
+ &cfg->options->setflags1,
+ NOTIFY_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_sethoststatistics(dns_c_ctx_t *cfg, isc_boolean_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_boolean(cfg->options,
+ &cfg->options->host_statistics,
+ newval,
+ &cfg->options->setflags1,
+ HOST_STATISTICS_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setdealloconexit(dns_c_ctx_t *cfg, isc_boolean_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_boolean(cfg->options,
+ &cfg->options->dealloc_on_exit,
+ newval,
+ &cfg->options->setflags1,
+ DEALLOC_ON_EXIT_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setuseixfr(dns_c_ctx_t *cfg, isc_boolean_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_boolean(cfg->options,
+ &cfg->options->use_ixfr,
+ newval,
+ &cfg->options->setflags1,
+ USE_IXFR_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setmaintainixfrbase(dns_c_ctx_t *cfg, isc_boolean_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_boolean(cfg->options,
+ &cfg->options->maintain_ixfr_base,
+ newval,
+ &cfg->options->setflags1,
+ MAINTAIN_IXFR_BASE_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_sethasoldclients(dns_c_ctx_t *cfg, isc_boolean_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_boolean(cfg->options,
+ &cfg->options->has_old_clients,
+ newval,
+ &cfg->options->setflags1,
+ HAS_OLD_CLIENTS_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setauthnxdomain(dns_c_ctx_t *cfg, isc_boolean_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_boolean(cfg->options,
+ &cfg->options->auth_nx_domain,
+ newval,
+ &cfg->options->setflags1,
+ AUTH_NX_DOMAIN_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setmultiplecnames(dns_c_ctx_t *cfg, isc_boolean_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_boolean(cfg->options,
+ &cfg->options->multiple_cnames,
+ newval,
+ &cfg->options->setflags1,
+ MULTIPLE_CNAMES_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setuseidpool(dns_c_ctx_t *cfg, isc_boolean_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_boolean(cfg->options,
+ &cfg->options->use_id_pool,
+ newval,
+ &cfg->options->setflags1,
+ USE_ID_POOL_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setrfc2308type1(dns_c_ctx_t *cfg, isc_boolean_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_boolean(cfg->options,
+ &cfg->options->rfc2308_type1,
+ newval,
+ &cfg->options->setflags1,
+ RFC2308_TYPE1_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setdialup(dns_c_ctx_t *cfg, isc_boolean_t newval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ return (cfg_set_boolean(cfg->options,
+ &cfg->options->dialup,
+ newval,
+ &cfg->options->setflags1,
+ DIALUP_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_setquerysourceaddr(dns_c_ctx_t *cfg, isc_sockaddr_t addr)
+{
+ isc_boolean_t existed;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ existed = DNS_C_CHECKBIT(QUERY_SOURCE_ADDR_BIT,
+ &cfg->options->setflags1);
+ DNS_C_SETBIT(QUERY_SOURCE_ADDR_BIT, &cfg->options->setflags1);
+
+ cfg->options->query_source_addr = addr;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctx_setquerysourceport(dns_c_ctx_t *cfg, in_port_t port)
+{
+ isc_boolean_t existed;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ existed = DNS_C_CHECKBIT(QUERY_SOURCE_PORT_BIT,
+ &cfg->options->setflags1);
+ DNS_C_SETBIT(QUERY_SOURCE_PORT_BIT, &cfg->options->setflags1);
+
+ cfg->options->query_source_port = port;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctx_settransferformat(dns_c_ctx_t *cfg,
+ dns_transfer_format_t newval)
+{
+ isc_boolean_t existed;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ existed = DNS_C_CHECKBIT(OPTIONS_TRANSFER_FORMAT_BIT,
+ &cfg->options->setflags1);
+ DNS_C_SETBIT(OPTIONS_TRANSFER_FORMAT_BIT, &cfg->options->setflags1);
+
+ cfg->options->transfer_format = newval;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctx_setchecknames(dns_c_ctx_t *cfg,
+ dns_c_trans_t transtype,
+ dns_severity_t sever)
+{
+ isc_boolean_t existed = ISC_FALSE;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ switch(transtype) {
+ case dns_trans_primary:
+ existed = DNS_C_CHECKBIT(CHECKNAME_PRIM_BIT,
+ &cfg->options->setflags1);
+ DNS_C_SETBIT(CHECKNAME_PRIM_BIT, &cfg->options->setflags1);
+ break;
+
+ case dns_trans_secondary:
+ existed = DNS_C_CHECKBIT(CHECKNAME_SEC_BIT,
+ &cfg->options->setflags1);
+ DNS_C_SETBIT(CHECKNAME_SEC_BIT, &cfg->options->setflags1);
+ break;
+
+ case dns_trans_response:
+ existed = DNS_C_CHECKBIT(CHECKNAME_RESP_BIT,
+ &cfg->options->setflags1);
+ DNS_C_SETBIT(CHECKNAME_RESP_BIT, &cfg->options->setflags1);
+ break;
+
+ default:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "bad transport value: %d", transtype);
+ return (ISC_R_FAILURE);
+ }
+
+ cfg->options->check_names[transtype] = sever;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctx_setqueryacl(dns_c_ctx_t *cfg, isc_boolean_t copy,
+ dns_c_ipmatchlist_t *iml)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ REQUIRE(iml != NULL);
+
+ res = cfg_set_ipmatchlist(cfg->options, &cfg->options->queryacl,
+ iml, copy);
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ctx_settransferacl(dns_c_ctx_t *cfg, isc_boolean_t copy,
+ dns_c_ipmatchlist_t *iml)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ REQUIRE(iml != NULL);
+
+ res = cfg_set_ipmatchlist(cfg->options, &cfg->options->transferacl,
+ iml, copy);
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ctx_setrecursionacl(dns_c_ctx_t *cfg, isc_boolean_t copy,
+ dns_c_ipmatchlist_t *iml)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ REQUIRE(iml != NULL);
+
+ res = cfg_set_ipmatchlist(cfg->options, &cfg->options->recursionacl,
+ iml, copy);
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ctx_setblackhole(dns_c_ctx_t *cfg, isc_boolean_t copy,
+ dns_c_ipmatchlist_t *iml)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ REQUIRE(iml != NULL);
+
+ res = cfg_set_ipmatchlist(cfg->options, &cfg->options->blackhole,
+ iml, copy);
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ctx_settopology(dns_c_ctx_t *cfg, isc_boolean_t copy,
+ dns_c_ipmatchlist_t *iml)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ REQUIRE(iml != NULL);
+
+ res = cfg_set_ipmatchlist(cfg->options, &cfg->options->topology,
+ iml, copy);
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ctx_setsortlist(dns_c_ctx_t *cfg, isc_boolean_t copy,
+ dns_c_ipmatchlist_t *iml)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ REQUIRE(iml != NULL);
+
+ res = cfg_set_ipmatchlist(cfg->options, &cfg->options->sortlist,
+ iml, copy);
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ctx_setforward(dns_c_ctx_t *cfg, dns_c_forw_t forw)
+{
+ isc_boolean_t existed;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ existed = DNS_C_CHECKBIT(FORWARD_BIT, &cfg->options->setflags1);
+ DNS_C_SETBIT(FORWARD_BIT, &cfg->options->setflags1);
+
+ cfg->options->forward = forw;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctx_setforwarders(dns_c_ctx_t *cfg, isc_boolean_t copy,
+ dns_c_iplist_t *ipl)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ res = cfg_set_iplist(cfg->options, &cfg->options->forwarders,
+ ipl, copy);
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ctx_setrrsetorderlist(dns_c_ctx_t *cfg, isc_boolean_t copy,
+ dns_c_rrsolist_t *olist)
+{
+ isc_boolean_t existed;
+ dns_c_options_t *opts;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ opts = cfg->options;
+
+ existed = (opts->ordering == NULL ? ISC_FALSE : ISC_TRUE);
+
+ if (copy) {
+ if (opts->ordering == NULL) {
+ res = dns_c_rrsolist_new(opts->mem,
+ &opts->ordering);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ } else {
+ dns_c_rrsolist_clear(opts->ordering);
+ }
+
+ res = dns_c_rrsolist_append(opts->ordering, olist);
+ } else {
+ if (opts->ordering != NULL) {
+ dns_c_rrsolist_delete(&opts->ordering);
+ }
+
+ opts->ordering = olist;
+ res = ISC_R_SUCCESS;
+ }
+
+ if (res == ISC_R_SUCCESS && existed) {
+ res = ISC_R_EXISTS;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ctx_addlisten_on(dns_c_ctx_t *cfg,int port, dns_c_ipmatchlist_t *ml,
+ isc_boolean_t copy)
+{
+ dns_c_lstnon_t *lo;
+ isc_result_t res;
+ dns_c_options_t *opts;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(port >= 0 && port <= 65535);
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ opts = cfg->options;
+
+ if (opts->listens == NULL) {
+ res = dns_c_lstnlist_new(cfg->mem, &opts->listens);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ }
+
+#if 0
+ lo = ISC_LIST_HEAD(opts->listens->elements);
+ while (lo != NULL) {
+ /* XXX we should probably check that a listen on statement
+ * hasn't been done for the same post, ipmatch list
+ * combination
+ */
+ if (lo->port == port) { /* XXX incomplete */
+ return (ISC_R_FAILURE);
+ }
+ lo = ISC_LIST_NEXT(lo, next);
+ }
+#endif
+
+ res = dns_c_lstnon_new(cfg->mem, &lo);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ lo->port = port;
+ res = dns_c_lstnon_setiml(lo, ml, copy);
+
+ ISC_LIST_APPEND(opts->listens->elements, lo, next);
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ctx_settrustedkeys(dns_c_ctx_t *cfg, dns_c_tkeylist_t *list,
+ isc_boolean_t copy)
+{
+ isc_boolean_t existed;
+ dns_c_tkeylist_t *newl;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ existed = (cfg->trusted_keys == NULL ? ISC_FALSE : ISC_TRUE);
+
+ if (cfg->trusted_keys != NULL) {
+ res = dns_c_tkeylist_delete(&cfg->trusted_keys);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ }
+
+ if (copy) {
+ res = dns_c_tkeylist_copy(cfg->mem, &newl, list);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ } else {
+ newl = list;
+ }
+
+ cfg->trusted_keys = newl;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+/**
+ ** Accessors
+ **/
+
+isc_result_t
+dns_c_ctx_getdirectory(dns_c_ctx_t *cfg, char **retval)
+{
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(DNS_C_CONFOPT_VALID(cfg->options));
+
+ *retval = cfg->options->directory;
+
+ return (*retval == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctx_getversion(dns_c_ctx_t *cfg, char **retval)
+{
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(DNS_C_CONFOPT_VALID(cfg->options));
+
+ *retval = cfg->options->version;
+
+ return (*retval == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctx_getdumpfilename(dns_c_ctx_t *cfg, char **retval)
+{
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(DNS_C_CONFOPT_VALID(cfg->options));
+
+ *retval = cfg->options->dump_filename;
+
+ return (*retval == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctx_getpidfilename(dns_c_ctx_t *cfg, char **retval)
+{
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(DNS_C_CONFOPT_VALID(cfg->options));
+
+ *retval = cfg->options->pid_filename;
+
+ return (*retval == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctx_getstatsfilename(dns_c_ctx_t *cfg, char **retval)
+{
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(DNS_C_CONFOPT_VALID(cfg->options));
+
+ *retval = cfg->options->stats_filename;
+
+ return (*retval == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctx_getmemstatsfilename(dns_c_ctx_t *cfg, char **retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(DNS_C_CONFOPT_VALID(cfg->options));
+
+ *retval = cfg->options->memstats_filename;
+
+ return (*retval == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctx_getnamedxfer(dns_c_ctx_t *cfg, char **retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(DNS_C_CONFOPT_VALID(cfg->options));
+
+ *retval = cfg->options->named_xfer;
+
+ return (*retval == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctx_gettkeydomain(dns_c_ctx_t *cfg, char **retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(DNS_C_CONFOPT_VALID(cfg->options));
+
+ *retval = cfg->options->tkeydomain;
+
+ return (*retval == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctx_gettkeydhkey(dns_c_ctx_t *cfg,
+ char **charpval, isc_int32_t *intval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(charpval != NULL);
+ REQUIRE(intval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(DNS_C_CONFOPT_VALID(cfg->options));
+
+ if (cfg->options->tkeydhkeycp == NULL) {
+ res = ISC_R_NOTFOUND;
+ } else {
+ *charpval = cfg->options->tkeydhkeycp;
+ *intval = cfg->options->tkeydhkeyi;
+ res = ISC_R_SUCCESS;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ctx_getmaxncachettl(dns_c_ctx_t *cfg, isc_uint32_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(DNS_C_CONFOPT_VALID(cfg->options));
+
+ return (cfg_get_uint32(cfg->options,
+ &cfg->options->max_ncache_ttl,
+ retval,
+ &cfg->options->setflags1,
+ MAX_NCACHE_TTL_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_gettransfersin(dns_c_ctx_t *cfg, isc_int32_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(DNS_C_CONFOPT_VALID(cfg->options));
+
+
+ return (cfg_get_int32(cfg->options,
+ &cfg->options->transfers_in,
+ retval,
+ &cfg->options->setflags1,
+ TRANSFERS_IN_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_gettransfersperns(dns_c_ctx_t *cfg, isc_int32_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(DNS_C_CONFOPT_VALID(cfg->options));
+
+ return (cfg_get_int32(cfg->options,
+ &cfg->options->transfers_per_ns,
+ retval,
+ &cfg->options->setflags1,
+ TRANSFERS_PER_NS_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_gettransfersout(dns_c_ctx_t *cfg, isc_int32_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(DNS_C_CONFOPT_VALID(cfg->options));
+
+ return (cfg_get_int32(cfg->options,
+ &cfg->options->transfers_out,
+ retval,
+ &cfg->options->setflags1,
+ TRANSFERS_OUT_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getmaxlogsizeixfr(dns_c_ctx_t *cfg, isc_int32_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(DNS_C_CONFOPT_VALID(cfg->options));
+
+ return (cfg_get_int32(cfg->options,
+ &cfg->options->max_log_size_ixfr,
+ retval,
+ &cfg->options->setflags1,
+ MAX_LOG_SIZE_IXFR_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getcleaninterval(dns_c_ctx_t *cfg, isc_int32_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(DNS_C_CONFOPT_VALID(cfg->options));
+
+ return (cfg_get_int32(cfg->options,
+ &cfg->options->clean_interval,
+ retval,
+ &cfg->options->setflags1,
+ CLEAN_INTERVAL_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getinterfaceinterval(dns_c_ctx_t *cfg, isc_int32_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_int32(cfg->options,
+ &cfg->options->interface_interval,
+ retval,
+ &cfg->options->setflags1,
+ INTERFACE_INTERVAL_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getstatsinterval(dns_c_ctx_t *cfg, isc_int32_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_int32(cfg->options,
+ &cfg->options->stats_interval,
+ retval,
+ &cfg->options->setflags1,
+ STATS_INTERVAL_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getheartbeatinterval(dns_c_ctx_t *cfg, isc_int32_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_int32(cfg->options,
+ &cfg->options->heartbeat_interval,
+ retval,
+ &cfg->options->setflags1,
+ HEARTBEAT_INTERVAL_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getmaxtransfertimein(dns_c_ctx_t *cfg, isc_int32_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_int32(cfg->options,
+ &cfg->options->max_transfer_time_in,
+ retval,
+ &cfg->options->setflags1,
+ MAX_TRANSFER_TIME_IN_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getmaxtransfertimeout(dns_c_ctx_t *cfg, isc_int32_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_int32(cfg->options,
+ &cfg->options->max_transfer_time_out,
+ retval,
+ &cfg->options->setflags1,
+ MAX_TRANSFER_TIME_OUT_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getmaxtransferidlein(dns_c_ctx_t *cfg, isc_int32_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_int32(cfg->options,
+ &cfg->options->max_transfer_idle_in,
+ retval,
+ &cfg->options->setflags1,
+ MAX_TRANSFER_IDLE_IN_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getmaxtransferidleout(dns_c_ctx_t *cfg, isc_int32_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_int32(cfg->options,
+ &cfg->options->max_transfer_idle_out,
+ retval,
+ &cfg->options->setflags1,
+ MAX_TRANSFER_IDLE_OUT_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_gettcpclients(dns_c_ctx_t *cfg, isc_int32_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_int32(cfg->options,
+ &cfg->options->tcp_clients,
+ retval,
+ &cfg->options->setflags1,
+ TCP_CLIENTS_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getrecursiveclients(dns_c_ctx_t *cfg, isc_int32_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_int32(cfg->options,
+ &cfg->options->recursive_clients,
+ retval,
+ &cfg->options->setflags1,
+ RECURSIVE_CLIENTS_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getdatasize(dns_c_ctx_t *cfg, isc_uint32_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_uint32(cfg->options,
+ &cfg->options->data_size,
+ retval,
+ &cfg->options->setflags1,
+ DATA_SIZE_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getstacksize(dns_c_ctx_t *cfg, isc_uint32_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_uint32(cfg->options,
+ &cfg->options->stack_size,
+ retval,
+ &cfg->options->setflags1,
+ STACK_SIZE_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getcoresize(dns_c_ctx_t *cfg, isc_uint32_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_uint32(cfg->options,
+ &cfg->options->core_size,
+ retval,
+ &cfg->options->setflags1,
+ CORE_SIZE_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getfiles(dns_c_ctx_t *cfg, isc_uint32_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_uint32(cfg->options,
+ &cfg->options->files,
+ retval,
+ &cfg->options->setflags1,
+ FILES_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getexpertmode(dns_c_ctx_t *cfg, isc_boolean_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_boolean(cfg->options,
+ &cfg->options->expert_mode,
+ retval,
+ &cfg->options->setflags1,
+ EXPERT_MODE_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getfakeiquery(dns_c_ctx_t *cfg, isc_boolean_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_boolean(cfg->options,
+ &cfg->options->fake_iquery,
+ retval,
+ &cfg->options->setflags1,
+ FAKE_IQUERY_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getrecursion(dns_c_ctx_t *cfg, isc_boolean_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_boolean(cfg->options,
+ &cfg->options->recursion,
+ retval,
+ &cfg->options->setflags1,
+ RECURSION_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getfetchglue(dns_c_ctx_t *cfg, isc_boolean_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_boolean(cfg->options,
+ &cfg->options->fetch_glue,
+ retval,
+ &cfg->options->setflags1,
+ FETCH_GLUE_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getnotify(dns_c_ctx_t *cfg, isc_boolean_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_boolean(cfg->options,
+ &cfg->options->notify,
+ retval,
+ &cfg->options->setflags1,
+ NOTIFY_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_gethoststatistics(dns_c_ctx_t *cfg, isc_boolean_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_boolean(cfg->options,
+ &cfg->options->host_statistics,
+ retval,
+ &cfg->options->setflags1,
+ HOST_STATISTICS_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getdealloconexit(dns_c_ctx_t *cfg, isc_boolean_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_boolean(cfg->options,
+ &cfg->options->dealloc_on_exit,
+ retval,
+ &cfg->options->setflags1,
+ DEALLOC_ON_EXIT_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getuseixfr(dns_c_ctx_t *cfg, isc_boolean_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_boolean(cfg->options,
+ &cfg->options->use_ixfr,
+ retval,
+ &cfg->options->setflags1,
+ USE_IXFR_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getmaintainixfrbase(dns_c_ctx_t *cfg, isc_boolean_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_boolean(cfg->options,
+ &cfg->options->maintain_ixfr_base,
+ retval,
+ &cfg->options->setflags1,
+ MAINTAIN_IXFR_BASE_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_gethasoldclients(dns_c_ctx_t *cfg, isc_boolean_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_boolean(cfg->options,
+ &cfg->options->has_old_clients,
+ retval,
+ &cfg->options->setflags1,
+ HAS_OLD_CLIENTS_BIT));
+}
+
+
+
+isc_result_t
+dns_c_ctx_getauthnxdomain(dns_c_ctx_t *cfg, isc_boolean_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_boolean(cfg->options,
+ &cfg->options->auth_nx_domain,
+ retval,
+ &cfg->options->setflags1,
+ AUTH_NX_DOMAIN_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getmultiplecnames(dns_c_ctx_t *cfg, isc_boolean_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_boolean(cfg->options,
+ &cfg->options->multiple_cnames,
+ retval,
+ &cfg->options->setflags1,
+ MULTIPLE_CNAMES_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getuseidpool(dns_c_ctx_t *cfg, isc_boolean_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_boolean(cfg->options,
+ &cfg->options->use_id_pool,
+ retval,
+ &cfg->options->setflags1,
+ USE_ID_POOL_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getrfc2308type1(dns_c_ctx_t *cfg, isc_boolean_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_boolean(cfg->options,
+ &cfg->options->rfc2308_type1,
+ retval,
+ &cfg->options->setflags1,
+ RFC2308_TYPE1_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getdialup(dns_c_ctx_t *cfg, isc_boolean_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ return (cfg_get_boolean(cfg->options,
+ &cfg->options->dialup,
+ retval,
+ &cfg->options->setflags1,
+ DIALUP_BIT));
+}
+
+
+isc_result_t
+dns_c_ctx_getquerysourceaddr(dns_c_ctx_t *cfg, isc_sockaddr_t *addr)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(addr != NULL);
+
+ if (DNS_C_CHECKBIT(QUERY_SOURCE_ADDR_BIT, &cfg->options->setflags1)) {
+ *addr = cfg->options->query_source_addr;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ctx_getquerysourceport(dns_c_ctx_t *cfg, in_port_t *port)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(port != NULL);
+
+ if (DNS_C_CHECKBIT(QUERY_SOURCE_PORT_BIT, &cfg->options->setflags1)) {
+ *port = cfg->options->query_source_port;
+ return (ISC_R_SUCCESS);
+ } else {
+ return (ISC_R_NOTFOUND);
+ }
+}
+
+
+isc_result_t
+dns_c_ctx_gettransferformat(dns_c_ctx_t *cfg,
+ dns_transfer_format_t *retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+
+ if (DNS_C_CHECKBIT(OPTIONS_TRANSFER_FORMAT_BIT,
+ &cfg->options->setflags1)) {
+ *retval = cfg->options->transfer_format;
+ return (ISC_R_SUCCESS);
+ } else {
+ return (ISC_R_NOTFOUND);
+ }
+}
+
+
+isc_result_t
+dns_c_ctx_getchecknames(dns_c_ctx_t *cfg,
+ dns_c_trans_t transtype,
+ dns_severity_t *sever)
+{
+ isc_boolean_t isset = ISC_FALSE;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(sever != NULL);
+
+ switch (transtype) {
+ case dns_trans_primary:
+ isset = DNS_C_CHECKBIT(CHECKNAME_PRIM_BIT,
+ &cfg->options->setflags1);
+ break;
+
+ case dns_trans_secondary:
+ isset = DNS_C_CHECKBIT(CHECKNAME_SEC_BIT,
+ &cfg->options->setflags1);
+ break;
+
+ case dns_trans_response:
+ isset = DNS_C_CHECKBIT(CHECKNAME_RESP_BIT,
+ &cfg->options->setflags1);
+ break;
+
+ default:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "bad transport value: %d", transtype);
+ return (ISC_R_FAILURE);
+ }
+
+ if (isset) {
+ *sever = cfg->options->check_names[transtype];
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ctx_getqueryacl(dns_c_ctx_t *cfg, dns_c_ipmatchlist_t **list)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(list != NULL);
+
+ return (cfg_get_ipmatchlist(cfg->options, cfg->options->queryacl,
+ list));
+}
+
+
+isc_result_t
+dns_c_ctx_gettransferacl(dns_c_ctx_t *cfg, dns_c_ipmatchlist_t **list)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(list != NULL);
+
+ return (cfg_get_ipmatchlist(cfg->options,
+ cfg->options->transferacl, list));
+}
+
+
+isc_result_t
+dns_c_ctx_getrecursionacl(dns_c_ctx_t *cfg, dns_c_ipmatchlist_t **list)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(list != NULL);
+
+ return (cfg_get_ipmatchlist(cfg->options, cfg->options->recursionacl,
+ list));
+}
+
+
+isc_result_t
+dns_c_ctx_getblackhole(dns_c_ctx_t *cfg, dns_c_ipmatchlist_t **list)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(list != NULL);
+
+ return (cfg_get_ipmatchlist(cfg->options,
+ cfg->options->blackhole, list));
+}
+
+
+isc_result_t
+dns_c_ctx_gettopology(dns_c_ctx_t *cfg, dns_c_ipmatchlist_t **list)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(list != NULL);
+
+ return (cfg_get_ipmatchlist(cfg->options,
+ cfg->options->topology, list));
+}
+
+
+isc_result_t
+dns_c_ctx_getsortlist(dns_c_ctx_t *cfg, dns_c_ipmatchlist_t **list)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(list != NULL);
+
+ return (cfg_get_ipmatchlist(cfg->options,
+ cfg->options->sortlist, list));
+}
+
+
+isc_result_t
+dns_c_ctx_getlistenlist(dns_c_ctx_t *cfg, dns_c_lstnlist_t **ll)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(ll != NULL);
+
+ *ll = NULL;
+
+ if (cfg->options->listens != NULL) {
+ *ll = cfg->options->listens;
+ }
+
+ return (*ll == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctx_getforward(dns_c_ctx_t *cfg, dns_c_forw_t *forw)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(forw != NULL);
+
+ if (DNS_C_CHECKBIT(FORWARD_BIT, &cfg->options->setflags1)) {
+ return (ISC_R_NOTFOUND);
+ } else {
+ *forw = cfg->options->forward;
+ res = ISC_R_SUCCESS;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ctx_getforwarders(dns_c_ctx_t *cfg, dns_c_iplist_t **list)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(list != NULL);
+
+ return (cfg_get_iplist(cfg->options,
+ cfg->options->forwarders, list));
+}
+
+
+isc_result_t
+dns_c_ctx_getrrsetorderlist(dns_c_ctx_t *cfg, dns_c_rrsolist_t **retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->options == NULL || cfg->options->ordering == NULL) {
+ return (ISC_R_NOTFOUND);
+ } else {
+ *retval = cfg->options->ordering;
+ return (ISC_R_SUCCESS);
+ }
+}
+
+
+isc_result_t
+dns_c_ctx_gettrustedkeys(dns_c_ctx_t *cfg, dns_c_tkeylist_t **retval)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(retval != NULL);
+
+ if (cfg->trusted_keys == NULL) {
+ return (ISC_R_NOTFOUND);
+ } else {
+ *retval = cfg->trusted_keys;
+ return (ISC_R_SUCCESS);
+ }
+}
+
+
+
+isc_result_t
+dns_c_ctx_optionsnew(isc_mem_t *mem, dns_c_options_t **options)
+{
+ int i;
+ dns_c_options_t *opts = NULL;
+
+ REQUIRE(mem != NULL);
+ REQUIRE(options != NULL);
+
+ *options = NULL;
+
+ opts = isc_mem_get(mem, sizeof *opts);
+ if (opts == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ opts->directory = NULL;
+ opts->version = NULL;
+ opts->dump_filename = NULL;
+ opts->pid_filename = NULL;
+ opts->stats_filename = NULL;
+ opts->memstats_filename = NULL;
+ opts->named_xfer = NULL;
+ opts->tkeydomain = NULL;
+ opts->also_notify = NULL;
+ opts->tkeydhkeycp = NULL;
+ opts->tkeydhkeyi = 0;
+
+ opts->mem = mem;
+ opts->magic = DNS_C_OPTION_MAGIC;
+ opts->flags = 0;
+ opts->max_ncache_ttl = 0;
+
+ opts->transfers_in = 0;
+ opts->transfers_per_ns = 0;
+ opts->transfers_out = 0;
+ opts->max_log_size_ixfr = 0;
+ opts->clean_interval = 0;
+ opts->interface_interval = 0;
+ opts->stats_interval = 0;
+ opts->heartbeat_interval = 0;
+
+ opts->fake_iquery = ISC_FALSE;
+ opts->recursion = ISC_FALSE;
+ opts->fetch_glue = ISC_FALSE;
+ opts->notify = ISC_FALSE;
+ opts->host_statistics = ISC_FALSE;
+ opts->dealloc_on_exit = ISC_FALSE;
+ opts->use_ixfr = ISC_FALSE;
+ opts->maintain_ixfr_base = ISC_FALSE;
+ opts->has_old_clients = ISC_FALSE;
+ opts->expert_mode = ISC_FALSE;
+ opts->auth_nx_domain = ISC_FALSE;
+ opts->multiple_cnames = ISC_FALSE;
+ opts->use_id_pool = ISC_FALSE;
+ opts->rfc2308_type1 = ISC_FALSE;
+ opts->dialup = ISC_FALSE;
+
+ opts->tcp_clients = 0;
+ opts->recursive_clients = 0;
+
+ opts->max_transfer_time_in = 0;
+ opts->max_transfer_time_out = 0;
+ opts->max_transfer_idle_in = 0;
+ opts->max_transfer_idle_out = 0;
+
+ opts->data_size = 0;
+ opts->stack_size = 0;
+ opts->core_size = 0;
+ opts->files = 0;
+
+ opts->transfer_format = dns_one_answer;
+
+ for (i = 0 ; i < DNS_C_TRANSCOUNT ; i++) {
+ opts->check_names[i] = dns_severity_fail;
+ }
+
+ opts->queryacl = NULL;
+ opts->transferacl = NULL;
+ opts->recursionacl = NULL;
+ opts->blackhole = NULL;
+ opts->topology = NULL;
+ opts->sortlist = NULL;
+ opts->listens = NULL;
+ opts->ordering = NULL;
+
+ opts->forward = dns_c_forw_only;
+ opts->forwarders = NULL;
+
+ memset(&opts->setflags1, 0x0, sizeof opts->setflags1);
+
+ *options = opts;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctx_optionsdelete(dns_c_options_t **opts)
+{
+ dns_c_options_t *options;
+ isc_result_t r, result;
+
+ REQUIRE(opts != NULL);
+
+ options = *opts;
+ if (options == NULL) {
+ return (ISC_R_SUCCESS);
+ }
+
+ REQUIRE(DNS_C_CONFOPT_VALID(options));
+
+ if (options->directory != NULL) {
+ isc_mem_free(options->mem, options->directory);
+ }
+
+ if (options->version != NULL) {
+ isc_mem_free(options->mem, options->version);
+ }
+
+ if (options->dump_filename != NULL) {
+ isc_mem_free(options->mem, options->dump_filename);
+ }
+
+ if (options->pid_filename != NULL) {
+ isc_mem_free(options->mem, options->pid_filename);
+ }
+
+ if (options->stats_filename != NULL) {
+ isc_mem_free(options->mem, options->stats_filename);
+ }
+
+ if (options->memstats_filename != NULL) {
+ isc_mem_free(options->mem, options->memstats_filename);
+ }
+
+ if (options->named_xfer != NULL) {
+ isc_mem_free(options->mem, options->named_xfer);
+ }
+
+ if (options->also_notify != NULL) {
+ dns_c_iplist_detach(&options->also_notify);
+ }
+
+ if (options->tkeydomain != NULL) {
+ isc_mem_free(options->mem, options->tkeydomain);
+ }
+
+ if (options->tkeydhkeycp != NULL) {
+ isc_mem_free(options->mem, options->tkeydhkeycp);
+ }
+
+ result = ISC_R_SUCCESS;
+
+ if (options->queryacl != NULL) {
+ r = dns_c_ipmatchlist_detach(&options->queryacl);
+ if (r != ISC_R_SUCCESS)
+ result = r;
+ }
+
+ if (options->transferacl != NULL) {
+ r = dns_c_ipmatchlist_detach(&options->transferacl);
+ if (r != ISC_R_SUCCESS)
+ result = r;
+ }
+
+ if (options->recursionacl != NULL) {
+ r = dns_c_ipmatchlist_detach(&options->recursionacl);
+ if (r != ISC_R_SUCCESS)
+ result = r;
+ }
+
+ if (options->blackhole != NULL) {
+ r = dns_c_ipmatchlist_detach(&options->blackhole);
+ if (r != ISC_R_SUCCESS)
+ result = r;
+ }
+
+ if (options->topology != NULL) {
+ r = dns_c_ipmatchlist_detach(&options->topology);
+ if (r != ISC_R_SUCCESS)
+ result = r;
+ }
+
+ if (options->sortlist != NULL) {
+ r = dns_c_ipmatchlist_detach(&options->sortlist);
+ if (r != ISC_R_SUCCESS)
+ result = r;
+ }
+
+ if (options->listens != NULL) {
+ r = dns_c_lstnlist_delete(&options->listens);
+ if (r != ISC_R_SUCCESS)
+ result = r;
+ }
+
+ if (options->ordering != NULL) {
+ r = dns_c_rrsolist_delete(&options->ordering);
+ if (r != ISC_R_SUCCESS)
+ result = r;
+ }
+
+ if (options->forwarders != NULL) {
+ r = dns_c_iplist_detach(&options->forwarders);
+ if (r != ISC_R_SUCCESS)
+ result = r;
+ }
+
+ *opts = NULL;
+ options->magic = 0;
+
+ isc_mem_put(options->mem, options, sizeof *options);
+
+ return (result);
+}
+
+
+void
+dns_c_ctx_optionsprint(FILE *fp, int indent, dns_c_options_t *options)
+{
+ dns_severity_t nameseverity;
+
+ REQUIRE(fp != NULL);
+
+ if (options == NULL) {
+ return;
+ }
+
+ REQUIRE(DNS_C_CONFOPT_VALID(options));
+
+#define PRINT_INTEGER(field, bit, name, bitfield) \
+ if (DNS_C_CHECKBIT(bit, &options->bitfield)) { \
+ dns_c_printtabs(fp, indent + 1); \
+ fprintf(fp, "%s %d;\n",name,(int)options->field); \
+ }
+
+#define PRINT_AS_MINUTES(field, bit, name, bitfield) \
+ if (DNS_C_CHECKBIT(bit, &options->bitfield)) { \
+ dns_c_printtabs(fp, indent + 1); \
+ fprintf(fp, "%s %lu;\n",name, \
+ (unsigned long)options->field / 60); \
+ }
+
+#define PRINT_AS_BOOLEAN(field, bit, name, bitfield) \
+ if (DNS_C_CHECKBIT(bit, &options->bitfield)) { \
+ dns_c_printtabs(fp, indent + 1); \
+ fprintf(fp, "%s %s;\n",name, \
+ (options->field ? "true" : "false")); \
+ }
+
+#define PRINT_AS_SIZE_CLAUSE(field, bit, name, bitfield) \
+ if (DNS_C_CHECKBIT(bit, &options->bitfield)) { \
+ dns_c_printtabs(fp, indent + 1); \
+ fprintf(fp, "%s ",name); \
+ if (options->field == DNS_C_SIZE_SPEC_DEFAULT) { \
+ fprintf(fp, "default"); \
+ } else { \
+ dns_c_printinunits(fp, options->field); \
+ } \
+ fprintf(fp, ";\n"); \
+ }
+
+#define PRINT_CHAR_P(field, name) \
+ if (options->field != NULL) { \
+ dns_c_printtabs(fp, indent + 1); \
+ fprintf(fp, "%s \"%s\";\n", name, options->field); \
+ }
+
+
+
+ dns_c_printtabs(fp, indent);
+ fprintf (fp, "options {\n");
+
+ PRINT_CHAR_P(version, "version");
+ PRINT_CHAR_P(directory, "directory");
+ PRINT_CHAR_P(dump_filename, "dump-file");
+ PRINT_CHAR_P(pid_filename, "pid-file");
+ PRINT_CHAR_P(stats_filename, "statistics-file");
+ PRINT_CHAR_P(memstats_filename, "memstatistics-file");
+ PRINT_CHAR_P(named_xfer, "named-xfer");
+ PRINT_CHAR_P(tkeydomain, "tkey-domain");
+
+ if (options->tkeydhkeycp != NULL) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "tkey-dhkey \"%s\" %d ;\n",
+ options->tkeydhkeycp, options->tkeydhkeyi);
+ }
+
+ PRINT_INTEGER(transfers_in, TRANSFERS_IN_BIT,
+ "transfers-in", setflags1);
+ PRINT_INTEGER(transfers_per_ns, TRANSFERS_PER_NS_BIT,
+ "transfers-per-ns", setflags1);
+ PRINT_INTEGER(transfers_out, TRANSFERS_OUT_BIT,
+ "transfers-out", setflags1);
+ PRINT_INTEGER(max_log_size_ixfr, MAX_LOG_SIZE_IXFR_BIT,
+ "max-ixfr-log-size", setflags1);
+ PRINT_INTEGER(tcp_clients, TCP_CLIENTS_BIT,
+ "tcp-clients", setflags1);
+ PRINT_INTEGER(recursive_clients, RECURSIVE_CLIENTS_BIT,
+ "recursive-clients", setflags1);
+
+
+ PRINT_INTEGER(max_ncache_ttl, MAX_NCACHE_TTL_BIT,
+ "max-ncache-ttl", setflags1);
+
+ PRINT_AS_MINUTES(clean_interval, CLEAN_INTERVAL_BIT,
+ "cleaning-interval", setflags1);
+ PRINT_AS_MINUTES(interface_interval, INTERFACE_INTERVAL_BIT,
+ "interface-interval", setflags1);
+ PRINT_AS_MINUTES(stats_interval, STATS_INTERVAL_BIT,
+ "statistics-interval", setflags1);
+ PRINT_AS_MINUTES(heartbeat_interval, HEARTBEAT_INTERVAL_BIT,
+ "heartbeat-interval", setflags1);
+ PRINT_AS_MINUTES(max_transfer_time_in, MAX_TRANSFER_TIME_IN_BIT,
+ "max-transfer-time-in", setflags1);
+ PRINT_AS_MINUTES(max_transfer_time_out, MAX_TRANSFER_TIME_OUT_BIT,
+ "max-transfer-time-out", setflags1);
+ PRINT_AS_MINUTES(max_transfer_idle_in, MAX_TRANSFER_IDLE_IN_BIT,
+ "max-transfer-idle-in", setflags1);
+ PRINT_AS_MINUTES(max_transfer_idle_out, MAX_TRANSFER_IDLE_OUT_BIT,
+ "max-transfer-idle-out", setflags1);
+
+ PRINT_AS_SIZE_CLAUSE(data_size, DATA_SIZE_BIT, "datasize",
+ setflags1);
+ PRINT_AS_SIZE_CLAUSE(stack_size, STACK_SIZE_BIT, "stacksize",
+ setflags1);
+ PRINT_AS_SIZE_CLAUSE(core_size, CORE_SIZE_BIT, "coresize",
+ setflags1);
+ PRINT_AS_SIZE_CLAUSE(files, FILES_BIT, "files",
+ setflags1);
+
+ PRINT_AS_BOOLEAN(expert_mode, EXPERT_MODE_BIT,
+ "expert-mode", setflags1);
+ PRINT_AS_BOOLEAN(fake_iquery, FAKE_IQUERY_BIT,
+ "fake-iquery", setflags1);
+ PRINT_AS_BOOLEAN(recursion, RECURSION_BIT,
+ "recursion", setflags1);
+ PRINT_AS_BOOLEAN(fetch_glue, FETCH_GLUE_BIT,
+ "fetch-glue", setflags1);
+ PRINT_AS_BOOLEAN(notify, NOTIFY_BIT,
+ "notify", setflags1);
+ PRINT_AS_BOOLEAN(host_statistics, HOST_STATISTICS_BIT,
+ "host-statistics", setflags1);
+ PRINT_AS_BOOLEAN(dealloc_on_exit, DEALLOC_ON_EXIT_BIT,
+ "deallocate-on-exit", setflags1);
+ PRINT_AS_BOOLEAN(use_ixfr, USE_IXFR_BIT,
+ "use-ixfr", setflags1);
+ PRINT_AS_BOOLEAN(maintain_ixfr_base, MAINTAIN_IXFR_BASE_BIT,
+ "maintain-ixfr-base", setflags1);
+ PRINT_AS_BOOLEAN(has_old_clients, HAS_OLD_CLIENTS_BIT,
+ "has-old-clients", setflags1);
+ PRINT_AS_BOOLEAN(auth_nx_domain, AUTH_NX_DOMAIN_BIT,
+ "auth-nxdomain", setflags1);
+ PRINT_AS_BOOLEAN(multiple_cnames, MULTIPLE_CNAMES_BIT,
+ "multiple-cnames", setflags1);
+ PRINT_AS_BOOLEAN(use_id_pool, USE_ID_POOL_BIT,
+ "use-id-pool", setflags1);
+ PRINT_AS_BOOLEAN(rfc2308_type1, RFC2308_TYPE1_BIT,
+ "rfc2308-type1", setflags1);
+ PRINT_AS_BOOLEAN(dialup, DIALUP_BIT,
+ "dialup", setflags1);
+
+#undef PRINT_INTEGER
+#undef PRINT_AS_MINUTES
+#undef PRINT_AS_BOOLEAN
+#undef PRINT_AS_SIZE_CLAUSE
+#undef PRINT_CHAR_P
+
+
+ if (DNS_C_CHECKBIT(OPTIONS_TRANSFER_FORMAT_BIT, &options->setflags1)) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "transfer-format %s;\n",
+ dns_c_transformat2string(options->transfer_format,
+ ISC_TRUE));
+ }
+
+
+ if (DNS_C_CHECKBIT(QUERY_SOURCE_PORT_BIT, &options->setflags1) ||
+ DNS_C_CHECKBIT(QUERY_SOURCE_ADDR_BIT, &options->setflags1)) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "query-source ");
+
+ if (DNS_C_CHECKBIT(QUERY_SOURCE_ADDR_BIT,
+ &options->setflags1)) {
+ fprintf(fp, "address ");
+ dns_c_print_ipaddr(fp, &options->query_source_addr);
+ }
+
+ if (DNS_C_CHECKBIT(QUERY_SOURCE_PORT_BIT,
+ &options->setflags1)) {
+ if (options->query_source_port == 0) {
+ fprintf(fp, " port *");
+ } else {
+ fprintf(fp, " port %d",
+ options->query_source_port);
+ }
+ }
+ fprintf(fp, " ;\n");
+ }
+
+
+ if (DNS_C_CHECKBIT(CHECKNAME_PRIM_BIT, &options->setflags1)) {
+ nameseverity = options->check_names[dns_trans_primary];
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "check-names %s %s;\n",
+ dns_c_transport2string(dns_trans_primary,
+ ISC_TRUE),
+ dns_c_nameseverity2string(nameseverity,
+ ISC_TRUE));
+ }
+
+ if (DNS_C_CHECKBIT(CHECKNAME_SEC_BIT, &options->setflags1)) {
+ nameseverity = options->check_names[dns_trans_secondary];
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "check-names %s %s;\n",
+ dns_c_transport2string(dns_trans_secondary,
+ ISC_TRUE),
+ dns_c_nameseverity2string(nameseverity,
+ ISC_TRUE));
+ }
+
+ if (DNS_C_CHECKBIT(CHECKNAME_RESP_BIT, &options->setflags1)) {
+ nameseverity = options->check_names[dns_trans_response];
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "check-names %s %s;\n",
+ dns_c_transport2string(dns_trans_response,
+ ISC_TRUE),
+ dns_c_nameseverity2string(nameseverity,
+ ISC_TRUE));
+ }
+
+ fprintf(fp, "\n");
+
+ if (options->queryacl != NULL) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "allow-query ");
+ dns_c_ipmatchlist_print(fp, 2, options->queryacl);
+ fprintf(fp, ";\n");
+ }
+
+ if (options->transferacl != NULL) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "allow-transfer ");
+ dns_c_ipmatchlist_print(fp, 2, options->transferacl);
+ fprintf(fp, ";\n");
+ }
+
+ if (options->recursionacl != NULL) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "allow-recursion ");
+ dns_c_ipmatchlist_print(fp, 2, options->recursionacl);
+ fprintf(fp, ";\n");
+ }
+
+ if (options->blackhole != NULL) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "blackhole ");
+ dns_c_ipmatchlist_print(fp, 2, options->blackhole);
+ fprintf(fp, ";\n");
+ }
+
+ if (options->topology != NULL) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "topology ");
+ dns_c_ipmatchlist_print(fp, 2, options->topology);
+ fprintf(fp, ";\n");
+ }
+
+ if (options->sortlist != NULL) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "sortlist ");
+ dns_c_ipmatchlist_print(fp, 2, options->sortlist);
+ fprintf(fp, ";\n");
+ }
+
+ if (options->listens != NULL) {
+ dns_c_lstnlist_print(fp, indent + 1,
+ options->listens);
+ }
+
+ dns_c_ctx_forwarderprint(fp, indent + 1, options);
+
+ if (options->ordering != NULL) {
+ dns_c_rrsolist_print(fp, indent + 1, options->ordering);
+ }
+
+ if (options->also_notify != NULL) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "also-notify ") ;
+ dns_c_iplist_print(fp, indent + 2, options->also_notify);
+ fprintf(fp, ";\n");
+ }
+
+ if (DNS_C_CHECKBIT(TRANSFER_SOURCE_BIT, &options->setflags1)) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "transfer-source ");
+ dns_c_print_ipaddr(fp, &options->transfer_source);
+ fprintf(fp, ";\n");
+ }
+
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp,"};\n");
+}
+
+
+isc_boolean_t
+dns_c_ctx_keydefinedp(dns_c_ctx_t *ctx, const char *keyname)
+{
+ dns_c_kdef_t *keyid;
+ isc_result_t res;
+ isc_boolean_t rval = ISC_FALSE;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(ctx));
+ REQUIRE(keyname != NULL);
+ REQUIRE(strlen(keyname) > 0);
+
+ if (ctx->keydefs != NULL) {
+ res = dns_c_kdeflist_find(ctx->keydefs, keyname, &keyid);
+ if (res == ISC_R_SUCCESS) {
+ rval = ISC_TRUE;
+ }
+ }
+
+ return rval;
+}
+
+
+isc_result_t
+dns_c_ctx_setalsonotify(dns_c_ctx_t *cfg,
+ dns_c_iplist_t *iml,
+ isc_boolean_t copy)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ REQUIRE(iml != NULL);
+
+ res = cfg_set_iplist(cfg->options, &cfg->options->also_notify,
+ iml, copy);
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ctx_getalsonotify(dns_c_ctx_t *cfg, dns_c_iplist_t **ret)
+{
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(ret != NULL);
+
+ return (cfg_get_iplist(cfg->options, cfg->options->also_notify, ret));
+}
+
+
+isc_result_t
+dns_c_ctx_settransfersource(dns_c_ctx_t *cfg, isc_sockaddr_t newval)
+{
+ isc_boolean_t existed;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ res = make_options(cfg);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ existed = DNS_C_CHECKBIT(TRANSFER_SOURCE_BIT,
+ &cfg->options->setflags1);
+ DNS_C_SETBIT(TRANSFER_SOURCE_BIT, &cfg->options->setflags1);
+
+ cfg->options->transfer_source = newval;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ctx_gettransfersource(dns_c_ctx_t *cfg, isc_sockaddr_t *retval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ if (cfg->options == NULL) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ REQUIRE(retval != NULL);
+
+ if (DNS_C_CHECKBIT(TRANSFER_SOURCE_BIT, &cfg->options->setflags1)) {
+ *retval = cfg->options->transfer_source;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+
+
+/***************************************************************************/
+
+
+static isc_result_t
+cfg_set_string(dns_c_options_t *options, char **field, const char *newval)
+{
+ char *p;
+ isc_boolean_t existed = ISC_FALSE;
+
+ REQUIRE(DNS_C_CONFOPT_VALID(options));
+ REQUIRE(field != NULL);
+
+ p = *field;
+ *field = NULL;
+
+ if (p != NULL) {
+ existed = ISC_TRUE;
+ }
+
+ if (newval == NULL) {
+ if (p != NULL) {
+ isc_mem_free(options->mem, p);
+ }
+ p = NULL;
+ } else if (p == NULL) {
+ p = isc_mem_strdup(options->mem, newval);
+ if (p == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+ } else if (strlen(p) >= strlen(newval)) {
+ strcpy(p, newval);
+ } else {
+ isc_mem_free(options->mem, p);
+ p = isc_mem_strdup(options->mem, newval);
+ if (p == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+ }
+
+ *field = p;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+static isc_result_t
+cfg_set_iplist(dns_c_options_t *options,
+ dns_c_iplist_t **fieldaddr,
+ dns_c_iplist_t *newval,
+ isc_boolean_t copy)
+{
+ isc_result_t res;
+ isc_boolean_t existed = ISC_FALSE;
+
+ REQUIRE(DNS_C_CONFOPT_VALID(options));
+ REQUIRE(fieldaddr != NULL);
+
+ if (*fieldaddr != NULL) {
+ existed = ISC_TRUE;
+ }
+
+ if (newval == NULL) {
+ res = dns_c_iplist_new(options->mem,
+ newval->size,
+ fieldaddr);
+ } else if (copy) {
+ if (*fieldaddr != NULL) {
+ dns_c_iplist_detach(fieldaddr);
+ }
+
+ res = dns_c_iplist_copy(options->mem, fieldaddr,
+ newval);
+ } else {
+ if (*fieldaddr != NULL) {
+ res = dns_c_iplist_detach(fieldaddr);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ }
+
+ res = ISC_R_SUCCESS;
+
+ *fieldaddr = newval;
+ }
+
+ if (res == ISC_R_SUCCESS && existed) {
+ res = ISC_R_EXISTS;
+ }
+
+ return (res);
+}
+
+
+static isc_result_t
+cfg_set_ipmatchlist(dns_c_options_t *options,
+ dns_c_ipmatchlist_t **fieldaddr,
+ dns_c_ipmatchlist_t *newval,
+ isc_boolean_t copy)
+{
+ isc_result_t res;
+ isc_boolean_t existed = ISC_FALSE;
+
+ REQUIRE(DNS_C_CONFOPT_VALID(options));
+ REQUIRE(fieldaddr != NULL);
+
+ if (*fieldaddr != NULL) {
+ existed = ISC_TRUE;
+ }
+
+ if (newval == NULL) {
+ res = dns_c_ipmatchlist_new(options->mem, fieldaddr);
+ } else if (copy) {
+ if (*fieldaddr != NULL) {
+ res = dns_c_ipmatchlist_empty(*fieldaddr);
+ if (res == ISC_R_SUCCESS && newval != NULL) {
+ res = dns_c_ipmatchlist_append(*fieldaddr,
+ newval,
+ ISC_FALSE);
+ }
+ } else {
+ res = dns_c_ipmatchlist_copy(options->mem,
+ fieldaddr, newval);
+ }
+ } else {
+ if (*fieldaddr != NULL) {
+ res = dns_c_ipmatchlist_detach(fieldaddr);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ }
+
+ res = ISC_R_SUCCESS;
+
+ *fieldaddr = newval;
+ }
+
+ if (res == ISC_R_SUCCESS && existed) {
+ res = ISC_R_EXISTS;
+ }
+
+ return (res);
+}
+
+
+
+static isc_result_t
+cfg_set_boolean(dns_c_options_t *options,
+ isc_boolean_t *fieldaddr,
+ isc_boolean_t newval,
+ dns_c_setbits_t *setfield,
+ isc_uint32_t bitnumber)
+{
+ isc_boolean_t existed;
+
+ REQUIRE(DNS_C_CONFOPT_VALID(options));
+ REQUIRE(setfield != NULL);
+ REQUIRE(fieldaddr != NULL);
+ REQUIRE(bitnumber < DNS_C_SETBITS_SIZE);
+
+ *fieldaddr = newval;
+
+ existed = DNS_C_CHECKBIT(bitnumber, setfield);
+ DNS_C_SETBIT(bitnumber, setfield);
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+static isc_result_t
+cfg_set_int32(dns_c_options_t *options,
+ isc_int32_t *fieldaddr,
+ isc_int32_t newval,
+ dns_c_setbits_t *setfield,
+ isc_uint32_t bitnumber)
+{
+ isc_boolean_t existed;
+
+ REQUIRE(DNS_C_CONFOPT_VALID(options));
+ REQUIRE(setfield != NULL);
+ REQUIRE(fieldaddr != NULL);
+ REQUIRE(bitnumber < DNS_C_SETBITS_SIZE);
+
+ *fieldaddr = newval;
+
+ existed = DNS_C_CHECKBIT(bitnumber, setfield);
+ DNS_C_SETBIT(bitnumber, setfield);
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+static isc_result_t
+cfg_set_uint32(dns_c_options_t *options,
+ isc_uint32_t *fieldaddr,
+ isc_uint32_t newval,
+ dns_c_setbits_t *setfield,
+ isc_uint32_t bitnumber)
+{
+ isc_boolean_t existed;
+
+ REQUIRE(DNS_C_CONFOPT_VALID(options));
+ REQUIRE(setfield != NULL);
+ REQUIRE(fieldaddr != NULL);
+ REQUIRE(bitnumber < DNS_C_SETBITS_SIZE);
+
+ *fieldaddr = newval;
+
+ existed = DNS_C_CHECKBIT(bitnumber, setfield);
+ DNS_C_SETBIT(bitnumber, setfield);
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+static isc_result_t
+cfg_get_ipmatchlist(dns_c_options_t *options,
+ dns_c_ipmatchlist_t *field,
+ dns_c_ipmatchlist_t **resval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFOPT_VALID(options));
+ REQUIRE(resval != NULL);
+
+ if (field != NULL && !ISC_LIST_EMPTY(field->elements)) {
+ dns_c_ipmatchlist_attach(field, resval);
+ res = ISC_R_SUCCESS;
+ } else {
+ *resval = NULL;
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+static isc_result_t
+cfg_get_iplist(dns_c_options_t *options,
+ dns_c_iplist_t *field,
+ dns_c_iplist_t **resval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFOPT_VALID(options));
+ REQUIRE(resval != NULL);
+
+ if (field != NULL && field->nextidx != 0) {
+ dns_c_iplist_attach(field, resval);
+ res = ISC_R_SUCCESS;
+ } else {
+ *resval = NULL;
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+static isc_result_t
+cfg_get_boolean(dns_c_options_t *options,
+ isc_boolean_t *field,
+ isc_boolean_t *result,
+ dns_c_setbits_t *setfield,
+ isc_uint32_t bitnumber)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFOPT_VALID(options));
+ REQUIRE(result != NULL);
+ REQUIRE(field != NULL);
+ REQUIRE(setfield != NULL);
+ REQUIRE(bitnumber < DNS_C_SETBITS_SIZE);
+
+ if (DNS_C_CHECKBIT(bitnumber,setfield)) {
+ *result = *field;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+static isc_result_t
+cfg_get_int32(dns_c_options_t *options,
+ isc_int32_t *field,
+ isc_int32_t *result,
+ dns_c_setbits_t *setfield,
+ isc_uint32_t bitnumber)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFOPT_VALID(options));
+ REQUIRE(result != NULL);
+ REQUIRE(field != NULL);
+ REQUIRE(setfield != NULL);
+ REQUIRE(bitnumber < DNS_C_SETBITS_SIZE);
+
+ if (DNS_C_CHECKBIT(bitnumber,setfield)) {
+ *result = *field;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+static isc_result_t
+cfg_get_uint32(dns_c_options_t *options,
+ isc_uint32_t *field,
+ isc_uint32_t *result,
+ dns_c_setbits_t *setfield,
+ isc_uint32_t bitnumber)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_CONFOPT_VALID(options));
+ REQUIRE(result != NULL);
+ REQUIRE(field != NULL);
+ REQUIRE(setfield != NULL);
+ REQUIRE(bitnumber < DNS_C_SETBITS_SIZE);
+
+ if (DNS_C_CHECKBIT(bitnumber,setfield)) {
+ *result = *field;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+static isc_result_t
+acl_init(dns_c_ctx_t *cfg)
+{
+ dns_c_ipmatchelement_t *ime;
+ dns_c_ipmatchlist_t *iml;
+ isc_sockaddr_t addr;
+ dns_c_acl_t *acl;
+ isc_result_t r;
+ static struct in_addr zeroaddr;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ isc_sockaddr_fromin(&addr, &zeroaddr, 0);
+
+ r = dns_c_acltable_new(cfg->mem, &cfg->acls);
+ if (r != ISC_R_SUCCESS) return (r);
+
+
+ /*
+ * The ANY acl.
+ */
+ r = dns_c_acl_new(cfg->acls, "any", ISC_TRUE, &acl);
+ if (r != ISC_R_SUCCESS) return (r);
+
+ r = dns_c_ipmatchpattern_new(cfg->mem, &ime, addr, 0);
+ if (r != ISC_R_SUCCESS) return (r);
+
+ r = dns_c_ipmatchlist_new(cfg->mem, &iml);
+ if (r != ISC_R_SUCCESS) return (r);
+
+ ISC_LIST_APPEND(iml->elements, ime, next);
+
+ dns_c_acl_setipml(acl, iml, ISC_FALSE);
+ iml = NULL;
+
+
+ /*
+ * The NONE acl
+ */
+
+ r = dns_c_acl_new(cfg->acls, "none", ISC_TRUE, &acl);
+ if (r != ISC_R_SUCCESS) return (r);
+
+ r = dns_c_ipmatchpattern_new(cfg->mem, &ime, addr, 0);
+ if (r != ISC_R_SUCCESS) return (r);
+
+ dns_c_ipmatch_negate(ime);
+
+ r = dns_c_ipmatchlist_new(cfg->mem, &iml);
+ if (r != ISC_R_SUCCESS) return (r);
+
+ ISC_LIST_APPEND(iml->elements, ime, next);
+
+ dns_c_acl_setipml(acl, iml, ISC_FALSE);
+ iml = NULL;
+
+
+ /*
+ * The LOCALHOST acl
+ */
+ r = dns_c_acl_new(cfg->acls, "localhost", ISC_TRUE, &acl);
+ if (r != ISC_R_SUCCESS) return (r);
+
+ r = dns_c_ipmatchlocalhost_new(cfg->mem, &ime);
+ if (r != ISC_R_SUCCESS) return (r);
+
+ r = dns_c_ipmatchlist_new(cfg->mem, &iml);
+ if (r != ISC_R_SUCCESS) return (r);
+
+ ISC_LIST_APPEND(iml->elements, ime, next);
+
+ dns_c_acl_setipml(acl, iml, ISC_FALSE);
+ iml = NULL;
+
+
+ /*
+ * The LOCALNETS acl
+ */
+ r = dns_c_acl_new(cfg->acls, "localnets", ISC_TRUE, &acl);
+ if (r != ISC_R_SUCCESS) return (r);
+
+ r = dns_c_ipmatchlocalnets_new(cfg->mem, &ime);
+ if (r != ISC_R_SUCCESS) return (r);
+
+ r = dns_c_ipmatchlist_new(cfg->mem, &iml);
+ if (r != ISC_R_SUCCESS) return (r);
+
+ ISC_LIST_APPEND(iml->elements, ime, next);
+
+ dns_c_acl_setipml(acl, iml, ISC_FALSE);
+ iml = NULL;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+static isc_result_t
+logging_init (dns_c_ctx_t *cfg)
+{
+ isc_result_t res;
+ dns_c_logcat_t *cat;
+ dns_c_logchan_t *chan;
+
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+ REQUIRE(cfg->logging == NULL);
+
+ res = dns_c_logginglist_new(cfg->mem, &cfg->logging);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ /* default_syslog channel */
+ chan = NULL;
+ res = dns_c_ctx_addsyslogchannel(cfg, DNS_C_DEFAULT_SYSLOG,
+ &chan);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ dns_c_logchan_setpredef(chan, ISC_TRUE);
+ dns_c_logchan_setfacility(chan, LOG_DAEMON);
+ dns_c_logchan_setseverity(chan, dns_c_log_info);
+
+
+ /* default_debug channel */
+ chan = NULL;
+ res = dns_c_ctx_addfile_channel(cfg, DNS_C_DEFAULT_DEBUG, &chan);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ dns_c_logchan_setpredef(chan, ISC_TRUE);
+ dns_c_logchan_setpath(chan, DNS_C_DEFAULT_DEBUG_PATH);
+ dns_c_logchan_setseverity(chan, dns_c_log_dynamic);
+
+
+ /* null channel */
+ chan = NULL;
+ res = dns_c_ctx_addnullchannel(cfg, DNS_C_NULL, &chan);
+ dns_c_logchan_setpredef(chan, ISC_TRUE);
+
+
+ /* default_stderr channel */
+ chan = NULL;
+ res = dns_c_ctx_addfile_channel(cfg, DNS_C_DEFAULT_STDERR,
+ &chan);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ dns_c_logchan_setpredef(chan, ISC_TRUE);
+ dns_c_logchan_setpath(chan, DNS_C_STDERR_PATH);
+ dns_c_logchan_setseverity(chan, dns_c_log_info);
+
+
+ /* default category */
+ cat = NULL;
+ res = dns_c_ctx_addcategory(cfg, dns_c_cat_default, &cat);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ dns_c_logcat_setpredef(cat, ISC_TRUE);
+ dns_c_logcat_addname(cat, DNS_C_DEFAULT_SYSLOG);
+ dns_c_logcat_addname(cat, DNS_C_DEFAULT_DEBUG);
+
+
+ /* panic category */
+ cat = NULL;
+ res = dns_c_ctx_addcategory(cfg, dns_c_cat_panic, &cat);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ dns_c_logcat_setpredef(cat, ISC_TRUE);
+ dns_c_logcat_addname(cat, DNS_C_DEFAULT_SYSLOG);
+ dns_c_logcat_addname(cat, DNS_C_DEFAULT_DEBUG);
+
+
+ /* eventlib category */
+ cat = NULL;
+ res = dns_c_ctx_addcategory(cfg, dns_c_cat_eventlib, &cat);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ dns_c_logcat_setpredef(cat, ISC_TRUE);
+ dns_c_logcat_addname(cat, DNS_C_DEFAULT_DEBUG);
+
+
+ /* packet category */
+ cat = NULL;
+ res = dns_c_ctx_addcategory(cfg, dns_c_cat_packet, &cat);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ dns_c_logcat_setpredef(cat, ISC_TRUE);
+ dns_c_logcat_addname(cat, DNS_C_DEFAULT_DEBUG);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+static isc_result_t
+make_options(dns_c_ctx_t *cfg)
+{
+ isc_result_t res = ISC_R_SUCCESS;
+ REQUIRE(DNS_C_CONFCTX_VALID(cfg));
+
+ if (cfg->options == NULL) {
+ res = dns_c_ctx_optionsnew(cfg->mem, &cfg->options);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ }
+
+ REQUIRE(DNS_C_CONFOPT_VALID(cfg->options));
+
+ return (res);
+}
+
+
diff --git a/lib/dns/config/confip.c b/lib/dns/config/confip.c
new file mode 100644
index 00000000..55d86001
--- /dev/null
+++ b/lib/dns/config/confip.c
@@ -0,0 +1,1044 @@
+/*
+ * 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.
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <isc/assertions.h>
+#include <isc/error.h>
+#include <isc/magic.h>
+
+#include <dns/confip.h>
+#include <dns/confcommon.h>
+#include <dns/log.h>
+
+/* Flag for dns_c_ipmatch_element */
+#define DNS_C_IPMATCH_NEGATE 0x01 /* match means deny access */
+
+
+static isc_result_t checkmask(isc_sockaddr_t *address, isc_uint32_t bits);
+static isc_result_t bits2v6mask(struct in6_addr *addr, isc_uint32_t bits);
+
+isc_result_t
+dns_c_ipmatchelement_new(isc_mem_t *mem, dns_c_ipmatchelement_t **result)
+{
+ dns_c_ipmatchelement_t *ime ;
+
+ REQUIRE(result != NULL);
+
+ *result = NULL;
+
+ ime = isc_mem_get(mem, sizeof *ime);
+ if (ime == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ ime->magic = DNS_C_IPMELEM_MAGIC;
+ ime->type = dns_c_ipmatch_none;
+ ime->flags = 0;
+ memset(&ime->u, 0x0, sizeof ime->u);
+
+ ISC_LINK_INIT(ime, next);
+
+ *result = ime;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_boolean_t
+dns_c_ipmatchelement_isneg(dns_c_ipmatchelement_t *elem)
+{
+
+ REQUIRE(DNS_C_IPMELEM_VALID(elem));
+
+ return (ISC_TF((elem->flags & DNS_C_IPMATCH_NEGATE) ==
+ DNS_C_IPMATCH_NEGATE));
+}
+
+
+isc_result_t
+dns_c_ipmatchelement_delete(isc_mem_t *mem, dns_c_ipmatchelement_t **ipme)
+{
+ dns_c_ipmatchelement_t *elem;
+
+ REQUIRE(mem != NULL);
+ REQUIRE(ipme != NULL);
+ REQUIRE(*ipme != NULL);
+
+ elem = *ipme;
+
+ REQUIRE(DNS_C_IPMELEM_VALID(elem));
+
+ switch (elem->type) {
+ case dns_c_ipmatch_localhost:
+ case dns_c_ipmatch_localnets:
+ case dns_c_ipmatch_pattern:
+ /* nothing */
+ break;
+
+ case dns_c_ipmatch_indirect:
+ INSIST(elem->u.indirect.list != NULL);
+
+ if (elem->u.indirect.list != NULL)
+ dns_c_ipmatchlist_detach(&elem->u.indirect.list);
+
+ if (elem->u.indirect.refname.base != NULL) {
+ isc_mem_put(mem, elem->u.indirect.refname.base,
+ elem->u.indirect.refname.length);
+ }
+ break;
+
+ case dns_c_ipmatch_key:
+ isc_mem_free(mem, elem->u.key );
+ break;
+
+ case dns_c_ipmatch_acl:
+ isc_mem_free(mem, elem->u.aclname);
+ break;
+
+ case dns_c_ipmatch_none:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "dns_ipmath_none element type");
+ return (ISC_R_FAILURE);
+ }
+
+ elem->magic = 0;
+ isc_mem_put(mem, elem, sizeof *elem);
+
+ *ipme = NULL;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ipmatchelement_copy(isc_mem_t *mem,
+ dns_c_ipmatchelement_t **dest,
+ dns_c_ipmatchelement_t *src)
+{
+ isc_result_t result;
+ dns_c_ipmatchelement_t *newel;
+
+ REQUIRE(mem != NULL);
+ REQUIRE(dest != NULL);
+ REQUIRE(DNS_C_IPMELEM_VALID(src));
+
+ result = dns_c_ipmatchelement_new(mem, &newel);
+ if (result != ISC_R_SUCCESS) {
+ return (result);
+ }
+
+ newel->type = src->type;
+ newel->flags = src->flags;
+
+ switch(src->type) {
+ case dns_c_ipmatch_pattern:
+ newel->u.direct.address = src->u.direct.address;
+ newel->u.direct.mask = src->u.direct.mask;
+ break;
+
+ case dns_c_ipmatch_indirect:
+ result = dns_c_ipmatchlist_copy(mem,
+ &newel->u.indirect.list,
+ src->u.indirect.list);
+ break;
+
+ case dns_c_ipmatch_localhost:
+ break;
+
+ case dns_c_ipmatch_localnets:
+ break;
+
+ case dns_c_ipmatch_key:
+ newel->u.key = isc_mem_strdup(mem, src->u.key);
+ break;
+
+ case dns_c_ipmatch_acl:
+ newel->u.aclname = isc_mem_strdup(mem, src->u.aclname);
+ break;
+
+ case dns_c_ipmatch_none:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "ipmatch 'none' element type");
+ return (ISC_R_FAILURE);
+ }
+
+ *dest = newel;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+isc_boolean_t
+dns_c_ipmatchelement_equal(dns_c_ipmatchelement_t *e1,
+ dns_c_ipmatchelement_t *e2)
+{
+ REQUIRE(DNS_C_IPMELEM_VALID(e1));
+ REQUIRE(DNS_C_IPMELEM_VALID(e2));
+
+ if ((e1->type != e2->type) || (e1->flags != e2->flags))
+ return (ISC_FALSE);
+
+ switch (e1->type) {
+ case dns_c_ipmatch_pattern:
+ if (e1->u.direct.mask != e2->u.direct.mask)
+ return (ISC_FALSE);
+ return (isc_sockaddr_equal(&e1->u.direct.address,
+ &e2->u.direct.address));
+
+ case dns_c_ipmatch_indirect:
+ return (dns_c_ipmatchlist_equal(e1->u.indirect.list,
+ e2->u.indirect.list));
+
+ case dns_c_ipmatch_localhost:
+ break;
+
+ case dns_c_ipmatch_localnets:
+ break;
+
+ case dns_c_ipmatch_key:
+ return (ISC_TF(strcmp(e1->u.key, e2->u.key) == 0));
+
+ case dns_c_ipmatch_acl:
+ return (ISC_TF(strcmp(e1->u.aclname, e2->u.aclname) == 0));
+
+ case dns_c_ipmatch_none:
+ break;
+ }
+ return (ISC_TRUE);
+}
+
+isc_result_t
+dns_c_ipmatchlocalhost_new(isc_mem_t *mem, dns_c_ipmatchelement_t **result)
+{
+ dns_c_ipmatchelement_t *ime = NULL;
+ isc_result_t res;
+
+ REQUIRE(mem != NULL);
+ REQUIRE(result != NULL);
+
+ *result = NULL;
+
+ res = dns_c_ipmatchelement_new(mem, &ime);
+ if (res == ISC_R_SUCCESS) {
+ ime->type = dns_c_ipmatch_localhost;
+ }
+
+ *result = ime;
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ipmatchlocalnets_new(isc_mem_t *mem,
+ dns_c_ipmatchelement_t **result)
+{
+ dns_c_ipmatchelement_t *ime = NULL;
+ isc_result_t res;
+
+ REQUIRE(mem != NULL);
+ REQUIRE(result != NULL);
+
+ *result = NULL;
+
+ res = dns_c_ipmatchelement_new(mem, &ime);
+ if (res == ISC_R_SUCCESS) {
+ ime->type = dns_c_ipmatch_localnets;
+ }
+
+ *result = ime;
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ipmatchindirect_new(isc_mem_t *mem,
+ dns_c_ipmatchelement_t **result,
+ dns_c_ipmatchlist_t *iml,
+ const char *name)
+{
+ dns_c_ipmatchelement_t *ime;
+ dns_c_ipmatchlist_t *iml_copy;
+ isc_result_t res;
+
+ REQUIRE(mem != NULL);
+ REQUIRE(result != NULL);
+ REQUIRE(DNS_C_IPMLIST_VALID(iml));
+
+ *result = NULL;
+
+ res = dns_c_ipmatchlist_copy(mem, &iml_copy, iml);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ res = dns_c_ipmatchelement_new(mem, &ime);
+ if (res == ISC_R_SUCCESS) {
+ ime->type = dns_c_ipmatch_indirect;
+ ime->u.indirect.list = iml_copy;
+ if (name != NULL) {
+ ime->u.indirect.refname.length = strlen(name) + 1;
+ ime->u.indirect.refname.base =
+ isc_mem_get(mem,
+ ime->u.indirect.refname.length);
+ RUNTIME_CHECK(ime->u.indirect.refname.base != NULL);
+ strcpy(ime->u.indirect.refname.base, name);
+ }
+ } else {
+ dns_c_ipmatchlist_detach(&iml_copy);
+ }
+
+ *result = ime;
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ipmatchpattern_new(isc_mem_t *mem,
+ dns_c_ipmatchelement_t **result,
+ isc_sockaddr_t address,
+ isc_uint32_t maskbits)
+{
+ dns_c_ipmatchelement_t *ime ;
+ isc_result_t res;
+
+ REQUIRE(result != NULL);
+ REQUIRE(mem != NULL);
+
+ *result = NULL;
+
+ res = checkmask(&address, maskbits);
+
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ res = dns_c_ipmatchelement_new(mem, &ime);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ ime->type = dns_c_ipmatch_pattern;
+ ime->u.direct.address = address;
+ ime->u.direct.mask = maskbits;
+
+ *result = ime;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ipmatchkey_new(isc_mem_t *mem,
+ dns_c_ipmatchelement_t **result,
+ const char *key)
+{
+ dns_c_ipmatchelement_t *ipme;
+ isc_result_t res;
+
+ REQUIRE(result != NULL);
+ REQUIRE(mem != NULL);
+ REQUIRE(key != NULL);
+
+ *result = NULL;
+
+ res = dns_c_ipmatchelement_new(mem, &ipme);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ ipme->type = dns_c_ipmatch_key;
+ ipme->u.key = isc_mem_strdup(mem, key);
+
+ *result = ipme;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ipmatch_aclnew(isc_mem_t *mem,
+ dns_c_ipmatchelement_t **result,
+ const char *aclname)
+{
+ dns_c_ipmatchelement_t *ipme;
+ isc_result_t res;
+
+ REQUIRE(result != NULL);
+ REQUIRE(mem != NULL);
+ REQUIRE(aclname != NULL);
+ REQUIRE(strlen(aclname) > 0);
+
+ *result = NULL;
+
+ res = dns_c_ipmatchelement_new(mem, &ipme);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ ipme->type = dns_c_ipmatch_acl;
+ ipme->u.aclname = isc_mem_strdup(mem, aclname);
+
+ *result = ipme;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ipmatch_negate(dns_c_ipmatchelement_t *ipe)
+{
+ REQUIRE(DNS_C_IPMELEM_VALID(ipe));
+
+ if ((ipe->flags & DNS_C_IPMATCH_NEGATE) == DNS_C_IPMATCH_NEGATE) {
+ ipe->flags &= ~DNS_C_IPMATCH_NEGATE;
+ } else {
+ ipe->flags |= DNS_C_IPMATCH_NEGATE;
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ipmatchlist_new(isc_mem_t *mem, dns_c_ipmatchlist_t **ptr)
+{
+ dns_c_ipmatchlist_t *newlist;
+
+ REQUIRE(ptr != NULL);
+ REQUIRE(mem != NULL);
+
+ newlist = isc_mem_get(mem, sizeof *newlist);
+ if (newlist == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ newlist->magic = DNS_C_IPMLIST_MAGIC;
+ newlist->mem = mem;
+ newlist->refcount = 1;
+
+ ISC_LIST_INIT(newlist->elements);
+
+ *ptr = newlist;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ipmatchlist_detach(dns_c_ipmatchlist_t **ml)
+{
+ dns_c_ipmatchelement_t *ime;
+ dns_c_ipmatchelement_t *iptr;
+ dns_c_ipmatchlist_t *iml;
+ isc_mem_t *mem;
+
+ REQUIRE(ml != NULL);
+ REQUIRE(*ml != NULL);
+
+ iml = *ml;
+ *ml = NULL;
+
+ REQUIRE(DNS_C_IPMLIST_VALID(iml));
+ INSIST(iml->refcount > 0);
+
+ iml->refcount--;
+ if (iml->refcount > 0) {
+ return (ISC_R_SUCCESS);
+ }
+
+ mem = iml->mem;
+ INSIST(mem != NULL);
+
+ ime = ISC_LIST_HEAD(iml->elements);
+ while (ime != NULL) {
+ iptr = ISC_LIST_NEXT(ime, next);
+ dns_c_ipmatchelement_delete(mem, &ime);
+
+ ime = iptr;
+ }
+
+ isc_mem_put(mem, iml, sizeof *iml);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+void
+dns_c_ipmatchlist_attach(dns_c_ipmatchlist_t *source,
+ dns_c_ipmatchlist_t **target)
+{
+
+ REQUIRE(DNS_C_IPMLIST_VALID(source));
+
+ INSIST(source->refcount > 0);
+
+ source->refcount++;
+ *target = source;
+}
+
+
+isc_result_t
+dns_c_ipmatchlist_empty(dns_c_ipmatchlist_t *ipml)
+{
+ dns_c_ipmatchelement_t *ime ;
+ dns_c_ipmatchelement_t *imptmp;
+ isc_result_t res = ISC_R_SUCCESS;
+
+ REQUIRE(DNS_C_IPMLIST_VALID(ipml));
+
+ ime = ISC_LIST_HEAD(ipml->elements);
+ while (ime != NULL) {
+ imptmp = ISC_LIST_NEXT(ime, next);
+ res = dns_c_ipmatchelement_delete(ipml->mem, &ime);
+ if (res != ISC_R_SUCCESS) {
+ break;
+ }
+ ime = imptmp;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_ipmatchlist_copy(isc_mem_t *mem,
+ dns_c_ipmatchlist_t **dest, dns_c_ipmatchlist_t *src)
+{
+ dns_c_ipmatchelement_t *ime;
+ dns_c_ipmatchelement_t *ptr;
+ dns_c_ipmatchlist_t *newlist;
+ isc_result_t result;
+
+ REQUIRE(mem != NULL);
+ REQUIRE(dest != NULL);
+ REQUIRE(DNS_C_IPMLIST_VALID(src));
+
+ *dest = NULL;
+
+ result = dns_c_ipmatchlist_new(mem, &newlist);
+ if (result != ISC_R_SUCCESS) {
+ return (result);
+ }
+
+ ime = ISC_LIST_HEAD(src->elements);
+ while (ime != NULL) {
+ result = dns_c_ipmatchelement_copy(mem, &ptr, ime);
+ if (result != ISC_R_SUCCESS) {
+ dns_c_ipmatchlist_detach(&newlist);
+ return (result);
+ }
+
+ ISC_LIST_APPEND(newlist->elements, ptr, next);
+
+ ime = ISC_LIST_NEXT(ime, next);
+ }
+
+ *dest = newlist;
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_boolean_t
+dns_c_ipmatchlist_equal(dns_c_ipmatchlist_t *l1, dns_c_ipmatchlist_t *l2) {
+ dns_c_ipmatchelement_t *e1, *e2;
+
+ REQUIRE(l1 == NULL || DNS_C_IPMLIST_VALID(l1));
+ REQUIRE(l2 == NULL || DNS_C_IPMLIST_VALID(l2));
+
+ if (l1 == NULL && l2 == NULL)
+ return (ISC_TRUE);
+ if (l1 != NULL || l2 != NULL)
+ return (ISC_FALSE);
+
+ e1 = ISC_LIST_HEAD(l1->elements);
+ e2 = ISC_LIST_HEAD(l2->elements);
+ while (e1 != NULL && e2 != NULL) {
+ if (!dns_c_ipmatchelement_equal(e1, e2))
+ return (ISC_FALSE);
+ e1 = ISC_LIST_NEXT(e1, next);
+ e2 = ISC_LIST_NEXT(e2, next);
+ }
+
+ if (l1 != NULL || l2 != NULL)
+ return (ISC_FALSE);
+ return (ISC_TRUE);
+}
+
+
+isc_result_t
+dns_c_ipmatchlist_append(dns_c_ipmatchlist_t *dest,
+ dns_c_ipmatchlist_t *src,
+ isc_boolean_t negate)
+{
+ dns_c_ipmatchelement_t *ime;
+ dns_c_ipmatchelement_t *ime_copy;
+ isc_result_t result = ISC_R_SUCCESS;
+
+ REQUIRE(DNS_C_IPMLIST_VALID(dest));
+ REQUIRE(DNS_C_IPMLIST_VALID(src));
+
+ ime = ISC_LIST_HEAD(src->elements);
+ while (ime != NULL) {
+ result = dns_c_ipmatchelement_copy(dest->mem,
+ &ime_copy,
+ ime);
+ if (result != ISC_R_SUCCESS) {
+ break;
+ }
+
+ if (negate) {
+ dns_c_ipmatch_negate(ime_copy);
+ }
+
+ ISC_LIST_APPEND(dest->elements, ime_copy, next);
+
+ ime = ISC_LIST_NEXT(ime, next);
+ }
+
+ return (result);
+}
+
+
+isc_result_t
+dns_c_ipmatchelement_print(FILE *fp, int indent,
+ dns_c_ipmatchelement_t *ipme)
+{
+ int bits;
+
+ REQUIRE(fp != NULL);
+ REQUIRE(DNS_C_IPMELEM_VALID(ipme));
+
+ if ((ipme->flags & DNS_C_IPMATCH_NEGATE) == DNS_C_IPMATCH_NEGATE) {
+ fputc('!', fp);
+ } else {
+ fputc(' ', fp);
+ }
+
+ switch (ipme->type) {
+ case dns_c_ipmatch_pattern:
+ dns_c_print_ipaddr(fp, &ipme->u.direct.address);
+
+ bits = ipme->u.direct.mask;
+ if (bits > 0) {
+ isc_uint32_t fam =
+ ipme->u.direct.address.type.sa.sa_family;
+ if ((fam == AF_INET && bits < 32) ||
+ (fam == AF_INET6 && bits < 128)) {
+ fprintf(fp, "/%d", bits);
+ }
+ }
+ break;
+
+ case dns_c_ipmatch_indirect:
+ if (ipme->u.indirect.refname.base != NULL) {
+ fprintf(fp, "%s", ipme->u.indirect.refname.base);
+ } else {
+ dns_c_ipmatchlist_print(fp, indent,
+ ipme->u.indirect.list);
+ }
+
+ break;
+
+ case dns_c_ipmatch_key:
+ fprintf(fp, "key %s", ipme->u.key);
+ break;
+
+ case dns_c_ipmatch_localhost:
+ fprintf(fp, "localhost");
+ break;
+
+ case dns_c_ipmatch_localnets:
+ fprintf(fp, "localnets");
+ break;
+
+ case dns_c_ipmatch_none:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "dns_ipmatch_none element type");
+ return (ISC_R_FAILURE);
+
+ case dns_c_ipmatch_acl:
+ fprintf(fp, "%s", ipme->u.aclname);
+ break;
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_ipmatchlist_print(FILE *fp, int indent, dns_c_ipmatchlist_t *ml)
+{
+ dns_c_ipmatchelement_t *ipme ;
+
+ REQUIRE(DNS_C_IPMLIST_VALID(ml));
+ REQUIRE(fp != NULL);
+
+ /* no indent on first line. */
+ fprintf(fp, "{\n");
+ ipme = ISC_LIST_HEAD(ml->elements);
+ if (ipme == NULL) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp,
+ "/* this list intentionally left blank */\n");
+ } else {
+ while (ipme != NULL) {
+ dns_c_printtabs(fp, indent);
+ dns_c_ipmatchelement_print(fp, indent + 1, ipme);
+ fprintf(fp, ";\n");
+
+ ipme = ISC_LIST_NEXT(ipme, next);
+ }
+ }
+
+ dns_c_printtabs(fp, indent - 1);
+ fprintf(fp, "}");
+
+ return (ISC_R_SUCCESS);
+}
+
+
+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;
+
+ REQUIRE(mem != NULL);
+ REQUIRE(length > 0);
+ REQUIRE(newlist != NULL);
+
+ list = isc_mem_get(mem, sizeof *list);
+ if (list == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ bytes = sizeof (isc_sockaddr_t) * length;
+ list->ips = isc_mem_get(mem, bytes);
+ if (list->ips == NULL) {
+ isc_mem_put(mem, list, sizeof *list);
+ return (ISC_R_NOMEMORY);
+ }
+
+ memset(list->ips, 0x0, bytes);
+
+ list->magic = DNS_C_IPLIST_MAGIC;
+ list->size = length;
+ list->nextidx = 0;
+ list->mem = mem;
+ list->refcount = 1;
+
+ *newlist = list;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_iplist_detach(dns_c_iplist_t **list)
+{
+ dns_c_iplist_t *l ;
+
+ REQUIRE(list != NULL);
+ REQUIRE(*list != NULL);
+
+ l = *list;
+
+ REQUIRE(DNS_C_IPLIST_VALID(l));
+ INSIST(l->refcount > 0);
+
+ l->refcount--;
+
+ if (l->refcount == 0) {
+ isc_mem_put(l->mem, l->ips, sizeof (isc_sockaddr_t) * l->size);
+ isc_mem_put(l->mem, l, sizeof *l);
+ }
+
+ *list = NULL;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+void
+dns_c_iplist_attach(dns_c_iplist_t *source,
+ dns_c_iplist_t **target)
+{
+ REQUIRE(DNS_C_IPLIST_VALID(source));
+ INSIST(source->refcount > 0);
+
+ source->refcount++;
+ *target = source;
+}
+
+
+
+isc_result_t
+dns_c_iplist_copy(isc_mem_t *mem, dns_c_iplist_t **dest, dns_c_iplist_t *src)
+{
+ dns_c_iplist_t *newl;
+ isc_result_t res;
+ isc_uint32_t i;
+
+ REQUIRE(dest != NULL);
+ REQUIRE(DNS_C_IPLIST_VALID(src));
+
+ res = dns_c_iplist_new(mem, src->size, &newl);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ for (i = 0 ; i < src->nextidx ; i++) {
+ newl->ips[i] = src->ips[i];
+ }
+ newl->nextidx = src->nextidx;
+
+ *dest = newl;
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_boolean_t
+dns_c_iplist_equal(dns_c_iplist_t *list1, dns_c_iplist_t *list2) {
+ isc_uint32_t i;
+
+ REQUIRE(DNS_C_IPLIST_VALID(list1));
+ REQUIRE(DNS_C_IPLIST_VALID(list2));
+
+ if (list1->nextidx != list2->nextidx)
+ return (ISC_FALSE);
+
+ for (i = 0 ; i < list1->nextidx ; i++) {
+ if (!isc_sockaddr_equal(&list1->ips[i], &list2->ips[i]))
+ return (ISC_FALSE);
+ }
+
+ return (ISC_TRUE);
+}
+
+
+void
+dns_c_iplist_print(FILE *fp, int indent, dns_c_iplist_t *list)
+{
+ isc_uint32_t i;
+
+ REQUIRE(DNS_C_IPLIST_VALID(list));
+
+ fprintf(fp, "{\n");
+
+ if (list->nextidx == 0) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "/* no ip addresses defined */\n");
+ } else {
+ for (i = 0 ; i < list->nextidx ; i++) {
+ dns_c_printtabs(fp, indent);
+ dns_c_print_ipaddr(fp, &list->ips[i]);
+ fprintf(fp, ";\n");
+ }
+ }
+
+ dns_c_printtabs(fp, indent - 1);
+ fprintf(fp, "}");
+}
+
+
+isc_result_t
+dns_c_iplist_append(dns_c_iplist_t *list, isc_sockaddr_t newaddr)
+{
+ isc_uint32_t i;
+
+ REQUIRE(DNS_C_IPLIST_VALID(list));
+
+ for (i = 0 ; i < list->nextidx ; i++) {
+ if (memcmp(&list->ips[i], &newaddr, sizeof newaddr) == 0) {
+ break;
+ }
+ }
+
+ if (i < list->nextidx) {
+ return (ISC_R_FAILURE);
+ }
+
+ if (list->nextidx == list->size) {
+ isc_sockaddr_t *newlist;
+ size_t newbytes;
+ size_t oldbytes = list->size * sizeof (list->ips[0]);
+ size_t newsize = list->size + 10;
+
+ newbytes = sizeof (list->ips[0]) * newsize;
+ newlist = isc_mem_get(list->mem, newbytes);
+ if (newlist == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ memset(newlist, 0x0, newbytes);
+ memcpy(newlist, list->ips, oldbytes);
+
+ isc_mem_put(list->mem, list->ips, oldbytes);
+ list->ips = newlist;
+ list->size = newsize;
+ }
+
+ list->ips[i] = newaddr;
+ list->nextidx++;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_iplist_remove(dns_c_iplist_t *list, isc_sockaddr_t newaddr)
+{
+ isc_uint32_t i;
+
+ REQUIRE(DNS_C_IPLIST_VALID(list));
+
+ for (i = 0 ; i < list->nextidx ; i++) {
+ if (memcmp(&list->ips[0], &newaddr, sizeof newaddr) == 0) {
+ break;
+ }
+ }
+
+ if (i == list->nextidx) {
+ return (ISC_R_FAILURE);
+ }
+
+ list->nextidx--;
+ for ( /* nothing */ ; i < list->nextidx ; i++) {
+ list->ips[i] = list->ips[i + 1];
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+
+/*
+ * Check that the address given is a network address with the given number
+ * of high order bits.
+ */
+static isc_result_t
+checkmask(isc_sockaddr_t *address, isc_uint32_t bits)
+{
+ if (bits > 0) {
+ if (address->type.sa.sa_family == AF_INET) {
+ isc_uint32_t mask;
+
+ if (bits > 32) {
+ return (ISC_R_FAILURE);
+ }
+
+ mask = ntohl(0xffffffffU << (32 - bits));
+
+ if ((mask & address->type.sin.sin_addr.s_addr) !=
+ address->type.sin.sin_addr.s_addr) {
+ return (ISC_R_FAILURE);
+ }
+ } else if (address->type.sa.sa_family == AF_INET6) {
+ struct in6_addr iaddr;
+ unsigned char *maskp;
+ unsigned char *addrp;
+ int i;
+
+ if (bits > 128) {
+ return (ISC_R_FAILURE);
+ }
+
+ if (bits2v6mask(&iaddr, bits) != ISC_R_SUCCESS) {
+ return (ISC_R_FAILURE);
+ }
+
+ addrp = (unsigned char *)&address->type.sin6.sin6_addr;
+ maskp = (unsigned char *)&iaddr;
+ for (i = 0 ; i < 16 ; i++) {
+ if ((addrp[i] & maskp[i]) != addrp[i]) {
+ return (ISC_R_FAILURE);
+ }
+ }
+ }
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+/*
+ * Create a 128 bits mask in network byte order in the the IPv6 address
+ * section of the sockaddr. The bits argument is the number of high bits
+ * that are to be set to 1.
+ */
+static isc_result_t
+bits2v6mask(struct in6_addr *addr, isc_uint32_t bits)
+{
+ int i;
+ isc_uint32_t bitmask[4];
+ char addrbuff [ sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" + 1 ];
+
+ INSIST(bits <= 128);
+
+ /* Break the 128 bits up into 32-bit sections */
+ bitmask[0] = bitmask[1] = bitmask[2] = bitmask[3] = 0U;
+
+ if (bits >= 32) {
+ bitmask[0] = 0xffffffffU;
+ } else if (bits > 0) {
+ bitmask[0] = 0xffffffffU << (32 - bits);
+ }
+
+ if (bits >= 64) {
+ bitmask[1] = 0xffffffffU;
+ } else if (bits > 32) {
+ bitmask[1] = 0xffffffffU << (64 - bits);
+ }
+
+ if (bits >= 96) {
+ bitmask[2] = 0xffffffffU;
+ bitmask[3] = 0xffffffffU << (128 - bits);
+ } else if (bits > 64) {
+ bitmask[2] = 0xffffffffU << (96 - bits);
+ }
+
+ memset(addr, 0x0, sizeof *addr);
+
+ sprintf(addrbuff, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
+ (((bitmask[0] & 0xffff0000U) >> 16) & 0xffffU),
+ (bitmask[0] & 0xffff),
+ (((bitmask[1] & 0xffff0000U) >> 16) & 0xffffU),
+ (bitmask[1] & 0xffff),
+ (((bitmask[2] & 0xffff0000U) >> 16) & 0xffffU),
+ (bitmask[2] & 0xffff),
+ (((bitmask[3] & 0xffff0000U) >> 16) & 0xffffU),
+ (bitmask[3] & 0xffff));
+
+ i = inet_pton(AF_INET6, addrbuff, addr);
+
+ return (i == 1 ? ISC_R_SUCCESS : ISC_R_FAILURE);
+}
+
+
+
diff --git a/lib/dns/config/confkeys.c b/lib/dns/config/confkeys.c
new file mode 100644
index 00000000..b4064d19
--- /dev/null
+++ b/lib/dns/config/confkeys.c
@@ -0,0 +1,1177 @@
+/*
+ * 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.
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <isc/assertions.h>
+#include <isc/magic.h>
+
+#include <dns/result.h>
+#include <dns/confkeys.h>
+#include <dns/confcommon.h>
+
+static isc_result_t keyid_delete(dns_c_kid_t **ki);
+
+
+isc_result_t
+dns_c_kdeflist_new(isc_mem_t *mem, dns_c_kdeflist_t **list)
+{
+ dns_c_kdeflist_t *newlist;
+
+ REQUIRE(mem != NULL);
+ REQUIRE(list != NULL);
+
+ newlist = isc_mem_get(mem, sizeof *newlist);
+ if (newlist == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ newlist->mem = mem;
+ newlist->magic = DNS_C_KDEFLIST_MAGIC;
+
+ ISC_LIST_INIT(newlist->keydefs);
+
+ *list = newlist;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_kdeflist_delete(dns_c_kdeflist_t **list)
+{
+ dns_c_kdeflist_t *l;
+ dns_c_kdef_t *kd;
+ dns_c_kdef_t *tmpkd;
+ isc_result_t res;
+
+ REQUIRE(list != NULL);
+ REQUIRE(DNS_C_KDEFLIST_VALID(*list));
+
+ l = *list;
+
+ kd = ISC_LIST_HEAD(l->keydefs);
+ while (kd != NULL) {
+ tmpkd = ISC_LIST_NEXT(kd, next);
+ ISC_LIST_UNLINK(l->keydefs, kd, next);
+ res = dns_c_kdef_delete(&kd);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ kd = tmpkd;
+ }
+
+ l->magic = 0;
+ isc_mem_put(l->mem, l, sizeof *l);
+
+ *list = NULL;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_kdeflist_copy(isc_mem_t *mem, dns_c_kdeflist_t **dest,
+ dns_c_kdeflist_t *src)
+{
+ dns_c_kdeflist_t *newlist;
+ dns_c_kdef_t *key;
+ isc_result_t res;
+
+ REQUIRE(dest != NULL);
+ REQUIRE(DNS_C_KDEFLIST_VALID(src));
+
+ res = dns_c_kdeflist_new(mem, &newlist);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ key = ISC_LIST_HEAD(src->keydefs);
+ while (key != NULL) {
+ res = dns_c_kdeflist_append(newlist, key, ISC_TRUE);
+ if (res != ISC_R_SUCCESS) {
+ dns_c_kdeflist_delete(&newlist);
+ return (res);
+ }
+
+ key = ISC_LIST_NEXT(key, next);
+ }
+
+ *dest = newlist;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_kdeflist_append(dns_c_kdeflist_t *list,
+ dns_c_kdef_t *key, isc_boolean_t copy)
+{
+ dns_c_kdef_t *newe;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_KDEFLIST_VALID(list));
+ REQUIRE(DNS_C_KDEF_VALID(key));
+
+ if (copy) {
+ res = dns_c_kdef_copy(list->mem, &newe, key);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ } else {
+ newe = key;
+ }
+
+ ISC_LIST_APPEND(list->keydefs, newe, next);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+isc_result_t
+dns_c_kdeflist_undef(dns_c_kdeflist_t *list, const char *keyid)
+{
+ dns_c_kdef_t *kd;
+ isc_result_t r;
+
+ REQUIRE(DNS_C_KDEFLIST_VALID(list));
+ REQUIRE(keyid != NULL);
+ REQUIRE(strlen(keyid) > 0);
+
+ kd = ISC_LIST_HEAD(list->keydefs);
+ while (kd != NULL) {
+ if (strcmp(kd->keyid, keyid) == 0) {
+ break;
+ }
+ kd = ISC_LIST_NEXT(kd, next);
+ }
+
+ if (kd != NULL) {
+ ISC_LIST_UNLINK(list->keydefs, kd, next);
+ (void)dns_c_kdef_delete(&kd);
+ r = ISC_R_SUCCESS;
+ } else {
+ r = ISC_R_NOTFOUND;
+ }
+
+ return (r);
+}
+
+
+isc_result_t
+dns_c_kdeflist_find(dns_c_kdeflist_t *list, const char *keyid,
+ dns_c_kdef_t **retval)
+{
+ dns_c_kdef_t *kd;
+ isc_result_t r;
+
+ REQUIRE(DNS_C_KDEFLIST_VALID(list));
+ REQUIRE(keyid != NULL);
+ REQUIRE(strlen(keyid) > 0);
+
+ kd = ISC_LIST_HEAD(list->keydefs);
+ while (kd != NULL) {
+ if (strcmp(kd->keyid, keyid) == 0) {
+ break;
+ }
+ kd = ISC_LIST_NEXT(kd, next);
+ }
+
+ if (kd != NULL) {
+ *retval = kd;
+ r = ISC_R_SUCCESS;
+ } else {
+ r = ISC_R_NOTFOUND;
+ }
+
+ return (r);
+}
+
+
+
+void
+dns_c_kdeflist_print(FILE *fp, int indent, dns_c_kdeflist_t *list)
+{
+ dns_c_kdef_t *kd;
+
+ REQUIRE(fp != NULL);
+ REQUIRE(indent >= 0);
+ REQUIRE(DNS_C_KDEFLIST_VALID(list));
+
+ if (list == NULL) {
+ return;
+ }
+
+ kd = ISC_LIST_HEAD(list->keydefs);
+ while (kd != NULL) {
+ dns_c_kdef_print(fp, indent, kd);
+ fprintf(fp, "\n");
+ kd = ISC_LIST_NEXT(kd, next);
+ }
+}
+
+
+isc_result_t
+dns_c_kdef_new(dns_c_kdeflist_t *list, const char *name,
+ dns_c_kdef_t **keyid)
+{
+ dns_c_kdef_t *kd;
+
+ REQUIRE(DNS_C_KDEFLIST_VALID(list));
+ REQUIRE(keyid != NULL);
+ REQUIRE(name != NULL);
+ REQUIRE(strlen(name) > 0);
+
+ kd = isc_mem_get(list->mem, sizeof *kd);
+ if (kd == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ kd->keyid = isc_mem_strdup(list->mem, name);
+ if (kd->keyid == NULL) {
+ isc_mem_put(list->mem, kd, sizeof *kd);
+ }
+
+ kd->magic = DNS_C_KDEF_MAGIC;
+ kd->mylist = list;
+ kd->algorithm = NULL;
+ kd->secret = NULL;
+
+ ISC_LIST_APPEND(list->keydefs, kd, next);
+
+ *keyid = kd;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_kdef_delete(dns_c_kdef_t **keydef)
+{
+ dns_c_kdef_t *kd;
+ isc_mem_t *mem;
+
+ REQUIRE(keydef != NULL);
+ REQUIRE(DNS_C_KDEF_VALID(*keydef));
+
+ kd = *keydef;
+
+ mem = kd->mylist->mem;
+
+ isc_mem_free(mem, kd->keyid);
+
+ if (kd->algorithm != NULL) {
+ isc_mem_free(mem, kd->algorithm);
+ }
+
+ if (kd->secret != NULL) {
+ isc_mem_free(mem, kd->secret);
+ }
+
+ kd->magic = 0;
+ kd->keyid = NULL;
+ kd->mylist = NULL;
+ kd->algorithm = NULL;
+ kd->secret = NULL;
+
+ ISC_LINK_INIT(kd,next);
+
+ isc_mem_put(mem, kd, sizeof *kd);
+
+ *keydef = NULL;
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+dns_c_kdef_copy(isc_mem_t *mem,
+ dns_c_kdef_t **dest, dns_c_kdef_t *src)
+{
+ dns_c_kdef_t *newk;
+
+ REQUIRE(dest != NULL);
+ REQUIRE(DNS_C_KDEF_VALID(src));
+
+ newk = isc_mem_get(mem, sizeof *newk);
+ if (newk == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+ newk->magic = DNS_C_KDEF_MAGIC;
+ newk->secret = newk->algorithm = newk->keyid = NULL;
+
+ newk->keyid = isc_mem_strdup(mem, src->keyid);
+ if (newk->keyid == NULL) {
+ dns_c_kdef_delete(&newk);
+ return (ISC_R_NOMEMORY);
+ }
+
+ newk->algorithm = isc_mem_strdup(mem, src->algorithm);
+ if (newk->algorithm == NULL) {
+ dns_c_kdef_delete(&newk);
+ return (ISC_R_NOMEMORY);
+ }
+
+ newk->secret = isc_mem_strdup(mem, src->secret);
+ if (newk->secret == NULL) {
+ dns_c_kdef_delete(&newk);
+ return (ISC_R_NOMEMORY);
+ }
+
+ *dest = newk;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+void
+dns_c_kdef_print(FILE *fp, int indent, dns_c_kdef_t *keydef)
+{
+ const char *quote = "";
+
+ REQUIRE(fp != NULL);
+ REQUIRE(DNS_C_KDEF_VALID(keydef));
+
+ if (dns_c_need_quote(keydef->keyid)) {
+ quote = "\"";
+ }
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "key %s%s%s {\n",quote, keydef->keyid, quote);
+
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "algorithm \"%s\";\n",keydef->algorithm);
+
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "secret \"%s\";\n",keydef->secret);
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "};\n");
+}
+
+
+isc_result_t
+dns_c_kdef_setalgorithm(dns_c_kdef_t *keydef, const char *algorithm)
+{
+ REQUIRE(DNS_C_KDEF_VALID(keydef));
+ REQUIRE(algorithm != NULL);
+ REQUIRE(strlen(algorithm) > 0);
+
+ if (keydef->algorithm != NULL) {
+ isc_mem_free(keydef->mylist->mem, keydef->algorithm);
+ }
+
+ keydef->algorithm = isc_mem_strdup(keydef->mylist->mem,
+ algorithm);
+ if (keydef->algorithm == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_kdef_setsecret(dns_c_kdef_t *keydef, const char *secret)
+{
+ REQUIRE(DNS_C_KDEF_VALID(keydef));
+ REQUIRE(secret != NULL);
+ REQUIRE(strlen(secret) > 0);
+
+ if (keydef->secret != NULL) {
+ isc_mem_free(keydef->mylist->mem, keydef->secret);
+ }
+
+ keydef->secret = isc_mem_strdup(keydef->mylist->mem, secret);
+ if (keydef->secret == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+isc_result_t
+dns_c_kidlist_new(isc_mem_t *mem, dns_c_kidlist_t **list)
+{
+ dns_c_kidlist_t *l;
+
+ l = isc_mem_get(mem, sizeof *l);
+ if (l == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ l->magic = DNS_C_KEYIDLIST_MAGIC;
+ l->mem = mem;
+ *list = l;
+
+ ISC_LIST_INIT(l->keyids);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_kidlist_delete(dns_c_kidlist_t **list)
+{
+ dns_c_kidlist_t *l;
+ dns_c_kid_t *ki, *tmpki;
+ isc_result_t r;
+
+ REQUIRE(list != NULL);
+ REQUIRE(DNS_C_KEYIDLIST_VALID(*list));
+
+ l = *list;
+
+ ki = ISC_LIST_HEAD(l->keyids);
+ while (ki != NULL) {
+ tmpki = ISC_LIST_NEXT(ki, next);
+ ISC_LIST_UNLINK(l->keyids, ki, next);
+ r = keyid_delete(&ki);
+ if (r != ISC_R_SUCCESS) {
+ return (r);
+ }
+ ki = tmpki;
+ }
+
+ l->magic = 0;
+ isc_mem_put(l->mem, l, sizeof *l);
+
+ *list = NULL;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+static isc_result_t
+keyid_delete(dns_c_kid_t **keyid)
+{
+ dns_c_kid_t *ki;
+
+ REQUIRE(keyid != NULL);
+ REQUIRE(DNS_C_KEYID_VALID(*keyid));
+
+ ki = *keyid;
+
+ isc_mem_free(ki->mylist->mem, ki->keyid);
+
+ ki->magic = 0;
+ isc_mem_put(ki->mylist->mem, ki, sizeof *ki);
+
+ *keyid = NULL;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_kidlist_undef(dns_c_kidlist_t *list, const char *keyid)
+{
+ dns_c_kid_t *ki;
+ isc_result_t r;
+
+ REQUIRE(DNS_C_KEYIDLIST_VALID(list));
+ REQUIRE(keyid != NULL);
+ REQUIRE(strlen(keyid) > 0);
+
+ dns_c_kidlist_find(list, keyid, &ki);
+
+ if (ki != NULL) {
+ ISC_LIST_UNLINK(list->keyids, ki, next);
+ r = keyid_delete(&ki);
+ } else {
+ r = ISC_R_SUCCESS;
+ }
+
+ return (r);
+}
+
+
+isc_result_t
+dns_c_kidlist_find(dns_c_kidlist_t *list, const char *keyid,
+ dns_c_kid_t **retval)
+{
+ dns_c_kid_t *iter;
+
+ REQUIRE(DNS_C_KEYIDLIST_VALID(list));
+ REQUIRE(keyid != NULL);
+ REQUIRE(strlen(keyid) > 0);
+ REQUIRE(retval != NULL);
+
+ iter = ISC_LIST_HEAD(list->keyids);
+ while (iter != NULL) {
+ if (strcmp(keyid, iter->keyid) == 0) {
+ break;
+ }
+
+ iter = ISC_LIST_NEXT(iter, next);
+ }
+
+ *retval = iter;
+
+ return (iter == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+void
+dns_c_kidlist_print(FILE *fp, int indent,
+ dns_c_kidlist_t *list)
+{
+ dns_c_kid_t *iter;
+ const char *quote;
+
+ REQUIRE(fp != NULL);
+ REQUIRE(DNS_C_KEYIDLIST_VALID(list));
+
+ if (ISC_LIST_EMPTY(list->keyids)) {
+ return;
+ }
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "keys {\n");
+ iter = ISC_LIST_HEAD(list->keyids);
+ if (iter == NULL) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "/* no keys defined */\n");
+ } else {
+ while (iter != NULL) {
+ if (dns_c_need_quote(iter->keyid)) {
+ quote = "\"";
+ } else {
+ quote = "";
+ }
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "%s%s%s;\n", quote, iter->keyid, quote);
+ iter = ISC_LIST_NEXT(iter, next);
+ }
+ }
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "};\n");
+}
+
+
+isc_result_t
+dns_c_kid_new(dns_c_kidlist_t *list, const char *name, dns_c_kid_t **keyid)
+{
+ dns_c_kid_t *ki;
+
+ REQUIRE(DNS_C_KEYIDLIST_VALID(list));
+ REQUIRE(name != NULL);
+ REQUIRE(strlen(name) > 0);
+ REQUIRE(keyid != NULL);
+
+ ki = isc_mem_get(list->mem, sizeof *ki);
+ if (ki == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ ki->magic = DNS_C_KEYID_MAGIC;
+ ki->mylist = list;
+ ki->keyid = isc_mem_strdup(list->mem, name);
+
+ ISC_LINK_INIT(ki, next);
+ ISC_LIST_APPEND(list->keyids, ki, next);
+
+ *keyid = ki;
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+dns_c_pklist_new(isc_mem_t *mem, dns_c_pklist_t **pklist)
+{
+ dns_c_pklist_t *newl;
+
+ REQUIRE(pklist != NULL);
+
+ newl = isc_mem_get(mem, sizeof *newl);
+ if (newl == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ newl->mem = mem;
+ newl->magic = DNS_C_PKLIST_MAGIC;
+
+ ISC_LIST_INIT(newl->keylist);
+
+ *pklist = newl;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_pklist_delete(dns_c_pklist_t **list)
+{
+ dns_c_pklist_t *l;
+ dns_c_pubkey_t *pk;
+ dns_c_pubkey_t *tmppk;
+ isc_result_t r;
+
+ REQUIRE(list != NULL);
+ REQUIRE(DNS_C_PKLIST_VALID(*list));
+
+ l = *list;
+
+ pk = ISC_LIST_HEAD(l->keylist);
+ while (pk != NULL) {
+ tmppk = ISC_LIST_NEXT(pk, next);
+ ISC_LIST_UNLINK(l->keylist, pk, next);
+ r = dns_c_pubkey_delete(&pk);
+ if (r != ISC_R_SUCCESS) {
+ return (r);
+ }
+
+ pk = tmppk;
+ }
+
+ l->magic = 0;
+ isc_mem_put(l->mem, l, sizeof *l);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+void
+dns_c_pklist_print(FILE *fp, int indent, dns_c_pklist_t *list)
+{
+ dns_c_pubkey_t *pk;
+
+ REQUIRE(fp != NULL);
+ REQUIRE(indent >= 0);
+
+ if (list == NULL) {
+ return;
+ }
+
+ REQUIRE(DNS_C_PKLIST_VALID(list));
+
+ pk = ISC_LIST_HEAD(list->keylist);
+ while (pk != NULL) {
+ dns_c_pubkey_print(fp, indent, pk);
+ pk = ISC_LIST_NEXT(pk, next);
+ }
+ fprintf(fp, "\n");
+}
+
+
+
+isc_result_t
+dns_c_pklist_addpubkey(dns_c_pklist_t *list,
+ dns_c_pubkey_t *pkey,
+ isc_boolean_t deepcopy)
+{
+ dns_c_pubkey_t *pk;
+ isc_result_t r;
+
+ REQUIRE(DNS_C_PKLIST_VALID(list));
+ REQUIRE(DNS_C_PUBKEY_VALID(pkey));
+
+ if (deepcopy) {
+ r = dns_c_pubkey_copy(list->mem, &pk, pkey);
+ if (r != ISC_R_SUCCESS) {
+ return (r);
+ }
+ } else {
+ pk = pkey;
+ }
+
+ ISC_LIST_APPEND(list->keylist, pk, next);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_pklist_findpubkey(dns_c_pklist_t *list,
+ dns_c_pubkey_t **pubkey, isc_int32_t flags,
+ isc_int32_t protocol, isc_int32_t algorithm,
+ const char *key)
+{
+ dns_c_pubkey_t *pk;
+
+ REQUIRE(DNS_C_PKLIST_VALID(list));
+ REQUIRE(pubkey != NULL);
+
+ *pubkey = NULL;
+ pk = ISC_LIST_HEAD(list->keylist);
+ while (pk != NULL) {
+ if (pk->flags == flags &&
+ pk->protocol == protocol &&
+ pk->algorithm == algorithm &&
+ strcmp(pk->key, key) == 0) {
+ *pubkey = pk;
+ pk = NULL;
+ } else {
+ pk = ISC_LIST_NEXT(pk, next);
+ }
+ }
+
+ return (*pubkey == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+
+isc_result_t
+dns_c_pklist_rmpubkey(dns_c_pklist_t *list,
+ isc_int32_t flags,
+ isc_int32_t protocol, isc_int32_t algorithm,
+ const char *key)
+{
+ dns_c_pubkey_t *pk;
+ isc_result_t r;
+
+ REQUIRE(DNS_C_PKLIST_VALID(list));
+ REQUIRE(key != NULL);
+ REQUIRE(strlen(key) > 0);
+
+ r = dns_c_pklist_findpubkey(list, &pk, flags, protocol,
+ algorithm, key);
+ if (r == ISC_R_SUCCESS) {
+ ISC_LIST_UNLINK(list->keylist, pk, next);
+ r = dns_c_pubkey_delete(&pk);
+ }
+
+ return (r);
+}
+
+
+
+isc_result_t
+dns_c_pubkey_new(isc_mem_t *mem, isc_int32_t flags,
+ isc_int32_t protocol,
+ isc_int32_t algorithm,
+ const char *key, dns_c_pubkey_t **pubkey)
+{
+ dns_c_pubkey_t *pkey;
+
+ REQUIRE(pubkey != NULL);
+ REQUIRE(key != NULL);
+ REQUIRE(strlen(key) > 0);
+
+ pkey = isc_mem_get(mem, sizeof *pkey);
+ if (pkey == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ pkey->magic = DNS_C_PUBKEY_MAGIC;
+ pkey->mem = mem;
+ pkey->flags = flags;
+ pkey->protocol = protocol;
+ pkey->algorithm = algorithm;
+ pkey->key = isc_mem_strdup(mem, key);
+ if (pkey->key == NULL) {
+ isc_mem_put(mem, pkey, sizeof *pkey);
+ return (ISC_R_NOMEMORY);
+ }
+
+ *pubkey = pkey;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_pubkey_delete(dns_c_pubkey_t **pubkey)
+{
+ dns_c_pubkey_t *pkey;
+
+ REQUIRE(pubkey != NULL);
+ REQUIRE(DNS_C_PUBKEY_VALID(*pubkey));
+
+ pkey = *pubkey;
+
+ if (pkey->key != NULL) {
+ isc_mem_free(pkey->mem, pkey->key);
+ }
+
+ pkey->magic = 0;
+ isc_mem_put(pkey->mem, pkey, sizeof *pkey);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_pubkey_copy(isc_mem_t *mem, dns_c_pubkey_t **dest, dns_c_pubkey_t *src)
+{
+ dns_c_pubkey_t *k;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_PUBKEY_VALID(src));
+ REQUIRE(dest != NULL);
+
+ res = dns_c_pubkey_new(mem, src->flags, src->protocol,
+ src->algorithm, src->key, &k);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ *dest = k;
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_boolean_t
+dns_c_pubkey_equal(dns_c_pubkey_t *k1, dns_c_pubkey_t *k2) {
+
+ REQUIRE(DNS_C_PUBKEY_VALID(k1));
+ REQUIRE(DNS_C_PUBKEY_VALID(k2));
+
+ return (ISC_TF(k1->flags == k2->flags &&
+ k1->protocol == k2->protocol &&
+ k1->algorithm == k2->algorithm &&
+ strcmp(k1->key, k2->key) == 0));
+}
+
+void
+dns_c_pubkey_print(FILE *fp, int indent, dns_c_pubkey_t *pubkey)
+{
+ REQUIRE(fp != NULL);
+ REQUIRE(DNS_C_PUBKEY_VALID(pubkey));
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "pubkey %d %d %d \"%s\";\n",
+ pubkey->flags, pubkey->protocol,
+ pubkey->algorithm, pubkey->key);
+}
+
+
+isc_result_t
+dns_c_tkeylist_new(isc_mem_t *mem, dns_c_tkeylist_t **newlist)
+{
+ dns_c_tkeylist_t *nl;
+
+ REQUIRE(newlist != NULL);
+
+ nl = isc_mem_get(mem, sizeof *nl);
+ if (nl == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ nl->magic = DNS_C_TKEYLIST_MAGIC;
+ nl->mem = mem;
+ ISC_LIST_INIT(nl->tkeylist);
+
+ *newlist = nl;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_tkeylist_delete(dns_c_tkeylist_t **list)
+{
+ dns_c_tkeylist_t *l;
+ dns_c_tkey_t *tkey, *tmptkey;
+ isc_result_t res;
+
+ REQUIRE(list != NULL);
+ REQUIRE(DNS_C_TKEYLIST_VALID(*list));
+
+ l = *list;
+
+ tkey = ISC_LIST_HEAD(l->tkeylist);
+ while (tkey != NULL) {
+ tmptkey = ISC_LIST_NEXT(tkey, next);
+ ISC_LIST_UNLINK(l->tkeylist, tkey, next);
+
+ res = dns_c_tkey_delete(&tkey);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ tkey = tmptkey;
+ }
+
+ l->magic = 0;
+ isc_mem_put(l->mem, l, sizeof *l);
+
+ *list = NULL;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_tkeylist_copy(isc_mem_t *mem, dns_c_tkeylist_t **dest,
+ dns_c_tkeylist_t *src)
+{
+ dns_c_tkeylist_t *newlist;
+ dns_c_tkey_t *tkey, *tmptkey;
+ isc_result_t res;
+
+ REQUIRE(dest != NULL);
+ REQUIRE(DNS_C_TKEYLIST_VALID(src));
+
+ res = dns_c_tkeylist_new(mem, &newlist);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ tkey = ISC_LIST_HEAD(src->tkeylist);
+ while (tkey != NULL) {
+ res = dns_c_tkey_copy(mem, &tmptkey, tkey);
+ if (res != ISC_R_SUCCESS) {
+ dns_c_tkeylist_delete(&newlist);
+ return (res);
+ }
+
+ res = dns_c_tkeylist_append(newlist, tmptkey, ISC_FALSE);
+ if (res != ISC_R_SUCCESS) {
+ dns_c_tkey_delete(&tmptkey);
+ dns_c_tkeylist_delete(&newlist);
+ return (res);
+ }
+
+ tkey = ISC_LIST_NEXT(tkey, next);
+ }
+
+ *dest = newlist;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+void
+dns_c_tkeylist_print(FILE *fp, int indent, dns_c_tkeylist_t *list)
+{
+ dns_c_tkey_t *tkey;
+
+ REQUIRE(fp != NULL);
+ REQUIRE(DNS_C_TKEYLIST_VALID(list));
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "trusted-keys {\n");
+ tkey = ISC_LIST_HEAD(list->tkeylist);
+ if (tkey == NULL) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "/* empty list */\n");
+ } else {
+ while (tkey != NULL) {
+ dns_c_tkey_print(fp, indent + 1, tkey);
+ tkey = ISC_LIST_NEXT(tkey, next);
+ }
+ }
+ dns_c_printtabs(fp, indent);
+ fprintf(fp,"};\n");
+}
+
+
+isc_result_t
+dns_c_tkeylist_append(dns_c_tkeylist_t *list, dns_c_tkey_t *element,
+ isc_boolean_t copy)
+{
+ dns_c_tkey_t *newe;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_TKEYLIST_VALID(list));
+ REQUIRE(DNS_C_TKEY_VALID(element));
+
+ if (copy) {
+ res = dns_c_tkey_copy(list->mem, &newe, element);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ } else {
+ newe = element;
+ }
+
+ ISC_LIST_APPEND(list->tkeylist, newe, next);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+isc_result_t
+dns_c_tkey_new(isc_mem_t *mem, const char *domain, isc_int32_t flags,
+ isc_int32_t protocol, isc_int32_t algorithm,
+ const char *key, dns_c_tkey_t **newkey)
+{
+ dns_c_tkey_t *newk;
+ dns_c_pubkey_t *pk;
+ isc_result_t res;
+
+ REQUIRE(domain != NULL);
+ REQUIRE(strlen(domain) > 0);
+ REQUIRE(key != NULL);
+ REQUIRE(strlen(key) > 0);
+ REQUIRE(newkey != NULL);
+
+ newk = isc_mem_get(mem, sizeof *newk);
+ if (newk == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ res = dns_c_pubkey_new(mem, flags, protocol,
+ algorithm, key, &pk);
+ if (res != ISC_R_SUCCESS) {
+ isc_mem_put(mem, newk, sizeof *newk);
+ return (res);
+ }
+
+ newk->mem = mem;
+ newk->magic = DNS_C_TKEY_MAGIC;
+
+ newk->domain = isc_mem_strdup(mem, domain);
+ if (newk->domain == NULL) {
+ dns_c_pubkey_delete(&pk);
+ isc_mem_put(mem, newk, sizeof *newk);
+ return (ISC_R_NOMEMORY);
+ }
+
+ newk->pubkey = pk;
+
+ ISC_LINK_INIT(newk, next);
+
+ *newkey = newk;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_tkey_delete(dns_c_tkey_t **tkey)
+{
+ isc_result_t res;
+ dns_c_tkey_t *tk;
+
+ REQUIRE(tkey != NULL);
+ REQUIRE(DNS_C_TKEY_VALID(*tkey));
+
+ tk = *tkey;
+
+ isc_mem_free(tk->mem, tk->domain);
+
+ res = dns_c_pubkey_delete(&tk->pubkey);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ tk->magic = 0;
+ isc_mem_put(tk->mem, tk, sizeof *tk);
+
+ *tkey = NULL;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_tkey_copy(isc_mem_t *mem, dns_c_tkey_t **dest, dns_c_tkey_t *src)
+{
+ dns_c_tkey_t *newk;
+ dns_c_pubkey_t *newpk;
+ isc_result_t res;
+
+ REQUIRE(dest != NULL);
+ REQUIRE(DNS_C_TKEY_VALID(src));
+
+ newk = isc_mem_get(mem, sizeof *newk);
+ if (newk == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ newk->magic = DNS_C_TKEY_MAGIC;
+ newk->domain = isc_mem_strdup(mem, src->domain);
+ if (newk->domain == NULL) {
+ isc_mem_put(mem, newk, sizeof *newk);
+ return (ISC_R_NOMEMORY);
+ }
+
+ res = dns_c_pubkey_copy(mem, &newpk, src->pubkey);
+ if (res != ISC_R_SUCCESS) {
+ isc_mem_free(mem, newk->domain);
+ isc_mem_put(mem, newk, sizeof *newk);
+ return (res);
+ }
+
+ newk->pubkey = newpk;
+
+ *dest = newk;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_tkey_getflags(dns_c_tkey_t *tkey, isc_int32_t *flags)
+{
+ REQUIRE(DNS_C_TKEY_VALID(tkey));
+
+ *flags = tkey->pubkey->flags;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_tkey_getprotocol(dns_c_tkey_t *tkey, isc_int32_t *protocol)
+{
+ REQUIRE(DNS_C_TKEY_VALID(tkey));
+
+ *protocol = tkey->pubkey->protocol;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_tkey_getalgorithm(dns_c_tkey_t *tkey, isc_int32_t *algorithm)
+{
+ REQUIRE(DNS_C_TKEY_VALID(tkey));
+
+ *algorithm = tkey->pubkey->algorithm;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_tkey_getkey(dns_c_tkey_t *tkey, const char **key)
+{
+ REQUIRE(key != NULL);
+ REQUIRE(DNS_C_TKEY_VALID(tkey));
+
+ *key = tkey->pubkey->key;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+void
+dns_c_tkey_print(FILE *fp, int indent, dns_c_tkey_t *tkey)
+{
+ REQUIRE(fp != NULL);
+ REQUIRE(DNS_C_TKEY_VALID(tkey));
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "\"%s\" %d %d %d \"%s\";\n",
+ tkey->domain, tkey->pubkey->flags,
+ tkey->pubkey->protocol, tkey->pubkey->algorithm,
+ tkey->pubkey->key);
+
+ return;
+}
+
diff --git a/lib/dns/config/conflog.c b/lib/dns/config/conflog.c
new file mode 100644
index 00000000..fe83e239
--- /dev/null
+++ b/lib/dns/config/conflog.c
@@ -0,0 +1,1345 @@
+/*
+ * 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.
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <isc/assertions.h>
+#include <isc/magic.h>
+
+#include <dns/conflog.h>
+#include <dns/confcommon.h>
+#include <dns/log.h>
+
+
+#include "confpvt.h"
+
+
+#define UNLIM_VERSIONS (-1) /* XXX check this is right? */
+
+/*
+ * Bit positions in the dns_c_logchan_t structure setflags field.
+ */
+#define CHAN_VERSIONS_BIT 0
+#define CHAN_SIZE_BIT 1
+#define CHAN_SEVERITY_BIT 2
+#define CHAN_DEBUG_LEVEL_BIT 3
+#define CHAN_PCAT_BIT 4
+#define CHAN_PSEV_BIT 5
+#define CHAN_PTIME_BIT 6
+#define CHAN_FACILITY_BIT 7
+
+
+
+static void print_log_facility(FILE *fp,
+ int value);
+static void print_log_severity(FILE *fp,
+ dns_c_logseverity_t severity);
+static void print_log_category(FILE *fp,
+ dns_c_category_t category);
+static isc_boolean_t logginglist_empty(dns_c_logginglist_t *ll);
+
+
+
+isc_result_t
+dns_c_logginglist_new(isc_mem_t *mem,
+ dns_c_logginglist_t **list)
+{
+ dns_c_logginglist_t *newl;
+
+ REQUIRE(list != NULL);
+
+ newl = isc_mem_get(mem, sizeof *newl);
+ if (newl == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ newl->magic = DNS_C_LOGLIST_MAGIC;
+ newl->mem = mem;
+ ISC_LIST_INIT(newl->channels);
+ ISC_LIST_INIT(newl->categories);
+
+ *list = newl;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_logginglist_delete(dns_c_logginglist_t **list)
+{
+ dns_c_logginglist_t *l;
+ dns_c_logchan_t *chan, *tmpchan;
+ dns_c_logcat_t *cat, *tmpcat;
+ isc_result_t res;
+
+ REQUIRE(list != NULL);
+ REQUIRE(DNS_C_LOGLIST_VALID(*list));
+
+ l = *list;
+
+ chan = ISC_LIST_HEAD(l->channels);
+ while (chan != NULL) {
+ tmpchan = ISC_LIST_NEXT(chan, next);
+ ISC_LIST_UNLINK(l->channels, chan, next);
+ res = dns_c_logchan_delete(&chan);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ chan = tmpchan;
+ }
+
+ cat = ISC_LIST_HEAD(l->categories);
+ while (cat != NULL) {
+ tmpcat = ISC_LIST_NEXT(cat, next);
+ ISC_LIST_UNLINK(l->categories, cat, next);
+ res = dns_c_logcat_delete(&cat);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ cat = tmpcat;
+ }
+
+ l->magic = 0;
+ isc_mem_put(l->mem, l, sizeof *l);
+
+ *list = NULL;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_logginglist_copy(isc_mem_t *mem,
+ dns_c_logginglist_t **dest,
+ dns_c_logginglist_t *src)
+{
+ dns_c_logginglist_t *newl;
+ dns_c_logchan_t *logchan, *tmplogchan;
+ dns_c_logcat_t *logcat, *tmplogcat;
+ isc_result_t res;
+
+ REQUIRE(dest != NULL);
+ REQUIRE(DNS_C_LOGLIST_VALID(src));
+
+ res = dns_c_logginglist_new(mem, &newl);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ logchan = ISC_LIST_HEAD(src->channels);
+ while (logchan != NULL) {
+ res = dns_c_logchan_copy(mem, &tmplogchan, logchan);
+ if (res != ISC_R_SUCCESS) {
+ dns_c_logginglist_delete(&newl);
+ return (res);
+ }
+
+ ISC_LIST_APPEND(newl->channels, tmplogchan, next);
+ logchan = ISC_LIST_NEXT(logchan, next);
+ }
+
+
+ logcat = ISC_LIST_HEAD(src->categories);
+ while (logcat != NULL) {
+ res = dns_c_logcat_copy(mem, &tmplogcat, logcat);
+ if (res != ISC_R_SUCCESS) {
+ dns_c_logginglist_delete(&newl);
+ return (res);
+ }
+
+ ISC_LIST_APPEND(newl->categories, tmplogcat, next);
+ logcat = ISC_LIST_NEXT(logcat, next);
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+
+static isc_boolean_t
+logginglist_empty(dns_c_logginglist_t *ll)
+{
+ dns_c_logchan_t *logchan;
+ dns_c_logcat_t *logcat;
+
+ REQUIRE(DNS_C_LOGLIST_VALID(ll));
+
+ logchan = ISC_LIST_HEAD(ll->channels);
+ while (logchan != NULL) {
+ if (!logchan->predefined) {
+ return ISC_TRUE;
+ }
+
+ logchan = ISC_LIST_NEXT(logchan, next);
+ }
+
+ logcat = ISC_LIST_HEAD(ll->categories);
+ while (logcat != NULL) {
+ if (!logcat->predefined) {
+ return ISC_FALSE;
+ }
+ logcat = ISC_LIST_NEXT(logcat, next);
+ }
+
+ return ISC_TRUE;
+}
+
+
+void
+dns_c_logginglist_print(FILE *fp, int indent, dns_c_logginglist_t *ll,
+ isc_boolean_t if_predef_too)
+{
+ dns_c_logchan_t *logchan;
+ dns_c_logcat_t *logcat;
+
+ REQUIRE(fp != NULL);
+ REQUIRE(DNS_C_LOGLIST_VALID(ll));
+
+ if (logginglist_empty(ll)) {
+ return;
+ }
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "logging {\n");
+
+ logchan = ISC_LIST_HEAD(ll->channels);
+ while (logchan != NULL) {
+ dns_c_logchan_print(fp, indent + 1, logchan,
+ if_predef_too);
+ logchan = ISC_LIST_NEXT(logchan, next);
+ }
+
+ logcat = ISC_LIST_HEAD(ll->categories);
+ while (logcat != NULL) {
+ dns_c_logcat_print(fp, indent + 1, logcat,
+ if_predef_too);
+ logcat = ISC_LIST_NEXT(logcat, next);
+ }
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "};\n");
+}
+
+
+isc_result_t
+dns_c_logginglist_addchannel(dns_c_logginglist_t *list,
+ dns_c_logchan_t *newchan,
+ isc_boolean_t deepcopy)
+{
+ dns_c_logchan_t *newc, *tmpchan;
+ isc_result_t res;
+ isc_boolean_t existed = ISC_FALSE;
+ isc_boolean_t predefined = ISC_FALSE;
+
+ REQUIRE(DNS_C_LOGLIST_VALID(list));
+ REQUIRE(DNS_C_LOGCHAN_VALID(newchan));
+
+ if (deepcopy) {
+ res = dns_c_logchan_copy(list->mem, &newc, newchan);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ } else {
+ newc = newchan;
+ }
+
+ tmpchan = ISC_LIST_HEAD(list->channels);
+ while (tmpchan != NULL) {
+ if (strcmp(newchan->name, tmpchan->name) == 0) {
+ existed = ISC_TRUE;
+ predefined = tmpchan->predefined;
+
+ ISC_LIST_UNLINK(list->channels, tmpchan, next);
+ res = dns_c_logchan_delete(&tmpchan);
+ if (res != ISC_R_SUCCESS) {
+ if (deepcopy) {
+ dns_c_logchan_delete(&newc);
+ }
+ return (res);
+ }
+ break;
+ }
+
+ tmpchan = ISC_LIST_NEXT(tmpchan, next);
+ }
+
+ ISC_LIST_APPEND(list->channels, newc, next);
+
+ /* replacing a predefined channel is a plain success. */
+ return (existed && !predefined ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_logginglist_addcategory(dns_c_logginglist_t *list,
+ dns_c_logcat_t *newcat,
+ isc_boolean_t deepcopy)
+{
+ dns_c_logcat_t *newc, *tmpcat;
+ isc_result_t res;
+ isc_boolean_t existed = ISC_FALSE;
+ isc_boolean_t predefined = ISC_FALSE;
+
+ REQUIRE(DNS_C_LOGLIST_VALID(list));
+ REQUIRE(DNS_C_LOGCAT_VALID(newcat));
+
+
+ if (deepcopy) {
+ res = dns_c_logcat_copy(list->mem, &newc, newcat);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ } else {
+ newc = newcat;
+ }
+
+ /* Remove old category defintion if there. */
+ tmpcat = ISC_LIST_HEAD(list->categories);
+ while (tmpcat != NULL) {
+ if (newcat->category == tmpcat->category) {
+ existed = ISC_TRUE;
+ predefined = tmpcat->predefined;
+
+ ISC_LIST_UNLINK(list->categories, tmpcat, next);
+ res = dns_c_logcat_delete(&tmpcat);
+ if (res != ISC_R_SUCCESS) {
+ if (deepcopy) {
+ dns_c_logcat_delete(&newc);
+ }
+ return (res);
+ }
+ break;
+ }
+
+ tmpcat = ISC_LIST_NEXT(tmpcat, next);
+ }
+
+ ISC_LIST_APPEND(list->categories, newc, next);
+
+ /* replacing a predefined category is a simple success. */
+ return (existed && !predefined ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_logginglist_delchannel(dns_c_logginglist_t *list,
+ const char *name)
+{
+ dns_c_logchan_t *logc;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_LOGLIST_VALID(list));
+ REQUIRE(name != NULL);
+ REQUIRE(strlen(name) > 0);
+
+ res = dns_c_logginglist_chanbyname(list, name, &logc);
+ if (res == ISC_R_SUCCESS) {
+ ISC_LIST_UNLINK(list->channels, logc, next);
+
+ res = dns_c_logchan_delete(&logc);
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_logginglist_delcategory(dns_c_logginglist_t *list,
+ const char *name)
+{
+ dns_c_logcat_t *logc;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_LOGLIST_VALID(list));
+ REQUIRE(name != NULL);
+ REQUIRE(strlen(name) > 0);
+
+ res = dns_c_logginglist_catbyname(list, name, &logc);
+ if (res == ISC_R_SUCCESS) {
+ ISC_LIST_UNLINK(list->categories, logc, next);
+
+ res = dns_c_logcat_delete(&logc);
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_logginglist_chanbyname(dns_c_logginglist_t *list,
+ const char *name,
+ dns_c_logchan_t **chan)
+{
+ dns_c_logchan_t *logc;
+
+ REQUIRE(DNS_C_LOGLIST_VALID(list));
+ REQUIRE(name != NULL);
+ REQUIRE(strlen(name) > 0);
+ REQUIRE(chan != NULL);
+
+ logc = ISC_LIST_HEAD(list->channels);
+ while (logc != NULL) {
+ if (strcmp(logc->name, name) == 0) {
+ break;
+ }
+
+ logc = ISC_LIST_NEXT(logc, next);
+ }
+
+ if (logc == NULL) {
+ return (ISC_R_NOTFOUND);
+ } else {
+ *chan = logc;
+ return (ISC_R_SUCCESS);
+ }
+}
+
+
+isc_result_t
+dns_c_logginglist_catbyname(dns_c_logginglist_t *list,
+ const char *name,
+ dns_c_logcat_t **cat)
+{
+ dns_c_category_t cattype;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_LOGLIST_VALID(list));
+ REQUIRE(name != NULL);
+ REQUIRE(strlen(name) > 0);
+ REQUIRE(cat != NULL);
+
+ res = dns_c_string2category(name, &cattype);
+ if (res != ISC_R_SUCCESS) {
+ return (ISC_R_FAILURE);
+ }
+
+ return (dns_c_logginglist_catbytype(list, cattype, cat));
+}
+
+
+isc_result_t
+dns_c_logginglist_catbytype(dns_c_logginglist_t *list,
+ dns_c_category_t cattype,
+ dns_c_logcat_t **cat)
+{
+ dns_c_logcat_t *logc;
+
+ REQUIRE(DNS_C_LOGLIST_VALID(list));
+ REQUIRE(cat != NULL);
+
+ logc = ISC_LIST_HEAD(list->categories);
+ while (logc != NULL) {
+ if (logc->category == cattype) {
+ break;
+ }
+
+ logc = ISC_LIST_NEXT(logc, next);
+ }
+
+ if (logc == NULL) {
+ return (ISC_R_NOTFOUND);
+ } else {
+ *cat = logc;
+ return (ISC_R_SUCCESS);
+ }
+}
+
+
+/* ************************************************************************ */
+/* **************************** LOGGING CHANNELS ************************** */
+/* ************************************************************************ */
+
+isc_result_t
+dns_c_logchan_new(isc_mem_t *mem, const char *name,
+ dns_c_logchantype_t ctype,
+ dns_c_logchan_t **newchan)
+{
+ dns_c_logchan_t *newc;
+
+ REQUIRE(name != NULL);
+ REQUIRE(strlen(name) > 0);
+ REQUIRE(newchan != NULL);
+
+ newc = isc_mem_get(mem, sizeof *newc);
+ if (newc == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ newc->magic = DNS_C_LOGCHAN_MAGIC;
+ newc->mem = mem;
+ newc->ctype = ctype;
+ newc->severity = dns_c_log_info;
+ newc->debug_level = 0;
+ newc->print_category = ISC_FALSE;
+ newc->print_severity = ISC_FALSE;
+ newc->print_time = ISC_FALSE;
+ newc->predefined = ISC_FALSE;
+
+ memset(&newc->setflags, 0x0, sizeof newc->setflags);
+
+ ISC_LINK_INIT(newc, next);
+
+ newc->name = isc_mem_strdup(mem, name);
+ if (newc->name == NULL) {
+ isc_mem_put(mem, newc, sizeof *newc);
+ return (ISC_R_NOMEMORY);
+ }
+
+ switch (ctype) {
+ case dns_c_logchan_file:
+ newc->u.filec.path = NULL;
+ break;
+
+ case dns_c_logchan_syslog:
+ case dns_c_logchan_null:
+ break;
+ }
+
+ *newchan = newc;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_logchan_delete(dns_c_logchan_t **channel)
+{
+ dns_c_logchan_t *logc;
+
+ REQUIRE(channel != NULL);
+ REQUIRE(DNS_C_LOGCHAN_VALID(*channel));
+
+ logc = *channel;
+
+ isc_mem_free(logc->mem, logc->name);
+
+ switch (logc->ctype) {
+ case dns_c_logchan_file:
+ if (logc->u.filec.path != NULL) {
+ isc_mem_free(logc->mem, logc->u.filec.path);
+ }
+ break;
+
+ case dns_c_logchan_syslog:
+ case dns_c_logchan_null:
+ break;
+ }
+
+ *channel = NULL;
+
+ logc->magic = 0;
+ isc_mem_put(logc->mem, logc, sizeof *logc);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_logchan_copy(isc_mem_t *mem, dns_c_logchan_t **dest,
+ dns_c_logchan_t *src)
+{
+ dns_c_logchan_t *logc;
+ isc_result_t res;
+
+ REQUIRE(dest != NULL);
+ REQUIRE(DNS_C_LOGCHAN_VALID(src));
+
+ res = dns_c_logchan_new(mem, src->name, src->ctype, &logc);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ logc->severity = src->severity;
+ logc->debug_level = src->debug_level;
+ logc->print_category = src->print_category;
+ logc->print_severity = src->print_severity;
+ logc->print_time = src->print_time;
+ logc->setflags = src->setflags;
+
+ switch (logc->ctype) {
+ case dns_c_logchan_file:
+ logc->u.filec.path = isc_mem_strdup(mem, src->u.filec.path);
+ logc->u.filec.versions = src->u.filec.versions;
+ logc->u.filec.size = src->u.filec.size;
+ break;
+
+ case dns_c_logchan_syslog:
+ logc->u.syslogc.facility = src->u.syslogc.facility;
+ break;
+
+ case dns_c_logchan_null:
+ break;
+ }
+
+ *dest = logc;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+void
+dns_c_logchan_print(FILE *fp, int indent, dns_c_logchan_t *logchan,
+ isc_boolean_t if_predef_too)
+{
+ REQUIRE(fp != NULL);
+ REQUIRE(DNS_C_LOGCHAN_VALID(logchan));
+
+ if (logchan->predefined && !if_predef_too) {
+ return;
+ }
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "channel %s {\n", logchan->name) ;
+
+ dns_c_printtabs(fp, indent + 1) ;
+ switch (logchan->ctype) {
+ case dns_c_logchan_file:
+ fprintf(fp, "file \"%s\"",
+ (logchan->u.filec.path == NULL ?
+ "No path defined" : logchan->u.filec.path));
+
+ if (DNS_C_CHECKBIT(CHAN_VERSIONS_BIT, &logchan->setflags)) {
+ fprintf(fp, " versions ");
+ if (logchan->u.filec.versions == DNS_C_UNLIM_VERSIONS){
+ fprintf(fp, "unlimited");
+ } else {
+ fprintf(fp, "%u", logchan->u.filec.versions);
+ }
+ }
+
+ if (DNS_C_CHECKBIT(CHAN_SIZE_BIT, &logchan->setflags)) {
+ fprintf(fp, " size ");
+ dns_c_printinunits(fp, logchan->u.filec.size);
+ }
+ break;
+
+ case dns_c_logchan_syslog:
+ fprintf(fp, "syslog ");
+ print_log_facility(fp, logchan->u.syslogc.facility);
+ break;
+
+ case dns_c_logchan_null:
+ fputs("null", fp);
+ break;
+ }
+ fprintf(fp, ";\n");
+
+ if (DNS_C_CHECKBIT(CHAN_SEVERITY_BIT, &logchan->setflags)) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "severity ");
+ print_log_severity(fp, logchan->severity);
+ if (logchan->severity == dns_c_log_debug &&
+ DNS_C_CHECKBIT(CHAN_DEBUG_LEVEL_BIT, &logchan->setflags)) {
+ fprintf(fp, " %d", logchan->debug_level);
+ }
+ fprintf(fp, ";\n");
+ }
+
+ if (DNS_C_CHECKBIT(CHAN_PSEV_BIT, &logchan->setflags)) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "print-severity %s;\n",
+ (logchan->print_severity ? "true" : "false"));
+ }
+
+ if (DNS_C_CHECKBIT(CHAN_PCAT_BIT, &logchan->setflags)) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "print-category %s;\n",
+ (logchan->print_category ? "true" : "false"));
+ }
+
+ if (DNS_C_CHECKBIT(CHAN_PTIME_BIT, &logchan->setflags)) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "print-time %s;\n",
+ (logchan->print_time ? "true" : "false"));
+ }
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "};\n");
+}
+
+
+isc_result_t
+dns_c_logchan_setpath(dns_c_logchan_t *channel, const char *path)
+{
+ isc_boolean_t existed = ISC_FALSE;
+
+ REQUIRE(DNS_C_LOGCHAN_VALID(channel));
+ REQUIRE(path != NULL);
+ REQUIRE(strlen(path) > 0);
+
+ if (channel->ctype != dns_c_logchan_file) {
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "This type of channel doesn't have a "
+ "path field");
+ return (ISC_R_FAILURE);
+ }
+
+ if (channel->u.filec.path != NULL) {
+ existed = ISC_TRUE;
+ isc_mem_free(channel->mem, channel->u.filec.path);
+ }
+
+ channel->u.filec.path = isc_mem_strdup(channel->mem, path);
+ if (channel->u.filec.path == NULL) {
+ return (ISC_R_NOMEMORY);
+ } else {
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+ }
+}
+
+
+isc_result_t
+dns_c_logchan_setversions(dns_c_logchan_t *channel, isc_uint32_t versions)
+{
+ isc_boolean_t existed;
+
+ REQUIRE(DNS_C_LOGCHAN_VALID(channel));
+
+ existed = DNS_C_CHECKBIT(CHAN_VERSIONS_BIT, &channel->setflags);
+
+ if (channel->ctype != dns_c_logchan_file) {
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "This type of channel doesn't have a "
+ "version field");
+ return (ISC_R_FAILURE);
+ }
+
+ DNS_C_SETBIT(CHAN_VERSIONS_BIT, &channel->setflags);
+ channel->u.filec.versions = versions;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_logchan_setsize(dns_c_logchan_t *channel, isc_uint32_t size)
+{
+ isc_boolean_t existed;
+
+ REQUIRE(DNS_C_LOGCHAN_VALID(channel));
+
+ if (channel->ctype != dns_c_logchan_file) {
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "This type of channel doesn't have a "
+ "size field");
+ return (ISC_R_FAILURE);
+ }
+
+ existed = DNS_C_CHECKBIT(CHAN_SIZE_BIT, &channel->setflags);
+
+ DNS_C_SETBIT(CHAN_SIZE_BIT, &channel->setflags);
+ channel->u.filec.size = size;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_logchan_setfacility(dns_c_logchan_t *channel, int facility)
+{
+ isc_boolean_t existed;
+
+ REQUIRE(DNS_C_LOGCHAN_VALID(channel));
+
+ if (channel->ctype != dns_c_logchan_syslog) {
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "This type of channel doesn't have a "
+ "facility field");
+ return (ISC_R_FAILURE);
+ }
+
+
+ if (dns_c_facility2string(facility, ISC_FALSE) == NULL) {
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Not a legal facility for a syslog channel: %d",
+ facility);
+ return (ISC_R_FAILURE);
+ }
+
+
+ existed = DNS_C_CHECKBIT(CHAN_FACILITY_BIT, &channel->setflags);
+
+ DNS_C_SETBIT(CHAN_FACILITY_BIT, &channel->setflags);
+ channel->u.syslogc.facility = facility;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_logchan_setseverity(dns_c_logchan_t *channel,
+ dns_c_logseverity_t severity)
+{
+ isc_boolean_t existed;
+
+ REQUIRE(DNS_C_LOGCHAN_VALID(channel));
+
+ existed = DNS_C_CHECKBIT(CHAN_SEVERITY_BIT, &channel->setflags);
+
+ DNS_C_SETBIT(CHAN_SEVERITY_BIT, &channel->setflags);
+ channel->severity = severity;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_logchan_setdebuglevel(dns_c_logchan_t *channel, isc_int32_t level)
+{
+ isc_boolean_t existed;
+
+ REQUIRE(DNS_C_LOGCHAN_VALID(channel));
+
+ if (channel->severity == dns_c_log_debug) {
+ existed = DNS_C_CHECKBIT(CHAN_DEBUG_LEVEL_BIT,
+ &channel->setflags);
+
+ DNS_C_SETBIT(CHAN_DEBUG_LEVEL_BIT, &channel->setflags);
+ channel->debug_level = level;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+ } else {
+ return (ISC_R_FAILURE);
+ }
+}
+
+
+isc_result_t
+dns_c_logchan_setprintcat(dns_c_logchan_t *channel, isc_boolean_t newval)
+{
+ isc_boolean_t existed;
+
+ REQUIRE(DNS_C_LOGCHAN_VALID(channel));
+
+ existed = DNS_C_CHECKBIT(CHAN_PCAT_BIT, &channel->setflags);
+
+ DNS_C_SETBIT(CHAN_PCAT_BIT, &channel->setflags);
+ channel->print_category = newval;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_logchan_setprintsev(dns_c_logchan_t *channel, isc_boolean_t newval)
+{
+ isc_boolean_t existed;
+
+ REQUIRE(DNS_C_LOGCHAN_VALID(channel));
+
+ existed = DNS_C_CHECKBIT(CHAN_PSEV_BIT, &channel->setflags);
+
+ DNS_C_SETBIT(CHAN_PSEV_BIT, &channel->setflags);
+ channel->print_severity = newval;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_logchan_setprinttime(dns_c_logchan_t *channel, isc_boolean_t newval)
+{
+ isc_boolean_t existed;
+
+ REQUIRE(DNS_C_LOGCHAN_VALID(channel));
+
+ existed = DNS_C_CHECKBIT(CHAN_PTIME_BIT, &channel->setflags);
+
+ DNS_C_SETBIT(CHAN_PTIME_BIT, &channel->setflags);
+ channel->print_time = newval;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+isc_result_t
+dns_c_logchan_setpredef(dns_c_logchan_t *channel, isc_boolean_t newval)
+{
+ REQUIRE(DNS_C_LOGCHAN_VALID(channel));
+
+ channel->predefined = newval;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+
+
+isc_result_t
+dns_c_logchan_getpath(dns_c_logchan_t *channel, const char **path)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_LOGCHAN_VALID(channel));
+ REQUIRE(path != NULL);
+
+ if (channel->ctype == dns_c_logchan_file &&
+ channel->u.filec.path != NULL) {
+ *path = channel->u.filec.path;
+ res = ISC_R_SUCCESS;
+ } else if (channel->ctype == dns_c_logchan_file) {
+ res = ISC_R_NOTFOUND;
+ } else {
+ res = ISC_R_FAILURE;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_logchan_getversions(dns_c_logchan_t *channel, isc_uint32_t *retval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_LOGCHAN_VALID(channel));
+ REQUIRE(retval != NULL);
+
+ if (channel->ctype == dns_c_logchan_file &&
+ DNS_C_CHECKBIT(CHAN_VERSIONS_BIT, &channel->setflags)) {
+ *retval = channel->u.filec.versions;
+ res = ISC_R_SUCCESS;
+ } else if (channel->ctype == dns_c_logchan_file) {
+ res = ISC_R_NOTFOUND;
+ } else {
+ res = ISC_R_FAILURE;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_logchan_getsize(dns_c_logchan_t *channel, isc_uint32_t *retval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_LOGCHAN_VALID(channel));
+ REQUIRE(retval != NULL);
+
+ if (channel->ctype == dns_c_logchan_file &&
+ DNS_C_CHECKBIT(CHAN_SIZE_BIT, &channel->setflags)) {
+ *retval = channel->u.filec.size;
+ res = ISC_R_SUCCESS;
+ } else if (channel->ctype == dns_c_logchan_file) {
+ res = ISC_R_NOTFOUND;
+ } else {
+ res = ISC_R_FAILURE;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_logchan_getfacility(dns_c_logchan_t *channel, int *retval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_LOGCHAN_VALID(channel));
+ REQUIRE(retval != NULL);
+
+ if (channel->ctype == dns_c_logchan_syslog &&
+ DNS_C_CHECKBIT(CHAN_FACILITY_BIT, &channel->setflags)) {
+ *retval = channel->u.syslogc.facility;
+ res = ISC_R_SUCCESS;
+ } else if (channel->ctype == dns_c_logchan_syslog) {
+ res = ISC_R_NOTFOUND;
+ } else {
+ res = ISC_R_FAILURE;
+ }
+
+ return (res);
+
+}
+
+
+isc_result_t
+dns_c_logchan_getseverity(dns_c_logchan_t *channel,
+ dns_c_logseverity_t *retval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_LOGCHAN_VALID(channel));
+ REQUIRE(retval != NULL);
+
+ if (DNS_C_CHECKBIT(CHAN_SEVERITY_BIT, &channel->setflags)) {
+ *retval = channel->severity;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_logchan_getdebuglevel(dns_c_logchan_t *channel, isc_int32_t *retval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_LOGCHAN_VALID(channel));
+ REQUIRE(retval != NULL);
+
+ if (DNS_C_CHECKBIT(CHAN_DEBUG_LEVEL_BIT, &channel->setflags)) {
+ *retval = channel->debug_level;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_logchan_getprintcat(dns_c_logchan_t *channel, isc_boolean_t *retval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_LOGCHAN_VALID(channel));
+ REQUIRE(retval != NULL);
+
+ if (DNS_C_CHECKBIT(CHAN_PCAT_BIT, &channel->setflags)) {
+ *retval = channel->print_category;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_logchan_getprintsev(dns_c_logchan_t *channel, isc_boolean_t *retval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_LOGCHAN_VALID(channel));
+ REQUIRE(retval != NULL);
+
+ if (DNS_C_CHECKBIT(CHAN_PSEV_BIT, &channel->setflags)) {
+ *retval = channel->print_severity;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+
+}
+
+
+isc_result_t
+dns_c_logchan_getprinttime(dns_c_logchan_t *channel, isc_boolean_t *retval)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_LOGCHAN_VALID(channel));
+ REQUIRE(retval != NULL);
+
+ if (DNS_C_CHECKBIT(CHAN_PTIME_BIT, &channel->setflags)) {
+ *retval = channel->print_time;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_logchan_getpredef(dns_c_logchan_t *channel, isc_boolean_t *retval)
+{
+ REQUIRE(DNS_C_LOGCHAN_VALID(channel));
+ REQUIRE(retval != NULL);
+
+ *retval = channel->predefined;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+/*
+ * Logging category
+ */
+isc_result_t
+dns_c_logcat_new(isc_mem_t *mem, dns_c_category_t cat, dns_c_logcat_t **newlc)
+{
+ dns_c_logcat_t *newc;
+ unsigned int i;
+
+ REQUIRE(newlc != NULL);
+
+ newc = isc_mem_get(mem, sizeof *newc);
+ if (newc == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ newc->magic = DNS_C_LOGCAT_MAGIC;
+ newc->mem = mem;
+ newc->category = cat;
+ newc->cnames_len = 2;
+ newc->nextcname = 0;
+ newc->predefined = ISC_FALSE;
+ newc->channel_names = isc_mem_get(mem,
+ sizeof (char *) * newc->cnames_len);
+ if (newc->channel_names == NULL) {
+ isc_mem_put(mem, newc, sizeof *newc);
+ return (ISC_R_NOMEMORY);
+ }
+
+ for (i = 0 ; i < newc->cnames_len ; i++) {
+ newc->channel_names[i] = NULL;
+ }
+
+ *newlc = newc;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_logcat_delete(dns_c_logcat_t **logcat)
+{
+ dns_c_logcat_t *logc;
+ unsigned int i;
+
+ REQUIRE(logcat != NULL);
+ REQUIRE(DNS_C_LOGCAT_VALID(*logcat));
+
+ logc = *logcat;
+ if (logc == NULL) {
+ return (ISC_R_SUCCESS);
+ }
+
+ for (i = 0 ; i < logc->nextcname ; i++) {
+ REQUIRE(logc->channel_names[i] != NULL);
+
+ isc_mem_free(logc->mem, logc->channel_names[i]);
+ }
+
+ logc->magic = 0;
+ isc_mem_put(logc->mem, logc->channel_names,
+ sizeof (char *) * logc->cnames_len);
+ isc_mem_put(logc->mem, logc, sizeof *logc);
+
+ *logcat = NULL;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_logcat_copy(isc_mem_t *mem, dns_c_logcat_t **dest, dns_c_logcat_t *src)
+{
+ unsigned int i;
+ dns_c_logcat_t *newc;
+ isc_result_t res;
+
+ REQUIRE(dest != NULL);
+ REQUIRE(DNS_C_LOGCAT_VALID(src));
+
+ res = dns_c_logcat_new(mem, src->category, &newc);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ for (i = 0 ; i < src->nextcname ; i++) {
+ res = dns_c_logcat_addname(newc, src->channel_names[i]);
+ if (res != ISC_R_SUCCESS) {
+ dns_c_logcat_delete(&newc);
+ return (res);
+ }
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+
+void
+dns_c_logcat_print(FILE *fp, int indent, dns_c_logcat_t *logcat,
+ isc_boolean_t if_predef_too)
+{
+ unsigned int i;
+
+ REQUIRE(fp != NULL);
+ REQUIRE(DNS_C_LOGCAT_VALID(logcat));
+
+ if (logcat->predefined && !if_predef_too) {
+ return;
+ }
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "category ");
+ print_log_category(fp, logcat->category);
+ fprintf(fp, " {\n");
+
+ for (i = 0 ; i < logcat->nextcname ; i++) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "%s;\n", logcat->channel_names[i]);
+ }
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "};\n");
+}
+
+
+isc_result_t
+dns_c_logcat_addname(dns_c_logcat_t *logcat, const char *name)
+{
+ unsigned int i;
+
+ REQUIRE(DNS_C_LOGCAT_VALID(logcat));
+ REQUIRE(name != NULL);
+ REQUIRE(strlen(name) > 0);
+
+ if (logcat->cnames_len == logcat->nextcname) {
+ size_t newsize = logcat->cnames_len + 5;
+ char **newarr = isc_mem_get(logcat->mem,
+ newsize * sizeof (char *));
+
+ if (newarr == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ for (i = 0 ; i < newsize ; i++) {
+ if (i < logcat->cnames_len) {
+ newarr[i] = logcat->channel_names[i];
+ } else {
+ newarr[i] = NULL;
+ }
+ }
+
+ isc_mem_put(logcat->mem, logcat->channel_names,
+ sizeof (char *) * logcat->cnames_len);
+
+ logcat->channel_names = newarr;
+ logcat->cnames_len = newsize;
+ }
+
+ logcat->channel_names[logcat->nextcname] =
+ isc_mem_strdup(logcat->mem, name);
+ if (logcat->channel_names[logcat->nextcname] == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ logcat->nextcname++;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_logcat_delname(dns_c_logcat_t *logcat, const char *name)
+{
+ unsigned int i ;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_LOGCAT_VALID(logcat));
+ REQUIRE(name != NULL);
+ REQUIRE(strlen(name) > 0);
+
+ for (i = 0 ; i < logcat->nextcname ; i++) {
+ INSIST(logcat->channel_names[i] != NULL);
+ if (strcmp(logcat->channel_names[i], name) == 0) {
+ break;
+ }
+ }
+
+ if (i < logcat->nextcname) {
+ res = ISC_R_SUCCESS;
+ isc_mem_free(logcat->mem, logcat->channel_names[i]);
+ while (i < (logcat->nextcname - 1)) {
+ logcat->channel_names[i] = logcat->channel_names[i+1];
+ i++;
+ }
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+
+ return (res);
+}
+
+
+
+isc_result_t
+dns_c_logcat_setpredef(dns_c_logcat_t *logcat,isc_boolean_t newval)
+{
+ REQUIRE(DNS_C_LOGCAT_VALID(logcat));
+
+ logcat->predefined = newval;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_logcat_getpredef(dns_c_logcat_t *logcat, isc_boolean_t *retval)
+{
+ REQUIRE(DNS_C_LOGCAT_VALID(logcat));
+ REQUIRE(retval != NULL);
+
+ *retval = logcat->predefined;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+
+/***************************************************************************/
+
+
+static void
+print_log_facility(FILE *fp, int value)
+{
+ REQUIRE(fp != NULL);
+
+ fputs(dns_c_facility2string(value, ISC_TRUE), fp);
+}
+
+
+static void
+print_log_severity(FILE *fp, dns_c_logseverity_t severity)
+{
+ REQUIRE(fp != NULL);
+
+ fputs(dns_c_logseverity2string(severity, ISC_TRUE), fp);
+}
+
+
+static void
+print_log_category(FILE *fp, dns_c_category_t category)
+{
+ REQUIRE(fp != NULL);
+
+ fputs(dns_c_category2string(category, ISC_TRUE), fp);
+}
+
diff --git a/lib/dns/config/conflsn.c b/lib/dns/config/conflsn.c
new file mode 100644
index 00000000..35ef6a8d
--- /dev/null
+++ b/lib/dns/config/conflsn.c
@@ -0,0 +1,213 @@
+/*
+ * 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.
+ */
+
+#include <config.h>
+
+#include <isc/assertions.h>
+#include <isc/magic.h>
+
+#include <dns/conflsn.h>
+#include <dns/confcommon.h>
+
+#include "confpvt.h"
+
+
+isc_result_t
+dns_c_lstnon_new(isc_mem_t *mem, dns_c_lstnon_t **listen)
+{
+ dns_c_lstnon_t *ll;
+ isc_result_t result;
+
+ REQUIRE(listen != NULL);
+
+ *listen = NULL;
+
+ ll = isc_mem_get(mem, sizeof *ll);
+ ll->mem = mem;
+ ll->port = 0;
+ ll->magic = DNS_C_LISTEN_MAGIC;
+
+ result = dns_c_ipmatchlist_new(mem, &ll->iml);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(mem, ll, sizeof *ll);
+ return (result);
+ }
+
+ ISC_LINK_INIT(ll, next);
+
+ *listen = ll;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_lstnon_delete(dns_c_lstnon_t **listen)
+{
+ dns_c_lstnon_t *lo;
+ isc_result_t r;
+
+ REQUIRE(listen != NULL);
+ REQUIRE(DNS_C_LISTEN_VALID(*listen));
+
+ lo = *listen;
+
+ if (lo->iml != NULL) {
+ r = dns_c_ipmatchlist_detach(&lo->iml);
+ } else {
+ r = ISC_R_SUCCESS;
+ }
+
+ lo->magic = 0;
+ isc_mem_put(lo->mem, lo, sizeof *lo);
+
+ *listen = NULL;
+
+ return (r);
+}
+
+
+isc_result_t
+dns_c_lstnon_setiml(dns_c_lstnon_t *listen,
+ dns_c_ipmatchlist_t *iml, isc_boolean_t deepcopy)
+{
+ isc_result_t result;
+
+ REQUIRE(DNS_C_LISTEN_VALID(listen));
+ REQUIRE(DNS_C_IPMLIST_VALID(iml));
+
+ if (listen->iml != NULL) {
+ result = dns_c_ipmatchlist_detach(&listen->iml);
+ if (result != ISC_R_SUCCESS) {
+ return (result);
+ }
+ } else {
+ result = ISC_R_SUCCESS;
+ }
+
+
+ if (deepcopy) {
+ result = dns_c_ipmatchlist_copy(listen->mem,
+ &listen->iml, iml);
+ } else {
+ listen->iml = iml;
+ }
+
+ return (result);
+}
+
+
+
+
+
+
+
+isc_result_t
+dns_c_lstnlist_new(isc_mem_t *mem, dns_c_lstnlist_t **llist)
+{
+ dns_c_lstnlist_t *ll;
+
+ REQUIRE(llist != NULL);
+
+ *llist = NULL;
+
+ ll = isc_mem_get(mem, sizeof *ll);
+ if (ll == NULL) {
+ /* XXXJAB logwrite */
+ return (ISC_R_NOMEMORY);
+ }
+
+ ll->mem = mem;
+ ll->magic = DNS_C_LLIST_MAGIC;
+ ISC_LIST_INIT(ll->elements);
+
+ *llist = ll;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_lstnlist_delete(dns_c_lstnlist_t **llist)
+{
+ dns_c_lstnlist_t *ll;
+ dns_c_lstnon_t *lo, *lotmp;
+ isc_result_t r;
+
+ REQUIRE(llist != NULL);
+ REQUIRE(DNS_C_LISTENLIST_VALID(*llist));
+
+ ll = *llist;
+
+ lo = ISC_LIST_HEAD(ll->elements);
+ while (lo != NULL) {
+ lotmp = ISC_LIST_NEXT(lo, next);
+ ISC_LIST_UNLINK(ll->elements, lo, next);
+ r = dns_c_lstnon_delete(&lo);
+ if (r != ISC_R_SUCCESS) {
+ return (r);
+ }
+
+ lo = lotmp;
+ }
+
+ ll->magic = 0;
+ isc_mem_put(ll->mem, ll, sizeof *ll);
+
+ *llist = NULL;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_lstnlist_print(FILE *fp, int indent,
+ dns_c_lstnlist_t *ll)
+{
+ dns_c_lstnon_t *lo;
+
+ REQUIRE(DNS_C_LISTENLIST_VALID(ll));
+
+ lo = ISC_LIST_HEAD(ll->elements);
+ while (lo != NULL) {
+ dns_c_printtabs(fp, indent);
+ dns_c_lstnon_print(fp, indent, lo);
+ lo = ISC_LIST_NEXT(lo, next);
+ fprintf(fp, "\n");
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_lstnon_print(FILE *fp, int indent, dns_c_lstnon_t *lo)
+{
+ REQUIRE(lo != NULL);
+ REQUIRE(DNS_C_LISTEN_VALID(lo));
+
+ fprintf(fp, "listen-on ");
+ if (lo->port != DNS_C_DEFAULTPORT) {
+ fprintf(fp, "port %d ", lo->port);
+ }
+
+ dns_c_ipmatchlist_print(fp, indent + 1, lo->iml);
+ fprintf(fp, ";\n");
+
+ return (ISC_R_SUCCESS);
+}
+
diff --git a/lib/dns/config/confparser.y b/lib/dns/config/confparser.y
new file mode 100644
index 00000000..6bcf7f37
--- /dev/null
+++ b/lib/dns/config/confparser.y
@@ -0,0 +1,4508 @@
+%{
+/*
+ * Copyright (c) 1996-1999 by 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.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid[] = "$Id: confparser.y,v 1.37 2000/02/02 00:38:11 halley Exp $";
+#endif /* not lint */
+
+#include <config.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <syslog.h>
+
+#include <isc/assertions.h>
+#include <isc/error.h>
+#include <isc/mutex.h>
+#include <isc/lex.h>
+#include <isc/symtab.h>
+#include <isc/error.h>
+#include <isc/once.h>
+#include <isc/dir.h>
+#include <isc/net.h>
+
+#include <dns/confparser.h>
+#include <dns/confctx.h>
+#include <dns/log.h>
+
+#include <dns/result.h>
+#include <dns/rdatatype.h>
+#include <dns/rdataclass.h>
+
+#include <dns/types.h>
+
+#include <dns/confcommon.h>
+
+
+/* Type keys for symtab lookup */
+#define KEYWORD_SYM_TYPE 0x1
+#define CLASS_SYM_TYPE 0x2
+#define ACL_SYM_TYPE 0x3
+
+
+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;
+
+#define CONF_MAX_IDENT 1024
+
+/* This should be sufficient to permit multiple parsers and lexers if needed */
+#define yyparse confyyparse
+#define yylex confyylex
+
+#define YYDEBUG 1
+
+static isc_result_t tmpres;
+static int debug_lexer;
+
+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_boolean_t unit_to_uint32(char *in, isc_uint32_t *out);
+static void yyerror(const char *);
+
+/* returns true if (base * mult) would be too big.*/
+static isc_boolean_t int_too_big(isc_uint32_t base, isc_uint32_t mult);
+
+%}
+
+%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;
+
+ isc_boolean_t boolean;
+ dns_rdataclass_t rrclass;
+ dns_severity_t severity;
+ dns_c_trans_t transport;
+ dns_transfer_format_t tformat;
+ dns_c_category_t logcat;
+
+ 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;
+}
+
+/* Misc */
+%token <text> L_STRING
+%token <text> L_QSTRING
+%token <l_int> L_INTEGER
+%token <ip4_addr> L_IP4ADDR
+%token <ip6_addr> L_IP6ADDR
+
+%token L_LBRACE
+%token L_RBRACE
+%token L_EOS
+%token L_SLASH
+%token L_BANG
+%token L_QUOTE
+
+%token L_MASTER
+%token L_SLAVE
+%token L_SORTLIST
+%token L_HINT
+%token L_STUB
+%token L_FORWARD
+
+%token L_INCLUDE
+%token L_END_INCLUDE
+
+%token L_OPTIONS
+%token L_DIRECTORY
+%token L_DIRECTORY
+%token L_PIDFILE
+%token L_NAMED_XFER
+%token L_TKEY_DOMAIN
+%token L_TKEY_DHKEY
+%token L_DUMP_FILE
+%token L_STATS_FILE
+%token L_MEMSTATS_FILE
+%token L_FAKE_IQUERY
+%token L_RECURSION
+%token L_FETCH_GLUE
+%token L_QUERY_SOURCE
+%token L_LISTEN_ON
+%token L_PORT
+%token L_ACL
+%token L_ADDRESS
+%token L_ALGID
+%token L_ALLOW_QUERY
+%token L_ALLOW_TRANSFER
+%token L_ALLOW_UPDATE
+%token L_ALLOW_RECURSION
+%token L_ALSO_NOTIFY
+%token L_BLACKHOLE
+%token L_BOGUS
+%token L_CATEGORY
+%token L_CHANNEL
+%token L_CHECK_NAMES
+%token L_DEBUG
+%token L_DIALUP
+%token L_DYNAMIC
+%token L_FAIL
+%token L_FIRST
+%token L_FORWARDERS
+%token L_IF_NO_ANSWER
+%token L_IF_NO_DOMAIN
+%token L_IGNORE
+%token L_FILE_IXFR
+%token L_IXFR_TMP
+%token L_SEC_KEY
+%token L_KEYS
+%token L_LOGGING
+%token L_MASTERS
+%token L_NULL_OUTPUT
+%token L_ONLY
+%token L_PRINT_CATEGORY
+%token L_PRINT_SEVERITY
+%token L_PRINT_TIME
+%token L_PUBKEY
+%token L_RESPONSE
+%token L_SECRET
+%token L_SERVER
+%token L_SEVERITY
+%token L_SIZE
+%token L_SUPPORT_IXFR
+%token L_SYSLOG
+%token L_TOPOLOGY
+%token L_TRANSFER_SOURCE
+%token L_TRANSFERS
+%token L_TRUSTED_KEYS
+%token L_VERSIONS
+%token L_WARN
+%token L_RRSET_ORDER
+%token L_ORDER
+%token L_NAME
+%token L_CLASS
+%token L_CONTROLS
+%token L_INET
+%token L_UNIX
+%token L_PERM
+%token L_OWNER
+%token L_GROUP
+%token L_ALLOW
+%token L_DATASIZE
+%token L_STACKSIZE
+%token L_CORESIZE
+%token L_DEFAULT
+%token L_UNLIMITED
+%token L_FILES
+%token L_VERSION
+%token L_HOSTSTATS
+%token L_DEALLOC_ON_EXIT
+%token L_TRANSFERS_IN
+%token L_TRANSFERS_OUT
+%token L_TRANSFERS_PER_NS
+%token L_TRANSFER_FORMAT
+%token L_MAX_TRANSFER_TIME_IN
+%token L_MAX_TRANSFER_TIME_OUT
+%token L_MAX_TRANSFER_IDLE_IN
+%token L_MAX_TRANSFER_IDLE_OUT
+%token L_TCP_CLIENTS
+%token L_RECURSIVE_CLIENTS
+%token L_ONE_ANSWER
+%token L_MANY_ANSWERS
+%token L_NOTIFY
+%token L_AUTH_NXDOMAIN
+%token L_MULTIPLE_CNAMES
+%token L_USE_IXFR
+%token L_MAINTAIN_IXFR_BASE
+%token L_CLEAN_INTERVAL
+%token L_INTERFACE_INTERVAL
+%token L_STATS_INTERVAL
+%token L_MAX_LOG_SIZE_IXFR
+%token L_HEARTBEAT
+%token L_USE_ID_POOL
+%token L_MAX_NCACHE_TTL
+%token L_HAS_OLD_CLIENTS
+%token L_EXPERT_MODE
+%token L_ZONE
+%token L_TYPE
+%token L_FILE
+%token L_YES
+%token L_TRUE
+%token L_NO
+%token L_FALSE
+%token L_VIEW
+%token L_RFC2308_TYPE1
+
+%type <boolean> yea_or_nay
+
+%type <forward> forward_opt
+%type <forward> zone_forward_opt
+
+%type <ime> address_match_element
+%type <ime> address_match_simple
+%type <ime> address_name
+
+%type <iml> address_match_list
+
+%type <ipaddress> in_addr_elem
+%type <ipaddress> ip4_address
+%type <ipaddress> ip6_address
+%type <ipaddress> ip_address
+%type <ipaddress> maybe_wild_addr
+
+%type <iplist> in_addr_list
+%type <iplist> master_in_addr_list
+%type <iplist> master_in_addr_list
+%type <iplist> master_in_addr_list
+%type <iplist> notify_in_addr_list
+%type <iplist> opt_in_addr_list
+%type <iplist> opt_zone_forwarders_list
+
+%type <logcat> category_name
+
+%type <number> facility_name
+%type <number> maybe_syslog_facility
+
+%type <orderclass> ordering_class
+
+%type <ordertype> ordering_type
+
+%type <port_int> in_port
+%type <port_int> maybe_port
+%type <port_int> maybe_wild_port
+%type <port_int> maybe_zero_port
+
+%type <rrclass> class_name
+%type <rrclass> optional_class
+
+%type <severity> check_names_opt;
+
+/* %type <text> optional_string */
+%type <text> algorithm_id
+%type <text> any_string
+%type <text> channel_name
+%type <text> domain_name
+%type <text> key_ref
+%type <text> ordering_name
+%type <text> secret
+
+%type <tformat> transfer_format
+
+%type <transport> check_names_type;
+
+%type <ul_int> size_spec
+
+%type <ztype> zone_type
+
+/* Miscellaneous items (used in several places): */
+
+%%
+
+config_file: statement_list
+ ;
+
+statement_list: statement
+ | statement_list statement
+ ;
+
+statement: include_stmt L_EOS
+ | 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
+ ;
+
+
+include_stmt: L_INCLUDE L_QSTRING
+ {
+ if (isc_lex_openfile(mylexer, $2) != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE ,"Can't open file %s", $2);
+ YYABORT;
+ }
+
+ isc_mem_free(memctx, $2);
+ }
+ ;
+
+options_stmt: L_OPTIONS
+ {
+ dns_c_options_t *options;
+
+ 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: option L_EOS
+ | options option L_EOS
+ ;
+
+
+option: /* Empty */
+ | L_VERSION L_QSTRING
+ {
+ tmpres = dns_c_ctx_setversion(currcfg, $2);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE, "Redefining version.");
+ } 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, "Redefining directory");
+ } 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, "Redefining named-xfer");
+ } 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_TKEY_DOMAIN L_QSTRING
+ {
+ tmpres = dns_c_ctx_settkeydomain(currcfg, $2);
+
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE, "Redefining tkey-domain");
+ } 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, "Redefining tkey-dhkey");
+ } 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, "Redefining pid-file");
+ } 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, "Redefining statistics-file");
+ } 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,
+ "Redefining memstatistics-file");
+ } 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, "Redefining dump-file");
+ } 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, "Redefining expert-mode.");
+ }
+ }
+ | L_FAKE_IQUERY yea_or_nay
+ {
+ tmpres = dns_c_ctx_setfakeiquery(currcfg, ISC_FALSE);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE, "Redefining fake-iquery.");
+ }
+ }
+ | L_RECURSION yea_or_nay
+ {
+ tmpres = dns_c_ctx_setrecursion(currcfg, $2);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE, "Redefining recursion");
+ }
+ }
+ | L_FETCH_GLUE yea_or_nay
+ {
+ tmpres = dns_c_ctx_setfetchglue(currcfg, $2);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE, "Redefining fetch-glue.");
+ }
+ }
+ | L_NOTIFY yea_or_nay
+ {
+ tmpres = dns_c_ctx_setnotify(currcfg, $2);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE, "Redefining notify.");
+ }
+ }
+ | L_HOSTSTATS yea_or_nay
+ {
+ tmpres = dns_c_ctx_sethoststatistics(currcfg, $2);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE, "Redefining host-statistics.");
+ }
+ }
+ | L_DEALLOC_ON_EXIT yea_or_nay
+ {
+ tmpres = dns_c_ctx_setdealloconexit(currcfg, $2);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE,
+ "Redefining deallocate-on-exit.");
+ }
+ }
+ | L_USE_IXFR yea_or_nay
+ {
+ tmpres = dns_c_ctx_setuseixfr(currcfg, $2);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE, "Redefining use-ixfr.");
+ }
+ }
+ | L_MAINTAIN_IXFR_BASE yea_or_nay
+ {
+ tmpres = dns_c_ctx_setmaintainixfrbase(currcfg, $2);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE,
+ "Redefining maintain-ixfr-base.");
+ }
+ }
+ | L_HAS_OLD_CLIENTS yea_or_nay
+ {
+ tmpres = dns_c_ctx_sethasoldclients(currcfg, $2);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE, "Redefining has-old-clients.");
+ }
+ }
+ | L_AUTH_NXDOMAIN yea_or_nay
+ {
+ tmpres = dns_c_ctx_setauthnxdomain(currcfg, $2);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE, "Redefining auth-nxdomain.");
+ }
+ }
+ | L_MULTIPLE_CNAMES yea_or_nay
+ {
+ tmpres = dns_c_ctx_setmultiplecnames(currcfg, $2);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE, "Redefining multiple-cnames.");
+ }
+ }
+ | 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, "Redefining check-names.");
+ }
+ }
+ | L_USE_ID_POOL yea_or_nay
+ {
+ tmpres = dns_c_ctx_setuseidpool(currcfg, $2);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE, "Redefining use-id-pool.");
+ }
+ }
+ | L_RFC2308_TYPE1 yea_or_nay
+ {
+ tmpres = dns_c_ctx_setrfc2308type1(currcfg, $2);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE, "Redefining rfc2308-type.");
+ }
+ }
+ | L_LISTEN_ON maybe_port L_LBRACE address_match_list L_RBRACE
+ {
+ if ($4 == NULL) {
+ parser_warning(ISC_FALSE,
+ "address-match-list empty. "
+ "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_FORWARD forward_opt
+ {
+ tmpres = dns_c_ctx_setforward(currcfg, $2);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE, "Redefining forward");
+ }
+ }
+ | L_FORWARDERS {
+ dns_c_iplist_t *forwarders;
+
+ tmpres = dns_c_ctx_getforwarders(currcfg, &forwarders);
+ if (tmpres != ISC_R_NOTFOUND) {
+ parser_error(ISC_FALSE,
+ "Redefining 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
+ | L_TRANSFER_SOURCE maybe_wild_addr
+ {
+ tmpres = dns_c_ctx_settransfersource(currcfg, $2);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE, "Redefining transfer-source");
+ } else if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE,
+ "Failed to set transfer-source");
+ YYABORT;
+ }
+ }
+ | L_ALLOW_QUERY L_LBRACE address_match_list L_RBRACE
+ {
+ if ($3 == NULL)
+ YYABORT;
+ tmpres = dns_c_ctx_setqueryacl(currcfg, ISC_FALSE, $3);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE, "Redefining allow-query list");
+ } 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_settransferacl(currcfg, ISC_FALSE, $3);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE,
+ "Redefining allow-transfer list");
+ } 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_setrecursionacl(currcfg, ISC_FALSE, $3);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE,
+ "Redefining allow-recursion list");
+ } 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, ISC_FALSE, $3);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE, "Redefining sortlist.");
+ } else if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE, "Failed to set sortlist");
+ YYABORT;
+ }
+ }
+ | L_ALSO_NOTIFY L_LBRACE notify_in_addr_list L_RBRACE
+ {
+ tmpres = dns_c_ctx_setalsonotify(currcfg, $3, ISC_FALSE);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE, "Redefining also-notify.");
+ } 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, ISC_FALSE, $3);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE, "Redefining blackhole.");
+ } 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, ISC_FALSE, $3);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE, "Redefining topology.");
+ } 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, "Redefining transfer-format.");
+ } 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,
+ "Redefining max-transfer-time-in.");
+ } else if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE,
+ "Failed to set max-transfer-time-in.");
+ YYABORT;
+ }
+ }
+ | 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,
+ "Redefining max-transfer-time-out.");
+ } 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,
+ "Redefining max-transfer-idle-in.");
+ } 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,
+ "Redefining max-transfer-idle-out.");
+ } 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,
+ "Redefining tcp-clients.");
+ } else if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE,
+ "Failed to set tcp-clients.");
+ YYABORT;
+ }
+ }
+ | L_RECURSIVE_CLIENTS L_INTEGER
+ {
+ tmpres = dns_c_ctx_setrecursiveclients(currcfg, $2);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE,
+ "Redefining recursive-clients.");
+ } else if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE,
+ "Failed to set recursive-clients.");
+ 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,
+ "Redefining cleaning-interval.");
+ } 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,
+ "Redefining interface-interval.");
+ } 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,
+ "Redefining statistics-interval.");
+ } 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,
+ "Redefining max-ixfr-log-size.");
+ } 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,
+ "Redefining max-ncache-ttl.");
+ } else if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE,
+ "Failed to set max-ncache-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_setheartbeat_interval(currcfg, $2 * 60);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE,
+ "Redefining heartbeat-interval.");
+ } 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, "Redefining dialup.");
+ } 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_error(ISC_FALSE,
+ "Redefining 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
+ ;
+
+
+/*
+ * Controls.
+ */
+controls_stmt: L_CONTROLS
+ {
+ if (currcfg->controls != NULL) {
+ parser_error(ISC_FALSE, "Redefining 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 L_PORT in_port
+ L_ALLOW L_LBRACE address_match_list L_RBRACE
+ {
+ dns_c_ctrl_t *control;
+
+ tmpres = dns_c_ctrlinet_new(currcfg->mem, &control,
+ $2, $4, $7, 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);
+ }
+ ;
+
+rrset_ordering_list: rrset_ordering_element L_EOS
+ | rrset_ordering_list rrset_ordering_element L_EOS
+ ;
+
+ordering_class: /* nothing */
+ {
+ $$ = dns_rdataclass_any;
+ }
+ | L_CLASS 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, &reg);
+ if (tmpres != DNS_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
+ {
+ $$ = $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;
+ }
+ ;
+
+
+maybe_wild_addr: ip_address
+ {
+ $$ = $1;
+ }
+ | L_STRING
+ {
+ struct in_addr any;
+ any.s_addr = htonl(INADDR_ANY);
+ isc_sockaddr_fromin(&$$, &any, 0);
+
+ if (strcmp($1, "*") != 0) {
+ parser_error(ISC_TRUE, "Bad ip-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);
+ }
+ ;
+
+query_source_address: L_ADDRESS maybe_wild_addr
+ {
+ tmpres = dns_c_ctx_setquerysourceaddr(currcfg, $2);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE,
+ "Redefining query-source address.");
+ } else if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE,
+ "Failed to set query-source address.");
+ YYABORT;
+ }
+ }
+ ;
+
+query_source_port: L_PORT maybe_wild_port
+ {
+ tmpres = dns_c_ctx_setquerysourceport(currcfg, $2);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_error(ISC_FALSE,
+ "Redefining query-source port.");
+ } else if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE,
+ "Failed to set query-source port.");
+ YYABORT;
+ }
+ }
+ ;
+
+query_source: query_source_address
+ | query_source_port
+ | query_source_address query_source_port
+ | query_source_port query_source_address
+ ;
+
+maybe_port: /* nothing */
+ {
+ $$ = DNS_C_DEFAULTPORT;
+ }
+ | L_PORT in_port
+ {
+ $$ = $2;
+ }
+ ;
+
+maybe_zero_port : /* nothing */
+ {
+ $$ = 0;
+ }
+ | L_PORT in_port
+ {
+ $$ = $2;
+ }
+ ;
+
+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;
+ }
+ }
+ ;
+
+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, "Redefining datasize.");
+ } 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, "Redefining stacksize.");
+ } 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, "Redefining coresize.");
+ } 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, "Redefining files.");
+ } else if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE, "Failed to set files.");
+ YYABORT;
+ }
+ }
+ ;
+
+
+size_spec: any_string
+ {
+ isc_uint32_t result;
+
+ if (unit_to_uint32($1, &result)) {
+ $$ = result;
+ 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; }
+ } else {
+ parser_warning(ISC_FALSE,
+ "invalid unit string '%s'. Using "
+ "default", $1);
+ $$ = 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, "Redefining transfers-in.");
+ } 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,
+ "Redefining transfers-out.");
+ } 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,
+ "Redefining transfers-per-ns.");
+ } 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
+ {
+ tmpres = dns_c_iplist_append(currcfg->options->forwarders, $1);
+ 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_warning(ISC_FALSE,
+ "Redefing channel %s", $2);
+ } 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_warning(ISC_FALSE, "Redefining channel %s", $2);
+ } 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_warning(ISC_FALSE, "Redefining channel %s", $2);
+ } 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_warning(ISC_FALSE,
+ "Redefining category ``%s''", $2);
+ } else if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE,
+ "Failed to add new logging category.");
+ YYABORT;
+ }
+ } 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_warning(ISC_FALSE, "Redefining severity.");
+ } 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_warning(ISC_FALSE, "Redefining severity.");
+ } 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_warning(ISC_FALSE, "Redefining severity.");
+ } 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_warning(ISC_FALSE, "Redefining severity.");
+ } 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_warning(ISC_FALSE, "Redefining versions.");
+ } 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, -1);
+ if (tmpres == ISC_R_EXISTS) {
+ parser_warning(ISC_FALSE, "Redefining versions.");
+ } 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_warning(ISC_FALSE, "Redefining size.");
+ } 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_warning(ISC_FALSE, "Redefining print-time.");
+ } 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_warning(ISC_FALSE,
+ "Redefining print-category.");
+ } 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_warning(ISC_FALSE,
+ "Redefining print-severity.");
+ } 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.");
+ }
+
+ isc_mem_free(memctx, $1);
+ }
+ ;
+
+
+channel_list: channel L_EOS
+ | channel_list channel L_EOS
+ ;
+
+
+category_name: any_string
+ {
+ dns_c_category_t cat;
+
+ tmpres = dns_c_string2category($1, &cat);
+ if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE, "Unknown category ``%s''", $1);
+ YYABORT;
+ }
+
+ isc_mem_free(memctx, $1);
+
+ $$ = cat;
+ }
+ | L_DEFAULT
+ {
+ $$ = dns_c_cat_default;
+ }
+ | L_NOTIFY
+ {
+ $$ = dns_c_cat_notify;
+ }
+ ;
+
+/*
+ * Server Information
+ */
+
+server_stmt: L_SERVER ip_address
+ {
+ dns_c_srv_t *server;
+ dns_c_srv_t *tmpserver;
+ dns_c_srvlist_t *servers = currcfg->servers;
+
+ if (servers == NULL) {
+ tmpres = dns_c_srvlist_new(currcfg->mem,
+ &currcfg->servers);
+ if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE,
+ "Failed to create server list");
+ YYABORT;
+ }
+ servers = currcfg->servers;
+ }
+
+ /*
+ * Check that this IP hasn't already bee used and if it has
+ * remove the old definition.
+ */
+ server = ISC_LIST_HEAD(servers->elements);
+ while (server != NULL) {
+ tmpserver = ISC_LIST_NEXT(server, next);
+ if (memcmp(&server->address, &$2,
+ sizeof(isc_sockaddr_t)) == 0) {
+ parser_error(ISC_TRUE, "Redefining server");
+ ISC_LIST_UNLINK(servers->elements,
+ server, next);
+ dns_c_srv_delete(&server);
+ break;
+ }
+ server = tmpserver;
+ }
+
+ tmpres = dns_c_srv_new(currcfg->mem, $2, &server);
+ if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE,
+ "Failed to create server structure");
+ YYABORT;
+ }
+
+ ISC_LIST_APPEND(currcfg->servers->elements, server, next);
+ }
+ 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_c_srv_t *server;
+ isc_boolean_t tv;
+
+ INSIST(currcfg->servers != NULL);
+ server = ISC_LIST_TAIL(currcfg->servers->elements);
+
+ INSIST(server != NULL);
+
+ tmpres = dns_c_srv_getbogus(server, &tv);
+ if (tmpres != ISC_R_NOTFOUND) {
+ parser_warning(ISC_FALSE,
+ "Redefining server bogus value");
+ }
+
+ dns_c_srv_setbogus(server, $2);
+ }
+ | L_SUPPORT_IXFR yea_or_nay
+ {
+ dns_c_srv_t *server;
+ isc_boolean_t tv;
+
+ INSIST(currcfg->servers != NULL);
+ server = ISC_LIST_TAIL(currcfg->servers->elements);
+
+ INSIST(server != NULL);
+
+ tmpres = dns_c_srv_getsupportixfr(server, &tv);
+ if(tmpres != ISC_R_NOTFOUND) {
+ parser_warning(ISC_FALSE,
+ "Redefining server support-ixfr value");
+ }
+
+ dns_c_srv_setsupportixfr(server, $2);
+ }
+ | L_TRANSFERS L_INTEGER
+ {
+ dns_c_srv_t *server;
+ isc_int32_t tv;
+
+ INSIST(currcfg->servers != NULL);
+ server = ISC_LIST_TAIL(currcfg->servers->elements);
+
+ INSIST(server != NULL);
+
+ tmpres = dns_c_srv_gettransfers(server, &tv);
+ if (tmpres != ISC_R_NOTFOUND) {
+ parser_warning(ISC_FALSE,
+ "Redefining server transfers value");
+ }
+
+ dns_c_srv_settransfers(server, $2);
+ }
+ | L_TRANSFER_FORMAT transfer_format
+ {
+ dns_c_srv_t *server;
+ dns_transfer_format_t tv;
+
+ INSIST(currcfg->servers != NULL);
+ server = ISC_LIST_TAIL(currcfg->servers->elements);
+
+ INSIST(server != NULL);
+
+ tmpres = dns_c_srv_gettransferformat(server, &tv);
+ if (tmpres != ISC_R_NOTFOUND) {
+ parser_warning(ISC_FALSE,
+ "Redefining server transfer-format "
+ "value");
+ }
+
+
+ dns_c_srv_settransferformat(server, $2);
+ }
+ | L_KEYS L_LBRACE {
+ dns_c_srv_t *server;
+
+ INSIST(currcfg->servers != NULL);
+ server = ISC_LIST_TAIL(currcfg->servers->elements);
+ INSIST(server != NULL);
+
+ if (server->keys == NULL) {
+ tmpres = dns_c_kidlist_new(currcfg->mem,
+ &server->keys);
+ if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE,
+ "Failed to create keyid_list");
+ YYABORT;
+ }
+ }
+ } key_list L_RBRACE
+ ;
+
+/*
+ * 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 (!dns_c_ctx_keydefinedp(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);
+ switch (tmpres) {
+ case ISC_R_SUCCESS:
+ break;
+
+ case ISC_R_NOMEMORY:
+ parser_error(ISC_FALSE,
+ "Insufficient memory "
+ "available.");
+ YYABORT;
+ break;
+ }
+ }
+
+ dns_c_ipmatchlist_detach(&$2);
+
+ $$ = ime;
+ }
+ ;
+
+address_name: any_string
+ {
+ dns_c_ipmatchelement_t *elem;
+ dns_c_acl_t *acl;
+
+ 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_ref: any_string
+ ;
+
+key_list_element: key_ref
+ {
+ dns_c_srv_t *currserver;
+ dns_c_kid_t *keyid;
+
+ INSIST(currcfg->servers != NULL);
+ currserver = ISC_LIST_TAIL(currcfg->servers->elements);
+ INSIST(currserver != NULL);
+
+ INSIST(currserver->keys != NULL);
+
+ if (!dns_c_ctx_keydefinedp(currcfg, $1)) {
+ parser_error(ISC_FALSE,
+ "Server keys key_id (%s) "
+ "referenced before defined", $1);
+ YYABORT;
+ } else {
+ tmpres = dns_c_kid_new(currserver->keys, $1, &keyid);
+ if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE,
+ "Failed to create keyid");
+ YYABORT;
+ }
+ }
+
+ isc_mem_free(memctx, $1);
+ }
+ ;
+
+
+/*
+ * The grammer in the man page implies a semicolon is not required before
+ * key_list_elements. We'll support either way.
+ */
+maybe_eos: | L_EOS
+ ;
+
+key_list: key_list_element maybe_eos
+ | key_list key_list_element maybe_eos
+ ;
+
+key_stmt: L_SEC_KEY any_string
+ {
+ dns_c_kdef_t *keydef;
+
+ if (currcfg->keydefs == NULL) {
+ tmpres = dns_c_kdeflist_new(currcfg->mem,
+ &currcfg->keydefs);
+ if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE,
+ "Failed to create keylist");
+ YYABORT;
+ }
+ }
+
+ tmpres = dns_c_kdef_new(currcfg->keydefs,
+ $2, &keydef);
+ if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE,
+ "Failed to create key definition");
+ YYABORT;
+ }
+
+ isc_mem_free(memctx, $2);
+ }
+ L_LBRACE key_definition L_RBRACE
+ ;
+
+key_definition: algorithm_id secret
+ {
+ dns_c_kdef_t *keydef;
+
+ INSIST(currcfg->keydefs != NULL);
+
+ keydef = ISC_LIST_TAIL(currcfg->keydefs->keydefs);
+ INSIST(keydef != NULL);
+
+ dns_c_kdef_setalgorithm(keydef, $1);
+ dns_c_kdef_setsecret(keydef, $2);
+
+ isc_mem_free(memctx, $1);
+ isc_mem_free(memctx, $2);
+ }
+ | secret algorithm_id
+ {
+ dns_c_kdef_t *keydef;
+
+ INSIST(currcfg->keydefs != NULL);
+
+ keydef = ISC_LIST_TAIL(currcfg->keydefs->keydefs);
+ INSIST(keydef != NULL);
+
+ dns_c_kdef_setsecret(keydef, $1);
+ dns_c_kdef_setalgorithm(keydef, $2);
+
+ isc_mem_free(memctx, $1);
+ isc_mem_free(memctx, $2);
+ }
+ ;
+
+algorithm_id: L_ALGID any_string L_EOS
+ {
+ $$ = $2;
+ }
+ ;
+
+secret: L_SECRET any_string L_EOS
+ {
+ $$ = $2;
+ }
+ ;
+
+
+/*
+ * Views
+ */
+
+
+view_stmt: L_VIEW any_string 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, &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_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,
+ ISC_FALSE);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining view allow-query.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set view allow-query.");
+ break;
+ }
+ }
+ | 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_setallowtransfer(view,
+ $3, ISC_FALSE);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining view allow-transfer.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set view allow-transfer.");
+ break;
+ }
+ }
+ | 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_setallowrecursion(view,
+ $3, ISC_FALSE);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining view allow-recursion.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set view allow-recursion.");
+ break;
+ }
+ }
+ | L_BLACKHOLE L_LBRACE address_match_list L_RBRACE
+ {
+ dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg);
+
+ INSIST(view != NULL);
+
+ tmpres = dns_c_view_setblackhole(view,
+ $3, ISC_FALSE);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining view blackhole.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set view blackhole.");
+ break;
+ }
+ }
+ | 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);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining view forwarders.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set view forwarders.");
+ break;
+ }
+ }
+ | 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, ISC_FALSE);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining view sortlist.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set view sortlist.");
+ break;
+ }
+ }
+ | 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, ISC_FALSE);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining view topology.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set view topology.");
+ break;
+ }
+ }
+ | L_LISTEN_ON maybe_port L_LBRACE address_match_list L_RBRACE
+ {
+ dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg);
+
+ INSIST(view != NULL);
+
+ if ($4 == NULL) {
+ parser_warning(ISC_FALSE,
+ "address-match-list empty. "
+ "listen statement ignored.");
+ } else {
+ tmpres = dns_c_view_addlisten_on(view, $2, $4,
+ ISC_FALSE);
+
+ if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE,
+ "Failed to add listen statement");
+ YYABORT;
+ }
+ }
+ }
+/* XXX not implemented yet
+ | L_RRSET_ORDER L_LBRACE rrset_ordering_list L_RBRACE
+ | L_CHECK_NAMES
+ | L_TRANSFER_FORMAT
+*/
+ | zone_stmt;
+ ;
+
+/* XXX other view statements need to go in here???. */
+
+
+/*
+ key
+ trusted-keys
+ server
+ options {
+ forwarders
+ blackhole
+ lame-ttl
+ max-ncache-ttl
+ min-roots
+ cleaning-interval
+ }
+*/
+
+/*
+ * 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;
+ }
+
+ if (currcfg->options != NULL) {
+ zone->afteropts = ISC_TRUE;
+ }
+
+ 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 (callbacks != NULL && callbacks->zonecbk != NULL) {
+ 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;
+
+ if (strcmp($1, "*") == 0) {
+ cl = dns_rdataclass_any;
+ } else {
+ reg.base = $1;
+ reg.length = strlen($1);
+
+ tmpres = dns_rdataclass_fromtext(&cl, &reg);
+ if (tmpres != DNS_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
+ ;
+
+
+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_QUERY |
+ L_ALLOW_TRANSFER | L_FORWARD | L_FORWARDERS | L_MAX_TRANSFER_TIME_IN |
+ L_TCP_CLIENTS | L_RECURSIVE_CLIENTS |
+ 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
+ ;
+
+
+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_warning(ISC_FALSE,
+ "redefining zone filename.");
+ } else if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE,
+ "Failed to set zone file name");
+ }
+ 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_warning(ISC_FALSE,
+ "Redefining ixfr-base.");
+ } else if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE,
+ "Failed to set zone ixfr_base.");
+ }
+ 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_warning(ISC_FALSE,
+ "Redefining ixfr-tmp-file.");
+ } else if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_FALSE,
+ "Failed to set zone ixfr_tmp-file.");
+ }
+ isc_mem_free(memctx, $2);
+ }
+ | L_MASTERS maybe_zero_port L_LBRACE master_in_addr_list L_RBRACE
+ {
+ dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg);
+
+ INSIST(zone != NULL);
+
+ tmpres = dns_c_zone_setmasterport(zone, $2);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining zone master's port.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set zone master port.");
+ break;
+ }
+
+ tmpres = dns_c_zone_setmasterips(zone,
+ $4, ISC_FALSE);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining zone masters ips.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set zone masters ips.");
+ break;
+ }
+ }
+ | L_TRANSFER_SOURCE maybe_wild_addr
+ {
+ dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg);
+
+ INSIST(zone != NULL);
+
+ tmpres = dns_c_zone_settransfersource(zone, $2);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining zone transfer-source.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set zone transfer-source.");
+ break;
+ }
+ }
+ | 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);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining zone check-names.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set zone check-names.");
+ break;
+ }
+ }
+ | 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);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining zone allow-update.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set zone allow-update.");
+ break;
+ }
+ }
+ | 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);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining zone allow-query.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set zone allow-query.");
+ break;
+ }
+ }
+ | 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);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining zone allow-transfer.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set zone allow-transfer.");
+ break;
+ }
+ }
+ | 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);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining zone forward.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set zone forward.");
+ break;
+ }
+ }
+ | 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);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining zone forwarders.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set zone forwarders.");
+ dns_c_iplist_detach(&$3);
+ break;
+ }
+ }
+ | 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);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining zone "
+ "max-transfer-time-in.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set zone "
+ "max-transfer-time-in.");
+ break;
+ }
+ }
+ | 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);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining zone "
+ "max-transfer-time-out.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set zone "
+ "max-transfer-time-out.");
+ break;
+ }
+ }
+ | 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);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining zone "
+ "max-transfer-idle-in.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set zone "
+ "max-transfer-idle-in.");
+ break;
+ }
+ }
+ | 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);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining zone "
+ "max-transfer-idle-out.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set zone "
+ "max-transfer-idle-out.");
+ break;
+ }
+ }
+ | 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);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining zone max-ixfr-log-size.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set zone max-ixfr-log-size.");
+ break;
+ }
+ }
+ | L_NOTIFY yea_or_nay
+ {
+ dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg);
+
+ INSIST(zone != NULL);
+
+ tmpres = dns_c_zone_setnotify(zone, $2);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining zone notify.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set zone notify.");
+ break;
+ }
+ }
+ | 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);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining zone maintain-ixfr-base.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set zone maintain-ixfr-base.");
+ break;
+ }
+ }
+ | 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);
+ switch (tmpres) {
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ dns_c_pubkey_delete(&pubkey);
+ parser_error(ISC_FALSE,
+ "Failed to add a zone pubkey.");
+ break;
+ }
+
+ isc_mem_free(memctx, $5);
+ }
+ | L_ALSO_NOTIFY L_LBRACE notify_in_addr_list L_RBRACE
+ {
+ dns_c_zone_t *zone = dns_c_ctx_getcurrzone(currcfg);
+
+ INSIST(zone != NULL);
+
+ tmpres = dns_c_zone_setalsonotify(zone, $3,
+ ISC_FALSE);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining zone also-notify.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set zone also-notify.");
+ break;
+ }
+ }
+ | 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);
+ switch (tmpres) {
+ case ISC_R_EXISTS:
+ parser_warning(ISC_FALSE,
+ "Redefining zone dialup.");
+ break;
+
+ case ISC_R_SUCCESS:
+ /* nothing */
+ break;
+
+ default:
+ parser_error(ISC_FALSE,
+ "Failed to set zone dialup.");
+ break;
+ }
+ }
+ ;
+
+
+master_in_addr_list: in_addr_list
+ ;
+
+notify_in_addr_list: opt_in_addr_list
+ ;
+
+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;
+ }
+
+ tmpres = dns_c_iplist_append(list, $1);
+ if (tmpres != ISC_R_SUCCESS) {
+ parser_error(ISC_TRUE,
+ "Failed to append master address");
+ YYABORT;
+ }
+
+ $$ = list;
+ }
+ | in_addr_list in_addr_elem L_EOS
+ {
+ tmpres = dns_c_iplist_append($1, $2);
+ 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;
+
+ tmpres = dns_c_ctx_gettrustedkeys(currcfg,
+ &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;
+ }
+
+ tmpres = dns_c_ctx_settrustedkeys(currcfg,
+ 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: domain_name L_INTEGER L_INTEGER L_INTEGER L_QSTRING
+ {
+ dns_c_tkey_t *tkey;
+ dns_c_tkeylist_t *list;
+
+ tmpres = dns_c_ctx_gettrustedkeys(currcfg, &list);
+ 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(currcfg->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
+ ;
+
+%%
+
+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 int yylex(void);
+int yyparse(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
+{
+ char *token;
+ int yaccval;
+};
+
+static struct token keyword_tokens [] = {
+ { "{", L_LBRACE },
+ { "}", L_RBRACE },
+ { ";", L_EOS },
+ { "/", L_SLASH },
+ { "!", L_BANG },
+
+ { "acl", L_ACL },
+ { "address", L_ADDRESS },
+ { "algorithm", L_ALGID },
+ { "allow", L_ALLOW },
+ { "allow-query", L_ALLOW_QUERY },
+ { "allow-transfer", L_ALLOW_TRANSFER },
+ { "allow-recursion", L_ALLOW_RECURSION },
+ { "allow-update", L_ALLOW_UPDATE },
+ { "also-notify", L_ALSO_NOTIFY },
+ { "auth-nxdomain", L_AUTH_NXDOMAIN },
+ { "blackhole", L_BLACKHOLE },
+ { "bogus", L_BOGUS },
+ { "category", L_CATEGORY },
+ { "class", L_CLASS },
+ { "channel", L_CHANNEL },
+ { "check-names", L_CHECK_NAMES },
+ { "cleaning-interval", L_CLEAN_INTERVAL },
+ { "controls", L_CONTROLS },
+ { "coresize", L_CORESIZE },
+ { "datasize", L_DATASIZE },
+ { "deallocate-on-exit", L_DEALLOC_ON_EXIT },
+ { "debug", L_DEBUG },
+ { "default", L_DEFAULT },
+ { "dialup", L_DIALUP },
+ { "directory", L_DIRECTORY },
+ { "dump-file", L_DUMP_FILE },
+ { "dynamic", L_DYNAMIC },
+ { "expert-mode", L_EXPERT_MODE },
+ { "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 },
+ { "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 },
+ { "ixfr-base", L_FILE_IXFR },
+ { "ixfr-tmp-file", L_IXFR_TMP },
+ { "key", L_SEC_KEY },
+ { "keys", L_KEYS },
+ { "listen-on", L_LISTEN_ON },
+ { "logging", L_LOGGING },
+ { "maintain-ixfr-base", L_MAINTAIN_IXFR_BASE },
+ { "many-answers", L_MANY_ANSWERS },
+ { "master", L_MASTER },
+ { "masters", L_MASTERS },
+ { "max-ixfr-log-size", L_MAX_LOG_SIZE_IXFR },
+ { "max-ncache-ttl", L_MAX_NCACHE_TTL },
+ { "max-transfer-time-in", L_MAX_TRANSFER_TIME_IN },
+ { "max-transfer-time-out", L_MAX_TRANSFER_TIME_OUT },
+ { "max-transfer-idle-in", L_MAX_TRANSFER_IDLE_IN },
+ { "max-transfer-idle-out", L_MAX_TRANSFER_IDLE_OUT },
+ { "memstatistics-file", L_MEMSTATS_FILE },
+ { "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 },
+ { "order", L_ORDER },
+ { "options", L_OPTIONS },
+ { "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 },
+ { "pubkey", L_PUBKEY },
+ { "query-source", L_QUERY_SOURCE },
+ { "rfc2308-type1", L_RFC2308_TYPE1 },
+ { "rrset-order", L_RRSET_ORDER },
+ { "recursion", L_RECURSION },
+ { "recursive-clients", L_RECURSIVE_CLIENTS },
+ { "response", L_RESPONSE },
+ { "secret", L_SECRET },
+ { "server", L_SERVER },
+ { "severity", L_SEVERITY },
+ { "size", L_SIZE },
+ { "slave", L_SLAVE },
+ { "sortlist", L_SORTLIST },
+ { "stacksize", L_STACKSIZE },
+ { "statistics-file", L_STATS_FILE },
+ { "statistics-interval", L_STATS_INTERVAL },
+ { "stub", L_STUB },
+ { "support-ixfr", L_SUPPORT_IXFR },
+ { "syslog", L_SYSLOG },
+ { "tcp-clients", L_TCP_CLIENTS },
+ { "tkey-domain", L_TKEY_DOMAIN },
+ { "tkey-dhkey", L_TKEY_DHKEY },
+ { "topology", L_TOPOLOGY },
+ { "transfer-format", L_TRANSFER_FORMAT },
+ { "transfer-source", L_TRANSFER_SOURCE },
+ { "transfers", L_TRANSFERS },
+ { "transfers-in", L_TRANSFERS_IN },
+ { "transfers-out", L_TRANSFERS_OUT },
+ { "transfers-per-ns", L_TRANSFERS_PER_NS },
+ { "true", L_TRUE },
+ { "trusted-keys", L_TRUSTED_KEYS },
+ { "type", L_TYPE },
+ { "unix", L_UNIX },
+ { "unlimited", L_UNLIMITED },
+ { "use-id-pool", L_USE_ID_POOL },
+ { "use-ixfr", L_USE_IXFR },
+ { "version", L_VERSION },
+ { "versions", L_VERSIONS },
+ { "view", L_VIEW },
+ { "warn", L_WARN },
+ { "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(strlen(filename) > 0);
+ REQUIRE(configctx != NULL);
+ INSIST(mylexer == NULL);
+ INSIST(memctx == NULL);
+ INSIST(keywords == NULL);
+ INSIST(callbacks == NULL);
+
+#if 0
+ if (getenv("DEBUG_LEXER") != NULL) { /* XXX debug */
+ debug_lexer++;
+ }
+#endif
+
+ specials['{'] = 1;
+ specials['}'] = 1;
+ specials[';'] = 1;
+ specials['/'] = 1;
+ specials['"'] = 1;
+ specials['!'] = 1;
+#if 0
+ specials['*'] = 1;
+#endif
+
+
+ /*
+ * 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_ERROR,
+ "%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_ERROR,
+ "%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_ERROR,
+ "%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_ERROR,
+ "%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, (char *)filename) ; /* remove const */
+ if (res != ISC_R_SUCCESS) {
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_ERROR,
+ "%s: Error opening file %s.",
+ funcname, filename);
+ 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_destroy_check(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_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: %d: unbalanced parentheses",
+ isc_lex_getsourcename(mylexer),
+ (int)isc_lex_getsourceline(mylexer));
+ res = -1;
+ break;
+
+ case ISC_R_NOSPACE:
+ parser_error(ISC_TRUE,
+ "%s: %d: token too big.",
+ isc_lex_getsourcename(mylexer),
+ (int)isc_lex_getsourceline(mylexer));
+ res = -1;
+ break;
+
+ case ISC_R_UNEXPECTEDEND:
+ parser_error(ISC_TRUE,
+ "%s: %d: unexpected EOF",
+ isc_lex_getsourcename(mylexer),
+ (int)isc_lex_getsourceline(mylexer));
+ res = -1;
+ break;
+
+ default:
+ parser_error(ISC_TRUE,
+ "%s: %d unknown lexer error (%d)",
+ isc_lex_getsourcename(mylexer),
+ (int)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];
+ int i;
+
+ /* Yacc keeps token numbers above 128, it seems. */
+ if (token < 128) {
+ if (token == 0)
+ strncpy(buffer, "<end of file>", 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, "<end of include>");
+ break;
+ default:
+ for (i = 0 ; keyword_tokens[i].token != NULL ; i++) {
+ if (keyword_tokens[i].yaccval == token)
+ break;
+ }
+
+ if (keyword_tokens[i].token == NULL) {
+ sprintf(buffer, "UNKNOWN-TOKEN-TYPE (%d)",
+ (int)token);
+ } else {
+ strncpy(buffer, keyword_tokens[i].token,
+ sizeof buffer - 1);
+ buffer[sizeof buffer - 1] = '\0';
+ }
+ break;
+ }
+ }
+
+ return (buffer);
+}
+
+
+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);
+ int 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:%d: ", 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:
+ if (debug_lexer) {
+ fprintf(stderr, "unknown lexer token\n");
+ }
+
+ 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;
+ }
+
+ if (debug_lexer) {
+ fprintf(stderr, "lexer token: %s : %s\n",
+ (token->type == isc_tokentype_special ?
+ "special" : "string"), tokstring);
+ }
+
+ 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;
+
+ if(debug_lexer) {
+ fprintf(stderr, "lexer token: number : %lu\n",
+ (unsigned long)yylval.ul_int);
+ }
+
+ 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;
+ }
+
+ if (debug_lexer) {
+ fprintf(stderr, "lexer token: qstring : \"%s\"\n",
+ yylval.text);
+ }
+
+ 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
+ */
+ if (debug_lexer) {
+ fprintf(stderr, "lexer token: EOF\n");
+ }
+ res = 0;
+ } else {
+ if (debug_lexer) {
+ fprintf(stderr, "lexer token: EOF (main)\n");
+ }
+ res = L_END_INCLUDE;
+ }
+ break;
+
+ case isc_tokentype_initialws:
+ if (debug_lexer) {
+ fprintf(stderr, "lexer token: initial ws\n");
+ }
+ res = -1;
+ break;
+
+ case isc_tokentype_eol:
+ if (debug_lexer) {
+ fprintf(stderr, "lexer token: eol\n");
+ }
+ res = -1;
+ break;
+
+ case isc_tokentype_nomore:
+ if (debug_lexer) {
+ fprintf(stderr, "lexer token: nomore\n");
+ }
+ 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_boolean_t
+unit_to_uint32(char *in, isc_uint32_t *out) {
+ int c, units_done = 0;
+ isc_uint32_t result = 0L;
+
+ INSIST(in != NULL);
+
+ for (; (c = *in) != '\0'; in++) {
+ if (units_done)
+ return (ISC_FALSE);
+ if (isdigit(c)) {
+ result *= 10;
+ result += (c - '0');
+ } else {
+ switch (c) {
+ case 'k':
+ case 'K':
+ result *= 1024;
+ units_done = 1;
+ break;
+ case 'm':
+ case 'M':
+ result *= (1024*1024);
+ units_done = 1;
+ break;
+ case 'g':
+ case 'G':
+ result *= (1024*1024*1024);
+ units_done = 1;
+ break;
+ default:
+ return (ISC_FALSE);
+ }
+ }
+ }
+
+ *out = result;
+ return (ISC_TRUE);
+}
+
+
+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;
+}
diff --git a/lib/dns/config/confpvt.h b/lib/dns/config/confpvt.h
new file mode 100644
index 00000000..402054d2
--- /dev/null
+++ b/lib/dns/config/confpvt.h
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+#ifndef DNS_CONFIG_CONFPVT_H
+#define DNS_CONFIG_CONFPVT_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*
+ * Some private definitions for config module internal use.
+ */
+
+/*
+ * Various structures keep track of whether fields have been assigned
+ * to. They do this with a bit field.
+ */
+#define DNS_C_SETBITS_SIZE (sizeof(dns_c_setbits_t) * 8)
+#define DNS_C_SETBIT(bit, flags) \
+ (*(flags) |= ((dns_c_setbits_t)1 << (bit)))
+#define DNS_C_CLEARBIT(bit, flags) \
+ (*(flags) &= ~((dns_c_setbits_t)1 << (bit)))
+#define DNS_C_CHECKBIT(bit,flags) \
+ ISC_TF((*(flags) & ((dns_c_setbits_t)1 << (bit))) == ((dns_c_setbits_t)1 << (bit)))
+
+#endif
diff --git a/lib/dns/config/confresolv.c b/lib/dns/config/confresolv.c
new file mode 100644
index 00000000..fff0609d
--- /dev/null
+++ b/lib/dns/config/confresolv.c
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+#include <config.h>
+
+#include <dns/confresolv.h>
+#include <dns/result.h>
+
+
+#include "confpvt.h"
+
+isc_result_t
+dns_c_resolv_new(isc_mem_t *mem, dns_c_resolv_t **cfgres)
+{
+ (void) mem; (void) cfgres;
+
+ /* XXX nothing yet */
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_resolv_delete(dns_c_resolv_t **cfgres)
+{
+ (void) cfgres;
+ /* XXX nothin yet */
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
diff --git a/lib/dns/config/confrrset.c b/lib/dns/config/confrrset.c
new file mode 100644
index 00000000..3291c08b
--- /dev/null
+++ b/lib/dns/config/confrrset.c
@@ -0,0 +1,300 @@
+/*
+ * 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.
+ */
+
+#include <config.h>
+
+#include <isc/assertions.h>
+#include <isc/magic.h>
+
+#include <dns/confrrset.h>
+#include <dns/confcommon.h>
+
+
+isc_result_t
+dns_c_rrsolist_clear(dns_c_rrsolist_t *olist)
+{
+ dns_c_rrso_t *elem;
+
+ REQUIRE(DNS_C_RRSOLIST_VALID(olist));
+
+ elem = ISC_LIST_HEAD(olist->elements);
+ while (elem != NULL) {
+ ISC_LIST_UNLINK(olist->elements, elem, next);
+ dns_c_rrso_delete(&elem);
+ elem = ISC_LIST_HEAD(olist->elements);
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_rrsolist_append(dns_c_rrsolist_t *dest,
+ dns_c_rrsolist_t *src)
+{
+ dns_c_rrso_t *oldelem;
+ dns_c_rrso_t *newelem;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_RRSOLIST_VALID(dest));
+ REQUIRE(DNS_C_RRSOLIST_VALID(src));
+
+ oldelem = ISC_LIST_HEAD(src->elements);
+ while (oldelem != NULL) {
+ res = dns_c_rrso_copy(dest->mem, &newelem, oldelem);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ ISC_LIST_APPEND(dest->elements, newelem, next);
+ oldelem = ISC_LIST_NEXT(oldelem, next);
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_rrsolist_new(isc_mem_t *mem, dns_c_rrsolist_t **rval)
+{
+ dns_c_rrsolist_t *ro;
+
+ ro = isc_mem_get(mem, sizeof *ro);
+ if (ro == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ ISC_LIST_INIT(ro->elements);
+ ro->mem = mem;
+ ro->magic = DNS_C_RRSOLIST_MAGIC;
+
+ *rval = ro;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_rrso_new(isc_mem_t *mem, dns_c_rrso_t **res,
+ dns_rdataclass_t oclass,
+ dns_rdatatype_t otype, char *name, dns_c_ordering_t ordering)
+{
+ dns_c_rrso_t *newo;
+
+ REQUIRE(mem != NULL);
+ REQUIRE(res != NULL);
+
+ if (name == NULL) {
+ name = "*";
+ }
+
+ newo = isc_mem_get(mem, sizeof *newo);
+ if (newo == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ newo->magic = DNS_C_RRSO_MAGIC;
+ newo->mem = mem;
+ newo->otype = otype;
+ newo->oclass = oclass;
+ newo->ordering = ordering;
+ ISC_LINK_INIT(newo, next);
+
+ newo->name = isc_mem_strdup(mem, name);
+ if (newo->name == NULL) {
+ newo->magic = 0;
+ isc_mem_put(mem, newo, sizeof *newo);
+ return (ISC_R_NOMEMORY);
+ }
+
+ *res = newo;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_rrsolist_delete(dns_c_rrsolist_t **list)
+{
+ dns_c_rrso_t *elem, *q;
+ dns_c_rrsolist_t *l;
+ isc_result_t r;
+
+ REQUIRE(list != NULL);
+ REQUIRE(DNS_C_RRSOLIST_VALID(*list));
+
+ l = *list;
+
+ elem = ISC_LIST_HEAD(l->elements);
+ while (elem != NULL) {
+ q = ISC_LIST_NEXT(elem, next);
+ ISC_LIST_UNLINK(l->elements, elem, next);
+ r = dns_c_rrso_delete(&elem);
+ if (r != ISC_R_SUCCESS) {
+ return (r);
+ }
+
+ elem = q;
+ }
+
+ l->magic = 0;
+ isc_mem_put(l->mem, l, sizeof *l);
+
+ *list = NULL;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_rrso_delete(dns_c_rrso_t **order)
+{
+ dns_c_rrso_t *oldo;
+
+ REQUIRE(order != NULL);
+ REQUIRE(DNS_C_RRSO_VALID(*order));
+
+ oldo = *order;
+
+ REQUIRE(oldo->name != NULL);
+ isc_mem_free(oldo->mem, oldo->name);
+
+ oldo->magic = 0;
+ isc_mem_put(oldo->mem, oldo, sizeof *oldo);
+
+ *order = NULL;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_rrso_copy(isc_mem_t *mem, dns_c_rrso_t **dest,
+ dns_c_rrso_t *source)
+{
+ dns_c_rrso_t *newo;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_RRSO_VALID(*dest));
+ REQUIRE(DNS_C_RRSO_VALID(source));
+
+ res = dns_c_rrso_new(mem, &newo, source->oclass,
+ source->otype, source->name,
+ source->ordering);
+ if (res == ISC_R_SUCCESS) {
+ *dest = newo;
+ } else {
+ *dest = NULL;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_rrsolist_copy(isc_mem_t *mem, dns_c_rrsolist_t **dest,
+ dns_c_rrsolist_t *source)
+
+{
+ dns_c_rrsolist_t *nlist;
+ dns_c_rrso_t *elem;
+ dns_c_rrso_t *newe;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_RRSOLIST_VALID(source));
+ REQUIRE(dest != NULL);
+
+ res = dns_c_rrsolist_new(mem, &nlist);
+ if (res != DNS_R_SUCCESS) {
+ return (res);
+ }
+
+ elem = ISC_LIST_HEAD(source->elements);
+ while (elem != NULL) {
+ res = dns_c_rrso_copy(mem, &newe, elem);
+ if (res != DNS_R_SUCCESS) {
+ dns_c_rrsolist_delete(&nlist);
+ return (res);
+ }
+
+ ISC_LIST_APPEND(nlist->elements, newe, next);
+
+ elem = ISC_LIST_NEXT(elem, next);
+ }
+
+ *dest = nlist;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+void
+dns_c_rrsolist_print(FILE *fp, int indent,
+ dns_c_rrsolist_t *rrlist)
+{
+ dns_c_rrso_t *or;
+
+ REQUIRE(DNS_C_RRSOLIST_VALID(rrlist));
+
+ if (ISC_LIST_EMPTY(rrlist->elements)) {
+ return;
+ }
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "rrset-order {\n");
+
+ or = ISC_LIST_HEAD(rrlist->elements);
+ while (or != NULL) {
+ dns_c_rrso_print(fp, indent + 1, or);
+ or = ISC_LIST_NEXT(or, next);
+ }
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "};\n");
+
+}
+
+
+void
+dns_c_rrso_print(FILE *fp, int indent, dns_c_rrso_t *order)
+{
+ REQUIRE(DNS_C_RRSO_VALID(order));
+
+ dns_c_printtabs(fp, indent);
+
+ fputs("class ", fp);
+ if (order->oclass == dns_rdataclass_any) {
+ fputc('*', fp);
+ } else {
+ dns_c_dataclass_tostream(fp, order->oclass);
+ }
+
+
+ fputs(" type ", fp);
+ if (order->otype == dns_rdatatype_any) {
+ fputc('*', fp);
+ } else {
+ dns_c_datatype_tostream(fp, order->otype);
+ }
+
+ fprintf(fp, " name %s", order->name);
+
+ fprintf(fp, " order %s",
+ dns_c_ordering2string(order->ordering, ISC_TRUE));
+
+ fputs(";\n", fp);
+}
diff --git a/lib/dns/config/confserv.c b/lib/dns/config/confserv.c
new file mode 100644
index 00000000..5181ffa6
--- /dev/null
+++ b/lib/dns/config/confserv.c
@@ -0,0 +1,414 @@
+/*
+ * 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.
+ */
+
+#include <config.h>
+
+#include <sys/types.h> /* XXXRTH */
+
+#include <string.h>
+
+#include <isc/assertions.h>
+#include <isc/magic.h>
+#include <isc/net.h>
+
+#include <dns/confserv.h>
+#include <dns/confcommon.h>
+#include "confpvt.h"
+
+
+/*
+ * Bit positions in the dns_c_srv_t structure flags field
+ */
+#define BOGUS_BIT 0
+#define SERVER_TRANSFER_FORMAT_BIT 1
+#define TRANSFERS_BIT 2
+#define SUPPORT_IXFR_BIT 3
+
+isc_result_t
+dns_c_srvlist_new(isc_mem_t *mem, dns_c_srvlist_t **list)
+{
+ dns_c_srvlist_t *l;
+
+ REQUIRE(list != NULL);
+
+ l = isc_mem_get(mem, sizeof *l);
+ if (l == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ ISC_LIST_INIT(l->elements);
+ l->mem = mem;
+ l->magic = DNS_C_SRVLIST_MAGIC;
+
+ *list = l;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_srvlist_delete(dns_c_srvlist_t **list)
+{
+ dns_c_srvlist_t *l;
+ dns_c_srv_t *server, *stmp;
+ isc_result_t r;
+
+ REQUIRE(list != NULL);
+ REQUIRE(DNS_C_SRVLIST_VALID(*list));
+
+ l = *list;
+
+ server = ISC_LIST_HEAD(l->elements);
+ while (server != NULL) {
+ stmp = ISC_LIST_NEXT(server, next);
+ ISC_LIST_UNLINK(l->elements, server, next);
+ r = dns_c_srv_delete(&server);
+ if (r != ISC_R_SUCCESS) {
+ return (r);
+ }
+
+ server = stmp;
+ }
+
+ l->magic = 0;
+ isc_mem_put(l->mem, l, sizeof *l);
+
+ *list = NULL;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+void
+dns_c_srvlist_print(FILE *fp, int indent,
+ dns_c_srvlist_t *servers)
+{
+ dns_c_srv_t *server;
+
+ REQUIRE(fp != NULL);
+ REQUIRE(DNS_C_SRVLIST_VALID(servers));
+
+ server = ISC_LIST_HEAD(servers->elements);
+ while (server != NULL) {
+ dns_c_srv_print(fp, indent, server);
+ server = ISC_LIST_NEXT(server, next);
+ if (server != NULL) {
+ fprintf(fp, "\n");
+ }
+ }
+
+ return;
+}
+
+
+isc_result_t
+dns_c_srvlist_servbyaddr(dns_c_srvlist_t *servers,
+ isc_sockaddr_t addr, dns_c_srv_t **retval)
+{
+ dns_c_srv_t *server;
+ isc_result_t res;
+
+ REQUIRE(retval != NULL);
+ REQUIRE(DNS_C_SRVLIST_VALID(servers));
+
+ server = ISC_LIST_HEAD(servers->elements);
+ while (server != NULL) {
+ if (isc_sockaddr_eqaddr(&addr, &server->address)) {
+ break;
+ }
+
+ server = ISC_LIST_NEXT(server, next);
+ }
+
+ if (server != NULL) {
+ *retval = server;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+
+
+isc_result_t
+dns_c_srv_new(isc_mem_t *mem, isc_sockaddr_t addr,
+ dns_c_srv_t **server)
+{
+ dns_c_srv_t *serv;
+
+ REQUIRE(server != NULL);
+
+ serv = isc_mem_get(mem, sizeof *serv);
+ if (serv == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ serv->magic = DNS_C_SRV_MAGIC;
+ serv->address = addr;
+ serv->mem = mem;
+ serv->bogus = ISC_FALSE;
+ serv->transfer_format = dns_one_answer;
+ serv->transfers = 0;
+ serv->support_ixfr = ISC_FALSE;
+ serv->keys = NULL;
+
+ memset(&serv->bitflags, 0x0, sizeof serv->bitflags);
+
+ ISC_LINK_INIT(serv, next);
+
+ *server = serv;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_srv_delete(dns_c_srv_t **server)
+{
+ dns_c_srv_t *serv;
+ isc_mem_t *mem;
+
+ REQUIRE(server != NULL);
+ REQUIRE(DNS_C_SRV_VALID(*server));
+
+ serv = *server;
+
+ mem = serv->mem;
+ serv->mem = NULL;
+ serv->magic = 0;
+
+ if (serv->keys != NULL)
+ dns_c_kidlist_delete(&serv->keys);
+
+ isc_mem_put(mem, serv, sizeof *serv);
+
+ *server = NULL;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+void
+dns_c_srv_print(FILE *fp, int indent, dns_c_srv_t *server)
+{
+ REQUIRE(DNS_C_SRV_VALID(server));
+ REQUIRE(fp != NULL);
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "server ");
+ dns_c_print_ipaddr(fp, &server->address);
+ fprintf(fp, " {\n");
+
+ if (DNS_C_CHECKBIT(BOGUS_BIT, &server->bitflags)) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "bogus %s;\n",
+ (server->bogus ? "true" : "false"));
+ }
+
+ if (DNS_C_CHECKBIT(SERVER_TRANSFER_FORMAT_BIT, &server->bitflags)) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "transfer-format %s;\n",
+ dns_c_transformat2string(server->transfer_format,
+ ISC_TRUE));
+ }
+
+ if (DNS_C_CHECKBIT(TRANSFERS_BIT, &server->bitflags)) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "transfers %d;\n", server->transfers);
+ }
+
+ if (DNS_C_CHECKBIT(SUPPORT_IXFR_BIT,&server->bitflags)) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "support-ixfr %s;\n",
+ (server->support_ixfr ? "true" : "false"));
+ }
+
+ if (server->keys != NULL) {
+ dns_c_kidlist_print(fp, indent + 1, server->keys);
+ }
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "};\n");
+}
+
+
+isc_result_t
+dns_c_srv_setbogus(dns_c_srv_t *server, isc_boolean_t newval)
+{
+ isc_boolean_t existed;
+
+ REQUIRE(DNS_C_SRV_VALID(server));
+
+ existed = DNS_C_CHECKBIT(BOGUS_BIT, &server->bitflags);
+
+ server->bogus = newval;
+ DNS_C_SETBIT(BOGUS_BIT, &server->bitflags);
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_srv_getbogus(dns_c_srv_t *server,
+ isc_boolean_t *retval)
+{
+ REQUIRE(DNS_C_SRV_VALID(server));
+ REQUIRE(retval != NULL);
+
+ if (DNS_C_CHECKBIT(BOGUS_BIT, &server->bitflags)) {
+ *retval = server->bogus;
+ return (ISC_R_SUCCESS);
+ } else {
+ return (ISC_R_NOTFOUND);
+ }
+}
+
+
+isc_result_t
+dns_c_srv_setsupportixfr(dns_c_srv_t *server,
+ isc_boolean_t newval)
+{
+ isc_boolean_t existed;
+
+ REQUIRE(DNS_C_SRV_VALID(server));
+
+ existed = DNS_C_CHECKBIT(SUPPORT_IXFR_BIT, &server->bitflags);
+
+ server->support_ixfr = newval;
+ DNS_C_SETBIT(SUPPORT_IXFR_BIT, &server->bitflags);
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_srv_getsupportixfr(dns_c_srv_t *server,
+ isc_boolean_t *retval)
+{
+ REQUIRE(DNS_C_SRV_VALID(server));
+ REQUIRE(retval != NULL);
+
+ if (DNS_C_CHECKBIT(SUPPORT_IXFR_BIT, &server->bitflags)) {
+ *retval = server->support_ixfr;
+ return (ISC_R_SUCCESS);
+ } else {
+ return (ISC_R_NOTFOUND);
+ }
+}
+
+
+isc_result_t
+dns_c_srv_settransfers(dns_c_srv_t *server,
+ isc_int32_t newval)
+{
+ isc_boolean_t existed;
+
+ REQUIRE(DNS_C_SRV_VALID(server));
+
+ existed = DNS_C_CHECKBIT(TRANSFERS_BIT, &server->bitflags);
+
+ server->transfers = newval;
+ DNS_C_SETBIT(TRANSFERS_BIT, &server->bitflags);
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_srv_gettransfers(dns_c_srv_t *server,
+ isc_int32_t *retval)
+{
+ REQUIRE(DNS_C_SRV_VALID(server));
+ REQUIRE(retval != NULL);
+
+ if (DNS_C_CHECKBIT(TRANSFERS_BIT, &server->bitflags)) {
+ *retval = server->transfers;
+ return (ISC_R_SUCCESS);
+ } else {
+ return (ISC_R_NOTFOUND);
+ }
+}
+
+
+isc_result_t
+dns_c_srv_settransferformat(dns_c_srv_t *server,
+ dns_transfer_format_t newval)
+{
+ isc_boolean_t existed;
+
+ REQUIRE(DNS_C_SRV_VALID(server));
+
+ existed = DNS_C_CHECKBIT(SERVER_TRANSFER_FORMAT_BIT,
+ &server->bitflags);
+
+ server->transfer_format = newval;
+ DNS_C_SETBIT(SERVER_TRANSFER_FORMAT_BIT, &server->bitflags);
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_srv_gettransferformat(dns_c_srv_t *server,
+ dns_transfer_format_t *retval)
+{
+ REQUIRE(DNS_C_SRV_VALID(server));
+ REQUIRE(retval != NULL);
+
+ if (DNS_C_CHECKBIT(SERVER_TRANSFER_FORMAT_BIT, &server->bitflags)) {
+ *retval = server->transfer_format;
+ return (ISC_R_SUCCESS);
+ } else {
+ return (ISC_R_NOTFOUND);
+ }
+}
+
+
+isc_result_t
+dns_c_srv_getkeys(dns_c_srv_t *server, dns_c_kidlist_t **retval)
+{
+ REQUIRE(DNS_C_SRV_VALID(server));
+ REQUIRE(retval != NULL);
+
+ *retval = server->keys;
+
+ return (server->keys == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_srv_setkeys(dns_c_srv_t *server, dns_c_kidlist_t *newval)
+{
+ isc_boolean_t existed = ISC_FALSE;
+
+ REQUIRE(DNS_C_SRV_VALID(server));
+ REQUIRE(DNS_C_KEYIDLIST_VALID(newval));
+
+ if (server->keys != NULL) {
+ dns_c_kidlist_delete(&server->keys);
+ existed = ISC_TRUE;
+ }
+
+ server->keys = newval;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
diff --git a/lib/dns/config/confview.c b/lib/dns/config/confview.c
new file mode 100644
index 00000000..1afdf671
--- /dev/null
+++ b/lib/dns/config/confview.c
@@ -0,0 +1,1056 @@
+/*
+ * 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.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#include <isc/assertions.h>
+#include <isc/magic.h>
+#include <isc/net.h>
+
+#include <dns/confacl.h>
+#include <dns/confzone.h>
+#include <dns/confcommon.h>
+#include <dns/confview.h>
+#include <dns/confzone.h>
+#include <dns/log.h>
+
+#include "confpvt.h"
+
+#define CHECKNAME_PRIM_BIT 1
+#define CHECKNAME_SEC_BIT 2
+#define CHECKNAME_RESP_BIT 3
+#define MULTIPLE_CNAMES_BIT 4
+#define DIALUP_BIT 5
+#define FETCH_GLUE_BIT 6
+#define HAS_OLD_CLIENTS_BIT 7
+#define HOST_STATISTICS_BIT 8
+#define MAINTAIN_IXFR_BASE_BIT 9
+#define NOTIFY_BIT 11
+#define RECURSION_BIT 12
+#define RFC2308_TYPE1_BIT 13
+#define USE_ID_POOL_BIT 14
+#define FAKE_IQUERY_BIT 15
+#define USE_IXFR_BIT 16
+#define TCP_CLIENTS_BIT 17
+#define RECURSIVE_CLIENTS_BIT 18
+#define CLEAN_INTERVAL_BIT 19
+#define MAX_LOG_SIZE_IXFR_BIT 20
+#define MAX_NCACHE_TTL_BIT 21
+#define MAX_TRANSFER_TIME_IN_BIT 22
+#define MAX_TRANSFER_TIME_OUT_BIT 23
+#define MAX_TRANSFER_IDLE_IN_BIT 24
+#define MAX_TRANSFER_IDLE_OUT_BIT 25
+#define STATS_INTERVAL_BIT 26
+#define TRANSFERS_IN_BIT 27
+#define TRANSFERS_OUT_BIT 28
+#define TRANSFERS_PER_NS_BIT 29
+#define TRANSFER_FORMAT_BIT 30
+
+isc_result_t
+dns_c_viewtable_new(isc_mem_t *mem, dns_c_viewtable_t **viewtable)
+{
+ dns_c_viewtable_t *table;
+
+ REQUIRE(viewtable != NULL);
+
+ table = isc_mem_get(mem, sizeof *table);
+ if (table == NULL) {
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Out of memory");
+ return (ISC_R_NOMEMORY);
+ }
+
+ table->magic = DNS_C_VIEWTABLE_MAGIC;
+ table->mem = mem;
+
+ ISC_LIST_INIT(table->views);
+
+ *viewtable = table;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_viewtable_delete(dns_c_viewtable_t **viewtable)
+{
+ dns_c_viewtable_t *table;
+
+ REQUIRE(viewtable != NULL);
+ REQUIRE(DNS_C_VIEWTABLE_VALID(*viewtable));
+
+ table = *viewtable;
+ *viewtable = NULL;
+
+ dns_c_viewtable_clear(table);
+
+ table->magic = 0;
+ isc_mem_put(table->mem, table, sizeof *table);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+void
+dns_c_viewtable_addview(dns_c_viewtable_t *viewtable, dns_c_view_t *view)
+{
+ REQUIRE(DNS_C_VIEWTABLE_VALID(viewtable));
+ REQUIRE(DNS_C_VIEW_VALID(view));
+
+ ISC_LIST_APPEND(viewtable->views, view, next);
+}
+
+
+
+void
+dns_c_viewtable_rmview(dns_c_viewtable_t *viewtable, dns_c_view_t *view)
+{
+ REQUIRE(DNS_C_VIEWTABLE_VALID(viewtable));
+ REQUIRE(DNS_C_VIEW_VALID(view));
+
+ ISC_LIST_UNLINK(viewtable->views, view, next);
+}
+
+
+
+isc_result_t
+dns_c_viewtable_clear(dns_c_viewtable_t *table)
+{
+ dns_c_view_t *elem;
+ dns_c_view_t *tmpelem;
+ isc_result_t r;
+
+ REQUIRE(DNS_C_VIEWTABLE_VALID(table));
+
+ elem = ISC_LIST_HEAD(table->views);
+ while (elem != NULL) {
+ tmpelem = ISC_LIST_NEXT(elem, next);
+ ISC_LIST_UNLINK(table->views, elem, next);
+
+ r = dns_c_view_delete(&elem);
+ if (r != ISC_R_SUCCESS) {
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG,
+ ISC_LOG_CRITICAL,
+ "Failed to delete view.\n");
+ return (r);
+ }
+
+ elem = tmpelem;
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+isc_result_t
+dns_c_viewtable_viewbyname(dns_c_viewtable_t *viewtable,
+ const char *viewname,
+ dns_c_view_t **retval)
+{
+ dns_c_view_t *elem;
+
+ REQUIRE(DNS_C_VIEWTABLE_VALID(viewtable));
+ REQUIRE(retval != NULL);
+ REQUIRE(viewname != NULL);
+ REQUIRE(strlen(viewname) > 0);
+
+ elem = ISC_LIST_HEAD(viewtable->views);
+ while (elem != NULL) {
+ if (strcmp(viewname, elem->name) == 0) {
+ break;
+ }
+
+ elem = ISC_LIST_NEXT(elem, next);
+ }
+
+ if (elem != NULL) {
+ *retval = elem;
+ }
+
+ return (elem == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+
+isc_result_t
+dns_c_viewtable_rmviewbyname(dns_c_viewtable_t *viewtable,
+ const char *name)
+{
+ dns_c_view_t *view;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_VIEWTABLE_VALID(viewtable));
+
+ res = dns_c_viewtable_viewbyname(viewtable, name, &view);
+ if (res == ISC_R_SUCCESS) {
+ ISC_LIST_UNLINK(viewtable->views, view, next);
+ dns_c_view_delete(&view);
+ }
+
+ return (res);
+}
+
+
+
+isc_result_t
+dns_c_view_new(isc_mem_t *mem, const char *name, dns_c_view_t **newview)
+{
+ dns_c_view_t *view;
+ int i;
+
+
+ REQUIRE(name != NULL);
+ REQUIRE(strlen(name) > 0);
+ REQUIRE(newview != NULL);
+
+ view = isc_mem_get(mem, sizeof *view);
+ if (view == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ /* XXXJAB not portable -- should set each field */
+ memset(view, 0x0, sizeof *view);
+
+ memset(&view->setflags, 0x0, sizeof (view->setflags));
+
+ view->magic = DNS_C_VIEW_MAGIC;
+ view->mem = mem;
+
+ view->allowquery = NULL;
+ view->transferacl = NULL;
+ view->recursionacl = NULL;
+ view->blackhole = NULL;
+ view->sortlist = NULL;
+ view->topology = NULL;
+ view->forwarders = NULL;
+ view->listens = NULL;
+ view->ordering = NULL;
+
+ for (i = 0 ; i < DNS_C_TRANSCOUNT ; i++) {
+ view->check_names[i] = dns_severity_fail;
+ }
+
+ view->transfer_format = dns_one_answer;
+
+ view->auth_nx_domain = ISC_FALSE;
+ view->dialup = ISC_FALSE;
+ view->fetch_glue = ISC_FALSE;
+ view->has_old_clients = ISC_FALSE;
+ view->host_statistics = ISC_FALSE;
+ view->maintain_ixfr_base = ISC_FALSE;
+ view->multiple_cnames = ISC_FALSE;
+ view->notify = ISC_FALSE;
+ view->recursion = ISC_FALSE;
+ view->rfc2308_type1 = ISC_FALSE;
+ view->use_id_pool = ISC_FALSE;
+ view->fake_iquery = ISC_FALSE;
+ view->use_ixfr = ISC_FALSE;
+
+ view->clean_interval = 0;
+ view->lamettl = 0; /* XXX not implemented */
+ view->max_log_size_ixfr = 0;
+ view->max_ncache_ttl = 0;
+ view->max_transfer_time_in = 0;
+ view->max_transfer_time_out = 0;
+ view->max_transfer_idle_in = 0;
+ view->max_transfer_idle_out = 0;
+ view->stats_interval = 0;
+ view->transfers_in = 0;
+ view->transfers_out = 0;
+ view->transfers_per_ns = 0;
+
+ view->zonelist = NULL;
+ view->name = isc_mem_strdup(mem, name);
+ if (view->name == NULL) {
+ isc_mem_put(mem, view, sizeof *view);
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Insufficient memory");
+ }
+
+ *newview = view;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+void
+dns_c_viewtable_print(FILE *fp, int indent,
+ dns_c_viewtable_t *table)
+{
+ dns_c_view_t *view;
+
+ REQUIRE(fp != NULL);
+ REQUIRE(indent >= 0);
+ REQUIRE(DNS_C_VIEWTABLE_VALID(table));
+
+ view = ISC_LIST_HEAD(table->views);
+ while (view != NULL) {
+ dns_c_view_print(fp, indent, view);
+ fprintf(fp, "\n");
+
+ view = ISC_LIST_NEXT(view, next);
+ }
+}
+
+void
+dns_c_view_print(FILE *fp, int indent, dns_c_view_t *view)
+{
+ dns_severity_t nameseverity;
+
+ REQUIRE(DNS_C_VIEW_VALID(view));
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "view \"%s\" {\n", view->name);
+
+ if (view->allowquery != NULL) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "allow-query ");
+ dns_c_ipmatchlist_print(fp, indent + 2,
+ view->allowquery);
+ fprintf(fp, ";\n");
+ }
+
+ if (view->transferacl != NULL) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "allow-transfer ");
+ dns_c_ipmatchlist_print(fp, indent + 2,
+ view->transferacl);
+ fprintf(fp, ";\n");
+ }
+
+ if (view->recursionacl != NULL) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "allow-recursion ");
+ dns_c_ipmatchlist_print(fp, indent + 2,
+ view->recursionacl);
+ fprintf(fp, ";\n");
+ }
+
+ if (view->blackhole != NULL) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "blackhole ");
+ dns_c_ipmatchlist_print(fp, indent + 2,
+ view->blackhole);
+ fprintf(fp, ";\n");
+ }
+
+ if (view->forwarders != NULL) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "forwarders ");
+ dns_c_iplist_print(fp, indent + 2,
+ view->forwarders);
+ fprintf(fp, ";\n");
+ }
+
+ if (view->sortlist != NULL) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "sortlist ");
+ dns_c_ipmatchlist_print(fp, indent + 2,
+ view->sortlist);
+ fprintf(fp, ";\n");
+ }
+
+ if (view->topology != NULL) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "topology ");
+ dns_c_ipmatchlist_print(fp, indent + 2,
+ view->topology);
+ fprintf(fp, ";\n");
+ }
+
+ if (view->listens != NULL) {
+ dns_c_lstnlist_print(fp, indent + 1, view->listens);
+ }
+
+ if (view->ordering != NULL) {
+ dns_c_rrsolist_print(fp, indent + 1, view->ordering);
+ }
+
+ if (DNS_C_CHECKBIT(CHECKNAME_PRIM_BIT, &view->setflags)) {
+ nameseverity = view->check_names[dns_trans_primary];
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "check-names %s %s;\n",
+ dns_c_transport2string(dns_trans_primary,
+ ISC_TRUE),
+ dns_c_nameseverity2string(nameseverity,
+ ISC_TRUE));
+ }
+
+ if (DNS_C_CHECKBIT(CHECKNAME_SEC_BIT, &view->setflags)) {
+ nameseverity = view->check_names[dns_trans_secondary];
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "check-names %s %s;\n",
+ dns_c_transport2string(dns_trans_secondary,
+ ISC_TRUE),
+ dns_c_nameseverity2string(nameseverity,
+ ISC_TRUE));
+ }
+
+ if (DNS_C_CHECKBIT(CHECKNAME_RESP_BIT, &view->setflags)) {
+ nameseverity = view->check_names[dns_trans_response];
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "check-names %s %s;\n",
+ dns_c_transport2string(dns_trans_response,
+ ISC_TRUE),
+ dns_c_nameseverity2string(nameseverity,
+ ISC_TRUE));
+ }
+
+
+ if (DNS_C_CHECKBIT(TRANSFER_FORMAT_BIT, &view->setflags)) {
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "transfer-format %s;\n",
+ dns_c_transformat2string(view->transfer_format,
+ ISC_TRUE));
+ }
+
+
+ fprintf(fp, "\n");
+
+
+
+ /* XXXJAB rest of view fields */
+
+ if (view->zonelist != NULL) {
+ dns_c_zonelist_print(fp, indent + 1, view->zonelist);
+ }
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "};\n");
+}
+
+
+isc_result_t
+dns_c_view_setallowquery(dns_c_view_t *view,
+ dns_c_ipmatchlist_t *ipml,
+ isc_boolean_t deepcopy)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_VIEW_VALID(view));
+ REQUIRE(DNS_C_IPMLIST_VALID(ipml));
+
+ if (view->allowquery != NULL) {
+ dns_c_ipmatchlist_detach(&view->allowquery);
+ }
+
+ if (deepcopy) {
+ res = dns_c_ipmatchlist_copy(view->mem,
+ &view->allowquery, ipml);
+ } else {
+ view->allowquery = ipml;
+ res = ISC_R_SUCCESS;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_view_setallowtransfer(dns_c_view_t *view,
+ dns_c_ipmatchlist_t *ipml,
+ isc_boolean_t deepcopy)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_VIEW_VALID(view));
+ REQUIRE(DNS_C_IPMLIST_VALID(ipml));
+
+ if (view->transferacl != NULL) {
+ dns_c_ipmatchlist_detach(&view->transferacl);
+ }
+
+ if (deepcopy) {
+ res = dns_c_ipmatchlist_copy(view->mem,
+ &view->transferacl, ipml);
+ } else {
+ view->transferacl = ipml;
+ res = ISC_R_SUCCESS;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_view_setallowrecursion(dns_c_view_t *view,
+ dns_c_ipmatchlist_t *ipml,
+ isc_boolean_t deepcopy)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_VIEW_VALID(view));
+ REQUIRE(DNS_C_IPMLIST_VALID(ipml));
+
+ if (view->recursionacl != NULL) {
+ dns_c_ipmatchlist_detach(&view->recursionacl);
+ }
+
+ if (deepcopy) {
+ res = dns_c_ipmatchlist_copy(view->mem,
+ &view->recursionacl, ipml);
+ } else {
+ view->recursionacl = ipml;
+ res = ISC_R_SUCCESS;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_view_setblackhole(dns_c_view_t *view,
+ dns_c_ipmatchlist_t *ipml,
+ isc_boolean_t deepcopy)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_VIEW_VALID(view));
+ REQUIRE(DNS_C_IPMLIST_VALID(ipml));
+
+ if (view->blackhole != NULL) {
+ dns_c_ipmatchlist_detach(&view->blackhole);
+ }
+
+ if (deepcopy) {
+ res = dns_c_ipmatchlist_copy(view->mem,
+ &view->blackhole, ipml);
+ } else {
+ view->blackhole = ipml;
+ res = ISC_R_SUCCESS;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_view_setforwarders(dns_c_view_t *view,
+ dns_c_iplist_t *ipl,
+ isc_boolean_t deepcopy)
+{
+ isc_boolean_t existed = ISC_FALSE;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_VIEW_VALID(view));
+ REQUIRE(DNS_C_IPLIST_VALID(ipl));
+
+ if (view->forwarders != NULL) {
+ existed = ISC_TRUE;
+ dns_c_iplist_detach(&view->forwarders);
+ }
+
+ if (deepcopy) {
+ res = dns_c_iplist_copy(view->mem, &view->forwarders, ipl);
+ } else {
+ view->forwarders = ipl;
+ res = ISC_R_SUCCESS;
+ }
+
+ if (res == ISC_R_SUCCESS) {
+ return (existed ? ISC_R_EXISTS : res);
+ } else {
+ return (res);
+ }
+}
+
+
+
+isc_result_t
+dns_c_view_setsortlist(dns_c_view_t *view,
+ dns_c_ipmatchlist_t *ipml,
+ isc_boolean_t deepcopy)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_VIEW_VALID(view));
+ REQUIRE(DNS_C_IPMLIST_VALID(ipml));
+
+ if (view->sortlist != NULL) {
+ dns_c_ipmatchlist_detach(&view->sortlist);
+ }
+
+ if (deepcopy) {
+ res = dns_c_ipmatchlist_copy(view->mem,
+ &view->sortlist, ipml);
+ } else {
+ view->sortlist = ipml;
+ res = ISC_R_SUCCESS;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_view_settopology(dns_c_view_t *view,
+ dns_c_ipmatchlist_t *ipml,
+ isc_boolean_t deepcopy)
+{
+ isc_result_t res;
+
+ REQUIRE(DNS_C_VIEW_VALID(view));
+ REQUIRE(DNS_C_IPMLIST_VALID(ipml));
+
+ if (view->topology != NULL) {
+ dns_c_ipmatchlist_detach(&view->topology);
+ }
+
+ if (deepcopy) {
+ res = dns_c_ipmatchlist_copy(view->mem,
+ &view->topology, ipml);
+ } else {
+ view->topology = ipml;
+ res = ISC_R_SUCCESS;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_view_getallowquery(dns_c_view_t *view, dns_c_ipmatchlist_t **ipml)
+{
+ REQUIRE(DNS_C_VIEW_VALID(view));
+ REQUIRE(ipml != NULL);
+
+ *ipml = view->allowquery;
+
+ return (*ipml == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+isc_result_t dns_c_view_getallowtransfer(dns_c_view_t *view,
+ dns_c_ipmatchlist_t **ipml)
+{
+ REQUIRE(DNS_C_VIEW_VALID(view));
+ REQUIRE(ipml != NULL);
+
+ *ipml = view->transferacl;
+
+ return (*ipml == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+isc_result_t dns_c_view_getallowrecursion(dns_c_view_t *view,
+ dns_c_ipmatchlist_t **ipml)
+{
+ REQUIRE(DNS_C_VIEW_VALID(view));
+ REQUIRE(ipml != NULL);
+
+ *ipml = view->recursionacl;
+
+ return (*ipml == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+isc_result_t dns_c_view_getblackhole(dns_c_view_t *view,
+ dns_c_ipmatchlist_t **ipml)
+{
+ REQUIRE(DNS_C_VIEW_VALID(view));
+ REQUIRE(ipml != NULL);
+
+ *ipml = view->blackhole;
+
+ return (*ipml == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+isc_result_t dns_c_view_getforwarders(dns_c_view_t *view,
+ dns_c_iplist_t **ipl)
+{
+ REQUIRE(DNS_C_VIEW_VALID(view));
+ REQUIRE(ipl != NULL);
+
+ *ipl = view->forwarders;
+
+ return (*ipl == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+isc_result_t dns_c_view_getsortlist(dns_c_view_t *view,
+ dns_c_ipmatchlist_t **ipml)
+{
+ REQUIRE(DNS_C_VIEW_VALID(view));
+ REQUIRE(ipml != NULL);
+
+ *ipml = view->sortlist;
+
+ return (*ipml == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+isc_result_t dns_c_view_gettopology(dns_c_view_t *view,
+ dns_c_ipmatchlist_t **ipml)
+{
+ REQUIRE(DNS_C_VIEW_VALID(view));
+ REQUIRE(ipml != NULL);
+
+ *ipml = view->topology;
+
+ return (*ipml == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+
+isc_result_t
+dns_c_view_getallowqueryexpanded(isc_mem_t *mem,
+ dns_c_view_t *view,
+ dns_c_acltable_t *acltable,
+ dns_c_ipmatchlist_t **retval)
+{
+ dns_c_ipmatchlist_t *newlist;
+ isc_result_t r;
+
+ REQUIRE(DNS_C_VIEW_VALID(view));
+ REQUIRE(DNS_C_CONFACLTABLE_VALID(acltable));
+ REQUIRE(retval != NULL);
+
+ if (view->allowquery == NULL) {
+ newlist = NULL;
+ r = ISC_R_SUCCESS;
+ } else {
+ r = dns_c_ipmatchlist_copy(mem, &newlist, view->allowquery);
+ if (r != ISC_R_SUCCESS) {
+ return (r);
+ }
+
+ r = dns_c_acl_expandacls(acltable, newlist);
+ }
+
+ *retval = newlist;
+
+ return (r);
+}
+
+
+
+isc_result_t
+dns_c_view_delete(dns_c_view_t **viewptr)
+{
+ dns_c_view_t *view;
+
+ REQUIRE(viewptr != NULL);
+ REQUIRE(DNS_C_VIEW_VALID(*viewptr));
+
+ view = *viewptr;
+
+ isc_mem_free(view->mem, view->name);
+
+ if (view->allowquery != NULL)
+ dns_c_ipmatchlist_detach(&view->allowquery);
+
+ if (view->transferacl != NULL)
+ dns_c_ipmatchlist_detach(&view->transferacl);
+
+ if (view->recursionacl != NULL)
+ dns_c_ipmatchlist_detach(&view->recursionacl);
+
+ if (view->blackhole != NULL)
+ dns_c_ipmatchlist_detach(&view->blackhole);
+
+ if (view->forwarders != NULL)
+ dns_c_iplist_detach(&view->forwarders);
+
+ if (view->sortlist != NULL)
+ dns_c_ipmatchlist_detach(&view->sortlist);
+
+ if (view->topology != NULL)
+ dns_c_ipmatchlist_detach(&view->topology);
+
+ if (view->listens != NULL) {
+ dns_c_lstnlist_delete(&view->listens);
+ }
+
+ if (view->ordering != NULL) {
+ dns_c_rrsolist_delete(&view->ordering);
+ }
+
+ if (view->zonelist != NULL) {
+ dns_c_zonelist_delete(&view->zonelist);
+ }
+
+ view->magic = 0;
+ isc_mem_put(view->mem, view, sizeof *view);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_view_getname(dns_c_view_t *view, const char **retval)
+{
+ REQUIRE(DNS_C_VIEW_VALID(view));
+ REQUIRE(retval != NULL);
+
+ *retval = view->name;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+isc_result_t
+dns_c_view_addzone(dns_c_view_t *view, dns_c_zone_t *zone)
+{
+ isc_result_t res;
+ dns_c_zone_t *attached;
+
+ REQUIRE(DNS_C_VIEW_VALID(view));
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+
+ dns_c_zone_attach(zone, &attached);
+
+ if (view->zonelist == NULL) {
+ res = dns_c_zonelist_new(view->mem, &view->zonelist);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ }
+
+ return (dns_c_zonelist_addzone(view->zonelist, attached));
+}
+
+
+isc_result_t
+dns_c_view_addlisten_on(dns_c_view_t *view, in_port_t port,
+ dns_c_ipmatchlist_t *ml,
+ isc_boolean_t copy)
+{
+ dns_c_lstnon_t *lo;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_VIEW_VALID(view));
+
+ if (view->listens == NULL) {
+ res = dns_c_lstnlist_new(view->mem, &view->listens);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ }
+
+ res = dns_c_lstnon_new(view->mem, &lo);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ lo->port = port;
+ res = dns_c_lstnon_setiml(lo, ml, copy);
+
+ ISC_LIST_APPEND(view->listens->elements, lo, next);
+
+ return (res);
+}
+
+
+
+isc_result_t
+dns_c_view_getlistenlist(dns_c_view_t *view, dns_c_lstnlist_t **ll)
+{
+ REQUIRE(DNS_C_VIEW_VALID(view));
+ REQUIRE(ll != NULL);
+
+ *ll = NULL;
+
+ if (view->listens != NULL) {
+ *ll = view->listens;
+ }
+
+ return (*ll == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+isc_result_t dns_c_view_setrrsetorderlist(dns_c_view_t *view,
+ isc_boolean_t copy,
+ dns_c_rrsolist_t *olist)
+{
+ isc_boolean_t existed;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_VIEW_VALID(view));
+
+ existed = (view->ordering == NULL ? ISC_FALSE : ISC_TRUE);
+
+ if (copy) {
+ if (view->ordering == NULL) {
+ res = dns_c_rrsolist_new(view->mem,
+ &view->ordering);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ } else {
+ dns_c_rrsolist_clear(view->ordering);
+ }
+
+ res = dns_c_rrsolist_append(view->ordering, olist);
+ } else {
+ if (view->ordering != NULL) {
+ dns_c_rrsolist_delete(&view->ordering);
+ }
+
+ view->ordering = olist;
+ res = ISC_R_SUCCESS;
+ }
+
+ if (res == ISC_R_SUCCESS && existed) {
+ res = ISC_R_EXISTS;
+ }
+
+ return (res);
+}
+
+
+
+
+isc_result_t dns_c_view_getrrsetorderlist(dns_c_view_t *view,
+ dns_c_rrsolist_t **olist)
+{
+ REQUIRE(DNS_C_VIEW_VALID(view));
+ REQUIRE(olist != NULL);
+
+ if (view->ordering != NULL) {
+ *olist = view->ordering;
+ }
+
+ return (*olist == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+
+
+isc_result_t
+dns_c_view_setchecknames(dns_c_view_t *view,
+ dns_c_trans_t transtype,
+ dns_severity_t sever)
+{
+ isc_boolean_t existed = ISC_FALSE;
+
+ REQUIRE(DNS_C_VIEW_VALID(view));
+
+ switch(transtype) {
+ case dns_trans_primary:
+ existed = DNS_C_CHECKBIT(CHECKNAME_PRIM_BIT,
+ &view->setflags);
+ DNS_C_SETBIT(CHECKNAME_PRIM_BIT, &view->setflags);
+ break;
+
+ case dns_trans_secondary:
+ existed = DNS_C_CHECKBIT(CHECKNAME_SEC_BIT,
+ &view->setflags);
+ DNS_C_SETBIT(CHECKNAME_SEC_BIT, &view->setflags);
+ break;
+
+ case dns_trans_response:
+ existed = DNS_C_CHECKBIT(CHECKNAME_RESP_BIT,
+ &view->setflags);
+ DNS_C_SETBIT(CHECKNAME_RESP_BIT, &view->setflags);
+ break;
+
+ default:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "bad transport value: %d", transtype);
+ return (ISC_R_FAILURE);
+ }
+
+ view->check_names[transtype] = sever;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+
+isc_result_t
+dns_c_view_getchecknames(dns_c_view_t *view,
+ dns_c_trans_t transtype,
+ dns_severity_t *sever)
+{
+ isc_boolean_t isset = ISC_FALSE;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_VIEW_VALID(view));
+
+ REQUIRE(sever != NULL);
+
+ switch (transtype) {
+ case dns_trans_primary:
+ isset = DNS_C_CHECKBIT(CHECKNAME_PRIM_BIT,
+ &view->setflags);
+ break;
+
+ case dns_trans_secondary:
+ isset = DNS_C_CHECKBIT(CHECKNAME_SEC_BIT,
+ &view->setflags);
+ break;
+
+ case dns_trans_response:
+ isset = DNS_C_CHECKBIT(CHECKNAME_RESP_BIT,
+ &view->setflags);
+ break;
+
+ default:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "bad transport value: %d", transtype);
+ return (ISC_R_FAILURE);
+ }
+
+ if (isset) {
+ *sever = view->check_names[transtype];
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+isc_result_t dns_c_view_settransferformat(dns_c_view_t *view,
+ dns_transfer_format_t format)
+{
+ isc_boolean_t existed = ISC_FALSE;
+
+ REQUIRE(DNS_C_VIEW_VALID(view));
+
+ existed = DNS_C_CHECKBIT(TRANSFER_FORMAT_BIT,
+ &view->setflags);
+ DNS_C_SETBIT(TRANSFER_FORMAT_BIT, &view->setflags);
+
+ view->transfer_format = format;
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t dns_c_view_gettransferformat(dns_c_view_t *view,
+ dns_transfer_format_t *format)
+{
+ REQUIRE(DNS_C_VIEW_VALID(view));
+ REQUIRE(format != NULL);
+
+
+ if (!DNS_C_CHECKBIT(TRANSFER_FORMAT_BIT, &view->setflags)) {
+ return (ISC_R_NOTFOUND);
+ }
+
+ *format = view->transfer_format;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
diff --git a/lib/dns/config/confzone.c b/lib/dns/config/confzone.c
new file mode 100644
index 00000000..11b5e091
--- /dev/null
+++ b/lib/dns/config/confzone.c
@@ -0,0 +1,3596 @@
+/*
+ * 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.
+ */
+
+#include <config.h>
+
+#include <isc/assertions.h>
+
+#include <dns/confzone.h>
+#include <dns/confcommon.h>
+#include <dns/log.h>
+
+#include "confpvt.h"
+
+
+/*
+ * Bit positions in the dns_c_masterzone_t structure setflags field.
+ */
+#define MZ_CHECK_NAME_BIT 0
+#define MZ_DIALUP_BIT 1
+#define MZ_NOTIFY_BIT 2
+#define MZ_MAINT_IXFR_BASE_BIT 3
+#define MZ_MAX_IXFR_LOG_BIT 4
+#define MZ_FORWARD_BIT 5
+#define MZ_MAX_TRANS_TIME_OUT_BIT 6
+#define MZ_MAX_TRANS_IDLE_OUT_BIT 7
+
+
+
+/*
+ * Bit positions in the dns_c_slavezone_t structure setflags field.
+ */
+#define SZ_CHECK_NAME_BIT 0
+#define SZ_DIALUP_BIT 1
+#define SZ_MASTER_PORT_BIT 2
+#define SZ_TRANSFER_SOURCE_BIT 3
+#define SZ_MAX_TRANS_TIME_IN_BIT 4
+#define SZ_MAX_TRANS_TIME_OUT_BIT 5
+#define SZ_MAX_TRANS_IDLE_IN_BIT 6
+#define SZ_MAX_TRANS_IDLE_OUT_BIT 7
+#define SZ_NOTIFY_BIT 8
+#define SZ_MAINT_IXFR_BASE_BIT 9
+#define SZ_MAX_IXFR_LOG_BIT 10
+#define SZ_FORWARD_BIT 11
+
+
+
+/* Bit positions of the stub zones */
+#define TZ_CHECK_NAME_BIT 0
+#define TZ_DIALUP_BIT 1
+#define TZ_MASTER_PORT_BIT 2
+#define TZ_TRANSFER_SOURCE_BIT 3
+#define TZ_MAX_TRANS_TIME_IN_BIT 4
+#define TZ_MAX_TRANS_TIME_OUT_BIT 5
+#define TZ_MAX_TRANS_IDLE_IN_BIT 6
+#define TZ_MAX_TRANS_IDLE_OUT_BIT 7
+#define TZ_FORWARD_BIT 8
+
+
+/*
+ * Bit positions in the dns_c_forwardzone_t structure setflags field.
+ */
+#define FZ_CHECK_NAME_BIT 0
+#define FZ_FORWARD_BIT 1
+
+
+/*
+ * Bit positions in the dns_c_hintzone_t structure setflags field.
+ */
+#define HZ_CHECK_NAME_BIT 0
+
+
+typedef enum { zones_preopts, zones_postopts, zones_all } zone_print_type;
+
+static isc_result_t master_zone_init(dns_c_masterzone_t *mzone);
+static isc_result_t slave_zone_init(dns_c_slavezone_t *szone);
+static isc_result_t stub_zone_init(dns_c_stubzone_t *szone);
+static isc_result_t hint_zone_init(dns_c_hintzone_t *hzone);
+static isc_result_t forward_zone_init(dns_c_forwardzone_t *fzone);
+static isc_result_t zone_delete(dns_c_zone_t **zone);
+static isc_result_t master_zone_clear(isc_mem_t *mem,
+ dns_c_masterzone_t *mzone);
+static isc_result_t slave_zone_clear(isc_mem_t *mem,
+ dns_c_slavezone_t *szone);
+static isc_result_t stub_zone_clear(isc_mem_t *mem,
+ dns_c_stubzone_t *szone);
+static isc_result_t forward_zone_clear(isc_mem_t *mem,
+ dns_c_forwardzone_t *fzone);
+static isc_result_t hint_zone_clear(isc_mem_t *mem,
+ dns_c_hintzone_t *hzone);
+
+static void master_zone_print(FILE *fp, int indent,
+ dns_c_masterzone_t *mzone);
+static void slave_zone_print(FILE *fp, int indent,
+ dns_c_slavezone_t *szone);
+static void stub_zone_print(FILE *fp, int indent,
+ dns_c_stubzone_t *szone);
+static void hint_zone_print(FILE *fp, int indent,
+ dns_c_hintzone_t *hzone);
+static void forward_zone_print(FILE *fp, int indent,
+ dns_c_forwardzone_t *fzone);
+static isc_result_t set_iplist_field(isc_mem_t *mem,
+ dns_c_iplist_t **dest,
+ dns_c_iplist_t *src,
+ isc_boolean_t deepcopy);
+static isc_result_t set_ipmatch_list_field(isc_mem_t *mem,
+ dns_c_ipmatchlist_t **dest,
+ dns_c_ipmatchlist_t *src,
+ isc_boolean_t deepcopy);
+
+static void zone_list_print(zone_print_type zpt,
+ FILE *fp, int indent, dns_c_zonelist_t *list);
+
+
+
+isc_result_t
+dns_c_zonelist_new(isc_mem_t *mem, dns_c_zonelist_t **zlist)
+{
+ dns_c_zonelist_t *list;
+
+ REQUIRE(zlist != NULL);
+
+ list = isc_mem_get(mem, sizeof *list);
+ if (list == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ list->mem = mem;
+ list->magic = DNS_C_ZONELIST_MAGIC;
+
+ ISC_LIST_INIT(list->zones);
+
+ *zlist = list;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_zonelist_delete(dns_c_zonelist_t **zlist)
+{
+ dns_c_zonelist_t *list;
+ dns_c_zonelem_t *zoneelem;
+ dns_c_zonelem_t *tmpelem;
+ dns_c_zone_t *zone;
+ isc_result_t res;
+
+ REQUIRE(zlist != NULL);
+ REQUIRE(*zlist != NULL);
+
+ list = *zlist;
+
+ zoneelem = ISC_LIST_HEAD(list->zones);
+ while (zoneelem != NULL) {
+ tmpelem = ISC_LIST_NEXT(zoneelem, next);
+ ISC_LIST_UNLINK(list->zones, zoneelem, next);
+
+ zone = zoneelem->thezone;
+ isc_mem_put(list->mem, zoneelem, sizeof *zoneelem);
+
+ res = dns_c_zone_detach(&zone);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+
+ zoneelem = tmpelem;
+ }
+
+ list->magic = 0;
+ isc_mem_put(list->mem, list, sizeof *list);
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+dns_c_zonelist_addzone(dns_c_zonelist_t *zlist,
+ dns_c_zone_t *zone)
+{
+ dns_c_zonelem_t *zoneelem;
+
+ REQUIRE(DNS_C_ZONELIST_VALID(zlist));
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(zone->refcount > 0);
+
+ zoneelem = isc_mem_get(zlist->mem, sizeof *zoneelem);
+ if (zoneelem == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ zoneelem->thezone = zone;
+ ISC_LINK_INIT(zoneelem, next);
+
+ ISC_LIST_APPEND(zlist->zones, zoneelem, next);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+isc_result_t
+dns_c_zonelist_find(dns_c_zonelist_t *zlist, const char *name,
+ dns_c_zone_t **retval)
+{
+ dns_c_zonelem_t *zoneelem;
+
+ REQUIRE(DNS_C_ZONELIST_VALID(zlist));
+ REQUIRE(name != NULL);
+ REQUIRE(strlen(name) > 0);
+ REQUIRE(retval != NULL);
+
+ zoneelem = ISC_LIST_HEAD(zlist->zones);
+ while (zoneelem != NULL) {
+ REQUIRE(zoneelem->thezone != NULL);
+
+ if (strcmp(name, zoneelem->thezone->name) == 0) {
+ break;
+ }
+ }
+
+ if (zoneelem != NULL) {
+ *retval = zoneelem->thezone;
+ }
+
+ return (zoneelem == NULL ? ISC_R_NOTFOUND : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_zonelist_rmbyname(dns_c_zonelist_t *zlist,
+ const char *name)
+{
+ dns_c_zonelem_t *zoneelem;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_ZONELIST_VALID(zlist));
+ REQUIRE(name != NULL);
+ REQUIRE(strlen(name) > 0);
+
+ zoneelem = ISC_LIST_HEAD(zlist->zones);
+ while (zoneelem != NULL) {
+ REQUIRE(zoneelem->thezone != NULL);
+
+ if (strcmp(name, zoneelem->thezone->name) == 0) {
+ break;
+ }
+ }
+
+ if (zoneelem != NULL) {
+ ISC_LIST_UNLINK(zlist->zones, zoneelem, next);
+ res = dns_c_zone_detach(&zoneelem->thezone);
+ isc_mem_put(zlist->mem, zoneelem, sizeof *zoneelem);
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zonelist_rmzone(dns_c_zonelist_t *zlist,
+ dns_c_zone_t *zone)
+{
+ dns_c_zonelem_t *zoneelem;
+ isc_result_t res;
+
+ REQUIRE(zlist != NULL);
+ REQUIRE(zone != NULL);
+
+ zoneelem = ISC_LIST_HEAD(zlist->zones);
+ while (zoneelem != NULL) {
+ REQUIRE(zoneelem->thezone != NULL);
+
+ if (zone == zoneelem->thezone) {
+ break;
+ }
+ }
+
+ if (zoneelem != NULL) {
+ ISC_LIST_UNLINK(zlist->zones, zoneelem, next);
+ res = dns_c_zone_detach(&zoneelem->thezone);
+ isc_mem_put(zlist->mem, zoneelem, sizeof *zoneelem);
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+void
+dns_c_zonelist_print(FILE *fp, int indent,
+ dns_c_zonelist_t *list)
+{
+ REQUIRE(DNS_C_ZONELIST_VALID(list));
+ zone_list_print(zones_all, fp, indent, list);
+}
+
+
+void
+dns_c_zonelist_printpreopts(FILE *fp, int indent,
+ dns_c_zonelist_t *list)
+{
+ REQUIRE(DNS_C_ZONELIST_VALID(list));
+ zone_list_print(zones_preopts, fp, indent, list);
+}
+
+
+void
+dns_c_zonelist_printpostopts(FILE *fp, int indent,
+ dns_c_zonelist_t *list)
+{
+ REQUIRE(DNS_C_ZONELIST_VALID(list));
+ zone_list_print(zones_postopts, fp, indent, list);
+}
+
+
+
+static void
+zone_list_print(zone_print_type zpt, FILE *fp, int indent,
+ dns_c_zonelist_t *list)
+{
+ dns_c_zonelem_t *zoneelem;
+
+ REQUIRE(fp != NULL);
+ REQUIRE(indent >= 0);
+
+ if (list == NULL) {
+ return;
+ }
+
+#define PRINTIT(zone, zpt) \
+ (zpt == zones_all || \
+ (zone->view == NULL && \
+ ((zpt == zones_preopts && zone->afteropts == ISC_FALSE) || \
+ ((zpt == zones_postopts && zone->afteropts == ISC_TRUE)))))
+
+ zoneelem = ISC_LIST_HEAD(list->zones);
+ while (zoneelem != NULL) {
+ if (PRINTIT(zoneelem->thezone, zpt)) {
+ dns_c_zone_print(fp, indent, zoneelem->thezone);
+ }
+
+ zoneelem = ISC_LIST_NEXT(zoneelem, next);
+ if (zoneelem != NULL && PRINTIT(zoneelem->thezone, zpt)) {
+ fprintf(fp, "\n");
+ }
+ }
+
+#undef PRINTIT
+
+ return;
+}
+
+
+/* ************************************************************************ */
+/* ******************************** ZONEs ********************************* */
+/* ************************************************************************ */
+
+isc_result_t
+dns_c_zone_new(isc_mem_t *mem,
+ dns_c_zonetype_t ztype, dns_rdataclass_t zclass,
+ const char *name, const char *internalname,
+ dns_c_zone_t **zone)
+{
+ dns_c_zone_t *newzone;
+ isc_result_t res;
+
+ REQUIRE(mem != NULL);
+ REQUIRE(name != NULL);
+ REQUIRE(strlen(name) > 0);
+
+ newzone = isc_mem_get(mem, sizeof *newzone);
+ if (newzone == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ newzone->magic = DNS_C_ZONE_MAGIC;
+ newzone->mem = mem;
+ newzone->refcount = 1;
+ newzone->ztype = ztype;
+ newzone->zclass = zclass;
+ newzone->view = NULL;
+ newzone->afteropts = ISC_FALSE;
+ newzone->name = isc_mem_strdup(mem, name);
+ newzone->internalname = (internalname == NULL ?
+ isc_mem_strdup(mem, name) :
+ isc_mem_strdup(mem, internalname));
+
+ switch (ztype) {
+ case dns_c_zone_master:
+ res = master_zone_init(&newzone->u.mzone);
+ break;
+
+ case dns_c_zone_slave:
+ res = slave_zone_init(&newzone->u.szone);
+ break;
+
+ case dns_c_zone_stub:
+ res = stub_zone_init(&newzone->u.tzone);
+ break;
+
+ case dns_c_zone_hint:
+ res = hint_zone_init(&newzone->u.hzone);
+ break;
+
+ case dns_c_zone_forward:
+ res = forward_zone_init(&newzone->u.fzone);
+ break;
+ }
+
+ *zone = newzone;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_zone_detach(dns_c_zone_t **zone)
+{
+ dns_c_zone_t *zoneptr;
+ isc_result_t res = ISC_R_SUCCESS;
+
+ REQUIRE(zone != NULL);
+ REQUIRE(DNS_C_ZONE_VALID(*zone));
+
+ zoneptr = *zone;
+ *zone = NULL;
+
+ REQUIRE(zoneptr->refcount > 0);
+ zoneptr->refcount--;
+
+ if (zoneptr->refcount == 0) {
+ res = zone_delete(&zoneptr);
+ }
+
+ return (res);
+}
+
+
+void
+dns_c_zone_attach(dns_c_zone_t *source,
+ dns_c_zone_t **target)
+{
+ REQUIRE(DNS_C_ZONE_VALID(source));
+ REQUIRE(target != NULL);
+
+ source->refcount++;
+
+ *target = source;
+}
+
+
+
+void
+dns_c_zone_print(FILE *fp, int indent, dns_c_zone_t *zone)
+{
+ REQUIRE(fp != NULL);
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "zone \"%s\"", zone->name);
+ if (zone->zclass != dns_rdataclass_in) {
+ fputc(' ', fp);
+ dns_c_dataclass_tostream(fp, zone->zclass);
+ }
+
+ fprintf(fp, " {\n");
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "type master;\n");
+ master_zone_print(fp, indent + 1, &zone->u.mzone);
+ break;
+
+ case dns_c_zone_slave:
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "type slave;\n");
+ slave_zone_print(fp, indent + 1, &zone->u.szone);
+ break;
+
+ case dns_c_zone_stub:
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "type stub;\n");
+ stub_zone_print(fp, indent + 1, &zone->u.tzone);
+ break;
+
+ case dns_c_zone_hint:
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "type hint;\n");
+ hint_zone_print(fp, indent + 1, &zone->u.hzone);
+ break;
+
+ case dns_c_zone_forward:
+ dns_c_printtabs(fp, indent + 1);
+ fprintf(fp, "type forward;\n");
+ forward_zone_print(fp, indent + 1, &zone->u.fzone);
+ break;
+ }
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "};\n");
+}
+
+
+isc_result_t
+dns_c_zone_setfile(dns_c_zone_t *zone, const char *newfile)
+{
+ char **p = NULL;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(newfile != NULL);
+ REQUIRE(strlen(newfile) > 0);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ p = &zone->u.mzone.file;
+ break;
+
+ case dns_c_zone_slave:
+ p = &zone->u.szone.file;
+ break;
+
+ case dns_c_zone_stub:
+ p = &zone->u.tzone.file;
+ break;
+
+ case dns_c_zone_hint:
+ p = &zone->u.hzone.file;
+ break;
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a file field");
+ return (ISC_R_FAILURE);
+ }
+
+ if (*p != NULL) {
+ isc_mem_free(zone->mem, *p);
+ res = ISC_R_EXISTS;
+ } else {
+ res = ISC_R_SUCCESS;
+ }
+
+ *p = isc_mem_strdup(zone->mem, newfile);
+ if (*p == NULL) {
+ res = ISC_R_NOMEMORY;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_setchecknames(dns_c_zone_t *zone,
+ dns_severity_t severity)
+{
+ dns_severity_t *p = NULL;
+ dns_c_setbits_t *bits = NULL;
+ int bit = 0;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ p = &zone->u.mzone.check_names;
+ bits = &zone->u.mzone.setflags;
+ bit = MZ_CHECK_NAME_BIT;
+ break;
+
+ case dns_c_zone_slave:
+ p = &zone->u.szone.check_names;
+ bits = &zone->u.szone.setflags;
+ bit = SZ_CHECK_NAME_BIT;
+ break;
+
+ case dns_c_zone_stub:
+ p = &zone->u.tzone.check_names;
+ bits = &zone->u.tzone.setflags;
+ bit = TZ_CHECK_NAME_BIT;
+ break;
+
+ case dns_c_zone_hint:
+ p = &zone->u.hzone.check_names;
+ bits = &zone->u.hzone.setflags;
+ bit = HZ_CHECK_NAME_BIT;
+ break;
+
+ case dns_c_zone_forward:
+ p = &zone->u.fzone.check_names;
+ bits = &zone->u.fzone.setflags;
+ bit = FZ_CHECK_NAME_BIT;
+ break;
+ }
+
+ if (DNS_C_CHECKBIT(bit, bits)) {
+ res = ISC_R_EXISTS;
+ } else {
+ res = ISC_R_SUCCESS;
+ }
+
+ *p = severity;
+ DNS_C_SETBIT(bit, bits);
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_setallowupd(dns_c_zone_t *zone,
+ dns_c_ipmatchlist_t *ipml,
+ isc_boolean_t deepcopy)
+{
+ dns_c_ipmatchlist_t **p = NULL;
+ isc_result_t res;
+ isc_boolean_t existed;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(DNS_C_IPMLIST_VALID(ipml));
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ p = &zone->u.mzone.allow_update;
+ break;
+
+ case dns_c_zone_slave:
+ p = &zone->u.szone.allow_update;
+ break;
+
+ case dns_c_zone_stub:
+ p = &zone->u.tzone.allow_update;
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have an allow_update field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have an "
+ "allow_update field");
+ return (ISC_R_FAILURE);
+ }
+
+ existed = (*p != NULL ? ISC_TRUE : ISC_FALSE);
+
+ res = set_ipmatch_list_field(zone->mem, p,
+ ipml, deepcopy);
+ if (res == ISC_R_SUCCESS && existed) {
+ res = ISC_R_EXISTS;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_setallowquery(dns_c_zone_t *zone,
+ dns_c_ipmatchlist_t *ipml,
+ isc_boolean_t deepcopy)
+{
+ dns_c_ipmatchlist_t **p = NULL;
+ isc_boolean_t existed;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(DNS_C_IPMLIST_VALID(ipml));
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ p = &zone->u.mzone.allow_query;
+ break;
+
+ case dns_c_zone_slave:
+ p = &zone->u.szone.allow_query;
+ break;
+
+ case dns_c_zone_stub:
+ p = &zone->u.tzone.allow_query;
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have an allow_query field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have an "
+ "allow_query field");
+ return (ISC_R_FAILURE);
+ }
+
+ existed = (*p != NULL ? ISC_TRUE : ISC_FALSE);
+
+ res = set_ipmatch_list_field(zone->mem, p,
+ ipml, deepcopy);
+ if (res == ISC_R_SUCCESS && existed) {
+ res = ISC_R_EXISTS;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_setallowtransfer(dns_c_zone_t *zone,
+ dns_c_ipmatchlist_t *ipml,
+ isc_boolean_t deepcopy)
+{
+ dns_c_ipmatchlist_t **p = NULL;
+ isc_boolean_t existed;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(DNS_C_IPMLIST_VALID(ipml));
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ p = &zone->u.mzone.allow_transfer;
+ break;
+
+ case dns_c_zone_slave:
+ p = &zone->u.szone.allow_transfer;
+ break;
+
+ case dns_c_zone_stub:
+ p = &zone->u.tzone.allow_transfer;
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have an "
+ "allow_transfer field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have an "
+ "allow_transfer field");
+ return (ISC_R_FAILURE);
+ }
+
+ existed = (*p != NULL ? ISC_TRUE : ISC_FALSE);
+ res = set_ipmatch_list_field(zone->mem, p,
+ ipml, deepcopy);
+
+ if (res == ISC_R_SUCCESS && existed) {
+ res = ISC_R_EXISTS;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_setdialup(dns_c_zone_t *zone, isc_boolean_t newval)
+{
+ isc_boolean_t existed = ISC_FALSE;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ zone->u.mzone.dialup = newval;
+ existed = DNS_C_CHECKBIT(MZ_DIALUP_BIT,
+ &zone->u.mzone.setflags);
+ DNS_C_SETBIT(MZ_DIALUP_BIT, &zone->u.mzone.setflags);
+ break;
+
+ case dns_c_zone_slave:
+ zone->u.szone.dialup = newval;
+ existed = DNS_C_CHECKBIT(SZ_DIALUP_BIT,
+ &zone->u.szone.setflags);
+ DNS_C_SETBIT(SZ_DIALUP_BIT, &zone->u.szone.setflags);
+ break;
+
+ case dns_c_zone_stub:
+ zone->u.tzone.dialup = newval;
+ existed = DNS_C_CHECKBIT(TZ_DIALUP_BIT,
+ &zone->u.tzone.setflags);
+ DNS_C_SETBIT(TZ_DIALUP_BIT, &zone->u.tzone.setflags);
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a dialup field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a dialup field");
+ return (ISC_R_FAILURE);
+ }
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_zone_setnotify(dns_c_zone_t *zone, isc_boolean_t newval)
+{
+ isc_boolean_t existed = ISC_FALSE;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ zone->u.mzone.notify = newval;
+ existed = DNS_C_CHECKBIT(MZ_NOTIFY_BIT,
+ &zone->u.mzone.setflags);
+ DNS_C_SETBIT(MZ_NOTIFY_BIT, &zone->u.mzone.setflags);
+ break;
+
+ case dns_c_zone_slave:
+ zone->u.szone.notify = newval;
+ existed = DNS_C_CHECKBIT(SZ_NOTIFY_BIT,
+ &zone->u.szone.setflags);
+ DNS_C_SETBIT(SZ_NOTIFY_BIT, &zone->u.szone.setflags);
+ break;
+
+ case dns_c_zone_stub:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Stub zones do not have a notify field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a notify field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a notify field");
+ return (ISC_R_FAILURE);
+ }
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_zone_setmaintixfrbase(dns_c_zone_t *zone,
+ isc_boolean_t newval)
+{
+ isc_boolean_t existed = ISC_FALSE;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ zone->u.mzone.maint_ixfr_base = newval;
+ existed = DNS_C_CHECKBIT(MZ_MAINT_IXFR_BASE_BIT,
+ &zone->u.mzone.setflags);
+ DNS_C_SETBIT(MZ_MAINT_IXFR_BASE_BIT, &zone->u.mzone.setflags);
+ break;
+
+ case dns_c_zone_slave:
+ zone->u.szone.maint_ixfr_base = newval;
+ existed = DNS_C_CHECKBIT(SZ_MAINT_IXFR_BASE_BIT,
+ &zone->u.szone.setflags);
+ DNS_C_SETBIT(SZ_MAINT_IXFR_BASE_BIT, &zone->u.szone.setflags);
+ break;
+
+ case dns_c_zone_stub:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Stub zones do not have a "
+ "maintain-xfer-base field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a "
+ "maintain-xfer-base field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a "
+ "maintain-xfer-base field");
+ return (ISC_R_FAILURE);
+ }
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_zone_setalsonotify(dns_c_zone_t *zone,
+ dns_c_iplist_t *newval,
+ isc_boolean_t deepcopy)
+{
+ isc_boolean_t existed;
+ isc_result_t res;
+ dns_c_iplist_t **p = NULL;
+
+ REQUIRE(zone != NULL);
+ REQUIRE(DNS_C_IPLIST_VALID(newval));
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ p = &zone->u.mzone.also_notify ;
+ break;
+
+ case dns_c_zone_slave:
+ p = &zone->u.szone.also_notify ;
+ break;
+
+ case dns_c_zone_stub:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Stub zones do not have a also_notify field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a also_notify field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a also_notify field");
+ return (ISC_R_FAILURE);
+ }
+
+ existed = (*p != NULL ? ISC_TRUE : ISC_FALSE);
+ res = set_iplist_field(zone->mem, p, newval, deepcopy);
+ if (res == ISC_R_SUCCESS && existed) {
+ res = ISC_R_EXISTS;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_setixfrbase(dns_c_zone_t *zone, const char *newval)
+{
+ isc_boolean_t existed ;
+ char **p = NULL;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(newval != NULL);
+ REQUIRE(strlen(newval) > 0);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ p = &zone->u.mzone.ixfr_base;
+ break;
+
+ case dns_c_zone_slave:
+ p = &zone->u.szone.ixfr_base;
+ break;
+
+ case dns_c_zone_stub:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Stub zones do not have a ixfr_base field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a ixfr_base field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a file field");
+ return (ISC_R_FAILURE);
+ }
+
+ if (*p != NULL) {
+ existed = ISC_TRUE;
+ isc_mem_free(zone->mem, *p);
+ } else {
+ existed = ISC_FALSE;
+ }
+
+ *p = isc_mem_strdup(zone->mem, newval);
+ if (*p == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_zone_setixfrtmp(dns_c_zone_t *zone, const char *newval)
+{
+ isc_boolean_t existed;
+ char **p = NULL;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(newval != NULL);
+ REQUIRE(strlen(newval) > 0);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ p = &zone->u.mzone.ixfr_tmp;
+ break;
+
+ case dns_c_zone_slave:
+ p = &zone->u.szone.ixfr_tmp;
+ break;
+
+ case dns_c_zone_stub:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Stub zones do not have a ixfr_tmp field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a ixfr_tmp field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a file field");
+ return (ISC_R_FAILURE);
+ }
+
+ if (*p != NULL) {
+ existed = ISC_TRUE;
+ isc_mem_free(zone->mem, *p);
+ } else {
+ existed = ISC_FALSE;
+ }
+
+ *p = isc_mem_strdup(zone->mem, newval);
+ if (*p == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_zone_addpubkey(dns_c_zone_t *zone,
+ dns_c_pubkey_t *pubkey,
+ isc_boolean_t deepcopy)
+{
+ dns_c_pklist_t **p = NULL;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(DNS_C_PUBKEY_VALID(pubkey));
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ p = &zone->u.mzone.pubkeylist;
+ break;
+
+ case dns_c_zone_slave:
+ p = &zone->u.szone.pubkeylist;
+ break;
+
+ case dns_c_zone_stub:
+ p = &zone->u.tzone.pubkeylist;
+ break;
+
+ case dns_c_zone_hint:
+#if 1
+ p = &zone->u.hzone.pubkeylist;
+#else
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a pubkey field");
+#endif
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a pubkey field");
+ return (ISC_R_FAILURE);
+ }
+
+ if (*p == NULL) {
+ res = dns_c_pklist_new(zone->mem, p);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ }
+
+ res = dns_c_pklist_addpubkey(*p, pubkey, deepcopy);
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_setmasterport(dns_c_zone_t *zone, in_port_t port)
+{
+ isc_boolean_t existed = ISC_FALSE;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+
+ switch(zone->ztype) {
+ case dns_c_zone_master:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a "
+ "master_port field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_slave:
+ zone->u.szone.master_port = port;
+ existed = DNS_C_CHECKBIT(SZ_MASTER_PORT_BIT,
+ &zone->u.szone.setflags);
+ DNS_C_SETBIT(SZ_MASTER_PORT_BIT, &zone->u.szone.setflags);
+ break;
+
+ case dns_c_zone_stub:
+ zone->u.tzone.master_port = port;
+ existed = DNS_C_CHECKBIT(TZ_MASTER_PORT_BIT,
+ &zone->u.tzone.setflags);
+ DNS_C_SETBIT(TZ_MASTER_PORT_BIT, &zone->u.tzone.setflags);
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a master_port field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a "
+ "master_port field");
+ return (ISC_R_FAILURE);
+ }
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_zone_setmasterips(dns_c_zone_t *zone,
+ dns_c_iplist_t *newval,
+ isc_boolean_t deepcopy)
+{
+ isc_boolean_t existed;
+ isc_result_t res = ISC_R_SUCCESS;
+ dns_c_iplist_t **p;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(DNS_C_IPLIST_VALID(newval));
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Master zones do not have a master_ips field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_slave:
+ case dns_c_zone_stub:
+ if (zone->ztype == dns_c_zone_slave) {
+ p = &zone->u.szone.master_ips ;
+ } else {
+ p = &zone->u.tzone.master_ips ;
+ }
+
+ existed = (*p != NULL ? ISC_TRUE : ISC_FALSE);
+ res = set_iplist_field(zone->mem, p,
+ newval, deepcopy);
+ if (res == ISC_R_SUCCESS && existed) {
+ res = ISC_R_EXISTS;
+ }
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a master_ips field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a master_ips field");
+ return (ISC_R_FAILURE);
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_settransfersource(dns_c_zone_t *zone,
+ isc_sockaddr_t newval)
+{
+ isc_boolean_t existed = ISC_FALSE;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Master zones do not have a "
+ "transfer_source field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_slave:
+ zone->u.szone.transfer_source = newval ;
+ existed = DNS_C_CHECKBIT(SZ_TRANSFER_SOURCE_BIT,
+ &zone->u.szone.setflags);
+ DNS_C_SETBIT(SZ_TRANSFER_SOURCE_BIT, &zone->u.szone.setflags);
+ break;
+
+ case dns_c_zone_stub:
+ zone->u.tzone.transfer_source = newval ;
+ existed = DNS_C_CHECKBIT(TZ_TRANSFER_SOURCE_BIT,
+ &zone->u.tzone.setflags);
+ DNS_C_SETBIT(TZ_TRANSFER_SOURCE_BIT, &zone->u.tzone.setflags);
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a master_ips field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a master_ips field");
+ return (ISC_R_FAILURE);
+ }
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_zone_setmaxtranstimein(dns_c_zone_t *zone,
+ isc_int32_t newval)
+{
+ isc_boolean_t existed = ISC_FALSE;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Master zones do not have a "
+ "max_trans_time_in field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_slave:
+ zone->u.szone.max_trans_time_in = newval ;
+ existed = DNS_C_CHECKBIT(SZ_MAX_TRANS_TIME_IN_BIT,
+ &zone->u.szone.setflags);
+ DNS_C_SETBIT(SZ_MAX_TRANS_TIME_IN_BIT,
+ &zone->u.szone.setflags);
+ break;
+
+ case dns_c_zone_stub:
+ zone->u.tzone.max_trans_time_in = newval ;
+ existed = DNS_C_CHECKBIT(TZ_MAX_TRANS_TIME_IN_BIT,
+ &zone->u.tzone.setflags);
+ DNS_C_SETBIT(TZ_MAX_TRANS_TIME_IN_BIT,
+ &zone->u.tzone.setflags);
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a "
+ "max_trans_time_in field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a "
+ "max_trans_time_in field");
+ return (ISC_R_FAILURE);
+ }
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_zone_setmaxtranstimeout(dns_c_zone_t *zone,
+ isc_int32_t newval)
+{
+ isc_boolean_t existed = ISC_FALSE;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ zone->u.mzone.max_trans_time_out = newval ;
+ existed = DNS_C_CHECKBIT(MZ_MAX_TRANS_TIME_OUT_BIT,
+ &zone->u.mzone.setflags);
+ DNS_C_SETBIT(MZ_MAX_TRANS_TIME_OUT_BIT,
+ &zone->u.mzone.setflags);
+ break;
+
+ case dns_c_zone_slave:
+ zone->u.szone.max_trans_time_out = newval ;
+ existed = DNS_C_CHECKBIT(SZ_MAX_TRANS_TIME_OUT_BIT,
+ &zone->u.szone.setflags);
+ DNS_C_SETBIT(SZ_MAX_TRANS_TIME_OUT_BIT,
+ &zone->u.szone.setflags);
+ break;
+
+ case dns_c_zone_stub:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Stub zones do not have a "
+ "max_trans_time_out field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a "
+ "max_trans_time_out field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a "
+ "max_trans_time_out field");
+ return (ISC_R_FAILURE);
+ }
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_zone_setmaxtransidlein(dns_c_zone_t *zone,
+ isc_int32_t newval)
+{
+ isc_boolean_t existed = ISC_FALSE;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Master zones do not have a "
+ "max_trans_idle_in field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_slave:
+ zone->u.szone.max_trans_idle_in = newval ;
+ existed = DNS_C_CHECKBIT(SZ_MAX_TRANS_IDLE_IN_BIT,
+ &zone->u.szone.setflags);
+ DNS_C_SETBIT(SZ_MAX_TRANS_IDLE_IN_BIT,
+ &zone->u.szone.setflags);
+ break;
+
+ case dns_c_zone_stub:
+ zone->u.tzone.max_trans_idle_in = newval ;
+ existed = DNS_C_CHECKBIT(TZ_MAX_TRANS_IDLE_IN_BIT,
+ &zone->u.tzone.setflags);
+ DNS_C_SETBIT(TZ_MAX_TRANS_IDLE_IN_BIT,
+ &zone->u.tzone.setflags);
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a "
+ "max_trans_idle_in field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a "
+ "max_trans_idle_in field");
+ return (ISC_R_FAILURE);
+ }
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_zone_setmaxtransidleout(dns_c_zone_t *zone,
+ isc_int32_t newval)
+{
+ isc_boolean_t existed = ISC_FALSE;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ zone->u.mzone.max_trans_idle_out = newval ;
+ existed = DNS_C_CHECKBIT(MZ_MAX_TRANS_IDLE_OUT_BIT,
+ &zone->u.mzone.setflags);
+ DNS_C_SETBIT(MZ_MAX_TRANS_IDLE_OUT_BIT,
+ &zone->u.mzone.setflags);
+ break;
+
+ case dns_c_zone_slave:
+ zone->u.szone.max_trans_idle_out = newval ;
+ existed = DNS_C_CHECKBIT(SZ_MAX_TRANS_IDLE_OUT_BIT,
+ &zone->u.szone.setflags);
+ DNS_C_SETBIT(SZ_MAX_TRANS_IDLE_OUT_BIT,
+ &zone->u.szone.setflags);
+ break;
+
+ case dns_c_zone_stub:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Stub zones do not have a "
+ "max_trans_idle_out field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a "
+ "max_trans_idle_out field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a "
+ "max_trans_idle_out field");
+ return (ISC_R_FAILURE);
+ }
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_zone_setmaxixfrlog(dns_c_zone_t *zone,
+ isc_int32_t newval)
+{
+ dns_c_setbits_t *bits = NULL;
+ isc_int32_t *p = NULL;
+ int bit = 0;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ p = &zone->u.mzone.max_ixfr_log;
+ bits = &zone->u.mzone.setflags;
+ bit = MZ_MAX_IXFR_LOG_BIT;
+ break;
+
+ case dns_c_zone_slave:
+ p = &zone->u.szone.max_ixfr_log;
+ bits = &zone->u.mzone.setflags;
+ bit = SZ_MAX_IXFR_LOG_BIT;
+ break;
+
+ case dns_c_zone_stub:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Stub zones do not have a max-ixfr-log field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a max-ixfr-log field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a "
+ "max-ixfr-log field");
+ return (ISC_R_FAILURE);
+ }
+
+ if (DNS_C_CHECKBIT(bit, bits)) {
+ res = ISC_R_EXISTS;
+ } else {
+ res = ISC_R_SUCCESS;
+ }
+
+ *p = newval;
+ DNS_C_SETBIT(bit, bits);
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_setforward(dns_c_zone_t *zone, dns_c_forw_t newval)
+{
+ isc_boolean_t existed = ISC_FALSE;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ zone->u.mzone.forward = newval;
+ existed = DNS_C_CHECKBIT(MZ_FORWARD_BIT,
+ &zone->u.mzone.setflags);
+ DNS_C_SETBIT(MZ_FORWARD_BIT, &zone->u.mzone.setflags);
+ break;
+
+ case dns_c_zone_slave:
+ zone->u.szone.forward = newval;
+ existed = DNS_C_CHECKBIT(SZ_FORWARD_BIT,
+ &zone->u.szone.setflags);
+ DNS_C_SETBIT(SZ_FORWARD_BIT, &zone->u.szone.setflags);
+ break;
+
+ case dns_c_zone_stub:
+ zone->u.tzone.forward = newval;
+ existed = DNS_C_CHECKBIT(TZ_FORWARD_BIT,
+ &zone->u.tzone.setflags);
+ DNS_C_SETBIT(TZ_FORWARD_BIT, &zone->u.tzone.setflags);
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a forward field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ zone->u.fzone.forward = newval;
+ existed = DNS_C_CHECKBIT(FZ_FORWARD_BIT,
+ &zone->u.fzone.setflags);
+ DNS_C_SETBIT(FZ_FORWARD_BIT, &zone->u.fzone.setflags);
+ break;
+ }
+
+ return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_zone_setforwarders(dns_c_zone_t *zone,
+ dns_c_iplist_t *ipl,
+ isc_boolean_t deepcopy)
+{
+ isc_boolean_t existed = ISC_FALSE;
+ isc_result_t res;
+ dns_c_iplist_t **p = NULL;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(DNS_C_IPLIST_VALID(ipl));
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ p = &zone->u.mzone.forwarders;
+ existed = (*p == NULL ? ISC_FALSE : ISC_TRUE);
+ break;
+
+ case dns_c_zone_slave:
+ p = &zone->u.szone.forwarders;
+ existed = (*p == NULL ? ISC_FALSE : ISC_TRUE);
+ break;
+
+ case dns_c_zone_stub:
+ p = &zone->u.tzone.forwarders;
+ existed = (*p == NULL ? ISC_FALSE : ISC_TRUE);
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a forwarders field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ p = &zone->u.fzone.forwarders;
+ existed = (*p == NULL ? ISC_FALSE : ISC_TRUE);
+ break;
+ }
+
+ res = set_iplist_field(zone->mem, p, ipl, deepcopy);
+ if (res == ISC_R_SUCCESS && existed) {
+ res = ISC_R_EXISTS;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_getname(dns_c_zone_t *zone, const char **retval)
+{
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ *retval = zone->name;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_zone_getinternalname(dns_c_zone_t *zone,
+ const char **retval)
+{
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ *retval = zone->internalname;
+
+ return (ISC_R_SUCCESS);
+}
+
+
+isc_result_t
+dns_c_zone_getfile(dns_c_zone_t *zone, const char **retval)
+{
+ const char *p = NULL;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ p = zone->u.mzone.file;
+ break;
+
+ case dns_c_zone_slave:
+ p = zone->u.szone.file;
+ break;
+
+ case dns_c_zone_stub:
+ p = zone->u.tzone.file;
+ break;
+
+ case dns_c_zone_hint:
+ p = zone->u.hzone.file;
+ break;
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a file field");
+ return (ISC_R_FAILURE);
+ }
+
+ if (p != NULL) {
+ *retval = p;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_getchecknames(dns_c_zone_t *zone,
+ dns_severity_t *retval)
+{
+ dns_severity_t *p = NULL;
+ dns_c_setbits_t *bits = NULL;
+ int bit = 0;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ p = &zone->u.mzone.check_names;
+ bits = &zone->u.mzone.setflags;
+ bit = MZ_CHECK_NAME_BIT;
+ break;
+
+ case dns_c_zone_slave:
+ p = &zone->u.szone.check_names;
+ bits = &zone->u.szone.setflags;
+ bit = SZ_CHECK_NAME_BIT;
+ break;
+
+ case dns_c_zone_stub:
+ p = &zone->u.tzone.check_names;
+ bits = &zone->u.tzone.setflags;
+ bit = TZ_CHECK_NAME_BIT;
+ break;
+
+ case dns_c_zone_hint:
+ p = &zone->u.hzone.check_names;
+ bits = &zone->u.hzone.setflags;
+ bit = HZ_CHECK_NAME_BIT;
+ break;
+
+ case dns_c_zone_forward:
+ p = &zone->u.fzone.check_names;
+ bits = &zone->u.fzone.setflags;
+ bit = FZ_CHECK_NAME_BIT;
+ break;
+ }
+
+ if (DNS_C_CHECKBIT(bit, bits)) {
+ *retval = *p;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_getallowupd(dns_c_zone_t *zone,
+ dns_c_ipmatchlist_t **retval)
+{
+ dns_c_ipmatchlist_t *p = NULL;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ p = zone->u.mzone.allow_update;
+ break;
+
+ case dns_c_zone_slave:
+ p = zone->u.szone.allow_update;
+ break;
+
+ case dns_c_zone_stub:
+ p = zone->u.tzone.allow_update;
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have an allow_update field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have an "
+ "allow_update field");
+ return (ISC_R_FAILURE);
+ }
+
+ if (p != NULL) {
+ dns_c_ipmatchlist_attach(p, retval);
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_getallowquery(dns_c_zone_t *zone,
+ dns_c_ipmatchlist_t **retval)
+{
+ dns_c_ipmatchlist_t *p = NULL;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ p = zone->u.mzone.allow_query;
+ break;
+
+ case dns_c_zone_slave:
+ p = zone->u.szone.allow_query;
+ break;
+
+ case dns_c_zone_stub:
+ p = zone->u.tzone.allow_query;
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have an allow_query field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have an "
+ "allow_query field");
+ return (ISC_R_FAILURE);
+ }
+
+ if (p != NULL) {
+ dns_c_ipmatchlist_attach(p, retval);
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_getallowtransfer(dns_c_zone_t *zone,
+ dns_c_ipmatchlist_t **retval)
+{
+ dns_c_ipmatchlist_t *p = NULL;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ p = zone->u.mzone.allow_transfer;
+ break;
+
+ case dns_c_zone_slave:
+ p = zone->u.szone.allow_transfer;
+ break;
+
+ case dns_c_zone_stub:
+ p = zone->u.tzone.allow_transfer;
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have an "
+ "allow_transfer field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have an "
+ "allow_transfer field");
+ return (ISC_R_FAILURE);
+ }
+
+ if (p != NULL) {
+ dns_c_ipmatchlist_attach(p, retval);
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_getdialup(dns_c_zone_t *zone,
+ isc_boolean_t *retval)
+{
+ isc_result_t res = ISC_R_SUCCESS;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ if (DNS_C_CHECKBIT(MZ_DIALUP_BIT, &zone->u.mzone.setflags)) {
+ *retval = zone->u.mzone.dialup;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+ case dns_c_zone_slave:
+ if (DNS_C_CHECKBIT(SZ_DIALUP_BIT, &zone->u.szone.setflags)) {
+ *retval = zone->u.szone.dialup;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+ case dns_c_zone_stub:
+ if (DNS_C_CHECKBIT(TZ_DIALUP_BIT, &zone->u.tzone.setflags)) {
+ *retval = zone->u.tzone.dialup;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a dialup field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a dialup field");
+ return (ISC_R_FAILURE);
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_getnotify(dns_c_zone_t *zone,
+ isc_boolean_t *retval)
+{
+ isc_result_t res;
+ dns_c_setbits_t *bits = NULL;
+ isc_boolean_t val = ISC_FALSE;
+ int bit = 0;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ val = zone->u.mzone.notify;
+ bit = MZ_DIALUP_BIT;
+ bits = &zone->u.mzone.setflags;
+ break;
+
+ case dns_c_zone_slave:
+ val = zone->u.szone.notify;
+ bit = SZ_DIALUP_BIT;
+ bits = &zone->u.szone.setflags;
+ break;
+
+ case dns_c_zone_stub:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Stub zones do not have a notify field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a notify field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a notify field");
+ return (ISC_R_FAILURE);
+ }
+
+ if (DNS_C_CHECKBIT(bit,bits)) {
+ *retval = val;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_getmaintixfrbase(dns_c_zone_t *zone,
+ isc_boolean_t *retval)
+{
+ isc_result_t res;
+ dns_c_setbits_t *bits = NULL;
+ isc_boolean_t val = ISC_FALSE;
+ int bit = 0;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ val = zone->u.mzone.maint_ixfr_base;
+ bit = MZ_MAINT_IXFR_BASE_BIT;
+ bits = &zone->u.mzone.setflags;
+ break;
+
+ case dns_c_zone_slave:
+ val = zone->u.szone.maint_ixfr_base;
+ bit = SZ_MAINT_IXFR_BASE_BIT;
+ bits = &zone->u.szone.setflags;
+ break;
+
+ case dns_c_zone_stub:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Stub zones do not have a notify field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a notify field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a notify field");
+ return (ISC_R_FAILURE);
+ }
+
+ if (DNS_C_CHECKBIT(bit,bits)) {
+ *retval = val;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_getalsonotify(dns_c_zone_t *zone,
+ dns_c_iplist_t **retval)
+{
+ dns_c_iplist_t *p = NULL;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ p = zone->u.mzone.also_notify ;
+ break;
+
+ case dns_c_zone_slave:
+ p = zone->u.szone.also_notify ;
+ break;
+
+ case dns_c_zone_stub:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Stub zones do not have a also_notify field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a also_notify field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a also_notify field");
+ return (ISC_R_FAILURE);
+ }
+
+ if (p != NULL) {
+ *retval = p;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_getixfrbase(dns_c_zone_t *zone,
+ const char **retval)
+{
+ char *p = NULL;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ p = zone->u.mzone.ixfr_base;
+ break;
+
+ case dns_c_zone_slave:
+ p = zone->u.szone.ixfr_base;
+ break;
+
+ case dns_c_zone_stub:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Stub zones do not have a ixfr_base field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a ixfr_base field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a file field");
+ return (ISC_R_FAILURE);
+ }
+
+ if (p != NULL) {
+ *retval = p;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_getixfrtmp(dns_c_zone_t *zone, const char **retval)
+{
+ char *p = NULL;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ p = zone->u.mzone.ixfr_tmp;
+ break;
+
+ case dns_c_zone_slave:
+ p = zone->u.szone.ixfr_tmp;
+ break;
+
+ case dns_c_zone_stub:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Stub zones do not have a ixfr_tmp field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a ixfr_tmp field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a file field");
+ return (ISC_R_FAILURE);
+ }
+
+ if (p != NULL) {
+ *retval = p;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_getpubkeylist(dns_c_zone_t *zone,
+ dns_c_pklist_t **retval)
+{
+ dns_c_pklist_t *p = NULL;
+ isc_result_t res;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ p = zone->u.mzone.pubkeylist;
+ break;
+
+ case dns_c_zone_slave:
+ p = zone->u.szone.pubkeylist;
+ break;
+
+ case dns_c_zone_stub:
+ p = zone->u.tzone.pubkeylist;
+ break;
+
+ case dns_c_zone_hint:
+#if 1
+ p = zone->u.hzone.pubkeylist;
+#else
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a pubkey field");
+#endif
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a pubkey field");
+ return (ISC_R_FAILURE);
+ }
+
+ if (p != NULL) {
+ *retval = p;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_getmasterport(dns_c_zone_t *zone,
+ in_port_t *retval)
+{
+ isc_result_t res = ISC_R_SUCCESS;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch(zone->ztype) {
+ case dns_c_zone_master:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a "
+ "master_port field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_slave:
+ if (DNS_C_CHECKBIT(SZ_MASTER_PORT_BIT,
+ &zone->u.szone.setflags)) {
+ *retval = zone->u.szone.master_port;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+ case dns_c_zone_stub:
+ if (DNS_C_CHECKBIT(TZ_MASTER_PORT_BIT,
+ &zone->u.tzone.setflags)) {
+ *retval = zone->u.tzone.master_port;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a master_port field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a "
+ "master_port field");
+ return (ISC_R_FAILURE);
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_getmasterips(dns_c_zone_t *zone,
+ dns_c_iplist_t **retval)
+{
+ isc_result_t res = ISC_R_SUCCESS;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Master zones do not have a master_ips field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_slave:
+ if (zone->u.szone.master_ips != NULL) {
+ *retval = zone->u.szone.master_ips;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+ case dns_c_zone_stub:
+ if (zone->u.tzone.master_ips != NULL) {
+ *retval = zone->u.tzone.master_ips;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a master_ips field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a master_ips field");
+ return (ISC_R_FAILURE);
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_gettransfersource(dns_c_zone_t *zone,
+ isc_sockaddr_t *retval)
+{
+ isc_result_t res = ISC_R_SUCCESS;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Master zones do not have a "
+ "transfer_source field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_slave:
+ if (DNS_C_CHECKBIT(SZ_TRANSFER_SOURCE_BIT,
+ &zone->u.szone.setflags)) {
+ *retval = zone->u.szone.transfer_source ;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ break;
+
+ case dns_c_zone_stub:
+ if (DNS_C_CHECKBIT(TZ_TRANSFER_SOURCE_BIT,
+ &zone->u.tzone.setflags)) {
+ *retval = zone->u.tzone.transfer_source ;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a master_ips field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a master_ips field");
+ return (ISC_R_FAILURE);
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_getmaxtranstimein(dns_c_zone_t *zone,
+ isc_int32_t *retval)
+{
+ isc_result_t res = ISC_R_SUCCESS;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Master zones do not have a "
+ "max_trans_time_in field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_slave:
+ if (DNS_C_CHECKBIT(SZ_MAX_TRANS_TIME_IN_BIT,
+ &zone->u.szone.setflags)) {
+ *retval = zone->u.szone.max_trans_time_in;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+ case dns_c_zone_stub:
+ if (DNS_C_CHECKBIT(TZ_MAX_TRANS_TIME_IN_BIT,
+ &zone->u.tzone.setflags)) {
+ *retval = zone->u.tzone.max_trans_time_in;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a "
+ "max_trans_time_in field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a "
+ "max_trans_time_in field");
+ return (ISC_R_FAILURE);
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_getmaxtranstimeout(dns_c_zone_t *zone,
+ isc_int32_t *retval)
+{
+ isc_result_t res = ISC_R_SUCCESS;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ if (DNS_C_CHECKBIT(SZ_MAX_TRANS_TIME_OUT_BIT,
+ &zone->u.mzone.setflags)) {
+ *retval = zone->u.mzone.max_trans_time_out;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+ case dns_c_zone_slave:
+ if (DNS_C_CHECKBIT(SZ_MAX_TRANS_TIME_OUT_BIT,
+ &zone->u.szone.setflags)) {
+ *retval = zone->u.szone.max_trans_time_out;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+ case dns_c_zone_stub:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Stub zones do not have a "
+ "max_trans_time_out field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a "
+ "max_trans_time_out field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a "
+ "max_trans_time_out field");
+ return (ISC_R_FAILURE);
+ }
+
+ return (res);
+}
+
+
+
+isc_result_t
+dns_c_zone_getmaxtransidlein(dns_c_zone_t *zone,
+ isc_int32_t *retval)
+{
+ isc_result_t res = ISC_R_SUCCESS;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Master zones do not have a "
+ "max_trans_idle_in field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_slave:
+ if (DNS_C_CHECKBIT(SZ_MAX_TRANS_IDLE_IN_BIT,
+ &zone->u.szone.setflags)) {
+ *retval = zone->u.szone.max_trans_idle_in;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+ case dns_c_zone_stub:
+ if (DNS_C_CHECKBIT(TZ_MAX_TRANS_IDLE_IN_BIT,
+ &zone->u.tzone.setflags)) {
+ *retval = zone->u.tzone.max_trans_idle_in;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a "
+ "max_trans_idle_in field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a "
+ "max_trans_idle_in field");
+ return (ISC_R_FAILURE);
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_getmaxtransidleout(dns_c_zone_t *zone,
+ isc_int32_t *retval)
+{
+ isc_result_t res = ISC_R_SUCCESS;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ if (DNS_C_CHECKBIT(SZ_MAX_TRANS_IDLE_OUT_BIT,
+ &zone->u.mzone.setflags)) {
+ *retval = zone->u.mzone.max_trans_idle_out;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+
+ case dns_c_zone_slave:
+ if (DNS_C_CHECKBIT(SZ_MAX_TRANS_IDLE_OUT_BIT,
+ &zone->u.szone.setflags)) {
+ *retval = zone->u.szone.max_trans_idle_out;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+ case dns_c_zone_stub:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Stub zones do not have a "
+ "max_trans_idle_out field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a "
+ "max_trans_idle_out field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a "
+ "max_trans_idle_out field");
+ return (ISC_R_FAILURE);
+ }
+
+ return (res);
+}
+
+
+
+isc_result_t
+dns_c_zone_getmaxixfrlog(dns_c_zone_t *zone,
+ isc_int32_t *retval)
+{
+ isc_result_t res;
+ dns_c_setbits_t *bits = NULL;
+ int bit = 0;
+ isc_int32_t *ptr = NULL;
+
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ bits = &zone->u.mzone.setflags;
+ bit = MZ_MAX_IXFR_LOG_BIT;
+ ptr = &zone->u.mzone.max_ixfr_log;
+ break;
+
+ case dns_c_zone_slave:
+ bits = &zone->u.szone.setflags;
+ bit = SZ_MAX_IXFR_LOG_BIT;
+ ptr = &zone->u.szone.max_ixfr_log;
+ break;
+
+ case dns_c_zone_stub:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Stub zones do not have a max_ixfr_log field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a max_ixfr_log field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Forward zones do not have a "
+ "max_ixfr_log field");
+ return (ISC_R_FAILURE);
+ }
+
+ if (DNS_C_CHECKBIT(bit, bits)) {
+ *retval = *ptr;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_getforward(dns_c_zone_t *zone,
+ dns_c_forw_t *retval)
+{
+ isc_result_t res = ISC_R_SUCCESS;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ if (DNS_C_CHECKBIT(MZ_FORWARD_BIT, &zone->u.mzone.setflags)) {
+ *retval = zone->u.mzone.forward;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+ case dns_c_zone_slave:
+ if (DNS_C_CHECKBIT(SZ_FORWARD_BIT, &zone->u.szone.setflags)) {
+ *retval = zone->u.szone.forward;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+ case dns_c_zone_stub:
+ if (DNS_C_CHECKBIT(TZ_FORWARD_BIT, &zone->u.tzone.setflags)) {
+ *retval = zone->u.tzone.forward;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a forward field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ if (DNS_C_CHECKBIT(FZ_FORWARD_BIT, &zone->u.fzone.setflags)) {
+ *retval = zone->u.fzone.forward;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+ }
+
+ return (res);
+}
+
+
+isc_result_t
+dns_c_zone_getforwarders(dns_c_zone_t *zone,
+ dns_c_iplist_t **retval)
+{
+ isc_result_t res = ISC_R_SUCCESS;
+
+ REQUIRE(DNS_C_ZONE_VALID(zone));
+ REQUIRE(retval != NULL);
+
+ switch (zone->ztype) {
+ case dns_c_zone_master:
+ if (zone->u.mzone.forwarders != NULL &&
+ zone->u.mzone.forwarders->nextidx > 0) {
+ *retval = zone->u.mzone.forwarders;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+ case dns_c_zone_slave:
+ if (zone->u.szone.forwarders != NULL &&
+ zone->u.szone.forwarders->nextidx > 0) {
+ *retval = zone->u.szone.forwarders;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+ case dns_c_zone_stub:
+ if (zone->u.tzone.forwarders != NULL &&
+ zone->u.tzone.forwarders->nextidx > 0) {
+ *retval = zone->u.tzone.forwarders;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+
+ case dns_c_zone_hint:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CONFIG,
+ DNS_LOGMODULE_CONFIG, ISC_LOG_CRITICAL,
+ "Hint zones do not have a forwarders field");
+ return (ISC_R_FAILURE);
+
+ case dns_c_zone_forward:
+ if (zone->u.fzone.forwarders != NULL &&
+ zone->u.fzone.forwarders->nextidx > 0) {
+ *retval = zone->u.fzone.forwarders;
+ res = ISC_R_SUCCESS;
+ } else {
+ res = ISC_R_NOTFOUND;
+ }
+ break;
+ }
+
+ return (res);
+}
+
+
+/*
+ * Zone privates
+ */
+
+static void
+master_zone_print(FILE *fp, int indent,
+ dns_c_masterzone_t *mzone)
+{
+ REQUIRE(mzone != NULL);
+
+ if (mzone->file != NULL) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "file \"%s\";\n", mzone->file);
+ }
+
+ if (DNS_C_CHECKBIT(MZ_CHECK_NAME_BIT, &mzone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "check-names %s;\n",
+ dns_c_nameseverity2string(mzone->check_names,
+ ISC_TRUE));
+ }
+
+ if (mzone->allow_update != NULL &&
+ !ISC_LIST_EMPTY(mzone->allow_update->elements)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "allow-update ");
+ dns_c_ipmatchlist_print(fp, indent + 1,
+ mzone->allow_update);
+ fprintf(fp, ";\n");
+ }
+
+ if (mzone->allow_query != NULL &&
+ !ISC_LIST_EMPTY(mzone->allow_query->elements)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "allow-query ");
+ dns_c_ipmatchlist_print(fp, indent + 1,
+ mzone->allow_query);
+ fprintf(fp, ";\n");
+ }
+
+ if (mzone->allow_transfer != NULL &&
+ !ISC_LIST_EMPTY(mzone->allow_transfer->elements)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "allow-transfer ");
+ dns_c_ipmatchlist_print(fp, indent + 1,
+ mzone->allow_transfer);
+ fprintf(fp, ";\n");
+ }
+
+ if (DNS_C_CHECKBIT(MZ_DIALUP_BIT, &mzone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "dialup %s;\n",
+ (mzone->dialup ? "true" : "false"));
+ }
+
+ if (DNS_C_CHECKBIT(MZ_MAINT_IXFR_BASE_BIT, &mzone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "maintain-ixfr-base %s;\n",
+ (mzone->maint_ixfr_base ? "true" : "false"));
+ }
+
+ if (DNS_C_CHECKBIT(MZ_NOTIFY_BIT, &mzone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "notify %s;\n",
+ (mzone->notify ? "true" : "false"));
+ }
+
+ if (mzone->also_notify != NULL) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "also-notify ");
+ dns_c_iplist_print(fp, indent + 1, mzone->also_notify);
+ fprintf(fp, ";\n");
+ }
+
+ if (mzone->ixfr_base != NULL) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "ixfr-base \"%s\";\n", mzone->ixfr_base);
+ }
+
+ if (mzone->ixfr_tmp != NULL) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "ixfr-tmp-file \"%s\";\n", mzone->ixfr_tmp);
+ }
+
+ if (DNS_C_CHECKBIT(MZ_MAX_TRANS_IDLE_OUT_BIT, &mzone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "max-transfer-idle-out %d;\n",
+ mzone->max_trans_idle_out / 60);
+ }
+
+ if (DNS_C_CHECKBIT(MZ_MAX_TRANS_TIME_OUT_BIT, &mzone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "max-transfer-time-out %d;\n",
+ mzone->max_trans_time_out / 60);
+ }
+
+ if (mzone->pubkeylist != NULL) {
+ fprintf(fp, "\n");
+ dns_c_pklist_print(fp, indent, mzone->pubkeylist);
+ }
+
+ if (DNS_C_CHECKBIT(MZ_FORWARD_BIT, &mzone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "forward %s;\n",
+ dns_c_forward2string(mzone->forward, ISC_TRUE));
+ }
+
+ if (mzone->forwarders != NULL && mzone->forwarders->nextidx > 0) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "forwarders ");
+ dns_c_iplist_print(fp, indent + 1,
+ mzone->forwarders);
+ fprintf(fp, ";\n");
+ }
+}
+
+
+static void
+slave_zone_print(FILE *fp, int indent,
+ dns_c_slavezone_t *szone)
+{
+ REQUIRE(szone != NULL);
+
+ if (szone->file != NULL) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "file \"%s\";\n", szone->file);
+ }
+
+ if (szone->ixfr_base != NULL) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "ixfr-base \"%s\";\n", szone->ixfr_base);
+ }
+
+ if (szone->ixfr_tmp != NULL) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "ixfr-tmp-file \"%s\";\n", szone->ixfr_tmp);
+ }
+
+ if (DNS_C_CHECKBIT(SZ_MAINT_IXFR_BASE_BIT, &szone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "maintain-ixfr-base %s;\n",
+ (szone->maint_ixfr_base ? "true" : "false"));
+ }
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "masters ");
+ if (DNS_C_CHECKBIT(SZ_MASTER_PORT_BIT, &szone->setflags)) {
+ if (szone->master_port != 0) {
+ fprintf(fp, "port %d ", szone->master_port);
+ }
+ }
+ if (szone->master_ips == NULL ||
+ szone->master_ips->nextidx == 0) {
+ fprintf(fp, "{ /* none defined */ }");
+ } else {
+ dns_c_iplist_print(fp, indent + 1, szone->master_ips);
+ }
+ fprintf(fp, ";\n");
+
+ if (DNS_C_CHECKBIT(SZ_FORWARD_BIT, &szone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "forward %s;\n",
+ dns_c_forward2string(szone->forward, ISC_TRUE));
+ }
+
+ if (szone->forwarders != NULL && szone->forwarders->nextidx > 0) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "forwarders ");
+ dns_c_iplist_print(fp, indent + 1,
+ szone->forwarders);
+ fprintf(fp, ";\n");
+ }
+
+ if (DNS_C_CHECKBIT(SZ_CHECK_NAME_BIT, &szone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "check-names %s;\n",
+ dns_c_nameseverity2string(szone->check_names,
+ ISC_TRUE));
+ }
+
+ if (szone->allow_update != NULL &&
+ !ISC_LIST_EMPTY(szone->allow_update->elements)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "allow-update ");
+ dns_c_ipmatchlist_print(fp, indent + 1,
+ szone->allow_update);
+ fprintf(fp, ";\n");
+ }
+
+ if (szone->allow_query != NULL &&
+ !ISC_LIST_EMPTY(szone->allow_query->elements)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "allow-query ");
+ dns_c_ipmatchlist_print(fp, indent + 1,
+ szone->allow_query);
+ fprintf(fp, ";\n");
+ }
+
+ if (szone->allow_transfer != NULL &&
+ !ISC_LIST_EMPTY(szone->allow_transfer->elements)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "allow-transfer ");
+ dns_c_ipmatchlist_print(fp, indent + 1,
+ szone->allow_transfer);
+ fprintf(fp, ";\n");
+ }
+
+ if (DNS_C_CHECKBIT(SZ_TRANSFER_SOURCE_BIT, &szone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "transfer-source ");
+ dns_c_print_ipaddr(fp, &szone->transfer_source);
+ fprintf(fp, " ;\n");
+ }
+
+ if (DNS_C_CHECKBIT(SZ_MAX_TRANS_TIME_IN_BIT, &szone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "max-transfer-time-in %d;\n",
+ szone->max_trans_time_in / 60);
+ }
+
+ if (DNS_C_CHECKBIT(SZ_MAX_TRANS_TIME_OUT_BIT, &szone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "max-transfer-time-out %d;\n",
+ szone->max_trans_time_out / 60);
+ }
+
+ if (DNS_C_CHECKBIT(SZ_MAX_TRANS_IDLE_IN_BIT, &szone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "max-transfer-idle-in %d;\n",
+ szone->max_trans_idle_in / 60);
+ }
+
+ if (DNS_C_CHECKBIT(SZ_MAX_TRANS_IDLE_OUT_BIT, &szone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "max-transfer-idle-out %d;\n",
+ szone->max_trans_idle_out / 60);
+ }
+
+ if (DNS_C_CHECKBIT(SZ_DIALUP_BIT, &szone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "dialup %s;\n",
+ (szone->dialup ? "true" : "false"));
+ }
+
+ if (DNS_C_CHECKBIT(SZ_NOTIFY_BIT, &szone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "notify %s;\n",
+ (szone->notify ? "true" : "false"));
+ }
+
+ if (szone->also_notify != NULL) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "also-notify ");
+ dns_c_iplist_print(fp, indent + 1, szone->also_notify);
+ fprintf(fp, ";\n");
+ }
+
+ if (szone->pubkeylist != NULL) {
+ fprintf(fp, "\n");
+ dns_c_pklist_print(fp, indent, szone->pubkeylist);
+ }
+}
+
+
+static void
+stub_zone_print(FILE *fp, int indent, dns_c_stubzone_t *tzone)
+{
+ REQUIRE(tzone != NULL);
+
+ if (tzone->file != NULL) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "file \"%s\";\n", tzone->file);
+ }
+
+
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "masters ");
+ if (DNS_C_CHECKBIT(TZ_MASTER_PORT_BIT, &tzone->setflags)) {
+ if (tzone->master_port != 0) {
+ fprintf(fp, "port %d ", tzone->master_port);
+ }
+ }
+ if (tzone->master_ips == NULL ||
+ tzone->master_ips->nextidx == 0) {
+ fprintf(fp, "{ /* none defined */ }");
+ } else {
+ dns_c_iplist_print(fp, indent + 1, tzone->master_ips);
+ }
+ fprintf(fp, ";\n");
+
+ if (DNS_C_CHECKBIT(TZ_FORWARD_BIT, &tzone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "forward %s;\n",
+ dns_c_forward2string(tzone->forward, ISC_TRUE));
+ }
+
+ if (tzone->forwarders != NULL && tzone->forwarders->nextidx > 0) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "forwarders ");
+ dns_c_iplist_print(fp, indent + 1,
+ tzone->forwarders);
+ fprintf(fp, ";\n");
+ }
+
+ if (DNS_C_CHECKBIT(TZ_CHECK_NAME_BIT, &tzone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "check-names %s;\n",
+ dns_c_nameseverity2string(tzone->check_names,
+ ISC_TRUE));
+ }
+
+ if (tzone->allow_update != NULL &&
+ !ISC_LIST_EMPTY(tzone->allow_update->elements)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "allow-update ");
+ dns_c_ipmatchlist_print(fp, indent + 1,
+ tzone->allow_update);
+ fprintf(fp, ";\n");
+ }
+
+ if (tzone->allow_query != NULL &&
+ !ISC_LIST_EMPTY(tzone->allow_query->elements)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "allow-query ");
+ dns_c_ipmatchlist_print(fp, indent + 1,
+ tzone->allow_query);
+ fprintf(fp, ";\n");
+ }
+
+ if (tzone->allow_transfer != NULL &&
+ !ISC_LIST_EMPTY(tzone->allow_transfer->elements)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "allow-transfer ");
+ dns_c_ipmatchlist_print(fp, indent + 1,
+ tzone->allow_transfer);
+ fprintf(fp, ";\n");
+ }
+
+ if (DNS_C_CHECKBIT(TZ_DIALUP_BIT, &tzone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "dialup %s;\n",
+ (tzone->dialup ? "true" : "false"));
+ }
+
+ if (DNS_C_CHECKBIT(TZ_TRANSFER_SOURCE_BIT, &tzone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "transfer-source ");
+ dns_c_print_ipaddr(fp, &tzone->transfer_source);
+ fprintf(fp, ";\n");
+ }
+
+ if (DNS_C_CHECKBIT(TZ_MAX_TRANS_TIME_IN_BIT, &tzone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "max-transfer-time-in %d;\n",
+ tzone->max_trans_time_in / 60);
+ }
+
+ if (DNS_C_CHECKBIT(TZ_MAX_TRANS_IDLE_IN_BIT, &tzone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "max-transfer-idle-in %d;\n",
+ tzone->max_trans_idle_in / 60);
+ }
+
+ if (tzone->pubkeylist != NULL) {
+ fprintf(fp, "\n");
+ dns_c_pklist_print(fp, indent, tzone->pubkeylist);
+ }
+}
+
+
+static void
+hint_zone_print(FILE *fp, int indent, dns_c_hintzone_t *hzone)
+{
+ REQUIRE(hzone != NULL);
+
+ if (hzone->file != NULL) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "file \"%s\";\n", hzone->file);
+ }
+
+ if (DNS_C_CHECKBIT(HZ_CHECK_NAME_BIT, &hzone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "check-names %s;\n",
+ dns_c_nameseverity2string(hzone->check_names,
+ ISC_TRUE));
+ }
+
+ if (hzone->pubkeylist != NULL) {
+ fprintf(fp, "\n");
+ dns_c_pklist_print(fp, indent, hzone->pubkeylist);
+ }
+}
+
+
+static void
+forward_zone_print(FILE *fp, int indent,
+ dns_c_forwardzone_t *fzone)
+{
+ REQUIRE(fzone != NULL);
+
+ if (DNS_C_CHECKBIT(FZ_FORWARD_BIT, &fzone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "forward %s;\n",
+ dns_c_forward2string(fzone->forward, ISC_TRUE));
+ }
+
+ if (fzone->forwarders != NULL && fzone->forwarders->nextidx > 0) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "forwarders ");
+ dns_c_iplist_print(fp, indent + 1,
+ fzone->forwarders);
+ fprintf(fp, ";\n");
+ }
+
+ if (DNS_C_CHECKBIT(FZ_CHECK_NAME_BIT, &fzone->setflags)) {
+ dns_c_printtabs(fp, indent);
+ fprintf(fp, "check-names %s;\n",
+ dns_c_nameseverity2string(fzone->check_names,
+ ISC_TRUE));
+ }
+}
+
+
+static isc_result_t
+master_zone_init(dns_c_masterzone_t *mzone)
+{
+ REQUIRE(mzone != NULL);
+
+ mzone->file = NULL;
+ mzone->allow_update = NULL;
+ mzone->allow_query = NULL;
+ mzone->allow_transfer = NULL;
+ mzone->also_notify = NULL;
+ mzone->ixfr_base = NULL;
+ mzone->ixfr_tmp = NULL;
+ mzone->pubkeylist = NULL;
+ mzone->forwarders = NULL;
+
+ memset(&mzone->setflags, 0x0, sizeof (mzone->setflags));
+
+ return (ISC_R_SUCCESS);
+}
+
+
+static isc_result_t
+slave_zone_init(dns_c_slavezone_t *szone)
+{
+ REQUIRE(szone != NULL);
+
+ szone->file = NULL;
+ szone->ixfr_base = NULL;
+ szone->ixfr_tmp = NULL;
+ szone->master_ips = NULL;
+ szone->allow_update = NULL;
+ szone->allow_query = NULL;
+ szone->allow_transfer = NULL;
+ szone->also_notify = NULL;
+ szone->pubkeylist = NULL;
+ szone->forwarders = NULL;
+
+ memset(&szone->setflags, 0x0, sizeof (szone->setflags));
+
+ return (ISC_R_SUCCESS);
+}
+
+
+static isc_result_t
+stub_zone_init(dns_c_stubzone_t *tzone)
+{
+ REQUIRE(tzone != NULL);
+
+ tzone->file = NULL;
+ tzone->master_ips = NULL;
+ tzone->allow_update = NULL;
+ tzone->allow_query = NULL;
+ tzone->allow_transfer = NULL;
+ tzone->pubkeylist = NULL;
+ tzone->forwarders = NULL;
+
+ memset(&tzone->setflags, 0x0, sizeof (tzone->setflags));
+
+ return (ISC_R_SUCCESS);
+}
+
+
+static isc_result_t
+hint_zone_init(dns_c_hintzone_t *hzone)
+{
+ REQUIRE(hzone != NULL);
+
+ hzone->file = NULL;
+ hzone->pubkeylist = NULL;
+ memset(&hzone->setflags, 0x0, sizeof (hzone->setflags));
+
+ return (ISC_R_SUCCESS);
+}
+
+
+static isc_result_t
+forward_zone_init(dns_c_forwardzone_t *fzone)
+{
+ REQUIRE(fzone != NULL);
+
+ fzone->forwarders = NULL;
+ memset(&fzone->setflags, 0x0, sizeof (fzone->setflags));
+
+ return (ISC_R_SUCCESS);
+}
+
+
+static isc_result_t
+zone_delete(dns_c_zone_t **zone)
+{
+ dns_c_zone_t *z;
+ isc_result_t res = ISC_R_SUCCESS;
+
+ REQUIRE(zone != NULL);
+ REQUIRE(DNS_C_ZONE_VALID(*zone));
+
+ z = *zone;
+
+ isc_mem_free(z->mem, z->name);
+ isc_mem_free(z->mem, z->internalname);
+
+ switch(z->ztype) {
+ case dns_c_zone_master:
+ res = master_zone_clear(z->mem, &z->u.mzone);
+ break;
+
+ case dns_c_zone_slave:
+ res = slave_zone_clear(z->mem, &z->u.szone);
+ break;
+
+ case dns_c_zone_stub:
+ res = stub_zone_clear(z->mem, &z->u.tzone);
+ break;
+
+ case dns_c_zone_hint:
+ res = hint_zone_clear(z->mem, &z->u.hzone);
+ break;
+
+ case dns_c_zone_forward:
+ res = forward_zone_clear(z->mem, &z->u.fzone);
+ break;
+ }
+
+ z->magic = 0;
+ z->view = NULL;
+ isc_mem_put(z->mem, z, sizeof *z);
+
+ return (res);
+}
+
+
+static isc_result_t
+master_zone_clear(isc_mem_t *mem, dns_c_masterzone_t *mzone)
+{
+ REQUIRE(mzone != NULL);
+
+ if (mzone == NULL) {
+ return (ISC_R_SUCCESS);
+ }
+
+ if (mzone->file != NULL) {
+ isc_mem_free(mem, mzone->file);
+ }
+
+ if (mzone->allow_update != NULL)
+ dns_c_ipmatchlist_detach(&mzone->allow_update);
+
+ if (mzone->allow_query != NULL)
+ dns_c_ipmatchlist_detach(&mzone->allow_query);
+
+ if (mzone->allow_transfer != NULL)
+ dns_c_ipmatchlist_detach(&mzone->allow_transfer);
+
+ if (mzone->also_notify != NULL)
+ dns_c_iplist_detach(&mzone->also_notify);
+
+ if (mzone->ixfr_base != NULL) {
+ isc_mem_free(mem, mzone->ixfr_base);
+ }
+
+ if (mzone->ixfr_tmp != NULL) {
+ isc_mem_free(mem, mzone->ixfr_tmp);
+ }
+
+ if (mzone->pubkeylist != NULL)
+ dns_c_pklist_delete(&mzone->pubkeylist);
+
+ if (mzone->forwarders != NULL)
+ dns_c_iplist_detach(&mzone->forwarders);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+static isc_result_t
+slave_zone_clear(isc_mem_t *mem, dns_c_slavezone_t *szone)
+{
+ REQUIRE(szone != NULL);
+
+ if (szone == NULL) {
+ return (ISC_R_SUCCESS);
+ }
+
+ if (szone->file != NULL) {
+ isc_mem_free(mem, szone->file);
+ }
+
+ if (szone->ixfr_base != NULL) {
+ isc_mem_free(mem, szone->ixfr_base);
+ }
+
+ if (szone->ixfr_tmp != NULL) {
+ isc_mem_free(mem, szone->ixfr_tmp);
+ }
+
+ if (szone->master_ips != NULL)
+ dns_c_iplist_detach(&szone->master_ips);
+
+ if (szone->allow_update != NULL)
+ dns_c_ipmatchlist_detach(&szone->allow_update);
+
+ if (szone->allow_query != NULL)
+ dns_c_ipmatchlist_detach(&szone->allow_query);
+
+ if (szone->allow_transfer != NULL)
+ dns_c_ipmatchlist_detach(&szone->allow_transfer);
+
+ if (szone->also_notify != NULL)
+ dns_c_iplist_detach(&szone->also_notify);
+
+ if (szone->forwarders != NULL)
+ dns_c_iplist_detach(&szone->forwarders);
+
+ if (szone->pubkeylist != NULL)
+ dns_c_pklist_delete(&szone->pubkeylist);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+
+static isc_result_t
+stub_zone_clear(isc_mem_t *mem, dns_c_stubzone_t *tzone)
+{
+ REQUIRE(tzone != NULL);
+
+ if (tzone == NULL) {
+ return (ISC_R_SUCCESS);
+ }
+
+ if (tzone->file != NULL) {
+ isc_mem_free(mem, tzone->file);
+ }
+
+ if (tzone->master_ips != NULL)
+ dns_c_iplist_detach(&tzone->master_ips);
+
+ if (tzone->allow_update != NULL)
+ dns_c_ipmatchlist_detach(&tzone->allow_update);
+
+ if (tzone->allow_query != NULL)
+ dns_c_ipmatchlist_detach(&tzone->allow_query);
+
+ if (tzone->allow_transfer != NULL)
+ dns_c_ipmatchlist_detach(&tzone->allow_transfer);
+
+ if (tzone->forwarders != NULL)
+ dns_c_iplist_detach(&tzone->forwarders);
+
+ if (tzone->pubkeylist != NULL)
+ dns_c_pklist_delete(&tzone->pubkeylist);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+static isc_result_t
+forward_zone_clear(isc_mem_t *mem, dns_c_forwardzone_t *fzone)
+{
+ REQUIRE(fzone != NULL);
+
+ if (fzone == NULL) {
+ return (ISC_R_SUCCESS);
+ }
+
+ (void) mem; /* lint happiness */
+
+ if (fzone->forwarders != NULL)
+ dns_c_iplist_detach(&fzone->forwarders);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+static isc_result_t
+hint_zone_clear(isc_mem_t *mem, dns_c_hintzone_t *hzone)
+{
+ REQUIRE(hzone != NULL);
+
+ if (hzone == NULL) {
+ return (ISC_R_SUCCESS);
+ }
+
+ if (hzone->file != NULL) {
+ isc_mem_free(mem, hzone->file);
+ }
+
+ if (hzone->pubkeylist != NULL)
+ dns_c_pklist_delete(&hzone->pubkeylist);
+
+ return (ISC_R_SUCCESS);
+}
+
+
+/**************************************************/
+
+static isc_result_t
+set_ipmatch_list_field(isc_mem_t *mem,
+ dns_c_ipmatchlist_t **dest, dns_c_ipmatchlist_t *src,
+ isc_boolean_t deepcopy)
+{
+ isc_result_t res;
+
+ if (*dest != NULL) {
+ res = dns_c_ipmatchlist_detach(dest);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ }
+
+ if (deepcopy) {
+ res = dns_c_ipmatchlist_copy(mem, dest, src);
+ } else {
+ *dest = src;
+ res = ISC_R_SUCCESS;
+ }
+
+ return (res);
+}
+
+
+static isc_result_t
+set_iplist_field(isc_mem_t *mem,
+ dns_c_iplist_t **dest, dns_c_iplist_t *src,
+ isc_boolean_t deepcopy)
+{
+ isc_result_t res;
+
+ if (*dest != NULL) {
+ res = dns_c_iplist_detach(dest);
+ if (res != ISC_R_SUCCESS) {
+ return (res);
+ }
+ }
+
+ if (deepcopy) {
+ res = dns_c_iplist_copy(mem, dest, src);
+ } else {
+ *dest = src;
+ res = ISC_R_SUCCESS;
+ }
+
+ return (res);
+}
+