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/check | |
parent | Initial commit. (diff) | |
download | bind9-3b9b6d0b8e7f798023c9d109c490449d528fde80.tar.xz bind9-3b9b6d0b8e7f798023c9d109c490449d528fde80.zip |
Adding upstream version 1:9.18.19.upstream/1%9.18.19
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'bin/check')
-rw-r--r-- | bin/check/Makefile.am | 34 | ||||
-rw-r--r-- | bin/check/Makefile.in | 872 | ||||
-rw-r--r-- | bin/check/check-tool.c | 693 | ||||
-rw-r--r-- | bin/check/check-tool.h | 52 | ||||
-rw-r--r-- | bin/check/named-checkconf.c | 754 | ||||
-rw-r--r-- | bin/check/named-checkconf.rst | 108 | ||||
-rw-r--r-- | bin/check/named-checkzone.c | 569 | ||||
-rw-r--r-- | bin/check/named-checkzone.rst | 222 | ||||
-rw-r--r-- | bin/check/named-compilezone.rst | 224 |
9 files changed, 3528 insertions, 0 deletions
diff --git a/bin/check/Makefile.am b/bin/check/Makefile.am new file mode 100644 index 0000000..8f63c35 --- /dev/null +++ b/bin/check/Makefile.am @@ -0,0 +1,34 @@ +include $(top_srcdir)/Makefile.top + +AM_CPPFLAGS += \ + $(LIBISC_CFLAGS) \ + $(LIBDNS_CFLAGS) \ + $(LIBNS_CFLAGS) \ + $(LIBISCCFG_CFLAGS) \ + $(LIBBIND9_CFLAGS) + +AM_CPPFLAGS += \ + -DNAMED_CONFFILE=\"${sysconfdir}/named.conf\" + +noinst_LTLIBRARIES = libcheck-tool.la + +libcheck_tool_la_SOURCES = \ + check-tool.h \ + check-tool.c + +LDADD += \ + libcheck-tool.la \ + $(LIBISC_LIBS) \ + $(LIBDNS_LIBS) \ + $(LIBNS_LIBS) \ + $(LIBISCCFG_LIBS) \ + $(LIBBIND9_LIBS) + +bin_PROGRAMS = named-checkconf named-checkzone + +install-exec-hook: + ln -f $(DESTDIR)$(bindir)/named-checkzone \ + $(DESTDIR)$(bindir)/named-compilezone + +uninstall-hook: + -rm -f $(DESTDIR)$(bindir)/named-compilezone diff --git a/bin/check/Makefile.in b/bin/check/Makefile.in new file mode 100644 index 0000000..1f2d67a --- /dev/null +++ b/bin/check/Makefile.in @@ -0,0 +1,872 @@ +# 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 + +bin_PROGRAMS = named-checkconf$(EXEEXT) named-checkzone$(EXEEXT) +subdir = bin/check +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 = +am__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +LTLIBRARIES = $(noinst_LTLIBRARIES) +libcheck_tool_la_LIBADD = +am_libcheck_tool_la_OBJECTS = check-tool.lo +libcheck_tool_la_OBJECTS = $(am_libcheck_tool_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 = +named_checkconf_SOURCES = named-checkconf.c +named_checkconf_OBJECTS = named-checkconf.$(OBJEXT) +named_checkconf_LDADD = $(LDADD) +named_checkconf_DEPENDENCIES = libcheck-tool.la $(LIBISC_LIBS) \ + $(LIBDNS_LIBS) $(LIBNS_LIBS) $(LIBISCCFG_LIBS) \ + $(LIBBIND9_LIBS) +named_checkzone_SOURCES = named-checkzone.c +named_checkzone_OBJECTS = named-checkzone.$(OBJEXT) +named_checkzone_LDADD = $(LDADD) +named_checkzone_DEPENDENCIES = libcheck-tool.la $(LIBISC_LIBS) \ + $(LIBDNS_LIBS) $(LIBNS_LIBS) $(LIBISCCFG_LIBS) \ + $(LIBBIND9_LIBS) +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)/check-tool.Plo \ + ./$(DEPDIR)/named-checkconf.Po ./$(DEPDIR)/named-checkzone.Po +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 = $(libcheck_tool_la_SOURCES) named-checkconf.c \ + named-checkzone.c +DIST_SOURCES = $(libcheck_tool_la_SOURCES) named-checkconf.c \ + named-checkzone.c +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) \ + $(LIBNS_CFLAGS) $(LIBISCCFG_CFLAGS) $(LIBBIND9_CFLAGS) \ + -DNAMED_CONFFILE=\"${sysconfdir}/named.conf\" +AM_LDFLAGS = $(STD_LDFLAGS) $(am__append_1) +LDADD = libcheck-tool.la $(LIBISC_LIBS) $(LIBDNS_LIBS) $(LIBNS_LIBS) \ + $(LIBISCCFG_LIBS) $(LIBBIND9_LIBS) +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 = libcheck-tool.la +libcheck_tool_la_SOURCES = \ + check-tool.h \ + check-tool.c + +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/check/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign bin/check/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): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +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}; \ + } + +libcheck-tool.la: $(libcheck_tool_la_OBJECTS) $(libcheck_tool_la_DEPENDENCIES) $(EXTRA_libcheck_tool_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libcheck_tool_la_OBJECTS) $(libcheck_tool_la_LIBADD) $(LIBS) + +named-checkconf$(EXEEXT): $(named_checkconf_OBJECTS) $(named_checkconf_DEPENDENCIES) $(EXTRA_named_checkconf_DEPENDENCIES) + @rm -f named-checkconf$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(named_checkconf_OBJECTS) $(named_checkconf_LDADD) $(LIBS) + +named-checkzone$(EXEEXT): $(named_checkzone_OBJECTS) $(named_checkzone_DEPENDENCIES) $(EXTRA_named_checkzone_DEPENDENCIES) + @rm -f named-checkzone$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(named_checkzone_OBJECTS) $(named_checkzone_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-tool.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/named-checkconf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/named-checkzone.Po@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 $(PROGRAMS) $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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-binPROGRAMS clean-generic clean-libtool \ + clean-noinstLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/check-tool.Plo + -rm -f ./$(DEPDIR)/named-checkconf.Po + -rm -f ./$(DEPDIR)/named-checkzone.Po + -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-binPROGRAMS + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-exec-hook +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)/check-tool.Plo + -rm -f ./$(DEPDIR)/named-checkconf.Po + -rm -f ./$(DEPDIR)/named-checkzone.Po + -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: uninstall-binPROGRAMS + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-hook +unit: unit-am + +unit-am: unit-local + +.MAKE: install-am install-exec-am install-strip uninstall-am + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-binPROGRAMS 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-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-exec-hook 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 uninstall-binPROGRAMS uninstall-hook unit-am \ + unit-local + +.PRECIOUS: Makefile + + +install-exec-hook: + ln -f $(DESTDIR)$(bindir)/named-checkzone \ + $(DESTDIR)$(bindir)/named-compilezone + +uninstall-hook: + -rm -f $(DESTDIR)$(bindir)/named-compilezone + +# 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/check/check-tool.c b/bin/check/check-tool.c new file mode 100644 index 0000000..fd008dc --- /dev/null +++ b/bin/check/check-tool.c @@ -0,0 +1,693 @@ +/* + * 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. + */ + +/*! \file */ + +#include <inttypes.h> +#include <stdbool.h> +#include <stdio.h> + +#include <isc/buffer.h> +#include <isc/log.h> +#include <isc/mem.h> +#include <isc/net.h> +#include <isc/netdb.h> +#include <isc/print.h> +#include <isc/region.h> +#include <isc/result.h> +#include <isc/stdio.h> +#include <isc/string.h> +#include <isc/symtab.h> +#include <isc/types.h> +#include <isc/util.h> + +#include <dns/db.h> +#include <dns/dbiterator.h> +#include <dns/fixedname.h> +#include <dns/log.h> +#include <dns/name.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rdataset.h> +#include <dns/rdatasetiter.h> +#include <dns/rdatatype.h> +#include <dns/types.h> +#include <dns/zone.h> + +#include <isccfg/log.h> + +#include <ns/log.h> + +#include "check-tool.h" + +#ifndef CHECK_SIBLING +#define CHECK_SIBLING 1 +#endif /* ifndef CHECK_SIBLING */ + +#ifndef CHECK_LOCAL +#define CHECK_LOCAL 1 +#endif /* ifndef CHECK_LOCAL */ + +#define CHECK(r) \ + do { \ + result = (r); \ + if (result != ISC_R_SUCCESS) \ + goto cleanup; \ + } while (0) + +#define ERR_IS_CNAME 1 +#define ERR_NO_ADDRESSES 2 +#define ERR_LOOKUP_FAILURE 3 +#define ERR_EXTRA_A 4 +#define ERR_EXTRA_AAAA 5 +#define ERR_MISSING_GLUE 5 +#define ERR_IS_MXCNAME 6 +#define ERR_IS_SRVCNAME 7 + +static const char *dbtype[] = { "rbt" }; + +int debug = 0; +const char *journal = NULL; +bool nomerge = true; +#if CHECK_LOCAL +bool docheckmx = true; +bool dochecksrv = true; +bool docheckns = true; +#else /* if CHECK_LOCAL */ +bool docheckmx = false; +bool dochecksrv = false; +bool docheckns = false; +#endif /* if CHECK_LOCAL */ +dns_zoneopt_t zone_options = DNS_ZONEOPT_CHECKNS | DNS_ZONEOPT_CHECKMX | + DNS_ZONEOPT_MANYERRORS | DNS_ZONEOPT_CHECKNAMES | + DNS_ZONEOPT_CHECKINTEGRITY | +#if CHECK_SIBLING + DNS_ZONEOPT_CHECKSIBLING | +#endif /* if CHECK_SIBLING */ + DNS_ZONEOPT_CHECKWILDCARD | + DNS_ZONEOPT_WARNMXCNAME | DNS_ZONEOPT_WARNSRVCNAME; + +/* + * This needs to match the list in bin/named/log.c. + */ +static isc_logcategory_t categories[] = { { "", 0 }, + { "unmatched", 0 }, + { NULL, 0 } }; + +static isc_symtab_t *symtab = NULL; +static isc_mem_t *sym_mctx; + +static void +freekey(char *key, unsigned int type, isc_symvalue_t value, void *userarg) { + UNUSED(type); + UNUSED(value); + isc_mem_free(userarg, key); +} + +static void +add(char *key, int value) { + isc_result_t result; + isc_symvalue_t symvalue; + + if (sym_mctx == NULL) { + isc_mem_create(&sym_mctx); + } + + if (symtab == NULL) { + result = isc_symtab_create(sym_mctx, 100, freekey, sym_mctx, + false, &symtab); + if (result != ISC_R_SUCCESS) { + return; + } + } + + key = isc_mem_strdup(sym_mctx, key); + + symvalue.as_pointer = NULL; + result = isc_symtab_define(symtab, key, value, symvalue, + isc_symexists_reject); + if (result != ISC_R_SUCCESS) { + isc_mem_free(sym_mctx, key); + } +} + +static bool +logged(char *key, int value) { + isc_result_t result; + + if (symtab == NULL) { + return (false); + } + + result = isc_symtab_lookup(symtab, key, value, NULL); + if (result == ISC_R_SUCCESS) { + return (true); + } + return (false); +} + +static bool +checkns(dns_zone_t *zone, const dns_name_t *name, const dns_name_t *owner, + dns_rdataset_t *a, dns_rdataset_t *aaaa) { + dns_rdataset_t *rdataset; + dns_rdata_t rdata = DNS_RDATA_INIT; + struct addrinfo hints, *ai, *cur; + char namebuf[DNS_NAME_FORMATSIZE + 1]; + char ownerbuf[DNS_NAME_FORMATSIZE]; + char addrbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123")]; + bool answer = true; + bool match; + const char *type; + void *ptr = NULL; + int result; + + REQUIRE(a == NULL || !dns_rdataset_isassociated(a) || + a->type == dns_rdatatype_a); + REQUIRE(aaaa == NULL || !dns_rdataset_isassociated(aaaa) || + aaaa->type == dns_rdatatype_aaaa); + + if (a == NULL || aaaa == NULL) { + return (answer); + } + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_CANONNAME; + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + dns_name_format(name, namebuf, sizeof(namebuf) - 1); + /* + * Turn off search. + */ + if (dns_name_countlabels(name) > 1U) { + strlcat(namebuf, ".", sizeof(namebuf)); + } + dns_name_format(owner, ownerbuf, sizeof(ownerbuf)); + + result = getaddrinfo(namebuf, NULL, &hints, &ai); + dns_name_format(name, namebuf, sizeof(namebuf) - 1); + switch (result) { + case 0: + /* + * Work around broken getaddrinfo() implementations that + * fail to set ai_canonname on first entry. + */ + cur = ai; + while (cur != NULL && cur->ai_canonname == NULL && + cur->ai_next != NULL) + { + cur = cur->ai_next; + } + if (cur != NULL && cur->ai_canonname != NULL && + strcasecmp(cur->ai_canonname, namebuf) != 0 && + !logged(namebuf, ERR_IS_CNAME)) + { + dns_zone_log(zone, ISC_LOG_ERROR, + "%s/NS '%s' (out of zone) " + "is a CNAME '%s' (illegal)", + ownerbuf, namebuf, cur->ai_canonname); + /* XXX950 make fatal for 9.5.0 */ + /* answer = false; */ + add(namebuf, ERR_IS_CNAME); + } + break; + case EAI_NONAME: +#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) + case EAI_NODATA: +#endif /* if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) */ + if (!logged(namebuf, ERR_NO_ADDRESSES)) { + dns_zone_log(zone, ISC_LOG_ERROR, + "%s/NS '%s' (out of zone) " + "has no addresses records (A or AAAA)", + ownerbuf, namebuf); + add(namebuf, ERR_NO_ADDRESSES); + } + /* XXX950 make fatal for 9.5.0 */ + return (true); + + default: + if (!logged(namebuf, ERR_LOOKUP_FAILURE)) { + dns_zone_log(zone, ISC_LOG_WARNING, + "getaddrinfo(%s) failed: %s", namebuf, + gai_strerror(result)); + add(namebuf, ERR_LOOKUP_FAILURE); + } + return (true); + } + + /* + * Check that all glue records really exist. + */ + if (!dns_rdataset_isassociated(a)) { + goto checkaaaa; + } + result = dns_rdataset_first(a); + while (result == ISC_R_SUCCESS) { + dns_rdataset_current(a, &rdata); + match = false; + for (cur = ai; cur != NULL; cur = cur->ai_next) { + if (cur->ai_family != AF_INET) { + continue; + } + ptr = &((struct sockaddr_in *)(cur->ai_addr))->sin_addr; + if (memcmp(ptr, rdata.data, rdata.length) == 0) { + match = true; + break; + } + } + if (!match && !logged(namebuf, ERR_EXTRA_A)) { + dns_zone_log(zone, ISC_LOG_ERROR, + "%s/NS '%s' " + "extra GLUE A record (%s)", + ownerbuf, namebuf, + inet_ntop(AF_INET, rdata.data, addrbuf, + sizeof(addrbuf))); + add(namebuf, ERR_EXTRA_A); + /* XXX950 make fatal for 9.5.0 */ + /* answer = false; */ + } + dns_rdata_reset(&rdata); + result = dns_rdataset_next(a); + } + +checkaaaa: + if (!dns_rdataset_isassociated(aaaa)) { + goto checkmissing; + } + result = dns_rdataset_first(aaaa); + while (result == ISC_R_SUCCESS) { + dns_rdataset_current(aaaa, &rdata); + match = false; + for (cur = ai; cur != NULL; cur = cur->ai_next) { + if (cur->ai_family != AF_INET6) { + continue; + } + ptr = &((struct sockaddr_in6 *)(cur->ai_addr)) + ->sin6_addr; + if (memcmp(ptr, rdata.data, rdata.length) == 0) { + match = true; + break; + } + } + if (!match && !logged(namebuf, ERR_EXTRA_AAAA)) { + dns_zone_log(zone, ISC_LOG_ERROR, + "%s/NS '%s' " + "extra GLUE AAAA record (%s)", + ownerbuf, namebuf, + inet_ntop(AF_INET6, rdata.data, addrbuf, + sizeof(addrbuf))); + add(namebuf, ERR_EXTRA_AAAA); + /* XXX950 make fatal for 9.5.0. */ + /* answer = false; */ + } + dns_rdata_reset(&rdata); + result = dns_rdataset_next(aaaa); + } + +checkmissing: + /* + * Check that all addresses appear in the glue. + */ + if (!logged(namebuf, ERR_MISSING_GLUE)) { + bool missing_glue = false; + for (cur = ai; cur != NULL; cur = cur->ai_next) { + switch (cur->ai_family) { + case AF_INET: + rdataset = a; + ptr = &((struct sockaddr_in *)(cur->ai_addr)) + ->sin_addr; + type = "A"; + break; + case AF_INET6: + rdataset = aaaa; + ptr = &((struct sockaddr_in6 *)(cur->ai_addr)) + ->sin6_addr; + type = "AAAA"; + break; + default: + continue; + } + match = false; + if (dns_rdataset_isassociated(rdataset)) { + result = dns_rdataset_first(rdataset); + } else { + result = ISC_R_FAILURE; + } + while (result == ISC_R_SUCCESS && !match) { + dns_rdataset_current(rdataset, &rdata); + if (memcmp(ptr, rdata.data, rdata.length) == 0) + { + match = true; + } + dns_rdata_reset(&rdata); + result = dns_rdataset_next(rdataset); + } + if (!match) { + dns_zone_log(zone, ISC_LOG_ERROR, + "%s/NS '%s' " + "missing GLUE %s record (%s)", + ownerbuf, namebuf, type, + inet_ntop(cur->ai_family, ptr, + addrbuf, + sizeof(addrbuf))); + /* XXX950 make fatal for 9.5.0. */ + /* answer = false; */ + missing_glue = true; + } + } + if (missing_glue) { + add(namebuf, ERR_MISSING_GLUE); + } + } + freeaddrinfo(ai); + return (answer); +} + +static bool +checkmx(dns_zone_t *zone, const dns_name_t *name, const dns_name_t *owner) { + struct addrinfo hints, *ai, *cur; + char namebuf[DNS_NAME_FORMATSIZE + 1]; + char ownerbuf[DNS_NAME_FORMATSIZE]; + int result; + int level = ISC_LOG_ERROR; + bool answer = true; + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_CANONNAME; + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + dns_name_format(name, namebuf, sizeof(namebuf) - 1); + /* + * Turn off search. + */ + if (dns_name_countlabels(name) > 1U) { + strlcat(namebuf, ".", sizeof(namebuf)); + } + dns_name_format(owner, ownerbuf, sizeof(ownerbuf)); + + result = getaddrinfo(namebuf, NULL, &hints, &ai); + dns_name_format(name, namebuf, sizeof(namebuf) - 1); + switch (result) { + case 0: + /* + * Work around broken getaddrinfo() implementations that + * fail to set ai_canonname on first entry. + */ + cur = ai; + while (cur != NULL && cur->ai_canonname == NULL && + cur->ai_next != NULL) + { + cur = cur->ai_next; + } + if (cur != NULL && cur->ai_canonname != NULL && + strcasecmp(cur->ai_canonname, namebuf) != 0) + { + if ((zone_options & DNS_ZONEOPT_WARNMXCNAME) != 0) { + level = ISC_LOG_WARNING; + } + if ((zone_options & DNS_ZONEOPT_IGNOREMXCNAME) == 0) { + if (!logged(namebuf, ERR_IS_MXCNAME)) { + dns_zone_log(zone, level, + "%s/MX '%s' (out of zone)" + " is a CNAME '%s' " + "(illegal)", + ownerbuf, namebuf, + cur->ai_canonname); + add(namebuf, ERR_IS_MXCNAME); + } + if (level == ISC_LOG_ERROR) { + answer = false; + } + } + } + freeaddrinfo(ai); + return (answer); + + case EAI_NONAME: +#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) + case EAI_NODATA: +#endif /* if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) */ + if (!logged(namebuf, ERR_NO_ADDRESSES)) { + dns_zone_log(zone, ISC_LOG_ERROR, + "%s/MX '%s' (out of zone) " + "has no addresses records (A or AAAA)", + ownerbuf, namebuf); + add(namebuf, ERR_NO_ADDRESSES); + } + /* XXX950 make fatal for 9.5.0. */ + return (true); + + default: + if (!logged(namebuf, ERR_LOOKUP_FAILURE)) { + dns_zone_log(zone, ISC_LOG_WARNING, + "getaddrinfo(%s) failed: %s", namebuf, + gai_strerror(result)); + add(namebuf, ERR_LOOKUP_FAILURE); + } + return (true); + } +} + +static bool +checksrv(dns_zone_t *zone, const dns_name_t *name, const dns_name_t *owner) { + struct addrinfo hints, *ai, *cur; + char namebuf[DNS_NAME_FORMATSIZE + 1]; + char ownerbuf[DNS_NAME_FORMATSIZE]; + int result; + int level = ISC_LOG_ERROR; + bool answer = true; + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_CANONNAME; + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + dns_name_format(name, namebuf, sizeof(namebuf) - 1); + /* + * Turn off search. + */ + if (dns_name_countlabels(name) > 1U) { + strlcat(namebuf, ".", sizeof(namebuf)); + } + dns_name_format(owner, ownerbuf, sizeof(ownerbuf)); + + result = getaddrinfo(namebuf, NULL, &hints, &ai); + dns_name_format(name, namebuf, sizeof(namebuf) - 1); + switch (result) { + case 0: + /* + * Work around broken getaddrinfo() implementations that + * fail to set ai_canonname on first entry. + */ + cur = ai; + while (cur != NULL && cur->ai_canonname == NULL && + cur->ai_next != NULL) + { + cur = cur->ai_next; + } + if (cur != NULL && cur->ai_canonname != NULL && + strcasecmp(cur->ai_canonname, namebuf) != 0) + { + if ((zone_options & DNS_ZONEOPT_WARNSRVCNAME) != 0) { + level = ISC_LOG_WARNING; + } + if ((zone_options & DNS_ZONEOPT_IGNORESRVCNAME) == 0) { + if (!logged(namebuf, ERR_IS_SRVCNAME)) { + dns_zone_log(zone, level, + "%s/SRV '%s'" + " (out of zone) is a " + "CNAME '%s' (illegal)", + ownerbuf, namebuf, + cur->ai_canonname); + add(namebuf, ERR_IS_SRVCNAME); + } + if (level == ISC_LOG_ERROR) { + answer = false; + } + } + } + freeaddrinfo(ai); + return (answer); + + case EAI_NONAME: +#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) + case EAI_NODATA: +#endif /* if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) */ + if (!logged(namebuf, ERR_NO_ADDRESSES)) { + dns_zone_log(zone, ISC_LOG_ERROR, + "%s/SRV '%s' (out of zone) " + "has no addresses records (A or AAAA)", + ownerbuf, namebuf); + add(namebuf, ERR_NO_ADDRESSES); + } + /* XXX950 make fatal for 9.5.0. */ + return (true); + + default: + if (!logged(namebuf, ERR_LOOKUP_FAILURE)) { + dns_zone_log(zone, ISC_LOG_WARNING, + "getaddrinfo(%s) failed: %s", namebuf, + gai_strerror(result)); + add(namebuf, ERR_LOOKUP_FAILURE); + } + return (true); + } +} + +isc_result_t +setup_logging(isc_mem_t *mctx, FILE *errout, isc_log_t **logp) { + isc_logdestination_t destination; + isc_logconfig_t *logconfig = NULL; + isc_log_t *log = NULL; + + isc_log_create(mctx, &log, &logconfig); + isc_log_registercategories(log, categories); + isc_log_setcontext(log); + dns_log_init(log); + dns_log_setcontext(log); + cfg_log_init(log); + ns_log_init(log); + + destination.file.stream = errout; + destination.file.name = NULL; + destination.file.versions = ISC_LOG_ROLLNEVER; + destination.file.maximum_size = 0; + isc_log_createchannel(logconfig, "stderr", ISC_LOG_TOFILEDESC, + ISC_LOG_DYNAMIC, &destination, 0); + + RUNTIME_CHECK(isc_log_usechannel(logconfig, "stderr", NULL, NULL) == + ISC_R_SUCCESS); + + *logp = log; + return (ISC_R_SUCCESS); +} + +/*% load the zone */ +isc_result_t +load_zone(isc_mem_t *mctx, const char *zonename, const char *filename, + dns_masterformat_t fileformat, const char *classname, + dns_ttl_t maxttl, dns_zone_t **zonep) { + isc_result_t result; + dns_rdataclass_t rdclass; + isc_textregion_t region; + isc_buffer_t buffer; + dns_fixedname_t fixorigin; + dns_name_t *origin; + dns_zone_t *zone = NULL; + + REQUIRE(zonep == NULL || *zonep == NULL); + + if (debug) { + fprintf(stderr, "loading \"%s\" from \"%s\" class \"%s\"\n", + zonename, filename, classname); + } + + CHECK(dns_zone_create(&zone, mctx)); + + dns_zone_settype(zone, dns_zone_primary); + + isc_buffer_constinit(&buffer, zonename, strlen(zonename)); + isc_buffer_add(&buffer, strlen(zonename)); + origin = dns_fixedname_initname(&fixorigin); + CHECK(dns_name_fromtext(origin, &buffer, dns_rootname, 0, NULL)); + CHECK(dns_zone_setorigin(zone, origin)); + dns_zone_setdbtype(zone, 1, (const char *const *)dbtype); + if (strcmp(filename, "-") == 0) { + CHECK(dns_zone_setstream(zone, stdin, fileformat, + &dns_master_style_default)); + } else { + CHECK(dns_zone_setfile(zone, filename, fileformat, + &dns_master_style_default)); + } + if (journal != NULL) { + CHECK(dns_zone_setjournal(zone, journal)); + } + + DE_CONST(classname, region.base); + region.length = strlen(classname); + CHECK(dns_rdataclass_fromtext(&rdclass, ®ion)); + + dns_zone_setclass(zone, rdclass); + dns_zone_setoption(zone, zone_options, true); + dns_zone_setoption(zone, DNS_ZONEOPT_NOMERGE, nomerge); + + dns_zone_setmaxttl(zone, maxttl); + + if (docheckmx) { + dns_zone_setcheckmx(zone, checkmx); + } + if (docheckns) { + dns_zone_setcheckns(zone, checkns); + } + if (dochecksrv) { + dns_zone_setchecksrv(zone, checksrv); + } + + CHECK(dns_zone_load(zone, false)); + + if (zonep != NULL) { + *zonep = zone; + zone = NULL; + } + +cleanup: + if (zone != NULL) { + dns_zone_detach(&zone); + } + return (result); +} + +/*% dump the zone */ +isc_result_t +dump_zone(const char *zonename, dns_zone_t *zone, const char *filename, + dns_masterformat_t fileformat, const dns_master_style_t *style, + const uint32_t rawversion) { + isc_result_t result; + FILE *output = stdout; + const char *flags; + + flags = (fileformat == dns_masterformat_text) ? "w" : "wb"; + + if (debug) { + if (filename != NULL && strcmp(filename, "-") != 0) { + fprintf(stderr, "dumping \"%s\" to \"%s\"\n", zonename, + filename); + } else { + fprintf(stderr, "dumping \"%s\"\n", zonename); + } + } + + if (filename != NULL && strcmp(filename, "-") != 0) { + result = isc_stdio_open(filename, flags, &output); + + if (result != ISC_R_SUCCESS) { + fprintf(stderr, + "could not open output " + "file \"%s\" for writing\n", + filename); + return (ISC_R_FAILURE); + } + } + + result = dns_zone_dumptostream(zone, output, fileformat, style, + rawversion); + if (output != stdout) { + (void)isc_stdio_close(output); + } + + return (result); +} diff --git a/bin/check/check-tool.h b/bin/check/check-tool.h new file mode 100644 index 0000000..64ac9e7 --- /dev/null +++ b/bin/check/check-tool.h @@ -0,0 +1,52 @@ +/* + * 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 + +/*! \file */ + +#include <inttypes.h> +#include <stdbool.h> + +#include <isc/lang.h> +#include <isc/stdio.h> +#include <isc/types.h> + +#include <dns/masterdump.h> +#include <dns/types.h> +#include <dns/zone.h> + +ISC_LANG_BEGINDECLS + +isc_result_t +setup_logging(isc_mem_t *mctx, FILE *errout, isc_log_t **logp); + +isc_result_t +load_zone(isc_mem_t *mctx, const char *zonename, const char *filename, + dns_masterformat_t fileformat, const char *classname, + dns_ttl_t maxttl, dns_zone_t **zonep); + +isc_result_t +dump_zone(const char *zonename, dns_zone_t *zone, const char *filename, + dns_masterformat_t fileformat, const dns_master_style_t *style, + const uint32_t rawversion); + +extern int debug; +extern const char *journal; +extern bool nomerge; +extern bool docheckmx; +extern bool docheckns; +extern bool dochecksrv; +extern dns_zoneopt_t zone_options; + +ISC_LANG_ENDDECLS diff --git a/bin/check/named-checkconf.c b/bin/check/named-checkconf.c new file mode 100644 index 0000000..fd7cfa5 --- /dev/null +++ b/bin/check/named-checkconf.c @@ -0,0 +1,754 @@ +/* + * 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. + */ + +/*! \file */ + +#include <errno.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> + +#include <isc/attributes.h> +#include <isc/commandline.h> +#include <isc/dir.h> +#include <isc/hash.h> +#include <isc/log.h> +#include <isc/mem.h> +#include <isc/print.h> +#include <isc/result.h> +#include <isc/string.h> +#include <isc/util.h> + +#include <dns/db.h> +#include <dns/fixedname.h> +#include <dns/log.h> +#include <dns/name.h> +#include <dns/rdataclass.h> +#include <dns/rootns.h> +#include <dns/zone.h> + +#include <isccfg/grammar.h> +#include <isccfg/namedconf.h> + +#include <bind9/check.h> + +#include "check-tool.h" + +static const char *program = "named-checkconf"; + +static bool loadplugins = true; + +isc_log_t *logc = NULL; + +#define CHECK(r) \ + do { \ + result = (r); \ + if (result != ISC_R_SUCCESS) \ + goto cleanup; \ + } while (0) + +/*% usage */ +noreturn static void +usage(void); + +static void +usage(void) { + fprintf(stderr, + "usage: %s [-chijlvz] [-p [-x]] [-t directory] " + "[named.conf]\n", + program); + exit(1); +} + +/*% directory callback */ +static isc_result_t +directory_callback(const char *clausename, const cfg_obj_t *obj, void *arg) { + isc_result_t result; + const char *directory; + + REQUIRE(strcasecmp("directory", clausename) == 0); + + UNUSED(arg); + UNUSED(clausename); + + /* + * Change directory. + */ + directory = cfg_obj_asstring(obj); + result = isc_dir_chdir(directory); + if (result != ISC_R_SUCCESS) { + cfg_obj_log(obj, logc, ISC_LOG_ERROR, + "change directory to '%s' failed: %s\n", directory, + isc_result_totext(result)); + return (result); + } + + return (ISC_R_SUCCESS); +} + +static bool +get_maps(const cfg_obj_t **maps, const char *name, const cfg_obj_t **obj) { + int i; + for (i = 0;; i++) { + if (maps[i] == NULL) { + return (false); + } + if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS) { + return (true); + } + } +} + +static bool +get_checknames(const cfg_obj_t **maps, const cfg_obj_t **obj) { + const cfg_listelt_t *element; + const cfg_obj_t *checknames; + const cfg_obj_t *type; + const cfg_obj_t *value; + isc_result_t result; + int i; + + for (i = 0;; i++) { + if (maps[i] == NULL) { + return (false); + } + checknames = NULL; + result = cfg_map_get(maps[i], "check-names", &checknames); + if (result != ISC_R_SUCCESS) { + continue; + } + if (checknames != NULL && !cfg_obj_islist(checknames)) { + *obj = checknames; + return (true); + } + 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), "primary") != + 0) && + (strcasecmp(cfg_obj_asstring(type), "master") != 0)) + { + continue; + } + *obj = cfg_tuple_get(value, "mode"); + return (true); + } + } +} + +static isc_result_t +configure_hint(const char *zfile, const char *zclass, isc_mem_t *mctx) { + isc_result_t result; + dns_db_t *db = NULL; + dns_rdataclass_t rdclass; + isc_textregion_t r; + + if (zfile == NULL) { + return (ISC_R_FAILURE); + } + + DE_CONST(zclass, r.base); + r.length = strlen(zclass); + result = dns_rdataclass_fromtext(&rdclass, &r); + if (result != ISC_R_SUCCESS) { + return (result); + } + + result = dns_rootns_create(mctx, rdclass, zfile, &db); + if (result != ISC_R_SUCCESS) { + return (result); + } + + dns_db_detach(&db); + return (ISC_R_SUCCESS); +} + +/*% configure the zone */ +static isc_result_t +configure_zone(const char *vclass, const char *view, const cfg_obj_t *zconfig, + const cfg_obj_t *vconfig, const cfg_obj_t *config, + isc_mem_t *mctx, bool list) { + int i = 0; + isc_result_t result; + const char *zclass; + const char *zname; + const char *zfile = NULL; + const cfg_obj_t *maps[4]; + const cfg_obj_t *primariesobj = NULL; + const cfg_obj_t *inviewobj = NULL; + const cfg_obj_t *zoptions = NULL; + const cfg_obj_t *classobj = NULL; + const cfg_obj_t *typeobj = NULL; + const cfg_obj_t *fileobj = NULL; + const cfg_obj_t *dlzobj = NULL; + const cfg_obj_t *dbobj = NULL; + const cfg_obj_t *obj = NULL; + const cfg_obj_t *fmtobj = NULL; + dns_masterformat_t masterformat; + dns_ttl_t maxttl = 0; + + zone_options = DNS_ZONEOPT_CHECKNS | DNS_ZONEOPT_MANYERRORS; + + zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); + classobj = cfg_tuple_get(zconfig, "class"); + if (!cfg_obj_isstring(classobj)) { + zclass = vclass; + } else { + zclass = cfg_obj_asstring(classobj); + } + + zoptions = cfg_tuple_get(zconfig, "options"); + maps[i++] = zoptions; + if (vconfig != NULL) { + maps[i++] = cfg_tuple_get(vconfig, "options"); + } + if (config != NULL) { + cfg_map_get(config, "options", &obj); + if (obj != NULL) { + maps[i++] = obj; + } + } + maps[i] = NULL; + + cfg_map_get(zoptions, "in-view", &inviewobj); + if (inviewobj != NULL && list) { + const char *inview = cfg_obj_asstring(inviewobj); + printf("%s %s %s in-view %s\n", zname, zclass, view, inview); + } + if (inviewobj != NULL) { + return (ISC_R_SUCCESS); + } + + cfg_map_get(zoptions, "type", &typeobj); + if (typeobj == NULL) { + return (ISC_R_FAILURE); + } + + if (list) { + const char *ztype = cfg_obj_asstring(typeobj); + printf("%s %s %s %s\n", zname, zclass, view, ztype); + return (ISC_R_SUCCESS); + } + + /* + * Skip checks when using an alternate data source. + */ + cfg_map_get(zoptions, "database", &dbobj); + if (dbobj != NULL && strcmp("rbt", cfg_obj_asstring(dbobj)) != 0 && + strcmp("rbt64", cfg_obj_asstring(dbobj)) != 0) + { + return (ISC_R_SUCCESS); + } + + cfg_map_get(zoptions, "dlz", &dlzobj); + if (dlzobj != NULL) { + return (ISC_R_SUCCESS); + } + + cfg_map_get(zoptions, "file", &fileobj); + if (fileobj != NULL) { + zfile = cfg_obj_asstring(fileobj); + } + + /* + * Check hints files for hint zones. + * Skip loading checks for any type other than + * master and redirect + */ + if (strcasecmp(cfg_obj_asstring(typeobj), "hint") == 0) { + return (configure_hint(zfile, zclass, mctx)); + } else if ((strcasecmp(cfg_obj_asstring(typeobj), "primary") != 0) && + (strcasecmp(cfg_obj_asstring(typeobj), "master") != 0) && + (strcasecmp(cfg_obj_asstring(typeobj), "redirect") != 0)) + { + return (ISC_R_SUCCESS); + } + + /* + * Is the redirect zone configured as a secondary? + */ + if (strcasecmp(cfg_obj_asstring(typeobj), "redirect") == 0) { + cfg_map_get(zoptions, "primaries", &primariesobj); + if (primariesobj == NULL) { + cfg_map_get(zoptions, "masters", &primariesobj); + } + + if (primariesobj != NULL) { + return (ISC_R_SUCCESS); + } + } + + if (zfile == NULL) { + return (ISC_R_FAILURE); + } + + obj = NULL; + if (get_maps(maps, "check-dup-records", &obj)) { + if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { + zone_options |= DNS_ZONEOPT_CHECKDUPRR; + zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL; + } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { + zone_options |= DNS_ZONEOPT_CHECKDUPRR; + zone_options |= DNS_ZONEOPT_CHECKDUPRRFAIL; + } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { + zone_options &= ~DNS_ZONEOPT_CHECKDUPRR; + zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL; + } else { + UNREACHABLE(); + } + } else { + zone_options |= DNS_ZONEOPT_CHECKDUPRR; + zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL; + } + + obj = NULL; + if (get_maps(maps, "check-mx", &obj)) { + if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { + zone_options |= DNS_ZONEOPT_CHECKMX; + zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; + } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { + zone_options |= DNS_ZONEOPT_CHECKMX; + zone_options |= DNS_ZONEOPT_CHECKMXFAIL; + } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { + zone_options &= ~DNS_ZONEOPT_CHECKMX; + zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; + } else { + UNREACHABLE(); + } + } else { + zone_options |= DNS_ZONEOPT_CHECKMX; + zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; + } + + obj = NULL; + if (get_maps(maps, "check-integrity", &obj)) { + if (cfg_obj_asboolean(obj)) { + zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; + } else { + zone_options &= ~DNS_ZONEOPT_CHECKINTEGRITY; + } + } else { + zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; + } + + obj = NULL; + if (get_maps(maps, "check-mx-cname", &obj)) { + if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { + zone_options |= DNS_ZONEOPT_WARNMXCNAME; + zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; + } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { + zone_options &= ~DNS_ZONEOPT_WARNMXCNAME; + zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; + } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { + zone_options |= DNS_ZONEOPT_WARNMXCNAME; + zone_options |= DNS_ZONEOPT_IGNOREMXCNAME; + } else { + UNREACHABLE(); + } + } else { + zone_options |= DNS_ZONEOPT_WARNMXCNAME; + zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; + } + + obj = NULL; + if (get_maps(maps, "check-srv-cname", &obj)) { + if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { + zone_options |= DNS_ZONEOPT_WARNSRVCNAME; + zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; + } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { + zone_options &= ~DNS_ZONEOPT_WARNSRVCNAME; + zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; + } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { + zone_options |= DNS_ZONEOPT_WARNSRVCNAME; + zone_options |= DNS_ZONEOPT_IGNORESRVCNAME; + } else { + UNREACHABLE(); + } + } else { + zone_options |= DNS_ZONEOPT_WARNSRVCNAME; + zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; + } + + obj = NULL; + if (get_maps(maps, "check-sibling", &obj)) { + if (cfg_obj_asboolean(obj)) { + zone_options |= DNS_ZONEOPT_CHECKSIBLING; + } else { + zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; + } + } + + obj = NULL; + if (get_maps(maps, "check-spf", &obj)) { + if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { + zone_options |= DNS_ZONEOPT_CHECKSPF; + } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { + zone_options &= ~DNS_ZONEOPT_CHECKSPF; + } else { + UNREACHABLE(); + } + } else { + zone_options |= DNS_ZONEOPT_CHECKSPF; + } + + obj = NULL; + if (get_maps(maps, "check-wildcard", &obj)) { + if (cfg_obj_asboolean(obj)) { + zone_options |= DNS_ZONEOPT_CHECKWILDCARD; + } else { + zone_options &= ~DNS_ZONEOPT_CHECKWILDCARD; + } + } else { + zone_options |= DNS_ZONEOPT_CHECKWILDCARD; + } + + obj = NULL; + if (get_checknames(maps, &obj)) { + if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) { + zone_options |= DNS_ZONEOPT_CHECKNAMES; + zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; + } else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) { + zone_options |= DNS_ZONEOPT_CHECKNAMES; + zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL; + } else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) { + zone_options &= ~DNS_ZONEOPT_CHECKNAMES; + zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; + } else { + UNREACHABLE(); + } + } else { + zone_options |= DNS_ZONEOPT_CHECKNAMES; + zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL; + } + + masterformat = dns_masterformat_text; + fmtobj = NULL; + if (get_maps(maps, "masterfile-format", &fmtobj)) { + const char *masterformatstr = cfg_obj_asstring(fmtobj); + if (strcasecmp(masterformatstr, "text") == 0) { + masterformat = dns_masterformat_text; + } else if (strcasecmp(masterformatstr, "raw") == 0) { + masterformat = dns_masterformat_raw; + } else { + UNREACHABLE(); + } + } + + obj = NULL; + if (get_maps(maps, "max-zone-ttl", &obj)) { + maxttl = cfg_obj_asduration(obj); + zone_options |= DNS_ZONEOPT_CHECKTTL; + } + + result = load_zone(mctx, zname, zfile, masterformat, zclass, maxttl, + NULL); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "%s/%s/%s: %s\n", view, zname, zclass, + isc_result_totext(result)); + } + return (result); +} + +/*% configure a view */ +static isc_result_t +configure_view(const char *vclass, const char *view, const cfg_obj_t *config, + const cfg_obj_t *vconfig, isc_mem_t *mctx, bool list) { + const cfg_listelt_t *element; + const cfg_obj_t *voptions; + const cfg_obj_t *zonelist; + isc_result_t result = ISC_R_SUCCESS; + isc_result_t tresult; + + voptions = NULL; + if (vconfig != NULL) { + voptions = cfg_tuple_get(vconfig, "options"); + } + + 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)) + { + const cfg_obj_t *zconfig = cfg_listelt_value(element); + tresult = configure_zone(vclass, view, zconfig, vconfig, config, + mctx, list); + if (tresult != ISC_R_SUCCESS) { + result = tresult; + } + } + return (result); +} + +static isc_result_t +config_getclass(const cfg_obj_t *classobj, dns_rdataclass_t defclass, + dns_rdataclass_t *classp) { + isc_textregion_t r; + + if (!cfg_obj_isstring(classobj)) { + *classp = defclass; + return (ISC_R_SUCCESS); + } + DE_CONST(cfg_obj_asstring(classobj), r.base); + r.length = strlen(r.base); + return (dns_rdataclass_fromtext(classp, &r)); +} + +/*% load zones from the configuration */ +static isc_result_t +load_zones_fromconfig(const cfg_obj_t *config, isc_mem_t *mctx, + bool list_zones) { + const cfg_listelt_t *element; + const cfg_obj_t *views; + const cfg_obj_t *vconfig; + isc_result_t result = ISC_R_SUCCESS; + isc_result_t tresult; + + views = NULL; + + (void)cfg_map_get(config, "view", &views); + for (element = cfg_list_first(views); element != NULL; + element = cfg_list_next(element)) + { + const cfg_obj_t *classobj; + dns_rdataclass_t viewclass; + const char *vname; + char buf[sizeof("CLASS65535")]; + + vconfig = cfg_listelt_value(element); + if (vconfig == NULL) { + continue; + } + + classobj = cfg_tuple_get(vconfig, "class"); + tresult = config_getclass(classobj, dns_rdataclass_in, + &viewclass); + if (tresult != ISC_R_SUCCESS) { + CHECK(tresult); + } + + if (dns_rdataclass_ismeta(viewclass)) { + CHECK(ISC_R_FAILURE); + } + + dns_rdataclass_format(viewclass, buf, sizeof(buf)); + vname = cfg_obj_asstring(cfg_tuple_get(vconfig, "name")); + tresult = configure_view(buf, vname, config, vconfig, mctx, + list_zones); + if (tresult != ISC_R_SUCCESS) { + result = tresult; + } + } + + if (views == NULL) { + tresult = configure_view("IN", "_default", config, NULL, mctx, + list_zones); + if (tresult != ISC_R_SUCCESS) { + result = tresult; + } + } + +cleanup: + return (result); +} + +static void +output(void *closure, const char *text, int textlen) { + UNUSED(closure); + if (fwrite(text, 1, textlen, stdout) != (size_t)textlen) { + perror("fwrite"); + exit(1); + } +} + +/*% The main processing routine */ +int +main(int argc, char **argv) { + int c; + cfg_parser_t *parser = NULL; + cfg_obj_t *config = NULL; + const char *conffile = NULL; + isc_mem_t *mctx = NULL; + isc_result_t result; + int exit_status = 0; + bool load_zones = false; + bool list_zones = false; + bool print = false; + bool nodeprecate = false; + unsigned int flags = 0; + + isc_commandline_errprint = false; + + /* + * Process memory debugging argument first. + */ +#define CMDLINE_FLAGS "cdhijlm:t:pvxz" + while ((c = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { + switch (c) { + case 'm': + if (strcasecmp(isc_commandline_argument, "record") == 0) + { + isc_mem_debugging |= ISC_MEM_DEBUGRECORD; + } + if (strcasecmp(isc_commandline_argument, "trace") == 0) + { + isc_mem_debugging |= ISC_MEM_DEBUGTRACE; + } + if (strcasecmp(isc_commandline_argument, "usage") == 0) + { + isc_mem_debugging |= ISC_MEM_DEBUGUSAGE; + } + break; + default: + break; + } + } + isc_commandline_reset = true; + + isc_mem_create(&mctx); + + while ((c = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != EOF) { + switch (c) { + case 'c': + loadplugins = false; + break; + + case 'd': + debug++; + break; + + case 'i': + nodeprecate = true; + break; + + case 'j': + nomerge = false; + break; + + case 'l': + list_zones = true; + break; + + case 'm': + break; + + case 't': + result = isc_dir_chroot(isc_commandline_argument); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "isc_dir_chroot: %s\n", + isc_result_totext(result)); + exit(1); + } + break; + + case 'p': + print = true; + break; + + case 'v': + printf("%s\n", PACKAGE_VERSION); + exit(0); + + case 'x': + flags |= CFG_PRINTER_XKEY; + break; + + case 'z': + load_zones = true; + docheckmx = false; + docheckns = false; + dochecksrv = false; + break; + + case '?': + if (isc_commandline_option != '?') { + fprintf(stderr, "%s: invalid argument -%c\n", + program, isc_commandline_option); + } + FALLTHROUGH; + case 'h': + usage(); + + default: + fprintf(stderr, "%s: unhandled option -%c\n", program, + isc_commandline_option); + exit(1); + } + } + + if (((flags & CFG_PRINTER_XKEY) != 0) && !print) { + fprintf(stderr, "%s: -x cannot be used without -p\n", program); + exit(1); + } + if (print && list_zones) { + fprintf(stderr, "%s: -l cannot be used with -p\n", program); + exit(1); + } + + if (isc_commandline_index + 1 < argc) { + usage(); + } + if (argv[isc_commandline_index] != NULL) { + conffile = argv[isc_commandline_index]; + } + if (conffile == NULL || conffile[0] == '\0') { + conffile = NAMED_CONFFILE; + } + + RUNTIME_CHECK(setup_logging(mctx, stdout, &logc) == ISC_R_SUCCESS); + + RUNTIME_CHECK(cfg_parser_create(mctx, logc, &parser) == ISC_R_SUCCESS); + + if (nodeprecate) { + cfg_parser_setflags(parser, CFG_PCTX_NODEPRECATED, true); + } + cfg_parser_setcallback(parser, directory_callback, NULL); + + if (cfg_parse_file(parser, conffile, &cfg_type_namedconf, &config) != + ISC_R_SUCCESS) + { + exit(1); + } + + result = bind9_check_namedconf(config, loadplugins, nodeprecate, logc, + mctx); + if (result != ISC_R_SUCCESS) { + exit_status = 1; + } + + if (result == ISC_R_SUCCESS && (load_zones || list_zones)) { + result = load_zones_fromconfig(config, mctx, list_zones); + if (result != ISC_R_SUCCESS) { + exit_status = 1; + } + } + + if (print && exit_status == 0) { + cfg_printx(config, flags, output, NULL); + } + cfg_obj_destroy(parser, &config); + + cfg_parser_destroy(&parser); + + isc_log_destroy(&logc); + + isc_mem_destroy(&mctx); + + return (exit_status); +} diff --git a/bin/check/named-checkconf.rst b/bin/check/named-checkconf.rst new file mode 100644 index 0000000..b3065a5 --- /dev/null +++ b/bin/check/named-checkconf.rst @@ -0,0 +1,108 @@ +.. 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. + +.. highlight: console + +.. iscman:: named-checkconf +.. program:: named-checkconf +.. _man_named-checkconf: + +named-checkconf - named configuration file syntax checking tool +--------------------------------------------------------------- + +Synopsis +~~~~~~~~ + +:program:`named-checkconf` [**-chjlvz**] [**-p** [**-x** ]] [**-t** directory] {filename} + +Description +~~~~~~~~~~~ + +:program:`named-checkconf` checks the syntax, but not the semantics, of a +:iscman:`named` configuration file. The file, along with all files included by it, is parsed and checked for syntax +errors. If no file is specified, +|named_conf| is read by default. + +Note: files that :iscman:`named` reads in separate parser contexts, such as +``rndc.key`` and ``bind.keys``, are not automatically read by +:program:`named-checkconf`. Configuration errors in these files may cause +:iscman:`named` to fail to run, even if :program:`named-checkconf` was successful. +However, :program:`named-checkconf` can be run on these files explicitly. + +Options +~~~~~~~ + +.. option:: -h + + This option prints the usage summary and exits. + +.. option:: -j + + When loading a zonefile, this option instructs :iscman:`named` to read the journal if it exists. + +.. option:: -l + + This option lists all the configured zones. Each line of output contains the zone + name, class (e.g. IN), view, and type (e.g. primary or secondary). + +.. option:: -c + + This option specifies that only the "core" configuration should be checked. This suppresses the loading of + plugin modules, and causes all parameters to ``plugin`` statements to + be ignored. + +.. option:: -i + + This option ignores warnings on deprecated options. + +.. option:: -p + + This option prints out the :iscman:`named.conf` and included files in canonical form if + no errors were detected. See also the :option:`-x` option. + +.. option:: -t directory + + This option instructs :iscman:`named` to chroot to ``directory``, so that ``include`` directives in the + configuration file are processed as if run by a similarly chrooted + :iscman:`named`. + +.. option:: -v + + This option prints the version of the :program:`named-checkconf` program and exits. + +.. option:: -x + + When printing the configuration files in canonical form, this option obscures + shared secrets by replacing them with strings of question marks + (``?``). This allows the contents of :iscman:`named.conf` and related files + to be shared - for example, when submitting bug reports - + without compromising private data. This option cannot be used without + :option:`-p`. + +.. option:: -z + + This option performs a test load of all zones of type ``primary`` found in :iscman:`named.conf`. + +.. option:: filename + + This indicates the name of the configuration file to be checked. If not specified, + it defaults to |named_conf|. + +Return Values +~~~~~~~~~~~~~ + +:program:`named-checkconf` returns an exit status of 1 if errors were detected +and 0 otherwise. + +See Also +~~~~~~~~ + +:iscman:`named(8) <named>`, :iscman:`named-checkzone(8) <named-checkzone>`, BIND 9 Administrator Reference Manual. diff --git a/bin/check/named-checkzone.c b/bin/check/named-checkzone.c new file mode 100644 index 0000000..5c74660 --- /dev/null +++ b/bin/check/named-checkzone.c @@ -0,0 +1,569 @@ +/* + * 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. + */ + +/*! \file */ + +#include <inttypes.h> +#include <stdbool.h> +#include <stdlib.h> + +#include <isc/app.h> +#include <isc/attributes.h> +#include <isc/commandline.h> +#include <isc/dir.h> +#include <isc/file.h> +#include <isc/hash.h> +#include <isc/log.h> +#include <isc/mem.h> +#include <isc/print.h> +#include <isc/result.h> +#include <isc/string.h> +#include <isc/task.h> +#include <isc/timer.h> +#include <isc/util.h> + +#include <dns/db.h> +#include <dns/fixedname.h> +#include <dns/log.h> +#include <dns/master.h> +#include <dns/masterdump.h> +#include <dns/name.h> +#include <dns/rdataclass.h> +#include <dns/rdataset.h> +#include <dns/types.h> +#include <dns/zone.h> + +#include "check-tool.h" + +static int quiet = 0; +static isc_mem_t *mctx = NULL; +dns_zone_t *zone = NULL; +dns_zonetype_t zonetype = dns_zone_primary; +static int dumpzone = 0; +static const char *output_filename; +static const char *prog_name = NULL; +static const dns_master_style_t *outputstyle = NULL; +static enum { progmode_check, progmode_compile } progmode; + +#define ERRRET(result, function) \ + do { \ + if (result != ISC_R_SUCCESS) { \ + if (!quiet) \ + fprintf(stderr, "%s() returned %s\n", \ + function, isc_result_totext(result)); \ + return (result); \ + } \ + } while (0) + +noreturn static void +usage(void); + +static void +usage(void) { + fprintf(stderr, + "usage: %s [-djqvD] [-c class] " + "[-f inputformat] [-F outputformat] [-J filename] " + "[-s (full|relative)] [-t directory] [-w directory] " + "[-k (ignore|warn|fail)] [-m (ignore|warn|fail)] " + "[-n (ignore|warn|fail)] [-r (ignore|warn|fail)] " + "[-i (full|full-sibling|local|local-sibling|none)] " + "[-M (ignore|warn|fail)] [-S (ignore|warn|fail)] " + "[-W (ignore|warn)] " + "%s zonename [ (filename|-) ]\n", + prog_name, + progmode == progmode_check ? "[-o filename]" : "-o filename"); + exit(1); +} + +static void +destroy(void) { + if (zone != NULL) { + dns_zone_detach(&zone); + } +} + +/*% main processing routine */ +int +main(int argc, char **argv) { + int c; + char *origin = NULL; + const char *filename = NULL; + isc_log_t *lctx = NULL; + isc_result_t result; + char classname_in[] = "IN"; + char *classname = classname_in; + const char *workdir = NULL; + const char *inputformatstr = NULL; + const char *outputformatstr = NULL; + dns_masterformat_t inputformat = dns_masterformat_text; + dns_masterformat_t outputformat = dns_masterformat_text; + dns_masterrawheader_t header; + uint32_t rawversion = 1, serialnum = 0; + dns_ttl_t maxttl = 0; + bool snset = false; + bool logdump = false; + FILE *errout = stdout; + char *endp; + + /* + * Uncomment the following line if memory debugging is needed: + * isc_mem_debugging |= ISC_MEM_DEBUGRECORD; + */ + + outputstyle = &dns_master_style_full; + + prog_name = strrchr(argv[0], '/'); + if (prog_name == NULL) { + prog_name = strrchr(argv[0], '\\'); + } + if (prog_name != NULL) { + prog_name++; + } else { + prog_name = argv[0]; + } + /* + * Libtool doesn't preserve the program name prior to final + * installation. Remove the libtool prefix ("lt-"). + */ + if (strncmp(prog_name, "lt-", 3) == 0) { + prog_name += 3; + } + +#define PROGCMP(X) \ + (strcasecmp(prog_name, X) == 0 || strcasecmp(prog_name, X ".exe") == 0) + + if (PROGCMP("named-checkzone")) { + progmode = progmode_check; + } else if (PROGCMP("named-compilezone")) { + progmode = progmode_compile; + } else { + UNREACHABLE(); + } + + /* Compilation specific defaults */ + if (progmode == progmode_compile) { + zone_options |= (DNS_ZONEOPT_CHECKNS | DNS_ZONEOPT_FATALNS | + DNS_ZONEOPT_CHECKSPF | DNS_ZONEOPT_CHECKDUPRR | + DNS_ZONEOPT_CHECKNAMES | + DNS_ZONEOPT_CHECKNAMESFAIL | + DNS_ZONEOPT_CHECKWILDCARD); + } else { + zone_options |= (DNS_ZONEOPT_CHECKDUPRR | DNS_ZONEOPT_CHECKSPF); + } + +#define ARGCMP(X) (strcmp(isc_commandline_argument, X) == 0) + + isc_commandline_errprint = false; + + while ((c = isc_commandline_parse(argc, argv, + "c:df:hi:jJ:k:L:l:m:n:qr:s:t:o:vw:DF:" + "M:S:T:W:")) != EOF) + { + switch (c) { + case 'c': + classname = isc_commandline_argument; + break; + + case 'd': + debug++; + break; + + case 'i': + if (ARGCMP("full")) { + zone_options |= DNS_ZONEOPT_CHECKINTEGRITY | + DNS_ZONEOPT_CHECKSIBLING; + docheckmx = true; + docheckns = true; + dochecksrv = true; + } else if (ARGCMP("full-sibling")) { + zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; + zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; + docheckmx = true; + docheckns = true; + dochecksrv = true; + } else if (ARGCMP("local")) { + zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; + zone_options |= DNS_ZONEOPT_CHECKSIBLING; + docheckmx = false; + docheckns = false; + dochecksrv = false; + } else if (ARGCMP("local-sibling")) { + zone_options |= DNS_ZONEOPT_CHECKINTEGRITY; + zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; + docheckmx = false; + docheckns = false; + dochecksrv = false; + } else if (ARGCMP("none")) { + zone_options &= ~DNS_ZONEOPT_CHECKINTEGRITY; + zone_options &= ~DNS_ZONEOPT_CHECKSIBLING; + docheckmx = false; + docheckns = false; + dochecksrv = false; + } else { + fprintf(stderr, "invalid argument to -i: %s\n", + isc_commandline_argument); + exit(1); + } + break; + + case 'f': + inputformatstr = isc_commandline_argument; + break; + + case 'F': + outputformatstr = isc_commandline_argument; + break; + + case 'j': + nomerge = false; + break; + + case 'J': + journal = isc_commandline_argument; + nomerge = false; + break; + + case 'k': + if (ARGCMP("warn")) { + zone_options |= DNS_ZONEOPT_CHECKNAMES; + zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL; + } else if (ARGCMP("fail")) { + zone_options |= DNS_ZONEOPT_CHECKNAMES | + DNS_ZONEOPT_CHECKNAMESFAIL; + } else if (ARGCMP("ignore")) { + zone_options &= ~(DNS_ZONEOPT_CHECKNAMES | + DNS_ZONEOPT_CHECKNAMESFAIL); + } else { + fprintf(stderr, "invalid argument to -k: %s\n", + isc_commandline_argument); + exit(1); + } + break; + + case 'L': + snset = true; + endp = NULL; + serialnum = strtol(isc_commandline_argument, &endp, 0); + if (*endp != '\0') { + fprintf(stderr, "source serial number " + "must be numeric"); + exit(1); + } + break; + + case 'l': + zone_options |= DNS_ZONEOPT_CHECKTTL; + endp = NULL; + maxttl = strtol(isc_commandline_argument, &endp, 0); + if (*endp != '\0') { + fprintf(stderr, "maximum TTL " + "must be numeric"); + exit(1); + } + break; + + case 'n': + if (ARGCMP("ignore")) { + zone_options &= ~(DNS_ZONEOPT_CHECKNS | + DNS_ZONEOPT_FATALNS); + } else if (ARGCMP("warn")) { + zone_options |= DNS_ZONEOPT_CHECKNS; + zone_options &= ~DNS_ZONEOPT_FATALNS; + } else if (ARGCMP("fail")) { + zone_options |= DNS_ZONEOPT_CHECKNS | + DNS_ZONEOPT_FATALNS; + } else { + fprintf(stderr, "invalid argument to -n: %s\n", + isc_commandline_argument); + exit(1); + } + break; + + case 'm': + if (ARGCMP("warn")) { + zone_options |= DNS_ZONEOPT_CHECKMX; + zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL; + } else if (ARGCMP("fail")) { + zone_options |= DNS_ZONEOPT_CHECKMX | + DNS_ZONEOPT_CHECKMXFAIL; + } else if (ARGCMP("ignore")) { + zone_options &= ~(DNS_ZONEOPT_CHECKMX | + DNS_ZONEOPT_CHECKMXFAIL); + } else { + fprintf(stderr, "invalid argument to -m: %s\n", + isc_commandline_argument); + exit(1); + } + break; + + case 'o': + output_filename = isc_commandline_argument; + break; + + case 'q': + quiet++; + break; + + case 'r': + if (ARGCMP("warn")) { + zone_options |= DNS_ZONEOPT_CHECKDUPRR; + zone_options &= ~DNS_ZONEOPT_CHECKDUPRRFAIL; + } else if (ARGCMP("fail")) { + zone_options |= DNS_ZONEOPT_CHECKDUPRR | + DNS_ZONEOPT_CHECKDUPRRFAIL; + } else if (ARGCMP("ignore")) { + zone_options &= ~(DNS_ZONEOPT_CHECKDUPRR | + DNS_ZONEOPT_CHECKDUPRRFAIL); + } else { + fprintf(stderr, "invalid argument to -r: %s\n", + isc_commandline_argument); + exit(1); + } + break; + + case 's': + if (ARGCMP("full")) { + outputstyle = &dns_master_style_full; + } else if (ARGCMP("relative")) { + outputstyle = &dns_master_style_default; + } else { + fprintf(stderr, + "unknown or unsupported style: %s\n", + isc_commandline_argument); + exit(1); + } + break; + + case 't': + result = isc_dir_chroot(isc_commandline_argument); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "isc_dir_chroot: %s: %s\n", + isc_commandline_argument, + isc_result_totext(result)); + exit(1); + } + break; + + case 'v': + printf("%s\n", PACKAGE_VERSION); + exit(0); + + case 'w': + workdir = isc_commandline_argument; + break; + + case 'D': + dumpzone++; + break; + + case 'M': + if (ARGCMP("fail")) { + zone_options &= ~DNS_ZONEOPT_WARNMXCNAME; + zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; + } else if (ARGCMP("warn")) { + zone_options |= DNS_ZONEOPT_WARNMXCNAME; + zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME; + } else if (ARGCMP("ignore")) { + zone_options |= DNS_ZONEOPT_WARNMXCNAME; + zone_options |= DNS_ZONEOPT_IGNOREMXCNAME; + } else { + fprintf(stderr, "invalid argument to -M: %s\n", + isc_commandline_argument); + exit(1); + } + break; + + case 'S': + if (ARGCMP("fail")) { + zone_options &= ~DNS_ZONEOPT_WARNSRVCNAME; + zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; + } else if (ARGCMP("warn")) { + zone_options |= DNS_ZONEOPT_WARNSRVCNAME; + zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME; + } else if (ARGCMP("ignore")) { + zone_options |= DNS_ZONEOPT_WARNSRVCNAME; + zone_options |= DNS_ZONEOPT_IGNORESRVCNAME; + } else { + fprintf(stderr, "invalid argument to -S: %s\n", + isc_commandline_argument); + exit(1); + } + break; + + case 'T': + if (ARGCMP("warn")) { + zone_options |= DNS_ZONEOPT_CHECKSPF; + } else if (ARGCMP("ignore")) { + zone_options &= ~DNS_ZONEOPT_CHECKSPF; + } else { + fprintf(stderr, "invalid argument to -T: %s\n", + isc_commandline_argument); + exit(1); + } + break; + + case 'W': + if (ARGCMP("warn")) { + zone_options |= DNS_ZONEOPT_CHECKWILDCARD; + } else if (ARGCMP("ignore")) { + zone_options &= ~DNS_ZONEOPT_CHECKWILDCARD; + } + break; + + case '?': + if (isc_commandline_option != '?') { + fprintf(stderr, "%s: invalid argument -%c\n", + prog_name, isc_commandline_option); + } + FALLTHROUGH; + case 'h': + usage(); + + default: + fprintf(stderr, "%s: unhandled option -%c\n", prog_name, + isc_commandline_option); + exit(1); + } + } + + if (workdir != NULL) { + result = isc_dir_chdir(workdir); + if (result != ISC_R_SUCCESS) { + fprintf(stderr, "isc_dir_chdir: %s: %s\n", workdir, + isc_result_totext(result)); + exit(1); + } + } + + if (inputformatstr != NULL) { + if (strcasecmp(inputformatstr, "text") == 0) { + inputformat = dns_masterformat_text; + } else if (strcasecmp(inputformatstr, "raw") == 0) { + inputformat = dns_masterformat_raw; + } else if (strncasecmp(inputformatstr, "raw=", 4) == 0) { + inputformat = dns_masterformat_raw; + fprintf(stderr, "WARNING: input format raw, version " + "ignored\n"); + } else { + fprintf(stderr, "unknown file format: %s\n", + inputformatstr); + exit(1); + } + } + + if (outputformatstr != NULL) { + if (strcasecmp(outputformatstr, "text") == 0) { + outputformat = dns_masterformat_text; + } else if (strcasecmp(outputformatstr, "raw") == 0) { + outputformat = dns_masterformat_raw; + } else if (strncasecmp(outputformatstr, "raw=", 4) == 0) { + char *end; + + outputformat = dns_masterformat_raw; + rawversion = strtol(outputformatstr + 4, &end, 10); + if (end == outputformatstr + 4 || *end != '\0' || + rawversion > 1U) + { + fprintf(stderr, "unknown raw format version\n"); + exit(1); + } + } else { + fprintf(stderr, "unknown file format: %s\n", + outputformatstr); + exit(1); + } + } + + if (progmode == progmode_compile) { + dumpzone = 1; /* always dump */ + logdump = !quiet; + if (output_filename == NULL) { + fprintf(stderr, "output file required, but not " + "specified\n"); + usage(); + } + } + + if (output_filename != NULL) { + dumpzone = 1; + } + + /* + * If we are printing to stdout then send the informational + * output to stderr. + */ + if (dumpzone && + (output_filename == NULL || strcmp(output_filename, "-") == 0 || + strcmp(output_filename, "/dev/fd/1") == 0 || + strcmp(output_filename, "/dev/stdout") == 0)) + { + errout = stderr; + logdump = false; + } + + if (argc - isc_commandline_index < 1 || + argc - isc_commandline_index > 2) + { + usage(); + } + + isc_mem_create(&mctx); + if (!quiet) { + RUNTIME_CHECK(setup_logging(mctx, errout, &lctx) == + ISC_R_SUCCESS); + } + + origin = argv[isc_commandline_index++]; + + if (isc_commandline_index == argc) { + /* "-" will be interpreted as stdin */ + filename = "-"; + } else { + filename = argv[isc_commandline_index]; + } + + isc_commandline_index++; + + result = load_zone(mctx, origin, filename, inputformat, classname, + maxttl, &zone); + + if (snset) { + dns_master_initrawheader(&header); + header.flags = DNS_MASTERRAW_SOURCESERIALSET; + header.sourceserial = serialnum; + dns_zone_setrawdata(zone, &header); + } + + if (result == ISC_R_SUCCESS && dumpzone) { + if (logdump) { + fprintf(errout, "dump zone to %s...", output_filename); + fflush(errout); + } + result = dump_zone(origin, zone, output_filename, outputformat, + outputstyle, rawversion); + if (logdump) { + fprintf(errout, "done\n"); + } + } + + if (!quiet && result == ISC_R_SUCCESS) { + fprintf(errout, "OK\n"); + } + destroy(); + if (lctx != NULL) { + isc_log_destroy(&lctx); + } + isc_mem_destroy(&mctx); + + return ((result == ISC_R_SUCCESS) ? 0 : 1); +} diff --git a/bin/check/named-checkzone.rst b/bin/check/named-checkzone.rst new file mode 100644 index 0000000..563752f --- /dev/null +++ b/bin/check/named-checkzone.rst @@ -0,0 +1,222 @@ +.. 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. + +.. highlight: console + +.. BEWARE: Do not forget to edit also named-compilezone.rst! + +.. iscman:: named-checkzone +.. program:: named-checkzone +.. _man_named-checkzone: + +named-checkzone - zone file validation tool +------------------------------------------- + +Synopsis +~~~~~~~~ + +:program:`named-checkzone` [**-d**] [**-h**] [**-j**] [**-q**] [**-v**] [**-c** class] [**-f** format] [**-F** format] [**-J** filename] [**-i** mode] [**-k** mode] [**-m** mode] [**-M** mode] [**-n** mode] [**-l** ttl] [**-L** serial] [**-o** filename] [**-r** mode] [**-s** style] [**-S** mode] [**-t** directory] [**-T** mode] [**-w** directory] [**-D**] [**-W** mode] {zonename} {filename} + +Description +~~~~~~~~~~~ + +:program:`named-checkzone` checks the syntax and integrity of a zone file. It +performs the same checks as :iscman:`named` does when loading a zone. This +makes :program:`named-checkzone` useful for checking zone files before +configuring them into a name server. + +Options +~~~~~~~ + +.. option:: -d + + This option enables debugging. + +.. option:: -h + + This option prints the usage summary and exits. + +.. option:: -q + + This option sets quiet mode, which only sets an exit code to indicate + successful or failed completion. + +.. option:: -v + + This option prints the version of the :program:`named-checkzone` program and exits. + +.. option:: -j + + When loading a zone file, this option tells :iscman:`named` to read the journal if it exists. The journal + file name is assumed to be the zone file name with the + string ``.jnl`` appended. + +.. option:: -J filename + + When loading the zone file, this option tells :iscman:`named` to read the journal from the given file, if + it exists. This implies :option:`-j`. + +.. option:: -c class + + This option specifies the class of the zone. If not specified, ``IN`` is assumed. + +.. option:: -i mode + + This option performs post-load zone integrity checks. Possible modes are + ``full`` (the default), ``full-sibling``, ``local``, + ``local-sibling``, and ``none``. + + Mode ``full`` checks that MX records refer to A or AAAA records + (both in-zone and out-of-zone hostnames). Mode ``local`` only + checks MX records which refer to in-zone hostnames. + + Mode ``full`` checks that SRV records refer to A or AAAA records + (both in-zone and out-of-zone hostnames). Mode ``local`` only + checks SRV records which refer to in-zone hostnames. + + Mode ``full`` checks that delegation NS records refer to A or AAAA + records (both in-zone and out-of-zone hostnames). It also checks that + glue address records in the zone match those advertised by the child. + Mode ``local`` only checks NS records which refer to in-zone + hostnames or verifies that some required glue exists, i.e., when the + name server is in a child zone. + + Modes ``full-sibling`` and ``local-sibling`` disable sibling glue + checks, but are otherwise the same as ``full`` and ``local``, + respectively. + + Mode ``none`` disables the checks. + +.. option:: -f format + + This option specifies the format of the zone file. Possible formats are + ``text`` (the default), and ``raw``. + +.. option:: -F format + + This option specifies the format of the output file specified. For + :program:`named-checkzone`, this does not have any effect unless it dumps + the zone contents. + + Possible formats are ``text`` (the default), which is the standard + textual representation of the zone, and ``raw`` and ``raw=N``, which + store the zone in a binary format for rapid loading by :iscman:`named`. + ``raw=N`` specifies the format version of the raw zone file: if ``N`` is + 0, the raw file can be read by any version of :iscman:`named`; if N is 1, the + file can only be read by release 9.9.0 or higher. The default is 1. + +.. option:: -k mode + + This option performs ``check-names`` checks with the specified failure mode. + Possible modes are ``fail``, ``warn`` (the default), and ``ignore``. + +.. option:: -l ttl + + This option sets a maximum permissible TTL for the input file. Any record with a + TTL higher than this value causes the zone to be rejected. This + is similar to using the ``max-zone-ttl`` option in :iscman:`named.conf`. + +.. option:: -L serial + + When compiling a zone to ``raw`` format, this option sets the "source + serial" value in the header to the specified serial number. This is + expected to be used primarily for testing purposes. + +.. option:: -m mode + + This option specifies whether MX records should be checked to see if they are + addresses. Possible modes are ``fail``, ``warn`` (the default), and + ``ignore``. + +.. option:: -M mode + + This option checks whether a MX record refers to a CNAME. Possible modes are + ``fail``, ``warn`` (the default), and ``ignore``. + +.. option:: -n mode + + This option specifies whether NS records should be checked to see if they are + addresses. Possible modes are ``fail``, ``warn`` (the default), and ``ignore``. + +.. option:: -o filename + + This option writes the zone output to ``filename``. If ``filename`` is ``-``, then + the zone output is written to standard output. + +.. option:: -r mode + + This option checks for records that are treated as different by DNSSEC but are + semantically equal in plain DNS. Possible modes are ``fail``, + ``warn`` (the default), and ``ignore``. + +.. option:: -s style + + This option specifies the style of the dumped zone file. Possible styles are + ``full`` (the default) and ``relative``. The ``full`` format is most + suitable for processing automatically by a separate script. + The relative format is more human-readable and is thus + suitable for editing by hand. This does not have any effect unless it dumps + the zone contents. It also does not have any meaning if the output format + is not text. + +.. option:: -S mode + + This option checks whether an SRV record refers to a CNAME. Possible modes are + ``fail``, ``warn`` (the default), and ``ignore``. + +.. option:: -t directory + + This option tells :iscman:`named` to chroot to ``directory``, so that ``include`` directives in the + configuration file are processed as if run by a similarly chrooted + :iscman:`named`. + +.. option:: -T mode + + This option checks whether Sender Policy Framework (SPF) records exist and issues a + warning if an SPF-formatted TXT record is not also present. Possible + modes are ``warn`` (the default) and ``ignore``. + +.. option:: -w directory + + This option instructs :iscman:`named` to chdir to ``directory``, so that relative filenames in master file + ``$INCLUDE`` directives work. This is similar to the directory clause in + :iscman:`named.conf`. + +.. option:: -D + + This option dumps the zone file in canonical format. + +.. option:: -W mode + + This option specifies whether to check for non-terminal wildcards. Non-terminal + wildcards are almost always the result of a failure to understand the + wildcard matching algorithm (:rfc:`4592`). Possible modes are ``warn`` + (the default) and ``ignore``. + +.. option:: zonename + + This indicates the domain name of the zone being checked. + +.. option:: filename + + This is the name of the zone file. + +Return Values +~~~~~~~~~~~~~ + +:program:`named-checkzone` returns an exit status of 1 if errors were detected +and 0 otherwise. + +See Also +~~~~~~~~ + +:iscman:`named(8) <named>`, :iscman:`named-checkconf(8) <named-checkconf>`, :iscman:`named-compilezone(8) <named-compilezone>`, :rfc:`1035`, BIND 9 Administrator Reference +Manual. diff --git a/bin/check/named-compilezone.rst b/bin/check/named-compilezone.rst new file mode 100644 index 0000000..41ecff7 --- /dev/null +++ b/bin/check/named-compilezone.rst @@ -0,0 +1,224 @@ +.. 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. + +.. highlight: console + +.. BEWARE: Do not forget to edit also named-checkzone.rst! + +.. iscman:: named-compilezone +.. program:: named-compilezone +.. _man_named-compilezone: + +named-compilezone - zone file converting tool +--------------------------------------------- + +Synopsis +~~~~~~~~ + +:program:`named-compilezone` [**-d**] [**-h**] [**-j**] [**-q**] [**-v**] [**-c** class] [**-f** format] [**-F** format] [**-J** filename] [**-i** mode] [**-k** mode] [**-m** mode] [**-M** mode] [**-n** mode] [**-l** ttl] [**-L** serial] [**-r** mode] [**-s** style] [**-S** mode] [**-t** directory] [**-T** mode] [**-w** directory] [**-D**] [**-W** mode] {**-o** filename} {zonename} {filename} + +Description +~~~~~~~~~~~ + +:program:`named-compilezone` checks the syntax and integrity of a zone file, +and dumps the zone contents to a specified file in a specified format. +It applies strict check levels by default, since the +dump output is used as an actual zone file loaded by :iscman:`named`. +When manually specified otherwise, the check levels must at least be as +strict as those specified in the :iscman:`named` configuration file. + +Options +~~~~~~~ + +.. option:: -d + + This option enables debugging. + +.. option:: -h + + This option prints the usage summary and exits. + +.. option:: -q + + This option sets quiet mode, which only sets an exit code to indicate + successful or failed completion. + +.. option:: -v + + This option prints the version of the :iscman:`named-checkzone` program and exits. + +.. option:: -j + + When loading a zone file, this option tells :iscman:`named` to read the journal if it exists. The journal + file name is assumed to be the zone file name with the + string ``.jnl`` appended. + +.. option:: -J filename + + When loading the zone file, this option tells :iscman:`named` to read the journal from the given file, if + it exists. This implies :option:`-j`. + +.. option:: -c class + + This option specifies the class of the zone. If not specified, ``IN`` is assumed. + +.. option:: -i mode + + This option performs post-load zone integrity checks. Possible modes are + ``full`` (the default), ``full-sibling``, ``local``, + ``local-sibling``, and ``none``. + + Mode ``full`` checks that MX records refer to A or AAAA records + (both in-zone and out-of-zone hostnames). Mode ``local`` only + checks MX records which refer to in-zone hostnames. + + Mode ``full`` checks that SRV records refer to A or AAAA records + (both in-zone and out-of-zone hostnames). Mode ``local`` only + checks SRV records which refer to in-zone hostnames. + + Mode ``full`` checks that delegation NS records refer to A or AAAA + records (both in-zone and out-of-zone hostnames). It also checks that + glue address records in the zone match those advertised by the child. + Mode ``local`` only checks NS records which refer to in-zone + hostnames or verifies that some required glue exists, i.e., when the + name server is in a child zone. + + Modes ``full-sibling`` and ``local-sibling`` disable sibling glue + checks, but are otherwise the same as ``full`` and ``local``, + respectively. + + Mode ``none`` disables the checks. + +.. option:: -f format + + This option specifies the format of the zone file. Possible formats are + ``text`` (the default), and ``raw``. + +.. option:: -F format + + This option specifies the format of the output file specified. For + :iscman:`named-checkzone`, this does not have any effect unless it dumps + the zone contents. + + Possible formats are ``text`` (the default), which is the standard + textual representation of the zone, and ``raw`` and ``raw=N``, which + store the zone in a binary format for rapid loading by :iscman:`named`. + ``raw=N`` specifies the format version of the raw zone file: if ``N`` is + 0, the raw file can be read by any version of :iscman:`named`; if N is 1, the + file can only be read by release 9.9.0 or higher. The default is 1. + +.. option:: -k mode + + This option performs ``check-names`` checks with the specified failure mode. + Possible modes are ``fail`` (the default), ``warn``, and ``ignore``. + +.. option:: -l ttl + + This option sets a maximum permissible TTL for the input file. Any record with a + TTL higher than this value causes the zone to be rejected. This + is similar to using the ``max-zone-ttl`` option in :iscman:`named.conf`. + +.. option:: -L serial + + When compiling a zone to ``raw`` format, this option sets the "source + serial" value in the header to the specified serial number. This is + expected to be used primarily for testing purposes. + +.. option:: -m mode + + This option specifies whether MX records should be checked to see if they are + addresses. Possible modes are ``fail``, ``warn`` (the default), and + ``ignore``. + +.. option:: -M mode + + This option checks whether a MX record refers to a CNAME. Possible modes are + ``fail``, ``warn`` (the default), and ``ignore``. + +.. option:: -n mode + + This option specifies whether NS records should be checked to see if they are + addresses. Possible modes are ``fail`` (the default), ``warn``, and + ``ignore``. + +.. option:: -o filename + + This option writes the zone output to ``filename``. If ``filename`` is ``-``, then + the zone output is written to standard output. This is mandatory for :program:`named-compilezone`. + +.. option:: -r mode + + This option checks for records that are treated as different by DNSSEC but are + semantically equal in plain DNS. Possible modes are ``fail``, + ``warn`` (the default), and ``ignore``. + +.. option:: -s style + + This option specifies the style of the dumped zone file. Possible styles are + ``full`` (the default) and ``relative``. The ``full`` format is most + suitable for processing automatically by a separate script. + The relative format is more human-readable and is thus + suitable for editing by hand. + +.. option:: -S mode + + This option checks whether an SRV record refers to a CNAME. Possible modes are + ``fail``, ``warn`` (the default), and ``ignore``. + +.. option:: -t directory + + This option tells :iscman:`named` to chroot to ``directory``, so that ``include`` directives in the + configuration file are processed as if run by a similarly chrooted + :iscman:`named`. + +.. option:: -T mode + + This option checks whether Sender Policy Framework (SPF) records exist and issues a + warning if an SPF-formatted TXT record is not also present. Possible + modes are ``warn`` (the default) and ``ignore``. + +.. option:: -w directory + + This option instructs :iscman:`named` to chdir to ``directory``, so that relative filenames in master file + ``$INCLUDE`` directives work. This is similar to the directory clause in + :iscman:`named.conf`. + +.. option:: -D + + This option dumps the zone file in canonical format. This is always enabled for + :program:`named-compilezone`. + +.. option:: -W mode + + This option specifies whether to check for non-terminal wildcards. Non-terminal + wildcards are almost always the result of a failure to understand the + wildcard matching algorithm (:rfc:`4592`). Possible modes are ``warn`` + (the default) and ``ignore``. + +.. option:: zonename + + This indicates the domain name of the zone being checked. + +.. option:: filename + + This is the name of the zone file. + +Return Values +~~~~~~~~~~~~~ + +:program:`named-compilezone` returns an exit status of 1 if errors were detected +and 0 otherwise. + +See Also +~~~~~~~~ + +:iscman:`named(8) <named>`, :iscman:`named-checkconf(8) <named-checkconf>`, :iscman:`named-checkzone(8) <named-checkzone>`, :rfc:`1035`, +BIND 9 Administrator Reference Manual. |