曾与蒿藜同雨露,한때 잡초와 쑥과 함께 비와 이슬을 나누던 곳이 이제는 소나무와 삼나무와 함께 서리와 눈을 견뎌내고 있다.终随松柏到冰霜.かつては雑草やヨモギと共に雨や露を分かち合っていたが、今では松やヒノキと共に霜や雪に耐えている。曾与蒿藜同雨露,Once sharing rain and dew with weeds and wormwood, now enduring frost and snow with pines and cypresses.终随松柏到冰霜.曾与蒿藜同雨露한때 잡초와 쑥과 함께 비와 이슬을 나누던 곳이 이제는 소나무와 삼나무와 함께 서리와 눈을 견뎌내고 있다.,终随松柏到冰霜.譖セ荳手珍阯懷酔髮ィ髴イ�檎サ磯囂譚セ譟丞芦蜀ー髴�曾与蒿藜同雨露,鏇句笌钂胯棞鍚岄洦闇诧紝缁堥殢鏉炬煆鍒板啺闇�终随松柏到冰霜.曾与蒿藜同雨露,한때 잡초와 쑥과 함께 비와 이슬을 나누던 곳이 이제는 소나무와 삼나무와 함께 서리와 눈을 견뎌내고 있다.终随松柏到冰霜.曾与蒿藜同雨露,终随松柏到冰霜.
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
/* $Id: acl.h,v 1.35 2011/06/17 23:47:49 tbox Exp $ */
#ifndef DNS_ACL_H
#define DNS_ACL_H 1
/*****
***** Module Info
*****/
/*! \file dns/acl.h
* \brief
* Address match list handling.
*/
/***
*** Imports
***/
#include <isc/lang.h>
#include <isc/magic.h>
#include <isc/netaddr.h>
#include <isc/refcount.h>
#ifdef HAVE_GEOIP
#include <dns/geoip.h>
#endif
#include <dns/name.h>
#include <dns/types.h>
#include <dns/iptable.h>
#ifdef HAVE_GEOIP
#include <GeoIP.h>
#endif
/***
*** Types
***/
typedef enum {
dns_aclelementtype_ipprefix,
dns_aclelementtype_keyname,
dns_aclelementtype_nestedacl,
dns_aclelementtype_localhost,
dns_aclelementtype_localnets,
#ifdef HAVE_GEOIP
dns_aclelementtype_geoip,
#endif /* HAVE_GEOIP */
dns_aclelementtype_any
} dns_aclelementtype_t;
typedef struct dns_aclipprefix dns_aclipprefix_t;
struct dns_aclipprefix {
isc_netaddr_t address; /* IP4/IP6 */
unsigned int prefixlen;
};
struct dns_aclelement {
dns_aclelementtype_t type;
isc_boolean_t negative;
dns_name_t keyname;
#ifdef HAVE_GEOIP
dns_geoip_elem_t geoip_elem;
#endif /* HAVE_GEOIP */
dns_acl_t *nestedacl;
int node_num;
};
struct dns_acl {
unsigned int magic;
isc_mem_t *mctx;
isc_refcount_t refcount;
dns_iptable_t *iptable;
#define node_count iptable->radix->num_added_node
dns_aclelement_t *elements;
isc_boolean_t has_negatives;
unsigned int alloc; /*%< Elements allocated */
unsigned int length; /*%< Elements initialized */
char *name; /*%< Temporary use only */
ISC_LINK(dns_acl_t) nextincache; /*%< Ditto */
};
struct dns_aclenv {
dns_acl_t *localhost;
dns_acl_t *localnets;
isc_boolean_t match_mapped;
#ifdef HAVE_GEOIP
dns_geoip_databases_t *geoip;
isc_boolean_t geoip_use_ecs;
#endif
};
#define DNS_ACL_MAGIC ISC_MAGIC('D','a','c','l')
#define DNS_ACL_VALID(a) ISC_MAGIC_VALID(a, DNS_ACL_MAGIC)
/***
*** Functions
***/
ISC_LANG_BEGINDECLS
isc_result_t
dns_acl_create(isc_mem_t *mctx, int n, dns_acl_t **target);
/*%<
* Create a new ACL, including an IP table and an array with room
* for 'n' ACL elements. The elements are uninitialized and the
* length is 0.
*/
isc_result_t
dns_acl_any(isc_mem_t *mctx, dns_acl_t **target);
/*%<
* Create a new ACL that matches everything.
*/
isc_result_t
dns_acl_none(isc_mem_t *mctx, dns_acl_t **target);
/*%<
* Create a new ACL that matches nothing.
*/
isc_boolean_t
dns_acl_isany(dns_acl_t *acl);
/*%<
* Test whether ACL is set to "{ any; }"
*/
isc_boolean_t
dns_acl_isnone(dns_acl_t *acl);
/*%<
* Test whether ACL is set to "{ none; }"
*/
isc_result_t
dns_acl_merge(dns_acl_t *dest, dns_acl_t *source, isc_boolean_t pos);
/*%<
* Merge the contents of one ACL into another. Call dns_iptable_merge()
* for the IP tables, then concatenate the element arrays.
*
* If pos is set to false, then the nested ACL is to be negated. This
* means reverse the sense of each *positive* element or IP table node,
* but leave negatives alone, so as to prevent a double-negative causing
* an unexpected positive match in the parent ACL.
*/
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);
/*%<
* Return #ISC_TRUE iff the acl 'a' is considered insecure, that is,
* if it contains IP addresses other than those of the local host.
* This is intended for applications such as printing warning
* messages for suspect ACLs; it is not intended for making access
* control decisions. We make no guarantee that an ACL for which
* this function returns #ISC_FALSE is safe.
*/
isc_result_t
dns_aclenv_init(isc_mem_t *mctx, dns_aclenv_t *env);
/*%<
* Initialize ACL environment, setting up localhost and localnets ACLs
*/
void
dns_aclenv_copy(dns_aclenv_t *t, dns_aclenv_t *s);
void
dns_aclenv_destroy(dns_aclenv_t *env);
isc_result_t
dns_acl_match(const isc_netaddr_t *reqaddr,
const dns_name_t *reqsigner,
const dns_acl_t *acl,
const dns_aclenv_t *env,
int *match,
const dns_aclelement_t **matchelt);
isc_result_t
dns_acl_match2(const isc_netaddr_t *reqaddr,
const dns_name_t *reqsigner,
const isc_netaddr_t *ecs,
isc_uint8_t ecslen,
isc_uint8_t *scope,
const dns_acl_t *acl,
const dns_aclenv_t *env,
int *match,
const dns_aclelement_t **matchelt);
/*%<
* General, low-level ACL matching. This is expected to
* be useful even for weird stuff like the topology and sortlist statements.
*
* Match the address 'reqaddr', and optionally the key name 'reqsigner',
* and optionally the client prefix 'ecs' of length 'ecslen'
* (reported via EDNS client subnet option) against 'acl'.
*
* 'reqsigner' and 'ecs' may be NULL. If an ACL matches against 'ecs'
* and 'ecslen', then 'scope' will be set to indicate the netmask that
* matched.
*
* If there is a match, '*match' will be set to an integer whose absolute
* value corresponds to the order in which the matching value was inserted
* into the ACL. For a positive match, this value will be positive; for a
* negative match, it will be negative.
*
* If there is no match, *match will be set to zero.
*
* If there is a match in the element list (either positive or negative)
* and 'matchelt' is non-NULL, *matchelt will be pointed to the matching
* element.
*
* 'env' points to the current ACL environment, including the
* current values of localhost and localnets and (if applicable)
* the GeoIP context.
*
* Returns:
*\li #ISC_R_SUCCESS Always succeeds.
*/
isc_boolean_t
dns_aclelement_match(const isc_netaddr_t *reqaddr,
const dns_name_t *reqsigner,
const dns_aclelement_t *e,
const dns_aclenv_t *env,
const dns_aclelement_t **matchelt);
isc_boolean_t
dns_aclelement_match2(const isc_netaddr_t *reqaddr,
const dns_name_t *reqsigner,
const isc_netaddr_t *ecs,
isc_uint8_t ecslen,
isc_uint8_t *scope,
const dns_aclelement_t *e,
const dns_aclenv_t *env,
const dns_aclelement_t **matchelt);
/*%<
* Like dns_acl_match, but matches against the single ACL element 'e'
* rather than a complete ACL, and returns ISC_TRUE iff it matched.
*
* To determine whether the match was positive or negative, the
* caller should examine e->negative. Since the element 'e' may be
* a reference to a named ACL or a nested ACL, a matching element
* returned through 'matchelt' is not necessarily 'e' itself.
*/
ISC_LANG_ENDDECLS
#endif /* DNS_ACL_H */