diff -up bind-9.3.6-P1/bin/named/controlconf.c.rh496495 bind-9.3.6-P1/bin/named/controlconf.c --- bind-9.3.6-P1/bin/named/controlconf.c.rh496495 2009-04-24 15:56:08.394902656 +0200 +++ bind-9.3.6-P1/bin/named/controlconf.c 2009-04-24 15:56:08.402901982 +0200 @@ -997,8 +997,9 @@ update_listener(ns_controls_t *cp, contr */ if (control != NULL) { allow = cfg_tuple_get(control, "allow"); - result = cfg_acl_fromconfig(allow, config, aclconfctx, - listener->mctx, &new_acl); + result = cfg_acl_fromconfig(allow, config, ns_g_lctx, + aclconfctx, listener->mctx, + &new_acl); } else { result = dns_acl_any(listener->mctx, &new_acl); } @@ -1059,8 +1060,9 @@ add_listener(ns_controls_t *cp, controll */ if (control != NULL) { allow = cfg_tuple_get(control, "allow"); - result = cfg_acl_fromconfig(allow, config, aclconfctx, - mctx, &new_acl); + result = cfg_acl_fromconfig(allow, config, ns_g_lctx, + aclconfctx, mctx, + &new_acl); } else { result = dns_acl_any(mctx, &new_acl); } diff -up bind-9.3.6-P1/bin/named/server.c.rh496495 bind-9.3.6-P1/bin/named/server.c --- bind-9.3.6-P1/bin/named/server.c.rh496495 2009-04-24 15:56:08.398901949 +0200 +++ bind-9.3.6-P1/bin/named/server.c 2009-04-24 15:56:08.454901362 +0200 @@ -229,7 +231,8 @@ configure_view_acl(const cfg_obj_t *vcon */ return (ISC_R_SUCCESS); - result = cfg_acl_fromconfig(aclobj, config, actx, mctx, aclp); + result = cfg_acl_fromconfig(aclobj, config, ns_g_lctx, actx, mctx, + aclp); return (result); } @@ -3851,7 +3871,7 @@ ns_listenelt_fromconfig(const cfg_obj_t return (result); result = cfg_acl_fromconfig(cfg_tuple_get(listener, "acl"), - config, actx, mctx, &delt->acl); + config, ns_g_lctx, actx, mctx, &delt->acl); if (result != ISC_R_SUCCESS) { ns_listenelt_destroy(delt); return (result); diff -up bind-9.3.6-P1/bin/named/zoneconf.c.rh496495 bind-9.3.6-P1/bin/named/zoneconf.c --- bind-9.3.6-P1/bin/named/zoneconf.c.rh496495 2009-04-24 15:56:08.398901949 +0200 +++ bind-9.3.6-P1/bin/named/zoneconf.c 2009-04-24 15:56:08.406902192 +0200 @@ -87,7 +87,7 @@ configure_zone_acl(const cfg_obj_t *zcon return (ISC_R_SUCCESS); } - result = cfg_acl_fromconfig(aclobj, config, actx, + result = cfg_acl_fromconfig(aclobj, config, ns_g_lctx, actx, dns_zone_getmctx(zone), &dacl); if (result != ISC_R_SUCCESS) return (result); diff -up bind-9.3.6-P1/lib/bind9/check.c.rh496495 bind-9.3.6-P1/lib/bind9/check.c --- bind-9.3.6-P1/lib/bind9/check.c.rh496495 2008-04-29 01:45:35.000000000 +0200 +++ bind-9.3.6-P1/lib/bind9/check.c 2009-04-24 16:07:36.354995442 +0200 @@ -33,12 +33,14 @@ #include <isc/symtab.h> #include <isc/util.h> +#include <dns/acl.h> #include <dns/fixedname.h> #include <dns/rdataclass.h> #include <dns/rdatatype.h> #include <dns/secalg.h> #include <isccfg/cfg.h> +#include <isccfg/aclconf.h> #include <bind9/check.h> @@ -356,6 +358,56 @@ mustbesecure(const cfg_obj_t *secure, is return (result); } +static isc_result_t +checkacl(const char *aclname, cfg_aclconfctx_t *actx, const cfg_obj_t *zconfig, + const cfg_obj_t *voptions, const cfg_obj_t *config, + isc_log_t *logctx, isc_mem_t *mctx) +{ + isc_result_t result; + const cfg_obj_t *aclobj = NULL; + const cfg_obj_t *options; + dns_acl_t *acl = NULL; + + if (zconfig != NULL) { + options = cfg_tuple_get(zconfig, "options"); + cfg_map_get(options, aclname, &aclobj); + } + if (voptions != NULL && aclobj == NULL) + cfg_map_get(voptions, aclname, &aclobj); + if (config != NULL && aclobj == NULL) { + options = NULL; + cfg_map_get(config, "options", &options); + if (options != NULL) + cfg_map_get(options, aclname, &aclobj); + } + if (aclobj == NULL) + return (ISC_R_SUCCESS); + result = cfg_acl_fromconfig(aclobj, config, logctx, actx, mctx, &acl); + if (acl != NULL) + dns_acl_detach(&acl); + return (result); +} + +static isc_result_t +check_viewacls(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions, + const cfg_obj_t *config, isc_log_t *logctx, isc_mem_t *mctx) +{ + isc_result_t result = ISC_R_SUCCESS, tresult; + int i = 0; + + static const char *acls[] = { "allow-query", "allow-query-cache", + "allow-recursion", "blackhole", "match-clients", + "match-destinations", "sortlist", NULL }; + + while (acls[i] != NULL) { + tresult = checkacl(acls[i++], actx, NULL, voptions, config, + logctx, mctx); + if (tresult != ISC_R_SUCCESS) + result = tresult; + } + return (result); +} + typedef struct { const char *name; unsigned int scale; @@ -697,6 +749,7 @@ validate_masters(const cfg_obj_t *obj, c #define HINTZONE 8 #define FORWARDZONE 16 #define DELEGATIONZONE 32 +#define CHECKACL 64 typedef struct { const char *name; @@ -706,7 +759,8 @@ typedef struct { static isc_result_t check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, const cfg_obj_t *config, isc_symtab_t *symtab, - dns_rdataclass_t defclass, isc_log_t *logctx, isc_mem_t *mctx) + dns_rdataclass_t defclass, cfg_aclconfctx_t *actx, + isc_log_t *logctx, isc_mem_t *mctx) { const char *zname; const char *typestr; @@ -722,9 +776,9 @@ check_zoneconf(const cfg_obj_t *zconfig, isc_boolean_t root = ISC_FALSE; static optionstable options[] = { - { "allow-query", MASTERZONE | SLAVEZONE | STUBZONE }, - { "allow-notify", SLAVEZONE }, - { "allow-transfer", MASTERZONE | SLAVEZONE }, + { "allow-query", MASTERZONE | SLAVEZONE | STUBZONE | CHECKACL }, + { "allow-notify", SLAVEZONE | CHECKACL }, + { "allow-transfer", MASTERZONE | SLAVEZONE | CHECKACL }, { "notify", MASTERZONE | SLAVEZONE }, { "also-notify", MASTERZONE | SLAVEZONE }, { "dialup", MASTERZONE | SLAVEZONE | STUBZONE }, @@ -747,8 +801,8 @@ check_zoneconf(const cfg_obj_t *zconfig, { "min-refresh-time", SLAVEZONE | STUBZONE }, { "sig-validity-interval", MASTERZONE }, { "zone-statistics", MASTERZONE | SLAVEZONE | STUBZONE }, - { "allow-update", MASTERZONE }, - { "allow-update-forwarding", SLAVEZONE }, + { "allow-update", MASTERZONE | CHECKACL }, + { "allow-update-forwarding", SLAVEZONE | CHECKACL }, { "file", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE }, { "ixfr-base", MASTERZONE | SLAVEZONE }, { "ixfr-tmp-file", MASTERZONE | SLAVEZONE }, @@ -851,6 +905,7 @@ check_zoneconf(const cfg_obj_t *zconfig, /* * Look for inappropriate options for the given zone type. + * Check that ACLs expand correctly. */ for (i = 0; i < sizeof(options) / sizeof(options[0]); i++) { obj = NULL; @@ -871,6 +926,15 @@ check_zoneconf(const cfg_obj_t *zconfig, "in '%s' zone '%s'", options[i].name, typestr, zname); } + obj = NULL; + if ((options[i].allowed & ztype) != 0 && + (options[i].allowed & CHECKACL) != 0) { + + tresult = checkacl(options[i].name, actx, zconfig, + voptions, config, logctx, mctx); + if (tresult != ISC_R_SUCCESS) + result = tresult; + } } /* @@ -1132,6 +1196,7 @@ check_viewconf(const cfg_obj_t *config, isc_symtab_t *symtab = NULL; isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult = ISC_R_SUCCESS; + cfg_aclconfctx_t actx; /* * Check that all zone statements are syntactically correct and @@ -1142,6 +1207,8 @@ check_viewconf(const cfg_obj_t *config, if (tresult != ISC_R_SUCCESS) return (ISC_R_NOMEMORY); + cfg_aclconfctx_init(&actx); + if (voptions != NULL) (void)cfg_map_get(voptions, "zone", &zones); else @@ -1155,7 +1222,7 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *zone = cfg_listelt_value(element); tresult = check_zoneconf(zone, voptions, config, symtab, vclass, - logctx, mctx); + &actx, logctx, mctx); if (tresult != ISC_R_SUCCESS) result = ISC_R_FAILURE; } @@ -1243,6 +1310,12 @@ check_viewconf(const cfg_obj_t *config, if (tresult != ISC_R_SUCCESS) result = tresult; + tresult = check_viewacls(&actx, voptions, config, logctx, mctx); + if (tresult != ISC_R_SUCCESS) + result = tresult; + + cfg_aclconfctx_destroy(&actx); + return (result); } diff -up bind-9.3.6-P1/lib/isccfg/aclconf.c.rh496495 bind-9.3.6-P1/lib/isccfg/aclconf.c --- bind-9.3.6-P1/lib/isccfg/aclconf.c.rh496495 2009-04-24 15:56:08.398901949 +0200 +++ bind-9.3.6-P1/lib/isccfg/aclconf.c 2009-04-24 16:06:07.779201993 +0200 @@ -76,7 +76,7 @@ get_acl_def(const cfg_obj_t *cctx, const static isc_result_t convert_named_acl(const cfg_obj_t *nameobj, const cfg_obj_t *cctx, - cfg_aclconfctx_t *ctx, isc_mem_t *mctx, + isc_log_t *lctx, cfg_aclconfctx_t *ctx, isc_mem_t *mctx, dns_acl_t **target) { isc_result_t result; @@ -92,7 +92,7 @@ convert_named_acl(const cfg_obj_t *nameo { if (strcasecmp(aclname, dacl->name) == 0) { if (ISC_MAGIC_VALID(dacl, LOOP_MAGIC)) { - cfg_obj_log(nameobj, dns_lctx, ISC_LOG_ERROR, + cfg_obj_log(nameobj, lctx, ISC_LOG_ERROR, "acl loop detected: %s", aclname); return (ISC_R_FAILURE); } @@ -103,7 +103,7 @@ convert_named_acl(const cfg_obj_t *nameo /* Not yet converted. Convert now. */ result = get_acl_def(cctx, aclname, &cacl); if (result != ISC_R_SUCCESS) { - cfg_obj_log(nameobj, dns_lctx, ISC_LOG_WARNING, + cfg_obj_log(nameobj, lctx, ISC_LOG_WARNING, "undefined ACL '%s'", aclname); return (result); } @@ -115,7 +115,7 @@ convert_named_acl(const cfg_obj_t *nameo DE_CONST(aclname, loop.name); loop.magic = LOOP_MAGIC; ISC_LIST_APPEND(ctx->named_acl_cache, &loop, nextincache); - result = cfg_acl_fromconfig(cacl, cctx, ctx, mctx, &dacl); + result = cfg_acl_fromconfig(cacl, cctx, lctx, ctx, mctx, &dacl); ISC_LIST_UNLINK(ctx->named_acl_cache, &loop, nextincache); loop.magic = 0; loop.name = NULL; @@ -130,7 +130,8 @@ convert_named_acl(const cfg_obj_t *nameo } static isc_result_t -convert_keyname(const cfg_obj_t *keyobj, isc_mem_t *mctx, dns_name_t *dnsname) { +convert_keyname(const cfg_obj_t *keyobj, isc_log_t *lctx, isc_mem_t *mctx, + dns_name_t *dnsname) { isc_result_t result; isc_buffer_t buf; dns_fixedname_t fixname; @@ -144,7 +145,7 @@ convert_keyname(const cfg_obj_t *keyobj, result = dns_name_fromtext(dns_fixedname_name(&fixname), &buf, dns_rootname, ISC_FALSE, NULL); if (result != ISC_R_SUCCESS) { - cfg_obj_log(keyobj, dns_lctx, ISC_LOG_WARNING, + cfg_obj_log(keyobj, lctx, ISC_LOG_WARNING, "key name '%s' is not a valid domain name", txtname); return (result); @@ -155,6 +156,7 @@ convert_keyname(const cfg_obj_t *keyobj, isc_result_t cfg_acl_fromconfig(const cfg_obj_t *caml, const cfg_obj_t *cctx, + isc_log_t *lctx, cfg_aclconfctx_t *ctx, isc_mem_t *mctx, dns_acl_t **target) @@ -202,13 +204,14 @@ cfg_acl_fromconfig(const cfg_obj_t *caml /* Key name */ de->type = dns_aclelementtype_keyname; dns_name_init(&de->u.keyname, NULL); - result = convert_keyname(ce, mctx, &de->u.keyname); + result = convert_keyname(ce, lctx, mctx, + &de->u.keyname); if (result != ISC_R_SUCCESS) goto cleanup; } else if (cfg_obj_islist(ce)) { /* Nested ACL */ de->type = dns_aclelementtype_nestedacl; - result = cfg_acl_fromconfig(ce, cctx, ctx, mctx, + result = cfg_acl_fromconfig(ce, cctx, lctx, ctx, mctx, &de->u.nestedacl); if (result != ISC_R_SUCCESS) goto cleanup; @@ -226,13 +229,13 @@ cfg_acl_fromconfig(const cfg_obj_t *caml de->negative = ISC_TF(! de->negative); } else { de->type = dns_aclelementtype_nestedacl; - result = convert_named_acl(ce, cctx, ctx, mctx, + result = convert_named_acl(ce, cctx, lctx, ctx, mctx, &de->u.nestedacl); if (result != ISC_R_SUCCESS) goto cleanup; } } else { - cfg_obj_log(ce, dns_lctx, ISC_LOG_WARNING, + cfg_obj_log(ce, lctx, ISC_LOG_WARNING, "address match list contains " "unsupported element type"); result = ISC_R_FAILURE; diff -up bind-9.3.6-P1/lib/isccfg/include/isccfg/aclconf.h.rh496495 bind-9.3.6-P1/lib/isccfg/include/isccfg/aclconf.h --- bind-9.3.6-P1/lib/isccfg/include/isccfg/aclconf.h.rh496495 2009-04-24 15:56:08.398901949 +0200 +++ bind-9.3.6-P1/lib/isccfg/include/isccfg/aclconf.h 2009-04-24 16:03:55.475315126 +0200 @@ -50,10 +50,11 @@ cfg_aclconfctx_destroy(cfg_aclconfctx_t isc_result_t cfg_acl_fromconfig(const cfg_obj_t *caml, - const cfg_obj_t *cctx, - cfg_aclconfctx_t *ctx, - isc_mem_t *mctx, - dns_acl_t **target); + const cfg_obj_t *cctx, + isc_log_t *lctx, + cfg_aclconfctx_t *ctx, + isc_mem_t *mctx, + dns_acl_t **target); /* * Construct a new dns_acl_t from configuration data in 'caml' and * 'cctx'. Memory is allocated through 'mctx'.