diff options
Diffstat (limited to 'contrib/bind9/bin/named')
67 files changed, 0 insertions, 27070 deletions
diff --git a/contrib/bind9/bin/named/Makefile.in b/contrib/bind9/bin/named/Makefile.in deleted file mode 100644 index 50fb93bf11d9..000000000000 --- a/contrib/bind9/bin/named/Makefile.in +++ /dev/null @@ -1,135 +0,0 @@ -# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 1998-2002 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 ISC DISCLAIMS ALL WARRANTIES WITH -# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, -# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -# PERFORMANCE OF THIS SOFTWARE. - -# $Id: Makefile.in,v 1.74.12.11 2004/09/06 21:47:25 marka Exp $ - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -@BIND9_VERSION@ - -@BIND9_MAKE_INCLUDES@ - -# -# Add database drivers here. -# -DBDRIVER_OBJS = -DBDRIVER_SRCS = -DBDRIVER_INCLUDES = -DBDRIVER_LIBS = - -CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include \ - ${LWRES_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES} \ - ${ISCCFG_INCLUDES} ${ISCCC_INCLUDES} ${ISC_INCLUDES} \ - ${DBDRIVER_INCLUDES} - -CDEFINES = -CWARNINGS = - -DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ -ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@ -ISCCCLIBS = ../../lib/isccc/libisccc.@A@ -ISCLIBS = ../../lib/isc/libisc.@A@ -LWRESLIBS = ../../lib/lwres/liblwres.@A@ -BIND9LIBS = ../../lib/bind9/libbind9.@A@ - -DNSDEPLIBS = ../../lib/dns/libdns.@A@ -ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@ -ISCCCDEPLIBS = ../../lib/isccc/libisccc.@A@ -ISCDEPLIBS = ../../lib/isc/libisc.@A@ -LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@ -BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@ - -DEPLIBS = ${LWRESDEPLIBS} ${DNSDEPLIBS} ${BIND9DEPLIBS} \ - ${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${ISCDEPLIBS} - -LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} \ - ${ISCCFGLIBS} ${ISCCCLIBS} ${ISCLIBS} ${DBDRIVER_LIBS} @LIBS@ - -SUBDIRS = unix - -TARGETS = named@EXEEXT@ lwresd@EXEEXT@ - -OBJS = aclconf.@O@ builtin.@O@ client.@O@ config.@O@ control.@O@ \ - controlconf.@O@ interfacemgr.@O@ \ - listenlist.@O@ log.@O@ logconf.@O@ main.@O@ notify.@O@ \ - query.@O@ server.@O@ sortlist.@O@ \ - tkeyconf.@O@ tsigconf.@O@ update.@O@ xfrout.@O@ \ - zoneconf.@O@ \ - lwaddr.@O@ lwresd.@O@ lwdclient.@O@ lwderror.@O@ lwdgabn.@O@ \ - lwdgnba.@O@ lwdgrbn.@O@ lwdnoop.@O@ lwsearch.@O@ \ - $(DBDRIVER_OBJS) - -UOBJS = unix/os.@O@ - -SRCS = aclconf.c builtin.c client.c config.c control.c \ - controlconf.c interfacemgr.c \ - listenlist.c log.c logconf.c main.c notify.c \ - query.c server.c sortlist.c \ - tkeyconf.c tsigconf.c update.c xfrout.c \ - zoneconf.c \ - lwaddr.c lwresd.c lwdclient.c lwderror.c lwdgabn.c \ - lwdgnba.c lwdgrbn.c lwdnoop.c lwsearch.c \ - $(DBDRIVER_SRCS) - -MANPAGES = named.8 lwresd.8 named.conf.5 - -HTMLPAGES = named.html lwresd.html named.conf.html - -MANOBJS = ${MANPAGES} ${HTMLPAGES} - -@BIND9_MAKE_RULES@ - -main.@O@: main.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ - -DVERSION=\"${VERSION}\" \ - -DNS_LOCALSTATEDIR=\"${localstatedir}\" \ - -DNS_SYSCONFDIR=\"${sysconfdir}\" -c ${srcdir}/main.c - -config.@O@: config.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ - -DVERSION=\"${VERSION}\" \ - -DNS_LOCALSTATEDIR=\"${localstatedir}\" \ - -c ${srcdir}/config.c - -named@EXEEXT@: ${OBJS} ${UOBJS} ${DEPLIBS} - ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ - ${OBJS} ${UOBJS} ${LIBS} - -lwresd@EXEEXT@: named@EXEEXT@ - rm -f lwresd@EXEEXT@ - @LN@ named@EXEEXT@ lwresd@EXEEXT@ - -doc man:: ${MANOBJS} - -docclean manclean maintainer-clean:: - rm -f ${MANOBJS} - -clean distclean maintainer-clean:: - rm -f ${TARGETS} ${OBJS} - -installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir} - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man5 - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 - -install:: named@EXEEXT@ lwresd@EXEEXT@ installdirs - ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named@EXEEXT@ ${DESTDIR}${sbindir} - (cd ${DESTDIR}${sbindir}; rm -f lwresd@EXEEXT@; @LN@ named@EXEEXT@ lwresd@EXEEXT@) - ${INSTALL_DATA} ${srcdir}/named.8 ${DESTDIR}${mandir}/man8 - ${INSTALL_DATA} ${srcdir}/lwresd.8 ${DESTDIR}${mandir}/man8 - ${INSTALL_DATA} ${srcdir}/named.conf.5 ${DESTDIR}${mandir}/man5 - diff --git a/contrib/bind9/bin/named/aclconf.c b/contrib/bind9/bin/named/aclconf.c deleted file mode 100644 index 8b6d0c767d4f..000000000000 --- a/contrib/bind9/bin/named/aclconf.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: aclconf.c,v 1.27.12.5 2005/03/17 03:58:25 marka Exp $ */ - -#include <config.h> - -#include <isc/mem.h> -#include <isc/string.h> /* Required for HP/UX (and others?) */ -#include <isc/util.h> - -#include <isccfg/namedconf.h> - -#include <dns/acl.h> -#include <dns/fixedname.h> -#include <dns/log.h> - -#include <named/aclconf.h> - -#define LOOP_MAGIC ISC_MAGIC('L','O','O','P') - -void -ns_aclconfctx_init(ns_aclconfctx_t *ctx) { - ISC_LIST_INIT(ctx->named_acl_cache); -} - -void -ns_aclconfctx_destroy(ns_aclconfctx_t *ctx) { - dns_acl_t *dacl, *next; - for (dacl = ISC_LIST_HEAD(ctx->named_acl_cache); - dacl != NULL; - dacl = next) - { - next = ISC_LIST_NEXT(dacl, nextincache); - dns_acl_detach(&dacl); - } -} - -/* - * Find the definition of the named acl whose name is "name". - */ -static isc_result_t -get_acl_def(cfg_obj_t *cctx, char *name, cfg_obj_t **ret) { - isc_result_t result; - cfg_obj_t *acls = NULL; - cfg_listelt_t *elt; - - result = cfg_map_get(cctx, "acl", &acls); - if (result != ISC_R_SUCCESS) - return (result); - for (elt = cfg_list_first(acls); - elt != NULL; - elt = cfg_list_next(elt)) { - cfg_obj_t *acl = cfg_listelt_value(elt); - const char *aclname = cfg_obj_asstring(cfg_tuple_get(acl, "name")); - if (strcasecmp(aclname, name) == 0) { - *ret = cfg_tuple_get(acl, "value"); - return (ISC_R_SUCCESS); - } - } - return (ISC_R_NOTFOUND); -} - -static isc_result_t -convert_named_acl(cfg_obj_t *nameobj, cfg_obj_t *cctx, - ns_aclconfctx_t *ctx, isc_mem_t *mctx, - dns_acl_t **target) -{ - isc_result_t result; - cfg_obj_t *cacl = NULL; - dns_acl_t *dacl; - dns_acl_t loop; - char *aclname = cfg_obj_asstring(nameobj); - - /* Look for an already-converted version. */ - for (dacl = ISC_LIST_HEAD(ctx->named_acl_cache); - dacl != NULL; - dacl = ISC_LIST_NEXT(dacl, nextincache)) - { - if (strcasecmp(aclname, dacl->name) == 0) { - if (ISC_MAGIC_VALID(dacl, LOOP_MAGIC)) { - cfg_obj_log(nameobj, dns_lctx, ISC_LOG_ERROR, - "acl loop detected: %s", aclname); - return (ISC_R_FAILURE); - } - dns_acl_attach(dacl, target); - return (ISC_R_SUCCESS); - } - } - /* Not yet converted. Convert now. */ - result = get_acl_def(cctx, aclname, &cacl); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(nameobj, dns_lctx, ISC_LOG_WARNING, - "undefined ACL '%s'", aclname); - return (result); - } - /* - * Add a loop detection element. - */ - memset(&loop, 0, sizeof(loop)); - ISC_LINK_INIT(&loop, nextincache); - loop.name = aclname; - loop.magic = LOOP_MAGIC; - ISC_LIST_APPEND(ctx->named_acl_cache, &loop, nextincache); - result = ns_acl_fromconfig(cacl, cctx, ctx, mctx, &dacl); - ISC_LIST_UNLINK(ctx->named_acl_cache, &loop, nextincache); - loop.magic = 0; - loop.name = NULL; - if (result != ISC_R_SUCCESS) - return (result); - dacl->name = isc_mem_strdup(dacl->mctx, aclname); - if (dacl->name == NULL) - return (ISC_R_NOMEMORY); - ISC_LIST_APPEND(ctx->named_acl_cache, dacl, nextincache); - dns_acl_attach(dacl, target); - return (ISC_R_SUCCESS); -} - -static isc_result_t -convert_keyname(cfg_obj_t *keyobj, isc_mem_t *mctx, dns_name_t *dnsname) { - isc_result_t result; - isc_buffer_t buf; - dns_fixedname_t fixname; - unsigned int keylen; - const char *txtname = cfg_obj_asstring(keyobj); - - keylen = strlen(txtname); - isc_buffer_init(&buf, txtname, keylen); - isc_buffer_add(&buf, keylen); - dns_fixedname_init(&fixname); - result = dns_name_fromtext(dns_fixedname_name(&fixname), &buf, - dns_rootname, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(keyobj, dns_lctx, ISC_LOG_WARNING, - "key name '%s' is not a valid domain name", - txtname); - return (result); - } - return (dns_name_dup(dns_fixedname_name(&fixname), mctx, dnsname)); -} - -isc_result_t -ns_acl_fromconfig(cfg_obj_t *caml, - cfg_obj_t *cctx, - ns_aclconfctx_t *ctx, - isc_mem_t *mctx, - dns_acl_t **target) -{ - isc_result_t result; - unsigned int count; - dns_acl_t *dacl = NULL; - dns_aclelement_t *de; - cfg_listelt_t *elt; - - REQUIRE(target != NULL && *target == NULL); - - count = 0; - for (elt = cfg_list_first(caml); - elt != NULL; - elt = cfg_list_next(elt)) - count++; - - result = dns_acl_create(mctx, count, &dacl); - if (result != ISC_R_SUCCESS) - return (result); - - de = dacl->elements; - for (elt = cfg_list_first(caml); - elt != NULL; - elt = cfg_list_next(elt)) - { - cfg_obj_t *ce = cfg_listelt_value(elt); - if (cfg_obj_istuple(ce)) { - /* This must be a negated element. */ - ce = cfg_tuple_get(ce, "value"); - de->negative = ISC_TRUE; - } else { - de->negative = ISC_FALSE; - } - - if (cfg_obj_isnetprefix(ce)) { - /* Network prefix */ - de->type = dns_aclelementtype_ipprefix; - - cfg_obj_asnetprefix(ce, - &de->u.ip_prefix.address, - &de->u.ip_prefix.prefixlen); - } else if (cfg_obj_istype(ce, &cfg_type_keyref)) { - /* Key name */ - de->type = dns_aclelementtype_keyname; - dns_name_init(&de->u.keyname, NULL); - result = convert_keyname(ce, mctx, &de->u.keyname); - if (result != ISC_R_SUCCESS) - goto cleanup; - } else if (cfg_obj_islist(ce)) { - /* Nested ACL */ - de->type = dns_aclelementtype_nestedacl; - result = ns_acl_fromconfig(ce, cctx, ctx, mctx, - &de->u.nestedacl); - if (result != ISC_R_SUCCESS) - goto cleanup; - } else if (cfg_obj_isstring(ce)) { - /* ACL name */ - char *name = cfg_obj_asstring(ce); - if (strcasecmp(name, "localhost") == 0) { - de->type = dns_aclelementtype_localhost; - } else if (strcasecmp(name, "localnets") == 0) { - de->type = dns_aclelementtype_localnets; - } else if (strcasecmp(name, "any") == 0) { - de->type = dns_aclelementtype_any; - } else if (strcasecmp(name, "none") == 0) { - de->type = dns_aclelementtype_any; - de->negative = ISC_TF(! de->negative); - } else { - de->type = dns_aclelementtype_nestedacl; - result = convert_named_acl(ce, cctx, ctx, mctx, - &de->u.nestedacl); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - } else { - cfg_obj_log(ce, dns_lctx, ISC_LOG_WARNING, - "address match list contains " - "unsupported element type"); - result = ISC_R_FAILURE; - goto cleanup; - } - de++; - dacl->length++; - } - - *target = dacl; - return (ISC_R_SUCCESS); - - cleanup: - dns_acl_detach(&dacl); - return (result); -} diff --git a/contrib/bind9/bin/named/builtin.c b/contrib/bind9/bin/named/builtin.c deleted file mode 100644 index af4d7a3f0d43..000000000000 --- a/contrib/bind9/bin/named/builtin.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001-2003 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: builtin.c,v 1.4.106.4 2004/03/08 04:04:18 marka Exp $ */ - -/* - * The built-in "version", "hostname", "id" and "authors" databases. - */ - -#include <config.h> - -#include <string.h> -#include <stdio.h> - -#include <isc/print.h> -#include <isc/result.h> -#include <isc/util.h> - -#include <dns/sdb.h> -#include <dns/result.h> - -#include <named/builtin.h> -#include <named/globals.h> -#include <named/server.h> -#include <named/os.h> - -typedef struct builtin builtin_t; - -static isc_result_t do_version_lookup(dns_sdblookup_t *lookup); -static isc_result_t do_hostname_lookup(dns_sdblookup_t *lookup); -static isc_result_t do_authors_lookup(dns_sdblookup_t *lookup); -static isc_result_t do_id_lookup(dns_sdblookup_t *lookup); - -/* - * We can't use function pointers as the db_data directly - * because ANSI C does not guarantee that function pointers - * can safely be cast to void pointers and back. - */ - -struct builtin { - isc_result_t (*do_lookup)(dns_sdblookup_t *lookup); -}; - -static builtin_t version_builtin = { do_version_lookup }; -static builtin_t hostname_builtin = { do_hostname_lookup }; -static builtin_t authors_builtin = { do_authors_lookup }; -static builtin_t id_builtin = { do_id_lookup }; - -static dns_sdbimplementation_t *builtin_impl; - -static isc_result_t -builtin_lookup(const char *zone, const char *name, void *dbdata, - dns_sdblookup_t *lookup) -{ - builtin_t *b = (builtin_t *) dbdata; - - UNUSED(zone); - - if (strcmp(name, "@") == 0) - return (b->do_lookup(lookup)); - else - return (ISC_R_NOTFOUND); -} - -static isc_result_t -put_txt(dns_sdblookup_t *lookup, const char *text) { - unsigned char buf[256]; - unsigned int len = strlen(text); - if (len > 255) - len = 255; /* Silently truncate */ - buf[0] = len; - memcpy(&buf[1], text, len); - return (dns_sdb_putrdata(lookup, dns_rdatatype_txt, 0, buf, len + 1)); -} - -static isc_result_t -do_version_lookup(dns_sdblookup_t *lookup) { - if (ns_g_server->version_set) { - if (ns_g_server->version == NULL) - return (ISC_R_SUCCESS); - else - return (put_txt(lookup, ns_g_server->version)); - } else { - return (put_txt(lookup, ns_g_version)); - } -} - -static isc_result_t -do_hostname_lookup(dns_sdblookup_t *lookup) { - if (ns_g_server->hostname_set) { - if (ns_g_server->hostname == NULL) - return (ISC_R_SUCCESS); - else - return (put_txt(lookup, ns_g_server->hostname)); - } else { - char buf[256]; - isc_result_t result = ns_os_gethostname(buf, sizeof(buf)); - if (result != ISC_R_SUCCESS) - return (result); - return (put_txt(lookup, buf)); - } -} - -static isc_result_t -do_authors_lookup(dns_sdblookup_t *lookup) { - isc_result_t result; - const char **p; - static const char *authors[] = { - "Mark Andrews", - "James Brister", - "Ben Cottrell", - "Michael Graff", - "Andreas Gustafsson", - "Bob Halley", - "David Lawrence", - "Danny Mayer", - "Damien Neil", - "Matt Nelson", - "Michael Sawyer", - "Brian Wellington", - NULL - }; - - /* - * If a version string is specified, disable the authors.bind zone. - */ - if (ns_g_server->version_set) - return (ISC_R_SUCCESS); - - for (p = authors; *p != NULL; p++) { - result = put_txt(lookup, *p); - if (result != ISC_R_SUCCESS) - return (result); - } - return (ISC_R_SUCCESS); -} - -static isc_result_t -do_id_lookup(dns_sdblookup_t *lookup) { - - if (ns_g_server->server_usehostname) { - char buf[256]; - isc_result_t result = ns_os_gethostname(buf, sizeof(buf)); - if (result != ISC_R_SUCCESS) - return (result); - return (put_txt(lookup, buf)); - } - - if (ns_g_server->server_id == NULL) - return (ISC_R_SUCCESS); - else - return (put_txt(lookup, ns_g_server->server_id)); -} - -static isc_result_t -builtin_authority(const char *zone, void *dbdata, dns_sdblookup_t *lookup) { - isc_result_t result; - - UNUSED(zone); - UNUSED(dbdata); - - result = dns_sdb_putsoa(lookup, "@", "hostmaster", 0); - if (result != ISC_R_SUCCESS) - return (ISC_R_FAILURE); - result = dns_sdb_putrr(lookup, "ns", 0, "@"); - if (result != ISC_R_SUCCESS) - return (ISC_R_FAILURE); - - return (ISC_R_SUCCESS); -} - -static isc_result_t -builtin_create(const char *zone, int argc, char **argv, - void *driverdata, void **dbdata) -{ - UNUSED(zone); - UNUSED(driverdata); - if (argc != 1) - return (DNS_R_SYNTAX); - if (strcmp(argv[0], "version") == 0) - *dbdata = &version_builtin; - else if (strcmp(argv[0], "hostname") == 0) - *dbdata = &hostname_builtin; - else if (strcmp(argv[0], "authors") == 0) - *dbdata = &authors_builtin; - else if (strcmp(argv[0], "id") == 0) - *dbdata = &id_builtin; - else - return (ISC_R_NOTIMPLEMENTED); - return (ISC_R_SUCCESS); -} - -static dns_sdbmethods_t builtin_methods = { - builtin_lookup, - builtin_authority, - NULL, /* allnodes */ - builtin_create, - NULL /* destroy */ -}; - -isc_result_t -ns_builtin_init(void) { - RUNTIME_CHECK(dns_sdb_register("_builtin", &builtin_methods, NULL, - DNS_SDBFLAG_RELATIVEOWNER | - DNS_SDBFLAG_RELATIVERDATA, - ns_g_mctx, &builtin_impl) - == ISC_R_SUCCESS); - return (ISC_R_SUCCESS); -} - -void -ns_builtin_deinit(void) { - dns_sdb_unregister(&builtin_impl); -} diff --git a/contrib/bind9/bin/named/client.c b/contrib/bind9/bin/named/client.c deleted file mode 100644 index baecc2345cb9..000000000000 --- a/contrib/bind9/bin/named/client.c +++ /dev/null @@ -1,2366 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: client.c,v 1.176.2.13.4.26 2005/07/27 02:53:14 marka Exp $ */ - -#include <config.h> - -#include <isc/formatcheck.h> -#include <isc/mutex.h> -#include <isc/once.h> -#include <isc/print.h> -#include <isc/stdio.h> -#include <isc/string.h> -#include <isc/task.h> -#include <isc/timer.h> -#include <isc/util.h> - -#include <dns/db.h> -#include <dns/dispatch.h> -#include <dns/events.h> -#include <dns/message.h> -#include <dns/rcode.h> -#include <dns/resolver.h> -#include <dns/rdata.h> -#include <dns/rdataclass.h> -#include <dns/rdatalist.h> -#include <dns/rdataset.h> -#include <dns/tsig.h> -#include <dns/view.h> -#include <dns/zone.h> - -#include <named/interfacemgr.h> -#include <named/log.h> -#include <named/notify.h> -#include <named/server.h> -#include <named/update.h> - -/*** - *** Client - ***/ - -/* - * Important note! - * - * All client state changes, other than that from idle to listening, occur - * as a result of events. This guarantees serialization and avoids the - * need for locking. - * - * If a routine is ever created that allows someone other than the client's - * task to change the client, then the client will have to be locked. - */ - -#define NS_CLIENT_TRACE -#ifdef NS_CLIENT_TRACE -#define CTRACE(m) ns_client_log(client, \ - NS_LOGCATEGORY_CLIENT, \ - NS_LOGMODULE_CLIENT, \ - ISC_LOG_DEBUG(3), \ - "%s", (m)) -#define MTRACE(m) isc_log_write(ns_g_lctx, \ - NS_LOGCATEGORY_GENERAL, \ - NS_LOGMODULE_CLIENT, \ - ISC_LOG_DEBUG(3), \ - "clientmgr @%p: %s", manager, (m)) -#else -#define CTRACE(m) ((void)(m)) -#define MTRACE(m) ((void)(m)) -#endif - -#define TCP_CLIENT(c) (((c)->attributes & NS_CLIENTATTR_TCP) != 0) - -#define TCP_BUFFER_SIZE (65535 + 2) -#define SEND_BUFFER_SIZE 4096 -#define RECV_BUFFER_SIZE 4096 - -struct ns_clientmgr { - /* Unlocked. */ - unsigned int magic; - isc_mem_t * mctx; - isc_taskmgr_t * taskmgr; - isc_timermgr_t * timermgr; - isc_mutex_t lock; - /* Locked by lock. */ - isc_boolean_t exiting; - client_list_t active; /* Active clients */ - client_list_t recursing; /* Recursing clients */ - client_list_t inactive; /* To be recycled */ -}; - -#define MANAGER_MAGIC ISC_MAGIC('N', 'S', 'C', 'm') -#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, MANAGER_MAGIC) - -/* - * Client object states. Ordering is significant: higher-numbered - * states are generally "more active", meaning that the client can - * have more dynamically allocated data, outstanding events, etc. - * In the list below, any such properties listed for state N - * also apply to any state > N. - * - * To force the client into a less active state, set client->newstate - * to that state and call exit_check(). This will cause any - * activities defined for higher-numbered states to be aborted. - */ - -#define NS_CLIENTSTATE_FREED 0 -/* - * The client object no longer exists. - */ - -#define NS_CLIENTSTATE_INACTIVE 1 -/* - * The client object exists and has a task and timer. - * Its "query" struct and sendbuf are initialized. - * It is on the client manager's list of inactive clients. - * It has a message and OPT, both in the reset state. - */ - -#define NS_CLIENTSTATE_READY 2 -/* - * The client object is either a TCP or a UDP one, and - * it is associated with a network interface. It is on the - * client manager's list of active clients. - * - * If it is a TCP client object, it has a TCP listener socket - * and an outstanding TCP listen request. - * - * If it is a UDP client object, it has a UDP listener socket - * and an outstanding UDP receive request. - */ - -#define NS_CLIENTSTATE_READING 3 -/* - * The client object is a TCP client object that has received - * a connection. It has a tcpsocket, tcpmsg, TCP quota, and an - * outstanding TCP read request. This state is not used for - * UDP client objects. - */ - -#define NS_CLIENTSTATE_WORKING 4 -/* - * The client object has received a request and is working - * on it. It has a view, and it may have any of a non-reset OPT, - * recursion quota, and an outstanding write request. - */ - -#define NS_CLIENTSTATE_MAX 9 -/* - * Sentinel value used to indicate "no state". When client->newstate - * has this value, we are not attempting to exit the current state. - * Must be greater than any valid state. - */ - - -static void client_read(ns_client_t *client); -static void client_accept(ns_client_t *client); -static void client_udprecv(ns_client_t *client); -static void clientmgr_destroy(ns_clientmgr_t *manager); -static isc_boolean_t exit_check(ns_client_t *client); -static void ns_client_endrequest(ns_client_t *client); -static void ns_client_checkactive(ns_client_t *client); -static void client_start(isc_task_t *task, isc_event_t *event); -static void client_request(isc_task_t *task, isc_event_t *event); -static void ns_client_dumpmessage(ns_client_t *client, const char *reason); - -void -ns_client_recursing(ns_client_t *client) { - REQUIRE(NS_CLIENT_VALID(client)); - - LOCK(&client->manager->lock); - ISC_LIST_UNLINK(*client->list, client, link); - ISC_LIST_APPEND(client->manager->recursing, client, link); - client->list = &client->manager->recursing; - UNLOCK(&client->manager->lock); -} - -void -ns_client_killoldestquery(ns_client_t *client) { - ns_client_t *oldest; - REQUIRE(NS_CLIENT_VALID(client)); - - LOCK(&client->manager->lock); - oldest = ISC_LIST_HEAD(client->manager->recursing); - if (oldest != NULL) { - ns_query_cancel(oldest); - ISC_LIST_UNLINK(*oldest->list, oldest, link); - ISC_LIST_APPEND(client->manager->active, oldest, link); - oldest->list = &client->manager->active; - } - UNLOCK(&client->manager->lock); -} - -void -ns_client_settimeout(ns_client_t *client, unsigned int seconds) { - isc_result_t result; - isc_interval_t interval; - - isc_interval_set(&interval, seconds, 0); - result = isc_timer_reset(client->timer, isc_timertype_once, NULL, - &interval, ISC_FALSE); - client->timerset = ISC_TRUE; - if (result != ISC_R_SUCCESS) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_ERROR, - "setting timeout: %s", - isc_result_totext(result)); - /* Continue anyway. */ - } -} - -/* - * Check for a deactivation or shutdown request and take appropriate - * action. Returns ISC_TRUE if either is in progress; in this case - * the caller must no longer use the client object as it may have been - * freed. - */ -static isc_boolean_t -exit_check(ns_client_t *client) { - ns_clientmgr_t *locked_manager = NULL; - ns_clientmgr_t *destroy_manager = NULL; - - REQUIRE(NS_CLIENT_VALID(client)); - - if (client->state <= client->newstate) - return (ISC_FALSE); /* Business as usual. */ - - INSIST(client->newstate < NS_CLIENTSTATE_WORKING); - - /* - * We need to detach from the view early when shutting down - * the server to break the following vicious circle: - * - * - The resolver will not shut down until the view refcount is zero - * - The view refcount does not go to zero until all clients detach - * - The client does not detach from the view until references is zero - * - references does not go to zero until the resolver has shut down - * - * Keep the view attached until any outstanding updates complete. - */ - if (client->nupdates == 0 && - client->newstate == NS_CLIENTSTATE_FREED && client->view != NULL) - dns_view_detach(&client->view); - - if (client->state == NS_CLIENTSTATE_WORKING) { - INSIST(client->newstate <= NS_CLIENTSTATE_READING); - /* - * Let the update processing complete. - */ - if (client->nupdates > 0) - return (ISC_TRUE); - /* - * We are trying to abort request processing. - */ - if (client->nsends > 0) { - isc_socket_t *socket; - if (TCP_CLIENT(client)) - socket = client->tcpsocket; - else - socket = client->udpsocket; - isc_socket_cancel(socket, client->task, - ISC_SOCKCANCEL_SEND); - } - - if (! (client->nsends == 0 && client->nrecvs == 0 && - client->references == 0)) - { - /* - * Still waiting for I/O cancel completion. - * or lingering references. - */ - return (ISC_TRUE); - } - /* - * I/O cancel is complete. Burn down all state - * related to the current request. - */ - ns_client_endrequest(client); - - client->state = NS_CLIENTSTATE_READING; - INSIST(client->recursionquota == NULL); - if (NS_CLIENTSTATE_READING == client->newstate) { - client_read(client); - client->newstate = NS_CLIENTSTATE_MAX; - return (ISC_TRUE); /* We're done. */ - } - } - - if (client->state == NS_CLIENTSTATE_READING) { - /* - * We are trying to abort the current TCP connection, - * if any. - */ - INSIST(client->recursionquota == NULL); - INSIST(client->newstate <= NS_CLIENTSTATE_READY); - if (client->nreads > 0) - dns_tcpmsg_cancelread(&client->tcpmsg); - if (! client->nreads == 0) { - /* Still waiting for read cancel completion. */ - return (ISC_TRUE); - } - - if (client->tcpmsg_valid) { - dns_tcpmsg_invalidate(&client->tcpmsg); - client->tcpmsg_valid = ISC_FALSE; - } - if (client->tcpsocket != NULL) { - CTRACE("closetcp"); - isc_socket_detach(&client->tcpsocket); - } - - if (client->tcpquota != NULL) - isc_quota_detach(&client->tcpquota); - - if (client->timerset) { - (void)isc_timer_reset(client->timer, - isc_timertype_inactive, - NULL, NULL, ISC_TRUE); - client->timerset = ISC_FALSE; - } - - client->peeraddr_valid = ISC_FALSE; - - client->state = NS_CLIENTSTATE_READY; - INSIST(client->recursionquota == NULL); - - /* - * Now the client is ready to accept a new TCP connection - * or UDP request, but we may have enough clients doing - * that already. Check whether this client needs to remain - * active and force it to go inactive if not. - */ - ns_client_checkactive(client); - - if (NS_CLIENTSTATE_READY == client->newstate) { - if (TCP_CLIENT(client)) { - client_accept(client); - } else - client_udprecv(client); - client->newstate = NS_CLIENTSTATE_MAX; - return (ISC_TRUE); - } - } - - if (client->state == NS_CLIENTSTATE_READY) { - INSIST(client->newstate <= NS_CLIENTSTATE_INACTIVE); - /* - * We are trying to enter the inactive state. - */ - if (client->naccepts > 0) - isc_socket_cancel(client->tcplistener, client->task, - ISC_SOCKCANCEL_ACCEPT); - - if (! (client->naccepts == 0)) { - /* Still waiting for accept cancel completion. */ - return (ISC_TRUE); - } - /* Accept cancel is complete. */ - - if (client->nrecvs > 0) - isc_socket_cancel(client->udpsocket, client->task, - ISC_SOCKCANCEL_RECV); - if (! (client->nrecvs == 0)) { - /* Still waiting for recv cancel completion. */ - return (ISC_TRUE); - } - /* Recv cancel is complete. */ - - if (client->nctls > 0) { - /* Still waiting for control event to be delivered */ - return (ISC_TRUE); - } - - /* Deactivate the client. */ - if (client->interface) - ns_interface_detach(&client->interface); - - INSIST(client->naccepts == 0); - INSIST(client->recursionquota == NULL); - if (client->tcplistener != NULL) - isc_socket_detach(&client->tcplistener); - - if (client->udpsocket != NULL) - isc_socket_detach(&client->udpsocket); - - if (client->dispatch != NULL) - dns_dispatch_detach(&client->dispatch); - - client->attributes = 0; - client->mortal = ISC_FALSE; - - LOCK(&client->manager->lock); - /* - * Put the client on the inactive list. If we are aiming for - * the "freed" state, it will be removed from the inactive - * list shortly, and we need to keep the manager locked until - * that has been done, lest the manager decide to reactivate - * the dying client inbetween. - */ - locked_manager = client->manager; - ISC_LIST_UNLINK(*client->list, client, link); - ISC_LIST_APPEND(client->manager->inactive, client, link); - client->list = &client->manager->inactive; - client->state = NS_CLIENTSTATE_INACTIVE; - INSIST(client->recursionquota == NULL); - - if (client->state == client->newstate) { - client->newstate = NS_CLIENTSTATE_MAX; - goto unlock; - } - } - - if (client->state == NS_CLIENTSTATE_INACTIVE) { - INSIST(client->newstate == NS_CLIENTSTATE_FREED); - /* - * We are trying to free the client. - * - * When "shuttingdown" is true, either the task has received - * its shutdown event or no shutdown event has ever been - * set up. Thus, we have no outstanding shutdown - * event at this point. - */ - REQUIRE(client->state == NS_CLIENTSTATE_INACTIVE); - - INSIST(client->recursionquota == NULL); - - ns_query_free(client); - isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE); - isc_event_free((isc_event_t **)&client->sendevent); - isc_event_free((isc_event_t **)&client->recvevent); - isc_timer_detach(&client->timer); - - if (client->tcpbuf != NULL) - isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); - if (client->opt != NULL) { - INSIST(dns_rdataset_isassociated(client->opt)); - dns_rdataset_disassociate(client->opt); - dns_message_puttemprdataset(client->message, &client->opt); - } - dns_message_destroy(&client->message); - if (client->manager != NULL) { - ns_clientmgr_t *manager = client->manager; - if (locked_manager == NULL) { - LOCK(&manager->lock); - locked_manager = manager; - } - ISC_LIST_UNLINK(*client->list, client, link); - client->list = NULL; - if (manager->exiting && - ISC_LIST_EMPTY(manager->active) && - ISC_LIST_EMPTY(manager->inactive) && - ISC_LIST_EMPTY(manager->recursing)) - destroy_manager = manager; - } - /* - * Detaching the task must be done after unlinking from - * the manager's lists because the manager accesses - * client->task. - */ - if (client->task != NULL) - isc_task_detach(&client->task); - - CTRACE("free"); - client->magic = 0; - isc_mem_put(client->mctx, client, sizeof(*client)); - - goto unlock; - } - - unlock: - if (locked_manager != NULL) { - UNLOCK(&locked_manager->lock); - locked_manager = NULL; - } - - /* - * Only now is it safe to destroy the client manager (if needed), - * because we have accessed its lock for the last time. - */ - if (destroy_manager != NULL) - clientmgr_destroy(destroy_manager); - - return (ISC_TRUE); -} - -/* - * The client's task has received the client's control event - * as part of the startup process. - */ -static void -client_start(isc_task_t *task, isc_event_t *event) { - ns_client_t *client = (ns_client_t *) event->ev_arg; - - INSIST(task == client->task); - - UNUSED(task); - - INSIST(client->nctls == 1); - client->nctls--; - - if (exit_check(client)) - return; - - if (TCP_CLIENT(client)) { - client_accept(client); - } else { - client_udprecv(client); - } -} - - -/* - * The client's task has received a shutdown event. - */ -static void -client_shutdown(isc_task_t *task, isc_event_t *event) { - ns_client_t *client; - - REQUIRE(event != NULL); - REQUIRE(event->ev_type == ISC_TASKEVENT_SHUTDOWN); - client = event->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - - UNUSED(task); - - CTRACE("shutdown"); - - isc_event_free(&event); - - if (client->shutdown != NULL) { - (client->shutdown)(client->shutdown_arg, ISC_R_SHUTTINGDOWN); - client->shutdown = NULL; - client->shutdown_arg = NULL; - } - - client->newstate = NS_CLIENTSTATE_FREED; - (void)exit_check(client); -} - -static void -ns_client_endrequest(ns_client_t *client) { - INSIST(client->naccepts == 0); - INSIST(client->nreads == 0); - INSIST(client->nsends == 0); - INSIST(client->nrecvs == 0); - INSIST(client->nupdates == 0); - INSIST(client->state == NS_CLIENTSTATE_WORKING); - - CTRACE("endrequest"); - - if (client->next != NULL) { - (client->next)(client); - client->next = NULL; - } - - if (client->view != NULL) - dns_view_detach(&client->view); - if (client->opt != NULL) { - INSIST(dns_rdataset_isassociated(client->opt)); - dns_rdataset_disassociate(client->opt); - dns_message_puttemprdataset(client->message, &client->opt); - } - - client->udpsize = 512; - client->extflags = 0; - dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE); - - if (client->recursionquota != NULL) - isc_quota_detach(&client->recursionquota); - - /* - * Clear all client attributes that are specific to - * the request; that's all except the TCP flag. - */ - client->attributes &= NS_CLIENTATTR_TCP; -} - -static void -ns_client_checkactive(ns_client_t *client) { - if (client->mortal) { - /* - * This client object should normally go inactive - * at this point, but if we have fewer active client - * objects than desired due to earlier quota exhaustion, - * keep it active to make up for the shortage. - */ - isc_boolean_t need_another_client = ISC_FALSE; - if (TCP_CLIENT(client)) { - LOCK(&client->interface->lock); - if (client->interface->ntcpcurrent < - client->interface->ntcptarget) - need_another_client = ISC_TRUE; - UNLOCK(&client->interface->lock); - } else { - /* - * The UDP client quota is enforced by making - * requests fail rather than by not listening - * for new ones. Therefore, there is always a - * full set of UDP clients listening. - */ - } - if (! need_another_client) { - /* - * We don't need this client object. Recycle it. - */ - if (client->newstate >= NS_CLIENTSTATE_INACTIVE) - client->newstate = NS_CLIENTSTATE_INACTIVE; - } - } -} - -void -ns_client_next(ns_client_t *client, isc_result_t result) { - int newstate; - - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(client->state == NS_CLIENTSTATE_WORKING || - client->state == NS_CLIENTSTATE_READING); - - CTRACE("next"); - - if (result != ISC_R_SUCCESS) - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "request failed: %s", isc_result_totext(result)); - - /* - * An error processing a TCP request may have left - * the connection out of sync. To be safe, we always - * sever the connection when result != ISC_R_SUCCESS. - */ - if (result == ISC_R_SUCCESS && TCP_CLIENT(client)) - newstate = NS_CLIENTSTATE_READING; - else - newstate = NS_CLIENTSTATE_READY; - - if (client->newstate > newstate) - client->newstate = newstate; - (void)exit_check(client); -} - - -static void -client_senddone(isc_task_t *task, isc_event_t *event) { - ns_client_t *client; - isc_socketevent_t *sevent = (isc_socketevent_t *) event; - - REQUIRE(sevent != NULL); - REQUIRE(sevent->ev_type == ISC_SOCKEVENT_SENDDONE); - client = sevent->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - REQUIRE(sevent == client->sendevent); - - UNUSED(task); - - CTRACE("senddone"); - - if (sevent->result != ISC_R_SUCCESS) - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_WARNING, - "error sending response: %s", - isc_result_totext(sevent->result)); - - INSIST(client->nsends > 0); - client->nsends--; - - if (client->tcpbuf != NULL) { - INSIST(TCP_CLIENT(client)); - isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); - client->tcpbuf = NULL; - } - - if (exit_check(client)) - return; - - ns_client_next(client, ISC_R_SUCCESS); -} - -/* - * We only want to fail with ISC_R_NOSPACE when called from - * ns_client_sendraw() and not when called from ns_client_send(), - * tcpbuffer is NULL when called from ns_client_sendraw() and - * length != 0. tcpbuffer != NULL when called from ns_client_send() - * and length == 0. - */ - -static isc_result_t -client_allocsendbuf(ns_client_t *client, isc_buffer_t *buffer, - isc_buffer_t *tcpbuffer, isc_uint32_t length, - unsigned char *sendbuf, unsigned char **datap) -{ - unsigned char *data; - isc_uint32_t bufsize; - isc_result_t result; - - INSIST(datap != NULL); - INSIST((tcpbuffer == NULL && length != 0) || - (tcpbuffer != NULL && length == 0)); - - if (TCP_CLIENT(client)) { - INSIST(client->tcpbuf == NULL); - if (length + 2 > TCP_BUFFER_SIZE) { - result = ISC_R_NOSPACE; - goto done; - } - client->tcpbuf = isc_mem_get(client->mctx, TCP_BUFFER_SIZE); - if (client->tcpbuf == NULL) { - result = ISC_R_NOMEMORY; - goto done; - } - data = client->tcpbuf; - if (tcpbuffer != NULL) { - isc_buffer_init(tcpbuffer, data, TCP_BUFFER_SIZE); - isc_buffer_init(buffer, data + 2, TCP_BUFFER_SIZE - 2); - } else { - isc_buffer_init(buffer, data, TCP_BUFFER_SIZE); - INSIST(length <= 0xffff); - isc_buffer_putuint16(buffer, (isc_uint16_t)length); - } - } else { - data = sendbuf; - if (client->udpsize < SEND_BUFFER_SIZE) - bufsize = client->udpsize; - else - bufsize = SEND_BUFFER_SIZE; - if (length > bufsize) { - result = ISC_R_NOSPACE; - goto done; - } - isc_buffer_init(buffer, data, bufsize); - } - *datap = data; - result = ISC_R_SUCCESS; - - done: - return (result); -} - -static isc_result_t -client_sendpkg(ns_client_t *client, isc_buffer_t *buffer) { - struct in6_pktinfo *pktinfo; - isc_result_t result; - isc_region_t r; - isc_sockaddr_t *address; - isc_socket_t *socket; - isc_netaddr_t netaddr; - int match; - unsigned int sockflags = ISC_SOCKFLAG_IMMEDIATE; - - if (TCP_CLIENT(client)) { - socket = client->tcpsocket; - address = NULL; - } else { - socket = client->udpsocket; - address = &client->peeraddr; - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - if (ns_g_server->blackholeacl != NULL && - dns_acl_match(&netaddr, NULL, - ns_g_server->blackholeacl, - &ns_g_server->aclenv, - &match, NULL) == ISC_R_SUCCESS && - match > 0) - return (DNS_R_BLACKHOLED); - sockflags |= ISC_SOCKFLAG_NORETRY; - } - - if ((client->attributes & NS_CLIENTATTR_PKTINFO) != 0 && - (client->attributes & NS_CLIENTATTR_MULTICAST) == 0) - pktinfo = &client->pktinfo; - else - pktinfo = NULL; - - isc_buffer_usedregion(buffer, &r); - - CTRACE("sendto"); - - result = isc_socket_sendto2(socket, &r, client->task, - address, pktinfo, - client->sendevent, sockflags); - if (result == ISC_R_SUCCESS || result == ISC_R_INPROGRESS) { - client->nsends++; - if (result == ISC_R_SUCCESS) - client_senddone(client->task, - (isc_event_t *)client->sendevent); - result = ISC_R_SUCCESS; - } - return (result); -} - -void -ns_client_sendraw(ns_client_t *client, dns_message_t *message) { - isc_result_t result; - unsigned char *data; - isc_buffer_t buffer; - isc_region_t r; - isc_region_t *mr; - unsigned char sendbuf[SEND_BUFFER_SIZE]; - - REQUIRE(NS_CLIENT_VALID(client)); - - CTRACE("sendraw"); - - mr = dns_message_getrawmessage(message); - if (mr == NULL) { - result = ISC_R_UNEXPECTEDEND; - goto done; - } - - result = client_allocsendbuf(client, &buffer, NULL, mr->length, - sendbuf, &data); - if (result != ISC_R_SUCCESS) - goto done; - - /* - * Copy message to buffer and fixup id. - */ - isc_buffer_availableregion(&buffer, &r); - result = isc_buffer_copyregion(&buffer, mr); - if (result != ISC_R_SUCCESS) - goto done; - r.base[0] = (client->message->id >> 8) & 0xff; - r.base[1] = client->message->id & 0xff; - - result = client_sendpkg(client, &buffer); - if (result == ISC_R_SUCCESS) - return; - - done: - if (client->tcpbuf != NULL) { - isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); - client->tcpbuf = NULL; - } - ns_client_next(client, result); -} - -void -ns_client_send(ns_client_t *client) { - isc_result_t result; - unsigned char *data; - isc_buffer_t buffer; - isc_buffer_t tcpbuffer; - isc_region_t r; - dns_compress_t cctx; - isc_boolean_t cleanup_cctx = ISC_FALSE; - unsigned char sendbuf[SEND_BUFFER_SIZE]; - unsigned int dnssec_opts; - unsigned int preferred_glue; - - REQUIRE(NS_CLIENT_VALID(client)); - - CTRACE("send"); - - if ((client->attributes & NS_CLIENTATTR_RA) != 0) - client->message->flags |= DNS_MESSAGEFLAG_RA; - - if ((client->attributes & NS_CLIENTATTR_WANTDNSSEC) != 0) - dnssec_opts = 0; - else - dnssec_opts = DNS_MESSAGERENDER_OMITDNSSEC; - - preferred_glue = 0; - if (client->view != NULL) { - if (client->view->preferred_glue == dns_rdatatype_a) - preferred_glue = DNS_MESSAGERENDER_PREFER_A; - else if (client->view->preferred_glue == dns_rdatatype_aaaa) - preferred_glue = DNS_MESSAGERENDER_PREFER_AAAA; - } - - /* - * XXXRTH The following doesn't deal with TCP buffer resizing. - */ - result = client_allocsendbuf(client, &buffer, &tcpbuffer, 0, - sendbuf, &data); - if (result != ISC_R_SUCCESS) - goto done; - - result = dns_compress_init(&cctx, -1, client->mctx); - if (result != ISC_R_SUCCESS) - goto done; - cleanup_cctx = ISC_TRUE; - - result = dns_message_renderbegin(client->message, &cctx, &buffer); - if (result != ISC_R_SUCCESS) - goto done; - if (client->opt != NULL) { - result = dns_message_setopt(client->message, client->opt); - /* - * XXXRTH dns_message_setopt() should probably do this... - */ - client->opt = NULL; - if (result != ISC_R_SUCCESS) - goto done; - } - result = dns_message_rendersection(client->message, - DNS_SECTION_QUESTION, 0); - if (result == ISC_R_NOSPACE) { - client->message->flags |= DNS_MESSAGEFLAG_TC; - goto renderend; - } - if (result != ISC_R_SUCCESS) - goto done; - result = dns_message_rendersection(client->message, - DNS_SECTION_ANSWER, - DNS_MESSAGERENDER_PARTIAL | - dnssec_opts); - if (result == ISC_R_NOSPACE) { - client->message->flags |= DNS_MESSAGEFLAG_TC; - goto renderend; - } - if (result != ISC_R_SUCCESS) - goto done; - result = dns_message_rendersection(client->message, - DNS_SECTION_AUTHORITY, - DNS_MESSAGERENDER_PARTIAL | - dnssec_opts); - if (result == ISC_R_NOSPACE) { - client->message->flags |= DNS_MESSAGEFLAG_TC; - goto renderend; - } - if (result != ISC_R_SUCCESS) - goto done; - result = dns_message_rendersection(client->message, - DNS_SECTION_ADDITIONAL, - preferred_glue | dnssec_opts); - if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE) - goto done; - renderend: - result = dns_message_renderend(client->message); - - if (result != ISC_R_SUCCESS) - goto done; - - if (cleanup_cctx) { - dns_compress_invalidate(&cctx); - cleanup_cctx = ISC_FALSE; - } - - if (TCP_CLIENT(client)) { - isc_buffer_usedregion(&buffer, &r); - isc_buffer_putuint16(&tcpbuffer, (isc_uint16_t) r.length); - isc_buffer_add(&tcpbuffer, r.length); - result = client_sendpkg(client, &tcpbuffer); - } else - result = client_sendpkg(client, &buffer); - if (result == ISC_R_SUCCESS) - return; - - done: - if (client->tcpbuf != NULL) { - isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); - client->tcpbuf = NULL; - } - - if (cleanup_cctx) - dns_compress_invalidate(&cctx); - - ns_client_next(client, result); -} - -void -ns_client_error(ns_client_t *client, isc_result_t result) { - dns_rcode_t rcode; - dns_message_t *message; - - REQUIRE(NS_CLIENT_VALID(client)); - - CTRACE("error"); - - message = client->message; - rcode = dns_result_torcode(result); - - /* - * Message may be an in-progress reply that we had trouble - * with, in which case QR will be set. We need to clear QR before - * calling dns_message_reply() to avoid triggering an assertion. - */ - message->flags &= ~DNS_MESSAGEFLAG_QR; - /* - * AA and AD shouldn't be set. - */ - message->flags &= ~(DNS_MESSAGEFLAG_AA | DNS_MESSAGEFLAG_AD); - result = dns_message_reply(message, ISC_TRUE); - if (result != ISC_R_SUCCESS) { - /* - * It could be that we've got a query with a good header, - * but a bad question section, so we try again with - * want_question_section set to ISC_FALSE. - */ - result = dns_message_reply(message, ISC_FALSE); - if (result != ISC_R_SUCCESS) { - ns_client_next(client, result); - return; - } - } - message->rcode = rcode; - - /* - * FORMERR loop avoidance: If we sent a FORMERR message - * with the same ID to the same client less than two - * seconds ago, assume that we are in an infinite error - * packet dialog with a server for some protocol whose - * error responses look enough like DNS queries to - * elicit a FORMERR response. Drop a packet to break - * the loop. - */ - if (rcode == dns_rcode_formerr) { - if (isc_sockaddr_equal(&client->peeraddr, - &client->formerrcache.addr) && - message->id == client->formerrcache.id && - client->requesttime - client->formerrcache.time < 2) { - /* Drop packet. */ - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), - "possible error packet loop, " - "FORMERR dropped"); - ns_client_next(client, result); - return; - } - client->formerrcache.addr = client->peeraddr; - client->formerrcache.time = client->requesttime; - client->formerrcache.id = message->id; - } - ns_client_send(client); -} - -static inline isc_result_t -client_addopt(ns_client_t *client) { - dns_rdataset_t *rdataset; - dns_rdatalist_t *rdatalist; - dns_rdata_t *rdata; - isc_result_t result; - dns_view_t *view; - dns_resolver_t *resolver; - isc_uint16_t udpsize; - - REQUIRE(client->opt == NULL); /* XXXRTH free old. */ - - rdatalist = NULL; - result = dns_message_gettemprdatalist(client->message, &rdatalist); - if (result != ISC_R_SUCCESS) - return (result); - rdata = NULL; - result = dns_message_gettemprdata(client->message, &rdata); - if (result != ISC_R_SUCCESS) - return (result); - rdataset = NULL; - result = dns_message_gettemprdataset(client->message, &rdataset); - if (result != ISC_R_SUCCESS) - return (result); - dns_rdataset_init(rdataset); - - rdatalist->type = dns_rdatatype_opt; - rdatalist->covers = 0; - - /* - * Set the maximum UDP buffer size. - */ - view = client->view; - resolver = (view != NULL) ? view->resolver : NULL; - if (resolver != NULL) - udpsize = dns_resolver_getudpsize(resolver); - else - udpsize = ns_g_udpsize; - rdatalist->rdclass = udpsize; - - /* - * Set EXTENDED-RCODE, VERSION and Z to 0. - */ - rdatalist->ttl = (client->extflags & DNS_MESSAGEEXTFLAG_REPLYPRESERVE); - - /* - * No ENDS options in the default case. - */ - rdata->data = NULL; - rdata->length = 0; - rdata->rdclass = rdatalist->rdclass; - rdata->type = rdatalist->type; - rdata->flags = 0; - - ISC_LIST_INIT(rdatalist->rdata); - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) - == ISC_R_SUCCESS); - - client->opt = rdataset; - - return (ISC_R_SUCCESS); -} - -static inline isc_boolean_t -allowed(isc_netaddr_t *addr, dns_name_t *signer, dns_acl_t *acl) { - int match; - isc_result_t result; - - if (acl == NULL) - return (ISC_TRUE); - result = dns_acl_match(addr, signer, acl, &ns_g_server->aclenv, - &match, NULL); - if (result == ISC_R_SUCCESS && match > 0) - return (ISC_TRUE); - return (ISC_FALSE); -} - -/* - * Handle an incoming request event from the socket (UDP case) - * or tcpmsg (TCP case). - */ -static void -client_request(isc_task_t *task, isc_event_t *event) { - ns_client_t *client; - isc_socketevent_t *sevent; - isc_result_t result; - isc_result_t sigresult = ISC_R_SUCCESS; - isc_buffer_t *buffer; - isc_buffer_t tbuffer; - dns_view_t *view; - dns_rdataset_t *opt; - isc_boolean_t ra; /* Recursion available. */ - isc_netaddr_t netaddr; - isc_netaddr_t destaddr; - int match; - dns_messageid_t id; - unsigned int flags; - isc_boolean_t notimp; - - REQUIRE(event != NULL); - client = event->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - - INSIST(client->recursionquota == NULL); - - INSIST(client->state == - TCP_CLIENT(client) ? - NS_CLIENTSTATE_READING : - NS_CLIENTSTATE_READY); - - if (event->ev_type == ISC_SOCKEVENT_RECVDONE) { - INSIST(!TCP_CLIENT(client)); - sevent = (isc_socketevent_t *)event; - REQUIRE(sevent == client->recvevent); - isc_buffer_init(&tbuffer, sevent->region.base, sevent->n); - isc_buffer_add(&tbuffer, sevent->n); - buffer = &tbuffer; - result = sevent->result; - if (result == ISC_R_SUCCESS) { - client->peeraddr = sevent->address; - client->peeraddr_valid = ISC_TRUE; - } - if ((sevent->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0) { - client->attributes |= NS_CLIENTATTR_PKTINFO; - client->pktinfo = sevent->pktinfo; - } - if ((sevent->attributes & ISC_SOCKEVENTATTR_MULTICAST) != 0) - client->attributes |= NS_CLIENTATTR_MULTICAST; - client->nrecvs--; - } else { - INSIST(TCP_CLIENT(client)); - REQUIRE(event->ev_type == DNS_EVENT_TCPMSG); - REQUIRE(event->ev_sender == &client->tcpmsg); - buffer = &client->tcpmsg.buffer; - result = client->tcpmsg.result; - INSIST(client->nreads == 1); - /* - * client->peeraddr was set when the connection was accepted. - */ - client->nreads--; - } - - if (exit_check(client)) - goto cleanup; - client->state = client->newstate = NS_CLIENTSTATE_WORKING; - - isc_task_getcurrenttime(task, &client->requesttime); - client->now = client->requesttime; - - if (result != ISC_R_SUCCESS) { - if (TCP_CLIENT(client)) { - ns_client_next(client, result); - } else { - if (result != ISC_R_CANCELED) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, - ISC_LOG_ERROR, - "UDP client handler shutting " - "down due to fatal receive " - "error: %s", - isc_result_totext(result)); - isc_task_shutdown(client->task); - } - goto cleanup; - } - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "%s request", - TCP_CLIENT(client) ? "TCP" : "UDP"); - - /* - * Check the blackhole ACL for UDP only, since TCP is done in - * client_newconn. - */ - if (!TCP_CLIENT(client)) { - - if (ns_g_server->blackholeacl != NULL && - dns_acl_match(&netaddr, NULL, ns_g_server->blackholeacl, - &ns_g_server->aclenv, - &match, NULL) == ISC_R_SUCCESS && - match > 0) - { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "blackholed UDP datagram"); - ns_client_next(client, ISC_R_SUCCESS); - goto cleanup; - } - } - - /* - * Silently drop multicast requests for the present. - * XXXMPA look at when/if mDNS spec stabilizes. - */ - if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), - "dropping multicast request"); - ns_client_next(client, DNS_R_REFUSED); - } - - result = dns_message_peekheader(buffer, &id, &flags); - if (result != ISC_R_SUCCESS) { - /* - * There isn't enough header to determine whether - * this was a request or a response. Drop it. - */ - ns_client_next(client, result); - goto cleanup; - } - - /* - * The client object handles requests, not responses. - * If this is a UDP response, forward it to the dispatcher. - * If it's a TCP response, discard it here. - */ - if ((flags & DNS_MESSAGEFLAG_QR) != 0) { - if (TCP_CLIENT(client)) { - CTRACE("unexpected response"); - ns_client_next(client, DNS_R_FORMERR); - goto cleanup; - } else { - dns_dispatch_importrecv(client->dispatch, event); - ns_client_next(client, ISC_R_SUCCESS); - goto cleanup; - } - } - - /* - * It's a request. Parse it. - */ - result = dns_message_parse(client->message, buffer, 0); - if (result != ISC_R_SUCCESS) { - /* - * Parsing the request failed. Send a response - * (typically FORMERR or SERVFAIL). - */ - ns_client_error(client, result); - goto cleanup; - } - - switch (client->message->opcode) { - case dns_opcode_query: - case dns_opcode_update: - case dns_opcode_notify: - notimp = ISC_FALSE; - break; - case dns_opcode_iquery: - default: - notimp = ISC_TRUE; - break; - } - - client->message->rcode = dns_rcode_noerror; - - /* RFC1123 section 6.1.3.2 */ - if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0) - client->message->flags &= ~DNS_MESSAGEFLAG_RD; - - /* - * Deal with EDNS. - */ - opt = dns_message_getopt(client->message); - if (opt != NULL) { - unsigned int version; - - /* - * Set the client's UDP buffer size. - */ - client->udpsize = opt->rdclass; - - /* - * If the requested UDP buffer size is less than 512, - * ignore it and use 512. - */ - if (client->udpsize < 512) - client->udpsize = 512; - - /* - * Get the flags out of the OPT record. - */ - client->extflags = (isc_uint16_t)(opt->ttl & 0xFFFF); - - /* - * Create an OPT for our reply. - */ - result = client_addopt(client); - if (result != ISC_R_SUCCESS) { - ns_client_error(client, result); - goto cleanup; - } - - /* - * Do we understand this version of ENDS? - * - * XXXRTH need library support for this! - */ - version = (opt->ttl & 0x00FF0000) >> 16; - if (version != 0) { - ns_client_error(client, DNS_R_BADVERS); - goto cleanup; - } - } - - if (client->message->rdclass == 0) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), - "message class could not be determined"); - ns_client_dumpmessage(client, - "message class could not be determined"); - ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_FORMERR); - goto cleanup; - } - - /* - * Determine the destination address. If the receiving interface is - * bound to a specific address, we simply use it regardless of the - * address family. All IPv4 queries should fall into this case. - * Otherwise, if this is a TCP query, get the address from the - * receiving socket (this needs a system call and can be heavy). - * For IPv6 UDP queries, we get this from the pktinfo structure (if - * supported). - * If all the attempts fail (this can happen due to memory shortage, - * etc), we regard this as an error for safety. - */ - if ((client->interface->flags & NS_INTERFACEFLAG_ANYADDR) == 0) - isc_netaddr_fromsockaddr(&destaddr, &client->interface->addr); - else { - result = ISC_R_FAILURE; - - if (TCP_CLIENT(client)) { - isc_sockaddr_t destsockaddr; - - result = isc_socket_getsockname(client->tcpsocket, - &destsockaddr); - if (result == ISC_R_SUCCESS) - isc_netaddr_fromsockaddr(&destaddr, - &destsockaddr); - } - if (result != ISC_R_SUCCESS && - client->interface->addr.type.sa.sa_family == AF_INET6 && - (client->attributes & NS_CLIENTATTR_PKTINFO) != 0) { - isc_uint32_t zone = 0; - - /* - * XXXJT technically, we should convert the receiving - * interface ID to a proper scope zone ID. However, - * due to the fact there is no standard API for this, - * we only handle link-local addresses and use the - * interface index as link ID. Despite the assumption, - * it should cover most typical cases. - */ - if (IN6_IS_ADDR_LINKLOCAL(&client->pktinfo.ipi6_addr)) - zone = (isc_uint32_t)client->pktinfo.ipi6_ifindex; - - isc_netaddr_fromin6(&destaddr, - &client->pktinfo.ipi6_addr); - isc_netaddr_setzone(&destaddr, zone); - result = ISC_R_SUCCESS; - } - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "failed to get request's " - "destination: %s", - isc_result_totext(result)); - goto cleanup; - } - } - - /* - * Find a view that matches the client's source address. - */ - for (view = ISC_LIST_HEAD(ns_g_server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - if (client->message->rdclass == view->rdclass || - client->message->rdclass == dns_rdataclass_any) - { - dns_name_t *tsig = NULL; - sigresult = dns_message_rechecksig(client->message, - view); - if (sigresult == ISC_R_SUCCESS) - tsig = client->message->tsigname; - - if (allowed(&netaddr, tsig, view->matchclients) && - allowed(&destaddr, tsig, view->matchdestinations) && - !((client->message->flags & DNS_MESSAGEFLAG_RD) - == 0 && view->matchrecursiveonly)) - { - dns_view_attach(view, &client->view); - break; - } - } - } - - if (view == NULL) { - char classname[DNS_RDATACLASS_FORMATSIZE]; - - /* - * Do a dummy TSIG verification attempt so that the - * response will have a TSIG if the query did, as - * required by RFC2845. - */ - isc_buffer_t b; - isc_region_t *r; - - dns_message_resetsig(client->message); - - r = dns_message_getrawmessage(client->message); - isc_buffer_init(&b, r->base, r->length); - isc_buffer_add(&b, r->length); - (void)dns_tsig_verify(&b, client->message, NULL, NULL); - - dns_rdataclass_format(client->message->rdclass, classname, - sizeof(classname)); - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), - "no matching view in class '%s'", classname); - ns_client_dumpmessage(client, "no matching view in class"); - ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_REFUSED); - goto cleanup; - } - - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(5), - "using view '%s'", view->name); - - /* - * Check for a signature. We log bad signatures regardless of - * whether they ultimately cause the request to be rejected or - * not. We do not log the lack of a signature unless we are - * debugging. - */ - client->signer = NULL; - dns_name_init(&client->signername, NULL); - result = dns_message_signer(client->message, &client->signername); - if (result == ISC_R_SUCCESS) { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "request has valid signature"); - client->signer = &client->signername; - } else if (result == ISC_R_NOTFOUND) { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "request is not signed"); - } else if (result == DNS_R_NOIDENTITY) { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "request is signed by a nonauthoritative key"); - } else { - char tsigrcode[64]; - isc_buffer_t b; - dns_name_t *name = NULL; - - isc_buffer_init(&b, tsigrcode, sizeof(tsigrcode) - 1); - RUNTIME_CHECK(dns_tsigrcode_totext(client->message->tsigstatus, - &b) == ISC_R_SUCCESS); - tsigrcode[isc_buffer_usedlength(&b)] = '\0'; - /* There is a signature, but it is bad. */ - if (dns_message_gettsig(client->message, &name) != NULL) { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(name, namebuf, sizeof(namebuf)); - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_ERROR, - "request has invalid signature: " - "TSIG %s: %s (%s)", namebuf, - isc_result_totext(result), tsigrcode); - } else { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_ERROR, - "request has invalid signature: %s (%s)", - isc_result_totext(result), tsigrcode); - } - /* - * Accept update messages signed by unknown keys so that - * update forwarding works transparently through slaves - * that don't have all the same keys as the master. - */ - if (!(client->message->tsigstatus == dns_tsigerror_badkey && - client->message->opcode == dns_opcode_update)) { - ns_client_error(client, sigresult); - goto cleanup; - } - } - - /* - * Decide whether recursive service is available to this client. - * We do this here rather than in the query code so that we can - * set the RA bit correctly on all kinds of responses, not just - * responses to ordinary queries. - */ - ra = ISC_FALSE; - if (client->view->resolver != NULL && - client->view->recursion == ISC_TRUE && - ns_client_checkaclsilent(client, client->view->recursionacl, - ISC_TRUE) == ISC_R_SUCCESS) - ra = ISC_TRUE; - - if (ra == ISC_TRUE) - client->attributes |= NS_CLIENTATTR_RA; - - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, NS_LOGMODULE_CLIENT, - ISC_LOG_DEBUG(3), ra ? "recursion available" : - "recursion not available"); - - /* - * Dispatch the request. - */ - switch (client->message->opcode) { - case dns_opcode_query: - CTRACE("query"); - ns_query_start(client); - break; - case dns_opcode_update: - CTRACE("update"); - ns_client_settimeout(client, 60); - ns_update_start(client, sigresult); - break; - case dns_opcode_notify: - CTRACE("notify"); - ns_client_settimeout(client, 60); - ns_notify_start(client); - break; - case dns_opcode_iquery: - CTRACE("iquery"); - ns_client_error(client, DNS_R_NOTIMP); - break; - default: - CTRACE("unknown opcode"); - ns_client_error(client, DNS_R_NOTIMP); - } - - cleanup: - return; -} - -static void -client_timeout(isc_task_t *task, isc_event_t *event) { - ns_client_t *client; - - REQUIRE(event != NULL); - REQUIRE(event->ev_type == ISC_TIMEREVENT_LIFE || - event->ev_type == ISC_TIMEREVENT_IDLE); - client = event->ev_arg; - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(task == client->task); - REQUIRE(client->timer != NULL); - - UNUSED(task); - - CTRACE("timeout"); - - isc_event_free(&event); - - if (client->shutdown != NULL) { - (client->shutdown)(client->shutdown_arg, ISC_R_TIMEDOUT); - client->shutdown = NULL; - client->shutdown_arg = NULL; - } - - if (client->newstate > NS_CLIENTSTATE_READY) - client->newstate = NS_CLIENTSTATE_READY; - (void)exit_check(client); -} - -static isc_result_t -client_create(ns_clientmgr_t *manager, ns_client_t **clientp) { - ns_client_t *client; - isc_result_t result; - - /* - * Caller must be holding the manager lock. - * - * Note: creating a client does not add the client to the - * manager's client list or set the client's manager pointer. - * The caller is responsible for that. - */ - - REQUIRE(clientp != NULL && *clientp == NULL); - - client = isc_mem_get(manager->mctx, sizeof(*client)); - if (client == NULL) - return (ISC_R_NOMEMORY); - - client->task = NULL; - result = isc_task_create(manager->taskmgr, 0, &client->task); - if (result != ISC_R_SUCCESS) - goto cleanup_client; - isc_task_setname(client->task, "client", client); - - client->timer = NULL; - result = isc_timer_create(manager->timermgr, isc_timertype_inactive, - NULL, NULL, client->task, client_timeout, - client, &client->timer); - if (result != ISC_R_SUCCESS) - goto cleanup_task; - client->timerset = ISC_FALSE; - - client->message = NULL; - result = dns_message_create(manager->mctx, DNS_MESSAGE_INTENTPARSE, - &client->message); - if (result != ISC_R_SUCCESS) - goto cleanup_timer; - - /* XXXRTH Hardwired constants */ - - client->sendevent = (isc_socketevent_t *) - isc_event_allocate(manager->mctx, client, - ISC_SOCKEVENT_SENDDONE, - client_senddone, client, - sizeof(isc_socketevent_t)); - if (client->sendevent == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_message; - } - - client->recvbuf = isc_mem_get(manager->mctx, RECV_BUFFER_SIZE); - if (client->recvbuf == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_sendevent; - } - - client->recvevent = (isc_socketevent_t *) - isc_event_allocate(manager->mctx, client, - ISC_SOCKEVENT_RECVDONE, - client_request, client, - sizeof(isc_socketevent_t)); - if (client->recvevent == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup_recvbuf; - } - - client->magic = NS_CLIENT_MAGIC; - client->mctx = manager->mctx; - client->manager = NULL; - client->state = NS_CLIENTSTATE_INACTIVE; - client->newstate = NS_CLIENTSTATE_MAX; - client->naccepts = 0; - client->nreads = 0; - client->nsends = 0; - client->nrecvs = 0; - client->nupdates = 0; - client->nctls = 0; - client->references = 0; - client->attributes = 0; - client->view = NULL; - client->dispatch = NULL; - client->udpsocket = NULL; - client->tcplistener = NULL; - client->tcpsocket = NULL; - client->tcpmsg_valid = ISC_FALSE; - client->tcpbuf = NULL; - client->opt = NULL; - client->udpsize = 512; - client->extflags = 0; - client->next = NULL; - client->shutdown = NULL; - client->shutdown_arg = NULL; - dns_name_init(&client->signername, NULL); - client->mortal = ISC_FALSE; - client->tcpquota = NULL; - client->recursionquota = NULL; - client->interface = NULL; - client->peeraddr_valid = ISC_FALSE; - ISC_EVENT_INIT(&client->ctlevent, sizeof(client->ctlevent), 0, NULL, - NS_EVENT_CLIENTCONTROL, client_start, client, client, - NULL, NULL); - /* - * Initialize FORMERR cache to sentinel value that will not match - * any actual FORMERR response. - */ - isc_sockaddr_any(&client->formerrcache.addr); - client->formerrcache.time = 0; - client->formerrcache.id = 0; - ISC_LINK_INIT(client, link); - client->list = NULL; - - /* - * We call the init routines for the various kinds of client here, - * after we have created an otherwise valid client, because some - * of them call routines that REQUIRE(NS_CLIENT_VALID(client)). - */ - result = ns_query_init(client); - if (result != ISC_R_SUCCESS) - goto cleanup_recvevent; - - result = isc_task_onshutdown(client->task, client_shutdown, client); - if (result != ISC_R_SUCCESS) - goto cleanup_query; - - CTRACE("create"); - - *clientp = client; - - return (ISC_R_SUCCESS); - - cleanup_query: - ns_query_free(client); - - cleanup_recvevent: - isc_event_free((isc_event_t **)&client->recvevent); - - cleanup_recvbuf: - isc_mem_put(manager->mctx, client->recvbuf, RECV_BUFFER_SIZE); - - cleanup_sendevent: - isc_event_free((isc_event_t **)&client->sendevent); - - client->magic = 0; - - cleanup_message: - dns_message_destroy(&client->message); - - cleanup_timer: - isc_timer_detach(&client->timer); - - cleanup_task: - isc_task_detach(&client->task); - - cleanup_client: - isc_mem_put(manager->mctx, client, sizeof(*client)); - - return (result); -} - -static void -client_read(ns_client_t *client) { - isc_result_t result; - - CTRACE("read"); - - result = dns_tcpmsg_readmessage(&client->tcpmsg, client->task, - client_request, client); - if (result != ISC_R_SUCCESS) - goto fail; - - /* - * Set a timeout to limit the amount of time we will wait - * for a request on this TCP connection. - */ - ns_client_settimeout(client, 30); - - client->state = client->newstate = NS_CLIENTSTATE_READING; - INSIST(client->nreads == 0); - INSIST(client->recursionquota == NULL); - client->nreads++; - - return; - fail: - ns_client_next(client, result); -} - -static void -client_newconn(isc_task_t *task, isc_event_t *event) { - ns_client_t *client = event->ev_arg; - isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event; - isc_result_t result; - - REQUIRE(event->ev_type == ISC_SOCKEVENT_NEWCONN); - REQUIRE(NS_CLIENT_VALID(client)); - REQUIRE(client->task == task); - - UNUSED(task); - - INSIST(client->state == NS_CLIENTSTATE_READY); - - INSIST(client->naccepts == 1); - client->naccepts--; - - LOCK(&client->interface->lock); - INSIST(client->interface->ntcpcurrent > 0); - client->interface->ntcpcurrent--; - UNLOCK(&client->interface->lock); - - /* - * We must take ownership of the new socket before the exit - * check to make sure it gets destroyed if we decide to exit. - */ - if (nevent->result == ISC_R_SUCCESS) { - client->tcpsocket = nevent->newsocket; - client->state = NS_CLIENTSTATE_READING; - INSIST(client->recursionquota == NULL); - - (void)isc_socket_getpeername(client->tcpsocket, - &client->peeraddr); - client->peeraddr_valid = ISC_TRUE; - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "new TCP connection"); - } else { - /* - * XXXRTH What should we do? We're trying to accept but - * it didn't work. If we just give up, then TCP - * service may eventually stop. - * - * For now, we just go idle. - * - * Going idle is probably the right thing if the - * I/O was canceled. - */ - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "accept failed: %s", - isc_result_totext(nevent->result)); - } - - if (exit_check(client)) - goto freeevent; - - if (nevent->result == ISC_R_SUCCESS) { - int match; - isc_netaddr_t netaddr; - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - - if (ns_g_server->blackholeacl != NULL && - dns_acl_match(&netaddr, NULL, - ns_g_server->blackholeacl, - &ns_g_server->aclenv, - &match, NULL) == ISC_R_SUCCESS && - match > 0) - { - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "blackholed connection attempt"); - client->newstate = NS_CLIENTSTATE_READY; - (void)exit_check(client); - goto freeevent; - } - - INSIST(client->tcpmsg_valid == ISC_FALSE); - dns_tcpmsg_init(client->mctx, client->tcpsocket, - &client->tcpmsg); - client->tcpmsg_valid = ISC_TRUE; - - /* - * Let a new client take our place immediately, before - * we wait for a request packet. If we don't, - * telnetting to port 53 (once per CPU) will - * deny service to legititmate TCP clients. - */ - result = isc_quota_attach(&ns_g_server->tcpquota, - &client->tcpquota); - if (result == ISC_R_SUCCESS) - result = ns_client_replace(client); - if (result != ISC_R_SUCCESS) { - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_WARNING, - "no more TCP clients: %s", - isc_result_totext(result)); - } - - client_read(client); - } - - freeevent: - isc_event_free(&event); -} - -static void -client_accept(ns_client_t *client) { - isc_result_t result; - - CTRACE("accept"); - - result = isc_socket_accept(client->tcplistener, client->task, - client_newconn, client); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_socket_accept() failed: %s", - isc_result_totext(result)); - /* - * XXXRTH What should we do? We're trying to accept but - * it didn't work. If we just give up, then TCP - * service may eventually stop. - * - * For now, we just go idle. - */ - return; - } - INSIST(client->naccepts == 0); - client->naccepts++; - LOCK(&client->interface->lock); - client->interface->ntcpcurrent++; - UNLOCK(&client->interface->lock); -} - -static void -client_udprecv(ns_client_t *client) { - isc_result_t result; - isc_region_t r; - - CTRACE("udprecv"); - - r.base = client->recvbuf; - r.length = RECV_BUFFER_SIZE; - result = isc_socket_recv2(client->udpsocket, &r, 1, - client->task, client->recvevent, 0); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_socket_recv2() failed: %s", - isc_result_totext(result)); - /* - * This cannot happen in the current implementation, since - * isc_socket_recv2() cannot fail if flags == 0. - * - * If this does fail, we just go idle. - */ - return; - } - INSIST(client->nrecvs == 0); - client->nrecvs++; -} - -void -ns_client_attach(ns_client_t *source, ns_client_t **targetp) { - REQUIRE(NS_CLIENT_VALID(source)); - REQUIRE(targetp != NULL && *targetp == NULL); - - source->references++; - ns_client_log(source, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "ns_client_attach: ref = %d", source->references); - *targetp = source; -} - -void -ns_client_detach(ns_client_t **clientp) { - ns_client_t *client = *clientp; - - client->references--; - INSIST(client->references >= 0); - *clientp = NULL; - ns_client_log(client, NS_LOGCATEGORY_CLIENT, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), - "ns_client_detach: ref = %d", client->references); - (void)exit_check(client); -} - -isc_boolean_t -ns_client_shuttingdown(ns_client_t *client) { - return (ISC_TF(client->newstate == NS_CLIENTSTATE_FREED)); -} - -isc_result_t -ns_client_replace(ns_client_t *client) { - isc_result_t result; - - CTRACE("replace"); - - result = ns_clientmgr_createclients(client->manager, - 1, client->interface, - (TCP_CLIENT(client) ? - ISC_TRUE : ISC_FALSE)); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * The responsibility for listening for new requests is hereby - * transferred to the new client. Therefore, the old client - * should refrain from listening for any more requests. - */ - client->mortal = ISC_TRUE; - - return (ISC_R_SUCCESS); -} - -/*** - *** Client Manager - ***/ - -static void -clientmgr_destroy(ns_clientmgr_t *manager) { - REQUIRE(ISC_LIST_EMPTY(manager->active)); - REQUIRE(ISC_LIST_EMPTY(manager->inactive)); - REQUIRE(ISC_LIST_EMPTY(manager->recursing)); - - MTRACE("clientmgr_destroy"); - - DESTROYLOCK(&manager->lock); - manager->magic = 0; - isc_mem_put(manager->mctx, manager, sizeof(*manager)); -} - -isc_result_t -ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr, ns_clientmgr_t **managerp) -{ - ns_clientmgr_t *manager; - isc_result_t result; - - manager = isc_mem_get(mctx, sizeof(*manager)); - if (manager == NULL) - return (ISC_R_NOMEMORY); - - result = isc_mutex_init(&manager->lock); - if (result != ISC_R_SUCCESS) - goto cleanup_manager; - - manager->mctx = mctx; - manager->taskmgr = taskmgr; - manager->timermgr = timermgr; - manager->exiting = ISC_FALSE; - ISC_LIST_INIT(manager->active); - ISC_LIST_INIT(manager->inactive); - ISC_LIST_INIT(manager->recursing); - manager->magic = MANAGER_MAGIC; - - MTRACE("create"); - - *managerp = manager; - - return (ISC_R_SUCCESS); - - cleanup_manager: - isc_mem_put(manager->mctx, manager, sizeof(*manager)); - - return (result); -} - -void -ns_clientmgr_destroy(ns_clientmgr_t **managerp) { - ns_clientmgr_t *manager; - ns_client_t *client; - isc_boolean_t need_destroy = ISC_FALSE; - - REQUIRE(managerp != NULL); - manager = *managerp; - REQUIRE(VALID_MANAGER(manager)); - - MTRACE("destroy"); - - LOCK(&manager->lock); - - manager->exiting = ISC_TRUE; - - for (client = ISC_LIST_HEAD(manager->recursing); - client != NULL; - client = ISC_LIST_NEXT(client, link)) - isc_task_shutdown(client->task); - - for (client = ISC_LIST_HEAD(manager->active); - client != NULL; - client = ISC_LIST_NEXT(client, link)) - isc_task_shutdown(client->task); - - for (client = ISC_LIST_HEAD(manager->inactive); - client != NULL; - client = ISC_LIST_NEXT(client, link)) - isc_task_shutdown(client->task); - - if (ISC_LIST_EMPTY(manager->active) && - ISC_LIST_EMPTY(manager->inactive) && - ISC_LIST_EMPTY(manager->recursing)) - need_destroy = ISC_TRUE; - - UNLOCK(&manager->lock); - - if (need_destroy) - clientmgr_destroy(manager); - - *managerp = NULL; -} - -isc_result_t -ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n, - ns_interface_t *ifp, isc_boolean_t tcp) -{ - isc_result_t result = ISC_R_SUCCESS; - unsigned int i; - ns_client_t *client; - - REQUIRE(VALID_MANAGER(manager)); - REQUIRE(n > 0); - - MTRACE("createclients"); - - /* - * We MUST lock the manager lock for the entire client creation - * process. If we didn't do this, then a client could get a - * shutdown event and disappear out from under us. - */ - - LOCK(&manager->lock); - - for (i = 0; i < n; i++) { - isc_event_t *ev; - /* - * Allocate a client. First try to get a recycled one; - * if that fails, make a new one. - */ - client = ISC_LIST_HEAD(manager->inactive); - if (client != NULL) { - MTRACE("recycle"); - ISC_LIST_UNLINK(manager->inactive, client, link); - client->list = NULL; - } else { - MTRACE("create new"); - result = client_create(manager, &client); - if (result != ISC_R_SUCCESS) - break; - } - - ns_interface_attach(ifp, &client->interface); - client->state = NS_CLIENTSTATE_READY; - INSIST(client->recursionquota == NULL); - - if (tcp) { - client->attributes |= NS_CLIENTATTR_TCP; - isc_socket_attach(ifp->tcpsocket, - &client->tcplistener); - } else { - isc_socket_t *sock; - - dns_dispatch_attach(ifp->udpdispatch, - &client->dispatch); - sock = dns_dispatch_getsocket(client->dispatch); - isc_socket_attach(sock, &client->udpsocket); - } - client->manager = manager; - ISC_LIST_APPEND(manager->active, client, link); - client->list = &manager->active; - - INSIST(client->nctls == 0); - client->nctls++; - ev = &client->ctlevent; - isc_task_send(client->task, &ev); - } - if (i != 0) { - /* - * We managed to create at least one client, so we - * declare victory. - */ - result = ISC_R_SUCCESS; - } - - UNLOCK(&manager->lock); - - return (result); -} - -isc_sockaddr_t * -ns_client_getsockaddr(ns_client_t *client) { - return (&client->peeraddr); -} - -isc_result_t -ns_client_checkaclsilent(ns_client_t *client, dns_acl_t *acl, - isc_boolean_t default_allow) -{ - isc_result_t result; - int match; - isc_netaddr_t netaddr; - - if (acl == NULL) { - if (default_allow) - goto allow; - else - goto deny; - } - - isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); - - result = dns_acl_match(&netaddr, client->signer, acl, - &ns_g_server->aclenv, - &match, NULL); - if (result != ISC_R_SUCCESS) - goto deny; /* Internal error, already logged. */ - if (match > 0) - goto allow; - goto deny; /* Negative match or no match. */ - - allow: - return (ISC_R_SUCCESS); - - deny: - return (DNS_R_REFUSED); -} - -isc_result_t -ns_client_checkacl(ns_client_t *client, - const char *opname, dns_acl_t *acl, - isc_boolean_t default_allow, int log_level) -{ - isc_result_t result = - ns_client_checkaclsilent(client, acl, default_allow); - - if (result == ISC_R_SUCCESS) - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), - "%s approved", opname); - else - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, - log_level, "%s denied", opname); - return (result); -} - -static void -ns_client_name(ns_client_t *client, char *peerbuf, size_t len) { - if (client->peeraddr_valid) - isc_sockaddr_format(&client->peeraddr, peerbuf, len); - else - snprintf(peerbuf, len, "@%p", client); -} - -void -ns_client_logv(ns_client_t *client, isc_logcategory_t *category, - isc_logmodule_t *module, int level, const char *fmt, va_list ap) -{ - char msgbuf[2048]; - char peerbuf[ISC_SOCKADDR_FORMATSIZE]; - const char *name = ""; - const char *sep = ""; - - vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); - ns_client_name(client, peerbuf, sizeof(peerbuf)); - if (client->view != NULL && strcmp(client->view->name, "_bind") != 0 && - strcmp(client->view->name, "_default") != 0) { - name = client->view->name; - sep = ": view "; - } - - isc_log_write(ns_g_lctx, category, module, level, - "client %s%s%s: %s", peerbuf, sep, name, msgbuf); -} - -void -ns_client_log(ns_client_t *client, isc_logcategory_t *category, - isc_logmodule_t *module, int level, const char *fmt, ...) -{ - va_list ap; - - if (! isc_log_wouldlog(ns_g_lctx, level)) - return; - - va_start(ap, fmt); - ns_client_logv(client, category, module, level, fmt, ap); - va_end(ap); -} - -void -ns_client_aclmsg(const char *msg, dns_name_t *name, dns_rdatatype_t type, - dns_rdataclass_t rdclass, char *buf, size_t len) -{ - char namebuf[DNS_NAME_FORMATSIZE]; - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - - dns_name_format(name, namebuf, sizeof(namebuf)); - dns_rdatatype_format(type, typebuf, sizeof(typebuf)); - dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf)); - (void)snprintf(buf, len, "%s '%s/%s/%s'", msg, namebuf, typebuf, - classbuf); -} - -static void -ns_client_dumpmessage(ns_client_t *client, const char *reason) { - isc_buffer_t buffer; - char *buf = NULL; - int len = 1024; - isc_result_t result; - - /* - * Note that these are multiline debug messages. We want a newline - * to appear in the log after each message. - */ - - do { - buf = isc_mem_get(client->mctx, len); - if (buf == NULL) - break; - isc_buffer_init(&buffer, buf, len); - result = dns_message_totext(client->message, - &dns_master_style_debug, - 0, &buffer); - if (result == ISC_R_NOSPACE) { - isc_mem_put(client->mctx, buf, len); - len += 1024; - } else if (result == ISC_R_SUCCESS) - ns_client_log(client, NS_LOGCATEGORY_UNMATCHED, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), - "%s\n%.*s", reason, - (int)isc_buffer_usedlength(&buffer), - buf); - } while (result == ISC_R_NOSPACE); - - if (buf != NULL) - isc_mem_put(client->mctx, buf, len); -} - -void -ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) { - ns_client_t *client; - char namebuf[DNS_NAME_FORMATSIZE]; - char peerbuf[ISC_SOCKADDR_FORMATSIZE]; - const char *name; - const char *sep; - - REQUIRE(VALID_MANAGER(manager)); - - LOCK(&manager->lock); - client = ISC_LIST_HEAD(manager->recursing); - while (client != NULL) { - ns_client_name(client, peerbuf, sizeof(peerbuf)); - if (client->view != NULL && - strcmp(client->view->name, "_bind") != 0 && - strcmp(client->view->name, "_default") != 0) { - name = client->view->name; - sep = ": view "; - } else { - name = ""; - sep = ""; - } - dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); - fprintf(f, "; client %s%s%s: '%s' requesttime %d\n", - peerbuf, sep, name, namebuf, client->requesttime); - client = ISC_LIST_NEXT(client, link); - } - UNLOCK(&manager->lock); -} diff --git a/contrib/bind9/bin/named/config.c b/contrib/bind9/bin/named/config.c deleted file mode 100644 index 99e5ffa7f418..000000000000 --- a/contrib/bind9/bin/named/config.c +++ /dev/null @@ -1,723 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001-2003 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: config.c,v 1.11.2.4.8.29 2004/10/05 02:52:26 marka Exp $ */ - -#include <config.h> - -#include <stdlib.h> -#include <string.h> - -#include <isc/buffer.h> -#include <isc/log.h> -#include <isc/mem.h> -#include <isc/region.h> -#include <isc/result.h> -#include <isc/sockaddr.h> -#include <isc/util.h> - -#include <isccfg/namedconf.h> - -#include <dns/fixedname.h> -#include <dns/name.h> -#include <dns/rdataclass.h> -#include <dns/rdatatype.h> -#include <dns/tsig.h> -#include <dns/zone.h> - -#include <named/config.h> -#include <named/globals.h> - -static char defaultconf[] = "\ -options {\n\ -# blackhole {none;};\n" -#ifndef WIN32 -" coresize default;\n\ - datasize default;\n\ - files default;\n\ - stacksize default;\n" -#endif -" deallocate-on-exit true;\n\ -# directory <none>\n\ - dump-file \"named_dump.db\";\n\ - fake-iquery no;\n\ - has-old-clients false;\n\ - heartbeat-interval 60;\n\ - host-statistics no;\n\ - interface-interval 60;\n\ - listen-on {any;};\n\ - listen-on-v6 {none;};\n\ - match-mapped-addresses no;\n\ - memstatistics-file \"named.memstats\";\n\ - multiple-cnames no;\n\ -# named-xfer <obsolete>;\n\ -# pid-file \"" NS_LOCALSTATEDIR "/named.pid\"; /* or /lwresd.pid */\n\ - port 53;\n\ - recursing-file \"named.recursing\";\n\ -" -#ifdef PATH_RANDOMDEV -"\ - random-device \"" PATH_RANDOMDEV "\";\n\ -" -#endif -"\ - recursive-clients 1000;\n\ - rrset-order {order cyclic;};\n\ - serial-queries 20;\n\ - serial-query-rate 20;\n\ - server-id none;\n\ - statistics-file \"named.stats\";\n\ - statistics-interval 60;\n\ - tcp-clients 100;\n\ - tcp-listen-queue 3;\n\ -# tkey-dhkey <none>\n\ -# tkey-gssapi-credential <none>\n\ -# tkey-domain <none>\n\ - transfers-per-ns 2;\n\ - transfers-in 10;\n\ - transfers-out 10;\n\ - treat-cr-as-space true;\n\ - use-id-pool true;\n\ - use-ixfr true;\n\ - edns-udp-size 4096;\n\ -\n\ - /* view */\n\ - allow-notify {none;};\n\ - allow-update-forwarding {none;};\n\ - allow-recursion {any;};\n\ -# allow-v6-synthesis <obsolete>;\n\ -# sortlist <none>\n\ -# topology <none>\n\ - auth-nxdomain false;\n\ - minimal-responses false;\n\ - recursion true;\n\ - provide-ixfr true;\n\ - request-ixfr true;\n\ - fetch-glue no;\n\ - rfc2308-type1 no;\n\ - additional-from-auth true;\n\ - additional-from-cache true;\n\ - query-source address *;\n\ - query-source-v6 address *;\n\ - notify-source *;\n\ - notify-source-v6 *;\n\ - cleaning-interval 60;\n\ - min-roots 2;\n\ - lame-ttl 600;\n\ - max-ncache-ttl 10800; /* 3 hours */\n\ - max-cache-ttl 604800; /* 1 week */\n\ - transfer-format many-answers;\n\ - max-cache-size 0;\n\ - check-names master fail;\n\ - check-names slave warn;\n\ - check-names response ignore;\n\ - dnssec-enable no; /* Make yes for 9.4. */ \n\ -" - -" /* zone */\n\ - allow-query {any;};\n\ - allow-transfer {any;};\n\ - notify yes;\n\ -# also-notify <none>\n\ - dialup no;\n\ -# forward <none>\n\ -# forwarders <none>\n\ - maintain-ixfr-base no;\n\ -# max-ixfr-log-size <obsolete>\n\ - transfer-source *;\n\ - transfer-source-v6 *;\n\ - alt-transfer-source *;\n\ - alt-transfer-source-v6 *;\n\ - max-transfer-time-in 120;\n\ - max-transfer-time-out 120;\n\ - max-transfer-idle-in 60;\n\ - max-transfer-idle-out 60;\n\ - max-retry-time 1209600; /* 2 weeks */\n\ - min-retry-time 500;\n\ - max-refresh-time 2419200; /* 4 weeks */\n\ - min-refresh-time 300;\n\ - multi-master no;\n\ - sig-validity-interval 30; /* days */\n\ - zone-statistics false;\n\ - max-journal-size unlimited;\n\ - ixfr-from-differences false;\n\ -};\n\ -" - -"#\n\ -# Zones in the \"_bind\" view are NOT counted is the count of zones.\n\ -#\n\ -view \"_bind\" chaos {\n\ - recursion no;\n\ - notify no;\n\ -\n\ - zone \"version.bind\" chaos {\n\ - type master;\n\ - database \"_builtin version\";\n\ - };\n\ -\n\ - zone \"hostname.bind\" chaos {\n\ - type master;\n\ - database \"_builtin hostname\";\n\ - };\n\ -\n\ - zone \"authors.bind\" chaos {\n\ - type master;\n\ - database \"_builtin authors\";\n\ - };\n\ - zone \"id.server\" chaos {\n\ - type master;\n\ - database \"_builtin id\";\n\ - };\n\ -};\n\ -"; - -isc_result_t -ns_config_parsedefaults(cfg_parser_t *parser, cfg_obj_t **conf) { - isc_buffer_t b; - - isc_buffer_init(&b, defaultconf, sizeof(defaultconf) - 1); - isc_buffer_add(&b, sizeof(defaultconf) - 1); - return (cfg_parse_buffer(parser, &b, &cfg_type_namedconf, conf)); -} - -isc_result_t -ns_config_get(cfg_obj_t **maps, const char *name, cfg_obj_t **obj) { - int i; - - for (i = 0;; i++) { - if (maps[i] == NULL) - return (ISC_R_NOTFOUND); - if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - } -} - -isc_result_t -ns_checknames_get(cfg_obj_t **maps, const char *which, cfg_obj_t **obj) { - cfg_listelt_t *element; - cfg_obj_t *checknames; - cfg_obj_t *type; - cfg_obj_t *value; - int i; - - for (i = 0;; i++) { - if (maps[i] == NULL) - return (ISC_R_NOTFOUND); - checknames = NULL; - if (cfg_map_get(maps[i], "check-names", &checknames) == ISC_R_SUCCESS) { - /* - * Zone map entry is not a list. - */ - if (checknames != NULL && !cfg_obj_islist(checknames)) { - *obj = checknames; - return (ISC_R_SUCCESS); - } - for (element = cfg_list_first(checknames); - element != NULL; - element = cfg_list_next(element)) { - value = cfg_listelt_value(element); - type = cfg_tuple_get(value, "type"); - if (strcasecmp(cfg_obj_asstring(type), which) == 0) { - *obj = cfg_tuple_get(value, "mode"); - return (ISC_R_SUCCESS); - } - } - - } - } -} - -int -ns_config_listcount(cfg_obj_t *list) { - cfg_listelt_t *e; - int i = 0; - - for (e = cfg_list_first(list); e != NULL; e = cfg_list_next(e)) - i++; - - return (i); -} - -isc_result_t -ns_config_getclass(cfg_obj_t *classobj, dns_rdataclass_t defclass, - dns_rdataclass_t *classp) { - char *str; - isc_textregion_t r; - isc_result_t result; - - if (!cfg_obj_isstring(classobj)) { - *classp = defclass; - return (ISC_R_SUCCESS); - } - str = cfg_obj_asstring(classobj); - r.base = str; - r.length = strlen(str); - result = dns_rdataclass_fromtext(classp, &r); - if (result != ISC_R_SUCCESS) - cfg_obj_log(classobj, ns_g_lctx, ISC_LOG_ERROR, - "unknown class '%s'", str); - return (result); -} - -isc_result_t -ns_config_gettype(cfg_obj_t *typeobj, dns_rdatatype_t deftype, - dns_rdatatype_t *typep) { - char *str; - isc_textregion_t r; - isc_result_t result; - - if (!cfg_obj_isstring(typeobj)) { - *typep = deftype; - return (ISC_R_SUCCESS); - } - str = cfg_obj_asstring(typeobj); - r.base = str; - r.length = strlen(str); - result = dns_rdatatype_fromtext(typep, &r); - if (result != ISC_R_SUCCESS) - cfg_obj_log(typeobj, ns_g_lctx, ISC_LOG_ERROR, - "unknown type '%s'", str); - return (result); -} - -dns_zonetype_t -ns_config_getzonetype(cfg_obj_t *zonetypeobj) { - dns_zonetype_t ztype = dns_zone_none; - char *str; - - str = cfg_obj_asstring(zonetypeobj); - if (strcasecmp(str, "master") == 0) - ztype = dns_zone_master; - else if (strcasecmp(str, "slave") == 0) - ztype = dns_zone_slave; - else if (strcasecmp(str, "stub") == 0) - ztype = dns_zone_stub; - else - INSIST(0); - return (ztype); -} - -isc_result_t -ns_config_getiplist(cfg_obj_t *config, cfg_obj_t *list, - in_port_t defport, isc_mem_t *mctx, - isc_sockaddr_t **addrsp, isc_uint32_t *countp) -{ - int count, i = 0; - cfg_obj_t *addrlist; - cfg_obj_t *portobj; - cfg_listelt_t *element; - isc_sockaddr_t *addrs; - in_port_t port; - isc_result_t result; - - INSIST(addrsp != NULL && *addrsp == NULL); - INSIST(countp != NULL); - - addrlist = cfg_tuple_get(list, "addresses"); - count = ns_config_listcount(addrlist); - - portobj = cfg_tuple_get(list, "port"); - if (cfg_obj_isuint32(portobj)) { - isc_uint32_t val = cfg_obj_asuint32(portobj); - if (val > ISC_UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port '%u' out of range", val); - return (ISC_R_RANGE); - } - port = (in_port_t) val; - } else if (defport != 0) - port = defport; - else { - result = ns_config_getport(config, &port); - if (result != ISC_R_SUCCESS) - return (result); - } - - addrs = isc_mem_get(mctx, count * sizeof(isc_sockaddr_t)); - if (addrs == NULL) - return (ISC_R_NOMEMORY); - - for (element = cfg_list_first(addrlist); - element != NULL; - element = cfg_list_next(element), i++) - { - INSIST(i < count); - addrs[i] = *cfg_obj_assockaddr(cfg_listelt_value(element)); - if (isc_sockaddr_getport(&addrs[i]) == 0) - isc_sockaddr_setport(&addrs[i], port); - } - INSIST(i == count); - - *addrsp = addrs; - *countp = count; - - return (ISC_R_SUCCESS); -} - -void -ns_config_putiplist(isc_mem_t *mctx, isc_sockaddr_t **addrsp, - isc_uint32_t count) -{ - INSIST(addrsp != NULL && *addrsp != NULL); - - isc_mem_put(mctx, *addrsp, count * sizeof(isc_sockaddr_t)); - *addrsp = NULL; -} - -static isc_result_t -get_masters_def(cfg_obj_t *cctx, char *name, cfg_obj_t **ret) { - isc_result_t result; - cfg_obj_t *masters = NULL; - cfg_listelt_t *elt; - - result = cfg_map_get(cctx, "masters", &masters); - if (result != ISC_R_SUCCESS) - return (result); - for (elt = cfg_list_first(masters); - elt != NULL; - elt = cfg_list_next(elt)) { - cfg_obj_t *list; - const char *listname; - - list = cfg_listelt_value(elt); - listname = cfg_obj_asstring(cfg_tuple_get(list, "name")); - - if (strcasecmp(listname, name) == 0) { - *ret = list; - return (ISC_R_SUCCESS); - } - } - return (ISC_R_NOTFOUND); -} - -isc_result_t -ns_config_getipandkeylist(cfg_obj_t *config, cfg_obj_t *list, isc_mem_t *mctx, - isc_sockaddr_t **addrsp, dns_name_t ***keysp, - isc_uint32_t *countp) -{ - isc_uint32_t addrcount = 0, keycount = 0, i = 0; - isc_uint32_t listcount = 0, l = 0, j; - isc_uint32_t stackcount = 0, pushed = 0; - isc_result_t result; - cfg_listelt_t *element; - cfg_obj_t *addrlist; - cfg_obj_t *portobj; - in_port_t port; - dns_fixedname_t fname; - isc_sockaddr_t *addrs = NULL; - dns_name_t **keys = NULL; - char **lists = NULL; - struct { - cfg_listelt_t *element; - in_port_t port; - } *stack = NULL; - - REQUIRE(addrsp != NULL && *addrsp == NULL); - REQUIRE(keysp != NULL && *keysp == NULL); - REQUIRE(countp != NULL); - - newlist: - addrlist = cfg_tuple_get(list, "addresses"); - portobj = cfg_tuple_get(list, "port"); - if (cfg_obj_isuint32(portobj)) { - isc_uint32_t val = cfg_obj_asuint32(portobj); - if (val > ISC_UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port '%u' out of range", val); - return (ISC_R_RANGE); - } - port = (in_port_t) val; - } else { - result = ns_config_getport(config, &port); - if (result != ISC_R_SUCCESS) - return (result); - } - - result = ISC_R_NOMEMORY; - - element = cfg_list_first(addrlist); - resume: - for ( ; - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *addr; - cfg_obj_t *key; - char *keystr; - isc_buffer_t b; - - addr = cfg_tuple_get(cfg_listelt_value(element), - "masterselement"); - key = cfg_tuple_get(cfg_listelt_value(element), "key"); - - if (!cfg_obj_issockaddr(addr)) { - char *listname = cfg_obj_asstring(addr); - isc_result_t tresult; - - /* Grow lists? */ - if (listcount == l) { - void * new; - isc_uint32_t newlen = listcount + 16; - size_t newsize, oldsize; - - newsize = newlen * sizeof(*lists); - oldsize = listcount * sizeof(*lists); - new = isc_mem_get(mctx, newsize); - if (new == NULL) - goto cleanup; - if (listcount != 0) { - memcpy(new, lists, oldsize); - isc_mem_put(mctx, lists, oldsize); - } - lists = new; - listcount = newlen; - } - /* Seen? */ - for (j = 0; j < l; j++) - if (strcasecmp(lists[j], listname) == 0) - break; - if (j < l) - continue; - tresult = get_masters_def(config, listname, &list); - if (tresult == ISC_R_NOTFOUND) { - cfg_obj_log(addr, ns_g_lctx, ISC_LOG_ERROR, - "masters \"%s\" not found", listname); - - result = tresult; - goto cleanup; - } - if (tresult != ISC_R_SUCCESS) - goto cleanup; - lists[l++] = listname; - /* Grow stack? */ - if (stackcount == pushed) { - void * new; - isc_uint32_t newlen = stackcount + 16; - size_t newsize, oldsize; - - newsize = newlen * sizeof(*stack); - oldsize = stackcount * sizeof(*stack); - new = isc_mem_get(mctx, newsize); - if (new == NULL) - goto cleanup; - if (stackcount != 0) { - memcpy(new, stack, oldsize); - isc_mem_put(mctx, stack, oldsize); - } - stack = new; - stackcount = newlen; - } - /* - * We want to resume processing this list on the - * next element. - */ - stack[pushed].element = cfg_list_next(element); - stack[pushed].port = port; - pushed++; - goto newlist; - } - - if (i == addrcount) { - void * new; - isc_uint32_t newlen = addrcount + 16; - size_t newsize, oldsize; - - newsize = newlen * sizeof(isc_sockaddr_t); - oldsize = addrcount * sizeof(isc_sockaddr_t); - new = isc_mem_get(mctx, newsize); - if (new == NULL) - goto cleanup; - if (addrcount != 0) { - memcpy(new, addrs, oldsize); - isc_mem_put(mctx, addrs, oldsize); - } - addrs = new; - addrcount = newlen; - - newsize = newlen * sizeof(dns_name_t *); - oldsize = keycount * sizeof(dns_name_t *); - new = isc_mem_get(mctx, newsize); - if (new == NULL) - goto cleanup; - if (keycount != 0) { - memcpy(new, keys, oldsize); - isc_mem_put(mctx, keys, oldsize); - } - keys = new; - keycount = newlen; - } - - addrs[i] = *cfg_obj_assockaddr(addr); - if (isc_sockaddr_getport(&addrs[i]) == 0) - isc_sockaddr_setport(&addrs[i], port); - keys[i] = NULL; - if (!cfg_obj_isstring(key)) { - i++; - continue; - } - keys[i] = isc_mem_get(mctx, sizeof(dns_name_t)); - if (keys[i] == NULL) - goto cleanup; - dns_name_init(keys[i], NULL); - - keystr = cfg_obj_asstring(key); - isc_buffer_init(&b, keystr, strlen(keystr)); - isc_buffer_add(&b, strlen(keystr)); - dns_fixedname_init(&fname); - result = dns_name_fromtext(dns_fixedname_name(&fname), &b, - dns_rootname, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_name_dup(dns_fixedname_name(&fname), mctx, - keys[i]); - if (result != ISC_R_SUCCESS) - goto cleanup; - i++; - } - if (pushed != 0) { - pushed--; - element = stack[pushed].element; - port = stack[pushed].port; - goto resume; - } - if (i < addrcount) { - void * new; - size_t newsize, oldsize; - - newsize = i * sizeof(isc_sockaddr_t); - oldsize = addrcount * sizeof(isc_sockaddr_t); - if (i != 0) { - new = isc_mem_get(mctx, newsize); - if (new == NULL) - goto cleanup; - memcpy(new, addrs, newsize); - isc_mem_put(mctx, addrs, oldsize); - } else - new = NULL; - addrs = new; - addrcount = i; - - newsize = i * sizeof(dns_name_t *); - oldsize = keycount * sizeof(dns_name_t *); - if (i != 0) { - new = isc_mem_get(mctx, newsize); - if (new == NULL) - goto cleanup; - memcpy(new, keys, newsize); - isc_mem_put(mctx, keys, oldsize); - } else - new = NULL; - keys = new; - keycount = i; - } - - if (lists != NULL) - isc_mem_put(mctx, lists, listcount * sizeof(*lists)); - if (stack != NULL) - isc_mem_put(mctx, stack, stackcount * sizeof(*stack)); - - INSIST(keycount == addrcount); - - *addrsp = addrs; - *keysp = keys; - *countp = addrcount; - - return (ISC_R_SUCCESS); - - cleanup: - if (addrs != NULL) - isc_mem_put(mctx, addrs, addrcount * sizeof(isc_sockaddr_t)); - if (keys != NULL) { - for (j = 0; j <= i; j++) { - if (keys[j] == NULL) - continue; - if (dns_name_dynamic(keys[j])) - dns_name_free(keys[j], mctx); - isc_mem_put(mctx, keys[j], sizeof(dns_name_t)); - } - isc_mem_put(mctx, keys, keycount * sizeof(dns_name_t *)); - } - if (lists != NULL) - isc_mem_put(mctx, lists, listcount * sizeof(*lists)); - if (stack != NULL) - isc_mem_put(mctx, stack, stackcount * sizeof(*stack)); - return (result); -} - -void -ns_config_putipandkeylist(isc_mem_t *mctx, isc_sockaddr_t **addrsp, - dns_name_t ***keysp, isc_uint32_t count) -{ - unsigned int i; - dns_name_t **keys = *keysp; - - INSIST(addrsp != NULL && *addrsp != NULL); - - isc_mem_put(mctx, *addrsp, count * sizeof(isc_sockaddr_t)); - for (i = 0; i < count; i++) { - if (keys[i] == NULL) - continue; - if (dns_name_dynamic(keys[i])) - dns_name_free(keys[i], mctx); - isc_mem_put(mctx, keys[i], sizeof(dns_name_t)); - } - isc_mem_put(mctx, *keysp, count * sizeof(dns_name_t *)); - *addrsp = NULL; - *keysp = NULL; -} - -isc_result_t -ns_config_getport(cfg_obj_t *config, in_port_t *portp) { - cfg_obj_t *maps[3]; - cfg_obj_t *options = NULL; - cfg_obj_t *portobj = NULL; - isc_result_t result; - int i; - - (void)cfg_map_get(config, "options", &options); - i = 0; - if (options != NULL) - maps[i++] = options; - maps[i++] = ns_g_defaults; - maps[i] = NULL; - - result = ns_config_get(maps, "port", &portobj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_asuint32(portobj) >= ISC_UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port '%u' out of range", - cfg_obj_asuint32(portobj)); - return (ISC_R_RANGE); - } - *portp = (in_port_t)cfg_obj_asuint32(portobj); - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_config_getkeyalgorithm(const char *str, dns_name_t **name) -{ - if (strcasecmp(str, "hmac-md5") == 0 || - strcasecmp(str, "hmac-md5.sig-alg.reg.int") == 0 || - strcasecmp(str, "hmac-md5.sig-alg.reg.int.") == 0) - { - if (name != NULL) - *name = dns_tsig_hmacmd5_name; - return (ISC_R_SUCCESS); - } - return (ISC_R_NOTFOUND); -} diff --git a/contrib/bind9/bin/named/control.c b/contrib/bind9/bin/named/control.c deleted file mode 100644 index c9d17abe0276..000000000000 --- a/contrib/bind9/bin/named/control.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001-2003 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: control.c,v 1.7.2.2.2.14 2005/04/29 01:04:47 marka Exp $ */ - -#include <config.h> - -#include <string.h> - -#include <isc/app.h> -#include <isc/event.h> -#include <isc/mem.h> -#include <isc/timer.h> -#include <isc/util.h> - -#include <dns/result.h> - -#include <isccc/alist.h> -#include <isccc/cc.h> -#include <isccc/result.h> - -#include <named/control.h> -#include <named/log.h> -#include <named/os.h> -#include <named/server.h> -#ifdef HAVE_LIBSCF -#include <named/ns_smf_globals.h> -#endif - -static isc_boolean_t -command_compare(const char *text, const char *command) { - unsigned int commandlen = strlen(command); - if (strncasecmp(text, command, commandlen) == 0 && - (text[commandlen] == '\0' || - text[commandlen] == ' ' || - text[commandlen] == '\t')) - return (ISC_TRUE); - return (ISC_FALSE); -} - -/* - * This function is called to process the incoming command - * when a control channel message is received. - */ -isc_result_t -ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) { - isccc_sexpr_t *data; - char *command; - isc_result_t result; -#ifdef HAVE_LIBSCF - ns_smf_want_disable = 0; -#endif - - data = isccc_alist_lookup(message, "_data"); - if (data == NULL) { - /* - * No data section. - */ - return (ISC_R_FAILURE); - } - - result = isccc_cc_lookupstring(data, "type", &command); - if (result != ISC_R_SUCCESS) { - /* - * We have no idea what this is. - */ - return (result); - } - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_DEBUG(1), - "received control channel command '%s'", - command); - - /* - * Compare the 'command' parameter against all known control commands. - */ - if (command_compare(command, NS_COMMAND_RELOAD)) { - result = ns_server_reloadcommand(ns_g_server, command, text); - } else if (command_compare(command, NS_COMMAND_RECONFIG)) { - result = ns_server_reconfigcommand(ns_g_server, command); - } else if (command_compare(command, NS_COMMAND_REFRESH)) { - result = ns_server_refreshcommand(ns_g_server, command, text); - } else if (command_compare(command, NS_COMMAND_RETRANSFER)) { - result = ns_server_retransfercommand(ns_g_server, command); - } else if (command_compare(command, NS_COMMAND_HALT)) { -#ifdef HAVE_LIBSCF - /* - * If we are managed by smf(5), AND in chroot, then - * we cannot connect to the smf repository, so just - * return with an appropriate message back to rndc. - */ - if (ns_smf_got_instance == 1 && ns_smf_chroot == 1) { - result = ns_smf_add_message(text); - return (result); - } - /* - * If we are managed by smf(5) but not in chroot, - * try to disable ourselves the smf way. - */ - if (ns_smf_got_instance == 1 && ns_smf_chroot == 0) - ns_smf_want_disable = 1; - /* - * If ns_smf_got_instance = 0, ns_smf_chroot - * is not relevant and we fall through to - * isc_app_shutdown below. - */ -#endif - ns_server_flushonshutdown(ns_g_server, ISC_FALSE); - ns_os_shutdownmsg(command, text); - isc_app_shutdown(); - result = ISC_R_SUCCESS; - } else if (command_compare(command, NS_COMMAND_STOP)) { -#ifdef HAVE_LIBSCF - if (ns_smf_got_instance == 1 && ns_smf_chroot == 1) { - result = ns_smf_add_message(text); - return (result); - } - if (ns_smf_got_instance == 1 && ns_smf_chroot == 0) - ns_smf_want_disable = 1; -#endif - ns_server_flushonshutdown(ns_g_server, ISC_TRUE); - ns_os_shutdownmsg(command, text); - isc_app_shutdown(); - result = ISC_R_SUCCESS; - } else if (command_compare(command, NS_COMMAND_DUMPSTATS)) { - result = ns_server_dumpstats(ns_g_server); - } else if (command_compare(command, NS_COMMAND_QUERYLOG)) { - result = ns_server_togglequerylog(ns_g_server); - } else if (command_compare(command, NS_COMMAND_DUMPDB)) { - ns_server_dumpdb(ns_g_server, command); - result = ISC_R_SUCCESS; - } else if (command_compare(command, NS_COMMAND_TRACE)) { - result = ns_server_setdebuglevel(ns_g_server, command); - } else if (command_compare(command, NS_COMMAND_NOTRACE)) { - ns_g_debuglevel = 0; - isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel); - result = ISC_R_SUCCESS; - } else if (command_compare(command, NS_COMMAND_FLUSH)) { - result = ns_server_flushcache(ns_g_server, command); - } else if (command_compare(command, NS_COMMAND_FLUSHNAME)) { - result = ns_server_flushname(ns_g_server, command); - } else if (command_compare(command, NS_COMMAND_STATUS)) { - result = ns_server_status(ns_g_server, text); - } else if (command_compare(command, NS_COMMAND_FREEZE)) { - result = ns_server_freeze(ns_g_server, ISC_TRUE, command); - } else if (command_compare(command, NS_COMMAND_UNFREEZE) || - command_compare(command, NS_COMMAND_THAW)) { - result = ns_server_freeze(ns_g_server, ISC_FALSE, command); - } else if (command_compare(command, NS_COMMAND_RECURSING)) { - result = ns_server_dumprecursing(ns_g_server); - } else if (command_compare(command, NS_COMMAND_NULL)) { - result = ISC_R_SUCCESS; - } else { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "unknown control channel command '%s'", - command); - result = DNS_R_UNKNOWNCOMMAND; - } - - return (result); -} diff --git a/contrib/bind9/bin/named/controlconf.c b/contrib/bind9/bin/named/controlconf.c deleted file mode 100644 index 5b87fb9c0a1f..000000000000 --- a/contrib/bind9/bin/named/controlconf.c +++ /dev/null @@ -1,1323 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001-2003 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: controlconf.c,v 1.28.2.9.2.6 2004/03/08 09:04:14 marka Exp $ */ - -#include <config.h> - -#include <isc/base64.h> -#include <isc/buffer.h> -#include <isc/event.h> -#include <isc/mem.h> -#include <isc/net.h> -#include <isc/netaddr.h> -#include <isc/random.h> -#include <isc/result.h> -#include <isc/stdtime.h> -#include <isc/string.h> -#include <isc/timer.h> -#include <isc/util.h> - -#include <isccfg/namedconf.h> - -#include <bind9/check.h> - -#include <isccc/alist.h> -#include <isccc/cc.h> -#include <isccc/ccmsg.h> -#include <isccc/events.h> -#include <isccc/result.h> -#include <isccc/sexpr.h> -#include <isccc/symtab.h> -#include <isccc/util.h> - -#include <dns/result.h> - -#include <named/config.h> -#include <named/control.h> -#include <named/log.h> -#include <named/server.h> - -/* - * Note: Listeners and connections are not locked. All event handlers are - * executed by the server task, and all callers of exported routines must - * be running under the server task. - */ - -typedef struct controlkey controlkey_t; -typedef ISC_LIST(controlkey_t) controlkeylist_t; - -typedef struct controlconnection controlconnection_t; -typedef ISC_LIST(controlconnection_t) controlconnectionlist_t; - -typedef struct controllistener controllistener_t; -typedef ISC_LIST(controllistener_t) controllistenerlist_t; - -struct controlkey { - char * keyname; - isc_region_t secret; - ISC_LINK(controlkey_t) link; -}; - -struct controlconnection { - isc_socket_t * sock; - isccc_ccmsg_t ccmsg; - isc_boolean_t ccmsg_valid; - isc_boolean_t sending; - isc_timer_t * timer; - unsigned char buffer[2048]; - controllistener_t * listener; - isc_uint32_t nonce; - ISC_LINK(controlconnection_t) link; -}; - -struct controllistener { - ns_controls_t * controls; - isc_mem_t * mctx; - isc_task_t * task; - isc_sockaddr_t address; - isc_socket_t * sock; - dns_acl_t * acl; - isc_boolean_t listening; - isc_boolean_t exiting; - controlkeylist_t keys; - controlconnectionlist_t connections; - ISC_LINK(controllistener_t) link; -}; - -struct ns_controls { - ns_server_t *server; - controllistenerlist_t listeners; - isc_boolean_t shuttingdown; - isccc_symtab_t *symtab; -}; - -static void control_newconn(isc_task_t *task, isc_event_t *event); -static void control_recvmessage(isc_task_t *task, isc_event_t *event); - -#define CLOCKSKEW 300 - -static void -free_controlkey(controlkey_t *key, isc_mem_t *mctx) { - if (key->keyname != NULL) - isc_mem_free(mctx, key->keyname); - if (key->secret.base != NULL) - isc_mem_put(mctx, key->secret.base, key->secret.length); - isc_mem_put(mctx, key, sizeof(*key)); -} - -static void -free_controlkeylist(controlkeylist_t *keylist, isc_mem_t *mctx) { - while (!ISC_LIST_EMPTY(*keylist)) { - controlkey_t *key = ISC_LIST_HEAD(*keylist); - ISC_LIST_UNLINK(*keylist, key, link); - free_controlkey(key, mctx); - } -} - -static void -free_listener(controllistener_t *listener) { - INSIST(listener->exiting); - INSIST(!listener->listening); - INSIST(ISC_LIST_EMPTY(listener->connections)); - - if (listener->sock != NULL) - isc_socket_detach(&listener->sock); - - free_controlkeylist(&listener->keys, listener->mctx); - - if (listener->acl != NULL) - dns_acl_detach(&listener->acl); - - isc_mem_put(listener->mctx, listener, sizeof(*listener)); -} - -static void -maybe_free_listener(controllistener_t *listener) { - if (listener->exiting && - !listener->listening && - ISC_LIST_EMPTY(listener->connections)) - free_listener(listener); -} - -static void -maybe_free_connection(controlconnection_t *conn) { - controllistener_t *listener = conn->listener; - - if (conn->timer != NULL) - isc_timer_detach(&conn->timer); - - if (conn->ccmsg_valid) { - isccc_ccmsg_cancelread(&conn->ccmsg); - return; - } - - if (conn->sending) { - isc_socket_cancel(conn->sock, listener->task, - ISC_SOCKCANCEL_SEND); - return; - } - - ISC_LIST_UNLINK(listener->connections, conn, link); - isc_mem_put(listener->mctx, conn, sizeof(*conn)); -} - -static void -shutdown_listener(controllistener_t *listener) { - controlconnection_t *conn; - controlconnection_t *next; - - if (!listener->exiting) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - - ISC_LIST_UNLINK(listener->controls->listeners, listener, link); - - isc_sockaddr_format(&listener->address, socktext, - sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE, - "stopping command channel on %s", socktext); - listener->exiting = ISC_TRUE; - } - - for (conn = ISC_LIST_HEAD(listener->connections); - conn != NULL; - conn = next) - { - next = ISC_LIST_NEXT(conn, link); - maybe_free_connection(conn); - } - - if (listener->listening) - isc_socket_cancel(listener->sock, listener->task, - ISC_SOCKCANCEL_ACCEPT); - - maybe_free_listener(listener); -} - -static isc_boolean_t -address_ok(isc_sockaddr_t *sockaddr, dns_acl_t *acl) { - isc_netaddr_t netaddr; - isc_result_t result; - int match; - - isc_netaddr_fromsockaddr(&netaddr, sockaddr); - - result = dns_acl_match(&netaddr, NULL, acl, - &ns_g_server->aclenv, &match, NULL); - - if (result != ISC_R_SUCCESS || match <= 0) - return (ISC_FALSE); - else - return (ISC_TRUE); -} - -static isc_result_t -control_accept(controllistener_t *listener) { - isc_result_t result; - result = isc_socket_accept(listener->sock, - listener->task, - control_newconn, listener); - if (result != ISC_R_SUCCESS) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_socket_accept() failed: %s", - isc_result_totext(result)); - else - listener->listening = ISC_TRUE; - return (result); -} - -static isc_result_t -control_listen(controllistener_t *listener) { - isc_result_t result; - - result = isc_socket_listen(listener->sock, 0); - if (result != ISC_R_SUCCESS) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_socket_listen() failed: %s", - isc_result_totext(result)); - return (result); -} - -static void -control_next(controllistener_t *listener) { - (void)control_accept(listener); -} - -static void -control_senddone(isc_task_t *task, isc_event_t *event) { - isc_socketevent_t *sevent = (isc_socketevent_t *) event; - controlconnection_t *conn = event->ev_arg; - controllistener_t *listener = conn->listener; - isc_socket_t *sock = (isc_socket_t *)sevent->ev_sender; - isc_result_t result; - - REQUIRE(conn->sending); - - UNUSED(task); - - conn->sending = ISC_FALSE; - - if (sevent->result != ISC_R_SUCCESS && - sevent->result != ISC_R_CANCELED) - { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_t peeraddr; - - (void)isc_socket_getpeername(sock, &peeraddr); - isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "error sending command response to %s: %s", - socktext, isc_result_totext(sevent->result)); - } - isc_event_free(&event); - - result = isccc_ccmsg_readmessage(&conn->ccmsg, listener->task, - control_recvmessage, conn); - if (result != ISC_R_SUCCESS) { - isc_socket_detach(&conn->sock); - maybe_free_connection(conn); - maybe_free_listener(listener); - } -} - -static inline void -log_invalid(isccc_ccmsg_t *ccmsg, isc_result_t result) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_t peeraddr; - - (void)isc_socket_getpeername(ccmsg->sock, &peeraddr); - isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_ERROR, - "invalid command from %s: %s", - socktext, isc_result_totext(result)); -} - -static void -control_recvmessage(isc_task_t *task, isc_event_t *event) { - controlconnection_t *conn; - controllistener_t *listener; - controlkey_t *key; - isccc_sexpr_t *request = NULL; - isccc_sexpr_t *response = NULL; - isccc_region_t ccregion; - isccc_region_t secret; - isc_stdtime_t now; - isc_buffer_t b; - isc_region_t r; - isc_uint32_t len; - isc_buffer_t text; - char textarray[1024]; - isc_result_t result; - isc_result_t eresult; - isccc_sexpr_t *_ctrl; - isccc_time_t sent; - isccc_time_t exp; - isc_uint32_t nonce; - - REQUIRE(event->ev_type == ISCCC_EVENT_CCMSG); - - conn = event->ev_arg; - listener = conn->listener; - secret.rstart = NULL; - - /* Is the server shutting down? */ - if (listener->controls->shuttingdown) - goto cleanup; - - if (conn->ccmsg.result != ISC_R_SUCCESS) { - if (conn->ccmsg.result != ISC_R_CANCELED && - conn->ccmsg.result != ISC_R_EOF) - log_invalid(&conn->ccmsg, conn->ccmsg.result); - goto cleanup; - } - - request = NULL; - - for (key = ISC_LIST_HEAD(listener->keys); - key != NULL; - key = ISC_LIST_NEXT(key, link)) - { - ccregion.rstart = isc_buffer_base(&conn->ccmsg.buffer); - ccregion.rend = isc_buffer_used(&conn->ccmsg.buffer); - secret.rstart = isc_mem_get(listener->mctx, key->secret.length); - if (secret.rstart == NULL) - goto cleanup; - memcpy(secret.rstart, key->secret.base, key->secret.length); - secret.rend = secret.rstart + key->secret.length; - result = isccc_cc_fromwire(&ccregion, &request, &secret); - if (result == ISC_R_SUCCESS) - break; - else if (result == ISCCC_R_BADAUTH) { - /* - * For some reason, request is non-NULL when - * isccc_cc_fromwire returns ISCCC_R_BADAUTH. - */ - if (request != NULL) - isccc_sexpr_free(&request); - isc_mem_put(listener->mctx, secret.rstart, - REGION_SIZE(secret)); - } else { - log_invalid(&conn->ccmsg, result); - goto cleanup; - } - } - - if (key == NULL) { - log_invalid(&conn->ccmsg, ISCCC_R_BADAUTH); - goto cleanup; - } - - /* We shouldn't be getting a reply. */ - if (isccc_cc_isreply(request)) { - log_invalid(&conn->ccmsg, ISC_R_FAILURE); - goto cleanup; - } - - isc_stdtime_get(&now); - - /* - * Limit exposure to replay attacks. - */ - _ctrl = isccc_alist_lookup(request, "_ctrl"); - if (_ctrl == NULL) { - log_invalid(&conn->ccmsg, ISC_R_FAILURE); - goto cleanup; - } - - if (isccc_cc_lookupuint32(_ctrl, "_tim", &sent) == ISC_R_SUCCESS) { - if ((sent + CLOCKSKEW) < now || (sent - CLOCKSKEW) > now) { - log_invalid(&conn->ccmsg, ISCCC_R_CLOCKSKEW); - goto cleanup; - } - } else { - log_invalid(&conn->ccmsg, ISC_R_FAILURE); - goto cleanup; - } - - /* - * Expire messages that are too old. - */ - if (isccc_cc_lookupuint32(_ctrl, "_exp", &exp) == ISC_R_SUCCESS && - now > exp) { - log_invalid(&conn->ccmsg, ISCCC_R_EXPIRED); - goto cleanup; - } - - /* - * Duplicate suppression (required for UDP). - */ - isccc_cc_cleansymtab(listener->controls->symtab, now); - result = isccc_cc_checkdup(listener->controls->symtab, request, now); - if (result != ISC_R_SUCCESS) { - if (result == ISC_R_EXISTS) - result = ISCCC_R_DUPLICATE; - log_invalid(&conn->ccmsg, result); - goto cleanup; - } - - if (conn->nonce != 0 && - (isccc_cc_lookupuint32(_ctrl, "_nonce", &nonce) != ISC_R_SUCCESS || - conn->nonce != nonce)) { - log_invalid(&conn->ccmsg, ISCCC_R_BADAUTH); - goto cleanup; - } - - /* - * Establish nonce. - */ - while (conn->nonce == 0) - isc_random_get(&conn->nonce); - - isc_buffer_init(&text, textarray, sizeof(textarray)); - eresult = ns_control_docommand(request, &text); - - result = isccc_cc_createresponse(request, now, now + 60, &response); - if (result != ISC_R_SUCCESS) - goto cleanup; - if (eresult != ISC_R_SUCCESS) { - isccc_sexpr_t *data; - - data = isccc_alist_lookup(response, "_data"); - if (data != NULL) { - const char *estr = isc_result_totext(eresult); - if (isccc_cc_definestring(data, "err", estr) == NULL) - goto cleanup; - } - } - - if (isc_buffer_usedlength(&text) > 0) { - isccc_sexpr_t *data; - - data = isccc_alist_lookup(response, "_data"); - if (data != NULL) { - char *str = (char *)isc_buffer_base(&text); - if (isccc_cc_definestring(data, "text", str) == NULL) - goto cleanup; - } - } - - _ctrl = isccc_alist_lookup(response, "_ctrl"); - if (_ctrl == NULL || - isccc_cc_defineuint32(_ctrl, "_nonce", conn->nonce) == NULL) - goto cleanup; - - ccregion.rstart = conn->buffer + 4; - ccregion.rend = conn->buffer + sizeof(conn->buffer); - result = isccc_cc_towire(response, &ccregion, &secret); - if (result != ISC_R_SUCCESS) - goto cleanup; - isc_buffer_init(&b, conn->buffer, 4); - len = sizeof(conn->buffer) - REGION_SIZE(ccregion); - isc_buffer_putuint32(&b, len - 4); - r.base = conn->buffer; - r.length = len; - - result = isc_socket_send(conn->sock, &r, task, control_senddone, conn); - if (result != ISC_R_SUCCESS) - goto cleanup; - conn->sending = ISC_TRUE; - - if (secret.rstart != NULL) - isc_mem_put(listener->mctx, secret.rstart, - REGION_SIZE(secret)); - if (request != NULL) - isccc_sexpr_free(&request); - if (response != NULL) - isccc_sexpr_free(&response); - return; - - cleanup: - if (secret.rstart != NULL) - isc_mem_put(listener->mctx, secret.rstart, - REGION_SIZE(secret)); - isc_socket_detach(&conn->sock); - isccc_ccmsg_invalidate(&conn->ccmsg); - conn->ccmsg_valid = ISC_FALSE; - maybe_free_connection(conn); - maybe_free_listener(listener); - if (request != NULL) - isccc_sexpr_free(&request); - if (response != NULL) - isccc_sexpr_free(&response); -} - -static void -control_timeout(isc_task_t *task, isc_event_t *event) { - controlconnection_t *conn = event->ev_arg; - - UNUSED(task); - - isc_timer_detach(&conn->timer); - maybe_free_connection(conn); - - isc_event_free(&event); -} - -static isc_result_t -newconnection(controllistener_t *listener, isc_socket_t *sock) { - controlconnection_t *conn; - isc_interval_t interval; - isc_result_t result; - - conn = isc_mem_get(listener->mctx, sizeof(*conn)); - if (conn == NULL) - return (ISC_R_NOMEMORY); - - conn->sock = sock; - isccc_ccmsg_init(listener->mctx, sock, &conn->ccmsg); - conn->ccmsg_valid = ISC_TRUE; - conn->sending = ISC_FALSE; - conn->timer = NULL; - isc_interval_set(&interval, 60, 0); - result = isc_timer_create(ns_g_timermgr, isc_timertype_once, - NULL, &interval, listener->task, - control_timeout, conn, &conn->timer); - if (result != ISC_R_SUCCESS) - goto cleanup; - - conn->listener = listener; - conn->nonce = 0; - ISC_LINK_INIT(conn, link); - - result = isccc_ccmsg_readmessage(&conn->ccmsg, listener->task, - control_recvmessage, conn); - if (result != ISC_R_SUCCESS) - goto cleanup; - isccc_ccmsg_setmaxsize(&conn->ccmsg, 2048); - - ISC_LIST_APPEND(listener->connections, conn, link); - return (ISC_R_SUCCESS); - - cleanup: - isccc_ccmsg_invalidate(&conn->ccmsg); - if (conn->timer != NULL) - isc_timer_detach(&conn->timer); - isc_mem_put(listener->mctx, conn, sizeof(*conn)); - return (result); -} - -static void -control_newconn(isc_task_t *task, isc_event_t *event) { - isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event; - controllistener_t *listener = event->ev_arg; - isc_socket_t *sock; - isc_sockaddr_t peeraddr; - isc_result_t result; - - UNUSED(task); - - listener->listening = ISC_FALSE; - - if (nevent->result != ISC_R_SUCCESS) { - if (nevent->result == ISC_R_CANCELED) { - shutdown_listener(listener); - goto cleanup; - } - goto restart; - } - - sock = nevent->newsocket; - (void)isc_socket_getpeername(sock, &peeraddr); - if (!address_ok(&peeraddr, listener->acl)) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "rejected command channel message from %s", - socktext); - isc_socket_detach(&sock); - goto restart; - } - - result = newconnection(listener, sock); - if (result != ISC_R_SUCCESS) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_WARNING, - "dropped command channel from %s: %s", - socktext, isc_result_totext(result)); - isc_socket_detach(&sock); - goto restart; - } - - restart: - control_next(listener); - cleanup: - isc_event_free(&event); -} - -static void -controls_shutdown(ns_controls_t *controls) { - controllistener_t *listener; - controllistener_t *next; - - for (listener = ISC_LIST_HEAD(controls->listeners); - listener != NULL; - listener = next) - { - /* - * This is asynchronous. As listeners shut down, they will - * call their callbacks. - */ - next = ISC_LIST_NEXT(listener, link); - shutdown_listener(listener); - } -} - -void -ns_controls_shutdown(ns_controls_t *controls) { - controls_shutdown(controls); - controls->shuttingdown = ISC_TRUE; -} - -static isc_result_t -cfgkeylist_find(cfg_obj_t *keylist, const char *keyname, cfg_obj_t **objp) { - cfg_listelt_t *element; - const char *str; - cfg_obj_t *obj; - - for (element = cfg_list_first(keylist); - element != NULL; - element = cfg_list_next(element)) - { - obj = cfg_listelt_value(element); - str = cfg_obj_asstring(cfg_map_getname(obj)); - if (strcasecmp(str, keyname) == 0) - break; - } - if (element == NULL) - return (ISC_R_NOTFOUND); - obj = cfg_listelt_value(element); - *objp = obj; - return (ISC_R_SUCCESS); -} - -static isc_result_t -controlkeylist_fromcfg(cfg_obj_t *keylist, isc_mem_t *mctx, - controlkeylist_t *keyids) -{ - cfg_listelt_t *element; - char *newstr = NULL; - const char *str; - cfg_obj_t *obj; - controlkey_t *key = NULL; - - for (element = cfg_list_first(keylist); - element != NULL; - element = cfg_list_next(element)) - { - obj = cfg_listelt_value(element); - str = cfg_obj_asstring(obj); - newstr = isc_mem_strdup(mctx, str); - if (newstr == NULL) - goto cleanup; - key = isc_mem_get(mctx, sizeof(*key)); - if (key == NULL) - goto cleanup; - key->keyname = newstr; - key->secret.base = NULL; - key->secret.length = 0; - ISC_LINK_INIT(key, link); - ISC_LIST_APPEND(*keyids, key, link); - key = NULL; - newstr = NULL; - } - return (ISC_R_SUCCESS); - - cleanup: - if (newstr != NULL) - isc_mem_free(mctx, newstr); - if (key != NULL) - isc_mem_put(mctx, key, sizeof(*key)); - free_controlkeylist(keyids, mctx); - return (ISC_R_NOMEMORY); -} - -static void -register_keys(cfg_obj_t *control, cfg_obj_t *keylist, - controlkeylist_t *keyids, isc_mem_t *mctx, const char *socktext) -{ - controlkey_t *keyid, *next; - cfg_obj_t *keydef; - char secret[1024]; - isc_buffer_t b; - isc_result_t result; - - /* - * Find the keys corresponding to the keyids used by this listener. - */ - for (keyid = ISC_LIST_HEAD(*keyids); keyid != NULL; keyid = next) { - next = ISC_LIST_NEXT(keyid, link); - - result = cfgkeylist_find(keylist, keyid->keyname, &keydef); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't find key '%s' for use with " - "command channel %s", - keyid->keyname, socktext); - ISC_LIST_UNLINK(*keyids, keyid, link); - free_controlkey(keyid, mctx); - } else { - cfg_obj_t *algobj = NULL; - cfg_obj_t *secretobj = NULL; - char *algstr = NULL; - char *secretstr = NULL; - - (void)cfg_map_get(keydef, "algorithm", &algobj); - (void)cfg_map_get(keydef, "secret", &secretobj); - INSIST(algobj != NULL && secretobj != NULL); - - algstr = cfg_obj_asstring(algobj); - secretstr = cfg_obj_asstring(secretobj); - - if (ns_config_getkeyalgorithm(algstr, NULL) != - ISC_R_SUCCESS) - { - cfg_obj_log(control, ns_g_lctx, - ISC_LOG_WARNING, - "unsupported algorithm '%s' in " - "key '%s' for use with command " - "channel %s", - algstr, keyid->keyname, socktext); - ISC_LIST_UNLINK(*keyids, keyid, link); - free_controlkey(keyid, mctx); - continue; - } - - isc_buffer_init(&b, secret, sizeof(secret)); - result = isc_base64_decodestring(secretstr, &b); - - if (result != ISC_R_SUCCESS) { - cfg_obj_log(keydef, ns_g_lctx, ISC_LOG_WARNING, - "secret for key '%s' on " - "command channel %s: %s", - keyid->keyname, socktext, - isc_result_totext(result)); - ISC_LIST_UNLINK(*keyids, keyid, link); - free_controlkey(keyid, mctx); - continue; - } - - keyid->secret.length = isc_buffer_usedlength(&b); - keyid->secret.base = isc_mem_get(mctx, - keyid->secret.length); - if (keyid->secret.base == NULL) { - cfg_obj_log(keydef, ns_g_lctx, ISC_LOG_WARNING, - "couldn't register key '%s': " - "out of memory", keyid->keyname); - ISC_LIST_UNLINK(*keyids, keyid, link); - free_controlkey(keyid, mctx); - break; - } - memcpy(keyid->secret.base, isc_buffer_base(&b), - keyid->secret.length); - } - } -} - -#define CHECK(x) \ - do { \ - result = (x); \ - if (result != ISC_R_SUCCESS) \ - goto cleanup; \ - } while (0) - -static isc_result_t -get_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) { - isc_result_t result; - cfg_parser_t *pctx = NULL; - cfg_obj_t *config = NULL; - cfg_obj_t *key = NULL; - cfg_obj_t *algobj = NULL; - cfg_obj_t *secretobj = NULL; - char *algstr = NULL; - char *secretstr = NULL; - controlkey_t *keyid = NULL; - char secret[1024]; - isc_buffer_t b; - - CHECK(cfg_parser_create(mctx, ns_g_lctx, &pctx)); - CHECK(cfg_parse_file(pctx, ns_g_keyfile, &cfg_type_rndckey, &config)); - CHECK(cfg_map_get(config, "key", &key)); - - keyid = isc_mem_get(mctx, sizeof(*keyid)); - if (keyid == NULL) - CHECK(ISC_R_NOMEMORY); - keyid->keyname = isc_mem_strdup(mctx, - cfg_obj_asstring(cfg_map_getname(key))); - keyid->secret.base = NULL; - keyid->secret.length = 0; - ISC_LINK_INIT(keyid, link); - if (keyid->keyname == NULL) - CHECK(ISC_R_NOMEMORY); - - CHECK(bind9_check_key(key, ns_g_lctx)); - - (void)cfg_map_get(key, "algorithm", &algobj); - (void)cfg_map_get(key, "secret", &secretobj); - INSIST(algobj != NULL && secretobj != NULL); - - algstr = cfg_obj_asstring(algobj); - secretstr = cfg_obj_asstring(secretobj); - - if (ns_config_getkeyalgorithm(algstr, NULL) != ISC_R_SUCCESS) { - cfg_obj_log(key, ns_g_lctx, - ISC_LOG_WARNING, - "unsupported algorithm '%s' in " - "key '%s' for use with command " - "channel", - algstr, keyid->keyname); - goto cleanup; - } - - isc_buffer_init(&b, secret, sizeof(secret)); - result = isc_base64_decodestring(secretstr, &b); - - if (result != ISC_R_SUCCESS) { - cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING, - "secret for key '%s' on command channel: %s", - keyid->keyname, isc_result_totext(result)); - CHECK(result); - } - - keyid->secret.length = isc_buffer_usedlength(&b); - keyid->secret.base = isc_mem_get(mctx, - keyid->secret.length); - if (keyid->secret.base == NULL) { - cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING, - "couldn't register key '%s': " - "out of memory", keyid->keyname); - CHECK(ISC_R_NOMEMORY); - } - memcpy(keyid->secret.base, isc_buffer_base(&b), - keyid->secret.length); - ISC_LIST_APPEND(*keyids, keyid, link); - keyid = NULL; - result = ISC_R_SUCCESS; - - cleanup: - if (keyid != NULL) - free_controlkey(keyid, mctx); - if (config != NULL) - cfg_obj_destroy(pctx, &config); - if (pctx != NULL) - cfg_parser_destroy(&pctx); - return (result); -} - -/* - * Ensures that both '*global_keylistp' and '*control_keylistp' are - * valid or both are NULL. - */ -static void -get_key_info(cfg_obj_t *config, cfg_obj_t *control, - cfg_obj_t **global_keylistp, cfg_obj_t **control_keylistp) -{ - isc_result_t result; - cfg_obj_t *control_keylist = NULL; - cfg_obj_t *global_keylist = NULL; - - REQUIRE(global_keylistp != NULL && *global_keylistp == NULL); - REQUIRE(control_keylistp != NULL && *control_keylistp == NULL); - - control_keylist = cfg_tuple_get(control, "keys"); - - if (!cfg_obj_isvoid(control_keylist) && - cfg_list_first(control_keylist) != NULL) { - result = cfg_map_get(config, "key", &global_keylist); - - if (result == ISC_R_SUCCESS) { - *global_keylistp = global_keylist; - *control_keylistp = control_keylist; - } - } -} - -static void -update_listener(ns_controls_t *cp, - controllistener_t **listenerp, cfg_obj_t *control, - cfg_obj_t *config, isc_sockaddr_t *addr, - ns_aclconfctx_t *aclconfctx, const char *socktext) -{ - controllistener_t *listener; - cfg_obj_t *allow; - cfg_obj_t *global_keylist = NULL; - cfg_obj_t *control_keylist = NULL; - dns_acl_t *new_acl = NULL; - controlkeylist_t keys; - isc_result_t result = ISC_R_SUCCESS; - - for (listener = ISC_LIST_HEAD(cp->listeners); - listener != NULL; - listener = ISC_LIST_NEXT(listener, link)) - if (isc_sockaddr_equal(addr, &listener->address)) - break; - - if (listener == NULL) { - *listenerp = NULL; - return; - } - - /* - * There is already a listener for this sockaddr. - * Update the access list and key information. - * - * First try to deal with the key situation. There are a few - * possibilities: - * (a) It had an explicit keylist and still has an explicit keylist. - * (b) It had an automagic key and now has an explicit keylist. - * (c) It had an explicit keylist and now needs an automagic key. - * (d) It has an automagic key and still needs the automagic key. - * - * (c) and (d) are the annoying ones. The caller needs to know - * that it should use the automagic configuration for key information - * in place of the named.conf configuration. - * - * XXXDCL There is one other hazard that has not been dealt with, - * the problem that if a key change is being caused by a control - * channel reload, then the response will be with the new key - * and not able to be decrypted by the client. - */ - if (control != NULL) - get_key_info(config, control, &global_keylist, - &control_keylist); - - if (control_keylist != NULL) { - INSIST(global_keylist != NULL); - - ISC_LIST_INIT(keys); - result = controlkeylist_fromcfg(control_keylist, - listener->mctx, &keys); - if (result == ISC_R_SUCCESS) { - free_controlkeylist(&listener->keys, listener->mctx); - listener->keys = keys; - register_keys(control, global_keylist, &listener->keys, - listener->mctx, socktext); - } - } else { - free_controlkeylist(&listener->keys, listener->mctx); - result = get_rndckey(listener->mctx, &listener->keys); - } - - if (result != ISC_R_SUCCESS && global_keylist != NULL) - /* - * This message might be a little misleading since the - * "new keys" might in fact be identical to the old ones, - * but tracking whether they are identical just for the - * sake of avoiding this message would be too much trouble. - */ - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't install new keys for " - "command channel %s: %s", - socktext, isc_result_totext(result)); - - - /* - * Now, keep the old access list unless a new one can be made. - */ - if (control != NULL) { - allow = cfg_tuple_get(control, "allow"); - result = ns_acl_fromconfig(allow, config, aclconfctx, - listener->mctx, &new_acl); - } else { - result = dns_acl_any(listener->mctx, &new_acl); - } - - if (result == ISC_R_SUCCESS) { - dns_acl_detach(&listener->acl); - dns_acl_attach(new_acl, &listener->acl); - dns_acl_detach(&new_acl); - } else - /* XXXDCL say the old acl is still used? */ - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't install new acl for " - "command channel %s: %s", - socktext, isc_result_totext(result)); - - *listenerp = listener; -} - -static void -add_listener(ns_controls_t *cp, controllistener_t **listenerp, - cfg_obj_t *control, cfg_obj_t *config, isc_sockaddr_t *addr, - ns_aclconfctx_t *aclconfctx, const char *socktext) -{ - isc_mem_t *mctx = cp->server->mctx; - controllistener_t *listener; - cfg_obj_t *allow; - cfg_obj_t *global_keylist = NULL; - cfg_obj_t *control_keylist = NULL; - dns_acl_t *new_acl = NULL; - isc_result_t result = ISC_R_SUCCESS; - - listener = isc_mem_get(mctx, sizeof(*listener)); - if (listener == NULL) - result = ISC_R_NOMEMORY; - - if (result == ISC_R_SUCCESS) { - listener->controls = cp; - listener->mctx = mctx; - listener->task = cp->server->task; - listener->address = *addr; - listener->sock = NULL; - listener->listening = ISC_FALSE; - listener->exiting = ISC_FALSE; - listener->acl = NULL; - ISC_LINK_INIT(listener, link); - ISC_LIST_INIT(listener->keys); - ISC_LIST_INIT(listener->connections); - - /* - * Make the acl. - */ - if (control != NULL) { - allow = cfg_tuple_get(control, "allow"); - result = ns_acl_fromconfig(allow, config, aclconfctx, - mctx, &new_acl); - } else { - result = dns_acl_any(mctx, &new_acl); - } - } - - if (result == ISC_R_SUCCESS) { - dns_acl_attach(new_acl, &listener->acl); - dns_acl_detach(&new_acl); - - if (config != NULL) - get_key_info(config, control, &global_keylist, - &control_keylist); - - if (control_keylist != NULL) { - result = controlkeylist_fromcfg(control_keylist, - listener->mctx, - &listener->keys); - if (result == ISC_R_SUCCESS) - register_keys(control, global_keylist, - &listener->keys, - listener->mctx, socktext); - } else - result = get_rndckey(mctx, &listener->keys); - - if (result != ISC_R_SUCCESS && control != NULL) - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't install keys for " - "command channel %s: %s", - socktext, isc_result_totext(result)); - } - - if (result == ISC_R_SUCCESS) { - int pf = isc_sockaddr_pf(&listener->address); - if ((pf == AF_INET && isc_net_probeipv4() != ISC_R_SUCCESS) || - (pf == AF_INET6 && isc_net_probeipv6() != ISC_R_SUCCESS)) - result = ISC_R_FAMILYNOSUPPORT; - } - - if (result == ISC_R_SUCCESS) - result = isc_socket_create(ns_g_socketmgr, - isc_sockaddr_pf(&listener->address), - isc_sockettype_tcp, - &listener->sock); - - if (result == ISC_R_SUCCESS) - result = isc_socket_bind(listener->sock, - &listener->address); - - if (result == ISC_R_SUCCESS) - result = control_listen(listener); - - if (result == ISC_R_SUCCESS) - result = control_accept(listener); - - if (result == ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE, - "command channel listening on %s", socktext); - *listenerp = listener; - - } else { - if (listener != NULL) { - listener->exiting = ISC_TRUE; - free_listener(listener); - } - - if (control != NULL) - cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING, - "couldn't add command channel %s: %s", - socktext, isc_result_totext(result)); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE, - "couldn't add command channel %s: %s", - socktext, isc_result_totext(result)); - - *listenerp = NULL; - } - - /* XXXDCL return error results? fail hard? */ -} - -isc_result_t -ns_controls_configure(ns_controls_t *cp, cfg_obj_t *config, - ns_aclconfctx_t *aclconfctx) -{ - controllistener_t *listener; - controllistenerlist_t new_listeners; - cfg_obj_t *controlslist = NULL; - cfg_listelt_t *element, *element2; - char socktext[ISC_SOCKADDR_FORMATSIZE]; - - ISC_LIST_INIT(new_listeners); - - /* - * Get the list of named.conf 'controls' statements. - */ - (void)cfg_map_get(config, "controls", &controlslist); - - /* - * Run through the new control channel list, noting sockets that - * are already being listened on and moving them to the new list. - * - * Identifying duplicate addr/port combinations is left to either - * the underlying config code, or to the bind attempt getting an - * address-in-use error. - */ - if (controlslist != NULL) { - for (element = cfg_list_first(controlslist); - element != NULL; - element = cfg_list_next(element)) { - cfg_obj_t *controls; - cfg_obj_t *inetcontrols = NULL; - - controls = cfg_listelt_value(element); - (void)cfg_map_get(controls, "inet", &inetcontrols); - if (inetcontrols == NULL) - continue; - - for (element2 = cfg_list_first(inetcontrols); - element2 != NULL; - element2 = cfg_list_next(element2)) { - cfg_obj_t *control; - cfg_obj_t *obj; - isc_sockaddr_t *addr; - - /* - * The parser handles BIND 8 configuration file - * syntax, so it allows unix phrases as well - * inet phrases with no keys{} clause. - * - * "unix" phrases have been reported as - * unsupported by the parser. - */ - control = cfg_listelt_value(element2); - - obj = cfg_tuple_get(control, "address"); - addr = cfg_obj_assockaddr(obj); - if (isc_sockaddr_getport(addr) == 0) - isc_sockaddr_setport(addr, - NS_CONTROL_PORT); - - isc_sockaddr_format(addr, socktext, - sizeof(socktext)); - - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_CONTROL, - ISC_LOG_DEBUG(9), - "processing control channel %s", - socktext); - - update_listener(cp, &listener, control, config, - addr, aclconfctx, socktext); - - if (listener != NULL) - /* - * Remove the listener from the old - * list, so it won't be shut down. - */ - ISC_LIST_UNLINK(cp->listeners, - listener, link); - else - /* - * This is a new listener. - */ - add_listener(cp, &listener, control, - config, addr, aclconfctx, - socktext); - - if (listener != NULL) - ISC_LIST_APPEND(new_listeners, - listener, link); - } - } - } else { - int i; - - for (i = 0; i < 2; i++) { - isc_sockaddr_t addr; - - if (i == 0) { - struct in_addr localhost; - - if (isc_net_probeipv4() != ISC_R_SUCCESS) - continue; - localhost.s_addr = htonl(INADDR_LOOPBACK); - isc_sockaddr_fromin(&addr, &localhost, 0); - } else { - if (isc_net_probeipv6() != ISC_R_SUCCESS) - continue; - isc_sockaddr_fromin6(&addr, - &in6addr_loopback, 0); - } - isc_sockaddr_setport(&addr, NS_CONTROL_PORT); - - isc_sockaddr_format(&addr, socktext, sizeof(socktext)); - - update_listener(cp, &listener, NULL, NULL, - &addr, NULL, socktext); - - if (listener != NULL) - /* - * Remove the listener from the old - * list, so it won't be shut down. - */ - ISC_LIST_UNLINK(cp->listeners, - listener, link); - else - /* - * This is a new listener. - */ - add_listener(cp, &listener, NULL, NULL, - &addr, NULL, socktext); - - if (listener != NULL) - ISC_LIST_APPEND(new_listeners, - listener, link); - } - } - - /* - * ns_control_shutdown() will stop whatever is on the global - * listeners list, which currently only has whatever sockaddrs - * were in the previous configuration (if any) that do not - * remain in the current configuration. - */ - controls_shutdown(cp); - - /* - * Put all of the valid listeners on the listeners list. - * Anything already on listeners in the process of shutting - * down will be taken care of by listen_done(). - */ - ISC_LIST_APPENDLIST(cp->listeners, new_listeners, link); - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp) { - isc_mem_t *mctx = server->mctx; - isc_result_t result; - ns_controls_t *controls = isc_mem_get(mctx, sizeof(*controls)); - - if (controls == NULL) - return (ISC_R_NOMEMORY); - controls->server = server; - ISC_LIST_INIT(controls->listeners); - controls->shuttingdown = ISC_FALSE; - controls->symtab = NULL; - result = isccc_cc_createsymtab(&controls->symtab); - if (result != ISC_R_SUCCESS) { - isc_mem_put(server->mctx, controls, sizeof(*controls)); - return (result); - } - *ctrlsp = controls; - return (ISC_R_SUCCESS); -} - -void -ns_controls_destroy(ns_controls_t **ctrlsp) { - ns_controls_t *controls = *ctrlsp; - - REQUIRE(ISC_LIST_EMPTY(controls->listeners)); - - isccc_symtab_destroy(&controls->symtab); - isc_mem_put(controls->server->mctx, controls, sizeof(*controls)); - *ctrlsp = NULL; -} diff --git a/contrib/bind9/bin/named/include/named/aclconf.h b/contrib/bind9/bin/named/include/named/aclconf.h deleted file mode 100644 index 812657278485..000000000000 --- a/contrib/bind9/bin/named/include/named/aclconf.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: aclconf.h,v 1.12.208.1 2004/03/06 10:21:23 marka Exp $ */ - -#ifndef NS_ACLCONF_H -#define NS_ACLCONF_H 1 - -#include <isc/lang.h> - -#include <isccfg/cfg.h> - -#include <dns/types.h> - -typedef struct ns_aclconfctx { - ISC_LIST(dns_acl_t) named_acl_cache; -} ns_aclconfctx_t; - -/*** - *** Functions - ***/ - -ISC_LANG_BEGINDECLS - -void -ns_aclconfctx_init(ns_aclconfctx_t *ctx); -/* - * Initialize an ACL configuration context. - */ - -void -ns_aclconfctx_destroy(ns_aclconfctx_t *ctx); -/* - * Destroy an ACL configuration context. - */ - -isc_result_t -ns_acl_fromconfig(cfg_obj_t *caml, - cfg_obj_t *cctx, - ns_aclconfctx_t *ctx, - isc_mem_t *mctx, - dns_acl_t **target); -/* - * Construct a new dns_acl_t from configuration data in 'caml' and - * 'cctx'. Memory is allocated through 'mctx'. - * - * Any named ACLs referred to within 'caml' will be be converted - * inte nested dns_acl_t objects. Multiple references to the same - * named ACLs will be converted into shared references to a single - * nested dns_acl_t object when the referring objects were created - * passing the same ACL configuration context 'ctx'. - * - * On success, attach '*target' to the new dns_acl_t object. - */ - -ISC_LANG_ENDDECLS - -#endif /* NS_ACLCONF_H */ diff --git a/contrib/bind9/bin/named/include/named/builtin.h b/contrib/bind9/bin/named/include/named/builtin.h deleted file mode 100644 index 15564bf3fb0d..000000000000 --- a/contrib/bind9/bin/named/include/named/builtin.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: builtin.h,v 1.1.204.3 2004/03/08 04:04:20 marka Exp $ */ - -#ifndef NAMED_BUILTIN_H -#define NAMED_BUILTIN_H 1 - -#include <isc/types.h> - -isc_result_t ns_builtin_init(void); - -void ns_builtin_deinit(void); - -#endif /* NAMED_BUILTIN_H */ diff --git a/contrib/bind9/bin/named/include/named/client.h b/contrib/bind9/bin/named/include/named/client.h deleted file mode 100644 index 7097a3bb05b5..000000000000 --- a/contrib/bind9/bin/named/include/named/client.h +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: client.h,v 1.60.2.2.10.10 2005/07/29 00:13:08 marka Exp $ */ - -#ifndef NAMED_CLIENT_H -#define NAMED_CLIENT_H 1 - -/***** - ***** Module Info - *****/ - -/* - * Client - * - * This module defines two objects, ns_client_t and ns_clientmgr_t. - * - * An ns_client_t object handles incoming DNS requests from clients - * on a given network interface. - * - * Each ns_client_t object can handle only one TCP connection or UDP - * request at a time. Therefore, several ns_client_t objects are - * typically created to serve each network interface, e.g., one - * for handling TCP requests and a few (one per CPU) for handling - * UDP requests. - * - * Incoming requests are classified as queries, zone transfer - * requests, update requests, notify requests, etc, and handed off - * to the appropriate request handler. When the request has been - * fully handled (which can be much later), the ns_client_t must be - * notified of this by calling one of the following functions - * exactly once in the context of its task: - * - * ns_client_send() (sending a non-error response) - * ns_client_sendraw() (sending a raw response) - * ns_client_error() (sending an error response) - * ns_client_next() (sending no response) - * - * This will release any resources used by the request and - * and allow the ns_client_t to listen for the next request. - * - * A ns_clientmgr_t manages a number of ns_client_t objects. - * New ns_client_t objects are created by calling - * ns_clientmgr_createclients(). They are destroyed by - * destroying their manager. - */ - -/*** - *** Imports - ***/ - -#include <isc/buffer.h> -#include <isc/magic.h> -#include <isc/stdtime.h> -#include <isc/quota.h> - -#include <dns/fixedname.h> -#include <dns/name.h> -#include <dns/rdataclass.h> -#include <dns/rdatatype.h> -#include <dns/tcpmsg.h> -#include <dns/types.h> - -#include <named/types.h> -#include <named/query.h> - -/*** - *** Types - ***/ - -typedef ISC_LIST(ns_client_t) client_list_t; - -struct ns_client { - unsigned int magic; - isc_mem_t * mctx; - ns_clientmgr_t * manager; - int state; - int newstate; - int naccepts; - int nreads; - int nsends; - int nrecvs; - int nupdates; - int nctls; - int references; - unsigned int attributes; - isc_task_t * task; - dns_view_t * view; - dns_dispatch_t * dispatch; - isc_socket_t * udpsocket; - isc_socket_t * tcplistener; - isc_socket_t * tcpsocket; - unsigned char * tcpbuf; - dns_tcpmsg_t tcpmsg; - isc_boolean_t tcpmsg_valid; - isc_timer_t * timer; - isc_boolean_t timerset; - dns_message_t * message; - isc_socketevent_t * sendevent; - isc_socketevent_t * recvevent; - unsigned char * recvbuf; - dns_rdataset_t * opt; - isc_uint16_t udpsize; - isc_uint16_t extflags; - void (*next)(ns_client_t *); - void (*shutdown)(void *arg, isc_result_t result); - void *shutdown_arg; - ns_query_t query; - isc_stdtime_t requesttime; - isc_stdtime_t now; - dns_name_t signername; /* [T]SIG key name */ - dns_name_t * signer; /* NULL if not valid sig */ - isc_boolean_t mortal; /* Die after handling request */ - isc_quota_t *tcpquota; - isc_quota_t *recursionquota; - ns_interface_t *interface; - isc_sockaddr_t peeraddr; - isc_boolean_t peeraddr_valid; - struct in6_pktinfo pktinfo; - isc_event_t ctlevent; - /* - * Information about recent FORMERR response(s), for - * FORMERR loop avoidance. This is separate for each - * client object rather than global only to avoid - * the need for locking. - */ - struct { - isc_sockaddr_t addr; - isc_stdtime_t time; - dns_messageid_t id; - } formerrcache; - ISC_LINK(ns_client_t) link; - /* - * The list 'link' is part of, or NULL if not on any list. - */ - client_list_t *list; -}; - -#define NS_CLIENT_MAGIC ISC_MAGIC('N','S','C','c') -#define NS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC) - -#define NS_CLIENTATTR_TCP 0x01 -#define NS_CLIENTATTR_RA 0x02 /* Client gets recusive service */ -#define NS_CLIENTATTR_PKTINFO 0x04 /* pktinfo is valid */ -#define NS_CLIENTATTR_MULTICAST 0x08 /* recv'd from multicast */ -#define NS_CLIENTATTR_WANTDNSSEC 0x10 /* include dnssec records */ - - -/*** - *** Functions - ***/ - -/* - * Note! These ns_client_ routines MUST be called ONLY from the client's - * task in order to ensure synchronization. - */ - -void -ns_client_send(ns_client_t *client); -/* - * Finish processing the current client request and - * send client->message as a response. - */ - -void -ns_client_sendraw(ns_client_t *client, dns_message_t *msg); -/* - * Finish processing the current client request and - * send msg as a response using client->message->id for the id. - */ - -void -ns_client_error(ns_client_t *client, isc_result_t result); -/* - * Finish processing the current client request and return - * an error response to the client. The error response - * will have an RCODE determined by 'result'. - */ - -void -ns_client_next(ns_client_t *client, isc_result_t result); -/* - * Finish processing the current client request, - * return no response to the client. - */ - -isc_boolean_t -ns_client_shuttingdown(ns_client_t *client); -/* - * Return ISC_TRUE iff the client is currently shutting down. - */ - -void -ns_client_attach(ns_client_t *source, ns_client_t **target); -/* - * Attach '*targetp' to 'source'. - */ - -void -ns_client_detach(ns_client_t **clientp); -/* - * Detach '*clientp' from its client. - */ - -isc_result_t -ns_client_replace(ns_client_t *client); -/* - * Try to replace the current client with a new one, so that the - * current one can go off and do some lengthy work without - * leaving the dispatch/socket without service. - */ - -void -ns_client_settimeout(ns_client_t *client, unsigned int seconds); -/* - * Set a timer in the client to go off in the specified amount of time. - */ - -isc_result_t -ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_timermgr_t *timermgr, ns_clientmgr_t **managerp); -/* - * Create a client manager. - */ - -void -ns_clientmgr_destroy(ns_clientmgr_t **managerp); -/* - * Destroy a client manager and all ns_client_t objects - * managed by it. - */ - -isc_result_t -ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n, - ns_interface_t *ifp, isc_boolean_t tcp); -/* - * Create up to 'n' clients listening on interface 'ifp'. - * If 'tcp' is ISC_TRUE, the clients will listen for TCP connections, - * otherwise for UDP requests. - */ - -isc_sockaddr_t * -ns_client_getsockaddr(ns_client_t *client); -/* - * Get the socket address of the client whose request is - * currently being processed. - */ - -isc_result_t -ns_client_checkaclsilent(ns_client_t *client,dns_acl_t *acl, - isc_boolean_t default_allow); - -/* - * Convenience function for client request ACL checking. - * - * Check the current client request against 'acl'. If 'acl' - * is NULL, allow the request iff 'default_allow' is ISC_TRUE. - * - * Notes: - * This is appropriate for checking allow-update, - * allow-query, allow-transfer, etc. It is not appropriate - * for checking the blackhole list because we treat positive - * matches as "allow" and negative matches as "deny"; in - * the case of the blackhole list this would be backwards. - * - * Requires: - * 'client' points to a valid client. - * 'acl' points to a valid ACL, or is NULL. - * - * Returns: - * ISC_R_SUCCESS if the request should be allowed - * ISC_R_REFUSED if the request should be denied - * No other return values are possible. - */ - -isc_result_t -ns_client_checkacl(ns_client_t *client, - const char *opname, dns_acl_t *acl, - isc_boolean_t default_allow, - int log_level); -/* - * Like ns_client_checkacl, but also logs the outcome of the - * check at log level 'log_level' if denied, and at debug 3 - * if approved. Log messages will refer to the request as - * an 'opname' request. - * - * Requires: - * Those of ns_client_checkaclsilent(), and: - * - * 'opname' points to a null-terminated string. - */ - -void -ns_client_log(ns_client_t *client, isc_logcategory_t *category, - isc_logmodule_t *module, int level, - const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6); - -void -ns_client_logv(ns_client_t *client, isc_logcategory_t *category, - isc_logmodule_t *module, int level, const char *fmt, va_list ap) ISC_FORMAT_PRINTF(5, 0); - -void -ns_client_aclmsg(const char *msg, dns_name_t *name, dns_rdatatype_t type, - dns_rdataclass_t rdclass, char *buf, size_t len); - -#define NS_CLIENT_ACLMSGSIZE(x) \ - (DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + \ - DNS_RDATACLASS_FORMATSIZE + sizeof(x) + sizeof("'/'")) - -void -ns_client_recursing(ns_client_t *client); -/*% - * Add client to end of recursing list. If 'killoldest' is true - * kill the oldest recursive client (list head). - */ - -void -ns_client_killoldestquery(ns_client_t *client); -/*% - * Kill the oldest recursive query (recursing list head). - */ - -void -ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager); -/* - * Dump the outstanding recursive queries to 'f'. - */ - -#endif /* NAMED_CLIENT_H */ diff --git a/contrib/bind9/bin/named/include/named/config.h b/contrib/bind9/bin/named/include/named/config.h deleted file mode 100644 index b3b4f121606b..000000000000 --- a/contrib/bind9/bin/named/include/named/config.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001, 2002 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: config.h,v 1.4.12.4 2004/04/20 14:12:10 marka Exp $ */ - -#ifndef NAMED_CONFIG_H -#define NAMED_CONFIG_H 1 - -#include <isccfg/cfg.h> - -#include <dns/types.h> -#include <dns/zone.h> - -isc_result_t -ns_config_parsedefaults(cfg_parser_t *parser, cfg_obj_t **conf); - -isc_result_t -ns_config_get(cfg_obj_t **maps, const char* name, cfg_obj_t **obj); - -isc_result_t -ns_checknames_get(cfg_obj_t **maps, const char* name, cfg_obj_t **obj); - -int -ns_config_listcount(cfg_obj_t *list); - -isc_result_t -ns_config_getclass(cfg_obj_t *classobj, dns_rdataclass_t defclass, - dns_rdataclass_t *classp); - -isc_result_t -ns_config_gettype(cfg_obj_t *typeobj, dns_rdatatype_t deftype, - dns_rdatatype_t *typep); - -dns_zonetype_t -ns_config_getzonetype(cfg_obj_t *zonetypeobj); - -isc_result_t -ns_config_getiplist(cfg_obj_t *config, cfg_obj_t *list, - in_port_t defport, isc_mem_t *mctx, - isc_sockaddr_t **addrsp, isc_uint32_t *countp); - -void -ns_config_putiplist(isc_mem_t *mctx, isc_sockaddr_t **addrsp, - isc_uint32_t count); - -isc_result_t -ns_config_getipandkeylist(cfg_obj_t *config, cfg_obj_t *list, isc_mem_t *mctx, - isc_sockaddr_t **addrsp, dns_name_t ***keys, - isc_uint32_t *countp); - -void -ns_config_putipandkeylist(isc_mem_t *mctx, isc_sockaddr_t **addrsp, - dns_name_t ***keys, isc_uint32_t count); - -isc_result_t -ns_config_getport(cfg_obj_t *config, in_port_t *portp); - -isc_result_t -ns_config_getkeyalgorithm(const char *str, dns_name_t **name); - -#endif /* NAMED_CONFIG_H */ diff --git a/contrib/bind9/bin/named/include/named/control.h b/contrib/bind9/bin/named/include/named/control.h deleted file mode 100644 index bbb7d36cbbe7..000000000000 --- a/contrib/bind9/bin/named/include/named/control.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001-2003 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: control.h,v 1.6.2.2.2.7 2004/09/03 03:43:32 marka Exp $ */ - -#ifndef NAMED_CONTROL_H -#define NAMED_CONTROL_H 1 - -/* - * The name server command channel. - */ - -#include <isccc/types.h> - -#include <named/aclconf.h> -#include <named/types.h> - -#define NS_CONTROL_PORT 953 - -#define NS_COMMAND_STOP "stop" -#define NS_COMMAND_HALT "halt" -#define NS_COMMAND_RELOAD "reload" -#define NS_COMMAND_RECONFIG "reconfig" -#define NS_COMMAND_REFRESH "refresh" -#define NS_COMMAND_RETRANSFER "retransfer" -#define NS_COMMAND_DUMPSTATS "stats" -#define NS_COMMAND_QUERYLOG "querylog" -#define NS_COMMAND_DUMPDB "dumpdb" -#define NS_COMMAND_TRACE "trace" -#define NS_COMMAND_NOTRACE "notrace" -#define NS_COMMAND_FLUSH "flush" -#define NS_COMMAND_FLUSHNAME "flushname" -#define NS_COMMAND_STATUS "status" -#define NS_COMMAND_FREEZE "freeze" -#define NS_COMMAND_UNFREEZE "unfreeze" -#define NS_COMMAND_THAW "thaw" -#define NS_COMMAND_RECURSING "recursing" -#define NS_COMMAND_NULL "null" - -isc_result_t -ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp); -/* - * Create an initial, empty set of command channels for 'server'. - */ - -void -ns_controls_destroy(ns_controls_t **ctrlsp); -/* - * Destroy a set of command channels. - * - * Requires: - * Shutdown of the channels has completed. - */ - -isc_result_t -ns_controls_configure(ns_controls_t *controls, cfg_obj_t *config, - ns_aclconfctx_t *aclconfctx); -/* - * Configure zero or more command channels into 'controls' - * as defined in the configuration parse tree 'config'. - * The channels will evaluate ACLs in the context of - * 'aclconfctx'. - */ - -void -ns_controls_shutdown(ns_controls_t *controls); -/* - * Initiate shutdown of all the command channels in 'controls'. - */ - -isc_result_t -ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text); - -#endif /* NAMED_CONTROL_H */ diff --git a/contrib/bind9/bin/named/include/named/globals.h b/contrib/bind9/bin/named/include/named/globals.h deleted file mode 100644 index 2cc854839562..000000000000 --- a/contrib/bind9/bin/named/include/named/globals.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: globals.h,v 1.59.68.5 2004/03/08 04:04:20 marka Exp $ */ - -#ifndef NAMED_GLOBALS_H -#define NAMED_GLOBALS_H 1 - -#include <isc/rwlock.h> -#include <isc/log.h> -#include <isc/net.h> - -#include <isccfg/cfg.h> - -#include <dns/zone.h> - -#include <named/types.h> - -#undef EXTERN -#undef INIT -#ifdef NS_MAIN -#define EXTERN -#define INIT(v) = (v) -#else -#define EXTERN extern -#define INIT(v) -#endif - -EXTERN isc_mem_t * ns_g_mctx INIT(NULL); -EXTERN unsigned int ns_g_cpus INIT(0); -EXTERN isc_taskmgr_t * ns_g_taskmgr INIT(NULL); -EXTERN dns_dispatchmgr_t * ns_g_dispatchmgr INIT(NULL); -EXTERN isc_entropy_t * ns_g_entropy INIT(NULL); -EXTERN isc_entropy_t * ns_g_fallbackentropy INIT(NULL); - -/* - * XXXRTH We're going to want multiple timer managers eventually. One - * for really short timers, another for client timers, and one - * for zone timers. - */ -EXTERN isc_timermgr_t * ns_g_timermgr INIT(NULL); -EXTERN isc_socketmgr_t * ns_g_socketmgr INIT(NULL); -EXTERN cfg_parser_t * ns_g_parser INIT(NULL); -EXTERN const char * ns_g_version INIT(VERSION); -EXTERN in_port_t ns_g_port INIT(0); -EXTERN in_port_t lwresd_g_listenport INIT(0); - -EXTERN ns_server_t * ns_g_server INIT(NULL); - -EXTERN isc_boolean_t ns_g_lwresdonly INIT(ISC_FALSE); - -/* - * Logging. - */ -EXTERN isc_log_t * ns_g_lctx INIT(NULL); -EXTERN isc_logcategory_t * ns_g_categories INIT(NULL); -EXTERN isc_logmodule_t * ns_g_modules INIT(NULL); -EXTERN unsigned int ns_g_debuglevel INIT(0); - -/* - * Current configuration information. - */ -EXTERN cfg_obj_t * ns_g_config INIT(NULL); -EXTERN cfg_obj_t * ns_g_defaults INIT(NULL); -EXTERN const char * ns_g_conffile INIT(NS_SYSCONFDIR - "/named.conf"); -EXTERN const char * ns_g_keyfile INIT(NS_SYSCONFDIR - "/rndc.key"); -EXTERN const char * lwresd_g_conffile INIT(NS_SYSCONFDIR - "/lwresd.conf"); -EXTERN const char * lwresd_g_resolvconffile INIT("/etc" - "/resolv.conf"); -EXTERN isc_boolean_t ns_g_conffileset INIT(ISC_FALSE); -EXTERN isc_boolean_t lwresd_g_useresolvconf INIT(ISC_FALSE); -EXTERN isc_uint16_t ns_g_udpsize INIT(4096); - -/* - * Initial resource limits. - */ -EXTERN isc_resourcevalue_t ns_g_initstacksize INIT(0); -EXTERN isc_resourcevalue_t ns_g_initdatasize INIT(0); -EXTERN isc_resourcevalue_t ns_g_initcoresize INIT(0); -EXTERN isc_resourcevalue_t ns_g_initopenfiles INIT(0); - -/* - * Misc. - */ -EXTERN isc_boolean_t ns_g_coreok INIT(ISC_TRUE); -EXTERN const char * ns_g_chrootdir INIT(NULL); -EXTERN isc_boolean_t ns_g_foreground INIT(ISC_FALSE); -EXTERN isc_boolean_t ns_g_logstderr INIT(ISC_FALSE); - -EXTERN const char * ns_g_defaultpidfile INIT(NS_LOCALSTATEDIR - "/run/named.pid"); -EXTERN const char * lwresd_g_defaultpidfile INIT(NS_LOCALSTATEDIR - "/run/lwresd.pid"); -EXTERN const char * ns_g_username INIT(NULL); - -EXTERN int ns_g_listen INIT(3); - -#undef EXTERN -#undef INIT - -#endif /* NAMED_GLOBALS_H */ diff --git a/contrib/bind9/bin/named/include/named/interfacemgr.h b/contrib/bind9/bin/named/include/named/interfacemgr.h deleted file mode 100644 index 54bd91cbd4c5..000000000000 --- a/contrib/bind9/bin/named/include/named/interfacemgr.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: interfacemgr.h,v 1.23.24.7 2004/04/29 01:31:22 marka Exp $ */ - -#ifndef NAMED_INTERFACEMGR_H -#define NAMED_INTERFACEMGR_H 1 - -/***** - ***** Module Info - *****/ - -/* - * Interface manager - * - * The interface manager monitors the operating system's list - * of network interfaces, creating and destroying listeners - * as needed. - * - * Reliability: - * No impact expected. - * - * Resources: - * - * Security: - * The server will only be able to bind to the DNS port on - * newly discovered interfaces if it is running as root. - * - * Standards: - * The API for scanning varies greatly among operating systems. - * This module attempts to hide the differences. - */ - -/*** - *** Imports - ***/ - -#include <isc/magic.h> -#include <isc/mem.h> -#include <isc/socket.h> - -#include <dns/result.h> - -#include <named/listenlist.h> -#include <named/types.h> - -/*** - *** Types - ***/ - -#define IFACE_MAGIC ISC_MAGIC('I',':','-',')') -#define NS_INTERFACE_VALID(t) ISC_MAGIC_VALID(t, IFACE_MAGIC) - -#define NS_INTERFACEFLAG_ANYADDR 0x01U /* bound to "any" address */ - -struct ns_interface { - unsigned int magic; /* Magic number. */ - ns_interfacemgr_t * mgr; /* Interface manager. */ - isc_mutex_t lock; - int references; /* Locked */ - unsigned int generation; /* Generation number. */ - isc_sockaddr_t addr; /* Address and port. */ - unsigned int flags; /* Interface characteristics */ - char name[32]; /* Null terminated. */ - dns_dispatch_t * udpdispatch; /* UDP dispatcher. */ - isc_socket_t * tcpsocket; /* TCP socket. */ - int ntcptarget; /* Desired number of concurrent - TCP accepts */ - int ntcpcurrent; /* Current ditto, locked */ - ns_clientmgr_t * clientmgr; /* Client manager. */ - ISC_LINK(ns_interface_t) link; -}; - -/*** - *** Functions - ***/ - -isc_result_t -ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_socketmgr_t *socketmgr, - dns_dispatchmgr_t *dispatchmgr, - ns_interfacemgr_t **mgrp); -/* - * Create a new interface manager. - * - * Initially, the new manager will not listen on any interfaces. - * Call ns_interfacemgr_setlistenon() and/or ns_interfacemgr_setlistenon6() - * to set nonempty listen-on lists. - */ - -void -ns_interfacemgr_attach(ns_interfacemgr_t *source, ns_interfacemgr_t **target); - -void -ns_interfacemgr_detach(ns_interfacemgr_t **targetp); - -void -ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr); - -void -ns_interfacemgr_scan(ns_interfacemgr_t *mgr, isc_boolean_t verbose); -/* - * Scan the operatings system's list of network interfaces - * and create listeners when new interfaces are discovered. - * Shut down the sockets for interfaces that go away. - * - * This should be called once on server startup and then - * periodically according to the 'interface-interval' option - * in named.conf. - */ - -void -ns_interfacemgr_adjust(ns_interfacemgr_t *mgr, ns_listenlist_t *list, - isc_boolean_t verbose); -/* - * Similar to ns_interfacemgr_scan(), but this function also tries to see the - * need for an explicit listen-on when a list element in 'list' is going to - * override an already-listening a wildcard interface. - * - * This function does not update localhost and localnets ACLs. - * - * This should be called once on server startup, after configuring views and - * zones. - */ - -void -ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value); -/* - * Set the IPv4 "listen-on" list of 'mgr' to 'value'. - * The previous IPv4 listen-on list is freed. - */ - -void -ns_interfacemgr_setlistenon6(ns_interfacemgr_t *mgr, ns_listenlist_t *value); -/* - * Set the IPv6 "listen-on" list of 'mgr' to 'value'. - * The previous IPv6 listen-on list is freed. - */ - -dns_aclenv_t * -ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr); - -void -ns_interface_attach(ns_interface_t *source, ns_interface_t **target); - -void -ns_interface_detach(ns_interface_t **targetp); - -void -ns_interface_shutdown(ns_interface_t *ifp); -/* - * Stop listening for queries on interface 'ifp'. - * May safely be called multiple times. - */ - -void -ns_interfacemgr_dumprecursing(FILE *f, ns_interfacemgr_t *mgr); - -#endif /* NAMED_INTERFACEMGR_H */ diff --git a/contrib/bind9/bin/named/include/named/listenlist.h b/contrib/bind9/bin/named/include/named/listenlist.h deleted file mode 100644 index 31e889393895..000000000000 --- a/contrib/bind9/bin/named/include/named/listenlist.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: listenlist.h,v 1.10.208.1 2004/03/06 10:21:24 marka Exp $ */ - -#ifndef NAMED_LISTENLIST_H -#define NAMED_LISTENLIST_H 1 - -/***** - ***** Module Info - *****/ - -/* - * "Listen lists", as in the "listen-on" configuration statement. - */ - -/*** - *** Imports - ***/ -#include <isc/net.h> - -#include <dns/types.h> - -/*** - *** Types - ***/ - -typedef struct ns_listenelt ns_listenelt_t; -typedef struct ns_listenlist ns_listenlist_t; - -struct ns_listenelt { - isc_mem_t * mctx; - in_port_t port; - dns_acl_t * acl; - ISC_LINK(ns_listenelt_t) link; -}; - -struct ns_listenlist { - isc_mem_t * mctx; - int refcount; - ISC_LIST(ns_listenelt_t) elts; -}; - -/*** - *** Functions - ***/ - -isc_result_t -ns_listenelt_create(isc_mem_t *mctx, in_port_t port, - dns_acl_t *acl, ns_listenelt_t **target); -/* - * Create a listen-on list element. - */ - -void -ns_listenelt_destroy(ns_listenelt_t *elt); -/* - * Destroy a listen-on list element. - */ - -isc_result_t -ns_listenlist_create(isc_mem_t *mctx, ns_listenlist_t **target); -/* - * Create a new, empty listen-on list. - */ - -void -ns_listenlist_attach(ns_listenlist_t *source, ns_listenlist_t **target); -/* - * Attach '*target' to '*source'. - */ - -void -ns_listenlist_detach(ns_listenlist_t **listp); -/* - * Detach 'listp'. - */ - -isc_result_t -ns_listenlist_default(isc_mem_t *mctx, in_port_t port, - isc_boolean_t enabled, ns_listenlist_t **target); -/* - * Create a listen-on list with default contents, matching - * all addresses with port 'port' (if 'enabled' is ISC_TRUE), - * or no addresses (if 'enabled' is ISC_FALSE). - */ - -#endif /* NAMED_LISTENLIST_H */ - - diff --git a/contrib/bind9/bin/named/include/named/log.h b/contrib/bind9/bin/named/include/named/log.h deleted file mode 100644 index e8ad1ca15ff1..000000000000 --- a/contrib/bind9/bin/named/include/named/log.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: log.h,v 1.19.12.3 2004/03/08 04:04:21 marka Exp $ */ - -#ifndef NAMED_LOG_H -#define NAMED_LOG_H 1 - -#include <isc/log.h> -#include <isc/types.h> - -#include <dns/log.h> - -#include <named/globals.h> /* Required for ns_g_(categories|modules). */ - -/* Unused slot 0. */ -#define NS_LOGCATEGORY_CLIENT (&ns_g_categories[1]) -#define NS_LOGCATEGORY_NETWORK (&ns_g_categories[2]) -#define NS_LOGCATEGORY_UPDATE (&ns_g_categories[3]) -#define NS_LOGCATEGORY_QUERIES (&ns_g_categories[4]) -#define NS_LOGCATEGORY_UNMATCHED (&ns_g_categories[5]) -#define NS_LOGCATEGORY_UPDATE_SECURITY (&ns_g_categories[6]) - -/* - * Backwards compatibility. - */ -#define NS_LOGCATEGORY_GENERAL ISC_LOGCATEGORY_GENERAL - -#define NS_LOGMODULE_MAIN (&ns_g_modules[0]) -#define NS_LOGMODULE_CLIENT (&ns_g_modules[1]) -#define NS_LOGMODULE_SERVER (&ns_g_modules[2]) -#define NS_LOGMODULE_QUERY (&ns_g_modules[3]) -#define NS_LOGMODULE_INTERFACEMGR (&ns_g_modules[4]) -#define NS_LOGMODULE_UPDATE (&ns_g_modules[5]) -#define NS_LOGMODULE_XFER_IN (&ns_g_modules[6]) -#define NS_LOGMODULE_XFER_OUT (&ns_g_modules[7]) -#define NS_LOGMODULE_NOTIFY (&ns_g_modules[8]) -#define NS_LOGMODULE_CONTROL (&ns_g_modules[9]) -#define NS_LOGMODULE_LWRESD (&ns_g_modules[10]) - -isc_result_t -ns_log_init(isc_boolean_t safe); -/* - * Initialize the logging system and set up an initial default - * logging default configuration that will be used until the - * config file has been read. - * - * If 'safe' is true, use a default configuration that refrains - * from opening files. This is to avoid creating log files - * as root. - */ - -isc_result_t -ns_log_setdefaultchannels(isc_logconfig_t *lcfg); -/* - * Set up logging channels according to the named defaults, which - * may differ from the logging library defaults. Currently, - * this just means setting up default_debug. - */ - -isc_result_t -ns_log_setsafechannels(isc_logconfig_t *lcfg); -/* - * Like ns_log_setdefaultchannels(), but omits any logging to files. - */ - -isc_result_t -ns_log_setdefaultcategory(isc_logconfig_t *lcfg); -/* - * Set up "category default" to go to the right places. - */ - -isc_result_t -ns_log_setunmatchedcategory(isc_logconfig_t *lcfg); -/* - * Set up "category unmatched" to go to the right places. - */ - -void -ns_log_shutdown(void); - -#endif /* NAMED_LOG_H */ diff --git a/contrib/bind9/bin/named/include/named/logconf.h b/contrib/bind9/bin/named/include/named/logconf.h deleted file mode 100644 index a6f7450c9386..000000000000 --- a/contrib/bind9/bin/named/include/named/logconf.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: logconf.h,v 1.10.208.1 2004/03/06 10:21:24 marka Exp $ */ - -#ifndef NAMED_LOGCONF_H -#define NAMED_LOGCONF_H 1 - -#include <isc/log.h> - -isc_result_t -ns_log_configure(isc_logconfig_t *logconf, cfg_obj_t *logstmt); -/* - * Set up the logging configuration in '*logconf' according to - * the named.conf data in 'logstmt'. - */ - -#endif /* NAMED_LOGCONF_H */ diff --git a/contrib/bind9/bin/named/include/named/lwaddr.h b/contrib/bind9/bin/named/include/named/lwaddr.h deleted file mode 100644 index 0aa66b78019f..000000000000 --- a/contrib/bind9/bin/named/include/named/lwaddr.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: lwaddr.h,v 1.3.208.1 2004/03/06 10:21:24 marka Exp $ */ - -#include <lwres/lwres.h> -#include <lwres/net.h> - -isc_result_t -lwaddr_netaddr_fromlwresaddr(isc_netaddr_t *na, lwres_addr_t *la); - -isc_result_t -lwaddr_sockaddr_fromlwresaddr(isc_sockaddr_t *sa, lwres_addr_t *la, - in_port_t port); - -isc_result_t -lwaddr_lwresaddr_fromnetaddr(lwres_addr_t *la, isc_netaddr_t *na); - -isc_result_t -lwaddr_lwresaddr_fromsockaddr(lwres_addr_t *la, isc_sockaddr_t *sa); diff --git a/contrib/bind9/bin/named/include/named/lwdclient.h b/contrib/bind9/bin/named/include/named/lwdclient.h deleted file mode 100644 index 09d68ff086e3..000000000000 --- a/contrib/bind9/bin/named/include/named/lwdclient.h +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: lwdclient.h,v 1.13.208.1 2004/03/06 10:21:24 marka Exp $ */ - -#ifndef NAMED_LWDCLIENT_H -#define NAMED_LWDCLIENT_H 1 - -#include <isc/event.h> -#include <isc/eventclass.h> -#include <isc/netaddr.h> -#include <isc/sockaddr.h> -#include <isc/types.h> - -#include <dns/fixedname.h> -#include <dns/types.h> - -#include <lwres/lwres.h> - -#include <named/lwsearch.h> - -#define LWRD_EVENTCLASS ISC_EVENTCLASS(4242) - -#define LWRD_SHUTDOWN (LWRD_EVENTCLASS + 0x0001) - -struct ns_lwdclient { - isc_sockaddr_t address; /* where to reply */ - struct in6_pktinfo pktinfo; - isc_boolean_t pktinfo_valid; - ns_lwdclientmgr_t *clientmgr; /* our parent */ - ISC_LINK(ns_lwdclient_t) link; - unsigned int state; - void *arg; /* packet processing state */ - - /* - * Received data info. - */ - unsigned char buffer[LWRES_RECVLENGTH]; /* receive buffer */ - isc_uint32_t recvlength; /* length recv'd */ - lwres_lwpacket_t pkt; - - /* - * Send data state. If sendbuf != buffer (that is, the send buffer - * isn't our receive buffer) it will be freed to the lwres_context_t. - */ - unsigned char *sendbuf; - isc_uint32_t sendlength; - isc_buffer_t recv_buffer; - - /* - * gabn (get address by name) state info. - */ - dns_adbfind_t *find; - dns_adbfind_t *v4find; - dns_adbfind_t *v6find; - unsigned int find_wanted; /* Addresses we want */ - dns_fixedname_t query_name; - dns_fixedname_t target_name; - ns_lwsearchctx_t searchctx; - lwres_gabnresponse_t gabn; - - /* - * gnba (get name by address) state info. - */ - lwres_gnbaresponse_t gnba; - dns_byaddr_t *byaddr; - unsigned int options; - isc_netaddr_t na; - - /* - * grbn (get rrset by name) state info. - * - * Note: this also uses target_name and searchctx. - */ - lwres_grbnresponse_t grbn; - dns_lookup_t *lookup; - dns_rdatatype_t rdtype; - - /* - * Alias and address info. This is copied up to the gabn/gnba - * structures eventually. - * - * XXXMLG We can keep all of this in a client since we only service - * three packet types right now. If we started handling more, - * we'd need to use "arg" above and allocate/destroy things. - */ - char *aliases[LWRES_MAX_ALIASES]; - isc_uint16_t aliaslen[LWRES_MAX_ALIASES]; - lwres_addr_t addrs[LWRES_MAX_ADDRS]; -}; - -/* - * Client states. - * - * _IDLE The client is not doing anything at all. - * - * _RECV The client is waiting for data after issuing a socket recv(). - * - * _RECVDONE Data has been received, and is being processed. - * - * _FINDWAIT An adb (or other) request was made that cannot be satisfied - * immediately. An event will wake the client up. - * - * _SEND All data for a response has completed, and a reply was - * sent via a socket send() call. - * - * Badly formatted state table: - * - * IDLE -> RECV when client has a recv() queued. - * - * RECV -> RECVDONE when recvdone event received. - * - * RECVDONE -> SEND if the data for a reply is at hand. - * RECVDONE -> FINDWAIT if more searching is needed, and events will - * eventually wake us up again. - * - * FINDWAIT -> SEND when enough data was received to reply. - * - * SEND -> IDLE when a senddone event was received. - * - * At any time -> IDLE on error. Sometimes this will be -> SEND - * instead, if enough data is on hand to reply with a meaningful - * error. - * - * Packets which are badly formatted may or may not get error returns. - */ -#define NS_LWDCLIENT_STATEIDLE 1 -#define NS_LWDCLIENT_STATERECV 2 -#define NS_LWDCLIENT_STATERECVDONE 3 -#define NS_LWDCLIENT_STATEFINDWAIT 4 -#define NS_LWDCLIENT_STATESEND 5 -#define NS_LWDCLIENT_STATESENDDONE 6 - -#define NS_LWDCLIENT_ISIDLE(c) \ - ((c)->state == NS_LWDCLIENT_STATEIDLE) -#define NS_LWDCLIENT_ISRECV(c) \ - ((c)->state == NS_LWDCLIENT_STATERECV) -#define NS_LWDCLIENT_ISRECVDONE(c) \ - ((c)->state == NS_LWDCLIENT_STATERECVDONE) -#define NS_LWDCLIENT_ISFINDWAIT(c) \ - ((c)->state == NS_LWDCLIENT_STATEFINDWAIT) -#define NS_LWDCLIENT_ISSEND(c) \ - ((c)->state == NS_LWDCLIENT_STATESEND) - -/* - * Overall magic test that means we're not idle. - */ -#define NS_LWDCLIENT_ISRUNNING(c) (!NS_LWDCLIENT_ISIDLE(c)) - -#define NS_LWDCLIENT_SETIDLE(c) \ - ((c)->state = NS_LWDCLIENT_STATEIDLE) -#define NS_LWDCLIENT_SETRECV(c) \ - ((c)->state = NS_LWDCLIENT_STATERECV) -#define NS_LWDCLIENT_SETRECVDONE(c) \ - ((c)->state = NS_LWDCLIENT_STATERECVDONE) -#define NS_LWDCLIENT_SETFINDWAIT(c) \ - ((c)->state = NS_LWDCLIENT_STATEFINDWAIT) -#define NS_LWDCLIENT_SETSEND(c) \ - ((c)->state = NS_LWDCLIENT_STATESEND) -#define NS_LWDCLIENT_SETSENDDONE(c) \ - ((c)->state = NS_LWDCLIENT_STATESENDDONE) - -struct ns_lwdclientmgr { - ns_lwreslistener_t *listener; - isc_mem_t *mctx; - isc_socket_t *sock; /* socket to use */ - dns_view_t *view; - lwres_context_t *lwctx; /* lightweight proto context */ - isc_task_t *task; /* owning task */ - unsigned int flags; - ISC_LINK(ns_lwdclientmgr_t) link; - ISC_LIST(ns_lwdclient_t) idle; /* idle client slots */ - ISC_LIST(ns_lwdclient_t) running; /* running clients */ -}; - -#define NS_LWDCLIENTMGR_FLAGRECVPENDING 0x00000001 -#define NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN 0x00000002 - -isc_result_t -ns_lwdclientmgr_create(ns_lwreslistener_t *, unsigned int, isc_taskmgr_t *); - -void -ns_lwdclient_initialize(ns_lwdclient_t *, ns_lwdclientmgr_t *); - -isc_result_t -ns_lwdclient_startrecv(ns_lwdclientmgr_t *); - -void -ns_lwdclient_stateidle(ns_lwdclient_t *); - -void -ns_lwdclient_recv(isc_task_t *, isc_event_t *); - -void -ns_lwdclient_shutdown(isc_task_t *, isc_event_t *); - -void -ns_lwdclient_send(isc_task_t *, isc_event_t *); - -isc_result_t -ns_lwdclient_sendreply(ns_lwdclient_t *client, isc_region_t *r); - -/* - * Processing functions of various types. - */ -void ns_lwdclient_processgabn(ns_lwdclient_t *, lwres_buffer_t *); -void ns_lwdclient_processgnba(ns_lwdclient_t *, lwres_buffer_t *); -void ns_lwdclient_processgrbn(ns_lwdclient_t *, lwres_buffer_t *); -void ns_lwdclient_processnoop(ns_lwdclient_t *, lwres_buffer_t *); - -void ns_lwdclient_errorpktsend(ns_lwdclient_t *, isc_uint32_t); - -void ns_lwdclient_log(int level, const char *format, ...) - ISC_FORMAT_PRINTF(2, 3); - -#endif /* NAMED_LWDCLIENT_H */ diff --git a/contrib/bind9/bin/named/include/named/lwresd.h b/contrib/bind9/bin/named/include/named/lwresd.h deleted file mode 100644 index 7ba857c04ed1..000000000000 --- a/contrib/bind9/bin/named/include/named/lwresd.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: lwresd.h,v 1.12.208.1 2004/03/06 10:21:25 marka Exp $ */ - -#ifndef NAMED_LWRESD_H -#define NAMED_LWRESD_H 1 - -#include <isc/types.h> -#include <isc/sockaddr.h> - -#include <isccfg/cfg.h> - -#include <dns/types.h> - -struct ns_lwresd { - unsigned int magic; - - isc_mutex_t lock; - dns_view_t *view; - ns_lwsearchlist_t *search; - unsigned int ndots; - isc_mem_t *mctx; - isc_boolean_t shutting_down; - unsigned int refs; -}; - -struct ns_lwreslistener { - unsigned int magic; - - isc_mutex_t lock; - isc_mem_t *mctx; - isc_sockaddr_t address; - ns_lwresd_t *manager; - isc_socket_t *sock; - unsigned int refs; - ISC_LIST(ns_lwdclientmgr_t) cmgrs; - ISC_LINK(ns_lwreslistener_t) link; -}; - -/* - * Configure lwresd. - */ -isc_result_t -ns_lwresd_configure(isc_mem_t *mctx, cfg_obj_t *config); - -isc_result_t -ns_lwresd_parseeresolvconf(isc_mem_t *mctx, cfg_parser_t *pctx, - cfg_obj_t **configp); - -/* - * Trigger shutdown. - */ -void -ns_lwresd_shutdown(void); - -/* - * Manager functions - */ -isc_result_t -ns_lwdmanager_create(isc_mem_t *mctx, cfg_obj_t *lwres, ns_lwresd_t **lwresdp); - -void -ns_lwdmanager_attach(ns_lwresd_t *source, ns_lwresd_t **targetp); - -void -ns_lwdmanager_detach(ns_lwresd_t **lwresdp); - -/* - * Listener functions - */ -void -ns_lwreslistener_attach(ns_lwreslistener_t *source, - ns_lwreslistener_t **targetp); - -void -ns_lwreslistener_detach(ns_lwreslistener_t **listenerp); - -void -ns_lwreslistener_unlinkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm); - -void -ns_lwreslistener_linkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm); - - - - -/* - * INTERNAL FUNCTIONS. - */ -void * -ns__lwresd_memalloc(void *arg, size_t size); - -void -ns__lwresd_memfree(void *arg, void *mem, size_t size); - -#endif /* NAMED_LWRESD_H */ diff --git a/contrib/bind9/bin/named/include/named/lwsearch.h b/contrib/bind9/bin/named/include/named/lwsearch.h deleted file mode 100644 index a864a89d8292..000000000000 --- a/contrib/bind9/bin/named/include/named/lwsearch.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: lwsearch.h,v 1.4.208.1 2004/03/06 10:21:25 marka Exp $ */ - -#ifndef NAMED_LWSEARCH_H -#define NAMED_LWSEARCH_H 1 - -#include <isc/mutex.h> -#include <isc/result.h> -#include <isc/types.h> - -#include <dns/types.h> - -#include <named/types.h> - -/* - * Lightweight resolver search list types and routines. - * - * An ns_lwsearchlist_t holds a list of search path elements. - * - * An ns_lwsearchctx stores the state of search list during a lookup - * operation. - */ - -struct ns_lwsearchlist { - unsigned int magic; - - isc_mutex_t lock; - isc_mem_t *mctx; - unsigned int refs; - dns_namelist_t names; -}; - -struct ns_lwsearchctx { - dns_name_t *relname; - dns_name_t *searchname; - unsigned int ndots; - ns_lwsearchlist_t *list; - isc_boolean_t doneexact; - isc_boolean_t exactfirst; -}; - -isc_result_t -ns_lwsearchlist_create(isc_mem_t *mctx, ns_lwsearchlist_t **listp); -/* - * Create an empty search list object. - */ - -void -ns_lwsearchlist_attach(ns_lwsearchlist_t *source, ns_lwsearchlist_t **target); -/* - * Attach to a search list object. - */ - -void -ns_lwsearchlist_detach(ns_lwsearchlist_t **listp); -/* - * Detach from a search list object. - */ - -isc_result_t -ns_lwsearchlist_append(ns_lwsearchlist_t *list, dns_name_t *name); -/* - * Append an element to a search list. This creates a copy of the name. - */ - -void -ns_lwsearchctx_init(ns_lwsearchctx_t *sctx, ns_lwsearchlist_t *list, - dns_name_t *name, unsigned int ndots); -/* - * Creates a search list context structure. - */ - -void -ns_lwsearchctx_first(ns_lwsearchctx_t *sctx); -/* - * Moves the search list context iterator to the first element, which - * is usually the exact name. - */ - -isc_result_t -ns_lwsearchctx_next(ns_lwsearchctx_t *sctx); -/* - * Moves the search list context iterator to the next element. - */ - -isc_result_t -ns_lwsearchctx_current(ns_lwsearchctx_t *sctx, dns_name_t *absname); -/* - * Obtains the current name to be looked up. This involves either - * concatenating the name with a search path element, making an - * exact name absolute, or doing nothing. - */ - -#endif /* NAMED_LWSEARCH_H */ diff --git a/contrib/bind9/bin/named/include/named/main.h b/contrib/bind9/bin/named/include/named/main.h deleted file mode 100644 index e37b5198fd03..000000000000 --- a/contrib/bind9/bin/named/include/named/main.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: main.h,v 1.8.2.2.8.4 2004/03/08 04:04:21 marka Exp $ */ - -#ifndef NAMED_MAIN_H -#define NAMED_MAIN_H 1 - -void -ns_main_earlyfatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); - -void -ns_main_earlywarning(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); - -void -ns_main_setmemstats(const char *); - -#endif /* NAMED_MAIN_H */ diff --git a/contrib/bind9/bin/named/include/named/notify.h b/contrib/bind9/bin/named/include/named/notify.h deleted file mode 100644 index 3cb1d854e932..000000000000 --- a/contrib/bind9/bin/named/include/named/notify.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: notify.h,v 1.9.208.1 2004/03/06 10:21:25 marka Exp $ */ - -#ifndef NAMED_NOTIFY_H -#define NAMED_NOTIFY_H 1 - -#include <named/types.h> -#include <named/client.h> - -/*** - *** Module Info - ***/ - -/* - * RFC 1996 - * A Mechanism for Prompt Notification of Zone Changes (DNS NOTIFY) - */ - -/*** - *** Functions. - ***/ - -void -ns_notify_start(ns_client_t *client); - -/* - * Examines the incoming message to determine apporiate zone. - * Returns FORMERR if there is not exactly one question. - * Returns REFUSED if we do not serve the listed zone. - * Pass the message to the zone module for processing - * and returns the return status. - * - * Requires - * client to be valid. - */ - -#endif /* NAMED_NOTIFY_H */ - diff --git a/contrib/bind9/bin/named/include/named/ns_smf_globals.h b/contrib/bind9/bin/named/include/named/ns_smf_globals.h deleted file mode 100644 index 49aa31dc5c06..000000000000 --- a/contrib/bind9/bin/named/include/named/ns_smf_globals.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2005 Internet Systems Consortium, Inc. ("ISC") - * - * 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: ns_smf_globals.h,v 1.2.4.4 2005/05/13 01:22:33 marka Exp $ */ - -#ifndef NS_SMF_GLOBALS_H -#define NS_SMF_GLOBALS_H 1 - -#include <libscf.h> - -#undef EXTERN -#undef INIT -#ifdef NS_MAIN -#define EXTERN -#define INIT(v) = (v) -#else -#define EXTERN extern -#define INIT(v) -#endif - -EXTERN unsigned int ns_smf_got_instance INIT(0); -EXTERN unsigned int ns_smf_chroot INIT(0); -EXTERN unsigned int ns_smf_want_disable INIT(0); - -isc_result_t ns_smf_add_message(isc_buffer_t *text); -isc_result_t ns_smf_get_instance(char **name, int debug, isc_mem_t *mctx); - -#undef EXTERN -#undef INIT - -#endif /* NS_SMF_GLOBALS_H */ diff --git a/contrib/bind9/bin/named/include/named/query.h b/contrib/bind9/bin/named/include/named/query.h deleted file mode 100644 index 6f348d530e7c..000000000000 --- a/contrib/bind9/bin/named/include/named/query.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: query.h,v 1.28.2.3.8.6 2004/03/08 04:04:21 marka Exp $ */ - -#ifndef NAMED_QUERY_H -#define NAMED_QUERY_H 1 - -#include <isc/types.h> -#include <isc/buffer.h> -#include <isc/netaddr.h> - -#include <dns/types.h> - -#include <named/types.h> - -typedef struct ns_dbversion { - dns_db_t *db; - dns_dbversion_t *version; - isc_boolean_t queryok; - ISC_LINK(struct ns_dbversion) link; -} ns_dbversion_t; - -struct ns_query { - unsigned int attributes; - unsigned int restarts; - isc_boolean_t timerset; - dns_name_t * qname; - dns_name_t * origqname; - unsigned int dboptions; - unsigned int fetchoptions; - dns_db_t * gluedb; - dns_db_t * authdb; - dns_zone_t * authzone; - isc_boolean_t authdbset; - isc_boolean_t isreferral; - isc_mutex_t fetchlock; - dns_fetch_t * fetch; - isc_bufferlist_t namebufs; - ISC_LIST(ns_dbversion_t) activeversions; - ISC_LIST(ns_dbversion_t) freeversions; -}; - -#define NS_QUERYATTR_RECURSIONOK 0x0001 -#define NS_QUERYATTR_CACHEOK 0x0002 -#define NS_QUERYATTR_PARTIALANSWER 0x0004 -#define NS_QUERYATTR_NAMEBUFUSED 0x0008 -#define NS_QUERYATTR_RECURSING 0x0010 -#define NS_QUERYATTR_CACHEGLUEOK 0x0020 -#define NS_QUERYATTR_QUERYOKVALID 0x0040 -#define NS_QUERYATTR_QUERYOK 0x0080 -#define NS_QUERYATTR_WANTRECURSION 0x0100 -#define NS_QUERYATTR_SECURE 0x0200 -#define NS_QUERYATTR_NOAUTHORITY 0x0400 -#define NS_QUERYATTR_NOADDITIONAL 0x0800 - -isc_result_t -ns_query_init(ns_client_t *client); - -void -ns_query_free(ns_client_t *client); - -void -ns_query_start(ns_client_t *client); - -void -ns_query_cancel(ns_client_t *client); - -#endif /* NAMED_QUERY_H */ diff --git a/contrib/bind9/bin/named/include/named/server.h b/contrib/bind9/bin/named/include/named/server.h deleted file mode 100644 index 97eb2efce341..000000000000 --- a/contrib/bind9/bin/named/include/named/server.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: server.h,v 1.58.2.1.10.11 2004/03/08 04:04:21 marka Exp $ */ - -#ifndef NAMED_SERVER_H -#define NAMED_SERVER_H 1 - -#include <isc/log.h> -#include <isc/sockaddr.h> -#include <isc/magic.h> -#include <isc/types.h> -#include <isc/quota.h> - -#include <dns/types.h> -#include <dns/acl.h> - -#include <named/types.h> - -#define NS_EVENTCLASS ISC_EVENTCLASS(0x4E43) -#define NS_EVENT_RELOAD (NS_EVENTCLASS + 0) -#define NS_EVENT_CLIENTCONTROL (NS_EVENTCLASS + 1) - -/* - * Name server state. Better here than in lots of separate global variables. - */ -struct ns_server { - unsigned int magic; - isc_mem_t * mctx; - - isc_task_t * task; - - /* Configurable data. */ - isc_quota_t xfroutquota; - isc_quota_t tcpquota; - isc_quota_t recursionquota; - dns_acl_t *blackholeacl; - char * statsfile; /* Statistics file name */ - char * dumpfile; /* Dump file name */ - char * recfile; /* Recursive file name */ - isc_boolean_t version_set; /* User has set version */ - char * version; /* User-specified version */ - isc_boolean_t hostname_set; /* User has set hostname */ - char * hostname; /* User-specified hostname */ - /* Use hostname for server id */ - isc_boolean_t server_usehostname; - char * server_id; /* User-specified server id */ - - /* - * Current ACL environment. This defines the - * current values of the localhost and localnets - * ACLs. - */ - dns_aclenv_t aclenv; - - /* Server data structures. */ - dns_loadmgr_t * loadmgr; - dns_zonemgr_t * zonemgr; - dns_viewlist_t viewlist; - ns_interfacemgr_t * interfacemgr; - dns_db_t * in_roothints; - dns_tkeyctx_t * tkeyctx; - - isc_timer_t * interface_timer; - isc_timer_t * heartbeat_timer; - isc_uint32_t interface_interval; - isc_uint32_t heartbeat_interval; - - isc_mutex_t reload_event_lock; - isc_event_t * reload_event; - - isc_boolean_t flushonshutdown; - isc_boolean_t log_queries; /* For BIND 8 compatibility */ - - isc_uint64_t * querystats; /* Query statistics counters */ - - ns_controls_t * controls; /* Control channels */ - unsigned int dispatchgen; - ns_dispatchlist_t dispatches; - -}; - -#define NS_SERVER_MAGIC ISC_MAGIC('S','V','E','R') -#define NS_SERVER_VALID(s) ISC_MAGIC_VALID(s, NS_SERVER_MAGIC) - -void -ns_server_create(isc_mem_t *mctx, ns_server_t **serverp); -/* - * Create a server object with default settings. - * This function either succeeds or causes the program to exit - * with a fatal error. - */ - -void -ns_server_destroy(ns_server_t **serverp); -/* - * Destroy a server object, freeing its memory. - */ - -void -ns_server_reloadwanted(ns_server_t *server); -/* - * Inform a server that a reload is wanted. This function - * may be called asynchronously, from outside the server's task. - * If a reload is already scheduled or in progress, the call - * is ignored. - */ - -void -ns_server_flushonshutdown(ns_server_t *server, isc_boolean_t flush); -/* - * Inform the server that the zones should be flushed to disk on shutdown. - */ - -isc_result_t -ns_server_reloadcommand(ns_server_t *server, char *args, isc_buffer_t *text); -/* - * Act on a "reload" command from the command channel. - */ - -isc_result_t -ns_server_reconfigcommand(ns_server_t *server, char *args); -/* - * Act on a "reconfig" command from the command channel. - */ - -isc_result_t -ns_server_refreshcommand(ns_server_t *server, char *args, isc_buffer_t *text); -/* - * Act on a "refresh" command from the command channel. - */ - -isc_result_t -ns_server_retransfercommand(ns_server_t *server, char *args); -/* - * Act on a "retransfer" command from the command channel. - */ - -isc_result_t -ns_server_togglequerylog(ns_server_t *server); -/* - * Toggle logging of queries, as in BIND 8. - */ - -/* - * Dump the current statistics to the statistics file. - */ -isc_result_t -ns_server_dumpstats(ns_server_t *server); - -/* - * Dump the current cache to the dump file. - */ -isc_result_t -ns_server_dumpdb(ns_server_t *server, char *args); - -/* - * Change or increment the server debug level. - */ -isc_result_t -ns_server_setdebuglevel(ns_server_t *server, char *args); - -/* - * Flush the server's cache(s) - */ -isc_result_t -ns_server_flushcache(ns_server_t *server, char *args); - -/* - * Flush a particular name from the server's cache(s) - */ -isc_result_t -ns_server_flushname(ns_server_t *server, char *args); - -/* - * Report the server's status. - */ -isc_result_t -ns_server_status(ns_server_t *server, isc_buffer_t *text); - -/* - * Enable or disable updates for a zone. - */ -isc_result_t -ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args); - -/* - * Dump the current recursive queries. - */ -isc_result_t -ns_server_dumprecursing(ns_server_t *server); - -/* - * Maintain a list of dispatches that require reserved ports. - */ -void -ns_add_reserved_dispatch(ns_server_t *server, isc_sockaddr_t *addr); - -#endif /* NAMED_SERVER_H */ diff --git a/contrib/bind9/bin/named/include/named/sortlist.h b/contrib/bind9/bin/named/include/named/sortlist.h deleted file mode 100644 index 88a149387795..000000000000 --- a/contrib/bind9/bin/named/include/named/sortlist.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: sortlist.h,v 1.4.208.1 2004/03/06 10:21:26 marka Exp $ */ - -#ifndef NAMED_SORTLIST_H -#define NAMED_SORTLIST_H 1 - -#include <isc/types.h> - -#include <dns/types.h> - -/* - * Type for callback functions that rank addresses. - */ -typedef int -(*dns_addressorderfunc_t)(isc_netaddr_t *address, void *arg); - -/* - * Return value type for setup_sortlist. - */ -typedef enum { - NS_SORTLISTTYPE_NONE, - NS_SORTLISTTYPE_1ELEMENT, - NS_SORTLISTTYPE_2ELEMENT -} ns_sortlisttype_t; - -ns_sortlisttype_t -ns_sortlist_setup(dns_acl_t *acl, isc_netaddr_t *clientaddr, void **argp); -/* - * Find the sortlist statement in 'acl' that applies to 'clientaddr', if any. - * - * If a 1-element sortlist item applies, return NS_SORTLISTTYPE_1ELEMENT and - * make '*argp' point to the matching subelement. - * - * If a 2-element sortlist item applies, return NS_SORTLISTTYPE_2ELEMENT and - * make '*argp' point to ACL that forms the second element. - * - * If no sortlist item applies, return NS_SORTLISTTYPE_NONE and set '*argp' - * to NULL. - */ - -int -ns_sortlist_addrorder1(isc_netaddr_t *addr, void *arg); -/* - * Find the sort order of 'addr' in 'arg', the matching element - * of a 1-element top-level sortlist statement. - */ - -int -ns_sortlist_addrorder2(isc_netaddr_t *addr, void *arg); -/* - * Find the sort order of 'addr' in 'arg', a topology-like - * ACL forming the second element in a 2-element top-level - * sortlist statement. - */ - -void -ns_sortlist_byaddrsetup(dns_acl_t *sortlist_acl, isc_netaddr_t *client_addr, - dns_addressorderfunc_t *orderp, - void **argp); -/* - * Find the sortlist statement in 'acl' that applies to 'clientaddr', if any. - * If a sortlist statement applies, return in '*orderp' a pointer to a function - * for ranking network addresses based on that sortlist statement, and in - * '*argp' an argument to pass to said function. If no sortlist statement - * applies, set '*orderp' and '*argp' to NULL. - */ - -#endif /* NAMED_SORTLIST_H */ diff --git a/contrib/bind9/bin/named/include/named/tkeyconf.h b/contrib/bind9/bin/named/include/named/tkeyconf.h deleted file mode 100644 index e3710eae3e00..000000000000 --- a/contrib/bind9/bin/named/include/named/tkeyconf.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: tkeyconf.h,v 1.9.208.1 2004/03/06 10:21:26 marka Exp $ */ - -#ifndef NS_TKEYCONF_H -#define NS_TKEYCONF_H 1 - -#include <isc/types.h> -#include <isc/lang.h> - -#include <isccfg/cfg.h> - -ISC_LANG_BEGINDECLS - -isc_result_t -ns_tkeyctx_fromconfig(cfg_obj_t *options, isc_mem_t *mctx, isc_entropy_t *ectx, - dns_tkeyctx_t **tctxp); -/* - * Create a TKEY context and configure it, including the default DH key - * and default domain, according to 'options'. - * - * Requires: - * 'cfg' is a valid configuration options object. - * 'mctx' is not NULL - * 'ectx' is not NULL - * 'tctx' is not NULL - * '*tctx' is NULL - * - * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - */ - -ISC_LANG_ENDDECLS - -#endif /* NS_TKEYCONF_H */ diff --git a/contrib/bind9/bin/named/include/named/tsigconf.h b/contrib/bind9/bin/named/include/named/tsigconf.h deleted file mode 100644 index ef4161ded8a1..000000000000 --- a/contrib/bind9/bin/named/include/named/tsigconf.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: tsigconf.h,v 1.9.208.1 2004/03/06 10:21:26 marka Exp $ */ - -#ifndef NS_TSIGCONF_H -#define NS_TSIGCONF_H 1 - -#include <isc/types.h> -#include <isc/lang.h> - -ISC_LANG_BEGINDECLS - -isc_result_t -ns_tsigkeyring_fromconfig(cfg_obj_t *config, cfg_obj_t *vconfig, - isc_mem_t *mctx, dns_tsig_keyring_t **ringp); -/* - * Create a TSIG key ring and configure it according to the 'key' - * statements in the global and view configuration objects. - * - * Requires: - * 'config' is not NULL. - * 'mctx' is not NULL - * 'ring' is not NULL, and '*ring' is NULL - * - * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - */ - -ISC_LANG_ENDDECLS - -#endif /* NS_TSIGCONF_H */ diff --git a/contrib/bind9/bin/named/include/named/types.h b/contrib/bind9/bin/named/include/named/types.h deleted file mode 100644 index eb44c53b66f3..000000000000 --- a/contrib/bind9/bin/named/include/named/types.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: types.h,v 1.19.208.2 2004/03/06 10:21:26 marka Exp $ */ - -#ifndef NAMED_TYPES_H -#define NAMED_TYPES_H 1 - -#include <dns/types.h> - -typedef struct ns_client ns_client_t; -typedef struct ns_clientmgr ns_clientmgr_t; -typedef struct ns_query ns_query_t; -typedef struct ns_server ns_server_t; -typedef struct ns_interface ns_interface_t; -typedef struct ns_interfacemgr ns_interfacemgr_t; -typedef struct ns_lwresd ns_lwresd_t; -typedef struct ns_lwreslistener ns_lwreslistener_t; -typedef struct ns_lwdclient ns_lwdclient_t; -typedef struct ns_lwdclientmgr ns_lwdclientmgr_t; -typedef struct ns_lwsearchlist ns_lwsearchlist_t; -typedef struct ns_lwsearchctx ns_lwsearchctx_t; -typedef struct ns_controls ns_controls_t; -typedef struct ns_dispatch ns_dispatch_t; -typedef ISC_LIST(ns_dispatch_t) ns_dispatchlist_t; - -#endif /* NAMED_TYPES_H */ diff --git a/contrib/bind9/bin/named/include/named/update.h b/contrib/bind9/bin/named/include/named/update.h deleted file mode 100644 index 4c97235cc93c..000000000000 --- a/contrib/bind9/bin/named/include/named/update.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: update.h,v 1.8.208.1 2004/03/06 10:21:26 marka Exp $ */ - -#ifndef NAMED_UPDATE_H -#define NAMED_UPDATE_H 1 - -/***** - ***** Module Info - *****/ - -/* - * RFC2136 Dynamic Update - */ - -/*** - *** Imports - ***/ - -#include <dns/types.h> -#include <dns/result.h> - -/*** - *** Types. - ***/ - -/*** - *** Functions - ***/ - -void -ns_update_start(ns_client_t *client, isc_result_t sigresult); - -#endif /* NAMED_UPDATE_H */ diff --git a/contrib/bind9/bin/named/include/named/xfrout.h b/contrib/bind9/bin/named/include/named/xfrout.h deleted file mode 100644 index e96ff31dd2de..000000000000 --- a/contrib/bind9/bin/named/include/named/xfrout.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: xfrout.h,v 1.7.208.1 2004/03/06 10:21:27 marka Exp $ */ - -#ifndef NAMED_XFROUT_H -#define NAMED_XFROUT_H 1 - -/***** - ***** Module Info - *****/ - -/* - * Outgoing zone transfers (AXFR + IXFR). - */ - -/*** - *** Functions - ***/ - -void -ns_xfr_start(ns_client_t *client, dns_rdatatype_t xfrtype); - -#endif /* NAMED_XFROUT_H */ diff --git a/contrib/bind9/bin/named/include/named/zoneconf.h b/contrib/bind9/bin/named/include/named/zoneconf.h deleted file mode 100644 index 3b8f200dc79f..000000000000 --- a/contrib/bind9/bin/named/include/named/zoneconf.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: zoneconf.h,v 1.16.2.2.8.1 2004/03/06 10:21:27 marka Exp $ */ - -#ifndef NS_ZONECONF_H -#define NS_ZONECONF_H 1 - -#include <isc/lang.h> -#include <isc/types.h> - -#include <isccfg/cfg.h> - -#include <named/aclconf.h> - -ISC_LANG_BEGINDECLS - -isc_result_t -ns_zone_configure(cfg_obj_t *config, cfg_obj_t *vconfig, cfg_obj_t *zconfig, - ns_aclconfctx_t *ac, dns_zone_t *zone); -/* - * Configure or reconfigure a zone according to the named.conf - * data in 'cctx' and 'czone'. - * - * The zone origin is not configured, it is assumed to have been set - * at zone creation time. - * - * Require: - * 'lctx' to be initialized or NULL. - * 'cctx' to be initialized or NULL. - * 'ac' to point to an initialized ns_aclconfctx_t. - * 'czone' to be initialized. - * 'zone' to be initialized. - */ - -isc_boolean_t -ns_zone_reusable(dns_zone_t *zone, cfg_obj_t *zconfig); -/* - * If 'zone' can be safely reconfigured according to the configuration - * data in 'zconfig', return ISC_TRUE. If the configuration data is so - * different from the current zone state that the zone needs to be destroyed - * and recreated, return ISC_FALSE. - */ - -ISC_LANG_ENDDECLS - -#endif /* NS_ZONECONF_H */ diff --git a/contrib/bind9/bin/named/interfacemgr.c b/contrib/bind9/bin/named/interfacemgr.c deleted file mode 100644 index b212892c8e1a..000000000000 --- a/contrib/bind9/bin/named/interfacemgr.c +++ /dev/null @@ -1,911 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: interfacemgr.c,v 1.59.2.5.8.15 2004/08/10 04:56:23 jinmei Exp $ */ - -#include <config.h> - -#include <isc/interfaceiter.h> -#include <isc/string.h> -#include <isc/task.h> -#include <isc/util.h> - -#include <dns/acl.h> -#include <dns/dispatch.h> - -#include <named/client.h> -#include <named/log.h> -#include <named/interfacemgr.h> - -#define IFMGR_MAGIC ISC_MAGIC('I', 'F', 'M', 'G') -#define NS_INTERFACEMGR_VALID(t) ISC_MAGIC_VALID(t, IFMGR_MAGIC) - -#define IFMGR_COMMON_LOGARGS \ - ns_g_lctx, NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR - -struct ns_interfacemgr { - unsigned int magic; /* Magic number. */ - int references; - isc_mutex_t lock; - isc_mem_t * mctx; /* Memory context. */ - isc_taskmgr_t * taskmgr; /* Task manager. */ - isc_socketmgr_t * socketmgr; /* Socket manager. */ - dns_dispatchmgr_t * dispatchmgr; - unsigned int generation; /* Current generation no. */ - ns_listenlist_t * listenon4; - ns_listenlist_t * listenon6; - dns_aclenv_t aclenv; /* Localhost/localnets ACLs */ - ISC_LIST(ns_interface_t) interfaces; /* List of interfaces. */ -}; - -static void -purge_old_interfaces(ns_interfacemgr_t *mgr); - -isc_result_t -ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, - isc_socketmgr_t *socketmgr, - dns_dispatchmgr_t *dispatchmgr, - ns_interfacemgr_t **mgrp) -{ - isc_result_t result; - ns_interfacemgr_t *mgr; - - REQUIRE(mctx != NULL); - REQUIRE(mgrp != NULL); - REQUIRE(*mgrp == NULL); - - mgr = isc_mem_get(mctx, sizeof(*mgr)); - if (mgr == NULL) - return (ISC_R_NOMEMORY); - - result = isc_mutex_init(&mgr->lock); - if (result != ISC_R_SUCCESS) - goto cleanup_mem; - - mgr->mctx = mctx; - mgr->taskmgr = taskmgr; - mgr->socketmgr = socketmgr; - mgr->dispatchmgr = dispatchmgr; - mgr->generation = 1; - mgr->listenon4 = NULL; - mgr->listenon6 = NULL; - - ISC_LIST_INIT(mgr->interfaces); - - /* - * The listen-on lists are initially empty. - */ - result = ns_listenlist_create(mctx, &mgr->listenon4); - if (result != ISC_R_SUCCESS) - goto cleanup_mem; - ns_listenlist_attach(mgr->listenon4, &mgr->listenon6); - - result = dns_aclenv_init(mctx, &mgr->aclenv); - if (result != ISC_R_SUCCESS) - goto cleanup_listenon; - - mgr->references = 1; - mgr->magic = IFMGR_MAGIC; - *mgrp = mgr; - return (ISC_R_SUCCESS); - - cleanup_listenon: - ns_listenlist_detach(&mgr->listenon4); - ns_listenlist_detach(&mgr->listenon6); - cleanup_mem: - isc_mem_put(mctx, mgr, sizeof(*mgr)); - return (result); -} - -static void -ns_interfacemgr_destroy(ns_interfacemgr_t *mgr) { - REQUIRE(NS_INTERFACEMGR_VALID(mgr)); - dns_aclenv_destroy(&mgr->aclenv); - ns_listenlist_detach(&mgr->listenon4); - ns_listenlist_detach(&mgr->listenon6); - DESTROYLOCK(&mgr->lock); - mgr->magic = 0; - isc_mem_put(mgr->mctx, mgr, sizeof(*mgr)); -} - -dns_aclenv_t * -ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr) { - return (&mgr->aclenv); -} - -void -ns_interfacemgr_attach(ns_interfacemgr_t *source, ns_interfacemgr_t **target) { - REQUIRE(NS_INTERFACEMGR_VALID(source)); - LOCK(&source->lock); - INSIST(source->references > 0); - source->references++; - UNLOCK(&source->lock); - *target = source; -} - -void -ns_interfacemgr_detach(ns_interfacemgr_t **targetp) { - isc_result_t need_destroy = ISC_FALSE; - ns_interfacemgr_t *target = *targetp; - REQUIRE(target != NULL); - REQUIRE(NS_INTERFACEMGR_VALID(target)); - LOCK(&target->lock); - REQUIRE(target->references > 0); - target->references--; - if (target->references == 0) - need_destroy = ISC_TRUE; - UNLOCK(&target->lock); - if (need_destroy) - ns_interfacemgr_destroy(target); - *targetp = NULL; -} - -void -ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr) { - REQUIRE(NS_INTERFACEMGR_VALID(mgr)); - - /* - * Shut down and detach all interfaces. - * By incrementing the generation count, we make purge_old_interfaces() - * consider all interfaces "old". - */ - mgr->generation++; - purge_old_interfaces(mgr); -} - - -static isc_result_t -ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, - const char *name, ns_interface_t **ifpret) -{ - ns_interface_t *ifp; - isc_result_t result; - - REQUIRE(NS_INTERFACEMGR_VALID(mgr)); - ifp = isc_mem_get(mgr->mctx, sizeof(*ifp)); - if (ifp == NULL) - return (ISC_R_NOMEMORY); - ifp->mgr = NULL; - ifp->generation = mgr->generation; - ifp->addr = *addr; - strncpy(ifp->name, name, sizeof(ifp->name)); - ifp->name[sizeof(ifp->name)-1] = '\0'; - ifp->clientmgr = NULL; - - result = isc_mutex_init(&ifp->lock); - if (result != ISC_R_SUCCESS) - goto lock_create_failure; - - result = ns_clientmgr_create(mgr->mctx, mgr->taskmgr, - ns_g_timermgr, - &ifp->clientmgr); - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "ns_clientmgr_create() failed: %s", - isc_result_totext(result)); - goto clientmgr_create_failure; - } - - ifp->udpdispatch = NULL; - - ifp->tcpsocket = NULL; - /* - * Create a single TCP client object. It will replace itself - * with a new one as soon as it gets a connection, so the actual - * connections will be handled in parallel even though there is - * only one client initially. - */ - ifp->ntcptarget = 1; - ifp->ntcpcurrent = 0; - - ISC_LINK_INIT(ifp, link); - - ns_interfacemgr_attach(mgr, &ifp->mgr); - ISC_LIST_APPEND(mgr->interfaces, ifp, link); - - ifp->references = 1; - ifp->magic = IFACE_MAGIC; - *ifpret = ifp; - - return (ISC_R_SUCCESS); - - clientmgr_create_failure: - DESTROYLOCK(&ifp->lock); - lock_create_failure: - ifp->magic = 0; - isc_mem_put(mgr->mctx, ifp, sizeof(*ifp)); - - return (ISC_R_UNEXPECTED); -} - -static isc_result_t -ns_interface_listenudp(ns_interface_t *ifp) { - isc_result_t result; - unsigned int attrs; - unsigned int attrmask; - - attrs = 0; - attrs |= DNS_DISPATCHATTR_UDP; - if (isc_sockaddr_pf(&ifp->addr) == AF_INET) - attrs |= DNS_DISPATCHATTR_IPV4; - else - attrs |= DNS_DISPATCHATTR_IPV6; - attrs |= DNS_DISPATCHATTR_NOLISTEN; - attrmask = 0; - attrmask |= DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP; - attrmask |= DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6; - result = dns_dispatch_getudp(ifp->mgr->dispatchmgr, ns_g_socketmgr, - ns_g_taskmgr, &ifp->addr, - 4096, 1000, 32768, 8219, 8237, - attrs, attrmask, &ifp->udpdispatch); - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "could not listen on UDP socket: %s", - isc_result_totext(result)); - goto udp_dispatch_failure; - } - - result = ns_clientmgr_createclients(ifp->clientmgr, ns_g_cpus, - ifp, ISC_FALSE); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "UDP ns_clientmgr_createclients(): %s", - isc_result_totext(result)); - goto addtodispatch_failure; - } - return (ISC_R_SUCCESS); - - addtodispatch_failure: - dns_dispatch_changeattributes(ifp->udpdispatch, 0, - DNS_DISPATCHATTR_NOLISTEN); - dns_dispatch_detach(&ifp->udpdispatch); - udp_dispatch_failure: - return (result); -} - -static isc_result_t -ns_interface_accepttcp(ns_interface_t *ifp) { - isc_result_t result; - - /* - * Open a TCP socket. - */ - result = isc_socket_create(ifp->mgr->socketmgr, - isc_sockaddr_pf(&ifp->addr), - isc_sockettype_tcp, - &ifp->tcpsocket); - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "creating TCP socket: %s", - isc_result_totext(result)); - goto tcp_socket_failure; - } -#ifndef ISC_ALLOW_MAPPED - isc_socket_ipv6only(ifp->tcpsocket, ISC_TRUE); -#endif - result = isc_socket_bind(ifp->tcpsocket, &ifp->addr); - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "binding TCP socket: %s", - isc_result_totext(result)); - goto tcp_bind_failure; - } - result = isc_socket_listen(ifp->tcpsocket, ns_g_listen); - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR, - "listening on TCP socket: %s", - isc_result_totext(result)); - goto tcp_listen_failure; - } - - /* - * If/when there a multiple filters listen to the - * result. - */ - (void)isc_socket_filter(ifp->tcpsocket, "dataready"); - - result = ns_clientmgr_createclients(ifp->clientmgr, - ifp->ntcptarget, ifp, - ISC_TRUE); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "TCP ns_clientmgr_createclients(): %s", - isc_result_totext(result)); - goto accepttcp_failure; - } - return (ISC_R_SUCCESS); - - accepttcp_failure: - tcp_listen_failure: - tcp_bind_failure: - isc_socket_detach(&ifp->tcpsocket); - tcp_socket_failure: - return (ISC_R_SUCCESS); -} - -static isc_result_t -ns_interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, - const char *name, ns_interface_t **ifpret, - isc_boolean_t accept_tcp) -{ - isc_result_t result; - ns_interface_t *ifp = NULL; - REQUIRE(ifpret != NULL && *ifpret == NULL); - - result = ns_interface_create(mgr, addr, name, &ifp); - if (result != ISC_R_SUCCESS) - return (result); - - result = ns_interface_listenudp(ifp); - if (result != ISC_R_SUCCESS) - goto cleanup_interface; - - if (accept_tcp == ISC_TRUE) { - result = ns_interface_accepttcp(ifp); - if (result != ISC_R_SUCCESS) { - /* - * XXXRTH We don't currently have a way to easily stop - * dispatch service, so we currently return - * ISC_R_SUCCESS (the UDP stuff will work even if TCP - * creation failed). This will be fixed later. - */ - result = ISC_R_SUCCESS; - } - } - *ifpret = ifp; - return (ISC_R_SUCCESS); - - cleanup_interface: - ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link); - ns_interface_detach(&ifp); - return (result); -} - -void -ns_interface_shutdown(ns_interface_t *ifp) { - if (ifp->clientmgr != NULL) - ns_clientmgr_destroy(&ifp->clientmgr); -} - -static void -ns_interface_destroy(ns_interface_t *ifp) { - isc_mem_t *mctx = ifp->mgr->mctx; - REQUIRE(NS_INTERFACE_VALID(ifp)); - - ns_interface_shutdown(ifp); - - if (ifp->udpdispatch != NULL) { - dns_dispatch_changeattributes(ifp->udpdispatch, 0, - DNS_DISPATCHATTR_NOLISTEN); - dns_dispatch_detach(&ifp->udpdispatch); - } - if (ifp->tcpsocket != NULL) - isc_socket_detach(&ifp->tcpsocket); - - DESTROYLOCK(&ifp->lock); - - ns_interfacemgr_detach(&ifp->mgr); - - ifp->magic = 0; - isc_mem_put(mctx, ifp, sizeof(*ifp)); -} - -void -ns_interface_attach(ns_interface_t *source, ns_interface_t **target) { - REQUIRE(NS_INTERFACE_VALID(source)); - LOCK(&source->lock); - INSIST(source->references > 0); - source->references++; - UNLOCK(&source->lock); - *target = source; -} - -void -ns_interface_detach(ns_interface_t **targetp) { - isc_result_t need_destroy = ISC_FALSE; - ns_interface_t *target = *targetp; - REQUIRE(target != NULL); - REQUIRE(NS_INTERFACE_VALID(target)); - LOCK(&target->lock); - REQUIRE(target->references > 0); - target->references--; - if (target->references == 0) - need_destroy = ISC_TRUE; - UNLOCK(&target->lock); - if (need_destroy) - ns_interface_destroy(target); - *targetp = NULL; -} - -/* - * Search the interface list for an interface whose address and port - * both match those of 'addr'. Return a pointer to it, or NULL if not found. - */ -static ns_interface_t * -find_matching_interface(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr) { - ns_interface_t *ifp; - for (ifp = ISC_LIST_HEAD(mgr->interfaces); ifp != NULL; - ifp = ISC_LIST_NEXT(ifp, link)) { - if (isc_sockaddr_equal(&ifp->addr, addr)) - break; - } - return (ifp); -} - -/* - * Remove any interfaces whose generation number is not the current one. - */ -static void -purge_old_interfaces(ns_interfacemgr_t *mgr) { - ns_interface_t *ifp, *next; - for (ifp = ISC_LIST_HEAD(mgr->interfaces); ifp != NULL; ifp = next) { - INSIST(NS_INTERFACE_VALID(ifp)); - next = ISC_LIST_NEXT(ifp, link); - if (ifp->generation != mgr->generation) { - char sabuf[256]; - ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link); - isc_sockaddr_format(&ifp->addr, sabuf, sizeof(sabuf)); - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_INFO, - "no longer listening on %s", sabuf); - ns_interface_shutdown(ifp); - ns_interface_detach(&ifp); - } - } -} - -static isc_result_t -clearacl(isc_mem_t *mctx, dns_acl_t **aclp) { - dns_acl_t *newacl = NULL; - isc_result_t result; - result = dns_acl_create(mctx, 10, &newacl); - if (result != ISC_R_SUCCESS) - return (result); - dns_acl_detach(aclp); - dns_acl_attach(newacl, aclp); - dns_acl_detach(&newacl); - return (ISC_R_SUCCESS); -} - -static isc_boolean_t -listenon_is_ip6_any(ns_listenelt_t *elt) { - if (elt->acl->length != 1) - return (ISC_FALSE); - if (elt->acl->elements[0].negative == ISC_FALSE && - elt->acl->elements[0].type == dns_aclelementtype_any) - return (ISC_TRUE); /* listen-on-v6 { any; } */ - return (ISC_FALSE); /* All others */ -} - -static isc_result_t -setup_locals(ns_interfacemgr_t *mgr, isc_interface_t *interface) { - isc_result_t result; - dns_aclelement_t elt; - unsigned int family; - unsigned int prefixlen; - - family = interface->address.family; - - elt.type = dns_aclelementtype_ipprefix; - elt.negative = ISC_FALSE; - elt.u.ip_prefix.address = interface->address; - elt.u.ip_prefix.prefixlen = (family == AF_INET) ? 32 : 128; - result = dns_acl_appendelement(mgr->aclenv.localhost, &elt); - if (result != ISC_R_SUCCESS) - return (result); - - result = isc_netaddr_masktoprefixlen(&interface->netmask, - &prefixlen); - - /* Non contigious netmasks not allowed by IPv6 arch. */ - if (result != ISC_R_SUCCESS && family == AF_INET6) - return (result); - - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_WARNING, - "omitting IPv4 interface %s from " - "localnets ACL: %s", - interface->name, - isc_result_totext(result)); - } else { - elt.u.ip_prefix.prefixlen = prefixlen; - if (dns_acl_elementmatch(mgr->aclenv.localnets, &elt, - NULL) == ISC_R_NOTFOUND) { - result = dns_acl_appendelement(mgr->aclenv.localnets, - &elt); - if (result != ISC_R_SUCCESS) - return (result); - } - } - - return (ISC_R_SUCCESS); -} - -static isc_result_t -do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, - isc_boolean_t verbose) -{ - isc_interfaceiter_t *iter = NULL; - isc_boolean_t scan_ipv4 = ISC_FALSE; - isc_boolean_t scan_ipv6 = ISC_FALSE; - isc_boolean_t adjusting = ISC_FALSE; - isc_boolean_t ipv6only = ISC_TRUE; - isc_boolean_t ipv6pktinfo = ISC_TRUE; - isc_result_t result; - isc_netaddr_t zero_address, zero_address6; - ns_listenelt_t *le; - isc_sockaddr_t listen_addr; - ns_interface_t *ifp; - isc_boolean_t log_explicit = ISC_FALSE; - - if (ext_listen != NULL) - adjusting = ISC_TRUE; - - if (isc_net_probeipv6() == ISC_R_SUCCESS) - scan_ipv6 = ISC_TRUE; -#ifdef WANT_IPV6 - else - isc_log_write(IFMGR_COMMON_LOGARGS, - verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1), - "no IPv6 interfaces found"); -#endif - - if (isc_net_probeipv4() == ISC_R_SUCCESS) - scan_ipv4 = ISC_TRUE; - else - isc_log_write(IFMGR_COMMON_LOGARGS, - verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1), - "no IPv4 interfaces found"); - - /* - * A special, but typical case; listen-on-v6 { any; }. - * When we can make the socket IPv6-only, open a single wildcard - * socket for IPv6 communication. Otherwise, make separate socket - * for each IPv6 address in order to avoid accepting IPv4 packets - * as the form of mapped addresses unintentionally unless explicitly - * allowed. - */ -#ifndef ISC_ALLOW_MAPPED - if (scan_ipv6 == ISC_TRUE && - isc_net_probe_ipv6only() != ISC_R_SUCCESS) { - ipv6only = ISC_FALSE; - log_explicit = ISC_TRUE; - } -#endif - if (scan_ipv6 == ISC_TRUE && - isc_net_probe_ipv6pktinfo() != ISC_R_SUCCESS) { - ipv6pktinfo = ISC_FALSE; - log_explicit = ISC_TRUE; - } - if (scan_ipv6 == ISC_TRUE && ipv6only && ipv6pktinfo) { - for (le = ISC_LIST_HEAD(mgr->listenon6->elts); - le != NULL; - le = ISC_LIST_NEXT(le, link)) { - struct in6_addr in6a; - - if (!listenon_is_ip6_any(le)) - continue; - - in6a = in6addr_any; - isc_sockaddr_fromin6(&listen_addr, &in6a, le->port); - - ifp = find_matching_interface(mgr, &listen_addr); - if (ifp != NULL) { - ifp->generation = mgr->generation; - } else { - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_INFO, - "listening on IPv6 " - "interfaces, port %u", - le->port); - result = ns_interface_setup(mgr, &listen_addr, - "<any>", &ifp, - ISC_TRUE); - if (result == ISC_R_SUCCESS) - ifp->flags |= NS_INTERFACEFLAG_ANYADDR; - else - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_ERROR, - "listening on all IPv6 " - "interfaces failed"); - /* Continue. */ - } - } - } - - isc_netaddr_any(&zero_address); - isc_netaddr_any6(&zero_address6); - - result = isc_interfaceiter_create(mgr->mctx, &iter); - if (result != ISC_R_SUCCESS) - return (result); - - if (adjusting == ISC_FALSE) { - result = clearacl(mgr->mctx, &mgr->aclenv.localhost); - if (result != ISC_R_SUCCESS) - goto cleanup_iter; - result = clearacl(mgr->mctx, &mgr->aclenv.localnets); - if (result != ISC_R_SUCCESS) - goto cleanup_iter; - } - - for (result = isc_interfaceiter_first(iter); - result == ISC_R_SUCCESS; - result = isc_interfaceiter_next(iter)) - { - isc_interface_t interface; - ns_listenlist_t *ll; - unsigned int family; - - result = isc_interfaceiter_current(iter, &interface); - if (result != ISC_R_SUCCESS) - break; - - family = interface.address.family; - if (family != AF_INET && family != AF_INET6) - continue; - if (scan_ipv4 == ISC_FALSE && family == AF_INET) - continue; - if (scan_ipv6 == ISC_FALSE && family == AF_INET6) - continue; - - /* - * Test for the address being nonzero rather than testing - * INTERFACE_F_UP, because on some systems the latter - * follows the media state and we could end up ignoring - * the interface for an entire rescan interval due to - * a temporary media glitch at rescan time. - */ - if (family == AF_INET && - isc_netaddr_equal(&interface.address, &zero_address)) { - continue; - } - if (family == AF_INET6 && - isc_netaddr_equal(&interface.address, &zero_address6)) { - continue; - } - - if (adjusting == ISC_FALSE) { - result = setup_locals(mgr, &interface); - if (result != ISC_R_SUCCESS) - goto ignore_interface; - } - - ll = (family == AF_INET) ? mgr->listenon4 : mgr->listenon6; - for (le = ISC_LIST_HEAD(ll->elts); - le != NULL; - le = ISC_LIST_NEXT(le, link)) - { - int match; - isc_boolean_t ipv6_wildcard = ISC_FALSE; - isc_netaddr_t listen_netaddr; - isc_sockaddr_t listen_sockaddr; - - /* - * Construct a socket address for this IP/port - * combination. - */ - if (family == AF_INET) { - isc_netaddr_fromin(&listen_netaddr, - &interface.address.type.in); - } else { - isc_netaddr_fromin6(&listen_netaddr, - &interface.address.type.in6); - isc_netaddr_setzone(&listen_netaddr, - interface.address.zone); - } - isc_sockaddr_fromnetaddr(&listen_sockaddr, - &listen_netaddr, - le->port); - - /* - * See if the address matches the listen-on statement; - * if not, ignore the interface. - */ - result = dns_acl_match(&listen_netaddr, NULL, - le->acl, &mgr->aclenv, - &match, NULL); - if (match <= 0) - continue; - - /* - * The case of "any" IPv6 address will require - * special considerations later, so remember it. - */ - if (family == AF_INET6 && ipv6only && ipv6pktinfo && - listenon_is_ip6_any(le)) - ipv6_wildcard = ISC_TRUE; - - /* - * When adjusting interfaces with extra a listening - * list, see if the address matches the extra list. - * If it does, and is also covered by a wildcard - * interface, we need to listen on the address - * explicitly. - */ - if (adjusting == ISC_TRUE) { - ns_listenelt_t *ele; - - match = 0; - for (ele = ISC_LIST_HEAD(ext_listen->elts); - ele != NULL; - ele = ISC_LIST_NEXT(ele, link)) { - dns_acl_match(&listen_netaddr, NULL, - ele->acl, NULL, - &match, NULL); - if (match > 0 && ele->port == le->port) - break; - else - match = 0; - } - if (ipv6_wildcard == ISC_TRUE && match == 0) - continue; - } - - ifp = find_matching_interface(mgr, &listen_sockaddr); - if (ifp != NULL) { - ifp->generation = mgr->generation; - } else { - char sabuf[ISC_SOCKADDR_FORMATSIZE]; - - if (adjusting == ISC_FALSE && - ipv6_wildcard == ISC_TRUE) - continue; - - if (log_explicit && family == AF_INET6 && - !adjusting && listenon_is_ip6_any(le)) { - isc_log_write(IFMGR_COMMON_LOGARGS, - verbose ? ISC_LOG_INFO : - ISC_LOG_DEBUG(1), - "IPv6 socket API is " - "incomplete; explicitly " - "binding to each IPv6 " - "address separately"); - log_explicit = ISC_FALSE; - } - isc_sockaddr_format(&listen_sockaddr, - sabuf, sizeof(sabuf)); - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_INFO, - "%s" - "listening on %s interface " - "%s, %s", - (adjusting == ISC_TRUE) ? - "additionally " : "", - (family == AF_INET) ? - "IPv4" : "IPv6", - interface.name, sabuf); - - result = ns_interface_setup(mgr, - &listen_sockaddr, - interface.name, - &ifp, - (adjusting == ISC_TRUE) ? - ISC_FALSE : - ISC_TRUE); - - if (result != ISC_R_SUCCESS) { - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_ERROR, - "creating %s interface " - "%s failed; interface " - "ignored", - (family == AF_INET) ? - "IPv4" : "IPv6", - interface.name); - } - /* Continue. */ - } - - } - continue; - - ignore_interface: - isc_log_write(IFMGR_COMMON_LOGARGS, - ISC_LOG_ERROR, - "ignoring %s interface %s: %s", - (family == AF_INET) ? "IPv4" : "IPv6", - interface.name, isc_result_totext(result)); - continue; - } - if (result != ISC_R_NOMORE) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "interface iteration failed: %s", - isc_result_totext(result)); - else - result = ISC_R_SUCCESS; - cleanup_iter: - isc_interfaceiter_destroy(&iter); - return (result); -} - -static void -ns_interfacemgr_scan0(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, - isc_boolean_t verbose) -{ - isc_boolean_t purge = ISC_TRUE; - - REQUIRE(NS_INTERFACEMGR_VALID(mgr)); - - mgr->generation++; /* Increment the generation count. */ - - if (do_scan(mgr, ext_listen, verbose) != ISC_R_SUCCESS) - purge = ISC_FALSE; - - /* - * Now go through the interface list and delete anything that - * does not have the current generation number. This is - * how we catch interfaces that go away or change their - * addresses. - */ - if (purge) - purge_old_interfaces(mgr); - - /* - * Warn if we are not listening on any interface, unless - * we're in lwresd-only mode, in which case that is to - * be expected. - */ - if (ext_listen == NULL && - ISC_LIST_EMPTY(mgr->interfaces) && ! ns_g_lwresdonly) { - isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_WARNING, - "not listening on any interfaces"); - } -} - -void -ns_interfacemgr_scan(ns_interfacemgr_t *mgr, isc_boolean_t verbose) { - ns_interfacemgr_scan0(mgr, NULL, verbose); -} - -void -ns_interfacemgr_adjust(ns_interfacemgr_t *mgr, ns_listenlist_t *list, - isc_boolean_t verbose) -{ - ns_interfacemgr_scan0(mgr, list, verbose); -} - -void -ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value) { - LOCK(&mgr->lock); - ns_listenlist_detach(&mgr->listenon4); - ns_listenlist_attach(value, &mgr->listenon4); - UNLOCK(&mgr->lock); -} - -void -ns_interfacemgr_setlistenon6(ns_interfacemgr_t *mgr, ns_listenlist_t *value) { - LOCK(&mgr->lock); - ns_listenlist_detach(&mgr->listenon6); - ns_listenlist_attach(value, &mgr->listenon6); - UNLOCK(&mgr->lock); -} - -void -ns_interfacemgr_dumprecursing(FILE *f, ns_interfacemgr_t *mgr) { - ns_interface_t *interface; - - LOCK(&mgr->lock); - interface = ISC_LIST_HEAD(mgr->interfaces); - while (interface != NULL) { - if (interface->clientmgr != NULL) - ns_client_dumprecursing(f, interface->clientmgr); - interface = ISC_LIST_NEXT(interface, link); - } - UNLOCK(&mgr->lock); -} diff --git a/contrib/bind9/bin/named/listenlist.c b/contrib/bind9/bin/named/listenlist.c deleted file mode 100644 index bba164f08126..000000000000 --- a/contrib/bind9/bin/named/listenlist.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: listenlist.c,v 1.9.208.1 2004/03/06 10:21:18 marka Exp $ */ - -#include <config.h> - -#include <isc/mem.h> -#include <isc/util.h> - -#include <dns/acl.h> - -#include <named/listenlist.h> - -static void -destroy(ns_listenlist_t *list); - -isc_result_t -ns_listenelt_create(isc_mem_t *mctx, in_port_t port, - dns_acl_t *acl, ns_listenelt_t **target) -{ - ns_listenelt_t *elt = NULL; - REQUIRE(target != NULL && *target == NULL); - elt = isc_mem_get(mctx, sizeof(*elt)); - if (elt == NULL) - return (ISC_R_NOMEMORY); - elt->mctx = mctx; - ISC_LINK_INIT(elt, link); - elt->port = port; - elt->acl = acl; - *target = elt; - return (ISC_R_SUCCESS); -} - -void -ns_listenelt_destroy(ns_listenelt_t *elt) { - if (elt->acl != NULL) - dns_acl_detach(&elt->acl); - isc_mem_put(elt->mctx, elt, sizeof(*elt)); -} - -isc_result_t -ns_listenlist_create(isc_mem_t *mctx, ns_listenlist_t **target) { - ns_listenlist_t *list = NULL; - REQUIRE(target != NULL && *target == NULL); - list = isc_mem_get(mctx, sizeof(*list)); - if (list == NULL) - return (ISC_R_NOMEMORY); - list->mctx = mctx; - list->refcount = 1; - ISC_LIST_INIT(list->elts); - *target = list; - return (ISC_R_SUCCESS); -} - -static void -destroy(ns_listenlist_t *list) { - ns_listenelt_t *elt, *next; - for (elt = ISC_LIST_HEAD(list->elts); - elt != NULL; - elt = next) - { - next = ISC_LIST_NEXT(elt, link); - ns_listenelt_destroy(elt); - } - isc_mem_put(list->mctx, list, sizeof(*list)); -} - -void -ns_listenlist_attach(ns_listenlist_t *source, ns_listenlist_t **target) { - INSIST(source->refcount > 0); - source->refcount++; - *target = source; -} - -void -ns_listenlist_detach(ns_listenlist_t **listp) { - ns_listenlist_t *list = *listp; - INSIST(list->refcount > 0); - list->refcount--; - if (list->refcount == 0) - destroy(list); - *listp = NULL; -} - -isc_result_t -ns_listenlist_default(isc_mem_t *mctx, in_port_t port, - isc_boolean_t enabled, ns_listenlist_t **target) -{ - isc_result_t result; - dns_acl_t *acl = NULL; - ns_listenelt_t *elt = NULL; - ns_listenlist_t *list = NULL; - - REQUIRE(target != NULL && *target == NULL); - if (enabled) - result = dns_acl_any(mctx, &acl); - else - result = dns_acl_none(mctx, &acl); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = ns_listenelt_create(mctx, port, acl, &elt); - if (result != ISC_R_SUCCESS) - goto cleanup_acl; - - result = ns_listenlist_create(mctx, &list); - if (result != ISC_R_SUCCESS) - goto cleanup_listenelt; - - ISC_LIST_APPEND(list->elts, elt, link); - - *target = list; - return (ISC_R_SUCCESS); - - cleanup_listenelt: - ns_listenelt_destroy(elt); - cleanup_acl: - dns_acl_detach(&acl); - cleanup: - return (result); -} diff --git a/contrib/bind9/bin/named/log.c b/contrib/bind9/bin/named/log.c deleted file mode 100644 index 9032af795d4f..000000000000 --- a/contrib/bind9/bin/named/log.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: log.c,v 1.33.2.1.10.6 2005/05/24 23:58:17 marka Exp $ */ - -#include <config.h> - -#include <isc/result.h> - -#include <isccfg/log.h> - -#include <named/log.h> - -#ifndef ISC_FACILITY -#define ISC_FACILITY LOG_DAEMON -#endif - -/* - * When adding a new category, be sure to add the appropriate - * #define to <named/log.h>. - */ -static isc_logcategory_t categories[] = { - { "", 0 }, - { "client", 0 }, - { "network", 0 }, - { "update", 0 }, - { "queries", 0 }, - { "unmatched", 0 }, - { "update-security", 0 }, - { NULL, 0 } -}; - -/* - * When adding a new module, be sure to add the appropriate - * #define to <dns/log.h>. - */ -static isc_logmodule_t modules[] = { - { "main", 0 }, - { "client", 0 }, - { "server", 0 }, - { "query", 0 }, - { "interfacemgr", 0 }, - { "update", 0 }, - { "xfer-in", 0 }, - { "xfer-out", 0 }, - { "notify", 0 }, - { "control", 0 }, - { "lwresd", 0 }, - { NULL, 0 } -}; - -isc_result_t -ns_log_init(isc_boolean_t safe) { - isc_result_t result; - isc_logconfig_t *lcfg = NULL; - - ns_g_categories = categories; - ns_g_modules = modules; - - /* - * Setup a logging context. - */ - result = isc_log_create(ns_g_mctx, &ns_g_lctx, &lcfg); - if (result != ISC_R_SUCCESS) - return (result); - - isc_log_registercategories(ns_g_lctx, ns_g_categories); - isc_log_registermodules(ns_g_lctx, ns_g_modules); - isc_log_setcontext(ns_g_lctx); - dns_log_init(ns_g_lctx); - dns_log_setcontext(ns_g_lctx); - cfg_log_init(ns_g_lctx); - - if (safe) - result = ns_log_setsafechannels(lcfg); - else - result = ns_log_setdefaultchannels(lcfg); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = ns_log_setdefaultcategory(lcfg); - if (result != ISC_R_SUCCESS) - goto cleanup; - - return (ISC_R_SUCCESS); - - cleanup: - isc_log_destroy(&ns_g_lctx); - isc_log_setcontext(NULL); - dns_log_setcontext(NULL); - - return (result); -} - -isc_result_t -ns_log_setdefaultchannels(isc_logconfig_t *lcfg) { - isc_result_t result; - isc_logdestination_t destination; - - /* - * By default, the logging library makes "default_debug" log to - * stderr. In BIND, we want to override this and log to named.run - * instead, unless the the -g option was given. - */ - if (! ns_g_logstderr) { - destination.file.stream = NULL; - destination.file.name = "named.run"; - destination.file.versions = ISC_LOG_ROLLNEVER; - destination.file.maximum_size = 0; - result = isc_log_createchannel(lcfg, "default_debug", - ISC_LOG_TOFILE, - ISC_LOG_DYNAMIC, - &destination, - ISC_LOG_PRINTTIME| - ISC_LOG_DEBUGONLY); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - -#if ISC_FACILITY != LOG_DAEMON - destination.facility = ISC_FACILITY; - result = isc_log_createchannel(lcfg, "default_syslog", - ISC_LOG_TOSYSLOG, ISC_LOG_INFO, - &destination, 0); - if (result != ISC_R_SUCCESS) - goto cleanup; -#endif - - /* - * Set the initial debug level. - */ - isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel); - - result = ISC_R_SUCCESS; - - cleanup: - return (result); -} - -isc_result_t -ns_log_setsafechannels(isc_logconfig_t *lcfg) { - isc_result_t result; -#if ISC_FACILITY != LOG_DAEMON - isc_logdestination_t destination; -#endif - - if (! ns_g_logstderr) { - result = isc_log_createchannel(lcfg, "default_debug", - ISC_LOG_TONULL, - ISC_LOG_DYNAMIC, - NULL, 0); - if (result != ISC_R_SUCCESS) - goto cleanup; - - /* - * Setting the debug level to zero should get the output - * discarded a bit faster. - */ - isc_log_setdebuglevel(ns_g_lctx, 0); - } else { - isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel); - } - -#if ISC_FACILITY != LOG_DAEMON - destination.facility = ISC_FACILITY; - result = isc_log_createchannel(lcfg, "default_syslog", - ISC_LOG_TOSYSLOG, ISC_LOG_INFO, - &destination, 0); - if (result != ISC_R_SUCCESS) - goto cleanup; -#endif - - result = ISC_R_SUCCESS; - - cleanup: - return (result); -} - -isc_result_t -ns_log_setdefaultcategory(isc_logconfig_t *lcfg) { - isc_result_t result; - - if (! ns_g_logstderr) { - result = isc_log_usechannel(lcfg, "default_syslog", - ISC_LOGCATEGORY_DEFAULT, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - result = isc_log_usechannel(lcfg, "default_debug", - ISC_LOGCATEGORY_DEFAULT, NULL); - if (result != ISC_R_SUCCESS) - goto cleanup; - - result = ISC_R_SUCCESS; - - cleanup: - return (result); -} - -isc_result_t -ns_log_setunmatchedcategory(isc_logconfig_t *lcfg) { - isc_result_t result; - - result = isc_log_usechannel(lcfg, "null", - NS_LOGCATEGORY_UNMATCHED, NULL); - return (result); -} - -void -ns_log_shutdown(void) { - isc_log_destroy(&ns_g_lctx); - isc_log_setcontext(NULL); - dns_log_setcontext(NULL); -} diff --git a/contrib/bind9/bin/named/logconf.c b/contrib/bind9/bin/named/logconf.c deleted file mode 100644 index 596d40166bb3..000000000000 --- a/contrib/bind9/bin/named/logconf.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: logconf.c,v 1.30.2.3.10.2 2004/03/06 10:21:18 marka Exp $ */ - -#include <config.h> - -#include <isc/offset.h> -#include <isc/result.h> -#include <isc/stdio.h> -#include <isc/string.h> -#include <isc/syslog.h> - -#include <isccfg/cfg.h> -#include <isccfg/log.h> - -#include <named/log.h> -#include <named/logconf.h> - -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto cleanup; \ - } while (0) - -/* - * Set up a logging category according to the named.conf data - * in 'ccat' and add it to 'lctx'. - */ -static isc_result_t -category_fromconf(cfg_obj_t *ccat, isc_logconfig_t *lctx) { - isc_result_t result; - const char *catname; - isc_logcategory_t *category; - isc_logmodule_t *module; - cfg_obj_t *destinations = NULL; - cfg_listelt_t *element = NULL; - - catname = cfg_obj_asstring(cfg_tuple_get(ccat, "name")); - category = isc_log_categorybyname(ns_g_lctx, catname); - if (category == NULL) { - cfg_obj_log(ccat, ns_g_lctx, ISC_LOG_ERROR, - "unknown logging category '%s' ignored", - catname); - /* - * Allow further processing by returning success. - */ - return (ISC_R_SUCCESS); - } - - module = NULL; - - destinations = cfg_tuple_get(ccat, "destinations"); - for (element = cfg_list_first(destinations); - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *channel = cfg_listelt_value(element); - char *channelname = cfg_obj_asstring(channel); - - result = isc_log_usechannel(lctx, channelname, category, - module); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, CFG_LOGCATEGORY_CONFIG, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "logging channel '%s': %s", channelname, - isc_result_totext(result)); - return (result); - } - } - return (ISC_R_SUCCESS); -} - -/* - * Set up a logging channel according to the named.conf data - * in 'cchan' and add it to 'lctx'. - */ -static isc_result_t -channel_fromconf(cfg_obj_t *channel, isc_logconfig_t *lctx) { - isc_result_t result; - isc_logdestination_t dest; - unsigned int type; - unsigned int flags = 0; - int level; - const char *channelname; - cfg_obj_t *fileobj = NULL; - cfg_obj_t *syslogobj = NULL; - cfg_obj_t *nullobj = NULL; - cfg_obj_t *stderrobj = NULL; - cfg_obj_t *severity = NULL; - int i; - - channelname = cfg_obj_asstring(cfg_map_getname(channel)); - - (void)cfg_map_get(channel, "file", &fileobj); - (void)cfg_map_get(channel, "syslog", &syslogobj); - (void)cfg_map_get(channel, "null", &nullobj); - (void)cfg_map_get(channel, "stderr", &stderrobj); - - i = 0; - if (fileobj != NULL) - i++; - if (syslogobj != NULL) - i++; - if (nullobj != NULL) - i++; - if (stderrobj != NULL) - i++; - - if (i != 1) { - cfg_obj_log(channel, ns_g_lctx, ISC_LOG_ERROR, - "channel '%s': exactly one of file, syslog, " - "null, and stderr must be present", channelname); - return (ISC_R_FAILURE); - } - - type = ISC_LOG_TONULL; - - if (fileobj != NULL) { - cfg_obj_t *pathobj = cfg_tuple_get(fileobj, "file"); - cfg_obj_t *sizeobj = cfg_tuple_get(fileobj, "size"); - cfg_obj_t *versionsobj = cfg_tuple_get(fileobj, "versions"); - isc_int32_t versions = ISC_LOG_ROLLNEVER; - isc_offset_t size = 0; - - type = ISC_LOG_TOFILE; - - if (versionsobj != NULL && cfg_obj_isuint32(versionsobj)) - versions = cfg_obj_asuint32(versionsobj); - if (versionsobj != NULL && cfg_obj_isstring(versionsobj) && - strcasecmp(cfg_obj_asstring(versionsobj), "unlimited") == 0) - versions = ISC_LOG_ROLLINFINITE; - if (sizeobj != NULL && - cfg_obj_isuint64(sizeobj) && - cfg_obj_asuint64(sizeobj) < ISC_OFFSET_MAXIMUM) - size = (isc_offset_t)cfg_obj_asuint64(sizeobj); - dest.file.stream = NULL; - dest.file.name = cfg_obj_asstring(pathobj); - dest.file.versions = versions; - dest.file.maximum_size = size; - } else if (syslogobj != NULL) { - int facility = LOG_DAEMON; - - type = ISC_LOG_TOSYSLOG; - - if (cfg_obj_isstring(syslogobj)) { - char *facilitystr = cfg_obj_asstring(syslogobj); - (void)isc_syslog_facilityfromstring(facilitystr, - &facility); - } - dest.facility = facility; - } else if (stderrobj != NULL) { - type = ISC_LOG_TOFILEDESC; - dest.file.stream = stderr; - dest.file.name = NULL; - dest.file.versions = ISC_LOG_ROLLNEVER; - dest.file.maximum_size = 0; - } - - /* - * Munge flags. - */ - { - cfg_obj_t *printcat = NULL; - cfg_obj_t *printsev = NULL; - cfg_obj_t *printtime = NULL; - - (void)cfg_map_get(channel, "print-category", &printcat); - (void)cfg_map_get(channel, "print-severity", &printsev); - (void)cfg_map_get(channel, "print-time", &printtime); - - if (printcat != NULL && cfg_obj_asboolean(printcat)) - flags |= ISC_LOG_PRINTCATEGORY; - if (printtime != NULL && cfg_obj_asboolean(printtime)) - flags |= ISC_LOG_PRINTTIME; - if (printsev != NULL && cfg_obj_asboolean(printsev)) - flags |= ISC_LOG_PRINTLEVEL; - } - - level = ISC_LOG_INFO; - if (cfg_map_get(channel, "severity", &severity) == ISC_R_SUCCESS) { - if (cfg_obj_isstring(severity)) { - char *str = cfg_obj_asstring(severity); - if (strcasecmp(str, "critical") == 0) - level = ISC_LOG_CRITICAL; - else if (strcasecmp(str, "error") == 0) - level = ISC_LOG_ERROR; - else if (strcasecmp(str, "warning") == 0) - level = ISC_LOG_WARNING; - else if (strcasecmp(str, "notice") == 0) - level = ISC_LOG_NOTICE; - else if (strcasecmp(str, "info") == 0) - level = ISC_LOG_INFO; - else if (strcasecmp(str, "dynamic") == 0) - level = ISC_LOG_DYNAMIC; - } else - /* debug */ - level = cfg_obj_asuint32(severity); - } - - result = isc_log_createchannel(lctx, channelname, - type, level, &dest, flags); - - if (result == ISC_R_SUCCESS && type == ISC_LOG_TOFILE) { - FILE *fp; - - /* - * Test that the file can be opened, since isc_log_open() - * can't effectively report failures when called in - * isc_log_doit(). - */ - result = isc_stdio_open(dest.file.name, "a", &fp); - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, CFG_LOGCATEGORY_CONFIG, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "logging channel '%s' file '%s': %s", - channelname, dest.file.name, - isc_result_totext(result)); - else - (void)isc_stdio_close(fp); - - /* - * Allow named to continue by returning success. - */ - result = ISC_R_SUCCESS; - } - - return (result); -} - -isc_result_t -ns_log_configure(isc_logconfig_t *logconf, cfg_obj_t *logstmt) { - isc_result_t result; - cfg_obj_t *channels = NULL; - cfg_obj_t *categories = NULL; - cfg_listelt_t *element; - isc_boolean_t default_set = ISC_FALSE; - isc_boolean_t unmatched_set = ISC_FALSE; - - CHECK(ns_log_setdefaultchannels(logconf)); - - (void)cfg_map_get(logstmt, "channel", &channels); - for (element = cfg_list_first(channels); - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *channel = cfg_listelt_value(element); - CHECK(channel_fromconf(channel, logconf)); - } - - (void)cfg_map_get(logstmt, "category", &categories); - for (element = cfg_list_first(categories); - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *category = cfg_listelt_value(element); - CHECK(category_fromconf(category, logconf)); - if (!default_set) { - cfg_obj_t *catname = cfg_tuple_get(category, "name"); - if (strcmp(cfg_obj_asstring(catname), "default") == 0) - default_set = ISC_TRUE; - } - if (!unmatched_set) { - cfg_obj_t *catname = cfg_tuple_get(category, "name"); - if (strcmp(cfg_obj_asstring(catname), "unmatched") == 0) - unmatched_set = ISC_TRUE; - } - } - - if (!default_set) - CHECK(ns_log_setdefaultcategory(logconf)); - - if (!unmatched_set) - CHECK(ns_log_setunmatchedcategory(logconf)); - - return (ISC_R_SUCCESS); - - cleanup: - if (logconf != NULL) - isc_logconfig_destroy(&logconf); - return (result); -} diff --git a/contrib/bind9/bin/named/lwaddr.c b/contrib/bind9/bin/named/lwaddr.c deleted file mode 100644 index 1bd8d82875e7..000000000000 --- a/contrib/bind9/bin/named/lwaddr.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: lwaddr.c,v 1.3.208.1 2004/03/06 10:21:18 marka Exp $ */ - -#include <config.h> - -#include <string.h> - -#include <isc/result.h> -#include <isc/netaddr.h> -#include <isc/sockaddr.h> - -#include <lwres/lwres.h> - -#include <named/lwaddr.h> - -/* - * Convert addresses from lwres to isc format. - */ -isc_result_t -lwaddr_netaddr_fromlwresaddr(isc_netaddr_t *na, lwres_addr_t *la) { - if (la->family != LWRES_ADDRTYPE_V4 && la->family != LWRES_ADDRTYPE_V6) - return (ISC_R_FAMILYNOSUPPORT); - - if (la->family == LWRES_ADDRTYPE_V4) { - struct in_addr ina; - memcpy(&ina.s_addr, la->address, 4); - isc_netaddr_fromin(na, &ina); - } else { - struct in6_addr ina6; - memcpy(&ina6.s6_addr, la->address, 16); - isc_netaddr_fromin6(na, &ina6); - } - return (ISC_R_SUCCESS); -} - -isc_result_t -lwaddr_sockaddr_fromlwresaddr(isc_sockaddr_t *sa, lwres_addr_t *la, - in_port_t port) -{ - isc_netaddr_t na; - isc_result_t result; - - result = lwaddr_netaddr_fromlwresaddr(&na, la); - if (result != ISC_R_SUCCESS) - return (result); - isc_sockaddr_fromnetaddr(sa, &na, port); - return (ISC_R_SUCCESS); -} - -/* - * Convert addresses from isc to lwres format. - */ - -isc_result_t -lwaddr_lwresaddr_fromnetaddr(lwres_addr_t *la, isc_netaddr_t *na) { - if (na->family != AF_INET && na->family != AF_INET6) - return (ISC_R_FAMILYNOSUPPORT); - - if (na->family == AF_INET) { - la->family = LWRES_ADDRTYPE_V4; - la->length = 4; - memcpy(la->address, &na->type.in, 4); - } else { - la->family = LWRES_ADDRTYPE_V6; - la->length = 16; - memcpy(la->address, &na->type.in, 16); - } - return (ISC_R_SUCCESS); -} - -isc_result_t -lwaddr_lwresaddr_fromsockaddr(lwres_addr_t *la, isc_sockaddr_t *sa) { - isc_netaddr_t na; - isc_netaddr_fromsockaddr(&na, sa); - return (lwaddr_lwresaddr_fromnetaddr(la, &na)); -} diff --git a/contrib/bind9/bin/named/lwdclient.c b/contrib/bind9/bin/named/lwdclient.c deleted file mode 100644 index 7975a4991e13..000000000000 --- a/contrib/bind9/bin/named/lwdclient.c +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: lwdclient.c,v 1.13.12.5 2004/03/08 09:04:15 marka Exp $ */ - -#include <config.h> - -#include <isc/socket.h> -#include <isc/string.h> -#include <isc/task.h> -#include <isc/util.h> - -#include <dns/adb.h> -#include <dns/view.h> -#include <dns/log.h> - -#include <named/types.h> -#include <named/log.h> -#include <named/lwresd.h> -#include <named/lwdclient.h> - -#define SHUTTINGDOWN(cm) ((cm->flags & NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN) != 0) - -static void -lwdclientmgr_shutdown_callback(isc_task_t *task, isc_event_t *ev); - -void -ns_lwdclient_log(int level, const char *format, ...) { - va_list args; - - va_start(args, format); - isc_log_vwrite(dns_lctx, - DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB, - ISC_LOG_DEBUG(level), format, args); - va_end(args); -} - -isc_result_t -ns_lwdclientmgr_create(ns_lwreslistener_t *listener, unsigned int nclients, - isc_taskmgr_t *taskmgr) -{ - ns_lwresd_t *lwresd = listener->manager; - ns_lwdclientmgr_t *cm; - ns_lwdclient_t *client; - unsigned int i; - isc_result_t result = ISC_R_FAILURE; - - cm = isc_mem_get(lwresd->mctx, sizeof(ns_lwdclientmgr_t)); - if (cm == NULL) - return (ISC_R_NOMEMORY); - - cm->listener = NULL; - ns_lwreslistener_attach(listener, &cm->listener); - cm->mctx = lwresd->mctx; - cm->sock = NULL; - isc_socket_attach(listener->sock, &cm->sock); - cm->view = lwresd->view; - cm->lwctx = NULL; - cm->task = NULL; - cm->flags = 0; - ISC_LINK_INIT(cm, link); - ISC_LIST_INIT(cm->idle); - ISC_LIST_INIT(cm->running); - - if (lwres_context_create(&cm->lwctx, cm->mctx, - ns__lwresd_memalloc, ns__lwresd_memfree, - LWRES_CONTEXT_SERVERMODE) - != ISC_R_SUCCESS) - goto errout; - - for (i = 0; i < nclients; i++) { - client = isc_mem_get(lwresd->mctx, sizeof(ns_lwdclient_t)); - if (client != NULL) { - ns_lwdclient_log(50, "created client %p, manager %p", - client, cm); - ns_lwdclient_initialize(client, cm); - } - } - - /* - * If we could create no clients, clean up and return. - */ - if (ISC_LIST_EMPTY(cm->idle)) - goto errout; - - result = isc_task_create(taskmgr, 0, &cm->task); - if (result != ISC_R_SUCCESS) - goto errout; - - /* - * This MUST be last, since there is no way to cancel an onshutdown... - */ - result = isc_task_onshutdown(cm->task, lwdclientmgr_shutdown_callback, - cm); - if (result != ISC_R_SUCCESS) - goto errout; - - ns_lwreslistener_linkcm(listener, cm); - - return (ISC_R_SUCCESS); - - errout: - client = ISC_LIST_HEAD(cm->idle); - while (client != NULL) { - ISC_LIST_UNLINK(cm->idle, client, link); - isc_mem_put(lwresd->mctx, client, sizeof(*client)); - client = ISC_LIST_HEAD(cm->idle); - } - - if (cm->task != NULL) - isc_task_detach(&cm->task); - - if (cm->lwctx != NULL) - lwres_context_destroy(&cm->lwctx); - - isc_mem_put(lwresd->mctx, cm, sizeof(*cm)); - return (result); -} - -static void -lwdclientmgr_destroy(ns_lwdclientmgr_t *cm) { - ns_lwdclient_t *client; - ns_lwreslistener_t *listener; - - if (!SHUTTINGDOWN(cm)) - return; - - /* - * run through the idle list and free the clients there. Idle - * clients do not have a recv running nor do they have any finds - * or similar running. - */ - client = ISC_LIST_HEAD(cm->idle); - while (client != NULL) { - ns_lwdclient_log(50, "destroying client %p, manager %p", - client, cm); - ISC_LIST_UNLINK(cm->idle, client, link); - isc_mem_put(cm->mctx, client, sizeof(*client)); - client = ISC_LIST_HEAD(cm->idle); - } - - if (!ISC_LIST_EMPTY(cm->running)) - return; - - lwres_context_destroy(&cm->lwctx); - cm->view = NULL; - isc_socket_detach(&cm->sock); - isc_task_detach(&cm->task); - - listener = cm->listener; - ns_lwreslistener_unlinkcm(listener, cm); - ns_lwdclient_log(50, "destroying manager %p", cm); - isc_mem_put(cm->mctx, cm, sizeof(*cm)); - ns_lwreslistener_detach(&listener); -} - -static void -process_request(ns_lwdclient_t *client) { - lwres_buffer_t b; - isc_result_t result; - - lwres_buffer_init(&b, client->buffer, client->recvlength); - lwres_buffer_add(&b, client->recvlength); - - result = lwres_lwpacket_parseheader(&b, &client->pkt); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_log(50, "invalid packet header received"); - goto restart; - } - - ns_lwdclient_log(50, "opcode %08x", client->pkt.opcode); - - switch (client->pkt.opcode) { - case LWRES_OPCODE_GETADDRSBYNAME: - ns_lwdclient_processgabn(client, &b); - return; - case LWRES_OPCODE_GETNAMEBYADDR: - ns_lwdclient_processgnba(client, &b); - return; - case LWRES_OPCODE_GETRDATABYNAME: - ns_lwdclient_processgrbn(client, &b); - return; - case LWRES_OPCODE_NOOP: - ns_lwdclient_processnoop(client, &b); - return; - default: - ns_lwdclient_log(50, "unknown opcode %08x", client->pkt.opcode); - goto restart; - } - - /* - * Drop the packet. - */ - restart: - ns_lwdclient_log(50, "restarting client %p...", client); - ns_lwdclient_stateidle(client); -} - -void -ns_lwdclient_recv(isc_task_t *task, isc_event_t *ev) { - isc_result_t result; - ns_lwdclient_t *client = ev->ev_arg; - ns_lwdclientmgr_t *cm = client->clientmgr; - isc_socketevent_t *dev = (isc_socketevent_t *)ev; - - INSIST(dev->region.base == client->buffer); - INSIST(NS_LWDCLIENT_ISRECV(client)); - - NS_LWDCLIENT_SETRECVDONE(client); - - INSIST((cm->flags & NS_LWDCLIENTMGR_FLAGRECVPENDING) != 0); - cm->flags &= ~NS_LWDCLIENTMGR_FLAGRECVPENDING; - - ns_lwdclient_log(50, - "event received: task %p, length %u, result %u (%s)", - task, dev->n, dev->result, - isc_result_totext(dev->result)); - - if (dev->result != ISC_R_SUCCESS) { - isc_event_free(&ev); - dev = NULL; - - /* - * Go idle. - */ - ns_lwdclient_stateidle(client); - - return; - } - - client->recvlength = dev->n; - client->address = dev->address; - if ((dev->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0) { - client->pktinfo = dev->pktinfo; - client->pktinfo_valid = ISC_TRUE; - } else - client->pktinfo_valid = ISC_FALSE; - isc_event_free(&ev); - dev = NULL; - - result = ns_lwdclient_startrecv(cm); - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_ERROR, - "could not start lwres " - "client handler: %s", - isc_result_totext(result)); - - process_request(client); -} - -/* - * This function will start a new recv() on a socket for this client manager. - */ -isc_result_t -ns_lwdclient_startrecv(ns_lwdclientmgr_t *cm) { - ns_lwdclient_t *client; - isc_result_t result; - isc_region_t r; - - if (SHUTTINGDOWN(cm)) { - lwdclientmgr_destroy(cm); - return (ISC_R_SUCCESS); - } - - /* - * If a recv is already running, don't bother. - */ - if ((cm->flags & NS_LWDCLIENTMGR_FLAGRECVPENDING) != 0) - return (ISC_R_SUCCESS); - - /* - * If we have no idle slots, just return success. - */ - client = ISC_LIST_HEAD(cm->idle); - if (client == NULL) - return (ISC_R_SUCCESS); - INSIST(NS_LWDCLIENT_ISIDLE(client)); - - /* - * Issue the recv. If it fails, return that it did. - */ - r.base = client->buffer; - r.length = LWRES_RECVLENGTH; - result = isc_socket_recv(cm->sock, &r, 0, cm->task, ns_lwdclient_recv, - client); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Set the flag to say we've issued a recv() call. - */ - cm->flags |= NS_LWDCLIENTMGR_FLAGRECVPENDING; - - /* - * Remove the client from the idle list, and put it on the running - * list. - */ - NS_LWDCLIENT_SETRECV(client); - ISC_LIST_UNLINK(cm->idle, client, link); - ISC_LIST_APPEND(cm->running, client, link); - - return (ISC_R_SUCCESS); -} - -static void -lwdclientmgr_shutdown_callback(isc_task_t *task, isc_event_t *ev) { - ns_lwdclientmgr_t *cm = ev->ev_arg; - ns_lwdclient_t *client; - - REQUIRE(!SHUTTINGDOWN(cm)); - - ns_lwdclient_log(50, "got shutdown event, task %p, lwdclientmgr %p", - task, cm); - - /* - * run through the idle list and free the clients there. Idle - * clients do not have a recv running nor do they have any finds - * or similar running. - */ - client = ISC_LIST_HEAD(cm->idle); - while (client != NULL) { - ns_lwdclient_log(50, "destroying client %p, manager %p", - client, cm); - ISC_LIST_UNLINK(cm->idle, client, link); - isc_mem_put(cm->mctx, client, sizeof(*client)); - client = ISC_LIST_HEAD(cm->idle); - } - - /* - * Cancel any pending I/O. - */ - isc_socket_cancel(cm->sock, task, ISC_SOCKCANCEL_ALL); - - /* - * Run through the running client list and kill off any finds - * in progress. - */ - client = ISC_LIST_HEAD(cm->running); - while (client != NULL) { - if (client->find != client->v4find - && client->find != client->v6find) - dns_adb_cancelfind(client->find); - if (client->v4find != NULL) - dns_adb_cancelfind(client->v4find); - if (client->v6find != NULL) - dns_adb_cancelfind(client->v6find); - client = ISC_LIST_NEXT(client, link); - } - - cm->flags |= NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN; - - isc_event_free(&ev); -} - -/* - * Do all the crap needed to move a client from the run queue to the idle - * queue. - */ -void -ns_lwdclient_stateidle(ns_lwdclient_t *client) { - ns_lwdclientmgr_t *cm; - isc_result_t result; - - cm = client->clientmgr; - - INSIST(client->sendbuf == NULL); - INSIST(client->sendlength == 0); - INSIST(client->arg == NULL); - INSIST(client->v4find == NULL); - INSIST(client->v6find == NULL); - - ISC_LIST_UNLINK(cm->running, client, link); - ISC_LIST_PREPEND(cm->idle, client, link); - - NS_LWDCLIENT_SETIDLE(client); - - result = ns_lwdclient_startrecv(cm); - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_ERROR, - "could not start lwres " - "client handler: %s", - isc_result_totext(result)); -} - -void -ns_lwdclient_send(isc_task_t *task, isc_event_t *ev) { - ns_lwdclient_t *client = ev->ev_arg; - ns_lwdclientmgr_t *cm = client->clientmgr; - isc_socketevent_t *dev = (isc_socketevent_t *)ev; - - UNUSED(task); - UNUSED(dev); - - INSIST(NS_LWDCLIENT_ISSEND(client)); - INSIST(client->sendbuf == dev->region.base); - - ns_lwdclient_log(50, "task %p for client %p got send-done event", - task, client); - - if (client->sendbuf != client->buffer) - lwres_context_freemem(cm->lwctx, client->sendbuf, - client->sendlength); - client->sendbuf = NULL; - client->sendlength = 0; - - ns_lwdclient_stateidle(client); - - isc_event_free(&ev); -} - -isc_result_t -ns_lwdclient_sendreply(ns_lwdclient_t *client, isc_region_t *r) { - struct in6_pktinfo *pktinfo; - ns_lwdclientmgr_t *cm = client->clientmgr; - - if (client->pktinfo_valid) - pktinfo = &client->pktinfo; - else - pktinfo = NULL; - return (isc_socket_sendto(cm->sock, r, cm->task, ns_lwdclient_send, - client, &client->address, pktinfo)); -} - -void -ns_lwdclient_initialize(ns_lwdclient_t *client, ns_lwdclientmgr_t *cmgr) { - client->clientmgr = cmgr; - ISC_LINK_INIT(client, link); - NS_LWDCLIENT_SETIDLE(client); - client->arg = NULL; - - client->recvlength = 0; - - client->sendbuf = NULL; - client->sendlength = 0; - - client->find = NULL; - client->v4find = NULL; - client->v6find = NULL; - client->find_wanted = 0; - - client->options = 0; - client->byaddr = NULL; - - client->lookup = NULL; - - client->pktinfo_valid = ISC_FALSE; - - ISC_LIST_APPEND(cmgr->idle, client, link); -} diff --git a/contrib/bind9/bin/named/lwderror.c b/contrib/bind9/bin/named/lwderror.c deleted file mode 100644 index 51cecf0abd57..000000000000 --- a/contrib/bind9/bin/named/lwderror.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: lwderror.c,v 1.7.208.1 2004/03/06 10:21:18 marka Exp $ */ - -#include <config.h> - -#include <isc/socket.h> -#include <isc/util.h> - -#include <named/types.h> -#include <named/lwdclient.h> - -/* - * Generate an error packet for the client, schedule a send, and put us in - * the SEND state. - * - * The client->pkt structure will be modified to form an error return. - * The receiver needs to verify that it is in fact an error, and do the - * right thing with it. The opcode will be unchanged. The result needs - * to be set before calling this function. - * - * The only change this code makes is to set the receive buffer size to the - * size we use, set the reply bit, and recompute any security information. - */ -void -ns_lwdclient_errorpktsend(ns_lwdclient_t *client, isc_uint32_t _result) { - isc_result_t result; - int lwres; - isc_region_t r; - lwres_buffer_t b; - - REQUIRE(NS_LWDCLIENT_ISRUNNING(client)); - - /* - * Since we are only sending the packet header, we can safely toss - * the receive buffer. This means we won't need to allocate space - * for sending an error reply. This is a Good Thing. - */ - client->pkt.length = LWRES_LWPACKET_LENGTH; - client->pkt.pktflags |= LWRES_LWPACKETFLAG_RESPONSE; - client->pkt.recvlength = LWRES_RECVLENGTH; - client->pkt.authtype = 0; /* XXXMLG */ - client->pkt.authlength = 0; - client->pkt.result = _result; - - lwres_buffer_init(&b, client->buffer, LWRES_RECVLENGTH); - lwres = lwres_lwpacket_renderheader(&b, &client->pkt); - if (lwres != LWRES_R_SUCCESS) { - ns_lwdclient_stateidle(client); - return; - } - - r.base = client->buffer; - r.length = b.used; - client->sendbuf = client->buffer; - result = ns_lwdclient_sendreply(client, &r); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_stateidle(client); - return; - } - - NS_LWDCLIENT_SETSEND(client); -} diff --git a/contrib/bind9/bin/named/lwdgabn.c b/contrib/bind9/bin/named/lwdgabn.c deleted file mode 100644 index 030a77ae7864..000000000000 --- a/contrib/bind9/bin/named/lwdgabn.c +++ /dev/null @@ -1,655 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: lwdgabn.c,v 1.13.12.3 2004/03/08 04:04:19 marka Exp $ */ - -#include <config.h> - -#include <stdlib.h> - -#include <isc/netaddr.h> -#include <isc/sockaddr.h> -#include <isc/socket.h> -#include <isc/string.h> /* Required for HP/UX (and others?) */ -#include <isc/util.h> - -#include <dns/adb.h> -#include <dns/events.h> -#include <dns/result.h> - -#include <named/types.h> -#include <named/lwaddr.h> -#include <named/lwdclient.h> -#include <named/lwresd.h> -#include <named/lwsearch.h> -#include <named/sortlist.h> - -#define NEED_V4(c) ((((c)->find_wanted & LWRES_ADDRTYPE_V4) != 0) \ - && ((c)->v4find == NULL)) -#define NEED_V6(c) ((((c)->find_wanted & LWRES_ADDRTYPE_V6) != 0) \ - && ((c)->v6find == NULL)) - -static isc_result_t start_find(ns_lwdclient_t *); -static void restart_find(ns_lwdclient_t *); -static void init_gabn(ns_lwdclient_t *); - -/* - * Destroy any finds. This can be used to "start over from scratch" and - * should only be called when events are _not_ being generated by the finds. - */ -static void -cleanup_gabn(ns_lwdclient_t *client) { - ns_lwdclient_log(50, "cleaning up client %p", client); - - if (client->v6find != NULL) { - if (client->v6find == client->v4find) - client->v6find = NULL; - else - dns_adb_destroyfind(&client->v6find); - } - if (client->v4find != NULL) - dns_adb_destroyfind(&client->v4find); -} - -static void -setup_addresses(ns_lwdclient_t *client, dns_adbfind_t *find, unsigned int at) { - dns_adbaddrinfo_t *ai; - lwres_addr_t *addr; - int af; - const struct sockaddr *sa; - isc_result_t result; - - if (at == DNS_ADBFIND_INET) - af = AF_INET; - else - af = AF_INET6; - - ai = ISC_LIST_HEAD(find->list); - while (ai != NULL && client->gabn.naddrs < LWRES_MAX_ADDRS) { - sa = &ai->sockaddr.type.sa; - if (sa->sa_family != af) - goto next; - - addr = &client->addrs[client->gabn.naddrs]; - - result = lwaddr_lwresaddr_fromsockaddr(addr, &ai->sockaddr); - if (result != ISC_R_SUCCESS) - goto next; - - ns_lwdclient_log(50, "adding address %p, family %d, length %d", - addr->address, addr->family, addr->length); - - client->gabn.naddrs++; - REQUIRE(!LWRES_LINK_LINKED(addr, link)); - LWRES_LIST_APPEND(client->gabn.addrs, addr, link); - - next: - ai = ISC_LIST_NEXT(ai, publink); - } -} - -typedef struct { - isc_netaddr_t address; - int rank; -} rankedaddress; - -static int -addr_compare(const void *av, const void *bv) { - const rankedaddress *a = (const rankedaddress *) av; - const rankedaddress *b = (const rankedaddress *) bv; - return (a->rank - b->rank); -} - -static void -sort_addresses(ns_lwdclient_t *client) { - unsigned int naddrs; - rankedaddress *addrs; - isc_netaddr_t remote; - dns_addressorderfunc_t order; - void *arg; - ns_lwresd_t *lwresd = client->clientmgr->listener->manager; - unsigned int i; - isc_result_t result; - - naddrs = client->gabn.naddrs; - - if (naddrs <= 1 || lwresd->view->sortlist == NULL) - return; - - addrs = isc_mem_get(lwresd->mctx, sizeof(rankedaddress) * naddrs); - if (addrs == NULL) - return; - - isc_netaddr_fromsockaddr(&remote, &client->address); - ns_sortlist_byaddrsetup(lwresd->view->sortlist, - &remote, &order, &arg); - if (order == NULL) { - isc_mem_put(lwresd->mctx, addrs, - sizeof(rankedaddress) * naddrs); - return; - } - for (i = 0; i < naddrs; i++) { - result = lwaddr_netaddr_fromlwresaddr(&addrs[i].address, - &client->addrs[i]); - INSIST(result == ISC_R_SUCCESS); - addrs[i].rank = (*order)(&addrs[i].address, arg); - } - qsort(addrs, naddrs, sizeof(rankedaddress), addr_compare); - for (i = 0; i < naddrs; i++) { - result = lwaddr_lwresaddr_fromnetaddr(&client->addrs[i], - &addrs[i].address); - INSIST(result == ISC_R_SUCCESS); - } - - isc_mem_put(lwresd->mctx, addrs, sizeof(rankedaddress) * naddrs); -} - -static void -generate_reply(ns_lwdclient_t *client) { - isc_result_t result; - int lwres; - isc_region_t r; - lwres_buffer_t lwb; - ns_lwdclientmgr_t *cm; - - cm = client->clientmgr; - lwb.base = NULL; - - ns_lwdclient_log(50, "generating gabn reply for client %p", client); - - /* - * We must make certain the client->find is not still active. - * If it is either the v4 or v6 answer, just set it to NULL and - * let the cleanup code destroy it. Otherwise, destroy it now. - */ - if (client->find == client->v4find || client->find == client->v6find) - client->find = NULL; - else - if (client->find != NULL) - dns_adb_destroyfind(&client->find); - - /* - * perhaps there are some here? - */ - if (NEED_V6(client) && client->v4find != NULL) - client->v6find = client->v4find; - - /* - * Run through the finds we have and wire them up to the gabn - * structure. - */ - LWRES_LIST_INIT(client->gabn.addrs); - if (client->v4find != NULL) - setup_addresses(client, client->v4find, DNS_ADBFIND_INET); - if (client->v6find != NULL) - setup_addresses(client, client->v6find, DNS_ADBFIND_INET6); - - /* - * If there are no addresses, try the next element in the search - * path, if there are any more. Otherwise, fall through into - * the error handling code below. - */ - if (client->gabn.naddrs == 0) { - do { - result = ns_lwsearchctx_next(&client->searchctx); - if (result == ISC_R_SUCCESS) { - cleanup_gabn(client); - result = start_find(client); - if (result == ISC_R_SUCCESS) - return; - } - } while (result == ISC_R_SUCCESS); - } - - /* - * Render the packet. - */ - client->pkt.recvlength = LWRES_RECVLENGTH; - client->pkt.authtype = 0; /* XXXMLG */ - client->pkt.authlength = 0; - - /* - * If there are no addresses, return failure. - */ - if (client->gabn.naddrs != 0) - client->pkt.result = LWRES_R_SUCCESS; - else - client->pkt.result = LWRES_R_NOTFOUND; - - sort_addresses(client); - - lwres = lwres_gabnresponse_render(cm->lwctx, &client->gabn, - &client->pkt, &lwb); - if (lwres != LWRES_R_SUCCESS) - goto out; - - r.base = lwb.base; - r.length = lwb.used; - client->sendbuf = r.base; - client->sendlength = r.length; - result = ns_lwdclient_sendreply(client, &r); - if (result != ISC_R_SUCCESS) - goto out; - - NS_LWDCLIENT_SETSEND(client); - - /* - * All done! - */ - cleanup_gabn(client); - - return; - - out: - cleanup_gabn(client); - - if (lwb.base != NULL) - lwres_context_freemem(client->clientmgr->lwctx, - lwb.base, lwb.length); - - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} - -/* - * Take the current real name, move it to an alias slot (if any are - * open) then put this new name in as the real name for the target. - * - * Return success if it can be rendered, otherwise failure. Note that - * not having enough alias slots open is NOT a failure. - */ -static isc_result_t -add_alias(ns_lwdclient_t *client) { - isc_buffer_t b; - isc_result_t result; - isc_uint16_t naliases; - - b = client->recv_buffer; - - /* - * Render the new name to the buffer. - */ - result = dns_name_totext(dns_fixedname_name(&client->target_name), - ISC_TRUE, &client->recv_buffer); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Are there any open slots? - */ - naliases = client->gabn.naliases; - if (naliases < LWRES_MAX_ALIASES) { - client->gabn.aliases[naliases] = client->gabn.realname; - client->gabn.aliaslen[naliases] = client->gabn.realnamelen; - client->gabn.naliases++; - } - - /* - * Save this name away as the current real name. - */ - client->gabn.realname = (char *)(b.base) + b.used; - client->gabn.realnamelen = client->recv_buffer.used - b.used; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -store_realname(ns_lwdclient_t *client) { - isc_buffer_t b; - isc_result_t result; - dns_name_t *tname; - - b = client->recv_buffer; - - tname = dns_fixedname_name(&client->target_name); - result = ns_lwsearchctx_current(&client->searchctx, tname); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Render the new name to the buffer. - */ - result = dns_name_totext(tname, ISC_TRUE, &client->recv_buffer); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Save this name away as the current real name. - */ - client->gabn.realname = (char *) b.base + b.used; - client->gabn.realnamelen = client->recv_buffer.used - b.used; - - return (ISC_R_SUCCESS); -} - -static void -process_gabn_finddone(isc_task_t *task, isc_event_t *ev) { - ns_lwdclient_t *client = ev->ev_arg; - isc_eventtype_t evtype; - isc_boolean_t claimed; - - ns_lwdclient_log(50, "find done for task %p, client %p", task, client); - - evtype = ev->ev_type; - isc_event_free(&ev); - - /* - * No more info to be had? If so, we have all the good stuff - * right now, so we can render things. - */ - claimed = ISC_FALSE; - if (evtype == DNS_EVENT_ADBNOMOREADDRESSES) { - if (NEED_V4(client)) { - client->v4find = client->find; - claimed = ISC_TRUE; - } - if (NEED_V6(client)) { - client->v6find = client->find; - claimed = ISC_TRUE; - } - if (client->find != NULL) { - if (claimed) - client->find = NULL; - else - dns_adb_destroyfind(&client->find); - - } - generate_reply(client); - return; - } - - /* - * We probably don't need this find anymore. We're either going to - * reissue it, or an error occurred. Either way, we're done with - * it. - */ - if ((client->find != client->v4find) - && (client->find != client->v6find)) { - dns_adb_destroyfind(&client->find); - } else { - client->find = NULL; - } - - /* - * We have some new information we can gather. Run off and fetch - * it. - */ - if (evtype == DNS_EVENT_ADBMOREADDRESSES) { - restart_find(client); - return; - } - - /* - * An error or other strangeness happened. Drop this query. - */ - cleanup_gabn(client); - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} - -static void -restart_find(ns_lwdclient_t *client) { - unsigned int options; - isc_result_t result; - isc_boolean_t claimed; - - ns_lwdclient_log(50, "starting find for client %p", client); - - /* - * Issue a find for the name contained in the request. We won't - * set the bit that says "anything is good enough" -- we want it - * all. - */ - options = 0; - options |= DNS_ADBFIND_WANTEVENT; - options |= DNS_ADBFIND_RETURNLAME; - - /* - * Set the bits up here to mark that we want this address family - * and that we do not currently have a find pending. We will - * set that bit again below if it turns out we will get an event. - */ - if (NEED_V4(client)) - options |= DNS_ADBFIND_INET; - if (NEED_V6(client)) - options |= DNS_ADBFIND_INET6; - - find_again: - INSIST(client->find == NULL); - result = dns_adb_createfind(client->clientmgr->view->adb, - client->clientmgr->task, - process_gabn_finddone, client, - dns_fixedname_name(&client->target_name), - dns_rootname, options, 0, - dns_fixedname_name(&client->target_name), - client->clientmgr->view->dstport, - &client->find); - - /* - * Did we get an alias? If so, save it and re-issue the query. - */ - if (result == DNS_R_ALIAS) { - ns_lwdclient_log(50, "found alias, restarting query"); - dns_adb_destroyfind(&client->find); - cleanup_gabn(client); - result = add_alias(client); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_log(50, - "out of buffer space adding alias"); - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); - return; - } - goto find_again; - } - - ns_lwdclient_log(50, "find returned %d (%s)", result, - isc_result_totext(result)); - - /* - * Did we get an error? - */ - if (result != ISC_R_SUCCESS) { - if (client->find != NULL) - dns_adb_destroyfind(&client->find); - cleanup_gabn(client); - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); - return; - } - - claimed = ISC_FALSE; - - /* - * Did we get our answer to V4 addresses? - */ - if (NEED_V4(client) - && ((client->find->query_pending & DNS_ADBFIND_INET) == 0)) { - ns_lwdclient_log(50, "client %p ipv4 satisfied by find %p", - client, client->find); - claimed = ISC_TRUE; - client->v4find = client->find; - } - - /* - * Did we get our answer to V6 addresses? - */ - if (NEED_V6(client) - && ((client->find->query_pending & DNS_ADBFIND_INET6) == 0)) { - ns_lwdclient_log(50, "client %p ipv6 satisfied by find %p", - client, client->find); - claimed = ISC_TRUE; - client->v6find = client->find; - } - - /* - * If we're going to get an event, set our internal pending flag - * and return. When we get an event back we'll do the right - * thing, basically by calling this function again, perhaps with a - * new target name. - * - * If we have both v4 and v6, and we are still getting an event, - * we have a programming error, so die hard. - */ - if ((client->find->options & DNS_ADBFIND_WANTEVENT) != 0) { - ns_lwdclient_log(50, "event will be sent"); - INSIST(client->v4find == NULL || client->v6find == NULL); - return; - } - ns_lwdclient_log(50, "no event will be sent"); - if (claimed) - client->find = NULL; - else - dns_adb_destroyfind(&client->find); - - /* - * We seem to have everything we asked for, or at least we are - * able to respond with things we've learned. - */ - - generate_reply(client); -} - -static isc_result_t -start_find(ns_lwdclient_t *client) { - isc_result_t result; - - /* - * Initialize the real name and alias arrays in the reply we're - * going to build up. - */ - init_gabn(client); - - result = store_realname(client); - if (result != ISC_R_SUCCESS) - return (result); - restart_find(client); - return (ISC_R_SUCCESS); - -} - -static void -init_gabn(ns_lwdclient_t *client) { - int i; - - /* - * Initialize the real name and alias arrays in the reply we're - * going to build up. - */ - for (i = 0; i < LWRES_MAX_ALIASES; i++) { - client->aliases[i] = NULL; - client->aliaslen[i] = 0; - } - for (i = 0; i < LWRES_MAX_ADDRS; i++) { - client->addrs[i].family = 0; - client->addrs[i].length = 0; - memset(client->addrs[i].address, 0, LWRES_ADDR_MAXLEN); - LWRES_LINK_INIT(&client->addrs[i], link); - } - - client->gabn.naliases = 0; - client->gabn.naddrs = 0; - client->gabn.realname = NULL; - client->gabn.aliases = client->aliases; - client->gabn.realnamelen = 0; - client->gabn.aliaslen = client->aliaslen; - LWRES_LIST_INIT(client->gabn.addrs); - client->gabn.base = NULL; - client->gabn.baselen = 0; - - /* - * Set up the internal buffer to point to the receive region. - */ - isc_buffer_init(&client->recv_buffer, client->buffer, LWRES_RECVLENGTH); -} - -/* - * When we are called, we can be assured that: - * - * client->sockaddr contains the address we need to reply to, - * - * client->pkt contains the packet header data, - * - * the packet "checks out" overall -- any MD5 hashes or crypto - * bits have been verified, - * - * "b" points to the remaining data after the packet header - * was parsed off. - * - * We are in a the RECVDONE state. - * - * From this state we will enter the SEND state if we happen to have - * everything we need or we need to return an error packet, or to the - * FINDWAIT state if we need to look things up. - */ -void -ns_lwdclient_processgabn(ns_lwdclient_t *client, lwres_buffer_t *b) { - isc_result_t result; - lwres_gabnrequest_t *req; - ns_lwdclientmgr_t *cm; - isc_buffer_t namebuf; - - REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); - - cm = client->clientmgr; - req = NULL; - - result = lwres_gabnrequest_parse(client->clientmgr->lwctx, - b, &client->pkt, &req); - if (result != LWRES_R_SUCCESS) - goto out; - if (req->name == NULL) - goto out; - - isc_buffer_init(&namebuf, req->name, req->namelen); - isc_buffer_add(&namebuf, req->namelen); - - dns_fixedname_init(&client->target_name); - dns_fixedname_init(&client->query_name); - result = dns_name_fromtext(dns_fixedname_name(&client->query_name), - &namebuf, NULL, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) - goto out; - ns_lwsearchctx_init(&client->searchctx, - cm->listener->manager->search, - dns_fixedname_name(&client->query_name), - cm->listener->manager->ndots); - ns_lwsearchctx_first(&client->searchctx); - - client->find_wanted = req->addrtypes; - ns_lwdclient_log(50, "client %p looking for addrtypes %08x", - client, client->find_wanted); - - /* - * We no longer need to keep this around. - */ - lwres_gabnrequest_free(client->clientmgr->lwctx, &req); - - /* - * Start the find. - */ - result = start_find(client); - if (result != ISC_R_SUCCESS) - goto out; - - return; - - /* - * We're screwed. Return an error packet to our caller. - */ - out: - if (req != NULL) - lwres_gabnrequest_free(client->clientmgr->lwctx, &req); - - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} diff --git a/contrib/bind9/bin/named/lwdgnba.c b/contrib/bind9/bin/named/lwdgnba.c deleted file mode 100644 index 21ef804ac933..000000000000 --- a/contrib/bind9/bin/named/lwdgnba.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000-2002 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: lwdgnba.c,v 1.13.2.1.2.5 2004/03/08 04:04:19 marka Exp $ */ - -#include <config.h> - -#include <isc/socket.h> -#include <isc/string.h> /* Required for HP/UX (and others?) */ -#include <isc/util.h> - -#include <dns/adb.h> -#include <dns/byaddr.h> -#include <dns/result.h> - -#include <named/types.h> -#include <named/lwdclient.h> - -static void start_byaddr(ns_lwdclient_t *); - -static void -byaddr_done(isc_task_t *task, isc_event_t *event) { - ns_lwdclient_t *client; - ns_lwdclientmgr_t *cm; - dns_byaddrevent_t *bevent; - int lwres; - lwres_buffer_t lwb; - dns_name_t *name; - isc_result_t result; - lwres_result_t lwresult; - isc_region_t r; - isc_buffer_t b; - lwres_gnbaresponse_t *gnba; - isc_uint16_t naliases; - - UNUSED(task); - - lwb.base = NULL; - client = event->ev_arg; - cm = client->clientmgr; - INSIST(client->byaddr == (dns_byaddr_t *)event->ev_sender); - - bevent = (dns_byaddrevent_t *)event; - gnba = &client->gnba; - - ns_lwdclient_log(50, "byaddr event result = %s", - isc_result_totext(bevent->result)); - - result = bevent->result; - if (result != ISC_R_SUCCESS) { - dns_byaddr_destroy(&client->byaddr); - isc_event_free(&event); - bevent = NULL; - - if (client->na.family != AF_INET6 || - (client->options & DNS_BYADDROPT_IPV6INT) != 0) { - if (result == DNS_R_NCACHENXDOMAIN || - result == DNS_R_NCACHENXRRSET || - result == DNS_R_NXDOMAIN || - result == DNS_R_NXRRSET) - lwresult = LWRES_R_NOTFOUND; - else - lwresult = LWRES_R_FAILURE; - ns_lwdclient_errorpktsend(client, lwresult); - return; - } - - /* - * Fall back to ip6.int reverse if the default ip6.arpa - * fails. - */ - client->options |= DNS_BYADDROPT_IPV6INT; - - start_byaddr(client); - return; - } - - for (name = ISC_LIST_HEAD(bevent->names); - name != NULL; - name = ISC_LIST_NEXT(name, link)) - { - b = client->recv_buffer; - - result = dns_name_totext(name, ISC_TRUE, &client->recv_buffer); - if (result != ISC_R_SUCCESS) - goto out; - ns_lwdclient_log(50, "found name '%.*s'", - (int)(client->recv_buffer.used - b.used), - (char *)(b.base) + b.used); - if (gnba->realname == NULL) { - gnba->realname = (char *)(b.base) + b.used; - gnba->realnamelen = client->recv_buffer.used - b.used; - } else { - naliases = gnba->naliases; - if (naliases >= LWRES_MAX_ALIASES) - break; - gnba->aliases[naliases] = (char *)(b.base) + b.used; - gnba->aliaslen[naliases] = - client->recv_buffer.used - b.used; - gnba->naliases++; - } - } - - dns_byaddr_destroy(&client->byaddr); - isc_event_free(&event); - - /* - * Render the packet. - */ - client->pkt.recvlength = LWRES_RECVLENGTH; - client->pkt.authtype = 0; /* XXXMLG */ - client->pkt.authlength = 0; - client->pkt.result = LWRES_R_SUCCESS; - - lwres = lwres_gnbaresponse_render(cm->lwctx, - gnba, &client->pkt, &lwb); - if (lwres != LWRES_R_SUCCESS) - goto out; - - r.base = lwb.base; - r.length = lwb.used; - client->sendbuf = r.base; - client->sendlength = r.length; - result = ns_lwdclient_sendreply(client, &r); - if (result != ISC_R_SUCCESS) - goto out; - - NS_LWDCLIENT_SETSEND(client); - - return; - - out: - if (client->byaddr != NULL) - dns_byaddr_destroy(&client->byaddr); - if (lwb.base != NULL) - lwres_context_freemem(cm->lwctx, - lwb.base, lwb.length); - - if (event != NULL) - isc_event_free(&event); -} - -static void -start_byaddr(ns_lwdclient_t *client) { - isc_result_t result; - ns_lwdclientmgr_t *cm; - - cm = client->clientmgr; - - INSIST(client->byaddr == NULL); - - result = dns_byaddr_create(cm->mctx, &client->na, cm->view, - client->options, cm->task, byaddr_done, - client, &client->byaddr); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); - return; - } -} - -static void -init_gnba(ns_lwdclient_t *client) { - int i; - - /* - * Initialize the real name and alias arrays in the reply we're - * going to build up. - */ - for (i = 0; i < LWRES_MAX_ALIASES; i++) { - client->aliases[i] = NULL; - client->aliaslen[i] = 0; - } - for (i = 0; i < LWRES_MAX_ADDRS; i++) { - client->addrs[i].family = 0; - client->addrs[i].length = 0; - memset(client->addrs[i].address, 0, LWRES_ADDR_MAXLEN); - LWRES_LINK_INIT(&client->addrs[i], link); - } - - client->gnba.naliases = 0; - client->gnba.realname = NULL; - client->gnba.aliases = client->aliases; - client->gnba.realnamelen = 0; - client->gnba.aliaslen = client->aliaslen; - client->gnba.base = NULL; - client->gnba.baselen = 0; - isc_buffer_init(&client->recv_buffer, client->buffer, LWRES_RECVLENGTH); -} - -void -ns_lwdclient_processgnba(ns_lwdclient_t *client, lwres_buffer_t *b) { - lwres_gnbarequest_t *req; - isc_result_t result; - isc_sockaddr_t sa; - ns_lwdclientmgr_t *cm; - - REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); - INSIST(client->byaddr == NULL); - - cm = client->clientmgr; - req = NULL; - - result = lwres_gnbarequest_parse(cm->lwctx, - b, &client->pkt, &req); - if (result != LWRES_R_SUCCESS) - goto out; - if (req->addr.address == NULL) - goto out; - - client->options = 0; - if (req->addr.family == LWRES_ADDRTYPE_V4) { - client->na.family = AF_INET; - if (req->addr.length != 4) - goto out; - memcpy(&client->na.type.in, req->addr.address, 4); - } else if (req->addr.family == LWRES_ADDRTYPE_V6) { - client->na.family = AF_INET6; - if (req->addr.length != 16) - goto out; - memcpy(&client->na.type.in6, req->addr.address, 16); - } else { - goto out; - } - isc_sockaddr_fromnetaddr(&sa, &client->na, 53); - - ns_lwdclient_log(50, "client %p looking for addrtype %08x", - client, req->addr.family); - - /* - * We no longer need to keep this around. - */ - lwres_gnbarequest_free(cm->lwctx, &req); - - /* - * Initialize the real name and alias arrays in the reply we're - * going to build up. - */ - init_gnba(client); - client->options = 0; - - /* - * Start the find. - */ - start_byaddr(client); - - return; - - /* - * We're screwed. Return an error packet to our caller. - */ - out: - if (req != NULL) - lwres_gnbarequest_free(cm->lwctx, &req); - - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} diff --git a/contrib/bind9/bin/named/lwdgrbn.c b/contrib/bind9/bin/named/lwdgrbn.c deleted file mode 100644 index 665226539b4f..000000000000 --- a/contrib/bind9/bin/named/lwdgrbn.c +++ /dev/null @@ -1,513 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001, 2003 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: lwdgrbn.c,v 1.11.208.3 2004/03/08 04:04:19 marka Exp $ */ - -#include <config.h> - -#include <isc/mem.h> -#include <isc/socket.h> -#include <isc/string.h> /* Required for HP/UX (and others?) */ -#include <isc/util.h> - -#include <dns/db.h> -#include <dns/lookup.h> -#include <dns/rdata.h> -#include <dns/rdataset.h> -#include <dns/rdatasetiter.h> -#include <dns/result.h> -#include <dns/view.h> - -#include <named/types.h> -#include <named/lwdclient.h> -#include <named/lwresd.h> -#include <named/lwsearch.h> - -static void start_lookup(ns_lwdclient_t *); - -static isc_result_t -fill_array(int *pos, dns_rdataset_t *rdataset, - int size, unsigned char **rdatas, lwres_uint16_t *rdatalen) -{ - dns_rdata_t rdata; - isc_result_t result; - isc_region_t r; - - UNUSED(size); - - dns_rdata_init(&rdata); - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) - { - INSIST(*pos < size); - dns_rdataset_current(rdataset, &rdata); - dns_rdata_toregion(&rdata, &r); - rdatas[*pos] = r.base; - rdatalen[*pos] = r.length; - dns_rdata_reset(&rdata); - (*pos)++; - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - return (result); -} - -static isc_result_t -iterate_node(lwres_grbnresponse_t *grbn, dns_db_t *db, dns_dbnode_t *node, - isc_mem_t *mctx) -{ - int used = 0, count; - int size = 8, oldsize = 0; - unsigned char **rdatas = NULL, **oldrdatas = NULL, **newrdatas = NULL; - lwres_uint16_t *lens = NULL, *oldlens = NULL, *newlens = NULL; - dns_rdatasetiter_t *iter = NULL; - dns_rdataset_t set; - dns_ttl_t ttl = ISC_INT32_MAX; - lwres_uint32_t flags = LWRDATA_VALIDATED; - isc_result_t result = ISC_R_NOMEMORY; - - result = dns_db_allrdatasets(db, node, NULL, 0, &iter); - if (result != ISC_R_SUCCESS) - goto out; - - rdatas = isc_mem_get(mctx, size * sizeof(*rdatas)); - if (rdatas == NULL) - goto out; - lens = isc_mem_get(mctx, size * sizeof(*lens)); - if (lens == NULL) - goto out; - - for (result = dns_rdatasetiter_first(iter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(iter)) - { - result = ISC_R_NOMEMORY; - dns_rdataset_init(&set); - dns_rdatasetiter_current(iter, &set); - - if (set.type != dns_rdatatype_rrsig) { - dns_rdataset_disassociate(&set); - continue; - } - - count = dns_rdataset_count(&set); - if (used + count > size) { - /* copy & reallocate */ - oldsize = size; - oldrdatas = rdatas; - oldlens = lens; - rdatas = NULL; - lens = NULL; - - size *= 2; - - rdatas = isc_mem_get(mctx, size * sizeof(*rdatas)); - if (rdatas == NULL) - goto out; - lens = isc_mem_get(mctx, size * sizeof(*lens)); - if (lens == NULL) - goto out; - memcpy(rdatas, oldrdatas, used * sizeof(*rdatas)); - memcpy(lens, oldlens, used * sizeof(*lens)); - isc_mem_put(mctx, oldrdatas, - oldsize * sizeof(*oldrdatas)); - isc_mem_put(mctx, oldlens, oldsize * sizeof(*oldlens)); - oldrdatas = NULL; - oldlens = NULL; - } - if (set.ttl < ttl) - ttl = set.ttl; - if (set.trust != dns_trust_secure) - flags &= (~LWRDATA_VALIDATED); - result = fill_array(&used, &set, size, rdatas, lens); - dns_rdataset_disassociate(&set); - if (result != ISC_R_SUCCESS) - goto out; - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - if (result != ISC_R_SUCCESS) - goto out; - dns_rdatasetiter_destroy(&iter); - - /* - * If necessary, shrink and copy the arrays. - */ - if (size != used) { - result = ISC_R_NOMEMORY; - newrdatas = isc_mem_get(mctx, used * sizeof(*rdatas)); - if (newrdatas == NULL) - goto out; - newlens = isc_mem_get(mctx, used * sizeof(*lens)); - if (newlens == NULL) - goto out; - memcpy(newrdatas, rdatas, used * sizeof(*rdatas)); - memcpy(newlens, lens, used * sizeof(*lens)); - isc_mem_put(mctx, rdatas, size * sizeof(*rdatas)); - isc_mem_put(mctx, lens, size * sizeof(*lens)); - grbn->rdatas = newrdatas; - grbn->rdatalen = newlens; - } else { - grbn->rdatas = rdatas; - grbn->rdatalen = lens; - } - grbn->nrdatas = used; - grbn->ttl = ttl; - grbn->flags = flags; - return (ISC_R_SUCCESS); - - out: - dns_rdatasetiter_destroy(&iter); - if (rdatas != NULL) - isc_mem_put(mctx, rdatas, size * sizeof(*rdatas)); - if (lens != NULL) - isc_mem_put(mctx, lens, size * sizeof(*lens)); - if (oldrdatas != NULL) - isc_mem_put(mctx, oldrdatas, oldsize * sizeof(*oldrdatas)); - if (oldlens != NULL) - isc_mem_put(mctx, oldlens, oldsize * sizeof(*oldlens)); - if (newrdatas != NULL) - isc_mem_put(mctx, newrdatas, used * sizeof(*oldrdatas)); - if (newlens != NULL) - isc_mem_put(mctx, newlens, used * sizeof(*oldlens)); - return (result); -} - -static void -lookup_done(isc_task_t *task, isc_event_t *event) { - ns_lwdclient_t *client; - ns_lwdclientmgr_t *cm; - dns_lookupevent_t *levent; - lwres_buffer_t lwb; - dns_name_t *name; - dns_rdataset_t *rdataset; - dns_rdataset_t *sigrdataset; - isc_result_t result; - lwres_result_t lwresult; - isc_region_t r; - isc_buffer_t b; - lwres_grbnresponse_t *grbn; - int i; - - UNUSED(task); - - lwb.base = NULL; - client = event->ev_arg; - cm = client->clientmgr; - INSIST(client->lookup == (dns_lookup_t *)event->ev_sender); - - levent = (dns_lookupevent_t *)event; - grbn = &client->grbn; - - ns_lwdclient_log(50, "lookup event result = %s", - isc_result_totext(levent->result)); - - result = levent->result; - if (result != ISC_R_SUCCESS) { - dns_lookup_destroy(&client->lookup); - isc_event_free(&event); - levent = NULL; - - switch (result) { - case DNS_R_NXDOMAIN: - case DNS_R_NCACHENXDOMAIN: - result = ns_lwsearchctx_next(&client->searchctx); - if (result != ISC_R_SUCCESS) - lwresult = LWRES_R_NOTFOUND; - else { - start_lookup(client); - return; - } - break; - case DNS_R_NXRRSET: - case DNS_R_NCACHENXRRSET: - lwresult = LWRES_R_TYPENOTFOUND; - break; - default: - lwresult = LWRES_R_FAILURE; - } - ns_lwdclient_errorpktsend(client, lwresult); - return; - } - - name = levent->name; - b = client->recv_buffer; - - grbn->flags = 0; - - grbn->nrdatas = 0; - grbn->rdatas = NULL; - grbn->rdatalen = NULL; - - grbn->nsigs = 0; - grbn->sigs = NULL; - grbn->siglen = NULL; - - result = dns_name_totext(name, ISC_TRUE, &client->recv_buffer); - if (result != ISC_R_SUCCESS) - goto out; - grbn->realname = (char *)isc_buffer_used(&b); - grbn->realnamelen = isc_buffer_usedlength(&client->recv_buffer) - - isc_buffer_usedlength(&b); - ns_lwdclient_log(50, "found name '%.*s'", grbn->realnamelen, - grbn->realname); - - grbn->rdclass = cm->view->rdclass; - grbn->rdtype = client->rdtype; - - rdataset = levent->rdataset; - if (rdataset != NULL) { - /* The normal case */ - grbn->nrdatas = dns_rdataset_count(rdataset); - grbn->rdatas = isc_mem_get(cm->mctx, grbn->nrdatas * - sizeof(unsigned char *)); - if (grbn->rdatas == NULL) - goto out; - grbn->rdatalen = isc_mem_get(cm->mctx, grbn->nrdatas * - sizeof(lwres_uint16_t)); - if (grbn->rdatalen == NULL) - goto out; - - i = 0; - result = fill_array(&i, rdataset, grbn->nrdatas, grbn->rdatas, - grbn->rdatalen); - if (result != ISC_R_SUCCESS) - goto out; - INSIST(i == grbn->nrdatas); - grbn->ttl = rdataset->ttl; - if (rdataset->trust == dns_trust_secure) - grbn->flags |= LWRDATA_VALIDATED; - } else { - /* The SIG query case */ - result = iterate_node(grbn, levent->db, levent->node, - cm->mctx); - if (result != ISC_R_SUCCESS) - goto out; - } - ns_lwdclient_log(50, "filled in %d rdata%s", grbn->nrdatas, - (grbn->nrdatas == 1) ? "" : "s"); - - sigrdataset = levent->sigrdataset; - if (sigrdataset != NULL) { - grbn->nsigs = dns_rdataset_count(sigrdataset); - grbn->sigs = isc_mem_get(cm->mctx, grbn->nsigs * - sizeof(unsigned char *)); - if (grbn->sigs == NULL) - goto out; - grbn->siglen = isc_mem_get(cm->mctx, grbn->nsigs * - sizeof(lwres_uint16_t)); - if (grbn->siglen == NULL) - goto out; - - i = 0; - result = fill_array(&i, sigrdataset, grbn->nsigs, grbn->sigs, - grbn->siglen); - if (result != ISC_R_SUCCESS) - goto out; - INSIST(i == grbn->nsigs); - ns_lwdclient_log(50, "filled in %d signature%s", grbn->nsigs, - (grbn->nsigs == 1) ? "" : "s"); - } - - dns_lookup_destroy(&client->lookup); - isc_event_free(&event); - - /* - * Render the packet. - */ - client->pkt.recvlength = LWRES_RECVLENGTH; - client->pkt.authtype = 0; /* XXXMLG */ - client->pkt.authlength = 0; - client->pkt.result = LWRES_R_SUCCESS; - - lwresult = lwres_grbnresponse_render(cm->lwctx, - grbn, &client->pkt, &lwb); - if (lwresult != LWRES_R_SUCCESS) - goto out; - - isc_mem_put(cm->mctx, grbn->rdatas, - grbn->nrdatas * sizeof(unsigned char *)); - isc_mem_put(cm->mctx, grbn->rdatalen, - grbn->nrdatas * sizeof(lwres_uint16_t)); - - if (grbn->sigs != NULL) - isc_mem_put(cm->mctx, grbn->sigs, - grbn->nsigs * sizeof(unsigned char *)); - if (grbn->siglen != NULL) - isc_mem_put(cm->mctx, grbn->siglen, - grbn->nsigs * sizeof(lwres_uint16_t)); - - r.base = lwb.base; - r.length = lwb.used; - client->sendbuf = r.base; - client->sendlength = r.length; - result = ns_lwdclient_sendreply(client, &r); - if (result != ISC_R_SUCCESS) - goto out; - - NS_LWDCLIENT_SETSEND(client); - - return; - - out: - if (grbn->rdatas != NULL) - isc_mem_put(cm->mctx, grbn->rdatas, - grbn->nrdatas * sizeof(unsigned char *)); - if (grbn->rdatalen != NULL) - isc_mem_put(cm->mctx, grbn->rdatalen, - grbn->nrdatas * sizeof(lwres_uint16_t)); - - if (grbn->sigs != NULL) - isc_mem_put(cm->mctx, grbn->sigs, - grbn->nsigs * sizeof(unsigned char *)); - if (grbn->siglen != NULL) - isc_mem_put(cm->mctx, grbn->siglen, - grbn->nsigs * sizeof(lwres_uint16_t)); - - if (client->lookup != NULL) - dns_lookup_destroy(&client->lookup); - if (lwb.base != NULL) - lwres_context_freemem(cm->lwctx, lwb.base, lwb.length); - - if (event != NULL) - isc_event_free(&event); - - ns_lwdclient_log(50, "error constructing getrrsetbyname response"); - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} - -static void -start_lookup(ns_lwdclient_t *client) { - isc_result_t result; - ns_lwdclientmgr_t *cm; - dns_fixedname_t absname; - - cm = client->clientmgr; - - INSIST(client->lookup == NULL); - - dns_fixedname_init(&absname); - result = ns_lwsearchctx_current(&client->searchctx, - dns_fixedname_name(&absname)); - /* - * This will return failure if relative name + suffix is too long. - * In this case, just go on to the next entry in the search path. - */ - if (result != ISC_R_SUCCESS) - start_lookup(client); - - result = dns_lookup_create(cm->mctx, - dns_fixedname_name(&absname), - client->rdtype, cm->view, - client->options, cm->task, lookup_done, - client, &client->lookup); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); - return; - } -} - -static void -init_grbn(ns_lwdclient_t *client) { - client->grbn.rdclass = 0; - client->grbn.rdtype = 0; - client->grbn.ttl = 0; - client->grbn.nrdatas = 0; - client->grbn.realname = NULL; - client->grbn.realnamelen = 0; - client->grbn.rdatas = 0; - client->grbn.rdatalen = 0; - client->grbn.base = NULL; - client->grbn.baselen = 0; - isc_buffer_init(&client->recv_buffer, client->buffer, LWRES_RECVLENGTH); -} - -void -ns_lwdclient_processgrbn(ns_lwdclient_t *client, lwres_buffer_t *b) { - lwres_grbnrequest_t *req; - isc_result_t result; - ns_lwdclientmgr_t *cm; - isc_buffer_t namebuf; - - REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); - INSIST(client->byaddr == NULL); - - cm = client->clientmgr; - req = NULL; - - result = lwres_grbnrequest_parse(cm->lwctx, - b, &client->pkt, &req); - if (result != LWRES_R_SUCCESS) - goto out; - if (req->name == NULL) - goto out; - - client->options = 0; - if (req->rdclass != cm->view->rdclass) - goto out; - - if (req->rdclass == dns_rdataclass_any || - req->rdtype == dns_rdatatype_any) - goto out; - - client->rdtype = req->rdtype; - - isc_buffer_init(&namebuf, req->name, req->namelen); - isc_buffer_add(&namebuf, req->namelen); - - dns_fixedname_init(&client->query_name); - result = dns_name_fromtext(dns_fixedname_name(&client->query_name), - &namebuf, NULL, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) - goto out; - ns_lwsearchctx_init(&client->searchctx, - cm->listener->manager->search, - dns_fixedname_name(&client->query_name), - cm->listener->manager->ndots); - ns_lwsearchctx_first(&client->searchctx); - - ns_lwdclient_log(50, "client %p looking for type %d", - client, client->rdtype); - - /* - * We no longer need to keep this around. - */ - lwres_grbnrequest_free(cm->lwctx, &req); - - /* - * Initialize the real name and alias arrays in the reply we're - * going to build up. - */ - init_grbn(client); - - /* - * Start the find. - */ - start_lookup(client); - - return; - - /* - * We're screwed. Return an error packet to our caller. - */ - out: - if (req != NULL) - lwres_grbnrequest_free(cm->lwctx, &req); - - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} diff --git a/contrib/bind9/bin/named/lwdnoop.c b/contrib/bind9/bin/named/lwdnoop.c deleted file mode 100644 index 30d95ee8d8e2..000000000000 --- a/contrib/bind9/bin/named/lwdnoop.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: lwdnoop.c,v 1.6.208.1 2004/03/06 10:21:19 marka Exp $ */ - -#include <config.h> - -#include <isc/socket.h> -#include <isc/util.h> - -#include <named/types.h> -#include <named/lwdclient.h> - -void -ns_lwdclient_processnoop(ns_lwdclient_t *client, lwres_buffer_t *b) { - lwres_nooprequest_t *req; - lwres_noopresponse_t resp; - isc_result_t result; - lwres_result_t lwres; - isc_region_t r; - lwres_buffer_t lwb; - - REQUIRE(NS_LWDCLIENT_ISRECVDONE(client)); - INSIST(client->byaddr == NULL); - - req = NULL; - - result = lwres_nooprequest_parse(client->clientmgr->lwctx, - b, &client->pkt, &req); - if (result != LWRES_R_SUCCESS) - goto out; - - client->pkt.recvlength = LWRES_RECVLENGTH; - client->pkt.authtype = 0; /* XXXMLG */ - client->pkt.authlength = 0; - client->pkt.result = LWRES_R_SUCCESS; - - resp.datalength = req->datalength; - resp.data = req->data; - - lwres = lwres_noopresponse_render(client->clientmgr->lwctx, &resp, - &client->pkt, &lwb); - if (lwres != LWRES_R_SUCCESS) - goto out; - - r.base = lwb.base; - r.length = lwb.used; - client->sendbuf = r.base; - client->sendlength = r.length; - result = ns_lwdclient_sendreply(client, &r); - if (result != ISC_R_SUCCESS) - goto out; - - /* - * We can now destroy request. - */ - lwres_nooprequest_free(client->clientmgr->lwctx, &req); - - NS_LWDCLIENT_SETSEND(client); - - return; - - out: - if (req != NULL) - lwres_nooprequest_free(client->clientmgr->lwctx, &req); - - if (lwb.base != NULL) - lwres_context_freemem(client->clientmgr->lwctx, - lwb.base, lwb.length); - - ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE); -} diff --git a/contrib/bind9/bin/named/lwresd.8 b/contrib/bind9/bin/named/lwresd.8 deleted file mode 100644 index 58f24b062374..000000000000 --- a/contrib/bind9/bin/named/lwresd.8 +++ /dev/null @@ -1,140 +0,0 @@ -.\" Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") -.\" Copyright (C) 2000, 2001 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 ISC DISCLAIMS ALL WARRANTIES WITH -.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, -.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -.\" PERFORMANCE OF THIS SOFTWARE. -.\" -.\" $Id: lwresd.8,v 1.13.208.5 2005/10/13 02:33:47 marka Exp $ -.\" -.hy 0 -.ad l -.\" ** You probably do not want to edit this file directly ** -.\" It was generated using the DocBook XSL Stylesheets (version 1.69.1). -.\" Instead of manually editing it, you probably should edit the DocBook XML -.\" source for it and then use the DocBook XSL Stylesheets to regenerate it. -.TH "LWRESD" "8" "June 30, 2000" "BIND9" "BIND9" -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.SH "NAME" -lwresd \- lightweight resolver daemon -.SH "SYNOPSIS" -.HP 7 -\fBlwresd\fR [\fB\-C\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-d\ \fR\fB\fIdebug\-level\fR\fR] [\fB\-f\fR] [\fB\-g\fR] [\fB\-i\ \fR\fB\fIpid\-file\fR\fR] [\fB\-n\ \fR\fB\fI#cpus\fR\fR] [\fB\-P\ \fR\fB\fIport\fR\fR] [\fB\-p\ \fR\fB\fIport\fR\fR] [\fB\-s\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] -.SH "DESCRIPTION" -.PP -\fBlwresd\fR -is the daemon providing name lookup services to clients that use the BIND 9 lightweight resolver library. It is essentially a stripped\-down, caching\-only name server that answers queries using the BIND 9 lightweight resolver protocol rather than the DNS protocol. -.PP -\fBlwresd\fR -listens for resolver queries on a UDP port on the IPv4 loopback interface, 127.0.0.1. This means that -\fBlwresd\fR -can only be used by processes running on the local machine. By default UDP port number 921 is used for lightweight resolver requests and responses. -.PP -Incoming lightweight resolver requests are decoded by the server which then resolves them using the DNS protocol. When the DNS lookup completes, -\fBlwresd\fR -encodes the answers in the lightweight resolver format and returns them to the client that made the request. -.PP -If -\fI/etc/resolv.conf\fR -contains any -\fBnameserver\fR -entries, -\fBlwresd\fR -sends recursive DNS queries to those servers. This is similar to the use of forwarders in a caching name server. If no -\fBnameserver\fR -entries are present, or if forwarding fails, -\fBlwresd\fR -resolves the queries autonomously starting at the root name servers, using a built\-in list of root server hints. -.SH "OPTIONS" -.TP -\-C \fIconfig\-file\fR -Use -\fIconfig\-file\fR -as the configuration file instead of the default, -\fI/etc/resolv.conf\fR. -.TP -\-d \fIdebug\-level\fR -Set the daemon's debug level to -\fIdebug\-level\fR. Debugging traces from -\fBlwresd\fR -become more verbose as the debug level increases. -.TP -\-f -Run the server in the foreground (i.e. do not daemonize). -.TP -\-g -Run the server in the foreground and force all logging to -\fIstderr\fR. -.TP -\-n \fI#cpus\fR -Create -\fI#cpus\fR -worker threads to take advantage of multiple CPUs. If not specified, -\fBlwresd\fR -will try to determine the number of CPUs present and create one thread per CPU. If it is unable to determine the number of CPUs, a single worker thread will be created. -.TP -\-P \fIport\fR -Listen for lightweight resolver queries on port -\fIport\fR. If not specified, the default is port 921. -.TP -\-p \fIport\fR -Send DNS lookups to port -\fIport\fR. If not specified, the default is port 53. This provides a way of testing the lightweight resolver daemon with a name server that listens for queries on a non\-standard port number. -.TP -\-s -Write memory usage statistics to -\fIstdout\fR -on exit. -.RS -.B "Note:" -This option is mainly of interest to BIND 9 developers and may be removed or changed in a future release. -.RE -.TP -\-t \fIdirectory\fR -\fBchroot()\fR -to -\fIdirectory\fR -after processing the command line arguments, but before reading the configuration file. -.RS -.B "Warning:" -This option should be used in conjunction with the -\fB\-u\fR -option, as chrooting a process running as root doesn't enhance security on most systems; the way -\fBchroot()\fR -is defined allows a process with root privileges to escape a chroot jail. -.RE -.TP -\-u \fIuser\fR -\fBsetuid()\fR -to -\fIuser\fR -after completing privileged operations, such as creating sockets that listen on privileged ports. -.TP -\-v -Report the version number and exit. -.SH "FILES" -.TP -\fI/etc/resolv.conf\fR -The default configuration file. -.TP -\fI/var/run/lwresd.pid\fR -The default process\-id file. -.SH "SEE ALSO" -.PP -\fBnamed\fR(8), -\fBlwres\fR(3), -\fBresolver\fR(5). -.SH "AUTHOR" -.PP -Internet Systems Consortium diff --git a/contrib/bind9/bin/named/lwresd.c b/contrib/bind9/bin/named/lwresd.c deleted file mode 100644 index 9da41681a533..000000000000 --- a/contrib/bind9/bin/named/lwresd.c +++ /dev/null @@ -1,861 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000-2003 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: lwresd.c,v 1.37.2.2.2.5 2004/03/08 04:04:19 marka Exp $ */ - -/* - * Main program for the Lightweight Resolver Daemon. - * - * To paraphrase the old saying about X11, "It's not a lightweight deamon - * for resolvers, it's a deamon for lightweight resolvers". - */ - -#include <config.h> - -#include <stdlib.h> -#include <string.h> - -#include <isc/list.h> -#include <isc/magic.h> -#include <isc/mem.h> -#include <isc/once.h> -#include <isc/print.h> -#include <isc/socket.h> -#include <isc/task.h> -#include <isc/util.h> - -#include <isccfg/namedconf.h> - -#include <dns/log.h> -#include <dns/result.h> -#include <dns/view.h> - -#include <named/config.h> -#include <named/globals.h> -#include <named/log.h> -#include <named/lwaddr.h> -#include <named/lwresd.h> -#include <named/lwdclient.h> -#include <named/lwsearch.h> -#include <named/server.h> - -#define LWRESD_MAGIC ISC_MAGIC('L', 'W', 'R', 'D') -#define VALID_LWRESD(l) ISC_MAGIC_VALID(l, LWRESD_MAGIC) - -#define LWRESLISTENER_MAGIC ISC_MAGIC('L', 'W', 'R', 'L') -#define VALID_LWRESLISTENER(l) ISC_MAGIC_VALID(l, LWRESLISTENER_MAGIC) - -/* - * The total number of clients we can handle will be NTASKS * NRECVS. - */ -#define NTASKS 2 /* tasks to create to handle lwres queries */ -#define NRECVS 2 /* max clients per task */ - -typedef ISC_LIST(ns_lwreslistener_t) ns_lwreslistenerlist_t; - -static ns_lwreslistenerlist_t listeners; -static isc_mutex_t listeners_lock; -static isc_once_t once = ISC_ONCE_INIT; - - -static void -initialize_mutex(void) { - RUNTIME_CHECK(isc_mutex_init(&listeners_lock) == ISC_R_SUCCESS); -} - - -/* - * Wrappers around our memory management stuff, for the lwres functions. - */ -void * -ns__lwresd_memalloc(void *arg, size_t size) { - return (isc_mem_get(arg, size)); -} - -void -ns__lwresd_memfree(void *arg, void *mem, size_t size) { - isc_mem_put(arg, mem, size); -} - - -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto cleanup; \ - } while (0) - -static isc_result_t -buffer_putstr(isc_buffer_t *b, const char *s) { - unsigned int len = strlen(s); - if (isc_buffer_availablelength(b) <= len) - return (ISC_R_NOSPACE); - isc_buffer_putmem(b, (const unsigned char *)s, len); - return (ISC_R_SUCCESS); -} - -/* - * Convert a resolv.conf file into a config structure. - */ -isc_result_t -ns_lwresd_parseeresolvconf(isc_mem_t *mctx, cfg_parser_t *pctx, - cfg_obj_t **configp) -{ - char text[4096]; - char str[16]; - isc_buffer_t b; - lwres_context_t *lwctx = NULL; - lwres_conf_t *lwc = NULL; - isc_sockaddr_t sa; - isc_netaddr_t na; - int i; - isc_result_t result; - lwres_result_t lwresult; - - lwctx = NULL; - lwresult = lwres_context_create(&lwctx, mctx, ns__lwresd_memalloc, - ns__lwresd_memfree, - LWRES_CONTEXT_SERVERMODE); - if (lwresult != LWRES_R_SUCCESS) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - - lwresult = lwres_conf_parse(lwctx, lwresd_g_resolvconffile); - if (lwresult != LWRES_R_SUCCESS) { - result = DNS_R_SYNTAX; - goto cleanup; - } - - lwc = lwres_conf_get(lwctx); - INSIST(lwc != NULL); - - isc_buffer_init(&b, text, sizeof(text)); - - CHECK(buffer_putstr(&b, "options {\n")); - - /* - * Build the list of forwarders. - */ - if (lwc->nsnext > 0) { - CHECK(buffer_putstr(&b, "\tforwarders {\n")); - - for (i = 0; i < lwc->nsnext; i++) { - CHECK(lwaddr_sockaddr_fromlwresaddr( - &sa, - &lwc->nameservers[i], - ns_g_port)); - isc_netaddr_fromsockaddr(&na, &sa); - CHECK(buffer_putstr(&b, "\t\t")); - CHECK(isc_netaddr_totext(&na, &b)); - CHECK(buffer_putstr(&b, ";\n")); - } - CHECK(buffer_putstr(&b, "\t};\n")); - } - - /* - * Build the sortlist - */ - if (lwc->sortlistnxt > 0) { - CHECK(buffer_putstr(&b, "\tsortlist {\n")); - CHECK(buffer_putstr(&b, "\t\t{\n")); - CHECK(buffer_putstr(&b, "\t\t\tany;\n")); - CHECK(buffer_putstr(&b, "\t\t\t{\n")); - for (i = 0; i < lwc->sortlistnxt; i++) { - lwres_addr_t *lwaddr = &lwc->sortlist[i].addr; - lwres_addr_t *lwmask = &lwc->sortlist[i].mask; - unsigned int mask; - - CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, lwmask, 0)); - isc_netaddr_fromsockaddr(&na, &sa); - result = isc_netaddr_masktoprefixlen(&na, &mask); - if (result != ISC_R_SUCCESS) { - char addrtext[ISC_NETADDR_FORMATSIZE]; - isc_netaddr_format(&na, addrtext, - sizeof(addrtext)); - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, - ISC_LOG_ERROR, - "processing sortlist: '%s' is " - "not a valid netmask", - addrtext); - goto cleanup; - } - - CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, lwaddr, 0)); - isc_netaddr_fromsockaddr(&na, &sa); - - CHECK(buffer_putstr(&b, "\t\t\t\t")); - CHECK(isc_netaddr_totext(&na, &b)); - snprintf(str, sizeof(str), "%u", mask); - CHECK(buffer_putstr(&b, "/")); - CHECK(buffer_putstr(&b, str)); - CHECK(buffer_putstr(&b, ";\n")); - } - CHECK(buffer_putstr(&b, "\t\t\t};\n")); - CHECK(buffer_putstr(&b, "\t\t};\n")); - CHECK(buffer_putstr(&b, "\t};\n")); - } - - CHECK(buffer_putstr(&b, "};\n\n")); - - CHECK(buffer_putstr(&b, "lwres {\n")); - - /* - * Build the search path - */ - if (lwc->searchnxt > 0) { - if (lwc->searchnxt > 0) { - CHECK(buffer_putstr(&b, "\tsearch {\n")); - for (i = 0; i < lwc->searchnxt; i++) { - CHECK(buffer_putstr(&b, "\t\t\"")); - CHECK(buffer_putstr(&b, lwc->search[i])); - CHECK(buffer_putstr(&b, "\";\n")); - } - CHECK(buffer_putstr(&b, "\t};\n")); - } - } - - /* - * Build the ndots line - */ - if (lwc->ndots != 1) { - CHECK(buffer_putstr(&b, "\tndots ")); - snprintf(str, sizeof(str), "%u", lwc->ndots); - CHECK(buffer_putstr(&b, str)); - CHECK(buffer_putstr(&b, ";\n")); - } - - /* - * Build the listen-on line - */ - if (lwc->lwnext > 0) { - CHECK(buffer_putstr(&b, "\tlisten-on {\n")); - - for (i = 0; i < lwc->lwnext; i++) { - CHECK(lwaddr_sockaddr_fromlwresaddr(&sa, - &lwc->lwservers[i], - 0)); - isc_netaddr_fromsockaddr(&na, &sa); - CHECK(buffer_putstr(&b, "\t\t")); - CHECK(isc_netaddr_totext(&na, &b)); - CHECK(buffer_putstr(&b, ";\n")); - } - CHECK(buffer_putstr(&b, "\t};\n")); - } - - CHECK(buffer_putstr(&b, "};\n")); - -#if 0 - printf("%.*s\n", - (int)isc_buffer_usedlength(&b), - (char *)isc_buffer_base(&b)); -#endif - - lwres_conf_clear(lwctx); - lwres_context_destroy(&lwctx); - - return (cfg_parse_buffer(pctx, &b, &cfg_type_namedconf, configp)); - - cleanup: - - if (lwctx != NULL) { - lwres_conf_clear(lwctx); - lwres_context_destroy(&lwctx); - } - - return (result); -} - - -/* - * Handle lwresd manager objects - */ -isc_result_t -ns_lwdmanager_create(isc_mem_t *mctx, cfg_obj_t *lwres, - ns_lwresd_t **lwresdp) -{ - ns_lwresd_t *lwresd; - const char *vname; - dns_rdataclass_t vclass; - cfg_obj_t *obj, *viewobj, *searchobj; - cfg_listelt_t *element; - isc_result_t result; - - INSIST(lwresdp != NULL && *lwresdp == NULL); - - lwresd = isc_mem_get(mctx, sizeof(ns_lwresd_t)); - if (lwresd == NULL) - return (ISC_R_NOMEMORY); - - lwresd->mctx = NULL; - isc_mem_attach(mctx, &lwresd->mctx); - lwresd->view = NULL; - lwresd->search = NULL; - lwresd->refs = 1; - - obj = NULL; - (void)cfg_map_get(lwres, "ndots", &obj); - if (obj != NULL) - lwresd->ndots = cfg_obj_asuint32(obj); - else - lwresd->ndots = 1; - - RUNTIME_CHECK(isc_mutex_init(&lwresd->lock) == ISC_R_SUCCESS); - - lwresd->shutting_down = ISC_FALSE; - - viewobj = NULL; - (void)cfg_map_get(lwres, "view", &viewobj); - if (viewobj != NULL) { - vname = cfg_obj_asstring(cfg_tuple_get(viewobj, "name")); - obj = cfg_tuple_get(viewobj, "class"); - result = ns_config_getclass(obj, dns_rdataclass_in, &vclass); - if (result != ISC_R_SUCCESS) - goto fail; - } else { - vname = "_default"; - vclass = dns_rdataclass_in; - } - - result = dns_viewlist_find(&ns_g_server->viewlist, vname, vclass, - &lwresd->view); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "couldn't find view %s", vname); - goto fail; - } - - searchobj = NULL; - (void)cfg_map_get(lwres, "search", &searchobj); - if (searchobj != NULL) { - lwresd->search = NULL; - result = ns_lwsearchlist_create(lwresd->mctx, - &lwresd->search); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "couldn't create searchlist"); - goto fail; - } - for (element = cfg_list_first(searchobj); - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *search; - char *searchstr; - isc_buffer_t namebuf; - dns_fixedname_t fname; - dns_name_t *name; - - search = cfg_listelt_value(element); - searchstr = cfg_obj_asstring(search); - - dns_fixedname_init(&fname); - name = dns_fixedname_name(&fname); - isc_buffer_init(&namebuf, searchstr, - strlen(searchstr)); - isc_buffer_add(&namebuf, strlen(searchstr)); - result = dns_name_fromtext(name, &namebuf, - dns_rootname, ISC_FALSE, - NULL); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, - ISC_LOG_WARNING, - "invalid name %s in searchlist", - searchstr); - continue; - } - - result = ns_lwsearchlist_append(lwresd->search, name); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, - ISC_LOG_WARNING, - "couldn't update searchlist"); - goto fail; - } - } - } - - lwresd->magic = LWRESD_MAGIC; - - *lwresdp = lwresd; - return (ISC_R_SUCCESS); - - fail: - if (lwresd->view != NULL) - dns_view_detach(&lwresd->view); - if (lwresd->search != NULL) - ns_lwsearchlist_detach(&lwresd->search); - if (lwresd->mctx != NULL) - isc_mem_detach(&lwresd->mctx); - return (result); -} - -void -ns_lwdmanager_attach(ns_lwresd_t *source, ns_lwresd_t **targetp) { - INSIST(VALID_LWRESD(source)); - INSIST(targetp != NULL && *targetp == NULL); - - LOCK(&source->lock); - source->refs++; - UNLOCK(&source->lock); - - *targetp = source; -} - -void -ns_lwdmanager_detach(ns_lwresd_t **lwresdp) { - ns_lwresd_t *lwresd; - isc_mem_t *mctx; - isc_boolean_t done = ISC_FALSE; - - INSIST(lwresdp != NULL && *lwresdp != NULL); - INSIST(VALID_LWRESD(*lwresdp)); - - lwresd = *lwresdp; - *lwresdp = NULL; - - LOCK(&lwresd->lock); - INSIST(lwresd->refs > 0); - lwresd->refs--; - if (lwresd->refs == 0) - done = ISC_TRUE; - UNLOCK(&lwresd->lock); - - if (!done) - return; - - dns_view_detach(&lwresd->view); - if (lwresd->search != NULL) - ns_lwsearchlist_detach(&lwresd->search); - mctx = lwresd->mctx; - lwresd->magic = 0; - isc_mem_put(mctx, lwresd, sizeof(*lwresd)); - isc_mem_detach(&mctx); -} - - -/* - * Handle listener objects - */ -void -ns_lwreslistener_attach(ns_lwreslistener_t *source, - ns_lwreslistener_t **targetp) -{ - INSIST(VALID_LWRESLISTENER(source)); - INSIST(targetp != NULL && *targetp == NULL); - - LOCK(&source->lock); - source->refs++; - UNLOCK(&source->lock); - - *targetp = source; -} - -void -ns_lwreslistener_detach(ns_lwreslistener_t **listenerp) { - ns_lwreslistener_t *listener; - isc_mem_t *mctx; - isc_boolean_t done = ISC_FALSE; - - INSIST(listenerp != NULL && *listenerp != NULL); - INSIST(VALID_LWRESLISTENER(*listenerp)); - - listener = *listenerp; - - LOCK(&listener->lock); - INSIST(listener->refs > 0); - listener->refs--; - if (listener->refs == 0) - done = ISC_TRUE; - UNLOCK(&listener->lock); - - if (!done) - return; - - if (listener->manager != NULL) - ns_lwdmanager_detach(&listener->manager); - - if (listener->sock != NULL) - isc_socket_detach(&listener->sock); - - listener->magic = 0; - mctx = listener->mctx; - isc_mem_put(mctx, listener, sizeof(*listener)); - isc_mem_detach(&mctx); - listenerp = NULL; -} - -static isc_result_t -listener_create(isc_mem_t *mctx, ns_lwresd_t *lwresd, - ns_lwreslistener_t **listenerp) -{ - ns_lwreslistener_t *listener; - - REQUIRE(listenerp != NULL && *listenerp == NULL); - - listener = isc_mem_get(mctx, sizeof(ns_lwreslistener_t)); - if (listener == NULL) - return (ISC_R_NOMEMORY); - RUNTIME_CHECK(isc_mutex_init(&listener->lock) == ISC_R_SUCCESS); - - listener->magic = LWRESLISTENER_MAGIC; - listener->refs = 1; - - listener->sock = NULL; - - listener->manager = NULL; - ns_lwdmanager_attach(lwresd, &listener->manager); - - listener->mctx = NULL; - isc_mem_attach(mctx, &listener->mctx); - - ISC_LINK_INIT(listener, link); - ISC_LIST_INIT(listener->cmgrs); - - *listenerp = listener; - return (ISC_R_SUCCESS); -} - -static isc_result_t -listener_bind(ns_lwreslistener_t *listener, isc_sockaddr_t *address) { - isc_socket_t *sock = NULL; - isc_result_t result = ISC_R_SUCCESS; - int pf; - - pf = isc_sockaddr_pf(address); - if ((pf == AF_INET && isc_net_probeipv4() != ISC_R_SUCCESS) || - (pf == AF_INET6 && isc_net_probeipv6() != ISC_R_SUCCESS)) - return (ISC_R_FAMILYNOSUPPORT); - - listener->address = *address; - - if (isc_sockaddr_getport(&listener->address) == 0) { - in_port_t port; - port = lwresd_g_listenport; - if (port == 0) - port = LWRES_UDP_PORT; - isc_sockaddr_setport(&listener->address, port); - } - - sock = NULL; - result = isc_socket_create(ns_g_socketmgr, pf, - isc_sockettype_udp, &sock); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "failed to create lwres socket: %s", - isc_result_totext(result)); - return (result); - } - - result = isc_socket_bind(sock, &listener->address); - if (result != ISC_R_SUCCESS) { - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format(&listener->address, socktext, - sizeof(socktext)); - isc_socket_detach(&sock); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "failed to add lwres socket: %s: %s", - socktext, isc_result_totext(result)); - return (result); - } - listener->sock = sock; - return (ISC_R_SUCCESS); -} - -static void -listener_copysock(ns_lwreslistener_t *oldlistener, - ns_lwreslistener_t *newlistener) -{ - newlistener->address = oldlistener->address; - isc_socket_attach(oldlistener->sock, &newlistener->sock); -} - -static isc_result_t -listener_startclients(ns_lwreslistener_t *listener) { - ns_lwdclientmgr_t *cm; - unsigned int i; - isc_result_t result; - - /* - * Create the client managers. - */ - result = ISC_R_SUCCESS; - for (i = 0; i < NTASKS && result == ISC_R_SUCCESS; i++) - result = ns_lwdclientmgr_create(listener, NRECVS, - ns_g_taskmgr); - - /* - * Ensure that we have created at least one. - */ - if (ISC_LIST_EMPTY(listener->cmgrs)) - return (result); - - /* - * Walk the list of clients and start each one up. - */ - LOCK(&listener->lock); - cm = ISC_LIST_HEAD(listener->cmgrs); - while (cm != NULL) { - result = ns_lwdclient_startrecv(cm); - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_ERROR, - "could not start lwres " - "client handler: %s", - isc_result_totext(result)); - cm = ISC_LIST_NEXT(cm, link); - } - UNLOCK(&listener->lock); - - return (ISC_R_SUCCESS); -} - -static void -listener_shutdown(ns_lwreslistener_t *listener) { - ns_lwdclientmgr_t *cm; - - cm = ISC_LIST_HEAD(listener->cmgrs); - while (cm != NULL) { - isc_task_shutdown(cm->task); - cm = ISC_LIST_NEXT(cm, link); - } -} - -static isc_result_t -find_listener(isc_sockaddr_t *address, ns_lwreslistener_t **listenerp) { - ns_lwreslistener_t *listener; - - INSIST(listenerp != NULL && *listenerp == NULL); - - for (listener = ISC_LIST_HEAD(listeners); - listener != NULL; - listener = ISC_LIST_NEXT(listener, link)) - { - if (!isc_sockaddr_equal(address, &listener->address)) - continue; - *listenerp = listener; - return (ISC_R_SUCCESS); - } - return (ISC_R_NOTFOUND); -} - -void -ns_lwreslistener_unlinkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm) -{ - REQUIRE(VALID_LWRESLISTENER(listener)); - - LOCK(&listener->lock); - ISC_LIST_UNLINK(listener->cmgrs, cm, link); - UNLOCK(&listener->lock); -} - -void -ns_lwreslistener_linkcm(ns_lwreslistener_t *listener, ns_lwdclientmgr_t *cm) { - REQUIRE(VALID_LWRESLISTENER(listener)); - - /* - * This does no locking, since it's called early enough that locking - * isn't needed. - */ - ISC_LIST_APPEND(listener->cmgrs, cm, link); -} - -static isc_result_t -configure_listener(isc_sockaddr_t *address, ns_lwresd_t *lwresd, - isc_mem_t *mctx, ns_lwreslistenerlist_t *newlisteners) -{ - ns_lwreslistener_t *listener, *oldlistener = NULL; - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_result_t result; - - (void)find_listener(address, &oldlistener); - listener = NULL; - result = listener_create(mctx, lwresd, &listener); - if (result != ISC_R_SUCCESS) { - isc_sockaddr_format(address, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "lwres failed to configure %s: %s", - socktext, isc_result_totext(result)); - return (result); - } - - /* - * If there's already a listener, don't rebind the socket. - */ - if (oldlistener == NULL) { - result = listener_bind(listener, address); - if (result != ISC_R_SUCCESS) { - ns_lwreslistener_detach(&listener); - return (ISC_R_SUCCESS); - } - } else - listener_copysock(oldlistener, listener); - - result = listener_startclients(listener); - if (result != ISC_R_SUCCESS) { - isc_sockaddr_format(address, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_WARNING, - "lwres: failed to start %s: %s", socktext, - isc_result_totext(result)); - ns_lwreslistener_detach(&listener); - return (ISC_R_SUCCESS); - } - - if (oldlistener != NULL) { - /* - * Remove the old listener from the old list and shut it down. - */ - ISC_LIST_UNLINK(listeners, oldlistener, link); - listener_shutdown(oldlistener); - ns_lwreslistener_detach(&oldlistener); - } else { - isc_sockaddr_format(address, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_NOTICE, - "lwres listening on %s", socktext); - } - - ISC_LIST_APPEND(*newlisteners, listener, link); - return (result); -} - -isc_result_t -ns_lwresd_configure(isc_mem_t *mctx, cfg_obj_t *config) { - cfg_obj_t *lwreslist = NULL; - cfg_obj_t *lwres = NULL; - cfg_obj_t *listenerslist = NULL; - cfg_listelt_t *element = NULL; - ns_lwreslistener_t *listener; - ns_lwreslistenerlist_t newlisteners; - isc_result_t result; - char socktext[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_t *addrs = NULL; - ns_lwresd_t *lwresd = NULL; - isc_uint32_t count = 0; - - REQUIRE(mctx != NULL); - REQUIRE(config != NULL); - - RUNTIME_CHECK(isc_once_do(&once, initialize_mutex) == ISC_R_SUCCESS); - - ISC_LIST_INIT(newlisteners); - - result = cfg_map_get(config, "lwres", &lwreslist); - if (result != ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - LOCK(&listeners_lock); - /* - * Run through the new lwres address list, noting sockets that - * are already being listened on and moving them to the new list. - * - * Identifying duplicates addr/port combinations is left to either - * the underlying config code, or to the bind attempt getting an - * address-in-use error. - */ - for (element = cfg_list_first(lwreslist); - element != NULL; - element = cfg_list_next(element)) - { - in_port_t port; - - lwres = cfg_listelt_value(element); - CHECK(ns_lwdmanager_create(mctx, lwres, &lwresd)); - - port = lwresd_g_listenport; - if (port == 0) - port = LWRES_UDP_PORT; - - listenerslist = NULL; - (void)cfg_map_get(lwres, "listen-on", &listenerslist); - if (listenerslist == NULL) { - struct in_addr localhost; - isc_sockaddr_t address; - - localhost.s_addr = htonl(INADDR_LOOPBACK); - isc_sockaddr_fromin(&address, &localhost, port); - CHECK(configure_listener(&address, lwresd, mctx, - &newlisteners)); - } else { - isc_uint32_t i; - - CHECK(ns_config_getiplist(config, listenerslist, - port, mctx, &addrs, &count)); - for (i = 0; i < count; i++) - CHECK(configure_listener(&addrs[i], lwresd, - mctx, &newlisteners)); - ns_config_putiplist(mctx, &addrs, count); - } - ns_lwdmanager_detach(&lwresd); - } - - /* - * Shutdown everything on the listeners list, and remove them from - * the list. Then put all of the new listeners on it. - */ - - while (!ISC_LIST_EMPTY(listeners)) { - listener = ISC_LIST_HEAD(listeners); - ISC_LIST_UNLINK(listeners, listener, link); - - isc_sockaddr_format(&listener->address, - socktext, sizeof(socktext)); - - listener_shutdown(listener); - ns_lwreslistener_detach(&listener); - - isc_log_write(ns_g_lctx, ISC_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_NOTICE, - "lwres no longer listening on %s", socktext); - } - - cleanup: - ISC_LIST_APPENDLIST(listeners, newlisteners, link); - - if (addrs != NULL) - ns_config_putiplist(mctx, &addrs, count); - - if (lwresd != NULL) - ns_lwdmanager_detach(&lwresd); - - UNLOCK(&listeners_lock); - - return (result); -} - -void -ns_lwresd_shutdown(void) { - ns_lwreslistener_t *listener; - - RUNTIME_CHECK(isc_once_do(&once, initialize_mutex) == ISC_R_SUCCESS); - - while (!ISC_LIST_EMPTY(listeners)) { - listener = ISC_LIST_HEAD(listeners); - ISC_LIST_UNLINK(listeners, listener, link); - ns_lwreslistener_detach(&listener); - } -} diff --git a/contrib/bind9/bin/named/lwresd.docbook b/contrib/bind9/bin/named/lwresd.docbook deleted file mode 100644 index c1f500bb8300..000000000000 --- a/contrib/bind9/bin/named/lwresd.docbook +++ /dev/null @@ -1,315 +0,0 @@ -<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.0//EN" - "http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd" - [<!ENTITY mdash "—">]> -<!-- - - Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - - Copyright (C) 2000, 2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - - PERFORMANCE OF THIS SOFTWARE. ---> - -<!-- $Id: lwresd.docbook,v 1.6.208.4 2005/05/13 01:22:33 marka Exp $ --> - -<refentry> - <refentryinfo> - <date>June 30, 2000</date> - </refentryinfo> - - <refmeta> - <refentrytitle><application>lwresd</application></refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo>BIND9</refmiscinfo> - </refmeta> - - <docinfo> - <copyright> - <year>2004</year> - <year>2005</year> - <holder>Internet Systems Consortium, Inc. ("ISC")</holder> - </copyright> - <copyright> - <year>2000</year> - <year>2001</year> - <holder>Internet Software Consortium.</holder> - </copyright> - </docinfo> - - <refnamediv> - <refname><application>lwresd</application></refname> - <refpurpose>lightweight resolver daemon</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis> - <command>lwresd</command> - <arg><option>-C <replaceable class="parameter">config-file</replaceable></option></arg> - <arg><option>-d <replaceable class="parameter">debug-level</replaceable></option></arg> - <arg><option>-f</option></arg> - <arg><option>-g</option></arg> - <arg><option>-i <replaceable class="parameter">pid-file</replaceable></option></arg> - <arg><option>-n <replaceable class="parameter">#cpus</replaceable></option></arg> - <arg><option>-P <replaceable class="parameter">port</replaceable></option></arg> - <arg><option>-p <replaceable class="parameter">port</replaceable></option></arg> - <arg><option>-s</option></arg> - <arg><option>-t <replaceable class="parameter">directory</replaceable></option></arg> - <arg><option>-u <replaceable class="parameter">user</replaceable></option></arg> - <arg><option>-v</option></arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1> - <title>DESCRIPTION</title> - <para> - <command>lwresd</command> is the daemon providing name lookup - services to clients that use the BIND 9 lightweight resolver - library. It is essentially a stripped-down, caching-only name - server that answers queries using the BIND 9 lightweight - resolver protocol rather than the DNS protocol. - </para> - <para> - <command>lwresd</command> listens for resolver queries on a - UDP port on the IPv4 loopback interface, 127.0.0.1. This - means that <command>lwresd</command> can only be used by - processes running on the local machine. By default UDP port - number 921 is used for lightweight resolver requests and - responses. - </para> - <para> - Incoming lightweight resolver requests are decoded by the - server which then resolves them using the DNS protocol. When - the DNS lookup completes, <command>lwresd</command> encodes - the answers in the lightweight resolver format and returns - them to the client that made the request. - </para> - <para> - If <filename>/etc/resolv.conf</filename> contains any - <option>nameserver</option> entries, <command>lwresd</command> - sends recursive DNS queries to those servers. This is similar - to the use of forwarders in a caching name server. If no - <option>nameserver</option> entries are present, or if - forwarding fails, <command>lwresd</command> resolves the - queries autonomously starting at the root name servers, using - a built-in list of root server hints. - </para> - </refsect1> - - <refsect1> - <title>OPTIONS</title> - - <variablelist> - <varlistentry> - <term>-C <replaceable class="parameter">config-file</replaceable></term> - <listitem> - <para> - Use <replaceable - class="parameter">config-file</replaceable> as the - configuration file instead of the default, - <filename>/etc/resolv.conf</filename>. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>-d <replaceable class="parameter">debug-level</replaceable></term> - <listitem> - <para> - Set the daemon's debug level to <replaceable - class="parameter">debug-level</replaceable>. - Debugging traces from <command>lwresd</command> become - more verbose as the debug level increases. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>-f</term> - <listitem> - <para> - Run the server in the foreground (i.e. do not daemonize). - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>-g</term> - <listitem> - <para> - Run the server in the foreground and force all logging - to <filename>stderr</filename>. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>-n <replaceable class="parameter">#cpus</replaceable></term> - <listitem> - <para> - Create <replaceable - class="parameter">#cpus</replaceable> worker threads - to take advantage of multiple CPUs. If not specified, - <command>lwresd</command> will try to determine the - number of CPUs present and create one thread per CPU. - If it is unable to determine the number of CPUs, a - single worker thread will be created. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>-P <replaceable class="parameter">port</replaceable></term> - <listitem> - <para> - Listen for lightweight resolver queries on port - <replaceable class="parameter">port</replaceable>. If - not specified, the default is port 921. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>-p <replaceable class="parameter">port</replaceable></term> - <listitem> - <para> - Send DNS lookups to port <replaceable - class="parameter">port</replaceable>. If not - specified, the default is port 53. This provides a - way of testing the lightweight resolver daemon with a - name server that listens for queries on a non-standard - port number. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>-s</term> - <listitem> - <para> - Write memory usage statistics to <filename>stdout</filename> - on exit. - </para> - <note> - <para> - This option is mainly of interest to BIND 9 developers - and may be removed or changed in a future release. - </para> - </note> - </listitem> - </varlistentry> - - <varlistentry> - <term>-t <replaceable class="parameter">directory</replaceable></term> - <listitem> - <para> - <function>chroot()</function> to <replaceable - class="parameter">directory</replaceable> after - processing the command line arguments, but before - reading the configuration file. - </para> - <warning> - <para> - This option should be used in conjunction with the - <option>-u</option> option, as chrooting a process - running as root doesn't enhance security on most - systems; the way <function>chroot()</function> is - defined allows a process with root privileges to - escape a chroot jail. - </para> - </warning> - </listitem> - </varlistentry> - - <varlistentry> - <term>-u <replaceable class="parameter">user</replaceable></term> - <listitem> - <para> - <function>setuid()</function> to <replaceable - class="parameter">user</replaceable> after completing - privileged operations, such as creating sockets that - listen on privileged ports. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>-v</term> - <listitem> - <para> - Report the version number and exit. - </para> - </listitem> - </varlistentry> - - </variablelist> - - </refsect1> - - <refsect1> - <title>FILES</title> - - <variablelist> - - <varlistentry> - <term><filename>/etc/resolv.conf</filename></term> - <listitem> - <para> - The default configuration file. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term><filename>/var/run/lwresd.pid</filename></term> - <listitem> - <para> - The default process-id file. - </para> - </listitem> - </varlistentry> - - </variablelist> - - </refsect1> - - <refsect1> - <title>SEE ALSO</title> - <para> - <citerefentry> - <refentrytitle>named</refentrytitle> - <manvolnum>8</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>lwres</refentrytitle> - <manvolnum>3</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>resolver</refentrytitle> - <manvolnum>5</manvolnum> - </citerefentry>. - </para> - </refsect1> - - <refsect1> - <title>AUTHOR</title> - <para> - <corpauthor>Internet Systems Consortium</corpauthor> - </para> - </refsect1> - -</refentry> - - -<!-- - - Local variables: - - mode: sgml - - End: ---> diff --git a/contrib/bind9/bin/named/lwresd.html b/contrib/bind9/bin/named/lwresd.html deleted file mode 100644 index 439153aa826a..000000000000 --- a/contrib/bind9/bin/named/lwresd.html +++ /dev/null @@ -1,189 +0,0 @@ -<!-- - - Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - - Copyright (C) 2000, 2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - - PERFORMANCE OF THIS SOFTWARE. ---> -<!-- $Id: lwresd.html,v 1.4.2.1.4.8 2005/10/13 02:33:47 marka Exp $ --> -<html> -<head> -<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> -<title>lwresd</title> -<meta name="generator" content="DocBook XSL Stylesheets V1.69.1"> -</head> -<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en"> -<a name="id2463721"></a><div class="titlepage"></div> -<div class="refnamediv"> -<h2>Name</h2> -<p><span class="application">lwresd</span> — lightweight resolver daemon</p> -</div> -<div class="refsynopsisdiv"> -<h2>Synopsis</h2> -<div class="cmdsynopsis"><p><code class="command">lwresd</code> [<code class="option">-C <em class="replaceable"><code>config-file</code></em></code>] [<code class="option">-d <em class="replaceable"><code>debug-level</code></em></code>] [<code class="option">-f</code>] [<code class="option">-g</code>] [<code class="option">-i <em class="replaceable"><code>pid-file</code></em></code>] [<code class="option">-n <em class="replaceable"><code>#cpus</code></em></code>] [<code class="option">-P <em class="replaceable"><code>port</code></em></code>] [<code class="option">-p <em class="replaceable"><code>port</code></em></code>] [<code class="option">-s</code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-u <em class="replaceable"><code>user</code></em></code>] [<code class="option">-v</code>]</p></div> -</div> -<div class="refsect1" lang="en"> -<a name="id2525920"></a><h2>DESCRIPTION</h2> -<p> - <span><strong class="command">lwresd</strong></span> is the daemon providing name lookup - services to clients that use the BIND 9 lightweight resolver - library. It is essentially a stripped-down, caching-only name - server that answers queries using the BIND 9 lightweight - resolver protocol rather than the DNS protocol. - </p> -<p> - <span><strong class="command">lwresd</strong></span> listens for resolver queries on a - UDP port on the IPv4 loopback interface, 127.0.0.1. This - means that <span><strong class="command">lwresd</strong></span> can only be used by - processes running on the local machine. By default UDP port - number 921 is used for lightweight resolver requests and - responses. - </p> -<p> - Incoming lightweight resolver requests are decoded by the - server which then resolves them using the DNS protocol. When - the DNS lookup completes, <span><strong class="command">lwresd</strong></span> encodes - the answers in the lightweight resolver format and returns - them to the client that made the request. - </p> -<p> - If <code class="filename">/etc/resolv.conf</code> contains any - <code class="option">nameserver</code> entries, <span><strong class="command">lwresd</strong></span> - sends recursive DNS queries to those servers. This is similar - to the use of forwarders in a caching name server. If no - <code class="option">nameserver</code> entries are present, or if - forwarding fails, <span><strong class="command">lwresd</strong></span> resolves the - queries autonomously starting at the root name servers, using - a built-in list of root server hints. - </p> -</div> -<div class="refsect1" lang="en"> -<a name="id2525969"></a><h2>OPTIONS</h2> -<div class="variablelist"><dl> -<dt><span class="term">-C <em class="replaceable"><code>config-file</code></em></span></dt> -<dd><p> - Use <em class="replaceable"><code>config-file</code></em> as the - configuration file instead of the default, - <code class="filename">/etc/resolv.conf</code>. - </p></dd> -<dt><span class="term">-d <em class="replaceable"><code>debug-level</code></em></span></dt> -<dd><p> - Set the daemon's debug level to <em class="replaceable"><code>debug-level</code></em>. - Debugging traces from <span><strong class="command">lwresd</strong></span> become - more verbose as the debug level increases. - </p></dd> -<dt><span class="term">-f</span></dt> -<dd><p> - Run the server in the foreground (i.e. do not daemonize). - </p></dd> -<dt><span class="term">-g</span></dt> -<dd><p> - Run the server in the foreground and force all logging - to <code class="filename">stderr</code>. - </p></dd> -<dt><span class="term">-n <em class="replaceable"><code>#cpus</code></em></span></dt> -<dd><p> - Create <em class="replaceable"><code>#cpus</code></em> worker threads - to take advantage of multiple CPUs. If not specified, - <span><strong class="command">lwresd</strong></span> will try to determine the - number of CPUs present and create one thread per CPU. - If it is unable to determine the number of CPUs, a - single worker thread will be created. - </p></dd> -<dt><span class="term">-P <em class="replaceable"><code>port</code></em></span></dt> -<dd><p> - Listen for lightweight resolver queries on port - <em class="replaceable"><code>port</code></em>. If - not specified, the default is port 921. - </p></dd> -<dt><span class="term">-p <em class="replaceable"><code>port</code></em></span></dt> -<dd><p> - Send DNS lookups to port <em class="replaceable"><code>port</code></em>. If not - specified, the default is port 53. This provides a - way of testing the lightweight resolver daemon with a - name server that listens for queries on a non-standard - port number. - </p></dd> -<dt><span class="term">-s</span></dt> -<dd> -<p> - Write memory usage statistics to <code class="filename">stdout</code> - on exit. - </p> -<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"> -<h3 class="title">Note</h3> -<p> - This option is mainly of interest to BIND 9 developers - and may be removed or changed in a future release. - </p> -</div> -</dd> -<dt><span class="term">-t <em class="replaceable"><code>directory</code></em></span></dt> -<dd> -<p> - <code class="function">chroot()</code> to <em class="replaceable"><code>directory</code></em> after - processing the command line arguments, but before - reading the configuration file. - </p> -<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;"> -<h3 class="title">Warning</h3> -<p> - This option should be used in conjunction with the - <code class="option">-u</code> option, as chrooting a process - running as root doesn't enhance security on most - systems; the way <code class="function">chroot()</code> is - defined allows a process with root privileges to - escape a chroot jail. - </p> -</div> -</dd> -<dt><span class="term">-u <em class="replaceable"><code>user</code></em></span></dt> -<dd><p> - <code class="function">setuid()</code> to <em class="replaceable"><code>user</code></em> after completing - privileged operations, such as creating sockets that - listen on privileged ports. - </p></dd> -<dt><span class="term">-v</span></dt> -<dd><p> - Report the version number and exit. - </p></dd> -</dl></div> -</div> -<div class="refsect1" lang="en"> -<a name="id2526237"></a><h2>FILES</h2> -<div class="variablelist"><dl> -<dt><span class="term"><code class="filename">/etc/resolv.conf</code></span></dt> -<dd><p> - The default configuration file. - </p></dd> -<dt><span class="term"><code class="filename">/var/run/lwresd.pid</code></span></dt> -<dd><p> - The default process-id file. - </p></dd> -</dl></div> -</div> -<div class="refsect1" lang="en"> -<a name="id2526277"></a><h2>SEE ALSO</h2> -<p> - <span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>, - <span class="citerefentry"><span class="refentrytitle">lwres</span>(3)</span>, - <span class="citerefentry"><span class="refentrytitle">resolver</span>(5)</span>. - </p> -</div> -<div class="refsect1" lang="en"> -<a name="id2526315"></a><h2>AUTHOR</h2> -<p> - <span class="corpauthor">Internet Systems Consortium</span> - </p> -</div> -</div></body> -</html> diff --git a/contrib/bind9/bin/named/lwsearch.c b/contrib/bind9/bin/named/lwsearch.c deleted file mode 100644 index 8b9ea526f1e5..000000000000 --- a/contrib/bind9/bin/named/lwsearch.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: lwsearch.c,v 1.7.208.1 2004/03/06 10:21:20 marka Exp $ */ - -#include <config.h> - -#include <isc/magic.h> -#include <isc/mem.h> -#include <isc/mutex.h> -#include <isc/result.h> -#include <isc/types.h> -#include <isc/util.h> - -#include <dns/name.h> -#include <dns/types.h> - -#include <named/lwsearch.h> -#include <named/types.h> - -#define LWSEARCHLIST_MAGIC ISC_MAGIC('L', 'W', 'S', 'L') -#define VALID_LWSEARCHLIST(l) ISC_MAGIC_VALID(l, LWSEARCHLIST_MAGIC) - -isc_result_t -ns_lwsearchlist_create(isc_mem_t *mctx, ns_lwsearchlist_t **listp) { - ns_lwsearchlist_t *list; - - REQUIRE(mctx != NULL); - REQUIRE(listp != NULL && *listp == NULL); - - list = isc_mem_get(mctx, sizeof(ns_lwsearchlist_t)); - if (list == NULL) - return (ISC_R_NOMEMORY); - - RUNTIME_CHECK(isc_mutex_init(&list->lock) == ISC_R_SUCCESS); - list->mctx = NULL; - isc_mem_attach(mctx, &list->mctx); - list->refs = 1; - ISC_LIST_INIT(list->names); - list->magic = LWSEARCHLIST_MAGIC; - - *listp = list; - return (ISC_R_SUCCESS); -} - -void -ns_lwsearchlist_attach(ns_lwsearchlist_t *source, ns_lwsearchlist_t **target) { - REQUIRE(VALID_LWSEARCHLIST(source)); - REQUIRE(target != NULL && *target == NULL); - - LOCK(&source->lock); - INSIST(source->refs > 0); - source->refs++; - INSIST(source->refs != 0); - UNLOCK(&source->lock); - - *target = source; -} - -void -ns_lwsearchlist_detach(ns_lwsearchlist_t **listp) { - ns_lwsearchlist_t *list; - isc_mem_t *mctx; - - REQUIRE(listp != NULL); - list = *listp; - REQUIRE(VALID_LWSEARCHLIST(list)); - - LOCK(&list->lock); - INSIST(list->refs > 0); - list->refs--; - UNLOCK(&list->lock); - - *listp = NULL; - if (list->refs != 0) - return; - - mctx = list->mctx; - while (!ISC_LIST_EMPTY(list->names)) { - dns_name_t *name = ISC_LIST_HEAD(list->names); - ISC_LIST_UNLINK(list->names, name, link); - dns_name_free(name, list->mctx); - isc_mem_put(list->mctx, name, sizeof(dns_name_t)); - } - list->magic = 0; - isc_mem_put(mctx, list, sizeof(ns_lwsearchlist_t)); - isc_mem_detach(&mctx); -} - -isc_result_t -ns_lwsearchlist_append(ns_lwsearchlist_t *list, dns_name_t *name) { - dns_name_t *newname; - isc_result_t result; - - REQUIRE(VALID_LWSEARCHLIST(list)); - REQUIRE(name != NULL); - - newname = isc_mem_get(list->mctx, sizeof(dns_name_t)); - if (newname == NULL) - return (ISC_R_NOMEMORY); - dns_name_init(newname, NULL); - result = dns_name_dup(name, list->mctx, newname); - if (result != ISC_R_SUCCESS) { - isc_mem_put(list->mctx, newname, sizeof(dns_name_t)); - return (result); - } - ISC_LINK_INIT(newname, link); - ISC_LIST_APPEND(list->names, newname, link); - return (ISC_R_SUCCESS); -} - -void -ns_lwsearchctx_init(ns_lwsearchctx_t *sctx, ns_lwsearchlist_t *list, - dns_name_t *name, unsigned int ndots) -{ - INSIST(sctx != NULL); - sctx->relname = name; - sctx->searchname = NULL; - sctx->doneexact = ISC_FALSE; - sctx->exactfirst = ISC_FALSE; - sctx->ndots = ndots; - if (dns_name_isabsolute(name) || list == NULL) { - sctx->list = NULL; - return; - } - sctx->list = list; - sctx->searchname = ISC_LIST_HEAD(sctx->list->names); - if (dns_name_countlabels(name) > ndots) - sctx->exactfirst = ISC_TRUE; -} - -void -ns_lwsearchctx_first(ns_lwsearchctx_t *sctx) { - REQUIRE(sctx != NULL); - UNUSED(sctx); -} - -isc_result_t -ns_lwsearchctx_next(ns_lwsearchctx_t *sctx) { - REQUIRE(sctx != NULL); - - if (sctx->list == NULL) - return (ISC_R_NOMORE); - - if (sctx->searchname == NULL) { - INSIST (!sctx->exactfirst || sctx->doneexact); - if (sctx->exactfirst || sctx->doneexact) - return (ISC_R_NOMORE); - sctx->doneexact = ISC_TRUE; - } else { - if (sctx->exactfirst && !sctx->doneexact) - sctx->doneexact = ISC_TRUE; - else { - sctx->searchname = ISC_LIST_NEXT(sctx->searchname, - link); - if (sctx->searchname == NULL && sctx->doneexact) - return (ISC_R_NOMORE); - } - } - - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_lwsearchctx_current(ns_lwsearchctx_t *sctx, dns_name_t *absname) { - dns_name_t *tname; - isc_boolean_t useexact = ISC_FALSE; - - REQUIRE(sctx != NULL); - - if (sctx->list == NULL || - sctx->searchname == NULL || - (sctx->exactfirst && !sctx->doneexact)) - useexact = ISC_TRUE; - - if (useexact) { - if (dns_name_isabsolute(sctx->relname)) - tname = NULL; - else - tname = dns_rootname; - } else - tname = sctx->searchname; - - return (dns_name_concatenate(sctx->relname, tname, absname, NULL)); -} diff --git a/contrib/bind9/bin/named/main.c b/contrib/bind9/bin/named/main.c deleted file mode 100644 index c155291d6ca6..000000000000 --- a/contrib/bind9/bin/named/main.c +++ /dev/null @@ -1,895 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: main.c,v 1.119.2.3.2.22 2005/04/29 01:04:47 marka Exp $ */ - -#include <config.h> - -#include <ctype.h> -#include <stdlib.h> -#include <string.h> - -#include <isc/app.h> -#include <isc/commandline.h> -#include <isc/dir.h> -#include <isc/entropy.h> -#include <isc/file.h> -#include <isc/hash.h> -#include <isc/os.h> -#include <isc/platform.h> -#include <isc/resource.h> -#include <isc/stdio.h> -#include <isc/string.h> -#include <isc/task.h> -#include <isc/timer.h> -#include <isc/util.h> - -#include <isccc/result.h> - -#include <dns/dispatch.h> -#include <dns/name.h> -#include <dns/result.h> -#include <dns/view.h> - -#include <dst/result.h> - -/* - * Defining NS_MAIN provides storage declarations (rather than extern) - * for variables in named/globals.h. - */ -#define NS_MAIN 1 - -#include <named/builtin.h> -#include <named/control.h> -#include <named/globals.h> /* Explicit, though named/log.h includes it. */ -#include <named/interfacemgr.h> -#include <named/log.h> -#include <named/os.h> -#include <named/server.h> -#include <named/lwresd.h> -#include <named/main.h> -#ifdef HAVE_LIBSCF -#include <named/ns_smf_globals.h> -#endif - -/* - * Include header files for database drivers here. - */ -/* #include "xxdb.h" */ - -static isc_boolean_t want_stats = ISC_FALSE; -static char program_name[ISC_DIR_NAMEMAX] = "named"; -static char absolute_conffile[ISC_DIR_PATHMAX]; -static char saved_command_line[512]; -static char version[512]; - -void -ns_main_earlywarning(const char *format, ...) { - va_list args; - - va_start(args, format); - if (ns_g_lctx != NULL) { - isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_WARNING, - format, args); - } else { - fprintf(stderr, "%s: ", program_name); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - fflush(stderr); - } - va_end(args); -} - -void -ns_main_earlyfatal(const char *format, ...) { - va_list args; - - va_start(args, format); - if (ns_g_lctx != NULL) { - isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - format, args); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - "exiting (due to early fatal error)"); - } else { - fprintf(stderr, "%s: ", program_name); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - fflush(stderr); - } - va_end(args); - - exit(1); -} - -static void -assertion_failed(const char *file, int line, isc_assertiontype_t type, - const char *cond) -{ - /* - * Handle assertion failures. - */ - - if (ns_g_lctx != NULL) { - /* - * Reset the assetion callback in case it is the log - * routines causing the assertion. - */ - isc_assertion_setcallback(NULL); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - "%s:%d: %s(%s) failed", file, line, - isc_assertion_typetotext(type), cond); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - "exiting (due to assertion failure)"); - } else { - fprintf(stderr, "%s:%d: %s(%s) failed\n", - file, line, isc_assertion_typetotext(type), cond); - fflush(stderr); - } - - if (ns_g_coreok) - abort(); - exit(1); -} - -static void -library_fatal_error(const char *file, int line, const char *format, - va_list args) ISC_FORMAT_PRINTF(3, 0); - -static void -library_fatal_error(const char *file, int line, const char *format, - va_list args) -{ - /* - * Handle isc_error_fatal() calls from our libraries. - */ - - if (ns_g_lctx != NULL) { - /* - * Reset the error callback in case it is the log - * routines causing the assertion. - */ - isc_error_setfatal(NULL); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - "%s:%d: fatal error:", file, line); - isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - format, args); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_CRITICAL, - "exiting (due to fatal error in library)"); - } else { - fprintf(stderr, "%s:%d: fatal error: ", file, line); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - fflush(stderr); - } - - if (ns_g_coreok) - abort(); - exit(1); -} - -static void -library_unexpected_error(const char *file, int line, const char *format, - va_list args) ISC_FORMAT_PRINTF(3, 0); - -static void -library_unexpected_error(const char *file, int line, const char *format, - va_list args) -{ - /* - * Handle isc_error_unexpected() calls from our libraries. - */ - - if (ns_g_lctx != NULL) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_ERROR, - "%s:%d: unexpected error:", file, line); - isc_log_vwrite(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_MAIN, ISC_LOG_ERROR, - format, args); - } else { - fprintf(stderr, "%s:%d: fatal error: ", file, line); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - fflush(stderr); - } -} - -static void -lwresd_usage(void) { - fprintf(stderr, - "usage: lwresd [-4|-6] [-c conffile | -C resolvconffile] " - "[-d debuglevel]\n" - " [-f|-g] [-n number_of_cpus] [-p port] " - "[-P listen-port] [-s]\n" - " [-t chrootdir] [-u username] [-i pidfile]\n" - " [-m {usage|trace|record}]\n"); -} - -static void -usage(void) { - if (ns_g_lwresdonly) { - lwresd_usage(); - return; - } - fprintf(stderr, - "usage: named [-4|-6] [-c conffile] [-d debuglevel] " - "[-f|-g] [-n number_of_cpus]\n" - " [-p port] [-s] [-t chrootdir] [-u username]\n" - " [-m {usage|trace|record}]\n"); -} - -static void -save_command_line(int argc, char *argv[]) { - int i; - char *src; - char *dst; - char *eob; - const char truncated[] = "..."; - isc_boolean_t quoted = ISC_FALSE; - - dst = saved_command_line; - eob = saved_command_line + sizeof(saved_command_line); - - for (i = 1; i < argc && dst < eob; i++) { - *dst++ = ' '; - - src = argv[i]; - while (*src != '\0' && dst < eob) { - /* - * This won't perfectly produce a shell-independent - * pastable command line in all circumstances, but - * comes close, and for practical purposes will - * nearly always be fine. - */ - if (quoted || isalnum(*src & 0xff) || - *src == '-' || *src == '_' || - *src == '.' || *src == '/') { - *dst++ = *src++; - quoted = ISC_FALSE; - } else { - *dst++ = '\\'; - quoted = ISC_TRUE; - } - } - } - - INSIST(sizeof(saved_command_line) >= sizeof(truncated)); - - if (dst == eob) - strcpy(eob - sizeof(truncated), truncated); - else - *dst = '\0'; -} - -static int -parse_int(char *arg, const char *desc) { - char *endp; - int tmp; - long int ltmp; - - ltmp = strtol(arg, &endp, 10); - tmp = (int) ltmp; - if (*endp != '\0') - ns_main_earlyfatal("%s '%s' must be numeric", desc, arg); - if (tmp < 0 || tmp != ltmp) - ns_main_earlyfatal("%s '%s' out of range", desc, arg); - return (tmp); -} - -static struct flag_def { - const char *name; - unsigned int value; -} mem_debug_flags[] = { - { "trace", ISC_MEM_DEBUGTRACE }, - { "record", ISC_MEM_DEBUGRECORD }, - { "usage", ISC_MEM_DEBUGUSAGE }, - { NULL, 0 } -}; - -static void -set_flags(const char *arg, struct flag_def *defs, unsigned int *ret) { - for (;;) { - const struct flag_def *def; - const char *end = strchr(arg, ','); - int arglen; - if (end == NULL) - end = arg + strlen(arg); - arglen = end - arg; - for (def = defs; def->name != NULL; def++) { - if (arglen == (int)strlen(def->name) && - memcmp(arg, def->name, arglen) == 0) { - *ret |= def->value; - goto found; - } - } - ns_main_earlyfatal("unrecognized flag '%.*s'", arglen, arg); - found: - if (*end == '\0') - break; - arg = end + 1; - } -} - -static void -parse_command_line(int argc, char *argv[]) { - int ch; - int port; - isc_boolean_t disable6 = ISC_FALSE; - isc_boolean_t disable4 = ISC_FALSE; - - save_command_line(argc, argv); - - isc_commandline_errprint = ISC_FALSE; - while ((ch = isc_commandline_parse(argc, argv, - "46c:C:d:fgi:lm:n:N:p:P:st:u:vx:")) != -1) { - switch (ch) { - case '4': - if (disable4) - ns_main_earlyfatal("cannot specify -4 and -6"); - if (isc_net_probeipv4() != ISC_R_SUCCESS) - ns_main_earlyfatal("IPv4 not supported by OS"); - isc_net_disableipv6(); - disable6 = ISC_TRUE; - break; - case '6': - if (disable6) - ns_main_earlyfatal("cannot specify -4 and -6"); - if (isc_net_probeipv6() != ISC_R_SUCCESS) - ns_main_earlyfatal("IPv6 not supported by OS"); - isc_net_disableipv4(); - disable4 = ISC_TRUE; - break; - case 'c': - ns_g_conffile = isc_commandline_argument; - lwresd_g_conffile = isc_commandline_argument; - if (lwresd_g_useresolvconf) - ns_main_earlyfatal("cannot specify -c and -C"); - ns_g_conffileset = ISC_TRUE; - break; - case 'C': - lwresd_g_resolvconffile = isc_commandline_argument; - if (ns_g_conffileset) - ns_main_earlyfatal("cannot specify -c and -C"); - lwresd_g_useresolvconf = ISC_TRUE; - break; - case 'd': - ns_g_debuglevel = parse_int(isc_commandline_argument, - "debug level"); - break; - case 'f': - ns_g_foreground = ISC_TRUE; - break; - case 'g': - ns_g_foreground = ISC_TRUE; - ns_g_logstderr = ISC_TRUE; - break; - /* XXXBEW -i should be removed */ - case 'i': - lwresd_g_defaultpidfile = isc_commandline_argument; - break; - case 'l': - ns_g_lwresdonly = ISC_TRUE; - break; - case 'm': - set_flags(isc_commandline_argument, mem_debug_flags, - &isc_mem_debugging); - break; - case 'N': /* Deprecated. */ - case 'n': - ns_g_cpus = parse_int(isc_commandline_argument, - "number of cpus"); - if (ns_g_cpus == 0) - ns_g_cpus = 1; - break; - case 'p': - port = parse_int(isc_commandline_argument, "port"); - if (port < 1 || port > 65535) - ns_main_earlyfatal("port '%s' out of range", - isc_commandline_argument); - ns_g_port = port; - break; - /* XXXBEW Should -P be removed? */ - case 'P': - port = parse_int(isc_commandline_argument, "port"); - if (port < 1 || port > 65535) - ns_main_earlyfatal("port '%s' out of range", - isc_commandline_argument); - lwresd_g_listenport = port; - break; - case 's': - /* XXXRTH temporary syntax */ - want_stats = ISC_TRUE; - break; - case 't': - /* XXXJAB should we make a copy? */ - ns_g_chrootdir = isc_commandline_argument; - break; - case 'u': - ns_g_username = isc_commandline_argument; - break; - case 'v': - printf("BIND %s\n", ns_g_version); - exit(0); - case '?': - usage(); - ns_main_earlyfatal("unknown option '-%c'", - isc_commandline_option); - default: - ns_main_earlyfatal("parsing options returned %d", ch); - } - } - - argc -= isc_commandline_index; - argv += isc_commandline_index; - - if (argc > 0) { - usage(); - ns_main_earlyfatal("extra command line arguments"); - } -} - -static isc_result_t -create_managers(void) { - isc_result_t result; -#ifdef ISC_PLATFORM_USETHREADS - unsigned int cpus_detected; -#endif - -#ifdef ISC_PLATFORM_USETHREADS - cpus_detected = isc_os_ncpus(); - if (ns_g_cpus == 0) - ns_g_cpus = cpus_detected; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "found %u CPU%s, using %u worker thread%s", - cpus_detected, cpus_detected == 1 ? "" : "s", - ns_g_cpus, ns_g_cpus == 1 ? "" : "s"); -#else - ns_g_cpus = 1; -#endif - result = isc_taskmgr_create(ns_g_mctx, ns_g_cpus, 0, &ns_g_taskmgr); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "ns_taskmgr_create() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - result = isc_timermgr_create(ns_g_mctx, &ns_g_timermgr); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "ns_timermgr_create() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - result = isc_socketmgr_create(ns_g_mctx, &ns_g_socketmgr); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_socketmgr_create() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - result = isc_entropy_create(ns_g_mctx, &ns_g_entropy); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_entropy_create() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - result = isc_hash_create(ns_g_mctx, ns_g_entropy, DNS_NAME_MAXWIRE); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_hash_create() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } - - return (ISC_R_SUCCESS); -} - -static void -destroy_managers(void) { - ns_lwresd_shutdown(); - - isc_entropy_detach(&ns_g_entropy); - if (ns_g_fallbackentropy != NULL) - isc_entropy_detach(&ns_g_fallbackentropy); - - /* - * isc_taskmgr_destroy() will block until all tasks have exited, - */ - isc_taskmgr_destroy(&ns_g_taskmgr); - isc_timermgr_destroy(&ns_g_timermgr); - isc_socketmgr_destroy(&ns_g_socketmgr); - - /* - * isc_hash_destroy() cannot be called as long as a resolver may be - * running. Calling this after isc_taskmgr_destroy() ensures the - * call is safe. - */ - isc_hash_destroy(); -} - -static void -setup(void) { - isc_result_t result; -#ifdef HAVE_LIBSCF - char *instance = NULL; -#endif - - /* - * Get the user and group information before changing the root - * directory, so the administrator does not need to keep a copy - * of the user and group databases in the chroot'ed environment. - */ - ns_os_inituserinfo(ns_g_username); - - /* - * Initialize time conversion information - */ - ns_os_tzset(); - - ns_os_opendevnull(); - -#ifdef HAVE_LIBSCF - /* Check if named is under smf control, before chroot. */ - result = ns_smf_get_instance(&instance, 0, ns_g_mctx); - /* We don't care about instance, just check if we got one. */ - if (result == ISC_R_SUCCESS) - ns_smf_got_instance = 1; - else - ns_smf_got_instance = 0; - if (instance != NULL) - isc_mem_free(ns_g_mctx, instance); -#endif /* HAVE_LIBSCF */ - -#ifdef PATH_RANDOMDEV - /* - * Initialize system's random device as fallback entropy source - * if running chroot'ed. - */ - if (ns_g_chrootdir != NULL) { - result = isc_entropy_create(ns_g_mctx, &ns_g_fallbackentropy); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("isc_entropy_create() failed: %s", - isc_result_totext(result)); - - result = isc_entropy_createfilesource(ns_g_fallbackentropy, - PATH_RANDOMDEV); - if (result != ISC_R_SUCCESS) { - ns_main_earlywarning("could not open pre-chroot " - "entropy source %s: %s", - PATH_RANDOMDEV, - isc_result_totext(result)); - isc_entropy_detach(&ns_g_fallbackentropy); - } - } -#endif - - ns_os_chroot(ns_g_chrootdir); - - /* - * For operating systems which have a capability mechanism, now - * is the time to switch to minimal privs and change our user id. - * On traditional UNIX systems, this call will be a no-op, and we - * will change the user ID after reading the config file the first - * time. (We need to read the config file to know which possibly - * privileged ports to bind() to.) - */ - ns_os_minprivs(); - - result = ns_log_init(ISC_TF(ns_g_username != NULL)); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("ns_log_init() failed: %s", - isc_result_totext(result)); - - /* - * Now is the time to daemonize (if we're not running in the - * foreground). We waited until now because we wanted to get - * a valid logging context setup. We cannot daemonize any later, - * because calling create_managers() will create threads, which - * would be lost after fork(). - */ - if (!ns_g_foreground) - ns_os_daemonize(); - - /* - * We call isc_app_start() here as some versions of FreeBSD's fork() - * destroys all the signal handling it sets up. - */ - result = isc_app_start(); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("isc_app_start() failed: %s", - isc_result_totext(result)); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, "starting BIND %s%s", ns_g_version, - saved_command_line); - - /* - * Get the initial resource limits. - */ - (void)isc_resource_getlimit(isc_resource_stacksize, - &ns_g_initstacksize); - (void)isc_resource_getlimit(isc_resource_datasize, - &ns_g_initdatasize); - (void)isc_resource_getlimit(isc_resource_coresize, - &ns_g_initcoresize); - (void)isc_resource_getlimit(isc_resource_openfiles, - &ns_g_initopenfiles); - - /* - * If the named configuration filename is relative, prepend the current - * directory's name before possibly changing to another directory. - */ - if (! isc_file_isabsolute(ns_g_conffile)) { - result = isc_file_absolutepath(ns_g_conffile, - absolute_conffile, - sizeof(absolute_conffile)); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("could not construct absolute path of " - "configuration file: %s", - isc_result_totext(result)); - ns_g_conffile = absolute_conffile; - } - - result = create_managers(); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("create_managers() failed: %s", - isc_result_totext(result)); - - ns_builtin_init(); - - /* - * Add calls to register sdb drivers here. - */ - /* xxdb_init(); */ - - ns_server_create(ns_g_mctx, &ns_g_server); -} - -static void -cleanup(void) { - destroy_managers(); - - ns_server_destroy(&ns_g_server); - - ns_builtin_deinit(); - - /* - * Add calls to unregister sdb drivers here. - */ - /* xxdb_clear(); */ - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, - ISC_LOG_NOTICE, "exiting"); - ns_log_shutdown(); -} - -static char *memstats = NULL; - -void -ns_main_setmemstats(const char *filename) { - /* - * Caller has to ensure locking. - */ - - if (memstats != NULL) { - free(memstats); - memstats = NULL; - } - if (filename == NULL) - return; - memstats = malloc(strlen(filename) + 1); - if (memstats) - strcpy(memstats, filename); -} - -#ifdef HAVE_LIBSCF -/* - * Get FMRI for the named process. - */ -isc_result_t -ns_smf_get_instance(char **ins_name, int debug, isc_mem_t *mctx) { - scf_handle_t *h = NULL; - int namelen; - char *instance; - - REQUIRE(ins_name != NULL && *ins_name == NULL); - - if ((h = scf_handle_create(SCF_VERSION)) == NULL) { - if (debug) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "scf_handle_create() failed: %s", - scf_strerror(scf_error())); - return (ISC_R_FAILURE); - } - - if (scf_handle_bind(h) == -1) { - if (debug) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "scf_handle_bind() failed: %s", - scf_strerror(scf_error())); - scf_handle_destroy(h); - return (ISC_R_FAILURE); - } - - if ((namelen = scf_myname(h, NULL, 0)) == -1) { - if (debug) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "scf_myname() failed: %s", - scf_strerror(scf_error())); - scf_handle_destroy(h); - return (ISC_R_FAILURE); - } - - if ((instance = isc_mem_allocate(mctx, namelen + 1)) == NULL) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "ns_smf_get_instance memory " - "allocation failed: %s", - isc_result_totext(ISC_R_NOMEMORY)); - scf_handle_destroy(h); - return (ISC_R_FAILURE); - } - - if (scf_myname(h, instance, namelen + 1) == -1) { - if (debug) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "scf_myname() failed: %s", - scf_strerror(scf_error())); - scf_handle_destroy(h); - isc_mem_free(mctx, instance); - return (ISC_R_FAILURE); - } - - scf_handle_destroy(h); - *ins_name = instance; - return (ISC_R_SUCCESS); -} -#endif /* HAVE_LIBSCF */ - -int -main(int argc, char *argv[]) { - isc_result_t result; -#ifdef HAVE_LIBSCF - char *instance = NULL; -#endif - - /* - * Record version in core image. - * strings named.core | grep "named version:" - */ - strlcat(version, -#ifdef __DATE__ - "named version: BIND " VERSION " (" __DATE__ ")", -#else - "named version: BIND " VERSION, -#endif - sizeof(version)); - result = isc_file_progname(*argv, program_name, sizeof(program_name)); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("program name too long"); - - if (strcmp(program_name, "lwresd") == 0) - ns_g_lwresdonly = ISC_TRUE; - - isc_assertion_setcallback(assertion_failed); - isc_error_setfatal(library_fatal_error); - isc_error_setunexpected(library_unexpected_error); - - ns_os_init(program_name); - - dns_result_register(); - dst_result_register(); - isccc_result_register(); - - parse_command_line(argc, argv); - - /* - * Warn about common configuration error. - */ - if (ns_g_chrootdir != NULL) { - int len = strlen(ns_g_chrootdir); - if (strncmp(ns_g_chrootdir, ns_g_conffile, len) == 0 && - (ns_g_conffile[len] == '/' || ns_g_conffile[len] == '\\')) - ns_main_earlywarning("config filename (-c %s) contains " - "chroot path (-t %s)", - ns_g_conffile, ns_g_chrootdir); - } - - result = isc_mem_create(0, 0, &ns_g_mctx); - if (result != ISC_R_SUCCESS) - ns_main_earlyfatal("isc_mem_create() failed: %s", - isc_result_totext(result)); - - setup(); - - /* - * Start things running and then wait for a shutdown request - * or reload. - */ - do { - result = isc_app_run(); - - if (result == ISC_R_RELOAD) { - ns_server_reloadwanted(ns_g_server); - } else if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_app_run(): %s", - isc_result_totext(result)); - /* - * Force exit. - */ - result = ISC_R_SUCCESS; - } - } while (result != ISC_R_SUCCESS); - -#ifdef HAVE_LIBSCF - if (ns_smf_want_disable == 1) { - result = ns_smf_get_instance(&instance, 1, ns_g_mctx); - if (result == ISC_R_SUCCESS && instance != NULL) { - if (smf_disable_instance(instance, 0) != 0) - UNEXPECTED_ERROR(__FILE__, __LINE__, - "smf_disable_instance() ", - "failed for %s : %s", - instance, - scf_strerror(scf_error())); - } - if (instance != NULL) - isc_mem_free(ns_g_mctx, instance); - } -#endif /* HAVE_LIBSCF */ - - cleanup(); - - if (want_stats) { - isc_mem_stats(ns_g_mctx, stdout); - isc_mutex_stats(stdout); - } - if (memstats != NULL) { - FILE *fp = NULL; - result = isc_stdio_open(memstats, "w", &fp); - if (result == ISC_R_SUCCESS) { - isc_mem_stats(ns_g_mctx, fp); - isc_mutex_stats(fp); - isc_stdio_close(fp); - } - } - isc_mem_destroy(&ns_g_mctx); - - ns_main_setmemstats(NULL); - - isc_app_finish(); - - ns_os_closedevnull(); - - ns_os_shutdown(); - - return (0); -} diff --git a/contrib/bind9/bin/named/named.8 b/contrib/bind9/bin/named/named.8 deleted file mode 100644 index e072c169be3e..000000000000 --- a/contrib/bind9/bin/named/named.8 +++ /dev/null @@ -1,182 +0,0 @@ -.\" Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") -.\" Copyright (C) 2000, 2001, 2003 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 ISC DISCLAIMS ALL WARRANTIES WITH -.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, -.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -.\" PERFORMANCE OF THIS SOFTWARE. -.\" -.\" $Id: named.8,v 1.17.208.6 2005/10/13 02:33:46 marka Exp $ -.\" -.hy 0 -.ad l -.\" ** You probably do not want to edit this file directly ** -.\" It was generated using the DocBook XSL Stylesheets (version 1.69.1). -.\" Instead of manually editing it, you probably should edit the DocBook XML -.\" source for it and then use the DocBook XSL Stylesheets to regenerate it. -.TH "NAMED" "8" "June 30, 2000" "BIND9" "BIND9" -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.SH "NAME" -named \- Internet domain name server -.SH "SYNOPSIS" -.HP 6 -\fBnamed\fR [\fB\-4\fR] [\fB\-6\fR] [\fB\-c\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-d\ \fR\fB\fIdebug\-level\fR\fR] [\fB\-f\fR] [\fB\-g\fR] [\fB\-n\ \fR\fB\fI#cpus\fR\fR] [\fB\-p\ \fR\fB\fIport\fR\fR] [\fB\-s\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-x\ \fR\fB\fIcache\-file\fR\fR] -.SH "DESCRIPTION" -.PP -\fBnamed\fR -is a Domain Name System (DNS) server, part of the BIND 9 distribution from ISC. For more information on the DNS, see RFCs 1033, 1034, and 1035. -.PP -When invoked without arguments, -\fBnamed\fR -will read the default configuration file -\fI/etc/named.conf\fR, read any initial data, and listen for queries. -.SH "OPTIONS" -.TP -\-4 -Use IPv4 only even if the host machine is capable of IPv6. -\fB\-4\fR -and -\fB\-6\fR -are mutually exclusive. -.TP -\-6 -Use IPv6 only even if the host machine is capable of IPv4. -\fB\-4\fR -and -\fB\-6\fR -are mutually exclusive. -.TP -\-c \fIconfig\-file\fR -Use -\fIconfig\-file\fR -as the configuration file instead of the default, -\fI/etc/named.conf\fR. To ensure that reloading the configuration file continues to work after the server has changed its working directory due to to a possible -\fBdirectory\fR -option in the configuration file, -\fIconfig\-file\fR -should be an absolute pathname. -.TP -\-d \fIdebug\-level\fR -Set the daemon's debug level to -\fIdebug\-level\fR. Debugging traces from -\fBnamed\fR -become more verbose as the debug level increases. -.TP -\-f -Run the server in the foreground (i.e. do not daemonize). -.TP -\-g -Run the server in the foreground and force all logging to -\fIstderr\fR. -.TP -\-n \fI#cpus\fR -Create -\fI#cpus\fR -worker threads to take advantage of multiple CPUs. If not specified, -\fBnamed\fR -will try to determine the number of CPUs present and create one thread per CPU. If it is unable to determine the number of CPUs, a single worker thread will be created. -.TP -\-p \fIport\fR -Listen for queries on port -\fIport\fR. If not specified, the default is port 53. -.TP -\-s -Write memory usage statistics to -\fIstdout\fR -on exit. -.RS -.B "Note:" -This option is mainly of interest to BIND 9 developers and may be removed or changed in a future release. -.RE -.TP -\-t \fIdirectory\fR -\fBchroot()\fR -to -\fIdirectory\fR -after processing the command line arguments, but before reading the configuration file. -.RS -.B "Warning:" -This option should be used in conjunction with the -\fB\-u\fR -option, as chrooting a process running as root doesn't enhance security on most systems; the way -\fBchroot()\fR -is defined allows a process with root privileges to escape a chroot jail. -.RE -.TP -\-u \fIuser\fR -\fBsetuid()\fR -to -\fIuser\fR -after completing privileged operations, such as creating sockets that listen on privileged ports. -.RS -.B "Note:" -On Linux, -\fBnamed\fR -uses the kernel's capability mechanism to drop all root privileges except the ability to -\fBbind()\fR -to a privileged port and set process resource limits. Unfortunately, this means that the -\fB\-u\fR -option only works when -\fBnamed\fR -is run on kernel 2.2.18 or later, or kernel 2.3.99\-pre3 or later, since previous kernels did not allow privileges to be retained after -\fBsetuid()\fR. -.RE -.TP -\-v -Report the version number and exit. -.TP -\-x \fIcache\-file\fR -Load data from -\fIcache\-file\fR -into the cache of the default view. -.RS -.B "Warning:" -This option must not be used. It is only of interest to BIND 9 developers and may be removed or changed in a future release. -.RE -.SH "SIGNALS" -.PP -In routine operation, signals should not be used to control the nameserver; -\fBrndc\fR -should be used instead. -.TP -SIGHUP -Force a reload of the server. -.TP -SIGINT, SIGTERM -Shut down the server. -.PP -The result of sending any other signals to the server is undefined. -.SH "CONFIGURATION" -.PP -The -\fBnamed\fR -configuration file is too complex to describe in detail here. A complete description is provided in the -BIND 9 Administrator Reference Manual. -.SH "FILES" -.TP -\fI/etc/named.conf\fR -The default configuration file. -.TP -\fI/var/run/named.pid\fR -The default process\-id file. -.SH "SEE ALSO" -.PP -RFC 1033, -RFC 1034, -RFC 1035, -\fBrndc\fR(8), -\fBlwresd\fR(8), -BIND 9 Administrator Reference Manual. -.SH "AUTHOR" -.PP -Internet Systems Consortium diff --git a/contrib/bind9/bin/named/named.conf.5 b/contrib/bind9/bin/named/named.conf.5 deleted file mode 100644 index d0b690b1b5a0..000000000000 --- a/contrib/bind9/bin/named/named.conf.5 +++ /dev/null @@ -1,438 +0,0 @@ -.\" Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") -.\" -.\" 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 ISC DISCLAIMS ALL WARRANTIES WITH -.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, -.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -.\" PERFORMANCE OF THIS SOFTWARE. -.\" -.\" $Id: named.conf.5,v 1.1.4.6 2005/10/13 02:33:47 marka Exp $ -.\" -.hy 0 -.ad l -.\" ** You probably do not want to edit this file directly ** -.\" It was generated using the DocBook XSL Stylesheets (version 1.69.1). -.\" Instead of manually editing it, you probably should edit the DocBook XML -.\" source for it and then use the DocBook XSL Stylesheets to regenerate it. -.TH "\\FINAMED.CONF\\FR" "5" "Aug 13, 2004" "BIND9" "BIND9" -.\" disable hyphenation -.nh -.\" disable justification (adjust text to left margin only) -.ad l -.SH "NAME" -named.conf \- configuration file for named -.SH "SYNOPSIS" -.HP 11 -\fBnamed.conf\fR -.SH "DESCRIPTION" -.PP -\fInamed.conf\fR -is the configuration file for -\fBnamed\fR. Statements are enclosed in braces and terminated with a semi\-colon. Clauses in the statements are also semi\-colon terminated. The usual comment styles are supported: -.PP -C style: /* */ -.PP -C++ style: // to end of line -.PP -Unix style: # to end of line -.SH "ACL" -.sp -.nf -acl \fIstring\fR { \fIaddress_match_element\fR; ... }; -.fi -.SH "KEY" -.sp -.nf -key \fIdomain_name\fR { - algorithm \fIstring\fR; - secret \fIstring\fR; -}; -.fi -.SH "MASTERS" -.sp -.nf -masters \fIstring\fR [ port \fIinteger\fR ] { - ( \fImasters\fR | \fIipv4_address\fR [port \fIinteger\fR] | - \fIipv6_address\fR [port \fIinteger\fR] ) [ key \fIstring\fR ]; ... -}; -.fi -.SH "SERVER" -.sp -.nf -server ( \fIipv4_address\fR | \fIipv6_address\fR ) { - bogus \fIboolean\fR; - edns \fIboolean\fR; - provide\-ixfr \fIboolean\fR; - request\-ixfr \fIboolean\fR; - keys \fIserver_key\fR; - transfers \fIinteger\fR; - transfer\-format ( many\-answers | one\-answer ); - transfer\-source ( \fIipv4_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - transfer\-source\-v6 ( \fIipv6_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - support\-ixfr \fIboolean\fR; // obsolete -}; -.fi -.SH "TRUSTED\-KEYS" -.sp -.nf -trusted\-keys { - \fIdomain_name\fR \fIflags\fR \fIprotocol\fR \fIalgorithm\fR \fIkey\fR; ... -}; -.fi -.SH "CONTROLS" -.sp -.nf -controls { - inet ( \fIipv4_address\fR | \fIipv6_address\fR | * ) - [ port ( \fIinteger\fR | * ) ] - allow { \fIaddress_match_element\fR; ... } - [ keys { \fIstring\fR; ... } ]; - unix \fIunsupported\fR; // not implemented -}; -.fi -.SH "LOGGING" -.sp -.nf -logging { - channel \fIstring\fR { - file \fIlog_file\fR; - syslog \fIoptional_facility\fR; - null; - stderr; - severity \fIlog_severity\fR; - print\-time \fIboolean\fR; - print\-severity \fIboolean\fR; - print\-category \fIboolean\fR; - }; - category \fIstring\fR { \fIstring\fR; ... }; -}; -.fi -.SH "LWRES" -.sp -.nf -lwres { - listen\-on [ port \fIinteger\fR ] { - ( \fIipv4_address\fR | \fIipv6_address\fR ) [ port \fIinteger\fR ]; ... - }; - view \fIstring\fR \fIoptional_class\fR; - search { \fIstring\fR; ... }; - ndots \fIinteger\fR; -}; -.fi -.SH "OPTIONS" -.sp -.nf -options { - avoid\-v4\-udp\-ports { \fIport\fR; ... }; - avoid\-v6\-udp\-ports { \fIport\fR; ... }; - blackhole { \fIaddress_match_element\fR; ... }; - coresize \fIsize\fR; - datasize \fIsize\fR; - directory \fIquoted_string\fR; - dump\-file \fIquoted_string\fR; - files \fIsize\fR; - heartbeat\-interval \fIinteger\fR; - host\-statistics \fIboolean\fR; // not implemented - host\-statistics\-max \fInumber\fR; // not implemented - hostname ( \fIquoted_string\fR | none ); - interface\-interval \fIinteger\fR; - listen\-on [ port \fIinteger\fR ] { \fIaddress_match_element\fR; ... }; - listen\-on\-v6 [ port \fIinteger\fR ] { \fIaddress_match_element\fR; ... }; - match\-mapped\-addresses \fIboolean\fR; - memstatistics\-file \fIquoted_string\fR; - pid\-file ( \fIquoted_string\fR | none ); - port \fIinteger\fR; - querylog \fIboolean\fR; - recursing\-file \fIquoted_string\fR; - random\-device \fIquoted_string\fR; - recursive\-clients \fIinteger\fR; - serial\-query\-rate \fIinteger\fR; - server\-id ( \fIquoted_string\fR | none |; - stacksize \fIsize\fR; - statistics\-file \fIquoted_string\fR; - statistics\-interval \fIinteger\fR; // not yet implemented - tcp\-clients \fIinteger\fR; - tcp\-listen\-queue \fIinteger\fR; - tkey\-dhkey \fIquoted_string\fR \fIinteger\fR; - tkey\-gssapi\-credential \fIquoted_string\fR; - tkey\-domain \fIquoted_string\fR; - transfers\-per\-ns \fIinteger\fR; - transfers\-in \fIinteger\fR; - transfers\-out \fIinteger\fR; - use\-ixfr \fIboolean\fR; - version ( \fIquoted_string\fR | none ); - allow\-recursion { \fIaddress_match_element\fR; ... }; - sortlist { \fIaddress_match_element\fR; ... }; - topology { \fIaddress_match_element\fR; ... }; // not implemented - auth\-nxdomain \fIboolean\fR; // default changed - minimal\-responses \fIboolean\fR; - recursion \fIboolean\fR; - rrset\-order { - [ class \fIstring\fR ] [ type \fIstring\fR ] - [ name \fIquoted_string\fR ] \fIstring\fR \fIstring\fR; ... - }; - provide\-ixfr \fIboolean\fR; - request\-ixfr \fIboolean\fR; - rfc2308\-type1 \fIboolean\fR; // not yet implemented - additional\-from\-auth \fIboolean\fR; - additional\-from\-cache \fIboolean\fR; - query\-source \fIquerysource4\fR; - query\-source\-v6 \fIquerysource6\fR; - cleaning\-interval \fIinteger\fR; - min\-roots \fIinteger\fR; // not implemented - lame\-ttl \fIinteger\fR; - max\-ncache\-ttl \fIinteger\fR; - max\-cache\-ttl \fIinteger\fR; - transfer\-format ( many\-answers | one\-answer ); - max\-cache\-size \fIsize_no_default\fR; - check\-names ( master | slave | response ) - ( fail | warn | ignore ); - cache\-file \fIquoted_string\fR; - suppress\-initial\-notify \fIboolean\fR; // not yet implemented - preferred\-glue \fIstring\fR; - dual\-stack\-servers [ port \fIinteger\fR ] { - ( \fIquoted_string\fR [port \fIinteger\fR] | - \fIipv4_address\fR [port \fIinteger\fR] | - \fIipv6_address\fR [port \fIinteger\fR] ); ... - } - edns\-udp\-size \fIinteger\fR; - root\-delegation\-only [ exclude { \fIquoted_string\fR; ... } ]; - disable\-algorithms \fIstring\fR { \fIstring\fR; ... }; - dnssec\-enable \fIboolean\fR; - dnssec\-lookaside \fIstring\fR trust\-anchor \fIstring\fR; - dnssec\-must\-be\-secure \fIstring\fR \fIboolean\fR; - dialup \fIdialuptype\fR; - ixfr\-from\-differences \fIixfrdiff\fR; - allow\-query { \fIaddress_match_element\fR; ... }; - allow\-transfer { \fIaddress_match_element\fR; ... }; - allow\-update\-forwarding { \fIaddress_match_element\fR; ... }; - notify \fInotifytype\fR; - notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ]; - notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) ]; - also\-notify [ port \fIinteger\fR ] { ( \fIipv4_address\fR | \fIipv6_address\fR ) - [ port \fIinteger\fR ]; ... }; - allow\-notify { \fIaddress_match_element\fR; ... }; - forward ( first | only ); - forwarders [ port \fIinteger\fR ] { - ( \fIipv4_address\fR | \fIipv6_address\fR ) [ port \fIinteger\fR ]; ... - }; - max\-journal\-size \fIsize_no_default\fR; - max\-transfer\-time\-in \fIinteger\fR; - max\-transfer\-time\-out \fIinteger\fR; - max\-transfer\-idle\-in \fIinteger\fR; - max\-transfer\-idle\-out \fIinteger\fR; - max\-retry\-time \fIinteger\fR; - min\-retry\-time \fIinteger\fR; - max\-refresh\-time \fIinteger\fR; - min\-refresh\-time \fIinteger\fR; - multi\-master \fIboolean\fR; - sig\-validity\-interval \fIinteger\fR; - transfer\-source ( \fIipv4_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - transfer\-source\-v6 ( \fIipv6_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - alt\-transfer\-source ( \fIipv4_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - alt\-transfer\-source\-v6 ( \fIipv6_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - use\-alt\-transfer\-source \fIboolean\fR; - zone\-statistics \fIboolean\fR; - key\-directory \fIquoted_string\fR; - allow\-v6\-synthesis { \fIaddress_match_element\fR; ... }; // obsolete - deallocate\-on\-exit \fIboolean\fR; // obsolete - fake\-iquery \fIboolean\fR; // obsolete - fetch\-glue \fIboolean\fR; // obsolete - has\-old\-clients \fIboolean\fR; // obsolete - maintain\-ixfr\-base \fIboolean\fR; // obsolete - max\-ixfr\-log\-size \fIsize\fR; // obsolete - multiple\-cnames \fIboolean\fR; // obsolete - named\-xfer \fIquoted_string\fR; // obsolete - serial\-queries \fIinteger\fR; // obsolete - treat\-cr\-as\-space \fIboolean\fR; // obsolete - use\-id\-pool \fIboolean\fR; // obsolete -}; -.fi -.SH "VIEW" -.sp -.nf -view \fIstring\fR \fIoptional_class\fR { - match\-clients { \fIaddress_match_element\fR; ... }; - match\-destinations { \fIaddress_match_element\fR; ... }; - match\-recursive\-only \fIboolean\fR; - key \fIstring\fR { - algorithm \fIstring\fR; - secret \fIstring\fR; - }; - zone \fIstring\fR \fIoptional_class\fR { - ... - }; - server ( \fIipv4_address\fR | \fIipv6_address\fR ) { - ... - }; - trusted\-keys { - \fIstring\fR \fIinteger\fR \fIinteger\fR \fIinteger\fR \fIquoted_string\fR; ... - }; - allow\-recursion { \fIaddress_match_element\fR; ... }; - sortlist { \fIaddress_match_element\fR; ... }; - topology { \fIaddress_match_element\fR; ... }; // not implemented - auth\-nxdomain \fIboolean\fR; // default changed - minimal\-responses \fIboolean\fR; - recursion \fIboolean\fR; - rrset\-order { - [ class \fIstring\fR ] [ type \fIstring\fR ] - [ name \fIquoted_string\fR ] \fIstring\fR \fIstring\fR; ... - }; - provide\-ixfr \fIboolean\fR; - request\-ixfr \fIboolean\fR; - rfc2308\-type1 \fIboolean\fR; // not yet implemented - additional\-from\-auth \fIboolean\fR; - additional\-from\-cache \fIboolean\fR; - query\-source \fIquerysource4\fR; - query\-source\-v6 \fIquerysource6\fR; - cleaning\-interval \fIinteger\fR; - min\-roots \fIinteger\fR; // not implemented - lame\-ttl \fIinteger\fR; - max\-ncache\-ttl \fIinteger\fR; - max\-cache\-ttl \fIinteger\fR; - transfer\-format ( many\-answers | one\-answer ); - max\-cache\-size \fIsize_no_default\fR; - check\-names ( master | slave | response ) - ( fail | warn | ignore ); - cache\-file \fIquoted_string\fR; - suppress\-initial\-notify \fIboolean\fR; // not yet implemented - preferred\-glue \fIstring\fR; - dual\-stack\-servers [ port \fIinteger\fR ] { - ( \fIquoted_string\fR [port \fIinteger\fR] | - \fIipv4_address\fR [port \fIinteger\fR] | - \fIipv6_address\fR [port \fIinteger\fR] ); ... - }; - edns\-udp\-size \fIinteger\fR; - root\-delegation\-only [ exclude { \fIquoted_string\fR; ... } ]; - disable\-algorithms \fIstring\fR { \fIstring\fR; ... }; - dnssec\-enable \fIboolean\fR; - dnssec\-lookaside \fIstring\fR trust\-anchor \fIstring\fR; - dnssec\-must\-be\-secure \fIstring\fR \fIboolean\fR; - dialup \fIdialuptype\fR; - ixfr\-from\-differences \fIixfrdiff\fR; - allow\-query { \fIaddress_match_element\fR; ... }; - allow\-transfer { \fIaddress_match_element\fR; ... }; - allow\-update\-forwarding { \fIaddress_match_element\fR; ... }; - notify \fInotifytype\fR; - notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ]; - notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) ]; - also\-notify [ port \fIinteger\fR ] { ( \fIipv4_address\fR | \fIipv6_address\fR ) - [ port \fIinteger\fR ]; ... }; - allow\-notify { \fIaddress_match_element\fR; ... }; - forward ( first | only ); - forwarders [ port \fIinteger\fR ] { - ( \fIipv4_address\fR | \fIipv6_address\fR ) [ port \fIinteger\fR ]; ... - }; - max\-journal\-size \fIsize_no_default\fR; - max\-transfer\-time\-in \fIinteger\fR; - max\-transfer\-time\-out \fIinteger\fR; - max\-transfer\-idle\-in \fIinteger\fR; - max\-transfer\-idle\-out \fIinteger\fR; - max\-retry\-time \fIinteger\fR; - min\-retry\-time \fIinteger\fR; - max\-refresh\-time \fIinteger\fR; - min\-refresh\-time \fIinteger\fR; - multi\-master \fIboolean\fR; - sig\-validity\-interval \fIinteger\fR; - transfer\-source ( \fIipv4_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - transfer\-source\-v6 ( \fIipv6_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - alt\-transfer\-source ( \fIipv4_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - alt\-transfer\-source\-v6 ( \fIipv6_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - use\-alt\-transfer\-source \fIboolean\fR; - zone\-statistics \fIboolean\fR; - key\-directory \fIquoted_string\fR; - allow\-v6\-synthesis { \fIaddress_match_element\fR; ... }; // obsolete - fetch\-glue \fIboolean\fR; // obsolete - maintain\-ixfr\-base \fIboolean\fR; // obsolete - max\-ixfr\-log\-size \fIsize\fR; // obsolete -}; -.fi -.SH "ZONE" -.sp -.nf -zone \fIstring\fR \fIoptional_class\fR { - type ( master | slave | stub | hint | - forward | delegation\-only ); - file \fIquoted_string\fR; - masters [ port \fIinteger\fR ] { - ( \fImasters\fR | - \fIipv4_address\fR [port \fIinteger\fR] | - \fIipv6_address\fR [ port \fIinteger\fR ] ) [ key \fIstring\fR ]; ... - }; - database \fIstring\fR; - delegation\-only \fIboolean\fR; - check\-names ( fail | warn | ignore ); - dialup \fIdialuptype\fR; - ixfr\-from\-differences \fIboolean\fR; - allow\-query { \fIaddress_match_element\fR; ... }; - allow\-transfer { \fIaddress_match_element\fR; ... }; - allow\-update { \fIaddress_match_element\fR; ... }; - allow\-update\-forwarding { \fIaddress_match_element\fR; ... }; - update\-policy { - ( grant | deny ) \fIstring\fR - ( name | subdomain | wildcard | self ) \fIstring\fR - \fIrrtypelist\fR; ... - }; - notify \fInotifytype\fR; - notify\-source ( \fIipv4_address\fR | * ) [ port ( \fIinteger\fR | * ) ]; - notify\-source\-v6 ( \fIipv6_address\fR | * ) [ port ( \fIinteger\fR | * ) ]; - also\-notify [ port \fIinteger\fR ] { ( \fIipv4_address\fR | \fIipv6_address\fR ) - [ port \fIinteger\fR ]; ... }; - allow\-notify { \fIaddress_match_element\fR; ... }; - forward ( first | only ); - forwarders [ port \fIinteger\fR ] { - ( \fIipv4_address\fR | \fIipv6_address\fR ) [ port \fIinteger\fR ]; ... - }; - max\-journal\-size \fIsize_no_default\fR; - max\-transfer\-time\-in \fIinteger\fR; - max\-transfer\-time\-out \fIinteger\fR; - max\-transfer\-idle\-in \fIinteger\fR; - max\-transfer\-idle\-out \fIinteger\fR; - max\-retry\-time \fIinteger\fR; - min\-retry\-time \fIinteger\fR; - max\-refresh\-time \fIinteger\fR; - min\-refresh\-time \fIinteger\fR; - multi\-master \fIboolean\fR; - sig\-validity\-interval \fIinteger\fR; - transfer\-source ( \fIipv4_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - transfer\-source\-v6 ( \fIipv6_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - alt\-transfer\-source ( \fIipv4_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - alt\-transfer\-source\-v6 ( \fIipv6_address\fR | * ) - [ port ( \fIinteger\fR | * ) ]; - use\-alt\-transfer\-source \fIboolean\fR; - zone\-statistics \fIboolean\fR; - key\-directory \fIquoted_string\fR; - ixfr\-base \fIquoted_string\fR; // obsolete - ixfr\-tmp\-file \fIquoted_string\fR; // obsolete - maintain\-ixfr\-base \fIboolean\fR; // obsolete - max\-ixfr\-log\-size \fIsize\fR; // obsolete - pubkey \fIinteger\fR \fIinteger\fR \fIinteger\fR \fIquoted_string\fR; // obsolete -}; -.fi -.SH "FILES" -.PP -\fI/etc/named.conf\fR -.SH "SEE ALSO" -.PP -\fBnamed\fR(8), -\fBrndc\fR(8), -\fBBIND 9 Adminstrators Reference Manual\fR(). diff --git a/contrib/bind9/bin/named/named.conf.docbook b/contrib/bind9/bin/named/named.conf.docbook deleted file mode 100644 index 4ba10844cc32..000000000000 --- a/contrib/bind9/bin/named/named.conf.docbook +++ /dev/null @@ -1,543 +0,0 @@ -<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.0//EN" - "http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd" - [<!ENTITY mdash "—">]> -<!-- - - Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - - - - 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 ISC DISCLAIMS ALL WARRANTIES WITH - - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - - PERFORMANCE OF THIS SOFTWARE. ---> - -<!-- $Id: named.conf.docbook,v 1.1.4.4 2005/05/13 01:22:33 marka Exp $ --> - -<refentry> - <refentryinfo> - <date>Aug 13, 2004</date> - </refentryinfo> - - <refmeta> - <refentrytitle><filename>named.conf</filename></refentrytitle> - <manvolnum>5</manvolnum> - <refmiscinfo>BIND9</refmiscinfo> - </refmeta> - - <docinfo> - <copyright> - <year>2004</year> - <year>2005</year> - <holder>Internet Systems Consortium, Inc. ("ISC")</holder> - </copyright> - </docinfo> - - <refnamediv> - <refname><filename>named.conf</filename></refname> - <refpurpose>configuration file for named</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis> - <command>named.conf</command> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1> - <title>DESCRIPTION</title> - <para> - <filename>named.conf</filename> is the configuration file for - <command>named</command>. Statements are enclosed - in braces and terminated with a semi-colon. Clauses in - the statements are also semi-colon terminated. The usual - comment styles are supported: - </para> - <para> - C style: /* */ - </para> - <para> - C++ style: // to end of line - </para> - <para> - Unix style: # to end of line - </para> - </refsect1> - -<refsect1> -<title>ACL</title> -<literallayout> -acl <replaceable>string</replaceable> { <replaceable>address_match_element</replaceable>; ... }; - -</literallayout> -</refsect1> - -<refsect1> -<title>KEY</title> -<literallayout> -key <replaceable>domain_name</replaceable> { - algorithm <replaceable>string</replaceable>; - secret <replaceable>string</replaceable>; -}; -</literallayout> -</refsect1> - -<refsect1> -<title>MASTERS</title> -<literallayout> -masters <replaceable>string</replaceable> <optional> port <replaceable>integer</replaceable> </optional> { - ( <replaceable>masters</replaceable> | <replaceable>ipv4_address</replaceable> <optional>port <replaceable>integer</replaceable></optional> | - <replaceable>ipv6_address</replaceable> <optional>port <replaceable>integer</replaceable></optional> ) <optional> key <replaceable>string</replaceable> </optional>; ... -}; -</literallayout> -</refsect1> - -<refsect1> -<title>SERVER</title> -<literallayout> -server ( <replaceable>ipv4_address</replaceable> | <replaceable>ipv6_address</replaceable> ) { - bogus <replaceable>boolean</replaceable>; - edns <replaceable>boolean</replaceable>; - provide-ixfr <replaceable>boolean</replaceable>; - request-ixfr <replaceable>boolean</replaceable>; - keys <replaceable>server_key</replaceable>; - transfers <replaceable>integer</replaceable>; - transfer-format ( many-answers | one-answer ); - transfer-source ( <replaceable>ipv4_address</replaceable> | * ) - <optional> port ( <replaceable>integer</replaceable> | * ) </optional>; - transfer-source-v6 ( <replaceable>ipv6_address</replaceable> | * ) - <optional> port ( <replaceable>integer</replaceable> | * ) </optional>; - - support-ixfr <replaceable>boolean</replaceable>; // obsolete -}; -</literallayout> -</refsect1> - -<refsect1> -<title>TRUSTED-KEYS</title> -<literallayout> -trusted-keys { - <replaceable>domain_name</replaceable> <replaceable>flags</replaceable> <replaceable>protocol</replaceable> <replaceable>algorithm</replaceable> <replaceable>key</replaceable>; ... -}; -</literallayout> -</refsect1> - -<refsect1> -<title>CONTROLS</title> -<literallayout> -controls { - inet ( <replaceable>ipv4_address</replaceable> | <replaceable>ipv6_address</replaceable> | * ) - <optional> port ( <replaceable>integer</replaceable> | * ) </optional> - allow { <replaceable>address_match_element</replaceable>; ... } - <optional> keys { <replaceable>string</replaceable>; ... } </optional>; - unix <replaceable>unsupported</replaceable>; // not implemented -}; -</literallayout> -</refsect1> - -<refsect1> -<title>LOGGING</title> -<literallayout> -logging { - channel <replaceable>string</replaceable> { - file <replaceable>log_file</replaceable>; - syslog <replaceable>optional_facility</replaceable>; - null; - stderr; - severity <replaceable>log_severity</replaceable>; - print-time <replaceable>boolean</replaceable>; - print-severity <replaceable>boolean</replaceable>; - print-category <replaceable>boolean</replaceable>; - }; - category <replaceable>string</replaceable> { <replaceable>string</replaceable>; ... }; -}; -</literallayout> -</refsect1> - -<refsect1> -<title>LWRES</title> -<literallayout> -lwres { - listen-on <optional> port <replaceable>integer</replaceable> </optional> { - ( <replaceable>ipv4_address</replaceable> | <replaceable>ipv6_address</replaceable> ) <optional> port <replaceable>integer</replaceable> </optional>; ... - }; - view <replaceable>string</replaceable> <replaceable>optional_class</replaceable>; - search { <replaceable>string</replaceable>; ... }; - ndots <replaceable>integer</replaceable>; -}; -</literallayout> -</refsect1> - -<refsect1> -<title>OPTIONS</title> -<literallayout> -options { - avoid-v4-udp-ports { <replaceable>port</replaceable>; ... }; - avoid-v6-udp-ports { <replaceable>port</replaceable>; ... }; - blackhole { <replaceable>address_match_element</replaceable>; ... }; - coresize <replaceable>size</replaceable>; - datasize <replaceable>size</replaceable>; - directory <replaceable>quoted_string</replaceable>; - dump-file <replaceable>quoted_string</replaceable>; - files <replaceable>size</replaceable>; - heartbeat-interval <replaceable>integer</replaceable>; - host-statistics <replaceable>boolean</replaceable>; // not implemented - host-statistics-max <replaceable>number</replaceable>; // not implemented - hostname ( <replaceable>quoted_string</replaceable> | none ); - interface-interval <replaceable>integer</replaceable>; - listen-on <optional> port <replaceable>integer</replaceable> </optional> { <replaceable>address_match_element</replaceable>; ... }; - listen-on-v6 <optional> port <replaceable>integer</replaceable> </optional> { <replaceable>address_match_element</replaceable>; ... }; - match-mapped-addresses <replaceable>boolean</replaceable>; - memstatistics-file <replaceable>quoted_string</replaceable>; - pid-file ( <replaceable>quoted_string</replaceable> | none ); - port <replaceable>integer</replaceable>; - querylog <replaceable>boolean</replaceable>; - recursing-file <replaceable>quoted_string</replaceable>; - random-device <replaceable>quoted_string</replaceable>; - recursive-clients <replaceable>integer</replaceable>; - serial-query-rate <replaceable>integer</replaceable>; - server-id ( <replaceable>quoted_string</replaceable> | none |; - stacksize <replaceable>size</replaceable>; - statistics-file <replaceable>quoted_string</replaceable>; - statistics-interval <replaceable>integer</replaceable>; // not yet implemented - tcp-clients <replaceable>integer</replaceable>; - tcp-listen-queue <replaceable>integer</replaceable>; - tkey-dhkey <replaceable>quoted_string</replaceable> <replaceable>integer</replaceable>; - tkey-gssapi-credential <replaceable>quoted_string</replaceable>; - tkey-domain <replaceable>quoted_string</replaceable>; - transfers-per-ns <replaceable>integer</replaceable>; - transfers-in <replaceable>integer</replaceable>; - transfers-out <replaceable>integer</replaceable>; - use-ixfr <replaceable>boolean</replaceable>; - version ( <replaceable>quoted_string</replaceable> | none ); - allow-recursion { <replaceable>address_match_element</replaceable>; ... }; - sortlist { <replaceable>address_match_element</replaceable>; ... }; - topology { <replaceable>address_match_element</replaceable>; ... }; // not implemented - auth-nxdomain <replaceable>boolean</replaceable>; // default changed - minimal-responses <replaceable>boolean</replaceable>; - recursion <replaceable>boolean</replaceable>; - rrset-order { - <optional> class <replaceable>string</replaceable> </optional> <optional> type <replaceable>string</replaceable> </optional> - <optional> name <replaceable>quoted_string</replaceable> </optional> <replaceable>string</replaceable> <replaceable>string</replaceable>; ... - }; - provide-ixfr <replaceable>boolean</replaceable>; - request-ixfr <replaceable>boolean</replaceable>; - rfc2308-type1 <replaceable>boolean</replaceable>; // not yet implemented - additional-from-auth <replaceable>boolean</replaceable>; - additional-from-cache <replaceable>boolean</replaceable>; - query-source <replaceable>querysource4</replaceable>; - query-source-v6 <replaceable>querysource6</replaceable>; - cleaning-interval <replaceable>integer</replaceable>; - min-roots <replaceable>integer</replaceable>; // not implemented - lame-ttl <replaceable>integer</replaceable>; - max-ncache-ttl <replaceable>integer</replaceable>; - max-cache-ttl <replaceable>integer</replaceable>; - transfer-format ( many-answers | one-answer ); - max-cache-size <replaceable>size_no_default</replaceable>; - check-names ( master | slave | response ) - ( fail | warn | ignore ); - cache-file <replaceable>quoted_string</replaceable>; - suppress-initial-notify <replaceable>boolean</replaceable>; // not yet implemented - preferred-glue <replaceable>string</replaceable>; - dual-stack-servers <optional> port <replaceable>integer</replaceable> </optional> { - ( <replaceable>quoted_string</replaceable> <optional>port <replaceable>integer</replaceable></optional> | - <replaceable>ipv4_address</replaceable> <optional>port <replaceable>integer</replaceable></optional> | - <replaceable>ipv6_address</replaceable> <optional>port <replaceable>integer</replaceable></optional> ); ... - } - edns-udp-size <replaceable>integer</replaceable>; - root-delegation-only <optional> exclude { <replaceable>quoted_string</replaceable>; ... } </optional>; - disable-algorithms <replaceable>string</replaceable> { <replaceable>string</replaceable>; ... }; - dnssec-enable <replaceable>boolean</replaceable>; - dnssec-lookaside <replaceable>string</replaceable> trust-anchor <replaceable>string</replaceable>; - dnssec-must-be-secure <replaceable>string</replaceable> <replaceable>boolean</replaceable>; - - dialup <replaceable>dialuptype</replaceable>; - ixfr-from-differences <replaceable>ixfrdiff</replaceable>; - - allow-query { <replaceable>address_match_element</replaceable>; ... }; - allow-transfer { <replaceable>address_match_element</replaceable>; ... }; - allow-update-forwarding { <replaceable>address_match_element</replaceable>; ... }; - - notify <replaceable>notifytype</replaceable>; - notify-source ( <replaceable>ipv4_address</replaceable> | * ) <optional> port ( <replaceable>integer</replaceable> | * ) </optional>; - notify-source-v6 ( <replaceable>ipv6_address</replaceable> | * ) <optional> port ( <replaceable>integer</replaceable> | * ) </optional>; - also-notify <optional> port <replaceable>integer</replaceable> </optional> { ( <replaceable>ipv4_address</replaceable> | <replaceable>ipv6_address</replaceable> ) - <optional> port <replaceable>integer</replaceable> </optional>; ... }; - allow-notify { <replaceable>address_match_element</replaceable>; ... }; - - forward ( first | only ); - forwarders <optional> port <replaceable>integer</replaceable> </optional> { - ( <replaceable>ipv4_address</replaceable> | <replaceable>ipv6_address</replaceable> ) <optional> port <replaceable>integer</replaceable> </optional>; ... - }; - - max-journal-size <replaceable>size_no_default</replaceable>; - max-transfer-time-in <replaceable>integer</replaceable>; - max-transfer-time-out <replaceable>integer</replaceable>; - max-transfer-idle-in <replaceable>integer</replaceable>; - max-transfer-idle-out <replaceable>integer</replaceable>; - max-retry-time <replaceable>integer</replaceable>; - min-retry-time <replaceable>integer</replaceable>; - max-refresh-time <replaceable>integer</replaceable>; - min-refresh-time <replaceable>integer</replaceable>; - multi-master <replaceable>boolean</replaceable>; - sig-validity-interval <replaceable>integer</replaceable>; - - transfer-source ( <replaceable>ipv4_address</replaceable> | * ) - <optional> port ( <replaceable>integer</replaceable> | * ) </optional>; - transfer-source-v6 ( <replaceable>ipv6_address</replaceable> | * ) - <optional> port ( <replaceable>integer</replaceable> | * ) </optional>; - - alt-transfer-source ( <replaceable>ipv4_address</replaceable> | * ) - <optional> port ( <replaceable>integer</replaceable> | * ) </optional>; - alt-transfer-source-v6 ( <replaceable>ipv6_address</replaceable> | * ) - <optional> port ( <replaceable>integer</replaceable> | * ) </optional>; - use-alt-transfer-source <replaceable>boolean</replaceable>; - - zone-statistics <replaceable>boolean</replaceable>; - key-directory <replaceable>quoted_string</replaceable>; - - allow-v6-synthesis { <replaceable>address_match_element</replaceable>; ... }; // obsolete - deallocate-on-exit <replaceable>boolean</replaceable>; // obsolete - fake-iquery <replaceable>boolean</replaceable>; // obsolete - fetch-glue <replaceable>boolean</replaceable>; // obsolete - has-old-clients <replaceable>boolean</replaceable>; // obsolete - maintain-ixfr-base <replaceable>boolean</replaceable>; // obsolete - max-ixfr-log-size <replaceable>size</replaceable>; // obsolete - multiple-cnames <replaceable>boolean</replaceable>; // obsolete - named-xfer <replaceable>quoted_string</replaceable>; // obsolete - serial-queries <replaceable>integer</replaceable>; // obsolete - treat-cr-as-space <replaceable>boolean</replaceable>; // obsolete - use-id-pool <replaceable>boolean</replaceable>; // obsolete -}; -</literallayout> -</refsect1> - -<refsect1> -<title>VIEW</title> -<literallayout> -view <replaceable>string</replaceable> <replaceable>optional_class</replaceable> { - match-clients { <replaceable>address_match_element</replaceable>; ... }; - match-destinations { <replaceable>address_match_element</replaceable>; ... }; - match-recursive-only <replaceable>boolean</replaceable>; - - key <replaceable>string</replaceable> { - algorithm <replaceable>string</replaceable>; - secret <replaceable>string</replaceable>; - }; - - zone <replaceable>string</replaceable> <replaceable>optional_class</replaceable> { - ... - }; - - server ( <replaceable>ipv4_address</replaceable> | <replaceable>ipv6_address</replaceable> ) { - ... - }; - - trusted-keys { - <replaceable>string</replaceable> <replaceable>integer</replaceable> <replaceable>integer</replaceable> <replaceable>integer</replaceable> <replaceable>quoted_string</replaceable>; ... - }; - - allow-recursion { <replaceable>address_match_element</replaceable>; ... }; - sortlist { <replaceable>address_match_element</replaceable>; ... }; - topology { <replaceable>address_match_element</replaceable>; ... }; // not implemented - auth-nxdomain <replaceable>boolean</replaceable>; // default changed - minimal-responses <replaceable>boolean</replaceable>; - recursion <replaceable>boolean</replaceable>; - rrset-order { - <optional> class <replaceable>string</replaceable> </optional> <optional> type <replaceable>string</replaceable> </optional> - <optional> name <replaceable>quoted_string</replaceable> </optional> <replaceable>string</replaceable> <replaceable>string</replaceable>; ... - }; - provide-ixfr <replaceable>boolean</replaceable>; - request-ixfr <replaceable>boolean</replaceable>; - rfc2308-type1 <replaceable>boolean</replaceable>; // not yet implemented - additional-from-auth <replaceable>boolean</replaceable>; - additional-from-cache <replaceable>boolean</replaceable>; - query-source <replaceable>querysource4</replaceable>; - query-source-v6 <replaceable>querysource6</replaceable>; - cleaning-interval <replaceable>integer</replaceable>; - min-roots <replaceable>integer</replaceable>; // not implemented - lame-ttl <replaceable>integer</replaceable>; - max-ncache-ttl <replaceable>integer</replaceable>; - max-cache-ttl <replaceable>integer</replaceable>; - transfer-format ( many-answers | one-answer ); - max-cache-size <replaceable>size_no_default</replaceable>; - check-names ( master | slave | response ) - ( fail | warn | ignore ); - cache-file <replaceable>quoted_string</replaceable>; - suppress-initial-notify <replaceable>boolean</replaceable>; // not yet implemented - preferred-glue <replaceable>string</replaceable>; - dual-stack-servers <optional> port <replaceable>integer</replaceable> </optional> { - ( <replaceable>quoted_string</replaceable> <optional>port <replaceable>integer</replaceable></optional> | - <replaceable>ipv4_address</replaceable> <optional>port <replaceable>integer</replaceable></optional> | - <replaceable>ipv6_address</replaceable> <optional>port <replaceable>integer</replaceable></optional> ); ... - }; - edns-udp-size <replaceable>integer</replaceable>; - root-delegation-only <optional> exclude { <replaceable>quoted_string</replaceable>; ... } </optional>; - disable-algorithms <replaceable>string</replaceable> { <replaceable>string</replaceable>; ... }; - dnssec-enable <replaceable>boolean</replaceable>; - dnssec-lookaside <replaceable>string</replaceable> trust-anchor <replaceable>string</replaceable>; - - dnssec-must-be-secure <replaceable>string</replaceable> <replaceable>boolean</replaceable>; - dialup <replaceable>dialuptype</replaceable>; - ixfr-from-differences <replaceable>ixfrdiff</replaceable>; - - allow-query { <replaceable>address_match_element</replaceable>; ... }; - allow-transfer { <replaceable>address_match_element</replaceable>; ... }; - allow-update-forwarding { <replaceable>address_match_element</replaceable>; ... }; - - notify <replaceable>notifytype</replaceable>; - notify-source ( <replaceable>ipv4_address</replaceable> | * ) <optional> port ( <replaceable>integer</replaceable> | * ) </optional>; - notify-source-v6 ( <replaceable>ipv6_address</replaceable> | * ) <optional> port ( <replaceable>integer</replaceable> | * ) </optional>; - also-notify <optional> port <replaceable>integer</replaceable> </optional> { ( <replaceable>ipv4_address</replaceable> | <replaceable>ipv6_address</replaceable> ) - <optional> port <replaceable>integer</replaceable> </optional>; ... }; - allow-notify { <replaceable>address_match_element</replaceable>; ... }; - - forward ( first | only ); - forwarders <optional> port <replaceable>integer</replaceable> </optional> { - ( <replaceable>ipv4_address</replaceable> | <replaceable>ipv6_address</replaceable> ) <optional> port <replaceable>integer</replaceable> </optional>; ... - }; - - max-journal-size <replaceable>size_no_default</replaceable>; - max-transfer-time-in <replaceable>integer</replaceable>; - max-transfer-time-out <replaceable>integer</replaceable>; - max-transfer-idle-in <replaceable>integer</replaceable>; - max-transfer-idle-out <replaceable>integer</replaceable>; - max-retry-time <replaceable>integer</replaceable>; - min-retry-time <replaceable>integer</replaceable>; - max-refresh-time <replaceable>integer</replaceable>; - min-refresh-time <replaceable>integer</replaceable>; - multi-master <replaceable>boolean</replaceable>; - sig-validity-interval <replaceable>integer</replaceable>; - - transfer-source ( <replaceable>ipv4_address</replaceable> | * ) - <optional> port ( <replaceable>integer</replaceable> | * ) </optional>; - transfer-source-v6 ( <replaceable>ipv6_address</replaceable> | * ) - <optional> port ( <replaceable>integer</replaceable> | * ) </optional>; - - alt-transfer-source ( <replaceable>ipv4_address</replaceable> | * ) - <optional> port ( <replaceable>integer</replaceable> | * ) </optional>; - alt-transfer-source-v6 ( <replaceable>ipv6_address</replaceable> | * ) - <optional> port ( <replaceable>integer</replaceable> | * ) </optional>; - use-alt-transfer-source <replaceable>boolean</replaceable>; - - zone-statistics <replaceable>boolean</replaceable>; - key-directory <replaceable>quoted_string</replaceable>; - - allow-v6-synthesis { <replaceable>address_match_element</replaceable>; ... }; // obsolete - fetch-glue <replaceable>boolean</replaceable>; // obsolete - maintain-ixfr-base <replaceable>boolean</replaceable>; // obsolete - max-ixfr-log-size <replaceable>size</replaceable>; // obsolete -}; -</literallayout> -</refsect1> - -<refsect1> -<title>ZONE</title> -<literallayout> -zone <replaceable>string</replaceable> <replaceable>optional_class</replaceable> { - type ( master | slave | stub | hint | - forward | delegation-only ); - file <replaceable>quoted_string</replaceable>; - - masters <optional> port <replaceable>integer</replaceable> </optional> { - ( <replaceable>masters</replaceable> | - <replaceable>ipv4_address</replaceable> <optional>port <replaceable>integer</replaceable></optional> | - <replaceable>ipv6_address</replaceable> <optional> port <replaceable>integer</replaceable> </optional> ) <optional> key <replaceable>string</replaceable> </optional>; ... - }; - - database <replaceable>string</replaceable>; - delegation-only <replaceable>boolean</replaceable>; - check-names ( fail | warn | ignore ); - dialup <replaceable>dialuptype</replaceable>; - ixfr-from-differences <replaceable>boolean</replaceable>; - - allow-query { <replaceable>address_match_element</replaceable>; ... }; - allow-transfer { <replaceable>address_match_element</replaceable>; ... }; - allow-update { <replaceable>address_match_element</replaceable>; ... }; - allow-update-forwarding { <replaceable>address_match_element</replaceable>; ... }; - update-policy { - ( grant | deny ) <replaceable>string</replaceable> - ( name | subdomain | wildcard | self ) <replaceable>string</replaceable> - <replaceable>rrtypelist</replaceable>; ... - }; - - notify <replaceable>notifytype</replaceable>; - notify-source ( <replaceable>ipv4_address</replaceable> | * ) <optional> port ( <replaceable>integer</replaceable> | * ) </optional>; - notify-source-v6 ( <replaceable>ipv6_address</replaceable> | * ) <optional> port ( <replaceable>integer</replaceable> | * ) </optional>; - also-notify <optional> port <replaceable>integer</replaceable> </optional> { ( <replaceable>ipv4_address</replaceable> | <replaceable>ipv6_address</replaceable> ) - <optional> port <replaceable>integer</replaceable> </optional>; ... }; - allow-notify { <replaceable>address_match_element</replaceable>; ... }; - - forward ( first | only ); - forwarders <optional> port <replaceable>integer</replaceable> </optional> { - ( <replaceable>ipv4_address</replaceable> | <replaceable>ipv6_address</replaceable> ) <optional> port <replaceable>integer</replaceable> </optional>; ... - }; - - max-journal-size <replaceable>size_no_default</replaceable>; - max-transfer-time-in <replaceable>integer</replaceable>; - max-transfer-time-out <replaceable>integer</replaceable>; - max-transfer-idle-in <replaceable>integer</replaceable>; - max-transfer-idle-out <replaceable>integer</replaceable>; - max-retry-time <replaceable>integer</replaceable>; - min-retry-time <replaceable>integer</replaceable>; - max-refresh-time <replaceable>integer</replaceable>; - min-refresh-time <replaceable>integer</replaceable>; - multi-master <replaceable>boolean</replaceable>; - sig-validity-interval <replaceable>integer</replaceable>; - - transfer-source ( <replaceable>ipv4_address</replaceable> | * ) - <optional> port ( <replaceable>integer</replaceable> | * ) </optional>; - transfer-source-v6 ( <replaceable>ipv6_address</replaceable> | * ) - <optional> port ( <replaceable>integer</replaceable> | * ) </optional>; - - alt-transfer-source ( <replaceable>ipv4_address</replaceable> | * ) - <optional> port ( <replaceable>integer</replaceable> | * ) </optional>; - alt-transfer-source-v6 ( <replaceable>ipv6_address</replaceable> | * ) - <optional> port ( <replaceable>integer</replaceable> | * ) </optional>; - use-alt-transfer-source <replaceable>boolean</replaceable>; - - zone-statistics <replaceable>boolean</replaceable>; - key-directory <replaceable>quoted_string</replaceable>; - - ixfr-base <replaceable>quoted_string</replaceable>; // obsolete - ixfr-tmp-file <replaceable>quoted_string</replaceable>; // obsolete - maintain-ixfr-base <replaceable>boolean</replaceable>; // obsolete - max-ixfr-log-size <replaceable>size</replaceable>; // obsolete - pubkey <replaceable>integer</replaceable> <replaceable>integer</replaceable> <replaceable>integer</replaceable> <replaceable>quoted_string</replaceable>; // obsolete -}; -</literallayout> -</refsect1> - -<refsect1> -<title>FILES</title> -<para> -<filename>/etc/named.conf</filename> -</para> -</refsect1> - -<refsect1> -<title>SEE ALSO</title> -<para> -<citerefentry> -<refentrytitle>named</refentrytitle><manvolnum>8</manvolnum> -</citerefentry>, -<citerefentry> -<refentrytitle>rndc</refentrytitle><manvolnum>8</manvolnum> -</citerefentry>, -<citerefentry> -<refentrytitle>BIND 9 Adminstrators Reference Manual</refentrytitle> -</citerefentry>. -</para> -</refsect1> - -</refentry> -<!-- - - Local variables: - - mode: sgml - - End: ---> diff --git a/contrib/bind9/bin/named/named.conf.html b/contrib/bind9/bin/named/named.conf.html deleted file mode 100644 index 8b3b517d7d73..000000000000 --- a/contrib/bind9/bin/named/named.conf.html +++ /dev/null @@ -1,500 +0,0 @@ -<!-- - - Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - - - - 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 ISC DISCLAIMS ALL WARRANTIES WITH - - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - - PERFORMANCE OF THIS SOFTWARE. ---> -<!-- $Id: named.conf.html,v 1.1.4.10 2005/10/13 02:33:48 marka Exp $ --> -<html> -<head> -<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> -<title>named.conf</title> -<meta name="generator" content="DocBook XSL Stylesheets V1.69.1"> -</head> -<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en"> -<a name="id2463721"></a><div class="titlepage"></div> -<div class="refnamediv"> -<h2>Name</h2> -<p><code class="filename">named.conf</code> — configuration file for named</p> -</div> -<div class="refsynopsisdiv"> -<h2>Synopsis</h2> -<div class="cmdsynopsis"><p><code class="command">named.conf</code> </p></div> -</div> -<div class="refsect1" lang="en"> -<a name="id2525889"></a><h2>DESCRIPTION</h2> -<p> - <code class="filename">named.conf</code> is the configuration file for - <span><strong class="command">named</strong></span>. Statements are enclosed - in braces and terminated with a semi-colon. Clauses in - the statements are also semi-colon terminated. The usual - comment styles are supported: - </p> -<p> - C style: /* */ - </p> -<p> - C++ style: // to end of line - </p> -<p> - Unix style: # to end of line - </p> -</div> -<div class="refsect1" lang="en"> -<a name="id2525917"></a><h2>ACL</h2> -<div class="literallayout"><p><br> -acl <em class="replaceable"><code>string</code></em> { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> -<br> -</p></div> -</div> -<div class="refsect1" lang="en"> -<a name="id2525933"></a><h2>KEY</h2> -<div class="literallayout"><p><br> -key <em class="replaceable"><code>domain_name</code></em> {<br> - algorithm <em class="replaceable"><code>string</code></em>;<br> - secret <em class="replaceable"><code>string</code></em>;<br> -};<br> -</p></div> -</div> -<div class="refsect1" lang="en"> -<a name="id2525953"></a><h2>MASTERS</h2> -<div class="literallayout"><p><br> -masters <em class="replaceable"><code>string</code></em> [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] {<br> - ( <em class="replaceable"><code>masters</code></em> | <em class="replaceable"><code>ipv4_address</code></em> [<span class="optional">port <em class="replaceable"><code>integer</code></em></span>] |<br> - <em class="replaceable"><code>ipv6_address</code></em> [<span class="optional">port <em class="replaceable"><code>integer</code></em></span>] ) [<span class="optional"> key <em class="replaceable"><code>string</code></em> </span>]; ...<br> -};<br> -</p></div> -</div> -<div class="refsect1" lang="en"> -<a name="id2525998"></a><h2>SERVER</h2> -<div class="literallayout"><p><br> -server ( <em class="replaceable"><code>ipv4_address</code></em> | <em class="replaceable"><code>ipv6_address</code></em> ) {<br> - bogus <em class="replaceable"><code>boolean</code></em>;<br> - edns <em class="replaceable"><code>boolean</code></em>;<br> - provide-ixfr <em class="replaceable"><code>boolean</code></em>;<br> - request-ixfr <em class="replaceable"><code>boolean</code></em>;<br> - keys <em class="replaceable"><code>server_key</code></em>;<br> - transfers <em class="replaceable"><code>integer</code></em>;<br> - transfer-format ( many-answers | one-answer );<br> - transfer-source ( <em class="replaceable"><code>ipv4_address</code></em> | * )<br> - [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>];<br> - transfer-source-v6 ( <em class="replaceable"><code>ipv6_address</code></em> | * )<br> - [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>];<br> -<br> - support-ixfr <em class="replaceable"><code>boolean</code></em>; // obsolete<br> -};<br> -</p></div> -</div> -<div class="refsect1" lang="en"> -<a name="id2526056"></a><h2>TRUSTED-KEYS</h2> -<div class="literallayout"><p><br> -trusted-keys {<br> - <em class="replaceable"><code>domain_name</code></em> <em class="replaceable"><code>flags</code></em> <em class="replaceable"><code>protocol</code></em> <em class="replaceable"><code>algorithm</code></em> <em class="replaceable"><code>key</code></em>; ... <br> -};<br> -</p></div> -</div> -<div class="refsect1" lang="en"> -<a name="id2526082"></a><h2>CONTROLS</h2> -<div class="literallayout"><p><br> -controls {<br> - inet ( <em class="replaceable"><code>ipv4_address</code></em> | <em class="replaceable"><code>ipv6_address</code></em> | * )<br> - [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>]<br> - allow { <em class="replaceable"><code>address_match_element</code></em>; ... }<br> - [<span class="optional"> keys { <em class="replaceable"><code>string</code></em>; ... } </span>];<br> - unix <em class="replaceable"><code>unsupported</code></em>; // not implemented<br> -};<br> -</p></div> -</div> -<div class="refsect1" lang="en"> -<a name="id2526117"></a><h2>LOGGING</h2> -<div class="literallayout"><p><br> -logging {<br> - channel <em class="replaceable"><code>string</code></em> {<br> - file <em class="replaceable"><code>log_file</code></em>;<br> - syslog <em class="replaceable"><code>optional_facility</code></em>;<br> - null;<br> - stderr;<br> - severity <em class="replaceable"><code>log_severity</code></em>;<br> - print-time <em class="replaceable"><code>boolean</code></em>;<br> - print-severity <em class="replaceable"><code>boolean</code></em>;<br> - print-category <em class="replaceable"><code>boolean</code></em>;<br> - };<br> - category <em class="replaceable"><code>string</code></em> { <em class="replaceable"><code>string</code></em>; ... };<br> -};<br> -</p></div> -</div> -<div class="refsect1" lang="en"> -<a name="id2526155"></a><h2>LWRES</h2> -<div class="literallayout"><p><br> -lwres {<br> - listen-on [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] {<br> - ( <em class="replaceable"><code>ipv4_address</code></em> | <em class="replaceable"><code>ipv6_address</code></em> ) [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>]; ...<br> - };<br> - view <em class="replaceable"><code>string</code></em> <em class="replaceable"><code>optional_class</code></em>;<br> - search { <em class="replaceable"><code>string</code></em>; ... };<br> - ndots <em class="replaceable"><code>integer</code></em>;<br> -};<br> -</p></div> -</div> -<div class="refsect1" lang="en"> -<a name="id2526197"></a><h2>OPTIONS</h2> -<div class="literallayout"><p><br> -options {<br> - avoid-v4-udp-ports { <em class="replaceable"><code>port</code></em>; ... };<br> - avoid-v6-udp-ports { <em class="replaceable"><code>port</code></em>; ... };<br> - blackhole { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> - coresize <em class="replaceable"><code>size</code></em>;<br> - datasize <em class="replaceable"><code>size</code></em>;<br> - directory <em class="replaceable"><code>quoted_string</code></em>;<br> - dump-file <em class="replaceable"><code>quoted_string</code></em>;<br> - files <em class="replaceable"><code>size</code></em>;<br> - heartbeat-interval <em class="replaceable"><code>integer</code></em>;<br> - host-statistics <em class="replaceable"><code>boolean</code></em>; // not implemented<br> - host-statistics-max <em class="replaceable"><code>number</code></em>; // not implemented<br> - hostname ( <em class="replaceable"><code>quoted_string</code></em> | none );<br> - interface-interval <em class="replaceable"><code>integer</code></em>;<br> - listen-on [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> - listen-on-v6 [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> - match-mapped-addresses <em class="replaceable"><code>boolean</code></em>;<br> - memstatistics-file <em class="replaceable"><code>quoted_string</code></em>;<br> - pid-file ( <em class="replaceable"><code>quoted_string</code></em> | none );<br> - port <em class="replaceable"><code>integer</code></em>;<br> - querylog <em class="replaceable"><code>boolean</code></em>;<br> - recursing-file <em class="replaceable"><code>quoted_string</code></em>;<br> - random-device <em class="replaceable"><code>quoted_string</code></em>;<br> - recursive-clients <em class="replaceable"><code>integer</code></em>;<br> - serial-query-rate <em class="replaceable"><code>integer</code></em>;<br> - server-id ( <em class="replaceable"><code>quoted_string</code></em> | none |;<br> - stacksize <em class="replaceable"><code>size</code></em>;<br> - statistics-file <em class="replaceable"><code>quoted_string</code></em>;<br> - statistics-interval <em class="replaceable"><code>integer</code></em>; // not yet implemented<br> - tcp-clients <em class="replaceable"><code>integer</code></em>;<br> - tcp-listen-queue <em class="replaceable"><code>integer</code></em>;<br> - tkey-dhkey <em class="replaceable"><code>quoted_string</code></em> <em class="replaceable"><code>integer</code></em>;<br> - tkey-gssapi-credential <em class="replaceable"><code>quoted_string</code></em>;<br> - tkey-domain <em class="replaceable"><code>quoted_string</code></em>;<br> - transfers-per-ns <em class="replaceable"><code>integer</code></em>;<br> - transfers-in <em class="replaceable"><code>integer</code></em>;<br> - transfers-out <em class="replaceable"><code>integer</code></em>;<br> - use-ixfr <em class="replaceable"><code>boolean</code></em>;<br> - version ( <em class="replaceable"><code>quoted_string</code></em> | none );<br> - allow-recursion { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> - sortlist { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> - topology { <em class="replaceable"><code>address_match_element</code></em>; ... }; // not implemented<br> - auth-nxdomain <em class="replaceable"><code>boolean</code></em>; // default changed<br> - minimal-responses <em class="replaceable"><code>boolean</code></em>;<br> - recursion <em class="replaceable"><code>boolean</code></em>;<br> - rrset-order {<br> - [<span class="optional"> class <em class="replaceable"><code>string</code></em> </span>] [<span class="optional"> type <em class="replaceable"><code>string</code></em> </span>]<br> - [<span class="optional"> name <em class="replaceable"><code>quoted_string</code></em> </span>] <em class="replaceable"><code>string</code></em> <em class="replaceable"><code>string</code></em>; ...<br> - };<br> - provide-ixfr <em class="replaceable"><code>boolean</code></em>;<br> - request-ixfr <em class="replaceable"><code>boolean</code></em>;<br> - rfc2308-type1 <em class="replaceable"><code>boolean</code></em>; // not yet implemented<br> - additional-from-auth <em class="replaceable"><code>boolean</code></em>;<br> - additional-from-cache <em class="replaceable"><code>boolean</code></em>;<br> - query-source <em class="replaceable"><code>querysource4</code></em>;<br> - query-source-v6 <em class="replaceable"><code>querysource6</code></em>;<br> - cleaning-interval <em class="replaceable"><code>integer</code></em>;<br> - min-roots <em class="replaceable"><code>integer</code></em>; // not implemented<br> - lame-ttl <em class="replaceable"><code>integer</code></em>;<br> - max-ncache-ttl <em class="replaceable"><code>integer</code></em>;<br> - max-cache-ttl <em class="replaceable"><code>integer</code></em>;<br> - transfer-format ( many-answers | one-answer );<br> - max-cache-size <em class="replaceable"><code>size_no_default</code></em>;<br> - check-names ( master | slave | response )<br> - ( fail | warn | ignore );<br> - cache-file <em class="replaceable"><code>quoted_string</code></em>;<br> - suppress-initial-notify <em class="replaceable"><code>boolean</code></em>; // not yet implemented<br> - preferred-glue <em class="replaceable"><code>string</code></em>;<br> - dual-stack-servers [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] {<br> - ( <em class="replaceable"><code>quoted_string</code></em> [<span class="optional">port <em class="replaceable"><code>integer</code></em></span>] |<br> - <em class="replaceable"><code>ipv4_address</code></em> [<span class="optional">port <em class="replaceable"><code>integer</code></em></span>] |<br> - <em class="replaceable"><code>ipv6_address</code></em> [<span class="optional">port <em class="replaceable"><code>integer</code></em></span>] ); ...<br> - }<br> - edns-udp-size <em class="replaceable"><code>integer</code></em>;<br> - root-delegation-only [<span class="optional"> exclude { <em class="replaceable"><code>quoted_string</code></em>; ... } </span>];<br> - disable-algorithms <em class="replaceable"><code>string</code></em> { <em class="replaceable"><code>string</code></em>; ... };<br> - dnssec-enable <em class="replaceable"><code>boolean</code></em>;<br> - dnssec-lookaside <em class="replaceable"><code>string</code></em> trust-anchor <em class="replaceable"><code>string</code></em>;<br> - dnssec-must-be-secure <em class="replaceable"><code>string</code></em> <em class="replaceable"><code>boolean</code></em>;<br> -<br> - dialup <em class="replaceable"><code>dialuptype</code></em>;<br> - ixfr-from-differences <em class="replaceable"><code>ixfrdiff</code></em>;<br> -<br> - allow-query { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> - allow-transfer { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> - allow-update-forwarding { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> -<br> - notify <em class="replaceable"><code>notifytype</code></em>;<br> - notify-source ( <em class="replaceable"><code>ipv4_address</code></em> | * ) [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>];<br> - notify-source-v6 ( <em class="replaceable"><code>ipv6_address</code></em> | * ) [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>];<br> - also-notify [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] { ( <em class="replaceable"><code>ipv4_address</code></em> | <em class="replaceable"><code>ipv6_address</code></em> )<br> - [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>]; ... };<br> - allow-notify { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> -<br> - forward ( first | only );<br> - forwarders [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] {<br> - ( <em class="replaceable"><code>ipv4_address</code></em> | <em class="replaceable"><code>ipv6_address</code></em> ) [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>]; ...<br> - };<br> -<br> - max-journal-size <em class="replaceable"><code>size_no_default</code></em>;<br> - max-transfer-time-in <em class="replaceable"><code>integer</code></em>;<br> - max-transfer-time-out <em class="replaceable"><code>integer</code></em>;<br> - max-transfer-idle-in <em class="replaceable"><code>integer</code></em>;<br> - max-transfer-idle-out <em class="replaceable"><code>integer</code></em>;<br> - max-retry-time <em class="replaceable"><code>integer</code></em>;<br> - min-retry-time <em class="replaceable"><code>integer</code></em>;<br> - max-refresh-time <em class="replaceable"><code>integer</code></em>;<br> - min-refresh-time <em class="replaceable"><code>integer</code></em>;<br> - multi-master <em class="replaceable"><code>boolean</code></em>;<br> - sig-validity-interval <em class="replaceable"><code>integer</code></em>;<br> -<br> - transfer-source ( <em class="replaceable"><code>ipv4_address</code></em> | * )<br> - [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>];<br> - transfer-source-v6 ( <em class="replaceable"><code>ipv6_address</code></em> | * )<br> - [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>];<br> -<br> - alt-transfer-source ( <em class="replaceable"><code>ipv4_address</code></em> | * )<br> - [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>];<br> - alt-transfer-source-v6 ( <em class="replaceable"><code>ipv6_address</code></em> | * )<br> - [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>];<br> - use-alt-transfer-source <em class="replaceable"><code>boolean</code></em>;<br> -<br> - zone-statistics <em class="replaceable"><code>boolean</code></em>;<br> - key-directory <em class="replaceable"><code>quoted_string</code></em>;<br> -<br> - allow-v6-synthesis { <em class="replaceable"><code>address_match_element</code></em>; ... }; // obsolete<br> - deallocate-on-exit <em class="replaceable"><code>boolean</code></em>; // obsolete<br> - fake-iquery <em class="replaceable"><code>boolean</code></em>; // obsolete<br> - fetch-glue <em class="replaceable"><code>boolean</code></em>; // obsolete<br> - has-old-clients <em class="replaceable"><code>boolean</code></em>; // obsolete<br> - maintain-ixfr-base <em class="replaceable"><code>boolean</code></em>; // obsolete<br> - max-ixfr-log-size <em class="replaceable"><code>size</code></em>; // obsolete<br> - multiple-cnames <em class="replaceable"><code>boolean</code></em>; // obsolete<br> - named-xfer <em class="replaceable"><code>quoted_string</code></em>; // obsolete<br> - serial-queries <em class="replaceable"><code>integer</code></em>; // obsolete<br> - treat-cr-as-space <em class="replaceable"><code>boolean</code></em>; // obsolete<br> - use-id-pool <em class="replaceable"><code>boolean</code></em>; // obsolete<br> -};<br> -</p></div> -</div> -<div class="refsect1" lang="en"> -<a name="id2526858"></a><h2>VIEW</h2> -<div class="literallayout"><p><br> -view <em class="replaceable"><code>string</code></em> <em class="replaceable"><code>optional_class</code></em> {<br> - match-clients { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> - match-destinations { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> - match-recursive-only <em class="replaceable"><code>boolean</code></em>;<br> -<br> - key <em class="replaceable"><code>string</code></em> {<br> - algorithm <em class="replaceable"><code>string</code></em>;<br> - secret <em class="replaceable"><code>string</code></em>;<br> - };<br> -<br> - zone <em class="replaceable"><code>string</code></em> <em class="replaceable"><code>optional_class</code></em> {<br> - ...<br> - };<br> -<br> - server ( <em class="replaceable"><code>ipv4_address</code></em> | <em class="replaceable"><code>ipv6_address</code></em> ) {<br> - ...<br> - };<br> -<br> - trusted-keys {<br> - <em class="replaceable"><code>string</code></em> <em class="replaceable"><code>integer</code></em> <em class="replaceable"><code>integer</code></em> <em class="replaceable"><code>integer</code></em> <em class="replaceable"><code>quoted_string</code></em>; ...<br> - };<br> -<br> - allow-recursion { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> - sortlist { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> - topology { <em class="replaceable"><code>address_match_element</code></em>; ... }; // not implemented<br> - auth-nxdomain <em class="replaceable"><code>boolean</code></em>; // default changed<br> - minimal-responses <em class="replaceable"><code>boolean</code></em>;<br> - recursion <em class="replaceable"><code>boolean</code></em>;<br> - rrset-order {<br> - [<span class="optional"> class <em class="replaceable"><code>string</code></em> </span>] [<span class="optional"> type <em class="replaceable"><code>string</code></em> </span>]<br> - [<span class="optional"> name <em class="replaceable"><code>quoted_string</code></em> </span>] <em class="replaceable"><code>string</code></em> <em class="replaceable"><code>string</code></em>; ...<br> - };<br> - provide-ixfr <em class="replaceable"><code>boolean</code></em>;<br> - request-ixfr <em class="replaceable"><code>boolean</code></em>;<br> - rfc2308-type1 <em class="replaceable"><code>boolean</code></em>; // not yet implemented<br> - additional-from-auth <em class="replaceable"><code>boolean</code></em>;<br> - additional-from-cache <em class="replaceable"><code>boolean</code></em>;<br> - query-source <em class="replaceable"><code>querysource4</code></em>;<br> - query-source-v6 <em class="replaceable"><code>querysource6</code></em>;<br> - cleaning-interval <em class="replaceable"><code>integer</code></em>;<br> - min-roots <em class="replaceable"><code>integer</code></em>; // not implemented<br> - lame-ttl <em class="replaceable"><code>integer</code></em>;<br> - max-ncache-ttl <em class="replaceable"><code>integer</code></em>;<br> - max-cache-ttl <em class="replaceable"><code>integer</code></em>;<br> - transfer-format ( many-answers | one-answer );<br> - max-cache-size <em class="replaceable"><code>size_no_default</code></em>;<br> - check-names ( master | slave | response )<br> - ( fail | warn | ignore );<br> - cache-file <em class="replaceable"><code>quoted_string</code></em>;<br> - suppress-initial-notify <em class="replaceable"><code>boolean</code></em>; // not yet implemented<br> - preferred-glue <em class="replaceable"><code>string</code></em>;<br> - dual-stack-servers [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] {<br> - ( <em class="replaceable"><code>quoted_string</code></em> [<span class="optional">port <em class="replaceable"><code>integer</code></em></span>] |<br> - <em class="replaceable"><code>ipv4_address</code></em> [<span class="optional">port <em class="replaceable"><code>integer</code></em></span>] |<br> - <em class="replaceable"><code>ipv6_address</code></em> [<span class="optional">port <em class="replaceable"><code>integer</code></em></span>] ); ...<br> - };<br> - edns-udp-size <em class="replaceable"><code>integer</code></em>;<br> - root-delegation-only [<span class="optional"> exclude { <em class="replaceable"><code>quoted_string</code></em>; ... } </span>];<br> - disable-algorithms <em class="replaceable"><code>string</code></em> { <em class="replaceable"><code>string</code></em>; ... };<br> - dnssec-enable <em class="replaceable"><code>boolean</code></em>;<br> - dnssec-lookaside <em class="replaceable"><code>string</code></em> trust-anchor <em class="replaceable"><code>string</code></em>;<br> -<br> - dnssec-must-be-secure <em class="replaceable"><code>string</code></em> <em class="replaceable"><code>boolean</code></em>;<br> - dialup <em class="replaceable"><code>dialuptype</code></em>;<br> - ixfr-from-differences <em class="replaceable"><code>ixfrdiff</code></em>;<br> -<br> - allow-query { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> - allow-transfer { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> - allow-update-forwarding { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> -<br> - notify <em class="replaceable"><code>notifytype</code></em>;<br> - notify-source ( <em class="replaceable"><code>ipv4_address</code></em> | * ) [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>];<br> - notify-source-v6 ( <em class="replaceable"><code>ipv6_address</code></em> | * ) [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>];<br> - also-notify [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] { ( <em class="replaceable"><code>ipv4_address</code></em> | <em class="replaceable"><code>ipv6_address</code></em> )<br> - [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>]; ... };<br> - allow-notify { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> -<br> - forward ( first | only );<br> - forwarders [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] {<br> - ( <em class="replaceable"><code>ipv4_address</code></em> | <em class="replaceable"><code>ipv6_address</code></em> ) [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>]; ...<br> - };<br> -<br> - max-journal-size <em class="replaceable"><code>size_no_default</code></em>;<br> - max-transfer-time-in <em class="replaceable"><code>integer</code></em>;<br> - max-transfer-time-out <em class="replaceable"><code>integer</code></em>;<br> - max-transfer-idle-in <em class="replaceable"><code>integer</code></em>;<br> - max-transfer-idle-out <em class="replaceable"><code>integer</code></em>;<br> - max-retry-time <em class="replaceable"><code>integer</code></em>;<br> - min-retry-time <em class="replaceable"><code>integer</code></em>;<br> - max-refresh-time <em class="replaceable"><code>integer</code></em>;<br> - min-refresh-time <em class="replaceable"><code>integer</code></em>;<br> - multi-master <em class="replaceable"><code>boolean</code></em>;<br> - sig-validity-interval <em class="replaceable"><code>integer</code></em>;<br> -<br> - transfer-source ( <em class="replaceable"><code>ipv4_address</code></em> | * )<br> - [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>];<br> - transfer-source-v6 ( <em class="replaceable"><code>ipv6_address</code></em> | * )<br> - [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>];<br> -<br> - alt-transfer-source ( <em class="replaceable"><code>ipv4_address</code></em> | * )<br> - [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>];<br> - alt-transfer-source-v6 ( <em class="replaceable"><code>ipv6_address</code></em> | * )<br> - [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>];<br> - use-alt-transfer-source <em class="replaceable"><code>boolean</code></em>;<br> -<br> - zone-statistics <em class="replaceable"><code>boolean</code></em>;<br> - key-directory <em class="replaceable"><code>quoted_string</code></em>;<br> -<br> - allow-v6-synthesis { <em class="replaceable"><code>address_match_element</code></em>; ... }; // obsolete<br> - fetch-glue <em class="replaceable"><code>boolean</code></em>; // obsolete<br> - maintain-ixfr-base <em class="replaceable"><code>boolean</code></em>; // obsolete<br> - max-ixfr-log-size <em class="replaceable"><code>size</code></em>; // obsolete<br> -};<br> -</p></div> -</div> -<div class="refsect1" lang="en"> -<a name="id2527269"></a><h2>ZONE</h2> -<div class="literallayout"><p><br> -zone <em class="replaceable"><code>string</code></em> <em class="replaceable"><code>optional_class</code></em> {<br> - type ( master | slave | stub | hint |<br> - forward | delegation-only );<br> - file <em class="replaceable"><code>quoted_string</code></em>;<br> -<br> - masters [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] {<br> - ( <em class="replaceable"><code>masters</code></em> |<br> - <em class="replaceable"><code>ipv4_address</code></em> [<span class="optional">port <em class="replaceable"><code>integer</code></em></span>] |<br> - <em class="replaceable"><code>ipv6_address</code></em> [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] ) [<span class="optional"> key <em class="replaceable"><code>string</code></em> </span>]; ...<br> - };<br> -<br> - database <em class="replaceable"><code>string</code></em>;<br> - delegation-only <em class="replaceable"><code>boolean</code></em>;<br> - check-names ( fail | warn | ignore );<br> - dialup <em class="replaceable"><code>dialuptype</code></em>;<br> - ixfr-from-differences <em class="replaceable"><code>boolean</code></em>;<br> -<br> - allow-query { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> - allow-transfer { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> - allow-update { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> - allow-update-forwarding { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> - update-policy {<br> - ( grant | deny ) <em class="replaceable"><code>string</code></em><br> - ( name | subdomain | wildcard | self ) <em class="replaceable"><code>string</code></em><br> - <em class="replaceable"><code>rrtypelist</code></em>; ...<br> - };<br> -<br> - notify <em class="replaceable"><code>notifytype</code></em>;<br> - notify-source ( <em class="replaceable"><code>ipv4_address</code></em> | * ) [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>];<br> - notify-source-v6 ( <em class="replaceable"><code>ipv6_address</code></em> | * ) [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>];<br> - also-notify [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] { ( <em class="replaceable"><code>ipv4_address</code></em> | <em class="replaceable"><code>ipv6_address</code></em> )<br> - [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>]; ... };<br> - allow-notify { <em class="replaceable"><code>address_match_element</code></em>; ... };<br> -<br> - forward ( first | only );<br> - forwarders [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] {<br> - ( <em class="replaceable"><code>ipv4_address</code></em> | <em class="replaceable"><code>ipv6_address</code></em> ) [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>]; ...<br> - };<br> -<br> - max-journal-size <em class="replaceable"><code>size_no_default</code></em>;<br> - max-transfer-time-in <em class="replaceable"><code>integer</code></em>;<br> - max-transfer-time-out <em class="replaceable"><code>integer</code></em>;<br> - max-transfer-idle-in <em class="replaceable"><code>integer</code></em>;<br> - max-transfer-idle-out <em class="replaceable"><code>integer</code></em>;<br> - max-retry-time <em class="replaceable"><code>integer</code></em>;<br> - min-retry-time <em class="replaceable"><code>integer</code></em>;<br> - max-refresh-time <em class="replaceable"><code>integer</code></em>;<br> - min-refresh-time <em class="replaceable"><code>integer</code></em>;<br> - multi-master <em class="replaceable"><code>boolean</code></em>;<br> - sig-validity-interval <em class="replaceable"><code>integer</code></em>;<br> -<br> - transfer-source ( <em class="replaceable"><code>ipv4_address</code></em> | * )<br> - [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>];<br> - transfer-source-v6 ( <em class="replaceable"><code>ipv6_address</code></em> | * )<br> - [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>];<br> -<br> - alt-transfer-source ( <em class="replaceable"><code>ipv4_address</code></em> | * )<br> - [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>];<br> - alt-transfer-source-v6 ( <em class="replaceable"><code>ipv6_address</code></em> | * )<br> - [<span class="optional"> port ( <em class="replaceable"><code>integer</code></em> | * ) </span>];<br> - use-alt-transfer-source <em class="replaceable"><code>boolean</code></em>;<br> -<br> - zone-statistics <em class="replaceable"><code>boolean</code></em>;<br> - key-directory <em class="replaceable"><code>quoted_string</code></em>;<br> -<br> - ixfr-base <em class="replaceable"><code>quoted_string</code></em>; // obsolete<br> - ixfr-tmp-file <em class="replaceable"><code>quoted_string</code></em>; // obsolete<br> - maintain-ixfr-base <em class="replaceable"><code>boolean</code></em>; // obsolete<br> - max-ixfr-log-size <em class="replaceable"><code>size</code></em>; // obsolete<br> - pubkey <em class="replaceable"><code>integer</code></em> <em class="replaceable"><code>integer</code></em> <em class="replaceable"><code>integer</code></em> <em class="replaceable"><code>quoted_string</code></em>; // obsolete<br> -};<br> -</p></div> -</div> -<div class="refsect1" lang="en"> -<a name="id2527606"></a><h2>FILES</h2> -<p> -<code class="filename">/etc/named.conf</code> -</p> -</div> -<div class="refsect1" lang="en"> -<a name="id2527619"></a><h2>SEE ALSO</h2> -<p> -<span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>, -<span class="citerefentry"><span class="refentrytitle">rndc</span>(8)</span>, -<span class="citerefentry"><span class="refentrytitle">BIND 9 Adminstrators Reference Manual</span></span>. -</p> -</div> -</div></body> -</html> diff --git a/contrib/bind9/bin/named/named.docbook b/contrib/bind9/bin/named/named.docbook deleted file mode 100644 index 47ccf54b38e8..000000000000 --- a/contrib/bind9/bin/named/named.docbook +++ /dev/null @@ -1,386 +0,0 @@ -<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.0//EN" - "http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd" - [<!ENTITY mdash "—">]> -<!-- - - Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - - Copyright (C) 2000, 2001, 2003 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 ISC DISCLAIMS ALL WARRANTIES WITH - - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - - PERFORMANCE OF THIS SOFTWARE. ---> - -<!-- $Id: named.docbook,v 1.5.98.5 2005/05/13 01:22:33 marka Exp $ --> - -<refentry> - <refentryinfo> - <date>June 30, 2000</date> - </refentryinfo> - - <refmeta> - <refentrytitle><application>named</application></refentrytitle> - <manvolnum>8</manvolnum> - <refmiscinfo>BIND9</refmiscinfo> - </refmeta> - - <docinfo> - <copyright> - <year>2004</year> - <year>2005</year> - <holder>Internet Systems Consortium, Inc. ("ISC")</holder> - </copyright> - <copyright> - <year>2000</year> - <year>2001</year> - <year>2003</year> - <holder>Internet Software Consortium.</holder> - </copyright> - </docinfo> - - <refnamediv> - <refname><application>named</application></refname> - <refpurpose>Internet domain name server</refpurpose> - </refnamediv> - - <refsynopsisdiv> - <cmdsynopsis> - <command>named</command> - <arg><option>-4</option></arg> - <arg><option>-6</option></arg> - <arg><option>-c <replaceable class="parameter">config-file</replaceable></option></arg> - <arg><option>-d <replaceable class="parameter">debug-level</replaceable></option></arg> - <arg><option>-f</option></arg> - <arg><option>-g</option></arg> - <arg><option>-n <replaceable class="parameter">#cpus</replaceable></option></arg> - <arg><option>-p <replaceable class="parameter">port</replaceable></option></arg> - <arg><option>-s</option></arg> - <arg><option>-t <replaceable class="parameter">directory</replaceable></option></arg> - <arg><option>-u <replaceable class="parameter">user</replaceable></option></arg> - <arg><option>-v</option></arg> - <arg><option>-x <replaceable class="parameter">cache-file</replaceable></option></arg> - </cmdsynopsis> - </refsynopsisdiv> - - <refsect1> - <title>DESCRIPTION</title> - <para> - <command>named</command> is a Domain Name System (DNS) server, - part of the BIND 9 distribution from ISC. For more - information on the DNS, see RFCs 1033, 1034, and 1035. - </para> - <para> - When invoked without arguments, <command>named</command> will - read the default configuration file - <filename>/etc/named.conf</filename>, read any initial - data, and listen for queries. - </para> - </refsect1> - - <refsect1> - <title>OPTIONS</title> - - <variablelist> - <varlistentry> - <term>-4</term> - <listitem> - <para> - Use IPv4 only even if the host machine is capable of IPv6. - <option>-4</option> and <option>-6</option> are mutually - exclusive. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>-6</term> - <listitem> - <para> - Use IPv6 only even if the host machine is capable of IPv4. - <option>-4</option> and <option>-6</option> are mutually - exclusive. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term>-c <replaceable class="parameter">config-file</replaceable></term> - <listitem> - <para> - Use <replaceable - class="parameter">config-file</replaceable> as the - configuration file instead of the default, - <filename>/etc/named.conf</filename>. To - ensure that reloading the configuration file continues - to work after the server has changed its working - directory due to to a possible - <option>directory</option> option in the configuration - file, <replaceable - class="parameter">config-file</replaceable> should be - an absolute pathname. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>-d <replaceable class="parameter">debug-level</replaceable></term> - <listitem> - <para> - Set the daemon's debug level to <replaceable - class="parameter">debug-level</replaceable>. - Debugging traces from <command>named</command> become - more verbose as the debug level increases. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>-f</term> - <listitem> - <para> - Run the server in the foreground (i.e. do not daemonize). - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>-g</term> - <listitem> - <para> - Run the server in the foreground and force all logging - to <filename>stderr</filename>. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>-n <replaceable class="parameter">#cpus</replaceable></term> - <listitem> - <para> - Create <replaceable - class="parameter">#cpus</replaceable> worker threads - to take advantage of multiple CPUs. If not specified, - <command>named</command> will try to determine the - number of CPUs present and create one thread per CPU. - If it is unable to determine the number of CPUs, a - single worker thread will be created. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>-p <replaceable class="parameter">port</replaceable></term> - <listitem> - <para> - Listen for queries on port <replaceable - class="parameter">port</replaceable>. If not - specified, the default is port 53. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>-s</term> - <listitem> - <para> - Write memory usage statistics to <filename>stdout</filename> on exit. - </para> - <note> - <para> - This option is mainly of interest to BIND 9 developers - and may be removed or changed in a future release. - </para> - </note> - </listitem> - </varlistentry> - - <varlistentry> - <term>-t <replaceable class="parameter">directory</replaceable></term> - <listitem> - <para> - <function>chroot()</function> to <replaceable - class="parameter">directory</replaceable> after - processing the command line arguments, but before - reading the configuration file. - </para> - <warning> - <para> - This option should be used in conjunction with the - <option>-u</option> option, as chrooting a process - running as root doesn't enhance security on most - systems; the way <function>chroot()</function> is - defined allows a process with root privileges to - escape a chroot jail. - </para> - </warning> - </listitem> - </varlistentry> - - <varlistentry> - <term>-u <replaceable class="parameter">user</replaceable></term> - <listitem> - <para> - <function>setuid()</function> to <replaceable - class="parameter">user</replaceable> after completing - privileged operations, such as creating sockets that - listen on privileged ports. - </para> - <note> - <para> - On Linux, <command>named</command> uses the kernel's - capability mechanism to drop all root privileges - except the ability to <function>bind()</function> to a - privileged port and set process resource limits. - Unfortunately, this means that the <option>-u</option> - option only works when <command>named</command> is run - on kernel 2.2.18 or later, or kernel 2.3.99-pre3 or - later, since previous kernels did not allow privileges - to be retained after <function>setuid()</function>. - </para> - </note> - </listitem> - </varlistentry> - - <varlistentry> - <term>-v</term> - <listitem> - <para> - Report the version number and exit. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>-x <replaceable class="parameter">cache-file</replaceable></term> - <listitem> - <para> - Load data from <replaceable - class="parameter">cache-file</replaceable> into the - cache of the default view. - </para> - <warning> - <para> - This option must not be used. It is only of interest - to BIND 9 developers and may be removed or changed in a - future release. - </para> - </warning> - </listitem> - </varlistentry> - - </variablelist> - - </refsect1> - - <refsect1> - <title>SIGNALS</title> - <para> - In routine operation, signals should not be used to control - the nameserver; <command>rndc</command> should be used - instead. - </para> - - <variablelist> - - <varlistentry> - <term>SIGHUP</term> - <listitem> - <para> - Force a reload of the server. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term>SIGINT, SIGTERM</term> - <listitem> - <para> - Shut down the server. - </para> - </listitem> - </varlistentry> - - </variablelist> - - <para> - The result of sending any other signals to the server is undefined. - </para> - - </refsect1> - - <refsect1> - <title>CONFIGURATION</title> - <para> - The <command>named</command> configuration file is too complex - to describe in detail here. A complete description is - provided in the <citetitle>BIND 9 Administrator Reference - Manual</citetitle>. - </para> - </refsect1> - - <refsect1> - <title>FILES</title> - - <variablelist> - - <varlistentry> - <term><filename>/etc/named.conf</filename></term> - <listitem> - <para> - The default configuration file. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term><filename>/var/run/named.pid</filename></term> - <listitem> - <para> - The default process-id file. - </para> - </listitem> - </varlistentry> - - </variablelist> - - </refsect1> - - <refsect1> - <title>SEE ALSO</title> - <para> - <citetitle>RFC 1033</citetitle>, - <citetitle>RFC 1034</citetitle>, - <citetitle>RFC 1035</citetitle>, - <citerefentry> - <refentrytitle>rndc</refentrytitle> - <manvolnum>8</manvolnum> - </citerefentry>, - <citerefentry> - <refentrytitle>lwresd</refentrytitle> - <manvolnum>8</manvolnum> - </citerefentry>, - <citetitle>BIND 9 Administrator Reference Manual</citetitle>. - </para> - </refsect1> - - <refsect1> - <title>AUTHOR</title> - <para> - <corpauthor>Internet Systems Consortium</corpauthor> - </para> - </refsect1> - -</refentry> - - -<!-- - - Local variables: - - mode: sgml - - End: ---> diff --git a/contrib/bind9/bin/named/named.html b/contrib/bind9/bin/named/named.html deleted file mode 100644 index f266e70af554..000000000000 --- a/contrib/bind9/bin/named/named.html +++ /dev/null @@ -1,240 +0,0 @@ -<!-- - - Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - - Copyright (C) 2000, 2001, 2003 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 ISC DISCLAIMS ALL WARRANTIES WITH - - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - - PERFORMANCE OF THIS SOFTWARE. ---> -<!-- $Id: named.html,v 1.4.2.1.4.9 2005/10/13 02:33:47 marka Exp $ --> -<html> -<head> -<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> -<title>named</title> -<meta name="generator" content="DocBook XSL Stylesheets V1.69.1"> -</head> -<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en"> -<a name="id2463721"></a><div class="titlepage"></div> -<div class="refnamediv"> -<h2>Name</h2> -<p><span class="application">named</span> — Internet domain name server</p> -</div> -<div class="refsynopsisdiv"> -<h2>Synopsis</h2> -<div class="cmdsynopsis"><p><code class="command">named</code> [<code class="option">-4</code>] [<code class="option">-6</code>] [<code class="option">-c <em class="replaceable"><code>config-file</code></em></code>] [<code class="option">-d <em class="replaceable"><code>debug-level</code></em></code>] [<code class="option">-f</code>] [<code class="option">-g</code>] [<code class="option">-n <em class="replaceable"><code>#cpus</code></em></code>] [<code class="option">-p <em class="replaceable"><code>port</code></em></code>] [<code class="option">-s</code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-u <em class="replaceable"><code>user</code></em></code>] [<code class="option">-v</code>] [<code class="option">-x <em class="replaceable"><code>cache-file</code></em></code>]</p></div> -</div> -<div class="refsect1" lang="en"> -<a name="id2525923"></a><h2>DESCRIPTION</h2> -<p> - <span><strong class="command">named</strong></span> is a Domain Name System (DNS) server, - part of the BIND 9 distribution from ISC. For more - information on the DNS, see RFCs 1033, 1034, and 1035. - </p> -<p> - When invoked without arguments, <span><strong class="command">named</strong></span> will - read the default configuration file - <code class="filename">/etc/named.conf</code>, read any initial - data, and listen for queries. - </p> -</div> -<div class="refsect1" lang="en"> -<a name="id2525948"></a><h2>OPTIONS</h2> -<div class="variablelist"><dl> -<dt><span class="term">-4</span></dt> -<dd><p> - Use IPv4 only even if the host machine is capable of IPv6. - <code class="option">-4</code> and <code class="option">-6</code> are mutually - exclusive. - </p></dd> -<dt><span class="term">-6</span></dt> -<dd><p> - Use IPv6 only even if the host machine is capable of IPv4. - <code class="option">-4</code> and <code class="option">-6</code> are mutually - exclusive. - </p></dd> -<dt><span class="term">-c <em class="replaceable"><code>config-file</code></em></span></dt> -<dd><p> - Use <em class="replaceable"><code>config-file</code></em> as the - configuration file instead of the default, - <code class="filename">/etc/named.conf</code>. To - ensure that reloading the configuration file continues - to work after the server has changed its working - directory due to to a possible - <code class="option">directory</code> option in the configuration - file, <em class="replaceable"><code>config-file</code></em> should be - an absolute pathname. - </p></dd> -<dt><span class="term">-d <em class="replaceable"><code>debug-level</code></em></span></dt> -<dd><p> - Set the daemon's debug level to <em class="replaceable"><code>debug-level</code></em>. - Debugging traces from <span><strong class="command">named</strong></span> become - more verbose as the debug level increases. - </p></dd> -<dt><span class="term">-f</span></dt> -<dd><p> - Run the server in the foreground (i.e. do not daemonize). - </p></dd> -<dt><span class="term">-g</span></dt> -<dd><p> - Run the server in the foreground and force all logging - to <code class="filename">stderr</code>. - </p></dd> -<dt><span class="term">-n <em class="replaceable"><code>#cpus</code></em></span></dt> -<dd><p> - Create <em class="replaceable"><code>#cpus</code></em> worker threads - to take advantage of multiple CPUs. If not specified, - <span><strong class="command">named</strong></span> will try to determine the - number of CPUs present and create one thread per CPU. - If it is unable to determine the number of CPUs, a - single worker thread will be created. - </p></dd> -<dt><span class="term">-p <em class="replaceable"><code>port</code></em></span></dt> -<dd><p> - Listen for queries on port <em class="replaceable"><code>port</code></em>. If not - specified, the default is port 53. - </p></dd> -<dt><span class="term">-s</span></dt> -<dd> -<p> - Write memory usage statistics to <code class="filename">stdout</code> on exit. - </p> -<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"> -<h3 class="title">Note</h3> -<p> - This option is mainly of interest to BIND 9 developers - and may be removed or changed in a future release. - </p> -</div> -</dd> -<dt><span class="term">-t <em class="replaceable"><code>directory</code></em></span></dt> -<dd> -<p> - <code class="function">chroot()</code> to <em class="replaceable"><code>directory</code></em> after - processing the command line arguments, but before - reading the configuration file. - </p> -<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;"> -<h3 class="title">Warning</h3> -<p> - This option should be used in conjunction with the - <code class="option">-u</code> option, as chrooting a process - running as root doesn't enhance security on most - systems; the way <code class="function">chroot()</code> is - defined allows a process with root privileges to - escape a chroot jail. - </p> -</div> -</dd> -<dt><span class="term">-u <em class="replaceable"><code>user</code></em></span></dt> -<dd> -<p> - <code class="function">setuid()</code> to <em class="replaceable"><code>user</code></em> after completing - privileged operations, such as creating sockets that - listen on privileged ports. - </p> -<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"> -<h3 class="title">Note</h3> -<p> - On Linux, <span><strong class="command">named</strong></span> uses the kernel's - capability mechanism to drop all root privileges - except the ability to <code class="function">bind()</code> to a - privileged port and set process resource limits. - Unfortunately, this means that the <code class="option">-u</code> - option only works when <span><strong class="command">named</strong></span> is run - on kernel 2.2.18 or later, or kernel 2.3.99-pre3 or - later, since previous kernels did not allow privileges - to be retained after <code class="function">setuid()</code>. - </p> -</div> -</dd> -<dt><span class="term">-v</span></dt> -<dd><p> - Report the version number and exit. - </p></dd> -<dt><span class="term">-x <em class="replaceable"><code>cache-file</code></em></span></dt> -<dd> -<p> - Load data from <em class="replaceable"><code>cache-file</code></em> into the - cache of the default view. - </p> -<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;"> -<h3 class="title">Warning</h3> -<p> - This option must not be used. It is only of interest - to BIND 9 developers and may be removed or changed in a - future release. - </p> -</div> -</dd> -</dl></div> -</div> -<div class="refsect1" lang="en"> -<a name="id2526297"></a><h2>SIGNALS</h2> -<p> - In routine operation, signals should not be used to control - the nameserver; <span><strong class="command">rndc</strong></span> should be used - instead. - </p> -<div class="variablelist"><dl> -<dt><span class="term">SIGHUP</span></dt> -<dd><p> - Force a reload of the server. - </p></dd> -<dt><span class="term">SIGINT, SIGTERM</span></dt> -<dd><p> - Shut down the server. - </p></dd> -</dl></div> -<p> - The result of sending any other signals to the server is undefined. - </p> -</div> -<div class="refsect1" lang="en"> -<a name="id2526412"></a><h2>CONFIGURATION</h2> -<p> - The <span><strong class="command">named</strong></span> configuration file is too complex - to describe in detail here. A complete description is - provided in the <em class="citetitle">BIND 9 Administrator Reference - Manual</em>. - </p> -</div> -<div class="refsect1" lang="en"> -<a name="id2526429"></a><h2>FILES</h2> -<div class="variablelist"><dl> -<dt><span class="term"><code class="filename">/etc/named.conf</code></span></dt> -<dd><p> - The default configuration file. - </p></dd> -<dt><span class="term"><code class="filename">/var/run/named.pid</code></span></dt> -<dd><p> - The default process-id file. - </p></dd> -</dl></div> -</div> -<div class="refsect1" lang="en"> -<a name="id2526469"></a><h2>SEE ALSO</h2> -<p> - <em class="citetitle">RFC 1033</em>, - <em class="citetitle">RFC 1034</em>, - <em class="citetitle">RFC 1035</em>, - <span class="citerefentry"><span class="refentrytitle">rndc</span>(8)</span>, - <span class="citerefentry"><span class="refentrytitle">lwresd</span>(8)</span>, - <em class="citetitle">BIND 9 Administrator Reference Manual</em>. - </p> -</div> -<div class="refsect1" lang="en"> -<a name="id2526512"></a><h2>AUTHOR</h2> -<p> - <span class="corpauthor">Internet Systems Consortium</span> - </p> -</div> -</div></body> -</html> diff --git a/contrib/bind9/bin/named/notify.c b/contrib/bind9/bin/named/notify.c deleted file mode 100644 index e3c5b2a8987e..000000000000 --- a/contrib/bind9/bin/named/notify.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: notify.c,v 1.24.2.2.2.7 2004/08/28 06:25:30 marka Exp $ */ - -#include <config.h> - -#include <isc/log.h> -#include <isc/print.h> - -#include <dns/message.h> -#include <dns/rdataset.h> -#include <dns/result.h> -#include <dns/view.h> -#include <dns/zone.h> -#include <dns/zt.h> - -#include <named/log.h> -#include <named/notify.h> - -/* - * This module implements notify as in RFC 1996. - */ - -static void -notify_log(ns_client_t *client, int level, const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - ns_client_logv(client, DNS_LOGCATEGORY_NOTIFY, NS_LOGMODULE_NOTIFY, - level, fmt, ap); - va_end(ap); -} - -static void -respond(ns_client_t *client, isc_result_t result) { - dns_rcode_t rcode; - dns_message_t *message; - isc_result_t msg_result; - - message = client->message; - rcode = dns_result_torcode(result); - - msg_result = dns_message_reply(message, ISC_TRUE); - if (msg_result != ISC_R_SUCCESS) - msg_result = dns_message_reply(message, ISC_FALSE); - if (msg_result != ISC_R_SUCCESS) { - ns_client_next(client, msg_result); - return; - } - message->rcode = rcode; - if (rcode == dns_rcode_noerror) - message->flags |= DNS_MESSAGEFLAG_AA; - else - message->flags &= ~DNS_MESSAGEFLAG_AA; - ns_client_send(client); -} - -void -ns_notify_start(ns_client_t *client) { - dns_message_t *request = client->message; - isc_result_t result; - dns_name_t *zonename; - dns_rdataset_t *zone_rdataset; - dns_zone_t *zone = NULL; - char namebuf[DNS_NAME_FORMATSIZE]; - char tsigbuf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")]; - dns_name_t *tsigname; - - /* - * Interpret the question section. - */ - result = dns_message_firstname(request, DNS_SECTION_QUESTION); - if (result != ISC_R_SUCCESS) { - notify_log(client, ISC_LOG_NOTICE, - "notify question section empty"); - goto formerr; - } - - /* - * The question section must contain exactly one question. - */ - zonename = NULL; - dns_message_currentname(request, DNS_SECTION_QUESTION, &zonename); - zone_rdataset = ISC_LIST_HEAD(zonename->list); - if (ISC_LIST_NEXT(zone_rdataset, link) != NULL) { - notify_log(client, ISC_LOG_NOTICE, - "notify question section contains multiple RRs"); - goto formerr; - } - - /* The zone section must have exactly one name. */ - result = dns_message_nextname(request, DNS_SECTION_ZONE); - if (result != ISC_R_NOMORE) { - notify_log(client, ISC_LOG_NOTICE, - "notify question section contains multiple RRs"); - goto formerr; - } - - /* The one rdataset must be an SOA. */ - if (zone_rdataset->type != dns_rdatatype_soa) { - notify_log(client, ISC_LOG_NOTICE, - "notify question section contains no SOA"); - goto formerr; - } - - tsigname = NULL; - if (dns_message_gettsig(request, &tsigname) != NULL) { - dns_name_format(tsigname, namebuf, sizeof(namebuf)); - snprintf(tsigbuf, sizeof(tsigbuf), ": TSIG '%s'", namebuf); - } else - tsigbuf[0] = '\0'; - dns_name_format(zonename, namebuf, sizeof(namebuf)); - result = dns_zt_find(client->view->zonetable, zonename, 0, NULL, - &zone); - if (result != ISC_R_SUCCESS) - goto notauth; - - switch (dns_zone_gettype(zone)) { - case dns_zone_master: - case dns_zone_slave: - case dns_zone_stub: /* Allow dialup passive to work. */ - notify_log(client, ISC_LOG_INFO, - "received notify for zone '%s'%s", namebuf, tsigbuf); - respond(client, dns_zone_notifyreceive(zone, - ns_client_getsockaddr(client), request)); - break; - default: - goto notauth; - } - dns_zone_detach(&zone); - return; - - notauth: - notify_log(client, ISC_LOG_NOTICE, - "received notify for zone '%s'%s: not authoritative", - namebuf, tsigbuf); - result = DNS_R_NOTAUTH; - goto failure; - - formerr: - result = DNS_R_FORMERR; - - failure: - if (zone != NULL) - dns_zone_detach(&zone); - respond(client, result); -} diff --git a/contrib/bind9/bin/named/server.c b/contrib/bind9/bin/named/server.c deleted file mode 100644 index b9d30d02f644..000000000000 --- a/contrib/bind9/bin/named/server.c +++ /dev/null @@ -1,4153 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: server.c,v 1.339.2.15.2.65 2005/07/27 02:53:15 marka Exp $ */ - -#include <config.h> - -#include <stdlib.h> - -#include <isc/app.h> -#include <isc/base64.h> -#include <isc/dir.h> -#include <isc/entropy.h> -#include <isc/file.h> -#include <isc/hash.h> -#include <isc/lex.h> -#include <isc/parseint.h> -#include <isc/print.h> -#include <isc/resource.h> -#include <isc/stdio.h> -#include <isc/string.h> -#include <isc/task.h> -#include <isc/timer.h> -#include <isc/util.h> - -#include <isccfg/namedconf.h> - -#include <bind9/check.h> - -#include <dns/adb.h> -#include <dns/cache.h> -#include <dns/db.h> -#include <dns/dispatch.h> -#include <dns/forward.h> -#include <dns/journal.h> -#include <dns/keytable.h> -#include <dns/master.h> -#include <dns/masterdump.h> -#include <dns/order.h> -#include <dns/peer.h> -#include <dns/portlist.h> -#include <dns/rdataclass.h> -#include <dns/rdataset.h> -#include <dns/rdatastruct.h> -#include <dns/resolver.h> -#include <dns/rootns.h> -#include <dns/secalg.h> -#include <dns/stats.h> -#include <dns/tkey.h> -#include <dns/view.h> -#include <dns/zone.h> -#include <dns/zt.h> - -#include <dst/dst.h> -#include <dst/result.h> - -#include <named/client.h> -#include <named/config.h> -#include <named/control.h> -#include <named/interfacemgr.h> -#include <named/log.h> -#include <named/logconf.h> -#include <named/lwresd.h> -#include <named/main.h> -#include <named/os.h> -#include <named/server.h> -#include <named/tkeyconf.h> -#include <named/tsigconf.h> -#include <named/zoneconf.h> -#ifdef HAVE_LIBSCF -#include <named/ns_smf_globals.h> -#include <stdlib.h> -#endif - -/* - * Check an operation for failure. Assumes that the function - * using it has a 'result' variable and a 'cleanup' label. - */ -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto cleanup; \ - } while (0) - -#define CHECKM(op, msg) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) { \ - isc_log_write(ns_g_lctx, \ - NS_LOGCATEGORY_GENERAL, \ - NS_LOGMODULE_SERVER, \ - ISC_LOG_ERROR, \ - "%s: %s", msg, \ - isc_result_totext(result)); \ - goto cleanup; \ - } \ - } while (0) \ - -#define CHECKMF(op, msg, file) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) { \ - isc_log_write(ns_g_lctx, \ - NS_LOGCATEGORY_GENERAL, \ - NS_LOGMODULE_SERVER, \ - ISC_LOG_ERROR, \ - "%s '%s': %s", msg, file, \ - isc_result_totext(result)); \ - goto cleanup; \ - } \ - } while (0) \ - -#define CHECKFATAL(op, msg) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) \ - fatal(msg, result); \ - } while (0) \ - -struct ns_dispatch { - isc_sockaddr_t addr; - unsigned int dispatchgen; - dns_dispatch_t *dispatch; - ISC_LINK(struct ns_dispatch) link; -}; - -struct dumpcontext { - isc_mem_t *mctx; - isc_boolean_t dumpcache; - isc_boolean_t dumpzones; - FILE *fp; - ISC_LIST(struct viewlistentry) viewlist; - struct viewlistentry *view; - struct zonelistentry *zone; - dns_dumpctx_t *mdctx; - dns_db_t *db; - dns_db_t *cache; - isc_task_t *task; - dns_dbversion_t *version; -}; - -struct viewlistentry { - dns_view_t *view; - ISC_LINK(struct viewlistentry) link; - ISC_LIST(struct zonelistentry) zonelist; -}; - -struct zonelistentry { - dns_zone_t *zone; - ISC_LINK(struct zonelistentry) link; -}; - -static void -fatal(const char *msg, isc_result_t result); - -static void -ns_server_reload(isc_task_t *task, isc_event_t *event); - -static isc_result_t -ns_listenelt_fromconfig(cfg_obj_t *listener, cfg_obj_t *config, - ns_aclconfctx_t *actx, - isc_mem_t *mctx, ns_listenelt_t **target); -static isc_result_t -ns_listenlist_fromconfig(cfg_obj_t *listenlist, cfg_obj_t *config, - ns_aclconfctx_t *actx, - isc_mem_t *mctx, ns_listenlist_t **target); - -static isc_result_t -configure_forward(cfg_obj_t *config, dns_view_t *view, dns_name_t *origin, - cfg_obj_t *forwarders, cfg_obj_t *forwardtype); - -static isc_result_t -configure_alternates(cfg_obj_t *config, dns_view_t *view, - cfg_obj_t *alternates); - -static isc_result_t -configure_zone(cfg_obj_t *config, cfg_obj_t *zconfig, cfg_obj_t *vconfig, - isc_mem_t *mctx, dns_view_t *view, - ns_aclconfctx_t *aclconf); - -static void -end_reserved_dispatches(ns_server_t *server, isc_boolean_t all); - -/* - * Configure a single view ACL at '*aclp'. Get its configuration by - * calling 'getvcacl' (for per-view configuration) and maybe 'getscacl' - * (for a global default). - */ -static isc_result_t -configure_view_acl(cfg_obj_t *vconfig, cfg_obj_t *config, - const char *aclname, ns_aclconfctx_t *actx, - isc_mem_t *mctx, dns_acl_t **aclp) -{ - isc_result_t result; - cfg_obj_t *maps[3]; - cfg_obj_t *aclobj = NULL; - int i = 0; - - if (*aclp != NULL) - dns_acl_detach(aclp); - if (vconfig != NULL) - maps[i++] = cfg_tuple_get(vconfig, "options"); - if (config != NULL) { - cfg_obj_t *options = NULL; - (void)cfg_map_get(config, "options", &options); - if (options != NULL) - maps[i++] = options; - } - maps[i] = NULL; - - result = ns_config_get(maps, aclname, &aclobj); - if (aclobj == NULL) - /* - * No value available. *aclp == NULL. - */ - return (ISC_R_SUCCESS); - - result = ns_acl_fromconfig(aclobj, config, actx, mctx, aclp); - - return (result); -} - -static isc_result_t -configure_view_dnsseckey(cfg_obj_t *vconfig, cfg_obj_t *key, - dns_keytable_t *keytable, isc_mem_t *mctx) -{ - dns_rdataclass_t viewclass; - dns_rdata_dnskey_t keystruct; - isc_uint32_t flags, proto, alg; - char *keystr, *keynamestr; - unsigned char keydata[4096]; - isc_buffer_t keydatabuf; - unsigned char rrdata[4096]; - isc_buffer_t rrdatabuf; - isc_region_t r; - dns_fixedname_t fkeyname; - dns_name_t *keyname; - isc_buffer_t namebuf; - isc_result_t result; - dst_key_t *dstkey = NULL; - - flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags")); - proto = cfg_obj_asuint32(cfg_tuple_get(key, "protocol")); - alg = cfg_obj_asuint32(cfg_tuple_get(key, "algorithm")); - keyname = dns_fixedname_name(&fkeyname); - keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name")); - - if (vconfig == NULL) - viewclass = dns_rdataclass_in; - else { - cfg_obj_t *classobj = cfg_tuple_get(vconfig, "class"); - CHECK(ns_config_getclass(classobj, dns_rdataclass_in, - &viewclass)); - } - keystruct.common.rdclass = viewclass; - keystruct.common.rdtype = dns_rdatatype_dnskey; - /* - * The key data in keystruct is not dynamically allocated. - */ - keystruct.mctx = NULL; - - ISC_LINK_INIT(&keystruct.common, link); - - if (flags > 0xffff) - CHECKM(ISC_R_RANGE, "key flags"); - if (proto > 0xff) - CHECKM(ISC_R_RANGE, "key protocol"); - if (alg > 0xff) - CHECKM(ISC_R_RANGE, "key algorithm"); - keystruct.flags = (isc_uint16_t)flags; - keystruct.protocol = (isc_uint8_t)proto; - keystruct.algorithm = (isc_uint8_t)alg; - - isc_buffer_init(&keydatabuf, keydata, sizeof(keydata)); - isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata)); - - keystr = cfg_obj_asstring(cfg_tuple_get(key, "key")); - CHECK(isc_base64_decodestring(keystr, &keydatabuf)); - isc_buffer_usedregion(&keydatabuf, &r); - keystruct.datalen = r.length; - keystruct.data = r.base; - - CHECK(dns_rdata_fromstruct(NULL, - keystruct.common.rdclass, - keystruct.common.rdtype, - &keystruct, &rrdatabuf)); - dns_fixedname_init(&fkeyname); - isc_buffer_init(&namebuf, keynamestr, strlen(keynamestr)); - isc_buffer_add(&namebuf, strlen(keynamestr)); - CHECK(dns_name_fromtext(keyname, &namebuf, - dns_rootname, ISC_FALSE, - NULL)); - CHECK(dst_key_fromdns(keyname, viewclass, &rrdatabuf, - mctx, &dstkey)); - - CHECK(dns_keytable_add(keytable, &dstkey)); - INSIST(dstkey == NULL); - return (ISC_R_SUCCESS); - - cleanup: - if (result == DST_R_NOCRYPTO) { - cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR, - "ignoring trusted key for '%s': no crypto support", - keynamestr); - result = ISC_R_SUCCESS; - } else { - cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR, - "configuring trusted key for '%s': %s", - keynamestr, isc_result_totext(result)); - result = ISC_R_FAILURE; - } - - if (dstkey != NULL) - dst_key_free(&dstkey); - - return (result); -} - -/* - * Configure DNSSEC keys for a view. Currently used only for - * the security roots. - * - * The per-view configuration values and the server-global defaults are read - * from 'vconfig' and 'config'. The variable to be configured is '*target'. - */ -static isc_result_t -configure_view_dnsseckeys(cfg_obj_t *vconfig, cfg_obj_t *config, - isc_mem_t *mctx, dns_keytable_t **target) -{ - isc_result_t result; - cfg_obj_t *keys = NULL; - cfg_obj_t *voptions = NULL; - cfg_listelt_t *element, *element2; - cfg_obj_t *keylist; - cfg_obj_t *key; - dns_keytable_t *keytable = NULL; - - CHECK(dns_keytable_create(mctx, &keytable)); - - if (vconfig != NULL) - voptions = cfg_tuple_get(vconfig, "options"); - - keys = NULL; - if (voptions != NULL) - (void)cfg_map_get(voptions, "trusted-keys", &keys); - if (keys == NULL) - (void)cfg_map_get(config, "trusted-keys", &keys); - - for (element = cfg_list_first(keys); - element != NULL; - element = cfg_list_next(element)) - { - keylist = cfg_listelt_value(element); - for (element2 = cfg_list_first(keylist); - element2 != NULL; - element2 = cfg_list_next(element2)) - { - key = cfg_listelt_value(element2); - CHECK(configure_view_dnsseckey(vconfig, key, - keytable, mctx)); - } - } - - dns_keytable_detach(target); - *target = keytable; /* Transfer ownership. */ - keytable = NULL; - result = ISC_R_SUCCESS; - - cleanup: - return (result); -} - -static isc_result_t -mustbesecure(cfg_obj_t *mbs, dns_resolver_t *resolver) -{ - cfg_listelt_t *element; - cfg_obj_t *obj; - const char *str; - dns_fixedname_t fixed; - dns_name_t *name; - isc_boolean_t value; - isc_result_t result; - isc_buffer_t b; - - dns_fixedname_init(&fixed); - name = dns_fixedname_name(&fixed); - for (element = cfg_list_first(mbs); - element != NULL; - element = cfg_list_next(element)) - { - obj = cfg_listelt_value(element); - str = cfg_obj_asstring(cfg_tuple_get(obj, "name")); - isc_buffer_init(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - CHECK(dns_name_fromtext(name, &b, dns_rootname, - ISC_FALSE, NULL)); - value = cfg_obj_asboolean(cfg_tuple_get(obj, "value")); - CHECK(dns_resolver_setmustbesecure(resolver, name, value)); - } - - result = ISC_R_SUCCESS; - - cleanup: - return (result); -} - -/* - * Get a dispatch appropriate for the resolver of a given view. - */ -static isc_result_t -get_view_querysource_dispatch(cfg_obj_t **maps, - int af, dns_dispatch_t **dispatchp) -{ - isc_result_t result; - dns_dispatch_t *disp; - isc_sockaddr_t sa; - unsigned int attrs, attrmask; - cfg_obj_t *obj = NULL; - - /* - * Make compiler happy. - */ - result = ISC_R_FAILURE; - - switch (af) { - case AF_INET: - result = ns_config_get(maps, "query-source", &obj); - INSIST(result == ISC_R_SUCCESS); - - break; - case AF_INET6: - result = ns_config_get(maps, "query-source-v6", &obj); - INSIST(result == ISC_R_SUCCESS); - break; - default: - INSIST(0); - } - - sa = *(cfg_obj_assockaddr(obj)); - INSIST(isc_sockaddr_pf(&sa) == af); - - /* - * If we don't support this address family, we're done! - */ - switch (af) { - case AF_INET: - result = isc_net_probeipv4(); - break; - case AF_INET6: - result = isc_net_probeipv6(); - break; - default: - INSIST(0); - } - if (result != ISC_R_SUCCESS) - return (ISC_R_SUCCESS); - - /* - * Try to find a dispatcher that we can share. - */ - attrs = 0; - attrs |= DNS_DISPATCHATTR_UDP; - switch (af) { - case AF_INET: - attrs |= DNS_DISPATCHATTR_IPV4; - break; - case AF_INET6: - attrs |= DNS_DISPATCHATTR_IPV6; - break; - } - attrmask = 0; - attrmask |= DNS_DISPATCHATTR_UDP; - attrmask |= DNS_DISPATCHATTR_TCP; - attrmask |= DNS_DISPATCHATTR_IPV4; - attrmask |= DNS_DISPATCHATTR_IPV6; - - disp = NULL; - result = dns_dispatch_getudp(ns_g_dispatchmgr, ns_g_socketmgr, - ns_g_taskmgr, &sa, 4096, - 1000, 32768, 16411, 16433, - attrs, attrmask, &disp); - if (result != ISC_R_SUCCESS) { - isc_sockaddr_t any; - char buf[ISC_SOCKADDR_FORMATSIZE]; - - switch (af) { - case AF_INET: - isc_sockaddr_any(&any); - break; - case AF_INET6: - isc_sockaddr_any6(&any); - break; - } - if (isc_sockaddr_equal(&sa, &any)) - return (ISC_R_SUCCESS); - isc_sockaddr_format(&sa, buf, sizeof(buf)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "could not get query source dispatcher (%s)", - buf); - return (result); - } - - *dispatchp = disp; - - return (ISC_R_SUCCESS); -} - -static isc_result_t -configure_order(dns_order_t *order, cfg_obj_t *ent) { - dns_rdataclass_t rdclass; - dns_rdatatype_t rdtype; - cfg_obj_t *obj; - dns_fixedname_t fixed; - unsigned int mode = 0; - const char *str; - isc_buffer_t b; - isc_result_t result; - isc_boolean_t addroot; - - result = ns_config_getclass(cfg_tuple_get(ent, "class"), - dns_rdataclass_any, &rdclass); - if (result != ISC_R_SUCCESS) - return (result); - - result = ns_config_gettype(cfg_tuple_get(ent, "type"), - dns_rdatatype_any, &rdtype); - if (result != ISC_R_SUCCESS) - return (result); - - obj = cfg_tuple_get(ent, "name"); - if (cfg_obj_isstring(obj)) - str = cfg_obj_asstring(obj); - else - str = "*"; - addroot = ISC_TF(strcmp(str, "*") == 0); - isc_buffer_init(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - dns_fixedname_init(&fixed); - result = dns_name_fromtext(dns_fixedname_name(&fixed), &b, - dns_rootname, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) - return (result); - - obj = cfg_tuple_get(ent, "ordering"); - INSIST(cfg_obj_isstring(obj)); - str = cfg_obj_asstring(obj); - if (!strcasecmp(str, "fixed")) - mode = DNS_RDATASETATTR_FIXEDORDER; - else if (!strcasecmp(str, "random")) - mode = DNS_RDATASETATTR_RANDOMIZE; - else if (!strcasecmp(str, "cyclic")) - mode = 0; - else - INSIST(0); - - /* - * "*" should match everything including the root (BIND 8 compat). - * As dns_name_matcheswildcard(".", "*.") returns FALSE add a - * explict entry for "." when the name is "*". - */ - if (addroot) { - result = dns_order_add(order, dns_rootname, - rdtype, rdclass, mode); - if (result != ISC_R_SUCCESS) - return (result); - } - - return (dns_order_add(order, dns_fixedname_name(&fixed), - rdtype, rdclass, mode)); -} - -static isc_result_t -configure_peer(cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) { - isc_sockaddr_t *sa; - isc_netaddr_t na; - dns_peer_t *peer; - cfg_obj_t *obj; - char *str; - isc_result_t result; - - sa = cfg_obj_assockaddr(cfg_map_getname(cpeer)); - isc_netaddr_fromsockaddr(&na, sa); - - peer = NULL; - result = dns_peer_new(mctx, &na, &peer); - if (result != ISC_R_SUCCESS) - return (result); - - obj = NULL; - (void)cfg_map_get(cpeer, "bogus", &obj); - if (obj != NULL) - CHECK(dns_peer_setbogus(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "provide-ixfr", &obj); - if (obj != NULL) - CHECK(dns_peer_setprovideixfr(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "request-ixfr", &obj); - if (obj != NULL) - CHECK(dns_peer_setrequestixfr(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "edns", &obj); - if (obj != NULL) - CHECK(dns_peer_setsupportedns(peer, cfg_obj_asboolean(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "transfers", &obj); - if (obj != NULL) - CHECK(dns_peer_settransfers(peer, cfg_obj_asuint32(obj))); - - obj = NULL; - (void)cfg_map_get(cpeer, "transfer-format", &obj); - if (obj != NULL) { - str = cfg_obj_asstring(obj); - if (strcasecmp(str, "many-answers") == 0) - CHECK(dns_peer_settransferformat(peer, - dns_many_answers)); - else if (strcasecmp(str, "one-answer") == 0) - CHECK(dns_peer_settransferformat(peer, - dns_one_answer)); - else - INSIST(0); - } - - obj = NULL; - (void)cfg_map_get(cpeer, "keys", &obj); - if (obj != NULL) { - result = dns_peer_setkeybycharp(peer, cfg_obj_asstring(obj)); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - - obj = NULL; - if (isc_sockaddr_pf(sa) == AF_INET) - (void)cfg_map_get(cpeer, "transfer-source", &obj); - else - (void)cfg_map_get(cpeer, "transfer-source-v6", &obj); - if (obj != NULL) { - result = dns_peer_settransfersource(peer, - cfg_obj_assockaddr(obj)); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - *peerp = peer; - return (ISC_R_SUCCESS); - - cleanup: - dns_peer_detach(&peer); - return (result); -} - -static isc_result_t -disable_algorithms(cfg_obj_t *disabled, dns_resolver_t *resolver) { - isc_result_t result; - cfg_obj_t *algorithms; - cfg_listelt_t *element; - const char *str; - dns_fixedname_t fixed; - dns_name_t *name; - isc_buffer_t b; - - dns_fixedname_init(&fixed); - name = dns_fixedname_name(&fixed); - str = cfg_obj_asstring(cfg_tuple_get(disabled, "name")); - isc_buffer_init(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - CHECK(dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL)); - - algorithms = cfg_tuple_get(disabled, "algorithms"); - for (element = cfg_list_first(algorithms); - element != NULL; - element = cfg_list_next(element)) - { - isc_textregion_t r; - dns_secalg_t alg; - - r.base = cfg_obj_asstring(cfg_listelt_value(element)); - r.length = strlen(r.base); - - result = dns_secalg_fromtext(&alg, &r); - if (result != ISC_R_SUCCESS) { - isc_uint8_t ui; - result = isc_parse_uint8(&ui, r.base, 10); - alg = ui; - } - if (result != ISC_R_SUCCESS) { - cfg_obj_log(cfg_listelt_value(element), - ns_g_lctx, ISC_LOG_ERROR, - "invalid algorithm"); - CHECK(result); - } - CHECK(dns_resolver_disable_algorithm(resolver, name, alg)); - } - cleanup: - return (result); -} - -/* - * Configure 'view' according to 'vconfig', taking defaults from 'config' - * where values are missing in 'vconfig'. - * - * When configuring the default view, 'vconfig' will be NULL and the - * global defaults in 'config' used exclusively. - */ -static isc_result_t -configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, - isc_mem_t *mctx, ns_aclconfctx_t *actx, - isc_boolean_t need_hints) -{ - cfg_obj_t *maps[4]; - cfg_obj_t *cfgmaps[3]; - cfg_obj_t *options = NULL; - cfg_obj_t *voptions = NULL; - cfg_obj_t *forwardtype; - cfg_obj_t *forwarders; - cfg_obj_t *alternates; - cfg_obj_t *zonelist; - cfg_obj_t *disabled; - cfg_obj_t *obj; - cfg_listelt_t *element; - in_port_t port; - dns_cache_t *cache = NULL; - isc_result_t result; - isc_uint32_t max_adb_size; - isc_uint32_t max_cache_size; - isc_uint32_t lame_ttl; - dns_tsig_keyring_t *ring; - dns_view_t *pview = NULL; /* Production view */ - isc_mem_t *cmctx; - dns_dispatch_t *dispatch4 = NULL; - dns_dispatch_t *dispatch6 = NULL; - isc_boolean_t reused_cache = ISC_FALSE; - int i; - const char *str; - dns_order_t *order = NULL; - isc_uint32_t udpsize; - unsigned int check = 0; - - REQUIRE(DNS_VIEW_VALID(view)); - - cmctx = NULL; - - if (config != NULL) - (void)cfg_map_get(config, "options", &options); - - i = 0; - if (vconfig != NULL) { - voptions = cfg_tuple_get(vconfig, "options"); - maps[i++] = voptions; - } - if (options != NULL) - maps[i++] = options; - maps[i++] = ns_g_defaults; - maps[i] = NULL; - - i = 0; - if (voptions != NULL) - cfgmaps[i++] = voptions; - if (config != NULL) - cfgmaps[i++] = config; - cfgmaps[i] = NULL; - - /* - * Set the view's port number for outgoing queries. - */ - CHECKM(ns_config_getport(config, &port), "port"); - dns_view_setdstport(view, port); - - /* - * Configure the zones. - */ - zonelist = NULL; - if (voptions != NULL) - (void)cfg_map_get(voptions, "zone", &zonelist); - else - (void)cfg_map_get(config, "zone", &zonelist); - for (element = cfg_list_first(zonelist); - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *zconfig = cfg_listelt_value(element); - CHECK(configure_zone(config, zconfig, vconfig, mctx, view, - actx)); - } - - /* - * Configure the view's cache. Try to reuse an existing - * cache if possible, otherwise create a new cache. - * Note that the ADB is not preserved in either case. - * - * XXX Determining when it is safe to reuse a cache is - * tricky. When the view's configuration changes, the cached - * data may become invalid because it reflects our old - * view of the world. As more view attributes become - * configurable, we will have to add code here to check - * whether they have changed in ways that could - * invalidate the cache. - */ - result = dns_viewlist_find(&ns_g_server->viewlist, - view->name, view->rdclass, - &pview); - if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) - goto cleanup; - if (pview != NULL) { - INSIST(pview->cache != NULL); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(3), - "reusing existing cache"); - reused_cache = ISC_TRUE; - dns_cache_attach(pview->cache, &cache); - dns_view_detach(&pview); - } else { - CHECK(isc_mem_create(0, 0, &cmctx)); - CHECK(dns_cache_create(cmctx, ns_g_taskmgr, ns_g_timermgr, - view->rdclass, "rbt", 0, NULL, &cache)); - } - dns_view_setcache(view, cache); - - /* - * cache-file cannot be inherited if views are present, but this - * should be caught by the configuration checking stage. - */ - obj = NULL; - result = ns_config_get(maps, "cache-file", &obj); - if (result == ISC_R_SUCCESS && strcmp(view->name, "_bind") != 0) { - CHECK(dns_cache_setfilename(cache, cfg_obj_asstring(obj))); - if (!reused_cache) - CHECK(dns_cache_load(cache)); - } - - obj = NULL; - result = ns_config_get(maps, "cleaning-interval", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_cache_setcleaninginterval(cache, cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-cache-size", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isstring(obj)) { - str = cfg_obj_asstring(obj); - INSIST(strcasecmp(str, "unlimited") == 0); - max_cache_size = ISC_UINT32_MAX; - } else { - isc_resourcevalue_t value; - value = cfg_obj_asuint64(obj); - if (value > ISC_UINT32_MAX) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, - "'max-cache-size " - "%" ISC_PRINT_QUADFORMAT "d' is too large", - value); - result = ISC_R_RANGE; - goto cleanup; - } - max_cache_size = (isc_uint32_t)value; - } - dns_cache_setcachesize(cache, max_cache_size); - - dns_cache_detach(&cache); - - /* - * Check-names. - */ - obj = NULL; - result = ns_checknames_get(maps, "response", &obj); - INSIST(result == ISC_R_SUCCESS); - - str = cfg_obj_asstring(obj); - if (strcasecmp(str, "fail") == 0) { - check = DNS_RESOLVER_CHECKNAMES | - DNS_RESOLVER_CHECKNAMESFAIL; - view->checknames = ISC_TRUE; - } else if (strcasecmp(str, "warn") == 0) { - check = DNS_RESOLVER_CHECKNAMES; - view->checknames = ISC_FALSE; - } else if (strcasecmp(str, "ignore") == 0) { - check = 0; - view->checknames = ISC_FALSE; - } else - INSIST(0); - - /* - * Resolver. - * - * XXXRTH Hardwired number of tasks. - */ - CHECK(get_view_querysource_dispatch(maps, AF_INET, &dispatch4)); - CHECK(get_view_querysource_dispatch(maps, AF_INET6, &dispatch6)); - if (dispatch4 == NULL && dispatch6 == NULL) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "unable to obtain neither an IPv4 nor" - " an IPv6 dispatch"); - result = ISC_R_UNEXPECTED; - goto cleanup; - } - CHECK(dns_view_createresolver(view, ns_g_taskmgr, 31, - ns_g_socketmgr, ns_g_timermgr, - check, ns_g_dispatchmgr, - dispatch4, dispatch6)); - - /* - * Set the ADB cache size to 1/8th of the max-cache-size. - */ - max_adb_size = 0; - if (max_cache_size != 0) { - max_adb_size = max_cache_size / 8; - if (max_adb_size == 0) - max_adb_size = 1; /* Force minimum. */ - } - dns_adb_setadbsize(view->adb, max_adb_size); - - /* - * Set resolver's lame-ttl. - */ - obj = NULL; - result = ns_config_get(maps, "lame-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - lame_ttl = cfg_obj_asuint32(obj); - if (lame_ttl > 1800) - lame_ttl = 1800; - dns_resolver_setlamettl(view->resolver, lame_ttl); - - /* - * Set the resolver's EDNS UDP size. - */ - obj = NULL; - result = ns_config_get(maps, "edns-udp-size", &obj); - INSIST(result == ISC_R_SUCCESS); - udpsize = cfg_obj_asuint32(obj); - if (udpsize < 512) - udpsize = 512; - if (udpsize > 4096) - udpsize = 4096; - dns_resolver_setudpsize(view->resolver, (isc_uint16_t)udpsize); - - /* - * Set supported DNSSEC algorithms. - */ - dns_resolver_reset_algorithms(view->resolver); - disabled = NULL; - (void)ns_config_get(maps, "disable-algorithms", &disabled); - if (disabled != NULL) { - for (element = cfg_list_first(disabled); - element != NULL; - element = cfg_list_next(element)) - CHECK(disable_algorithms(cfg_listelt_value(element), - view->resolver)); - } - - /* - * A global or view "forwarders" option, if present, - * creates an entry for "." in the forwarding table. - */ - forwardtype = NULL; - forwarders = NULL; - (void)ns_config_get(maps, "forward", &forwardtype); - (void)ns_config_get(maps, "forwarders", &forwarders); - if (forwarders != NULL) - CHECK(configure_forward(config, view, dns_rootname, - forwarders, forwardtype)); - - /* - * Dual Stack Servers. - */ - alternates = NULL; - (void)ns_config_get(maps, "dual-stack-servers", &alternates); - if (alternates != NULL) - CHECK(configure_alternates(config, view, alternates)); - - /* - * We have default hints for class IN if we need them. - */ - if (view->rdclass == dns_rdataclass_in && view->hints == NULL) - dns_view_sethints(view, ns_g_server->in_roothints); - - /* - * If we still have no hints, this is a non-IN view with no - * "hints zone" configured. Issue a warning, except if this - * is a root server. Root servers never need to consult - * their hints, so it's no point requiring users to configure - * them. - */ - if (view->hints == NULL) { - dns_zone_t *rootzone = NULL; - (void)dns_view_findzone(view, dns_rootname, &rootzone); - if (rootzone != NULL) { - dns_zone_detach(&rootzone); - need_hints = ISC_FALSE; - } - if (need_hints) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "no root hints for view '%s'", - view->name); - } - - /* - * Configure the view's TSIG keys. - */ - ring = NULL; - CHECK(ns_tsigkeyring_fromconfig(config, vconfig, view->mctx, &ring)); - dns_view_setkeyring(view, ring); - - /* - * Configure the view's peer list. - */ - { - cfg_obj_t *peers = NULL; - cfg_listelt_t *element; - dns_peerlist_t *newpeers = NULL; - - (void)ns_config_get(cfgmaps, "server", &peers); - CHECK(dns_peerlist_new(mctx, &newpeers)); - for (element = cfg_list_first(peers); - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *cpeer = cfg_listelt_value(element); - dns_peer_t *peer; - - CHECK(configure_peer(cpeer, mctx, &peer)); - dns_peerlist_addpeer(newpeers, peer); - dns_peer_detach(&peer); - } - dns_peerlist_detach(&view->peers); - view->peers = newpeers; /* Transfer ownership. */ - } - - /* - * Configure the views rrset-order. - */ - { - cfg_obj_t *rrsetorder = NULL; - cfg_listelt_t *element; - - (void)ns_config_get(maps, "rrset-order", &rrsetorder); - CHECK(dns_order_create(mctx, &order)); - for (element = cfg_list_first(rrsetorder); - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *ent = cfg_listelt_value(element); - - CHECK(configure_order(order, ent)); - } - if (view->order != NULL) - dns_order_detach(&view->order); - dns_order_attach(order, &view->order); - dns_order_detach(&order); - } - /* - * Copy the aclenv object. - */ - dns_aclenv_copy(&view->aclenv, &ns_g_server->aclenv); - - /* - * Configure the "match-clients" and "match-destinations" ACL. - */ - CHECK(configure_view_acl(vconfig, config, "match-clients", actx, - ns_g_mctx, &view->matchclients)); - CHECK(configure_view_acl(vconfig, config, "match-destinations", actx, - ns_g_mctx, &view->matchdestinations)); - - /* - * Configure the "match-recursive-only" option. - */ - obj = NULL; - (void) ns_config_get(maps, "match-recursive-only", &obj); - if (obj != NULL && cfg_obj_asboolean(obj)) - view->matchrecursiveonly = ISC_TRUE; - else - view->matchrecursiveonly = ISC_FALSE; - - /* - * Configure other configurable data. - */ - obj = NULL; - result = ns_config_get(maps, "recursion", &obj); - INSIST(result == ISC_R_SUCCESS); - view->recursion = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "auth-nxdomain", &obj); - INSIST(result == ISC_R_SUCCESS); - view->auth_nxdomain = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "minimal-responses", &obj); - INSIST(result == ISC_R_SUCCESS); - view->minimalresponses = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "transfer-format", &obj); - INSIST(result == ISC_R_SUCCESS); - str = cfg_obj_asstring(obj); - if (strcasecmp(str, "many-answers") == 0) - view->transfer_format = dns_many_answers; - else if (strcasecmp(str, "one-answer") == 0) - view->transfer_format = dns_one_answer; - else - INSIST(0); - - /* - * Set sources where additional data and CNAME/DNAME - * targets for authoritative answers may be found. - */ - obj = NULL; - result = ns_config_get(maps, "additional-from-auth", &obj); - INSIST(result == ISC_R_SUCCESS); - view->additionalfromauth = cfg_obj_asboolean(obj); - if (view->recursion && ! view->additionalfromauth) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING, - "'additional-from-auth no' is only supported " - "with 'recursion no'"); - view->additionalfromauth = ISC_TRUE; - } - - obj = NULL; - result = ns_config_get(maps, "additional-from-cache", &obj); - INSIST(result == ISC_R_SUCCESS); - view->additionalfromcache = cfg_obj_asboolean(obj); - if (view->recursion && ! view->additionalfromcache) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING, - "'additional-from-cache no' is only supported " - "with 'recursion no'"); - view->additionalfromcache = ISC_TRUE; - } - - CHECK(configure_view_acl(vconfig, config, "allow-query", - actx, ns_g_mctx, &view->queryacl)); - - if (strcmp(view->name, "_bind") != 0) - CHECK(configure_view_acl(vconfig, config, "allow-recursion", - actx, ns_g_mctx, &view->recursionacl)); - - /* - * Warning if both "recursion no;" and allow-recursion are active - * except for "allow-recursion { none; };". - */ - if (!view->recursion && view->recursionacl != NULL && - (view->recursionacl->length != 1 || - view->recursionacl->elements[0].type != dns_aclelementtype_any || - view->recursionacl->elements[0].negative != ISC_TRUE)) { - const char *forview = " for view "; - const char *viewname = view->name; - - if (!strcmp(view->name, "_bind") || - !strcmp(view->name, "_default")) { - forview = ""; - viewname = ""; - } - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "both \"recursion no;\" and \"allow-recursion\" " - "active%s%s", forview, viewname); - } - - CHECK(configure_view_acl(vconfig, config, "sortlist", - actx, ns_g_mctx, &view->sortlist)); - - obj = NULL; - result = ns_config_get(maps, "request-ixfr", &obj); - INSIST(result == ISC_R_SUCCESS); - view->requestixfr = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "provide-ixfr", &obj); - INSIST(result == ISC_R_SUCCESS); - view->provideixfr = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "dnssec-enable", &obj); - INSIST(result == ISC_R_SUCCESS); - view->enablednssec = cfg_obj_asboolean(obj); - - obj = NULL; - result = ns_config_get(maps, "dnssec-lookaside", &obj); - if (result == ISC_R_SUCCESS) { - for (element = cfg_list_first(obj); - element != NULL; - element = cfg_list_next(element)) - { - const char *str; - isc_buffer_t b; - dns_name_t *dlv; - - obj = cfg_listelt_value(element); -#if 0 - dns_fixedname_t fixed; - dns_name_t *name; - - /* - * When we support multiple dnssec-lookaside - * entries this is how to find the domain to be - * checked. XXXMPA - */ - dns_fixedname_init(&fixed); - name = dns_fixedname_name(&fixed); - str = cfg_obj_asstring(cfg_tuple_get(obj, - "domain")); - isc_buffer_init(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - CHECK(dns_name_fromtext(name, &b, dns_rootname, - ISC_TRUE, NULL)); -#endif - str = cfg_obj_asstring(cfg_tuple_get(obj, - "trust-anchor")); - isc_buffer_init(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - dlv = dns_fixedname_name(&view->dlv_fixed); - CHECK(dns_name_fromtext(dlv, &b, dns_rootname, - ISC_TRUE, NULL)); - view->dlv = dns_fixedname_name(&view->dlv_fixed); - } - } else - view->dlv = NULL; - - /* - * For now, there is only one kind of trusted keys, the - * "security roots". - */ - if (view->enablednssec) { - CHECK(configure_view_dnsseckeys(vconfig, config, mctx, - &view->secroots)); - dns_resolver_resetmustbesecure(view->resolver); - obj = NULL; - result = ns_config_get(maps, "dnssec-must-be-secure", &obj); - if (result == ISC_R_SUCCESS) - CHECK(mustbesecure(obj, view->resolver)); - } - - obj = NULL; - result = ns_config_get(maps, "max-cache-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - view->maxcachettl = cfg_obj_asuint32(obj); - - obj = NULL; - result = ns_config_get(maps, "max-ncache-ttl", &obj); - INSIST(result == ISC_R_SUCCESS); - view->maxncachettl = cfg_obj_asuint32(obj); - if (view->maxncachettl > 7 * 24 * 3600) - view->maxncachettl = 7 * 24 * 3600; - - obj = NULL; - result = ns_config_get(maps, "preferred-glue", &obj); - if (result == ISC_R_SUCCESS) { - str = cfg_obj_asstring(obj); - if (strcasecmp(str, "a") == 0) - view->preferred_glue = dns_rdatatype_a; - else if (strcasecmp(str, "aaaa") == 0) - view->preferred_glue = dns_rdatatype_aaaa; - else - view->preferred_glue = 0; - } else - view->preferred_glue = 0; - - obj = NULL; - result = ns_config_get(maps, "root-delegation-only", &obj); - if (result == ISC_R_SUCCESS) { - dns_view_setrootdelonly(view, ISC_TRUE); - if (!cfg_obj_isvoid(obj)) { - dns_fixedname_t fixed; - dns_name_t *name; - isc_buffer_t b; - char *str; - cfg_obj_t *exclude; - - dns_fixedname_init(&fixed); - name = dns_fixedname_name(&fixed); - for (element = cfg_list_first(obj); - element != NULL; - element = cfg_list_next(element)) { - exclude = cfg_listelt_value(element); - str = cfg_obj_asstring(exclude); - isc_buffer_init(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - CHECK(dns_name_fromtext(name, &b, dns_rootname, - ISC_FALSE, NULL)); - CHECK(dns_view_excludedelegationonly(view, - name)); - } - } - } else - dns_view_setrootdelonly(view, ISC_FALSE); - - result = ISC_R_SUCCESS; - - cleanup: - if (dispatch4 != NULL) - dns_dispatch_detach(&dispatch4); - if (dispatch6 != NULL) - dns_dispatch_detach(&dispatch6); - if (order != NULL) - dns_order_detach(&order); - if (cmctx != NULL) - isc_mem_detach(&cmctx); - - if (cache != NULL) - dns_cache_detach(&cache); - - return (result); -} - -static isc_result_t -configure_hints(dns_view_t *view, const char *filename) { - isc_result_t result; - dns_db_t *db; - - db = NULL; - result = dns_rootns_create(view->mctx, view->rdclass, filename, &db); - if (result == ISC_R_SUCCESS) { - dns_view_sethints(view, db); - dns_db_detach(&db); - } - - return (result); -} - -static isc_result_t -configure_alternates(cfg_obj_t *config, dns_view_t *view, - cfg_obj_t *alternates) -{ - cfg_obj_t *portobj; - cfg_obj_t *addresses; - cfg_listelt_t *element; - isc_result_t result = ISC_R_SUCCESS; - in_port_t port; - - /* - * Determine which port to send requests to. - */ - if (ns_g_lwresdonly && ns_g_port != 0) - port = ns_g_port; - else - CHECKM(ns_config_getport(config, &port), "port"); - - if (alternates != NULL) { - portobj = cfg_tuple_get(alternates, "port"); - if (cfg_obj_isuint32(portobj)) { - isc_uint32_t val = cfg_obj_asuint32(portobj); - if (val > ISC_UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port '%u' out of range", val); - return (ISC_R_RANGE); - } - port = (in_port_t) val; - } - } - - addresses = NULL; - if (alternates != NULL) - addresses = cfg_tuple_get(alternates, "addresses"); - - for (element = cfg_list_first(addresses); - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *alternate = cfg_listelt_value(element); - isc_sockaddr_t sa; - - if (!cfg_obj_issockaddr(alternate)) { - dns_fixedname_t fixed; - dns_name_t *name; - char *str = cfg_obj_asstring(cfg_tuple_get(alternate, - "name")); - isc_buffer_t buffer; - in_port_t myport = port; - - isc_buffer_init(&buffer, str, strlen(str)); - isc_buffer_add(&buffer, strlen(str)); - dns_fixedname_init(&fixed); - name = dns_fixedname_name(&fixed); - CHECK(dns_name_fromtext(name, &buffer, dns_rootname, - ISC_FALSE, NULL)); - - portobj = cfg_tuple_get(alternate, "port"); - if (cfg_obj_isuint32(portobj)) { - isc_uint32_t val = cfg_obj_asuint32(portobj); - if (val > ISC_UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, - ISC_LOG_ERROR, - "port '%u' out of range", - val); - return (ISC_R_RANGE); - } - myport = (in_port_t) val; - } - CHECK(dns_resolver_addalternate(view->resolver, NULL, - name, myport)); - continue; - } - - sa = *cfg_obj_assockaddr(alternate); - if (isc_sockaddr_getport(&sa) == 0) - isc_sockaddr_setport(&sa, port); - CHECK(dns_resolver_addalternate(view->resolver, &sa, - NULL, 0)); - } - - cleanup: - return (result); -} - -static isc_result_t -configure_forward(cfg_obj_t *config, dns_view_t *view, dns_name_t *origin, - cfg_obj_t *forwarders, cfg_obj_t *forwardtype) -{ - cfg_obj_t *portobj; - cfg_obj_t *faddresses; - cfg_listelt_t *element; - dns_fwdpolicy_t fwdpolicy = dns_fwdpolicy_none; - isc_sockaddrlist_t addresses; - isc_sockaddr_t *sa; - isc_result_t result; - in_port_t port; - - /* - * Determine which port to send forwarded requests to. - */ - if (ns_g_lwresdonly && ns_g_port != 0) - port = ns_g_port; - else - CHECKM(ns_config_getport(config, &port), "port"); - - if (forwarders != NULL) { - portobj = cfg_tuple_get(forwarders, "port"); - if (cfg_obj_isuint32(portobj)) { - isc_uint32_t val = cfg_obj_asuint32(portobj); - if (val > ISC_UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port '%u' out of range", val); - return (ISC_R_RANGE); - } - port = (in_port_t) val; - } - } - - faddresses = NULL; - if (forwarders != NULL) - faddresses = cfg_tuple_get(forwarders, "addresses"); - - ISC_LIST_INIT(addresses); - - for (element = cfg_list_first(faddresses); - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *forwarder = cfg_listelt_value(element); - sa = isc_mem_get(view->mctx, sizeof(isc_sockaddr_t)); - if (sa == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - *sa = *cfg_obj_assockaddr(forwarder); - if (isc_sockaddr_getport(sa) == 0) - isc_sockaddr_setport(sa, port); - ISC_LINK_INIT(sa, link); - ISC_LIST_APPEND(addresses, sa, link); - } - - if (ISC_LIST_EMPTY(addresses)) { - if (forwardtype != NULL) - cfg_obj_log(forwarders, ns_g_lctx, ISC_LOG_WARNING, - "no forwarders seen; disabling " - "forwarding"); - fwdpolicy = dns_fwdpolicy_none; - } else { - if (forwardtype == NULL) - fwdpolicy = dns_fwdpolicy_first; - else { - char *forwardstr = cfg_obj_asstring(forwardtype); - if (strcasecmp(forwardstr, "first") == 0) - fwdpolicy = dns_fwdpolicy_first; - else if (strcasecmp(forwardstr, "only") == 0) - fwdpolicy = dns_fwdpolicy_only; - else - INSIST(0); - } - } - - result = dns_fwdtable_add(view->fwdtable, origin, &addresses, - fwdpolicy); - if (result != ISC_R_SUCCESS) { - char namebuf[DNS_NAME_FORMATSIZE]; - dns_name_format(origin, namebuf, sizeof(namebuf)); - cfg_obj_log(forwarders, ns_g_lctx, ISC_LOG_WARNING, - "could not set up forwarding for domain '%s': %s", - namebuf, isc_result_totext(result)); - goto cleanup; - } - - result = ISC_R_SUCCESS; - - cleanup: - - while (!ISC_LIST_EMPTY(addresses)) { - sa = ISC_LIST_HEAD(addresses); - ISC_LIST_UNLINK(addresses, sa, link); - isc_mem_put(view->mctx, sa, sizeof(isc_sockaddr_t)); - } - - return (result); -} - -/* - * Create a new view and add it to the list. - * - * If 'vconfig' is NULL, create the default view. - * - * The view created is attached to '*viewp'. - */ -static isc_result_t -create_view(cfg_obj_t *vconfig, dns_viewlist_t *viewlist, dns_view_t **viewp) { - isc_result_t result; - const char *viewname; - dns_rdataclass_t viewclass; - dns_view_t *view = NULL; - - if (vconfig != NULL) { - cfg_obj_t *classobj = NULL; - - viewname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name")); - classobj = cfg_tuple_get(vconfig, "class"); - result = ns_config_getclass(classobj, dns_rdataclass_in, - &viewclass); - } else { - viewname = "_default"; - viewclass = dns_rdataclass_in; - } - result = dns_viewlist_find(viewlist, viewname, viewclass, &view); - if (result == ISC_R_SUCCESS) - return (ISC_R_EXISTS); - if (result != ISC_R_NOTFOUND) - return (result); - INSIST(view == NULL); - - result = dns_view_create(ns_g_mctx, viewclass, viewname, &view); - if (result != ISC_R_SUCCESS) - return (result); - - ISC_LIST_APPEND(*viewlist, view, link); - dns_view_attach(view, viewp); - return (ISC_R_SUCCESS); -} - -/* - * Configure or reconfigure a zone. - */ -static isc_result_t -configure_zone(cfg_obj_t *config, cfg_obj_t *zconfig, cfg_obj_t *vconfig, - isc_mem_t *mctx, dns_view_t *view, - ns_aclconfctx_t *aclconf) -{ - dns_view_t *pview = NULL; /* Production view */ - dns_zone_t *zone = NULL; /* New or reused zone */ - dns_zone_t *dupzone = NULL; - cfg_obj_t *options = NULL; - cfg_obj_t *zoptions = NULL; - cfg_obj_t *typeobj = NULL; - cfg_obj_t *forwarders = NULL; - cfg_obj_t *forwardtype = NULL; - cfg_obj_t *only = NULL; - isc_result_t result; - isc_result_t tresult; - isc_buffer_t buffer; - dns_fixedname_t fixorigin; - dns_name_t *origin; - const char *zname; - dns_rdataclass_t zclass; - const char *ztypestr; - - options = NULL; - (void)cfg_map_get(config, "options", &options); - - zoptions = cfg_tuple_get(zconfig, "options"); - - /* - * Get the zone origin as a dns_name_t. - */ - zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); - isc_buffer_init(&buffer, zname, strlen(zname)); - isc_buffer_add(&buffer, strlen(zname)); - dns_fixedname_init(&fixorigin); - CHECK(dns_name_fromtext(dns_fixedname_name(&fixorigin), - &buffer, dns_rootname, ISC_FALSE, NULL)); - origin = dns_fixedname_name(&fixorigin); - - CHECK(ns_config_getclass(cfg_tuple_get(zconfig, "class"), - view->rdclass, &zclass)); - if (zclass != view->rdclass) { - const char *vname = NULL; - if (vconfig != NULL) - vname = cfg_obj_asstring(cfg_tuple_get(vconfig, - "name")); - else - vname = "<default view>"; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "zone '%s': wrong class for view '%s'", - zname, vname); - result = ISC_R_FAILURE; - goto cleanup; - } - - (void)cfg_map_get(zoptions, "type", &typeobj); - if (typeobj == NULL) { - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "zone '%s' 'type' not specified", zname); - return (ISC_R_FAILURE); - } - ztypestr = cfg_obj_asstring(typeobj); - - /* - * "hints zones" aren't zones. If we've got one, - * configure it and return. - */ - if (strcasecmp(ztypestr, "hint") == 0) { - cfg_obj_t *fileobj = NULL; - if (cfg_map_get(zoptions, "file", &fileobj) != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "zone '%s': 'file' not specified", - zname); - result = ISC_R_FAILURE; - goto cleanup; - } - if (dns_name_equal(origin, dns_rootname)) { - char *hintsfile = cfg_obj_asstring(fileobj); - - result = configure_hints(view, hintsfile); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_ERROR, - "could not configure root hints " - "from '%s': %s", hintsfile, - isc_result_totext(result)); - goto cleanup; - } - /* - * Hint zones may also refer to delegation only points. - */ - only = NULL; - tresult = cfg_map_get(zoptions, "delegation-only", - &only); - if (tresult == ISC_R_SUCCESS && cfg_obj_asboolean(only)) - CHECK(dns_view_adddelegationonly(view, origin)); - } else { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "ignoring non-root hint zone '%s'", - zname); - result = ISC_R_SUCCESS; - } - /* Skip ordinary zone processing. */ - goto cleanup; - } - - /* - * "forward zones" aren't zones either. Translate this syntax into - * the appropriate selective forwarding configuration and return. - */ - if (strcasecmp(ztypestr, "forward") == 0) { - forwardtype = NULL; - forwarders = NULL; - - (void)cfg_map_get(zoptions, "forward", &forwardtype); - (void)cfg_map_get(zoptions, "forwarders", &forwarders); - result = configure_forward(config, view, origin, forwarders, - forwardtype); - goto cleanup; - } - - /* - * "delegation-only zones" aren't zones either. - */ - if (strcasecmp(ztypestr, "delegation-only") == 0) { - result = dns_view_adddelegationonly(view, origin); - goto cleanup; - } - - /* - * Check for duplicates in the new zone table. - */ - result = dns_view_findzone(view, origin, &dupzone); - if (result == ISC_R_SUCCESS) { - /* - * We already have this zone! - */ - cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR, - "zone '%s' already exists", zname); - dns_zone_detach(&dupzone); - result = ISC_R_EXISTS; - goto cleanup; - } - INSIST(dupzone == NULL); - - /* - * See if we can reuse an existing zone. This is - * only possible if all of these are true: - * - The zone's view exists - * - A zone with the right name exists in the view - * - The zone is compatible with the config - * options (e.g., an existing master zone cannot - * be reused if the options specify a slave zone) - */ - result = dns_viewlist_find(&ns_g_server->viewlist, - view->name, view->rdclass, - &pview); - if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) - goto cleanup; - if (pview != NULL) - result = dns_view_findzone(pview, origin, &zone); - if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) - goto cleanup; - if (zone != NULL) { - if (! ns_zone_reusable(zone, zconfig)) - dns_zone_detach(&zone); - } - - if (zone != NULL) { - /* - * We found a reusable zone. Make it use the - * new view. - */ - dns_zone_setview(zone, view); - } else { - /* - * We cannot reuse an existing zone, we have - * to create a new one. - */ - CHECK(dns_zone_create(&zone, mctx)); - CHECK(dns_zone_setorigin(zone, origin)); - dns_zone_setview(zone, view); - CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone)); - } - - /* - * If the zone contains a 'forwarders' statement, configure - * selective forwarding. - */ - forwarders = NULL; - if (cfg_map_get(zoptions, "forwarders", &forwarders) == ISC_R_SUCCESS) - { - forwardtype = NULL; - (void)cfg_map_get(zoptions, "forward", &forwardtype); - CHECK(configure_forward(config, view, origin, forwarders, - forwardtype)); - } - - /* - * Stub and forward zones may also refer to delegation only points. - */ - only = NULL; - if (cfg_map_get(zoptions, "delegation-only", &only) == ISC_R_SUCCESS) - { - if (cfg_obj_asboolean(only)) - CHECK(dns_view_adddelegationonly(view, origin)); - } - - /* - * Configure the zone. - */ - CHECK(ns_zone_configure(config, vconfig, zconfig, aclconf, zone)); - - /* - * Add the zone to its view in the new view list. - */ - CHECK(dns_view_addzone(view, zone)); - - cleanup: - if (zone != NULL) - dns_zone_detach(&zone); - if (pview != NULL) - dns_view_detach(&pview); - - return (result); -} - -/* - * Configure a single server quota. - */ -static void -configure_server_quota(cfg_obj_t **maps, const char *name, isc_quota_t *quota) -{ - cfg_obj_t *obj = NULL; - isc_result_t result; - - result = ns_config_get(maps, name, &obj); - INSIST(result == ISC_R_SUCCESS); - isc_quota_max(quota, cfg_obj_asuint32(obj)); -} - -/* - * This function is called as soon as the 'directory' statement has been - * parsed. This can be extended to support other options if necessary. - */ -static isc_result_t -directory_callback(const char *clausename, cfg_obj_t *obj, void *arg) { - isc_result_t result; - char *directory; - - REQUIRE(strcasecmp("directory", clausename) == 0); - - UNUSED(arg); - UNUSED(clausename); - - /* - * Change directory. - */ - directory = cfg_obj_asstring(obj); - - if (! isc_file_ischdiridempotent(directory)) - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_WARNING, - "option 'directory' contains relative path '%s'", - directory); - - result = isc_dir_chdir(directory); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, - "change directory to '%s' failed: %s", - directory, isc_result_totext(result)); - return (result); - } - - return (ISC_R_SUCCESS); -} - -static void -scan_interfaces(ns_server_t *server, isc_boolean_t verbose) { - isc_boolean_t match_mapped = server->aclenv.match_mapped; - - ns_interfacemgr_scan(server->interfacemgr, verbose); - /* - * Update the "localhost" and "localnets" ACLs to match the - * current set of network interfaces. - */ - dns_aclenv_copy(&server->aclenv, - ns_interfacemgr_getaclenv(server->interfacemgr)); - - server->aclenv.match_mapped = match_mapped; -} - -static isc_result_t -add_listenelt(isc_mem_t *mctx, ns_listenlist_t *list, isc_sockaddr_t *addr) { - ns_listenelt_t *lelt = NULL; - dns_acl_t *src_acl = NULL; - dns_aclelement_t aelt; - isc_result_t result; - isc_sockaddr_t any_sa6; - - REQUIRE(isc_sockaddr_pf(addr) == AF_INET6); - - isc_sockaddr_any6(&any_sa6); - if (!isc_sockaddr_equal(&any_sa6, addr)) { - aelt.type = dns_aclelementtype_ipprefix; - aelt.negative = ISC_FALSE; - aelt.u.ip_prefix.prefixlen = 128; - isc_netaddr_fromin6(&aelt.u.ip_prefix.address, - &addr->type.sin6.sin6_addr); - - result = dns_acl_create(mctx, 1, &src_acl); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_acl_appendelement(src_acl, &aelt); - if (result != ISC_R_SUCCESS) - goto clean; - - result = ns_listenelt_create(mctx, isc_sockaddr_getport(addr), - src_acl, &lelt); - if (result != ISC_R_SUCCESS) - goto clean; - ISC_LIST_APPEND(list->elts, lelt, link); - } - - return (ISC_R_SUCCESS); - - clean: - INSIST(lelt == NULL); - if (src_acl != NULL) - dns_acl_detach(&src_acl); - - return (result); -} - -/* - * Make a list of xxx-source addresses and call ns_interfacemgr_adjust() - * to update the listening interfaces accordingly. - * We currently only consider IPv6, because this only affects IPv6 wildcard - * sockets. - */ -static void -adjust_interfaces(ns_server_t *server, isc_mem_t *mctx) { - isc_result_t result; - ns_listenlist_t *list = NULL; - dns_view_t *view; - dns_zone_t *zone, *next; - isc_sockaddr_t addr, *addrp; - - result = ns_listenlist_create(mctx, &list); - if (result != ISC_R_SUCCESS) - return; - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) { - dns_dispatch_t *dispatch6; - - dispatch6 = dns_resolver_dispatchv6(view->resolver); - if (dispatch6 == NULL) - continue; - result = dns_dispatch_getlocaladdress(dispatch6, &addr); - if (result != ISC_R_SUCCESS) - goto fail; - result = add_listenelt(mctx, list, &addr); - if (result != ISC_R_SUCCESS) - goto fail; - } - - zone = NULL; - for (result = dns_zone_first(server->zonemgr, &zone); - result == ISC_R_SUCCESS; - next = NULL, result = dns_zone_next(zone, &next), zone = next) { - dns_view_t *zoneview; - - /* - * At this point the zone list may contain a stale zone - * just removed from the configuration. To see the validity, - * check if the corresponding view is in our current view list. - * There may also be old zones that are still in the process - * of shutting down and have detached from their old view - * (zoneview == NULL). - */ - zoneview = dns_zone_getview(zone); - if (zoneview == NULL) - continue; - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL && view != zoneview; - view = ISC_LIST_NEXT(view, link)) - ; - if (view == NULL) - continue; - - addrp = dns_zone_getnotifysrc6(zone); - result = add_listenelt(mctx, list, addrp); - if (result != ISC_R_SUCCESS) - goto fail; - - addrp = dns_zone_getxfrsource6(zone); - result = add_listenelt(mctx, list, addrp); - if (result != ISC_R_SUCCESS) - goto fail; - } - - ns_interfacemgr_adjust(server->interfacemgr, list, ISC_TRUE); - - clean: - ns_listenlist_detach(&list); - return; - - fail: - /* - * Even when we failed the procedure, most of other interfaces - * should work correctly. We therefore just warn it. - */ - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "could not adjust the listen-on list; " - "some interfaces may not work"); - goto clean; -} - -/* - * This event callback is invoked to do periodic network - * interface scanning. - */ -static void -interface_timer_tick(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - ns_server_t *server = (ns_server_t *) event->ev_arg; - INSIST(task == server->task); - UNUSED(task); - isc_event_free(&event); - /* - * XXX should scan interfaces unlocked and get exclusive access - * only to replace ACLs. - */ - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - scan_interfaces(server, ISC_FALSE); - isc_task_endexclusive(server->task); -} - -static void -heartbeat_timer_tick(isc_task_t *task, isc_event_t *event) { - ns_server_t *server = (ns_server_t *) event->ev_arg; - dns_view_t *view; - - UNUSED(task); - isc_event_free(&event); - view = ISC_LIST_HEAD(server->viewlist); - while (view != NULL) { - dns_view_dialup(view); - view = ISC_LIST_NEXT(view, link); - } -} - -/* - * Replace the current value of '*field', a dynamically allocated - * string or NULL, with a dynamically allocated copy of the - * null-terminated string pointed to by 'value', or NULL. - */ -static isc_result_t -setstring(ns_server_t *server, char **field, const char *value) { - char *copy; - - if (value != NULL) { - copy = isc_mem_strdup(server->mctx, value); - if (copy == NULL) - return (ISC_R_NOMEMORY); - } else { - copy = NULL; - } - - if (*field != NULL) - isc_mem_free(server->mctx, *field); - - *field = copy; - return (ISC_R_SUCCESS); -} - -/* - * Replace the current value of '*field', a dynamically allocated - * string or NULL, with another dynamically allocated string - * or NULL if whether 'obj' is a string or void value, respectively. - */ -static isc_result_t -setoptstring(ns_server_t *server, char **field, cfg_obj_t *obj) { - if (cfg_obj_isvoid(obj)) - return (setstring(server, field, NULL)); - else - return (setstring(server, field, cfg_obj_asstring(obj))); -} - -static void -set_limit(cfg_obj_t **maps, const char *configname, const char *description, - isc_resource_t resourceid, isc_resourcevalue_t defaultvalue) -{ - cfg_obj_t *obj = NULL; - char *resource; - isc_resourcevalue_t value; - isc_result_t result; - - if (ns_config_get(maps, configname, &obj) != ISC_R_SUCCESS) - return; - - if (cfg_obj_isstring(obj)) { - resource = cfg_obj_asstring(obj); - if (strcasecmp(resource, "unlimited") == 0) - value = ISC_RESOURCE_UNLIMITED; - else { - INSIST(strcasecmp(resource, "default") == 0); - value = defaultvalue; - } - } else - value = cfg_obj_asuint64(obj); - - result = isc_resource_setlimit(resourceid, value); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - result == ISC_R_SUCCESS ? - ISC_LOG_DEBUG(3) : ISC_LOG_WARNING, - "set maximum %s to %" ISC_PRINT_QUADFORMAT "d: %s", - description, value, isc_result_totext(result)); -} - -#define SETLIMIT(cfgvar, resource, description) \ - set_limit(maps, cfgvar, description, isc_resource_ ## resource, \ - ns_g_init ## resource) - -static void -set_limits(cfg_obj_t **maps) { - SETLIMIT("stacksize", stacksize, "stack size"); - SETLIMIT("datasize", datasize, "data size"); - SETLIMIT("coresize", coresize, "core size"); - SETLIMIT("files", openfiles, "open files"); -} - -static isc_result_t -portlist_fromconf(dns_portlist_t *portlist, unsigned int family, - cfg_obj_t *ports) -{ - cfg_listelt_t *element; - isc_result_t result = ISC_R_SUCCESS; - - for (element = cfg_list_first(ports); - element != NULL; - element = cfg_list_next(element)) { - cfg_obj_t *obj = cfg_listelt_value(element); - in_port_t port = (in_port_t)cfg_obj_asuint32(obj); - - result = dns_portlist_add(portlist, family, port); - if (result != ISC_R_SUCCESS) - break; - } - return (result); -} - -static isc_result_t -load_configuration(const char *filename, ns_server_t *server, - isc_boolean_t first_time) -{ - isc_result_t result; - cfg_parser_t *parser = NULL; - cfg_obj_t *config; - cfg_obj_t *options; - cfg_obj_t *views; - cfg_obj_t *obj; - cfg_obj_t *v4ports, *v6ports; - cfg_obj_t *maps[3]; - cfg_obj_t *builtin_views; - cfg_listelt_t *element; - dns_view_t *view = NULL; - dns_view_t *view_next; - dns_viewlist_t viewlist; - dns_viewlist_t tmpviewlist; - ns_aclconfctx_t aclconfctx; - isc_uint32_t interface_interval; - isc_uint32_t heartbeat_interval; - isc_uint32_t udpsize; - in_port_t listen_port; - int i; - - ns_aclconfctx_init(&aclconfctx); - ISC_LIST_INIT(viewlist); - - /* Ensure exclusive access to configuration data. */ - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - /* - * Parse the global default pseudo-config file. - */ - if (first_time) { - CHECK(ns_config_parsedefaults(ns_g_parser, &ns_g_config)); - RUNTIME_CHECK(cfg_map_get(ns_g_config, "options", - &ns_g_defaults) == - ISC_R_SUCCESS); - } - - /* - * Parse the configuration file using the new config code. - */ - result = ISC_R_FAILURE; - config = NULL; - - /* - * Unless this is lwresd with the -C option, parse the config file. - */ - if (!(ns_g_lwresdonly && lwresd_g_useresolvconf)) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "loading configuration from '%s'", - filename); - CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &parser)); - cfg_parser_setcallback(parser, directory_callback, NULL); - result = cfg_parse_file(parser, filename, &cfg_type_namedconf, - &config); - } - - /* - * If this is lwresd with the -C option, or lwresd with no -C or -c - * option where the above parsing failed, parse resolv.conf. - */ - if (ns_g_lwresdonly && - (lwresd_g_useresolvconf || - (!ns_g_conffileset && result == ISC_R_FILENOTFOUND))) - { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "loading configuration from '%s'", - lwresd_g_resolvconffile); - if (parser != NULL) - cfg_parser_destroy(&parser); - CHECK(cfg_parser_create(ns_g_mctx, ns_g_lctx, &parser)); - result = ns_lwresd_parseeresolvconf(ns_g_mctx, parser, - &config); - } - CHECK(result); - - /* - * Check the validity of the configuration. - */ - CHECK(bind9_check_namedconf(config, ns_g_lctx, ns_g_mctx)); - - /* - * Fill in the maps array, used for resolving defaults. - */ - i = 0; - options = NULL; - result = cfg_map_get(config, "options", &options); - if (result == ISC_R_SUCCESS) - maps[i++] = options; - maps[i++] = ns_g_defaults; - maps[i++] = NULL; - - /* - * Set process limits, which (usually) needs to be done as root. - */ - set_limits(maps); - - /* - * Configure various server options. - */ - configure_server_quota(maps, "transfers-out", &server->xfroutquota); - configure_server_quota(maps, "tcp-clients", &server->tcpquota); - configure_server_quota(maps, "recursive-clients", - &server->recursionquota); - if (server->recursionquota.max > 1000) - isc_quota_soft(&server->recursionquota, - server->recursionquota.max - 100); - else - isc_quota_soft(&server->recursionquota, 0); - - CHECK(configure_view_acl(NULL, config, "blackhole", &aclconfctx, - ns_g_mctx, &server->blackholeacl)); - if (server->blackholeacl != NULL) - dns_dispatchmgr_setblackhole(ns_g_dispatchmgr, - server->blackholeacl); - - obj = NULL; - result = ns_config_get(maps, "match-mapped-addresses", &obj); - INSIST(result == ISC_R_SUCCESS); - server->aclenv.match_mapped = cfg_obj_asboolean(obj); - - v4ports = NULL; - v6ports = NULL; - (void)ns_config_get(maps, "avoid-v4-udp-ports", &v4ports); - (void)ns_config_get(maps, "avoid-v6-udp-ports", &v6ports); - if (v4ports != NULL || v6ports != NULL) { - dns_portlist_t *portlist = NULL; - result = dns_portlist_create(ns_g_mctx, &portlist); - if (result == ISC_R_SUCCESS && v4ports != NULL) - result = portlist_fromconf(portlist, AF_INET, v4ports); - if (result == ISC_R_SUCCESS && v6ports != NULL) - portlist_fromconf(portlist, AF_INET6, v6ports); - if (result == ISC_R_SUCCESS) - dns_dispatchmgr_setblackportlist(ns_g_dispatchmgr, portlist); - if (portlist != NULL) - dns_portlist_detach(&portlist); - CHECK(result); - } else - dns_dispatchmgr_setblackportlist(ns_g_dispatchmgr, NULL); - - /* - * Set the EDNS UDP size when we don't match a view. - */ - obj = NULL; - result = ns_config_get(maps, "edns-udp-size", &obj); - INSIST(result == ISC_R_SUCCESS); - udpsize = cfg_obj_asuint32(obj); - if (udpsize < 512) - udpsize = 512; - if (udpsize > 4096) - udpsize = 4096; - ns_g_udpsize = (isc_uint16_t)udpsize; - - /* - * Configure the zone manager. - */ - obj = NULL; - result = ns_config_get(maps, "transfers-in", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zonemgr_settransfersin(server->zonemgr, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "transfers-per-ns", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zonemgr_settransfersperns(server->zonemgr, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "serial-query-rate", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zonemgr_setserialqueryrate(server->zonemgr, cfg_obj_asuint32(obj)); - - /* - * Determine which port to use for listening for incoming connections. - */ - if (ns_g_port != 0) - listen_port = ns_g_port; - else - CHECKM(ns_config_getport(config, &listen_port), "port"); - - /* - * Find the listen queue depth. - */ - obj = NULL; - result = ns_config_get(maps, "tcp-listen-queue", &obj); - INSIST(result == ISC_R_SUCCESS); - ns_g_listen = cfg_obj_asuint32(obj); - if (ns_g_listen < 3) - ns_g_listen = 3; - - /* - * Configure the interface manager according to the "listen-on" - * statement. - */ - { - cfg_obj_t *clistenon = NULL; - ns_listenlist_t *listenon = NULL; - - clistenon = NULL; - /* - * Even though listen-on is present in the default - * configuration, we can't use it here, since it isn't - * used if we're in lwresd mode. This way is easier. - */ - if (options != NULL) - (void)cfg_map_get(options, "listen-on", &clistenon); - if (clistenon != NULL) { - result = ns_listenlist_fromconfig(clistenon, - config, - &aclconfctx, - ns_g_mctx, - &listenon); - } else if (!ns_g_lwresdonly) { - /* - * Not specified, use default. - */ - CHECK(ns_listenlist_default(ns_g_mctx, listen_port, - ISC_TRUE, &listenon)); - } - if (listenon != NULL) { - ns_interfacemgr_setlistenon4(server->interfacemgr, - listenon); - ns_listenlist_detach(&listenon); - } - } - /* - * Ditto for IPv6. - */ - { - cfg_obj_t *clistenon = NULL; - ns_listenlist_t *listenon = NULL; - - if (options != NULL) - (void)cfg_map_get(options, "listen-on-v6", &clistenon); - if (clistenon != NULL) { - result = ns_listenlist_fromconfig(clistenon, - config, - &aclconfctx, - ns_g_mctx, - &listenon); - } else if (!ns_g_lwresdonly) { - /* - * Not specified, use default. - */ - CHECK(ns_listenlist_default(ns_g_mctx, listen_port, - ISC_FALSE, &listenon)); - } - if (listenon != NULL) { - ns_interfacemgr_setlistenon6(server->interfacemgr, - listenon); - ns_listenlist_detach(&listenon); - } - } - - /* - * Rescan the interface list to pick up changes in the - * listen-on option. It's important that we do this before we try - * to configure the query source, since the dispatcher we use might - * be shared with an interface. - */ - scan_interfaces(server, ISC_TRUE); - - /* - * Arrange for further interface scanning to occur periodically - * as specified by the "interface-interval" option. - */ - obj = NULL; - result = ns_config_get(maps, "interface-interval", &obj); - INSIST(result == ISC_R_SUCCESS); - interface_interval = cfg_obj_asuint32(obj) * 60; - if (interface_interval == 0) { - CHECK(isc_timer_reset(server->interface_timer, - isc_timertype_inactive, - NULL, NULL, ISC_TRUE)); - } else if (server->interface_interval != interface_interval) { - isc_interval_t interval; - isc_interval_set(&interval, interface_interval, 0); - CHECK(isc_timer_reset(server->interface_timer, - isc_timertype_ticker, - NULL, &interval, ISC_FALSE)); - } - server->interface_interval = interface_interval; - - /* - * Configure the dialup heartbeat timer. - */ - obj = NULL; - result = ns_config_get(maps, "heartbeat-interval", &obj); - INSIST(result == ISC_R_SUCCESS); - heartbeat_interval = cfg_obj_asuint32(obj) * 60; - if (heartbeat_interval == 0) { - CHECK(isc_timer_reset(server->heartbeat_timer, - isc_timertype_inactive, - NULL, NULL, ISC_TRUE)); - } else if (server->heartbeat_interval != heartbeat_interval) { - isc_interval_t interval; - isc_interval_set(&interval, heartbeat_interval, 0); - CHECK(isc_timer_reset(server->heartbeat_timer, - isc_timertype_ticker, - NULL, &interval, ISC_FALSE)); - } - server->heartbeat_interval = heartbeat_interval; - - /* - * Configure and freeze all explicit views. Explicit - * views that have zones were already created at parsing - * time, but views with no zones must be created here. - */ - views = NULL; - (void)cfg_map_get(config, "view", &views); - for (element = cfg_list_first(views); - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *vconfig = cfg_listelt_value(element); - view = NULL; - - CHECK(create_view(vconfig, &viewlist, &view)); - INSIST(view != NULL); - CHECK(configure_view(view, config, vconfig, - ns_g_mctx, &aclconfctx, ISC_TRUE)); - dns_view_freeze(view); - dns_view_detach(&view); - } - - /* - * Make sure we have a default view if and only if there - * were no explicit views. - */ - if (views == NULL) { - /* - * No explicit views; there ought to be a default view. - * There may already be one created as a side effect - * of zone statements, or we may have to create one. - * In either case, we need to configure and freeze it. - */ - CHECK(create_view(NULL, &viewlist, &view)); - CHECK(configure_view(view, config, NULL, ns_g_mctx, - &aclconfctx, ISC_TRUE)); - dns_view_freeze(view); - dns_view_detach(&view); - } - - /* - * Create (or recreate) the built-in views. Currently - * there is only one, the _bind view. - */ - builtin_views = NULL; - RUNTIME_CHECK(cfg_map_get(ns_g_config, "view", - &builtin_views) == ISC_R_SUCCESS); - for (element = cfg_list_first(builtin_views); - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *vconfig = cfg_listelt_value(element); - CHECK(create_view(vconfig, &viewlist, &view)); - CHECK(configure_view(view, config, vconfig, ns_g_mctx, - &aclconfctx, ISC_FALSE)); - dns_view_freeze(view); - dns_view_detach(&view); - view = NULL; - } - - /* - * Swap our new view list with the production one. - */ - tmpviewlist = server->viewlist; - server->viewlist = viewlist; - viewlist = tmpviewlist; - - /* - * Load the TKEY information from the configuration. - */ - if (options != NULL) { - dns_tkeyctx_t *t = NULL; - CHECKM(ns_tkeyctx_fromconfig(options, ns_g_mctx, ns_g_entropy, - &t), - "configuring TKEY"); - if (server->tkeyctx != NULL) - dns_tkeyctx_destroy(&server->tkeyctx); - server->tkeyctx = t; - } - - /* - * Bind the control port(s). - */ - CHECKM(ns_controls_configure(ns_g_server->controls, config, - &aclconfctx), - "binding control channel(s)"); - - /* - * Bind the lwresd port(s). - */ - CHECKM(ns_lwresd_configure(ns_g_mctx, config), - "binding lightweight resolver ports"); - - /* - * Open the source of entropy. - */ - if (first_time) { - obj = NULL; - result = ns_config_get(maps, "random-device", &obj); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "no source of entropy found"); - } else { - const char *randomdev = cfg_obj_asstring(obj); - result = isc_entropy_createfilesource(ns_g_entropy, - randomdev); - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_INFO, - "could not open entropy source " - "%s: %s", - randomdev, - isc_result_totext(result)); -#ifdef PATH_RANDOMDEV - if (ns_g_fallbackentropy != NULL) { - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, - NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, - ISC_LOG_INFO, - "using pre-chroot entropy source " - "%s", - PATH_RANDOMDEV); - isc_entropy_detach(&ns_g_entropy); - isc_entropy_attach(ns_g_fallbackentropy, - &ns_g_entropy); - } - isc_entropy_detach(&ns_g_fallbackentropy); - } -#endif - } - } - - /* - * Relinquish root privileges. - */ - if (first_time) - ns_os_changeuser(); - - /* - * Configure the logging system. - * - * Do this after changing UID to make sure that any log - * files specified in named.conf get created by the - * unprivileged user, not root. - */ - if (ns_g_logstderr) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "ignoring config file logging " - "statement due to -g option"); - } else { - cfg_obj_t *logobj = NULL; - isc_logconfig_t *logc = NULL; - - CHECKM(isc_logconfig_create(ns_g_lctx, &logc), - "creating new logging configuration"); - - logobj = NULL; - (void)cfg_map_get(config, "logging", &logobj); - if (logobj != NULL) { - CHECKM(ns_log_configure(logc, logobj), - "configuring logging"); - } else { - CHECKM(ns_log_setdefaultchannels(logc), - "setting up default logging channels"); - CHECKM(ns_log_setunmatchedcategory(logc), - "setting up default 'category unmatched'"); - CHECKM(ns_log_setdefaultcategory(logc), - "setting up default 'category default'"); - } - - result = isc_logconfig_use(ns_g_lctx, logc); - if (result != ISC_R_SUCCESS) { - isc_logconfig_destroy(&logc); - CHECKM(result, "installing logging configuration"); - } - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(1), - "now using logging configuration from " - "config file"); - } - - /* - * Set the default value of the query logging flag depending - * whether a "queries" category has been defined. This is - * a disgusting hack, but we need to do this for BIND 8 - * compatibility. - */ - if (first_time) { - cfg_obj_t *logobj = NULL; - cfg_obj_t *categories = NULL; - - obj = NULL; - if (ns_config_get(maps, "querylog", &obj) == ISC_R_SUCCESS) { - server->log_queries = cfg_obj_asboolean(obj); - } else { - - (void)cfg_map_get(config, "logging", &logobj); - if (logobj != NULL) - (void)cfg_map_get(logobj, "category", - &categories); - if (categories != NULL) { - cfg_listelt_t *element; - for (element = cfg_list_first(categories); - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *catobj; - char *str; - - obj = cfg_listelt_value(element); - catobj = cfg_tuple_get(obj, "name"); - str = cfg_obj_asstring(catobj); - if (strcasecmp(str, "queries") == 0) - server->log_queries = ISC_TRUE; - } - } - } - } - - obj = NULL; - if (ns_config_get(maps, "pid-file", &obj) == ISC_R_SUCCESS) - if (cfg_obj_isvoid(obj)) - ns_os_writepidfile(NULL, first_time); - else - ns_os_writepidfile(cfg_obj_asstring(obj), first_time); - else if (ns_g_lwresdonly) - ns_os_writepidfile(lwresd_g_defaultpidfile, first_time); - else - ns_os_writepidfile(ns_g_defaultpidfile, first_time); - - obj = NULL; - if (options != NULL && - cfg_map_get(options, "memstatistics-file", &obj) == ISC_R_SUCCESS) - ns_main_setmemstats(cfg_obj_asstring(obj)); - else - ns_main_setmemstats(NULL); - - obj = NULL; - result = ns_config_get(maps, "statistics-file", &obj); - INSIST(result == ISC_R_SUCCESS); - CHECKM(setstring(server, &server->statsfile, cfg_obj_asstring(obj)), - "strdup"); - - obj = NULL; - result = ns_config_get(maps, "dump-file", &obj); - INSIST(result == ISC_R_SUCCESS); - CHECKM(setstring(server, &server->dumpfile, cfg_obj_asstring(obj)), - "strdup"); - - obj = NULL; - result = ns_config_get(maps, "recursing-file", &obj); - INSIST(result == ISC_R_SUCCESS); - CHECKM(setstring(server, &server->recfile, cfg_obj_asstring(obj)), - "strdup"); - - obj = NULL; - result = ns_config_get(maps, "version", &obj); - if (result == ISC_R_SUCCESS) { - CHECKM(setoptstring(server, &server->version, obj), "strdup"); - server->version_set = ISC_TRUE; - } else { - server->version_set = ISC_FALSE; - } - - obj = NULL; - result = ns_config_get(maps, "hostname", &obj); - if (result == ISC_R_SUCCESS) { - CHECKM(setoptstring(server, &server->hostname, obj), "strdup"); - server->hostname_set = ISC_TRUE; - } else { - server->hostname_set = ISC_FALSE; - } - - obj = NULL; - result = ns_config_get(maps, "server-id", &obj); - server->server_usehostname = ISC_FALSE; - if (result == ISC_R_SUCCESS && cfg_obj_isboolean(obj)) { - server->server_usehostname = ISC_TRUE; - } else if (result == ISC_R_SUCCESS) { - CHECKM(setoptstring(server, &server->server_id, obj), "strdup"); - } else { - result = setoptstring(server, &server->server_id, NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - } - - obj = NULL; - result = ns_config_get(maps, "flush-zones-on-shutdown", &obj); - if (result == ISC_R_SUCCESS) { - server->flushonshutdown = cfg_obj_asboolean(obj); - } else { - server->flushonshutdown = ISC_FALSE; - } - - result = ISC_R_SUCCESS; - - cleanup: - ns_aclconfctx_destroy(&aclconfctx); - - if (parser != NULL) { - if (config != NULL) - cfg_obj_destroy(parser, &config); - cfg_parser_destroy(&parser); - } - - if (view != NULL) - dns_view_detach(&view); - - /* - * This cleans up either the old production view list - * or our temporary list depending on whether they - * were swapped above or not. - */ - for (view = ISC_LIST_HEAD(viewlist); - view != NULL; - view = view_next) { - view_next = ISC_LIST_NEXT(view, link); - ISC_LIST_UNLINK(viewlist, view, link); - dns_view_detach(&view); - - } - - /* - * Adjust the listening interfaces in accordance with the source - * addresses specified in views and zones. - */ - if (isc_net_probeipv6() == ISC_R_SUCCESS) - adjust_interfaces(server, ns_g_mctx); - - /* Relinquish exclusive access to configuration data. */ - isc_task_endexclusive(server->task); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_DEBUG(1), "load_configuration: %s", - isc_result_totext(result)); - - return (result); -} - -static isc_result_t -load_zones(ns_server_t *server, isc_boolean_t stop) { - isc_result_t result; - dns_view_t *view; - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - /* - * Load zone data from disk. - */ - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - CHECK(dns_view_load(view, stop)); - } - - /* - * Force zone maintenance. Do this after loading - * so that we know when we need to force AXFR of - * slave zones whose master files are missing. - */ - CHECK(dns_zonemgr_forcemaint(server->zonemgr)); - cleanup: - isc_task_endexclusive(server->task); - return (result); -} - -static isc_result_t -load_new_zones(ns_server_t *server, isc_boolean_t stop) { - isc_result_t result; - dns_view_t *view; - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - /* - * Load zone data from disk. - */ - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - CHECK(dns_view_loadnew(view, stop)); - } - /* - * Force zone maintenance. Do this after loading - * so that we know when we need to force AXFR of - * slave zones whose master files are missing. - */ - dns_zonemgr_resumexfrs(server->zonemgr); - cleanup: - isc_task_endexclusive(server->task); - return (result); -} - -static void -run_server(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - ns_server_t *server = (ns_server_t *)event->ev_arg; - - INSIST(task == server->task); - - isc_event_free(&event); - - CHECKFATAL(dns_dispatchmgr_create(ns_g_mctx, ns_g_entropy, - &ns_g_dispatchmgr), - "creating dispatch manager"); - - CHECKFATAL(ns_interfacemgr_create(ns_g_mctx, ns_g_taskmgr, - ns_g_socketmgr, ns_g_dispatchmgr, - &server->interfacemgr), - "creating interface manager"); - - CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive, - NULL, NULL, server->task, - interface_timer_tick, - server, &server->interface_timer), - "creating interface timer"); - - CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive, - NULL, NULL, server->task, - heartbeat_timer_tick, - server, &server->heartbeat_timer), - "creating heartbeat timer"); - - CHECKFATAL(cfg_parser_create(ns_g_mctx, NULL, &ns_g_parser), - "creating default configuration parser"); - - if (ns_g_lwresdonly) - CHECKFATAL(load_configuration(lwresd_g_conffile, server, - ISC_TRUE), - "loading configuration"); - else - CHECKFATAL(load_configuration(ns_g_conffile, server, ISC_TRUE), - "loading configuration"); - - isc_hash_init(); - - CHECKFATAL(load_zones(server, ISC_FALSE), "loading zones"); - - ns_os_started(); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_NOTICE, "running"); -} - -void -ns_server_flushonshutdown(ns_server_t *server, isc_boolean_t flush) { - - REQUIRE(NS_SERVER_VALID(server)); - - server->flushonshutdown = flush; -} - -static void -shutdown_server(isc_task_t *task, isc_event_t *event) { - isc_result_t result; - dns_view_t *view, *view_next; - ns_server_t *server = (ns_server_t *)event->ev_arg; - isc_boolean_t flush = server->flushonshutdown; - - UNUSED(task); - INSIST(task == server->task); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_INFO, "shutting down%s", - flush ? ": flushing changes" : ""); - - ns_controls_shutdown(server->controls); - end_reserved_dispatches(server, ISC_TRUE); - - cfg_obj_destroy(ns_g_parser, &ns_g_config); - cfg_parser_destroy(&ns_g_parser); - - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = view_next) { - view_next = ISC_LIST_NEXT(view, link); - ISC_LIST_UNLINK(server->viewlist, view, link); - if (flush) - dns_view_flushanddetach(&view); - else - dns_view_detach(&view); - } - - isc_timer_detach(&server->interface_timer); - isc_timer_detach(&server->heartbeat_timer); - - ns_interfacemgr_shutdown(server->interfacemgr); - ns_interfacemgr_detach(&server->interfacemgr); - - dns_dispatchmgr_destroy(&ns_g_dispatchmgr); - - dns_zonemgr_shutdown(server->zonemgr); - - if (server->blackholeacl != NULL) - dns_acl_detach(&server->blackholeacl); - - dns_db_detach(&server->in_roothints); - - isc_task_endexclusive(server->task); - - isc_task_detach(&server->task); - - isc_event_free(&event); -} - -void -ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) { - isc_result_t result; - - ns_server_t *server = isc_mem_get(mctx, sizeof(*server)); - if (server == NULL) - fatal("allocating server object", ISC_R_NOMEMORY); - - server->mctx = mctx; - server->task = NULL; - - /* Initialize configuration data with default values. */ - - result = isc_quota_init(&server->xfroutquota, 10); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - result = isc_quota_init(&server->tcpquota, 10); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - result = isc_quota_init(&server->recursionquota, 100); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - result = dns_aclenv_init(mctx, &server->aclenv); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - - /* Initialize server data structures. */ - server->zonemgr = NULL; - server->interfacemgr = NULL; - ISC_LIST_INIT(server->viewlist); - server->in_roothints = NULL; - server->blackholeacl = NULL; - - CHECKFATAL(dns_rootns_create(mctx, dns_rdataclass_in, NULL, - &server->in_roothints), - "setting up root hints"); - - CHECKFATAL(isc_mutex_init(&server->reload_event_lock), - "initializing reload event lock"); - server->reload_event = - isc_event_allocate(ns_g_mctx, server, - NS_EVENT_RELOAD, - ns_server_reload, - server, - sizeof(isc_event_t)); - CHECKFATAL(server->reload_event == NULL ? - ISC_R_NOMEMORY : ISC_R_SUCCESS, - "allocating reload event"); - - CHECKFATAL(dst_lib_init(ns_g_mctx, ns_g_entropy, ISC_ENTROPY_GOODONLY), - "initializing DST"); - - server->tkeyctx = NULL; - CHECKFATAL(dns_tkeyctx_create(ns_g_mctx, ns_g_entropy, - &server->tkeyctx), - "creating TKEY context"); - - /* - * Setup the server task, which is responsible for coordinating - * startup and shutdown of the server. - */ - CHECKFATAL(isc_task_create(ns_g_taskmgr, 0, &server->task), - "creating server task"); - isc_task_setname(server->task, "server", server); - CHECKFATAL(isc_task_onshutdown(server->task, shutdown_server, server), - "isc_task_onshutdown"); - CHECKFATAL(isc_app_onrun(ns_g_mctx, server->task, run_server, server), - "isc_app_onrun"); - - server->interface_timer = NULL; - server->heartbeat_timer = NULL; - - server->interface_interval = 0; - server->heartbeat_interval = 0; - - CHECKFATAL(dns_zonemgr_create(ns_g_mctx, ns_g_taskmgr, ns_g_timermgr, - ns_g_socketmgr, &server->zonemgr), - "dns_zonemgr_create"); - - server->statsfile = isc_mem_strdup(server->mctx, "named.stats"); - CHECKFATAL(server->statsfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS, - "isc_mem_strdup"); - server->querystats = NULL; - - server->dumpfile = isc_mem_strdup(server->mctx, "named_dump.db"); - CHECKFATAL(server->dumpfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS, - "isc_mem_strdup"); - - server->recfile = isc_mem_strdup(server->mctx, "named.recursing"); - CHECKFATAL(server->recfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS, - "isc_mem_strdup"); - - server->hostname_set = ISC_FALSE; - server->hostname = NULL; - server->version_set = ISC_FALSE; - server->version = NULL; - server->server_usehostname = ISC_FALSE; - server->server_id = NULL; - - CHECKFATAL(dns_stats_alloccounters(ns_g_mctx, &server->querystats), - "dns_stats_alloccounters"); - - server->flushonshutdown = ISC_FALSE; - server->log_queries = ISC_FALSE; - - server->controls = NULL; - CHECKFATAL(ns_controls_create(server, &server->controls), - "ns_controls_create"); - server->dispatchgen = 0; - ISC_LIST_INIT(server->dispatches); - - server->magic = NS_SERVER_MAGIC; - *serverp = server; -} - -void -ns_server_destroy(ns_server_t **serverp) { - ns_server_t *server = *serverp; - REQUIRE(NS_SERVER_VALID(server)); - - ns_controls_destroy(&server->controls); - - dns_stats_freecounters(server->mctx, &server->querystats); - - isc_mem_free(server->mctx, server->statsfile); - isc_mem_free(server->mctx, server->dumpfile); - isc_mem_free(server->mctx, server->recfile); - - if (server->version != NULL) - isc_mem_free(server->mctx, server->version); - if (server->hostname != NULL) - isc_mem_free(server->mctx, server->hostname); - if (server->server_id != NULL) - isc_mem_free(server->mctx, server->server_id); - - dns_zonemgr_detach(&server->zonemgr); - - if (server->tkeyctx != NULL) - dns_tkeyctx_destroy(&server->tkeyctx); - - dst_lib_destroy(); - - isc_event_free(&server->reload_event); - - INSIST(ISC_LIST_EMPTY(server->viewlist)); - - dns_aclenv_destroy(&server->aclenv); - - isc_quota_destroy(&server->recursionquota); - isc_quota_destroy(&server->tcpquota); - isc_quota_destroy(&server->xfroutquota); - - server->magic = 0; - isc_mem_put(server->mctx, server, sizeof(*server)); - *serverp = NULL; -} - -static void -fatal(const char *msg, isc_result_t result) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_CRITICAL, "%s: %s", msg, - isc_result_totext(result)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, - ISC_LOG_CRITICAL, "exiting (due to fatal error)"); - exit(1); -} - -static void -start_reserved_dispatches(ns_server_t *server) { - - REQUIRE(NS_SERVER_VALID(server)); - - server->dispatchgen++; -} - -static void -end_reserved_dispatches(ns_server_t *server, isc_boolean_t all) { - ns_dispatch_t *dispatch, *nextdispatch; - - REQUIRE(NS_SERVER_VALID(server)); - - for (dispatch = ISC_LIST_HEAD(server->dispatches); - dispatch != NULL; - dispatch = nextdispatch) { - nextdispatch = ISC_LIST_NEXT(dispatch, link); - if (!all && server->dispatchgen == dispatch-> dispatchgen) - continue; - ISC_LIST_UNLINK(server->dispatches, dispatch, link); - dns_dispatch_detach(&dispatch->dispatch); - isc_mem_put(server->mctx, dispatch, sizeof(*dispatch)); - } -} - -void -ns_add_reserved_dispatch(ns_server_t *server, isc_sockaddr_t *addr) { - ns_dispatch_t *dispatch; - in_port_t port; - char addrbuf[ISC_SOCKADDR_FORMATSIZE]; - isc_result_t result; - unsigned int attrs, attrmask; - - REQUIRE(NS_SERVER_VALID(server)); - - port = isc_sockaddr_getport(addr); - if (port == 0 || port >= 1024) - return; - - for (dispatch = ISC_LIST_HEAD(server->dispatches); - dispatch != NULL; - dispatch = ISC_LIST_NEXT(dispatch, link)) { - if (isc_sockaddr_equal(&dispatch->addr, addr)) - break; - } - if (dispatch != NULL) { - dispatch->dispatchgen = server->dispatchgen; - return; - } - - dispatch = isc_mem_get(server->mctx, sizeof(*dispatch)); - if (dispatch == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - - dispatch->addr = *addr; - dispatch->dispatchgen = server->dispatchgen; - dispatch->dispatch = NULL; - - attrs = 0; - attrs |= DNS_DISPATCHATTR_UDP; - switch (isc_sockaddr_pf(addr)) { - case AF_INET: - attrs |= DNS_DISPATCHATTR_IPV4; - break; - case AF_INET6: - attrs |= DNS_DISPATCHATTR_IPV6; - break; - default: - result = ISC_R_NOTIMPLEMENTED; - goto cleanup; - } - attrmask = 0; - attrmask |= DNS_DISPATCHATTR_UDP; - attrmask |= DNS_DISPATCHATTR_TCP; - attrmask |= DNS_DISPATCHATTR_IPV4; - attrmask |= DNS_DISPATCHATTR_IPV6; - - result = dns_dispatch_getudp(ns_g_dispatchmgr, ns_g_socketmgr, - ns_g_taskmgr, &dispatch->addr, 4096, - 1000, 32768, 16411, 16433, - attrs, attrmask, &dispatch->dispatch); - if (result != ISC_R_SUCCESS) - goto cleanup; - - ISC_LIST_INITANDPREPEND(server->dispatches, dispatch, link); - - return; - - cleanup: - if (dispatch != NULL) - isc_mem_put(server->mctx, dispatch, sizeof(*dispatch)); - isc_sockaddr_format(addr, addrbuf, sizeof(addrbuf)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "unable to create dispatch for reserved port %s: %s", - addrbuf, isc_result_totext(result)); -} - - -static isc_result_t -loadconfig(ns_server_t *server) { - isc_result_t result; - start_reserved_dispatches(server); - result = load_configuration(ns_g_lwresdonly ? - lwresd_g_conffile : ns_g_conffile, - server, ISC_FALSE); - if (result == ISC_R_SUCCESS) - end_reserved_dispatches(server, ISC_FALSE); - else - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "reloading configuration failed: %s", - isc_result_totext(result)); - return (result); -} - -static isc_result_t -reload(ns_server_t *server) { - isc_result_t result; - CHECK(loadconfig(server)); - - result = load_zones(server, ISC_FALSE); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "reloading zones failed: %s", - isc_result_totext(result)); - } - cleanup: - return (result); -} - -static void -reconfig(ns_server_t *server) { - isc_result_t result; - CHECK(loadconfig(server)); - - result = load_new_zones(server, ISC_FALSE); - if (result != ISC_R_SUCCESS) { - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_ERROR, - "loading new zones failed: %s", - isc_result_totext(result)); - } - cleanup: ; -} - -/* - * Handle a reload event (from SIGHUP). - */ -static void -ns_server_reload(isc_task_t *task, isc_event_t *event) { - ns_server_t *server = (ns_server_t *)event->ev_arg; - - INSIST(task = server->task); - UNUSED(task); - - (void)reload(server); - - LOCK(&server->reload_event_lock); - INSIST(server->reload_event == NULL); - server->reload_event = event; - UNLOCK(&server->reload_event_lock); -} - -void -ns_server_reloadwanted(ns_server_t *server) { - LOCK(&server->reload_event_lock); - if (server->reload_event != NULL) - isc_task_send(server->task, &server->reload_event); - UNLOCK(&server->reload_event_lock); -} - -static char * -next_token(char **stringp, const char *delim) { - char *res; - - do { - res = strsep(stringp, delim); - if (res == NULL) - break; - } while (*res == '\0'); - return (res); -} - -/* - * Find the zone specified in the control channel command 'args', - * if any. If a zone is specified, point '*zonep' at it, otherwise - * set '*zonep' to NULL. - */ -static isc_result_t -zone_from_args(ns_server_t *server, char *args, dns_zone_t **zonep) { - char *input, *ptr; - const char *zonetxt; - char *classtxt; - const char *viewtxt = NULL; - dns_fixedname_t name; - isc_result_t result; - isc_buffer_t buf; - dns_view_t *view = NULL; - dns_rdataclass_t rdclass; - - REQUIRE(zonep != NULL && *zonep == NULL); - - input = args; - - /* Skip the command name. */ - ptr = next_token(&input, " \t"); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Look for the zone name. */ - zonetxt = next_token(&input, " \t"); - if (zonetxt == NULL) - return (ISC_R_SUCCESS); - - /* Look for the optional class name. */ - classtxt = next_token(&input, " \t"); - if (classtxt != NULL) { - /* Look for the optional view name. */ - viewtxt = next_token(&input, " \t"); - } - - isc_buffer_init(&buf, zonetxt, strlen(zonetxt)); - isc_buffer_add(&buf, strlen(zonetxt)); - dns_fixedname_init(&name); - result = dns_name_fromtext(dns_fixedname_name(&name), - &buf, dns_rootname, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) - goto fail1; - - if (classtxt != NULL) { - isc_textregion_t r; - r.base = classtxt; - r.length = strlen(classtxt); - result = dns_rdataclass_fromtext(&rdclass, &r); - if (result != ISC_R_SUCCESS) - goto fail1; - } else { - rdclass = dns_rdataclass_in; - } - - if (viewtxt == NULL) - viewtxt = "_default"; - result = dns_viewlist_find(&server->viewlist, viewtxt, - rdclass, &view); - if (result != ISC_R_SUCCESS) - goto fail1; - - result = dns_zt_find(view->zonetable, dns_fixedname_name(&name), - 0, NULL, zonep); - /* Partial match? */ - if (result != ISC_R_SUCCESS && *zonep != NULL) - dns_zone_detach(zonep); - dns_view_detach(&view); - fail1: - return (result); -} - -/* - * Act on a "retransfer" command from the command channel. - */ -isc_result_t -ns_server_retransfercommand(ns_server_t *server, char *args) { - isc_result_t result; - dns_zone_t *zone = NULL; - dns_zonetype_t type; - - result = zone_from_args(server, args, &zone); - if (result != ISC_R_SUCCESS) - return (result); - if (zone == NULL) - return (ISC_R_UNEXPECTEDEND); - type = dns_zone_gettype(zone); - if (type == dns_zone_slave || type == dns_zone_stub) - dns_zone_forcereload(zone); - else - result = ISC_R_NOTFOUND; - dns_zone_detach(&zone); - return (result); -} - -/* - * Act on a "reload" command from the command channel. - */ -isc_result_t -ns_server_reloadcommand(ns_server_t *server, char *args, isc_buffer_t *text) { - isc_result_t result; - dns_zone_t *zone = NULL; - dns_zonetype_t type; - const char *msg = NULL; - - result = zone_from_args(server, args, &zone); - if (result != ISC_R_SUCCESS) - return (result); - if (zone == NULL) { - result = reload(server); - if (result == ISC_R_SUCCESS) - msg = "server reload successful"; - } else { - type = dns_zone_gettype(zone); - if (type == dns_zone_slave || type == dns_zone_stub) { - dns_zone_refresh(zone); - msg = "zone refresh queued"; - } else { - result = dns_zone_load(zone); - dns_zone_detach(&zone); - switch (result) { - case ISC_R_SUCCESS: - msg = "zone reload successful"; - break; - case DNS_R_CONTINUE: - msg = "zone reload queued"; - result = ISC_R_SUCCESS; - break; - case DNS_R_UPTODATE: - msg = "zone reload up-to-date"; - result = ISC_R_SUCCESS; - break; - default: - /* failure message will be generated by rndc */ - break; - } - } - } - if (msg != NULL && strlen(msg) < isc_buffer_availablelength(text)) - isc_buffer_putmem(text, (const unsigned char *)msg, - strlen(msg) + 1); - return (result); -} - -/* - * Act on a "reconfig" command from the command channel. - */ -isc_result_t -ns_server_reconfigcommand(ns_server_t *server, char *args) { - UNUSED(args); - - reconfig(server); - return (ISC_R_SUCCESS); -} - -/* - * Act on a "refresh" command from the command channel. - */ -isc_result_t -ns_server_refreshcommand(ns_server_t *server, char *args, isc_buffer_t *text) { - isc_result_t result; - dns_zone_t *zone = NULL; - const unsigned char msg[] = "zone refresh queued"; - - result = zone_from_args(server, args, &zone); - if (result != ISC_R_SUCCESS) - return (result); - if (zone == NULL) - return (ISC_R_UNEXPECTEDEND); - - dns_zone_refresh(zone); - dns_zone_detach(&zone); - if (sizeof(msg) <= isc_buffer_availablelength(text)) - isc_buffer_putmem(text, msg, sizeof(msg)); - - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_server_togglequerylog(ns_server_t *server) { - server->log_queries = server->log_queries ? ISC_FALSE : ISC_TRUE; - - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "query logging is now %s", - server->log_queries ? "on" : "off"); - return (ISC_R_SUCCESS); -} - -static isc_result_t -ns_listenlist_fromconfig(cfg_obj_t *listenlist, cfg_obj_t *config, - ns_aclconfctx_t *actx, - isc_mem_t *mctx, ns_listenlist_t **target) -{ - isc_result_t result; - cfg_listelt_t *element; - ns_listenlist_t *dlist = NULL; - - REQUIRE(target != NULL && *target == NULL); - - result = ns_listenlist_create(mctx, &dlist); - if (result != ISC_R_SUCCESS) - return (result); - - for (element = cfg_list_first(listenlist); - element != NULL; - element = cfg_list_next(element)) - { - ns_listenelt_t *delt = NULL; - cfg_obj_t *listener = cfg_listelt_value(element); - result = ns_listenelt_fromconfig(listener, config, actx, - mctx, &delt); - if (result != ISC_R_SUCCESS) - goto cleanup; - ISC_LIST_APPEND(dlist->elts, delt, link); - } - *target = dlist; - return (ISC_R_SUCCESS); - - cleanup: - ns_listenlist_detach(&dlist); - return (result); -} - -/* - * Create a listen list from the corresponding configuration - * data structure. - */ -static isc_result_t -ns_listenelt_fromconfig(cfg_obj_t *listener, cfg_obj_t *config, - ns_aclconfctx_t *actx, - isc_mem_t *mctx, ns_listenelt_t **target) -{ - isc_result_t result; - cfg_obj_t *portobj; - in_port_t port; - ns_listenelt_t *delt = NULL; - REQUIRE(target != NULL && *target == NULL); - - portobj = cfg_tuple_get(listener, "port"); - if (!cfg_obj_isuint32(portobj)) { - if (ns_g_port != 0) { - port = ns_g_port; - } else { - result = ns_config_getport(config, &port); - if (result != ISC_R_SUCCESS) - return (result); - } - } else { - if (cfg_obj_asuint32(portobj) >= ISC_UINT16_MAX) { - cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, - "port value '%u' is out of range", - cfg_obj_asuint32(portobj)); - return (ISC_R_RANGE); - } - port = (in_port_t)cfg_obj_asuint32(portobj); - } - - result = ns_listenelt_create(mctx, port, NULL, &delt); - if (result != ISC_R_SUCCESS) - return (result); - - result = ns_acl_fromconfig(cfg_tuple_get(listener, "acl"), - config, actx, mctx, &delt->acl); - if (result != ISC_R_SUCCESS) { - ns_listenelt_destroy(delt); - return (result); - } - *target = delt; - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_server_dumpstats(ns_server_t *server) { - isc_result_t result; - dns_zone_t *zone, *next; - isc_stdtime_t now; - FILE *fp = NULL; - int i; - int ncounters; - - isc_stdtime_get(&now); - - CHECKMF(isc_stdio_open(server->statsfile, "a", &fp), - "could not open statistics dump file", server->statsfile); - - ncounters = DNS_STATS_NCOUNTERS; - fprintf(fp, "+++ Statistics Dump +++ (%lu)\n", (unsigned long)now); - - for (i = 0; i < ncounters; i++) - fprintf(fp, "%s %" ISC_PRINT_QUADFORMAT "u\n", - dns_statscounter_names[i], - server->querystats[i]); - - zone = NULL; - for (result = dns_zone_first(server->zonemgr, &zone); - result == ISC_R_SUCCESS; - next = NULL, result = dns_zone_next(zone, &next), zone = next) - { - isc_uint64_t *zonestats = dns_zone_getstatscounters(zone); - if (zonestats != NULL) { - char zonename[DNS_NAME_FORMATSIZE]; - dns_view_t *view; - char *viewname; - - dns_name_format(dns_zone_getorigin(zone), - zonename, sizeof(zonename)); - view = dns_zone_getview(zone); - viewname = view->name; - for (i = 0; i < ncounters; i++) { - fprintf(fp, "%s %" ISC_PRINT_QUADFORMAT - "u %s", - dns_statscounter_names[i], - zonestats[i], - zonename); - if (strcmp(viewname, "_default") != 0) - fprintf(fp, " %s", viewname); - fprintf(fp, "\n"); - } - } - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - CHECK(result); - - fprintf(fp, "--- Statistics Dump --- (%lu)\n", (unsigned long)now); - - cleanup: - if (fp != NULL) - (void)isc_stdio_close(fp); - return (result); -} - -static isc_result_t -add_zone_tolist(dns_zone_t *zone, void *uap) { - struct dumpcontext *dctx = uap; - struct zonelistentry *zle; - - zle = isc_mem_get(dctx->mctx, sizeof *zle); - if (zle == NULL) - return (ISC_R_NOMEMORY); - zle->zone = NULL; - dns_zone_attach(zone, &zle->zone); - ISC_LINK_INIT(zle, link); - ISC_LIST_APPEND(ISC_LIST_TAIL(dctx->viewlist)->zonelist, zle, link); - return (ISC_R_SUCCESS); -} - -static isc_result_t -add_view_tolist(struct dumpcontext *dctx, dns_view_t *view) { - struct viewlistentry *vle; - isc_result_t result = ISC_R_SUCCESS; - - /* - * Prevent duplicate views. - */ - for (vle = ISC_LIST_HEAD(dctx->viewlist); - vle != NULL; - vle = ISC_LIST_NEXT(vle, link)) - if (vle->view == view) - return (ISC_R_SUCCESS); - - vle = isc_mem_get(dctx->mctx, sizeof *vle); - if (vle == NULL) - return (ISC_R_NOMEMORY); - vle->view = NULL; - dns_view_attach(view, &vle->view); - ISC_LINK_INIT(vle, link); - ISC_LIST_INIT(vle->zonelist); - ISC_LIST_APPEND(dctx->viewlist, vle, link); - if (dctx->dumpzones) - result = dns_zt_apply(view->zonetable, ISC_TRUE, - add_zone_tolist, dctx); - return (result); -} - -static void -dumpcontext_destroy(struct dumpcontext *dctx) { - struct viewlistentry *vle; - struct zonelistentry *zle; - - vle = ISC_LIST_HEAD(dctx->viewlist); - while (vle != NULL) { - ISC_LIST_UNLINK(dctx->viewlist, vle, link); - zle = ISC_LIST_HEAD(vle->zonelist); - while (zle != NULL) { - ISC_LIST_UNLINK(vle->zonelist, zle, link); - dns_zone_detach(&zle->zone); - isc_mem_put(dctx->mctx, zle, sizeof *zle); - zle = ISC_LIST_HEAD(vle->zonelist); - } - dns_view_detach(&vle->view); - isc_mem_put(dctx->mctx, vle, sizeof *vle); - vle = ISC_LIST_HEAD(dctx->viewlist); - } - if (dctx->version != NULL) - dns_db_closeversion(dctx->db, &dctx->version, ISC_FALSE); - if (dctx->db != NULL) - dns_db_detach(&dctx->db); - if (dctx->cache != NULL) - dns_db_detach(&dctx->cache); - if (dctx->task != NULL) - isc_task_detach(&dctx->task); - if (dctx->fp != NULL) - (void)isc_stdio_close(dctx->fp); - if (dctx->mdctx != NULL) - dns_dumpctx_detach(&dctx->mdctx); - isc_mem_put(dctx->mctx, dctx, sizeof *dctx); -} - -static void -dumpdone(void *arg, isc_result_t result) { - struct dumpcontext *dctx = arg; - char buf[1024+32]; - const dns_master_style_t *style; - - if (result != ISC_R_SUCCESS) - goto cleanup; - if (dctx->mdctx != NULL) - dns_dumpctx_detach(&dctx->mdctx); - if (dctx->view == NULL) { - dctx->view = ISC_LIST_HEAD(dctx->viewlist); - if (dctx->view == NULL) - goto done; - INSIST(dctx->zone == NULL); - } else - goto resume; - nextview: - fprintf(dctx->fp, ";\n; Start view %s\n;\n", dctx->view->view->name); - resume: - if (dctx->zone == NULL && dctx->cache == NULL && dctx->dumpcache) { - style = &dns_master_style_cache; - /* start cache dump */ - if (dctx->view->view->cachedb != NULL) - dns_db_attach(dctx->view->view->cachedb, &dctx->cache); - if (dctx->cache != NULL) { - - fprintf(dctx->fp, ";\n; Cache dump of view '%s'\n;\n", - dctx->view->view->name); - result = dns_master_dumptostreaminc(dctx->mctx, - dctx->cache, NULL, - style, dctx->fp, - dctx->task, - dumpdone, dctx, - &dctx->mdctx); - if (result == DNS_R_CONTINUE) - return; - if (result == ISC_R_NOTIMPLEMENTED) - fprintf(dctx->fp, "; %s\n", - dns_result_totext(result)); - else if (result != ISC_R_SUCCESS) - goto cleanup; - } - } - if (dctx->cache != NULL) { - dns_adb_dump(dctx->view->view->adb, dctx->fp); - dns_db_detach(&dctx->cache); - } - if (dctx->dumpzones) { - style = &dns_master_style_full; - nextzone: - if (dctx->version != NULL) - dns_db_closeversion(dctx->db, &dctx->version, - ISC_FALSE); - if (dctx->db != NULL) - dns_db_detach(&dctx->db); - if (dctx->zone == NULL) - dctx->zone = ISC_LIST_HEAD(dctx->view->zonelist); - else - dctx->zone = ISC_LIST_NEXT(dctx->zone, link); - if (dctx->zone != NULL) { - /* start zone dump */ - dns_zone_name(dctx->zone->zone, buf, sizeof(buf)); - fprintf(dctx->fp, ";\n; Zone dump of '%s'\n;\n", buf); - result = dns_zone_getdb(dctx->zone->zone, &dctx->db); - if (result != ISC_R_SUCCESS) { - fprintf(dctx->fp, "; %s\n", - dns_result_totext(result)); - goto nextzone; - } - dns_db_currentversion(dctx->db, &dctx->version); - result = dns_master_dumptostreaminc(dctx->mctx, - dctx->db, - dctx->version, - style, dctx->fp, - dctx->task, - dumpdone, dctx, - &dctx->mdctx); - if (result == DNS_R_CONTINUE) - return; - if (result == ISC_R_NOTIMPLEMENTED) { - fprintf(dctx->fp, "; %s\n", - dns_result_totext(result)); - result = ISC_R_SUCCESS; - goto nextzone; - } - if (result != ISC_R_SUCCESS) - goto cleanup; - } - } - if (dctx->view != NULL) - dctx->view = ISC_LIST_NEXT(dctx->view, link); - if (dctx->view != NULL) - goto nextview; - done: - fprintf(dctx->fp, "; Dump complete\n"); - result = isc_stdio_flush(dctx->fp); - if (result == ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "dumpdb complete"); - cleanup: - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "dumpdb failed: %s", dns_result_totext(result)); - dumpcontext_destroy(dctx); -} - -isc_result_t -ns_server_dumpdb(ns_server_t *server, char *args) { - struct dumpcontext *dctx = NULL; - dns_view_t *view; - isc_result_t result; - char *ptr; - const char *sep; - - dctx = isc_mem_get(server->mctx, sizeof(*dctx)); - if (dctx == NULL) - return (ISC_R_NOMEMORY); - - dctx->mctx = server->mctx; - dctx->dumpcache = ISC_TRUE; - dctx->dumpzones = ISC_FALSE; - dctx->fp = NULL; - ISC_LIST_INIT(dctx->viewlist); - dctx->view = NULL; - dctx->zone = NULL; - dctx->cache = NULL; - dctx->mdctx = NULL; - dctx->db = NULL; - dctx->cache = NULL; - dctx->task = NULL; - dctx->version = NULL; - isc_task_attach(server->task, &dctx->task); - - CHECKMF(isc_stdio_open(server->dumpfile, "w", &dctx->fp), - "could not open dump file", server->dumpfile); - - /* Skip the command name. */ - ptr = next_token(&args, " \t"); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - sep = (args == NULL) ? "" : ": "; - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "dumpdb started%s%s", sep, (args != NULL) ? args : ""); - - ptr = next_token(&args, " \t"); - if (ptr != NULL && strcmp(ptr, "-all") == 0) { - dctx->dumpzones = ISC_TRUE; - dctx->dumpcache = ISC_TRUE; - ptr = next_token(&args, " \t"); - } else if (ptr != NULL && strcmp(ptr, "-cache") == 0) { - dctx->dumpzones = ISC_FALSE; - dctx->dumpcache = ISC_TRUE; - ptr = next_token(&args, " \t"); - } else if (ptr != NULL && strcmp(ptr, "-zones") == 0) { - dctx->dumpzones = ISC_TRUE; - dctx->dumpcache = ISC_FALSE; - ptr = next_token(&args, " \t"); - } - - nextview: - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (ptr != NULL && strcmp(view->name, ptr) != 0) - continue; - CHECK(add_view_tolist(dctx, view)); - } - if (ptr != NULL) { - ptr = next_token(&args, " \t"); - if (ptr != NULL) - goto nextview; - } - dumpdone(dctx, ISC_R_SUCCESS); - return (ISC_R_SUCCESS); - - cleanup: - if (dctx != NULL) - dumpcontext_destroy(dctx); - return (result); -} - -isc_result_t -ns_server_dumprecursing(ns_server_t *server) { - FILE *fp = NULL; - isc_result_t result; - - CHECKMF(isc_stdio_open(server->recfile, "w", &fp), - "could not open dump file", server->recfile); - fprintf(fp,";\n; Recursing Queries\n;\n"); - ns_interfacemgr_dumprecursing(fp, server->interfacemgr); - fprintf(fp, "; Dump complete\n"); - - cleanup: - if (fp != NULL) - result = isc_stdio_close(fp); - return (result); -} - -isc_result_t -ns_server_setdebuglevel(ns_server_t *server, char *args) { - char *ptr; - char *levelstr; - char *endp; - long newlevel; - - UNUSED(server); - - /* Skip the command name. */ - ptr = next_token(&args, " \t"); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Look for the new level name. */ - levelstr = next_token(&args, " \t"); - if (levelstr == NULL) { - if (ns_g_debuglevel < 99) - ns_g_debuglevel++; - } else { - newlevel = strtol(levelstr, &endp, 10); - if (*endp != '\0' || newlevel < 0 || newlevel > 99) - return (ISC_R_RANGE); - ns_g_debuglevel = (unsigned int)newlevel; - } - isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel); - return (ISC_R_SUCCESS); -} - -isc_result_t -ns_server_flushcache(ns_server_t *server, char *args) { - char *ptr, *viewname; - dns_view_t *view; - isc_boolean_t flushed = ISC_FALSE; - isc_result_t result; - - /* Skip the command name. */ - ptr = next_token(&args, " \t"); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Look for the view name. */ - viewname = next_token(&args, " \t"); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (viewname != NULL && strcasecmp(viewname, view->name) != 0) - continue; - result = dns_view_flushcache(view); - if (result != ISC_R_SUCCESS) - goto out; - flushed = ISC_TRUE; - } - if (flushed) - result = ISC_R_SUCCESS; - else - result = ISC_R_FAILURE; - out: - isc_task_endexclusive(server->task); - return (result); -} - -isc_result_t -ns_server_flushname(ns_server_t *server, char *args) { - char *ptr, *target, *viewname; - dns_view_t *view; - isc_boolean_t flushed = ISC_FALSE; - isc_result_t result; - isc_buffer_t b; - dns_fixedname_t fixed; - dns_name_t *name; - - /* Skip the command name. */ - ptr = next_token(&args, " \t"); - if (ptr == NULL) - return (ISC_R_UNEXPECTEDEND); - - /* Find the domain name to flush. */ - target = next_token(&args, " \t"); - if (target == NULL) - return (ISC_R_UNEXPECTEDEND); - - isc_buffer_init(&b, target, strlen(target)); - isc_buffer_add(&b, strlen(target)); - dns_fixedname_init(&fixed); - name = dns_fixedname_name(&fixed); - result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) - return (result); - - /* Look for the view name. */ - viewname = next_token(&args, " \t"); - - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - flushed = ISC_TRUE; - for (view = ISC_LIST_HEAD(server->viewlist); - view != NULL; - view = ISC_LIST_NEXT(view, link)) - { - if (viewname != NULL && strcasecmp(viewname, view->name) != 0) - continue; - result = dns_view_flushname(view, name); - if (result != ISC_R_SUCCESS) - flushed = ISC_FALSE; - } - if (flushed) - result = ISC_R_SUCCESS; - else - result = ISC_R_FAILURE; - isc_task_endexclusive(server->task); - return (result); -} - -isc_result_t -ns_server_status(ns_server_t *server, isc_buffer_t *text) { - int zonecount, xferrunning, xferdeferred, soaqueries; - unsigned int n; - - zonecount = dns_zonemgr_getcount(server->zonemgr, DNS_ZONESTATE_ANY); - xferrunning = dns_zonemgr_getcount(server->zonemgr, - DNS_ZONESTATE_XFERRUNNING); - xferdeferred = dns_zonemgr_getcount(server->zonemgr, - DNS_ZONESTATE_XFERDEFERRED); - soaqueries = dns_zonemgr_getcount(server->zonemgr, - DNS_ZONESTATE_SOAQUERY); - n = snprintf((char *)isc_buffer_used(text), - isc_buffer_availablelength(text), - "number of zones: %u\n" - "debug level: %d\n" - "xfers running: %u\n" - "xfers deferred: %u\n" - "soa queries in progress: %u\n" - "query logging is %s\n" - "recursive clients: %d/%d\n" - "tcp clients: %d/%d\n" - "server is up and running", - zonecount, ns_g_debuglevel, xferrunning, xferdeferred, - soaqueries, server->log_queries ? "ON" : "OFF", - server->recursionquota.used, server->recursionquota.max, - server->tcpquota.used, server->tcpquota.max); - if (n >= isc_buffer_availablelength(text)) - return (ISC_R_NOSPACE); - isc_buffer_add(text, n); - return (ISC_R_SUCCESS); -} - -/* - * Act on a "freeze" or "unfreeze" command from the command channel. - */ -isc_result_t -ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args) { - isc_result_t result; - dns_zone_t *zone = NULL; - dns_zonetype_t type; - char classstr[DNS_RDATACLASS_FORMATSIZE]; - char zonename[DNS_NAME_FORMATSIZE]; - dns_view_t *view; - char *journal; - const char *vname, *sep; - isc_boolean_t frozen; - - result = zone_from_args(server, args, &zone); - if (result != ISC_R_SUCCESS) - return (result); - if (zone == NULL) - return (ISC_R_UNEXPECTEDEND); - type = dns_zone_gettype(zone); - if (type != dns_zone_master) { - dns_zone_detach(&zone); - return (ISC_R_NOTFOUND); - } - - frozen = dns_zone_getupdatedisabled(zone); - if (freeze) { - if (frozen) - result = DNS_R_FROZEN; - if (result == ISC_R_SUCCESS) - result = dns_zone_flush(zone); - if (result == ISC_R_SUCCESS) { - journal = dns_zone_getjournal(zone); - if (journal != NULL) - (void)isc_file_remove(journal); - } - } else { - if (frozen) { - result = dns_zone_load(zone); - if (result == DNS_R_CONTINUE || - result == DNS_R_UPTODATE) - result = ISC_R_SUCCESS; - } - } - if (result == ISC_R_SUCCESS) - dns_zone_setupdatedisabled(zone, freeze); - - view = dns_zone_getview(zone); - if (strcmp(view->name, "_bind") == 0 || - strcmp(view->name, "_default") == 0) - { - vname = ""; - sep = ""; - } else { - vname = view->name; - sep = " "; - } - dns_rdataclass_format(dns_zone_getclass(zone), classstr, - sizeof(classstr)); - dns_name_format(dns_zone_getorigin(zone), - zonename, sizeof(zonename)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_SERVER, ISC_LOG_INFO, - "%s zone '%s/%s'%s%s: %s", - freeze ? "freezing" : "unfreezing", - zonename, classstr, sep, vname, - isc_result_totext(result)); - dns_zone_detach(&zone); - return (result); -} - -#ifdef HAVE_LIBSCF -/* - * This function adds a message for rndc to echo if named - * is managed by smf and is also running chroot. - */ -isc_result_t -ns_smf_add_message(isc_buffer_t *text) { - unsigned int n; - - n = snprintf((char *)isc_buffer_used(text), - isc_buffer_availablelength(text), - "use svcadm(1M) to manage named"); - if (n >= isc_buffer_availablelength(text)) - return (ISC_R_NOSPACE); - isc_buffer_add(text, n); - return (ISC_R_SUCCESS); -} -#endif /* HAVE_LIBSCF */ diff --git a/contrib/bind9/bin/named/sortlist.c b/contrib/bind9/bin/named/sortlist.c deleted file mode 100644 index 0098fe779c89..000000000000 --- a/contrib/bind9/bin/named/sortlist.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: sortlist.c,v 1.5.12.4 2004/03/08 04:04:19 marka Exp $ */ - -#include <config.h> - -#include <isc/mem.h> -#include <isc/util.h> - -#include <dns/acl.h> -#include <dns/result.h> - -#include <named/globals.h> -#include <named/server.h> -#include <named/sortlist.h> - -ns_sortlisttype_t -ns_sortlist_setup(dns_acl_t *acl, isc_netaddr_t *clientaddr, void **argp) { - unsigned int i; - - if (acl == NULL) - goto dont_sort; - - for (i = 0; i < acl->length; i++) { - /* - * 'e' refers to the current 'top level statement' - * in the sortlist (see ARM). - */ - dns_aclelement_t *e = &acl->elements[i]; - dns_aclelement_t *try_elt; - dns_aclelement_t *order_elt = NULL; - dns_aclelement_t *matched_elt = NULL; - - if (e->type == dns_aclelementtype_nestedacl) { - dns_acl_t *inner = e->u.nestedacl; - - if (inner->length < 1 || inner->length > 2) - goto dont_sort; - if (inner->elements[0].negative) - goto dont_sort; - try_elt = &inner->elements[0]; - if (inner->length == 2) - order_elt = &inner->elements[1]; - } else { - /* - * BIND 8 allows bare elements at the top level - * as an undocumented feature. - */ - try_elt = e; - } - - if (dns_aclelement_match(clientaddr, NULL, try_elt, - &ns_g_server->aclenv, - &matched_elt)) { - if (order_elt != NULL) { - if (order_elt->type == - dns_aclelementtype_nestedacl) { - *argp = order_elt->u.nestedacl; - return (NS_SORTLISTTYPE_2ELEMENT); - } else if (order_elt->type == - dns_aclelementtype_localhost && - ns_g_server->aclenv.localhost != NULL) { - *argp = ns_g_server->aclenv.localhost; - return (NS_SORTLISTTYPE_2ELEMENT); - } else if (order_elt->type == - dns_aclelementtype_localnets && - ns_g_server->aclenv.localnets != NULL) { - *argp = ns_g_server->aclenv.localnets; - return (NS_SORTLISTTYPE_2ELEMENT); - } else { - /* - * BIND 8 allows a bare IP prefix as - * the 2nd element of a 2-element - * sortlist statement. - */ - *argp = order_elt; - return (NS_SORTLISTTYPE_1ELEMENT); - } - } else { - INSIST(matched_elt != NULL); - *argp = matched_elt; - return (NS_SORTLISTTYPE_1ELEMENT); - } - } - } - - /* No match; don't sort. */ - dont_sort: - *argp = NULL; - return (NS_SORTLISTTYPE_NONE); -} - -int -ns_sortlist_addrorder2(isc_netaddr_t *addr, void *arg) { - dns_acl_t *sortacl = (dns_acl_t *) arg; - int match; - - (void)dns_acl_match(addr, NULL, sortacl, - &ns_g_server->aclenv, - &match, NULL); - if (match > 0) - return (match); - else if (match < 0) - return (INT_MAX - (-match)); - else - return (INT_MAX / 2); -} - -int -ns_sortlist_addrorder1(isc_netaddr_t *addr, void *arg) { - dns_aclelement_t *matchelt = (dns_aclelement_t *) arg; - if (dns_aclelement_match(addr, NULL, matchelt, - &ns_g_server->aclenv, - NULL)) { - return (0); - } else { - return (INT_MAX); - } -} - -void -ns_sortlist_byaddrsetup(dns_acl_t *sortlist_acl, isc_netaddr_t *client_addr, - dns_addressorderfunc_t *orderp, - void **argp) -{ - ns_sortlisttype_t sortlisttype; - - sortlisttype = ns_sortlist_setup(sortlist_acl, client_addr, argp); - - switch (sortlisttype) { - case NS_SORTLISTTYPE_1ELEMENT: - *orderp = ns_sortlist_addrorder1; - break; - case NS_SORTLISTTYPE_2ELEMENT: - *orderp = ns_sortlist_addrorder2; - break; - case NS_SORTLISTTYPE_NONE: - *orderp = NULL; - break; - default: - UNEXPECTED_ERROR(__FILE__, __LINE__, - "unexpected return from ns_sortlist_setup(): " - "%d", sortlisttype); - break; - } -} - diff --git a/contrib/bind9/bin/named/tkeyconf.c b/contrib/bind9/bin/named/tkeyconf.c deleted file mode 100644 index 7fc13f3d9c0b..000000000000 --- a/contrib/bind9/bin/named/tkeyconf.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: tkeyconf.c,v 1.19.208.2 2004/06/11 00:30:51 marka Exp $ */ - -#include <config.h> - -#include <isc/buffer.h> -#include <isc/string.h> /* Required for HP/UX (and others?) */ -#include <isc/mem.h> - -#include <isccfg/cfg.h> - -#include <dns/fixedname.h> -#include <dns/keyvalues.h> -#include <dns/name.h> -#include <dns/tkey.h> - -#include <dst/gssapi.h> - -#include <named/tkeyconf.h> - -#define RETERR(x) do { \ - result = (x); \ - if (result != ISC_R_SUCCESS) \ - goto failure; \ - } while (0) - - -isc_result_t -ns_tkeyctx_fromconfig(cfg_obj_t *options, isc_mem_t *mctx, isc_entropy_t *ectx, - dns_tkeyctx_t **tctxp) -{ - isc_result_t result; - dns_tkeyctx_t *tctx = NULL; - char *s; - isc_uint32_t n; - dns_fixedname_t fname; - dns_name_t *name; - isc_buffer_t b; - cfg_obj_t *obj; - int type; - - result = dns_tkeyctx_create(mctx, ectx, &tctx); - if (result != ISC_R_SUCCESS) - return (result); - - obj = NULL; - result = cfg_map_get(options, "tkey-dhkey", &obj); - if (result == ISC_R_SUCCESS) { - s = cfg_obj_asstring(cfg_tuple_get(obj, "name")); - n = cfg_obj_asuint32(cfg_tuple_get(obj, "keyid")); - isc_buffer_init(&b, s, strlen(s)); - isc_buffer_add(&b, strlen(s)); - dns_fixedname_init(&fname); - name = dns_fixedname_name(&fname); - RETERR(dns_name_fromtext(name, &b, dns_rootname, - ISC_FALSE, NULL)); - type = DST_TYPE_PUBLIC|DST_TYPE_PRIVATE|DST_TYPE_KEY; - RETERR(dst_key_fromfile(name, (dns_keytag_t) n, DNS_KEYALG_DH, - type, NULL, mctx, &tctx->dhkey)); - } - - obj = NULL; - result = cfg_map_get(options, "tkey-domain", &obj); - if (result == ISC_R_SUCCESS) { - s = cfg_obj_asstring(obj); - isc_buffer_init(&b, s, strlen(s)); - isc_buffer_add(&b, strlen(s)); - dns_fixedname_init(&fname); - name = dns_fixedname_name(&fname); - RETERR(dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, - NULL)); - tctx->domain = isc_mem_get(mctx, sizeof(dns_name_t)); - if (tctx->domain == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - dns_name_init(tctx->domain, NULL); - RETERR(dns_name_dup(name, mctx, tctx->domain)); - } - - obj = NULL; - result = cfg_map_get(options, "tkey-gssapi-credential", &obj); - if (result == ISC_R_SUCCESS) { - s = cfg_obj_asstring(obj); - isc_buffer_init(&b, s, strlen(s)); - isc_buffer_add(&b, strlen(s)); - dns_fixedname_init(&fname); - name = dns_fixedname_name(&fname); - RETERR(dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, - NULL)); - RETERR(dst_gssapi_acquirecred(name, ISC_FALSE, - &tctx->gsscred)); - } - - *tctxp = tctx; - return (ISC_R_SUCCESS); - - failure: - dns_tkeyctx_destroy(&tctx); - return (result); -} - diff --git a/contrib/bind9/bin/named/tsigconf.c b/contrib/bind9/bin/named/tsigconf.c deleted file mode 100644 index 38524c37fad7..000000000000 --- a/contrib/bind9/bin/named/tsigconf.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: tsigconf.c,v 1.21.208.4 2004/03/08 04:04:19 marka Exp $ */ - -#include <config.h> - -#include <isc/base64.h> -#include <isc/buffer.h> -#include <isc/mem.h> -#include <isc/string.h> - -#include <isccfg/cfg.h> - -#include <dns/tsig.h> -#include <dns/result.h> - -#include <named/log.h> - -#include <named/config.h> -#include <named/tsigconf.h> - -static isc_result_t -add_initial_keys(cfg_obj_t *list, dns_tsig_keyring_t *ring, isc_mem_t *mctx) { - cfg_listelt_t *element; - cfg_obj_t *key = NULL; - char *keyid = NULL; - unsigned char *secret = NULL; - int secretalloc = 0; - int secretlen = 0; - isc_result_t ret; - isc_stdtime_t now; - - for (element = cfg_list_first(list); - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *algobj = NULL; - cfg_obj_t *secretobj = NULL; - dns_name_t keyname; - dns_name_t *alg; - char *algstr; - char keynamedata[1024]; - isc_buffer_t keynamesrc, keynamebuf; - char *secretstr; - isc_buffer_t secretbuf; - - key = cfg_listelt_value(element); - keyid = cfg_obj_asstring(cfg_map_getname(key)); - - algobj = NULL; - secretobj = NULL; - (void)cfg_map_get(key, "algorithm", &algobj); - (void)cfg_map_get(key, "secret", &secretobj); - INSIST(algobj != NULL && secretobj != NULL); - - /* - * Create the key name. - */ - dns_name_init(&keyname, NULL); - isc_buffer_init(&keynamesrc, keyid, strlen(keyid)); - isc_buffer_add(&keynamesrc, strlen(keyid)); - isc_buffer_init(&keynamebuf, keynamedata, sizeof(keynamedata)); - ret = dns_name_fromtext(&keyname, &keynamesrc, dns_rootname, - ISC_TRUE, &keynamebuf); - if (ret != ISC_R_SUCCESS) - goto failure; - - /* - * Create the algorithm. - */ - algstr = cfg_obj_asstring(algobj); - if (ns_config_getkeyalgorithm(algstr, &alg) != ISC_R_SUCCESS) { - cfg_obj_log(algobj, ns_g_lctx, ISC_LOG_ERROR, - "key '%s': the only supported algorithm " - "is hmac-md5", keyid); - ret = DNS_R_BADALG; - goto failure; - } - - secretstr = cfg_obj_asstring(secretobj); - secretalloc = secretlen = strlen(secretstr) * 3 / 4; - secret = isc_mem_get(mctx, secretlen); - if (secret == NULL) { - ret = ISC_R_NOMEMORY; - goto failure; - } - isc_buffer_init(&secretbuf, secret, secretlen); - ret = isc_base64_decodestring(secretstr, &secretbuf); - if (ret != ISC_R_SUCCESS) - goto failure; - secretlen = isc_buffer_usedlength(&secretbuf); - - isc_stdtime_get(&now); - ret = dns_tsigkey_create(&keyname, alg, secret, secretlen, - ISC_FALSE, NULL, now, now, - mctx, ring, NULL); - isc_mem_put(mctx, secret, secretalloc); - secret = NULL; - if (ret != ISC_R_SUCCESS) - goto failure; - } - - return (ISC_R_SUCCESS); - - failure: - cfg_obj_log(key, ns_g_lctx, ISC_LOG_ERROR, - "configuring key '%s': %s", keyid, - isc_result_totext(ret)); - - if (secret != NULL) - isc_mem_put(mctx, secret, secretalloc); - return (ret); - -} - -isc_result_t -ns_tsigkeyring_fromconfig(cfg_obj_t *config, cfg_obj_t *vconfig, - isc_mem_t *mctx, dns_tsig_keyring_t **ringp) -{ - cfg_obj_t *maps[3]; - cfg_obj_t *keylist; - dns_tsig_keyring_t *ring = NULL; - isc_result_t result; - int i; - - i = 0; - if (config != NULL) - maps[i++] = config; - if (vconfig != NULL) - maps[i++] = cfg_tuple_get(vconfig, "options"); - maps[i] = NULL; - - result = dns_tsigkeyring_create(mctx, &ring); - if (result != ISC_R_SUCCESS) - return (result); - - for (i = 0; ; i++) { - if (maps[i] == NULL) - break; - keylist = NULL; - result = cfg_map_get(maps[i], "key", &keylist); - if (result != ISC_R_SUCCESS) - continue; - result = add_initial_keys(keylist, ring, mctx); - if (result != ISC_R_SUCCESS) - goto failure; - } - - *ringp = ring; - return (ISC_R_SUCCESS); - - failure: - dns_tsigkeyring_destroy(&ring); - return (result); -} diff --git a/contrib/bind9/bin/named/unix/Makefile.in b/contrib/bind9/bin/named/unix/Makefile.in deleted file mode 100644 index 60ce968865dc..000000000000 --- a/contrib/bind9/bin/named/unix/Makefile.in +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 1999-2001 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 ISC DISCLAIMS ALL WARRANTIES WITH -# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, -# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -# PERFORMANCE OF THIS SOFTWARE. - -# $Id: Makefile.in,v 1.6.12.3 2004/03/08 09:04:15 marka Exp $ - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -@BIND9_MAKE_INCLUDES@ - -CINCLUDES = -I${srcdir}/include -I${srcdir}/../include \ - ${DNS_INCLUDES} ${ISC_INCLUDES} - -CDEFINES = -CWARNINGS = - -OBJS = os.@O@ - -SRCS = os.c - -TARGETS = ${OBJS} - -@BIND9_MAKE_RULES@ diff --git a/contrib/bind9/bin/named/unix/include/named/os.h b/contrib/bind9/bin/named/unix/include/named/os.h deleted file mode 100644 index 03baee57ea48..000000000000 --- a/contrib/bind9/bin/named/unix/include/named/os.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: os.h,v 1.14.2.2.8.9 2004/09/29 06:36:44 marka Exp $ */ - -#ifndef NS_OS_H -#define NS_OS_H 1 - -#include <isc/types.h> - -void -ns_os_init(const char *progname); - -void -ns_os_daemonize(void); - -void -ns_os_opendevnull(void); - -void -ns_os_closedevnull(void); - -void -ns_os_chroot(const char *root); - -void -ns_os_inituserinfo(const char *username); - -void -ns_os_changeuser(void); - -void -ns_os_minprivs(void); - -void -ns_os_writepidfile(const char *filename, isc_boolean_t first_time); - -void -ns_os_shutdown(void); - -isc_result_t -ns_os_gethostname(char *buf, size_t len); - -void -ns_os_shutdownmsg(char *command, isc_buffer_t *text); - -void -ns_os_tzset(void); - -void -ns_os_started(void); - -#endif /* NS_OS_H */ diff --git a/contrib/bind9/bin/named/unix/os.c b/contrib/bind9/bin/named/unix/os.c deleted file mode 100644 index f306f1462259..000000000000 --- a/contrib/bind9/bin/named/unix/os.c +++ /dev/null @@ -1,682 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: os.c,v 1.46.2.4.8.22 2005/05/20 01:37:19 marka Exp $ */ - -#include <config.h> -#include <stdarg.h> - -#include <sys/types.h> /* dev_t FreeBSD 2.1 */ -#include <sys/stat.h> - -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> -#include <grp.h> /* Required for initgroups() on IRIX. */ -#include <pwd.h> -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <syslog.h> -#ifdef HAVE_TZSET -#include <time.h> -#endif -#include <unistd.h> - -#include <isc/buffer.h> -#include <isc/file.h> -#include <isc/print.h> -#include <isc/result.h> -#include <isc/strerror.h> -#include <isc/string.h> - -#include <named/main.h> -#include <named/os.h> -#ifdef HAVE_LIBSCF -#include <named/ns_smf_globals.h> -#endif - -static char *pidfile = NULL; -static int devnullfd = -1; - -#ifndef ISC_FACILITY -#define ISC_FACILITY LOG_DAEMON -#endif - -/* - * If there's no <linux/capability.h>, we don't care about <sys/prctl.h> - */ -#ifndef HAVE_LINUX_CAPABILITY_H -#undef HAVE_SYS_PRCTL_H -#endif - -/* - * Linux defines: - * (T) HAVE_LINUXTHREADS - * (C) HAVE_LINUX_CAPABILITY_H - * (P) HAVE_SYS_PRCTL_H - * The possible cases are: - * none: setuid() normally - * T: no setuid() - * C: setuid() normally, drop caps (keep CAP_SETUID) - * T+C: no setuid(), drop caps (don't keep CAP_SETUID) - * T+C+P: setuid() early, drop caps (keep CAP_SETUID) - * C+P: setuid() normally, drop caps (keep CAP_SETUID) - * P: not possible - * T+P: not possible - * - * if (C) - * caps = BIND_SERVICE + CHROOT + SETGID - * if ((T && C && P) || !T) - * caps += SETUID - * endif - * capset(caps) - * endif - * if (T && C && P && -u) - * setuid() - * else if (T && -u) - * fail - * --> start threads - * if (!T && -u) - * setuid() - * if (C && (P || !-u)) - * caps = BIND_SERVICE - * capset(caps) - * endif - * - * It will be nice when Linux threads work properly with setuid(). - */ - -#ifdef HAVE_LINUXTHREADS -static pid_t mainpid = 0; -#endif - -static struct passwd *runas_pw = NULL; -static isc_boolean_t done_setuid = ISC_FALSE; -static int dfd[2] = { -1, -1 }; - -#ifdef HAVE_LINUX_CAPABILITY_H - -static isc_boolean_t non_root = ISC_FALSE; -static isc_boolean_t non_root_caps = ISC_FALSE; - -/* - * We define _LINUX_FS_H to prevent it from being included. We don't need - * anything from it, and the files it includes cause warnings with 2.2 - * kernels, and compilation failures (due to conflicts between <linux/string.h> - * and <string.h>) on 2.3 kernels. - */ -#define _LINUX_FS_H - -#include <sys/syscall.h> /* Required for syscall(). */ -#include <linux/capability.h> /* Required for _LINUX_CAPABILITY_VERSION. */ - -#ifdef HAVE_SYS_PRCTL_H -#include <sys/prctl.h> /* Required for prctl(). */ - -/* - * If the value of PR_SET_KEEPCAPS is not in <sys/prctl.h>, define it - * here. This allows setuid() to work on systems running a new enough - * kernel but with /usr/include/linux pointing to "standard" kernel - * headers. - */ -#ifndef PR_SET_KEEPCAPS -#define PR_SET_KEEPCAPS 8 -#endif - -#endif /* HAVE_SYS_PRCTL_H */ - -#ifndef SYS_capset -#ifndef __NR_capset -#include <asm/unistd.h> /* Slackware 4.0 needs this. */ -#endif -#define SYS_capset __NR_capset -#endif - -static void -linux_setcaps(unsigned int caps) { - struct __user_cap_header_struct caphead; - struct __user_cap_data_struct cap; - char strbuf[ISC_STRERRORSIZE]; - - if ((getuid() != 0 && !non_root_caps) || non_root) - return; - - memset(&caphead, 0, sizeof(caphead)); - caphead.version = _LINUX_CAPABILITY_VERSION; - caphead.pid = 0; - memset(&cap, 0, sizeof(cap)); - cap.effective = caps; - cap.permitted = caps; - cap.inheritable = 0; - if (syscall(SYS_capset, &caphead, &cap) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("capset failed: %s:" - " please ensure that the capset kernel" - " module is loaded. see insmod(8)", - strbuf); - } -} - -static void -linux_initialprivs(void) { - unsigned int caps; - - /* - * We don't need most privileges, so we drop them right away. - * Later on linux_minprivs() will be called, which will drop our - * capabilities to the minimum needed to run the server. - */ - - caps = 0; - - /* - * We need to be able to bind() to privileged ports, notably port 53! - */ - caps |= (1 << CAP_NET_BIND_SERVICE); - - /* - * We need chroot() initially too. - */ - caps |= (1 << CAP_SYS_CHROOT); - -#if defined(HAVE_SYS_PRCTL_H) || !defined(HAVE_LINUXTHREADS) - /* - * We can setuid() only if either the kernel supports keeping - * capabilities after setuid() (which we don't know until we've - * tried) or we're not using threads. If either of these is - * true, we want the setuid capability. - */ - caps |= (1 << CAP_SETUID); -#endif - - /* - * Since we call initgroups, we need this. - */ - caps |= (1 << CAP_SETGID); - - /* - * Without this, we run into problems reading a configuration file - * owned by a non-root user and non-world-readable on startup. - */ - caps |= (1 << CAP_DAC_READ_SEARCH); - - /* - * XXX We might want to add CAP_SYS_RESOURCE, though it's not - * clear it would work right given the way linuxthreads work. - * XXXDCL But since we need to be able to set the maximum number - * of files, the stack size, data size, and core dump size to - * support named.conf options, this is now being added to test. - */ - caps |= (1 << CAP_SYS_RESOURCE); - - linux_setcaps(caps); -} - -static void -linux_minprivs(void) { - unsigned int caps; - - /* - * Drop all privileges except the ability to bind() to privileged - * ports. - * - * It's important that we drop CAP_SYS_CHROOT. If we didn't, it - * chroot() could be used to escape from the chrooted area. - */ - - caps = 0; - caps |= (1 << CAP_NET_BIND_SERVICE); - - /* - * XXX We might want to add CAP_SYS_RESOURCE, though it's not - * clear it would work right given the way linuxthreads work. - * XXXDCL But since we need to be able to set the maximum number - * of files, the stack size, data size, and core dump size to - * support named.conf options, this is now being added to test. - */ - caps |= (1 << CAP_SYS_RESOURCE); - - linux_setcaps(caps); -} - -#ifdef HAVE_SYS_PRCTL_H -static void -linux_keepcaps(void) { - char strbuf[ISC_STRERRORSIZE]; - /* - * Ask the kernel to allow us to keep our capabilities after we - * setuid(). - */ - - if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) { - if (errno != EINVAL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("prctl() failed: %s", strbuf); - } - } else { - non_root_caps = ISC_TRUE; - if (getuid() != 0) - non_root = ISC_TRUE; - } -} -#endif - -#endif /* HAVE_LINUX_CAPABILITY_H */ - - -static void -setup_syslog(const char *progname) { - int options; - - options = LOG_PID; -#ifdef LOG_NDELAY - options |= LOG_NDELAY; -#endif - openlog(isc_file_basename(progname), options, ISC_FACILITY); -} - -void -ns_os_init(const char *progname) { - setup_syslog(progname); -#ifdef HAVE_LINUX_CAPABILITY_H - linux_initialprivs(); -#endif -#ifdef HAVE_LINUXTHREADS - mainpid = getpid(); -#endif -#ifdef SIGXFSZ - signal(SIGXFSZ, SIG_IGN); -#endif -} - -void -ns_os_daemonize(void) { - pid_t pid; - char strbuf[ISC_STRERRORSIZE]; - - if (pipe(dfd) == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("pipe(): %s", strbuf); - } - - pid = fork(); - if (pid == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("fork(): %s", strbuf); - } - if (pid != 0) { - int n; - /* - * Wait for the child to finish loading for the first time. - * This would be so much simpler if fork() worked once we - * were multi-threaded. - */ - (void)close(dfd[1]); - do { - char buf; - n = read(dfd[0], &buf, 1); - if (n == 1) - _exit(0); - } while (n == -1 && errno == EINTR); - _exit(1); - } - (void)close(dfd[0]); - - /* - * We're the child. - */ - -#ifdef HAVE_LINUXTHREADS - mainpid = getpid(); -#endif - - if (setsid() == -1) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("setsid(): %s", strbuf); - } - - /* - * Try to set stdin, stdout, and stderr to /dev/null, but press - * on even if it fails. - * - * XXXMLG The close() calls here are unneeded on all but NetBSD, but - * are harmless to include everywhere. dup2() is supposed to close - * the FD if it is in use, but unproven-pthreads-0.16 is broken - * and will end up closing the wrong FD. This will be fixed eventually, - * and these calls will be removed. - */ - if (devnullfd != -1) { - if (devnullfd != STDIN_FILENO) { - (void)close(STDIN_FILENO); - (void)dup2(devnullfd, STDIN_FILENO); - } - if (devnullfd != STDOUT_FILENO) { - (void)close(STDOUT_FILENO); - (void)dup2(devnullfd, STDOUT_FILENO); - } - if (devnullfd != STDERR_FILENO) { - (void)close(STDERR_FILENO); - (void)dup2(devnullfd, STDERR_FILENO); - } - } -} - -void -ns_os_started(void) { - char buf = 0; - - /* - * Signal to the parent that we stated successfully. - */ - if (dfd[0] != -1 && dfd[1] != -1) { - write(dfd[1], &buf, 1); - close(dfd[1]); - dfd[0] = dfd[1] = -1; - } -} - -void -ns_os_opendevnull(void) { - devnullfd = open("/dev/null", O_RDWR, 0); -} - -void -ns_os_closedevnull(void) { - if (devnullfd != STDIN_FILENO && - devnullfd != STDOUT_FILENO && - devnullfd != STDERR_FILENO) { - close(devnullfd); - devnullfd = -1; - } -} - -static isc_boolean_t -all_digits(const char *s) { - if (*s == '\0') - return (ISC_FALSE); - while (*s != '\0') { - if (!isdigit((*s)&0xff)) - return (ISC_FALSE); - s++; - } - return (ISC_TRUE); -} - -void -ns_os_chroot(const char *root) { - char strbuf[ISC_STRERRORSIZE]; -#ifdef HAVE_LIBSCF - ns_smf_chroot = 0; -#endif - if (root != NULL) { - if (chroot(root) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("chroot(): %s", strbuf); - } - if (chdir("/") < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("chdir(/): %s", strbuf); - } -#ifdef HAVE_LIBSCF - /* Set ns_smf_chroot flag on successful chroot. */ - ns_smf_chroot = 1; -#endif - } -} - -void -ns_os_inituserinfo(const char *username) { - char strbuf[ISC_STRERRORSIZE]; - if (username == NULL) - return; - - if (all_digits(username)) - runas_pw = getpwuid((uid_t)atoi(username)); - else - runas_pw = getpwnam(username); - endpwent(); - - if (runas_pw == NULL) - ns_main_earlyfatal("user '%s' unknown", username); - - if (getuid() == 0) { - if (initgroups(runas_pw->pw_name, runas_pw->pw_gid) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("initgroups(): %s", strbuf); - } - } - -} - -void -ns_os_changeuser(void) { - char strbuf[ISC_STRERRORSIZE]; - if (runas_pw == NULL || done_setuid) - return; - - done_setuid = ISC_TRUE; - -#ifdef HAVE_LINUXTHREADS -#ifdef HAVE_LINUX_CAPABILITY_H - if (!non_root_caps) - ns_main_earlyfatal("-u with Linux threads not supported: " - "requires kernel support for " - "prctl(PR_SET_KEEPCAPS)"); -#else - ns_main_earlyfatal("-u with Linux threads not supported: " - "no capabilities support or capabilities " - "disabled at build time"); -#endif -#endif - - if (setgid(runas_pw->pw_gid) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("setgid(): %s", strbuf); - } - - if (setuid(runas_pw->pw_uid) < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - ns_main_earlyfatal("setuid(): %s", strbuf); - } - -#if defined(HAVE_LINUX_CAPABILITY_H) && !defined(HAVE_LINUXTHREADS) - linux_minprivs(); -#endif -} - -void -ns_os_minprivs(void) { -#ifdef HAVE_SYS_PRCTL_H - linux_keepcaps(); -#endif - -#ifdef HAVE_LINUXTHREADS - ns_os_changeuser(); /* Call setuid() before threads are started */ -#endif - -#if defined(HAVE_LINUX_CAPABILITY_H) && defined(HAVE_LINUXTHREADS) - linux_minprivs(); -#endif -} - -static int -safe_open(const char *filename, isc_boolean_t append) { - int fd; - struct stat sb; - - if (stat(filename, &sb) == -1) { - if (errno != ENOENT) - return (-1); - } else if ((sb.st_mode & S_IFREG) == 0) { - errno = EOPNOTSUPP; - return (-1); - } - - if (append) - fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, - S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); - else { - (void)unlink(filename); - fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, - S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); - } - return (fd); -} - -static void -cleanup_pidfile(void) { - if (pidfile != NULL) { - (void)unlink(pidfile); - free(pidfile); - } - pidfile = NULL; -} - -void -ns_os_writepidfile(const char *filename, isc_boolean_t first_time) { - int fd; - FILE *lockfile; - size_t len; - pid_t pid; - char strbuf[ISC_STRERRORSIZE]; - void (*report)(const char *, ...); - - /* - * The caller must ensure any required synchronization. - */ - - report = first_time ? ns_main_earlyfatal : ns_main_earlywarning; - - cleanup_pidfile(); - - if (filename == NULL) - return; - - len = strlen(filename); - pidfile = malloc(len + 1); - if (pidfile == NULL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - (*report)("couldn't malloc '%s': %s", filename, strbuf); - return; - } - /* This is safe. */ - strcpy(pidfile, filename); - - fd = safe_open(filename, ISC_FALSE); - if (fd < 0) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - (*report)("couldn't open pid file '%s': %s", filename, strbuf); - free(pidfile); - pidfile = NULL; - return; - } - lockfile = fdopen(fd, "w"); - if (lockfile == NULL) { - isc__strerror(errno, strbuf, sizeof(strbuf)); - (*report)("could not fdopen() pid file '%s': %s", - filename, strbuf); - (void)close(fd); - cleanup_pidfile(); - return; - } -#ifdef HAVE_LINUXTHREADS - pid = mainpid; -#else - pid = getpid(); -#endif - if (fprintf(lockfile, "%ld\n", (long)pid) < 0) { - (*report)("fprintf() to pid file '%s' failed", filename); - (void)fclose(lockfile); - cleanup_pidfile(); - return; - } - if (fflush(lockfile) == EOF) { - (*report)("fflush() to pid file '%s' failed", filename); - (void)fclose(lockfile); - cleanup_pidfile(); - return; - } - (void)fclose(lockfile); -} - -void -ns_os_shutdown(void) { - closelog(); - cleanup_pidfile(); -} - -isc_result_t -ns_os_gethostname(char *buf, size_t len) { - int n; - - n = gethostname(buf, len); - return ((n == 0) ? ISC_R_SUCCESS : ISC_R_FAILURE); -} - -static char * -next_token(char **stringp, const char *delim) { - char *res; - - do { - res = strsep(stringp, delim); - if (res == NULL) - break; - } while (*res == '\0'); - return (res); -} - -void -ns_os_shutdownmsg(char *command, isc_buffer_t *text) { - char *input, *ptr; - unsigned int n; - pid_t pid; - - input = command; - - /* Skip the command name. */ - ptr = next_token(&input, " \t"); - if (ptr == NULL) - return; - - ptr = next_token(&input, " \t"); - if (ptr == NULL) - return; - - if (strcmp(ptr, "-p") != 0) - return; - -#ifdef HAVE_LINUXTHREADS - pid = mainpid; -#else - pid = getpid(); -#endif - - n = snprintf((char *)isc_buffer_used(text), - isc_buffer_availablelength(text), - "pid: %ld", (long)pid); - /* Only send a message if it is complete. */ - if (n < isc_buffer_availablelength(text)) - isc_buffer_add(text, n); -} - -void -ns_os_tzset(void) { -#ifdef HAVE_TZSET - tzset(); -#endif -} diff --git a/contrib/bind9/bin/named/update.c b/contrib/bind9/bin/named/update.c deleted file mode 100644 index 6c2d7597f797..000000000000 --- a/contrib/bind9/bin/named/update.c +++ /dev/null @@ -1,2826 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: update.c,v 1.88.2.5.2.27 2005/10/08 00:21:06 marka Exp $ */ - -#include <config.h> - -#include <isc/print.h> -#include <isc/string.h> -#include <isc/taskpool.h> -#include <isc/util.h> - -#include <dns/db.h> -#include <dns/dbiterator.h> -#include <dns/diff.h> -#include <dns/dnssec.h> -#include <dns/events.h> -#include <dns/fixedname.h> -#include <dns/journal.h> -#include <dns/message.h> -#include <dns/nsec.h> -#include <dns/rdataclass.h> -#include <dns/rdataset.h> -#include <dns/rdatasetiter.h> -#include <dns/rdatatype.h> -#include <dns/soa.h> -#include <dns/ssu.h> -#include <dns/view.h> -#include <dns/zone.h> -#include <dns/zt.h> - -#include <named/client.h> -#include <named/log.h> -#include <named/update.h> - -/* - * This module implements dynamic update as in RFC2136. - */ - -/* - XXX TODO: - - document strict minimality -*/ - -/**************************************************************************/ - -/* - * Log level for tracing dynamic update protocol requests. - */ -#define LOGLEVEL_PROTOCOL ISC_LOG_INFO - -/* - * Log level for low-level debug tracing. - */ -#define LOGLEVEL_DEBUG ISC_LOG_DEBUG(8) - -/* - * Check an operation for failure. These macros all assume that - * the function using them has a 'result' variable and a 'failure' - * label. - */ -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -/* - * Fail unconditionally with result 'code', which must not - * be ISC_R_SUCCESS. The reason for failure presumably has - * been logged already. - * - * The test against ISC_R_SUCCESS is there to keep the Solaris compiler - * from complaining about "end-of-loop code not reached". - */ - -#define FAIL(code) \ - do { \ - result = (code); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -/* - * Fail unconditionally and log as a client error. - * The test against ISC_R_SUCCESS is there to keep the Solaris compiler - * from complaining about "end-of-loop code not reached". - */ -#define FAILC(code, msg) \ - do { \ - const char *_what = "failed"; \ - result = (code); \ - switch (result) { \ - case DNS_R_NXDOMAIN: \ - case DNS_R_YXDOMAIN: \ - case DNS_R_YXRRSET: \ - case DNS_R_NXRRSET: \ - _what = "unsuccessful"; \ - } \ - update_log(client, zone, LOGLEVEL_PROTOCOL, \ - "update %s: %s (%s)", _what, \ - msg, isc_result_totext(result)); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -#define FAILN(code, name, msg) \ - do { \ - const char *_what = "failed"; \ - result = (code); \ - switch (result) { \ - case DNS_R_NXDOMAIN: \ - case DNS_R_YXDOMAIN: \ - case DNS_R_YXRRSET: \ - case DNS_R_NXRRSET: \ - _what = "unsuccessful"; \ - } \ - if (isc_log_wouldlog(ns_g_lctx, LOGLEVEL_PROTOCOL)) { \ - char _nbuf[DNS_NAME_FORMATSIZE]; \ - dns_name_format(name, _nbuf, sizeof(_nbuf)); \ - update_log(client, zone, LOGLEVEL_PROTOCOL, \ - "update %s: %s: %s (%s)", _what, _nbuf, \ - msg, isc_result_totext(result)); \ - } \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -#define FAILNT(code, name, type, msg) \ - do { \ - const char *_what = "failed"; \ - result = (code); \ - switch (result) { \ - case DNS_R_NXDOMAIN: \ - case DNS_R_YXDOMAIN: \ - case DNS_R_YXRRSET: \ - case DNS_R_NXRRSET: \ - _what = "unsuccessful"; \ - } \ - if (isc_log_wouldlog(ns_g_lctx, LOGLEVEL_PROTOCOL)) { \ - char _nbuf[DNS_NAME_FORMATSIZE]; \ - char _tbuf[DNS_RDATATYPE_FORMATSIZE]; \ - dns_name_format(name, _nbuf, sizeof(_nbuf)); \ - dns_rdatatype_format(type, _tbuf, sizeof(_tbuf)); \ - update_log(client, zone, LOGLEVEL_PROTOCOL, \ - "update %s: %s/%s: %s (%s)", \ - _what, _nbuf, _tbuf, msg, \ - isc_result_totext(result)); \ - } \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) -/* - * Fail unconditionally and log as a server error. - * The test against ISC_R_SUCCESS is there to keep the Solaris compiler - * from complaining about "end-of-loop code not reached". - */ -#define FAILS(code, msg) \ - do { \ - result = (code); \ - update_log(client, zone, LOGLEVEL_PROTOCOL, \ - "error: %s: %s", \ - msg, isc_result_totext(result)); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -/**************************************************************************/ - -typedef struct rr rr_t; - -struct rr { - /* dns_name_t name; */ - isc_uint32_t ttl; - dns_rdata_t rdata; -}; - -typedef struct update_event update_event_t; - -struct update_event { - ISC_EVENT_COMMON(update_event_t); - dns_zone_t *zone; - isc_result_t result; - dns_message_t *answer; -}; - -/**************************************************************************/ -/* - * Forward declarations. - */ - -static void update_action(isc_task_t *task, isc_event_t *event); -static void updatedone_action(isc_task_t *task, isc_event_t *event); -static isc_result_t send_forward_event(ns_client_t *client, dns_zone_t *zone); -static void forward_done(isc_task_t *task, isc_event_t *event); - -/**************************************************************************/ - -static void -update_log(ns_client_t *client, dns_zone_t *zone, - int level, const char *fmt, ...) ISC_FORMAT_PRINTF(4, 5); - -static void -update_log(ns_client_t *client, dns_zone_t *zone, - int level, const char *fmt, ...) -{ - va_list ap; - char message[4096]; - char namebuf[DNS_NAME_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - - if (client == NULL || zone == NULL) - return; - - if (isc_log_wouldlog(ns_g_lctx, level) == ISC_FALSE) - return; - - dns_name_format(dns_zone_getorigin(zone), namebuf, - sizeof(namebuf)); - dns_rdataclass_format(dns_zone_getclass(zone), classbuf, - sizeof(classbuf)); - - va_start(ap, fmt); - vsnprintf(message, sizeof(message), fmt, ap); - va_end(ap); - - ns_client_log(client, NS_LOGCATEGORY_UPDATE, NS_LOGMODULE_UPDATE, - level, "updating zone '%s/%s': %s", - namebuf, classbuf, message); -} - -static isc_result_t -checkupdateacl(ns_client_t *client, dns_acl_t *acl, const char *message, - dns_name_t *zonename, isc_boolean_t slave) -{ - char namebuf[DNS_NAME_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - int level = ISC_LOG_ERROR; - const char *msg = "denied"; - isc_result_t result; - - if (slave && acl == NULL) { - result = DNS_R_NOTIMP; - level = ISC_LOG_DEBUG(3); - msg = "disabled"; - } else - result = ns_client_checkaclsilent(client, acl, ISC_FALSE); - - if (result == ISC_R_SUCCESS) { - level = ISC_LOG_DEBUG(3); - msg = "approved"; - } - - dns_name_format(zonename, namebuf, sizeof(namebuf)); - dns_rdataclass_format(client->view->rdclass, classbuf, - sizeof(classbuf)); - - ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY, - NS_LOGMODULE_UPDATE, level, "%s '%s/%s' %s", - message, namebuf, classbuf, msg); - return (result); -} - -/* - * Update a single RR in version 'ver' of 'db' and log the - * update in 'diff'. - * - * Ensures: - * '*tuple' == NULL. Either the tuple is freed, or its - * ownership has been transferred to the diff. - */ -static isc_result_t -do_one_tuple(dns_difftuple_t **tuple, - dns_db_t *db, dns_dbversion_t *ver, - dns_diff_t *diff) -{ - dns_diff_t temp_diff; - isc_result_t result; - - /* - * Create a singleton diff. - */ - dns_diff_init(diff->mctx, &temp_diff); - ISC_LIST_APPEND(temp_diff.tuples, *tuple, link); - - /* - * Apply it to the database. - */ - result = dns_diff_apply(&temp_diff, db, ver); - ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link); - if (result != ISC_R_SUCCESS) { - dns_difftuple_free(tuple); - return (result); - } - - /* - * Merge it into the current pending journal entry. - */ - dns_diff_appendminimal(diff, tuple); - - /* - * Do not clear temp_diff. - */ - return (ISC_R_SUCCESS); -} - -/* - * Perform the updates in 'updates' in version 'ver' of 'db' and log the - * update in 'diff'. - * - * Ensures: - * 'updates' is empty. - */ -static isc_result_t -do_diff(dns_diff_t *updates, dns_db_t *db, dns_dbversion_t *ver, - dns_diff_t *diff) -{ - isc_result_t result; - while (! ISC_LIST_EMPTY(updates->tuples)) { - dns_difftuple_t *t = ISC_LIST_HEAD(updates->tuples); - ISC_LIST_UNLINK(updates->tuples, t, link); - CHECK(do_one_tuple(&t, db, ver, diff)); - } - return (ISC_R_SUCCESS); - - failure: - dns_diff_clear(diff); - return (result); -} - -static isc_result_t -update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, - dns_diffop_t op, dns_name_t *name, - dns_ttl_t ttl, dns_rdata_t *rdata) -{ - dns_difftuple_t *tuple = NULL; - isc_result_t result; - result = dns_difftuple_create(diff->mctx, op, - name, ttl, rdata, &tuple); - if (result != ISC_R_SUCCESS) - return (result); - return (do_one_tuple(&tuple, db, ver, diff)); -} - -/**************************************************************************/ -/* - * Callback-style iteration over rdatasets and rdatas. - * - * foreach_rrset() can be used to iterate over the RRsets - * of a name and call a callback function with each - * one. Similarly, foreach_rr() can be used to iterate - * over the individual RRs at name, optionally restricted - * to RRs of a given type. - * - * The callback functions are called "actions" and take - * two arguments: a void pointer for passing arbitrary - * context information, and a pointer to the current RRset - * or RR. By convention, their names end in "_action". - */ - -/* - * XXXRTH We might want to make this public somewhere in libdns. - */ - -/* - * Function type for foreach_rrset() iterator actions. - */ -typedef isc_result_t rrset_func(void *data, dns_rdataset_t *rrset); - -/* - * Function type for foreach_rr() iterator actions. - */ -typedef isc_result_t rr_func(void *data, rr_t *rr); - -/* - * Internal context struct for foreach_node_rr(). - */ -typedef struct { - rr_func * rr_action; - void * rr_action_data; -} foreach_node_rr_ctx_t; - -/* - * Internal helper function for foreach_node_rr(). - */ -static isc_result_t -foreach_node_rr_action(void *data, dns_rdataset_t *rdataset) { - isc_result_t result; - foreach_node_rr_ctx_t *ctx = data; - for (result = dns_rdataset_first(rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(rdataset)) - { - rr_t rr = { 0, DNS_RDATA_INIT }; - - dns_rdataset_current(rdataset, &rr.rdata); - rr.ttl = rdataset->ttl; - result = (*ctx->rr_action)(ctx->rr_action_data, &rr); - if (result != ISC_R_SUCCESS) - return (result); - } - if (result != ISC_R_NOMORE) - return (result); - return (ISC_R_SUCCESS); -} - -/* - * For each rdataset of 'name' in 'ver' of 'db', call 'action' - * with the rdataset and 'action_data' as arguments. If the name - * does not exist, do nothing. - * - * If 'action' returns an error, abort iteration and return the error. - */ -static isc_result_t -foreach_rrset(dns_db_t *db, - dns_dbversion_t *ver, - dns_name_t *name, - rrset_func *action, - void *action_data) -{ - isc_result_t result; - dns_dbnode_t *node; - dns_rdatasetiter_t *iter; - - node = NULL; - result = dns_db_findnode(db, name, ISC_FALSE, &node); - if (result == ISC_R_NOTFOUND) - return (ISC_R_SUCCESS); - if (result != ISC_R_SUCCESS) - return (result); - - iter = NULL; - result = dns_db_allrdatasets(db, node, ver, - (isc_stdtime_t) 0, &iter); - if (result != ISC_R_SUCCESS) - goto cleanup_node; - - for (result = dns_rdatasetiter_first(iter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(iter)) - { - dns_rdataset_t rdataset; - - dns_rdataset_init(&rdataset); - dns_rdatasetiter_current(iter, &rdataset); - - result = (*action)(action_data, &rdataset); - - dns_rdataset_disassociate(&rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup_iterator; - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - - cleanup_iterator: - dns_rdatasetiter_destroy(&iter); - - cleanup_node: - dns_db_detachnode(db, &node); - - return (result); -} - -/* - * For each RR of 'name' in 'ver' of 'db', call 'action' - * with the RR and 'action_data' as arguments. If the name - * does not exist, do nothing. - * - * If 'action' returns an error, abort iteration - * and return the error. - */ -static isc_result_t -foreach_node_rr(dns_db_t *db, - dns_dbversion_t *ver, - dns_name_t *name, - rr_func *rr_action, - void *rr_action_data) -{ - foreach_node_rr_ctx_t ctx; - ctx.rr_action = rr_action; - ctx.rr_action_data = rr_action_data; - return (foreach_rrset(db, ver, name, - foreach_node_rr_action, &ctx)); -} - - -/* - * For each of the RRs specified by 'db', 'ver', 'name', 'type', - * (which can be dns_rdatatype_any to match any type), and 'covers', call - * 'action' with the RR and 'action_data' as arguments. If the name - * does not exist, or if no RRset of the given type exists at the name, - * do nothing. - * - * If 'action' returns an error, abort iteration and return the error. - */ -static isc_result_t -foreach_rr(dns_db_t *db, - dns_dbversion_t *ver, - dns_name_t *name, - dns_rdatatype_t type, - dns_rdatatype_t covers, - rr_func *rr_action, - void *rr_action_data) -{ - - isc_result_t result; - dns_dbnode_t *node; - dns_rdataset_t rdataset; - - if (type == dns_rdatatype_any) - return (foreach_node_rr(db, ver, name, - rr_action, rr_action_data)); - - node = NULL; - result = dns_db_findnode(db, name, ISC_FALSE, &node); - if (result == ISC_R_NOTFOUND) - return (ISC_R_SUCCESS); - if (result != ISC_R_SUCCESS) - return (result); - - dns_rdataset_init(&rdataset); - result = dns_db_findrdataset(db, node, ver, type, covers, - (isc_stdtime_t) 0, &rdataset, NULL); - if (result == ISC_R_NOTFOUND) { - result = ISC_R_SUCCESS; - goto cleanup_node; - } - if (result != ISC_R_SUCCESS) - goto cleanup_node; - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) - { - rr_t rr = { 0, DNS_RDATA_INIT }; - dns_rdataset_current(&rdataset, &rr.rdata); - rr.ttl = rdataset.ttl; - result = (*rr_action)(rr_action_data, &rr); - if (result != ISC_R_SUCCESS) - goto cleanup_rdataset; - } - if (result != ISC_R_NOMORE) - goto cleanup_rdataset; - result = ISC_R_SUCCESS; - - cleanup_rdataset: - dns_rdataset_disassociate(&rdataset); - cleanup_node: - dns_db_detachnode(db, &node); - - return (result); -} - -/**************************************************************************/ -/* - * Various tests on the database contents (for prerequisites, etc). - */ - -/* - * Function type for predicate functions that compare a database RR 'db_rr' - * against an update RR 'update_rr'. - */ -typedef isc_boolean_t rr_predicate(dns_rdata_t *update_rr, dns_rdata_t *db_rr); - -/* - * Helper function for rrset_exists(). - */ -static isc_result_t -rrset_exists_action(void *data, rr_t *rr) { - UNUSED(data); - UNUSED(rr); - return (ISC_R_EXISTS); -} - -/* - * Utility macro for RR existence checking functions. - * - * If the variable 'result' has the value ISC_R_EXISTS or - * ISC_R_SUCCESS, set *exists to ISC_TRUE or ISC_FALSE, - * respectively, and return success. - * - * If 'result' has any other value, there was a failure. - * Return the failure result code and do not set *exists. - * - * This would be more readable as "do { if ... } while(0)", - * but that form generates tons of warnings on Solaris 2.6. - */ -#define RETURN_EXISTENCE_FLAG \ - return ((result == ISC_R_EXISTS) ? \ - (*exists = ISC_TRUE, ISC_R_SUCCESS) : \ - ((result == ISC_R_SUCCESS) ? \ - (*exists = ISC_FALSE, ISC_R_SUCCESS) : \ - result)) - -/* - * Set '*exists' to true iff an rrset of the given type exists, - * to false otherwise. - */ -static isc_result_t -rrset_exists(dns_db_t *db, dns_dbversion_t *ver, - dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers, - isc_boolean_t *exists) -{ - isc_result_t result; - result = foreach_rr(db, ver, name, type, covers, - rrset_exists_action, NULL); - RETURN_EXISTENCE_FLAG; -} - -/* - * Helper function for cname_incompatible_rrset_exists. - */ -static isc_result_t -cname_compatibility_action(void *data, dns_rdataset_t *rrset) { - UNUSED(data); - if (rrset->type != dns_rdatatype_cname && - ! dns_rdatatype_isdnssec(rrset->type)) - return (ISC_R_EXISTS); - return (ISC_R_SUCCESS); -} - -/* - * Check whether there is an rrset incompatible with adding a CNAME RR, - * i.e., anything but another CNAME (which can be replaced) or a - * DNSSEC RR (which can coexist). - * - * If such an incompatible rrset exists, set '*exists' to ISC_TRUE. - * Otherwise, set it to ISC_FALSE. - */ -static isc_result_t -cname_incompatible_rrset_exists(dns_db_t *db, dns_dbversion_t *ver, - dns_name_t *name, isc_boolean_t *exists) { - isc_result_t result; - result = foreach_rrset(db, ver, name, - cname_compatibility_action, NULL); - RETURN_EXISTENCE_FLAG; -} - -/* - * Helper function for rr_count(). - */ -static isc_result_t -count_rr_action(void *data, rr_t *rr) { - int *countp = data; - UNUSED(rr); - (*countp)++; - return (ISC_R_SUCCESS); -} - -/* - * Count the number of RRs of 'type' belonging to 'name' in 'ver' of 'db'. - */ -static isc_result_t -rr_count(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - dns_rdatatype_t type, dns_rdatatype_t covers, int *countp) -{ - *countp = 0; - return (foreach_rr(db, ver, name, type, covers, - count_rr_action, countp)); -} - -/* - * Context struct and helper function for name_exists(). - */ - -static isc_result_t -name_exists_action(void *data, dns_rdataset_t *rrset) { - UNUSED(data); - UNUSED(rrset); - return (ISC_R_EXISTS); -} - -/* - * Set '*exists' to true iff the given name exists, to false otherwise. - */ -static isc_result_t -name_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - isc_boolean_t *exists) -{ - isc_result_t result; - result = foreach_rrset(db, ver, name, - name_exists_action, NULL); - RETURN_EXISTENCE_FLAG; -} - -typedef struct { - dns_name_t *name, *signer; - dns_ssutable_t *table; -} ssu_check_t; - -static isc_result_t -ssu_checkrule(void *data, dns_rdataset_t *rrset) { - ssu_check_t *ssuinfo = data; - isc_boolean_t result; - - /* - * If we're deleting all records, it's ok to delete RRSIG and NSEC even - * if we're normally not allowed to. - */ - if (rrset->type == dns_rdatatype_rrsig || - rrset->type == dns_rdatatype_nsec) - return (ISC_R_SUCCESS); - result = dns_ssutable_checkrules(ssuinfo->table, ssuinfo->signer, - ssuinfo->name, rrset->type); - return (result == ISC_TRUE ? ISC_R_SUCCESS : ISC_R_FAILURE); -} - -static isc_boolean_t -ssu_checkall(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - dns_ssutable_t *ssutable, dns_name_t *signer) -{ - isc_result_t result; - ssu_check_t ssuinfo; - - ssuinfo.name = name; - ssuinfo.table = ssutable; - ssuinfo.signer = signer; - result = foreach_rrset(db, ver, name, ssu_checkrule, &ssuinfo); - return (ISC_TF(result == ISC_R_SUCCESS)); -} - -/**************************************************************************/ -/* - * Checking of "RRset exists (value dependent)" prerequisites. - * - * In the RFC2136 section 3.2.5, this is the pseudocode involving - * a variable called "temp", a mapping of <name, type> tuples to rrsets. - * - * Here, we represent the "temp" data structure as (non-minimial) "dns_diff_t" - * where each typle has op==DNS_DIFFOP_EXISTS. - */ - - -/* - * Append a tuple asserting the existence of the RR with - * 'name' and 'rdata' to 'diff'. - */ -static isc_result_t -temp_append(dns_diff_t *diff, dns_name_t *name, dns_rdata_t *rdata) { - isc_result_t result; - dns_difftuple_t *tuple = NULL; - - REQUIRE(DNS_DIFF_VALID(diff)); - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_EXISTS, - name, 0, rdata, &tuple)); - ISC_LIST_APPEND(diff->tuples, tuple, link); - failure: - return (result); -} - -/* - * Compare two rdatasets represented as sorted lists of tuples. - * All list elements must have the same owner name and type. - * Return ISC_R_SUCCESS if the rdatasets are equal, rcode(dns_rcode_nxrrset) - * if not. - */ -static isc_result_t -temp_check_rrset(dns_difftuple_t *a, dns_difftuple_t *b) { - for (;;) { - if (a == NULL || b == NULL) - break; - INSIST(a->op == DNS_DIFFOP_EXISTS && - b->op == DNS_DIFFOP_EXISTS); - INSIST(a->rdata.type == b->rdata.type); - INSIST(dns_name_equal(&a->name, &b->name)); - if (dns_rdata_compare(&a->rdata, &b->rdata) != 0) - return (DNS_R_NXRRSET); - a = ISC_LIST_NEXT(a, link); - b = ISC_LIST_NEXT(b, link); - } - if (a != NULL || b != NULL) - return (DNS_R_NXRRSET); - return (ISC_R_SUCCESS); -} - -/* - * A comparison function defining the sorting order for the entries - * in the "temp" data structure. The major sort key is the owner name, - * followed by the type and rdata. - */ -static int -temp_order(const void *av, const void *bv) { - dns_difftuple_t const * const *ap = av; - dns_difftuple_t const * const *bp = bv; - dns_difftuple_t const *a = *ap; - dns_difftuple_t const *b = *bp; - int r; - r = dns_name_compare(&a->name, &b->name); - if (r != 0) - return (r); - r = (b->rdata.type - a->rdata.type); - if (r != 0) - return (r); - r = dns_rdata_compare(&a->rdata, &b->rdata); - return (r); -} - -/* - * Check the "RRset exists (value dependent)" prerequisite information - * in 'temp' against the contents of the database 'db'. - * - * Return ISC_R_SUCCESS if the prerequisites are satisfied, - * rcode(dns_rcode_nxrrset) if not. - * - * 'temp' must be pre-sorted. - */ - -static isc_result_t -temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db, - dns_dbversion_t *ver, dns_name_t *tmpname, dns_rdatatype_t *typep) -{ - isc_result_t result; - dns_name_t *name; - dns_dbnode_t *node; - dns_difftuple_t *t; - dns_diff_t trash; - - dns_diff_init(mctx, &trash); - - /* - * For each name and type in the prerequisites, - * construct a sorted rdata list of the corresponding - * database contents, and compare the lists. - */ - t = ISC_LIST_HEAD(temp->tuples); - while (t != NULL) { - name = &t->name; - (void)dns_name_copy(name, tmpname, NULL); - *typep = t->rdata.type; - - /* A new unique name begins here. */ - node = NULL; - result = dns_db_findnode(db, name, ISC_FALSE, &node); - if (result == ISC_R_NOTFOUND) - return (DNS_R_NXRRSET); - if (result != ISC_R_SUCCESS) - return (result); - - /* A new unique type begins here. */ - while (t != NULL && dns_name_equal(&t->name, name)) { - dns_rdatatype_t type, covers; - dns_rdataset_t rdataset; - dns_diff_t d_rrs; /* Database RRs with - this name and type */ - dns_diff_t u_rrs; /* Update RRs with - this name and type */ - - *typep = type = t->rdata.type; - if (type == dns_rdatatype_rrsig || - type == dns_rdatatype_sig) - covers = dns_rdata_covers(&t->rdata); - else - covers = 0; - - /* - * Collect all database RRs for this name and type - * onto d_rrs and sort them. - */ - dns_rdataset_init(&rdataset); - result = dns_db_findrdataset(db, node, ver, type, - covers, (isc_stdtime_t) 0, - &rdataset, NULL); - if (result != ISC_R_SUCCESS) { - dns_db_detachnode(db, &node); - return (DNS_R_NXRRSET); - } - - dns_diff_init(mctx, &d_rrs); - dns_diff_init(mctx, &u_rrs); - - for (result = dns_rdataset_first(&rdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&rdataset)) - { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_current(&rdataset, &rdata); - result = temp_append(&d_rrs, name, &rdata); - if (result != ISC_R_SUCCESS) - goto failure; - } - if (result != ISC_R_NOMORE) - goto failure; - result = dns_diff_sort(&d_rrs, temp_order); - if (result != ISC_R_SUCCESS) - goto failure; - - /* - * Collect all update RRs for this name and type - * onto u_rrs. No need to sort them here - - * they are already sorted. - */ - while (t != NULL && - dns_name_equal(&t->name, name) && - t->rdata.type == type) - { - dns_difftuple_t *next = - ISC_LIST_NEXT(t, link); - ISC_LIST_UNLINK(temp->tuples, t, link); - ISC_LIST_APPEND(u_rrs.tuples, t, link); - t = next; - } - - /* Compare the two sorted lists. */ - result = temp_check_rrset(ISC_LIST_HEAD(u_rrs.tuples), - ISC_LIST_HEAD(d_rrs.tuples)); - if (result != ISC_R_SUCCESS) - goto failure; - - /* - * We are done with the tuples, but we can't free - * them yet because "name" still points into one - * of them. Move them on a temporary list. - */ - ISC_LIST_APPENDLIST(trash.tuples, u_rrs.tuples, link); - ISC_LIST_APPENDLIST(trash.tuples, d_rrs.tuples, link); - dns_rdataset_disassociate(&rdataset); - - continue; - - failure: - dns_diff_clear(&d_rrs); - dns_diff_clear(&u_rrs); - dns_diff_clear(&trash); - dns_rdataset_disassociate(&rdataset); - dns_db_detachnode(db, &node); - return (result); - } - - dns_db_detachnode(db, &node); - } - - dns_diff_clear(&trash); - return (ISC_R_SUCCESS); -} - -/**************************************************************************/ -/* - * Conditional deletion of RRs. - */ - -/* - * Context structure for delete_if(). - */ - -typedef struct { - rr_predicate *predicate; - dns_db_t *db; - dns_dbversion_t *ver; - dns_diff_t *diff; - dns_name_t *name; - dns_rdata_t *update_rr; -} conditional_delete_ctx_t; - -/* - * Predicate functions for delete_if(). - */ - -/* - * Return true iff 'db_rr' is neither a SOA nor an NS RR nor - * an RRSIG nor a NSEC. - */ -static isc_boolean_t -type_not_soa_nor_ns_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { - UNUSED(update_rr); - return ((db_rr->type != dns_rdatatype_soa && - db_rr->type != dns_rdatatype_ns && - db_rr->type != dns_rdatatype_rrsig && - db_rr->type != dns_rdatatype_nsec) ? - ISC_TRUE : ISC_FALSE); -} - -/* - * Return true iff 'db_rr' is neither a RRSIG nor a NSEC. - */ -static isc_boolean_t -type_not_dnssec(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { - UNUSED(update_rr); - return ((db_rr->type != dns_rdatatype_rrsig && - db_rr->type != dns_rdatatype_nsec) ? - ISC_TRUE : ISC_FALSE); -} - -/* - * Return true always. - */ -static isc_boolean_t -true_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { - UNUSED(update_rr); - UNUSED(db_rr); - return (ISC_TRUE); -} - -/* - * Return true iff the two RRs have identical rdata. - */ -static isc_boolean_t -rr_equal_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { - /* - * XXXRTH This is not a problem, but we should consider creating - * dns_rdata_equal() (that used dns_name_equal()), since it - * would be faster. Not a priority. - */ - return (dns_rdata_compare(update_rr, db_rr) == 0 ? - ISC_TRUE : ISC_FALSE); -} - -/* - * Return true iff 'update_rr' should replace 'db_rr' according - * to the special RFC2136 rules for CNAME, SOA, and WKS records. - * - * RFC2136 does not mention NSEC or DNAME, but multiple NSECs or DNAMEs - * make little sense, so we replace those, too. - */ -static isc_boolean_t -replaces_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { - if (db_rr->type != update_rr->type) - return (ISC_FALSE); - if (db_rr->type == dns_rdatatype_cname) - return (ISC_TRUE); - if (db_rr->type == dns_rdatatype_dname) - return (ISC_TRUE); - if (db_rr->type == dns_rdatatype_soa) - return (ISC_TRUE); - if (db_rr->type == dns_rdatatype_nsec) - return (ISC_TRUE); - if (db_rr->type == dns_rdatatype_wks) { - /* - * Compare the address and protocol fields only. These - * form the first five bytes of the RR data. Do a - * raw binary comparison; unpacking the WKS RRs using - * dns_rdata_tostruct() might be cleaner in some ways, - * but it would require us to pass around an mctx. - */ - INSIST(db_rr->length >= 5 && update_rr->length >= 5); - return (memcmp(db_rr->data, update_rr->data, 5) == 0 ? - ISC_TRUE : ISC_FALSE); - } - return (ISC_FALSE); -} - -/* - * Internal helper function for delete_if(). - */ -static isc_result_t -delete_if_action(void *data, rr_t *rr) { - conditional_delete_ctx_t *ctx = data; - if ((*ctx->predicate)(ctx->update_rr, &rr->rdata)) { - isc_result_t result; - result = update_one_rr(ctx->db, ctx->ver, ctx->diff, - DNS_DIFFOP_DEL, ctx->name, - rr->ttl, &rr->rdata); - return (result); - } else { - return (ISC_R_SUCCESS); - } -} - -/* - * Conditionally delete RRs. Apply 'predicate' to the RRs - * specified by 'db', 'ver', 'name', and 'type' (which can - * be dns_rdatatype_any to match any type). Delete those - * RRs for which the predicate returns true, and log the - * deletions in 'diff'. - */ -static isc_result_t -delete_if(rr_predicate *predicate, - dns_db_t *db, - dns_dbversion_t *ver, - dns_name_t *name, - dns_rdatatype_t type, - dns_rdatatype_t covers, - dns_rdata_t *update_rr, - dns_diff_t *diff) -{ - conditional_delete_ctx_t ctx; - ctx.predicate = predicate; - ctx.db = db; - ctx.ver = ver; - ctx.diff = diff; - ctx.name = name; - ctx.update_rr = update_rr; - return (foreach_rr(db, ver, name, type, covers, - delete_if_action, &ctx)); -} - -/**************************************************************************/ -/* - * Prepare an RR for the addition of the new RR 'ctx->update_rr', - * with TTL 'ctx->update_rr_ttl', to its rdataset, by deleting - * the RRs if it is replaced by the new RR or has a conflicting TTL. - * The necessary changes are appended to ctx->del_diff and ctx->add_diff; - * we need to do all deletions before any additions so that we don't run - * into transient states with conflicting TTLs. - */ - -typedef struct { - dns_db_t *db; - dns_dbversion_t *ver; - dns_diff_t *diff; - dns_name_t *name; - dns_rdata_t *update_rr; - dns_ttl_t update_rr_ttl; - isc_boolean_t ignore_add; - dns_diff_t del_diff; - dns_diff_t add_diff; -} add_rr_prepare_ctx_t; - -static isc_result_t -add_rr_prepare_action(void *data, rr_t *rr) { - isc_result_t result = ISC_R_SUCCESS; - add_rr_prepare_ctx_t *ctx = data; - dns_difftuple_t *tuple = NULL; - isc_boolean_t equal; - - /* - * If the update RR is a "duplicate" of the update RR, - * the update should be silently ignored. - */ - equal = ISC_TF(dns_rdata_compare(&rr->rdata, ctx->update_rr) == 0); - if (equal && rr->ttl == ctx->update_rr_ttl) { - ctx->ignore_add = ISC_TRUE; - return (ISC_R_SUCCESS); - } - - /* - * If this RR is "equal" to the update RR, it should - * be deleted before the update RR is added. - */ - if (replaces_p(ctx->update_rr, &rr->rdata)) { - CHECK(dns_difftuple_create(ctx->del_diff.mctx, - DNS_DIFFOP_DEL, ctx->name, - rr->ttl, - &rr->rdata, - &tuple)); - dns_diff_append(&ctx->del_diff, &tuple); - return (ISC_R_SUCCESS); - } - - /* - * If this RR differs in TTL from the update RR, - * its TTL must be adjusted. - */ - if (rr->ttl != ctx->update_rr_ttl) { - CHECK(dns_difftuple_create(ctx->del_diff.mctx, - DNS_DIFFOP_DEL, ctx->name, - rr->ttl, - &rr->rdata, - &tuple)); - dns_diff_append(&ctx->del_diff, &tuple); - if (!equal) { - CHECK(dns_difftuple_create(ctx->add_diff.mctx, - DNS_DIFFOP_ADD, ctx->name, - ctx->update_rr_ttl, - &rr->rdata, - &tuple)); - dns_diff_append(&ctx->add_diff, &tuple); - } - } - failure: - return (result); -} - -/**************************************************************************/ -/* - * Miscellaneous subroutines. - */ - -/* - * Extract a single update RR from 'section' of dynamic update message - * 'msg', with consistency checking. - * - * Stores the owner name, rdata, and TTL of the update RR at 'name', - * 'rdata', and 'ttl', respectively. - */ -static void -get_current_rr(dns_message_t *msg, dns_section_t section, - dns_rdataclass_t zoneclass, - dns_name_t **name, dns_rdata_t *rdata, dns_rdatatype_t *covers, - dns_ttl_t *ttl, - dns_rdataclass_t *update_class) -{ - dns_rdataset_t *rdataset; - isc_result_t result; - dns_message_currentname(msg, section, name); - rdataset = ISC_LIST_HEAD((*name)->list); - INSIST(rdataset != NULL); - INSIST(ISC_LIST_NEXT(rdataset, link) == NULL); - *covers = rdataset->covers; - *ttl = rdataset->ttl; - result = dns_rdataset_first(rdataset); - INSIST(result == ISC_R_SUCCESS); - dns_rdataset_current(rdataset, rdata); - INSIST(dns_rdataset_next(rdataset) == ISC_R_NOMORE); - *update_class = rdata->rdclass; - rdata->rdclass = zoneclass; -} - -/* - * Increment the SOA serial number of database 'db', version 'ver'. - * Replace the SOA record in the database, and log the - * change in 'diff'. - */ - - /* - * XXXRTH Failures in this routine will be worth logging, when - * we have a logging system. Failure to find the zonename - * or the SOA rdataset warrant at least an UNEXPECTED_ERROR(). - */ - -static isc_result_t -increment_soa_serial(dns_db_t *db, dns_dbversion_t *ver, - dns_diff_t *diff, isc_mem_t *mctx) -{ - dns_difftuple_t *deltuple = NULL; - dns_difftuple_t *addtuple = NULL; - isc_uint32_t serial; - isc_result_t result; - - CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple)); - CHECK(dns_difftuple_copy(deltuple, &addtuple)); - addtuple->op = DNS_DIFFOP_ADD; - - serial = dns_soa_getserial(&addtuple->rdata); - - /* RFC1982 */ - serial = (serial + 1) & 0xFFFFFFFF; - if (serial == 0) - serial = 1; - - dns_soa_setserial(serial, &addtuple->rdata); - CHECK(do_one_tuple(&deltuple, db, ver, diff)); - CHECK(do_one_tuple(&addtuple, db, ver, diff)); - result = ISC_R_SUCCESS; - - failure: - if (addtuple != NULL) - dns_difftuple_free(&addtuple); - if (deltuple != NULL) - dns_difftuple_free(&deltuple); - return (result); -} - -/* - * Check that the new SOA record at 'update_rdata' does not - * illegally cause the SOA serial number to decrease or stay - * unchanged relative to the existing SOA in 'db'. - * - * Sets '*ok' to ISC_TRUE if the update is legal, ISC_FALSE if not. - * - * William King points out that RFC2136 is inconsistent about - * the case where the serial number stays unchanged: - * - * section 3.4.2.2 requires a server to ignore a SOA update request - * if the serial number on the update SOA is less_than_or_equal to - * the zone SOA serial. - * - * section 3.6 requires a server to ignore a SOA update request if - * the serial is less_than the zone SOA serial. - * - * Paul says 3.4.2.2 is correct. - * - */ -static isc_result_t -check_soa_increment(dns_db_t *db, dns_dbversion_t *ver, - dns_rdata_t *update_rdata, - isc_boolean_t *ok) -{ - isc_uint32_t db_serial; - isc_uint32_t update_serial; - isc_result_t result; - - update_serial = dns_soa_getserial(update_rdata); - - result = dns_db_getsoaserial(db, ver, &db_serial); - if (result != ISC_R_SUCCESS) - return (result); - - if (DNS_SERIAL_GE(db_serial, update_serial)) { - *ok = ISC_FALSE; - } else { - *ok = ISC_TRUE; - } - - return (ISC_R_SUCCESS); - -} - -/**************************************************************************/ -/* - * Incremental updating of NSECs and RRSIGs. - */ - -#define MAXZONEKEYS 32 /* Maximum number of zone keys supported. */ - -/* - * We abuse the dns_diff_t type to represent a set of domain names - * affected by the update. - */ -static isc_result_t -namelist_append_name(dns_diff_t *list, dns_name_t *name) { - isc_result_t result; - dns_difftuple_t *tuple = NULL; - static dns_rdata_t dummy_rdata = { NULL, 0, 0, 0, 0, - { (void*)(-1), (void*)(-1) } }; - CHECK(dns_difftuple_create(list->mctx, DNS_DIFFOP_EXISTS, name, 0, - &dummy_rdata, &tuple)); - dns_diff_append(list, &tuple); - failure: - return (result); -} - -static isc_result_t -namelist_append_subdomain(dns_db_t *db, dns_name_t *name, dns_diff_t *affected) -{ - isc_result_t result; - dns_fixedname_t fixedname; - dns_name_t *child; - dns_dbiterator_t *dbit = NULL; - - dns_fixedname_init(&fixedname); - child = dns_fixedname_name(&fixedname); - - CHECK(dns_db_createiterator(db, ISC_FALSE, &dbit)); - - for (result = dns_dbiterator_seek(dbit, name); - result == ISC_R_SUCCESS; - result = dns_dbiterator_next(dbit)) - { - dns_dbnode_t *node = NULL; - CHECK(dns_dbiterator_current(dbit, &node, child)); - dns_db_detachnode(db, &node); - if (! dns_name_issubdomain(child, name)) - break; - CHECK(namelist_append_name(affected, child)); - } - if (result == ISC_R_NOMORE) - result = ISC_R_SUCCESS; - failure: - if (dbit != NULL) - dns_dbiterator_destroy(&dbit); - return (result); -} - - - -/* - * Helper function for non_nsec_rrset_exists(). - */ -static isc_result_t -is_non_nsec_action(void *data, dns_rdataset_t *rrset) { - UNUSED(data); - if (!(rrset->type == dns_rdatatype_nsec || - (rrset->type == dns_rdatatype_rrsig && - rrset->covers == dns_rdatatype_nsec))) - return (ISC_R_EXISTS); - return (ISC_R_SUCCESS); -} - -/* - * Check whether there is an rrset other than a NSEC or RRSIG NSEC, - * i.e., anything that justifies the continued existence of a name - * after a secure update. - * - * If such an rrset exists, set '*exists' to ISC_TRUE. - * Otherwise, set it to ISC_FALSE. - */ -static isc_result_t -non_nsec_rrset_exists(dns_db_t *db, dns_dbversion_t *ver, - dns_name_t *name, isc_boolean_t *exists) -{ - isc_result_t result; - result = foreach_rrset(db, ver, name, - is_non_nsec_action, NULL); - RETURN_EXISTENCE_FLAG; -} - -/* - * A comparison function for sorting dns_diff_t:s by name. - */ -static int -name_order(const void *av, const void *bv) { - dns_difftuple_t const * const *ap = av; - dns_difftuple_t const * const *bp = bv; - dns_difftuple_t const *a = *ap; - dns_difftuple_t const *b = *bp; - return (dns_name_compare(&a->name, &b->name)); -} - -static isc_result_t -uniqify_name_list(dns_diff_t *list) { - isc_result_t result; - dns_difftuple_t *p, *q; - - CHECK(dns_diff_sort(list, name_order)); - - p = ISC_LIST_HEAD(list->tuples); - while (p != NULL) { - do { - q = ISC_LIST_NEXT(p, link); - if (q == NULL || ! dns_name_equal(&p->name, &q->name)) - break; - ISC_LIST_UNLINK(list->tuples, q, link); - dns_difftuple_free(&q); - } while (1); - p = ISC_LIST_NEXT(p, link); - } - failure: - return (result); -} - - -static isc_result_t -is_glue(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - isc_boolean_t *flag) -{ - isc_result_t result; - dns_fixedname_t foundname; - dns_fixedname_init(&foundname); - result = dns_db_find(db, name, ver, dns_rdatatype_any, - DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD, - (isc_stdtime_t) 0, NULL, - dns_fixedname_name(&foundname), - NULL, NULL); - if (result == ISC_R_SUCCESS) { - *flag = ISC_FALSE; - return (ISC_R_SUCCESS); - } else if (result == DNS_R_ZONECUT) { - /* - * We are at the zonecut. The name will have an NSEC, but - * non-delegation will be omitted from the type bit map. - */ - *flag = ISC_FALSE; - return (ISC_R_SUCCESS); - } else if (result == DNS_R_GLUE || result == DNS_R_DNAME) { - *flag = ISC_TRUE; - return (ISC_R_SUCCESS); - } else { - return (result); - } -} - -/* - * Find the next/previous name that has a NSEC record. - * In other words, skip empty database nodes and names that - * have had their NSECs removed because they are obscured by - * a zone cut. - */ -static isc_result_t -next_active(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, - dns_dbversion_t *ver, dns_name_t *oldname, dns_name_t *newname, - isc_boolean_t forward) -{ - isc_result_t result; - dns_dbiterator_t *dbit = NULL; - isc_boolean_t has_nsec; - unsigned int wraps = 0; - - CHECK(dns_db_createiterator(db, ISC_FALSE, &dbit)); - - CHECK(dns_dbiterator_seek(dbit, oldname)); - do { - dns_dbnode_t *node = NULL; - - if (forward) - result = dns_dbiterator_next(dbit); - else - result = dns_dbiterator_prev(dbit); - if (result == ISC_R_NOMORE) { - /* - * Wrap around. - */ - if (forward) - CHECK(dns_dbiterator_first(dbit)); - else - CHECK(dns_dbiterator_last(dbit)); - wraps++; - if (wraps == 2) { - update_log(client, zone, ISC_LOG_ERROR, - "secure zone with no NSECs"); - result = DNS_R_BADZONE; - goto failure; - } - } - CHECK(dns_dbiterator_current(dbit, &node, newname)); - dns_db_detachnode(db, &node); - - /* - * The iterator may hold the tree lock, and - * rrset_exists() calls dns_db_findnode() which - * may try to reacquire it. To avoid deadlock - * we must pause the iterator first. - */ - CHECK(dns_dbiterator_pause(dbit)); - CHECK(rrset_exists(db, ver, newname, - dns_rdatatype_nsec, 0, &has_nsec)); - - } while (! has_nsec); - failure: - if (dbit != NULL) - dns_dbiterator_destroy(&dbit); - - return (result); -} - -/* - * Add a NSEC record for "name", recording the change in "diff". - * The existing NSEC is removed. - */ -static isc_result_t -add_nsec(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, - dns_dbversion_t *ver, dns_name_t *name, dns_diff_t *diff) -{ - isc_result_t result; - dns_dbnode_t *node = NULL; - unsigned char buffer[DNS_NSEC_BUFFERSIZE]; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_difftuple_t *tuple = NULL; - dns_fixedname_t fixedname; - dns_name_t *target; - - dns_fixedname_init(&fixedname); - target = dns_fixedname_name(&fixedname); - - /* - * Find the successor name, aka NSEC target. - */ - CHECK(next_active(client, zone, db, ver, name, target, ISC_TRUE)); - - /* - * Create the NSEC RDATA. - */ - CHECK(dns_db_findnode(db, name, ISC_FALSE, &node)); - dns_rdata_init(&rdata); - CHECK(dns_nsec_buildrdata(db, ver, node, target, buffer, &rdata)); - dns_db_detachnode(db, &node); - - /* - * Delete the old NSEC and record the change. - */ - CHECK(delete_if(true_p, db, ver, name, dns_rdatatype_nsec, 0, - NULL, diff)); - /* - * Add the new NSEC and record the change. - */ - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, - 3600, /* XXXRTH */ - &rdata, &tuple)); - CHECK(do_one_tuple(&tuple, db, ver, diff)); - INSIST(tuple == NULL); - - failure: - if (node != NULL) - dns_db_detachnode(db, &node); - return (result); -} - -/* - * Add a placeholder NSEC record for "name", recording the change in "diff". - */ -static isc_result_t -add_placeholder_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - dns_diff_t *diff) { - isc_result_t result; - dns_difftuple_t *tuple = NULL; - isc_region_t r; - unsigned char data[1] = { 0 }; /* The root domain, no bits. */ - dns_rdata_t rdata = DNS_RDATA_INIT; - - r.base = data; - r.length = sizeof(data); - dns_rdata_fromregion(&rdata, dns_db_class(db), dns_rdatatype_nsec, &r); - CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, 0, - &rdata, &tuple)); - CHECK(do_one_tuple(&tuple, db, ver, diff)); - failure: - return (result); -} - -static isc_result_t -find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, - isc_mem_t *mctx, unsigned int maxkeys, - dst_key_t **keys, unsigned int *nkeys) -{ - isc_result_t result; - dns_dbnode_t *node = NULL; - const char *directory = dns_zone_getkeydirectory(zone); - CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node)); - CHECK(dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db), - directory, mctx, maxkeys, keys, nkeys)); - failure: - if (node != NULL) - dns_db_detachnode(db, &node); - return (result); -} - -/* - * Add RRSIG records for an RRset, recording the change in "diff". - */ -static isc_result_t -add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys, - unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception, - isc_stdtime_t expire) -{ - isc_result_t result; - dns_dbnode_t *node = NULL; - dns_rdataset_t rdataset; - dns_rdata_t sig_rdata = DNS_RDATA_INIT; - isc_buffer_t buffer; - unsigned char data[1024]; /* XXX */ - unsigned int i; - - dns_rdataset_init(&rdataset); - isc_buffer_init(&buffer, data, sizeof(data)); - - /* Get the rdataset to sign. */ - CHECK(dns_db_findnode(db, name, ISC_FALSE, &node)); - CHECK(dns_db_findrdataset(db, node, ver, type, 0, - (isc_stdtime_t) 0, - &rdataset, NULL)); - dns_db_detachnode(db, &node); - - for (i = 0; i < nkeys; i++) { - /* Calculate the signature, creating a RRSIG RDATA. */ - CHECK(dns_dnssec_sign(name, &rdataset, keys[i], - &inception, &expire, - mctx, &buffer, &sig_rdata)); - - /* Update the database and journal with the RRSIG. */ - /* XXX inefficient - will cause dataset merging */ - CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, - rdataset.ttl, &sig_rdata)); - dns_rdata_reset(&sig_rdata); - } - - failure: - if (dns_rdataset_isassociated(&rdataset)) - dns_rdataset_disassociate(&rdataset); - if (node != NULL) - dns_db_detachnode(db, &node); - return (result); -} - -/* - * Update RRSIG and NSEC records affected by an update. The original - * update, including the SOA serial update but exluding the RRSIG & NSEC - * changes, is in "diff" and has already been applied to "newver" of "db". - * The database version prior to the update is "oldver". - * - * The necessary RRSIG and NSEC changes will be applied to "newver" - * and added (as a minimal diff) to "diff". - * - * The RRSIGs generated will be valid for 'sigvalidityinterval' seconds. - */ -static isc_result_t -update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, - dns_dbversion_t *oldver, dns_dbversion_t *newver, - dns_diff_t *diff, isc_uint32_t sigvalidityinterval) -{ - isc_result_t result; - dns_difftuple_t *t; - dns_diff_t diffnames; - dns_diff_t affected; - dns_diff_t sig_diff; - dns_diff_t nsec_diff; - dns_diff_t nsec_mindiff; - isc_boolean_t flag; - dst_key_t *zone_keys[MAXZONEKEYS]; - unsigned int nkeys = 0; - unsigned int i; - isc_stdtime_t now, inception, expire; - - dns_diff_init(client->mctx, &diffnames); - dns_diff_init(client->mctx, &affected); - - dns_diff_init(client->mctx, &sig_diff); - dns_diff_init(client->mctx, &nsec_diff); - dns_diff_init(client->mctx, &nsec_mindiff); - - result = find_zone_keys(zone, db, newver, client->mctx, - MAXZONEKEYS, zone_keys, &nkeys); - if (result != ISC_R_SUCCESS) { - update_log(client, zone, ISC_LOG_ERROR, - "could not get zone keys for secure dynamic update"); - goto failure; - } - - isc_stdtime_get(&now); - inception = now - 3600; /* Allow for some clock skew. */ - expire = now + sigvalidityinterval; - - /* - * Find all RRsets directly affected by the update, and - * update their RRSIGs. Also build a list of names affected - * by the update in "diffnames". - */ - CHECK(dns_diff_sort(diff, temp_order)); - - t = ISC_LIST_HEAD(diff->tuples); - while (t != NULL) { - dns_name_t *name = &t->name; - /* Now "name" is a new, unique name affected by the update. */ - - CHECK(namelist_append_name(&diffnames, name)); - - while (t != NULL && dns_name_equal(&t->name, name)) { - dns_rdatatype_t type; - type = t->rdata.type; - - /* - * Now "name" and "type" denote a new unique RRset - * affected by the update. - */ - - /* Don't sign RRSIGs. */ - if (type == dns_rdatatype_rrsig) - goto skip; - - /* - * Delete all old RRSIGs covering this type, since they - * are all invalid when the signed RRset has changed. - * We may not be able to recreate all of them - tough. - */ - CHECK(delete_if(true_p, db, newver, name, - dns_rdatatype_rrsig, type, - NULL, &sig_diff)); - - /* - * If this RRset still exists after the update, - * add a new signature for it. - */ - CHECK(rrset_exists(db, newver, name, type, 0, &flag)); - if (flag) { - CHECK(add_sigs(db, newver, name, type, - &sig_diff, zone_keys, nkeys, - client->mctx, inception, - expire)); - } - skip: - /* Skip any other updates to the same RRset. */ - while (t != NULL && - dns_name_equal(&t->name, name) && - t->rdata.type == type) - { - t = ISC_LIST_NEXT(t, link); - } - } - } - - /* Remove orphaned NSECs and RRSIG NSECs. */ - for (t = ISC_LIST_HEAD(diffnames.tuples); - t != NULL; - t = ISC_LIST_NEXT(t, link)) - { - CHECK(non_nsec_rrset_exists(db, newver, &t->name, &flag)); - if (! flag) { - CHECK(delete_if(true_p, db, newver, &t->name, - dns_rdatatype_any, 0, - NULL, &sig_diff)); - } - } - - /* - * When a name is created or deleted, its predecessor needs to - * have its NSEC updated. - */ - for (t = ISC_LIST_HEAD(diffnames.tuples); - t != NULL; - t = ISC_LIST_NEXT(t, link)) - { - isc_boolean_t existed, exists; - dns_fixedname_t fixedname; - dns_name_t *prevname; - - dns_fixedname_init(&fixedname); - prevname = dns_fixedname_name(&fixedname); - - CHECK(name_exists(db, oldver, &t->name, &existed)); - CHECK(name_exists(db, newver, &t->name, &exists)); - if (exists == existed) - continue; - - /* - * Find the predecessor. - * When names become obscured or unobscured in this update - * transaction, we may find the wrong predecessor because - * the NSECs have not yet been updated to reflect the delegation - * change. This should not matter because in this case, - * the correct predecessor is either the delegation node or - * a newly unobscured node, and those nodes are on the - * "affected" list in any case. - */ - CHECK(next_active(client, zone, db, newver, - &t->name, prevname, ISC_FALSE)); - CHECK(namelist_append_name(&affected, prevname)); - } - - /* - * Find names potentially affected by delegation changes - * (obscured by adding an NS or DNAME, or unobscured by - * removing one). - */ - for (t = ISC_LIST_HEAD(diffnames.tuples); - t != NULL; - t = ISC_LIST_NEXT(t, link)) - { - isc_boolean_t ns_existed, dname_existed; - isc_boolean_t ns_exists, dname_exists; - - CHECK(rrset_exists(db, oldver, &t->name, dns_rdatatype_ns, 0, - &ns_existed)); - CHECK(rrset_exists(db, oldver, &t->name, dns_rdatatype_dname, 0, - &dname_existed)); - CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_ns, 0, - &ns_exists)); - CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_dname, 0, - &dname_exists)); - if ((ns_exists || dname_exists) == (ns_existed || dname_existed)) - continue; - /* - * There was a delegation change. Mark all subdomains - * of t->name as potentially needing a NSEC update. - */ - CHECK(namelist_append_subdomain(db, &t->name, &affected)); - } - - ISC_LIST_APPENDLIST(affected.tuples, diffnames.tuples, link); - INSIST(ISC_LIST_EMPTY(diffnames.tuples)); - - CHECK(uniqify_name_list(&affected)); - - /* - * Determine which names should have NSECs, and delete/create - * NSECs to make it so. We don't know the final NSEC targets yet, - * so we just create placeholder NSECs with arbitrary contents - * to indicate that their respective owner names should be part of - * the NSEC chain. - */ - for (t = ISC_LIST_HEAD(affected.tuples); - t != NULL; - t = ISC_LIST_NEXT(t, link)) - { - isc_boolean_t exists; - CHECK(name_exists(db, newver, &t->name, &exists)); - if (! exists) - continue; - CHECK(is_glue(db, newver, &t->name, &flag)); - if (flag) { - /* - * This name is obscured. Delete any - * existing NSEC record. - */ - CHECK(delete_if(true_p, db, newver, &t->name, - dns_rdatatype_nsec, 0, - NULL, &nsec_diff)); - } else { - /* - * This name is not obscured. It should have a NSEC. - */ - CHECK(rrset_exists(db, newver, &t->name, - dns_rdatatype_nsec, 0, &flag)); - if (! flag) - CHECK(add_placeholder_nsec(db, newver, &t->name, - diff)); - } - } - - /* - * Now we know which names are part of the NSEC chain. - * Make them all point at their correct targets. - */ - for (t = ISC_LIST_HEAD(affected.tuples); - t != NULL; - t = ISC_LIST_NEXT(t, link)) - { - CHECK(rrset_exists(db, newver, &t->name, - dns_rdatatype_nsec, 0, &flag)); - if (flag) { - /* - * There is a NSEC, but we don't know if it is correct. - * Delete it and create a correct one to be sure. - * If the update was unnecessary, the diff minimization - * will take care of eliminating it from the journal, - * IXFRs, etc. - * - * The RRSIG bit should always be set in the NSECs - * we generate, because they will all get RRSIG NSECs. - * (XXX what if the zone keys are missing?). - * Because the RRSIG NSECs have not necessarily been - * created yet, the correctness of the bit mask relies - * on the assumption that NSECs are only created if - * there is other data, and if there is other data, - * there are other RRSIGs. - */ - CHECK(add_nsec(client, zone, db, newver, - &t->name, &nsec_diff)); - } - } - - /* - * Minimize the set of NSEC updates so that we don't - * have to regenerate the RRSIG NSECs for NSECs that were - * replaced with identical ones. - */ - while ((t = ISC_LIST_HEAD(nsec_diff.tuples)) != NULL) { - ISC_LIST_UNLINK(nsec_diff.tuples, t, link); - dns_diff_appendminimal(&nsec_mindiff, &t); - } - - /* Update RRSIG NSECs. */ - for (t = ISC_LIST_HEAD(nsec_mindiff.tuples); - t != NULL; - t = ISC_LIST_NEXT(t, link)) - { - if (t->op == DNS_DIFFOP_DEL) { - CHECK(delete_if(true_p, db, newver, &t->name, - dns_rdatatype_rrsig, dns_rdatatype_nsec, - NULL, &sig_diff)); - } else if (t->op == DNS_DIFFOP_ADD) { - CHECK(add_sigs(db, newver, &t->name, dns_rdatatype_nsec, - &sig_diff, zone_keys, nkeys, - client->mctx, inception, expire)); - } else { - INSIST(0); - } - } - - /* Record our changes for the journal. */ - while ((t = ISC_LIST_HEAD(sig_diff.tuples)) != NULL) { - ISC_LIST_UNLINK(sig_diff.tuples, t, link); - dns_diff_appendminimal(diff, &t); - } - while ((t = ISC_LIST_HEAD(nsec_mindiff.tuples)) != NULL) { - ISC_LIST_UNLINK(nsec_mindiff.tuples, t, link); - dns_diff_appendminimal(diff, &t); - } - - INSIST(ISC_LIST_EMPTY(sig_diff.tuples)); - INSIST(ISC_LIST_EMPTY(nsec_diff.tuples)); - INSIST(ISC_LIST_EMPTY(nsec_mindiff.tuples)); - - failure: - dns_diff_clear(&sig_diff); - dns_diff_clear(&nsec_diff); - dns_diff_clear(&nsec_mindiff); - - dns_diff_clear(&affected); - dns_diff_clear(&diffnames); - - for (i = 0; i < nkeys; i++) - dst_key_free(&zone_keys[i]); - - return (result); -} - - -/**************************************************************************/ -/* - * The actual update code in all its glory. We try to follow - * the RFC2136 pseudocode as closely as possible. - */ - -static isc_result_t -send_update_event(ns_client_t *client, dns_zone_t *zone) { - isc_result_t result = ISC_R_SUCCESS; - update_event_t *event = NULL; - isc_task_t *zonetask = NULL; - ns_client_t *evclient; - - event = (update_event_t *) - isc_event_allocate(client->mctx, client, DNS_EVENT_UPDATE, - update_action, NULL, sizeof(*event)); - if (event == NULL) - FAIL(ISC_R_NOMEMORY); - event->zone = zone; - event->result = ISC_R_SUCCESS; - - evclient = NULL; - ns_client_attach(client, &evclient); - INSIST(client->nupdates == 0); - client->nupdates++; - event->ev_arg = evclient; - - dns_zone_gettask(zone, &zonetask); - isc_task_send(zonetask, ISC_EVENT_PTR(&event)); - - failure: - if (event != NULL) - isc_event_free(ISC_EVENT_PTR(&event)); - return (result); -} - -static void -respond(ns_client_t *client, isc_result_t result) { - isc_result_t msg_result; - - msg_result = dns_message_reply(client->message, ISC_TRUE); - if (msg_result != ISC_R_SUCCESS) - goto msg_failure; - client->message->rcode = dns_result_torcode(result); - - ns_client_send(client); - return; - - msg_failure: - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_UPDATE, NS_LOGMODULE_UPDATE, - ISC_LOG_ERROR, - "could not create update response message: %s", - isc_result_totext(msg_result)); - ns_client_next(client, msg_result); -} - -void -ns_update_start(ns_client_t *client, isc_result_t sigresult) { - dns_message_t *request = client->message; - isc_result_t result; - dns_name_t *zonename; - dns_rdataset_t *zone_rdataset; - dns_zone_t *zone = NULL; - - /* - * Interpret the zone section. - */ - result = dns_message_firstname(request, DNS_SECTION_ZONE); - if (result != ISC_R_SUCCESS) - FAILC(DNS_R_FORMERR, - "update zone section empty"); - - /* - * The zone section must contain exactly one "question", and - * it must be of type SOA. - */ - zonename = NULL; - dns_message_currentname(request, DNS_SECTION_ZONE, &zonename); - zone_rdataset = ISC_LIST_HEAD(zonename->list); - if (zone_rdataset->type != dns_rdatatype_soa) - FAILC(DNS_R_FORMERR, - "update zone section contains non-SOA"); - if (ISC_LIST_NEXT(zone_rdataset, link) != NULL) - FAILC(DNS_R_FORMERR, - "update zone section contains multiple RRs"); - - /* The zone section must have exactly one name. */ - result = dns_message_nextname(request, DNS_SECTION_ZONE); - if (result != ISC_R_NOMORE) - FAILC(DNS_R_FORMERR, - "update zone section contains multiple RRs"); - - result = dns_zt_find(client->view->zonetable, zonename, 0, NULL, - &zone); - if (result != ISC_R_SUCCESS) - FAILC(DNS_R_NOTAUTH, - "not authoritative for update zone"); - - switch(dns_zone_gettype(zone)) { - case dns_zone_master: - /* - * We can now fail due to a bad signature as we now know - * that we are the master. - */ - if (sigresult != ISC_R_SUCCESS) - FAIL(sigresult); - CHECK(send_update_event(client, zone)); - break; - case dns_zone_slave: - CHECK(checkupdateacl(client, dns_zone_getforwardacl(zone), - "update forwarding", zonename, ISC_TRUE)); - CHECK(send_forward_event(client, zone)); - break; - default: - FAILC(DNS_R_NOTAUTH, - "not authoritative for update zone"); - } - return; - - failure: - /* - * We failed without having sent an update event to the zone. - * We are still in the client task context, so we can - * simply give an error response without switching tasks. - */ - respond(client, result); - if (zone != NULL) - dns_zone_detach(&zone); -} - -/* - * DS records are not allowed to exist without corresponding NS records, - * draft-ietf-dnsext-delegation-signer-11.txt, 2.2 Protocol Change, - * "DS RRsets MUST NOT appear at non-delegation points or at a zone's apex". - */ - -static isc_result_t -remove_orphaned_ds(dns_db_t *db, dns_dbversion_t *newver, dns_diff_t *diff) { - isc_result_t result; - isc_boolean_t ns_exists, ds_exists; - dns_difftuple_t *t; - - for (t = ISC_LIST_HEAD(diff->tuples); - t != NULL; - t = ISC_LIST_NEXT(t, link)) { - if (t->op != DNS_DIFFOP_DEL || - t->rdata.type != dns_rdatatype_ns) - continue; - CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_ns, 0, - &ns_exists)); - if (ns_exists) - continue; - CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_ds, 0, - &ds_exists)); - if (!ds_exists) - continue; - CHECK(delete_if(true_p, db, newver, &t->name, - dns_rdatatype_ds, 0, NULL, diff)); - } - return (ISC_R_SUCCESS); - - failure: - return (result); -} - -static void -update_action(isc_task_t *task, isc_event_t *event) { - update_event_t *uev = (update_event_t *) event; - dns_zone_t *zone = uev->zone; - ns_client_t *client = (ns_client_t *)event->ev_arg; - - isc_result_t result; - dns_db_t *db = NULL; - dns_dbversion_t *oldver = NULL; - dns_dbversion_t *ver = NULL; - dns_diff_t diff; /* Pending updates. */ - dns_diff_t temp; /* Pending RR existence assertions. */ - isc_boolean_t soa_serial_changed = ISC_FALSE; - isc_mem_t *mctx = client->mctx; - dns_rdatatype_t covers; - dns_message_t *request = client->message; - dns_rdataclass_t zoneclass; - dns_name_t *zonename; - dns_ssutable_t *ssutable = NULL; - dns_fixedname_t tmpnamefixed; - dns_name_t *tmpname = NULL; - - INSIST(event->ev_type == DNS_EVENT_UPDATE); - - dns_diff_init(mctx, &diff); - dns_diff_init(mctx, &temp); - - CHECK(dns_zone_getdb(zone, &db)); - zonename = dns_db_origin(db); - zoneclass = dns_db_class(db); - dns_zone_getssutable(zone, &ssutable); - dns_db_currentversion(db, &oldver); - CHECK(dns_db_newversion(db, &ver)); - - /* - * Check prerequisites. - */ - - for (result = dns_message_firstname(request, DNS_SECTION_PREREQUISITE); - result == ISC_R_SUCCESS; - result = dns_message_nextname(request, DNS_SECTION_PREREQUISITE)) - { - dns_name_t *name = NULL; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_ttl_t ttl; - dns_rdataclass_t update_class; - isc_boolean_t flag; - - get_current_rr(request, DNS_SECTION_PREREQUISITE, zoneclass, - &name, &rdata, &covers, &ttl, &update_class); - - if (ttl != 0) - FAILC(DNS_R_FORMERR, "prerequisite TTL is not zero"); - - if (! dns_name_issubdomain(name, zonename)) - FAILN(DNS_R_NOTZONE, name, - "prerequisite name is out of zone"); - - if (update_class == dns_rdataclass_any) { - if (rdata.length != 0) - FAILC(DNS_R_FORMERR, - "class ANY prerequisite " - "RDATA is not empty"); - if (rdata.type == dns_rdatatype_any) { - CHECK(name_exists(db, ver, name, &flag)); - if (! flag) { - FAILN(DNS_R_NXDOMAIN, name, - "'name in use' prerequisite " - "not satisfied"); - } - } else { - CHECK(rrset_exists(db, ver, name, - rdata.type, covers, &flag)); - if (! flag) { - /* RRset does not exist. */ - FAILNT(DNS_R_NXRRSET, name, rdata.type, - "'rrset exists (value independent)' " - "prerequisite not satisfied"); - } - } - } else if (update_class == dns_rdataclass_none) { - if (rdata.length != 0) - FAILC(DNS_R_FORMERR, - "class NONE prerequisite " - "RDATA is not empty"); - if (rdata.type == dns_rdatatype_any) { - CHECK(name_exists(db, ver, name, &flag)); - if (flag) { - FAILN(DNS_R_YXDOMAIN, name, - "'name not in use' prerequisite " - "not satisfied"); - } - } else { - CHECK(rrset_exists(db, ver, name, - rdata.type, covers, &flag)); - if (flag) { - /* RRset exists. */ - FAILNT(DNS_R_YXRRSET, name, rdata.type, - "'rrset does not exist' " - "prerequisite not satisfied"); - } - } - } else if (update_class == zoneclass) { - /* "temp<rr.name, rr.type> += rr;" */ - result = temp_append(&temp, name, &rdata); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "temp entry creation failed: %s", - dns_result_totext(result)); - FAIL(ISC_R_UNEXPECTED); - } - } else { - FAILC(DNS_R_FORMERR, "malformed prerequisite"); - } - } - if (result != ISC_R_NOMORE) - FAIL(result); - - - /* - * Perform the final check of the "rrset exists (value dependent)" - * prerequisites. - */ - if (ISC_LIST_HEAD(temp.tuples) != NULL) { - dns_rdatatype_t type; - - /* - * Sort the prerequisite records by owner name, - * type, and rdata. - */ - result = dns_diff_sort(&temp, temp_order); - if (result != ISC_R_SUCCESS) - FAILC(result, "'RRset exists (value dependent)' " - "prerequisite not satisfied"); - - dns_fixedname_init(&tmpnamefixed); - tmpname = dns_fixedname_name(&tmpnamefixed); - result = temp_check(mctx, &temp, db, ver, tmpname, &type); - if (result != ISC_R_SUCCESS) - FAILNT(result, tmpname, type, - "'RRset exists (value dependent)' " - "prerequisite not satisfied"); - } - - update_log(client, zone, LOGLEVEL_DEBUG, - "prerequisites are OK"); - - /* - * Check Requestor's Permissions. It seems a bit silly to do this - * only after prerequisite testing, but that is what RFC2136 says. - */ - result = ISC_R_SUCCESS; - if (ssutable == NULL) - CHECK(checkupdateacl(client, dns_zone_getupdateacl(zone), - "update", zonename, ISC_FALSE)); - else if (client->signer == NULL) - CHECK(checkupdateacl(client, NULL, "update", zonename, - ISC_FALSE)); - - if (dns_zone_getupdatedisabled(zone)) - FAILC(DNS_R_REFUSED, "dynamic update temporarily disabled"); - - /* - * Perform the Update Section Prescan. - */ - - for (result = dns_message_firstname(request, DNS_SECTION_UPDATE); - result == ISC_R_SUCCESS; - result = dns_message_nextname(request, DNS_SECTION_UPDATE)) - { - dns_name_t *name = NULL; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_ttl_t ttl; - dns_rdataclass_t update_class; - get_current_rr(request, DNS_SECTION_UPDATE, zoneclass, - &name, &rdata, &covers, &ttl, &update_class); - - if (! dns_name_issubdomain(name, zonename)) - FAILC(DNS_R_NOTZONE, - "update RR is outside zone"); - if (update_class == zoneclass) { - /* - * Check for meta-RRs. The RFC2136 pseudocode says - * check for ANY|AXFR|MAILA|MAILB, but the text adds - * "or any other QUERY metatype" - */ - if (dns_rdatatype_ismeta(rdata.type)) { - FAILC(DNS_R_FORMERR, - "meta-RR in update"); - } - result = dns_zone_checknames(zone, name, &rdata); - if (result != ISC_R_SUCCESS) - FAIL(DNS_R_REFUSED); - } else if (update_class == dns_rdataclass_any) { - if (ttl != 0 || rdata.length != 0 || - (dns_rdatatype_ismeta(rdata.type) && - rdata.type != dns_rdatatype_any)) - FAILC(DNS_R_FORMERR, - "meta-RR in update"); - } else if (update_class == dns_rdataclass_none) { - if (ttl != 0 || - dns_rdatatype_ismeta(rdata.type)) - FAILC(DNS_R_FORMERR, - "meta-RR in update"); - } else { - update_log(client, zone, ISC_LOG_WARNING, - "update RR has incorrect class %d", - update_class); - FAIL(DNS_R_FORMERR); - } - /* - * draft-ietf-dnsind-simple-secure-update-01 says - * "Unlike traditional dynamic update, the client - * is forbidden from updating NSEC records." - */ - if (dns_db_issecure(db)) { - if (rdata.type == dns_rdatatype_nsec) { - FAILC(DNS_R_REFUSED, - "explicit NSEC updates are not allowed " - "in secure zones"); - } - else if (rdata.type == dns_rdatatype_rrsig) { - FAILC(DNS_R_REFUSED, - "explicit RRSIG updates are currently not " - "supported in secure zones"); - } - } - - if (ssutable != NULL && client->signer != NULL) { - if (rdata.type != dns_rdatatype_any) { - if (!dns_ssutable_checkrules(ssutable, - client->signer, - name, rdata.type)) - FAILC(DNS_R_REFUSED, - "rejected by secure update"); - } - else { - if (!ssu_checkall(db, ver, name, ssutable, - client->signer)) - FAILC(DNS_R_REFUSED, - "rejected by secure update"); - } - } - } - if (result != ISC_R_NOMORE) - FAIL(result); - - update_log(client, zone, LOGLEVEL_DEBUG, - "update section prescan OK"); - - /* - * Process the Update Section. - */ - - for (result = dns_message_firstname(request, DNS_SECTION_UPDATE); - result == ISC_R_SUCCESS; - result = dns_message_nextname(request, DNS_SECTION_UPDATE)) - { - dns_name_t *name = NULL; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_ttl_t ttl; - dns_rdataclass_t update_class; - isc_boolean_t flag; - - get_current_rr(request, DNS_SECTION_UPDATE, zoneclass, - &name, &rdata, &covers, &ttl, &update_class); - - if (update_class == zoneclass) { - - /* - * RFC 1123 doesn't allow MF and MD in master zones. */ - if (rdata.type == dns_rdatatype_md || - rdata.type == dns_rdatatype_mf) { - char typebuf[DNS_RDATATYPE_FORMATSIZE]; - - dns_rdatatype_format(rdata.type, typebuf, - sizeof(typebuf)); - update_log(client, zone, LOGLEVEL_PROTOCOL, - "attempt to add %s ignored", - typebuf); - continue; - } - if (rdata.type == dns_rdatatype_ns && - dns_name_iswildcard(name)) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to add wildcard NS record" - "ignored"); - continue; - } - if (rdata.type == dns_rdatatype_cname) { - CHECK(cname_incompatible_rrset_exists(db, ver, - name, - &flag)); - if (flag) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to add CNAME " - "alongside non-CNAME " - "ignored"); - continue; - } - } else { - CHECK(rrset_exists(db, ver, name, - dns_rdatatype_cname, 0, - &flag)); - if (flag && - ! dns_rdatatype_isdnssec(rdata.type)) - { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to add non-CNAME " - "alongside CNAME ignored"); - continue; - } - } - if (rdata.type == dns_rdatatype_soa) { - isc_boolean_t ok; - CHECK(rrset_exists(db, ver, name, - dns_rdatatype_soa, 0, - &flag)); - if (! flag) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to create 2nd " - "SOA ignored"); - continue; - } - CHECK(check_soa_increment(db, ver, &rdata, - &ok)); - if (! ok) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "SOA update failed to " - "increment serial, " - "ignoring it"); - continue; - } - soa_serial_changed = ISC_TRUE; - } - - if (isc_log_wouldlog(ns_g_lctx, LOGLEVEL_PROTOCOL)) { - char namestr[DNS_NAME_FORMATSIZE]; - char typestr[DNS_RDATATYPE_FORMATSIZE]; - dns_name_format(name, namestr, - sizeof(namestr)); - dns_rdatatype_format(rdata.type, typestr, - sizeof(typestr)); - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "adding an RR at '%s' %s", - namestr, typestr); - } - - /* Prepare the affected RRset for the addition. */ - { - add_rr_prepare_ctx_t ctx; - ctx.db = db; - ctx.ver = ver; - ctx.diff = &diff; - ctx.name = name; - ctx.update_rr = &rdata; - ctx.update_rr_ttl = ttl; - ctx.ignore_add = ISC_FALSE; - dns_diff_init(mctx, &ctx.del_diff); - dns_diff_init(mctx, &ctx.add_diff); - CHECK(foreach_rr(db, ver, name, rdata.type, - covers, add_rr_prepare_action, - &ctx)); - - if (ctx.ignore_add) { - dns_diff_clear(&ctx.del_diff); - dns_diff_clear(&ctx.add_diff); - } else { - CHECK(do_diff(&ctx.del_diff, db, ver, &diff)); - CHECK(do_diff(&ctx.add_diff, db, ver, &diff)); - CHECK(update_one_rr(db, ver, &diff, - DNS_DIFFOP_ADD, - name, ttl, &rdata)); - } - } - } else if (update_class == dns_rdataclass_any) { - if (rdata.type == dns_rdatatype_any) { - if (isc_log_wouldlog(ns_g_lctx, - LOGLEVEL_PROTOCOL)) - { - char namestr[DNS_NAME_FORMATSIZE]; - dns_name_format(name, namestr, - sizeof(namestr)); - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "delete all rrsets from " - "name '%s'", namestr); - } - if (dns_name_equal(name, zonename)) { - CHECK(delete_if(type_not_soa_nor_ns_p, - db, ver, name, - dns_rdatatype_any, 0, - &rdata, &diff)); - } else { - CHECK(delete_if(type_not_dnssec, - db, ver, name, - dns_rdatatype_any, 0, - &rdata, &diff)); - } - } else if (dns_name_equal(name, zonename) && - (rdata.type == dns_rdatatype_soa || - rdata.type == dns_rdatatype_ns)) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to delete all SOA " - "or NS records ignored"); - continue; - } else { - if (isc_log_wouldlog(ns_g_lctx, - LOGLEVEL_PROTOCOL)) - { - char namestr[DNS_NAME_FORMATSIZE]; - char typestr[DNS_RDATATYPE_FORMATSIZE]; - dns_name_format(name, namestr, - sizeof(namestr)); - dns_rdatatype_format(rdata.type, - typestr, - sizeof(typestr)); - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "deleting rrset at '%s' %s", - namestr, typestr); - } - CHECK(delete_if(true_p, db, ver, name, - rdata.type, covers, &rdata, - &diff)); - } - } else if (update_class == dns_rdataclass_none) { - /* - * The (name == zonename) condition appears in - * RFC2136 3.4.2.4 but is missing from the pseudocode. - */ - if (dns_name_equal(name, zonename)) { - if (rdata.type == dns_rdatatype_soa) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to delete SOA " - "ignored"); - continue; - } - if (rdata.type == dns_rdatatype_ns) { - int count; - CHECK(rr_count(db, ver, name, - dns_rdatatype_ns, - 0, &count)); - if (count == 1) { - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "attempt to " - "delete last " - "NS ignored"); - continue; - } - } - } - update_log(client, zone, - LOGLEVEL_PROTOCOL, - "deleting an RR"); - CHECK(delete_if(rr_equal_p, db, ver, name, - rdata.type, covers, &rdata, &diff)); - } - } - if (result != ISC_R_NOMORE) - FAIL(result); - - /* - * If any changes were made, increment the SOA serial number, - * update RRSIGs and NSECs (if zone is secure), and write the update - * to the journal. - */ - if (! ISC_LIST_EMPTY(diff.tuples)) { - char *journalfile; - dns_journal_t *journal; - - /* - * Increment the SOA serial, but only if it was not - * changed as a result of an update operation. - */ - if (! soa_serial_changed) { - CHECK(increment_soa_serial(db, ver, &diff, mctx)); - } - - CHECK(remove_orphaned_ds(db, ver, &diff)); - - if (dns_db_issecure(db)) { - result = update_signatures(client, zone, db, oldver, - ver, &diff, - dns_zone_getsigvalidityinterval(zone)); - if (result != ISC_R_SUCCESS) { - update_log(client, zone, - ISC_LOG_ERROR, - "RRSIG/NSEC update failed: %s", - isc_result_totext(result)); - goto failure; - } - } - - journalfile = dns_zone_getjournal(zone); - if (journalfile != NULL) { - update_log(client, zone, LOGLEVEL_DEBUG, - "writing journal %s", journalfile); - - journal = NULL; - result = dns_journal_open(mctx, journalfile, - ISC_TRUE, &journal); - if (result != ISC_R_SUCCESS) - FAILS(result, "journal open failed"); - - result = dns_journal_write_transaction(journal, &diff); - if (result != ISC_R_SUCCESS) { - dns_journal_destroy(&journal); - FAILS(result, "journal write failed"); - } - - dns_journal_destroy(&journal); - } - - /* - * XXXRTH Just a note that this committing code will have - * to change to handle databases that need two-phase - * commit, but this isn't a priority. - */ - update_log(client, zone, LOGLEVEL_DEBUG, - "committing update transaction"); - dns_db_closeversion(db, &ver, ISC_TRUE); - - /* - * Mark the zone as dirty so that it will be written to disk. - */ - dns_zone_markdirty(zone); - - /* - * Notify slaves of the change we just made. - */ - dns_zone_notify(zone); - } else { - update_log(client, zone, LOGLEVEL_DEBUG, "redundant request"); - dns_db_closeversion(db, &ver, ISC_TRUE); - } - result = ISC_R_SUCCESS; - goto common; - - failure: - /* - * The reason for failure should have been logged at this point. - */ - if (ver != NULL) { - update_log(client, zone, LOGLEVEL_DEBUG, - "rolling back"); - dns_db_closeversion(db, &ver, ISC_FALSE); - } - - common: - dns_diff_clear(&temp); - dns_diff_clear(&diff); - - if (oldver != NULL) - dns_db_closeversion(db, &oldver, ISC_FALSE); - - if (db != NULL) - dns_db_detach(&db); - - if (ssutable != NULL) - dns_ssutable_detach(&ssutable); - - if (zone != NULL) - dns_zone_detach(&zone); - - isc_task_detach(&task); - uev->result = result; - uev->ev_type = DNS_EVENT_UPDATEDONE; - uev->ev_action = updatedone_action; - isc_task_send(client->task, &event); - INSIST(event == NULL); -} - -static void -updatedone_action(isc_task_t *task, isc_event_t *event) { - update_event_t *uev = (update_event_t *) event; - ns_client_t *client = (ns_client_t *) event->ev_arg; - - UNUSED(task); - - INSIST(event->ev_type == DNS_EVENT_UPDATEDONE); - INSIST(task == client->task); - - INSIST(client->nupdates > 0); - client->nupdates--; - respond(client, uev->result); - isc_event_free(&event); - ns_client_detach(&client); -} - -/* - * Update forwarding support. - */ - -static void -forward_fail(isc_task_t *task, isc_event_t *event) { - ns_client_t *client = (ns_client_t *)event->ev_arg; - - UNUSED(task); - - INSIST(client->nupdates > 0); - client->nupdates--; - respond(client, DNS_R_SERVFAIL); - isc_event_free(&event); - ns_client_detach(&client); -} - - -static void -forward_callback(void *arg, isc_result_t result, dns_message_t *answer) { - update_event_t *uev = arg; - ns_client_t *client = uev->ev_arg; - - if (result != ISC_R_SUCCESS) { - INSIST(answer == NULL); - uev->ev_type = DNS_EVENT_UPDATEDONE; - uev->ev_action = forward_fail; - } else { - uev->ev_type = DNS_EVENT_UPDATEDONE; - uev->ev_action = forward_done; - uev->answer = answer; - } - isc_task_send(client->task, ISC_EVENT_PTR(&uev)); -} - -static void -forward_done(isc_task_t *task, isc_event_t *event) { - update_event_t *uev = (update_event_t *) event; - ns_client_t *client = (ns_client_t *)event->ev_arg; - - UNUSED(task); - - INSIST(client->nupdates > 0); - client->nupdates--; - ns_client_sendraw(client, uev->answer); - dns_message_destroy(&uev->answer); - isc_event_free(&event); - ns_client_detach(&client); -} - -static void -forward_action(isc_task_t *task, isc_event_t *event) { - update_event_t *uev = (update_event_t *) event; - dns_zone_t *zone = uev->zone; - ns_client_t *client = (ns_client_t *)event->ev_arg; - isc_result_t result; - - result = dns_zone_forwardupdate(zone, client->message, - forward_callback, event); - if (result != ISC_R_SUCCESS) { - uev->ev_type = DNS_EVENT_UPDATEDONE; - uev->ev_action = forward_fail; - isc_task_send(client->task, &event); - } - dns_zone_detach(&zone); - isc_task_detach(&task); -} - -static isc_result_t -send_forward_event(ns_client_t *client, dns_zone_t *zone) { - isc_result_t result = ISC_R_SUCCESS; - update_event_t *event = NULL; - isc_task_t *zonetask = NULL; - ns_client_t *evclient; - - event = (update_event_t *) - isc_event_allocate(client->mctx, client, DNS_EVENT_UPDATE, - forward_action, NULL, sizeof(*event)); - if (event == NULL) - FAIL(ISC_R_NOMEMORY); - event->zone = zone; - event->result = ISC_R_SUCCESS; - - evclient = NULL; - ns_client_attach(client, &evclient); - INSIST(client->nupdates == 0); - client->nupdates++; - event->ev_arg = evclient; - - dns_zone_gettask(zone, &zonetask); - isc_task_send(zonetask, ISC_EVENT_PTR(&event)); - - failure: - if (event != NULL) - isc_event_free(ISC_EVENT_PTR(&event)); - return (result); -} diff --git a/contrib/bind9/bin/named/xfrout.c b/contrib/bind9/bin/named/xfrout.c deleted file mode 100644 index 687c287f4bda..000000000000 --- a/contrib/bind9/bin/named/xfrout.c +++ /dev/null @@ -1,1718 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: xfrout.c,v 1.101.2.5.2.12 2005/10/14 02:13:05 marka Exp $ */ - -#include <config.h> - -#include <isc/formatcheck.h> -#include <isc/mem.h> -#include <isc/timer.h> -#include <isc/print.h> -#include <isc/util.h> - -#include <dns/db.h> -#include <dns/dbiterator.h> -#include <dns/fixedname.h> -#include <dns/journal.h> -#include <dns/message.h> -#include <dns/peer.h> -#include <dns/rdataclass.h> -#include <dns/rdatalist.h> -#include <dns/rdataset.h> -#include <dns/rdatasetiter.h> -#include <dns/result.h> -#include <dns/soa.h> -#include <dns/timer.h> -#include <dns/tsig.h> -#include <dns/view.h> -#include <dns/zone.h> -#include <dns/zt.h> - -#include <named/client.h> -#include <named/log.h> -#include <named/server.h> -#include <named/xfrout.h> - -/* - * Outgoing AXFR and IXFR. - */ - -/* - * TODO: - * - IXFR over UDP - */ - -#define XFROUT_COMMON_LOGARGS \ - ns_g_lctx, DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT - -#define XFROUT_PROTOCOL_LOGARGS \ - XFROUT_COMMON_LOGARGS, ISC_LOG_INFO - -#define XFROUT_DEBUG_LOGARGS(n) \ - XFROUT_COMMON_LOGARGS, ISC_LOG_DEBUG(n) - -#define XFROUT_RR_LOGARGS \ - XFROUT_COMMON_LOGARGS, XFROUT_RR_LOGLEVEL - -#define XFROUT_RR_LOGLEVEL ISC_LOG_DEBUG(8) - -/* - * Fail unconditionally and log as a client error. - * The test against ISC_R_SUCCESS is there to keep the Solaris compiler - * from complaining about "end-of-loop code not reached". - */ -#define FAILC(code, msg) \ - do { \ - result = (code); \ - ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \ - NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \ - "bad zone transfer request: %s (%s)", \ - msg, isc_result_totext(code)); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -#define FAILQ(code, msg, question, rdclass) \ - do { \ - char _buf1[DNS_NAME_FORMATSIZE]; \ - char _buf2[DNS_RDATACLASS_FORMATSIZE]; \ - result = (code); \ - dns_name_format(question, _buf1, sizeof(_buf1)); \ - dns_rdataclass_format(rdclass, _buf2, sizeof(_buf2)); \ - ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \ - NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \ - "bad zone transfer request: '%s/%s': %s (%s)", \ - _buf1, _buf2, msg, isc_result_totext(code)); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto failure; \ - } while (0) - -/**************************************************************************/ -/* - * A db_rr_iterator_t is an iterator that iterates over an entire database, - * returning one RR at a time, in some arbitrary order. - */ - -typedef struct db_rr_iterator db_rr_iterator_t; - -struct db_rr_iterator { - isc_result_t result; - dns_db_t *db; - dns_dbiterator_t *dbit; - dns_dbversion_t *ver; - isc_stdtime_t now; - dns_dbnode_t *node; - dns_fixedname_t fixedname; - dns_rdatasetiter_t *rdatasetit; - dns_rdataset_t rdataset; - dns_rdata_t rdata; -}; - -static isc_result_t -db_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db, dns_dbversion_t *ver, - isc_stdtime_t now); - -static isc_result_t -db_rr_iterator_first(db_rr_iterator_t *it); - -static isc_result_t -db_rr_iterator_next(db_rr_iterator_t *it); - -static void -db_rr_iterator_current(db_rr_iterator_t *it, dns_name_t **name, - isc_uint32_t *ttl, dns_rdata_t **rdata); - -static void -db_rr_iterator_destroy(db_rr_iterator_t *it); - -static isc_result_t -db_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db, dns_dbversion_t *ver, - isc_stdtime_t now) -{ - isc_result_t result; - it->db = db; - it->dbit = NULL; - it->ver = ver; - it->now = now; - it->node = NULL; - result = dns_db_createiterator(it->db, ISC_FALSE, &it->dbit); - if (result != ISC_R_SUCCESS) - return (result); - it->rdatasetit = NULL; - dns_rdata_init(&it->rdata); - dns_rdataset_init(&it->rdataset); - dns_fixedname_init(&it->fixedname); - INSIST(! dns_rdataset_isassociated(&it->rdataset)); - it->result = ISC_R_SUCCESS; - return (it->result); -} - -static isc_result_t -db_rr_iterator_first(db_rr_iterator_t *it) { - it->result = dns_dbiterator_first(it->dbit); - /* - * The top node may be empty when out of zone glue exists. - * Walk the tree to find the first node with data. - */ - while (it->result == ISC_R_SUCCESS) { - it->result = dns_dbiterator_current(it->dbit, &it->node, - dns_fixedname_name(&it->fixedname)); - if (it->result != ISC_R_SUCCESS) - return (it->result); - - it->result = dns_db_allrdatasets(it->db, it->node, - it->ver, it->now, - &it->rdatasetit); - if (it->result != ISC_R_SUCCESS) - return (it->result); - - it->result = dns_rdatasetiter_first(it->rdatasetit); - if (it->result != ISC_R_SUCCESS) { - /* - * This node is empty. Try next node. - */ - dns_rdatasetiter_destroy(&it->rdatasetit); - dns_db_detachnode(it->db, &it->node); - it->result = dns_dbiterator_next(it->dbit); - continue; - } - dns_rdatasetiter_current(it->rdatasetit, &it->rdataset); - - it->result = dns_rdataset_first(&it->rdataset); - return (it->result); - } - return (it->result); -} - - -static isc_result_t -db_rr_iterator_next(db_rr_iterator_t *it) { - if (it->result != ISC_R_SUCCESS) - return (it->result); - - INSIST(it->dbit != NULL); - INSIST(it->node != NULL); - INSIST(it->rdatasetit != NULL); - - it->result = dns_rdataset_next(&it->rdataset); - if (it->result == ISC_R_NOMORE) { - dns_rdataset_disassociate(&it->rdataset); - it->result = dns_rdatasetiter_next(it->rdatasetit); - /* - * The while loop body is executed more than once - * only when an empty dbnode needs to be skipped. - */ - while (it->result == ISC_R_NOMORE) { - dns_rdatasetiter_destroy(&it->rdatasetit); - dns_db_detachnode(it->db, &it->node); - it->result = dns_dbiterator_next(it->dbit); - if (it->result == ISC_R_NOMORE) { - /* We are at the end of the entire database. */ - return (it->result); - } - if (it->result != ISC_R_SUCCESS) - return (it->result); - it->result = dns_dbiterator_current(it->dbit, - &it->node, - dns_fixedname_name(&it->fixedname)); - if (it->result != ISC_R_SUCCESS) - return (it->result); - it->result = dns_db_allrdatasets(it->db, it->node, - it->ver, it->now, - &it->rdatasetit); - if (it->result != ISC_R_SUCCESS) - return (it->result); - it->result = dns_rdatasetiter_first(it->rdatasetit); - } - if (it->result != ISC_R_SUCCESS) - return (it->result); - dns_rdatasetiter_current(it->rdatasetit, &it->rdataset); - it->result = dns_rdataset_first(&it->rdataset); - if (it->result != ISC_R_SUCCESS) - return (it->result); - } - return (it->result); -} - -static void -db_rr_iterator_pause(db_rr_iterator_t *it) { - RUNTIME_CHECK(dns_dbiterator_pause(it->dbit) == ISC_R_SUCCESS); -} - -static void -db_rr_iterator_destroy(db_rr_iterator_t *it) { - if (dns_rdataset_isassociated(&it->rdataset)) - dns_rdataset_disassociate(&it->rdataset); - if (it->rdatasetit != NULL) - dns_rdatasetiter_destroy(&it->rdatasetit); - if (it->node != NULL) - dns_db_detachnode(it->db, &it->node); - dns_dbiterator_destroy(&it->dbit); -} - -static void -db_rr_iterator_current(db_rr_iterator_t *it, dns_name_t **name, - isc_uint32_t *ttl, dns_rdata_t **rdata) -{ - REQUIRE(name != NULL && *name == NULL); - REQUIRE(it->result == ISC_R_SUCCESS); - *name = dns_fixedname_name(&it->fixedname); - *ttl = it->rdataset.ttl; - dns_rdata_reset(&it->rdata); - dns_rdataset_current(&it->rdataset, &it->rdata); - *rdata = &it->rdata; -} - -/**************************************************************************/ - -/* Log an RR (for debugging) */ - -static void -log_rr(dns_name_t *name, dns_rdata_t *rdata, isc_uint32_t ttl) { - isc_result_t result; - isc_buffer_t buf; - char mem[2000]; - dns_rdatalist_t rdl; - dns_rdataset_t rds; - dns_rdata_t rd = DNS_RDATA_INIT; - - rdl.type = rdata->type; - rdl.rdclass = rdata->rdclass; - rdl.ttl = ttl; - ISC_LIST_INIT(rdl.rdata); - ISC_LINK_INIT(&rdl, link); - dns_rdataset_init(&rds); - dns_rdata_init(&rd); - dns_rdata_clone(rdata, &rd); - ISC_LIST_APPEND(rdl.rdata, &rd, link); - RUNTIME_CHECK(dns_rdatalist_tordataset(&rdl, &rds) == ISC_R_SUCCESS); - - isc_buffer_init(&buf, mem, sizeof(mem)); - result = dns_rdataset_totext(&rds, name, - ISC_FALSE, ISC_FALSE, &buf); - - /* - * We could use xfrout_log(), but that would produce - * very long lines with a repetitive prefix. - */ - if (result == ISC_R_SUCCESS) { - /* - * Get rid of final newline. - */ - INSIST(buf.used >= 1 && - ((char *) buf.base)[buf.used - 1] == '\n'); - buf.used--; - - isc_log_write(XFROUT_RR_LOGARGS, "%.*s", - (int)isc_buffer_usedlength(&buf), - (char *)isc_buffer_base(&buf)); - } else { - isc_log_write(XFROUT_RR_LOGARGS, "<RR too large to print>"); - } -} - -/**************************************************************************/ -/* - * An 'rrstream_t' is a polymorphic iterator that returns - * a stream of resource records. There are multiple implementations, - * e.g. for generating AXFR and IXFR records streams. - */ - -typedef struct rrstream_methods rrstream_methods_t; - -typedef struct rrstream { - isc_mem_t *mctx; - rrstream_methods_t *methods; -} rrstream_t; - -struct rrstream_methods { - isc_result_t (*first)(rrstream_t *); - isc_result_t (*next)(rrstream_t *); - void (*current)(rrstream_t *, - dns_name_t **, - isc_uint32_t *, - dns_rdata_t **); - void (*pause)(rrstream_t *); - void (*destroy)(rrstream_t **); -}; - -static void -rrstream_noop_pause(rrstream_t *rs) { - UNUSED(rs); -} - -/**************************************************************************/ -/* - * An 'ixfr_rrstream_t' is an 'rrstream_t' that returns - * an IXFR-like RR stream from a journal file. - * - * The SOA at the beginning of each sequence of additions - * or deletions are included in the stream, but the extra - * SOAs at the beginning and end of the entire transfer are - * not included. - */ - -typedef struct ixfr_rrstream { - rrstream_t common; - dns_journal_t *journal; -} ixfr_rrstream_t; - -/* Forward declarations. */ -static void -ixfr_rrstream_destroy(rrstream_t **sp); - -static rrstream_methods_t ixfr_rrstream_methods; - -/* - * Returns: anything dns_journal_open() or dns_journal_iter_init() - * may return. - */ - -static isc_result_t -ixfr_rrstream_create(isc_mem_t *mctx, - const char *journal_filename, - isc_uint32_t begin_serial, - isc_uint32_t end_serial, - rrstream_t **sp) -{ - ixfr_rrstream_t *s; - isc_result_t result; - - INSIST(sp != NULL && *sp == NULL); - - s = isc_mem_get(mctx, sizeof(*s)); - if (s == NULL) - return (ISC_R_NOMEMORY); - s->common.mctx = mctx; - s->common.methods = &ixfr_rrstream_methods; - s->journal = NULL; - - CHECK(dns_journal_open(mctx, journal_filename, - ISC_FALSE, &s->journal)); - CHECK(dns_journal_iter_init(s->journal, begin_serial, end_serial)); - - *sp = (rrstream_t *) s; - return (ISC_R_SUCCESS); - - failure: - ixfr_rrstream_destroy((rrstream_t **) (void *)&s); - return (result); -} - -static isc_result_t -ixfr_rrstream_first(rrstream_t *rs) { - ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; - return (dns_journal_first_rr(s->journal)); -} - -static isc_result_t -ixfr_rrstream_next(rrstream_t *rs) { - ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; - return (dns_journal_next_rr(s->journal)); -} - -static void -ixfr_rrstream_current(rrstream_t *rs, - dns_name_t **name, isc_uint32_t *ttl, - dns_rdata_t **rdata) -{ - ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs; - dns_journal_current_rr(s->journal, name, ttl, rdata); -} - -static void -ixfr_rrstream_destroy(rrstream_t **rsp) { - ixfr_rrstream_t *s = (ixfr_rrstream_t *) *rsp; - if (s->journal != 0) - dns_journal_destroy(&s->journal); - isc_mem_put(s->common.mctx, s, sizeof(*s)); -} - -static rrstream_methods_t ixfr_rrstream_methods = { - ixfr_rrstream_first, - ixfr_rrstream_next, - ixfr_rrstream_current, - rrstream_noop_pause, - ixfr_rrstream_destroy -}; - -/**************************************************************************/ -/* - * An 'axfr_rrstream_t' is an 'rrstream_t' that returns - * an AXFR-like RR stream from a database. - * - * The SOAs at the beginning and end of the transfer are - * not included in the stream. - */ - -typedef struct axfr_rrstream { - rrstream_t common; - db_rr_iterator_t it; - isc_boolean_t it_valid; -} axfr_rrstream_t; - -/* - * Forward declarations. - */ -static void -axfr_rrstream_destroy(rrstream_t **rsp); - -static rrstream_methods_t axfr_rrstream_methods; - -static isc_result_t -axfr_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver, - rrstream_t **sp) -{ - axfr_rrstream_t *s; - isc_result_t result; - - INSIST(sp != NULL && *sp == NULL); - - s = isc_mem_get(mctx, sizeof(*s)); - if (s == NULL) - return (ISC_R_NOMEMORY); - s->common.mctx = mctx; - s->common.methods = &axfr_rrstream_methods; - s->it_valid = ISC_FALSE; - - CHECK(db_rr_iterator_init(&s->it, db, ver, 0)); - s->it_valid = ISC_TRUE; - - *sp = (rrstream_t *) s; - return (ISC_R_SUCCESS); - - failure: - axfr_rrstream_destroy((rrstream_t **) (void *)&s); - return (result); -} - -static isc_result_t -axfr_rrstream_first(rrstream_t *rs) { - axfr_rrstream_t *s = (axfr_rrstream_t *) rs; - isc_result_t result; - result = db_rr_iterator_first(&s->it); - if (result != ISC_R_SUCCESS) - return (result); - /* Skip SOA records. */ - for (;;) { - dns_name_t *name_dummy = NULL; - isc_uint32_t ttl_dummy; - dns_rdata_t *rdata = NULL; - db_rr_iterator_current(&s->it, &name_dummy, - &ttl_dummy, &rdata); - if (rdata->type != dns_rdatatype_soa) - break; - result = db_rr_iterator_next(&s->it); - if (result != ISC_R_SUCCESS) - break; - } - return (result); -} - -static isc_result_t -axfr_rrstream_next(rrstream_t *rs) { - axfr_rrstream_t *s = (axfr_rrstream_t *) rs; - isc_result_t result; - - /* Skip SOA records. */ - for (;;) { - dns_name_t *name_dummy = NULL; - isc_uint32_t ttl_dummy; - dns_rdata_t *rdata = NULL; - result = db_rr_iterator_next(&s->it); - if (result != ISC_R_SUCCESS) - break; - db_rr_iterator_current(&s->it, &name_dummy, - &ttl_dummy, &rdata); - if (rdata->type != dns_rdatatype_soa) - break; - } - return (result); -} - -static void -axfr_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl, - dns_rdata_t **rdata) -{ - axfr_rrstream_t *s = (axfr_rrstream_t *) rs; - db_rr_iterator_current(&s->it, name, ttl, rdata); -} - -static void -axfr_rrstream_pause(rrstream_t *rs) { - axfr_rrstream_t *s = (axfr_rrstream_t *) rs; - db_rr_iterator_pause(&s->it); -} - -static void -axfr_rrstream_destroy(rrstream_t **rsp) { - axfr_rrstream_t *s = (axfr_rrstream_t *) *rsp; - if (s->it_valid) - db_rr_iterator_destroy(&s->it); - isc_mem_put(s->common.mctx, s, sizeof(*s)); -} - -static rrstream_methods_t axfr_rrstream_methods = { - axfr_rrstream_first, - axfr_rrstream_next, - axfr_rrstream_current, - axfr_rrstream_pause, - axfr_rrstream_destroy -}; - -/**************************************************************************/ -/* - * An 'soa_rrstream_t' is a degenerate 'rrstream_t' that returns - * a single SOA record. - */ - -typedef struct soa_rrstream { - rrstream_t common; - dns_difftuple_t *soa_tuple; -} soa_rrstream_t; - -/* - * Forward declarations. - */ -static void -soa_rrstream_destroy(rrstream_t **rsp); - -static rrstream_methods_t soa_rrstream_methods; - -static isc_result_t -soa_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver, - rrstream_t **sp) -{ - soa_rrstream_t *s; - isc_result_t result; - - INSIST(sp != NULL && *sp == NULL); - - s = isc_mem_get(mctx, sizeof(*s)); - if (s == NULL) - return (ISC_R_NOMEMORY); - s->common.mctx = mctx; - s->common.methods = &soa_rrstream_methods; - s->soa_tuple = NULL; - - CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS, - &s->soa_tuple)); - - *sp = (rrstream_t *) s; - return (ISC_R_SUCCESS); - - failure: - soa_rrstream_destroy((rrstream_t **) (void *)&s); - return (result); -} - -static isc_result_t -soa_rrstream_first(rrstream_t *rs) { - UNUSED(rs); - return (ISC_R_SUCCESS); -} - -static isc_result_t -soa_rrstream_next(rrstream_t *rs) { - UNUSED(rs); - return (ISC_R_NOMORE); -} - -static void -soa_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl, - dns_rdata_t **rdata) -{ - soa_rrstream_t *s = (soa_rrstream_t *) rs; - *name = &s->soa_tuple->name; - *ttl = s->soa_tuple->ttl; - *rdata = &s->soa_tuple->rdata; -} - -static void -soa_rrstream_destroy(rrstream_t **rsp) { - soa_rrstream_t *s = (soa_rrstream_t *) *rsp; - if (s->soa_tuple != NULL) - dns_difftuple_free(&s->soa_tuple); - isc_mem_put(s->common.mctx, s, sizeof(*s)); -} - -static rrstream_methods_t soa_rrstream_methods = { - soa_rrstream_first, - soa_rrstream_next, - soa_rrstream_current, - rrstream_noop_pause, - soa_rrstream_destroy -}; - -/**************************************************************************/ -/* - * A 'compound_rrstream_t' objects owns a soa_rrstream - * and another rrstream, the "data stream". It returns - * a concatenated stream consisting of the soa_rrstream, then - * the data stream, then the soa_rrstream again. - * - * The component streams are owned by the compound_rrstream_t - * and are destroyed with it. - */ - -typedef struct compound_rrstream { - rrstream_t common; - rrstream_t *components[3]; - int state; - isc_result_t result; -} compound_rrstream_t; - -/* - * Forward declarations. - */ -static void -compound_rrstream_destroy(rrstream_t **rsp); - -static isc_result_t -compound_rrstream_next(rrstream_t *rs); - -static rrstream_methods_t compound_rrstream_methods; - -/* - * Requires: - * soa_stream != NULL && *soa_stream != NULL - * data_stream != NULL && *data_stream != NULL - * sp != NULL && *sp == NULL - * - * Ensures: - * *soa_stream == NULL - * *data_stream == NULL - * *sp points to a valid compound_rrstream_t - * The soa and data streams will be destroyed - * when the compound_rrstream_t is destroyed. - */ -static isc_result_t -compound_rrstream_create(isc_mem_t *mctx, rrstream_t **soa_stream, - rrstream_t **data_stream, rrstream_t **sp) -{ - compound_rrstream_t *s; - - INSIST(sp != NULL && *sp == NULL); - - s = isc_mem_get(mctx, sizeof(*s)); - if (s == NULL) - return (ISC_R_NOMEMORY); - s->common.mctx = mctx; - s->common.methods = &compound_rrstream_methods; - s->components[0] = *soa_stream; - s->components[1] = *data_stream; - s->components[2] = *soa_stream; - s->state = -1; - s->result = ISC_R_FAILURE; - - *soa_stream = NULL; - *data_stream = NULL; - *sp = (rrstream_t *) s; - return (ISC_R_SUCCESS); -} - -static isc_result_t -compound_rrstream_first(rrstream_t *rs) { - compound_rrstream_t *s = (compound_rrstream_t *) rs; - s->state = 0; - do { - rrstream_t *curstream = s->components[s->state]; - s->result = curstream->methods->first(curstream); - } while (s->result == ISC_R_NOMORE && s->state < 2); - return (s->result); -} - -static isc_result_t -compound_rrstream_next(rrstream_t *rs) { - compound_rrstream_t *s = (compound_rrstream_t *) rs; - rrstream_t *curstream = s->components[s->state]; - s->result = curstream->methods->next(curstream); - while (s->result == ISC_R_NOMORE) { - /* - * Make sure locks held by the current stream - * are released before we switch streams. - */ - curstream->methods->pause(curstream); - if (s->state == 2) - return (ISC_R_NOMORE); - s->state++; - curstream = s->components[s->state]; - s->result = curstream->methods->first(curstream); - } - return (s->result); -} - -static void -compound_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl, - dns_rdata_t **rdata) -{ - compound_rrstream_t *s = (compound_rrstream_t *) rs; - rrstream_t *curstream; - INSIST(0 <= s->state && s->state < 3); - INSIST(s->result == ISC_R_SUCCESS); - curstream = s->components[s->state]; - curstream->methods->current(curstream, name, ttl, rdata); -} - -static void -compound_rrstream_pause(rrstream_t *rs) -{ - compound_rrstream_t *s = (compound_rrstream_t *) rs; - rrstream_t *curstream; - INSIST(0 <= s->state && s->state < 3); - curstream = s->components[s->state]; - curstream->methods->pause(curstream); -} - -static void -compound_rrstream_destroy(rrstream_t **rsp) { - compound_rrstream_t *s = (compound_rrstream_t *) *rsp; - s->components[0]->methods->destroy(&s->components[0]); - s->components[1]->methods->destroy(&s->components[1]); - s->components[2] = NULL; /* Copy of components[0]. */ - isc_mem_put(s->common.mctx, s, sizeof(*s)); -} - -static rrstream_methods_t compound_rrstream_methods = { - compound_rrstream_first, - compound_rrstream_next, - compound_rrstream_current, - compound_rrstream_pause, - compound_rrstream_destroy -}; - -/**************************************************************************/ -/* - * An 'xfrout_ctx_t' contains the state of an outgoing AXFR or IXFR - * in progress. - */ - -typedef struct { - isc_mem_t *mctx; - ns_client_t *client; - unsigned int id; /* ID of request */ - dns_name_t *qname; /* Question name of request */ - dns_rdatatype_t qtype; /* dns_rdatatype_{a,i}xfr */ - dns_rdataclass_t qclass; - dns_db_t *db; - dns_dbversion_t *ver; - isc_quota_t *quota; - rrstream_t *stream; /* The XFR RR stream */ - isc_boolean_t end_of_stream; /* EOS has been reached */ - isc_buffer_t buf; /* Buffer for message owner - names and rdatas */ - isc_buffer_t txlenbuf; /* Transmit length buffer */ - isc_buffer_t txbuf; /* Transmit message buffer */ - void *txmem; - unsigned int txmemlen; - unsigned int nmsg; /* Number of messages sent */ - dns_tsigkey_t *tsigkey; /* Key used to create TSIG */ - isc_buffer_t *lasttsig; /* the last TSIG */ - isc_boolean_t many_answers; - int sends; /* Send in progress */ - isc_boolean_t shuttingdown; - const char *mnemonic; /* Style of transfer */ -} xfrout_ctx_t; - -static isc_result_t -xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, - unsigned int id, dns_name_t *qname, dns_rdatatype_t qtype, - dns_rdataclass_t qclass, - dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota, - rrstream_t *stream, dns_tsigkey_t *tsigkey, - isc_buffer_t *lasttsig, - unsigned int maxtime, - unsigned int idletime, - isc_boolean_t many_answers, - xfrout_ctx_t **xfrp); - -static void -sendstream(xfrout_ctx_t *xfr); - -static void -xfrout_senddone(isc_task_t *task, isc_event_t *event); - -static void -xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg); - -static void -xfrout_maybe_destroy(xfrout_ctx_t *xfr); - -static void -xfrout_ctx_destroy(xfrout_ctx_t **xfrp); - -static void -xfrout_client_shutdown(void *arg, isc_result_t result); - -static void -xfrout_log1(ns_client_t *client, dns_name_t *zonename, - dns_rdataclass_t rdclass, int level, - const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6); - -static void -xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...) - ISC_FORMAT_PRINTF(3, 4); - -/**************************************************************************/ - -void -ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) { - isc_result_t result; - dns_name_t *question_name; - dns_rdataset_t *question_rdataset; - dns_zone_t *zone = NULL; - dns_db_t *db = NULL; - dns_dbversion_t *ver = NULL; - dns_rdataclass_t question_class; - rrstream_t *soa_stream = NULL; - rrstream_t *data_stream = NULL; - rrstream_t *stream = NULL; - dns_difftuple_t *current_soa_tuple = NULL; - dns_name_t *soa_name; - dns_rdataset_t *soa_rdataset; - dns_rdata_t soa_rdata = DNS_RDATA_INIT; - isc_boolean_t have_soa = ISC_FALSE; - const char *mnemonic = NULL; - isc_mem_t *mctx = client->mctx; - dns_message_t *request = client->message; - xfrout_ctx_t *xfr = NULL; - isc_quota_t *quota = NULL; - dns_transfer_format_t format = client->view->transfer_format; - isc_netaddr_t na; - dns_peer_t *peer = NULL; - isc_buffer_t *tsigbuf = NULL; - char *journalfile; - char msg[NS_CLIENT_ACLMSGSIZE("zone transfer")]; - char keyname[DNS_NAME_FORMATSIZE]; - isc_boolean_t is_poll = ISC_FALSE; - - switch (reqtype) { - case dns_rdatatype_axfr: - mnemonic = "AXFR"; - break; - case dns_rdatatype_ixfr: - mnemonic = "IXFR"; - break; - default: - INSIST(0); - break; - } - - ns_client_log(client, - DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT, - ISC_LOG_DEBUG(6), "%s request", mnemonic); - /* - * Apply quota. - */ - result = isc_quota_attach(&ns_g_server->xfroutquota, "a); - if (result != ISC_R_SUCCESS) { - isc_log_write(XFROUT_COMMON_LOGARGS, ISC_LOG_WARNING, - "%s request denied: %s", mnemonic, - isc_result_totext(result)); - goto failure; - } - - /* - * Interpret the question section. - */ - result = dns_message_firstname(request, DNS_SECTION_QUESTION); - INSIST(result == ISC_R_SUCCESS); - - /* - * The question section must contain exactly one question, and - * it must be for AXFR/IXFR as appropriate. - */ - question_name = NULL; - dns_message_currentname(request, DNS_SECTION_QUESTION, &question_name); - question_rdataset = ISC_LIST_HEAD(question_name->list); - question_class = question_rdataset->rdclass; - INSIST(question_rdataset->type == reqtype); - if (ISC_LIST_NEXT(question_rdataset, link) != NULL) - FAILC(DNS_R_FORMERR, "multiple questions"); - result = dns_message_nextname(request, DNS_SECTION_QUESTION); - if (result != ISC_R_NOMORE) - FAILC(DNS_R_FORMERR, "multiple questions"); - - result = dns_zt_find(client->view->zonetable, question_name, 0, NULL, - &zone); - if (result != ISC_R_SUCCESS) - FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", - question_name, question_class); - switch(dns_zone_gettype(zone)) { - case dns_zone_master: - case dns_zone_slave: - break; /* Master and slave zones are OK for transfer. */ - default: - FAILQ(DNS_R_NOTAUTH, "non-authoritative zone", - question_name, question_class); - } - CHECK(dns_zone_getdb(zone, &db)); - dns_db_currentversion(db, &ver); - - xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6), - "%s question section OK", mnemonic); - - /* - * Check the authority section. Look for a SOA record with - * the same name and class as the question. - */ - for (result = dns_message_firstname(request, DNS_SECTION_AUTHORITY); - result == ISC_R_SUCCESS; - result = dns_message_nextname(request, DNS_SECTION_AUTHORITY)) - { - soa_name = NULL; - dns_message_currentname(request, DNS_SECTION_AUTHORITY, - &soa_name); - - /* - * Ignore data whose owner name is not the zone apex. - */ - if (! dns_name_equal(soa_name, question_name)) - continue; - - for (soa_rdataset = ISC_LIST_HEAD(soa_name->list); - soa_rdataset != NULL; - soa_rdataset = ISC_LIST_NEXT(soa_rdataset, link)) - { - /* - * Ignore non-SOA data. - */ - if (soa_rdataset->type != dns_rdatatype_soa) - continue; - if (soa_rdataset->rdclass != question_class) - continue; - - CHECK(dns_rdataset_first(soa_rdataset)); - dns_rdataset_current(soa_rdataset, &soa_rdata); - result = dns_rdataset_next(soa_rdataset); - if (result == ISC_R_SUCCESS) - FAILC(DNS_R_FORMERR, - "IXFR authority section " - "has multiple SOAs"); - have_soa = ISC_TRUE; - goto got_soa; - } - } - got_soa: - if (result != ISC_R_NOMORE) - CHECK(result); - - xfrout_log1(client, question_name, question_class, ISC_LOG_DEBUG(6), - "%s authority section OK", mnemonic); - - /* - * Decide whether to allow this transfer. - */ - ns_client_aclmsg("zone transfer", question_name, reqtype, - client->view->rdclass, msg, sizeof(msg)); - CHECK(ns_client_checkacl(client, msg, - dns_zone_getxfracl(zone), ISC_TRUE, - ISC_LOG_ERROR)); - - /* - * AXFR over UDP is not possible. - */ - if (reqtype == dns_rdatatype_axfr && - (client->attributes & NS_CLIENTATTR_TCP) == 0) - FAILC(DNS_R_FORMERR, "attempted AXFR over UDP"); - - /* - * Look up the requesting server in the peer table. - */ - isc_netaddr_fromsockaddr(&na, &client->peeraddr); - (void)dns_peerlist_peerbyaddr(client->view->peers, &na, &peer); - - /* - * Decide on the transfer format (one-answer or many-answers). - */ - if (peer != NULL) - (void)dns_peer_gettransferformat(peer, &format); - - /* - * Get a dynamically allocated copy of the current SOA. - */ - CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS, - ¤t_soa_tuple)); - - if (reqtype == dns_rdatatype_ixfr) { - isc_uint32_t begin_serial, current_serial; - isc_boolean_t provide_ixfr; - - /* - * Outgoing IXFR may have been disabled for this peer - * or globally. - */ - provide_ixfr = client->view->provideixfr; - if (peer != NULL) - (void) dns_peer_getprovideixfr(peer, &provide_ixfr); - if (provide_ixfr == ISC_FALSE) - goto axfr_fallback; - - if (! have_soa) - FAILC(DNS_R_FORMERR, - "IXFR request missing SOA"); - - begin_serial = dns_soa_getserial(&soa_rdata); - current_serial = dns_soa_getserial(¤t_soa_tuple->rdata); - - /* - * RFC1995 says "If an IXFR query with the same or - * newer version number than that of the server - * is received, it is replied to with a single SOA - * record of the server's current version, just as - * in AXFR". The claim about AXFR is incorrect, - * but other than that, we do as the RFC says. - * - * Sending a single SOA record is also how we refuse - * IXFR over UDP (currently, we always do). - */ - if (DNS_SERIAL_GE(begin_serial, current_serial) || - (client->attributes & NS_CLIENTATTR_TCP) == 0) - { - CHECK(soa_rrstream_create(mctx, db, ver, &stream)); - is_poll = ISC_TRUE; - goto have_stream; - } - journalfile = dns_zone_getjournal(zone); - if (journalfile != NULL) - result = ixfr_rrstream_create(mctx, - journalfile, - begin_serial, - current_serial, - &data_stream); - else - result = ISC_R_NOTFOUND; - if (result == ISC_R_NOTFOUND || - result == ISC_R_RANGE) { - xfrout_log1(client, question_name, question_class, - ISC_LOG_DEBUG(4), - "IXFR version not in journal, " - "falling back to AXFR"); - mnemonic = "AXFR-style IXFR"; - goto axfr_fallback; - } - CHECK(result); - } else { - axfr_fallback: - CHECK(axfr_rrstream_create(mctx, db, ver, - &data_stream)); - } - - /* - * Bracket the the data stream with SOAs. - */ - CHECK(soa_rrstream_create(mctx, db, ver, &soa_stream)); - CHECK(compound_rrstream_create(mctx, &soa_stream, &data_stream, - &stream)); - soa_stream = NULL; - data_stream = NULL; - - have_stream: - CHECK(dns_message_getquerytsig(request, mctx, &tsigbuf)); - /* - * Create the xfrout context object. This transfers the ownership - * of "stream", "db", "ver", and "quota" to the xfrout context object. - */ - CHECK(xfrout_ctx_create(mctx, client, request->id, question_name, - reqtype, question_class, db, ver, quota, - stream, dns_message_gettsigkey(request), - tsigbuf, - dns_zone_getmaxxfrout(zone), - dns_zone_getidleout(zone), - (format == dns_many_answers) ? - ISC_TRUE : ISC_FALSE, - &xfr)); - xfr->mnemonic = mnemonic; - stream = NULL; - quota = NULL; - - CHECK(xfr->stream->methods->first(xfr->stream)); - - if (xfr->tsigkey != NULL) { - dns_name_format(&xfr->tsigkey->name, keyname, sizeof(keyname)); - } else - keyname[0] = '\0'; - if (is_poll) - xfrout_log1(client, question_name, question_class, - ISC_LOG_DEBUG(1), "IXFR poll up to date%s%s", - (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname); - else - xfrout_log1(client, question_name, question_class, - ISC_LOG_INFO, "%s started%s%s", mnemonic, - (xfr->tsigkey != NULL) ? ": TSIG " : "", keyname); - - /* - * Hand the context over to sendstream(). Set xfr to NULL; - * sendstream() is responsible for either passing the - * context on to a later event handler or destroying it. - */ - sendstream(xfr); - xfr = NULL; - - result = ISC_R_SUCCESS; - - failure: - if (quota != NULL) - isc_quota_detach("a); - if (current_soa_tuple != NULL) - dns_difftuple_free(¤t_soa_tuple); - if (stream != NULL) - stream->methods->destroy(&stream); - if (soa_stream != NULL) - soa_stream->methods->destroy(&soa_stream); - if (data_stream != NULL) - data_stream->methods->destroy(&data_stream); - if (ver != NULL) - dns_db_closeversion(db, &ver, ISC_FALSE); - if (db != NULL) - dns_db_detach(&db); - if (zone != NULL) - dns_zone_detach(&zone); - /* XXX kludge */ - if (xfr != NULL) { - xfrout_fail(xfr, result, "setting up zone transfer"); - } else if (result != ISC_R_SUCCESS) { - ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, - NS_LOGMODULE_XFER_OUT, - ISC_LOG_DEBUG(3), "zone transfer setup failed"); - ns_client_error(client, result); - } -} - -static isc_result_t -xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id, - dns_name_t *qname, dns_rdatatype_t qtype, - dns_rdataclass_t qclass, - dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota, - rrstream_t *stream, dns_tsigkey_t *tsigkey, - isc_buffer_t *lasttsig, unsigned int maxtime, - unsigned int idletime, isc_boolean_t many_answers, - xfrout_ctx_t **xfrp) -{ - xfrout_ctx_t *xfr; - isc_result_t result; - unsigned int len; - void *mem; - - INSIST(xfrp != NULL && *xfrp == NULL); - xfr = isc_mem_get(mctx, sizeof(*xfr)); - if (xfr == NULL) - return (ISC_R_NOMEMORY); - xfr->mctx = mctx; - xfr->client = NULL; - ns_client_attach(client, &xfr->client); - xfr->id = id; - xfr->qname = qname; - xfr->qtype = qtype; - xfr->qclass = qclass; - xfr->db = NULL; - xfr->ver = NULL; - dns_db_attach(db, &xfr->db); - dns_db_attachversion(db, ver, &xfr->ver); - xfr->end_of_stream = ISC_FALSE; - xfr->tsigkey = tsigkey; - xfr->lasttsig = lasttsig; - xfr->txmem = NULL; - xfr->txmemlen = 0; - xfr->nmsg = 0; - xfr->many_answers = many_answers, - xfr->sends = 0; - xfr->shuttingdown = ISC_FALSE; - xfr->mnemonic = NULL; - xfr->buf.base = NULL; - xfr->buf.length = 0; - xfr->txmem = NULL; - xfr->txmemlen = 0; - xfr->stream = NULL; - xfr->quota = NULL; - - /* - * Allocate a temporary buffer for the uncompressed response - * message data. The size should be no more than 65535 bytes - * so that the compressed data will fit in a TCP message, - * and no less than 65535 bytes so that an almost maximum-sized - * RR will fit. Note that although 65535-byte RRs are allowed - * in principle, they cannot be zone-transferred (at least not - * if uncompressible), because the message and RR headers would - * push the size of the TCP message over the 65536 byte limit. - */ - len = 65535; - mem = isc_mem_get(mctx, len); - if (mem == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - isc_buffer_init(&xfr->buf, mem, len); - - /* - * Allocate another temporary buffer for the compressed - * response message and its TCP length prefix. - */ - len = 2 + 65535; - mem = isc_mem_get(mctx, len); - if (mem == NULL) { - result = ISC_R_NOMEMORY; - goto failure; - } - isc_buffer_init(&xfr->txlenbuf, mem, 2); - isc_buffer_init(&xfr->txbuf, (char *) mem + 2, len - 2); - xfr->txmem = mem; - xfr->txmemlen = len; - - CHECK(dns_timer_setidle(xfr->client->timer, - maxtime, idletime, ISC_FALSE)); - - /* - * Register a shutdown callback with the client, so that we - * can stop the transfer immediately when the client task - * gets a shutdown event. - */ - xfr->client->shutdown = xfrout_client_shutdown; - xfr->client->shutdown_arg = xfr; - /* - * These MUST be after the last "goto failure;" / CHECK to - * prevent a double free by the caller. - */ - xfr->quota = quota; - xfr->stream = stream; - - *xfrp = xfr; - return (ISC_R_SUCCESS); - -failure: - xfrout_ctx_destroy(&xfr); - return (result); -} - - -/* - * Arrange to send as much as we can of "stream" without blocking. - * - * Requires: - * The stream iterator is initialized and points at an RR, - * or possiby at the end of the stream (that is, the - * _first method of the iterator has been called). - */ -static void -sendstream(xfrout_ctx_t *xfr) { - dns_message_t *tcpmsg = NULL; - dns_message_t *msg = NULL; /* Client message if UDP, tcpmsg if TCP */ - isc_result_t result; - isc_region_t used; - isc_region_t region; - dns_rdataset_t *qrdataset; - dns_name_t *msgname = NULL; - dns_rdata_t *msgrdata = NULL; - dns_rdatalist_t *msgrdl = NULL; - dns_rdataset_t *msgrds = NULL; - dns_compress_t cctx; - isc_boolean_t cleanup_cctx = ISC_FALSE; - - int n_rrs; - - isc_buffer_clear(&xfr->buf); - isc_buffer_clear(&xfr->txlenbuf); - isc_buffer_clear(&xfr->txbuf); - - if ((xfr->client->attributes & NS_CLIENTATTR_TCP) == 0) { - /* - * In the UDP case, we put the response data directly into - * the client message. - */ - msg = xfr->client->message; - CHECK(dns_message_reply(msg, ISC_TRUE)); - } else { - /* - * TCP. Build a response dns_message_t, temporarily storing - * the raw, uncompressed owner names and RR data contiguously - * in xfr->buf. We know that if the uncompressed data fits - * in xfr->buf, the compressed data will surely fit in a TCP - * message. - */ - - CHECK(dns_message_create(xfr->mctx, - DNS_MESSAGE_INTENTRENDER, &tcpmsg)); - msg = tcpmsg; - - msg->id = xfr->id; - msg->rcode = dns_rcode_noerror; - msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA; - if ((xfr->client->attributes & NS_CLIENTATTR_RA) != 0) - msg->flags |= DNS_MESSAGEFLAG_RA; - CHECK(dns_message_settsigkey(msg, xfr->tsigkey)); - CHECK(dns_message_setquerytsig(msg, xfr->lasttsig)); - if (xfr->lasttsig != NULL) - isc_buffer_free(&xfr->lasttsig); - - /* - * Include a question section in the first message only. - * BIND 8.2.1 will not recognize an IXFR if it does not - * have a question section. - */ - if (xfr->nmsg == 0) { - dns_name_t *qname = NULL; - isc_region_t r; - - /* - * Reserve space for the 12-byte message header - * and 4 bytes of question. - */ - isc_buffer_add(&xfr->buf, 12 + 4); - - qrdataset = NULL; - result = dns_message_gettemprdataset(msg, &qrdataset); - if (result != ISC_R_SUCCESS) - goto failure; - dns_rdataset_init(qrdataset); - dns_rdataset_makequestion(qrdataset, - xfr->client->message->rdclass, - xfr->qtype); - - result = dns_message_gettempname(msg, &qname); - if (result != ISC_R_SUCCESS) - goto failure; - dns_name_init(qname, NULL); - isc_buffer_availableregion(&xfr->buf, &r); - INSIST(r.length >= xfr->qname->length); - r.length = xfr->qname->length; - isc_buffer_putmem(&xfr->buf, xfr->qname->ndata, - xfr->qname->length); - dns_name_fromregion(qname, &r); - ISC_LIST_INIT(qname->list); - ISC_LIST_APPEND(qname->list, qrdataset, link); - - dns_message_addname(msg, qname, DNS_SECTION_QUESTION); - } - else - msg->tcp_continuation = 1; - } - - /* - * Try to fit in as many RRs as possible, unless "one-answer" - * format has been requested. - */ - for (n_rrs = 0; ; n_rrs++) { - dns_name_t *name = NULL; - isc_uint32_t ttl; - dns_rdata_t *rdata = NULL; - - unsigned int size; - isc_region_t r; - - msgname = NULL; - msgrdata = NULL; - msgrdl = NULL; - msgrds = NULL; - - xfr->stream->methods->current(xfr->stream, - &name, &ttl, &rdata); - size = name->length + 10 + rdata->length; - isc_buffer_availableregion(&xfr->buf, &r); - if (size >= r.length) { - /* - * RR would not fit. If there are other RRs in the - * buffer, send them now and leave this RR to the - * next message. If this RR overflows the buffer - * all by itself, fail. - * - * In theory some RRs might fit in a TCP message - * when compressed even if they do not fit when - * uncompressed, but surely we don't want - * to send such monstrosities to an unsuspecting - * slave. - */ - if (n_rrs == 0) { - xfrout_log(xfr, ISC_LOG_WARNING, - "RR too large for zone transfer " - "(%d bytes)", size); - /* XXX DNS_R_RRTOOLARGE? */ - result = ISC_R_NOSPACE; - goto failure; - } - break; - } - - if (isc_log_wouldlog(ns_g_lctx, XFROUT_RR_LOGLEVEL)) - log_rr(name, rdata, ttl); /* XXX */ - - result = dns_message_gettempname(msg, &msgname); - if (result != ISC_R_SUCCESS) - goto failure; - dns_name_init(msgname, NULL); - isc_buffer_availableregion(&xfr->buf, &r); - INSIST(r.length >= name->length); - r.length = name->length; - isc_buffer_putmem(&xfr->buf, name->ndata, name->length); - dns_name_fromregion(msgname, &r); - - /* Reserve space for RR header. */ - isc_buffer_add(&xfr->buf, 10); - - result = dns_message_gettemprdata(msg, &msgrdata); - if (result != ISC_R_SUCCESS) - goto failure; - isc_buffer_availableregion(&xfr->buf, &r); - r.length = rdata->length; - isc_buffer_putmem(&xfr->buf, rdata->data, rdata->length); - dns_rdata_init(msgrdata); - dns_rdata_fromregion(msgrdata, - rdata->rdclass, rdata->type, &r); - - result = dns_message_gettemprdatalist(msg, &msgrdl); - if (result != ISC_R_SUCCESS) - goto failure; - msgrdl->type = rdata->type; - msgrdl->rdclass = rdata->rdclass; - msgrdl->ttl = ttl; - ISC_LINK_INIT(msgrdl, link); - ISC_LIST_INIT(msgrdl->rdata); - ISC_LIST_APPEND(msgrdl->rdata, msgrdata, link); - - result = dns_message_gettemprdataset(msg, &msgrds); - if (result != ISC_R_SUCCESS) - goto failure; - dns_rdataset_init(msgrds); - result = dns_rdatalist_tordataset(msgrdl, msgrds); - INSIST(result == ISC_R_SUCCESS); - - ISC_LIST_APPEND(msgname->list, msgrds, link); - - dns_message_addname(msg, msgname, DNS_SECTION_ANSWER); - msgname = NULL; - - result = xfr->stream->methods->next(xfr->stream); - if (result == ISC_R_NOMORE) { - xfr->end_of_stream = ISC_TRUE; - break; - } - CHECK(result); - - if (! xfr->many_answers) - break; - } - - if ((xfr->client->attributes & NS_CLIENTATTR_TCP) != 0) { - CHECK(dns_compress_init(&cctx, -1, xfr->mctx)); - cleanup_cctx = ISC_TRUE; - CHECK(dns_message_renderbegin(msg, &cctx, &xfr->txbuf)); - CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0)); - CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0)); - CHECK(dns_message_renderend(msg)); - dns_compress_invalidate(&cctx); - cleanup_cctx = ISC_FALSE; - - isc_buffer_usedregion(&xfr->txbuf, &used); - isc_buffer_putuint16(&xfr->txlenbuf, - (isc_uint16_t)used.length); - region.base = xfr->txlenbuf.base; - region.length = 2 + used.length; - xfrout_log(xfr, ISC_LOG_DEBUG(8), - "sending TCP message of %d bytes", - used.length); - CHECK(isc_socket_send(xfr->client->tcpsocket, /* XXX */ - ®ion, xfr->client->task, - xfrout_senddone, - xfr)); - xfr->sends++; - } else { - xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending IXFR UDP response"); - ns_client_send(xfr->client); - xfr->stream->methods->pause(xfr->stream); - xfrout_ctx_destroy(&xfr); - return; - } - - /* Advance lasttsig to be the last TSIG generated */ - CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig)); - - xfr->nmsg++; - - failure: - if (msgname != NULL) { - if (msgrds != NULL) { - if (dns_rdataset_isassociated(msgrds)) - dns_rdataset_disassociate(msgrds); - dns_message_puttemprdataset(msg, &msgrds); - } - if (msgrdl != NULL) { - ISC_LIST_UNLINK(msgrdl->rdata, msgrdata, link); - dns_message_puttemprdatalist(msg, &msgrdl); - } - if (msgrdata != NULL) - dns_message_puttemprdata(msg, &msgrdata); - dns_message_puttempname(msg, &msgname); - } - - if (tcpmsg != NULL) - dns_message_destroy(&tcpmsg); - - if (cleanup_cctx) - dns_compress_invalidate(&cctx); - /* - * Make sure to release any locks held by database - * iterators before returning from the event handler. - */ - xfr->stream->methods->pause(xfr->stream); - - if (result == ISC_R_SUCCESS) - return; - - xfrout_fail(xfr, result, "sending zone data"); -} - -static void -xfrout_ctx_destroy(xfrout_ctx_t **xfrp) { - xfrout_ctx_t *xfr = *xfrp; - - INSIST(xfr->sends == 0); - - xfr->client->shutdown = NULL; - xfr->client->shutdown_arg = NULL; - - if (xfr->stream != NULL) - xfr->stream->methods->destroy(&xfr->stream); - if (xfr->buf.base != NULL) - isc_mem_put(xfr->mctx, xfr->buf.base, xfr->buf.length); - if (xfr->txmem != NULL) - isc_mem_put(xfr->mctx, xfr->txmem, xfr->txmemlen); - if (xfr->lasttsig != NULL) - isc_buffer_free(&xfr->lasttsig); - if (xfr->quota != NULL) - isc_quota_detach(&xfr->quota); - if (xfr->ver != NULL) - dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE); - if (xfr->db != NULL) - dns_db_detach(&xfr->db); - - ns_client_detach(&xfr->client); - - isc_mem_put(xfr->mctx, xfr, sizeof(*xfr)); - - *xfrp = NULL; -} - -static void -xfrout_senddone(isc_task_t *task, isc_event_t *event) { - isc_socketevent_t *sev = (isc_socketevent_t *)event; - xfrout_ctx_t *xfr = (xfrout_ctx_t *)event->ev_arg; - isc_result_t evresult = sev->result; - - UNUSED(task); - - INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE); - - isc_event_free(&event); - xfr->sends--; - INSIST(xfr->sends == 0); - - (void)isc_timer_touch(xfr->client->timer); - if (xfr->shuttingdown == ISC_TRUE) { - xfrout_maybe_destroy(xfr); - } else if (evresult != ISC_R_SUCCESS) { - xfrout_fail(xfr, evresult, "send"); - } else if (xfr->end_of_stream == ISC_FALSE) { - sendstream(xfr); - } else { - /* End of zone transfer stream. */ - xfrout_log(xfr, ISC_LOG_INFO, "%s ended", xfr->mnemonic); - ns_client_next(xfr->client, ISC_R_SUCCESS); - xfrout_ctx_destroy(&xfr); - } -} - -static void -xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, const char *msg) { - xfr->shuttingdown = ISC_TRUE; - xfrout_log(xfr, ISC_LOG_ERROR, "%s: %s", - msg, isc_result_totext(result)); - xfrout_maybe_destroy(xfr); -} - -static void -xfrout_maybe_destroy(xfrout_ctx_t *xfr) { - INSIST(xfr->shuttingdown == ISC_TRUE); - if (xfr->sends > 0) { - /* - * If we are currently sending, cancel it and wait for - * cancel event before destroying the context. - */ - isc_socket_cancel(xfr->client->tcpsocket, xfr->client->task, - ISC_SOCKCANCEL_SEND); - } else { - ns_client_next(xfr->client, ISC_R_CANCELED); - xfrout_ctx_destroy(&xfr); - } -} - -static void -xfrout_client_shutdown(void *arg, isc_result_t result) { - xfrout_ctx_t *xfr = (xfrout_ctx_t *) arg; - xfrout_fail(xfr, result, "aborted"); -} - -/* - * Log outgoing zone transfer messages in a format like - * <client>: transfer of <zone>: <message> - */ - -static void -xfrout_logv(ns_client_t *client, dns_name_t *zonename, - dns_rdataclass_t rdclass, int level, const char *fmt, va_list ap) - ISC_FORMAT_PRINTF(5, 0); - -static void -xfrout_logv(ns_client_t *client, dns_name_t *zonename, - dns_rdataclass_t rdclass, int level, const char *fmt, va_list ap) -{ - char msgbuf[2048]; - char namebuf[DNS_NAME_FORMATSIZE]; - char classbuf[DNS_RDATACLASS_FORMATSIZE]; - - dns_name_format(zonename, namebuf, sizeof(namebuf)); - dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf)); - vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); - ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, - NS_LOGMODULE_XFER_OUT, level, - "transfer of '%s/%s': %s", namebuf, classbuf, msgbuf); -} - -/* - * Logging function for use when a xfrout_ctx_t has not yet been created. - */ -static void -xfrout_log1(ns_client_t *client, dns_name_t *zonename, - dns_rdataclass_t rdclass, int level, const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - xfrout_logv(client, zonename, rdclass, level, fmt, ap); - va_end(ap); -} - -/* - * Logging function for use when there is a xfrout_ctx_t. - */ -static void -xfrout_log(xfrout_ctx_t *xfr, int level, const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - xfrout_logv(xfr->client, xfr->qname, xfr->qclass, level, fmt, ap); - va_end(ap); -} diff --git a/contrib/bind9/bin/named/zoneconf.c b/contrib/bind9/bin/named/zoneconf.c deleted file mode 100644 index 41ce69d6a627..000000000000 --- a/contrib/bind9/bin/named/zoneconf.c +++ /dev/null @@ -1,742 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2003 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 ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id: zoneconf.c,v 1.87.2.4.10.15 2005/09/06 02:12:39 marka Exp $ */ - -#include <config.h> - -#include <isc/buffer.h> -#include <isc/file.h> -#include <isc/mem.h> -#include <isc/print.h> -#include <isc/string.h> /* Required for HP/UX (and others?) */ -#include <isc/util.h> - -#include <dns/acl.h> -#include <dns/fixedname.h> -#include <dns/log.h> -#include <dns/name.h> -#include <dns/rdatatype.h> -#include <dns/ssu.h> -#include <dns/view.h> -#include <dns/zone.h> - -#include <named/config.h> -#include <named/globals.h> -#include <named/log.h> -#include <named/server.h> -#include <named/zoneconf.h> - -/* - * These are BIND9 server defaults, not necessarily identical to the - * library defaults defined in zone.c. - */ -#define RETERR(x) do { \ - isc_result_t _r = (x); \ - if (_r != ISC_R_SUCCESS) \ - return (_r); \ - } while (0) - -/* - * Convenience function for configuring a single zone ACL. - */ -static isc_result_t -configure_zone_acl(cfg_obj_t *zconfig, cfg_obj_t *vconfig, cfg_obj_t *config, - const char *aclname, ns_aclconfctx_t *actx, - dns_zone_t *zone, - void (*setzacl)(dns_zone_t *, dns_acl_t *), - void (*clearzacl)(dns_zone_t *)) -{ - isc_result_t result; - cfg_obj_t *maps[4]; - cfg_obj_t *aclobj = NULL; - int i = 0; - dns_acl_t *dacl = NULL; - - if (zconfig != NULL) - maps[i++] = cfg_tuple_get(zconfig, "options"); - if (vconfig != NULL) - maps[i++] = cfg_tuple_get(vconfig, "options"); - if (config != NULL) { - cfg_obj_t *options = NULL; - (void)cfg_map_get(config, "options", &options); - if (options != NULL) - maps[i++] = options; - } - maps[i] = NULL; - - result = ns_config_get(maps, aclname, &aclobj); - if (aclobj == NULL) { - (*clearzacl)(zone); - return (ISC_R_SUCCESS); - } - - result = ns_acl_fromconfig(aclobj, config, actx, - dns_zone_getmctx(zone), &dacl); - if (result != ISC_R_SUCCESS) - return (result); - (*setzacl)(zone, dacl); - dns_acl_detach(&dacl); - return (ISC_R_SUCCESS); -} - -/* - * Parse the zone update-policy statement. - */ -static isc_result_t -configure_zone_ssutable(cfg_obj_t *zconfig, dns_zone_t *zone) { - cfg_obj_t *updatepolicy = NULL; - cfg_listelt_t *element, *element2; - dns_ssutable_t *table = NULL; - isc_mem_t *mctx = dns_zone_getmctx(zone); - isc_result_t result; - - (void)cfg_map_get(zconfig, "update-policy", &updatepolicy); - if (updatepolicy == NULL) - return (ISC_R_SUCCESS); - - result = dns_ssutable_create(mctx, &table); - if (result != ISC_R_SUCCESS) - return (result); - - for (element = cfg_list_first(updatepolicy); - element != NULL; - element = cfg_list_next(element)) - { - cfg_obj_t *stmt = cfg_listelt_value(element); - cfg_obj_t *mode = cfg_tuple_get(stmt, "mode"); - cfg_obj_t *identity = cfg_tuple_get(stmt, "identity"); - cfg_obj_t *matchtype = cfg_tuple_get(stmt, "matchtype"); - cfg_obj_t *dname = cfg_tuple_get(stmt, "name"); - cfg_obj_t *typelist = cfg_tuple_get(stmt, "types"); - char *str; - isc_boolean_t grant = ISC_FALSE; - unsigned int mtype = DNS_SSUMATCHTYPE_NAME; - dns_fixedname_t fname, fident; - isc_buffer_t b; - dns_rdatatype_t *types; - unsigned int i, n; - - str = cfg_obj_asstring(mode); - if (strcasecmp(str, "grant") == 0) - grant = ISC_TRUE; - else if (strcasecmp(str, "deny") == 0) - grant = ISC_FALSE; - else - INSIST(0); - - str = cfg_obj_asstring(matchtype); - if (strcasecmp(str, "name") == 0) - mtype = DNS_SSUMATCHTYPE_NAME; - else if (strcasecmp(str, "subdomain") == 0) - mtype = DNS_SSUMATCHTYPE_SUBDOMAIN; - else if (strcasecmp(str, "wildcard") == 0) - mtype = DNS_SSUMATCHTYPE_WILDCARD; - else if (strcasecmp(str, "self") == 0) - mtype = DNS_SSUMATCHTYPE_SELF; - else - INSIST(0); - - dns_fixedname_init(&fident); - str = cfg_obj_asstring(identity); - isc_buffer_init(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - result = dns_name_fromtext(dns_fixedname_name(&fident), &b, - dns_rootname, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR, - "'%s' is not a valid name", str); - goto cleanup; - } - - dns_fixedname_init(&fname); - str = cfg_obj_asstring(dname); - isc_buffer_init(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - result = dns_name_fromtext(dns_fixedname_name(&fname), &b, - dns_rootname, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR, - "'%s' is not a valid name", str); - goto cleanup; - } - - n = ns_config_listcount(typelist); - if (n == 0) - types = NULL; - else { - types = isc_mem_get(mctx, n * sizeof(dns_rdatatype_t)); - if (types == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - } - - i = 0; - for (element2 = cfg_list_first(typelist); - element2 != NULL; - element2 = cfg_list_next(element2)) - { - cfg_obj_t *typeobj; - isc_textregion_t r; - - INSIST(i < n); - - typeobj = cfg_listelt_value(element2); - str = cfg_obj_asstring(typeobj); - r.base = str; - r.length = strlen(str); - - result = dns_rdatatype_fromtext(&types[i++], &r); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(identity, ns_g_lctx, ISC_LOG_ERROR, - "'%s' is not a valid type", str); - isc_mem_put(mctx, types, - n * sizeof(dns_rdatatype_t)); - goto cleanup; - } - } - INSIST(i == n); - - result = dns_ssutable_addrule(table, grant, - dns_fixedname_name(&fident), - mtype, - dns_fixedname_name(&fname), - n, types); - if (types != NULL) - isc_mem_put(mctx, types, n * sizeof(dns_rdatatype_t)); - if (result != ISC_R_SUCCESS) { - goto cleanup; - } - - } - - result = ISC_R_SUCCESS; - dns_zone_setssutable(zone, table); - - cleanup: - dns_ssutable_detach(&table); - return (result); -} - -/* - * Convert a config file zone type into a server zone type. - */ -static inline dns_zonetype_t -zonetype_fromconfig(cfg_obj_t *map) { - cfg_obj_t *obj = NULL; - isc_result_t result; - - result = cfg_map_get(map, "type", &obj); - INSIST(result == ISC_R_SUCCESS); - return (ns_config_getzonetype(obj)); -} - -/* - * Helper function for strtoargv(). Pardon the gratuitous recursion. - */ -static isc_result_t -strtoargvsub(isc_mem_t *mctx, char *s, unsigned int *argcp, - char ***argvp, unsigned int n) -{ - isc_result_t result; - - /* Discard leading whitespace. */ - while (*s == ' ' || *s == '\t') - s++; - - if (*s == '\0') { - /* We have reached the end of the string. */ - *argcp = n; - *argvp = isc_mem_get(mctx, n * sizeof(char *)); - if (*argvp == NULL) - return (ISC_R_NOMEMORY); - } else { - char *p = s; - while (*p != ' ' && *p != '\t' && *p != '\0') - p++; - if (*p != '\0') - *p++ = '\0'; - - result = strtoargvsub(mctx, p, argcp, argvp, n + 1); - if (result != ISC_R_SUCCESS) - return (result); - (*argvp)[n] = s; - } - return (ISC_R_SUCCESS); -} - -/* - * Tokenize the string "s" into whitespace-separated words, - * return the number of words in '*argcp' and an array - * of pointers to the words in '*argvp'. The caller - * must free the array using isc_mem_put(). The string - * is modified in-place. - */ -static isc_result_t -strtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, char ***argvp) { - return (strtoargvsub(mctx, s, argcp, argvp, 0)); -} - -static void -checknames(dns_zonetype_t ztype, cfg_obj_t **maps, cfg_obj_t **objp) { - const char *zone = NULL; - isc_result_t result; - - switch (ztype) { - case dns_zone_slave: zone = "slave"; break; - case dns_zone_master: zone = "master"; break; - default: - INSIST(0); - } - result = ns_checknames_get(maps, zone, objp); - INSIST(result == ISC_R_SUCCESS); -} - -isc_result_t -ns_zone_configure(cfg_obj_t *config, cfg_obj_t *vconfig, cfg_obj_t *zconfig, - ns_aclconfctx_t *ac, dns_zone_t *zone) -{ - isc_result_t result; - char *zname; - dns_rdataclass_t zclass; - dns_rdataclass_t vclass; - cfg_obj_t *maps[5]; - cfg_obj_t *zoptions = NULL; - cfg_obj_t *options = NULL; - cfg_obj_t *obj; - const char *filename = NULL; - dns_notifytype_t notifytype = dns_notifytype_yes; - isc_sockaddr_t *addrs; - dns_name_t **keynames; - isc_uint32_t count; - char *cpval; - unsigned int dbargc; - char **dbargv; - static char default_dbtype[] = "rbt"; - isc_mem_t *mctx = dns_zone_getmctx(zone); - dns_dialuptype_t dialup = dns_dialuptype_no; - dns_zonetype_t ztype; - int i; - isc_int32_t journal_size; - isc_boolean_t multi; - isc_boolean_t alt; - dns_view_t *view; - isc_boolean_t check = ISC_FALSE, fail = ISC_FALSE; - - i = 0; - if (zconfig != NULL) { - zoptions = cfg_tuple_get(zconfig, "options"); - maps[i++] = zoptions; - } - if (vconfig != NULL) - maps[i++] = cfg_tuple_get(vconfig, "options"); - if (config != NULL) { - (void)cfg_map_get(config, "options", &options); - if (options != NULL) - maps[i++] = options; - } - maps[i++] = ns_g_defaults; - maps[i++] = NULL; - - if (vconfig != NULL) - RETERR(ns_config_getclass(cfg_tuple_get(vconfig, "class"), - dns_rdataclass_in, &vclass)); - else - vclass = dns_rdataclass_in; - - /* - * Configure values common to all zone types. - */ - - zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); - - RETERR(ns_config_getclass(cfg_tuple_get(zconfig, "class"), - vclass, &zclass)); - dns_zone_setclass(zone, zclass); - - ztype = zonetype_fromconfig(zoptions); - dns_zone_settype(zone, ztype); - - obj = NULL; - result = cfg_map_get(zoptions, "database", &obj); - if (result == ISC_R_SUCCESS) - cpval = isc_mem_strdup(mctx, cfg_obj_asstring(obj)); - else - cpval = default_dbtype; - - if (cpval == NULL) - return(ISC_R_NOMEMORY); - - result = strtoargv(mctx, cpval, &dbargc, &dbargv); - if (result != ISC_R_SUCCESS && cpval != default_dbtype) { - isc_mem_free(mctx, cpval); - return (result); - } - - /* - * ANSI C is strange here. There is no logical reason why (char **) - * cannot be promoted automatically to (const char * const *) by the - * compiler w/o generating a warning. - */ - result = dns_zone_setdbtype(zone, dbargc, (const char * const *)dbargv); - isc_mem_put(mctx, dbargv, dbargc * sizeof(*dbargv)); - if (cpval != default_dbtype) - isc_mem_free(mctx, cpval); - if (result != ISC_R_SUCCESS) - return (result); - - obj = NULL; - result = cfg_map_get(zoptions, "file", &obj); - if (result == ISC_R_SUCCESS) - filename = cfg_obj_asstring(obj); - RETERR(dns_zone_setfile(zone, filename)); - - if (ztype == dns_zone_slave) - RETERR(configure_zone_acl(zconfig, vconfig, config, - "allow-notify", ac, zone, - dns_zone_setnotifyacl, - dns_zone_clearnotifyacl)); - /* - * XXXAG This probably does not make sense for stubs. - */ - RETERR(configure_zone_acl(zconfig, vconfig, config, - "allow-query", ac, zone, - dns_zone_setqueryacl, - dns_zone_clearqueryacl)); - - obj = NULL; - result = ns_config_get(maps, "dialup", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isboolean(obj)) { - if (cfg_obj_asboolean(obj)) - dialup = dns_dialuptype_yes; - else - dialup = dns_dialuptype_no; - } else { - char *dialupstr = cfg_obj_asstring(obj); - if (strcasecmp(dialupstr, "notify") == 0) - dialup = dns_dialuptype_notify; - else if (strcasecmp(dialupstr, "notify-passive") == 0) - dialup = dns_dialuptype_notifypassive; - else if (strcasecmp(dialupstr, "refresh") == 0) - dialup = dns_dialuptype_refresh; - else if (strcasecmp(dialupstr, "passive") == 0) - dialup = dns_dialuptype_passive; - else - INSIST(0); - } - dns_zone_setdialup(zone, dialup); - - obj = NULL; - result = ns_config_get(maps, "zone-statistics", &obj); - INSIST(result == ISC_R_SUCCESS); - RETERR(dns_zone_setstatistics(zone, cfg_obj_asboolean(obj))); - - /* - * Configure master functionality. This applies - * to primary masters (type "master") and slaves - * acting as masters (type "slave"), but not to stubs. - */ - if (ztype != dns_zone_stub) { - obj = NULL; - result = ns_config_get(maps, "notify", &obj); - INSIST(result == ISC_R_SUCCESS); - if (cfg_obj_isboolean(obj)) { - if (cfg_obj_asboolean(obj)) - notifytype = dns_notifytype_yes; - else - notifytype = dns_notifytype_no; - } else { - char *notifystr = cfg_obj_asstring(obj); - if (strcasecmp(notifystr, "explicit") == 0) - notifytype = dns_notifytype_explicit; - else - INSIST(0); - } - dns_zone_setnotifytype(zone, notifytype); - - obj = NULL; - result = ns_config_get(maps, "also-notify", &obj); - if (result == ISC_R_SUCCESS) { - isc_sockaddr_t *addrs = NULL; - isc_uint32_t addrcount; - result = ns_config_getiplist(config, obj, 0, mctx, - &addrs, &addrcount); - if (result != ISC_R_SUCCESS) - return (result); - result = dns_zone_setalsonotify(zone, addrs, - addrcount); - ns_config_putiplist(mctx, &addrs, addrcount); - if (result != ISC_R_SUCCESS) - return (result); - } else - RETERR(dns_zone_setalsonotify(zone, NULL, 0)); - - obj = NULL; - result = ns_config_get(maps, "notify-source", &obj); - INSIST(result == ISC_R_SUCCESS); - RETERR(dns_zone_setnotifysrc4(zone, cfg_obj_assockaddr(obj))); - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - - obj = NULL; - result = ns_config_get(maps, "notify-source-v6", &obj); - INSIST(result == ISC_R_SUCCESS); - RETERR(dns_zone_setnotifysrc6(zone, cfg_obj_assockaddr(obj))); - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - - RETERR(configure_zone_acl(zconfig, vconfig, config, - "allow-transfer", ac, zone, - dns_zone_setxfracl, - dns_zone_clearxfracl)); - - obj = NULL; - result = ns_config_get(maps, "max-transfer-time-out", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setmaxxfrout(zone, cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-transfer-idle-out", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setidleout(zone, cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-journal-size", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setjournalsize(zone, -1); - if (cfg_obj_isstring(obj)) { - const char *str = cfg_obj_asstring(obj); - INSIST(strcasecmp(str, "unlimited") == 0); - journal_size = ISC_UINT32_MAX / 2; - } else { - isc_resourcevalue_t value; - value = cfg_obj_asuint64(obj); - if (value > ISC_UINT32_MAX / 2) { - cfg_obj_log(obj, ns_g_lctx, - ISC_LOG_ERROR, - "'max-journal-size " - "%" ISC_PRINT_QUADFORMAT "d' " - "is too large", - value); - RETERR(ISC_R_RANGE); - } - journal_size = (isc_uint32_t)value; - } - dns_zone_setjournalsize(zone, journal_size); - - obj = NULL; - result = ns_config_get(maps, "ixfr-from-differences", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS, - cfg_obj_asboolean(obj)); - - checknames(ztype, maps, &obj); - INSIST(obj != NULL); - if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { - fail = ISC_FALSE; - check = ISC_TRUE; - } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { - fail = check = ISC_TRUE; - } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { - fail = check = ISC_FALSE; - } else - INSIST(0); - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES, check); - dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL, fail); - } - - /* - * Configure update-related options. These apply to - * primary masters only. - */ - if (ztype == dns_zone_master) { - dns_acl_t *updateacl; - RETERR(configure_zone_acl(zconfig, vconfig, config, - "allow-update", ac, zone, - dns_zone_setupdateacl, - dns_zone_clearupdateacl)); - - updateacl = dns_zone_getupdateacl(zone); - if (updateacl != NULL && dns_acl_isinsecure(updateacl)) - isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_SERVER, ISC_LOG_WARNING, - "zone '%s' allows updates by IP " - "address, which is insecure", - zname); - - RETERR(configure_zone_ssutable(zoptions, zone)); - - obj = NULL; - result = ns_config_get(maps, "sig-validity-interval", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setsigvalidityinterval(zone, - cfg_obj_asuint32(obj) * 86400); - - obj = NULL; - result = ns_config_get(maps, "key-directory", &obj); - if (result == ISC_R_SUCCESS) { - filename = cfg_obj_asstring(obj); - if (!isc_file_isabsolute(filename)) { - cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR, - "key-directory '%s' " - "is not absolute", filename); - return (ISC_R_FAILURE); - } - RETERR(dns_zone_setkeydirectory(zone, filename)); - } - - } else if (ztype == dns_zone_slave) { - RETERR(configure_zone_acl(zconfig, vconfig, config, - "allow-update-forwarding", ac, zone, - dns_zone_setforwardacl, - dns_zone_clearforwardacl)); - } - - /* - * Configure slave functionality. - */ - switch (ztype) { - case dns_zone_slave: - case dns_zone_stub: - obj = NULL; - result = cfg_map_get(zoptions, "masters", &obj); - if (obj != NULL) { - addrs = NULL; - keynames = NULL; - RETERR(ns_config_getipandkeylist(config, obj, mctx, - &addrs, &keynames, - &count)); - result = dns_zone_setmasterswithkeys(zone, addrs, - keynames, count); - ns_config_putipandkeylist(mctx, &addrs, &keynames, - count); - } else - result = dns_zone_setmasters(zone, NULL, 0); - RETERR(result); - - multi = ISC_FALSE; - if (count > 1) { - obj = NULL; - result = ns_config_get(maps, "multi-master", &obj); - INSIST(result == ISC_R_SUCCESS); - multi = cfg_obj_asboolean(obj); - } - dns_zone_setoption(zone, DNS_ZONEOPT_MULTIMASTER, multi); - - obj = NULL; - result = ns_config_get(maps, "max-transfer-time-in", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setmaxxfrin(zone, cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-transfer-idle-in", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setidlein(zone, cfg_obj_asuint32(obj) * 60); - - obj = NULL; - result = ns_config_get(maps, "max-refresh-time", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setmaxrefreshtime(zone, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "min-refresh-time", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setminrefreshtime(zone, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "max-retry-time", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setmaxretrytime(zone, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "min-retry-time", &obj); - INSIST(result == ISC_R_SUCCESS); - dns_zone_setminretrytime(zone, cfg_obj_asuint32(obj)); - - obj = NULL; - result = ns_config_get(maps, "transfer-source", &obj); - INSIST(result == ISC_R_SUCCESS); - RETERR(dns_zone_setxfrsource4(zone, cfg_obj_assockaddr(obj))); - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - - obj = NULL; - result = ns_config_get(maps, "transfer-source-v6", &obj); - INSIST(result == ISC_R_SUCCESS); - RETERR(dns_zone_setxfrsource6(zone, cfg_obj_assockaddr(obj))); - ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj)); - - obj = NULL; - result = ns_config_get(maps, "alt-transfer-source", &obj); - INSIST(result == ISC_R_SUCCESS); - RETERR(dns_zone_setaltxfrsource4(zone, cfg_obj_assockaddr(obj))); - - obj = NULL; - result = ns_config_get(maps, "alt-transfer-source-v6", &obj); - INSIST(result == ISC_R_SUCCESS); - RETERR(dns_zone_setaltxfrsource6(zone, cfg_obj_assockaddr(obj))); - - obj = NULL; - (void)ns_config_get(maps, "use-alt-transfer-source", &obj); - if (obj == NULL) { - /* - * Default off when views are in use otherwise - * on for BIND 8 compatibility. - */ - view = dns_zone_getview(zone); - if (view != NULL && strcmp(view->name, "_default") == 0) - alt = ISC_TRUE; - else - alt = ISC_FALSE; - } else - alt = cfg_obj_asboolean(obj); - dns_zone_setoption(zone, DNS_ZONEOPT_USEALTXFRSRC, alt); - - break; - - default: - break; - } - - return (ISC_R_SUCCESS); -} - -isc_boolean_t -ns_zone_reusable(dns_zone_t *zone, cfg_obj_t *zconfig) { - cfg_obj_t *zoptions = NULL; - cfg_obj_t *obj = NULL; - const char *cfilename; - const char *zfilename; - - zoptions = cfg_tuple_get(zconfig, "options"); - - if (zonetype_fromconfig(zoptions) != dns_zone_gettype(zone)) - return (ISC_FALSE); - - obj = NULL; - (void)cfg_map_get(zoptions, "file", &obj); - if (obj != NULL) - cfilename = cfg_obj_asstring(obj); - else - cfilename = NULL; - zfilename = dns_zone_getfile(zone); - if (!((cfilename == NULL && zfilename == NULL) || - (cfilename != NULL && zfilename != NULL && - strcmp(cfilename, zfilename) == 0))) - return (ISC_FALSE); - - return (ISC_TRUE); -} |