mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-09 07:12:11 -04:00
1862. [func] Add additional zone data constancy checks.
named-checkzone has extended checking of NS, MX and
SRV record and the hosts they reference.
named has extended post zone load checks.
New zone options: check-mx and integrity-check.
[RT #4940]
This commit is contained in:
parent
d73541ea2e
commit
c5223c9cb7
25 changed files with 1359 additions and 72 deletions
7
CHANGES
7
CHANGES
|
|
@ -1,3 +1,10 @@
|
|||
1862. [func] Add additional zone data constancy checks.
|
||||
named-checkzone has extended checking of NS, MX and
|
||||
SRV record and the hosts they reference.
|
||||
named has extended post zone load checks.
|
||||
New zone options: check-mx and integrity-check.
|
||||
[RT #4940]
|
||||
|
||||
1861. [placeholder] rt14801
|
||||
|
||||
1860. [placeholder] rt14775
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: check-tool.c,v 1.16 2005/04/27 04:55:42 sra Exp $ */
|
||||
/* $Id: check-tool.c,v 1.17 2005/05/19 04:58:59 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/log.h>
|
||||
#include <isc/net.h>
|
||||
#include <isc/netdb.h>
|
||||
#include <isc/region.h>
|
||||
#include <isc/stdio.h>
|
||||
#include <isc/types.h>
|
||||
|
|
@ -36,24 +38,39 @@
|
|||
#include <dns/fixedname.h>
|
||||
#include <dns/log.h>
|
||||
#include <dns/name.h>
|
||||
#include <dns/rdata.h>
|
||||
#include <dns/rdataclass.h>
|
||||
#include <dns/rdataset.h>
|
||||
#include <dns/types.h>
|
||||
#include <dns/zone.h>
|
||||
|
||||
#ifdef HAVE_ADDRINFO
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
#ifdef HAVE_GAISTRERROR
|
||||
#define USE_GETADDRINFO
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define CHECK(r) \
|
||||
do { \
|
||||
do { \
|
||||
result = (r); \
|
||||
if (result != ISC_R_SUCCESS) \
|
||||
goto cleanup; \
|
||||
} while (0)
|
||||
if (result != ISC_R_SUCCESS) \
|
||||
goto cleanup; \
|
||||
} while (0)
|
||||
|
||||
static const char *dbtype[] = { "rbt" };
|
||||
|
||||
int debug = 0;
|
||||
isc_boolean_t nomerge = ISC_TRUE;
|
||||
isc_boolean_t docheckmx = ISC_TRUE;
|
||||
isc_boolean_t dochecksrv = ISC_TRUE;
|
||||
isc_boolean_t docheckns = ISC_TRUE;
|
||||
unsigned int zone_options = DNS_ZONEOPT_CHECKNS |
|
||||
DNS_ZONEOPT_CHECKMX |
|
||||
DNS_ZONEOPT_MANYERRORS |
|
||||
DNS_ZONEOPT_CHECKNAMES |
|
||||
DNS_ZONEOPT_INTEGRITYCHECK |
|
||||
DNS_ZONEOPT_CHECKWILDCARD;
|
||||
|
||||
/*
|
||||
|
|
@ -70,6 +87,279 @@ static isc_logcategory_t categories[] = {
|
|||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static isc_boolean_t
|
||||
checkns(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner,
|
||||
dns_rdataset_t *a, dns_rdataset_t *aaaa)
|
||||
{
|
||||
#ifdef USE_GETADDRINFO
|
||||
dns_rdataset_t *rdataset;
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
struct addrinfo hints, *ai, *cur;
|
||||
char namebuf[DNS_NAME_FORMATSIZE + 1];
|
||||
char ownerbuf[DNS_NAME_FORMATSIZE];
|
||||
char addrbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123")];
|
||||
isc_boolean_t answer = ISC_TRUE;
|
||||
isc_boolean_t match;
|
||||
const char *type;
|
||||
void *ptr = NULL;
|
||||
int result;
|
||||
|
||||
REQUIRE(a == NULL || !dns_rdataset_isassociated(a) ||
|
||||
a->type == dns_rdatatype_a);
|
||||
REQUIRE(aaaa == NULL || !dns_rdataset_isassociated(aaaa) ||
|
||||
aaaa->type == dns_rdatatype_aaaa);
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
dns_name_format(name, namebuf, sizeof(namebuf) - 1);
|
||||
/*
|
||||
* Turn off search.
|
||||
*/
|
||||
if (dns_name_countlabels(name) > 1U)
|
||||
strcat(namebuf, ".");
|
||||
dns_name_format(owner, ownerbuf, sizeof(ownerbuf));
|
||||
|
||||
result = getaddrinfo(namebuf, NULL, &hints, &ai);
|
||||
dns_name_format(name, namebuf, sizeof(namebuf) - 1);
|
||||
switch (result) {
|
||||
case 0:
|
||||
if (strcasecmp(ai->ai_canonname, namebuf) != 0) {
|
||||
dns_zone_log(zone, ISC_LOG_ERROR,
|
||||
"%s/NS '%s' (out of zone) "
|
||||
"is a CNAME (illegal)",
|
||||
ownerbuf, namebuf);
|
||||
answer = ISC_FALSE;
|
||||
}
|
||||
break;
|
||||
case EAI_NONAME:
|
||||
#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
|
||||
case EAI_NODATA:
|
||||
#endif
|
||||
dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' (out of zone) "
|
||||
"has no addresses records (A or AAAA)",
|
||||
ownerbuf, namebuf);
|
||||
return (ISC_FALSE);
|
||||
|
||||
default:
|
||||
dns_zone_log(zone, ISC_LOG_WARNING,
|
||||
"getaddrinfo(%s) failed: %s",
|
||||
namebuf, gai_strerror(result));
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
if (a == NULL || aaaa == NULL)
|
||||
return (answer);
|
||||
/*
|
||||
* Check that all glue records really exist.
|
||||
*/
|
||||
if (!dns_rdataset_isassociated(a))
|
||||
goto checkaaaa;
|
||||
result = dns_rdataset_first(a);
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
dns_rdataset_current(a, &rdata);
|
||||
match = ISC_FALSE;
|
||||
for (cur = ai; cur != NULL; cur = cur->ai_next) {
|
||||
if (cur->ai_family != AF_INET)
|
||||
continue;
|
||||
ptr = &((struct sockaddr_in *)(cur->ai_addr))->sin_addr;
|
||||
if (memcmp(ptr, rdata.data, rdata.length) == 0) {
|
||||
match = ISC_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!match) {
|
||||
dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' "
|
||||
"extra GLUE A record (%s)",
|
||||
ownerbuf, namebuf,
|
||||
inet_ntop(AF_INET, rdata.data,
|
||||
addrbuf, sizeof(addrbuf)));
|
||||
answer = ISC_FALSE;
|
||||
}
|
||||
dns_rdata_reset(&rdata);
|
||||
result = dns_rdataset_next(a);
|
||||
}
|
||||
|
||||
checkaaaa:
|
||||
if (!dns_rdataset_isassociated(aaaa))
|
||||
goto checkmissing;
|
||||
result = dns_rdataset_first(aaaa);
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
dns_rdataset_current(aaaa, &rdata);
|
||||
match = ISC_FALSE;
|
||||
for (cur = ai; cur != NULL; cur = cur->ai_next) {
|
||||
if (cur->ai_family != AF_INET6)
|
||||
continue;
|
||||
ptr = &((struct sockaddr_in6 *)(cur->ai_addr))->sin6_addr;
|
||||
if (memcmp(ptr, rdata.data, rdata.length) == 0) {
|
||||
match = ISC_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!match) {
|
||||
dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' "
|
||||
"extra GLUE AAAA record (%s)",
|
||||
ownerbuf, namebuf,
|
||||
inet_ntop(AF_INET6, rdata.data,
|
||||
addrbuf, sizeof(addrbuf)));
|
||||
answer = ISC_FALSE;
|
||||
}
|
||||
dns_rdata_reset(&rdata);
|
||||
result = dns_rdataset_next(aaaa);
|
||||
}
|
||||
|
||||
checkmissing:
|
||||
/*
|
||||
* Check that all addresses appear in the glue.
|
||||
*/
|
||||
for (cur = ai; cur != NULL; cur = cur->ai_next) {
|
||||
switch (cur->ai_family) {
|
||||
case AF_INET:
|
||||
rdataset = a;
|
||||
ptr = &((struct sockaddr_in *)(cur->ai_addr))->sin_addr;
|
||||
type = "A";
|
||||
break;
|
||||
case AF_INET6:
|
||||
rdataset = aaaa;
|
||||
ptr = &((struct sockaddr_in6 *)(cur->ai_addr))->sin6_addr;
|
||||
type = "AAAA";
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
match = ISC_FALSE;
|
||||
if (dns_rdataset_isassociated(rdataset))
|
||||
result = dns_rdataset_first(rdataset);
|
||||
else
|
||||
result = ISC_R_FAILURE;
|
||||
while (result == ISC_R_SUCCESS && !match) {
|
||||
dns_rdataset_current(rdataset, &rdata);
|
||||
if (memcmp(ptr, rdata.data, rdata.length) == 0)
|
||||
match = ISC_TRUE;
|
||||
dns_rdata_reset(&rdata);
|
||||
result = dns_rdataset_next(rdataset);
|
||||
}
|
||||
if (!match) {
|
||||
dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' "
|
||||
"missing GLUE %s record (%s)",
|
||||
ownerbuf, namebuf, type,
|
||||
inet_ntop(cur->ai_family, ptr,
|
||||
addrbuf, sizeof(addrbuf)));
|
||||
answer = ISC_FALSE;
|
||||
}
|
||||
}
|
||||
freeaddrinfo(ai);
|
||||
return (answer);
|
||||
#else
|
||||
return (ISC_TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
checkmx(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) {
|
||||
#ifdef USE_GETADDRINFO
|
||||
struct addrinfo hints, *ai;
|
||||
char namebuf[DNS_NAME_FORMATSIZE + 1];
|
||||
char ownerbuf[DNS_NAME_FORMATSIZE];
|
||||
int result;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
dns_name_format(name, namebuf, sizeof(namebuf) - 1);
|
||||
/*
|
||||
* Turn off search.
|
||||
*/
|
||||
if (dns_name_countlabels(name) > 1U)
|
||||
strcat(namebuf, ".");
|
||||
dns_name_format(owner, ownerbuf, sizeof(ownerbuf));
|
||||
|
||||
result = getaddrinfo(namebuf, NULL, &hints, &ai);
|
||||
dns_name_format(name, namebuf, sizeof(namebuf) - 1);
|
||||
switch (result) {
|
||||
case 0:
|
||||
if (strcasecmp(ai->ai_canonname, namebuf) != 0)
|
||||
dns_zone_log(zone, ISC_LOG_WARNING,
|
||||
"%s/MX '%s' (out of zone) "
|
||||
"is a CNAME (illegal)",
|
||||
ownerbuf, namebuf);
|
||||
freeaddrinfo(ai);
|
||||
break;
|
||||
case EAI_NONAME:
|
||||
#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
|
||||
case EAI_NODATA:
|
||||
#endif
|
||||
dns_zone_log(zone, ISC_LOG_ERROR, "%s/MX '%s' (out of zone) "
|
||||
"has no addresses records (A or AAAA)",
|
||||
ownerbuf, namebuf);
|
||||
return (ISC_FALSE);
|
||||
|
||||
default:
|
||||
dns_zone_log(zone, ISC_LOG_WARNING,
|
||||
"getaddrinfo(%s) failed: %s",
|
||||
namebuf, gai_strerror(result));
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
#endif
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
checksrv(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) {
|
||||
#ifdef USE_GETADDRINFO
|
||||
struct addrinfo hints, *ai;
|
||||
char namebuf[DNS_NAME_FORMATSIZE + 1];
|
||||
char ownerbuf[DNS_NAME_FORMATSIZE];
|
||||
int result;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
dns_name_format(name, namebuf, sizeof(namebuf) - 1);
|
||||
/*
|
||||
* Turn off search.
|
||||
*/
|
||||
if (dns_name_countlabels(name) > 1U)
|
||||
strcat(namebuf, ".");
|
||||
dns_name_format(owner, ownerbuf, sizeof(ownerbuf));
|
||||
|
||||
result = getaddrinfo(namebuf, NULL, &hints, &ai);
|
||||
dns_name_format(name, namebuf, sizeof(namebuf) - 1);
|
||||
switch (result) {
|
||||
case 0:
|
||||
if (strcasecmp(ai->ai_canonname, namebuf) != 0)
|
||||
dns_zone_log(zone, ISC_LOG_WARNING,
|
||||
"%s/SRV '%s' (out of zone) "
|
||||
"is a CNAME (illegal)",
|
||||
ownerbuf, namebuf);
|
||||
freeaddrinfo(ai);
|
||||
break;
|
||||
case EAI_NONAME:
|
||||
#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
|
||||
case EAI_NODATA:
|
||||
#endif
|
||||
dns_zone_log(zone, ISC_LOG_ERROR, "%s/SRV '%s' (out of zone) "
|
||||
"has no addresses records (A or AAAA)",
|
||||
ownerbuf, namebuf);
|
||||
return (ISC_FALSE);
|
||||
|
||||
default:
|
||||
dns_zone_log(zone, ISC_LOG_WARNING,
|
||||
"getaddrinfo(%s) failed: %s",
|
||||
namebuf, gai_strerror(result));
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
#endif
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
setup_logging(isc_mem_t *mctx, isc_log_t **logp) {
|
||||
isc_logdestination_t destination;
|
||||
|
|
@ -124,7 +414,7 @@ load_zone(isc_mem_t *mctx, const char *zonename, const char *filename,
|
|||
dns_fixedname_init(&fixorigin);
|
||||
origin = dns_fixedname_name(&fixorigin);
|
||||
CHECK(dns_name_fromtext(origin, &buffer, dns_rootname,
|
||||
ISC_FALSE, NULL));
|
||||
ISC_FALSE, NULL));
|
||||
CHECK(dns_zone_setorigin(zone, origin));
|
||||
CHECK(dns_zone_setdbtype(zone, 1, (const char * const *) dbtype));
|
||||
CHECK(dns_zone_setfile(zone, filename));
|
||||
|
|
@ -136,6 +426,12 @@ load_zone(isc_mem_t *mctx, const char *zonename, const char *filename,
|
|||
dns_zone_setclass(zone, rdclass);
|
||||
dns_zone_setoption(zone, zone_options, ISC_TRUE);
|
||||
dns_zone_setoption(zone, DNS_ZONEOPT_NOMERGE, nomerge);
|
||||
if (docheckmx)
|
||||
dns_zone_setcheckmx(zone, checkmx);
|
||||
if (docheckns)
|
||||
dns_zone_setcheckns(zone, checkns);
|
||||
if (dochecksrv)
|
||||
dns_zone_setchecksrv(zone, checksrv);
|
||||
|
||||
CHECK(dns_zone_load(zone));
|
||||
if (zonep != NULL){
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: check-tool.h,v 1.9 2005/04/29 00:22:24 marka Exp $ */
|
||||
/* $Id: check-tool.h,v 1.10 2005/05/19 04:58:59 marka Exp $ */
|
||||
|
||||
#ifndef CHECK_TOOL_H
|
||||
#define CHECK_TOOL_H
|
||||
|
|
@ -41,6 +41,9 @@ dump_zone(const char *zonename, dns_zone_t *zone, const char *filename);
|
|||
|
||||
extern int debug;
|
||||
extern isc_boolean_t nomerge;
|
||||
extern isc_boolean_t docheckmx;
|
||||
extern isc_boolean_t docheckns;
|
||||
extern isc_boolean_t dochecksrv;
|
||||
extern unsigned int zone_options;
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: named-checkconf.c,v 1.31 2005/04/27 04:55:43 sra Exp $ */
|
||||
/* $Id: named-checkconf.c,v 1.32 2005/05/19 04:58:59 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
|
|
@ -41,11 +41,14 @@
|
|||
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/log.h>
|
||||
#include <dns/name.h>
|
||||
#include <dns/result.h>
|
||||
#include <dns/zone.h>
|
||||
|
||||
#include "check-tool.h"
|
||||
|
||||
isc_log_t *logc = NULL;
|
||||
static isc_entropy_t *ectx = NULL;
|
||||
|
||||
#define CHECK(r)\
|
||||
do { \
|
||||
|
|
@ -88,10 +91,54 @@ directory_callback(const char *clausename, cfg_obj_t *obj, void *arg) {
|
|||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
get_maps(cfg_obj_t **maps, const char *name, cfg_obj_t **obj) {
|
||||
int i;
|
||||
for (i = 0;; i++) {
|
||||
if (maps[i] == NULL)
|
||||
return (ISC_FALSE);
|
||||
if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS)
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
get_checknames(cfg_obj_t **maps, cfg_obj_t **obj) {
|
||||
cfg_listelt_t *element;
|
||||
cfg_obj_t *checknames;
|
||||
cfg_obj_t *type;
|
||||
cfg_obj_t *value;
|
||||
isc_result_t result;
|
||||
int i;
|
||||
|
||||
for (i = 0;; i++) {
|
||||
if (maps[i] == NULL)
|
||||
return (ISC_FALSE);
|
||||
checknames = NULL;
|
||||
result = cfg_map_get(maps[i], "check-names", &checknames);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
continue;
|
||||
if (checknames != NULL && !cfg_obj_islist(checknames)) {
|
||||
*obj = checknames;
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
for (element = cfg_list_first(checknames);
|
||||
element != NULL;
|
||||
element = cfg_list_next(element)) {
|
||||
value = cfg_listelt_value(element);
|
||||
type = cfg_tuple_get(value, "type");
|
||||
if (strcasecmp(cfg_obj_asstring(type), "master") != 0)
|
||||
continue;
|
||||
*obj = cfg_tuple_get(value, "mode");
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*% configure the zone */
|
||||
static isc_result_t
|
||||
configure_zone(const char *vclass, const char *view, cfg_obj_t *zconfig,
|
||||
isc_mem_t *mctx)
|
||||
cfg_obj_t *vconfig, cfg_obj_t *config, isc_mem_t *mctx)
|
||||
{
|
||||
isc_result_t result;
|
||||
const char *zclass;
|
||||
|
|
@ -102,6 +149,13 @@ configure_zone(const char *vclass, const char *view, cfg_obj_t *zconfig,
|
|||
cfg_obj_t *typeobj = NULL;
|
||||
cfg_obj_t *fileobj = NULL;
|
||||
cfg_obj_t *dbobj = NULL;
|
||||
cfg_obj_t *obj = NULL;
|
||||
cfg_obj_t *maps[4];
|
||||
int i = 0;
|
||||
|
||||
zone_options = DNS_ZONEOPT_CHECKNS |
|
||||
DNS_ZONEOPT_MANYERRORS |
|
||||
DNS_ZONEOPT_INTEGRITYCHECK;
|
||||
|
||||
zname = cfg_obj_asstring(cfg_tuple_get(zconfig, "name"));
|
||||
classobj = cfg_tuple_get(zconfig, "class");
|
||||
|
|
@ -109,7 +163,18 @@ configure_zone(const char *vclass, const char *view, cfg_obj_t *zconfig,
|
|||
zclass = vclass;
|
||||
else
|
||||
zclass = cfg_obj_asstring(classobj);
|
||||
|
||||
zoptions = cfg_tuple_get(zconfig, "options");
|
||||
maps[i++] = zoptions;
|
||||
if (vconfig != NULL)
|
||||
maps[i++] = cfg_tuple_get(vconfig, "options");
|
||||
if (config != NULL) {
|
||||
cfg_map_get(config, "options", &obj);
|
||||
if (obj != NULL)
|
||||
maps[i++] = obj;
|
||||
}
|
||||
maps[i++] = NULL;
|
||||
|
||||
cfg_map_get(zoptions, "type", &typeobj);
|
||||
if (typeobj == NULL)
|
||||
return (ISC_R_FAILURE);
|
||||
|
|
@ -122,6 +187,43 @@ configure_zone(const char *vclass, const char *view, cfg_obj_t *zconfig,
|
|||
if (fileobj == NULL)
|
||||
return (ISC_R_FAILURE);
|
||||
zfile = cfg_obj_asstring(fileobj);
|
||||
|
||||
obj = NULL;
|
||||
if (get_maps(maps, "check-mx", &obj)) {
|
||||
if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
|
||||
zone_options |= DNS_ZONEOPT_CHECKMX;
|
||||
zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL;
|
||||
} else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
|
||||
zone_options |= DNS_ZONEOPT_CHECKMX;
|
||||
zone_options |= DNS_ZONEOPT_CHECKMXFAIL;
|
||||
} else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
|
||||
zone_options &= ~DNS_ZONEOPT_CHECKMX;
|
||||
zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL;
|
||||
} else
|
||||
INSIST(0);
|
||||
} else {
|
||||
zone_options |= DNS_ZONEOPT_CHECKMX;
|
||||
zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL;
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
if (get_checknames(maps, &obj)) {
|
||||
if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
|
||||
zone_options |= DNS_ZONEOPT_CHECKNAMES;
|
||||
zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL;
|
||||
} else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
|
||||
zone_options |= DNS_ZONEOPT_CHECKNAMES;
|
||||
zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL;
|
||||
} else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
|
||||
zone_options &= ~DNS_ZONEOPT_CHECKNAMES;
|
||||
zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL;
|
||||
} else
|
||||
INSIST(0);
|
||||
} else {
|
||||
zone_options |= DNS_ZONEOPT_CHECKNAMES;
|
||||
zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL;
|
||||
}
|
||||
|
||||
result = load_zone(mctx, zname, zfile, zclass, NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
fprintf(stderr, "%s/%s/%s: %s\n", view, zname, zclass,
|
||||
|
|
@ -155,7 +257,8 @@ configure_view(const char *vclass, const char *view, cfg_obj_t *config,
|
|||
element = cfg_list_next(element))
|
||||
{
|
||||
cfg_obj_t *zconfig = cfg_listelt_value(element);
|
||||
tresult = configure_zone(vclass, view, zconfig, mctx);
|
||||
tresult = configure_zone(vclass, view, zconfig, vconfig,
|
||||
config, mctx);
|
||||
if (tresult != ISC_R_SUCCESS)
|
||||
result = tresult;
|
||||
}
|
||||
|
|
@ -248,6 +351,9 @@ main(int argc, char **argv) {
|
|||
|
||||
case 'z':
|
||||
load_zones = ISC_TRUE;
|
||||
docheckmx = ISC_FALSE;
|
||||
docheckns = ISC_FALSE;
|
||||
dochecksrv = ISC_FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -268,6 +374,10 @@ main(int argc, char **argv) {
|
|||
RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)
|
||||
== ISC_R_SUCCESS);
|
||||
|
||||
RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS);
|
||||
RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)
|
||||
== ISC_R_SUCCESS);
|
||||
|
||||
dns_result_register();
|
||||
|
||||
RUNTIME_CHECK(cfg_parser_create(mctx, logc, &parser) == ISC_R_SUCCESS);
|
||||
|
|
@ -294,6 +404,8 @@ main(int argc, char **argv) {
|
|||
|
||||
cfg_parser_destroy(&parser);
|
||||
|
||||
isc_hash_destroy();
|
||||
|
||||
isc_log_destroy(&logc);
|
||||
|
||||
isc_hash_destroy();
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: named-checkzone.c,v 1.34 2005/04/27 04:55:43 sra Exp $ */
|
||||
/* $Id: named-checkzone.c,v 1.35 2005/05/19 04:58:59 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
|
|
@ -39,6 +39,7 @@
|
|||
#include <dns/db.h>
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/log.h>
|
||||
#include <dns/name.h>
|
||||
#include <dns/rdataclass.h>
|
||||
#include <dns/rdataset.h>
|
||||
#include <dns/result.h>
|
||||
|
|
@ -69,7 +70,9 @@ usage(void) {
|
|||
fprintf(stderr,
|
||||
"usage: named-checkzone [-djqvD] [-c class] [-o output] "
|
||||
"[-t directory] [-w directory] [-k (ignore|warn|fail)] "
|
||||
"[-n (ignore|warn|fail)] [-W (ignore|warn)] zonename filename\n");
|
||||
"[-n (ignore|warn|fail)] [-m (ignore|warn|fail)] "
|
||||
"[-i (full|local|none)] [-W (ignore|warn)] "
|
||||
"zonename filename\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
@ -91,7 +94,8 @@ main(int argc, char **argv) {
|
|||
char *classname = classname_in;
|
||||
const char *workdir = NULL;
|
||||
|
||||
while ((c = isc_commandline_parse(argc, argv, "c:dijk:n:qst:o:vw:DW:")) != EOF) {
|
||||
while ((c = isc_commandline_parse(argc, argv,
|
||||
"c:di:jk:m:n:qst:o:vw:DW:")) != EOF) {
|
||||
switch (c) {
|
||||
case 'c':
|
||||
classname = isc_commandline_argument;
|
||||
|
|
@ -101,20 +105,33 @@ main(int argc, char **argv) {
|
|||
debug++;
|
||||
break;
|
||||
|
||||
case 'j':
|
||||
nomerge = ISC_FALSE;
|
||||
case 'i':
|
||||
if (!strcmp(isc_commandline_argument, "full")) {
|
||||
zone_options |= DNS_ZONEOPT_INTEGRITYCHECK;
|
||||
docheckmx = ISC_TRUE;
|
||||
docheckns = ISC_TRUE;
|
||||
dochecksrv = ISC_TRUE;
|
||||
} else if (!strcmp(isc_commandline_argument,
|
||||
"local")) {
|
||||
zone_options |= DNS_ZONEOPT_INTEGRITYCHECK;
|
||||
docheckmx = ISC_FALSE;
|
||||
docheckns = ISC_FALSE;
|
||||
dochecksrv = ISC_FALSE;
|
||||
} else if (!strcmp(isc_commandline_argument,
|
||||
"none")) {
|
||||
zone_options &= ~DNS_ZONEOPT_INTEGRITYCHECK;
|
||||
docheckmx = ISC_FALSE;
|
||||
docheckns = ISC_FALSE;
|
||||
dochecksrv = ISC_FALSE;
|
||||
} else {
|
||||
fprintf(stderr, "invalid argument to -i: %s\n",
|
||||
isc_commandline_argument);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
if (!strcmp(isc_commandline_argument, "ignore"))
|
||||
zone_options &= ~(DNS_ZONEOPT_CHECKNS|
|
||||
DNS_ZONEOPT_FATALNS);
|
||||
else if (!strcmp(isc_commandline_argument, "warn")) {
|
||||
zone_options |= DNS_ZONEOPT_CHECKNS;
|
||||
zone_options &= ~DNS_ZONEOPT_FATALNS;
|
||||
} else if (!strcmp(isc_commandline_argument, "fail"))
|
||||
zone_options |= DNS_ZONEOPT_CHECKNS|
|
||||
DNS_ZONEOPT_FATALNS;
|
||||
case 'j':
|
||||
nomerge = ISC_FALSE;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
|
|
@ -129,6 +146,46 @@ main(int argc, char **argv) {
|
|||
"ignore")) {
|
||||
zone_options &= ~(DNS_ZONEOPT_CHECKNAMES |
|
||||
DNS_ZONEOPT_CHECKNAMESFAIL);
|
||||
} else {
|
||||
fprintf(stderr, "invalid argument to -k: %s\n",
|
||||
isc_commandline_argument);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
if (!strcmp(isc_commandline_argument, "ignore")) {
|
||||
zone_options &= ~(DNS_ZONEOPT_CHECKNS|
|
||||
DNS_ZONEOPT_FATALNS);
|
||||
} else if (!strcmp(isc_commandline_argument, "warn")) {
|
||||
zone_options |= DNS_ZONEOPT_CHECKNS;
|
||||
zone_options &= ~DNS_ZONEOPT_FATALNS;
|
||||
} else if (!strcmp(isc_commandline_argument, "fail")) {
|
||||
zone_options |= DNS_ZONEOPT_CHECKNS|
|
||||
DNS_ZONEOPT_FATALNS;
|
||||
} else {
|
||||
fprintf(stderr, "invalid argument to -n: %s\n",
|
||||
isc_commandline_argument);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (!strcmp(isc_commandline_argument, "warn")) {
|
||||
zone_options |= DNS_ZONEOPT_CHECKMX;
|
||||
zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL;
|
||||
} else if (!strcmp(isc_commandline_argument,
|
||||
"fail")) {
|
||||
zone_options |= DNS_ZONEOPT_CHECKMX |
|
||||
DNS_ZONEOPT_CHECKMXFAIL;
|
||||
} else if (!strcmp(isc_commandline_argument,
|
||||
"ignore")) {
|
||||
zone_options &= ~(DNS_ZONEOPT_CHECKMX |
|
||||
DNS_ZONEOPT_CHECKMXFAIL);
|
||||
} else {
|
||||
fprintf(stderr, "invalid argument to -m: %s\n",
|
||||
isc_commandline_argument);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
- PERFORMANCE OF THIS SOFTWARE.
|
||||
-->
|
||||
|
||||
<!-- $Id: named-checkzone.docbook,v 1.18 2005/05/13 01:35:38 marka Exp $ -->
|
||||
<!-- $Id: named-checkzone.docbook,v 1.19 2005/05/19 04:58:59 marka Exp $ -->
|
||||
<refentry>
|
||||
<refentryinfo>
|
||||
<date>June 13, 2000</date>
|
||||
|
|
@ -57,7 +57,9 @@
|
|||
<arg><option>-q</option></arg>
|
||||
<arg><option>-v</option></arg>
|
||||
<arg><option>-c <replaceable class="parameter">class</replaceable></option></arg>
|
||||
<arg><option>-i <replaceable class="parameter">mode</replaceable></option></arg>
|
||||
<arg><option>-k <replaceable class="parameter">mode</replaceable></option></arg>
|
||||
<arg><option>-m <replaceable class="parameter">mode</replaceable></option></arg>
|
||||
<arg><option>-n <replaceable class="parameter">mode</replaceable></option></arg>
|
||||
<arg><option>-o <replaceable class="parameter">filename</replaceable></option></arg>
|
||||
<arg><option>-t <replaceable class="parameter">directory</replaceable></option></arg>
|
||||
|
|
@ -129,6 +131,42 @@
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-i <replaceable class="parameter">mode</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Perform post load zone integrity checks. Possible modes are
|
||||
<command>"full"</command> (default),
|
||||
<command>"local"</command> and
|
||||
<command>"none"</command>.
|
||||
</para>
|
||||
<para>
|
||||
Mode <command>"full"</command> checks that MX records
|
||||
refer to A or AAAA record (both in-zone and out-of-zone
|
||||
hostnames). Mode <command>"local"</command> only
|
||||
checks MX records which refer to in-zone hostnames.
|
||||
</para>
|
||||
<para>
|
||||
Mode <command>"full"</command> checks that SRV records
|
||||
refer to A or AAAA record (both in-zone and out-of-zone
|
||||
hostnames). Mode <command>"local"</command> only
|
||||
checks SRV records which refer to in-zone hostnames.
|
||||
</para>
|
||||
<para>
|
||||
Mode <command>"full"</command> checks that delegation NS
|
||||
records refer to A or AAAA record (both in-zone and out-of-zone
|
||||
hostnames). It also checks that glue addresses records
|
||||
in the zone match those advertised by the child.
|
||||
Mode <command>"local"</command> only checks NS records which
|
||||
refer to in-zone hostnames or that some required glue exists,
|
||||
that is when the nameserver is in a child zone.
|
||||
</para>
|
||||
<para>
|
||||
Mode <command>"none"</command> disables the checks.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-k <replaceable class="parameter">mode</replaceable></term>
|
||||
<listitem>
|
||||
|
|
@ -142,6 +180,18 @@
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-m <replaceable class="parameter">mode</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specify whether MX records should be checked to see if they
|
||||
are addresses. Possible modes are <command>"fail"</command>,
|
||||
<command>"warn"</command> (default) and
|
||||
<command>"ignore"</command>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-n <replaceable class="parameter">mode</replaceable></term>
|
||||
<listitem>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: config.c,v 1.56 2005/04/27 04:55:49 sra Exp $ */
|
||||
/* $Id: config.c,v 1.57 2005/05/19 04:59:00 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
|
|
@ -128,10 +128,12 @@ options {\n\
|
|||
check-names master fail;\n\
|
||||
check-names slave warn;\n\
|
||||
check-names response ignore;\n\
|
||||
check-mx warn;\n\
|
||||
use-additional-cache true;\n\
|
||||
acache-cleaning-interval 60;\n\
|
||||
max-acache-size 0;\n\
|
||||
dnssec-enable no; /* Make yes for 9.4. */ \n\
|
||||
integrity-check yes;\n\
|
||||
"
|
||||
|
||||
" /* zone */\n\
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
- PERFORMANCE OF THIS SOFTWARE.
|
||||
-->
|
||||
|
||||
<!-- $Id: named.conf.docbook,v 1.10 2005/05/13 01:35:40 marka Exp $ -->
|
||||
<!-- $Id: named.conf.docbook,v 1.11 2005/05/19 04:59:00 marka Exp $ -->
|
||||
<refentry>
|
||||
<refentryinfo>
|
||||
<date>Aug 13, 2004</date>
|
||||
|
|
@ -240,6 +240,8 @@ options {
|
|||
max-cache-size <replaceable>size_no_default</replaceable>;
|
||||
check-names ( master | slave | response )
|
||||
( fail | warn | ignore );
|
||||
check-mx ( fail | warn | ignore );
|
||||
integrity-check <replaceable>boolean</replaceable>;
|
||||
cache-file <replaceable>quoted_string</replaceable>;
|
||||
suppress-initial-notify <replaceable>boolean</replaceable>; // not yet implemented
|
||||
preferred-glue <replaceable>string</replaceable>;
|
||||
|
|
@ -370,6 +372,8 @@ view <replaceable>string</replaceable> <replaceable>optional_class</replaceable>
|
|||
max-cache-size <replaceable>size_no_default</replaceable>;
|
||||
check-names ( master | slave | response )
|
||||
( fail | warn | ignore );
|
||||
check-mx ( fail | warn | ignore );
|
||||
integrity-check <replaceable>boolean</replaceable>;
|
||||
cache-file <replaceable>quoted_string</replaceable>;
|
||||
suppress-initial-notify <replaceable>boolean</replaceable>; // not yet implemented
|
||||
preferred-glue <replaceable>string</replaceable>;
|
||||
|
|
@ -458,6 +462,8 @@ zone <replaceable>string</replaceable> <replaceable>optional_class</replaceable>
|
|||
database <replaceable>string</replaceable>;
|
||||
delegation-only <replaceable>boolean</replaceable>;
|
||||
check-names ( fail | warn | ignore );
|
||||
check-mx ( fail | warn | ignore );
|
||||
integrity-check <replaceable>boolean</replaceable>;
|
||||
dialup <replaceable>dialuptype</replaceable>;
|
||||
ixfr-from-differences <replaceable>boolean</replaceable>;
|
||||
journal <replaceable>quoted_string</replaceable>;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: update.c,v 1.121 2005/04/27 04:55:55 sra Exp $ */
|
||||
/* $Id: update.c,v 1.122 2005/05/19 04:59:00 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
|
@ -36,6 +36,7 @@
|
|||
#include <dns/rdataclass.h>
|
||||
#include <dns/rdataset.h>
|
||||
#include <dns/rdatasetiter.h>
|
||||
#include <dns/rdatastruct.h>
|
||||
#include <dns/rdatatype.h>
|
||||
#include <dns/soa.h>
|
||||
#include <dns/ssu.h>
|
||||
|
|
@ -2129,6 +2130,112 @@ remove_orphaned_ds(dns_db_t *db, dns_dbversion_t *newver, dns_diff_t *diff) {
|
|||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* This implements the post load integrity checks for mx records.
|
||||
*/
|
||||
static isc_result_t
|
||||
check_mx(ns_client_t *client, dns_zone_t *zone,
|
||||
dns_db_t *db, dns_dbversion_t *newver, dns_diff_t *diff)
|
||||
{
|
||||
char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123.")];
|
||||
char ownerbuf[DNS_NAME_FORMATSIZE];
|
||||
char namebuf[DNS_NAME_FORMATSIZE];
|
||||
char altbuf[DNS_NAME_FORMATSIZE];
|
||||
dns_difftuple_t *t;
|
||||
dns_fixedname_t fixed;
|
||||
dns_name_t *foundname;
|
||||
dns_rdata_mx_t mx;
|
||||
dns_rdata_t rdata;
|
||||
isc_boolean_t ok = ISC_TRUE;
|
||||
isc_boolean_t isaddress;
|
||||
isc_result_t result;
|
||||
struct in6_addr addr6;
|
||||
struct in_addr addr;
|
||||
unsigned int options;
|
||||
|
||||
dns_fixedname_init(&fixed);
|
||||
foundname = dns_fixedname_name(&fixed);
|
||||
dns_rdata_init(&rdata);
|
||||
options = dns_zone_getoptions(zone);
|
||||
|
||||
for (t = ISC_LIST_HEAD(diff->tuples);
|
||||
t != NULL;
|
||||
t = ISC_LIST_NEXT(t, link)) {
|
||||
if (t->op != DNS_DIFFOP_DEL ||
|
||||
t->rdata.type != dns_rdatatype_mx)
|
||||
continue;
|
||||
|
||||
result = dns_rdata_tostruct(&t->rdata, &mx, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
/*
|
||||
* Check if we will error out if we attempt to reload the
|
||||
* zone.
|
||||
*/
|
||||
dns_name_format(&mx.mx, namebuf, sizeof(namebuf));
|
||||
dns_name_format(&t->name, ownerbuf, sizeof(ownerbuf));
|
||||
isaddress = ISC_FALSE;
|
||||
if ((options & DNS_RDATA_CHECKMX) != 0 &&
|
||||
strlcpy(tmp, namebuf, sizeof(tmp)) < sizeof(tmp)) {
|
||||
if (tmp[strlen(tmp) - 1] == '.')
|
||||
tmp[strlen(tmp) - 1] = '\0';
|
||||
if (inet_aton(tmp, &addr) == 1 ||
|
||||
inet_pton(AF_INET6, tmp, &addr6) == 1)
|
||||
isaddress = ISC_TRUE;
|
||||
}
|
||||
|
||||
if (isaddress && (options & DNS_RDATA_CHECKMXFAIL) != 0) {
|
||||
update_log(client, zone, ISC_LOG_ERROR,
|
||||
"%s/MX: '%s': %s",
|
||||
ownerbuf, namebuf,
|
||||
dns_result_totext(DNS_R_MXISADDRESS));
|
||||
ok = ISC_FALSE;
|
||||
} else if (isaddress) {
|
||||
update_log(client, zone, ISC_LOG_WARNING,
|
||||
"%s/MX: warning: '%s': %s",
|
||||
ownerbuf, namebuf,
|
||||
dns_result_totext(DNS_R_MXISADDRESS));
|
||||
}
|
||||
|
||||
/*
|
||||
* Check zone integrity checks.
|
||||
*/
|
||||
if ((options & DNS_ZONEOPT_INTEGRITYCHECK) == 0)
|
||||
continue;
|
||||
result = dns_db_find(db, &mx.mx, newver, dns_rdatatype_a,
|
||||
0, 0, NULL, foundname, NULL, NULL);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
continue;
|
||||
|
||||
if (result == DNS_R_NXRRSET) {
|
||||
result = dns_db_find(db, &mx.mx, newver,
|
||||
dns_rdatatype_aaaa,
|
||||
0, 0, NULL, foundname,
|
||||
NULL, NULL);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN) {
|
||||
update_log(client, zone, ISC_LOG_ERROR,
|
||||
"%s/MX '%s' has no address records "
|
||||
"(A or AAAA)", ownerbuf, namebuf);
|
||||
ok = ISC_FALSE;
|
||||
} else if (result == DNS_R_CNAME) {
|
||||
update_log(client, zone, ISC_LOG_ERROR,
|
||||
"%s/MX '%s' is a CNAME (illegal)",
|
||||
ownerbuf, namebuf);
|
||||
ok = ISC_FALSE;
|
||||
} else if (result == DNS_R_DNAME) {
|
||||
dns_name_format(foundname, altbuf, sizeof altbuf);
|
||||
update_log(client, zone, ISC_LOG_ERROR,
|
||||
"%s/MX '%s' is below a DNAME '%s' (illegal)",
|
||||
ownerbuf, namebuf, altbuf);
|
||||
ok = ISC_FALSE;
|
||||
}
|
||||
}
|
||||
return (ok ? ISC_R_SUCCESS : DNS_R_REFUSED);
|
||||
}
|
||||
|
||||
static void
|
||||
update_action(isc_task_t *task, isc_event_t *event) {
|
||||
update_event_t *uev = (update_event_t *) event;
|
||||
|
|
@ -2628,6 +2735,8 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
|||
CHECK(increment_soa_serial(db, ver, &diff, mctx));
|
||||
}
|
||||
|
||||
CHECK(check_mx(client, zone, db, ver, &diff));
|
||||
|
||||
CHECK(remove_orphaned_ds(db, ver, &diff));
|
||||
|
||||
if (dns_db_issecure(db)) {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: zoneconf.c,v 1.120 2005/04/27 04:55:56 sra Exp $ */
|
||||
/* $Id: zoneconf.c,v 1.121 2005/05/19 04:59:01 marka Exp $ */
|
||||
|
||||
/*% */
|
||||
|
||||
|
|
@ -613,6 +613,7 @@ ns_zone_configure(cfg_obj_t *config, cfg_obj_t *vconfig, cfg_obj_t *zconfig,
|
|||
}
|
||||
RETERR(dns_zone_setkeydirectory(zone, filename));
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
result = ns_config_get(maps, "check-wildcard", &obj);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
|
|
@ -620,6 +621,69 @@ ns_zone_configure(cfg_obj_t *config, cfg_obj_t *vconfig, cfg_obj_t *zconfig,
|
|||
else
|
||||
check = ISC_FALSE;
|
||||
dns_zone_setoption(zone, DNS_ZONEOPT_CHECKWILDCARD, check);
|
||||
|
||||
obj = NULL;
|
||||
result = ns_config_get(maps, "check-mx", &obj);
|
||||
INSIST(obj != NULL);
|
||||
if (strcasecmp(cfg_obj_asstring(obj), "warn") == 0) {
|
||||
fail = ISC_FALSE;
|
||||
check = ISC_TRUE;
|
||||
} else if (strcasecmp(cfg_obj_asstring(obj), "fail") == 0) {
|
||||
fail = check = ISC_TRUE;
|
||||
} else if (strcasecmp(cfg_obj_asstring(obj), "ignore") == 0) {
|
||||
fail = check = ISC_FALSE;
|
||||
} else
|
||||
INSIST(0);
|
||||
dns_zone_setoption(zone, DNS_ZONEOPT_CHECKMX, check);
|
||||
dns_zone_setoption(zone, DNS_ZONEOPT_CHECKMXFAIL, fail);
|
||||
|
||||
obj = NULL;
|
||||
result = ns_config_get(maps, "integrity-check", &obj);
|
||||
INSIST(obj != NULL);
|
||||
dns_zone_setoption(zone, DNS_ZONEOPT_INTEGRITYCHECK,
|
||||
cfg_obj_asboolean(obj));
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure update-related options. These apply to
|
||||
* primary masters only.
|
||||
*/
|
||||
if (ztype == dns_zone_master) {
|
||||
dns_acl_t *updateacl;
|
||||
RETERR(configure_zone_acl(zconfig, vconfig, config,
|
||||
"allow-update", ac, zone,
|
||||
dns_zone_setupdateacl,
|
||||
dns_zone_clearupdateacl));
|
||||
|
||||
updateacl = dns_zone_getupdateacl(zone);
|
||||
if (updateacl != NULL && dns_acl_isinsecure(updateacl))
|
||||
isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY,
|
||||
NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
|
||||
"zone '%s' allows updates by IP "
|
||||
"address, which is insecure",
|
||||
zname);
|
||||
|
||||
RETERR(configure_zone_ssutable(zoptions, zone));
|
||||
|
||||
obj = NULL;
|
||||
result = ns_config_get(maps, "sig-validity-interval", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
dns_zone_setsigvalidityinterval(zone,
|
||||
cfg_obj_asuint32(obj) * 86400);
|
||||
|
||||
obj = NULL;
|
||||
result = ns_config_get(maps, "key-directory", &obj);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
filename = cfg_obj_asstring(obj);
|
||||
if (!isc_file_isabsolute(filename)) {
|
||||
cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR,
|
||||
"key-directory '%s' "
|
||||
"is not absolute", filename);
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
RETERR(dns_zone_setkeydirectory(zone, filename));
|
||||
}
|
||||
|
||||
} else if (ztype == dns_zone_slave) {
|
||||
RETERR(configure_zone_acl(zconfig, vconfig, config,
|
||||
"allow-update-forwarding", ac, zone,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: named.conf,v 1.12 2004/03/05 05:01:58 marka Exp $ */
|
||||
/* $Id: named.conf,v 1.13 2005/05/19 04:59:01 marka Exp $ */
|
||||
|
||||
controls { /* empty */ };
|
||||
|
||||
|
|
@ -43,6 +43,7 @@ controls {
|
|||
zone "example.nil" {
|
||||
type master;
|
||||
file "example.db";
|
||||
integrity-check no;
|
||||
allow-update { any; };
|
||||
allow-transfer { any; };
|
||||
};
|
||||
|
|
@ -50,6 +51,7 @@ zone "example.nil" {
|
|||
zone "update.nil" {
|
||||
type master;
|
||||
file "update.db";
|
||||
integrity-check no;
|
||||
allow-update { any; };
|
||||
allow-transfer { any; };
|
||||
also-notify { 10.53.0.2; };
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
- PERFORMANCE OF THIS SOFTWARE.
|
||||
-->
|
||||
|
||||
<!-- File: $Id: Bv9ARM-book.xml,v 1.268 2005/05/13 01:35:42 marka Exp $ -->
|
||||
<!-- File: $Id: Bv9ARM-book.xml,v 1.269 2005/05/19 04:59:01 marka Exp $ -->
|
||||
<book>
|
||||
<title>BIND 9 Administrator Reference Manual</title>
|
||||
|
||||
|
|
@ -4307,7 +4307,9 @@ category notify { null; };
|
|||
<optional> forwarders { <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; ... </optional> }; </optional>
|
||||
<optional> dual-stack-servers <optional>port <replaceable>ip_port</replaceable></optional> { ( <replaceable>domain_name</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> | <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ) ; ... }; </optional>
|
||||
<optional> check-names ( <replaceable>master</replaceable> | <replaceable>slave</replaceable> | <replaceable>response</replaceable> )( <replaceable>warn</replaceable> | <replaceable>fail</replaceable> | <replaceable>ignore</replaceable> ); </optional>
|
||||
<optional> check-mx ( <replaceable>warn</replaceable> | <replaceable>fail</replaceable> | <replaceable>ignore</replaceable> ); </optional>
|
||||
<optional> check-wildcard <replaceable>yes_or_no</replaceable>; </optional>
|
||||
<optional> integrity-checks <replaceable>yes_or_no</replaceable>; </optional>
|
||||
<optional> allow-notify { <replaceable>address_match_list</replaceable> }; </optional>
|
||||
<optional> allow-query { <replaceable>address_match_list</replaceable> }; </optional>
|
||||
<optional> allow-query-cache { <replaceable>address_match_list</replaceable> }; </optional>
|
||||
|
|
@ -5423,6 +5425,18 @@ options {
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>check-mx</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Check whether the MX record appears to refer to a IP address.
|
||||
The default is to <command>warn</command>. Other possible
|
||||
values are <command>fail</command> and
|
||||
<command>ignore</command>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>check-wildcard</command></term>
|
||||
<listitem>
|
||||
|
|
@ -5438,6 +5452,24 @@ options {
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>integrity-check</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Perform post load zone integrity checks on master
|
||||
zones. This checks that MX and SRV records refer
|
||||
to address (A or AAAA) records and that glue
|
||||
address records exist for delegated zones. For
|
||||
MX and SRV records only in-zone hostnames are
|
||||
checked (for out-of-zone hostnames use named-checkzone).
|
||||
For NS records only names below top of zone are
|
||||
checked (for out-of-zone names and glue consistancy
|
||||
checks use named-checkzone). The default is
|
||||
<command>yes</command>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</sect3>
|
||||
|
|
@ -7497,7 +7529,9 @@ view "external" {
|
|||
<optional> allow-update-forwarding { <replaceable>address_match_list</replaceable> } ; </optional>
|
||||
<optional> also-notify { <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; <optional> <replaceable>ip_addr</replaceable> <optional>port <replaceable>ip_port</replaceable></optional> ; ... </optional> }; </optional>
|
||||
<optional> check-names (<constant>warn</constant>|<constant>fail</constant>|<constant>ignore</constant>) ; </optional>
|
||||
<optional> check-mx (<constant>warn</constant>|<constant>fail</constant>|<constant>ignore</constant>) ; </optional>
|
||||
<optional> check-wildcard <replaceable>yes_or_no</replaceable>; </optional>
|
||||
<optional> integrity-checks <replaceable>yes_or_no</replaceable> ; </optional>
|
||||
<optional> dialup <replaceable>dialup_option</replaceable> ; </optional>
|
||||
<optional> delegation-only <replaceable>yes_or_no</replaceable> ; </optional>
|
||||
<optional> file <replaceable>string</replaceable> ; </optional>
|
||||
|
|
@ -7884,6 +7918,16 @@ view "external" {
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>check-mx</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
See the description of
|
||||
<command>check-mx</command> in <xref linkend="boolean_options"/>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>check-wildcard</command></term>
|
||||
<listitem>
|
||||
|
|
@ -7894,6 +7938,16 @@ view "external" {
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>integrity-check</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
See the description of
|
||||
<command>integrity-check</command> in <xref linkend="boolean_options"/>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>database</command></term>
|
||||
<listitem>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: check.c,v 1.57 2005/04/27 04:56:43 sra Exp $ */
|
||||
/* $Id: check.c,v 1.58 2005/05/19 04:59:02 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
|
|
@ -799,6 +799,8 @@ check_zoneconf(cfg_obj_t *zconfig, cfg_obj_t *voptions, cfg_obj_t *config,
|
|||
{ "database", MASTERZONE | SLAVEZONE | STUBZONE },
|
||||
{ "key-directory", MASTERZONE },
|
||||
{ "check-wildcard", MASTERZONE },
|
||||
{ "check-mx", MASTERZONE },
|
||||
{ "integrity-check", MASTERZONE },
|
||||
};
|
||||
|
||||
static optionstable dialups[] = {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: master.h,v 1.42 2005/04/27 04:56:56 sra Exp $ */
|
||||
/* $Id: master.h,v 1.43 2005/05/19 04:59:04 marka Exp $ */
|
||||
|
||||
#ifndef DNS_MASTER_H
|
||||
#define DNS_MASTER_H 1
|
||||
|
|
@ -52,6 +52,8 @@
|
|||
#define DNS_MASTER_CHECKNAMES 0x00000100
|
||||
#define DNS_MASTER_CHECKNAMESFAIL 0x00000200
|
||||
#define DNS_MASTER_CHECKWILDCARD 0x00000400 /* Check for internal wildcards. */
|
||||
#define DNS_MASTER_CHECKMX 0x00000800
|
||||
#define DNS_MASTER_CHECKMXFAIL 0x00001000
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: name.h,v 1.115 2005/04/27 04:56:57 sra Exp $ */
|
||||
/* $Id: name.h,v 1.116 2005/05/19 04:59:04 marka Exp $ */
|
||||
|
||||
#ifndef DNS_NAME_H
|
||||
#define DNS_NAME_H 1
|
||||
|
|
@ -145,6 +145,8 @@ struct dns_name {
|
|||
#define DNS_NAME_CHECKNAMES 0x0002 /*%< Used by rdata. */
|
||||
#define DNS_NAME_CHECKNAMESFAIL 0x0004 /*%< Used by rdata. */
|
||||
#define DNS_NAME_CHECKREVERSE 0x0008 /*%< Used by rdata. */
|
||||
#define DNS_NAME_CHECKMX 0x0010 /*%< Used by rdata. */
|
||||
#define DNS_NAME_CHECKMXFAIL 0x0020 /*%< Used by rdata. */
|
||||
|
||||
LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_rootname;
|
||||
LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_wildcardname;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rdata.h,v 1.62 2005/04/29 00:23:01 marka Exp $ */
|
||||
/* $Id: rdata.h,v 1.63 2005/05/19 04:59:04 marka Exp $ */
|
||||
|
||||
#ifndef DNS_RDATA_H
|
||||
#define DNS_RDATA_H 1
|
||||
|
|
@ -143,6 +143,8 @@ struct dns_rdata {
|
|||
#define DNS_RDATA_CHECKNAMES DNS_NAME_CHECKNAMES
|
||||
#define DNS_RDATA_CHECKNAMESFAIL DNS_NAME_CHECKNAMESFAIL
|
||||
#define DNS_RDATA_CHECKREVERSE DNS_NAME_CHECKREVERSE
|
||||
#define DNS_RDATA_CHECKMX DNS_NAME_CHECKMX
|
||||
#define DNS_RDATA_CHECKMXFAIL DNS_NAME_CHECKMXFAIL
|
||||
|
||||
/***
|
||||
*** Initialization
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: result.h,v 1.108 2005/04/29 00:23:02 marka Exp $ */
|
||||
/* $Id: result.h,v 1.109 2005/05/19 04:59:04 marka Exp $ */
|
||||
|
||||
#ifndef DNS_RESULT_H
|
||||
#define DNS_RESULT_H 1
|
||||
|
|
@ -145,8 +145,9 @@
|
|||
#define DNS_R_UNKNOWNCOMMAND (ISC_RESULTCLASS_DNS + 99)
|
||||
#define DNS_R_MUSTBESECURE (ISC_RESULTCLASS_DNS + 100)
|
||||
#define DNS_R_COVERINGNSEC (ISC_RESULTCLASS_DNS + 101)
|
||||
#define DNS_R_MXISADDRESS (ISC_RESULTCLASS_DNS + 102)
|
||||
|
||||
#define DNS_R_NRESULTS 102 /*%< Number of results */
|
||||
#define DNS_R_NRESULTS 103 /*%< Number of results */
|
||||
|
||||
/*
|
||||
* DNS wire format rcodes.
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: types.h,v 1.114 2005/04/27 04:57:00 sra Exp $ */
|
||||
/* $Id: types.h,v 1.115 2005/05/19 04:59:04 marka Exp $ */
|
||||
|
||||
#ifndef DNS_TYPES_H
|
||||
#define DNS_TYPES_H 1
|
||||
|
|
@ -298,7 +298,17 @@ typedef void
|
|||
(*dns_updatecallback_t)(void *, isc_result_t, dns_message_t *);
|
||||
|
||||
typedef int
|
||||
(*dns_rdatasetorderfunc_t)(dns_rdata_t *rdata, void *arg);
|
||||
(*dns_rdatasetorderfunc_t)(dns_rdata_t *, void *);
|
||||
|
||||
typedef isc_boolean_t
|
||||
(*dns_checkmxfunc_t)(dns_zone_t *, dns_name_t *, dns_name_t *);
|
||||
|
||||
typedef isc_boolean_t
|
||||
(*dns_checksrvfunc_t)(dns_zone_t *, dns_name_t *, dns_name_t *);
|
||||
|
||||
typedef isc_boolean_t
|
||||
(*dns_checknsfunc_t)(dns_zone_t *, dns_name_t *, dns_name_t *,
|
||||
dns_rdataset_t *, dns_rdataset_t *);
|
||||
|
||||
typedef isc_boolean_t
|
||||
(*dns_isselffunc_t)(dns_view_t *, dns_tsigkey_t *, isc_sockaddr_t *,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: zone.h,v 1.133 2005/04/27 04:57:01 sra Exp $ */
|
||||
/* $Id: zone.h,v 1.134 2005/05/19 04:59:05 marka Exp $ */
|
||||
|
||||
#ifndef DNS_ZONE_H
|
||||
#define DNS_ZONE_H 1
|
||||
|
|
@ -55,6 +55,9 @@ typedef enum {
|
|||
#define DNS_ZONEOPT_CHECKNAMES 0x00000800U /*%< check-names */
|
||||
#define DNS_ZONEOPT_CHECKNAMESFAIL 0x00001000U /*%< fatal check-name failures */
|
||||
#define DNS_ZONEOPT_CHECKWILDCARD 0x00002000U /*%< check for internal wildcards */
|
||||
#define DNS_ZONEOPT_CHECKMX 0x00004000U /*%< check-mx */
|
||||
#define DNS_ZONEOPT_CHECKMXFAIL 0x00008000U /*%< fatal check-mx failures */
|
||||
#define DNS_ZONEOPT_INTEGRITYCHECK 0x00010000U /*%< perform integrity checks */
|
||||
|
||||
#ifndef NOMINUM_PUBLIC
|
||||
/*
|
||||
|
|
@ -1448,6 +1451,36 @@ dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache);
|
|||
* 'zone' will have a reference to 'acache'
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx);
|
||||
/*
|
||||
* Set the post load integrity callback function 'checkmx'.
|
||||
* 'checkmx' will be called if the MX is not within the zone.
|
||||
*
|
||||
* Require:
|
||||
* 'zone' to be a valid zone.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setchecksrv(dns_zone_t *zone, dns_checkmxfunc_t checksrv);
|
||||
/*
|
||||
* Set the post load integrity callback function 'checksrv'.
|
||||
* 'checksrv' will be called if the SRV TARGET is not within the zone.
|
||||
*
|
||||
* Require:
|
||||
* 'zone' to be a valid zone.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns);
|
||||
/*
|
||||
* Set the post load integrity callback function 'checkmx'.
|
||||
* 'checkmx' will be called if the MX is not within the zone.
|
||||
*
|
||||
* Require:
|
||||
* 'zone' to be a valid zone.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay);
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: master.c,v 1.152 2005/04/27 04:56:47 sra Exp $ */
|
||||
/* $Id: master.c,v 1.153 2005/05/19 04:59:02 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
|
|
@ -959,11 +959,16 @@ load(dns_loadctx_t *lctx) {
|
|||
options |= DNS_RDATA_CHECKNAMES;
|
||||
if ((lctx->options & DNS_MASTER_CHECKNAMESFAIL) != 0)
|
||||
options |= DNS_RDATA_CHECKNAMESFAIL;
|
||||
if ((lctx->options & DNS_MASTER_CHECKMX) != 0)
|
||||
options |= DNS_RDATA_CHECKMX;
|
||||
if ((lctx->options & DNS_MASTER_CHECKMXFAIL) != 0)
|
||||
options |= DNS_RDATA_CHECKMXFAIL;
|
||||
source = isc_lex_getsourcename(lctx->lex);
|
||||
do {
|
||||
initialws = ISC_FALSE;
|
||||
line = isc_lex_getsourceline(lctx->lex);
|
||||
GETTOKEN(lctx->lex, ISC_LEXOPT_INITIALWS, &token, ISC_TRUE);
|
||||
GETTOKEN(lctx->lex, ISC_LEXOPT_INITIALWS | ISC_LEXOPT_QSTRING,
|
||||
&token, ISC_TRUE);
|
||||
line = isc_lex_getsourceline(lctx->lex);
|
||||
|
||||
if (token.type == isc_tokentype_eof) {
|
||||
|
|
@ -999,7 +1004,8 @@ load(dns_loadctx_t *lctx) {
|
|||
* Still working on the same name.
|
||||
*/
|
||||
initialws = ISC_TRUE;
|
||||
} else if (token.type == isc_tokentype_string) {
|
||||
} else if (token.type == isc_tokentype_string ||
|
||||
token.type == isc_tokentype_qstring) {
|
||||
|
||||
/*
|
||||
* "$" Support.
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rdata.c,v 1.188 2005/04/27 04:56:50 sra Exp $ */
|
||||
/* $Id: rdata.c,v 1.189 2005/05/19 04:59:03 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
|
|
@ -197,6 +197,10 @@ static void
|
|||
warn_badname(dns_name_t *name, isc_lex_t *lexer,
|
||||
dns_rdatacallbacks_t *callbacks);
|
||||
|
||||
static void
|
||||
warn_badmx(isc_token_t *token, isc_lex_t *lexer,
|
||||
dns_rdatacallbacks_t *callbacks);
|
||||
|
||||
static inline int
|
||||
getquad(const void *src, struct in_addr *dst,
|
||||
isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks)
|
||||
|
|
@ -1578,6 +1582,22 @@ fromtext_warneof(isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks) {
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
warn_badmx(isc_token_t *token, isc_lex_t *lexer,
|
||||
dns_rdatacallbacks_t *callbacks)
|
||||
{
|
||||
const char *file;
|
||||
unsigned long line;
|
||||
|
||||
if (lexer != NULL) {
|
||||
file = isc_lex_getsourcename(lexer);
|
||||
line = isc_lex_getsourceline(lexer);
|
||||
(*callbacks->warn)(callbacks, "%s:%u: warning: '%s': %s",
|
||||
file, line, DNS_AS_STR(*token),
|
||||
dns_result_totext(DNS_R_MXISADDRESS));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
warn_badname(dns_name_t *name, isc_lex_t *lexer,
|
||||
dns_rdatacallbacks_t *callbacks)
|
||||
|
|
|
|||
|
|
@ -15,15 +15,37 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: mx_15.c,v 1.52 2004/03/05 05:10:15 marka Exp $ */
|
||||
/* $Id: mx_15.c,v 1.53 2005/05/19 04:59:05 marka Exp $ */
|
||||
|
||||
/* reviewed: Wed Mar 15 18:05:46 PST 2000 by brister */
|
||||
|
||||
#ifndef RDATA_GENERIC_MX_15_C
|
||||
#define RDATA_GENERIC_MX_15_C
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/net.h>
|
||||
|
||||
#define RRTYPE_MX_ATTRIBUTES (0)
|
||||
|
||||
static isc_boolean_t
|
||||
check_mx(isc_token_t *token) {
|
||||
char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123.")];
|
||||
struct in_addr addr;
|
||||
struct in6_addr addr6;
|
||||
|
||||
if (strlcpy(tmp, DNS_AS_STR(*token), sizeof(tmp)) >= sizeof(tmp))
|
||||
return (ISC_TRUE);
|
||||
|
||||
if (tmp[strlen(tmp) - 1] == '.')
|
||||
tmp[strlen(tmp) - 1] = '\0';
|
||||
if (inet_aton(tmp, &addr) == 1 ||
|
||||
inet_pton(AF_INET6, tmp, &addr6) == 1)
|
||||
return (ISC_FALSE);
|
||||
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
static inline isc_result_t
|
||||
fromtext_mx(ARGS_FROMTEXT) {
|
||||
isc_token_t token;
|
||||
|
|
@ -45,6 +67,15 @@ fromtext_mx(ARGS_FROMTEXT) {
|
|||
|
||||
RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
|
||||
ISC_FALSE));
|
||||
|
||||
ok = ISC_TRUE;
|
||||
if ((options & DNS_RDATA_CHECKMX) != 0)
|
||||
ok = check_mx(&token);
|
||||
if (!ok && (options & DNS_RDATA_CHECKMXFAIL) != 0)
|
||||
RETTOK(DNS_R_MXISADDRESS);
|
||||
if (!ok && callbacks != NULL)
|
||||
warn_badmx(&token, lexer, callbacks);
|
||||
|
||||
dns_name_init(&name, NULL);
|
||||
buffer_fromregion(&buffer, &token.value.as_region);
|
||||
origin = (origin != NULL) ? origin : dns_rootname;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: result.c,v 1.119 2005/04/29 00:22:51 marka Exp $ */
|
||||
/* $Id: result.c,v 1.120 2005/05/19 04:59:03 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
|
|
@ -153,7 +153,8 @@ static const char *text[DNS_R_NRESULTS] = {
|
|||
"unknown command", /*%< 99 DNS_R_UNKNOWNCOMMAND */
|
||||
|
||||
"must-be-secure", /*%< 100 DNS_R_MUSTBESECURE */
|
||||
"covering NSEC record returned" /*%< 101 DNS_R_COVERINGNSEC */
|
||||
"covering NSEC record returned", /*%< 101 DNS_R_COVERINGNSEC */
|
||||
"MX is an address" /*%< 102 DNS_R_MXISADDRESS */
|
||||
};
|
||||
|
||||
static const char *rcode_text[DNS_R_NRCODERESULTS] = {
|
||||
|
|
|
|||
459
lib/dns/zone.c
459
lib/dns/zone.c
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: zone.c,v 1.433 2005/04/27 04:56:53 sra Exp $ */
|
||||
/* $Id: zone.c,v 1.434 2005/05/19 04:59:03 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
|
|
@ -38,6 +38,7 @@
|
|||
#include <dns/adb.h>
|
||||
#include <dns/callbacks.h>
|
||||
#include <dns/db.h>
|
||||
#include <dns/dbiterator.h>
|
||||
#include <dns/events.h>
|
||||
#include <dns/journal.h>
|
||||
#include <dns/log.h>
|
||||
|
|
@ -179,13 +180,13 @@ struct dns_zone {
|
|||
unsigned int notifycnt;
|
||||
isc_sockaddr_t notifyfrom;
|
||||
isc_task_t *task;
|
||||
isc_sockaddr_t notifysrc4;
|
||||
isc_sockaddr_t notifysrc6;
|
||||
isc_sockaddr_t xfrsource4;
|
||||
isc_sockaddr_t xfrsource6;
|
||||
isc_sockaddr_t altxfrsource4;
|
||||
isc_sockaddr_t altxfrsource6;
|
||||
isc_sockaddr_t sourceaddr;
|
||||
isc_sockaddr_t notifysrc4;
|
||||
isc_sockaddr_t notifysrc6;
|
||||
isc_sockaddr_t xfrsource4;
|
||||
isc_sockaddr_t xfrsource6;
|
||||
isc_sockaddr_t altxfrsource4;
|
||||
isc_sockaddr_t altxfrsource6;
|
||||
isc_sockaddr_t sourceaddr;
|
||||
dns_xfrin_ctx_t *xfr; /* task locked */
|
||||
dns_tsigkey_t *tsigkey; /* key used for xfr */
|
||||
/* Access Control Lists */
|
||||
|
|
@ -211,6 +212,9 @@ struct dns_zone {
|
|||
isc_uint32_t sigvalidityinterval;
|
||||
dns_view_t *view;
|
||||
dns_acache_t *acache;
|
||||
dns_checkmxfunc_t checkmx;
|
||||
dns_checksrvfunc_t checksrv;
|
||||
dns_checknsfunc_t checkns;
|
||||
/*%
|
||||
* Zones in certain states such as "waiting for zone transfer"
|
||||
* or "zone transfer in progress" are kept on per-state linked lists
|
||||
|
|
@ -586,6 +590,9 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
|
|||
zone->sigvalidityinterval = 30 * 24 * 3600;
|
||||
zone->view = NULL;
|
||||
zone->acache = NULL;
|
||||
zone->checkmx = NULL;
|
||||
zone->checksrv = NULL;
|
||||
zone->checkns = NULL;
|
||||
ISC_LINK_INIT(zone, statelink);
|
||||
zone->statelist = NULL;
|
||||
zone->counters = NULL;
|
||||
|
|
@ -1025,24 +1032,34 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Store the current time before the zone is loaded, so that if the
|
||||
* file changes between the time of the load and the time that
|
||||
* zone->loadtime is set, then the file will still be reloaded
|
||||
* the next time dns_zone_load is called.
|
||||
*/
|
||||
TIME_NOW(&loadtime);
|
||||
|
||||
/*
|
||||
* Don't do the load if the file that stores the zone is older
|
||||
* than the last time the zone was loaded. If the zone has not
|
||||
* been loaded yet, zone->loadtime will be the epoch.
|
||||
*/
|
||||
if (zone->masterfile != NULL && ! isc_time_isepoch(&zone->loadtime)) {
|
||||
if (zone->masterfile != NULL) {
|
||||
/*
|
||||
* The file is already loaded. If we are just doing a
|
||||
* "rndc reconfig", we are done.
|
||||
*/
|
||||
if ((flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
|
||||
if (!isc_time_isepoch(&zone->loadtime) &&
|
||||
(flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
|
||||
result = ISC_R_SUCCESS;
|
||||
goto cleanup;
|
||||
}
|
||||
if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE)) {
|
||||
result = isc_file_getmodtime(zone->masterfile,
|
||||
&filetime);
|
||||
if (result == ISC_R_SUCCESS &&
|
||||
|
||||
result = isc_file_getmodtime(zone->masterfile, &filetime);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) &&
|
||||
isc_time_compare(&filetime, &zone->loadtime) < 0) {
|
||||
dns_zone_log(zone, ISC_LOG_DEBUG(1),
|
||||
"skipping load: master file older "
|
||||
|
|
@ -1050,6 +1067,7 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
|
|||
result = DNS_R_UPTODATE;
|
||||
goto cleanup;
|
||||
}
|
||||
loadtime = filetime;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1073,14 +1091,6 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
|
|||
|
||||
dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");
|
||||
|
||||
/*
|
||||
* Store the current time before the zone is loaded, so that if the
|
||||
* file changes between the time of the load and the time that
|
||||
* zone->loadtime is set, then the file will still be reloaded
|
||||
* the next time dns_zone_load is called.
|
||||
*/
|
||||
TIME_NOW(&loadtime);
|
||||
|
||||
result = dns_db_create(zone->mctx, zone->db_argv[0],
|
||||
&zone->origin, (zone->type == dns_zone_stub) ?
|
||||
dns_dbtype_stub : dns_dbtype_zone,
|
||||
|
|
@ -1161,6 +1171,10 @@ zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
|
|||
options |= DNS_MASTER_CHECKNAMES;
|
||||
if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKNAMESFAIL))
|
||||
options |= DNS_MASTER_CHECKNAMESFAIL;
|
||||
if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKMX))
|
||||
options |= DNS_MASTER_CHECKMX;
|
||||
if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKMXFAIL))
|
||||
options |= DNS_MASTER_CHECKMXFAIL;
|
||||
if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKWILDCARD))
|
||||
options |= DNS_MASTER_CHECKWILDCARD;
|
||||
result = dns_master_loadfileinc(load->zone->masterfile,
|
||||
|
|
@ -1233,6 +1247,10 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
|
|||
options |= DNS_MASTER_CHECKNAMES;
|
||||
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
|
||||
options |= DNS_MASTER_CHECKNAMESFAIL;
|
||||
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
|
||||
options |= DNS_MASTER_CHECKMX;
|
||||
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
|
||||
options |= DNS_MASTER_CHECKMXFAIL;
|
||||
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
|
||||
options |= DNS_MASTER_CHECKWILDCARD;
|
||||
|
||||
|
|
@ -1293,6 +1311,375 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
|
|||
return (result);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
|
||||
dns_name_t *owner)
|
||||
{
|
||||
isc_result_t result;
|
||||
char ownerbuf[DNS_NAME_FORMATSIZE];
|
||||
char namebuf[DNS_NAME_FORMATSIZE];
|
||||
char altbuf[DNS_NAME_FORMATSIZE];
|
||||
dns_fixedname_t fixed;
|
||||
dns_name_t *foundname;
|
||||
int level;
|
||||
|
||||
/*
|
||||
* Outside of zone.
|
||||
*/
|
||||
if (!dns_name_issubdomain(name, &zone->origin)) {
|
||||
if (zone->checkmx != NULL)
|
||||
return ((zone->checkmx)(zone, name, owner));
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
if (zone->type == dns_zone_master)
|
||||
level = ISC_LOG_ERROR;
|
||||
else
|
||||
level = ISC_LOG_WARNING;
|
||||
|
||||
dns_fixedname_init(&fixed);
|
||||
foundname = dns_fixedname_name(&fixed);
|
||||
|
||||
result = dns_db_find(db, name, NULL, dns_rdatatype_a,
|
||||
0, 0, NULL, foundname, NULL, NULL);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
return (ISC_TRUE);
|
||||
|
||||
if (result == DNS_R_NXRRSET) {
|
||||
result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
|
||||
0, 0, NULL, foundname, NULL, NULL);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
dns_name_format(owner, ownerbuf, sizeof ownerbuf);
|
||||
dns_name_format(name, namebuf, sizeof namebuf);
|
||||
if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
|
||||
result == DNS_R_EMPTYNAME) {
|
||||
dns_zone_log(zone, level,
|
||||
"%s/MX '%s' has no address records (A or AAAA)",
|
||||
ownerbuf, namebuf);
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
if (result == DNS_R_CNAME) {
|
||||
dns_zone_log(zone, level, "%s/MX '%s' is a CNAME (illegal)",
|
||||
ownerbuf, namebuf);
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
if (result == DNS_R_DNAME) {
|
||||
dns_name_format(foundname, altbuf, sizeof altbuf);
|
||||
dns_zone_log(zone, level,
|
||||
"%s/MX '%s' is below a DNAME '%s' (illegal)",
|
||||
ownerbuf, namebuf, altbuf);
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
|
||||
return ((zone->checkmx)(zone, name, owner));
|
||||
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
|
||||
dns_name_t *owner)
|
||||
{
|
||||
isc_result_t result;
|
||||
char ownerbuf[DNS_NAME_FORMATSIZE];
|
||||
char namebuf[DNS_NAME_FORMATSIZE];
|
||||
char altbuf[DNS_NAME_FORMATSIZE];
|
||||
dns_fixedname_t fixed;
|
||||
dns_name_t *foundname;
|
||||
int level;
|
||||
|
||||
/*
|
||||
* Outside of zone.
|
||||
*/
|
||||
if (!dns_name_issubdomain(name, &zone->origin)) {
|
||||
if (zone->checksrv != NULL)
|
||||
return ((zone->checksrv)(zone, name, owner));
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
if (zone->type == dns_zone_master)
|
||||
level = ISC_LOG_ERROR;
|
||||
else
|
||||
level = ISC_LOG_WARNING;
|
||||
|
||||
dns_fixedname_init(&fixed);
|
||||
foundname = dns_fixedname_name(&fixed);
|
||||
|
||||
result = dns_db_find(db, name, NULL, dns_rdatatype_a,
|
||||
0, 0, NULL, foundname, NULL, NULL);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
return (ISC_TRUE);
|
||||
|
||||
if (result == DNS_R_NXRRSET) {
|
||||
result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
|
||||
0, 0, NULL, foundname, NULL, NULL);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
dns_name_format(owner, ownerbuf, sizeof ownerbuf);
|
||||
dns_name_format(name, namebuf, sizeof namebuf);
|
||||
if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
|
||||
result == DNS_R_EMPTYNAME) {
|
||||
dns_zone_log(zone, level,
|
||||
"%s/SRV '%s' has no address records (A or AAAA)",
|
||||
ownerbuf, namebuf);
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
if (result == DNS_R_CNAME) {
|
||||
dns_zone_log(zone, level, "%s/SRV '%s' is a CNAME (illegal)",
|
||||
ownerbuf, namebuf);
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
if (result == DNS_R_DNAME) {
|
||||
dns_name_format(foundname, altbuf, sizeof altbuf);
|
||||
dns_zone_log(zone, level,
|
||||
"%s/SRV '%s' is below a DNAME '%s' (illegal)",
|
||||
ownerbuf, namebuf, altbuf);
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
|
||||
return ((zone->checksrv)(zone, name, owner));
|
||||
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
|
||||
dns_name_t *owner)
|
||||
{
|
||||
isc_boolean_t answer = ISC_TRUE;
|
||||
isc_result_t result, tresult;
|
||||
char ownerbuf[DNS_NAME_FORMATSIZE];
|
||||
char namebuf[DNS_NAME_FORMATSIZE];
|
||||
char altbuf[DNS_NAME_FORMATSIZE];
|
||||
dns_fixedname_t fixed;
|
||||
dns_name_t *foundname;
|
||||
dns_rdataset_t a;
|
||||
dns_rdataset_t aaaa;
|
||||
int level;
|
||||
|
||||
/*
|
||||
* Outside of zone.
|
||||
*/
|
||||
if (!dns_name_issubdomain(name, &zone->origin)) {
|
||||
if (zone->checkns != NULL)
|
||||
return ((zone->checkns)(zone, name, owner, NULL, NULL));
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
if (zone->type == dns_zone_master)
|
||||
level = ISC_LOG_ERROR;
|
||||
else
|
||||
level = ISC_LOG_WARNING;
|
||||
|
||||
dns_fixedname_init(&fixed);
|
||||
foundname = dns_fixedname_name(&fixed);
|
||||
dns_rdataset_init(&a);
|
||||
dns_rdataset_init(&aaaa);
|
||||
|
||||
result = dns_db_find(db, name, NULL, dns_rdatatype_a,
|
||||
DNS_DBFIND_GLUEOK, 0, NULL,
|
||||
foundname, &a, NULL);
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
dns_rdataset_disassociate(&a);
|
||||
return (ISC_TRUE);
|
||||
} else if (result == DNS_R_DELEGATION)
|
||||
dns_rdataset_disassociate(&a);
|
||||
|
||||
if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
|
||||
result == DNS_R_GLUE) {
|
||||
tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
|
||||
DNS_DBFIND_GLUEOK, 0, NULL,
|
||||
foundname, &aaaa, NULL);
|
||||
if (tresult == ISC_R_SUCCESS) {
|
||||
dns_rdataset_disassociate(&aaaa);
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
if (tresult == DNS_R_DELEGATION)
|
||||
dns_rdataset_disassociate(&aaaa);
|
||||
if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
|
||||
/*
|
||||
* Check glue against child zone.
|
||||
*/
|
||||
if (zone->checkns != NULL)
|
||||
answer = (zone->checkns)(zone, name, owner,
|
||||
&a, &aaaa);
|
||||
if (dns_rdataset_isassociated(&a))
|
||||
dns_rdataset_disassociate(&a);
|
||||
if (dns_rdataset_isassociated(&aaaa))
|
||||
dns_rdataset_disassociate(&aaaa);
|
||||
return (answer);
|
||||
}
|
||||
} else
|
||||
tresult = result;
|
||||
|
||||
dns_name_format(owner, ownerbuf, sizeof ownerbuf);
|
||||
dns_name_format(name, namebuf, sizeof namebuf);
|
||||
if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
|
||||
result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
|
||||
const char *what;
|
||||
if (dns_name_issubdomain(name, owner))
|
||||
what = "REQUIRED GLUE ";
|
||||
else if (result == DNS_R_DELEGATION)
|
||||
what = "SIBLING GLUE ";
|
||||
else
|
||||
what = "";
|
||||
dns_zone_log(zone, level,
|
||||
"%s/NS '%s' has no %saddress records (A or AAAA)",
|
||||
ownerbuf, namebuf, what);
|
||||
/*
|
||||
* Log missing address record.
|
||||
*/
|
||||
if (result == DNS_R_DELEGATION && zone->checkns != NULL)
|
||||
answer = (zone->checkns)(zone, name, owner, &a, &aaaa);
|
||||
answer = ISC_FALSE;
|
||||
} else if (result == DNS_R_CNAME) {
|
||||
dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
|
||||
ownerbuf, namebuf);
|
||||
answer = ISC_FALSE;
|
||||
} else if (result == DNS_R_DNAME) {
|
||||
dns_name_format(foundname, altbuf, sizeof altbuf);
|
||||
dns_zone_log(zone, level,
|
||||
"%s/NS '%s' is below a DNAME '%s' (illegal)",
|
||||
ownerbuf, namebuf, altbuf);
|
||||
answer = ISC_FALSE;
|
||||
}
|
||||
|
||||
if (dns_rdataset_isassociated(&a))
|
||||
dns_rdataset_disassociate(&a);
|
||||
if (dns_rdataset_isassociated(&aaaa))
|
||||
dns_rdataset_disassociate(&aaaa);
|
||||
return (answer);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
integrity_checks(dns_zone_t *zone, dns_db_t *db) {
|
||||
dns_dbiterator_t *dbiterator = NULL;
|
||||
dns_dbnode_t *node = NULL;
|
||||
dns_rdataset_t rdataset;
|
||||
dns_fixedname_t fixed;
|
||||
dns_fixedname_t fixedbottom;
|
||||
dns_rdata_mx_t mx;
|
||||
dns_rdata_ns_t ns;
|
||||
dns_rdata_in_srv_t srv;
|
||||
dns_rdata_t rdata;
|
||||
dns_name_t *name;
|
||||
dns_name_t *bottom;
|
||||
isc_result_t result;
|
||||
isc_boolean_t ok = ISC_TRUE;
|
||||
|
||||
dns_fixedname_init(&fixed);
|
||||
name = dns_fixedname_name(&fixed);
|
||||
dns_fixedname_init(&fixedbottom);
|
||||
bottom = dns_fixedname_name(&fixedbottom);
|
||||
dns_rdataset_init(&rdataset);
|
||||
dns_rdata_init(&rdata);
|
||||
|
||||
result = dns_db_createiterator(db, ISC_FALSE, &dbiterator);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (ISC_TRUE);
|
||||
|
||||
result = dns_dbiterator_first(dbiterator);
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
result = dns_dbiterator_current(dbiterator, &node, name);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
/*
|
||||
* Is this name visible in the zone?
|
||||
*/
|
||||
if (!dns_name_issubdomain(name, &zone->origin) ||
|
||||
(dns_name_countlabels(bottom) > 0 &&
|
||||
dns_name_issubdomain(name, bottom)))
|
||||
goto next;
|
||||
|
||||
/*
|
||||
* Don't check the NS records at the origin.
|
||||
*/
|
||||
if (dns_name_equal(name, &zone->origin))
|
||||
goto checkmx;
|
||||
|
||||
result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
|
||||
0, 0, &rdataset, NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto checkmx;
|
||||
/*
|
||||
* Remember bottom of zone.
|
||||
*/
|
||||
dns_name_dup(name, NULL, bottom);
|
||||
|
||||
result = dns_rdataset_first(&rdataset);
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
dns_rdataset_current(&rdataset, &rdata);
|
||||
result = dns_rdata_tostruct(&rdata, &ns, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
if (!zone_check_glue(zone, db, &ns.name, name))
|
||||
ok = ISC_FALSE;
|
||||
dns_rdata_reset(&rdata);
|
||||
result = dns_rdataset_next(&rdataset);
|
||||
}
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
|
||||
checkmx:
|
||||
result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
|
||||
0, 0, &rdataset, NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto checksrv;
|
||||
result = dns_rdataset_first(&rdataset);
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
dns_rdataset_current(&rdataset, &rdata);
|
||||
result = dns_rdata_tostruct(&rdata, &mx, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
if (!zone_check_mx(zone, db, &mx.mx, name))
|
||||
ok = ISC_FALSE;
|
||||
dns_rdata_reset(&rdata);
|
||||
result = dns_rdataset_next(&rdataset);
|
||||
}
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
|
||||
checksrv:
|
||||
if (zone->rdclass != dns_rdataclass_in)
|
||||
goto next;
|
||||
result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
|
||||
0, 0, &rdataset, NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto next;
|
||||
result = dns_rdataset_first(&rdataset);
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
dns_rdataset_current(&rdataset, &rdata);
|
||||
result = dns_rdata_tostruct(&rdata, &srv, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
if (!zone_check_srv(zone, db, &srv.target, name))
|
||||
ok = ISC_FALSE;
|
||||
dns_rdata_reset(&rdata);
|
||||
result = dns_rdataset_next(&rdataset);
|
||||
}
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
|
||||
next:
|
||||
dns_db_detachnode(db, &node);
|
||||
result = dns_dbiterator_next(dbiterator);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (node != NULL)
|
||||
dns_db_detachnode(db, &node);
|
||||
dns_dbiterator_destroy(&dbiterator);
|
||||
|
||||
return (ok);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
|
||||
isc_result_t result)
|
||||
|
|
@ -1410,6 +1797,13 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
|
|||
result = DNS_R_BADZONE;
|
||||
goto cleanup;
|
||||
}
|
||||
if (zone->type == dns_zone_master &&
|
||||
DNS_ZONE_OPTION(zone, DNS_ZONEOPT_INTEGRITYCHECK) &&
|
||||
!integrity_checks(zone, db)) {
|
||||
result = DNS_R_BADZONE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (zone->db != NULL) {
|
||||
if (!isc_serial_ge(serial, zone->serial)) {
|
||||
dns_zone_log(zone, ISC_LOG_ERROR,
|
||||
|
|
@ -1555,7 +1949,8 @@ zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name) {
|
|||
}
|
||||
|
||||
dns_name_format(name, namebuf, sizeof namebuf);
|
||||
if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN) {
|
||||
if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
|
||||
result == DNS_R_EMPTYNAME) {
|
||||
dns_zone_log(zone, level,
|
||||
"NS '%s' has no address records (A or AAAA)",
|
||||
namebuf);
|
||||
|
|
@ -7062,6 +7457,24 @@ dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
|
|||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
zone->checkmx = checkmx;
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
zone->checksrv = checksrv;
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
zone->checkns = checkns;
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: namedconf.c,v 1.49 2005/05/12 04:38:23 marka Exp $ */
|
||||
/* $Id: namedconf.c,v 1.50 2005/05/19 04:59:05 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
|
|
@ -793,6 +793,8 @@ zone_clauses[] = {
|
|||
{ "zone-statistics", &cfg_type_boolean, 0 },
|
||||
{ "key-directory", &cfg_type_qstring, 0 },
|
||||
{ "check-wildcard", &cfg_type_boolean, 0 },
|
||||
{ "integrity-check", &cfg_type_boolean, 0 },
|
||||
{ "check-mx", &cfg_type_checkmode, 0 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue