/*
* Copyright (C) 2001-2018 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>
#include <isccfg/namedconf.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
return (result);
{
if (tresult != ISC_R_SUCCESS)
}
return (result);
}
static isc_result_t
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 char *str;
isc_buffer_t b;
if (tresult != ISC_R_SUCCESS) {
"bad domain name '%s'", str);
}
{
if (tresult != ISC_R_SUCCESS) {
r.base);
}
}
return (result);
}
static isc_result_t
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) {
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
{
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 isc_result_t
{
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++;
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
{
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
{
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
}
static isc_result_t
{
unsigned int i;
const char *str;
isc_buffer_t b;
#if defined(HAVE_OPENSSL_AES) || defined(HAVE_OPENSSL_EVP_AES)
#else
#endif
{ "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
{
"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;
}
"dnssec-lookaside 'auto' "
"is no longer supported");
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)) {
"dnssec-lookaside requires "
"either or 'no' or a "
"domain and trust anchor");
if (result == ISC_R_SUCCESS)
continue;
}
if (tresult != ISC_R_SUCCESS) {
"bad domain name '%s'", dlv);
if (result == ISC_R_SUCCESS)
continue;
}
"dlv.isc.org has been shut down: "
"dnssec-lookaside ignored");
continue;
}
}
}
/*
*/
"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
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 128 bits");
}
if (tresult == ISC_R_SUCCESS &&
isc_buffer_usedlength(&b) != ISC_SHA1_DIGESTLENGTH) {
"SHA1 cookie-secret must be 160 bits");
}
if (tresult == ISC_R_SUCCESS &&
isc_buffer_usedlength(&b) != ISC_SHA256_DIGESTLENGTH) {
"SHA256 cookie-secret must be 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
if (result != ISC_R_SUCCESS)
return (result);
const char *listname;
return (ISC_R_SUCCESS);
}
}
return (ISC_R_NOTFOUND);
}
static isc_result_t
{
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 * newstack;
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 char *str;
/* Check for "update-policy local;" */
if (cfg_obj_isstring(policy) &&
return (ISC_R_SUCCESS);
/* Now check the grant policy */
{
&mtype);
if (tresult != ISC_R_SUCCESS) {
"has a bad match-type");
}
if (tresult != ISC_R_SUCCESS) {
"'%s' is not a valid name", str);
}
/*
* There is no name field for subzone.
*/
if (tresult == ISC_R_SUCCESS &&
{
if (tresult != ISC_R_SUCCESS) {
"'%s' is not a valid name", str);
}
}
if (tresult == ISC_R_SUCCESS &&
{
"'%s' is not a wildcard", str);
}
/*
* For some match types, the name should be a placeholder
* value, either "." or the same as identity.
*/
switch (mtype) {
case dns_ssumatchtype_self:
case dns_ssumatchtype_selfsub:
if (tresult == ISC_R_SUCCESS &&
"identity and name fields are not "
"the same");
}
break;
case dns_ssumatchtype_selfms:
case dns_ssumatchtype_tcpself:
if (tresult == ISC_R_SUCCESS &&
"name field not set to "
"placeholder value '.'");
}
break;
case dns_ssumatchtype_name:
case dns_ssumatchtype_local:
break;
default:
INSIST(0);
}
{
if (tresult != ISC_R_SUCCESS) {
"'%s' is not a valid type", r.base);
}
}
}
return (result);
}
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;
static const char *acls[] = {
"allow-notify",
"allow-transfer",
"allow-update",
"allow-update-forwarding",
};
{ "notify-passive", CFG_ZONE_SLAVE },
};
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);
}
} 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 {
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.
*/
/*
* Check validity of the zone options.
*/
{
"option '%s' is not allowed "
"in '%s' zone '%s'",
}
}
/*
* Check that ACLs expand correctly.
*/
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 != CFG_ZONE_MASTER &&
}
}
"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 == CFG_ZONE_MASTER) ?
" dynamic DNS or" : "");
}
if (res1 == ISC_R_SUCCESS) {
"sig-signing-type: %u out of "
"range [%u..%u]", type,
0xff00U, 0xffffU);
}
!signing)
{
"dnssec-dnskey-kskonly: requires "
"inline-signing when used in slave zone");
}
!signing)
{
"dnssec-loadkeys-interval: requires "
"inline-signing when used in slave zone");
}
!signing)
{
"update-check-ksk: requires "
"inline-signing when used in slave zone");
}
}
/*
* Check the excessively complicated "dialup" option.
*/
ztype == CFG_ZONE_STUB)
{
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 &&
(ztype == CFG_ZONE_MASTER ||
ztype == CFG_ZONE_HINT))
{
if (tresult != ISC_R_SUCCESS)
}
}
return (result);
}
typedef struct keyalgorithms {
const char *name;
const char *algorithm;
int i;
#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
{
{
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 char *str;
return (ISC_FALSE);
{
return (ISC_TRUE);
}
return (ISC_FALSE);
}
static isc_result_t
{
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
{
isc_buffer_t b;
isc_region_t r;
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",
}
static const unsigned char root_ksk_2010[] = {
0x03, 0x01, 0x00, 0x01, 0xa8, 0x00, 0x20, 0xa9,
0x55, 0x66, 0xba, 0x42, 0xe8, 0x86, 0xbb, 0x80,
0x4c, 0xda, 0x84, 0xe4, 0x7e, 0xf5, 0x6d, 0xbd,
0x7a, 0xec, 0x61, 0x26, 0x15, 0x55, 0x2c, 0xec,
0x90, 0x6d, 0x21, 0x16, 0xd0, 0xef, 0x20, 0x70,
0x28, 0xc5, 0x15, 0x54, 0x14, 0x4d, 0xfe, 0xaf,
0xe7, 0xc7, 0xcb, 0x8f, 0x00, 0x5d, 0xd1, 0x82,
0x34, 0x13, 0x3a, 0xc0, 0x71, 0x0a, 0x81, 0x18,
0x2c, 0xe1, 0xfd, 0x14, 0xad, 0x22, 0x83, 0xbc,
0x83, 0x43, 0x5f, 0x9d, 0xf2, 0xf6, 0x31, 0x32,
0x51, 0x93, 0x1a, 0x17, 0x6d, 0xf0, 0xda, 0x51,
0xe5, 0x4f, 0x42, 0xe6, 0x04, 0x86, 0x0d, 0xfb,
0x35, 0x95, 0x80, 0x25, 0x0f, 0x55, 0x9c, 0xc5,
0x43, 0xc4, 0xff, 0xd5, 0x1c, 0xbe, 0x3d, 0xe8,
0xcf, 0xd0, 0x67, 0x19, 0x23, 0x7f, 0x9f, 0xc4,
0x7e, 0xe7, 0x29, 0xda, 0x06, 0x83, 0x5f, 0xa4,
0x52, 0xe8, 0x25, 0xe9, 0xa1, 0x8e, 0xbc, 0x2e,
0xcb, 0xcf, 0x56, 0x34, 0x74, 0x65, 0x2c, 0x33,
0xcf, 0x56, 0xa9, 0x03, 0x3b, 0xcd, 0xf5, 0xd9,
0x73, 0x12, 0x17, 0x97, 0xec, 0x80, 0x89, 0x04,
0x1b, 0x6e, 0x03, 0xa1, 0xb7, 0x2d, 0x0a, 0x73,
0x5b, 0x98, 0x4e, 0x03, 0x68, 0x73, 0x09, 0x33,
0x23, 0x24, 0xf2, 0x7c, 0x2d, 0xba, 0x85, 0xe9,
0xdb, 0x15, 0xe8, 0x3a, 0x01, 0x43, 0x38, 0x2e,
0x97, 0x4b, 0x06, 0x21, 0xc1, 0x8e, 0x62, 0x5e,
0xce, 0xc9, 0x07, 0x57, 0x7d, 0x9e, 0x7b, 0xad,
0xe9, 0x52, 0x41, 0xa8, 0x1e, 0xbb, 0xe8, 0xa9,
0x01, 0xd4, 0xd3, 0x27, 0x6e, 0x40, 0xb1, 0x14,
0xc0, 0xa2, 0xe6, 0xfc, 0x38, 0xd1, 0x9c, 0x2e,
0x6a, 0xab, 0x02, 0x64, 0x4b, 0x28, 0x13, 0xf5,
0x75, 0xfc, 0x21, 0x60, 0x1e, 0x0d, 0xee, 0x49,
0xcd, 0x9e, 0xe9, 0x6a, 0x43, 0x10, 0x3e, 0x52,
0x4d, 0x62, 0x87, 0x3d };
static const unsigned char root_ksk_2017[] = {
0x03, 0x01, 0x00, 0x01, 0xac, 0xff, 0xb4, 0x09,
0xbc, 0xc9, 0x39, 0xf8, 0x31, 0xf7, 0xa1, 0xe5,
0xec, 0x88, 0xf7, 0xa5, 0x92, 0x55, 0xec, 0x53,
0x04, 0x0b, 0xe4, 0x32, 0x02, 0x73, 0x90, 0xa4,
0xce, 0x89, 0x6d, 0x6f, 0x90, 0x86, 0xf3, 0xc5,
0xe1, 0x77, 0xfb, 0xfe, 0x11, 0x81, 0x63, 0xaa,
0xec, 0x7a, 0xf1, 0x46, 0x2c, 0x47, 0x94, 0x59,
0x44, 0xc4, 0xe2, 0xc0, 0x26, 0xbe, 0x5e, 0x98,
0xbb, 0xcd, 0xed, 0x25, 0x97, 0x82, 0x72, 0xe1,
0xe3, 0xe0, 0x79, 0xc5, 0x09, 0x4d, 0x57, 0x3f,
0x0e, 0x83, 0xc9, 0x2f, 0x02, 0xb3, 0x2d, 0x35,
0x13, 0xb1, 0x55, 0x0b, 0x82, 0x69, 0x29, 0xc8,
0x0d, 0xd0, 0xf9, 0x2c, 0xac, 0x96, 0x6d, 0x17,
0x76, 0x9f, 0xd5, 0x86, 0x7b, 0x64, 0x7c, 0x3f,
0x38, 0x02, 0x9a, 0xbd, 0xc4, 0x81, 0x52, 0xeb,
0x8f, 0x20, 0x71, 0x59, 0xec, 0xc5, 0xd2, 0x32,
0xc7, 0xc1, 0x53, 0x7c, 0x79, 0xf4, 0xb7, 0xac,
0x28, 0xff, 0x11, 0x68, 0x2f, 0x21, 0x68, 0x1b,
0xf6, 0xd6, 0xab, 0xa5, 0x55, 0x03, 0x2b, 0xf6,
0xf9, 0xf0, 0x36, 0xbe, 0xb2, 0xaa, 0xa5, 0xb3,
0x77, 0x8d, 0x6e, 0xeb, 0xfb, 0xa6, 0xbf, 0x9e,
0xa1, 0x91, 0xbe, 0x4a, 0xb0, 0xca, 0xea, 0x75,
0x9e, 0x2f, 0x77, 0x3a, 0x1f, 0x90, 0x29, 0xc7,
0x3e, 0xcb, 0x8d, 0x57, 0x35, 0xb9, 0x32, 0x1d,
0xb0, 0x85, 0xf1, 0xb8, 0xe2, 0xd8, 0x03, 0x8f,
0xe2, 0x94, 0x19, 0x92, 0x54, 0x8c, 0xee, 0x0d,
0x67, 0xdd, 0x45, 0x47, 0xe1, 0x1d, 0xd6, 0x3a,
0xf9, 0xc9, 0xfc, 0x1c, 0x54, 0x66, 0xfb, 0x68,
0x4c, 0xf0, 0x09, 0xd7, 0x19, 0x7c, 0x2c, 0xf7,
0x9e, 0x79, 0x2a, 0xb5, 0x01, 0xe6, 0xa8, 0xa1,
0xca, 0x51, 0x9a, 0xf2, 0xcb, 0x9b, 0x5f, 0x63,
0x67, 0xe9, 0x4c, 0x0d, 0x47, 0x50, 0x24, 0x51,
0x35, 0x7b, 0xe1, 0xb5 };
isc_buffer_usedlength(&b) == sizeof(root_ksk_2010) &&
*keyflags |= ROOT_KSK_2010;
}
isc_buffer_usedlength(&b) == sizeof(root_ksk_2017) &&
*keyflags |= ROOT_KSK_2017;
}
}
static const unsigned char dlviscorgkey[] = {
0x04, 0x40, 0x00, 0x00, 0x03, 0xc7, 0x32, 0xef,
0xf9, 0xa2, 0x7c, 0xeb, 0x10, 0x4e, 0xf3, 0xd5,
0xe8, 0x26, 0x86, 0x0f, 0xd6, 0x3c, 0xed, 0x3e,
0x8e, 0xea, 0x19, 0xad, 0x6d, 0xde, 0xb9, 0x61,
0x27, 0xe0, 0xcc, 0x43, 0x08, 0x4d, 0x7e, 0x94,
0xbc, 0xb6, 0x6e, 0xb8, 0x50, 0xbf, 0x9a, 0xcd,
0xdf, 0x64, 0x4a, 0xb4, 0xcc, 0xd7, 0xe8, 0xc8,
0xfb, 0xd2, 0x37, 0x73, 0x78, 0xd0, 0xf8, 0x5e,
0x49, 0xd6, 0xe7, 0xc7, 0x67, 0x24, 0xd3, 0xc2,
0xc6, 0x7f, 0x3e, 0x8c, 0x01, 0xa5, 0xd8, 0x56,
0x4b, 0x2b, 0xcb, 0x7e, 0xd6, 0xea, 0xb8, 0x5b,
0xe9, 0xe7, 0x03, 0x7a, 0x8e, 0xdb, 0xe0, 0xcb,
0xfa, 0x4e, 0x81, 0x0f, 0x89, 0x9e, 0xc0, 0xc2,
0xdb, 0x21, 0x81, 0x70, 0x7b, 0x43, 0xc6, 0xef,
0x74, 0xde, 0xf5, 0xf6, 0x76, 0x90, 0x96, 0xf9,
0xe9, 0xd8, 0x60, 0x31, 0xd7, 0xb9, 0xca, 0x65,
0xf8, 0x04, 0x8f, 0xe8, 0x43, 0xe7, 0x00, 0x2b,
0x9d, 0x3f, 0xc6, 0xf2, 0x6f, 0xd3, 0x41, 0x6b,
0x7f, 0xc9, 0x30, 0xea, 0xe7, 0x0c, 0x4f, 0x01,
0x65, 0x80, 0xf7, 0xbe, 0x8e, 0x71, 0xb1, 0x3c,
0xf1, 0x26, 0x1c, 0x0b, 0x5e, 0xfd, 0x44, 0x64,
0x63, 0xad, 0x99, 0x7e, 0x42, 0xe8, 0x04, 0x00,
0x03, 0x2c, 0x74, 0x3d, 0x22, 0xb4, 0xb6, 0xb6,
0xbc, 0x80, 0x7b, 0xb9, 0x9b, 0x05, 0x95, 0x5c,
0x3b, 0x02, 0x1e, 0x53, 0xf4, 0x70, 0xfe, 0x64,
0x71, 0xfe, 0xfc, 0x30, 0x30, 0x24, 0xe0, 0x35,
0xba, 0x0c, 0x40, 0xab, 0x54, 0x76, 0xf3, 0x57,
0x0e, 0xb6, 0x09, 0x0d, 0x21, 0xd9, 0xc2, 0xcd,
0xf1, 0x89, 0x15, 0xc5, 0xd5, 0x17, 0xfe, 0x6a,
0x5f, 0x54, 0x99, 0x97, 0xd2, 0x6a, 0xff, 0xf8,
0x35, 0x62, 0xca, 0x8c, 0x7c, 0xe9, 0x4f, 0x9f,
0x64, 0xfd, 0x54, 0xad, 0x4c, 0x33, 0x74, 0x61,
0x4b, 0x96, 0xac, 0x13, 0x61 };
isc_buffer_usedlength(&b) == sizeof(dlviscorgkey) &&
*keyflags |= DLV_KSK_KEY;
}
}
return (result);
}
static isc_result_t
{
viewname = "";
forview = "";
}
zonetype = "";
if (tresult != ISC_R_SUCCESS) {
"bad domain name '%s'", zonename);
if (result == ISC_R_SUCCESS)
continue;
}
if (tresult == ISC_R_SUCCESS) {
}
"%s '%s'%s%s is not a master or slave zone",
if (result == ISC_R_SUCCESS)
}
}
return (result);
}
static isc_result_t
{
#ifndef HAVE_DLOPEN
#endif
/*
* 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)
}
#ifndef HAVE_DLOPEN
else
"dynamic loading of databases is not supported");
if (tresult != ISC_R_SUCCESS)
}
#endif
/*
* 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.
*/
tflags = 0;
{
logctx);
if (tresult != ISC_R_SUCCESS)
}
}
"trusted-key for root from 2010 without updated "
"trusted-key from 2017: THIS WILL FAIL AFTER "
"KEY ROLLOVER");
}
if ((tflags & DLV_KSK_KEY) != 0) {
"trusted-key for dlv.isc.org still present; "
"dlv.isc.org has been shut down");
}
mflags = 0;
{
logctx);
if (tresult != ISC_R_SUCCESS)
}
}
"managed-key for root from 2010 without updated "
"managed-key from 2017");
}
if ((mflags & DLV_KSK_KEY) != 0) {
"managed-key for dlv.isc.org still present; "
"dlv.isc.org has been shut down");
}
{
"both trusted-keys and managed-keys for the ICANN "
"root are present");
}
/*
* 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 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 char *keyval;
return (ISC_R_SUCCESS);
{
"unknown key '%s'", keyval);
}
}
return (result);
}
static isc_result_t
{
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);
}
{
"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 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 char *aclname;
const char *name;
"name"));
file = "<unknown file>";
"attempt to redefine "
"kal '%s' previous "
"definition: %s:%u",
}
}
}
}
return (result);
}