zoneconf.c revision 0c27b3fe77ac1d5094ba3521e8142d9e7973133f
/*
* Copyright (C) 1999-2016 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/.
*/
#include <config.h>
#include <dns/ipkeylist.h>
#include <dns/fixedname.h>
#include <dns/masterdump.h>
#include <dns/rdatatype.h>
#include <dns/rdataset.h>
#include <dns/rdatalist.h>
#include <named/zoneconf.h>
/* ACLs associated with zone */
typedef enum {
} acl_type_t;
#define RETERR(x) do { \
isc_result_t _r = (x); \
if (_r != ISC_R_SUCCESS) \
return (_r); \
} while (0)
#define CHECK(x) do { \
result = (x); \
if (result != ISC_R_SUCCESS) \
goto cleanup; \
} while (0)
/*%
* Convenience function for configuring a single zone ACL.
*/
static isc_result_t
void (*clearzacl)(dns_zone_t *))
{
int i = 0;
const char *aclname;
switch (acltype) {
case allow_notify:
aclname = "allow-notify";
break;
case allow_query:
aclname = "allow-query";
break;
case allow_query_on:
aclname = "allow-query-on";
break;
case allow_transfer:
aclname = "allow-transfer";
break;
case allow_update:
aclname = "allow-update";
break;
case allow_update_forwarding:
aclname = "allow-update-forwarding";
break;
default:
INSIST(0);
return (ISC_R_FAILURE);
}
/* First check to see if ACL is defined within the zone */
goto parse_acl;
}
}
/* Failing that, see if there's a default ACL already in the view */
return (ISC_R_SUCCESS);
}
/* Check for default ACLs that haven't been parsed yet */
}
}
maps[i++] = ns_g_defaults;
return (ISC_R_SUCCESS);
}
if (result != ISC_R_SUCCESS)
return (result);
/* Set the view default now */
return (ISC_R_SUCCESS);
}
/*%
* Parse the zone update-policy statement.
*/
static isc_result_t
const char *zname)
{
if (updatepolicy == NULL) {
return (ISC_R_SUCCESS);
}
if (cfg_obj_isstring(updatepolicy) &&
updatepolicy = NULL;
}
if (result != ISC_R_SUCCESS)
return (result);
{
const char *str;
unsigned int mtype = DNS_SSUMATCHTYPE_NAME;
isc_buffer_t b;
unsigned int i, n;
else
INSIST(0);
else
INSIST(0);
dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
"'%s' is not a valid name", str);
goto cleanup;
}
if (usezone) {
NULL);
if (result != ISC_R_SUCCESS) {
"error copying origin: %s",
goto cleanup;
}
} else {
&b, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
"'%s' is not a valid name", str);
goto cleanup;
}
}
n = ns_config_listcount(typelist);
if (n == 0)
else {
goto cleanup;
}
}
i = 0;
{
INSIST(i < n);
if (result != ISC_R_SUCCESS) {
"'%s' is not a valid type", str);
n * sizeof(dns_rdatatype_t));
goto cleanup;
}
}
INSIST(i == n);
n, types);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
}
/*
* If "update-policy local;" and a session key exists,
* then use the default policy, which is equivalent to:
* update-policy { grant <session-keyname> zonesub any; };
*/
if (autoddns) {
"failed to enable auto DDNS policy "
"for zone %s: session key not found",
zname);
goto cleanup;
}
1, &any);
if (result != ISC_R_SUCCESS)
goto cleanup;
}
return (result);
}
/*
* This is the TTL used for internally generated RRsets for static-stub zones.
* The value doesn't matter because the mapping is static, but needs to be
* defined for the sake of implementation.
*/
#define STATICSTUB_SERVER_TTL 86400
/*%
* Configure an apex NS with glues for a static-stub zone.
* For example, for the zone named "example.com", the following RRs will be
* added to the zone DB:
* example.com. A 192.0.2.1
* example.com. AAAA 2001:db8::1
*/
static isc_result_t
{
const cfg_listelt_t *element;
{
const isc_sockaddr_t* sa;
if (isc_sockaddr_getport(sa) != 0) {
"port is not configurable for "
"static stub server-addresses");
return (ISC_R_FAILURE);
}
if (isc_netaddr_getzone(&na) != 0) {
"scoped address is not allowed "
"for static stub "
"server-addresses");
return (ISC_R_FAILURE);
}
case AF_INET:
break;
default:
break;
}
return (ISC_R_NOMEMORY);
}
/*
* If no address is specified (unlikely in this context, but possible),
* there's nothing to do anymore.
*/
return (ISC_R_SUCCESS);
}
/* Add to the list an apex NS with the ns name being the origin name */
/*
* Already allocated data will be freed in the caller, so
* we can simply return here.
*/
return (ISC_R_NOMEMORY);
}
return (result);
}
/*%
* Configure an apex NS with an out-of-zone NS names for a static-stub zone.
* For example, for the zone named "example.com", something like the following
* RRs will be added to the zone DB:
* example.com. NS ns.example.net.
*/
static isc_result_t
{
const cfg_listelt_t *element;
{
const char *str;
isc_buffer_t b;
if (result != ISC_R_SUCCESS) {
"server-name '%s' is not a valid "
"name", str);
return (result);
}
"server-name '%s' must not be a "
"subdomain of zone name '%s'",
return (ISC_R_FAILURE);
}
return (ISC_R_NOMEMORY);
}
return (result);
}
/*%
* Configure static-stub zone.
*/
static isc_result_t
{
int i = 0;
dns_rdatalist_t* rdatalists[] = {
};
/* Create the DB beforehand */
/* Prepare zone RRs from the configuration */
if (result == ISC_R_SUCCESS) {
if (result != ISC_R_SUCCESS)
goto cleanup;
}
if (result == ISC_R_SUCCESS) {
zname);
if (result != ISC_R_SUCCESS)
goto cleanup;
}
/*
* Sanity check: there should be at least one NS RR at the zone apex
* to trigger delegation.
*/
"No NS record is configured for a "
"static-stub zone '%s'", zname);
goto cleanup;
}
/*
* First open a new version for the add operation and get a pointer
* to the apex node (all RRs are of the apex name).
*/
if (result != ISC_R_SUCCESS)
goto cleanup;
if (result != ISC_R_SUCCESS)
goto cleanup;
/* Add NS RRset */
== ISC_R_SUCCESS);
0, NULL);
if (result != ISC_R_SUCCESS)
goto cleanup;
/* Add glue A RRset, if any */
== ISC_R_SUCCESS);
if (result != ISC_R_SUCCESS)
goto cleanup;
}
/* Add glue AAAA RRset, if any */
&rdataset)
== ISC_R_SUCCESS);
if (result != ISC_R_SUCCESS)
goto cleanup;
}
dns_db_detach(&db);
for (i = 0; rdatalists[i] != NULL; i++) {
}
}
return (result);
}
/*%
* Convert a config file zone type into a server zone type.
*/
static inline dns_zonetype_t
return (ns_config_getzonetype(obj));
}
/*%
* Helper function for strtoargv(). Pardon the gratuitous recursion.
*/
static isc_result_t
char ***argvp, unsigned int n)
{
/* Discard leading whitespace. */
while (*s == ' ' || *s == '\t')
s++;
if (*s == '\0') {
/* We have reached the end of the string. */
*argcp = n;
return (ISC_R_NOMEMORY);
} else {
char *p = s;
while (*p != ' ' && *p != '\t' && *p != '\0')
p++;
if (*p != '\0')
*p++ = '\0';
if (result != ISC_R_SUCCESS)
return (result);
(*argvp)[n] = s;
}
return (ISC_R_SUCCESS);
}
/*%
* Tokenize the string "s" into whitespace-separated words,
* return the number of words in '*argcp' and an array
* of pointers to the words in '*argvp'. The caller
* must free the array using isc_mem_put(). The string
* is modified in-place.
*/
static isc_result_t
}
static void
{
switch (ztype) {
default:
INSIST(0);
}
}
{
const char *zname;
const char *dupcheck;
unsigned int dbargc;
char **dbargv;
static char default_dbtype[] = "rbt";
static char dlz_dbtype[] = "dlz";
char *cpval = default_dbtype;
int i;
int seconds;
i = 0;
i++;
}
i++;
}
i++;
}
}
maps[i++] = ns_g_defaults;
dns_rdataclass_in, &vclass));
else
/*
* Configure values common to all zone types.
*/
} else
if (result == ISC_R_SUCCESS)
return(ISC_R_NOMEMORY);
if (result == ISC_R_SUCCESS) {
if (cpval != default_dbtype) {
"zone '%s': both 'database' and 'dlz' "
"specified", zname);
return (ISC_R_FAILURE);
}
return (ISC_R_NOMEMORY);
}
return (result);
}
/*
* ANSI C is strange here. There is no logical reason why (char **)
* cannot be promoted automatically to (const char * const *) by the
* compiler w/o generating a warning.
*/
if (result != ISC_R_SUCCESS)
return (result);
if (result == ISC_R_SUCCESS)
/*
* Unless we're using some alternative database, a master zone
* will be needing a master file.
*/
"zone '%s': 'file' not specified",
zname);
return (ISC_R_FAILURE);
}
if (ztype == dns_zone_slave)
else
if (result == ISC_R_SUCCESS) {
else
INSIST(0);
}
if (result == ISC_R_SUCCESS) {
if (masterformat != dns_masterformat_text) {
"zone '%s': 'masterfile-style' "
"can only be used with "
"'masterfile-format text'", zname);
return (ISC_R_FAILURE);
}
else
INSIST(0);
}
"zone '%s': 'max-zone-ttl' is not compatible "
"with 'masterfile-format map'", zname);
return (ISC_R_FAILURE);
} else if (result == ISC_R_SUCCESS) {
if (cfg_obj_isuint32(obj))
}
#define SIGNED ".signed"
char *signedname;
if (signedname == NULL)
return (ISC_R_NOMEMORY);
if (result != ISC_R_SUCCESS)
return (result);
} else
if (result == ISC_R_SUCCESS)
/*
* Notify messages are processed by the raw zone if it exists.
*/
if (ztype == dns_zone_slave)
/*
* XXXAG This probably does not make sense for stubs.
*/
if (cfg_obj_isboolean(obj)) {
if (cfg_obj_asboolean(obj))
else
} else {
else
INSIST(0);
}
if (cfg_obj_isboolean(obj)) {
if (cfg_obj_asboolean(obj))
else
} else {
else
INSIST(0);
}
zoneqrystats = NULL;
if (statlevel == dns_zonestat_full) {
&rcvquerystats));
}
if (zoneqrystats != NULL)
if(rcvquerystats != NULL)
/*
* Configure master functionality. This applies
* to primary masters (type "master") and slaves
* acting as masters (type "slave"), but not to stubs.
*/
ztype != dns_zone_redirect) {
if (cfg_obj_isboolean(obj)) {
if (cfg_obj_asboolean(obj))
else
} else {
else
INSIST(0);
}
if (result == ISC_R_SUCCESS &&
(notifytype == dns_notifytype_yes ||
ztype == dns_zone_master)))
{
&ipkl));
} else
if (dscp == -1)
if (dscp == -1)
if (cfg_obj_isstring(obj)) {
} else {
"'max-journal-size "
"is too large",
value);
}
}
if (cfg_obj_isboolean(obj))
ztype == dns_zone_master)
ztype == dns_zone_slave)
else
ISC_TRUE);
ISC_TRUE);
} else
ixfrdiff);
} else
INSIST(0);
check);
fail);
} else {
check);
fail);
}
} else
INSIST(0);
} else if (ztype == dns_zone_redirect) {
if (cfg_obj_isstring(obj)) {
} else {
"'max-journal-size "
"is too large",
value);
}
}
}
/*
* Configure update-related options. These apply to
* primary masters only.
*/
if (ztype == dns_zone_master) {
"zone '%s' allows updates by IP "
"address, which is insecure",
zname);
}
{
if (cfg_obj_isvoid(resign)) {
seconds /= 4;
} else {
86400;
else
3600;
}
}
if (result == ISC_R_SUCCESS) {
}
cfg_obj_asuint32(obj)));
if (result == ISC_R_SUCCESS) {
;
else
INSIST(0);
}
}
if (ztype == dns_zone_slave) {
}
/*%
* Primary master functionality.
*/
if (ztype == dns_zone_master) {
if (result == ISC_R_SUCCESS)
else
/*
* With map files, the default is ignore duplicate
* records. With other master formats, the default is
* taken from the global configuration.
*/
if (masterformat != dns_masterformat_map) {
} else {
&obj);
if (result == ISC_R_SUCCESS)
else
dupcheck = "ignore";
}
} else
INSIST(0);
} else
INSIST(0);
/*
* With map files, the default is *not* to check
* integrity. With other master formats, the default is
* taken from the global configuration.
*/
if (masterformat != dns_masterformat_map) {
} else {
&obj);
if (result == ISC_R_SUCCESS)
check);
}
} else
INSIST(0);
} else
INSIST(0);
ignore);
if (result == ISC_R_SUCCESS) {
ISC_TRUE);
;
else
INSIST(0);
}
else
}
/*
* Configure slave functionality.
*/
switch (ztype) {
case dns_zone_slave:
case dns_zone_stub:
case dns_zone_redirect:
count = 0;
&ipkl));
} else
if (count > 1) {
}
if (dscp == -1)
if (dscp == -1)
if (dscp == -1)
if (dscp == -1)
/*
* Default off when views are in use otherwise
* on for BIND 8 compatibility.
*/
else
} else
break;
case dns_zone_staticstub:
break;
default:
break;
}
return (ISC_R_SUCCESS);
}
/*
* Set up a DLZ zone as writeable
*/
{
if (result != ISC_R_SUCCESS)
return (result);
dns_db_detach(&db);
return (result);
}
const char *cfilename;
const char *zfilename;
/*
* We always reconfigure a static-stub zone for simplicity, assuming
* the amount of data to be loaded is small.
*/
"not reusable: staticstub");
return (ISC_FALSE);
}
/* If there's a raw zone, use that for filename and type comparison */
} else {
}
"not reusable: old zone was inline-signing");
return (ISC_FALSE);
"not reusable: old zone was not inline-signing");
return (ISC_FALSE);
}
"not reusable: type mismatch");
return (ISC_FALSE);
}
else
{
"not reusable: filename mismatch");
return (ISC_FALSE);
}
return (ISC_TRUE);
}