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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user