diff --git a/daemon/remote.c b/daemon/remote.c index 8324e1901..64057a57b 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -2860,6 +2860,57 @@ do_ip_ratelimit_list(RES* ssl, struct worker* worker, char* arg) slabhash_traverse(a.infra->client_ip_rates, 0, ip_rate_list, &a); } +/** do the rpz_enable/disable command */ +static void +do_rpz_enable_disable(RES* ssl, struct worker* worker, char* arg, int enable) { + size_t nmlen; + int nmlabs; + uint8_t *nm = NULL; + struct auth_zones *az = worker->env.auth_zones; + struct auth_zone *z = NULL; + if (!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs)) + return; + if (az) { + lock_rw_rdlock(&az->lock); + z = auth_zone_find(az, nm, nmlen, LDNS_RR_CLASS_IN); + if (z) { + lock_rw_wrlock(&z->lock); + } + lock_rw_unlock(&az->lock); + } + free(nm); + if (!z) { + (void) ssl_printf(ssl, "error no auth-zone %s\n", arg); + return; + } + if (!z->rpz) { + (void) ssl_printf(ssl, "error auth-zone %s not RPZ\n", arg); + lock_rw_unlock(&z->lock); + return; + } + if (enable) { + rpz_enable(z->rpz); + } else { + rpz_disable(z->rpz); + } + lock_rw_unlock(&z->lock); + send_ok(ssl); +} + +/** do the rpz_enable command */ +static void +do_rpz_enable(RES* ssl, struct worker* worker, char* arg) +{ + do_rpz_enable_disable(ssl, worker, arg, 1); +} + +/** do the rpz_disable command */ +static void +do_rpz_disable(RES* ssl, struct worker* worker, char* arg) +{ + do_rpz_enable_disable(ssl, worker, arg, 0); +} + /** tell other processes to execute the command */ static void distribute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd) @@ -3060,6 +3111,10 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd, do_flush_bogus(ssl, worker); } else if(cmdcmp(p, "flush_negative", 14)) { do_flush_negative(ssl, worker); + } else if(cmdcmp(p, "rpz_enable", 10)) { + do_rpz_enable(ssl, worker, skipwhite(p+10)); + } else if(cmdcmp(p, "rpz_disable", 11)) { + do_rpz_disable(ssl, worker, skipwhite(p+11)); } else { (void)ssl_printf(ssl, "error unknown command '%s'\n", p); } diff --git a/doc/unbound-control.8.in b/doc/unbound-control.8.in index 97972ff27..20325abf2 100644 --- a/doc/unbound-control.8.in +++ b/doc/unbound-control.8.in @@ -305,6 +305,12 @@ Transfer the auth zone from master. The auth zone probe sequence is started, where the masters are probed to see if they have an updated zone (with the SOA serial check). And then the zone is transferred for a newer zone version. .TP +.B rpz_enable \fIzone\fR +Enable the RPZ zone if it had previously been disabled. +.TP +.B rpz_enable \fIzone\fR +Disable the RPZ zone. +.TP .B view_list_local_zones \fIview\fR \fIlist_local_zones\fR for given view. .TP diff --git a/services/rpz.c b/services/rpz.c index 13304652c..d7dd17f7e 100644 --- a/services/rpz.c +++ b/services/rpz.c @@ -963,8 +963,8 @@ rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env, for(a = az->rpz_first; a; a = a->rpz_az_next) { lock_rw_rdlock(&a->lock); r = a->rpz; - if(!r->taglist || taglist_intersect(r->taglist, - r->taglistlen, taglist, taglen)) { + if(!r->disabled && (!r->taglist || taglist_intersect(r->taglist, + r->taglistlen, taglist, taglen))) { z = rpz_find_zone(r, qinfo->qname, qinfo->qname_len, qinfo->qclass, 0, 0, 0); if(z && r->action_override == RPZ_DISABLED_ACTION) { @@ -1044,3 +1044,17 @@ rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env, return ret; } + +void rpz_enable(struct rpz* r) +{ + if(!r) + return; + r->disabled = 0; +} + +void rpz_disable(struct rpz* r) +{ + if(!r) + return; + r->disabled = 1; +} diff --git a/services/rpz.h b/services/rpz.h index 77a2db55c..d5996a6cf 100644 --- a/services/rpz.h +++ b/services/rpz.h @@ -99,6 +99,7 @@ struct rpz { int log; char* log_name; struct regional* region; + int disabled; }; /** @@ -198,4 +199,16 @@ void rpz_finish_config(struct rpz* r); enum respip_action rpz_action_to_respip_action(enum rpz_action a); +/** + * Enable RPZ + * @param r: RPZ struct to enable + */ +void rpz_enable(struct rpz* r); + +/** + * Disable RPZ + * @param r: RPZ struct to disable + */ +void rpz_disable(struct rpz* r); + #endif /* SERVICES_RPZ_H */