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/rndc | |
parent | Initial commit. (diff) | |
download | bind9-3b9b6d0b8e7f798023c9d109c490449d528fde80.tar.xz bind9-3b9b6d0b8e7f798023c9d109c490449d528fde80.zip |
Adding upstream version 1:9.18.19.upstream/1%9.18.19upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'bin/rndc')
-rw-r--r-- | bin/rndc/Makefile.am | 26 | ||||
-rw-r--r-- | bin/rndc/Makefile.in | 831 | ||||
-rw-r--r-- | bin/rndc/rndc.c | 1125 | ||||
-rw-r--r-- | bin/rndc/rndc.conf.rst | 158 | ||||
-rw-r--r-- | bin/rndc/rndc.rst | 667 | ||||
-rw-r--r-- | bin/rndc/util.c | 49 | ||||
-rw-r--r-- | bin/rndc/util.h | 42 |
7 files changed, 2898 insertions, 0 deletions
diff --git a/bin/rndc/Makefile.am b/bin/rndc/Makefile.am new file mode 100644 index 0000000..a668522 --- /dev/null +++ b/bin/rndc/Makefile.am @@ -0,0 +1,26 @@ +include $(top_srcdir)/Makefile.top + +AM_CPPFLAGS += \ + $(LIBISC_CFLAGS) \ + $(LIBDNS_CFLAGS) \ + $(LIBISCCFG_CFLAGS) \ + $(LIBISCCC_CFLAGS) \ + $(LIBBIND9_CFLAGS) + +AM_CPPFLAGS += \ + -DRNDC_CONFFILE=\"${sysconfdir}/rndc.conf\" \ + -DRNDC_KEYFILE=\"${sysconfdir}/rndc.key\" + +sbin_PROGRAMS = rndc + +rndc_SOURCES = \ + rndc.c \ + util.c \ + util.h + +rndc_LDADD = \ + $(LIBISC_LIBS) \ + $(LIBDNS_LIBS) \ + $(LIBISCCC_LIBS) \ + $(LIBISCCFG_LIBS) \ + $(LIBBIND9_LIBS) diff --git a/bin/rndc/Makefile.in b/bin/rndc/Makefile.in new file mode 100644 index 0000000..7fdcb83 --- /dev/null +++ b/bin/rndc/Makefile.in @@ -0,0 +1,831 @@ +# 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 + +sbin_PROGRAMS = rndc$(EXEEXT) +subdir = bin/rndc +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)$(sbindir)" +PROGRAMS = $(sbin_PROGRAMS) +am_rndc_OBJECTS = rndc.$(OBJEXT) util.$(OBJEXT) +rndc_OBJECTS = $(am_rndc_OBJECTS) +rndc_DEPENDENCIES = $(LIBISC_LIBS) $(LIBDNS_LIBS) $(LIBISCCC_LIBS) \ + $(LIBISCCFG_LIBS) $(LIBBIND9_LIBS) +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 = +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)/rndc.Po ./$(DEPDIR)/util.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 = $(rndc_SOURCES) +DIST_SOURCES = $(rndc_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__extra_recursive_targets = test-recursive unit-recursive \ + doc-recursive +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/Makefile.top \ + $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_EXEEXT = @BUILD_EXEEXT@ +BUILD_OBJEXT = @BUILD_OBJEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS = @CFLAGS@ +CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ +CMOCKA_CFLAGS = @CMOCKA_CFLAGS@ +CMOCKA_LIBS = @CMOCKA_LIBS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@ +CPP_FOR_BUILD = @CPP_FOR_BUILD@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CURL = @CURL@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DEVELOPER_MODE = @DEVELOPER_MODE@ +DLLTOOL = @DLLTOOL@ +DNSTAP_CFLAGS = @DNSTAP_CFLAGS@ +DNSTAP_LIBS = @DNSTAP_LIBS@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILECMD = @FILECMD@ +FSTRM_CAPTURE = @FSTRM_CAPTURE@ +FUZZ_LDFLAGS = @FUZZ_LDFLAGS@ +FUZZ_LOG_COMPILER = @FUZZ_LOG_COMPILER@ +GREP = @GREP@ +GSSAPI_CFLAGS = @GSSAPI_CFLAGS@ +GSSAPI_LIBS = @GSSAPI_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@ +JEMALLOC_LIBS = @JEMALLOC_LIBS@ +JSON_C_CFLAGS = @JSON_C_CFLAGS@ +JSON_C_LIBS = @JSON_C_LIBS@ +KRB5_CFLAGS = @KRB5_CFLAGS@ +KRB5_CONFIG = @KRB5_CONFIG@ +KRB5_LIBS = @KRB5_LIBS@ +LATEXMK = @LATEXMK@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ +LIBCAP_LIBS = @LIBCAP_LIBS@ +LIBIDN2_CFLAGS = @LIBIDN2_CFLAGS@ +LIBIDN2_LIBS = @LIBIDN2_LIBS@ +LIBNGHTTP2_CFLAGS = @LIBNGHTTP2_CFLAGS@ +LIBNGHTTP2_LIBS = @LIBNGHTTP2_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUV_CFLAGS = @LIBUV_CFLAGS@ +LIBUV_LIBS = @LIBUV_LIBS@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LMDB_CFLAGS = @LMDB_CFLAGS@ +LMDB_LIBS = @LMDB_LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MAXMINDDB_CFLAGS = @MAXMINDDB_CFLAGS@ +MAXMINDDB_LIBS = @MAXMINDDB_LIBS@ +MAXMINDDB_PREFIX = @MAXMINDDB_PREFIX@ +MKDIR_P = @MKDIR_P@ +NC = @NC@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTOC_C = @PROTOC_C@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_CXX = @PTHREAD_CXX@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +PYTEST = @PYTEST@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +READLINE_CFLAGS = @READLINE_CFLAGS@ +READLINE_LIBS = @READLINE_LIBS@ +RELEASE_DATE = @RELEASE_DATE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SPHINX_BUILD = @SPHINX_BUILD@ +STD_CFLAGS = @STD_CFLAGS@ +STD_CPPFLAGS = @STD_CPPFLAGS@ +STD_LDFLAGS = @STD_LDFLAGS@ +STRIP = @STRIP@ +TEST_CFLAGS = @TEST_CFLAGS@ +VERSION = @VERSION@ +XELATEX = @XELATEX@ +XSLTPROC = @XSLTPROC@ +ZLIB_CFLAGS = @ZLIB_CFLAGS@ +ZLIB_LIBS = @ZLIB_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CC_FOR_BUILD = @ac_ct_CC_FOR_BUILD@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +ax_pthread_config = @ax_pthread_config@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +ACLOCAL_AMFLAGS = -I $(top_srcdir)/m4 +AM_CFLAGS = \ + $(STD_CFLAGS) + +AM_CPPFLAGS = $(STD_CPPFLAGS) -include $(top_builddir)/config.h \ + -I$(srcdir)/include $(LIBISC_CFLAGS) $(LIBDNS_CFLAGS) \ + $(LIBISCCFG_CFLAGS) $(LIBISCCC_CFLAGS) $(LIBBIND9_CFLAGS) \ + -DRNDC_CONFFILE=\"${sysconfdir}/rndc.conf\" \ + -DRNDC_KEYFILE=\"${sysconfdir}/rndc.key\" +AM_LDFLAGS = $(STD_LDFLAGS) $(am__append_1) +LDADD = +LIBISC_CFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/lib/isc/include \ + -I$(top_builddir)/lib/isc/include + +LIBISC_LIBS = $(top_builddir)/lib/isc/libisc.la +LIBDNS_CFLAGS = \ + -I$(top_srcdir)/lib/dns/include \ + -I$(top_builddir)/lib/dns/include + +LIBDNS_LIBS = \ + $(top_builddir)/lib/dns/libdns.la + +LIBNS_CFLAGS = \ + -I$(top_srcdir)/lib/ns/include + +LIBNS_LIBS = \ + $(top_builddir)/lib/ns/libns.la + +LIBIRS_CFLAGS = \ + -I$(top_srcdir)/lib/irs/include + +LIBIRS_LIBS = \ + $(top_builddir)/lib/irs/libirs.la + +LIBISCCFG_CFLAGS = \ + -I$(top_srcdir)/lib/isccfg/include + +LIBISCCFG_LIBS = \ + $(top_builddir)/lib/isccfg/libisccfg.la + +LIBISCCC_CFLAGS = \ + -I$(top_srcdir)/lib/isccc/include/ + +LIBISCCC_LIBS = \ + $(top_builddir)/lib/isccc/libisccc.la + +LIBBIND9_CFLAGS = \ + -I$(top_srcdir)/lib/bind9/include + +LIBBIND9_LIBS = \ + $(top_builddir)/lib/bind9/libbind9.la + +rndc_SOURCES = \ + rndc.c \ + util.c \ + util.h + +rndc_LDADD = \ + $(LIBISC_LIBS) \ + $(LIBDNS_LIBS) \ + $(LIBISCCC_LIBS) \ + $(LIBISCCFG_LIBS) \ + $(LIBBIND9_LIBS) + +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/rndc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign bin/rndc/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-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(sbindir)" || 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)$(sbindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || 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)$(sbindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(sbindir)" && rm -f $$files + +clean-sbinPROGRAMS: + @list='$(sbin_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 + +rndc$(EXEEXT): $(rndc_OBJECTS) $(rndc_DEPENDENCIES) $(EXTRA_rndc_DEPENDENCIES) + @rm -f rndc$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(rndc_OBJECTS) $(rndc_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rndc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.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) +installdirs: + for dir in "$(DESTDIR)$(sbindir)"; 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-generic clean-libtool clean-sbinPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/rndc.Po + -rm -f ./$(DEPDIR)/util.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-sbinPROGRAMS + +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)/rndc.Po + -rm -f ./$(DEPDIR)/util.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-sbinPROGRAMS + +unit: unit-am + +unit-am: unit-local + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-sbinPROGRAMS cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir doc-am doc-local dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \ + 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-sbinPROGRAMS unit-am unit-local + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/bin/rndc/rndc.c b/bin/rndc/rndc.c new file mode 100644 index 0000000..87c36ba --- /dev/null +++ b/bin/rndc/rndc.c @@ -0,0 +1,1125 @@ +/* + * 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/atomic.h> +#include <isc/attributes.h> +#include <isc/buffer.h> +#include <isc/commandline.h> +#include <isc/file.h> +#include <isc/log.h> +#include <isc/managers.h> +#include <isc/mem.h> +#include <isc/net.h> +#include <isc/netmgr.h> +#include <isc/print.h> +#include <isc/random.h> +#include <isc/refcount.h> +#include <isc/result.h> +#include <isc/stdtime.h> +#include <isc/string.h> +#include <isc/task.h> +#include <isc/thread.h> +#include <isc/util.h> + +#include <dns/name.h> + +#include <isccc/alist.h> +#include <isccc/base64.h> +#include <isccc/cc.h> +#include <isccc/ccmsg.h> +#include <isccc/sexpr.h> +#include <isccc/types.h> +#include <isccc/util.h> + +#include <isccfg/namedconf.h> + +#include <bind9/getaddresses.h> + +#include "util.h" + +#define SERVERADDRS 10 +#define RNDC_TIMEOUT 60 * 1000 + +const char *progname = NULL; +bool verbose; + +static isc_nm_t *netmgr = NULL; +static isc_taskmgr_t *taskmgr = NULL; +static isc_task_t *rndc_task = NULL; + +static const char *admin_conffile = NULL; +static const char *admin_keyfile = NULL; +static const char *version = PACKAGE_VERSION; +static const char *servername = NULL; +static isc_sockaddr_t serveraddrs[SERVERADDRS]; +static isc_sockaddr_t local4, local6; +static bool local4set = false, local6set = false; +static int nserveraddrs; +static int currentaddr = 0; +static unsigned int remoteport = 0; +static isc_buffer_t *databuf = NULL; +static isccc_ccmsg_t rndc_ccmsg; +static uint32_t algorithm; +static isccc_region_t secret; +static bool failed = false; +static bool c_flag = false; +static isc_mem_t *rndc_mctx = NULL; +static atomic_uint_fast32_t sends = 0; +static atomic_uint_fast32_t recvs = 0; +static atomic_uint_fast32_t connects = 0; +static char *command = NULL; +static char *args = NULL; +static char program[256]; +static uint32_t serial; +static bool quiet = false; +static bool showresult = false; +static bool shuttingdown = false; +static isc_nmhandle_t *recvdone_handle = NULL; +static isc_nmhandle_t *recvnonce_handle = NULL; + +static void +rndc_startconnect(isc_sockaddr_t *addr); + +noreturn static void +usage(int status); + +static void +usage(int status) { + fprintf(stderr, "\ +Usage: %s [-b address] [-c config] [-s server] [-p port]\n\ + [-k key-file ] [-y key] [-r] [-V] [-4 | -6] command\n\ +\n\ +command is one of the following:\n\ +\n\ + addzone zone [class [view]] { zone-options }\n\ + Add zone to given view. Requires allow-new-zones option.\n\ + delzone [-clean] zone [class [view]]\n\ + Removes zone from given view.\n\ + dnssec -checkds [-key id [-alg algorithm]] [-when time] (published|withdrawn) zone [class [view]]\n\ + Mark the DS record for the KSK of the given zone as seen\n\ + in the parent. If the zone has multiple KSKs, select a\n\ + specific key by providing the keytag with -key id and\n\ + optionally the key's algorithm with -alg algorithm.\n\ + Requires the zone to have a dnssec-policy.\n\ + dnssec -rollover -key id [-alg algorithm] [-when time] zone [class [view]]\n\ + Rollover key with id of the given zone. Requires the zone\n\ + to have a dnssec-policy.\n\ + dnssec -status zone [class [view]]\n\ + Show the DNSSEC signing state for the specified zone.\n\ + Requires the zone to have a dnssec-policy.\n\ + dnstap -reopen\n\ + Close, truncate and re-open the DNSTAP output file.\n\ + dnstap -roll [count]\n\ + Close, rename and re-open the DNSTAP output file(s).\n\ + dumpdb [-all|-cache|-zones|-adb|-bad|-expired|-fail] [view ...]\n\ + Dump cache(s) to the dump file (named_dump.db).\n\ + flush Flushes all of the server's caches.\n\ + flush [view] Flushes the server's cache for a view.\n\ + flushname name [view]\n\ + Flush the given name from the server's cache(s)\n\ + flushtree name [view]\n\ + Flush all names under the given name from the server's cache(s)\n\ + freeze Suspend updates to all dynamic zones.\n\ + freeze zone [class [view]]\n\ + Suspend updates to a dynamic zone.\n\ + halt Stop the server without saving pending updates.\n\ + halt -p Stop the server without saving pending updates reporting\n\ + process id.\n\ + loadkeys zone [class [view]]\n\ + Update keys without signing immediately.\n\ + managed-keys refresh [class [view]]\n\ + Check trust anchor for RFC 5011 key changes\n\ + managed-keys status [class [view]]\n\ + Display RFC 5011 managed keys information\n\ + managed-keys sync [class [view]]\n\ + Write RFC 5011 managed keys to disk\n\ + modzone zone [class [view]] { zone-options }\n\ + Modify a zone's configuration.\n\ + Requires allow-new-zones option.\n\ + notify zone [class [view]]\n\ + Resend NOTIFY messages for the zone.\n\ + notrace Set debugging level to 0.\n\ + nta -dump\n\ + List all negative trust anchors.\n\ + nta [-lifetime duration] [-force] domain [view]\n\ + Set a negative trust anchor, disabling DNSSEC validation\n\ + for the given domain.\n\ + Using -lifetime specifies the duration of the NTA, up\n\ + to one week.\n\ + Using -force prevents the NTA from expiring before its\n\ + full lifetime, even if the domain can validate sooner.\n\ + nta -remove domain [view]\n\ + Remove a negative trust anchor, re-enabling validation\n\ + for the given domain.\n\ + querylog [ on | off ]\n\ + Enable / disable query logging.\n\ + reconfig Reload configuration file and new zones only.\n\ + recursing Dump the queries that are currently recursing (named.recursing)\n\ + refresh zone [class [view]]\n\ + Schedule immediate maintenance for a zone.\n\ + reload Reload configuration file and zones.\n\ + reload zone [class [view]]\n\ + Reload a single zone.\n\ + retransfer zone [class [view]]\n\ + Retransfer a single zone without checking serial number.\n\ + scan Scan available network interfaces for changes.\n\ + secroots [view ...]\n\ + Write security roots to the secroots file.\n\ + serve-stale [ on | off | reset | status ] [class [view]]\n\ + Control whether stale answers are returned\n\ + showzone zone [class [view]]\n\ + Print a zone's configuration.\n\ + sign zone [class [view]]\n\ + Update zone keys, and sign as needed.\n\ + signing -clear all zone [class [view]]\n\ + Remove the private records for all keys that have\n\ + finished signing the given zone.\n\ + signing -clear <keyid>/<algorithm> zone [class [view]]\n\ + Remove the private record that indicating the given key\n\ + has finished signing the given zone.\n\ + signing -list zone [class [view]]\n\ + List the private records showing the state of DNSSEC\n\ + signing in the given zone.\n\ + signing -nsec3param hash flags iterations salt zone [class [view]]\n\ + Add NSEC3 chain to zone if already signed.\n\ + Prime zone with NSEC3 chain if not yet signed.\n\ + signing -nsec3param none zone [class [view]]\n\ + Remove NSEC3 chains from zone.\n\ + signing -serial <value> zone [class [view]]\n\ + Set the zones's serial to <value>.\n\ + stats Write server statistics to the statistics file.\n\ + status Display status of the server.\n\ + stop Save pending updates to master files and stop the server.\n\ + stop -p Save pending updates to master files and stop the server\n\ + reporting process id.\n\ + sync [-clean] Dump changes to all dynamic zones to disk, and optionally\n\ + remove their journal files.\n\ + sync [-clean] zone [class [view]]\n\ + Dump a single zone's changes to disk, and optionally\n\ + remove its journal file.\n\ + tcp-timeouts Display the tcp-*-timeout option values\n\ + tcp-timeouts initial idle keepalive advertised\n\ + Update the tcp-*-timeout option values\n\ + thaw Enable updates to all dynamic zones and reload them.\n\ + thaw zone [class [view]]\n\ + Enable updates to a frozen dynamic zone and reload it.\n\ + trace Increment debugging level by one.\n\ + trace level Change the debugging level.\n\ + tsig-delete keyname [view]\n\ + Delete a TKEY-negotiated TSIG key.\n\ + tsig-list List all currently active TSIG keys, including both statically\n\ + configured and TKEY-negotiated keys.\n\ + validation [ on | off | status ] [view]\n\ + Enable / disable DNSSEC validation.\n\ + zonestatus zone [class [view]]\n\ + Display the current status of a zone.\n\ +\n\ +Version: %s\n", + progname, version); + + exit(status); +} + +#define CMDLINE_FLAGS "46b:c:hk:Mmp:qrs:Vy:" + +static void +preparse_args(int argc, char **argv) { + bool ipv4only = false, ipv6only = false; + int ch; + + while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { + switch (ch) { + case '4': + if (ipv6only) { + fatal("only one of -4 and -6 allowed"); + } + ipv4only = true; + break; + case '6': + if (ipv4only) { + fatal("only one of -4 and -6 allowed"); + } + ipv6only = true; + break; + default: + break; + } + } + + isc_commandline_reset = true; + isc_commandline_index = 1; +} + +static void +get_addresses(const char *host, in_port_t port) { + isc_result_t result; + int found = 0, count; + + REQUIRE(host != NULL); + + if (*host == '/') { + result = isc_sockaddr_frompath(&serveraddrs[nserveraddrs], + host); + if (result == ISC_R_SUCCESS) { + nserveraddrs++; + } + } else { + count = SERVERADDRS - nserveraddrs; + result = bind9_getaddresses( + host, port, &serveraddrs[nserveraddrs], count, &found); + nserveraddrs += found; + } + if (result != ISC_R_SUCCESS) { + fatal("couldn't get address for '%s': %s", host, + isc_result_totext(result)); + } + INSIST(nserveraddrs > 0); +} + +static void +rndc_senddone(isc_nmhandle_t *handle, isc_result_t result, void *arg) { + isc_nmhandle_t *sendhandle = (isc_nmhandle_t *)arg; + + if (result != ISC_R_SUCCESS) { + fatal("send failed: %s", isc_result_totext(result)); + } + + REQUIRE(sendhandle == handle); + isc_nmhandle_detach(&sendhandle); + + if (atomic_fetch_sub_release(&sends, 1) == 1 && + atomic_load_acquire(&recvs) == 0) + { + shuttingdown = true; + isc_task_detach(&rndc_task); + isc_app_shutdown(); + } +} + +static void +rndc_recvdone(isc_nmhandle_t *handle, isc_result_t result, void *arg) { + isccc_ccmsg_t *ccmsg = (isccc_ccmsg_t *)arg; + isccc_sexpr_t *response = NULL; + isccc_sexpr_t *data = NULL; + isccc_region_t source; + char *errormsg = NULL; + char *textmsg = NULL; + + REQUIRE(ccmsg != NULL); + + if (shuttingdown && (result == ISC_R_EOF || result == ISC_R_CANCELED)) { + atomic_fetch_sub_release(&recvs, 1); + if (handle != NULL) { + REQUIRE(recvdone_handle == handle); + isc_nmhandle_detach(&recvdone_handle); + } + return; + } else if (result == ISC_R_EOF) { + fatal("connection to remote host closed.\n" + "* This may indicate that the\n" + "* remote server is using an older\n" + "* version of the command protocol,\n" + "* this host is not authorized to connect,\n" + "* the clocks are not synchronized,\n" + "* the key signing algorithm is incorrect,\n" + "* or the key is invalid."); + } else if (result != ISC_R_SUCCESS) { + fatal("recv failed: %s", isc_result_totext(result)); + } + + source.rstart = isc_buffer_base(ccmsg->buffer); + source.rend = isc_buffer_used(ccmsg->buffer); + + DO("parse message", + isccc_cc_fromwire(&source, &response, algorithm, &secret)); + + data = isccc_alist_lookup(response, "_data"); + if (!isccc_alist_alistp(data)) { + fatal("bad or missing data section in response"); + } + result = isccc_cc_lookupstring(data, "err", &errormsg); + if (result == ISC_R_SUCCESS) { + failed = true; + fprintf(stderr, "%s: '%s' failed: %s\n", progname, command, + errormsg); + } else if (result != ISC_R_NOTFOUND) { + fprintf(stderr, "%s: parsing response failed: %s\n", progname, + isc_result_totext(result)); + } + + result = isccc_cc_lookupstring(data, "text", &textmsg); + if (result == ISC_R_SUCCESS) { + if ((!quiet || failed) && strlen(textmsg) != 0U) { + fprintf(failed ? stderr : stdout, "%s\n", textmsg); + } + } else if (result != ISC_R_NOTFOUND) { + fprintf(stderr, "%s: parsing response failed: %s\n", progname, + isc_result_totext(result)); + } + + if (showresult) { + isc_result_t eresult; + + result = isccc_cc_lookupuint32(data, "result", &eresult); + if (result == ISC_R_SUCCESS) { + printf("%s %u\n", isc_result_toid(eresult), eresult); + } else { + printf("NONE -1\n"); + } + } + + isccc_sexpr_free(&response); + + REQUIRE(recvdone_handle == handle); + isc_nmhandle_detach(&recvdone_handle); + + if (atomic_fetch_sub_release(&recvs, 1) == 1 && + atomic_load_acquire(&sends) == 0) + { + shuttingdown = true; + isc_task_detach(&rndc_task); + isc_app_shutdown(); + } +} + +static void +rndc_recvnonce(isc_nmhandle_t *handle, isc_result_t result, void *arg) { + isccc_ccmsg_t *ccmsg = (isccc_ccmsg_t *)arg; + isccc_sexpr_t *response = NULL; + isc_nmhandle_t *sendhandle = NULL; + isccc_sexpr_t *_ctrl = NULL; + isccc_region_t source; + uint32_t nonce; + isccc_sexpr_t *request = NULL; + isccc_time_t now; + isc_region_t r; + isccc_sexpr_t *data = NULL; + isc_buffer_t b; + + REQUIRE(ccmsg != NULL); + + if (shuttingdown && (result == ISC_R_EOF || result == ISC_R_CANCELED)) { + atomic_fetch_sub_release(&recvs, 1); + if (handle != NULL) { + REQUIRE(recvnonce_handle == handle); + isc_nmhandle_detach(&recvnonce_handle); + } + return; + } else if (result == ISC_R_EOF) { + fatal("connection to remote host closed.\n" + "* This may indicate that the\n" + "* remote server is using an older\n" + "* version of the command protocol,\n" + "* this host is not authorized to connect,\n" + "* the clocks are not synchronized,\n" + "* the key signing algorithm is incorrect\n" + "* or the key is invalid."); + } else if (result != ISC_R_SUCCESS) { + fatal("recv failed: %s", isc_result_totext(result)); + } + + source.rstart = isc_buffer_base(ccmsg->buffer); + source.rend = isc_buffer_used(ccmsg->buffer); + + DO("parse message", + isccc_cc_fromwire(&source, &response, algorithm, &secret)); + + _ctrl = isccc_alist_lookup(response, "_ctrl"); + if (!isccc_alist_alistp(_ctrl)) { + fatal("bad or missing ctrl section in response"); + } + nonce = 0; + if (isccc_cc_lookupuint32(_ctrl, "_nonce", &nonce) != ISC_R_SUCCESS) { + nonce = 0; + } + + isc_stdtime_get(&now); + + DO("create message", isccc_cc_createmessage(1, NULL, NULL, ++serial, + now, now + 60, &request)); + data = isccc_alist_lookup(request, "_data"); + if (data == NULL) { + fatal("_data section missing"); + } + if (isccc_cc_definestring(data, "type", args) == NULL) { + fatal("out of memory"); + } + if (nonce != 0) { + _ctrl = isccc_alist_lookup(request, "_ctrl"); + if (_ctrl == NULL) { + fatal("_ctrl section missing"); + } + if (isccc_cc_defineuint32(_ctrl, "_nonce", nonce) == NULL) { + fatal("out of memory"); + } + } + + isc_buffer_clear(databuf); + /* Skip the length field (4 bytes) */ + isc_buffer_add(databuf, 4); + + DO("render message", + isccc_cc_towire(request, &databuf, algorithm, &secret)); + + isc_buffer_init(&b, databuf->base, 4); + isc_buffer_putuint32(&b, databuf->used - 4); + + r.base = databuf->base; + r.length = databuf->used; + + isc_nmhandle_attach(handle, &recvdone_handle); + atomic_fetch_add_relaxed(&recvs, 1); + isccc_ccmsg_readmessage(ccmsg, rndc_recvdone, ccmsg); + + isc_nmhandle_attach(handle, &sendhandle); + atomic_fetch_add_relaxed(&sends, 1); + isc_nm_send(handle, &r, rndc_senddone, sendhandle); + + REQUIRE(recvnonce_handle == handle); + isc_nmhandle_detach(&recvnonce_handle); + atomic_fetch_sub_release(&recvs, 1); + + isccc_sexpr_free(&response); + isccc_sexpr_free(&request); + return; +} + +static void +rndc_connected(isc_nmhandle_t *handle, isc_result_t result, void *arg) { + isccc_ccmsg_t *ccmsg = (isccc_ccmsg_t *)arg; + char socktext[ISC_SOCKADDR_FORMATSIZE]; + isccc_sexpr_t *request = NULL; + isccc_sexpr_t *data = NULL; + isccc_time_t now; + isc_region_t r; + isc_buffer_t b; + isc_nmhandle_t *connhandle = NULL; + isc_nmhandle_t *sendhandle = NULL; + + REQUIRE(ccmsg != NULL); + + if (result != ISC_R_SUCCESS) { + atomic_fetch_sub_release(&connects, 1); + isc_sockaddr_format(&serveraddrs[currentaddr], socktext, + sizeof(socktext)); + if (++currentaddr < nserveraddrs) { + notify("connection failed: %s: %s", socktext, + isc_result_totext(result)); + rndc_startconnect(&serveraddrs[currentaddr]); + return; + } + + fatal("connect failed: %s: %s", socktext, + isc_result_totext(result)); + } + + isc_nmhandle_attach(handle, &connhandle); + + isc_stdtime_get(&now); + DO("create message", isccc_cc_createmessage(1, NULL, NULL, ++serial, + now, now + 60, &request)); + data = isccc_alist_lookup(request, "_data"); + if (data == NULL) { + fatal("_data section missing"); + } + if (isccc_cc_definestring(data, "type", "null") == NULL) { + fatal("out of memory"); + } + + isc_buffer_clear(databuf); + /* Skip the length field (4 bytes) */ + isc_buffer_add(databuf, 4); + + DO("render message", + isccc_cc_towire(request, &databuf, algorithm, &secret)); + + isc_buffer_init(&b, databuf->base, 4); + isc_buffer_putuint32(&b, databuf->used - 4); + + r.base = databuf->base; + r.length = databuf->used; + + isccc_ccmsg_init(rndc_mctx, handle, ccmsg); + isccc_ccmsg_setmaxsize(ccmsg, 1024 * 1024); + + isc_nmhandle_attach(handle, &recvnonce_handle); + atomic_fetch_add_relaxed(&recvs, 1); + isccc_ccmsg_readmessage(ccmsg, rndc_recvnonce, ccmsg); + + isc_nmhandle_attach(handle, &sendhandle); + atomic_fetch_add_relaxed(&sends, 1); + isc_nm_send(handle, &r, rndc_senddone, sendhandle); + + isc_nmhandle_detach(&connhandle); + atomic_fetch_sub_release(&connects, 1); + + isccc_sexpr_free(&request); +} + +static void +rndc_startconnect(isc_sockaddr_t *addr) { + char socktext[ISC_SOCKADDR_FORMATSIZE]; + isc_sockaddr_t *local = NULL; + + isc_sockaddr_format(addr, socktext, sizeof(socktext)); + + notify("using server %s (%s)", servername, socktext); + + switch (isc_sockaddr_pf(addr)) { + case AF_INET: + local = &local4; + break; + case AF_INET6: + local = &local6; + break; + case AF_UNIX: + /* + * TODO: support UNIX domain sockets in netgmr. + */ + fatal("UNIX domain sockets not currently supported"); + default: + UNREACHABLE(); + } + + atomic_fetch_add_relaxed(&connects, 1); + isc_nm_tcpconnect(netmgr, local, addr, rndc_connected, &rndc_ccmsg, + RNDC_TIMEOUT, 0); +} + +static void +rndc_start(isc_task_t *task, isc_event_t *event) { + isc_event_free(&event); + + UNUSED(task); + + currentaddr = 0; + rndc_startconnect(&serveraddrs[currentaddr]); +} + +static void +parse_config(isc_mem_t *mctx, isc_log_t *log, const char *keyname, + cfg_parser_t **pctxp, cfg_obj_t **configp) { + isc_result_t result; + const char *conffile = admin_conffile; + const cfg_obj_t *addresses = NULL; + const cfg_obj_t *defkey = NULL; + const cfg_obj_t *options = NULL; + const cfg_obj_t *servers = NULL; + const cfg_obj_t *server = NULL; + const cfg_obj_t *keys = NULL; + const cfg_obj_t *key = NULL; + const cfg_obj_t *defport = NULL; + const cfg_obj_t *secretobj = NULL; + const cfg_obj_t *algorithmobj = NULL; + cfg_obj_t *config = NULL; + const cfg_obj_t *address = NULL; + const cfg_listelt_t *elt; + const char *secretstr; + const char *algorithmstr; + static char secretarray[1024]; + const cfg_type_t *conftype = &cfg_type_rndcconf; + bool key_only = false; + const cfg_listelt_t *element; + + if (!isc_file_exists(conffile)) { + conffile = admin_keyfile; + conftype = &cfg_type_rndckey; + + if (c_flag) { + fatal("%s does not exist", admin_conffile); + } + + if (!isc_file_exists(conffile)) { + fatal("neither %s nor %s was found", admin_conffile, + admin_keyfile); + } + key_only = true; + } else if (!c_flag && isc_file_exists(admin_keyfile)) { + fprintf(stderr, + "WARNING: key file (%s) exists, but using " + "default configuration file (%s)\n", + admin_keyfile, admin_conffile); + } + + DO("create parser", cfg_parser_create(mctx, log, pctxp)); + + /* + * The parser will output its own errors, so DO() is not used. + */ + result = cfg_parse_file(*pctxp, conffile, conftype, &config); + if (result != ISC_R_SUCCESS) { + fatal("could not load rndc configuration"); + } + + if (!key_only) { + (void)cfg_map_get(config, "options", &options); + } + + if (key_only && servername == NULL) { + servername = "127.0.0.1"; + } else if (servername == NULL && options != NULL) { + const cfg_obj_t *defserverobj = NULL; + (void)cfg_map_get(options, "default-server", &defserverobj); + if (defserverobj != NULL) { + servername = cfg_obj_asstring(defserverobj); + } + } + + if (servername == NULL) { + fatal("no server specified and no default"); + } + + if (!key_only) { + (void)cfg_map_get(config, "server", &servers); + if (servers != NULL) { + for (elt = cfg_list_first(servers); elt != NULL; + elt = cfg_list_next(elt)) + { + const char *name = NULL; + server = cfg_listelt_value(elt); + name = cfg_obj_asstring( + cfg_map_getname(server)); + if (strcasecmp(name, servername) == 0) { + break; + } + server = NULL; + } + } + } + + /* + * Look for the name of the key to use. + */ + if (keyname != NULL) { + /* Was set on command line, do nothing. */ + } else if (server != NULL) { + DO("get key for server", cfg_map_get(server, "key", &defkey)); + keyname = cfg_obj_asstring(defkey); + } else if (options != NULL) { + DO("get default key", + cfg_map_get(options, "default-key", &defkey)); + keyname = cfg_obj_asstring(defkey); + } else if (!key_only) { + fatal("no key for server and no default"); + } + + /* + * Get the key's definition. + */ + if (key_only) { + DO("get key", cfg_map_get(config, "key", &key)); + } else { + DO("get config key list", cfg_map_get(config, "key", &keys)); + for (elt = cfg_list_first(keys); elt != NULL; + elt = cfg_list_next(elt)) + { + const char *name = NULL; + + key = cfg_listelt_value(elt); + name = cfg_obj_asstring(cfg_map_getname(key)); + if (strcasecmp(name, keyname) == 0) { + break; + } + } + if (elt == NULL) { + fatal("no key definition for name %s", keyname); + } + } + (void)cfg_map_get(key, "secret", &secretobj); + (void)cfg_map_get(key, "algorithm", &algorithmobj); + if (secretobj == NULL || algorithmobj == NULL) { + fatal("key must have algorithm and secret"); + } + + secretstr = cfg_obj_asstring(secretobj); + algorithmstr = cfg_obj_asstring(algorithmobj); + + if (strcasecmp(algorithmstr, "hmac-md5") == 0) { + algorithm = ISCCC_ALG_HMACMD5; + } else if (strcasecmp(algorithmstr, "hmac-sha1") == 0) { + algorithm = ISCCC_ALG_HMACSHA1; + } else if (strcasecmp(algorithmstr, "hmac-sha224") == 0) { + algorithm = ISCCC_ALG_HMACSHA224; + } else if (strcasecmp(algorithmstr, "hmac-sha256") == 0) { + algorithm = ISCCC_ALG_HMACSHA256; + } else if (strcasecmp(algorithmstr, "hmac-sha384") == 0) { + algorithm = ISCCC_ALG_HMACSHA384; + } else if (strcasecmp(algorithmstr, "hmac-sha512") == 0) { + algorithm = ISCCC_ALG_HMACSHA512; + } else { + fatal("unsupported algorithm: %s", algorithmstr); + } + + secret.rstart = (unsigned char *)secretarray; + secret.rend = (unsigned char *)secretarray + sizeof(secretarray); + DO("decode base64 secret", isccc_base64_decode(secretstr, &secret)); + secret.rend = secret.rstart; + secret.rstart = (unsigned char *)secretarray; + + /* + * Find the port to connect to. + */ + if (remoteport != 0) { + /* Was set on command line, do nothing. */ + } else { + if (server != NULL) { + (void)cfg_map_get(server, "port", &defport); + } + if (defport == NULL && options != NULL) { + (void)cfg_map_get(options, "default-port", &defport); + } + } + if (defport != NULL) { + remoteport = cfg_obj_asuint32(defport); + if (remoteport > 65535 || remoteport == 0) { + fatal("port %u out of range", remoteport); + } + } else if (remoteport == 0) { + remoteport = NS_CONTROL_PORT; + } + + if (server != NULL) { + result = cfg_map_get(server, "addresses", &addresses); + } else { + result = ISC_R_NOTFOUND; + } + if (result == ISC_R_SUCCESS) { + for (element = cfg_list_first(addresses); element != NULL; + element = cfg_list_next(element)) + { + isc_sockaddr_t sa; + + address = cfg_listelt_value(element); + if (!cfg_obj_issockaddr(address)) { + unsigned int myport; + const char *name; + const cfg_obj_t *obj; + + obj = cfg_tuple_get(address, "name"); + name = cfg_obj_asstring(obj); + obj = cfg_tuple_get(address, "port"); + if (cfg_obj_isuint32(obj)) { + myport = cfg_obj_asuint32(obj); + if (myport > UINT16_MAX || myport == 0) + { + fatal("port %u out of range", + myport); + } + } else { + myport = remoteport; + } + if (nserveraddrs < SERVERADDRS) { + get_addresses(name, (in_port_t)myport); + } else { + fprintf(stderr, + "too many address: " + "%s: dropped\n", + name); + } + continue; + } + sa = *cfg_obj_assockaddr(address); + if (isc_sockaddr_getport(&sa) == 0) { + isc_sockaddr_setport(&sa, remoteport); + } + if (nserveraddrs < SERVERADDRS) { + serveraddrs[nserveraddrs++] = sa; + } else { + char socktext[ISC_SOCKADDR_FORMATSIZE]; + + isc_sockaddr_format(&sa, socktext, + sizeof(socktext)); + fprintf(stderr, + "too many address: %s: dropped\n", + socktext); + } + } + } + + if (!local4set && server != NULL) { + address = NULL; + cfg_map_get(server, "source-address", &address); + if (address != NULL) { + local4 = *cfg_obj_assockaddr(address); + local4set = true; + } + } + if (!local4set && options != NULL) { + address = NULL; + cfg_map_get(options, "default-source-address", &address); + if (address != NULL) { + local4 = *cfg_obj_assockaddr(address); + local4set = true; + } + } + + if (!local6set && server != NULL) { + address = NULL; + cfg_map_get(server, "source-address-v6", &address); + if (address != NULL) { + local6 = *cfg_obj_assockaddr(address); + local6set = true; + } + } + if (!local6set && options != NULL) { + address = NULL; + cfg_map_get(options, "default-source-address-v6", &address); + if (address != NULL) { + local6 = *cfg_obj_assockaddr(address); + local6set = true; + } + } + + *configp = config; +} + +int +main(int argc, char **argv) { + isc_result_t result = ISC_R_SUCCESS; + bool show_final_mem = false; + isc_log_t *log = NULL; + isc_logconfig_t *logconfig = NULL; + isc_logdestination_t logdest; + cfg_parser_t *pctx = NULL; + cfg_obj_t *config = NULL; + const char *keyname = NULL; + struct in_addr in; + struct in6_addr in6; + char *p; + size_t argslen; + int ch; + int i; + + result = isc_file_progname(*argv, program, sizeof(program)); + if (result != ISC_R_SUCCESS) { + memmove(program, "rndc", 5); + } + progname = program; + + admin_conffile = RNDC_CONFFILE; + admin_keyfile = RNDC_KEYFILE; + + isc_sockaddr_any(&local4); + isc_sockaddr_any6(&local6); + + result = isc_app_start(); + if (result != ISC_R_SUCCESS) { + fatal("isc_app_start() failed: %s", isc_result_totext(result)); + } + + isc_commandline_errprint = false; + + preparse_args(argc, argv); + + while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { + switch (ch) { + case '4': + if (isc_net_probeipv4() != ISC_R_SUCCESS) { + fatal("can't find IPv4 networking"); + } + isc_net_disableipv6(); + break; + case '6': + if (isc_net_probeipv6() != ISC_R_SUCCESS) { + fatal("can't find IPv6 networking"); + } + isc_net_disableipv4(); + break; + case 'b': + if (inet_pton(AF_INET, isc_commandline_argument, &in) == + 1) + { + isc_sockaddr_fromin(&local4, &in, 0); + local4set = true; + } else if (inet_pton(AF_INET6, isc_commandline_argument, + &in6) == 1) + { + isc_sockaddr_fromin6(&local6, &in6, 0); + local6set = true; + } + break; + + case 'c': + admin_conffile = isc_commandline_argument; + c_flag = true; + break; + + case 'k': + admin_keyfile = isc_commandline_argument; + break; + + case 'M': + isc_mem_debugging = ISC_MEM_DEBUGTRACE; + break; + + case 'm': + show_final_mem = true; + break; + + case 'p': + remoteport = atoi(isc_commandline_argument); + if (remoteport > 65535 || remoteport == 0) { + fatal("port '%s' out of range", + isc_commandline_argument); + } + break; + + case 'q': + quiet = true; + break; + + case 'r': + showresult = true; + break; + + case 's': + servername = isc_commandline_argument; + break; + + case 'V': + verbose = true; + break; + + case 'y': + keyname = isc_commandline_argument; + break; + + case '?': + if (isc_commandline_option != '?') { + fprintf(stderr, "%s: invalid argument -%c\n", + program, isc_commandline_option); + usage(1); + } + FALLTHROUGH; + case 'h': + usage(0); + break; + default: + fprintf(stderr, "%s: unhandled option -%c\n", program, + isc_commandline_option); + exit(1); + } + } + + argc -= isc_commandline_index; + argv += isc_commandline_index; + + if (argv[0] == NULL) { + usage(1); + } else { + command = argv[0]; + if (strcmp(command, "restart") == 0) { + fatal("'%s' is not implemented", command); + } + notify("%s", command); + } + + serial = isc_random32(); + + isc_mem_create(&rndc_mctx); + isc_managers_create(rndc_mctx, 1, 0, &netmgr, &taskmgr, NULL); + DO("create task", isc_task_create(taskmgr, 0, &rndc_task)); + + isc_nm_settimeouts(netmgr, RNDC_TIMEOUT, RNDC_TIMEOUT, RNDC_TIMEOUT, 0); + + isc_log_create(rndc_mctx, &log, &logconfig); + isc_log_setcontext(log); + isc_log_settag(logconfig, progname); + logdest.file.stream = stderr; + logdest.file.name = NULL; + logdest.file.versions = ISC_LOG_ROLLNEVER; + logdest.file.maximum_size = 0; + isc_log_createchannel(logconfig, "stderr", ISC_LOG_TOFILEDESC, + ISC_LOG_INFO, &logdest, + ISC_LOG_PRINTTAG | ISC_LOG_PRINTLEVEL); + DO("enabling log channel", + isc_log_usechannel(logconfig, "stderr", NULL, NULL)); + + parse_config(rndc_mctx, log, keyname, &pctx, &config); + + isc_buffer_allocate(rndc_mctx, &databuf, 2048); + + /* + * Convert argc/argv into a space-delimited command string + * similar to what the user might enter in interactive mode + * (if that were implemented). + */ + argslen = 0; + for (i = 0; i < argc; i++) { + argslen += strlen(argv[i]) + 1; + } + + args = isc_mem_get(rndc_mctx, argslen); + + p = args; + for (i = 0; i < argc; i++) { + size_t len = strlen(argv[i]); + memmove(p, argv[i], len); + p += len; + *p++ = ' '; + } + + p--; + *p++ = '\0'; + INSIST(p == args + argslen); + + if (nserveraddrs == 0 && servername != NULL) { + get_addresses(servername, (in_port_t)remoteport); + } + + DO("post event", isc_app_onrun(rndc_mctx, rndc_task, rndc_start, NULL)); + + result = isc_app_run(); + if (result != ISC_R_SUCCESS) { + fatal("isc_app_run() failed: %s", isc_result_totext(result)); + } + + isc_managers_destroy(&netmgr, &taskmgr, NULL); + + /* + * Note: when TCP connections are shut down, there will be a final + * call to the isccc callback routine with &rndc_ccmsg as its + * argument. We therefore need to delay invalidating it until + * after the netmgr is closed down. + */ + isccc_ccmsg_invalidate(&rndc_ccmsg); + + isc_log_destroy(&log); + isc_log_setcontext(NULL); + + cfg_obj_destroy(pctx, &config); + cfg_parser_destroy(&pctx); + + isc_mem_put(rndc_mctx, args, argslen); + + isc_buffer_free(&databuf); + + if (show_final_mem) { + isc_mem_stats(rndc_mctx, stderr); + } + + isc_mem_destroy(&rndc_mctx); + + if (failed) { + return (1); + } + + return (0); +} diff --git a/bin/rndc/rndc.conf.rst b/bin/rndc/rndc.conf.rst new file mode 100644 index 0000000..20e6bc9 --- /dev/null +++ b/bin/rndc/rndc.conf.rst @@ -0,0 +1,158 @@ +.. 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:: rndc.conf +.. program:: rndc.conf +.. _man_rndc.conf: + +rndc.conf - rndc configuration file +----------------------------------- + +Synopsis +~~~~~~~~ + +:program:`rndc.conf` + +Description +~~~~~~~~~~~ + +:program:`rndc.conf` is the configuration file for :iscman:`rndc`, the BIND 9 name +server control utility. This file has a similar structure and syntax to +:iscman:`named.conf`. Statements are enclosed in braces and terminated with a +semi-colon. Clauses in the statements are also semi-colon terminated. +The usual comment styles are supported: + +C style: /\* \*/ + +C++ style: // to end of line + +Unix style: # to end of line + +:program:`rndc.conf` is much simpler than :iscman:`named.conf`. The file uses three +statements: an options statement, a server statement, and a key +statement. + +The ``options`` statement contains five clauses. The ``default-server`` +clause is followed by the name or address of a name server. This host +is used when no name server is given as an argument to :iscman:`rndc`. +The ``default-key`` clause is followed by the name of a key, which is +identified by a ``key`` statement. If no ``keyid`` is provided on the +rndc command line, and no ``key`` clause is found in a matching +``server`` statement, this default key is used to authenticate the +server's commands and responses. The ``default-port`` clause is followed +by the port to connect to on the remote name server. If no ``port`` +option is provided on the rndc command line, and no ``port`` clause is +found in a matching ``server`` statement, this default port is used +to connect. The ``default-source-address`` and +``default-source-address-v6`` clauses can be used to set the IPv4 +and IPv6 source addresses respectively. + +After the ``server`` keyword, the server statement includes a string +which is the hostname or address for a name server. The statement has +three possible clauses: ``key``, ``port``, and ``addresses``. The key +name must match the name of a key statement in the file. The port number +specifies the port to connect to. If an ``addresses`` clause is supplied, +these addresses are used instead of the server name. Each address +can take an optional port. If an ``source-address`` or +``source-address-v6`` is supplied, it is used to specify the +IPv4 and IPv6 source address, respectively. + +The ``key`` statement begins with an identifying string, the name of the +key. The statement has two clauses. ``algorithm`` identifies the +authentication algorithm for :iscman:`rndc` to use; currently only HMAC-MD5 +(for compatibility), HMAC-SHA1, HMAC-SHA224, HMAC-SHA256 (default), +HMAC-SHA384, and HMAC-SHA512 are supported. This is followed by a secret +clause which contains the base-64 encoding of the algorithm's +authentication key. The base-64 string is enclosed in double quotes. + +There are two common ways to generate the base-64 string for the secret. +The BIND 9 program :iscman:`rndc-confgen` can be used to generate a random +key, or the ``mmencode`` program, also known as ``mimencode``, can be +used to generate a base-64 string from known input. ``mmencode`` does +not ship with BIND 9 but is available on many systems. See the Example +section for sample command lines for each. + +Example +~~~~~~~ + +:: + + options { + default-server localhost; + default-key samplekey; + }; + +:: + + server localhost { + key samplekey; + }; + +:: + + server testserver { + key testkey; + addresses { localhost port 5353; }; + }; + +:: + + key samplekey { + algorithm hmac-sha256; + secret "6FMfj43Osz4lyb24OIe2iGEz9lf1llJO+lz"; + }; + +:: + + key testkey { + algorithm hmac-sha256; + secret "R3HI8P6BKw9ZwXwN3VZKuQ=="; + }; + + +In the above example, :iscman:`rndc` by default uses the server at +localhost (127.0.0.1) and the key called "samplekey". Commands to the +localhost server use the "samplekey" key, which must also be defined +in the server's configuration file with the same name and secret. The +key statement indicates that "samplekey" uses the HMAC-SHA256 algorithm +and its secret clause contains the base-64 encoding of the HMAC-SHA256 +secret enclosed in double quotes. + +If :option:`rndc -s testserver <rndc -s>` is used, then :iscman:`rndc` connects to the server +on localhost port 5353 using the key "testkey". + +To generate a random secret with :iscman:`rndc-confgen`: + +:iscman:`rndc-confgen` + +A complete :program:`rndc.conf` file, including the randomly generated key, +is written to the standard output. Commented-out ``key`` and +``controls`` statements for :iscman:`named.conf` are also printed. + +To generate a base-64 secret with ``mmencode``: + +``echo "known plaintext for a secret" | mmencode`` + +Name Server Configuration +~~~~~~~~~~~~~~~~~~~~~~~~~ + +The name server must be configured to accept rndc connections and to +recognize the key specified in the :program:`rndc.conf` file, using the +controls statement in :iscman:`named.conf`. See the sections on the +``controls`` statement in the BIND 9 Administrator Reference Manual for +details. + +See Also +~~~~~~~~ + +:iscman:`rndc(8) <rndc>`, :iscman:`rndc-confgen(8) <rndc-confgen>`, :manpage:`mmencode(1)`, BIND 9 Administrator Reference Manual. diff --git a/bin/rndc/rndc.rst b/bin/rndc/rndc.rst new file mode 100644 index 0000000..35a4f31 --- /dev/null +++ b/bin/rndc/rndc.rst @@ -0,0 +1,667 @@ +.. 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:: rndc +.. program:: rndc +.. _man_rndc: + +rndc - name server control utility +---------------------------------- + +Synopsis +~~~~~~~~ + +:program:`rndc` [**-b** source-address] [**-c** config-file] [**-k** key-file] [**-s** server] [**-p** port] [**-q**] [**-r**] [**-V**] [**-y** server_key] [[**-4**] | [**-6**]] {command} + +Description +~~~~~~~~~~~ + +:program:`rndc` controls the operation of a name server. If :program:`rndc` is +invoked with no command line options or arguments, it prints a short +summary of the supported commands and the available options and their +arguments. + +:program:`rndc` communicates with the name server over a TCP connection, +sending commands authenticated with digital signatures. In the current +versions of :program:`rndc` and :iscman:`named`, the only supported authentication +algorithms are HMAC-MD5 (for compatibility), HMAC-SHA1, HMAC-SHA224, +HMAC-SHA256 (default), HMAC-SHA384, and HMAC-SHA512. They use a shared +secret on each end of the connection, which provides TSIG-style +authentication for the command request and the name server's response. +All commands sent over the channel must be signed by a server_key known to +the server. + +:program:`rndc` reads a configuration file to determine how to contact the name +server and decide what algorithm and key it should use. + +Options +~~~~~~~ + +.. option:: -4 + + This option indicates use of IPv4 only. + +.. option:: -6 + + This option indicates use of IPv6 only. + +.. option:: -b source-address + + This option indicates ``source-address`` as the source address for the connection to the + server. Multiple instances are permitted, to allow setting of both the + IPv4 and IPv6 source addresses. + +.. option:: -c config-file + + This option indicates ``config-file`` as the configuration file instead of the default, + |rndc_conf|. + +.. option:: -k key-file + + This option indicates ``key-file`` as the key file instead of the default, + |rndc_key|. The key in |rndc_key| is used to + authenticate commands sent to the server if the config-file does not + exist. + +.. option:: -s server + + ``server`` is the name or address of the server which matches a server + statement in the configuration file for :program:`rndc`. If no server is + supplied on the command line, the host named by the default-server + clause in the options statement of the :program:`rndc` configuration file + is used. + +.. option:: -p port + + This option instructs BIND 9 to send commands to TCP port ``port`` instead of its default control + channel port, 953. + +.. option:: -q + + This option sets quiet mode, where message text returned by the server is not printed + unless there is an error. + +.. option:: -r + + This option instructs :program:`rndc` to print the result code returned by :iscman:`named` + after executing the requested command (e.g., ISC_R_SUCCESS, + ISC_R_FAILURE, etc.). + +.. option:: -V + + This option enables verbose logging. + +.. option:: -y server_key + + This option indicates use of the key ``server_key`` from the configuration file. For control message validation to succeed, ``server_key`` must be known + by :iscman:`named` with the same algorithm and secret string. If no ``server_key`` is specified, + :program:`rndc` first looks for a key clause in the server statement of + the server being used, or if no server statement is present for that + host, then in the default-key clause of the options statement. Note that + the configuration file contains shared secrets which are used to send + authenticated control commands to name servers, and should therefore + not have general read or write access. + +Commands +~~~~~~~~ + +A list of commands supported by :program:`rndc` can be seen by running :program:`rndc` +without arguments. + +Currently supported commands are: + +.. option:: addzone zone [class [view]] configuration + + This command adds a zone while the server is running. This command requires the + ``allow-new-zones`` option to be set to ``yes``. The configuration + string specified on the command line is the zone configuration text + that would ordinarily be placed in :iscman:`named.conf`. + + The configuration is saved in a file called ``viewname.nzf`` (or, if + :iscman:`named` is compiled with liblmdb, an LMDB database file called + ``viewname.nzd``). ``viewname`` is the name of the view, unless the view + name contains characters that are incompatible with use as a file + name, in which case a cryptographic hash of the view name is used + instead. When :iscman:`named` is restarted, the file is loaded into + the view configuration so that zones that were added can persist + after a restart. + + This sample ``addzone`` command adds the zone ``example.com`` to + the default view: + + ``rndc addzone example.com '{ type primary; file "example.com.db"; };'`` + + (Note the brackets around and semi-colon after the zone configuration + text.) + + See also :option:`rndc delzone` and :option:`rndc modzone`. + +.. option:: delzone [-clean] zone [class [view]] + + This command deletes a zone while the server is running. + + If the ``-clean`` argument is specified, the zone's master file (and + journal file, if any) are deleted along with the zone. Without + the ``-clean`` option, zone files must be deleted manually. (If the + zone is of type ``secondary`` or ``stub``, the files needing to be removed + are reported in the output of the ``rndc delzone`` command.) + + If the zone was originally added via ``rndc addzone``, then it is + removed permanently. However, if it was originally configured in + :iscman:`named.conf`, then that original configuration remains in place; + when the server is restarted or reconfigured, the zone is + recreated. To remove it permanently, it must also be removed from + :iscman:`named.conf`. + + See also :option:`rndc addzone` and :option:`rndc modzone`. + +.. option:: dnssec (-status | -rollover -key id [-alg algorithm] [-when time] | -checkds [-key id [-alg algorithm]] [-when time] published | withdrawn)) zone [class [view]] + + This command allows you to interact with the "dnssec-policy" of a given + zone. + + ``rndc dnssec -status`` show the DNSSEC signing state for the specified + zone. + + ``rndc dnssec -rollover`` allows you to schedule key rollover for a + specific key (overriding the original key lifetime). + + ``rndc dnssec -checkds`` informs :iscman:`named` that the DS for + a specified zone's key-signing key has been confirmed to be published + in, or withdrawn from, the parent zone. This is required in order to + complete a KSK rollover. The ``-key id`` and ``-alg algorithm`` arguments + can be used to specify a particular KSK, if necessary; if there is only + one key acting as a KSK for the zone, these arguments can be omitted. + The time of publication or withdrawal for the DS is set to the current + time by default, but can be overridden to a specific time with the + argument ``-when time``, where ``time`` is expressed in YYYYMMDDHHMMSS + notation. + +.. option:: dnstap (-reopen | -roll [number]) + + This command closes and re-opens DNSTAP output files. + + ``rndc dnstap -reopen`` allows + the output file to be renamed externally, so that :iscman:`named` can + truncate and re-open it. + + ``rndc dnstap -roll`` causes the output file + to be rolled automatically, similar to log files. The most recent + output file has ".0" appended to its name; the previous most recent + output file is moved to ".1", and so on. If ``number`` is specified, then + the number of backup log files is limited to that number. + +.. option:: dumpdb [-all | -cache | -zones | -adb | -bad | -expired | -fail] [view ...] + + This command dumps the server's caches (default) and/or zones to the dump file for + the specified views. If no view is specified, all views are dumped. + (See the ``dump-file`` option in the BIND 9 Administrator Reference + Manual.) + +.. option:: flush + + This command flushes the server's cache. + +.. option:: flushname name [view] + + This command flushes the given name from the view's DNS cache and, if applicable, + from the view's nameserver address database, bad server cache, and + SERVFAIL cache. + +.. option:: flushtree name [view] + + This command flushes the given name, and all of its subdomains, from the view's + DNS cache, address database, bad server cache, and SERVFAIL cache. + +.. option:: freeze [zone [class [view]]] + + This command suspends updates to a dynamic zone. If no zone is specified, then all + zones are suspended. This allows manual edits to be made to a zone + normally updated by dynamic update, and causes changes in the + journal file to be synced into the master file. All dynamic update + attempts are refused while the zone is frozen. + + See also :option:`rndc thaw`. + +.. option:: halt [-p] + + This command stops the server immediately. Recent changes made through dynamic + update or IXFR are not saved to the master files, but are rolled + forward from the journal files when the server is restarted. If + ``-p`` is specified, :iscman:`named`'s process ID is returned. This allows + an external process to determine when :iscman:`named` has completed + halting. + + See also :option:`rndc stop`. + +.. option:: loadkeys [zone [class [view]]] + + This command fetches all DNSSEC keys for the given zone from the key directory. If + they are within their publication period, they are merged into the + zone's DNSKEY RRset. Unlike :option:`rndc sign`, however, the zone is not + immediately re-signed by the new keys, but is allowed to + incrementally re-sign over time. + + This command requires that the zone be configured with a ``dnssec-policy``, or + that the ``auto-dnssec`` zone option be set to ``maintain``, and also requires the + zone to be configured to allow dynamic DNS. (See "Dynamic Update Policies" in + the Administrator Reference Manual for more details.) + +.. option:: managed-keys (status | refresh | sync | destroy) [class [view]] + + This command inspects and controls the "managed-keys" database which handles + :rfc:`5011` DNSSEC trust anchor maintenance. If a view is specified, these + commands are applied to that view; otherwise, they are applied to all + views. + + - When run with the ``status`` keyword, this prints the current status of + the managed-keys database. + + - When run with the ``refresh`` keyword, this forces an immediate refresh + query to be sent for all the managed keys, updating the + managed-keys database if any new keys are found, without waiting + the normal refresh interval. + + - When run with the ``sync`` keyword, this forces an immediate dump of + the managed-keys database to disk (in the file + ``managed-keys.bind`` or (``viewname.mkeys``). This synchronizes + the database with its journal file, so that the database's current + contents can be inspected visually. + + - When run with the ``destroy`` keyword, the managed-keys database + is shut down and deleted, and all key maintenance is terminated. + This command should be used only with extreme caution. + + Existing keys that are already trusted are not deleted from + memory; DNSSEC validation can continue after this command is used. + However, key maintenance operations cease until :iscman:`named` is + restarted or reconfigured, and all existing key maintenance states + are deleted. + + Running :option:`rndc reconfig` or restarting :iscman:`named` immediately + after this command causes key maintenance to be reinitialized + from scratch, just as if the server were being started for the + first time. This is primarily intended for testing, but it may + also be used, for example, to jumpstart the acquisition of new + keys in the event of a trust anchor rollover, or as a brute-force + repair for key maintenance problems. + +.. option:: modzone zone [class [view]] configuration + + This command modifies the configuration of a zone while the server is running. This + command requires the ``allow-new-zones`` option to be set to ``yes``. + As with ``addzone``, the configuration string specified on the + command line is the zone configuration text that would ordinarily be + placed in :iscman:`named.conf`. + + If the zone was originally added via :option:`rndc addzone`, the + configuration changes are recorded permanently and are still + in effect after the server is restarted or reconfigured. However, if + it was originally configured in :iscman:`named.conf`, then that original + configuration remains in place; when the server is restarted or + reconfigured, the zone reverts to its original configuration. To + make the changes permanent, it must also be modified in + :iscman:`named.conf`. + + See also :option:`rndc addzone` and :option:`rndc delzone`. + +.. option:: notify zone [class [view]] + + This command resends NOTIFY messages for the zone. + +.. option:: notrace + + This command sets the server's debugging level to 0. + + See also :option:`rndc trace`. + +.. option:: nta [(-class class | -dump | -force | -remove | -lifetime duration)] domain [view] + + This command sets a DNSSEC negative trust anchor (NTA) for ``domain``, with a + lifetime of ``duration``. The default lifetime is configured in + :iscman:`named.conf` via the ``nta-lifetime`` option, and defaults to one + hour. The lifetime cannot exceed one week. + + A negative trust anchor selectively disables DNSSEC validation for + zones that are known to be failing because of misconfiguration rather + than an attack. When data to be validated is at or below an active + NTA (and above any other configured trust anchors), :iscman:`named` + aborts the DNSSEC validation process and treats the data as insecure + rather than bogus. This continues until the NTA's lifetime has + elapsed. + + NTAs persist across restarts of the :iscman:`named` server. The NTAs for a + view are saved in a file called ``name.nta``, where ``name`` is the name + of the view; if it contains characters that are incompatible with + use as a file name, a cryptographic hash is generated from the name of + the view. + + An existing NTA can be removed by using the ``-remove`` option. + + An NTA's lifetime can be specified with the ``-lifetime`` option. + TTL-style suffixes can be used to specify the lifetime in seconds, + minutes, or hours. If the specified NTA already exists, its lifetime + is updated to the new value. Setting ``lifetime`` to zero is + equivalent to ``-remove``. + + If ``-dump`` is used, any other arguments are ignored and a list + of existing NTAs is printed. Note that this may include NTAs that are + expired but have not yet been cleaned up. + + Normally, :iscman:`named` periodically tests to see whether data below + an NTA can now be validated (see the ``nta-recheck`` option in the + Administrator Reference Manual for details). If data can be + validated, then the NTA is regarded as no longer necessary and is + allowed to expire early. The ``-force`` parameter overrides this behavior + and forces an NTA to persist for its entire lifetime, regardless of + whether data could be validated if the NTA were not present. + + The view class can be specified with ``-class``. The default is class + ``IN``, which is the only class for which DNSSEC is currently + supported. + + All of these options can be shortened, i.e., to ``-l``, ``-r``, + ``-d``, ``-f``, and ``-c``. + + Unrecognized options are treated as errors. To refer to a domain or + view name that begins with a hyphen, use a double-hyphen (--) on the + command line to indicate the end of options. + +.. option:: querylog [(on | off)] + + This command enables or disables query logging. For backward compatibility, this + command can also be used without an argument to toggle query logging + on and off. + + Query logging can also be enabled by explicitly directing the + ``queries`` ``category`` to a ``channel`` in the ``logging`` section + of :iscman:`named.conf`, or by specifying ``querylog yes;`` in the + ``options`` section of :iscman:`named.conf`. + +.. option:: reconfig + + This command reloads the configuration file and loads new zones, but does not reload + existing zone files even if they have changed. This is faster than a + full :option:`rndc reload` when there is a large number of zones, because it + avoids the need to examine the modification times of the zone files. + +.. option:: recursing + + This command dumps the list of queries :iscman:`named` is currently + recursing on, and the list of domains to which iterative queries + are currently being sent. + + The first list includes all unique clients that are waiting for + recursion to complete, including the query that is awaiting a + response and the timestamp (seconds since the Unix epoch) of + when named started processing this client query. + + The second list comprises of domains for which there are active + (or recently active) fetches in progress. It reports the number + of active fetches for each domain and the number of queries that + have been passed (allowed) or dropped (spilled) as a result of + the ``fetches-per-zone`` limit. (Note: these counters are not + cumulative over time; whenever the number of active fetches for + a domain drops to zero, the counter for that domain is deleted, + and the next time a fetch is sent to that domain, it is recreated + with the counters set to zero). + +.. option:: refresh zone [class [view]] + + This command schedules zone maintenance for the given zone. + +.. option:: reload + + This command reloads the configuration file and zones. + + .. program:: rndc reload + .. option:: zone [class [view]] + + If a zone is specified, this command reloads only the given zone. + +.. program:: rndc + +.. option:: retransfer zone [class [view]] + + This command retransfers the given secondary zone from the primary server. + + If the zone is configured to use ``inline-signing``, the signed + version of the zone is discarded; after the retransfer of the + unsigned version is complete, the signed version is regenerated + with new signatures. + +.. option:: scan + + This command scans the list of available network interfaces for changes, without + performing a full :option:`rndc reconfig` or waiting for the + ``interface-interval`` timer. + +.. option:: secroots [-] [view ...] + + This command dumps the security roots (i.e., trust anchors configured via + ``trust-anchors``, or the ``managed-keys`` or ``trusted-keys`` statements + [both deprecated], or ``dnssec-validation auto``) and negative trust anchors + for the specified views. If no view is specified, all views are + dumped. Security roots indicate whether they are configured as trusted + keys, managed keys, or initializing managed keys (managed keys that have not + yet been updated by a successful key refresh query). + + If the first argument is ``-``, then the output is returned via the + :program:`rndc` response channel and printed to the standard output. + Otherwise, it is written to the secroots dump file, which defaults to + ``named.secroots``, but can be overridden via the ``secroots-file`` + option in :iscman:`named.conf`. + + See also :option:`rndc managed-keys`. + +.. option:: serve-stale (on | off | reset | status) [class [view]] + + This command enables, disables, resets, or reports the current status of + the serving of stale answers as configured in :iscman:`named.conf`. + + If serving of stale answers is disabled by ``rndc-serve-stale off``, then it + remains disabled even if :iscman:`named` is reloaded or reconfigured. ``rndc + serve-stale reset`` restores the setting as configured in :iscman:`named.conf`. + + ``rndc serve-stale status`` reports whether caching and serving of stale + answers is currently enabled or disabled. It also reports the values of + ``stale-answer-ttl`` and ``max-stale-ttl``. + +.. option:: showzone zone [class [view]] + + This command prints the configuration of a running zone. + + See also :option:`rndc zonestatus`. + +.. option:: sign zone [class [view]] + + This command fetches all DNSSEC keys for the given zone from the key directory (see + the ``key-directory`` option in the BIND 9 Administrator Reference + Manual). If they are within their publication period, they are merged into + the zone's DNSKEY RRset. If the DNSKEY RRset is changed, then the + zone is automatically re-signed with the new key set. + + This command requires that the zone be configured with a ``dnssec-policy``, or + that the ``auto-dnssec`` zone option be set to ``allow`` or ``maintain``, + and also requires the zone to be configured to allow dynamic DNS. (See + "Dynamic Update Policies" in the BIND 9 Administrator Reference Manual for more + details.) + + See also :option:`rndc loadkeys`. + +.. option:: signing [(-list | -clear keyid/algorithm | -clear all | -nsec3param (parameters | none) | -serial value) zone [class [view]] + + This command lists, edits, or removes the DNSSEC signing-state records for the + specified zone. The status of ongoing DNSSEC operations, such as + signing or generating NSEC3 chains, is stored in the zone in the form + of DNS resource records of type ``sig-signing-type``. + ``rndc signing -list`` converts these records into a human-readable + form, indicating which keys are currently signing or have finished + signing the zone, and which NSEC3 chains are being created or + removed. + + ``rndc signing -clear`` can remove a single key (specified in the + same format that ``rndc signing -list`` uses to display it), or all + keys. In either case, only completed keys are removed; any record + indicating that a key has not yet finished signing the zone is + retained. + + ``rndc signing -nsec3param`` sets the NSEC3 parameters for a zone. + This is the only supported mechanism for using NSEC3 with + ``inline-signing`` zones. Parameters are specified in the same format + as an NSEC3PARAM resource record: ``hash algorithm``, ``flags``, ``iterations``, + and ``salt``, in that order. + + Currently, the only defined value for ``hash algorithm`` is ``1``, + representing SHA-1. The ``flags`` may be set to ``0`` or ``1``, + depending on whether the opt-out bit in the NSEC3 + chain should be set. ``iterations`` defines the number of additional times to apply + the algorithm when generating an NSEC3 hash. The ``salt`` is a string + of data expressed in hexadecimal, a hyphen (``-``) if no salt is to be + used, or the keyword ``auto``, which causes :iscman:`named` to generate a + random 64-bit salt. + + The only recommended configuration is ``rndc signing -nsec3param 1 0 0 - zone``, + i.e. no salt, no additional iterations, no opt-out. + + .. warning:: + Do not use extra iterations, salt, or opt-out unless all their implications + are fully understood. A higher number of iterations causes interoperability + problems and opens servers to CPU-exhausting DoS attacks. + + ``rndc signing -nsec3param none`` removes an existing NSEC3 chain and + replaces it with NSEC. + + ``rndc signing -serial value`` sets the serial number of the zone to + ``value``. If the value would cause the serial number to go backwards, it + is rejected. The primary use of this parameter is to set the serial number on inline + signed zones. + +.. option:: stats + + This command writes server statistics to the statistics file. (See the + ``statistics-file`` option in the BIND 9 Administrator Reference + Manual.) + +.. option:: status + + This command displays the status of the server. Note that the number of zones includes + the internal ``bind/CH`` zone and the default ``./IN`` hint zone, if + there is no explicit root zone configured. + +.. option:: stop -p + + This command stops the server, making sure any recent changes made through dynamic + update or IXFR are first saved to the master files of the updated + zones. If ``-p`` is specified, :iscman:`named`'s process ID is returned. + This allows an external process to determine when :iscman:`named` has + completed stopping. + + See also :option:`rndc halt`. + +.. option:: sync -clean [zone [class [view]]] + + This command syncs changes in the journal file for a dynamic zone to the master + file. If the "-clean" option is specified, the journal file is also + removed. If no zone is specified, then all zones are synced. + +.. option:: tcp-timeouts [initial idle keepalive advertised] + + When called without arguments, this command displays the current values of the + ``tcp-initial-timeout``, ``tcp-idle-timeout``, + ``tcp-keepalive-timeout``, and ``tcp-advertised-timeout`` options. + When called with arguments, these values are updated. This allows an + administrator to make rapid adjustments when under a + denial-of-service (DoS) attack. See the descriptions of these options in the BIND 9 + Administrator Reference Manual for details of their use. + +.. option:: thaw [zone [class [view]]] + + This command enables updates to a frozen dynamic zone. If no zone is specified, + then all frozen zones are enabled. This causes the server to reload + the zone from disk, and re-enables dynamic updates after the load has + completed. After a zone is thawed, dynamic updates are no longer + refused. If the zone has changed and the ``ixfr-from-differences`` + option is in use, the journal file is updated to reflect + changes in the zone. Otherwise, if the zone has changed, any existing + journal file is removed. + + See also :option:`rndc freeze`. + +.. option:: trace [level] + + If no level is specified, this command increments the server's debugging + level by one. + + .. program:: rndc trace + .. option:: level + + If specified, this command sets the server's debugging level to the + provided value. + + See also :option:`rndc notrace`. + +.. program:: rndc + +.. option:: tsig-delete keyname [view] + + This command deletes a given TKEY-negotiated key from the server. This does not + apply to statically configured TSIG keys. + +.. option:: tsig-list + + This command lists the names of all TSIG keys currently configured for use by + :iscman:`named` in each view. The list includes both statically configured keys and + dynamic TKEY-negotiated keys. + +.. option:: validation (on | off | status) [view ...] + + This command enables, disables, or checks the current status of DNSSEC validation. By + default, validation is enabled. + + The cache is flushed when validation is turned on or off to avoid using data + that might differ between states. + +.. option:: zonestatus zone [class [view]] + + This command displays the current status of the given zone, including the master + file name and any include files from which it was loaded, when it was + most recently loaded, the current serial number, the number of nodes, + whether the zone supports dynamic updates, whether the zone is DNSSEC + signed, whether it uses automatic DNSSEC key management or inline + signing, and the scheduled refresh or expiry times for the zone. + + See also :option:`rndc showzone`. + +:program:`rndc` commands that specify zone names, such as :option:`reload` +:option:`retransfer`, or :option:`zonestatus`, can be ambiguous when applied to zones +of type ``redirect``. Redirect zones are always called ``.``, and can be +confused with zones of type ``hint`` or with secondary copies of the root +zone. To specify a redirect zone, use the special zone name +``-redirect``, without a trailing period. (With a trailing period, this +would specify a zone called "-redirect".) + +Limitations +~~~~~~~~~~~ + +There is currently no way to provide the shared secret for a ``server_key`` +without using the configuration file. + +Several error messages could be clearer. + +See Also +~~~~~~~~ + +:iscman:`rndc.conf(5) <rndc.conf>`, :iscman:`rndc-confgen(8) <rndc-confgen>`, +:iscman:`named(8) <named>`, :iscman:`named.conf(5) <named.conf>`, BIND 9 Administrator +Reference Manual. diff --git a/bin/rndc/util.c b/bin/rndc/util.c new file mode 100644 index 0000000..b0085fe --- /dev/null +++ b/bin/rndc/util.c @@ -0,0 +1,49 @@ +/* + * 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 "util.h" +#include <stdarg.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> + +#include <isc/print.h> + +extern bool verbose; +extern const char *progname; + +void +notify(const char *fmt, ...) { + va_list ap; + + if (verbose) { + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + } +} + +void +fatal(const char *format, ...) { + va_list args; + + fprintf(stderr, "%s: ", progname); + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fprintf(stderr, "\n"); + exit(1); +} diff --git a/bin/rndc/util.h b/bin/rndc/util.h new file mode 100644 index 0000000..4ac83e5 --- /dev/null +++ b/bin/rndc/util.h @@ -0,0 +1,42 @@ +/* + * 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 <isc/attributes.h> +#include <isc/formatcheck.h> +#include <isc/lang.h> + +#define NS_CONTROL_PORT 953 + +#undef DO +#define DO(name, function) \ + do { \ + result = function; \ + if (result != ISC_R_SUCCESS) \ + fatal("%s: %s", name, isc_result_totext(result)); \ + else \ + notify("%s", name); \ + } while (0) + +ISC_LANG_BEGINDECLS + +void +notify(const char *fmt, ...) ISC_FORMAT_PRINTF(1, 2); + +noreturn void +fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); + +ISC_LANG_ENDDECLS |