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)
* 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
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;
isc_stats_t * adbstats;
isc_stats_t * resstats;
dns_stats_t * resquerystats;
- bool cacheshared;
+ bool cacheshared;
/* Configurable data. */
dns_tsig_keyring_t * statickeys;
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;
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;
*/
dns_acl_t * matchclients;
dns_acl_t * matchdestinations;
- bool matchrecursiveonly;
+ bool matchrecursiveonly;
/* Locked by themselves. */
isc_refcount_t references;
/* 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);
}
#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
"crypto failure", /*%< 65 */
"disc quota", /*%< 66 */
"disc full", /*%< 67 */
+ "default", /*%< 68 */
};
static const char *identifier[ISC_R_NRESULTS] = {
"ISC_R_CRYPTOFAILURE",
"ISC_R_DISCQUOTA",
"ISC_R_DISCFULL",
+ "ISC_R_DEFAULT",
};
#define ISC_RESULT_RESULTSET 2
bool is_poll = false;
bool is_dlz = false;
bool is_ixfr = false;
+ bool useviewacl = false;
uint32_t begin_serial = 0, current_serial;
switch (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];
_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 {
/*
"%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));
}
/*
/*
* 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,
¤t_soa_tuple));