2000-11-14 03:22:53 +00:00
|
|
|
/*
|
2005-04-29 00:24:12 +00:00
|
|
|
* Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
|
2001-01-09 22:01:04 +00:00
|
|
|
* Copyright (C) 2000, 2001 Internet Software Consortium.
|
2000-11-14 03:22:53 +00:00
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
|
|
* copyright notice and this permission notice appear in all copies.
|
|
|
|
*
|
2004-03-05 05:14:21 +00:00
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
|
|
|
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
|
|
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
|
|
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
|
|
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
|
|
|
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
|
|
* PERFORMANCE OF THIS SOFTWARE.
|
2000-11-14 03:22:53 +00:00
|
|
|
*/
|
|
|
|
|
2005-04-29 00:24:12 +00:00
|
|
|
/* $Id: sortlist.c,v 1.11 2005/04/29 00:22:29 marka Exp $ */
|
2005-04-27 04:57:32 +00:00
|
|
|
|
|
|
|
/*! \file */
|
2000-11-14 03:22:53 +00:00
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include <isc/mem.h>
|
|
|
|
#include <isc/util.h>
|
|
|
|
|
|
|
|
#include <dns/acl.h>
|
|
|
|
#include <dns/result.h>
|
|
|
|
|
|
|
|
#include <named/globals.h>
|
|
|
|
#include <named/server.h>
|
|
|
|
#include <named/sortlist.h>
|
|
|
|
|
|
|
|
ns_sortlisttype_t
|
2000-11-15 18:12:38 +00:00
|
|
|
ns_sortlist_setup(dns_acl_t *acl, isc_netaddr_t *clientaddr, void **argp) {
|
2000-11-14 03:22:53 +00:00
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
if (acl == NULL)
|
|
|
|
goto dont_sort;
|
|
|
|
|
|
|
|
for (i = 0; i < acl->length; i++) {
|
|
|
|
/*
|
|
|
|
* 'e' refers to the current 'top level statement'
|
|
|
|
* in the sortlist (see ARM).
|
|
|
|
*/
|
|
|
|
dns_aclelement_t *e = &acl->elements[i];
|
2001-10-30 19:45:33 +00:00
|
|
|
dns_aclelement_t *try_elt;
|
|
|
|
dns_aclelement_t *order_elt = NULL;
|
|
|
|
dns_aclelement_t *matched_elt = NULL;
|
|
|
|
|
|
|
|
if (e->type == dns_aclelementtype_nestedacl) {
|
|
|
|
dns_acl_t *inner = e->u.nestedacl;
|
|
|
|
|
|
|
|
if (inner->length < 1 || inner->length > 2)
|
|
|
|
goto dont_sort;
|
|
|
|
if (inner->elements[0].negative)
|
|
|
|
goto dont_sort;
|
|
|
|
try_elt = &inner->elements[0];
|
|
|
|
if (inner->length == 2)
|
|
|
|
order_elt = &inner->elements[1];
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* BIND 8 allows bare elements at the top level
|
|
|
|
* as an undocumented feature.
|
|
|
|
*/
|
|
|
|
try_elt = e;
|
2001-10-30 06:41:58 +00:00
|
|
|
}
|
|
|
|
|
2001-10-30 19:45:33 +00:00
|
|
|
if (dns_aclelement_match(clientaddr, NULL, try_elt,
|
2000-11-14 03:22:53 +00:00
|
|
|
&ns_g_server->aclenv,
|
2001-10-30 19:45:33 +00:00
|
|
|
&matched_elt)) {
|
|
|
|
if (order_elt != NULL) {
|
|
|
|
if (order_elt->type ==
|
2001-10-30 20:19:34 +00:00
|
|
|
dns_aclelementtype_nestedacl) {
|
2001-10-30 19:45:33 +00:00
|
|
|
*argp = order_elt->u.nestedacl;
|
2001-10-30 20:19:34 +00:00
|
|
|
return (NS_SORTLISTTYPE_2ELEMENT);
|
|
|
|
} else if (order_elt->type ==
|
|
|
|
dns_aclelementtype_localhost &&
|
|
|
|
ns_g_server->aclenv.localhost != NULL) {
|
2001-03-26 23:36:00 +00:00
|
|
|
*argp = ns_g_server->aclenv.localhost;
|
2001-10-30 20:19:34 +00:00
|
|
|
return (NS_SORTLISTTYPE_2ELEMENT);
|
|
|
|
} else if (order_elt->type ==
|
|
|
|
dns_aclelementtype_localnets &&
|
|
|
|
ns_g_server->aclenv.localnets != NULL) {
|
2001-03-26 23:36:00 +00:00
|
|
|
*argp = ns_g_server->aclenv.localnets;
|
2001-10-30 20:19:34 +00:00
|
|
|
return (NS_SORTLISTTYPE_2ELEMENT);
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* BIND 8 allows a bare IP prefix as
|
|
|
|
* the 2nd element of a 2-element
|
|
|
|
* sortlist statement.
|
|
|
|
*/
|
|
|
|
*argp = order_elt;
|
|
|
|
return (NS_SORTLISTTYPE_1ELEMENT);
|
|
|
|
}
|
2000-11-14 03:22:53 +00:00
|
|
|
} else {
|
2001-10-30 19:45:33 +00:00
|
|
|
INSIST(matched_elt != NULL);
|
|
|
|
*argp = matched_elt;
|
2000-11-14 03:22:53 +00:00
|
|
|
return (NS_SORTLISTTYPE_1ELEMENT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* No match; don't sort. */
|
|
|
|
dont_sort:
|
|
|
|
*argp = NULL;
|
|
|
|
return (NS_SORTLISTTYPE_NONE);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
ns_sortlist_addrorder2(isc_netaddr_t *addr, void *arg) {
|
|
|
|
dns_acl_t *sortacl = (dns_acl_t *) arg;
|
|
|
|
int match;
|
|
|
|
|
|
|
|
(void)dns_acl_match(addr, NULL, sortacl,
|
|
|
|
&ns_g_server->aclenv,
|
|
|
|
&match, NULL);
|
|
|
|
if (match > 0)
|
|
|
|
return (match);
|
|
|
|
else if (match < 0)
|
|
|
|
return (INT_MAX - (-match));
|
|
|
|
else
|
|
|
|
return (INT_MAX / 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
ns_sortlist_addrorder1(isc_netaddr_t *addr, void *arg) {
|
|
|
|
dns_aclelement_t *matchelt = (dns_aclelement_t *) arg;
|
|
|
|
if (dns_aclelement_match(addr, NULL, matchelt,
|
|
|
|
&ns_g_server->aclenv,
|
|
|
|
NULL)) {
|
|
|
|
return (0);
|
|
|
|
} else {
|
|
|
|
return (INT_MAX);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ns_sortlist_byaddrsetup(dns_acl_t *sortlist_acl, isc_netaddr_t *client_addr,
|
|
|
|
dns_addressorderfunc_t *orderp,
|
|
|
|
void **argp)
|
|
|
|
{
|
2000-11-15 20:35:13 +00:00
|
|
|
ns_sortlisttype_t sortlisttype;
|
|
|
|
|
|
|
|
sortlisttype = ns_sortlist_setup(sortlist_acl, client_addr, argp);
|
|
|
|
|
|
|
|
switch (sortlisttype) {
|
2000-11-14 03:22:53 +00:00
|
|
|
case NS_SORTLISTTYPE_1ELEMENT:
|
2000-11-15 20:35:13 +00:00
|
|
|
*orderp = ns_sortlist_addrorder1;
|
2000-11-14 03:22:53 +00:00
|
|
|
break;
|
|
|
|
case NS_SORTLISTTYPE_2ELEMENT:
|
2000-11-15 20:35:13 +00:00
|
|
|
*orderp = ns_sortlist_addrorder2;
|
2000-11-14 03:22:53 +00:00
|
|
|
break;
|
|
|
|
case NS_SORTLISTTYPE_NONE:
|
2000-11-15 20:35:13 +00:00
|
|
|
*orderp = NULL;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
|
|
|
"unexpected return from ns_sortlist_setup(): "
|
|
|
|
"%d", sortlisttype);
|
2000-11-14 03:22:53 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|