diff --git a/CHANGES b/CHANGES index 410ed2d3c7..ee9d0881b9 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +3164. [func] Enable DLZ modules to retrieve client information, + so that responses can be changed depending on the + source address of the query. [RT #25768] + 3163. [bug] Use finer-grained locking in client.c to address concurrency problems with large numbers of threads. [RT #26044] diff --git a/bin/named/client.c b/bin/named/client.c index c1485092dc..ae2fe3f2bb 100644 --- a/bin/named/client.c +++ b/bin/named/client.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: client.c,v 1.278 2011/10/10 22:57:13 each Exp $ */ +/* $Id: client.c,v 1.279 2011/10/11 00:09:01 each Exp $ */ #include @@ -2852,3 +2852,14 @@ ns_client_qnamereplace(ns_client_t *client, dns_name_t *name) { client->query.qname = name; UNLOCK(&client->query.fetchlock); } + +isc_result_t +ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp) { + ns_client_t *client = (ns_client_t *) ci->data; + + REQUIRE(NS_CLIENT_VALID(client)); + REQUIRE(addrp != NULL); + + *addrp = &client->peeraddr; + return (ISC_R_SUCCESS); +} diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h index 5724fa8ae2..4f689d56df 100644 --- a/bin/named/include/named/client.h +++ b/bin/named/include/named/client.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: client.h,v 1.92 2011/10/10 22:57:13 each Exp $ */ +/* $Id: client.h,v 1.93 2011/10/11 00:09:01 each Exp $ */ #ifndef NAMED_CLIENT_H #define NAMED_CLIENT_H 1 @@ -68,6 +68,7 @@ #include #include +#include #include #include #include @@ -376,4 +377,7 @@ ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey, * Isself callback. */ +isc_result_t +ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp); + #endif /* NAMED_CLIENT_H */ diff --git a/bin/named/query.c b/bin/named/query.c index 0a58d8b64c..b78b9e8d68 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: query.c,v 1.369 2011/09/02 23:46:31 tbox Exp $ */ +/* $Id: query.c,v 1.370 2011/10/11 00:09:01 each Exp $ */ /*! \file */ @@ -1164,6 +1164,8 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { isc_boolean_t added_something, need_addname; dns_zone_t *zone; dns_rdatatype_t type; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; REQUIRE(NS_CLIENT_VALID(client)); REQUIRE(qtype != dns_rdatatype_any); @@ -1188,6 +1190,9 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { need_addname = ISC_FALSE; zone = NULL; + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); + /* * We treat type A additional section processing as if it * were "any address type" additional section processing. @@ -1232,9 +1237,10 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { * necessarily in the same database. */ node = NULL; - result = dns_db_find(db, name, version, type, client->query.dboptions, - client->now, &node, fname, rdataset, - sigrdataset); + result = dns_db_findext(db, name, version, type, + client->query.dboptions, + client->now, &node, fname, &cm, &ci, + rdataset, sigrdataset); if (result == ISC_R_SUCCESS) { if (sigrdataset != NULL && !dns_db_issecure(db) && dns_rdataset_isassociated(sigrdataset)) @@ -1270,11 +1276,11 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { if (sigrdataset == NULL) goto cleanup; } - result = dns_db_find(db, name, version, type, - client->query.dboptions | - DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK, - client->now, &node, fname, rdataset, - sigrdataset); + result = dns_db_findext(db, name, version, type, + client->query.dboptions | + DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK, + client->now, &node, fname, &cm, &ci, + rdataset, sigrdataset); if (result == DNS_R_GLUE && validate(client, db, fname, rdataset, sigrdataset)) result = ISC_R_SUCCESS; @@ -1317,10 +1323,10 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { goto cleanup; dns_db_attach(client->query.gluedb, &db); - result = dns_db_find(db, name, version, type, - client->query.dboptions | DNS_DBFIND_GLUEOK, - client->now, &node, fname, rdataset, - sigrdataset); + result = dns_db_findext(db, name, version, type, + client->query.dboptions | DNS_DBFIND_GLUEOK, + client->now, &node, fname, &cm, &ci, + rdataset, sigrdataset); if (!(result == ISC_R_SUCCESS || result == DNS_R_ZONECUT || result == DNS_R_GLUE)) @@ -1387,8 +1393,8 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { } result = dns_db_findrdataset(db, node, version, dns_rdatatype_a, 0, - client->now, rdataset, - sigrdataset); + client->now, + rdataset, sigrdataset); if (result == DNS_R_NCACHENXDOMAIN) goto addname; if (result == DNS_R_NCACHENXRRSET) { @@ -1432,8 +1438,8 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { } result = dns_db_findrdataset(db, node, version, dns_rdatatype_aaaa, 0, - client->now, rdataset, - sigrdataset); + client->now, + rdataset, sigrdataset); if (result == DNS_R_NCACHENXDOMAIN) goto addname; if (result == DNS_R_NCACHENXRRSET) { @@ -1593,6 +1599,8 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { dns_zone_t *zone; dns_rdatatype_t type; dns_rdatasetadditional_t additionaltype; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; if (qtype != dns_rdatatype_a) { /* @@ -1627,6 +1635,8 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { POST(needadditionalcache); additionaltype = dns_rdatasetadditional_fromauth; dns_name_init(&cfname, NULL); + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); CTRACE("query_addadditional2"); @@ -1729,8 +1739,10 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { * necessarily in the same database. */ node = NULL; - result = dns_db_find(db, name, version, type, client->query.dboptions, - client->now, &node, fname, NULL, NULL); + result = dns_db_findext(db, name, version, type, + client->query.dboptions, + client->now, &node, fname, &cm, &ci, + NULL, NULL); if (result == ISC_R_SUCCESS) goto found; @@ -1757,10 +1769,11 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { */ goto try_glue; - result = dns_db_find(db, name, version, type, - client->query.dboptions | - DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK, - client->now, &node, fname, NULL, NULL); + result = dns_db_findext(db, name, version, type, + client->query.dboptions | + DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK, + client->now, &node, fname, &cm, &ci, + NULL, NULL); if (result == ISC_R_SUCCESS) goto found; @@ -1829,9 +1842,10 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { findglue: dns_db_attach(client->query.gluedb, &db); - result = dns_db_find(db, name, version, type, - client->query.dboptions | DNS_DBFIND_GLUEOK, - client->now, &node, fname, NULL, NULL); + result = dns_db_findext(db, name, version, type, + client->query.dboptions | DNS_DBFIND_GLUEOK, + client->now, &node, fname, &cm, &ci, + NULL, NULL); if (!(result == ISC_R_SUCCESS || result == DNS_R_ZONECUT || result == DNS_R_GLUE)) { @@ -2474,6 +2488,8 @@ query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version, isc_result_t result, eresult; dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; dns_rdataset_t **sigrdatasetp = NULL; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; CTRACE("query_addsoa"); /* @@ -2484,6 +2500,9 @@ query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version, rdataset = NULL; node = NULL; + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); + /* * Don't add the SOA record for test which set "-T nosoa". */ @@ -2517,9 +2536,8 @@ query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version, result = dns_db_getoriginnode(db, &node); if (result == ISC_R_SUCCESS) { result = dns_db_findrdataset(db, node, version, - dns_rdatatype_soa, - 0, client->now, rdataset, - sigrdataset); + dns_rdatatype_soa, 0, client->now, + rdataset, sigrdataset); } else { dns_fixedname_t foundname; dns_name_t *fname; @@ -2527,9 +2545,9 @@ query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version, dns_fixedname_init(&foundname); fname = dns_fixedname_name(&foundname); - result = dns_db_find(db, name, version, dns_rdatatype_soa, - client->query.dboptions, 0, &node, - fname, rdataset, sigrdataset); + result = dns_db_findext(db, name, version, dns_rdatatype_soa, + client->query.dboptions, 0, &node, + fname, &cm, &ci, rdataset, sigrdataset); } if (result != ISC_R_SUCCESS) { /* @@ -2594,6 +2612,8 @@ query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) { dns_fixedname_t foundname; dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; dns_rdataset_t **sigrdatasetp = NULL; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; CTRACE("query_addns"); /* @@ -2605,6 +2625,8 @@ query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) { node = NULL; dns_fixedname_init(&foundname); fname = dns_fixedname_name(&foundname); + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); /* * Get resources and make 'name' be the database origin. @@ -2637,14 +2659,13 @@ query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) { result = dns_db_getoriginnode(db, &node); if (result == ISC_R_SUCCESS) { result = dns_db_findrdataset(db, node, version, - dns_rdatatype_ns, - 0, client->now, rdataset, - sigrdataset); + dns_rdatatype_ns, 0, client->now, + rdataset, sigrdataset); } else { CTRACE("query_addns: calling dns_db_find"); - result = dns_db_find(db, name, NULL, dns_rdatatype_ns, - client->query.dboptions, 0, &node, - fname, rdataset, sigrdataset); + result = dns_db_findext(db, name, NULL, dns_rdatatype_ns, + client->query.dboptions, 0, &node, + fname, &cm, &ci, rdataset, sigrdataset); CTRACE("query_addns: dns_db_find complete"); } if (result != ISC_R_SUCCESS) { @@ -2766,14 +2787,18 @@ mark_secure(ns_client_t *client, dns_db_t *db, dns_name_t *name, { isc_result_t result; dns_dbnode_t *node = NULL; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; rdataset->trust = dns_trust_secure; sigrdataset->trust = dns_trust_secure; + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); /* * Save the updated secure state. Ignore failures. */ - result = dns_db_findnode(db, name, ISC_TRUE, &node); + result = dns_db_findnodeext(db, name, ISC_TRUE, &cm, &ci, &node); if (result != ISC_R_SUCCESS) return; /* @@ -2808,9 +2833,15 @@ get_key(ns_client_t *client, dns_db_t *db, dns_rdata_rrsig_t *rrsig, isc_result_t result; dns_dbnode_t *node = NULL; isc_boolean_t secure = ISC_FALSE; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; + + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); if (!dns_rdataset_isassociated(keyrdataset)) { - result = dns_db_findnode(db, &rrsig->signer, ISC_FALSE, &node); + result = dns_db_findnodeext(db, &rrsig->signer, ISC_FALSE, + &cm, &ci, &node); if (result != ISC_R_SUCCESS) return (ISC_FALSE); @@ -2936,6 +2967,8 @@ query_addbestns(ns_client_t *client) { dns_dbversion_t *version; dns_zone_t *zone; isc_buffer_t b; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; CTRACE("query_addbestns"); fname = NULL; @@ -2952,6 +2985,9 @@ query_addbestns(ns_client_t *client) { is_zone = ISC_FALSE; use_zone = ISC_FALSE; + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); + /* * Find the right database. */ @@ -2985,10 +3021,11 @@ query_addbestns(ns_client_t *client) { * Now look for the zonecut. */ if (is_zone) { - result = dns_db_find(db, client->query.qname, version, - dns_rdatatype_ns, client->query.dboptions, - client->now, &node, fname, - rdataset, sigrdataset); + result = dns_db_findext(db, client->query.qname, version, + dns_rdatatype_ns, + client->query.dboptions, + client->now, &node, fname, + &cm, &ci, rdataset, sigrdataset); if (result != DNS_R_DELEGATION) goto cleanup; if (USECACHE(client)) { @@ -3257,6 +3294,8 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db, int order; dns_fixedname_t cfixed; dns_name_t *cname; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; CTRACE("query_addwildcardproof"); fname = NULL; @@ -3264,6 +3303,9 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db, sigrdataset = NULL; node = NULL; + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); + /* * Get the NOQNAME proof then if !ispositive * get the NOWILDCARD proof. @@ -3323,8 +3365,9 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db, if (fname == NULL || rdataset == NULL || sigrdataset == NULL) goto cleanup; - result = dns_db_find(db, name, version, dns_rdatatype_nsec, options, - 0, &node, fname, rdataset, sigrdataset); + result = dns_db_findext(db, name, version, dns_rdatatype_nsec, + options, 0, &node, fname, &cm, &ci, + rdataset, sigrdataset); if (node != NULL) dns_db_detachnode(db, &node); @@ -3341,10 +3384,10 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db, while (result == DNS_R_NXDOMAIN) { labels = dns_name_countlabels(cname) - 1; dns_name_split(cname, labels, NULL, cname); - result = dns_db_find(db, cname, version, - dns_rdatatype_nsec, - options, 0, NULL, fname, - NULL, NULL); + result = dns_db_findext(db, cname, version, + dns_rdatatype_nsec, + options, 0, NULL, fname, + &cm, &ci, NULL, NULL); } /* * Add closest (provable) encloser NSEC3. @@ -3833,6 +3876,11 @@ rpz_ns_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type, dns_fixedname_t fixed; dns_name_t *found; isc_result_t result; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; + + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); st = client->query.rpz_st; if ((st->state & DNS_RPZ_RECURSING) != 0) { @@ -3888,8 +3936,8 @@ rpz_ns_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type, node = NULL; dns_fixedname_init(&fixed); found = dns_fixedname_name(&fixed); - result = dns_db_find(*dbp, name, version, type, 0, client->now, &node, - found, *rdatasetp, NULL); + result = dns_db_findext(*dbp, name, version, type, 0, client->now, + &node, found, &cm, &ci, *rdatasetp, NULL); if (result == DNS_R_DELEGATION && is_zone && USECACHE(client)) { /* * Try the cache if we're authoritative for an @@ -3898,9 +3946,9 @@ rpz_ns_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type, rpz_clean(NULL, dbp, &node, rdatasetp); version = NULL; dns_db_attach(client->view->cachedb, dbp); - result = dns_db_find(*dbp, name, version, dns_rdatatype_ns, - 0, client->now, &node, found, - *rdatasetp, NULL); + result = dns_db_findext(*dbp, name, version, dns_rdatatype_ns, + 0, client->now, &node, found, + &cm, &ci, *rdatasetp, NULL); } rpz_clean(NULL, dbp, &node, NULL); if (result == DNS_R_DELEGATION) { @@ -4021,6 +4069,11 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef, dns_fixedname_t fixed; dns_name_t *found; isc_result_t result; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; + + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); result = rpz_ready(client, zonep, dbp, nodep, rdatasetp); if (result != ISC_R_SUCCESS) { @@ -4041,8 +4094,9 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef, dns_fixedname_init(&fixed); found = dns_fixedname_name(&fixed); - result = dns_db_find(*dbp, qnamef, version, dns_rdatatype_any, 0, - client->now, nodep, found, *rdatasetp, NULL); + result = dns_db_findext(*dbp, qnamef, version, dns_rdatatype_any, 0, + client->now, nodep, found, &cm, &ci, + *rdatasetp, NULL); if (result == ISC_R_SUCCESS) { dns_rdatasetiter_t *rdsiter; @@ -4086,10 +4140,10 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef, qtype == dns_rdatatype_sig) result = DNS_R_NXRRSET; else - result = dns_db_find(*dbp, qnamef, version, - qtype, 0, client->now, - nodep, found, *rdatasetp, - NULL); + result = dns_db_findext(*dbp, qnamef, version, + qtype, 0, client->now, + nodep, found, &cm, &ci, + *rdatasetp, NULL); } } switch (result) { @@ -4773,6 +4827,8 @@ query_findclosestnsec3(dns_name_t *qname, dns_db_t *db, dns_rdata_nsec3_t nsec3; dns_rdata_t rdata = DNS_RDATA_INIT; isc_boolean_t optout; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; salt_length = sizeof(salt); result = dns_db_getnsec3parameters(db, version, &hash, NULL, @@ -4782,6 +4838,8 @@ query_findclosestnsec3(dns_name_t *qname, dns_db_t *db, dns_name_init(&name, NULL); dns_name_clone(qname, &name); + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); /* * Map unknown algorithm to known value. @@ -4798,9 +4856,9 @@ query_findclosestnsec3(dns_name_t *qname, dns_db_t *db, return; dboptions = client->query.dboptions | DNS_DBFIND_FORCENSEC3; - result = dns_db_find(db, dns_fixedname_name(&fixed), version, - dns_rdatatype_nsec3, dboptions, client->now, - NULL, fname, rdataset, sigrdataset); + result = dns_db_findext(db, dns_fixedname_name(&fixed), version, + dns_rdatatype_nsec3, dboptions, client->now, + NULL, fname, &cm, &ci, rdataset, sigrdataset); if (result == DNS_R_NXDOMAIN) { if (!dns_rdataset_isassociated(rdataset)) { @@ -4956,6 +5014,8 @@ redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, dns_rdataset_t trdataset; isc_result_t result; dns_rdatatype_t type; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; CTRACE("redirect"); @@ -4966,6 +5026,9 @@ redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, found = dns_fixedname_name(&fixed); dns_rdataset_init(&trdataset); + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); + if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp)) return (ISC_FALSE); @@ -5004,8 +5067,9 @@ redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, /* * Lookup the requested data in the redirect zone. */ - result = dns_db_find(db, client->query.qname, NULL, qtype, 0, - client->now, &node, found, &trdataset, NULL); + result = dns_db_findext(db, client->query.qname, NULL, qtype, 0, + client->now, &node, found, &cm, &ci, + &trdataset, NULL); if (result != ISC_R_SUCCESS) { if (dns_rdataset_isassociated(&trdataset)) dns_rdataset_disassociate(&trdataset); @@ -5075,6 +5139,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) isc_boolean_t resuming; int line = -1; isc_boolean_t dns64_exclude, dns64; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; CTRACE("query_find"); @@ -5106,6 +5172,9 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) is_zone = ISC_FALSE; is_staticstub_zone = ISC_FALSE; + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); + if (event != NULL) { /* * We're returning from recursion. Restore the query context @@ -5342,9 +5411,9 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) /* * Now look for an answer in the database. */ - result = dns_db_find(db, client->query.qname, version, type, - client->query.dboptions, client->now, - &node, fname, rdataset, sigrdataset); + result = dns_db_findext(db, client->query.qname, version, type, + client->query.dboptions, client->now, + &node, fname, &cm, &ci, rdataset, sigrdataset); resume: CTRACE("query_find: resume"); @@ -5488,10 +5557,11 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) result = ISC_R_FAILURE; } else { dns_db_attach(client->view->hints, &db); - result = dns_db_find(db, dns_rootname, - NULL, dns_rdatatype_ns, - 0, client->now, &node, fname, - rdataset, sigrdataset); + result = dns_db_findext(db, dns_rootname, + NULL, dns_rdatatype_ns, + 0, client->now, &node, + fname, &cm, &ci, + rdataset, sigrdataset); } if (result != ISC_R_SUCCESS) { /* @@ -6589,9 +6659,9 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) if (qtype == dns_rdatatype_aaaa) { trdataset = query_newrdataset(client); result = dns_db_findrdataset(db, node, version, - dns_rdatatype_a, 0, - client->now, - trdataset, NULL); + dns_rdatatype_a, 0, + client->now, + trdataset, NULL); if (dns_rdataset_isassociated(trdataset)) dns_rdataset_disassociate(trdataset); query_putrdataset(client, &trdataset); diff --git a/bin/named/server.c b/bin/named/server.c index a15516a889..bf050e9f5f 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.c,v 1.620 2011/09/23 18:08:01 each Exp $ */ +/* $Id: server.c,v 1.621 2011/10/11 00:09:01 each Exp $ */ /*! \file */ @@ -1355,11 +1355,11 @@ dlzconfigure_callback(dns_view_t *view, dns_zone_t *zone) { result = dns_zonemgr_managezone(ns_g_server->zonemgr, zone); if (result != ISC_R_SUCCESS) - return result; + return (result); dns_zone_setstats(zone, ns_g_server->zonestats); - return ns_zone_configure_writeable_dlz(view->dlzdatabase, - zone, zclass, origin); + return (ns_zone_configure_writeable_dlz(view->dlzdatabase, + zone, zclass, origin)); } static isc_result_t diff --git a/bin/named/unix/dlz_dlopen_driver.c b/bin/named/unix/dlz_dlopen_driver.c index 633d72085c..2aa16fca8b 100644 --- a/bin/named/unix/dlz_dlopen_driver.c +++ b/bin/named/unix/dlz_dlopen_driver.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dlz_dlopen_driver.c,v 1.4 2011/03/17 09:25:53 fdupont Exp $ */ +/* $Id: dlz_dlopen_driver.c,v 1.5 2011/10/11 00:09:01 each Exp $ */ #include @@ -143,7 +143,7 @@ dlopen_dlz_allowzonexfr(void *driverarg, void *dbdata, const char *name, static isc_result_t dlopen_dlz_authority(const char *zone, void *driverarg, void *dbdata, - dns_sdlzlookup_t *lookup) + dns_sdlzlookup_t *lookup) { dlopen_data_t *cd = (dlopen_data_t *) dbdata; isc_result_t result; @@ -177,7 +177,9 @@ dlopen_dlz_findzonedb(void *driverarg, void *dbdata, const char *name) static isc_result_t dlopen_dlz_lookup(const char *zone, const char *name, void *driverarg, - void *dbdata, dns_sdlzlookup_t *lookup) + void *dbdata, dns_sdlzlookup_t *lookup, + dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo) { dlopen_data_t *cd = (dlopen_data_t *) dbdata; isc_result_t result; @@ -185,7 +187,8 @@ dlopen_dlz_lookup(const char *zone, const char *name, void *driverarg, UNUSED(driverarg); MAYBE_LOCK(cd); - result = cd->dlz_lookup(zone, name, cd->dbdata, lookup); + result = cd->dlz_lookup(zone, name, cd->dbdata, lookup, + methods, clientinfo); MAYBE_UNLOCK(cd); return (result); } diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c index 4046d2a406..7b332502c2 100644 --- a/bin/named/zoneconf.c +++ b/bin/named/zoneconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zoneconf.c,v 1.182 2011/09/06 22:29:32 smann Exp $ */ +/* $Id: zoneconf.c,v 1.183 2011/10/11 00:09:01 each Exp $ */ /*% */ @@ -1577,10 +1577,10 @@ ns_zone_configure_writeable_dlz(dns_dlzdb_t *dlzdatabase, dns_zone_t *zone, dns_zone_settype(zone, dns_zone_dlz); result = dns_sdlz_setdb(dlzdatabase, rdclass, name, &db); if (result != ISC_R_SUCCESS) - return result; + return (result); result = dns_zone_dlzpostload(zone, db); dns_db_detach(&db); - return result; + return (result); } isc_boolean_t diff --git a/bin/tests/system/dlzexternal/driver.c b/bin/tests/system/dlzexternal/driver.c index d82b459d26..185e099211 100644 --- a/bin/tests/system/dlzexternal/driver.c +++ b/bin/tests/system/dlzexternal/driver.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: driver.c,v 1.5 2011/03/21 00:30:18 marka Exp $ */ +/* $Id: driver.c,v 1.6 2011/10/11 00:09:01 each Exp $ */ /* * This provides a very simple example of an external loadable DLZ @@ -152,7 +152,32 @@ del_name(struct dlz_example_data *state, struct record *list, return (ISC_R_SUCCESS); } +static isc_result_t +fmt_address(isc_sockaddr_t *addr, char *buffer, size_t size) { + char addr_buf[100]; + const char *ret; + isc_uint16_t port = 0; + switch (addr->type.sa.sa_family) { + case AF_INET: + port = ntohs(addr->type.sin.sin_port); + ret = inet_ntop(AF_INET, &addr->type.sin.sin_addr, addr_buf, + sizeof(addr_buf)); + break; + case AF_INET6: + port = ntohs(addr->type.sin6.sin6_port); + ret = inet_ntop(AF_INET6, &addr->type.sin6.sin6_addr, addr_buf, + sizeof(addr_buf)); + default: + return (ISC_R_FAILURE); + } + + if (ret == NULL) + return (ISC_R_FAILURE); + + snprintf(buffer, size, "%s#%u", addr_buf, port); + return (ISC_R_SUCCESS); +} /* * Return the version of the API @@ -260,17 +285,18 @@ dlz_findzonedb(void *dbdata, const char *name) { return (ISC_R_NOTFOUND); } - - /* * Look up one record */ isc_result_t dlz_lookup(const char *zone, const char *name, void *dbdata, - dns_sdlzlookup_t *lookup) + dns_sdlzlookup_t *lookup, dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo) { + isc_result_t result; struct dlz_example_data *state = (struct dlz_example_data *)dbdata; isc_boolean_t found = ISC_FALSE; + isc_sockaddr_t *src; char full_name[100]; int i; @@ -281,21 +307,39 @@ dlz_lookup(const char *zone, const char *name, void *dbdata, else sprintf(full_name, "%s.%s", name, state->zone_name); + if (strcmp(name, "source-addr") == 0) { + char buf[100]; + strcpy(buf, "unknown"); + if (methods != NULL && + methods->version - methods->age >= + DNS_CLIENTINFOMETHODS_VERSION) + { + methods->sourceip(clientinfo, &src); + fmt_address(src, buf, sizeof(buf)); + } + + fprintf(stderr, "connection from: %s\n", buf); + + found = ISC_TRUE; + result = state->putrr(lookup, "TXT", 0, buf); + if (result != ISC_R_SUCCESS) + return (result); + } + for (i = 0; i < MAX_RECORDS; i++) { if (strcasecmp(state->current[i].name, full_name) == 0) { - isc_result_t result; found = ISC_TRUE; result = state->putrr(lookup, state->current[i].type, state->current[i].ttl, state->current[i].data); - if (result != ISC_R_SUCCESS) { + if (result != ISC_R_SUCCESS) return (result); - } } } if (!found) return (ISC_R_NOTFOUND); + return (ISC_R_SUCCESS); } diff --git a/bin/tests/system/dlzexternal/tests.sh b/bin/tests/system/dlzexternal/tests.sh index e8a46f9c9b..3272b8b5ca 100644 --- a/bin/tests/system/dlzexternal/tests.sh +++ b/bin/tests/system/dlzexternal/tests.sh @@ -52,4 +52,12 @@ status=`expr $status + $ret` test_update deny.example.nil. TXT "86400 TXT helloworld" "helloworld" should_fail && ret=1 status=`expr $status + $ret` +echo "I:testing passing client info into DLZ driver" +ret=0 +out=`$DIG $DIGOPTS +short -t txt -q source-addr.example.nil` +addr=`eval echo $out | cut -f1 -d'#'` +[ "$addr" = "10.53.0.1" ] || ret=1 +[ "$ret" -eq 0 ] || echo "I:failed" +status=`expr $status + $ret` + exit $status diff --git a/contrib/dlz/drivers/dlz_bdb_driver.c b/contrib/dlz/drivers/dlz_bdb_driver.c index a4d7a9d7ba..50abb28779 100644 --- a/contrib/dlz/drivers/dlz_bdb_driver.c +++ b/contrib/dlz/drivers/dlz_bdb_driver.c @@ -451,7 +451,8 @@ bdb_findzone(void *driverarg, void *dbdata, const char *name) static isc_result_t bdb_lookup(const char *zone, const char *name, void *driverarg, - void *dbdata, dns_sdlzlookup_t *lookup) + void *dbdata, dns_sdlzlookup_t *lookup, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo) { isc_result_t result = ISC_R_NOTFOUND; @@ -467,6 +468,8 @@ bdb_lookup(const char *zone, const char *name, void *driverarg, char *tmp = NULL; UNUSED(driverarg); + UNUSED(methods); + UNUSED(clientinfo); memset(&key, 0, sizeof(DBT)); memset(&data, 0, sizeof(DBT)); diff --git a/contrib/dlz/drivers/dlz_bdbhpt_driver.c b/contrib/dlz/drivers/dlz_bdbhpt_driver.c index 25d78d7e68..a3a2bc4de4 100644 --- a/contrib/dlz/drivers/dlz_bdbhpt_driver.c +++ b/contrib/dlz/drivers/dlz_bdbhpt_driver.c @@ -533,7 +533,8 @@ bdbhpt_findzone(void *driverarg, void *dbdata, const char *name) static isc_result_t bdbhpt_lookup(const char *zone, const char *name, void *driverarg, - void *dbdata, dns_sdlzlookup_t *lookup) + void *dbdata, dns_sdlzlookup_t *lookup, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo) { isc_result_t result = ISC_R_NOTFOUND; @@ -548,6 +549,8 @@ bdbhpt_lookup(const char *zone, const char *name, void *driverarg, char *keyStr = NULL; UNUSED(driverarg); + UNUSED(methods); + UNUSED(clientinfo); memset(&key, 0, sizeof(DBT)); memset(&data, 0, sizeof(DBT)); diff --git a/contrib/dlz/drivers/dlz_filesystem_driver.c b/contrib/dlz/drivers/dlz_filesystem_driver.c index a04faaac38..aa7f1835fa 100644 --- a/contrib/dlz/drivers/dlz_filesystem_driver.c +++ b/contrib/dlz/drivers/dlz_filesystem_driver.c @@ -774,7 +774,8 @@ fs_findzone(void *driverarg, void *dbdata, const char *name) static isc_result_t fs_lookup(const char *zone, const char *name, void *driverarg, - void *dbdata, dns_sdlzlookup_t *lookup) + void *dbdata, dns_sdlzlookup_t *lookup, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo) { isc_result_t result; char *path; @@ -784,6 +785,8 @@ fs_lookup(const char *zone, const char *name, void *driverarg, UNUSED(driverarg); UNUSED(lookup); + UNUSED(methods); + UNUSED(clientinfo); if (strcmp(name, "*") == 0) /* diff --git a/contrib/dlz/drivers/dlz_ldap_driver.c b/contrib/dlz/drivers/dlz_ldap_driver.c index 0318a400e1..d84dbb4792 100644 --- a/contrib/dlz/drivers/dlz_ldap_driver.c +++ b/contrib/dlz/drivers/dlz_ldap_driver.c @@ -913,10 +913,14 @@ dlz_ldap_findzone(void *driverarg, void *dbdata, const char *name) { static isc_result_t dlz_ldap_lookup(const char *zone, const char *name, void *driverarg, - void *dbdata, dns_sdlzlookup_t *lookup) + void *dbdata, dns_sdlzlookup_t *lookup, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo) { isc_result_t result; + UNUSED(driverarg); + UNUSED(methods); + UNUSED(clientinfo); if (strcmp(name, "*") == 0) result = ldap_get_results(zone, "~", NULL, LOOKUP, diff --git a/contrib/dlz/drivers/dlz_mysql_driver.c b/contrib/dlz/drivers/dlz_mysql_driver.c index dcfab1e6da..08c2adbde3 100644 --- a/contrib/dlz/drivers/dlz_mysql_driver.c +++ b/contrib/dlz/drivers/dlz_mysql_driver.c @@ -743,12 +743,15 @@ mysql_authority(const char *zone, void *driverarg, void *dbdata, /*% if zone is supported, lookup up a (or multiple) record(s) in it */ static isc_result_t mysql_lookup(const char *zone, const char *name, void *driverarg, - void *dbdata, dns_sdlzlookup_t *lookup) + void *dbdata, dns_sdlzlookup_t *lookup, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo) { isc_result_t result; MYSQL_RES *rs = NULL; UNUSED(driverarg); + UNUSED(methods); + UNUSED(clientinfo); /* run the query and get the result set from the database. */ result = mysql_get_resultset(zone, name, NULL, LOOKUP, dbdata, &rs); diff --git a/contrib/dlz/drivers/dlz_odbc_driver.c b/contrib/dlz/drivers/dlz_odbc_driver.c index 6031b08d70..9c1ff4613c 100644 --- a/contrib/dlz/drivers/dlz_odbc_driver.c +++ b/contrib/dlz/drivers/dlz_odbc_driver.c @@ -1219,12 +1219,15 @@ odbc_authority(const char *zone, void *driverarg, void *dbdata, static isc_result_t odbc_lookup(const char *zone, const char *name, void *driverarg, - void *dbdata, dns_sdlzlookup_t *lookup) + void *dbdata, dns_sdlzlookup_t *lookup, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo) { isc_result_t result; dbinstance_t *dbi = NULL; UNUSED(driverarg); + UNUSED(methods); + UNUSED(clientinfo); /* run the query and get the result set from the database. */ result = odbc_get_resultset(zone, name, NULL, LOOKUP, dbdata, &dbi); diff --git a/contrib/dlz/drivers/dlz_postgres_driver.c b/contrib/dlz/drivers/dlz_postgres_driver.c index c5367c6164..4149bff71b 100644 --- a/contrib/dlz/drivers/dlz_postgres_driver.c +++ b/contrib/dlz/drivers/dlz_postgres_driver.c @@ -1016,12 +1016,15 @@ postgres_authority(const char *zone, void *driverarg, void *dbdata, /*% if zone is supported, lookup up a (or multiple) record(s) in it */ static isc_result_t postgres_lookup(const char *zone, const char *name, void *driverarg, - void *dbdata, dns_sdlzlookup_t *lookup) + void *dbdata, dns_sdlzlookup_t *lookup, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo) { isc_result_t result; PGresult *rs = NULL; UNUSED(driverarg); + UNUSED(methods); + UNUSED(clientinfo); /* run the query and get the result set from the database. */ result = postgres_get_resultset(zone, name, NULL, LOOKUP, dbdata, &rs); diff --git a/contrib/dlz/drivers/dlz_stub_driver.c b/contrib/dlz/drivers/dlz_stub_driver.c index c2e72ddb92..a41697e344 100644 --- a/contrib/dlz/drivers/dlz_stub_driver.c +++ b/contrib/dlz/drivers/dlz_stub_driver.c @@ -170,13 +170,16 @@ stub_dlz_findzonedb(void *driverarg, void *dbdata, const char *name) static isc_result_t stub_dlz_lookup(const char *zone, const char *name, void *driverarg, - void *dbdata, dns_sdlzlookup_t *lookup) + void *dbdata, dns_sdlzlookup_t *lookup, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo) { isc_result_t result; config_data_t *cd; UNUSED(zone); UNUSED(driverarg); + UNUSED(methods); + UNUSED(clientinfo); cd = (config_data_t *) dbdata; diff --git a/contrib/dlz/example/dlz_minimal.h b/contrib/dlz/example/dlz_minimal.h index 923c63a90c..4337bdeb83 100644 --- a/contrib/dlz/example/dlz_minimal.h +++ b/contrib/dlz/example/dlz_minimal.h @@ -26,7 +26,7 @@ typedef unsigned int isc_result_t; typedef bool isc_boolean_t; typedef uint32_t dns_ttl_t; -#define DLZ_DLOPEN_VERSION 1 +#define DLZ_DLOPEN_VERSION 2 /* return this in flags to dlz_version() if thread safe */ #define DNS_SDLZFLAG_THREADSAFE 0x00000001U @@ -48,6 +48,7 @@ typedef uint32_t dns_ttl_t; typedef void *dns_sdlzlookup_t; typedef void *dns_sdlzallnodes_t; typedef void *dns_view_t; +typedef void *dns_dlzclientcallback_t; /* * prototypes for the functions you can include in your driver @@ -58,83 +59,109 @@ typedef void *dns_view_t; * dlz_version() is required for all DLZ external drivers. It should * return DLZ_DLOPEN_VERSION */ -int dlz_version(unsigned int *flags); +int +dlz_version(unsigned int *flags); /* * dlz_create() is required for all DLZ external drivers. */ -isc_result_t dlz_create(const char *dlzname, unsigned int argc, char *argv[], void **dbdata, ...); +isc_result_t +dlz_create(const char *dlzname, unsigned int argc, char *argv[], + void **dbdata, ...); /* * dlz_destroy() is optional, and will be called when the driver is * unloaded if supplied */ -void dlz_destroy(void *dbdata); +void +dlz_destroy(void *dbdata); /* - dlz_findzonedb is required for all DLZ external drivers + * dlz_findzonedb is required for all DLZ external drivers */ -isc_result_t dlz_findzonedb(void *dbdata, const char *name); +isc_result_t +dlz_findzonedb(void *dbdata, const char *name); /* - dlz_lookup is required for all DLZ external drivers + * dlz_lookup is required for all DLZ external drivers */ -isc_result_t dlz_lookup(const char *zone, const char *name, - void *dbdata, dns_sdlzlookup_t *lookup); +isc_result_t +dlz_lookup(const char *zone, const char *name, void *dbdata, + dns_sdlzlookup_t *lookup); /* - dlz_allowzonexfr() is optional, and should be supplied if you want - to support zone transfers + * dlz_allowzonexfr() is optional, and should be supplied if you want to + * support zone transfers */ -isc_result_t dlz_allowzonexfr(void *dbdata, const char *name, const char *client); +isc_result_t +dlz_allowzonexfr(void *dbdata, const char *name, const char *client); /* - dlz_allnodes() is optional, but must be supplied if supply a - dlz_allowzonexfr() function + * dlz_allnodes() is optional, but must be supplied if supply a + * dlz_allowzonexfr() function */ -isc_result_t dlz_allnodes(const char *zone, void *dbdata, dns_sdlzallnodes_t *allnodes); +isc_result_t +dlz_allnodes(const char *zone, void *dbdata, dns_sdlzallnodes_t *allnodes); /* - dlz_newversion() is optional. It should be supplied if you want to - support dynamic updates. + * dlz_newversion() is optional. It should be supplied if you want to + * support dynamic updates. */ -isc_result_t dlz_newversion(const char *zone, void *dbdata, void **versionp); +isc_result_t +dlz_newversion(const char *zone, void *dbdata, void **versionp); /* - dlz_closeversion() is optional, but must be supplied if you supply - a dlz_newversion() function + * dlz_closeversion() is optional, but must be supplied if you supply a + * dlz_newversion() function */ -void dlz_closeversion(const char *zone, isc_boolean_t commit, void *dbdata, void **versionp); +void +dlz_closeversion(const char *zone, isc_boolean_t commit, void *dbdata, + void **versionp); /* - dlz_configure() is optional, but must be supplied if you want to - support dynamic updates + * dlz_configure() is optional, but must be supplied if you want to support + * dynamic updates */ -isc_result_t dlz_configure(dns_view_t *view, void *dbdata); +isc_result_t +dlz_configure(dns_view_t *view, void *dbdata); /* - dlz_ssumatch() is optional, but must be supplied if you want to - support dynamic updates + * dlz_setclientcallback() is optional, but must be supplied if you want + * to retrieve information about the client before sending a reply. */ -isc_boolean_t dlz_ssumatch(const char *signer, const char *name, const char *tcpaddr, - const char *type, const char *key, uint32_t keydatalen, uint8_t *keydata, - void *dbdata); +isc_result_t +dlz_setclientcallback(dns_dlzclientcallback_t callback); /* - dlz_addrdataset() is optional, but must be supplied if you want to - support dynamic updates + * dlz_ssumatch() is optional, but must be supplied if you want to support + * dynamic updates */ -isc_result_t dlz_addrdataset(const char *name, const char *rdatastr, void *dbdata, void *version); + +isc_boolean_t +dlz_ssumatch(const char *signer, const char *name, const char *tcpaddr, + const char *type, const char *key, uint32_t keydatalen, + uint8_t *keydata, void *dbdata); /* - dlz_subrdataset() is optional, but must be supplied if you want to - support dynamic updates + * dlz_addrdataset() is optional, but must be supplied if you want to + * support dynamic updates */ -isc_result_t dlz_subrdataset(const char *name, const char *rdatastr, void *dbdata, void *version); +isc_result_t +dlz_addrdataset(const char *name, const char *rdatastr, void *dbdata, + void *version); + +/* dlz_subrdataset() is optional, but must be supplied if you want to + * support dynamic updates + */ +isc_result_t +dlz_subrdataset(const char *name, const char *rdatastr, void *dbdata, + void *version); /* - dlz_delrdataset() is optional, but must be supplied if you want to - support dynamic updates + * dlz_delrdataset() is optional, but must be supplied if you want to + * support dynamic updates */ -isc_result_t dlz_delrdataset(const char *name, const char *type, void *dbdata, void *version); +isc_result_t +dlz_delrdataset(const char *name, const char *type, void *dbdata, + void *version); diff --git a/contrib/sdb/bdb/bdb.c b/contrib/sdb/bdb/bdb.c index 10f5811357..e4393bc52c 100644 --- a/contrib/sdb/bdb/bdb.c +++ b/contrib/sdb/bdb/bdb.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: bdb.c,v 1.1 2002/05/16 04:25:22 marka Exp $ */ +/* $Id: bdb.c,v 1.2 2011/10/11 00:09:02 each Exp $ */ /* * BIND 9.1.x simple database driver @@ -98,8 +98,14 @@ bdb_create(const char *zone, int argc, char **argv, } static isc_result_t +#ifdef DNS_CLIENTINFO_VERSION +bdb_lookup(const char *zone, const char *name, void *dbdata, + dns_sdblookup_t *l, dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo) +#else bdb_lookup(const char *zone, const char *name, void *dbdata, dns_sdblookup_t *l) +#endif /* DNS_CLIENTINFO_VERSION */ { int ret; char *type, *rdata; @@ -109,6 +115,10 @@ bdb_lookup(const char *zone, const char *name, void *dbdata, DBT key, data; UNUSED(zone); +#ifdef DNS_CLIENTINFO_VERSION + UNUSED(methods); + UNUSED(clientinfo); +#endif /* DNS_CLIENTINFO_VERSION */ if ((ret = ((DB *)dbdata)->cursor((DB *)dbdata, NULL, &c, 0)) != 0) { isc_log_iwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE, diff --git a/contrib/sdb/dir/dirdb.c b/contrib/sdb/dir/dirdb.c index ca82cf8a22..70e18bd3a8 100644 --- a/contrib/sdb/dir/dirdb.c +++ b/contrib/sdb/dir/dirdb.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dirdb.c,v 1.12 2007/06/19 23:47:07 tbox Exp $ */ +/* $Id: dirdb.c,v 1.13 2011/10/11 00:09:02 each Exp $ */ /* * A simple database driver that returns basic information about @@ -60,9 +60,16 @@ static dns_sdbimplementation_t *dirdb = NULL; * Any name will be interpreted as a pathname offset from the directory * specified in the configuration file. */ +#ifdef DNS_CLIENTINFO_VERSION +static isc_result_t +dirdb_lookup(const char *zone, const char *name, void *dbdata, + dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo) +#else static isc_result_t dirdb_lookup(const char *zone, const char *name, void *dbdata, dns_sdblookup_t *lookup) +#endif /* DNS_CLIENTINFO_VERSION */ { char filename[255]; char filename2[255]; @@ -73,6 +80,10 @@ dirdb_lookup(const char *zone, const char *name, void *dbdata, UNUSED(zone); UNUSED(dbdata); +#ifdef DNS_CLIENTINFO_VERSION + UNUSED(methods); + UNUSED(clientinfo); +#endif /* DNS_CLIENTINFO_VERSION */ if (strcmp(name, "@") == 0) snprintf(filename, sizeof(filename), "%s", (char *)dbdata); diff --git a/contrib/sdb/ldap/ldapdb.c b/contrib/sdb/ldap/ldapdb.c index ed124c07ea..08d8df4539 100644 --- a/contrib/sdb/ldap/ldapdb.c +++ b/contrib/sdb/ldap/ldapdb.c @@ -217,8 +217,15 @@ ldapdb_bind(struct ldapdb_data *data, LDAP **ldp) } } +#ifdef DNS_CLIENTINFO_VERSION static isc_result_t -ldapdb_search(const char *zone, const char *name, void *dbdata, void *retdata) +ldapdb_search(const char *zone, const char *name, void *dbdata, void *retdata, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo) +#else +static isc_result_t +ldapdb_search(const char *zone, const char *name, void *dbdata, void *retdata, + void *methods, void *clientinfo) +#endif /* DNS_CLIENTINFO_VERSION */ { struct ldapdb_data *data = dbdata; isc_result_t result = ISC_R_NOTFOUND; @@ -233,6 +240,9 @@ ldapdb_search(const char *zone, const char *name, void *dbdata, void *retdata) #endif int i, j, errno, msgid; + UNUSED(methods); + UNUSED(clientinfo); + ldp = ldapdb_getconn(data); if (ldp == NULL) return (ISC_R_FAILURE); @@ -370,18 +380,29 @@ ldapdb_search(const char *zone, const char *name, void *dbdata, void *retdata) /* callback routines */ +#ifdef DNS_CLIENTINFO_VERSION +static isc_result_t +ldapdb_lookup(const char *zone, const char *name, void *dbdata, + dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo) +{ + return (ldapdb_search(zone, name, dbdata, lookup, NULL, NULL)); +} +#else static isc_result_t ldapdb_lookup(const char *zone, const char *name, void *dbdata, dns_sdblookup_t *lookup) { - return ldapdb_search(zone, name, dbdata, lookup); + return (ldapdb_search(zone, name, dbdata, lookup, methods, + clientinfo)); } +#endif /* DNS_CLIENTINFO_VERSION */ static isc_result_t ldapdb_allnodes(const char *zone, void *dbdata, dns_sdballnodes_t *allnodes) { - return ldapdb_search(zone, NULL, dbdata, allnodes); + return (ldapdb_search(zone, NULL, dbdata, allnodes, NULL, NULL)); } static char * diff --git a/contrib/sdb/pgsql/pgsqldb.c b/contrib/sdb/pgsql/pgsqldb.c index ca3bfbf14c..bf09282487 100644 --- a/contrib/sdb/pgsql/pgsqldb.c +++ b/contrib/sdb/pgsql/pgsqldb.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: pgsqldb.c,v 1.15 2007/06/19 23:47:07 tbox Exp $ */ +/* $Id: pgsqldb.c,v 1.16 2011/10/11 00:09:02 each Exp $ */ #include @@ -111,9 +111,16 @@ maybe_reconnect(struct dbinfo *dbi) { * Queries are converted into SQL queries and issued synchronously. Errors * are handled really badly. */ +#ifdef DNS_CLIENTINFO_VERSION +static isc_result_t +pgsqldb_lookup(const char *zone, const char *name, void *dbdata, + dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo) +#else static isc_result_t pgsqldb_lookup(const char *zone, const char *name, void *dbdata, dns_sdblookup_t *lookup) +#endif /* DNS_CLIENTINFO_VERSION */ { isc_result_t result; struct dbinfo *dbi = dbdata; @@ -123,6 +130,10 @@ pgsqldb_lookup(const char *zone, const char *name, void *dbdata, int i; UNUSED(zone); +#ifdef DNS_CLIENTINFO_VERSION + UNUSED(methods); + UNUSED(clientinfo); +#endif /* DNS_CLIENTINFO_VERSION */ canonname = isc_mem_get(ns_g_mctx, strlen(name) * 2 + 1); if (canonname == NULL) diff --git a/contrib/sdb/sqlite/sqlitedb.c b/contrib/sdb/sqlite/sqlitedb.c index c9d0096401..8491aa8a5a 100644 --- a/contrib/sdb/sqlite/sqlitedb.c +++ b/contrib/sdb/sqlite/sqlitedb.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sqlitedb.c,v 1.1 2007/03/05 05:30:22 marka Exp $ */ +/* $Id: sqlitedb.c,v 1.2 2011/10/11 00:09:02 each Exp $ */ #include @@ -108,10 +108,16 @@ sqlitedb_lookup_cb(void *p, int cc, char **cv, char **cn) } +#ifdef DNS_CLIENTINFO_VERSION static isc_result_t -sqlitedb_lookup(const char *zone, - const char *name, void *dbdata, +sqlitedb_lookup(const char *zone, const char *name, void *dbdata, + dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo) +#else +static isc_result_t +sqlitedb_lookup(const char *zone, const char *name, void *dbdata, dns_sdblookup_t *lookup) +#endif /* DNS_CLIENTINFO_VERSION */ /* * synchronous absolute name lookup */ @@ -123,6 +129,10 @@ sqlitedb_lookup(const char *zone, int result; UNUSED(zone); +#ifdef DNS_CLIENTINFO_VERSION + UNUSED(methods); + UNUSED(clientinfo); +#endif /* DNS_CLIENTINFO_VERSION */ sql = sqlite3_mprintf( "SELECT TTL,RDTYPE,RDATA FROM \"%q\" WHERE " diff --git a/contrib/sdb/tcl/tcldb.c b/contrib/sdb/tcl/tcldb.c index de6f4c58a4..d57e1efbd7 100644 --- a/contrib/sdb/tcl/tcldb.c +++ b/contrib/sdb/tcl/tcldb.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: tcldb.c,v 1.10 2007/06/19 23:47:10 tbox Exp $ */ +/* $Id: tcldb.c,v 1.11 2011/10/11 00:09:02 each Exp $ */ /* * A simple database driver that calls a Tcl procedure to define @@ -98,9 +98,16 @@ tcldb_driver_destroy(tcldb_driver_t **driverp) { /* * Perform a lookup, by invoking the Tcl procedure "lookup". */ +#ifdef DNS_CLIENTINFO_VERSION +static isc_result_t +tcldb_lookup(const char *zone, const char *name, void *dbdata, + dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo) +#else static isc_result_t tcldb_lookup(const char *zone, const char *name, void *dbdata, dns_sdblookup_t *lookup) +#endif /* DNS_CLIENTINFO_VERSION */ { isc_result_t result = ISC_R_SUCCESS; int tclres; @@ -110,6 +117,11 @@ tcldb_lookup(const char *zone, const char *name, void *dbdata, char *cmdv[3]; char *cmd; +#ifdef DNS_CLIENTINFO_VERSION + UNUSED(methods); + UNUSED(clientinfo); +#endif /* DNS_CLIENTINFO_VERSION */ + tcldb_driver_t *driver = (tcldb_driver_t *) dbdata; cmdv[0] = "lookup"; diff --git a/contrib/sdb/time/timedb.c b/contrib/sdb/time/timedb.c index f6ddaa41b4..b2311c0b4c 100644 --- a/contrib/sdb/time/timedb.c +++ b/contrib/sdb/time/timedb.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: timedb.c,v 1.10 2007/06/19 23:47:10 tbox Exp $ */ +/* $Id: timedb.c,v 1.11 2011/10/11 00:09:03 each Exp $ */ /* * A simple database driver that enables the server to return the @@ -47,14 +47,25 @@ static dns_sdbimplementation_t *timedb = NULL; * "clock" is a CNAME to "time" * "current" is a DNAME to "@" (try time.current.time) */ +#ifdef DNS_CLIENTINFO_VERSION +static isc_result_t +timedb_lookup(const char *zone, const char *name, void *dbdata, + dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo) +#else static isc_result_t timedb_lookup(const char *zone, const char *name, void *dbdata, dns_sdblookup_t *lookup) +#endif /* DNS_CLIENTINFO_VERSION */ { isc_result_t result; UNUSED(zone); UNUSED(dbdata); +#ifdef DNS_CLIENTINFO_VERSION + UNUSED(methods); + UNUSED(clientinfo); +#endif /* DNS_CLIENTINFO_VERSION */ if (strcmp(name, "@") == 0 || strcmp(name, "time") == 0) { time_t now = time(NULL); diff --git a/lib/dns/Makefile.in b/lib/dns/Makefile.in index b46b90cdb2..b68a1b0bfb 100644 --- a/lib/dns/Makefile.in +++ b/lib/dns/Makefile.in @@ -13,7 +13,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: Makefile.in,v 1.179 2011/07/01 02:25:47 marka Exp $ +# $Id: Makefile.in,v 1.180 2011/10/11 00:09:03 each Exp $ srcdir = @srcdir@ VPATH = @srcdir@ @@ -55,7 +55,7 @@ DSTOBJS = @DST_EXTRA_OBJS@ @OPENSSLLINKOBJS@ \ # Alphabetically DNSOBJS = acache.@O@ acl.@O@ adb.@O@ byaddr.@O@ \ - cache.@O@ callbacks.@O@ compress.@O@ \ + cache.@O@ callbacks.@O@ clientinfo.@O@ compress.@O@ \ db.@O@ dbiterator.@O@ dbtable.@O@ diff.@O@ dispatch.@O@ \ dlz.@O@ dns64.@O@ dnssec.@O@ ds.@O@ forward.@O@ iptable.@O@ \ journal.@O@ keydata.@O@ keytable.@O@ \ @@ -84,7 +84,7 @@ DSTSRCS = @DST_EXTRA_SRCS@ @OPENSSLLINKSRCS@ \ hmac_link.c key.c DNSSRCS = acache.c acl.c adb.c byaddr.c \ - cache.c callbacks.c compress.c \ + cache.c callbacks.c clientinfo.c compress.c \ db.c dbiterator.c dbtable.c diff.c dispatch.c \ dlz.c dns64.c dnssec.c ds.c forward.c iptable.c journal.c \ keydata.c keytable.c lib.c log.c lookup.c \ diff --git a/lib/dns/clientinfo.c b/lib/dns/clientinfo.c new file mode 100644 index 0000000000..a93554b4e7 --- /dev/null +++ b/lib/dns/clientinfo.c @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: clientinfo.c,v 1.2 2011/10/11 00:09:03 each Exp $ */ + +/*! \file */ + +#include + +void +dns_clientinfomethods_init(dns_clientinfomethods_t *methods, + dns_clientinfo_sourceip_t sourceip) +{ + methods->version = DNS_CLIENTINFOMETHODS_VERSION; + methods->age = DNS_CLIENTINFOMETHODS_AGE; + methods->sourceip = sourceip; +} + +void +dns_clientinfo_init(dns_clientinfo_t *ci, void *data) { + ci->version = DNS_CLIENTINFO_VERSION; + ci->data = data; +} diff --git a/lib/dns/db.c b/lib/dns/db.c index 698bb91b38..13778873f3 100644 --- a/lib/dns/db.c +++ b/lib/dns/db.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: db.c,v 1.97 2011/01/13 04:59:25 tbox Exp $ */ +/* $Id: db.c,v 1.98 2011/10/11 00:09:03 each Exp $ */ /*! \file */ @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -478,7 +479,31 @@ dns_db_findnode(dns_db_t *db, dns_name_t *name, REQUIRE(DNS_DB_VALID(db)); REQUIRE(nodep != NULL && *nodep == NULL); - return ((db->methods->findnode)(db, name, create, nodep)); + if (db->methods->findnode != NULL) + return ((db->methods->findnode)(db, name, create, nodep)); + else + return ((db->methods->findnodeext)(db, name, create, + NULL, NULL, nodep)); +} + +isc_result_t +dns_db_findnodeext(dns_db_t *db, dns_name_t *name, + isc_boolean_t create, dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep) +{ + /* + * Find the node with name 'name', passing 'arg' to the database + * implementation. + */ + + REQUIRE(DNS_DB_VALID(db)); + REQUIRE(nodep != NULL && *nodep == NULL); + + if (db->methods->findnodeext != NULL) + return ((db->methods->findnodeext)(db, name, create, + methods, clientinfo, nodep)); + else + return ((db->methods->findnode)(db, name, create, nodep)); } isc_result_t @@ -502,7 +527,6 @@ dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { - /* * Find the best match for 'name' and 'type' in version 'version' * of 'db'. @@ -519,8 +543,50 @@ dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, (DNS_RDATASET_VALID(sigrdataset) && ! dns_rdataset_isassociated(sigrdataset))); - return ((db->methods->find)(db, name, version, type, options, now, - nodep, foundname, rdataset, sigrdataset)); + if (db->methods->find != NULL) + return ((db->methods->find)(db, name, version, type, + options, now, nodep, foundname, + rdataset, sigrdataset)); + else + return ((db->methods->findext)(db, name, version, type, + options, now, nodep, foundname, + NULL, NULL, + rdataset, sigrdataset)); +} + +isc_result_t +dns_db_findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, + dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, + dns_dbnode_t **nodep, dns_name_t *foundname, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, + dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) +{ + + /* + * Find the best match for 'name' and 'type' in version 'version' + * of 'db', passing in 'arg'. + */ + + REQUIRE(DNS_DB_VALID(db)); + REQUIRE(type != dns_rdatatype_rrsig); + REQUIRE(nodep == NULL || (nodep != NULL && *nodep == NULL)); + REQUIRE(dns_name_hasbuffer(foundname)); + REQUIRE(rdataset == NULL || + (DNS_RDATASET_VALID(rdataset) && + ! dns_rdataset_isassociated(rdataset))); + REQUIRE(sigrdataset == NULL || + (DNS_RDATASET_VALID(sigrdataset) && + ! dns_rdataset_isassociated(sigrdataset))); + + if (db->methods->findext != NULL) + return ((db->methods->findext)(db, name, version, type, + options, now, nodep, foundname, + methods, clientinfo, + rdataset, sigrdataset)); + else + return ((db->methods->find)(db, name, version, type, + options, now, nodep, foundname, + rdataset, sigrdataset)); } isc_result_t @@ -653,11 +719,6 @@ dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_stdtime_t now, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { - /* - * Search for an rdataset of type 'type' at 'node' that are in version - * 'version' of 'db'. If found, make 'rdataset' refer to it. - */ - REQUIRE(DNS_DB_VALID(db)); REQUIRE(node != NULL); REQUIRE(DNS_RDATASET_VALID(rdataset)); @@ -668,8 +729,9 @@ dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, (DNS_RDATASET_VALID(sigrdataset) && ! dns_rdataset_isassociated(sigrdataset))); - return ((db->methods->findrdataset)(db, node, version, type, covers, - now, rdataset, sigrdataset)); + return ((db->methods->findrdataset)(db, node, version, type, + covers, now, rdataset, + sigrdataset)); } isc_result_t diff --git a/lib/dns/include/dns/clientinfo.h b/lib/dns/include/dns/clientinfo.h new file mode 100644 index 0000000000..b947197ffd --- /dev/null +++ b/lib/dns/include/dns/clientinfo.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: clientinfo.h,v 1.2 2011/10/11 00:09:03 each Exp $ */ + +#ifndef DNS_CLIENTINFO_H +#define DNS_CLIENTINFO_H 1 + +/***** + ***** Module Info + *****/ + +/*! \file dns/clientinfo.h + * \brief + * The DNS clientinfo interface allows libdns to retrieve information + * about the client from the caller. + * + * The clientinfo interface is used by the DNS DB and DLZ interfaces; + * it allows databases to modify their answers on the basis of information + * about the client, such as source IP address. + * + * dns_clientinfo_t contains a pointer to an opaque structure containing + * client information in some form. dns_clientinfomethods_t contains a + * list of methods which operate on that opaque structure to return + * potentially useful data. Both structures also contain versioning + * information. + */ + +/***** + ***** Imports + *****/ + +#include +#include + +ISC_LANG_BEGINDECLS + +/***** + ***** Types + *****/ + +#define DNS_CLIENTINFO_VERSION 1 +typedef struct dns_clientinfo { + isc_uint16_t version; + void *data; +} dns_clientinfo_t; + +typedef isc_result_t (*dns_clientinfo_sourceip_t)(dns_clientinfo_t *client, + isc_sockaddr_t **addrp); + +#define DNS_CLIENTINFOMETHODS_VERSION 1 +#define DNS_CLIENTINFOMETHODS_AGE 0 + +typedef struct dns_clientinfomethods { + isc_uint16_t version; + isc_uint16_t age; + dns_clientinfo_sourceip_t sourceip; +} dns_clientinfomethods_t; + +/***** + ***** Methods + *****/ +void +dns_clientinfomethods_init(dns_clientinfomethods_t *methods, + dns_clientinfo_sourceip_t sourceip); + +void +dns_clientinfo_init(dns_clientinfo_t *ci, void *data); + +ISC_LANG_ENDDECLS + +#endif /* DNS_CLIENTINFO_H */ diff --git a/lib/dns/include/dns/db.h b/lib/dns/include/dns/db.h index 5a5e5e9977..0c3ebb799c 100644 --- a/lib/dns/include/dns/db.h +++ b/lib/dns/include/dns/db.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: db.h,v 1.105 2011/05/19 00:31:57 smann Exp $ */ +/* $Id: db.h,v 1.106 2011/10/11 00:09:03 each Exp $ */ #ifndef DNS_DB_H #define DNS_DB_H 1 @@ -59,6 +59,7 @@ #include #include +#include #include #include #include @@ -178,6 +179,20 @@ typedef struct dns_dbmethods { dns_dbversion_t *version, dns_rdataset_t *ardataset, dns_rpz_st_t *st); + isc_result_t (*findnodeext)(dns_db_t *db, dns_name_t *name, + isc_boolean_t create, + dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo, + dns_dbnode_t **nodep); + isc_result_t (*findext)(dns_db_t *db, dns_name_t *name, + dns_dbversion_t *version, + dns_rdatatype_t type, unsigned int options, + isc_stdtime_t now, + dns_dbnode_t **nodep, dns_name_t *foundname, + dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo, + dns_rdataset_t *rdataset, + dns_rdataset_t *sigrdataset); } dns_dbmethods_t; typedef isc_result_t @@ -659,9 +674,19 @@ dns_db_closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_result_t dns_db_findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, dns_dbnode_t **nodep); + +isc_result_t +dns_db_findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create, + dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep); /*%< * Find the node with name 'name'. * + * dns_db_findnodeext() (findnode extended) also accepts parameters + * 'methods' and 'clientinfo', which, when provided, enable the database to + * retreive information about the client from the caller, and modify its + * response on the basis of that information. + * * Notes: * \li If 'create' is ISC_TRUE and no node with name 'name' exists, then * such a node will be created. @@ -698,9 +723,21 @@ dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); + +isc_result_t +dns_db_findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, + dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, + dns_dbnode_t **nodep, dns_name_t *foundname, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, + dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); /*%< * Find the best match for 'name' and 'type' in version 'version' of 'db'. * + * dns_db_findext() (find extended) also accepts parameters 'methods' + * and 'clientinfo', which when provided enable the database to retreive + * information about the client from the caller, and modify its response + * on the basis of this information. + * * Notes: * * \li If type == dns_rdataset_any, then rdataset will not be bound. @@ -1047,6 +1084,7 @@ dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdatatype_t type, dns_rdatatype_t covers, isc_stdtime_t now, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); + /*%< * Search for an rdataset of type 'type' at 'node' that are in version * 'version' of 'db'. If found, make 'rdataset' refer to it. diff --git a/lib/dns/include/dns/dlz_dlopen.h b/lib/dns/include/dns/dlz_dlopen.h index 1cc413cd2e..7975f902ce 100644 --- a/lib/dns/include/dns/dlz_dlopen.h +++ b/lib/dns/include/dns/dlz_dlopen.h @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dlz_dlopen.h,v 1.2 2011/03/17 09:25:54 fdupont Exp $ */ +/* $Id: dlz_dlopen.h,v 1.3 2011/10/11 00:09:03 each Exp $ */ /*! \file dns/dlz_open.h */ @@ -30,7 +30,7 @@ ISC_LANG_BEGINDECLS * for the entry points of an external DLZ module for bind9. */ -#define DLZ_DLOPEN_VERSION 1 +#define DLZ_DLOPEN_VERSION 2 /* * dlz_dlopen_version() is required for all DLZ external drivers. It @@ -65,7 +65,9 @@ typedef isc_result_t dlz_dlopen_findzonedb_t (void *dbdata, typedef isc_result_t dlz_dlopen_lookup_t (const char *zone, const char *name, void *dbdata, - dns_sdlzlookup_t *lookup); + dns_sdlzlookup_t *lookup, + dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo); /* * dlz_dlopen_authority is optional() if dlz_dlopen_lookup() @@ -115,6 +117,15 @@ typedef void dlz_dlopen_closeversion_t (const char *zone, typedef isc_result_t dlz_dlopen_configure_t (dns_view_t *view, void *dbdata); +/* + * dlz_dlopen_setclientcallback() is optional, but must be supplied if you + * want to retrieve information about the client (e.g., source address) + * before sending a replay. + */ +typedef isc_result_t dlz_dlopen_setclientcallback_t (dns_view_t *view, + void *dbdata); + + /* * dlz_dlopen_ssumatch() is optional, but must be supplied if you want * to support dynamic updates diff --git a/lib/dns/include/dns/sdb.h b/lib/dns/include/dns/sdb.h index b7fbc99eba..b6b3a79b1e 100644 --- a/lib/dns/include/dns/sdb.h +++ b/lib/dns/include/dns/sdb.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sdb.h,v 1.23 2009/01/17 23:47:43 tbox Exp $ */ +/* $Id: sdb.h,v 1.24 2011/10/11 00:09:03 each Exp $ */ #ifndef DNS_SDB_H #define DNS_SDB_H 1 @@ -35,6 +35,7 @@ #include +#include #include /*** @@ -58,7 +59,9 @@ typedef struct dns_sdballnodes dns_sdballnodes_t; typedef isc_result_t (*dns_sdblookupfunc_t)(const char *zone, const char *name, void *dbdata, - dns_sdblookup_t *); + dns_sdblookup_t *lookup, + dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo); typedef isc_result_t (*dns_sdbauthorityfunc_t)(const char *zone, void *dbdata, dns_sdblookup_t *); diff --git a/lib/dns/include/dns/sdlz.h b/lib/dns/include/dns/sdlz.h index 8dcddbedbf..1e2baaed4c 100644 --- a/lib/dns/include/dns/sdlz.h +++ b/lib/dns/include/dns/sdlz.h @@ -50,13 +50,14 @@ * USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sdlz.h,v 1.16 2011/03/17 23:47:30 tbox Exp $ */ +/* $Id: sdlz.h,v 1.17 2011/10/11 00:09:03 each Exp $ */ /*! \file dns/sdlz.h */ #ifndef SDLZ_H #define SDLZ_H 1 +#include #include ISC_LANG_BEGINDECLS @@ -182,18 +183,23 @@ typedef isc_result_t typedef isc_result_t (*dns_sdlzlookupfunc_t)(const char *zone, const char *name, void *driverarg, - void *dbdata, dns_sdlzlookup_t *lookup); + void *dbdata, dns_sdlzlookup_t *lookup, + dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo); /*%< * Method prototype. Drivers implementing the SDLZ interface MUST - * supply a lookup method. This method is called when the DNS server - * is performing a query, after the find zone and before any other - * methods have been called. This function returns record DNS record + * supply a lookup method. This method is called when the + * DNS server is performing a query, after the find zone and before any + * other methods have been called. This function returns DNS record * information using the dns_sdlz_putrr and dns_sdlz_putsoa functions. * If this function supplies authority information for the DNS record * the authority method is not required. If it does not, the - * authority function is required. A SDLZ driver must implement a - * lookup method. + * authority function is required. + * + * The 'methods' and 'clientinfo' args allow an SDLZ driver to retrieve + * information about the querying client (such as source IP address) + * from the caller. */ typedef isc_result_t (*dns_sdlznewversion_t)(const char *zone, diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 88ff8d63d2..96a8bbf4d9 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbtdb.c,v 1.316 2011/08/23 00:59:23 each Exp $ */ +/* $Id: rbtdb.c,v 1.317 2011/10/11 00:09:03 each Exp $ */ /*! \file */ @@ -7408,11 +7408,13 @@ static dns_dbmethods_t zone_methods = { NULL, #ifdef BIND9 get_rpz_enabled, - rpz_findips + rpz_findips, #else NULL, - NULL + NULL, #endif + NULL, + NULL }; static dns_dbmethods_t cache_methods = { @@ -7453,6 +7455,8 @@ static dns_dbmethods_t cache_methods = { isdnssec, getrrsetstats, NULL, + NULL, + NULL, NULL }; diff --git a/lib/dns/sdb.c b/lib/dns/sdb.c index 42bfad6765..ed99ea0e2a 100644 --- a/lib/dns/sdb.c +++ b/lib/dns/sdb.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sdb.c,v 1.78 2011/03/14 13:40:52 fdupont Exp $ */ +/* $Id: sdb.c,v 1.79 2011/10/11 00:09:03 each Exp $ */ /*! \file */ @@ -727,8 +727,9 @@ destroynode(dns_sdbnode_t *node) { } static isc_result_t -findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, - dns_dbnode_t **nodep) +findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, + dns_dbnode_t **nodep) { dns_sdb_t *sdb = (dns_sdb_t *)db; dns_sdbnode_t *node = NULL; @@ -773,7 +774,8 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, isorigin = dns_name_equal(name, &sdb->common.origin); MAYBE_LOCK(sdb); - result = imp->methods->lookup(sdb->zone, namestr, sdb->dbdata, node); + result = imp->methods->lookup(sdb->zone, namestr, sdb->dbdata, + node, methods, clientinfo); MAYBE_UNLOCK(sdb); if (result != ISC_R_SUCCESS && !(result == ISC_R_NOTFOUND && @@ -798,10 +800,11 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, } static isc_result_t -find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, - dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) +findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, + dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, + dns_dbnode_t **nodep, dns_name_t *foundname, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, + dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { dns_sdb_t *sdb = (dns_sdb_t *)db; dns_dbnode_t *node = NULL; @@ -840,7 +843,8 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * Look up the next label. */ dns_name_getlabelsequence(name, nlabels - i, i, xname); - result = findnode(db, xname, ISC_FALSE, &node); + result = findnodeext(db, xname, ISC_FALSE, methods, + clientinfo, &node); if (result != ISC_R_SUCCESS) { result = DNS_R_NXDOMAIN; continue; @@ -1227,8 +1231,8 @@ static dns_dbmethods_t sdb_methods = { newversion, attachversion, closeversion, - findnode, - find, + NULL, + NULL, findzonecut, attachnode, detachnode, @@ -1245,17 +1249,19 @@ static dns_dbmethods_t sdb_methods = { ispersistent, overmem, settask, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL + NULL, /* getoriginnode */ + NULL, /* transfernode */ + NULL, /* getnsec3parameters */ + NULL, /* findnsec3node */ + NULL, /* setsigningtime */ + NULL, /* getsigningtime */ + NULL, /* resigned */ + NULL, /* isdnssec */ + NULL, /* getrrsetstats */ + NULL, /* rpz_enabled */ + NULL, /* rpz_findips */ + findnodeext, + findext }; static isc_result_t diff --git a/lib/dns/sdlz.c b/lib/dns/sdlz.c index 25e9f986c4..0bb1e0e9fb 100644 --- a/lib/dns/sdlz.c +++ b/lib/dns/sdlz.c @@ -50,7 +50,7 @@ * USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sdlz.c,v 1.33 2011/03/21 19:54:03 each Exp $ */ +/* $Id: sdlz.c,v 1.34 2011/10/11 00:09:03 each Exp $ */ /*! \file */ @@ -538,8 +538,9 @@ destroynode(dns_sdlznode_t *node) { } static isc_result_t -findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, - dns_dbnode_t **nodep) +findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, + dns_dbnode_t **nodep) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; dns_sdlznode_t *node = NULL; @@ -598,17 +599,18 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, /* try to lookup the host (namestr) */ result = sdlz->dlzimp->methods->lookup(zonestr, namestr, sdlz->dlzimp->driverarg, - sdlz->dbdata, node); + sdlz->dbdata, node, + methods, clientinfo); /* * if the host (namestr) was not found, try to lookup a * "wildcard" host. */ - if (result != ISC_R_SUCCESS && !create) { + if (result != ISC_R_SUCCESS && !create) result = sdlz->dlzimp->methods->lookup(zonestr, "*", sdlz->dlzimp->driverarg, - sdlz->dbdata, node); - } + sdlz->dbdata, node, + methods, clientinfo); MAYBE_UNLOCK(sdlz->dlzimp); @@ -651,6 +653,13 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, return (ISC_R_SUCCESS); } +static isc_result_t +findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, + dns_dbnode_t **nodep) +{ + return (findnodeext(db, name, create, NULL, NULL, nodep)); +} + static isc_result_t findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, @@ -825,10 +834,11 @@ findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, } static isc_result_t -find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, - dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) +findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, + dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, + dns_dbnode_t **nodep, dns_name_t *foundname, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, + dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; dns_dbnode_t *node = NULL; @@ -867,7 +877,8 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * Look up the next label. */ dns_name_getlabelsequence(name, nlabels - i, i, xname); - result = findnode(db, xname, ISC_FALSE, &node); + result = findnodeext(db, xname, ISC_FALSE, + methods, clientinfo, &node); if (result != ISC_R_SUCCESS) { result = DNS_R_NXDOMAIN; continue; @@ -879,8 +890,8 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, */ if (i < nlabels) { result = findrdataset(db, node, version, - dns_rdatatype_dname, - 0, now, rdataset, sigrdataset); + dns_rdatatype_dname, 0, now, + rdataset, sigrdataset); if (result == ISC_R_SUCCESS) { result = DNS_R_DNAME; break; @@ -893,8 +904,8 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, */ if (i != olabels && (options & DNS_DBFIND_GLUEOK) == 0) { result = findrdataset(db, node, version, - dns_rdatatype_ns, - 0, now, rdataset, sigrdataset); + dns_rdatatype_ns, 0, now, + rdataset, sigrdataset); if (result == ISC_R_SUCCESS) { if (i == nlabels && type == dns_rdatatype_any) { @@ -933,8 +944,8 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, /* * Look for the qtype. */ - result = findrdataset(db, node, version, type, - 0, now, rdataset, sigrdataset); + result = findrdataset(db, node, version, type, 0, now, + rdataset, sigrdataset); if (result == ISC_R_SUCCESS) break; @@ -943,8 +954,8 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, */ if (type != dns_rdatatype_cname) { result = findrdataset(db, node, version, - dns_rdatatype_cname, - 0, now, rdataset, sigrdataset); + dns_rdatatype_cname, 0, now, + rdataset, sigrdataset); if (result == ISC_R_SUCCESS) { result = DNS_R_CNAME; break; @@ -979,6 +990,16 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, return (result); } +static isc_result_t +find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, + dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, + dns_dbnode_t **nodep, dns_name_t *foundname, + dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) +{ + return (findext(db, name, version, type, options, now, nodep, + foundname, NULL, NULL, rdataset, sigrdataset)); +} + static isc_result_t allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_stdtime_t now, dns_rdatasetiter_t **iteratorp) @@ -1194,7 +1215,8 @@ getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) { if (sdlz->dlzimp->methods->newversion == NULL) return (ISC_R_NOTIMPLEMENTED); - result = findnode(db, &sdlz->common.origin, ISC_FALSE, nodep); + result = findnodeext(db, &sdlz->common.origin, ISC_FALSE, + NULL, NULL, nodep); if (result != ISC_R_SUCCESS) sdlz_log(ISC_LOG_ERROR, "sdlz getoriginnode failed : %s", isc_result_totext(result)); @@ -1230,16 +1252,18 @@ static dns_dbmethods_t sdlzdb_methods = { overmem, settask, getoriginnode, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL + NULL, /* transfernode */ + NULL, /* getnsec3parameters */ + NULL, /* findnsec3node */ + NULL, /* setsigningtime */ + NULL, /* getsigningtime */ + NULL, /* resigned */ + NULL, /* isdnssec */ + NULL, /* getrrsetstats */ + NULL, /* rpz_enabled */ + NULL, /* rpz_findips */ + findnodeext, + findext }; /*