Commit 919a9ece authored by Mark Andrews's avatar Mark Andrews

enforce record count maximums

parent 79de6edd
......@@ -185,19 +185,32 @@ dns_ssutable_checkrules(dns_ssutable_t *table, const dns_name_t *signer,
/*% Accessor functions to extract rule components */
bool
dns_ssurule_isgrant(const dns_ssurule_t *rule);
/*% Accessor functions to extract rule components */
dns_name_t *
dns_ssurule_identity(const dns_ssurule_t *rule);
/*% Accessor functions to extract rule components */
unsigned int
dns_ssurule_matchtype(const dns_ssurule_t *rule);
/*% Accessor functions to extract rule components */
dns_name_t *
dns_ssurule_name(const dns_ssurule_t *rule);
/*% Accessor functions to extract rule components */
unsigned int
dns_ssurule_types(const dns_ssurule_t *rule, dns_ssuruletype_t **types);
unsigned int
dns_ssurule_max(const dns_ssurule_t *rule, dns_rdatatype_t type);
/*%<
* Returns the maximum number of records configured for type `type`.
* If no maximum has been configured for `type` but one has been
* configured for ANY, return that value instead. Otherwise, return
* zero, which implies "unlimited".
*/
isc_result_t
dns_ssutable_firstrule(const dns_ssutable_t *table, dns_ssurule_t **rule);
/*%<
......
......@@ -562,6 +562,24 @@ dns_ssurule_types(const dns_ssurule_t *rule, dns_ssuruletype_t **types) {
return (rule->ntypes);
}
unsigned int
dns_ssurule_max(const dns_ssurule_t *rule, dns_rdatatype_t type) {
unsigned int i;
unsigned int max = 0;
REQUIRE(VALID_SSURULE(rule));
for (i = 0; i < rule->ntypes; i++) {
if (rule->types[i].type == dns_rdatatype_any) {
max = rule->types[i].max;
}
if (rule->types[i].type == type) {
return (rule->types[i].max);
}
}
return (max);
}
isc_result_t
dns_ssutable_firstrule(const dns_ssutable_t *table, dns_ssurule_t **rule) {
REQUIRE(VALID_SSUTABLE(table));
......
......@@ -1019,9 +1019,10 @@ dns_soa_setretry
dns_soa_setserial
dns_ssu_external_match
dns_ssu_mtypefromstring
dns_ssurule_isgrant
dns_ssurule_identity
dns_ssurule_isgrant
dns_ssurule_matchtype
dns_ssurule_max
dns_ssurule_name
dns_ssurule_types
dns_ssutable_firstrule
......
......@@ -753,6 +753,17 @@ cleanup_node:
typedef bool
rr_predicate(dns_rdata_t *update_rr, dns_rdata_t *db_rr);
static isc_result_t
count_action(void *data, rr_t *rr) {
unsigned int *ui = (unsigned int *)data;
UNUSED(rr);
(*ui)++;
return (ISC_R_SUCCESS);
}
/*%
* Helper function for rrset_exists().
*/
......@@ -2878,6 +2889,8 @@ update_action(isc_task_t *task, isc_event_t *event) {
&rdata, &covers, &ttl, &update_class);
if (update_class == zoneclass) {
unsigned int max = 0;
/*
* RFC1123 doesn't allow MF and MD in master zones.
*/
......@@ -3003,6 +3016,24 @@ update_action(isc_task_t *task, isc_event_t *event) {
}
}
if (rules != NULL && rules[rule] != NULL) {
max = dns_ssurule_max(rules[rule], rdata.type);
}
if (max != 0) {
unsigned int count = 0;
CHECK(foreach_rr(db, ver, name, rdata.type,
covers, count_action, &count));
if (count >= max) {
update_log(client, zone,
LOGLEVEL_PROTOCOL,
"attempt to add more "
"records than permitted by "
"policy max=%u",
max);
continue;
}
}
if (isc_log_wouldlog(ns_lctx, LOGLEVEL_PROTOCOL)) {
char namestr[DNS_NAME_FORMATSIZE];
char typestr[DNS_RDATATYPE_FORMATSIZE];
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment