+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
* 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
#include <isc/log.h>
#include <isc/net.h>
+#include <isccfg/aclconf.h>
#include <isccfg/cfg.h>
#include <dns/zone.h>
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.
* 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 */
isc_mem_t * mctx;
cfg_obj_t * config;
cfg_parser_t * parser;
- cfg_aclconfctx_t actx;
+ cfg_aclconfctx_t * actx;
};
/*
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
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);
}
/*
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;
unsigned int maxsocks;
ns_cache_t *nsc;
- cfg_aclconfctx_init(&aclconfctx);
ISC_LIST_INIT(viewlist);
ISC_LIST_INIT(builtin_viewlist);
ISC_LIST_INIT(cachelist);
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.
*/
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);
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)");
/*
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.
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;
/*
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);
}
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);
}
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;
* Bind the control port(s).
*/
CHECKM(ns_controls_configure(ns_g_server->controls, config,
- &aclconfctx),
+ ns_g_aclconfctx),
"binding control channel(s)");
/*
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);
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);
/* 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;
}
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;
}
* 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 */ };
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; };
+};
# 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
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
* 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 */
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;
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);
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;
}
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);
}
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;
(void)cfg_map_get(config, "key", &keylist);
- cfg_aclconfctx_init(&actx);
+ cfg_aclconfctx_create(mctx, &actx);
/*
* INET: Check allow clause.
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)
result = tresult;
}
}
- cfg_aclconfctx_clear(&actx);
+ cfg_aclconfctx_detach(&actx);
return (result);
}
* 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 */
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);
}
}
-
/*
* Merge the iptables. Make sure the destination ACL's
* node_count value is set correctly afterward.
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;
}
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) {
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);
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);
* 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
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);
* 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>
#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, ©);
- 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;
}
/*
* 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
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;
/***
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