acl.c revision 175a8bd2b798bbc568cd912b72c8a026cfca8527
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * Copyright (C) 1999-2002 Internet Software Consortium.
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * Permission to use, copy, modify, and/or distribute this software for any
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * purpose with or without fee is hereby granted, provided that the above
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * copyright notice and this permission notice appear in all copies.
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * PERFORMANCE OF THIS SOFTWARE.
110d1702731f42dd620879c1d765ebe91f3920ceMichael Graff/* $Id: acl.c,v 1.51 2008/12/01 00:04:21 marka Exp $ */
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * Create a new ACL, including an IP table and an array with room
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * for 'n' ACL elements. The elements are uninitialized and the
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * length is 0.
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleydns_acl_create(isc_mem_t *mctx, int n, dns_acl_t **target) {
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * Work around silly limitation of isc_mem_get().
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley result = dns_iptable_create(mctx, &acl->iptable);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * Must set magic early because we use dns_acl_detach() to clean up.
078d49b63324f01d98301ee21671abee0c41fcdeBob Halley acl->elements = isc_mem_get(mctx, n * sizeof(dns_aclelement_t));
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley memset(acl->elements, 0, n * sizeof(dns_aclelement_t));
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * Create a new ACL and initialize it with the value "any" or "none",
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * depending on the value of the "neg" parameter.
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * "any" is a positive iptable entry with bit length 0.
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * "none" is the same as "!any".
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleydns_acl_anyornone(isc_mem_t *mctx, isc_boolean_t neg, dns_acl_t **target) {
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley result = dns_iptable_addprefix(acl->iptable, NULL, 0, ISC_TF(!neg));
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * Create a new ACL that matches everything.
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleydns_acl_any(isc_mem_t *mctx, dns_acl_t **target) {
078d49b63324f01d98301ee21671abee0c41fcdeBob Halley return (dns_acl_anyornone(mctx, ISC_FALSE, target));
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * Create a new ACL that matches nothing.
95552051abdb3b6fc4f56b015da27c000742646bBob Halleydns_acl_none(isc_mem_t *mctx, dns_acl_t **target) {
95552051abdb3b6fc4f56b015da27c000742646bBob Halley return (dns_acl_anyornone(mctx, ISC_TRUE, target));
95552051abdb3b6fc4f56b015da27c000742646bBob Halley * If pos is ISC_TRUE, test whether acl is set to "{ any; }"
95552051abdb3b6fc4f56b015da27c000742646bBob Halley * If pos is ISC_FALSE, test whether acl is set to "{ none; }"
95552051abdb3b6fc4f56b015da27c000742646bBob Halleydns_acl_isanyornone(dns_acl_t *acl, isc_boolean_t pos)
95552051abdb3b6fc4f56b015da27c000742646bBob Halley /* Should never happen but let's be safe */
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley if (acl->iptable->radix->head->prefix->bitlen == 0 &&
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley *(isc_boolean_t *) (acl->iptable->radix->head->data[0]) == pos)
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * Test whether acl is set to "{ any; }"
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley * Test whether acl is set to "{ none; }"
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley * Determine whether a given address or signer matches a given ACL.
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley * For a match with a positive ACL element or iptable radix entry,
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley * return with a positive value in match; for a match with a negated ACL
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley * element or radix entry, return with a negative value in match.
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley unsigned int i;
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley if (env == NULL || env->match_mapped == ISC_FALSE ||
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley /* Always match with host addresses. */
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley /* Assume no match. */
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley /* Search radix. */
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley result = isc_radix_search(acl->iptable->radix, &node, &pfx);
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley /* Found a match. */
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley if (*(isc_boolean_t *) node->data[ISC_IS6(family)] == ISC_TRUE)
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley /* Now search non-radix elements for a match with a lower node_num. */
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley /* Already found a better match? */
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley if (match_num != -1 && match_num < e->node_num) {
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley if (match_num == -1 || e->node_num < match_num) {
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * Merge the contents of one ACL into another. Call dns_iptable_merge()
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * for the IP tables, then concatenate the element arrays.
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * If pos is set to false, then the nested ACL is to be negated. This
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * means reverse the sense of each *positive* element or IP table node,
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * but leave negatives alone, so as to prevent a double-negative causing
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * an unexpected postive match in the parent ACL.
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halleydns_acl_merge(dns_acl_t *dest, dns_acl_t *source, isc_boolean_t pos)
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley /* Resize the element array if needed. */
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley if (dest->length + source->length > dest->alloc) {
return (ISC_R_NOMEMORY);
return result;
return (result);
return (ISC_R_SUCCESS);
const dns_aclelement_t *e,
int indirectmatch;
switch (e->type) {
*matchelt = e;
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_FALSE);
INSIST(0);
if (indirectmatch > 0) {
*matchelt = e;
return (ISC_TRUE);
return (ISC_FALSE);
unsigned int refs;
if (refs == 0)
initialize_action(void) {
if (!secure) {
switch (family) {
case AF_INET:
case AF_INET6:
if (insecure)
return(ISC_TRUE);
for (i = 0; i < a->length; i++) {
if (e->negative)
switch (e->type) {
return (ISC_TRUE);
return (ISC_TRUE);
INSIST(0);
return (ISC_TRUE);
return (ISC_FALSE);
goto cleanup_nothing;
goto cleanup_localhost;
return (ISC_R_SUCCESS);
return (result);