]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
allow dlz to signal that the view's transfer acl should be used
authorMark Andrews <marka@isc.org>
Wed, 2 Jan 2019 06:29:59 +0000 (17:29 +1100)
committerMark Andrews <marka@isc.org>
Mon, 11 Mar 2019 03:27:13 +0000 (14:27 +1100)
lib/dns/dlz.c
lib/dns/include/dns/dlz.h
lib/dns/include/dns/view.h
lib/dns/sdlz.c
lib/isc/include/isc/result.h
lib/isc/result.c
lib/ns/xfrout.c

index 03d699c15e7ef30b6eec6d2fdd3fe88312415485..b475e36dfe5282efe02edb5c82f0c34cbd0c31f0 100644 (file)
@@ -133,11 +133,17 @@ dns_dlzallowzonexfr(dns_view_t *view, const dns_name_t *name,
                                         view->rdclass, name, clientaddr, dbp);
 
                /*
-                * if ISC_R_NOPERM, we found the right database but
-                * the zone may not transfer.
+                * In these cases, we found the right database. Non-success
+                * result codes indicate the zone might not transfer.
                 */
-               if (result == ISC_R_SUCCESS || result == ISC_R_NOPERM)
+               switch (result) {
+               case ISC_R_SUCCESS:
+               case ISC_R_NOPERM:
+               case ISC_R_DEFAULT:
                        return (result);
+               default:
+                       break;
+               }
        }
 
        if (result == ISC_R_NOTIMPLEMENTED)
index 0f8cd3eb30b3277707a0e80f9fd5f7eacc01ed98..e769a97dc66415979200359577607903d276264e 100644 (file)
@@ -107,10 +107,11 @@ typedef isc_result_t
  * the DNS server is performing a zone transfer query.  The driver's
  * method should return ISC_R_SUCCESS and a database pointer to the
  * name server if the zone is supported by the database, and zone
- * transfer is allowed.  Otherwise it will return ISC_R_NOTFOUND if
- * the zone is not supported by the database, or ISC_R_NOPERM if zone
- * transfers are not allowed.  If an error occurs it should return a
- * result code indicating the type of error.
+ * transfer is allowed.  If the view's transfer acl should be used,
+ * then the driver's method should return ISC_R_DEFAULT.  Otherwise,
+ * it should return ISC_R_NOTFOUND if the zone is not supported by
+ * the database, or ISC_R_NOPERM if zone transfers are not allowed.
+ * If an error occurs, the result code should indicate the type of error.
  */
 
 typedef isc_result_t
