From: Wouter Wijngaards Date: Wed, 30 May 2018 09:33:21 +0000 (+0000) Subject: - Patch from Syzdek: Add ability to ignore RD bit and treat all X-Git-Tag: release-1.7.2rc1~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8d1af17449a6be5fbca4f0b4702968c5f03536f1;p=thirdparty%2Funbound.git - Patch from Syzdek: Add ability to ignore RD bit and treat all requests as if the RD bit is set. git-svn-id: file:///svn/unbound/trunk@4701 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/daemon/acl_list.c b/daemon/acl_list.c index f7d71b9fd..c16a920d9 100644 --- a/daemon/acl_list.c +++ b/daemon/acl_list.c @@ -111,6 +111,8 @@ acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2, control = acl_refuse_non_local; else if(strcmp(s2, "allow_snoop") == 0) control = acl_allow_snoop; + else if(strcmp(s2, "allow_setrd") == 0) + control = acl_allow_setrd; else { log_err("access control type %s unknown", str); return 0; diff --git a/daemon/acl_list.h b/daemon/acl_list.h index d0d42bfae..3a3b94bc5 100644 --- a/daemon/acl_list.h +++ b/daemon/acl_list.h @@ -63,7 +63,9 @@ enum acl_access { /** allow full access for recursion (+RD) queries */ acl_allow, /** allow full access for all queries, recursion and cache snooping */ - acl_allow_snoop + acl_allow_snoop, + /** allow full access for recursion queries and set RD flag regardless of request */ + acl_allow_setrd }; /** diff --git a/daemon/worker.c b/daemon/worker.c index 6121c7dbe..44a989a4e 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -1350,6 +1350,13 @@ worker_handle_request(struct comm_point* c, void* arg, int error, return ret; } + /* If this request does not have the recursion bit set, verify + * ACLs allow the recursion bit to be treated as set. */ + if(!(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) && + acl == acl_allow_setrd ) { + LDNS_RD_SET(sldns_buffer_begin(c->buffer)); + } + /* If this request does not have the recursion bit set, verify * ACLs allow the snooping. */ if(!(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) && diff --git a/doc/Changelog b/doc/Changelog index ff05afd92..d81c6ffa2 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,7 @@ +30 May 2018: Wouter + - Patch from Syzdek: Add ability to ignore RD bit and treat all + requests as if the RD bit is set. + 29 May 2018: Wouter - in compat/arc4random call getentropy_urandom when getentropy fails with ENOSYS. diff --git a/doc/example.conf.in b/doc/example.conf.in index fae36b918..38d44e722 100644 --- a/doc/example.conf.in +++ b/doc/example.conf.in @@ -223,7 +223,8 @@ server: # to this server. Specify classless netblocks with /size and action. # By default everything is refused, except for localhost. # Choose deny (drop message), refuse (polite error reply), - # allow (recursive ok), allow_snoop (recursive and nonrecursive ok) + # allow (recursive ok), allow_setrd (recursive ok, rd bit is forced on), + # allow_snoop (recursive and nonrecursive ok) # deny_non_local (drop queries unless can be answered from local-data) # refuse_non_local (like deny_non_local but polite error reply). # access-control: 0.0.0.0/0 refuse diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in index 182dfd45d..de1d5fa76 100644 --- a/doc/unbound.conf.5.in +++ b/doc/unbound.conf.5.in @@ -469,7 +469,8 @@ Default is yes. .B access\-control: \fI The netblock is given as an IP4 or IP6 address with /size appended for a classless network block. The action can be \fIdeny\fR, \fIrefuse\fR, -\fIallow\fR, \fIallow_snoop\fR, \fIdeny_non_local\fR or \fIrefuse_non_local\fR. +\fIallow\fR, \fIallow_setrd\fR, \fIallow_snoop\fR, \fIdeny_non_local\fR or +\fIrefuse_non_local\fR. The most specific netblock match is used, if none match \fIdeny\fR is used. .IP The action \fIdeny\fR stops queries from hosts from that netblock. @@ -488,6 +489,15 @@ in the reply. This supports normal operations where nonrecursive queries are made for the authoritative data. For nonrecursive queries any replies from the dynamic cache are refused. .IP +The \fIallow_setrd\fR action ignores the recursion desired (RD) bit and +treats all requests as if the recursion desired bit is set. Note that this +behavior violates RFC 1034 which states that a name server should never perform +recursive service unless asked via the RD bit since this interferes with +trouble shooting of name servers and their databases. This prohibited behavior +may be useful if another DNS server must forward requests for specific +zones to a resolver DNS server, but only supports stub domains and +sends queries to the resolver DNS server with the RD bit cleared. +.IP The action \fIallow_snoop\fR gives nonrecursive access too. This give both recursive and non recursive access. The name \fIallow_snoop\fR refers to cache snooping, a technique to use nonrecursive queries to examine diff --git a/util/configparser.c b/util/configparser.c index 70fc4e0a7..d0ede0851 100644 --- a/util/configparser.c +++ b/util/configparser.c @@ -3836,10 +3836,11 @@ yyreduce: strcmp((yyvsp[0].str), "deny_non_local")!=0 && strcmp((yyvsp[0].str), "refuse_non_local")!=0 && strcmp((yyvsp[0].str), "allow")!=0 && + strcmp((yyvsp[0].str), "allow_setrd")!=0 && strcmp((yyvsp[0].str), "allow_snoop")!=0) { yyerror("expected deny, refuse, deny_non_local, " - "refuse_non_local, allow or allow_snoop " - "in access control action"); + "refuse_non_local, allow, allow_setrd or " + "allow_snoop in access control action"); } else { if(!cfg_str2list_insert(&cfg_parser->cfg->acls, (yyvsp[-1].str), (yyvsp[0].str))) fatal_exit("out of memory adding acl"); diff --git a/util/configparser.y b/util/configparser.y index aa6b71d7a..1e7ad073a 100644 --- a/util/configparser.y +++ b/util/configparser.y @@ -1314,11 +1314,12 @@ server_access_control: VAR_ACCESS_CONTROL STRING_ARG STRING_ARG if(strcmp($3, "deny")!=0 && strcmp($3, "refuse")!=0 && strcmp($3, "deny_non_local")!=0 && strcmp($3, "refuse_non_local")!=0 && + strcmp($3, "allow_setrd")!=0 && strcmp($3, "allow")!=0 && strcmp($3, "allow_snoop")!=0) { yyerror("expected deny, refuse, deny_non_local, " - "refuse_non_local, allow or allow_snoop " - "in access control action"); + "refuse_non_local, allow, allow_setrd or " + "allow_snoop in access control action"); } else { if(!cfg_str2list_insert(&cfg_parser->cfg->acls, $2, $3)) fatal_exit("out of memory adding acl");