check.c revision af0d9b770594ece695cc9a7325ed42abb728a5f7
/*
* Copyright (C) 2001-2017 Internet Systems Consortium, Inc. ("ISC")
*
* 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 http://mozilla.org/MPL/2.0/.
*/
/*! \file */
#include <config.h>
#include <stdlib.h>
#include <isc/parseint.h>
#include <isc/platform.h>
#include <isc/sockaddr.h>
#include <dns/fixedname.h>
#include <dns/rdataclass.h>
#include <dns/rdatatype.h>
static isc_result_t
static void
}
static isc_result_t
isc_buffer_t b;
const char *str;
if (cfg_obj_isstring(obj)) {
if (tresult != ISC_R_SUCCESS) {
"rrset-order: invalid class '%s'",
r.base);
}
}
if (cfg_obj_isstring(obj)) {
if (tresult != ISC_R_SUCCESS) {
"rrset-order: invalid type '%s'",
r.base);
}
}
if (cfg_obj_isstring(obj)) {
dns_rootname, 0, NULL);
if (tresult != ISC_R_SUCCESS) {
"rrset-order: invalid name '%s'", str);
}
}
if (!cfg_obj_isstring(obj) ||
"rrset-order: keyword 'order' missing");
}
if (!cfg_obj_isstring(obj)) {
"rrset-order: missing ordering");
#if !DNS_RDATASET_FIXED
"rrset-order: order 'fixed' was disabled at "
"compilation time");
#endif
"rrset-order: invalid order '%s'",
}
return (result);
}
static isc_result_t
const cfg_listelt_t *element;
return (result);
{
if (tresult != ISC_R_SUCCESS)
}
return (result);
}
static isc_result_t
const cfg_listelt_t *element;
const char *str;
if (alternates == NULL)
return (ISC_R_SUCCESS);
if (cfg_obj_isuint32(obj)) {
if (val > ISC_UINT16_MAX) {
"port '%u' out of range", val);
}
}
if (cfg_obj_issockaddr(value))
continue;
0, NULL);
if (tresult != ISC_R_SUCCESS) {
"bad name '%s'", str);
}
if (cfg_obj_isuint32(obj)) {
if (val > ISC_UINT16_MAX) {
"port '%u' out of range", val);
}
}
}
return (result);
}
static isc_result_t
{
"forwarders declared in root zone and "
"in general configuration: %s:%u",
return (ISC_R_FAILURE);
}
"no matching 'forwarders' statement");
return (ISC_R_FAILURE);
}
return (ISC_R_SUCCESS);
}
static isc_result_t
const cfg_listelt_t *element;
const char *str;
isc_buffer_t b;
if (tresult != ISC_R_SUCCESS) {
"bad domain name '%s'", str);
}
{
if (tresult != ISC_R_SUCCESS) {
ISC_LOG_ERROR, "invalid algorithm '%s'",
r.base);
}
}
return (result);
}
static isc_result_t
const cfg_listelt_t *element;
const char *str;
isc_buffer_t b;
if (tresult != ISC_R_SUCCESS) {
"bad domain name '%s'", str);
}
{
/* works with a numeric argument too */
if (tresult != ISC_R_SUCCESS) {
ISC_LOG_ERROR, "invalid digest type '%s'",
r.base);
}
}
return (result);
}
static isc_result_t
{
char *key;
const char *file;
unsigned int line;
return (ISC_R_NOMEMORY);
if (result == ISC_R_EXISTS) {
&symvalue) == ISC_R_SUCCESS);
file = "<unknown file>";
} else if (result != ISC_R_SUCCESS) {
}
return (result);
}
static isc_result_t
{
char namebuf[DNS_NAME_FORMATSIZE];
const char *str;
isc_buffer_t b;
if (result != ISC_R_SUCCESS) {
"bad domain name '%s'", str);
} else {
"dnssec-must-be-secure '%s': already "
"exists previous definition: %s:%u",
}
return (result);
}
static isc_result_t
{
}
}
return (ISC_R_SUCCESS);
return (result);
}
static isc_result_t
{
int i = 0;
"allow-query-cache", "allow-query-cache-on",
"blackhole", "keep-response-order", "match-clients",
if (tresult != ISC_R_SUCCESS)
}
return (result);
}
static const unsigned char zeros[16];
static isc_result_t
{
const cfg_listelt_t *element;
unsigned int prefixlen;
int nbytes;
int i;
}
return (ISC_R_SUCCESS);
{
"dns64 requires a IPv6 prefix");
continue;
}
"bad prefix length %u [32/40/48/56/64/96]",
continue;
}
if (tresult != ISC_R_SUCCESS)
}
}
"dns64 requires a IPv6 suffix");
continue;
}
nbytes++;
char netaddrbuf[ISC_NETADDR_FORMATSIZE];
sizeof(netaddrbuf));
"bad suffix '%s' leading "
"%u octets not zeros",
netaddrbuf, nbytes);
}
}
}
return (result);
}
do { \
if (!(cond)) { \
if (result == ISC_R_SUCCESS) \
result = ISC_R_RANGE; \
} \
} while (0)
do { \
if (mresult == ISC_R_SUCCESS) { \
} \
} while (0)
static isc_result_t
{
int min_entries, i;
int all_per_second;
int errors_per_second;
int nodata_per_second;
int nxdomains_per_second;
int referrals_per_second;
int responses_per_second;
int slip;
}
return (ISC_R_SUCCESS);
min_entries = 500;
if (mresult == ISC_R_SUCCESS) {
if (min_entries < 1)
min_entries = 1;
}
if (mresult == ISC_R_SUCCESS) {
i = cfg_obj_asuint32(obj);
CHECK_RRL(i >= min_entries,
"max-table-size %d < min-table-size %d",
i, min_entries);
}
"responses-per-second");
DNS_RRL_MAX_RATE, "referrals-per-second");
DNS_RRL_MAX_RATE, "nodata-per-second");
DNS_RRL_MAX_RATE, "nxdomains-per-second");
DNS_RRL_MAX_RATE, "errors-per-second");
if (mresult == ISC_R_SUCCESS) {
i = cfg_obj_asuint32(obj);
"window %d < 1 or > %d", i, DNS_RRL_MAX_WINDOW);
}
if (mresult == ISC_R_SUCCESS) {
i = cfg_obj_asuint32(obj);
}
if (mresult == ISC_R_SUCCESS) {
i = cfg_obj_asuint32(obj);
"invalid 'ipv4-prefix-length %d'%s", i, "");
}
if (mresult == ISC_R_SUCCESS) {
i = cfg_obj_asuint32(obj);
"ipv6-prefix-length %d < 16 or > %d",
i, DNS_RRL_MAX_PREFIX);
}
if (result == ISC_R_SUCCESS)
}
return (result);
}
/*
* Check allow-recursion and allow-recursion-on acls, and also log a
* warning if they're inconsistent with the "recursion" option.
*/
static isc_result_t
{
const char *forview = " for view ";
int i = 0;
NULL };
}
else
viewname = "";
forview = "";
}
}
continue;
if (tresult != ISC_R_SUCCESS)
continue;
"both \"recursion no;\" and "
"\"%s\" active%s%s",
}
}
return (result);
}
static isc_result_t
{
const char *forview = " for view ";
viewname = "";
forview = "";
}
}
return (result);
if (result != ISC_R_SUCCESS)
goto failure;
}
else if (cfg_obj_isboolean(obj))
else
}
else if (cfg_obj_isboolean(obj))
else
{
"\"filter-aaaa\" is 'none;' but "
"either filter-aaaa-on-v4 or filter-aaaa-on-v6 "
{
"\"filter-aaaa\" is set but "
"neither filter-aaaa-on-v4 or filter-aaaa-on-v6 "
}
return (result);
}
typedef struct {
const char *name;
unsigned int scale;
unsigned int max;
typedef struct {
const char *name;
unsigned int min;
unsigned int max;
} fstrmtable;
typedef enum {
} optlevel_t;
static isc_result_t
/*
* Check that DSCP setting is within range
*/
if (dscp >= 64) {
"'dscp' out of range (0-63)");
}
}
return (result);
}
static isc_result_t
check_name(const char *str) {
}
static isc_result_t
{
unsigned int i;
const cfg_listelt_t *element;
const char *str;
isc_buffer_t b;
#if defined(HAVE_OPENSSL_AES) || defined(HAVE_OPENSSL_EVP_AES)
const char *ccalg = "aes";
#else
const char *ccalg = "sha256";
#endif
static intervaltable intervals[] = {
{ "cleaning-interval", 60, 28 * 24 * 60 }, /* 28 days */
{ "heartbeat-interval", 60, 28 * 24 * 60 }, /* 28 days */
{ "interface-interval", 60, 28 * 24 * 60 }, /* 28 days */
{ "max-transfer-idle-in", 60, 28 * 24 * 60 }, /* 28 days */
{ "max-transfer-idle-out", 60, 28 * 24 * 60 }, /* 28 days */
{ "max-transfer-time-in", 60, 28 * 24 * 60 }, /* 28 days */
{ "max-transfer-time-out", 60, 28 * 24 * 60 }, /* 28 days */
{ "statistics-interval", 60, 28 * 24 * 60 }, /* 28 days */
};
static const char *server_contact[] = {
"empty-server", "empty-contact",
"dns64-server", "dns64-contact",
};
#if HAVE_DNSTAP
static fstrmtable fstrm[] = {
{
"fstrm-set-buffer-hint",
},
{
"fstrm-set-flush-timeout",
},
{
"fstrm-set-input-queue-size",
},
{
"fstrm-set-output-notify-threshold",
0
},
{
"fstrm-set-output-queue-size",
},
{
"fstrm-set-reopen-interval",
}
};
#endif
/*
* Check that fields specified in units of time other than seconds
* have reasonable values.
*/
continue;
"%s '%u' is out of range (0..%u)",
"%s '%d' is out of range",
}
}
"max-rsa-exponent-size '%u' is out of "
"range (35..4096)", val);
}
}
if (!cfg_obj_isvoid(resignobj))
"%s '%u' is out of range (1..3660)",
"sig-validity-interval", validity);
}
if (!cfg_obj_isvoid(resignobj)) {
"%s '%u' is out of range (1..3660)",
"sig-validity-interval (re-sign)",
validity);
"validity interval (%u days) "
"less than re-signing interval "
}
}
}
"preferred-glue unexpected value '%s'",
str);
}
if (!cfg_obj_isvoid(obj)) {
if (tresult != ISC_R_SUCCESS) {
"bad domain name '%s'",
str);
}
}
}
}
/*
* Set supported DNSSEC algorithms.
*/
{
if (tresult != ISC_R_SUCCESS)
}
}
/*
*/
{
if (tresult != ISC_R_SUCCESS)
}
}
/*
* Check the DLV zone name.
*/
if (tresult != ISC_R_SUCCESS)
{
const char *dlv;
/*
* If domain is "auto" or "no" and trust anchor
* is missing, skip remaining tests
*/
if (cfg_obj_isvoid(anchor)) {
continue;
}
if (tresult != ISC_R_SUCCESS) {
"bad domain name '%s'", dlv);
continue;
}
"dnssec-lookaside '%s': "
"already exists previous "
"definition: %s:%u",
if (tresult != ISC_R_SUCCESS &&
result == ISC_R_SUCCESS)
}
/*
* XXXMPA to be removed when multiple lookaside
* namespaces are supported.
*/
"dnssec-lookaside '%s': "
"non-root not yet supported", dlv);
if (result == ISC_R_SUCCESS)
}
if (!cfg_obj_isvoid(anchor)) {
if (tresult != ISC_R_SUCCESS) {
"bad domain name '%s'",
dlv);
if (result == ISC_R_SUCCESS)
}
} else {
"dnssec-lookaside requires "
"either 'auto' or 'no', or a "
"domain and trust anchor");
if (result == ISC_R_SUCCESS)
}
}
}
/*
*/
"auto-dnssec may only be activated at the "
"zone level");
}
}
/*
* Check dnssec-must-be-secure.
*/
if (tresult != ISC_R_SUCCESS)
{
if (tresult != ISC_R_SUCCESS)
}
}
/*
*/
for (i= 0; server_contact[i] != NULL; i++) {
"%s: invalid name '%s'",
server_contact[i], str);
}
}
}
/*
* Check empty zone configuration.
*/
{
"disable-empty-zone: invalid name '%s'",
str);
}
}
/*
* Check that server-id is not too long.
* 1024 bytes should be big enough.
*/
"'server-id' too big (>1024 bytes)");
}
if (tresult != ISC_R_SUCCESS)
"'nta-lifetime' cannot exceed one week");
} else if (lifetime == 0) {
"'nta-lifetime' may not be zero");
}
}
"'nta-recheck' cannot exceed one week");
}
"'nta-recheck' (%d seconds) is "
"greater than 'nta-lifetime' "
}
#if !defined(HAVE_OPENSSL_AES) && !defined(HAVE_OPENSSL_EVP_AES)
"cookie-algorithm: '%s' not supported", ccalg);
}
#endif
unsigned char secret[32];
if (tresult == ISC_R_NOSPACE) {
"cookie-secret: too long");
} else if (tresult != ISC_R_SUCCESS) {
"cookie-secret: invalid hex string");
}
if (tresult != ISC_R_SUCCESS)
if (tresult == ISC_R_SUCCESS &&
isc_buffer_usedlength(&b) != ISC_AES128_KEYLENGTH) {
"AES cookie-secret must be on 128 bits");
}
if (tresult == ISC_R_SUCCESS &&
isc_buffer_usedlength(&b) != ISC_SHA1_DIGESTLENGTH) {
"SHA1 cookie-secret must be on 160 bits");
}
if (tresult == ISC_R_SUCCESS &&
isc_buffer_usedlength(&b) != ISC_SHA256_DIGESTLENGTH) {
"SHA256 cookie-secret must be on 256 bits");
}
}
#if HAVE_DNSTAP
continue;
"%s '%u' out of range (%u..%u)",
else
"%s out of range (%u < %u)",
}
int bits = 0;
do {
value >>= 1;
} while (value != 0U);
if (bits != 1) {
"%s '%u' not a power-of-2",
}
}
}
#endif
"'lmdb-mapsize "
"is too small",
mapsize);
return (ISC_R_RANGE);
"'lmdb-mapsize "
"is too large",
mapsize);
return (ISC_R_RANGE);
}
}
return (result);
}
static isc_result_t
const cfg_listelt_t *elt;
if (result != ISC_R_SUCCESS)
return (result);
const char *listname;
return (ISC_R_SUCCESS);
}
}
return (ISC_R_NOTFOUND);
}
static isc_result_t
{
isc_uint32_t count = 0;
const cfg_listelt_t *element;
if (result != ISC_R_SUCCESS) {
return (result);
}
for ( ;
{
const char *listname;
"masterselement");
if (cfg_obj_issockaddr(addr)) {
count++;
continue;
}
if (!cfg_obj_isvoid(key)) {
"unexpected token '%s'",
if (result == ISC_R_SUCCESS)
}
if (tresult == ISC_R_EXISTS)
continue;
if (tresult != ISC_R_SUCCESS) {
if (result == ISC_R_SUCCESS)
"unable to find masters list '%s'",
listname);
continue;
}
/* Grow stack? */
if (stackcount == pushed) {
void * new;
goto cleanup;
if (stackcount != 0) {
void *ptr;
}
stackcount = newlen;
}
goto newlist;
}
if (pushed != 0) {
goto resume;
}
void *ptr;
}
return (result);
}
static isc_result_t
const cfg_listelt_t *element;
const cfg_listelt_t *element2;
const char *str;
isc_buffer_t b;
/* Check for "update-policy local;" */
if (cfg_obj_isstring(policy) &&
return (ISC_R_SUCCESS);
/* Now check the grant policy */
{
dns_rootname, 0, NULL);
if (tresult != ISC_R_SUCCESS) {
"'%s' is not a valid name", str);
}
if (tresult == ISC_R_SUCCESS &&
&b, dns_rootname, 0, NULL);
if (tresult != ISC_R_SUCCESS) {
"'%s' is not a valid name", str);
}
}
if (tresult == ISC_R_SUCCESS &&
"'%s' is not a wildcard", str);
}
{
if (tresult != ISC_R_SUCCESS) {
"'%s' is not a valid type", r.base);
}
}
}
return (result);
}
#define MASTERZONE 1
#define SLAVEZONE 2
#define STUBZONE 4
#define HINTZONE 8
#define FORWARDZONE 16
#define DELEGATIONZONE 32
#define STATICSTUBZONE 64
#define REDIRECTZONE 128
#define STREDIRECTZONE 0 /* Set to REDIRECTZONE to allow xfr-in. */
#define CHECKACL 512
typedef struct {
const char *name;
int allowed;
} optionstable;
static isc_result_t
unsigned int i;
"max-refresh-time", "min-refresh-time" };
/*
* Check if value is zero.
*/
cfg_obj_asuint32(obj) == 0) {
"'%s' must not be zero", nonzero[i]);
}
}
return (result);
}
static isc_result_t
{
const char *znamestr;
const char *typestr;
unsigned int ztype;
unsigned int i;
isc_buffer_t b;
const cfg_listelt_t *element;
static optionstable options[] = {
CHECKACL | STATICSTUBZONE },
{ "check-dup-records", MASTERZONE },
{ "check-mx", MASTERZONE },
{ "check-mx-cname", MASTERZONE },
{ "check-srv-cname", MASTERZONE },
{ "check-wildcard", MASTERZONE },
{ "dnssec-secure-to-insecure", MASTERZONE },
FORWARDZONE },
FORWARDZONE },
{ "integrity-check", MASTERZONE },
REDIRECTZONE },
{ "server-addresses", STATICSTUBZONE },
{ "server-names", STATICSTUBZONE },
{ "update-policy", MASTERZONE },
};
static optionstable dialups[] = {
};
unsigned int maxopts = 1;
maxopts++;
maxopts++;
"zone '%s': 'in-view' used "
"with incompatible zone options",
znamestr);
return (ISC_R_FAILURE);
}
return (ISC_R_SUCCESS);
}
"zone '%s': type not present", znamestr);
return (ISC_R_FAILURE);
}
ztype = MASTERZONE;
ztype = FORWARDZONE;
else {
"zone '%s': invalid type %s",
return (ISC_R_FAILURE);
}
"redirect zones must be called \".\"");
return (ISC_R_FAILURE);
}
if (cfg_obj_isstring(obj)) {
if (result != ISC_R_SUCCESS) {
"zone '%s': invalid class %s",
return (ISC_R_FAILURE);
}
"zone '%s': class '%s' does not "
return (ISC_R_FAILURE);
}
}
/*
* Look for an already existing zone.
* We need to make this canonical as isc_symtab_define()
* deals with strings.
*/
if (tresult != ISC_R_SUCCESS) {
"zone '%s': is not a valid name", znamestr);
} else {
char namebuf[DNS_NAME_FORMATSIZE];
symtab, "zone '%s': already exists "
if (tresult != ISC_R_SUCCESS)
else if (dns_name_isrfc1918(zname))
else if (dns_name_isula(zname))
}
/*
* Check if value is zero.
*/
/*
* Look for inappropriate options for the given zone type.
* Check that ACLs expand correctly.
*/
{
"option '%s' is not allowed "
"in '%s' zone '%s'",
znamestr);
} else
"option '%s' is not allowed "
"in '%s' zone '%s'",
znamestr);
}
if (tresult != ISC_R_SUCCESS)
}
}
/*
* Master & slave zones may have an "also-notify" field, but
* shouldn't if notify is disabled.
*/
if (tresult == ISC_R_SUCCESS) {
if (cfg_obj_isboolean(obj))
else {
if (ztype != MASTERZONE &&
}
}
"zone '%s': 'also-notify' set but "
"'notify' is disabled", znamestr);
}
}
}
/*
* Slave & stub zones must have a "masters" field.
*/
"zone '%s': missing 'masters' entry",
znamestr);
} else {
"zone '%s': empty 'masters' entry",
znamestr);
}
}
}
/*
* Master zones can't have both "allow-update" and "update-policy".
*/
const char *arg;
"zone '%s': 'allow-update' is ignored "
"when 'update-policy' is present",
znamestr);
} else if (res2 == ISC_R_SUCCESS) {
if (res3 != ISC_R_SUCCESS)
}
/*
* To determine whether auto-dnssec is allowed,
* we should also check for allow-update at the
* view and options levels.
*/
if (res2 == ISC_R_SUCCESS)
else if (res1 == ISC_R_SUCCESS) {
if (res1 != ISC_R_SUCCESS) {
"acl expansion failed: %s",
if (!dns_acl_isnone(acl))
}
}
if (res1 == ISC_R_SUCCESS)
arg = "off";
if (res3 == ISC_R_SUCCESS)
"'auto-dnssec %s;' requires%s "
"inline-signing to be configured for "
"the zone", arg,
(ztype == MASTERZONE) ?
" dynamic DNS or" : "");
}
if (res1 == ISC_R_SUCCESS) {
"sig-signing-type: %u out of "
"range [%u..%u]", type,
0xff00U, 0xffffU);
}
"dnssec-dnskey-kskonly: requires "
"inline-signing when used in slave zone");
}
"dnssec-loadkeys-interval: requires "
"inline-signing when used in slave zone");
}
"update-check-ksk: requires "
"inline-signing when used in slave zone");
}
}
/*
* Check the excessively complicated "dialup" option.
*/
for (i = 0;
i++)
{
continue;
"dialup type '%s' is not "
"allowed in '%s' "
"zone '%s'",
}
break;
}
"invalid dialup type '%s' in zone "
}
}
}
/*
* Check that forwarding is reasonable.
*/
if (root) {
}
/*
* Check that a RFC 1918 / ULA reverse zone is not forward first
* unless explictly configured to be so.
*/
/*
* Forward mode not explicity configured.
*/
"inherited 'forward first;' for "
"%s zone '%s' - did you want "
"'forward only;'?",
znamestr);
}
}
/*
* Check validity of static stub server addresses.
*/
{
if (isc_sockaddr_getport(&sa) != 0) {
"port is not configurable for "
"static stub server-addresses");
}
if (isc_netaddr_getzone(&na) != 0) {
"scoped address is not allowed "
"for static stub "
"server-addresses");
}
}
}
/*
* Check validity of static stub server names.
*/
{
const char *snamestr;
0, NULL);
if (tresult != ISC_R_SUCCESS) {
"server-name '%s' is not a valid "
"name", snamestr);
"server-name '%s' must not be a "
"subdomain of zone name '%s'",
}
}
}
/*
* Check that max-zone-ttl isn't used with masterfile-format map
*/
else
INSIST(0);
}
if (masterformat == dns_masterformat_map) {
"zone '%s': 'max-zone-ttl' is not "
"compatible with 'masterfile-format map'",
znamestr);
}
}
/*
* Warn if key-directory doesn't exist
*/
if (tresult == ISC_R_SUCCESS) {
switch (tresult) {
case ISC_R_SUCCESS:
break;
case ISC_R_FILENOTFOUND:
"key-directory: '%s' does not exist",
dir);
break;
case ISC_R_INVALIDFILE:
"key-directory: '%s' is not a directory",
dir);
break;
default:
"key-directory: '%s' %s",
}
}
/*
* Check various options.
*/
if (tresult != ISC_R_SUCCESS)
/*
* require file clauses.
* If inline signing is used, then slave zones require a
* file clause as well
*/
if (tresult == ISC_R_SUCCESS)
"zone '%s': cannot specify both 'dlz' "
"and 'database'", znamestr);
} else if (!dlz &&
(tresult == ISC_R_NOTFOUND ||
(tresult == ISC_R_SUCCESS &&
{
if ((tresult != ISC_R_SUCCESS &&
cfg_obj_asboolean(obj))))) {
"zone '%s': missing 'file' entry",
znamestr);
} else if (tresult == ISC_R_SUCCESS &&
if (tresult != ISC_R_SUCCESS)
} else if (tresult == ISC_R_SUCCESS &&
if (tresult != ISC_R_SUCCESS)
}
}
return (result);
}
typedef struct keyalgorithms {
const char *name;
const char *algorithm;
int i;
unsigned char secretbuf[1024];
static const algorithmtable algorithms[] = {
#ifndef PK11_MD5_DISABLE
{ "hmac-md5", 128 },
{ "hmac-md5.sig-alg.reg.int", 0 },
{ "hmac-md5.sig-alg.reg.int.", 0 },
#endif
{ "hmac-sha1", 160 },
{ "hmac-sha224", 224 },
{ "hmac-sha256", 256 },
{ "hmac-sha384", 384 },
{ "hmac-sha512", 512 },
{ NULL, 0 }
};
"key '%s' must have both 'secret' and "
"'algorithm' defined",
keyname);
return (ISC_R_FAILURE);
}
if (result != ISC_R_SUCCESS) {
return (result);
}
break;
}
"unknown algorithm '%s'", algorithm);
return (ISC_R_NOTFOUND);
}
if (result == ISC_R_RANGE ||
"key '%s' digest-bits too large "
"[%u..%u]", keyname,
algorithms[i].size);
return (ISC_R_RANGE);
}
if ((digestbits % 8) != 0) {
"key '%s' digest-bits not multiple"
" of 8", keyname);
return (ISC_R_RANGE);
}
/*
* Recommended minima for hmac algorithms.
*/
(digestbits < 80U)))
"key '%s' digest-bits too small "
"[<%u]", keyname,
} else {
"key '%s': unable to parse digest-bits",
keyname);
return (result);
}
}
return (ISC_R_SUCCESS);
}
static isc_result_t
{
unsigned int line;
const char *file;
if (result == ISC_R_SUCCESS) {
if (writeable) {
"writeable file '%s': already in use: "
return (ISC_R_EXISTS);
}
&symvalue);
if (result == ISC_R_SUCCESS) {
"writeable file '%s': already in use: "
return (ISC_R_EXISTS);
}
return (ISC_R_SUCCESS);
}
return (result);
}
/*
* Check key list for duplicates key names and that the key names
* are valid domain names as these keys are used for TSIG.
*
* Check the key contents for validity.
*/
static isc_result_t
{
char namebuf[DNS_NAME_FORMATSIZE];
const cfg_listelt_t *element;
{
isc_buffer_t b;
char *keyname;
0, NULL);
if (tresult != ISC_R_SUCCESS) {
"key '%s': bad key name", keyid);
continue;
}
if (tresult != ISC_R_SUCCESS)
return (tresult);
return (ISC_R_NOMEMORY);
if (tresult == ISC_R_EXISTS) {
const char *file;
unsigned int line;
file = "<unknown file>";
"key '%s': already exists "
"previous definition: %s:%u",
} else if (tresult != ISC_R_SUCCESS) {
return (tresult);
}
}
return (result);
}
static struct {
const char *v4;
const char *v6;
} sources[] = {
{ "transfer-source", "transfer-source-v6" },
{ "notify-source", "notify-source-v6" },
{ "query-source", "query-source-v6" },
};
/*
* RNDC keys are not normalised unlike TSIG keys.
*
* "foo." is different to "foo".
*/
static isc_boolean_t
const cfg_listelt_t *element;
const char *str;
return (ISC_FALSE);
{
return (ISC_TRUE);
}
return (ISC_FALSE);
}
static isc_result_t
{
char buf[ISC_NETADDR_FORMATSIZE];
char namebuf[DNS_NAME_FORMATSIZE];
const char *xfr;
const char *keyval;
isc_buffer_t b;
int source;
return (ISC_R_SUCCESS);
/*
* Check that unused bits are zero.
*/
if (tresult != ISC_R_SUCCESS) {
"server '%s/%u': invalid prefix "
}
source = 0;
do {
else
"server '%s/%u': %s not legal",
}
file = "<unknown file>";
"server '%s/%u': already exists "
"previous definition: %s:%u",
}
}
/*
* Normalize key name.
*/
0, NULL);
if (tresult != ISC_R_SUCCESS) {
"bad key name '%s'", keyval);
continue;
}
if (tresult != ISC_R_SUCCESS) {
"unknown key '%s'", keyval);
}
}
}
return (result);
}
static isc_result_t
{
const char *keystr, *keynamestr;
isc_buffer_t b;
isc_region_t r;
unsigned char keydata[4096];
if (result != ISC_R_SUCCESS) {
}
if (flags > 0xffff) {
"flags too big: %u\n", flags);
}
if (proto > 0xff) {
"protocol too big: %u\n", proto);
}
if (alg > 0xff) {
"algorithm too big: %u\n", alg);
}
if (managed) {
const char *initmethod;
"managed key '%s': "
"invalid initialization method '%s'",
}
}
if (tresult != ISC_R_SUCCESS) {
} else {
isc_buffer_usedregion(&b, &r);
"%s key '%s' has a weak exponent",
}
return (result);
}
static isc_result_t
{
const cfg_listelt_t *element;
const char *forview = " for view ";
viewname = "";
forview = "";
}
zonetype = "";
if (tresult == ISC_R_SUCCESS) {
}
"%s '%s'%s%s is not a master or slave zone",
}
}
return (result);
}
static isc_result_t
{
const char *valstr = "no";
/*
* Get global options block
*/
/*
* The most relevant options for this view
*/
else
/*
* Check that all zone statements are syntactically correct and
* there are no duplicate zones.
*/
if (tresult != ISC_R_SUCCESS)
return (ISC_R_NOMEMORY);
else
{
mctx);
if (tresult != ISC_R_SUCCESS)
}
/*
* Check that the response-policy and catalog-zones options
* refer to zones that exist.
*/
}
/*
* Check that forwarding is reasonable.
*/
/*
* Check non-zero options at the global and view levels.
*/
/*
* Check that dual-stack-servers is reasonable.
*/
/*
* Check that rrset-order is reasonable.
*/
/*
* Check that all key statements are syntactically correct and
* there are no duplicate keys.
*/
if (tresult != ISC_R_SUCCESS)
goto cleanup;
if (tresult == ISC_R_EXISTS)
else if (tresult != ISC_R_SUCCESS) {
goto cleanup;
}
if (tresult == ISC_R_EXISTS)
else if (tresult != ISC_R_SUCCESS) {
goto cleanup;
}
}
/*
* Global servers can refer to keys in views.
*/
/*
* Check that dnssec-enable/dnssec-validation are sensible.
*/
else
valstr = "yes";
} else if (cfg_obj_isboolean(obj)) {
} else {
valstr = "auto";
}
if (enablevalidation && !enablednssec)
"'dnssec-validation %s;' and 'dnssec-enable no;'",
valstr);
/*
* Check trusted-keys and managed-keys.
*/
{
if (tresult != ISC_R_SUCCESS)
}
}
{
if (tresult != ISC_R_SUCCESS)
}
}
/*
* Check options.
*/
else
if (tresult != ISC_R_SUCCESS)
if (tresult != ISC_R_SUCCESS)
if (tresult != ISC_R_SUCCESS)
if (tresult != ISC_R_SUCCESS)
if (tresult != ISC_R_SUCCESS)
if (tresult != ISC_R_SUCCESS)
return (result);
}
static const char *
default_channels[] = {
"default_syslog",
"default_stderr",
"default_debug",
"null",
};
static isc_result_t
{
const cfg_listelt_t *element;
const cfg_listelt_t *delement;
const char *channelname;
const char *catname;
int i;
return (ISC_R_SUCCESS);
if (result != ISC_R_SUCCESS)
return (result);
for (i = 0; default_channels[i] != NULL; i++) {
if (tresult != ISC_R_SUCCESS)
}
{
i = 0;
i++;
i++;
i++;
i++;
if (i != 1) {
"channel '%s': exactly one of file, syslog, "
"null, and stderr must be present",
}
if (tresult != ISC_R_SUCCESS)
}
{
"undefined category: '%s'", catname);
}
{
&symvalue);
if (tresult != ISC_R_SUCCESS) {
"undefined channel: '%s'",
}
}
}
return (result);
}
static isc_result_t
{
const cfg_obj_t *control_keylist;
const cfg_listelt_t *element;
const char *keyval;
return (ISC_R_SUCCESS);
{
"unknown key '%s'", keyval);
}
}
return (result);
}
static isc_result_t
{
const cfg_obj_t *inetcontrols;
const cfg_obj_t *unixcontrols;
const char *path;
int i;
if (controlslist == NULL)
return (ISC_R_SUCCESS);
/*
* INET: Check allow clause.
* UNIX: Check "perm" for sanity, check path length.
*/
unixcontrols = NULL;
inetcontrols = NULL;
if (tresult != ISC_R_SUCCESS)
logctx);
if (tresult != ISC_R_SUCCESS)
}
if (tresult == ISC_R_NOSPACE) {
"unix control '%s': path too long",
path);
}
for (i = 0; i < 3; i++) {
#ifdef NEED_SECURE_DIRECTORY
#else
#endif
break;
}
if (i == 0) {
"unix control '%s' allows access "
"to everyone", path);
} else if (i == 3) {
"unix control '%s' allows access "
"to nobody", path);
}
logctx);
if (tresult != ISC_R_SUCCESS)
}
}
return (result);
}
{
const cfg_listelt_t *velement;
"any", "none"};
/*
* Use case insensitive comparision as not all file systems are
* case sensitive. This will prevent people using FOO.DB and foo.db
* on case sensitive file systems but that shouldn't be a major issue.
*/
&files);
if (tresult != ISC_R_SUCCESS)
} else {
"when using 'view' statements, "
"all zones must be in views");
}
}
if (tresult != ISC_R_SUCCESS)
{
unsigned int symtype;
if (cfg_obj_isstring(vclassobj)) {
if (tresult != ISC_R_SUCCESS)
"view '%s': invalid class %s",
}
if (tresult == ISC_R_EXISTS) {
const char *file;
unsigned int line;
"view '%s': already exists "
"previous definition: %s:%u",
} else if (tresult != ISC_R_SUCCESS) {
vclass == dns_rdataclass_ch) ||
vclass == dns_rdataclass_in)) {
"attempt to redefine builtin view "
"'%s'", key);
}
}
if (tresult == ISC_R_SUCCESS)
if (tresult != ISC_R_SUCCESS)
}
if (tresult == ISC_R_SUCCESS) {
"'cache-file' cannot be a global "
"option if views are present");
}
}
const cfg_listelt_t *elt;
const cfg_listelt_t *elt2;
const char *aclname;
unsigned int i;
for (i = 0;
i++)
"attempt to redefine "
"builtin acl '%s'",
aclname);
break;
}
const char *name;
"name"));
file = "<unknown file>";
"attempt to redefine "
"acl '%s' previous "
"definition: %s:%u",
}
}
}
}
if (tresult == ISC_R_SUCCESS) {
const cfg_listelt_t *elt;
const cfg_listelt_t *elt2;
const char *aclname;
const char *name;
"name"));
file = "<unknown file>";
"attempt to redefine "
"kal '%s' previous "
"definition: %s:%u",
}
}
}
}
return (result);
}