diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:59:48 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:59:48 +0000 |
commit | 3b9b6d0b8e7f798023c9d109c490449d528fde80 (patch) | |
tree | 2e1c188dd7b8d7475cd163de9ae02c428343669b /bin/tests/system/dlzexternal | |
parent | Initial commit. (diff) | |
download | bind9-3b9b6d0b8e7f798023c9d109c490449d528fde80.tar.xz bind9-3b9b6d0b8e7f798023c9d109c490449d528fde80.zip |
Adding upstream version 1:9.18.19.upstream/1%9.18.19upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'bin/tests/system/dlzexternal')
-rw-r--r-- | bin/tests/system/dlzexternal/clean.sh | 26 | ||||
-rw-r--r-- | bin/tests/system/dlzexternal/driver/Makefile.am | 13 | ||||
-rw-r--r-- | bin/tests/system/dlzexternal/driver/Makefile.in | 778 | ||||
-rw-r--r-- | bin/tests/system/dlzexternal/driver/driver.c | 862 | ||||
-rw-r--r-- | bin/tests/system/dlzexternal/driver/driver.h | 35 | ||||
-rw-r--r-- | bin/tests/system/dlzexternal/ns1/named.conf.in | 85 | ||||
-rw-r--r-- | bin/tests/system/dlzexternal/ns1/root.db | 26 | ||||
-rw-r--r-- | bin/tests/system/dlzexternal/prereq.sh | 21 | ||||
-rw-r--r-- | bin/tests/system/dlzexternal/setup.sh | 18 | ||||
-rw-r--r-- | bin/tests/system/dlzexternal/tests.sh | 231 | ||||
-rw-r--r-- | bin/tests/system/dlzexternal/tests_sh_dlzexternal.py | 14 |
11 files changed, 2109 insertions, 0 deletions
diff --git a/bin/tests/system/dlzexternal/clean.sh b/bin/tests/system/dlzexternal/clean.sh new file mode 100644 index 0000000..2bbf75b --- /dev/null +++ b/bin/tests/system/dlzexternal/clean.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# SPDX-License-Identifier: MPL-2.0 +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at https://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +# +# Clean up after dlzexternal tests. +# + +rm -f ns1/update.txt +rm -f */named.memstats +rm -f */named.conf +rm -f */named.run +rm -f ns1/ddns.key +rm -f dig.out* +rm -f ns*/named.lock +rm -f ns1/session.key +rm -f ns*/managed-keys.bind* diff --git a/bin/tests/system/dlzexternal/driver/Makefile.am b/bin/tests/system/dlzexternal/driver/Makefile.am new file mode 100644 index 0000000..0028edb --- /dev/null +++ b/bin/tests/system/dlzexternal/driver/Makefile.am @@ -0,0 +1,13 @@ +include $(top_srcdir)/Makefile.top + +AM_CPPFLAGS += \ + $(LIBISC_CFLAGS) \ + $(LIBDNS_CFLAGS) + +noinst_LTLIBRARIES = dlzexternal.la + +dlzexternal_la_SOURCES = \ + driver.c \ + driver.h + +dlzexternal_la_LDFLAGS = -avoid-version -module -shared -export-dynamic -rpath $(abs_builddir) diff --git a/bin/tests/system/dlzexternal/driver/Makefile.in b/bin/tests/system/dlzexternal/driver/Makefile.in new file mode 100644 index 0000000..8a26cb9 --- /dev/null +++ b/bin/tests/system/dlzexternal/driver/Makefile.in @@ -0,0 +1,778 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Hey Emacs, this is -*- makefile-automake -*- file! +# vim: filetype=automake + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +@HOST_MACOS_TRUE@am__append_1 = \ +@HOST_MACOS_TRUE@ -Wl,-flat_namespace + +subdir = bin/tests/system/dlzexternal/driver +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/ax_check_openssl.m4 \ + $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4/ax_jemalloc.m4 \ + $(top_srcdir)/m4/ax_lib_lmdb.m4 \ + $(top_srcdir)/m4/ax_perl_module.m4 \ + $(top_srcdir)/m4/ax_posix_shell.m4 \ + $(top_srcdir)/m4/ax_prog_cc_for_build.m4 \ + $(top_srcdir)/m4/ax_pthread.m4 \ + $(top_srcdir)/m4/ax_python_module.m4 \ + $(top_srcdir)/m4/ax_restore_flags.m4 \ + $(top_srcdir)/m4/ax_save_flags.m4 $(top_srcdir)/m4/ax_tls.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +dlzexternal_la_LIBADD = +am_dlzexternal_la_OBJECTS = driver.lo +dlzexternal_la_OBJECTS = $(am_dlzexternal_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +dlzexternal_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(dlzexternal_la_LDFLAGS) $(LDFLAGS) -o \ + $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/driver.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(dlzexternal_la_SOURCES) +DIST_SOURCES = $(dlzexternal_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__extra_recursive_targets = test-recursive unit-recursive \ + doc-recursive +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/Makefile.top \ + $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_EXEEXT = @BUILD_EXEEXT@ +BUILD_OBJEXT = @BUILD_OBJEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS = @CFLAGS@ +CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ +CMOCKA_CFLAGS = @CMOCKA_CFLAGS@ +CMOCKA_LIBS = @CMOCKA_LIBS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@ +CPP_FOR_BUILD = @CPP_FOR_BUILD@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CURL = @CURL@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DEVELOPER_MODE = @DEVELOPER_MODE@ +DLLTOOL = @DLLTOOL@ +DNSTAP_CFLAGS = @DNSTAP_CFLAGS@ +DNSTAP_LIBS = @DNSTAP_LIBS@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILECMD = @FILECMD@ +FSTRM_CAPTURE = @FSTRM_CAPTURE@ +FUZZ_LDFLAGS = @FUZZ_LDFLAGS@ +FUZZ_LOG_COMPILER = @FUZZ_LOG_COMPILER@ +GREP = @GREP@ +GSSAPI_CFLAGS = @GSSAPI_CFLAGS@ +GSSAPI_LIBS = @GSSAPI_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@ +JEMALLOC_LIBS = @JEMALLOC_LIBS@ +JSON_C_CFLAGS = @JSON_C_CFLAGS@ +JSON_C_LIBS = @JSON_C_LIBS@ +KRB5_CFLAGS = @KRB5_CFLAGS@ +KRB5_CONFIG = @KRB5_CONFIG@ +KRB5_LIBS = @KRB5_LIBS@ +LATEXMK = @LATEXMK@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ +LIBCAP_LIBS = @LIBCAP_LIBS@ +LIBIDN2_CFLAGS = @LIBIDN2_CFLAGS@ +LIBIDN2_LIBS = @LIBIDN2_LIBS@ +LIBNGHTTP2_CFLAGS = @LIBNGHTTP2_CFLAGS@ +LIBNGHTTP2_LIBS = @LIBNGHTTP2_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUV_CFLAGS = @LIBUV_CFLAGS@ +LIBUV_LIBS = @LIBUV_LIBS@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LMDB_CFLAGS = @LMDB_CFLAGS@ +LMDB_LIBS = @LMDB_LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MAXMINDDB_CFLAGS = @MAXMINDDB_CFLAGS@ +MAXMINDDB_LIBS = @MAXMINDDB_LIBS@ +MAXMINDDB_PREFIX = @MAXMINDDB_PREFIX@ +MKDIR_P = @MKDIR_P@ +NC = @NC@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTOC_C = @PROTOC_C@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +PYTEST = @PYTEST@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +READLINE_CFLAGS = @READLINE_CFLAGS@ +READLINE_LIBS = @READLINE_LIBS@ +RELEASE_DATE = @RELEASE_DATE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SPHINX_BUILD = @SPHINX_BUILD@ +STD_CFLAGS = @STD_CFLAGS@ +STD_CPPFLAGS = @STD_CPPFLAGS@ +STD_LDFLAGS = @STD_LDFLAGS@ +STRIP = @STRIP@ +TEST_CFLAGS = @TEST_CFLAGS@ +VERSION = @VERSION@ +XELATEX = @XELATEX@ +XSLTPROC = @XSLTPROC@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CC_FOR_BUILD = @ac_ct_CC_FOR_BUILD@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +ax_pthread_config = @ax_pthread_config@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +ACLOCAL_AMFLAGS = -I $(top_srcdir)/m4 +AM_CFLAGS = \ + $(STD_CFLAGS) + +AM_CPPFLAGS = $(STD_CPPFLAGS) -include $(top_builddir)/config.h \ + -I$(srcdir)/include $(LIBISC_CFLAGS) $(LIBDNS_CFLAGS) +AM_LDFLAGS = $(STD_LDFLAGS) $(am__append_1) +LDADD = +LIBISC_CFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/lib/isc/include \ + -I$(top_builddir)/lib/isc/include + +LIBISC_LIBS = $(top_builddir)/lib/isc/libisc.la +LIBDNS_CFLAGS = \ + -I$(top_srcdir)/lib/dns/include \ + -I$(top_builddir)/lib/dns/include + +LIBDNS_LIBS = \ + $(top_builddir)/lib/dns/libdns.la + +LIBNS_CFLAGS = \ + -I$(top_srcdir)/lib/ns/include + +LIBNS_LIBS = \ + $(top_builddir)/lib/ns/libns.la + +LIBIRS_CFLAGS = \ + -I$(top_srcdir)/lib/irs/include + +LIBIRS_LIBS = \ + $(top_builddir)/lib/irs/libirs.la + +LIBISCCFG_CFLAGS = \ + -I$(top_srcdir)/lib/isccfg/include + +LIBISCCFG_LIBS = \ + $(top_builddir)/lib/isccfg/libisccfg.la + +LIBISCCC_CFLAGS = \ + -I$(top_srcdir)/lib/isccc/include/ + +LIBISCCC_LIBS = \ + $(top_builddir)/lib/isccc/libisccc.la + +LIBBIND9_CFLAGS = \ + -I$(top_srcdir)/lib/bind9/include + +LIBBIND9_LIBS = \ + $(top_builddir)/lib/bind9/libbind9.la + +noinst_LTLIBRARIES = dlzexternal.la +dlzexternal_la_SOURCES = \ + driver.c \ + driver.h + +dlzexternal_la_LDFLAGS = -avoid-version -module -shared -export-dynamic -rpath $(abs_builddir) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/Makefile.top $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign bin/tests/system/dlzexternal/driver/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign bin/tests/system/dlzexternal/driver/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/Makefile.top $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +dlzexternal.la: $(dlzexternal_la_OBJECTS) $(dlzexternal_la_DEPENDENCIES) $(EXTRA_dlzexternal_la_DEPENDENCIES) + $(AM_V_CCLD)$(dlzexternal_la_LINK) $(dlzexternal_la_OBJECTS) $(dlzexternal_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +test-local: +unit-local: +doc-local: + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/driver.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +doc: doc-am + +doc-am: doc-local + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/driver.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +test: test-am + +test-am: test-local + +uninstall-am: + +unit: unit-am + +unit-am: unit-local + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir \ + doc-am doc-local dvi dvi-am html html-am info info-am install \ + install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-am test-am test-local uninstall \ + uninstall-am unit-am unit-local + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/bin/tests/system/dlzexternal/driver/driver.c b/bin/tests/system/dlzexternal/driver/driver.c new file mode 100644 index 0000000..20edfd0 --- /dev/null +++ b/bin/tests/system/dlzexternal/driver/driver.c @@ -0,0 +1,862 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/* + * This provides a very simple example of an external loadable DLZ + * driver, with update support. + */ + +#include "driver.h" +#include <inttypes.h> +#include <stdarg.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> + +#include <isc/log.h> +#include <isc/result.h> +#include <isc/string.h> +#include <isc/types.h> +#include <isc/util.h> + +#include <dns/dlz_dlopen.h> +#include <dns/types.h> + +/* aliases for exported symbols */ + +dlz_dlopen_version_t dlz_version; +dlz_dlopen_create_t dlz_create; +dlz_dlopen_destroy_t dlz_destroy; +dlz_dlopen_findzonedb_t dlz_findzonedb; +dlz_dlopen_lookup_t dlz_lookup; +dlz_dlopen_allowzonexfr_t dlz_allowzonexfr; +dlz_dlopen_allnodes_t dlz_allnodes; +dlz_dlopen_newversion_t dlz_newversion; +dlz_dlopen_closeversion_t dlz_closeversion; +dlz_dlopen_configure_t dlz_configure; +dlz_dlopen_ssumatch_t dlz_ssumatch; +dlz_dlopen_addrdataset_t dlz_addrdataset; +dlz_dlopen_subrdataset_t dlz_subrdataset; +dlz_dlopen_delrdataset_t dlz_delrdataset; + +#define CHECK(x) \ + do { \ + result = (x); \ + if (result != ISC_R_SUCCESS) \ + goto failure; \ + } while (0) + +#define loginfo(...) \ + ({ \ + if ((state != NULL) && (state->log != NULL)) \ + state->log(ISC_LOG_INFO, __VA_ARGS__); \ + }) +#define logerr(...) \ + ({ \ + if ((state != NULL) && (state->log != NULL)) \ + state->log(ISC_LOG_ERROR, __VA_ARGS__); \ + }) + +/* For this simple example, use fixed sized strings */ +struct record { + char name[100]; + char type[10]; + char data[200]; + dns_ttl_t ttl; +}; + +#define MAX_RECORDS 100 + +typedef void +log_t(int level, const char *fmt, ...); + +struct dlz_example_data { + char *zone_name; + + /* An example driver doesn't need good memory management :-) */ + struct record current[MAX_RECORDS]; + struct record adds[MAX_RECORDS]; + struct record deletes[MAX_RECORDS]; + + bool transaction_started; + + /* Helper functions from the dlz_dlopen driver */ + log_t *log; + dns_sdlz_putrr_t *putrr; + dns_sdlz_putnamedrr_t *putnamedrr; + dns_dlz_writeablezone_t *writeable_zone; +}; + +static bool +single_valued(const char *type) { + const char *single[] = { "soa", "cname", NULL }; + int i; + + for (i = 0; single[i]; i++) { + if (strcasecmp(single[i], type) == 0) { + return (true); + } + } + return (false); +} + +/* + * Add a record to a list + */ +static isc_result_t +add_name(struct dlz_example_data *state, struct record *list, const char *name, + const char *type, dns_ttl_t ttl, const char *data) { + int i; + bool single = single_valued(type); + int first_empty = -1; + + for (i = 0; i < MAX_RECORDS; i++) { + INSIST(list[i].name != NULL); + if (first_empty == -1 && strlen(list[i].name) == 0U) { + first_empty = i; + } + if (strcasecmp(list[i].name, name) != 0) { + continue; + } + if (strcasecmp(list[i].type, type) != 0) { + continue; + } + if (!single && strcasecmp(list[i].data, data) != 0) { + continue; + } + break; + } + if (i == MAX_RECORDS && first_empty != -1) { + i = first_empty; + } + if (i == MAX_RECORDS) { + logerr("dlz_example: out of record space"); + return (ISC_R_FAILURE); + } + + if (strlen(name) >= sizeof(list[i].name) || + strlen(type) >= sizeof(list[i].type) || + strlen(data) >= sizeof(list[i].data)) + { + return (ISC_R_NOSPACE); + } + + strncpy(list[i].name, name, sizeof(list[i].name) - 1); + list[i].name[sizeof(list[i].name) - 1] = '\0'; + + strncpy(list[i].type, type, sizeof(list[i].type) - 1); + list[i].type[sizeof(list[i].type) - 1] = '\0'; + + strncpy(list[i].data, data, sizeof(list[i].data) - 1); + list[i].data[sizeof(list[i].data) - 1] = '\0'; + + list[i].ttl = ttl; + + return (ISC_R_SUCCESS); +} + +/* + * Delete a record from a list + */ +static isc_result_t +del_name(struct dlz_example_data *state, struct record *list, const char *name, + const char *type, dns_ttl_t ttl, const char *data) { + int i; + + UNUSED(state); + + for (i = 0; i < MAX_RECORDS; i++) { + if (strcasecmp(name, list[i].name) == 0 && + strcasecmp(type, list[i].type) == 0 && + strcasecmp(data, list[i].data) == 0 && ttl == list[i].ttl) + { + break; + } + } + if (i == MAX_RECORDS) { + return (ISC_R_NOTFOUND); + } + memset(&list[i], 0, sizeof(struct record)); + return (ISC_R_SUCCESS); +} + +static isc_result_t +fmt_address(isc_sockaddr_t *addr, char *buffer, size_t size) { + char addr_buf[INET6_ADDRSTRLEN]; + const char *ret; + uint16_t port = 0; + + switch (addr->type.sa.sa_family) { + case AF_INET: + port = ntohs(addr->type.sin.sin_port); + ret = inet_ntop(AF_INET, &addr->type.sin.sin_addr, addr_buf, + sizeof(addr_buf)); + break; + case AF_INET6: + port = ntohs(addr->type.sin6.sin6_port); + ret = inet_ntop(AF_INET6, &addr->type.sin6.sin6_addr, addr_buf, + sizeof(addr_buf)); + break; + default: + return (ISC_R_FAILURE); + } + + if (ret == NULL) { + return (ISC_R_FAILURE); + } + + snprintf(buffer, size, "%s#%u", addr_buf, port); + return (ISC_R_SUCCESS); +} + +/* + * Return the version of the API + */ +int +dlz_version(unsigned int *flags) { + UNUSED(flags); + return (DLZ_DLOPEN_VERSION); +} + +/* + * Remember a helper function from the bind9 dlz_dlopen driver + */ +static void +b9_add_helper(struct dlz_example_data *state, const char *helper_name, + void *ptr) { + if (strcmp(helper_name, "log") == 0) { + state->log = (log_t *)ptr; + } + if (strcmp(helper_name, "putrr") == 0) { + state->putrr = (dns_sdlz_putrr_t *)ptr; + } + if (strcmp(helper_name, "putnamedrr") == 0) { + state->putnamedrr = (dns_sdlz_putnamedrr_t *)ptr; + } + if (strcmp(helper_name, "writeable_zone") == 0) { + state->writeable_zone = (dns_dlz_writeablezone_t *)ptr; + } +} + +/* + * Called to initialize the driver + */ +isc_result_t +dlz_create(const char *dlzname, unsigned int argc, char *argv[], void **dbdata, + ...) { + struct dlz_example_data *state; + const char *helper_name; + va_list ap; + char soa_data[sizeof("@ hostmaster.root 123 900 600 86400 3600")]; + isc_result_t result; + size_t n; + + UNUSED(dlzname); + + state = calloc(1, sizeof(struct dlz_example_data)); + if (state == NULL) { + return (ISC_R_NOMEMORY); + } + + /* Fill in the helper functions */ + va_start(ap, dbdata); + while ((helper_name = va_arg(ap, const char *)) != NULL) { + b9_add_helper(state, helper_name, va_arg(ap, void *)); + } + va_end(ap); + + if (argc < 2 || argv[1][0] == '\0') { + logerr("dlz_example: please specify a zone name"); + dlz_destroy(state); + return (ISC_R_FAILURE); + } + + /* Ensure zone name is absolute */ + state->zone_name = malloc(strlen(argv[1]) + 2); + if (state->zone_name == NULL) { + free(state); + return (ISC_R_NOMEMORY); + } + if (argv[1][strlen(argv[1]) - 1] == '.') { + strcpy(state->zone_name, argv[1]); + } else { + sprintf(state->zone_name, "%s.", argv[1]); + } + + /* + * Use relative names to trigger ISC_R_NOSPACE in dns_sdlz_putrr. + */ + if (strcmp(state->zone_name, ".") == 0) { + n = strlcpy(soa_data, + "@ hostmaster.root 123 900 600 86400 3600", + sizeof(soa_data)); + } else { + n = strlcpy(soa_data, "@ hostmaster 123 900 600 86400 3600", + sizeof(soa_data)); + } + + if (n >= sizeof(soa_data)) { + CHECK(ISC_R_NOSPACE); + } + + add_name(state, &state->current[0], state->zone_name, "soa", 3600, + soa_data); + add_name(state, &state->current[0], state->zone_name, "ns", 3600, + state->zone_name); + add_name(state, &state->current[0], state->zone_name, "a", 1800, + "10.53.0.1"); + + loginfo("dlz_example: started for zone %s", state->zone_name); + + *dbdata = state; + return (ISC_R_SUCCESS); + +failure: + free(state); + return (result); +} + +/* + * Shut down the backend + */ +void +dlz_destroy(void *dbdata) { + struct dlz_example_data *state = (struct dlz_example_data *)dbdata; + + loginfo("dlz_example: shutting down zone %s", state->zone_name); + free(state->zone_name); + free(state); +} + +/* + * See if we handle a given zone + */ +isc_result_t +dlz_findzonedb(void *dbdata, const char *name, dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo) { + struct dlz_example_data *state = (struct dlz_example_data *)dbdata; + isc_sockaddr_t *src; + char addrbuf[100]; + char absolute[1024]; + + strcpy(addrbuf, "unknown"); + if (methods != NULL && methods->sourceip != NULL && + methods->version - methods->age <= DNS_CLIENTINFOMETHODS_VERSION && + DNS_CLIENTINFOMETHODS_VERSION <= methods->version) + { + methods->sourceip(clientinfo, &src); + fmt_address(src, addrbuf, sizeof(addrbuf)); + } + + loginfo("dlz_example: dlz_findzonedb called with name '%s' " + "in zone DB '%s' from %s", + name, state->zone_name, addrbuf); + + /* + * Returning ISC_R_NOTFOUND will cause the query logic to + * check the database for parent names, looking for zone cuts. + * + * Returning ISC_R_NOMORE prevents the query logic from doing + * this; it will move onto the next database after a single query. + */ + if (strcasecmp(name, "test.example.com") == 0) { + return (ISC_R_NOMORE); + } + + /* + * For example.net, only return ISC_R_NOMORE when queried + * from 10.53.0.1. + */ + if (strcasecmp(name, "test.example.net") == 0 && + strncmp(addrbuf, "10.53.0.1", 9) == 0) + { + return (ISC_R_NOMORE); + } + + /* + * For bigcname.domain, return success so it appears to be + * the zone origin; this regression tests a bug in which + * zone origin nodes could fail to return SERVFAIL to the client. + */ + if (strcasecmp(name, "bigcname.domain") == 0) { + return (ISC_R_SUCCESS); + } + + /* + * Return success if we have an exact match between the + * zone name and the qname + */ + if (strcasecmp(state->zone_name, name) == 0) { + return (ISC_R_SUCCESS); + } + + snprintf(absolute, sizeof(absolute), "%s.", name); + if (strcasecmp(state->zone_name, absolute) == 0) { + return (ISC_R_SUCCESS); + } + + return (ISC_R_NOTFOUND); +} + +/* + * Look up one record in the sample database. + * + * If the queryname is "source-addr", send back a TXT record containing + * the address of the client, to test the use of 'methods' and 'clientinfo' + * + * If the queryname is "too-long", send back a TXT record that's too long + * to process; this should result in a SERVFAIL when queried. + */ +isc_result_t +dlz_lookup(const char *zone, const char *name, void *dbdata, + dns_sdlzlookup_t *lookup, dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo) { + isc_result_t result; + struct dlz_example_data *state = (struct dlz_example_data *)dbdata; + bool found = false; + void *dbversion = NULL; + isc_sockaddr_t *src; + char full_name[256]; + char buf[512]; + static char last[256]; + static int count = 0; + int i, size; + + UNUSED(zone); + + if (state->putrr == NULL) { + return (ISC_R_NOTIMPLEMENTED); + } + + if (strcmp(name, "@") == 0) { + size = snprintf(full_name, sizeof(full_name), "%s", + state->zone_name); + } else if (strcmp(state->zone_name, ".") == 0) { + size = snprintf(full_name, sizeof(full_name), "%s.", name); + } else { + size = snprintf(full_name, sizeof(full_name), "%s.%s", name, + state->zone_name); + } + + if (size < 0 || (size_t)size >= sizeof(full_name) || + (size_t)size >= sizeof(last)) + { + return (ISC_R_NOSPACE); + } + + /* + * For test purposes, log all calls to dlz_lookup() + */ + if (strcasecmp(full_name, last) == 0) { + count++; + } else { + count = 1; + memcpy(last, full_name, size + 1); + } + loginfo("lookup #%d for %s", count, full_name); + + /* + * If we need to know the database version (as set in + * the 'newversion' dlz function) we can pick it up from the + * clientinfo. + * + * This allows a lookup to query the correct version of the DNS + * data, if the DLZ can differentiate between versions. + * + * For example, if a new database transaction is created by + * 'newversion', the lookup should query within the same + * transaction scope if it can. + * + * If the DLZ only operates on 'live' data, then version + * wouldn't necessarily be needed. + */ + if (clientinfo != NULL && clientinfo->version >= 2) { + dbversion = clientinfo->dbversion; + if (dbversion != NULL && *(bool *)dbversion) { + loginfo("dlz_example: lookup against live transaction"); + } + } + + if (strcmp(name, "source-addr") == 0) { + char ecsbuf[DNS_ECS_FORMATSIZE] = "not supported"; + strncpy(buf, "unknown", sizeof(buf)); + if (methods != NULL && methods->sourceip != NULL && + (methods->version - methods->age <= + DNS_CLIENTINFOMETHODS_VERSION) && + DNS_CLIENTINFOMETHODS_VERSION <= methods->version) + { + methods->sourceip(clientinfo, &src); + fmt_address(src, buf, sizeof(buf)); + } + if (clientinfo != NULL && clientinfo->version >= 3) { + if (clientinfo->ecs.addr.family != AF_UNSPEC) { + dns_ecs_format(&clientinfo->ecs, ecsbuf, + sizeof(ecsbuf)); + } else { + snprintf(ecsbuf, sizeof(ecsbuf), "%s", + "not present"); + } + } + i = strlen(buf); + snprintf(buf + i, sizeof(buf) - i - 1, " ECS %s", ecsbuf); + + loginfo("dlz_example: lookup connection from %s", buf); + + found = true; + result = state->putrr(lookup, "TXT", 0, buf); + if (result != ISC_R_SUCCESS) { + return (result); + } + } + + if (strcmp(name, "too-long") == 0 || + strcmp(zone, "bigcname.domain") == 0) + { + for (i = 0; i < 511; i++) { + buf[i] = 'x'; + } + buf[i] = '\0'; + found = true; + result = state->putrr(lookup, "TXT", 0, buf); + if (result != ISC_R_SUCCESS) { + return (result); + } + } + + /* Tests for DLZ redirection zones */ + if (strcmp(name, "*") == 0 && strcmp(zone, ".") == 0) { + result = state->putrr(lookup, "A", 0, "100.100.100.2"); + found = true; + if (result != ISC_R_SUCCESS) { + return (result); + } + } + + if (strcmp(name, "long.name.is.not.there") == 0 && + strcmp(zone, ".") == 0) + { + result = state->putrr(lookup, "A", 0, "100.100.100.3"); + found = true; + if (result != ISC_R_SUCCESS) { + return (result); + } + } + + /* Answer from current records */ + for (i = 0; i < MAX_RECORDS; i++) { + if (strcasecmp(state->current[i].name, full_name) == 0) { + found = true; + result = state->putrr(lookup, state->current[i].type, + state->current[i].ttl, + state->current[i].data); + if (result != ISC_R_SUCCESS) { + return (result); + } + } + } + + if (!found) { + return (ISC_R_NOTFOUND); + } + + return (ISC_R_SUCCESS); +} + +/* + * See if a zone transfer is allowed + */ +isc_result_t +dlz_allowzonexfr(void *dbdata, const char *name, const char *client) { + struct dlz_example_data *state = (struct dlz_example_data *)dbdata; + isc_result_t result; + + loginfo("dlz_example: dlz_allowzonexfr called for %s", name); + + result = dlz_findzonedb(dbdata, name, NULL, NULL); + if (result != ISC_R_SUCCESS) { + loginfo("dlz_example: findzonedb returned %s", + isc_result_totext(result)); + return (result); + } + + /* + * Exception for "example.org" so we can test the use of + * the view ACL. + */ + if (strcmp(name, "example.org") == 0) { + loginfo("dlz_example: use view ACL for example.org"); + return (ISC_R_DEFAULT); + } + + /* + * Exception for 10.53.0.5 so we can test that allow-transfer + * is effective. + */ + if (strcmp(client, "10.53.0.5") == 0) { + loginfo("dlz_example: disallow transfer to 10.53.0.5"); + return (ISC_R_NOPERM); + } + + loginfo("dlz_example: transfer allowed for %s", name); + + return (ISC_R_SUCCESS); +} + +/* + * Perform a zone transfer + */ +isc_result_t +dlz_allnodes(const char *zone, void *dbdata, dns_sdlzallnodes_t *allnodes) { + struct dlz_example_data *state = (struct dlz_example_data *)dbdata; + int i; + + UNUSED(zone); + + if (state->putnamedrr == NULL) { + return (ISC_R_NOTIMPLEMENTED); + } + + for (i = 0; i < MAX_RECORDS; i++) { + isc_result_t result; + if (strlen(state->current[i].name) == 0U) { + continue; + } + result = state->putnamedrr(allnodes, state->current[i].name, + state->current[i].type, + state->current[i].ttl, + state->current[i].data); + if (result != ISC_R_SUCCESS) { + return (result); + } + } + + return (ISC_R_SUCCESS); +} + +/* + * Start a transaction + */ +isc_result_t +dlz_newversion(const char *zone, void *dbdata, void **versionp) { + struct dlz_example_data *state = (struct dlz_example_data *)dbdata; + + if (state->transaction_started) { + loginfo("dlz_example: transaction already started for zone %s", + zone); + return (ISC_R_FAILURE); + } + + state->transaction_started = true; + *versionp = (void *)&state->transaction_started; + + return (ISC_R_SUCCESS); +} + +/* + * End a transaction + */ +void +dlz_closeversion(const char *zone, bool commit, void *dbdata, void **versionp) { + struct dlz_example_data *state = (struct dlz_example_data *)dbdata; + + if (!state->transaction_started) { + loginfo("dlz_example: transaction not started for zone %s", + zone); + *versionp = NULL; + return; + } + + state->transaction_started = false; + + *versionp = NULL; + + if (commit) { + int i; + loginfo("dlz_example: committing transaction on zone %s", zone); + for (i = 0; i < MAX_RECORDS; i++) { + if (strlen(state->deletes[i].name) > 0U) { + (void)del_name(state, &state->current[0], + state->deletes[i].name, + state->deletes[i].type, + state->deletes[i].ttl, + state->deletes[i].data); + } + } + for (i = 0; i < MAX_RECORDS; i++) { + if (strlen(state->adds[i].name) > 0U) { + (void)add_name(state, &state->current[0], + state->adds[i].name, + state->adds[i].type, + state->adds[i].ttl, + state->adds[i].data); + } + } + } else { + loginfo("dlz_example: cancelling transaction on zone %s", zone); + } + memset(state->adds, 0, sizeof(state->adds)); + memset(state->deletes, 0, sizeof(state->deletes)); +} + +/* + * Configure a writeable zone + */ +isc_result_t +dlz_configure(dns_view_t *view, dns_dlzdb_t *dlzdb, void *dbdata) { + struct dlz_example_data *state = (struct dlz_example_data *)dbdata; + isc_result_t result; + + loginfo("dlz_example: starting configure"); + + if (state->writeable_zone == NULL) { + loginfo("dlz_example: no writeable_zone method available"); + return (ISC_R_FAILURE); + } + + result = state->writeable_zone(view, dlzdb, state->zone_name); + if (result != ISC_R_SUCCESS) { + loginfo("dlz_example: failed to configure zone %s", + state->zone_name); + return (result); + } + + loginfo("dlz_example: configured writeable zone %s", state->zone_name); + return (ISC_R_SUCCESS); +} + +/* + * Authorize a zone update + */ +bool +dlz_ssumatch(const char *signer, const char *name, const char *tcpaddr, + const char *type, const char *key, uint32_t keydatalen, + unsigned char *keydata, void *dbdata) { + struct dlz_example_data *state = (struct dlz_example_data *)dbdata; + + UNUSED(tcpaddr); + UNUSED(type); + UNUSED(key); + UNUSED(keydatalen); + UNUSED(keydata); + + if (strncmp(name, "deny.", 5) == 0) { + loginfo("dlz_example: denying update of name=%s by %s", name, + signer); + return (false); + } + loginfo("dlz_example: allowing update of name=%s by %s", name, signer); + return (true); +} + +static isc_result_t +modrdataset(struct dlz_example_data *state, const char *name, + const char *rdatastr, struct record *list) { + char *full_name, *dclass, *type, *data, *ttlstr, *buf; + char absolute[1024]; + isc_result_t result; + char *saveptr = NULL; + + buf = strdup(rdatastr); + if (buf == NULL) { + return (ISC_R_FAILURE); + } + + /* + * The format is: + * FULLNAME\tTTL\tDCLASS\tTYPE\tDATA + * + * The DATA field is space separated, and is in the data format + * for the type used by dig + */ + + full_name = strtok_r(buf, "\t", &saveptr); + if (full_name == NULL) { + goto error; + } + + ttlstr = strtok_r(NULL, "\t", &saveptr); + if (ttlstr == NULL) { + goto error; + } + + dclass = strtok_r(NULL, "\t", &saveptr); + if (dclass == NULL) { + goto error; + } + + type = strtok_r(NULL, "\t", &saveptr); + if (type == NULL) { + goto error; + } + + data = strtok_r(NULL, "\t", &saveptr); + if (data == NULL) { + goto error; + } + + if (name[strlen(name) - 1] != '.') { + snprintf(absolute, sizeof(absolute), "%s.", name); + name = absolute; + } + + result = add_name(state, list, name, type, strtoul(ttlstr, NULL, 10), + data); + free(buf); + return (result); + +error: + free(buf); + return (ISC_R_FAILURE); +} + +isc_result_t +dlz_addrdataset(const char *name, const char *rdatastr, void *dbdata, + void *version) { + struct dlz_example_data *state = (struct dlz_example_data *)dbdata; + + if (version != (void *)&state->transaction_started) { + return (ISC_R_FAILURE); + } + + loginfo("dlz_example: adding rdataset %s '%s'", name, rdatastr); + + return (modrdataset(state, name, rdatastr, &state->adds[0])); +} + +isc_result_t +dlz_subrdataset(const char *name, const char *rdatastr, void *dbdata, + void *version) { + struct dlz_example_data *state = (struct dlz_example_data *)dbdata; + + if (version != (void *)&state->transaction_started) { + return (ISC_R_FAILURE); + } + + loginfo("dlz_example: subtracting rdataset %s '%s'", name, rdatastr); + + return (modrdataset(state, name, rdatastr, &state->deletes[0])); +} + +isc_result_t +dlz_delrdataset(const char *name, const char *type, void *dbdata, + void *version) { + struct dlz_example_data *state = (struct dlz_example_data *)dbdata; + + if (version != (void *)&state->transaction_started) { + return (ISC_R_FAILURE); + } + + loginfo("dlz_example: deleting rdataset %s of type %s", name, type); + + return (ISC_R_SUCCESS); +} diff --git a/bin/tests/system/dlzexternal/driver/driver.h b/bin/tests/system/dlzexternal/driver/driver.h new file mode 100644 index 0000000..2c1a594 --- /dev/null +++ b/bin/tests/system/dlzexternal/driver/driver.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +#pragma once + +#include <dns/dlz_dlopen.h> + +/* + * This header includes the declarations of entry points. + */ + +dlz_dlopen_version_t dlz_version; +dlz_dlopen_create_t dlz_create; +dlz_dlopen_destroy_t dlz_destroy; +dlz_dlopen_findzonedb_t dlz_findzonedb; +dlz_dlopen_lookup_t dlz_lookup; +dlz_dlopen_allowzonexfr_t dlz_allowzonexfr; +dlz_dlopen_allnodes_t dlz_allnodes; +dlz_dlopen_newversion_t dlz_newversion; +dlz_dlopen_closeversion_t dlz_closeversion; +dlz_dlopen_configure_t dlz_configure; +dlz_dlopen_ssumatch_t dlz_ssumatch; +dlz_dlopen_addrdataset_t dlz_addrdataset; +dlz_dlopen_subrdataset_t dlz_subrdataset; +dlz_dlopen_delrdataset_t dlz_delrdataset; diff --git a/bin/tests/system/dlzexternal/ns1/named.conf.in b/bin/tests/system/dlzexternal/ns1/named.conf.in new file mode 100644 index 0000000..f8b36e9 --- /dev/null +++ b/bin/tests/system/dlzexternal/ns1/named.conf.in @@ -0,0 +1,85 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +options { + query-source address 10.53.0.1; + notify-source 10.53.0.1; + transfer-source 10.53.0.1; + port @PORT@; + pid-file "named.pid"; + session-keyfile "session.key"; + listen-on { 10.53.0.1; 127.0.0.1; }; + listen-on-v6 { none; }; + allow-transfer { !10.53.0.1; any; }; + recursion no; + notify yes; + dnssec-validation no; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +include "ddns.key"; + +controls { + inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +dlz "example one" { + database "dlopen ../driver/.libs/dlzexternal.so example.nil"; +}; + +dlz "example two" { + database "dlopen ../driver/.libs/dlzexternal.so alternate.nil"; +}; + +dlz "example three" { + database "dlopen ../driver/.libs/dlzexternal.so example.org"; +}; + +dlz "example four" { + // Long zone name to trigger ISC_R_NOSPACE in dns_sdlz_putrr. + database "dlopen ../driver/.libs/dlzexternal.so 123456789.123456789.123456789.123456789.123456789.example.foo"; +}; + +dlz "unsearched1" { + database "dlopen ../driver/.libs/dlzexternal.so other.nil"; + search no; +}; + +dlz "unsearched2" { + database "dlopen ../driver/.libs/dlzexternal.so zone.nil"; + search no; +}; + +dlz redzone { + database "dlopen ../driver/.libs/dlzexternal.so ."; + search no; +}; + +zone zone.nil { + type primary; + dlz unsearched2; +}; + +zone "." { + type redirect; + dlz redzone; +}; + +zone "." { + type primary; + file "root.db"; +}; diff --git a/bin/tests/system/dlzexternal/ns1/root.db b/bin/tests/system/dlzexternal/ns1/root.db new file mode 100644 index 0000000..6cbe579 --- /dev/null +++ b/bin/tests/system/dlzexternal/ns1/root.db @@ -0,0 +1,26 @@ +; Copyright (C) Internet Systems Consortium, Inc. ("ISC") +; +; SPDX-License-Identifier: MPL-2.0 +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, you can obtain one at https://mozilla.org/MPL/2.0/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +$TTL 300 +. IN SOA gson.nominum.com. a.root.servers.nil. ( + 2000042100 ; serial + 600 ; refresh + 600 ; retry + 1200 ; expire + 600 ; minimum + ) +. NS a.root-servers.nil. +a.root-servers.nil. A 10.53.0.1 + +example. NS ns1.example. +ns1.example. A 10.53.0.1 + +exists. A 10.10.10.10 diff --git a/bin/tests/system/dlzexternal/prereq.sh b/bin/tests/system/dlzexternal/prereq.sh new file mode 100644 index 0000000..066a74e --- /dev/null +++ b/bin/tests/system/dlzexternal/prereq.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# SPDX-License-Identifier: MPL-2.0 +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at https://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +. ../conf.sh + +$FEATURETEST --tsan && { + echo_i "TSAN - skipping dlzexternal test" + exit 255 +} + +exit 0 diff --git a/bin/tests/system/dlzexternal/setup.sh b/bin/tests/system/dlzexternal/setup.sh new file mode 100644 index 0000000..dda16df --- /dev/null +++ b/bin/tests/system/dlzexternal/setup.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# SPDX-License-Identifier: MPL-2.0 +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at https://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +. ../conf.sh + +$TSIGKEYGEN ddns-key.example.nil > ns1/ddns.key + +copy_setports ns1/named.conf.in ns1/named.conf diff --git a/bin/tests/system/dlzexternal/tests.sh b/bin/tests/system/dlzexternal/tests.sh new file mode 100644 index 0000000..a86ea7e --- /dev/null +++ b/bin/tests/system/dlzexternal/tests.sh @@ -0,0 +1,231 @@ +#!/bin/sh + +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# SPDX-License-Identifier: MPL-2.0 +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at https://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +set -e + +. ../conf.sh + +status=0 +n=0 + +DIGOPTS="@10.53.0.1 -p ${PORT} +nocookie" +RNDCCMD="$RNDC -c ../common/rndc.conf -p ${CONTROLPORT} -s" + +newtest() { + n=$((n + 1)) + echo_i "${1} (${n})" + ret=0 +} + +test_update() { + host="$1" + type="$2" + cmd="$3" + digout="$4" + should_fail="$5" + + cat <<EOF > ns1/update.txt +server 10.53.0.1 ${PORT} +update add $host $cmd +send +EOF + + newtest "testing update for $host $type $cmd${comment:+ }$comment" + $NSUPDATE -k ns1/ddns.key ns1/update.txt > /dev/null 2>&1 || { + [ "$should_fail" ] || \ + echo_i "update failed for $host $type $cmd" + return 1 + } + + out=$($DIG $DIGOPTS -t $type -q $host | grep -E "^$host") + lines=$(echo "$out" | grep "$digout" | wc -l) + [ $lines -eq 1 ] || { + [ "$should_fail" ] || \ + echo_i "dig output incorrect for $host $type $cmd: $out" + return 1 + } + return 0 +} + +test_update testdc1.example.nil. A "86400 A 10.53.0.10" "10.53.0.10" || ret=1 +status=$((status + ret)) + +test_update testdc2.example.nil. A "86400 A 10.53.0.11" "10.53.0.11" || ret=1 +status=$((status + ret)) + +test_update testdc3.example.nil. A "86400 A 10.53.0.10" "10.53.0.10" || ret=1 +status=$((status + ret)) + +test_update deny.example.nil. TXT "86400 TXT helloworld" "helloworld" should_fail && ret=1 +status=$((status + ret)) + +newtest "testing nxrrset" +$DIG $DIGOPTS testdc1.example.nil AAAA > dig.out.$n || ret=1 +grep "status: NOERROR" dig.out.$n > /dev/null || ret=1 +grep "ANSWER: 0" dig.out.$n > /dev/null || ret=1 +status=$((status + ret)) + +newtest "testing prerequisites are checked correctly" +cat > ns1/update.txt << EOF +server 10.53.0.1 ${PORT} +prereq nxdomain testdc3.example.nil +update add testdc3.example.nil 86500 in a 10.53.0.12 +send +EOF +$NSUPDATE -k ns1/ddns.key ns1/update.txt > /dev/null 2>&1 && ret=1 +out=$($DIG $DIGOPTS +short a testdc3.example.nil) +[ "$out" = "10.53.0.12" ] && ret=1 +[ "$ret" -eq 0 ] || echo_i "failed" +status=$((status + ret)) + +newtest "testing passing client info into DLZ driver" +out=$($DIG $DIGOPTS +short -t txt -q source-addr.example.nil | grep -v '^;') +addr=$(eval echo "$out" | cut -f1 -d'#') +[ "$addr" = "10.53.0.1" ] || ret=1 +[ "$ret" -eq 0 ] || echo_i "failed" +status=$((status + ret)) + +newtest "testing DLZ driver is cleaned up on reload" +rndc_reload ns1 10.53.0.1 +for i in 0 1 2 3 4 5 6 7 8 9; do + ret=0 + grep 'dlz_example: shutting down zone example.nil' ns1/named.run > /dev/null 2>&1 || ret=1 + [ "$ret" -eq 0 ] && break + sleep 1 +done +[ "$ret" -eq 0 ] || echo_i "failed" +status=$((status + ret)) + +newtest "testing multiple DLZ drivers" +test_update testdc1.alternate.nil. A "86400 A 10.53.0.10" "10.53.0.10" || ret=1 +status=$((status + ret)) + +newtest "testing AXFR from DLZ drivers" +$DIG $DIGOPTS +noall +answer axfr example.nil > dig.out.example.ns1.test$n || ret=1 +lines=$(cat dig.out.example.ns1.test$n | wc -l) +[ ${lines:-0} -eq 4 ] || ret=1 +$DIG $DIGOPTS +noall +answer axfr alternate.nil > dig.out.alternate.ns1.test$n || ret=1 +lines=$(cat dig.out.alternate.ns1.test$n | wc -l) +[ ${lines:-0} -eq 5 ] || ret=1 +[ "$ret" -eq 0 ] || echo_i "failed" +status=$((status + ret)) + +newtest "testing AXFR denied from DLZ drivers" +$DIG $DIGOPTS -b 10.53.0.5 +noall +answer axfr example.nil > dig.out.example.ns1.test$n || ret=1 +grep "; Transfer failed" dig.out.example.ns1.test$n > /dev/null || ret=1 +$DIG $DIGOPTS -b 10.53.0.5 +noall +answer axfr alternate.nil > dig.out.alternate.ns1.test$n || ret=1 +grep "; Transfer failed" dig.out.alternate.ns1.test$n > /dev/null || ret=1 +[ "$ret" -eq 0 ] || echo_i "failed" +status=$((status + ret)) + +newtest "testing AXFR denied based on view ACL" +# 10.53.0.1 should be disallowed +$DIG $DIGOPTS -b 10.53.0.1 +noall +answer axfr example.org > dig.out.example.ns1.test$n.1 || ret=1 +grep "; Transfer failed" dig.out.example.ns1.test$n.1 > /dev/null || ret=1 +# 10.53.0.2 should be allowed +$DIG $DIGOPTS -b 10.53.0.2 +noall +answer axfr example.org > dig.out.example.ns1.test$n.2 || ret=1 +grep "; Transfer failed" dig.out.example.ns1.test$n.2 > /dev/null && ret=1 +[ "$ret" -eq 0 ] || echo_i "failed" +status=$((status + ret)) + +newtest "testing unsearched/unregistered DLZ zone is not found" +$DIG $DIGOPTS +noall +answer ns other.nil > dig.out.ns1.test$n || ret=1 +grep "3600.IN.NS.other.nil." dig.out.ns1.test$n > /dev/null && ret=1 +[ "$ret" -eq 0 ] || echo_i "failed" +status=$((status + ret)) + +newtest "testing unsearched/registered DLZ zone is found" +$DIG $DIGOPTS +noall +answer ns zone.nil > dig.out.ns1.test$n || ret=1 +grep "3600.IN.NS.zone.nil." dig.out.ns1.test$n > /dev/null || ret=1 +[ "$ret" -eq 0 ] || echo_i "failed" +status=$((status + ret)) + +newtest "testing unsearched/registered DLZ zone is found" +$DIG $DIGOPTS +noall +answer ns zone.nil > dig.out.ns1.test$n || ret=1 +grep "3600.IN.NS.zone.nil." dig.out.ns1.test$n > /dev/null || ret=1 +[ "$ret" -eq 0 ] || echo_i "failed" +status=$((status + ret)) + +newtest "testing correct behavior with findzone returning ISC_R_NOMORE" +$DIG $DIGOPTS +noall a test.example.com > /dev/null 2>&1 || ret=1 +# we should only find one logged lookup per searched DLZ database +lines=$(grep "dlz_findzonedb.*test\.example\.com.*example.nil" ns1/named.run | wc -l) +[ $lines -eq 1 ] || ret=1 +lines=$(grep "dlz_findzonedb.*test\.example\.com.*alternate.nil" ns1/named.run | wc -l) +[ $lines -eq 1 ] || ret=1 +[ "$ret" -eq 0 ] || echo_i "failed" +status=$((status + ret)) + +newtest "testing findzone can return different results per client" +$DIG $DIGOPTS -b 10.53.0.1 +noall a test.example.net > /dev/null 2>&1 || ret=1 +# we should only find one logged lookup per searched DLZ database +lines=$(grep "dlz_findzonedb.*example\.net.*example.nil" ns1/named.run | wc -l) +[ $lines -eq 1 ] || ret=1 +lines=$(grep "dlz_findzonedb.*example\.net.*alternate.nil" ns1/named.run | wc -l) +[ $lines -eq 1 ] || ret=1 +$DIG $DIGOPTS -b 10.53.0.2 +noall a test.example.net > /dev/null 2>&1 || ret=1 +# we should find several logged lookups this time +lines=$(grep "dlz_findzonedb.*example\.net.*example.nil" ns1/named.run | wc -l) +[ $lines -gt 2 ] || ret=1 +lines=$(grep "dlz_findzonedb.*example\.net.*alternate.nil" ns1/named.run | wc -l) +[ $lines -gt 2 ] || ret=1 +[ "$ret" -eq 0 ] || echo_i "failed" +status=$((status + ret)) + +newtest "testing zone returning oversized data" +$DIG $DIGOPTS txt too-long.example.nil > dig.out.ns1.test$n 2>&1 || ret=1 +grep "status: SERVFAIL" dig.out.ns1.test$n > /dev/null || ret=1 +[ "$ret" -eq 0 ] || echo_i "failed" +status=$((status + ret)) + +newtest "testing zone returning oversized data at zone origin" +$DIG $DIGOPTS txt bigcname.domain > dig.out.ns1.test$n 2>&1 || ret=1 +grep "status: SERVFAIL" dig.out.ns1.test$n > /dev/null || ret=1 +[ "$ret" -eq 0 ] || echo_i "failed" +status=$((status + ret)) + +newtest "checking redirected lookup for nonexistent name" +$DIG $DIGOPTS @10.53.0.1 unexists a > dig.out.ns1.test$n || ret=1 +grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1 +grep "^unexists.*A.*100.100.100.2" dig.out.ns1.test$n > /dev/null || ret=1 +grep "flags:[^;]* aa[ ;]" dig.out.ns1.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +newtest "checking no redirected lookup for nonexistent type" +$DIG $DIGOPTS @10.53.0.1 exists aaaa > dig.out.ns1.test$n || ret=1 +grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1 +grep "ANSWER: 0" dig.out.ns1.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +newtest "checking redirected lookup for a long nonexistent name" +$DIG $DIGOPTS @10.53.0.1 long.name.is.not.there a > dig.out.ns1.test$n || ret=1 +grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1 +grep "^long.name.*A.*100.100.100.3" dig.out.ns1.test$n > /dev/null || ret=1 +grep "flags:[^;]* aa[ ;]" dig.out.ns1.test$n > /dev/null || ret=1 +lookups=$(grep "lookup #.*\.not\.there" ns1/named.run | wc -l) +[ "$lookups" -eq 1 ] || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +newtest "checking ECS data is passed to driver in clientinfo" +$DIG $DIGOPTS +short +subnet=192.0/16 source-addr.example.nil txt > dig.out.ns1.test$n.1 || ret=1 +grep "192.0.0.0/16/0" dig.out.ns1.test$n.1 > /dev/null || ret=1 +$DIG $DIGOPTS +short source-addr.example.nil txt > dig.out.ns1.test$n.2 || ret=1 +grep "not.*present" dig.out.ns1.test$n.2 > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +echo_i "exit status: $status" +[ $status -eq 0 ] || exit 1 diff --git a/bin/tests/system/dlzexternal/tests_sh_dlzexternal.py b/bin/tests/system/dlzexternal/tests_sh_dlzexternal.py new file mode 100644 index 0000000..1c0f7e5 --- /dev/null +++ b/bin/tests/system/dlzexternal/tests_sh_dlzexternal.py @@ -0,0 +1,14 @@ +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# SPDX-License-Identifier: MPL-2.0 +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at https://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + + +def test_dlzexternal(run_tests_sh): + run_tests_sh() |