unbound-checkconf.

git-svn-id: file:///svn/unbound/trunk@647 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-09-26 13:39:49 +00:00
parent c2f8d43f9d
commit 8f8627a0c3
8 changed files with 236 additions and 9 deletions

View file

@ -62,6 +62,8 @@ UNITTEST_SRC=$(wildcard testcode/unit*.c) testcode/readhex.c \
UNITTEST_OBJ=$(addprefix $(BUILD),$(UNITTEST_SRC:.c=.o)) $(COMPAT_OBJ) UNITTEST_OBJ=$(addprefix $(BUILD),$(UNITTEST_SRC:.c=.o)) $(COMPAT_OBJ)
DAEMON_SRC=$(wildcard daemon/*.c) $(COMMON_SRC) DAEMON_SRC=$(wildcard daemon/*.c) $(COMMON_SRC)
DAEMON_OBJ=$(addprefix $(BUILD),$(DAEMON_SRC:.c=.o)) $(COMPAT_OBJ) DAEMON_OBJ=$(addprefix $(BUILD),$(DAEMON_SRC:.c=.o)) $(COMPAT_OBJ)
CHECKCONF_SRC=checkconf/unbound-checkconf.c $(COMMON_SRC)
CHECKCONF_OBJ=$(addprefix $(BUILD),$(CHECKCONF_SRC:.c=.o)) $(COMPAT_OBJ)
TESTBOUND_SRC=testcode/testbound.c testcode/ldns-testpkts.c \ TESTBOUND_SRC=testcode/testbound.c testcode/ldns-testpkts.c \
daemon/worker.c daemon/daemon.c daemon/stats.c testcode/replay.c \ daemon/worker.c daemon/daemon.c daemon/stats.c testcode/replay.c \
testcode/fake_event.c $(filter-out util/netevent.c \ testcode/fake_event.c $(filter-out util/netevent.c \
@ -92,7 +94,7 @@ $(BUILD)%.o: $(srcdir)/%.c
.PHONY: clean realclean doc lint all install uninstall tests test .PHONY: clean realclean doc lint all install uninstall tests test
all: $(COMMON_OBJ) unbound all: $(COMMON_OBJ) unbound unbound-checkconf
tests: unittest testbound lock-verify pktview signit memstats tests: unittest testbound lock-verify pktview signit memstats
@ -103,6 +105,10 @@ unbound: $(DAEMON_OBJ)
$(INFO) Link $@ $(INFO) Link $@
$Q$(LINK) -o $@ $^ $(LIBS) $Q$(LINK) -o $@ $^ $(LIBS)
unbound-checkconf: $(CHECKCONF_OBJ)
$(INFO) Link $@
$Q$(LINK) -o $@ $^ $(LIBS)
unittest: $(UNITTEST_OBJ) unittest: $(UNITTEST_OBJ)
$(INFO) Link $@ $(INFO) Link $@
$Q$(LINK) -o $@ $^ $(LIBS) $Q$(LINK) -o $@ $^ $(LIBS)
@ -181,12 +187,14 @@ install:
$(INSTALL) -d $(mandir)/man8 $(INSTALL) -d $(mandir)/man8
$(INSTALL) -d $(mandir)/man5 $(INSTALL) -d $(mandir)/man5
$(LIBTOOL) --mode=install cp unbound $(bindir)/unbound $(LIBTOOL) --mode=install cp unbound $(bindir)/unbound
$(LIBTOOL) --mode=install cp unbound-checkconf $(bindir)/unbound-checkconf
$(INSTALL) -c -m 644 $(srcdir)/doc/unbound.8 $(mandir)/man8 $(INSTALL) -c -m 644 $(srcdir)/doc/unbound.8 $(mandir)/man8
$(INSTALL) -c -m 644 $(srcdir)/doc/unbound-checkconf.8 $(mandir)/man8
$(INSTALL) -c -m 644 $(srcdir)/doc/unbound.conf.5 $(mandir)/man5 $(INSTALL) -c -m 644 $(srcdir)/doc/unbound.conf.5 $(mandir)/man5
uninstall: uninstall:
rm -f -- $(bindir)/unbound rm -f -- $(bindir)/unbound $(bindir)/unbound-checkconf
rm -f -- $(mandir)/man8/unbound.8 $(mandir)/man5/unbound.conf.5 rm -f -- $(mandir)/man8/unbound.8 $(mandir)/man8/unbound-checkconf.8 $(mandir)/man5/unbound.conf.5
# Automatic dependencies. # Automatic dependencies.
$(BUILD)%.d: $(srcdir)/%.c $(BUILD)%.d: $(srcdir)/%.c

View file

@ -0,0 +1,171 @@
/*
* checkconf/unbound-checkconf.c - config file checker for unbound.conf file.
*
* Copyright (c) 2007, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* The config checker checks for syntax and other errors in the unbound.conf
* file, and can be used to check for errors before the server is started
* or sigHUPped.
* Exit status 1 means an error.
*/
#include "config.h"
#include "util/log.h"
#include "util/config_file.h"
#include "util/module.h"
#include "util/region-allocator.h"
#include "iterator/iterator.h"
#include "validator/validator.h"
#include <pwd.h>
/** Give checkconf usage, and exit (1). */
static void
usage()
{
printf("Usage: unbound-checkconf [options] file\n");
printf(" Checks unbound configuration file for errors.\n");
printf("-h show this usage help.\n");
printf("Version %s\n", PACKAGE_VERSION);
printf("BSD licensed, see LICENSE in source package for details.\n");
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
exit(1);
}
/** check if module works with config */
static void
check_mod(struct config_file* cfg, struct module_func_block* fb)
{
struct module_env env;
memset(&env, 0, sizeof(env));
env.cfg = cfg;
env.scratch = region_create(malloc, free);
env.scratch_buffer = ldns_buffer_new(BUFSIZ);
if(!(*fb->init)(&env, 0)) {
fatal_exit("bad config for %s module", fb->name);
}
(*fb->deinit)(&env, 0);
ldns_buffer_free(env.scratch_buffer);
region_destroy(env.scratch);
}
/** check configuration for errors */
static void
morechecks(struct config_file* cfg)
{
if(cfg->verbosity < 0)
fatal_exit("verbosity value < 0");
if(cfg->num_threads < 0 || cfg->num_threads > 10000)
fatal_exit("num_threads value weird");
if(!cfg->do_ip4 && !cfg->do_ip6)
fatal_exit("ip4 and ip6 are both disabled, pointless");
if(!cfg->do_udp && !cfg->do_tcp)
fatal_exit("udp and tcp are both disabled, pointless");
if(cfg->chrootdir && strncmp(cfg->chrootdir, cfg->directory,
strlen(cfg->chrootdir)) != 0)
fatal_exit("working directory %s not in chrootdir %s",
cfg->directory, cfg->chrootdir);
if(cfg->chrootdir && cfg->pidfile && cfg->pidfile[0] &&
strncmp(cfg->chrootdir, cfg->pidfile,
strlen(cfg->chrootdir)) != 0)
fatal_exit("pid file %s not in chrootdir %s",
cfg->pidfile, cfg->chrootdir);
if(cfg->chrootdir && cfg->logfile && cfg->logfile[0] &&
strncmp(cfg->chrootdir, cfg->logfile,
strlen(cfg->chrootdir)) != 0)
fatal_exit("log file %s not in chrootdir %s",
cfg->logfile, cfg->chrootdir);
if(strcmp(cfg->module_conf, "iterator") != 0 &&
strcmp(cfg->module_conf, "validator iterator") != 0) {
fatal_exit("module conf %s is not known to work",
cfg->module_conf);
}
if(cfg->username && cfg->username[0]) {
struct passwd *pwd;
if((pwd = getpwnam(cfg->username)) == NULL)
fatal_exit("user '%s' does not exist.", cfg->username);
endpwent();
}
}
/** check config file */
static void
checkconf(const char* cfgfile)
{
struct config_file* cfg = config_create();
if(!cfg)
fatal_exit("out of memory");
if(!config_read(cfg, cfgfile)) {
/* config_read prints messages to stderr */
config_delete(cfg);
exit(1);
}
morechecks(cfg);
check_mod(cfg, iter_get_funcblock());
check_mod(cfg, val_get_funcblock());
config_delete(cfg);
printf("unbound-checkconf: no errors in %s\n", cfgfile);
}
/** getopt global, in case header files fail to declare it. */
extern int optind;
/** getopt global, in case header files fail to declare it. */
extern char* optarg;
/** Main routine for checkconf */
int main(int argc, char* argv[])
{
int c;
log_ident_set("unbound-checkconf");
log_init(NULL, 0);
/* parse the options */
while( (c=getopt(argc, argv, "h")) != -1) {
switch(c) {
case '?':
case 'h':
default:
usage();
}
}
argc -= optind;
argv += optind;
if(argc != 1)
usage();
checkconf(argv[0]);
return 0;
}

View file

@ -2,6 +2,7 @@
- SIGHUP will reopen the log file. - SIGHUP will reopen the log file.
- Option to log to syslog. - Option to log to syslog.
- please lint, fixup tests (that went to syslog on open, oops). - please lint, fixup tests (that went to syslog on open, oops).
- config check program.
25 September 2007: Wouter 25 September 2007: Wouter
- tests for NSEC3. Fixup bitmap checks for NSEC3. - tests for NSEC3. Fixup bitmap checks for NSEC3.

39
doc/unbound-checkconf.8 Normal file
View file

@ -0,0 +1,39 @@
.\"
.\" unbound-checkconf.8 -- unbound configuration checker manual
.\"
.\" Copyright (c) 2007, NLnet Labs. All rights reserved.
.\"
.\" See LICENSE for the license.
.\"
.\"
.Dd @date@
.Dt unbound-checkconf 8
.Sh NAME
unbound-checkconf
.Nd Check unbound configuration file for errors.
.Sh SYNOPSIS
.Nm unbound-checkconf
.Op Fl h
cfgfile
.Sh DESCRIPTION
.Ic Unbound-checkconf
checks the configuration file for the
.Xr unbound 8
DNS resolver for syntax and other errors.
The config file syntax is
described in
.Xr unbound.conf 5 .
.Pp
The available options are:
.Bl -tag -width indent
.It Fl h
Show the version and commandline option help.
.It cfgfile
The config file to read with settings for unbound. It is checked.
.Sh EXIT CODE
The unbound-checkconf program exits with status code 1 on error,
0 for a correct config file.
.El
.Sh SEE ALSO
.Xr unbound.conf 5 ,
.Xr unbound 8 .

View file

@ -38,7 +38,8 @@ Increase verbosity. If given multiple times, more information is logged.
This is in addition to the verbosity (if any) from the config file. This is in addition to the verbosity (if any) from the config file.
.El .El
.Sh SEE ALSO .Sh SEE ALSO
.Xr unbound.conf 5 . .Xr unbound.conf 5 ,
.Xr unbound-checkconf 8 .
.Sh AUTHORS .Sh AUTHORS
.Ic Unbound .Ic Unbound
developers are mentioned in the CREDITS file in the distribution. developers are mentioned in the CREDITS file in the distribution.

View file

@ -23,6 +23,10 @@ The notation is: attribute: value.
.Pp .Pp
Comments start with # and last to the end of line. Empty lines are Comments start with # and last to the end of line. Empty lines are
ignored as is whitespace at the beginning of a line. ignored as is whitespace at the beginning of a line.
.Pp
The utility
.Xr unbound-checkconf 8
can be used to check unbound.conf prior to usage.
.Sh EXAMPLE .Sh EXAMPLE
An example config file is shown below. Copy this to /etc/unbound/unbound.conf An example config file is shown below. Copy this to /etc/unbound/unbound.conf
and start the server with: and start the server with:
@ -55,7 +59,7 @@ directive. It can appear anywhere, and takes a single filename as an argument.
Processing continues as if the text from the included file was copied into Processing continues as if the text from the included file was copied into
the config file at that point. the config file at that point.
.Ss Server Options .Ss Server Options
There may only be one These options are part of the
.Ic server: .Ic server:
clause. clause.
.Bl -tag -width indent .Bl -tag -width indent
@ -327,7 +331,8 @@ default unbound pidfile with process ID of the running daemon.
unbound log file. unbound log file.
.El .El
.Sh SEE ALSO .Sh SEE ALSO
.Xr unbound 8 .Xr unbound 8 ,
.Xr unbound-checkconf 8 .
.Sh AUTHORS .Sh AUTHORS
.Ic Unbound .Ic Unbound
was written by NLnet Labs. Please see CREDITS file was written by NLnet Labs. Please see CREDITS file

View file

@ -286,6 +286,7 @@ read_stubs(struct iter_hints* hints, struct config_file* cfg)
return 0; return 0;
if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp)) if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp))
return 0; return 0;
if(verbosity >= VERB_DETAIL)
delegpt_log(dp); delegpt_log(dp);
} }
return 1; return 1;
@ -312,6 +313,7 @@ hints_apply_cfg(struct iter_hints* hints, struct config_file* cfg)
return 0; return 0;
if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp)) if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp))
return 0; return 0;
if(verbosity >= VERB_DETAIL)
delegpt_log(dp); delegpt_log(dp);
} }

View file

@ -56,7 +56,7 @@
#endif #endif
/* default verbosity */ /* default verbosity */
enum verbosity_value verbosity = 4; enum verbosity_value verbosity = 0;
/** the file logged to. */ /** the file logged to. */
static FILE* logfile = 0; static FILE* logfile = 0;
/** if key has been created */ /** if key has been created */