Commit e7220c9b authored by Evan Hunt's avatar Evan Hunt
Browse files

3129. [bug] Named could crash on 'rndc reconfig' when

			allow-new-zones was set to yes and named ACLs
			were used, [RT #22739]
parent df3b71f7
3129. [bug] Named could crash on 'rndc reconfig' when
allow-new-zones was set to yes and named ACLs
were used, [RT #22739]
3128. [func] Inserting an NSEC3PARAM via dynamic update in an
auto-dnssec zone that has not been signed yet
will cause it to be signed with the specified NSEC3
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: globals.h,v 1.89 2010/09/15 12:07:55 marka Exp $ */
/* $Id: globals.h,v 1.90 2011/06/17 07:05:01 each Exp $ */
#ifndef NAMED_GLOBALS_H
#define NAMED_GLOBALS_H 1
......@@ -26,6 +26,7 @@
#include <isc/log.h>
#include <isc/net.h>
#include <isccfg/aclconf.h>
#include <isccfg/cfg.h>
#include <dns/zone.h>
......@@ -102,6 +103,7 @@ EXTERN const char * lwresd_g_resolvconffile INIT("/etc"
EXTERN isc_boolean_t ns_g_conffileset INIT(ISC_FALSE);
EXTERN isc_boolean_t lwresd_g_useresolvconf INIT(ISC_FALSE);
EXTERN isc_uint16_t ns_g_udpsize INIT(4096);
EXTERN cfg_aclconfctx_t * ns_g_aclconfctx INIT(NULL);
/*
* Initial resource limits.
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: server.c,v 1.611 2011/03/21 18:38:39 each Exp $ */
/* $Id: server.c,v 1.612 2011/06/17 07:05:01 each Exp $ */
/*! \file */
......@@ -210,7 +210,7 @@ struct cfg_context {
isc_mem_t * mctx;
cfg_obj_t * config;
cfg_parser_t * parser;
cfg_aclconfctx_t actx;
cfg_aclconfctx_t * actx;
};
/*
......@@ -302,7 +302,7 @@ static void
end_reserved_dispatches(ns_server_t *server, isc_boolean_t all);
static void
cfgctx_destroy(void **cfgp);
newzone_cfgctx_destroy(void **cfgp);
/*%
* Configure a single view ACL at '*aclp'. Get its configuration from
......@@ -1738,9 +1738,9 @@ configure_view(dns_view_t *view, cfg_parser_t* parser,
if (config != NULL)
cfg_obj_attach(config, &cfg->config);
cfg_parser_attach(parser, &cfg->parser);
cfg_aclconfctx_clone(actx, &cfg->actx);
cfg_aclconfctx_attach(actx, &cfg->actx);
}
dns_view_setnewzones(view, allow, cfg, cfgctx_destroy);
dns_view_setnewzones(view, allow, cfg, newzone_cfgctx_destroy);
}
/*
......@@ -4179,7 +4179,6 @@ static isc_result_t
load_configuration(const char *filename, ns_server_t *server,
isc_boolean_t first_time)
{
cfg_aclconfctx_t aclconfctx;
cfg_obj_t *config = NULL, *bindkeys = NULL;
cfg_parser_t *conf_parser = NULL, *bindkeys_parser = NULL;
const cfg_listelt_t *element;
......@@ -4208,7 +4207,6 @@ load_configuration(const char *filename, ns_server_t *server,
unsigned int maxsocks;
ns_cache_t *nsc;
cfg_aclconfctx_init(&aclconfctx);
ISC_LIST_INIT(viewlist);
ISC_LIST_INIT(builtin_viewlist);
ISC_LIST_INIT(cachelist);
......@@ -4217,6 +4215,11 @@ load_configuration(const char *filename, ns_server_t *server,
result = isc_task_beginexclusive(server->task);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
/* Create the ACL configuration context */
if (ns_g_aclconfctx != NULL)
cfg_aclconfctx_detach(&ns_g_aclconfctx);
CHECK(cfg_aclconfctx_create(ns_g_mctx, &ns_g_aclconfctx));
/*
* Parse the global default pseudo-config file.
*/
......@@ -4367,8 +4370,9 @@ load_configuration(const char *filename, ns_server_t *server,
else
isc_quota_soft(&server->recursionquota, 0);
CHECK(configure_view_acl(NULL, config, "blackhole", NULL, &aclconfctx,
ns_g_mctx, &server->blackholeacl));
CHECK(configure_view_acl(NULL, config, "blackhole", NULL,
ns_g_aclconfctx, ns_g_mctx,
&server->blackholeacl));
if (server->blackholeacl != NULL)
dns_dispatchmgr_setblackhole(ns_g_dispatchmgr,
server->blackholeacl);
......@@ -4378,7 +4382,7 @@ load_configuration(const char *filename, ns_server_t *server,
INSIST(result == ISC_R_SUCCESS);
server->aclenv.match_mapped = cfg_obj_asboolean(obj);
CHECKM(ns_statschannels_configure(ns_g_server, config, &aclconfctx),
CHECKM(ns_statschannels_configure(ns_g_server, config, ns_g_aclconfctx),
"configuring statistics server(s)");
/*
......@@ -4508,8 +4512,8 @@ load_configuration(const char *filename, ns_server_t *server,
if (clistenon != NULL) {
/* check return code? */
(void)ns_listenlist_fromconfig(clistenon, config,
&aclconfctx, ns_g_mctx,
&listenon);
ns_g_aclconfctx,
ns_g_mctx, &listenon);
} else if (!ns_g_lwresdonly) {
/*
* Not specified, use default.
......@@ -4535,8 +4539,8 @@ load_configuration(const char *filename, ns_server_t *server,
if (clistenon != NULL) {
/* check return code? */
(void)ns_listenlist_fromconfig(clistenon, config,
&aclconfctx, ns_g_mctx,
&listenon);
ns_g_aclconfctx,
ns_g_mctx, &listenon);
} else if (!ns_g_lwresdonly) {
isc_boolean_t enable;
/*
......@@ -4647,7 +4651,7 @@ load_configuration(const char *filename, ns_server_t *server,
INSIST(view != NULL);
CHECK(configure_view(view, conf_parser, config, vconfig,
&cachelist, bindkeys,
ns_g_mctx, &aclconfctx, ISC_TRUE));
ns_g_mctx, ns_g_aclconfctx, ISC_TRUE));
dns_view_freeze(view);
dns_view_detach(&view);
}
......@@ -4666,7 +4670,7 @@ load_configuration(const char *filename, ns_server_t *server,
CHECK(create_view(NULL, &viewlist, &view));
CHECK(configure_view(view, conf_parser, config, NULL,
&cachelist, bindkeys,
ns_g_mctx, &aclconfctx, ISC_TRUE));
ns_g_mctx, ns_g_aclconfctx, ISC_TRUE));
dns_view_freeze(view);
dns_view_detach(&view);
}
......@@ -4686,7 +4690,7 @@ load_configuration(const char *filename, ns_server_t *server,
CHECK(create_view(vconfig, &builtin_viewlist, &view));
CHECK(configure_view(view, conf_parser, config, vconfig,
&cachelist, bindkeys,
ns_g_mctx, &aclconfctx, ISC_FALSE));
ns_g_mctx, ns_g_aclconfctx, ISC_FALSE));
dns_view_freeze(view);
dns_view_detach(&view);
view = NULL;
......@@ -4727,7 +4731,7 @@ load_configuration(const char *filename, ns_server_t *server,
* Bind the control port(s).
*/
CHECKM(ns_controls_configure(ns_g_server->controls, config,
&aclconfctx),
ns_g_aclconfctx),
"binding control channel(s)");
/*
......@@ -4969,8 +4973,6 @@ load_configuration(const char *filename, ns_server_t *server,
if (v6portset != NULL)
isc_portset_destroy(ns_g_mctx, &v6portset);
cfg_aclconfctx_clear(&aclconfctx);
if (conf_parser != NULL) {
if (config != NULL)
cfg_obj_destroy(conf_parser, &config);
......@@ -5181,6 +5183,9 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
end_reserved_dispatches(server, ISC_TRUE);
cleanup_session_key(server, server->mctx);
if (ns_g_aclconfctx != NULL)
cfg_aclconfctx_detach(&ns_g_aclconfctx);
cfg_obj_destroy(ns_g_parser, &ns_g_config);
cfg_parser_destroy(&ns_g_parser);
......@@ -7320,7 +7325,7 @@ ns_server_add_zone(ns_server_t *server, char *args) {
/* Mark view unfrozen so that zone can be added */
dns_view_thaw(view);
result = configure_zone(cfg->config, parms, vconfig,
server->mctx, view, &cfg->actx, ISC_FALSE);
server->mctx, view, cfg->actx, ISC_FALSE);
dns_view_freeze(view);
if (result != ISC_R_SUCCESS) {
goto cleanup;
......@@ -7569,23 +7574,22 @@ ns_server_del_zone(ns_server_t *server, char *args) {
}
static void
cfgctx_destroy(void **cfgp) {
newzone_cfgctx_destroy(void **cfgp) {
struct cfg_context *cfg;
isc_mem_t *mctx;
REQUIRE(cfgp != NULL && *cfgp != NULL);
cfg = *cfgp;
mctx = cfg->mctx;
cfg->mctx = NULL;
if (cfg->actx != NULL)
cfg_aclconfctx_detach(&cfg->actx);
if (cfg->parser != NULL) {
if (cfg->config != NULL)
cfg_obj_destroy(cfg->parser, &cfg->config);
cfg_parser_destroy(&cfg->parser);
}
cfg_aclconfctx_clear(&cfg->actx);
isc_mem_put(mctx, cfg, sizeof(*cfg));
isc_mem_detach(&mctx);
isc_mem_putanddetach(&cfg->mctx, cfg, sizeof(*cfg));
*cfgp = NULL;
}
......@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: named2.conf,v 1.3 2010/09/24 05:09:03 marka Exp $ */
/* $Id: named2.conf,v 1.4 2011/06/17 07:05:01 each Exp $ */
controls { /* empty */ };
......@@ -48,3 +48,15 @@ view external {
file "../../common/root.hint";
};
};
# This view is only here to test that configuration context is cleaned
# up correctly when using multiple named ACLs (regression test for RT #22739)
acl match { none; };
acl nobody { none; };
view extra {
match-clients { match; };
allow-new-zones yes;
allow-transfer { nobody; };
allow-query { nobody; };
allow-recursion { nobody; };
};
......@@ -14,7 +14,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: tests.sh,v 1.4 2010/09/24 05:09:03 marka Exp $
# $Id: tests.sh,v 1.5 2011/06/17 07:05:01 each Exp $
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
......@@ -147,5 +147,14 @@ n=`expr $n + 1`
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I:ensure the configuration context is cleaned up correctly ($n)"
ret=0
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reconfig > /dev/null 2>&1 || ret=1
sleep 5
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 status > /dev/null 2>&1 || ret=1
n=`expr $n + 1`
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I:exit status: $status"
exit $status
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: check.c,v 1.132 2011/05/07 05:55:17 each Exp $ */
/* $Id: check.c,v 1.133 2011/06/17 07:05:02 each Exp $ */
/*! \file */
......@@ -2098,7 +2098,7 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
isc_symtab_t *symtab = NULL;
isc_result_t result = ISC_R_SUCCESS;
isc_result_t tresult = ISC_R_SUCCESS;
cfg_aclconfctx_t actx;
cfg_aclconfctx_t *actx = NULL;
const cfg_obj_t *obj;
const cfg_obj_t *options = NULL;
isc_boolean_t enablednssec, enablevalidation;
......@@ -2118,7 +2118,7 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
if (tresult != ISC_R_SUCCESS)
return (ISC_R_NOMEMORY);
cfg_aclconfctx_init(&actx);
cfg_aclconfctx_create(mctx, &actx);
if (voptions != NULL)
(void)cfg_map_get(voptions, "zone", &zones);
......@@ -2133,7 +2133,7 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
const cfg_obj_t *zone = cfg_listelt_value(element);
tresult = check_zoneconf(zone, voptions, config, symtab,
vclass, &actx, logctx, mctx);
vclass, actx, logctx, mctx);
if (tresult != ISC_R_SUCCESS)
result = ISC_R_FAILURE;
}
......@@ -2299,25 +2299,25 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
if (tresult != ISC_R_SUCCESS)
result = tresult;
tresult = check_viewacls(&actx, voptions, config, logctx, mctx);
tresult = check_viewacls(actx, voptions, config, logctx, mctx);
if (tresult != ISC_R_SUCCESS)
result = tresult;
tresult = check_recursionacls(&actx, voptions, viewname,
tresult = check_recursionacls(actx, voptions, viewname,
config, logctx, mctx);
if (tresult != ISC_R_SUCCESS)
result = tresult;
tresult = check_filteraaaa(&actx, voptions, viewname, config,
tresult = check_filteraaaa(actx, voptions, viewname, config,
logctx, mctx);
if (tresult != ISC_R_SUCCESS)
result = tresult;
tresult = check_dns64(&actx, voptions, config, logctx, mctx);
tresult = check_dns64(actx, voptions, config, logctx, mctx);
if (tresult != ISC_R_SUCCESS)
result = tresult;
cfg_aclconfctx_clear(&actx);
cfg_aclconfctx_detach(&actx);
return (result);
}
......@@ -2474,7 +2474,7 @@ bind9_check_controls(const cfg_obj_t *config, isc_log_t *logctx,
isc_mem_t *mctx)
{
isc_result_t result = ISC_R_SUCCESS, tresult;
cfg_aclconfctx_t actx;
cfg_aclconfctx_t *actx = NULL;
const cfg_listelt_t *element, *element2;
const cfg_obj_t *allow;
const cfg_obj_t *control;
......@@ -2495,7 +2495,7 @@ bind9_check_controls(const cfg_obj_t *config, isc_log_t *logctx,
(void)cfg_map_get(config, "key", &keylist);
cfg_aclconfctx_init(&actx);
cfg_aclconfctx_create(mctx, &actx);
/*
* INET: Check allow clause.
......@@ -2515,7 +2515,7 @@ bind9_check_controls(const cfg_obj_t *config, isc_log_t *logctx,
control = cfg_listelt_value(element2);
allow = cfg_tuple_get(control, "allow");
tresult = cfg_acl_fromconfig(allow, config, logctx,
&actx, mctx, 0, &acl);
actx, mctx, 0, &acl);
if (acl != NULL)
dns_acl_detach(&acl);
if (tresult != ISC_R_SUCCESS)
......@@ -2562,7 +2562,7 @@ bind9_check_controls(const cfg_obj_t *config, isc_log_t *logctx,
result = tresult;
}
}
cfg_aclconfctx_clear(&actx);
cfg_aclconfctx_detach(&actx);
return (result);
}
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: acl.c,v 1.53 2009/01/17 23:47:42 tbox Exp $ */
/* $Id: acl.c,v 1.54 2011/06/17 07:05:02 each Exp $ */
/*! \file */
......@@ -99,6 +99,7 @@ static isc_result_t
dns_acl_anyornone(isc_mem_t *mctx, isc_boolean_t neg, dns_acl_t **target) {
isc_result_t result;
dns_acl_t *acl = NULL;
result = dns_acl_create(mctx, 0, &acl);
if (result != ISC_R_SUCCESS)
return (result);
......@@ -341,7 +342,6 @@ dns_acl_merge(dns_acl_t *dest, dns_acl_t *source, isc_boolean_t pos)
}
}
/*
* Merge the iptables. Make sure the destination ACL's
* node_count value is set correctly afterward.
......@@ -439,6 +439,7 @@ dns_aclelement_match(const isc_netaddr_t *reqaddr,
void
dns_acl_attach(dns_acl_t *source, dns_acl_t **target) {
REQUIRE(DNS_ACL_VALID(source));
isc_refcount_increment(&source->refcount, NULL);
*target = source;
}
......@@ -446,6 +447,9 @@ dns_acl_attach(dns_acl_t *source, dns_acl_t **target) {
static void
destroy(dns_acl_t *dacl) {
unsigned int i;
INSIST(!ISC_LINK_LINKED(dacl, nextincache));
for (i = 0; i < dacl->length; i++) {
dns_aclelement_t *de = &dacl->elements[i];
if (de->type == dns_aclelementtype_keyname) {
......@@ -470,7 +474,9 @@ void
dns_acl_detach(dns_acl_t **aclp) {
dns_acl_t *acl = *aclp;
unsigned int refs;
REQUIRE(DNS_ACL_VALID(acl));
isc_refcount_decrement(&acl->refcount, &refs);
if (refs == 0)
destroy(acl);
......@@ -590,6 +596,7 @@ dns_acl_isinsecure(const dns_acl_t *a) {
isc_result_t
dns_aclenv_init(isc_mem_t *mctx, dns_aclenv_t *env) {
isc_result_t result;
env->localhost = NULL;
env->localnets = NULL;
result = dns_acl_create(mctx, 0, &env->localhost);
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: acl.h,v 1.33 2009/01/17 23:47:43 tbox Exp $ */
/* $Id: acl.h,v 1.34 2011/06/17 07:05:02 each Exp $ */
#ifndef DNS_ACL_H
#define DNS_ACL_H 1
......@@ -145,9 +145,26 @@ dns_acl_merge(dns_acl_t *dest, dns_acl_t *source, isc_boolean_t pos);
void
dns_acl_attach(dns_acl_t *source, dns_acl_t **target);
/*%<
* Attach to acl 'source'.
*
* Requires:
*\li 'source' to be a valid acl.
*\li 'target' to be non NULL and '*target' to be NULL.
*/
void
dns_acl_detach(dns_acl_t **aclp);
/*%<
* Detach the acl. On final detach the acl must not be linked on any
* list.
*
* Requires:
*\li '*aclp' to be a valid acl.
*
* Insists:
*\li '*aclp' is not linked on final detach.
*/
isc_boolean_t
dns_acl_isinsecure(const dns_acl_t *a);
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: aclconf.c,v 1.29 2010/08/13 23:47:03 tbox Exp $ */
/* $Id: aclconf.c,v 1.30 2011/06/17 07:05:02 each Exp $ */
#include <config.h>
......@@ -33,39 +33,70 @@
#define LOOP_MAGIC ISC_MAGIC('L','O','O','P')
void
cfg_aclconfctx_init(cfg_aclconfctx_t *ctx) {
ISC_LIST_INIT(ctx->named_acl_cache);
isc_result_t
cfg_aclconfctx_create(isc_mem_t *mctx, cfg_aclconfctx_t **ret) {
isc_result_t result;
cfg_aclconfctx_t *actx;
REQUIRE(mctx != NULL);
REQUIRE(ret != NULL && *ret == NULL);
actx = isc_mem_get(mctx, sizeof(*actx));
if (actx == NULL)
return (ISC_R_NOMEMORY);
result = isc_refcount_init(&actx->references, 1);
if (result != ISC_R_SUCCESS)
goto cleanup;
actx->mctx = NULL;
isc_mem_attach(mctx, &actx->mctx);
ISC_LIST_INIT(actx->named_acl_cache);
*ret = actx;
return (ISC_R_SUCCESS);
cleanup:
isc_mem_put(mctx, actx, sizeof(*actx));
return (result);
}
void
cfg_aclconfctx_clear(cfg_aclconfctx_t *ctx) {
dns_acl_t *dacl, *next;
cfg_aclconfctx_attach(cfg_aclconfctx_t *src, cfg_aclconfctx_t **dest) {
REQUIRE(src != NULL);
REQUIRE(dest != NULL && *dest == NULL);
for (dacl = ISC_LIST_HEAD(ctx->named_acl_cache);
dacl != NULL;
dacl = next)
{
next = ISC_LIST_NEXT(dacl, nextincache);
dns_acl_detach(&dacl);
}
isc_refcount_increment(&src->references, NULL);
*dest = src;
}
void
cfg_aclconfctx_clone(cfg_aclconfctx_t *src, cfg_aclconfctx_t *dest) {
cfg_aclconfctx_detach(cfg_aclconfctx_t **actxp) {
cfg_aclconfctx_t *actx;
dns_acl_t *dacl, *next;
REQUIRE(src != NULL && dest != NULL);
cfg_aclconfctx_init(dest);
for (dacl = ISC_LIST_HEAD(src->named_acl_cache);
dacl != NULL;
dacl = next)
{
dns_acl_t *copy;
next = ISC_LIST_NEXT(dacl, nextincache);
dns_acl_attach(dacl, &copy);
ISC_LIST_APPEND(dest->named_acl_cache, copy, nextincache);
isc_mem_t *mctx;
unsigned int refs;
REQUIRE(actxp != NULL && *actxp != NULL);
actx = *actxp;
mctx = actx->mctx;
isc_refcount_decrement(&actx->references, &refs);
if (refs == 0) {
for (dacl = ISC_LIST_HEAD(actx->named_acl_cache);
dacl != NULL;
dacl = next)
{
next = ISC_LIST_NEXT(dacl, nextincache);
ISC_LIST_UNLINK(actx->named_acl_cache, dacl,
nextincache);
dns_acl_detach(&dacl);
}
isc_mem_putanddetach(&actx->mctx, actx, sizeof(*actx));
}
*actxp = NULL;
}
/*
......
......@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: aclconf.h,v 1.12 2010/08/13 23:47:04 tbox Exp $ */
/* $Id: aclconf.h,v 1.13 2011/06/17 07:05:02 each Exp $ */
#ifndef ISCCFG_ACLCONF_H
#define ISCCFG_ACLCONF_H 1
......@@ -28,7 +28,8 @@
typedef struct cfg_aclconfctx {
ISC_LIST(dns_acl_t) named_acl_cache;
ISC_LIST(dns_iptable_t) named_iptable_cache;
isc_mem_t *mctx;
isc_refcount_t references;
} cfg_aclconfctx_t;
/***
......@@ -37,22 +38,23 @@ typedef struct cfg_aclconfctx {
ISC_LANG_BEGINDECLS
void
cfg_aclconfctx_init(cfg_aclconfctx_t *ctx);
isc_result_t
cfg_aclconfctx_create(isc_mem_t *mctx, cfg_aclconfctx_t **ret);
/*
* Initialize an ACL configuration context.
* Creates and initializes an ACL configuration context.
*/
void
cfg_aclconfctx_clone(cfg_aclconfctx_t *src, cfg_aclconfctx_t *dest);
cfg_aclconfctx_detach(cfg_aclconfctx_t **actxp);
/*
* Copy the contents of one ACL configuration context into another.
* Removes a reference to an ACL configuration context; when references
* reaches zero, clears the contents and deallocate the structure.
*/
void
cfg_aclconfctx_clear(cfg_aclconfctx_t *ctx);
cfg_aclconfctx_attach(cfg_aclconfctx_t *src, cfg_aclconfctx_t **dest);
/*
* Clear the contents of an ACL configuration context.
* Attaches a pointer to an existing ACL configuration context.
*/
isc_result_t
......
Supports Markdown
0% or . <