diff --git a/bin/named/client.c b/bin/named/client.c index bd5262ed5e..5221dce8c4 100644 --- a/bin/named/client.c +++ b/bin/named/client.c @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -268,6 +269,9 @@ ns_client_send(ns_client_t *client) { CTRACE("send"); + if ((client->attributes & NS_CLIENTATTR_RA) != 0) + client->message->flags |= DNS_MESSAGEFLAG_RA; + data = isc_mempool_get(client->sendbufs); if (data == NULL) { CTRACE("no buffers available"); @@ -475,6 +479,7 @@ client_request(isc_task_t *task, isc_event_t *event) { isc_buffer_t *buffer; dns_view_t *view; dns_rdataset_t *opt; + isc_boolean_t ra; /* Recursion available. */ REQUIRE(event != NULL); client = event->arg; @@ -597,6 +602,33 @@ client_request(isc_task_t *task, isc_event_t *event) { ns_client_error(client, DNS_R_REFUSED); return; } + + /* + * Decide whether recursive service is available to this client. + * We do this here rather than in the query code so that we can + * set the RA bit correctly on all kinds of responses, not just + * responses to ordinary queries. + */ + if (client->view->resolver == NULL) { + ra = ISC_FALSE; + } else { + ra = ISC_TRUE; + (void) dns_c_ctx_getrecursion(ns_g_confctx, &ra); + if (ra == ISC_TRUE) { + dns_c_ipmatchlist_t *acl = NULL; + /* XXX ACL should be view specific. */ + dns_c_ctx_getrecursionacl(ns_g_confctx, &acl); + /* XXX this will log too much too early */ + result = dns_aml_checkrequest(client->signer, + ns_client_getsockaddr(client), + ns_g_confctx->acls, "recursion", + acl, NULL, ISC_TRUE); + if (result != DNS_R_SUCCESS) + ra = ISC_FALSE; + } + } + if (ra == ISC_TRUE) + client->attributes |= NS_CLIENTATTR_RA; /* * Dispatch the request. diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h index 2223106dda..334ab704ee 100644 --- a/bin/named/include/named/client.h +++ b/bin/named/include/named/client.h @@ -81,6 +81,7 @@ struct ns_client { (c)->magic == NS_CLIENT_MAGIC) #define NS_CLIENTATTR_TCP 0x01 +#define NS_CLIENTATTR_RA 0x02 /* Client gets recusive service */ /* * Note! These ns_client_ routines MUST be called ONLY from the client's diff --git a/bin/named/query.c b/bin/named/query.c index 67a624e7c5..abd822714c 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -2562,26 +2562,18 @@ ns_query_start(ns_client_t *client) { client->query.attributes &= ~(NS_QUERYATTR_RECURSIONOK|NS_QUERYATTR_CACHEOK); set_ra = ISC_FALSE; - } else if ((message->flags & DNS_MESSAGEFLAG_RD) == 0 || - client->view->resolver == NULL) { + } else if ((client->attributes & NS_CLIENTATTR_RA) == 0 || + (message->flags & DNS_MESSAGEFLAG_RD) == 0) { /* - * If the client doesn't want recursion, or we don't have - * a resolver, turn recursion off. + * If the client isn't allowed to recurse (due to + * "recursion no", the allow-recursion ACL, or the + * lack of a resolver in this view), or if it + * doesn't want recursion, turn recursion off. */ client->query.attributes &= ~NS_QUERYATTR_RECURSIONOK; set_ra = ISC_FALSE; } - /* - * XXXRTH Deal with allow-query and allow-recursion here. - */ - - /* - * RA flag. - */ - if (set_ra) - message->flags |= DNS_MESSAGEFLAG_RA; - /* * Get the question name. */ diff --git a/bin/named/xfrout.c b/bin/named/xfrout.c index 3209013bca..31dd1b934c 100644 --- a/bin/named/xfrout.c +++ b/bin/named/xfrout.c @@ -15,7 +15,7 @@ * SOFTWARE. */ - /* $Id: xfrout.c,v 1.27 1999/12/10 18:14:49 gson Exp $ */ + /* $Id: xfrout.c,v 1.28 1999/12/10 23:58:03 gson Exp $ */ #include @@ -1132,6 +1132,8 @@ sendstream(xfrout_ctx_t *xfr) msg->id = xfr->id; msg->rcode = dns_rcode_noerror; msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA; + if ((xfr->client->attributes & NS_CLIENTATTR_RA) != 0) + msg->flags |= DNS_MESSAGEFLAG_RA; msg->tsigkey = xfr->tsigkey; msg->querytsig = xfr->lasttsig;