renamed dns_acl_checkrequest() to ns_client_checkacl()

and moved it to bin/named/client.c to reflect the fact that it
implemented BIND ACL policy more than general-purpose library
functionality; resolve ACL defaults at configuration time
rather than when the ACL is evaluated
This commit is contained in:
Andreas Gustafsson
2000-02-22 21:24:24 +00:00
parent 5300bfe023
commit 3eef7eaba0
11 changed files with 109 additions and 122 deletions

View File

@@ -979,13 +979,9 @@ client_request(isc_task_t *task, isc_event_t *event) {
if (ns_g_server->recursion == ISC_TRUE) {
/* XXX ACL should be view specific. */
/* XXX this will log too much too early */
result = dns_acl_checkrequest(client->signer,
ns_client_getsockaddr(client),
"recursion",
ns_g_server->recursionacl,
NULL,
&ns_g_server->aclenv,
ISC_TRUE);
result = ns_client_checkacl(client, "recursion",
ns_g_server->recursionacl,
ISC_TRUE);
if (result != DNS_R_SUCCESS)
ra = ISC_FALSE;
}
@@ -1528,3 +1524,44 @@ isc_sockaddr_t *
ns_client_getsockaddr(ns_client_t *client) {
return (&client->peeraddr);
}
isc_result_t
ns_client_checkacl(ns_client_t *client,
const char *opname, dns_acl_t *acl,
isc_boolean_t default_allow)
{
isc_result_t result;
int match;
isc_netaddr_t netaddr;
if (acl == NULL) {
if (default_allow)
goto allow;
else
goto deny;
}
isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
result = dns_acl_match(&netaddr, client->signer, acl,
&ns_g_server->aclenv,
&match, NULL);
if (result != DNS_R_SUCCESS)
goto deny; /* Internal error, already logged. */
if (match > 0)
goto allow;
goto deny; /* Negative match or no match. */
allow:
isc_log_write(dns_lctx, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
"%s approved", opname);
return (DNS_R_SUCCESS);
deny:
isc_log_write(dns_lctx, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT, ISC_LOG_ERROR,
"%s denied", opname);
return (DNS_R_REFUSED);
}

View File

@@ -217,4 +217,35 @@ ns_client_getsockaddr(ns_client_t *client);
* currently being processed.
*/
isc_result_t
ns_client_checkacl(ns_client_t *client,
const char *opname, dns_acl_t *acl,
isc_boolean_t default_allow);
/*
* Convenience function for client request ACL checking.
*
* Check the current client request against 'acl'. If 'acl'
* is NULL, allow the request iff 'default_allow' is ISC_TRUE.
* Log the outcome of the check if deemed appropriate.
* Log messages will refer to the request as an 'opname' request.
*
* Notes:
* This is appropriate for checking allow-update,
* allow-query, allow-transfer, etc. It is not appropriate
* for checking the blackhole list because we treat positive
* matches as "allow" and negative matches as "deny"; in
* the case of the blackhole list this would be backwards.
*
* Requires:
* 'client' points to a valid client.
* 'opname' points to a null-terminated string.
* 'acl' points to a valid ACL, or is NULL.
*
* Returns:
* ISC_R_SUCCESS if the request should be allowed
* ISC_R_REFUSED if the request should be denied
* No other return values are possible.
*/
#endif /* NS_CLIENT_H */

View File

@@ -47,7 +47,6 @@ struct ns_server {
dns_transfer_format_t transfer_format;
dns_acl_t * queryacl;
dns_acl_t * recursionacl;
dns_acl_t * transferacl;
isc_quota_t xfroutquota;
isc_quota_t tcpquota;
isc_quota_t recursionquota;

View File

@@ -1798,6 +1798,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
dns_fixedname_t fixed;
dns_dbversion_t *version;
dns_zone_t *zone;
dns_acl_t *queryacl;
CTRACE("query_find");
@@ -1923,19 +1924,16 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
} else
version = NULL;
queryacl = NULL;
if (is_zone)
queryacl = dns_zone_getqueryacl(zone);
if (queryacl == NULL)
queryacl = ns_g_server->queryacl;
/*
* Check the query against the "allow-query" AMLs.
* XXX there should also be a per-view one.
*/
result = dns_acl_checkrequest(client->signer,
ns_client_getsockaddr(client),
"query",
(is_zone ?
dns_zone_getqueryacl(zone) :
ns_g_server->queryacl),
ns_g_server->queryacl,
&ns_g_server->aclenv,
ISC_TRUE);
result = ns_client_checkacl(client, "query", queryacl, ISC_TRUE);
if (result != DNS_R_SUCCESS) {
QUERY_ERROR(result);
goto cleanup;

View File

@@ -788,10 +788,6 @@ load_configuration(const char *filename, ns_server_t *server,
dns_c_ctx_getrecursionacl,
&server->recursionacl));
CHECK(configure_server_acl(configctx, &aclconfctx, ns_g_mctx,
dns_c_ctx_gettransferacl,
&server->transferacl));
configure_server_quota(configctx, dns_c_ctx_gettransfersout,
&server->xfroutquota, 10);
configure_server_quota(configctx, dns_c_ctx_gettcpclients,
@@ -1058,7 +1054,6 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
server->queryacl = NULL;
server->recursionacl = NULL;
server->transferacl = NULL;
result = isc_quota_init(&server->xfroutquota, 10);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
@@ -1144,8 +1139,6 @@ ns_server_destroy(ns_server_t **serverp) {
dns_acl_detach(&server->queryacl);
if (server->recursionacl != NULL)
dns_acl_detach(&server->recursionacl);
if (server->transferacl != NULL)
dns_acl_detach(&server->transferacl);
dns_aclenv_destroy(&server->aclenv);

View File

@@ -1940,12 +1940,9 @@ update_action(isc_task_t *task, isc_event_t *event)
* Check Requestor's Permissions. It seems a bit silly to do this
* only after prerequisite testing, but that is what RFC2136 says.
*/
CHECK(dns_acl_checkrequest(client->signer,
ns_client_getsockaddr(client),
"update", dns_zone_getupdateacl(zone),
NULL,
&ns_g_server->aclenv,
ISC_FALSE));
CHECK(ns_client_checkacl(client, "update",
dns_zone_getupdateacl(zone),
ISC_FALSE));
/* Perform the Update Section Prescan. */

View File

@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: xfrout.c,v 1.44 2000/02/14 23:56:46 gson Exp $ */
/* $Id: xfrout.c,v 1.45 2000/02/22 21:24:23 gson Exp $ */
#include <config.h>
@@ -904,13 +904,9 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype)
mnemonic);
/* Decide whether to allow this transfer. */
CHECK(dns_acl_checkrequest(client->signer,
ns_client_getsockaddr(client),
"zone transfer",
dns_zone_getxfracl(zone),
ns_g_server->transferacl,
&ns_g_server->aclenv,
ISC_TRUE));
CHECK(ns_client_checkacl(client, "zone transfer",
dns_zone_getxfracl(zone),
ISC_TRUE));
/* AXFR over UDP is not possible. */
if (reqtype == dns_rdatatype_axfr &&

View File

@@ -39,6 +39,7 @@ static isc_result_t
configure_zone_acl(dns_c_zone_t *czone, dns_c_ctx_t *cctx,
dns_aclconfctx_t *aclconfctx, dns_zone_t *zone,
isc_result_t (*getcacl)(dns_c_zone_t *, dns_c_ipmatchlist_t **),
isc_result_t (*getdefaultcacl)(dns_c_ctx_t *, dns_c_ipmatchlist_t **),
void (*setzacl)(dns_zone_t *, dns_acl_t *),
void (*clearzacl)(dns_zone_t *))
{
@@ -46,6 +47,9 @@ configure_zone_acl(dns_c_zone_t *czone, dns_c_ctx_t *cctx,
dns_c_ipmatchlist_t *cacl;
dns_acl_t *dacl = NULL;
result = (*getcacl)(czone, &cacl);
if (result == ISC_R_NOTFOUND && getdefaultcacl != NULL) {
result = (*getdefaultcacl)(cctx, &cacl);
}
if (result == ISC_R_SUCCESS) {
result = dns_acl_fromconfig(cacl, cctx, aclconfctx,
dns_zone_getmctx(zone), &dacl);
@@ -130,6 +134,7 @@ dns_zone_configure(dns_c_ctx_t *cctx, dns_aclconfctx_t *ac,
#endif
result = configure_zone_acl(czone, cctx, ac, zone,
dns_c_zone_getallowupd,
NULL,
dns_zone_setupdateacl,
dns_zone_clearupdateacl);
if (result != DNS_R_SUCCESS)
@@ -137,6 +142,7 @@ dns_zone_configure(dns_c_ctx_t *cctx, dns_aclconfctx_t *ac,
result = configure_zone_acl(czone, cctx, ac, zone,
dns_c_zone_getallowquery,
dns_c_ctx_getqueryacl,
dns_zone_setqueryacl,
dns_zone_clearqueryacl);
if (result != DNS_R_SUCCESS)
@@ -144,6 +150,7 @@ dns_zone_configure(dns_c_ctx_t *cctx, dns_aclconfctx_t *ac,
result = configure_zone_acl(czone, cctx, ac, zone,
dns_c_zone_getallowtransfer,
dns_c_ctx_gettransferacl,
dns_zone_setxfracl,
dns_zone_clearxfracl);
if (result != DNS_R_SUCCESS)
@@ -219,6 +226,7 @@ dns_zone_configure(dns_c_ctx_t *cctx, dns_aclconfctx_t *ac,
#endif
result = configure_zone_acl(czone, cctx, ac, zone,
dns_c_zone_getallowquery,
dns_c_ctx_getqueryacl,
dns_zone_setqueryacl,
dns_zone_clearqueryacl);
if (result != DNS_R_SUCCESS)
@@ -309,7 +317,8 @@ dns_zone_configure(dns_c_ctx_t *cctx, dns_aclconfctx_t *ac,
dns_zone_setchecknames(zone, dns_c_severity_warn);
#endif
result = configure_zone_acl(czone, cctx, ac, zone,
dns_c_zone_getallowquery,
dns_c_zone_getallowquery,
dns_c_ctx_getqueryacl,
dns_zone_setqueryacl,
dns_zone_clearqueryacl);
if (result != DNS_R_SUCCESS)

View File

@@ -127,51 +127,6 @@ dns_acl_none(isc_mem_t *mctx, dns_acl_t **target) {
return (dns_acl_anyornone(mctx, ISC_TRUE, target));
}
isc_result_t
dns_acl_checkrequest(dns_name_t *signer, isc_sockaddr_t *reqaddr,
const char *opname,
dns_acl_t *main_acl,
dns_acl_t *fallback_acl,
dns_aclenv_t *env,
isc_boolean_t default_allow)
{
isc_result_t result;
int match;
isc_netaddr_t netaddr;
dns_acl_t *acl = NULL;
if (main_acl != NULL)
acl = main_acl;
else if (fallback_acl != NULL)
acl = fallback_acl;
else if (default_allow)
goto allow;
else
goto deny;
isc_netaddr_fromsockaddr(&netaddr, reqaddr);
result = dns_acl_match(&netaddr, signer, acl, env,
&match, NULL);
if (result != DNS_R_SUCCESS)
goto deny; /* Internal error, already logged. */
if (match > 0)
goto allow;
goto deny; /* Negative match or no match. */
allow:
isc_log_write(dns_lctx, DNS_LOGCATEGORY_SECURITY,
DNS_LOGMODULE_ACL, ISC_LOG_DEBUG(3),
"%s approved", opname);
return (DNS_R_SUCCESS);
deny:
isc_log_write(dns_lctx, DNS_LOGCATEGORY_SECURITY,
DNS_LOGMODULE_ACL, ISC_LOG_ERROR,
"%s denied", opname);
return (DNS_R_REFUSED);
}
isc_result_t
dns_acl_match(isc_netaddr_t *reqaddr,
dns_name_t *reqsigner,

View File

@@ -122,43 +122,6 @@ 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_checkrequest(dns_name_t *signer, isc_sockaddr_t *reqaddr,
const char *opname,
dns_acl_t *main_acl,
dns_acl_t *fallback_acl,
dns_aclenv_t *env,
isc_boolean_t default_allow);
/*
* Convenience function for "typical" DNS request permission checking.
*
* Check the DNS request signed by the key whose name is 'signer',
* from IP address 'reqaddr', against 'main_acl'. If main_acl is NULL,
* check against 'fallback_acl' instead. If fallback_acl
* is also NULL, allow the request iff 'default_allow' is ISC_TRUE.
* Log the outcome of the check if deemed appropriate.
* Log messages will refer to the request as an 'opname' request.
*
* Notes:
* This is appropriate for checking allow-update,
* allow-query, allow-transfer, etc. It is not appropriate
* for checking the blackhole list because we treat positive
* matches as "allow" and negative matches as "deny"; in
* the case of the blackhole list this would be backwards.
*
* Requires:
* 'signer' points to a valid name or is NULL.
* 'reqaddr' points to a valid socket address.
* 'opname' points to a null-terminated string.
* 'main_acl' points to a valid address match list, or is NULL.
* 'fallback_acl' points to a valid address match list, or is NULL.
*
* Returns:
* ISC_R_SUCCESS if the request should be allowed
* ISC_R_REFUSED if the request should be denied
* No other return values are possible.
*/
isc_result_t
dns_acl_match(isc_netaddr_t *reqaddr,
dns_name_t *reqsigner,

View File

@@ -39,6 +39,7 @@ static isc_result_t
configure_zone_acl(dns_c_zone_t *czone, dns_c_ctx_t *cctx,
dns_aclconfctx_t *aclconfctx, dns_zone_t *zone,
isc_result_t (*getcacl)(dns_c_zone_t *, dns_c_ipmatchlist_t **),
isc_result_t (*getdefaultcacl)(dns_c_ctx_t *, dns_c_ipmatchlist_t **),
void (*setzacl)(dns_zone_t *, dns_acl_t *),
void (*clearzacl)(dns_zone_t *))
{
@@ -46,6 +47,9 @@ configure_zone_acl(dns_c_zone_t *czone, dns_c_ctx_t *cctx,
dns_c_ipmatchlist_t *cacl;
dns_acl_t *dacl = NULL;
result = (*getcacl)(czone, &cacl);
if (result == ISC_R_NOTFOUND && getdefaultcacl != NULL) {
result = (*getdefaultcacl)(cctx, &cacl);
}
if (result == ISC_R_SUCCESS) {
result = dns_acl_fromconfig(cacl, cctx, aclconfctx,
dns_zone_getmctx(zone), &dacl);
@@ -130,6 +134,7 @@ dns_zone_configure(dns_c_ctx_t *cctx, dns_aclconfctx_t *ac,
#endif
result = configure_zone_acl(czone, cctx, ac, zone,
dns_c_zone_getallowupd,
NULL,
dns_zone_setupdateacl,
dns_zone_clearupdateacl);
if (result != DNS_R_SUCCESS)
@@ -137,6 +142,7 @@ dns_zone_configure(dns_c_ctx_t *cctx, dns_aclconfctx_t *ac,
result = configure_zone_acl(czone, cctx, ac, zone,
dns_c_zone_getallowquery,
dns_c_ctx_getqueryacl,
dns_zone_setqueryacl,
dns_zone_clearqueryacl);
if (result != DNS_R_SUCCESS)
@@ -144,6 +150,7 @@ dns_zone_configure(dns_c_ctx_t *cctx, dns_aclconfctx_t *ac,
result = configure_zone_acl(czone, cctx, ac, zone,
dns_c_zone_getallowtransfer,
dns_c_ctx_gettransferacl,
dns_zone_setxfracl,
dns_zone_clearxfracl);
if (result != DNS_R_SUCCESS)
@@ -219,6 +226,7 @@ dns_zone_configure(dns_c_ctx_t *cctx, dns_aclconfctx_t *ac,
#endif
result = configure_zone_acl(czone, cctx, ac, zone,
dns_c_zone_getallowquery,
dns_c_ctx_getqueryacl,
dns_zone_setqueryacl,
dns_zone_clearqueryacl);
if (result != DNS_R_SUCCESS)
@@ -309,7 +317,8 @@ dns_zone_configure(dns_c_ctx_t *cctx, dns_aclconfctx_t *ac,
dns_zone_setchecknames(zone, dns_c_severity_warn);
#endif
result = configure_zone_acl(czone, cctx, ac, zone,
dns_c_zone_getallowquery,
dns_c_zone_getallowquery,
dns_c_ctx_getqueryacl,
dns_zone_setqueryacl,
dns_zone_clearqueryacl);
if (result != DNS_R_SUCCESS)