]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2737. [func] UPDATE requests can leak existance information.
authorMark Andrews <marka@isc.org>
Tue, 27 Oct 2009 05:42:25 +0000 (05:42 +0000)
committerMark Andrews <marka@isc.org>
Tue, 27 Oct 2009 05:42:25 +0000 (05:42 +0000)
                        [RT #17261]

CHANGES
bin/named/update.c

diff --git a/CHANGES b/CHANGES
index 33d2f31e4e4238d9d027e3dc590600543963a88d..f89fac388bca03aa1830f1971f717b4257642fa9 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+2737.  [func]          UPDATE requests can leak existance information.
+                       [RT #17261]
+
 2736.  [func]          Improve the performance of NSEC signed zones with
                        more than a normal amount of glue below a delegation.
                        [RT #20191]
index db7ca032100e7fd059b50c440fc457f26148c1c0..140c8493af9e85e2e0452878d158e803dac1b38e 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: update.c,v 1.165 2009/10/22 23:48:07 tbox Exp $ */
+/* $Id: update.c,v 1.166 2009/10/27 05:42:25 marka Exp $ */
 
 #include <config.h>
 
@@ -281,6 +281,43 @@ inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
        }
 }
 
+/*%
+ * Check if we could have queried for the contents of this zone or
+ * if the zone is potentially updateable.
+ * If the zone can potentially be updated and the check failed then
+ * log a error otherwise we log a informational message.
+ */
+static isc_result_t
+checkqueryacl(ns_client_t *client, dns_acl_t *queryacl, dns_name_t *zonename,
+             dns_acl_t *updateacl, dns_ssutable_t *ssutable)
+{
+       char namebuf[DNS_NAME_FORMATSIZE];
+       char classbuf[DNS_RDATACLASS_FORMATSIZE];
+       int level;
+       isc_result_t result;
+
+       result = ns_client_checkaclsilent(client, NULL, queryacl, ISC_TRUE);
+       if (result != ISC_R_SUCCESS) {
+               dns_name_format(zonename, namebuf, sizeof(namebuf));
+               dns_rdataclass_format(client->view->rdclass, classbuf,
+                                     sizeof(classbuf));
+
+               level = (updateacl == NULL && ssutable == NULL) ?
+                               ISC_LOG_INFO : ISC_LOG_ERROR;
+
+               ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY,
+                             NS_LOGMODULE_UPDATE, level,
+                             "update '%s/%s' denied due to allow-query",
+                             namebuf, classbuf);
+       } else if (updateacl == NULL && ssutable == NULL) {
+               result = DNS_R_REFUSED;
+               ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY,
+                             NS_LOGMODULE_UPDATE, ISC_LOG_INFO,
+                             "update '%s/%s' denied", namebuf, classbuf);
+       }
+       return (result);
+}
+
 /*%
  * Override the default acl logging when checking whether a client
  * can update the zone or whether we can forward the request to the
@@ -3506,6 +3543,18 @@ update_action(isc_task_t *task, isc_event_t *event) {
        zonename = dns_db_origin(db);
        zoneclass = dns_db_class(db);
        dns_zone_getssutable(zone, &ssutable);
+
+       /*
+        * Update message processing can leak record existance information
+        * so check that we are allowed to query this zone.  Additionally
+        * if we would refuse all updates for this zone we bail out here.
+        */
+       CHECK(checkqueryacl(client, dns_zone_getqueryacl(zone), zonename,
+                           dns_zone_getupdateacl(zone), ssutable));
+
+       /*
+        * Get old and new versions now that queryacl has been checked.
+        */
        dns_db_currentversion(db, &oldver);
        CHECK(dns_db_newversion(db, &ver));
 
@@ -3598,7 +3647,6 @@ update_action(isc_task_t *task, isc_event_t *event) {
        if (result != ISC_R_NOMORE)
                FAIL(result);
 
-
        /*
         * Perform the final check of the "rrset exists (value dependent)"
         * prerequisites.