diff options
Diffstat (limited to 'lib/dns/zone.c')
-rw-r--r-- | lib/dns/zone.c | 178 |
1 files changed, 87 insertions, 91 deletions
diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 01ff97b11dcbc..7a9825bd96b02 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -2639,8 +2639,8 @@ integrity_checks(dns_zone_t *zone, dns_db_t *db) { checkspf: /* - * Check if there is a type TXT spf record without a type SPF - * RRset being present. + * Check if there is a type SPF record without an + * SPF-formatted type TXT record also being present. */ if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF)) goto next; @@ -2669,16 +2669,13 @@ integrity_checks(dns_zone_t *zone, dns_db_t *db) { dns_rdataset_disassociate(&rdataset); notxt: - if (have_spf != have_txt) { + if (have_spf && !have_txt) { char namebuf[DNS_NAME_FORMATSIZE]; - const char *found = have_txt ? "TXT" : "SPF"; - const char *need = have_txt ? "SPF" : "TXT"; dns_name_format(name, namebuf, sizeof(namebuf)); - dns_zone_log(zone, ISC_LOG_WARNING, "'%s' found SPF/%s " - "record but no SPF/%s record found, add " - "matching type %s record", namebuf, found, - need, need); + dns_zone_log(zone, ISC_LOG_WARNING, "'%s' found type " + "SPF record but no SPF TXT record found, " + "add matching type TXT record", namebuf); } next: @@ -4567,6 +4564,21 @@ zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, dns_db_currentversion(db, &version); + if (nscount != NULL) + *nscount = 0; + if (soacount != NULL) + *soacount = 0; + if (serial != NULL) + *serial = 0; + if (refresh != NULL) + *refresh = 0; + if (retry != NULL) + *retry = 0; + if (expire != NULL) + *expire = 0; + if (errors != NULL) + *errors = 0; + node = NULL; result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) { @@ -8544,8 +8556,10 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) { trust_key(zone, keyname, &dnskey, mctx); } - if (!deletekey) + if (!deletekey) { + INSIST(newkey || updatekey); set_refreshkeytimer(zone, &keydata, now); + } } /* @@ -10933,70 +10947,25 @@ create_query(dns_zone_t *zone, dns_rdatatype_t rdtype, static isc_result_t add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) { - dns_rdataset_t *rdataset = NULL; - dns_rdatalist_t *rdatalist = NULL; - dns_rdata_t *rdata = NULL; isc_result_t result; - - result = dns_message_gettemprdatalist(message, &rdatalist); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_message_gettemprdata(message, &rdata); - if (result != ISC_R_SUCCESS) - goto cleanup; - result = dns_message_gettemprdataset(message, &rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; - dns_rdataset_init(rdataset); - - rdatalist->type = dns_rdatatype_opt; - rdatalist->covers = 0; - - /* - * Set Maximum UDP buffer size. - */ - rdatalist->rdclass = udpsize; - - /* - * Set EXTENDED-RCODE, VERSION, DO and Z to 0. - */ - rdatalist->ttl = 0; + dns_rdataset_t *rdataset = NULL; + dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS]; + int count = 0; /* Set EDNS options if applicable */ if (reqnsid) { - unsigned char data[4]; - isc_buffer_t buf; - - isc_buffer_init(&buf, data, sizeof(data)); - isc_buffer_putuint16(&buf, DNS_OPT_NSID); - isc_buffer_putuint16(&buf, 0); - rdata->data = data; - rdata->length = sizeof(data); - } else { - rdata->data = NULL; - rdata->length = 0; + INSIST(count < DNS_EDNSOPTIONS); + ednsopts[count].code = DNS_OPT_NSID; + ednsopts[count].length = 0; + ednsopts[count].value = NULL; + count++; } - - rdata->rdclass = rdatalist->rdclass; - rdata->type = rdatalist->type; - rdata->flags = 0; - - ISC_LIST_INIT(rdatalist->rdata); - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) - == ISC_R_SUCCESS); + result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0, + ednsopts, count); + if (result != ISC_R_SUCCESS) + return (result); return (dns_message_setopt(message, rdataset)); - - cleanup: - if (rdatalist != NULL) - dns_message_puttemprdatalist(message, &rdatalist); - if (rdataset != NULL) - dns_message_puttemprdataset(message, &rdataset); - if (rdata != NULL) - dns_message_puttemprdata(message, &rdata); - - return (result); } static void @@ -11846,6 +11815,8 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, int match = 0; isc_netaddr_t netaddr; isc_sockaddr_t local, remote; + dns_tsigkey_t *tsigkey; + dns_name_t *tsig; REQUIRE(DNS_ZONE_VALID(zone)); @@ -11930,8 +11901,10 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, * Accept notify requests from non masters if they are on * 'zone->notify_acl'. */ + tsigkey = dns_message_gettsigkey(msg); + tsig = dns_tsigkey_identity(tsigkey); if (i >= zone->masterscnt && zone->notify_acl != NULL && - dns_acl_match(&netaddr, NULL, zone->notify_acl, + dns_acl_match(&netaddr, tsig, zone->notify_acl, &zone->view->aclenv, &match, NULL) == ISC_R_SUCCESS && match > 0) @@ -13048,7 +13021,6 @@ save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) { isc_result_t result; dns_dbnode_t *node = NULL; dns_rdataset_t rdataset, prdataset; - dns_rdata_t rdata_in, prdata_in, prdata_out; dns_dbversion_t *version = NULL; nsec3param_t *nsec3param = NULL; nsec3param_t *nsec3p = NULL; @@ -13060,10 +13032,12 @@ save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) { REQUIRE(nsec3list != NULL); REQUIRE(ISC_LIST_EMPTY(*nsec3list)); + dns_rdataset_init(&rdataset); + dns_rdataset_init(&prdataset); + dns_db_attach(zone->db, &db); CHECK(dns_db_getoriginnode(db, &node)); - dns_rdataset_init(&rdataset); dns_db_currentversion(db, &version); result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3param, @@ -13082,8 +13056,10 @@ save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) { result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { - dns_rdata_init(&rdata_in); - dns_rdataset_current(&rdataset, &rdata_in); + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdata_t private = DNS_RDATA_INIT; + + dns_rdataset_current(&rdataset, &rdata); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), "looping through nsec3param data"); @@ -13096,16 +13072,14 @@ save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) { * now transfer the data from the rdata to * the nsec3param */ - dns_rdata_init(&prdata_out); - dns_nsec3param_toprivate(&rdata_in, &prdata_out, + dns_nsec3param_toprivate(&rdata, &private, zone->privatetype, nsec3param->data, sizeof(nsec3param->data)); - nsec3param->length = prdata_out.length; + nsec3param->length = private.length; ISC_LIST_APPEND(*nsec3list, nsec3param, link); } getprivate: - dns_rdataset_init(&prdataset); result = dns_db_findrdataset(db, node, version, zone->privatetype, dns_rdatatype_none, 0, &prdataset, NULL); if (result != ISC_R_SUCCESS) @@ -13120,26 +13094,39 @@ save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) { result == ISC_R_SUCCESS; result = dns_rdataset_next(&prdataset)) { - dns_rdata_init(&prdata_in); - dns_rdataset_current(&prdataset, &prdata_in); + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdata_t private = DNS_RDATA_INIT; + + dns_rdataset_current(&prdataset, &private); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), "looping through nsec3param private data"); - if (!dns_nsec3param_fromprivate(&prdata_in, &prdata_out, + /* + * Do we have a valid private record? + */ + if (!dns_nsec3param_fromprivate(&private, &rdata, buf, sizeof(buf))) continue; - if ((prdata_out.data[1] & DNS_NSEC3FLAG_REMOVE) !=0) { - prdata_out.data[1] = 0; + /* + * Remove any NSEC3PARAM records scheduled to be removed. + */ + if (NSEC3REMOVE(rdata.data[1])) { + /* + * Zero out the flags. + */ + rdata.data[1] = 0; for (nsec3p = ISC_LIST_HEAD(*nsec3list); nsec3p != NULL; nsec3p = next) { next = ISC_LIST_NEXT(nsec3p, link); - if (memcmp(prdata_out.data, nsec3p->data, - sizeof(nsec3p->data)) == 0) { + + if (nsec3p->length == rdata.length + 1 && + memcmp(rdata.data, nsec3p->data + 1, + nsec3p->length - 1) == 0) { ISC_LIST_UNLINK(*nsec3list, nsec3p, link); isc_mem_put(zone->mctx, nsec3p, @@ -13154,11 +13141,13 @@ save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) { CHECK(ISC_R_NOMEMORY); ISC_LINK_INIT(nsec3param, link); - dns_rdata_init(&prdata_out); - dns_nsec3param_toprivate(&prdata_in, &prdata_out, - zone->privatetype, nsec3param->data, - sizeof(nsec3param->data)); - nsec3param->length = prdata_out.length; + /* + * Copy the remaining private records so the nsec/nsec3 + * chain gets created. + */ + INSIST(private.length <= sizeof(nsec3param->data)); + memmove(nsec3param->data, private.data, private.length); + nsec3param->length = private.length; ISC_LIST_APPEND(*nsec3list, nsec3param, link); } @@ -13374,6 +13363,12 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) { dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s", dns_result_totext(result)); + while (!ISC_LIST_EMPTY(nsec3list)) { + nsec3param_t *nsec3p; + nsec3p = ISC_LIST_HEAD(nsec3list); + ISC_LIST_UNLINK(nsec3list, nsec3p, link); + isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t)); + } if (dns_rdataset_isassociated(&rdataset)) dns_rdataset_disassociate(&rdataset); if (db != NULL) { @@ -13493,7 +13488,6 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) { isc_uint32_t serial, oldserial; - unsigned int soacount; dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs"); @@ -15691,10 +15685,12 @@ dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) { REQUIRE(DNS_ZONE_VALID(zone)); - if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) + if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES) && + rdata->type != dns_rdatatype_nsec3) return (ISC_R_SUCCESS); - if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) { + if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL) || + rdata->type == dns_rdatatype_nsec3) { level = ISC_LOG_ERROR; fail = ISC_TRUE; } |