index 43a3e9e0160cb55055a1908c3b78afad0b1701ff..f17e9733d0d764520c9c2a7933bd4c4d6c48f859 100644 (file)
@@ -100,7 +100,7 @@ struct dns_view {
        dns_ntatable_t *                ntatable_priv;
 
        isc_mutex_t                     lock;
-       bool                    frozen;
+       bool                            frozen;
        isc_task_t *                    task;
        isc_event_t                     resevent;
        isc_event_t                     adbevent;
@@ -108,7 +108,7 @@ struct dns_view {
        isc_stats_t *                   adbstats;
        isc_stats_t *                   resstats;
        dns_stats_t *                   resquerystats;
-       bool                    cacheshared;
+       bool                            cacheshared;
 
        /* Configurable data. */
        dns_tsig_keyring_t *            statickeys;
@@ -144,14 +144,14 @@ struct dns_view {
        dns_acl_t *                     upfwdacl;
        dns_acl_t *                     denyansweracl;
        dns_acl_t *                     nocasecompress;
-       bool                    msgcompression;
+       bool                            msgcompression;
        dns_rbt_t *                     answeracl_exclude;
        dns_rbt_t *                     denyanswernames;
        dns_rbt_t *                     answernames_exclude;
        dns_rrl_t *                     rrl;
-       bool                    provideixfr;
-       bool                    requestnsid;
-       bool                    sendcookie;
+       bool                            provideixfr;
+       bool                            requestnsid;
+       bool                            sendcookie;
        dns_ttl_t                       maxcachettl;
        dns_ttl_t                       maxncachettl;
        dns_ttl_t                       mincachettl;
@@ -164,17 +164,17 @@ struct dns_view {
        in_port_t                       dstport;
        dns_aclenv_t                    aclenv;
        dns_rdatatype_t                 preferred_glue;
-       bool                    flush;
+       bool                            flush;
        dns_namelist_t *                delonly;
-       bool                    rootdelonly;
+       bool                            rootdelonly;
        dns_namelist_t *                rootexclude;
-       bool                    checknames;
+       bool                            checknames;
        dns_name_t *                    dlv;
        dns_fixedname_t                 dlv_fixed;
        uint16_t                        maxudp;
        dns_ttl_t                       staleanswerttl;
        dns_stale_answer_t              staleanswersok;         /* rndc setting */
-       bool                    staleanswersenable;     /* named.conf setting */
+       bool                            staleanswersenable;     /* named.conf setting */
        uint16_t                        nocookieudp;
        uint16_t                        padding;
        dns_acl_t *                     pad_acl;
@@ -194,7 +194,7 @@ struct dns_view {
         */
        dns_acl_t *                     matchclients;
        dns_acl_t *                     matchdestinations;
-       bool                    matchrecursiveonly;
+       bool                            matchrecursiveonly;
 
        /* Locked by themselves. */
        isc_refcount_t                  references;
index 22c231de174c209c52f82d712cf2b632c3613429..2fd1f900a8dd370bd6c362d05407e919db41ed9d 100644 (file)
@@ -1610,17 +1610,23 @@ dns_sdlzallowzonexfr(void *driverarg, void *dbdata, isc_mem_t *mctx,
 
        /* Call SDLZ driver's find zone method */
        if (imp->methods->allowzonexfr != NULL) {
+               isc_result_t rresult = ISC_R_SUCCESS;
+
                MAYBE_LOCK(imp);
                result = imp->methods->allowzonexfr(imp->driverarg, dbdata,
                                                    namestr, clientstr);
                MAYBE_UNLOCK(imp);
                /*
-                * if zone is supported and transfers allowed build a 'bind'
-                * database driver
+                * if zone is supported and transfers are (or might be)
+                * allowed, build a 'bind' database driver
                 */
-               if (result == ISC_R_SUCCESS)
-                       result = dns_sdlzcreateDBP(mctx, driverarg, dbdata,
-                                                  name, rdclass, dbp);
+               if (result == ISC_R_SUCCESS || result == ISC_R_DEFAULT) {
+                       rresult = dns_sdlzcreateDBP(mctx, driverarg, dbdata,
+                                                   name, rdclass, dbp);
+               }
+               if (rresult != ISC_R_SUCCESS) {
+                       result = rresult;
+               }
                return (result);
        }
 
index 36792fa0dcbd3b7f8c9535d31f2bf081e765e6d8..634a343b5dafe272efff6900764561c15c8c80b5 100644 (file)
 #define ISC_R_CRYPTOFAILURE            65      /*%< cryptography library failure */
 #define ISC_R_DISCQUOTA                        66      /*%< disc quota */
 #define ISC_R_DISCFULL                 67      /*%< disc full */
+#define ISC_R_DEFAULT                  68      /*%< default */
 
 /*% Not a result code: the number of results. */
-#define ISC_R_NRESULTS                         68
+#define ISC_R_NRESULTS                         69
 
 ISC_LANG_BEGINDECLS
 
index efec95248471d315889f6b961c6fccdeaafd52f2..3cfaa86c72555987ce18315f84f031ab4c56c690 100644 (file)
@@ -99,6 +99,7 @@ static const char *description[ISC_R_NRESULTS] = {
        "crypto failure",                       /*%< 65 */
        "disc quota",                           /*%< 66 */
        "disc full",                            /*%< 67 */
+       "default",                              /*%< 68 */
 };
 
 static const char *identifier[ISC_R_NRESULTS] = {
@@ -170,6 +171,7 @@ static const char *identifier[ISC_R_NRESULTS] = {
        "ISC_R_CRYPTOFAILURE",
        "ISC_R_DISCQUOTA",
        "ISC_R_DISCFULL",
+       "ISC_R_DEFAULT",
 };
 
 #define ISC_RESULT_RESULTSET                   2
index e46eaf41e3bf7ebbb01b9ae74c0a84a6cf558333..ff383f68fe891106934231b80f3ff4c43b7bf092 100644 (file)
@@ -763,6 +763,7 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
        bool is_poll = false;
        bool is_dlz = false;
        bool is_ixfr = false;
+       bool useviewacl = false;
        uint32_t begin_serial = 0, current_serial;
 
        switch (reqtype) {
@@ -826,7 +827,10 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
                                                     question_name,
                                                     &client->peeraddr,
                                                     &db);
-
+                       if (result == ISC_R_DEFAULT) {
+                               useviewacl = true;
+                               result = ISC_R_SUCCESS;
+                       }
                        if (result == ISC_R_NOPERM) {
                                char _buf1[DNS_NAME_FORMATSIZE];
                                char _buf2[DNS_RDATACLASS_FORMATSIZE];
@@ -843,9 +847,10 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
                                              _buf1, _buf2);
                                goto failure;
                        }
-                       if (result != ISC_R_SUCCESS)
+                       if (result != ISC_R_SUCCESS) {
                                FAILQ(DNS_R_NOTAUTH, "non-authoritative zone",
                                      question_name, question_class);
+                       }
                        is_dlz = true;
                } else {
                        /*
@@ -926,14 +931,21 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
                    "%s authority section OK", mnemonic);
 
        /*
-        * If not a DLZ zone, decide whether to allow this transfer.
+        * If not a DLZ zone or we are falling back to the view's transfer
+        * ACL, decide whether to allow this transfer.
         */
-       if (!is_dlz) {
+       if (!is_dlz || useviewacl) {
+               dns_acl_t *acl;
+
                ns_client_aclmsg("zone transfer", question_name, reqtype,
                                 client->view->rdclass, msg, sizeof(msg));
-               CHECK(ns_client_checkacl(client, NULL, msg,
-                                        dns_zone_getxfracl(zone),
-                                        true, ISC_LOG_ERROR));
+               if (useviewacl) {
+                       acl = client->view->transferacl;
+               } else {
+                       acl = dns_zone_getxfracl(zone);
+               }
+               CHECK(ns_client_checkacl(client, NULL, msg, acl, true,
+                                        ISC_LOG_ERROR));
        }
 
        /*
@@ -958,8 +970,9 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
        /*
         * Get a dynamically allocated copy of the current SOA.
         */
-       if (is_dlz)
+       if (is_dlz) {
                dns_db_currentversion(db, &ver);
+       }
 
        CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS,
                                    &current_soa_tuple));