From: Alessio Podda Date: Wed, 22 Jul 2026 13:43:18 +0000 (+0200) Subject: Return wildcard names instead of synthetized names in dns_db_find() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bdcd4338aef7095186973035c5d01ff8d932d3a8;p=thirdparty%2Fbind9.git Return wildcard names instead of synthetized names in dns_db_find() Previously dns_db_find() would return the synthetized name on a wildcard match. This is insufficient, as sometimes query processing requires the wildcard name instead of the synthetized name. This commit modifies the dns_db_find() API to return the wildcard name instead of the synthetized name, and adds helper functions to query.c to derive the synthetized name if needed. --- diff --git a/lib/dns/qpzone.c b/lib/dns/qpzone.c index 23749db8b3f..9f55e51c480 100644 --- a/lib/dns/qpzone.c +++ b/lib/dns/qpzone.c @@ -3560,7 +3560,7 @@ qpzone_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version, */ result = find_wildcard(&search, &node, name, nspace); if (result == ISC_R_SUCCESS) { - dns_name_copy(name, foundname); + dns_name_copy(&node->name, foundname); wild = true; goto found; } else if (result != ISC_R_NOTFOUND) { @@ -3827,6 +3827,9 @@ found: * * Return the delegation. */ + if (wild) { + foundname->attributes.wildcard = true; + } NODE_UNLOCK(nlock, &nlocktype); result = qpzone_setup_delegation( &search, nodep, foundname, rdataset, diff --git a/lib/dns/sdlz.c b/lib/dns/sdlz.c index 49290aedff5..198967f738b 100644 --- a/lib/dns/sdlz.c +++ b/lib/dns/sdlz.c @@ -479,6 +479,9 @@ getnodedata(dns_db_t *db, const dns_name_t *name, bool create, char zonestr[DNS_NAME_MAXTEXT + 1]; bool isorigin; dns_sdlzauthorityfunc_t authority; + dns_fixedname_t wildfixed; + dns_name_t *wildname = dns_fixedname_initname(&wildfixed); + const dns_name_t *nodename = name; REQUIRE(VALID_SDLZDB(sdlz)); REQUIRE(nodep != NULL && *nodep == NULL); @@ -572,6 +575,12 @@ getnodedata(dns_db_t *db, const dns_name_t *name, bool create, zonestr, wildstr, sdlz->dlzimp->driverarg, sdlz->dbdata, node, methods, clientinfo); if (result == ISC_R_SUCCESS) { + result = dns_name_concatenate( + wild, &sdlz->common.origin, wildname); + if (result != ISC_R_SUCCESS) { + break; + } + nodename = wildname; break; } } @@ -603,7 +612,7 @@ getnodedata(dns_db_t *db, const dns_name_t *name, bool create, } if (!dns_name_dynamic(&node->name)) { - dns_name_dup(name, sdlz->common.mctx, &node->name); + dns_name_dup(nodename, sdlz->common.mctx, &node->name); } *nodep = (dns_dbnode_t *)node; @@ -902,7 +911,19 @@ find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version, } if (foundname != NULL) { - dns_name_copy(xname, foundname); + if (node != NULL) { + dns_sdlznode_t *sdlznode = (dns_sdlznode_t *)node; + + dns_name_copy(&sdlznode->name, foundname); + if (dns_name_iswildcard(&sdlznode->name) && + !dns_name_equal(name, &sdlznode->name) && + dns_name_matcheswildcard(name, &sdlznode->name)) + { + foundname->attributes.wildcard = true; + } + } else { + dns_name_copy(xname, foundname); + } } if (nodep != NULL) { diff --git a/lib/ns/query.c b/lib/ns/query.c index 950b6c7cfbc..9f44f75765b 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -1555,6 +1555,16 @@ query_isduplicate(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type, return false; } +static void +query_fix_wildcardname(const dns_name_t *qname, dns_name_t *fname) { + if (fname->attributes.wildcard) { + dns_name_copy(qname, fname); + fname->attributes.wildcard = true; + } else { + fname->attributes.wildcard = false; + } +} + /* * Look up data for given 'name' and 'type' in given 'version' of 'db' for * 'client'. Called from query_additionalauth(). @@ -1872,6 +1882,7 @@ found: * We have found a potential additional data rdataset, or * at least a node to iterate over. */ + query_fix_wildcardname(name, fname); ns_client_keepname(client, fname, dbuf); /* @@ -4417,6 +4428,7 @@ redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, result = dns_db_findext(db, client->query.qname, dbversion->version, qtype, DNS_DBFIND_NOZONECUT, client->inner.now, &node, found, &cm, &ci, &trdataset, NULL); + query_fix_wildcardname(client->query.qname, found); if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) { dns_rdataset_cleanup(rdataset); dns_rdataset_cleanup(&trdataset); @@ -4555,6 +4567,7 @@ redirect2(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, result = dns_db_findext(db, redirectname, version, qtype, 0, client->inner.now, &node, found, &cm, &ci, &trdataset, NULL); + query_fix_wildcardname(redirectname, found); if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) { dns_rdataset_cleanup(rdataset); dns_rdataset_cleanup(&trdataset); @@ -5496,7 +5509,10 @@ query_lookup(query_ctx_t *qctx) { */ if (qctx->dns64 && qctx->rpz) { dns_name_copy(qctx->client->query.qname, qctx->fname); + qctx->fname->attributes.wildcard = false; dns_rdataset_cleanup(qctx->sigrdataset); + } else { + query_fix_wildcardname(rpzqname, qctx->fname); } if (!qctx->is_zone) { diff --git a/tests/dns/qpzone_test.c b/tests/dns/qpzone_test.c index 066f5921a53..e4a0306a168 100644 --- a/tests/dns/qpzone_test.c +++ b/tests/dns/qpzone_test.c @@ -453,6 +453,49 @@ ISC_RUN_TEST_IMPL(diffop_add_sub) { assert_null(db); } +ISC_RUN_TEST_IMPL(wildcard_foundname) { + static const unsigned char address[] = { 192, 0, 2, 1 }; + isc_result_t result; + dns_db_t *db = NULL; + dns_dbversion_t *version = NULL; + dns_dbnode_t *node = NULL; + dns_fixedname_t fqname, fwild, ffound; + dns_name_t *qname = NULL, *wild = NULL, *found = NULL; + dns_rdataset_t rdataset; + + result = dns__qpzone_create(isc_g_mctx, &example_org_name, + dns_dbtype_zone, dns_rdataclass_in, 0, NULL, + NULL, &db); + assert_int_equal(result, ISC_R_SUCCESS); + assert_non_null(db); + + dns_test_namefromstring("host.example.org.", &fqname); + dns_test_namefromstring("*.example.org.", &fwild); + qname = dns_fixedname_name(&fqname); + wild = dns_fixedname_name(&fwild); + found = dns_fixedname_initname(&ffound); + + WITH_NEWVERSION(db, newversion, true) { + apply_dns_update(db, newversion, wild, dns_rdatatype_a, + dns_rdataclass_in, 300, address, + sizeof(address), DNS_DIFFOP_ADD); + } + + dns_rdataset_init(&rdataset); + dns_db_currentversion(db, &version); + result = dns_db_find(db, qname, version, dns_rdatatype_a, 0, 0, &node, + found, &rdataset, NULL); + assert_int_equal(result, ISC_R_SUCCESS); + assert_true(dns_name_equal(found, wild)); + assert_true(found->attributes.wildcard); + + dns_rdataset_disassociate(&rdataset); + dns_db_detachnode(&node); + dns_db_closeversion(db, &version, false); + dns_db_detach(&db); + assert_null(db); +} + ISC_RUN_TEST_IMPL(diffop_addresign) { isc_result_t result; dns_db_t *db = NULL; @@ -521,6 +564,7 @@ ISC_TEST_ENTRY(ownercase) ISC_TEST_ENTRY(setownercase) ISC_TEST_ENTRY(resign_sooner_values) ISC_TEST_ENTRY(diffop_add_sub) +ISC_TEST_ENTRY(wildcard_foundname) ISC_TEST_ENTRY(diffop_addresign) ISC_TEST_LIST_END