2001-03-01 23:46:49 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2001 Internet Software Consortium.
|
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
|
|
* copyright notice and this permission notice appear in all copies.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
|
|
|
|
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
|
|
|
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
|
|
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
|
|
|
|
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
|
|
|
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
|
|
|
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
2001-11-09 03:34:55 +00:00
|
|
|
/* $Id: check.c,v 1.7 2001/11/09 03:34:53 marka Exp $ */
|
2001-03-01 23:46:49 +00:00
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <isc/log.h>
|
|
|
|
#include <isc/result.h>
|
2001-03-08 00:55:50 +00:00
|
|
|
#include <isc/symtab.h>
|
2001-03-03 23:09:23 +00:00
|
|
|
#include <isc/util.h>
|
2001-09-20 15:17:07 +00:00
|
|
|
#include <isc/region.h>
|
|
|
|
|
|
|
|
#include <dns/rdataclass.h>
|
2001-03-01 23:46:49 +00:00
|
|
|
|
|
|
|
#include <isccfg/cfg.h>
|
2001-09-20 15:17:07 +00:00
|
|
|
|
|
|
|
#include <bind9/check.h>
|
2001-03-01 23:46:49 +00:00
|
|
|
|
2001-03-09 19:07:30 +00:00
|
|
|
static isc_result_t
|
|
|
|
check_forward(cfg_obj_t *options, isc_log_t *logctx) {
|
|
|
|
cfg_obj_t *forward = NULL;
|
|
|
|
cfg_obj_t *forwarders = NULL;
|
|
|
|
|
|
|
|
(void)cfg_map_get(options, "forward", &forward);
|
|
|
|
(void)cfg_map_get(options, "forwarders", &forwarders);
|
|
|
|
|
|
|
|
if (forward != NULL && forwarders == NULL) {
|
|
|
|
cfg_obj_log(forward, logctx, ISC_LOG_ERROR,
|
|
|
|
"no matching 'forwarders' statement");
|
|
|
|
return (ISC_R_FAILURE);
|
|
|
|
}
|
|
|
|
return (ISC_R_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2001-06-04 21:51:27 +00:00
|
|
|
typedef struct {
|
|
|
|
const char *name;
|
|
|
|
unsigned int scale;
|
2001-11-09 03:34:55 +00:00
|
|
|
unsigned int max;
|
2001-06-04 21:51:27 +00:00
|
|
|
} intervaltable;
|
|
|
|
|
|
|
|
static isc_result_t
|
|
|
|
check_options(cfg_obj_t *options, isc_log_t *logctx) {
|
|
|
|
isc_result_t result = ISC_R_SUCCESS;
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
static intervaltable intervals[] = {
|
2001-11-09 03:34:55 +00:00
|
|
|
{ "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 */
|
|
|
|
{ "sig-validity-interval", 86400, 10 * 366 }, /* 10 years */
|
|
|
|
{ "statistics-interval", 60, 28 * 24 * 60 }, /* 28 days */
|
2001-06-04 21:51:27 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check that fields specified in units of time other than seconds
|
|
|
|
* have reasonable values.
|
|
|
|
*/
|
|
|
|
for (i = 0; i < sizeof(intervals) / sizeof(intervals[0]); i++) {
|
|
|
|
isc_uint32_t val;
|
|
|
|
cfg_obj_t *obj = NULL;
|
|
|
|
(void)cfg_map_get(options, intervals[i].name, &obj);
|
|
|
|
if (obj == NULL)
|
|
|
|
continue;
|
|
|
|
val = cfg_obj_asuint32(obj);
|
2001-11-09 03:34:55 +00:00
|
|
|
if (val > intervals[i].max) {
|
|
|
|
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
|
|
|
"%s '%u' is out of range (0..%u)",
|
|
|
|
intervals[i].name, val,
|
|
|
|
intervals[i].max);
|
|
|
|
result = ISC_R_RANGE;
|
|
|
|
} else if (val > (ISC_UINT32_MAX / intervals[i].scale)) {
|
2001-06-04 21:51:27 +00:00
|
|
|
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
|
|
|
"%s '%d' is out of range",
|
|
|
|
intervals[i].name, val);
|
|
|
|
result = ISC_R_RANGE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
2001-03-01 23:46:49 +00:00
|
|
|
#define MASTERZONE 1
|
|
|
|
#define SLAVEZONE 2
|
|
|
|
#define STUBZONE 4
|
|
|
|
#define HINTZONE 8
|
|
|
|
#define FORWARDZONE 16
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
const char *name;
|
|
|
|
int allowed;
|
|
|
|
} optionstable;
|
|
|
|
|
|
|
|
static isc_result_t
|
2001-09-20 15:17:07 +00:00
|
|
|
check_zoneconf(cfg_obj_t *zconfig, isc_symtab_t *symtab,
|
|
|
|
dns_rdataclass_t defclass, isc_log_t *logctx)
|
|
|
|
{
|
2001-03-01 23:46:49 +00:00
|
|
|
const char *zname;
|
|
|
|
const char *typestr;
|
|
|
|
unsigned int ztype;
|
|
|
|
cfg_obj_t *zoptions;
|
|
|
|
cfg_obj_t *obj = NULL;
|
2001-03-08 00:55:50 +00:00
|
|
|
isc_symvalue_t symvalue;
|
2001-03-04 21:18:30 +00:00
|
|
|
isc_result_t result = ISC_R_SUCCESS;
|
2001-03-08 00:55:50 +00:00
|
|
|
isc_result_t tresult;
|
2001-03-01 23:46:49 +00:00
|
|
|
unsigned int i;
|
2001-09-20 15:17:07 +00:00
|
|
|
dns_rdataclass_t zclass;
|
2001-03-01 23:46:49 +00:00
|
|
|
|
|
|
|
static optionstable options[] = {
|
|
|
|
{ "allow-query", MASTERZONE | SLAVEZONE | STUBZONE },
|
2001-10-11 04:52:21 +00:00
|
|
|
{ "allow-transfer", MASTERZONE | SLAVEZONE },
|
2001-03-01 23:46:49 +00:00
|
|
|
{ "notify", MASTERZONE | SLAVEZONE },
|
|
|
|
{ "also-notify", MASTERZONE | SLAVEZONE },
|
|
|
|
{ "dialup", MASTERZONE | SLAVEZONE | STUBZONE },
|
|
|
|
{ "forward", MASTERZONE | SLAVEZONE | STUBZONE | FORWARDZONE},
|
|
|
|
{ "forwarders", MASTERZONE | SLAVEZONE | STUBZONE | FORWARDZONE},
|
|
|
|
{ "maintain-ixfr-base", MASTERZONE | SLAVEZONE },
|
|
|
|
{ "max-ixfr-log-size", MASTERZONE | SLAVEZONE },
|
2001-10-11 04:52:21 +00:00
|
|
|
{ "notify-source", MASTERZONE | SLAVEZONE },
|
|
|
|
{ "notify-source-v6", MASTERZONE | SLAVEZONE },
|
2001-10-11 01:55:03 +00:00
|
|
|
{ "transfer-source", SLAVEZONE | STUBZONE },
|
|
|
|
{ "transfer-source-v6", SLAVEZONE | STUBZONE },
|
2001-03-01 23:46:49 +00:00
|
|
|
{ "max-transfer-time-in", SLAVEZONE | STUBZONE },
|
|
|
|
{ "max-transfer-time-out", MASTERZONE | SLAVEZONE },
|
|
|
|
{ "max-transfer-idle-in", SLAVEZONE | STUBZONE },
|
|
|
|
{ "max-transfer-idle-out", MASTERZONE | SLAVEZONE },
|
|
|
|
{ "max-retry-time", SLAVEZONE | STUBZONE },
|
|
|
|
{ "min-retry-time", SLAVEZONE | STUBZONE },
|
|
|
|
{ "max-refresh-time", SLAVEZONE | STUBZONE },
|
|
|
|
{ "min-refresh-time", SLAVEZONE | STUBZONE },
|
|
|
|
{ "sig-validity-interval", MASTERZONE },
|
|
|
|
{ "zone-statistics", MASTERZONE | SLAVEZONE | STUBZONE },
|
|
|
|
{ "allow-update", MASTERZONE },
|
2001-03-07 23:36:26 +00:00
|
|
|
{ "allow-update-forwarding", SLAVEZONE },
|
2001-03-01 23:46:49 +00:00
|
|
|
{ "file", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE},
|
|
|
|
{ "ixfr-base", MASTERZONE | SLAVEZONE },
|
|
|
|
{ "ixfr-tmp-file", MASTERZONE | SLAVEZONE },
|
|
|
|
{ "masters", SLAVEZONE | STUBZONE },
|
|
|
|
{ "pubkey", MASTERZONE | SLAVEZONE | STUBZONE },
|
|
|
|
{ "update-policy", MASTERZONE },
|
|
|
|
{ "database", MASTERZONE | SLAVEZONE | STUBZONE },
|
|
|
|
};
|
|
|
|
|
|
|
|
static optionstable dialups[] = {
|
|
|
|
{ "notify", MASTERZONE | SLAVEZONE },
|
|
|
|
{ "notify-passive", SLAVEZONE },
|
|
|
|
{ "refresh", SLAVEZONE | STUBZONE },
|
|
|
|
{ "passive", SLAVEZONE | STUBZONE },
|
|
|
|
};
|
|
|
|
|
2001-03-02 01:30:32 +00:00
|
|
|
zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name"));
|
|
|
|
|
|
|
|
zoptions = cfg_tuple_get(zconfig, "options");
|
2001-03-01 23:46:49 +00:00
|
|
|
|
|
|
|
obj = NULL;
|
2001-03-02 01:30:32 +00:00
|
|
|
(void)cfg_map_get(zoptions, "type", &obj);
|
2001-03-01 23:46:49 +00:00
|
|
|
if (obj == NULL) {
|
|
|
|
cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR,
|
|
|
|
"zone '%s': type not present", zname);
|
|
|
|
return (ISC_R_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
typestr = cfg_obj_asstring(obj);
|
|
|
|
if (strcasecmp(typestr, "master") == 0)
|
|
|
|
ztype = MASTERZONE;
|
|
|
|
else if (strcasecmp(typestr, "slave") == 0)
|
|
|
|
ztype = SLAVEZONE;
|
|
|
|
else if (strcasecmp(typestr, "stub") == 0)
|
|
|
|
ztype = STUBZONE;
|
|
|
|
else if (strcasecmp(typestr, "forward") == 0)
|
|
|
|
ztype = FORWARDZONE;
|
|
|
|
else if (strcasecmp(typestr, "hint") == 0)
|
|
|
|
ztype = HINTZONE;
|
|
|
|
else {
|
|
|
|
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
|
|
|
"zone '%s': invalid type %s",
|
|
|
|
zname, typestr);
|
|
|
|
return (ISC_R_FAILURE);
|
|
|
|
}
|
|
|
|
|
2001-09-20 15:17:07 +00:00
|
|
|
obj = cfg_tuple_get(zconfig, "class");
|
|
|
|
if (cfg_obj_isstring(obj)) {
|
|
|
|
isc_textregion_t r;
|
|
|
|
|
|
|
|
DE_CONST(cfg_obj_asstring(obj), r.base);
|
|
|
|
r.length = strlen(r.base);
|
|
|
|
result = dns_rdataclass_fromtext(&zclass, &r);
|
|
|
|
if (result != ISC_R_SUCCESS) {
|
|
|
|
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
|
|
|
"zone '%s': invalid class %s",
|
|
|
|
zname, r.base);
|
|
|
|
return (ISC_R_FAILURE);
|
|
|
|
}
|
|
|
|
if (zclass != defclass) {
|
|
|
|
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
|
|
|
"zone '%s': class '%s' does not "
|
|
|
|
"match view/default class",
|
|
|
|
zname, r.base);
|
|
|
|
return (ISC_R_FAILURE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-03-08 00:55:50 +00:00
|
|
|
/*
|
|
|
|
* Look for an already existing zone.
|
|
|
|
*/
|
|
|
|
symvalue.as_pointer = NULL;
|
|
|
|
tresult = isc_symtab_define(symtab, zname,
|
|
|
|
ztype == HINTZONE ? 1 : 2,
|
|
|
|
symvalue, isc_symexists_reject);
|
|
|
|
if (tresult == ISC_R_EXISTS) {
|
|
|
|
cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR,
|
|
|
|
"zone '%s': already exists ", zname);
|
|
|
|
result = ISC_R_FAILURE;
|
|
|
|
} else if (tresult != ISC_R_SUCCESS)
|
|
|
|
return (tresult);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Look for inappropriate options for the given zone type.
|
|
|
|
*/
|
2001-03-01 23:46:49 +00:00
|
|
|
for (i = 0; i < sizeof(options) / sizeof(options[0]); i++) {
|
|
|
|
obj = NULL;
|
|
|
|
if ((options[i].allowed & ztype) == 0 &&
|
|
|
|
cfg_map_get(zoptions, options[i].name, &obj) ==
|
|
|
|
ISC_R_SUCCESS)
|
|
|
|
{
|
|
|
|
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
|
|
|
"option '%s' is not allowed in '%s' "
|
|
|
|
"zone '%s'",
|
|
|
|
options[i].name, typestr, zname);
|
|
|
|
result = ISC_R_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-03-08 00:55:50 +00:00
|
|
|
/*
|
|
|
|
* Slave & stub zones must have a "masters" field.
|
|
|
|
*/
|
2001-03-01 23:46:49 +00:00
|
|
|
if (ztype == SLAVEZONE || ztype == STUBZONE) {
|
|
|
|
obj = NULL;
|
|
|
|
if (cfg_map_get(zoptions, "masters", &obj) != ISC_R_SUCCESS) {
|
2001-07-19 16:29:14 +00:00
|
|
|
cfg_obj_log(zoptions, logctx, ISC_LOG_ERROR,
|
2001-03-01 23:46:49 +00:00
|
|
|
"zone '%s': missing 'masters' entry",
|
|
|
|
zname);
|
|
|
|
result = ISC_R_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-03-08 00:55:50 +00:00
|
|
|
/*
|
|
|
|
* Master zones can't have both "allow-update" and "update-policy".
|
|
|
|
*/
|
2001-03-01 23:46:49 +00:00
|
|
|
if (ztype == MASTERZONE) {
|
|
|
|
isc_result_t res1, res2;
|
|
|
|
obj = NULL;
|
|
|
|
res1 = cfg_map_get(zoptions, "allow-update", &obj);
|
|
|
|
obj = NULL;
|
|
|
|
res2 = cfg_map_get(zoptions, "update-policy", &obj);
|
|
|
|
if (res1 == ISC_R_SUCCESS && res2 == ISC_R_SUCCESS) {
|
|
|
|
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
|
|
|
"zone '%s': 'allow-update' is ignored "
|
|
|
|
"when 'update-policy' is present",
|
|
|
|
zname);
|
|
|
|
result = ISC_R_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-03-08 00:55:50 +00:00
|
|
|
/*
|
|
|
|
* Check the excessively complicated "dialup" option.
|
|
|
|
*/
|
2001-03-01 23:46:49 +00:00
|
|
|
if (ztype == MASTERZONE || ztype == SLAVEZONE || ztype == STUBZONE) {
|
|
|
|
cfg_obj_t *dialup = NULL;
|
|
|
|
cfg_map_get(zoptions, "dialup", &dialup);
|
|
|
|
if (dialup != NULL && cfg_obj_isstring(dialup)) {
|
|
|
|
char *str = cfg_obj_asstring(dialup);
|
|
|
|
for (i = 0;
|
|
|
|
i < sizeof(dialups) / sizeof(dialups[0]);
|
|
|
|
i++)
|
|
|
|
{
|
|
|
|
if (strcasecmp(dialups[i].name, str) != 0)
|
|
|
|
continue;
|
|
|
|
if ((dialups[i].allowed & ztype) == 0) {
|
|
|
|
cfg_obj_log(obj, logctx,
|
|
|
|
ISC_LOG_ERROR,
|
|
|
|
"dialup type '%s' is not "
|
|
|
|
"allowed in '%s' "
|
|
|
|
"zone '%s'",
|
|
|
|
str, typestr, zname);
|
|
|
|
result = ISC_R_FAILURE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (i == sizeof(dialups) / sizeof(dialups[0])) {
|
|
|
|
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
|
|
|
"invalid dialup type '%s' in zone "
|
|
|
|
"'%s'", str, zname);
|
|
|
|
result = ISC_R_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-03-09 19:07:30 +00:00
|
|
|
/*
|
|
|
|
* Check that forwarding is reasonable.
|
|
|
|
*/
|
|
|
|
if (check_forward(zoptions, logctx) != ISC_R_SUCCESS)
|
|
|
|
result = ISC_R_FAILURE;
|
|
|
|
|
2001-06-04 21:51:27 +00:00
|
|
|
/*
|
|
|
|
* Check various options.
|
|
|
|
*/
|
|
|
|
tresult = check_options(zoptions, logctx);
|
|
|
|
if (tresult != ISC_R_SUCCESS)
|
|
|
|
result = tresult;
|
|
|
|
|
2001-03-01 23:46:49 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
2001-08-03 17:24:11 +00:00
|
|
|
isc_result_t
|
2001-09-20 15:17:07 +00:00
|
|
|
bind9_check_key(cfg_obj_t *key, isc_log_t *logctx) {
|
2001-08-03 17:24:11 +00:00
|
|
|
cfg_obj_t *algobj = NULL;
|
|
|
|
cfg_obj_t *secretobj = NULL;
|
|
|
|
const char *keyname = cfg_obj_asstring(cfg_map_getname(key));
|
|
|
|
|
|
|
|
cfg_map_get(key, "algorithm", &algobj);
|
|
|
|
cfg_map_get(key, "secret", &secretobj);
|
|
|
|
if (secretobj == NULL || algobj == NULL) {
|
|
|
|
cfg_obj_log(key, logctx, ISC_LOG_ERROR,
|
|
|
|
"key '%s' must have both 'secret' and "
|
|
|
|
"'algorithm' defined",
|
|
|
|
keyname);
|
2001-10-25 17:07:21 +00:00
|
|
|
return (ISC_R_FAILURE);
|
2001-08-03 17:24:11 +00:00
|
|
|
}
|
2001-10-25 17:07:21 +00:00
|
|
|
return (ISC_R_SUCCESS);
|
2001-08-03 17:24:11 +00:00
|
|
|
}
|
2001-10-29 06:09:05 +00:00
|
|
|
|
|
|
|
static isc_result_t
|
|
|
|
check_keylist(cfg_obj_t *keys, isc_symtab_t *symtab, isc_log_t *logctx) {
|
|
|
|
isc_result_t result = ISC_R_SUCCESS;
|
|
|
|
isc_result_t tresult;
|
|
|
|
cfg_listelt_t *element;
|
|
|
|
|
|
|
|
for (element = cfg_list_first(keys);
|
|
|
|
element != NULL;
|
|
|
|
element = cfg_list_next(element))
|
|
|
|
{
|
|
|
|
cfg_obj_t *key = cfg_listelt_value(element);
|
|
|
|
const char *keyname = cfg_obj_asstring(cfg_map_getname(key));
|
|
|
|
isc_symvalue_t symvalue;
|
|
|
|
|
|
|
|
symvalue.as_pointer = NULL;
|
|
|
|
tresult = isc_symtab_define(symtab, keyname, 1,
|
|
|
|
symvalue, isc_symexists_reject);
|
|
|
|
if (tresult == ISC_R_EXISTS) {
|
|
|
|
cfg_obj_log(key, logctx, ISC_LOG_ERROR,
|
|
|
|
"key '%s': already exists ", keyname);
|
|
|
|
result = tresult;
|
|
|
|
} else if (tresult != ISC_R_SUCCESS)
|
|
|
|
return (tresult);
|
|
|
|
|
|
|
|
tresult = bind9_check_key(key, logctx);
|
|
|
|
if (tresult != ISC_R_SUCCESS)
|
|
|
|
return (tresult);
|
|
|
|
}
|
|
|
|
return (result);
|
|
|
|
}
|
2001-08-03 17:24:11 +00:00
|
|
|
|
2001-03-03 23:09:23 +00:00
|
|
|
static isc_result_t
|
2001-10-29 06:09:05 +00:00
|
|
|
check_viewconf(cfg_obj_t *config, cfg_obj_t *vconfig, dns_rdataclass_t vclass,
|
2001-09-20 15:17:07 +00:00
|
|
|
isc_log_t *logctx, isc_mem_t *mctx)
|
2001-03-08 00:55:50 +00:00
|
|
|
{
|
2001-03-03 23:09:23 +00:00
|
|
|
cfg_obj_t *zones = NULL;
|
|
|
|
cfg_obj_t *keys = NULL;
|
|
|
|
cfg_listelt_t *element;
|
2001-03-08 00:55:50 +00:00
|
|
|
isc_symtab_t *symtab = NULL;
|
2001-03-03 23:09:23 +00:00
|
|
|
isc_result_t result = ISC_R_SUCCESS;
|
2001-03-09 19:07:30 +00:00
|
|
|
isc_result_t tresult = ISC_R_SUCCESS;
|
2001-03-03 23:09:23 +00:00
|
|
|
|
2001-03-08 00:55:50 +00:00
|
|
|
/*
|
|
|
|
* Check that all zone statements are syntactically correct and
|
|
|
|
* there are no duplicate zones.
|
|
|
|
*/
|
2001-03-09 19:07:30 +00:00
|
|
|
tresult = isc_symtab_create(mctx, 100, NULL, NULL, ISC_TRUE, &symtab);
|
|
|
|
if (tresult != ISC_R_SUCCESS)
|
2001-03-08 00:55:50 +00:00
|
|
|
return (ISC_R_NOMEMORY);
|
|
|
|
|
2001-10-29 06:09:05 +00:00
|
|
|
if (vconfig != NULL)
|
|
|
|
(void)cfg_map_get(vconfig, "zone", &zones);
|
|
|
|
else
|
|
|
|
(void)cfg_map_get(config, "zone", &zones);
|
2001-09-20 15:17:07 +00:00
|
|
|
|
2001-03-03 23:09:23 +00:00
|
|
|
for (element = cfg_list_first(zones);
|
|
|
|
element != NULL;
|
|
|
|
element = cfg_list_next(element))
|
|
|
|
{
|
2001-09-20 15:17:07 +00:00
|
|
|
isc_result_t tresult;
|
2001-03-03 23:09:23 +00:00
|
|
|
cfg_obj_t *zone = cfg_listelt_value(element);
|
|
|
|
|
2001-09-20 15:17:07 +00:00
|
|
|
tresult = check_zoneconf(zone, symtab, vclass, logctx);
|
|
|
|
if (tresult != ISC_R_SUCCESS)
|
2001-03-03 23:09:23 +00:00
|
|
|
result = ISC_R_FAILURE;
|
|
|
|
}
|
|
|
|
|
2001-03-08 00:55:50 +00:00
|
|
|
isc_symtab_destroy(&symtab);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check that all key statements are syntactically correct and
|
|
|
|
* there are no duplicate keys.
|
|
|
|
*/
|
2001-03-09 19:07:30 +00:00
|
|
|
tresult = isc_symtab_create(mctx, 100, NULL, NULL, ISC_TRUE, &symtab);
|
|
|
|
if (tresult != ISC_R_SUCCESS)
|
2001-03-08 00:55:50 +00:00
|
|
|
return (ISC_R_NOMEMORY);
|
|
|
|
|
2001-10-29 06:09:05 +00:00
|
|
|
cfg_map_get(config, "key", &keys);
|
|
|
|
tresult = check_keylist(keys, symtab, logctx);
|
|
|
|
if (tresult == ISC_R_EXISTS)
|
|
|
|
result = ISC_R_FAILURE;
|
|
|
|
else if (tresult != ISC_R_SUCCESS) {
|
|
|
|
isc_symtab_destroy(&symtab);
|
|
|
|
return (tresult);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vconfig != NULL) {
|
|
|
|
keys = NULL;
|
|
|
|
(void)cfg_map_get(vconfig, "key", &keys);
|
|
|
|
tresult = check_keylist(keys, symtab, logctx);
|
|
|
|
if (tresult == ISC_R_EXISTS)
|
2001-03-08 00:55:50 +00:00
|
|
|
result = ISC_R_FAILURE;
|
2001-10-29 06:09:05 +00:00
|
|
|
else if (tresult != ISC_R_SUCCESS) {
|
2001-08-03 17:24:11 +00:00
|
|
|
isc_symtab_destroy(&symtab);
|
|
|
|
return (tresult);
|
2001-03-03 23:09:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-03-08 00:55:50 +00:00
|
|
|
isc_symtab_destroy(&symtab);
|
|
|
|
|
2001-03-09 19:07:30 +00:00
|
|
|
/*
|
|
|
|
* Check that forwarding is reasonable.
|
|
|
|
*/
|
2001-10-29 06:09:05 +00:00
|
|
|
if (vconfig == NULL) {
|
2001-03-09 19:07:30 +00:00
|
|
|
cfg_obj_t *options = NULL;
|
2001-10-29 06:09:05 +00:00
|
|
|
cfg_map_get(config, "options", &options);
|
2001-03-09 19:07:30 +00:00
|
|
|
if (options != NULL)
|
|
|
|
if (check_forward(options, logctx) != ISC_R_SUCCESS)
|
|
|
|
result = ISC_R_FAILURE;
|
|
|
|
} else {
|
|
|
|
if (check_forward(vconfig, logctx) != ISC_R_SUCCESS)
|
|
|
|
result = ISC_R_FAILURE;
|
|
|
|
}
|
|
|
|
|
2001-10-29 06:09:05 +00:00
|
|
|
if (vconfig != NULL)
|
|
|
|
tresult = check_options(vconfig, logctx);
|
|
|
|
else
|
|
|
|
tresult = check_options(config, logctx);
|
2001-06-04 21:51:27 +00:00
|
|
|
if (tresult != ISC_R_SUCCESS)
|
|
|
|
result = tresult;
|
|
|
|
|
2001-03-03 23:09:23 +00:00
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-03-01 23:46:49 +00:00
|
|
|
isc_result_t
|
2001-09-20 15:17:07 +00:00
|
|
|
bind9_check_namedconf(cfg_obj_t *config, isc_log_t *logctx, isc_mem_t *mctx) {
|
2001-03-03 23:05:23 +00:00
|
|
|
cfg_obj_t *options = NULL;
|
2001-03-01 23:46:49 +00:00
|
|
|
cfg_obj_t *views = NULL;
|
|
|
|
cfg_obj_t *obj;
|
|
|
|
cfg_listelt_t *velement;
|
2001-03-02 03:09:27 +00:00
|
|
|
isc_result_t result = ISC_R_SUCCESS;
|
2001-03-09 19:07:30 +00:00
|
|
|
isc_result_t tresult;
|
2001-03-01 23:46:49 +00:00
|
|
|
|
2001-03-03 23:05:23 +00:00
|
|
|
(void)cfg_map_get(config, "options", &options);
|
|
|
|
|
2001-06-04 21:51:27 +00:00
|
|
|
if (options != NULL)
|
|
|
|
check_options(options, logctx);
|
|
|
|
|
2001-03-01 23:46:49 +00:00
|
|
|
(void)cfg_map_get(config, "view", &views);
|
|
|
|
|
|
|
|
if (views == NULL) {
|
2001-10-29 06:09:05 +00:00
|
|
|
if (check_viewconf(config, NULL, dns_rdataclass_in,
|
2001-09-20 15:17:07 +00:00
|
|
|
logctx, mctx) != ISC_R_SUCCESS)
|
2001-03-03 23:09:23 +00:00
|
|
|
result = ISC_R_FAILURE;
|
2001-03-01 23:46:49 +00:00
|
|
|
} else {
|
|
|
|
cfg_obj_t *zones = NULL;
|
|
|
|
|
|
|
|
(void)cfg_map_get(config, "zone", &zones);
|
|
|
|
if (zones != NULL) {
|
|
|
|
cfg_obj_log(zones, logctx, ISC_LOG_ERROR,
|
|
|
|
"when using 'view' statements, "
|
|
|
|
"all zones must be in views");
|
|
|
|
result = ISC_R_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (velement = cfg_list_first(views);
|
|
|
|
velement != NULL;
|
|
|
|
velement = cfg_list_next(velement))
|
|
|
|
{
|
|
|
|
cfg_obj_t *view = cfg_listelt_value(velement);
|
2001-03-04 21:18:30 +00:00
|
|
|
cfg_obj_t *vname = cfg_tuple_get(view, "name");
|
2001-03-01 23:46:49 +00:00
|
|
|
cfg_obj_t *voptions = cfg_tuple_get(view, "options");
|
2001-09-20 15:17:07 +00:00
|
|
|
cfg_obj_t *vclassobj = cfg_tuple_get(view, "class");
|
|
|
|
dns_rdataclass_t vclass = dns_rdataclass_in;
|
|
|
|
isc_result_t tresult = ISC_R_SUCCESS;
|
2001-03-01 23:46:49 +00:00
|
|
|
|
2001-09-20 15:17:07 +00:00
|
|
|
if (cfg_obj_isstring(vclassobj)) {
|
|
|
|
isc_textregion_t r;
|
|
|
|
|
|
|
|
DE_CONST(cfg_obj_asstring(vclassobj), r.base);
|
|
|
|
r.length = strlen(r.base);
|
|
|
|
tresult = dns_rdataclass_fromtext(&vclass, &r);
|
|
|
|
if (tresult != ISC_R_SUCCESS)
|
|
|
|
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
|
|
|
"view '%s': invalid class %s",
|
|
|
|
cfg_obj_asstring(vname), r.base);
|
|
|
|
}
|
|
|
|
if (tresult == ISC_R_SUCCESS)
|
2001-10-29 06:09:05 +00:00
|
|
|
tresult = check_viewconf(config, voptions,
|
2001-09-20 15:17:07 +00:00
|
|
|
vclass, logctx, mctx);
|
|
|
|
if (tresult != ISC_R_SUCCESS)
|
2001-03-03 23:09:23 +00:00
|
|
|
result = ISC_R_FAILURE;
|
2001-03-01 23:46:49 +00:00
|
|
|
}
|
|
|
|
|
2001-03-03 23:05:23 +00:00
|
|
|
if (views != NULL && options != NULL) {
|
|
|
|
obj = NULL;
|
2001-03-09 19:07:30 +00:00
|
|
|
tresult = cfg_map_get(options, "cache-file", &obj);
|
|
|
|
if (tresult == ISC_R_SUCCESS) {
|
2001-03-03 23:05:23 +00:00
|
|
|
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
|
|
|
"'cache-file' cannot be a global "
|
|
|
|
"option if views are present");
|
|
|
|
result = ISC_R_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
2001-03-01 23:46:49 +00:00
|
|
|
|
|
|
|
return (result);
|
|
|
|
}
|