dns_ssumatchtype_t mtype = dns_ssumatchtype_name;
dns_fixedname_t fname, fident;
isc_buffer_t b;
- dns_rdatatype_t *types;
+ dns_ssuruletype_t *types;
unsigned int i, n;
str = cfg_obj_asstring(mode);
if (n == 0) {
types = NULL;
} else {
- types = isc_mem_get(mctx, n * sizeof(dns_rdatatype_t));
+ types = isc_mem_get(mctx, n * sizeof(*types));
}
i = 0;
element2 = cfg_list_next(element2))
{
const cfg_obj_t *typeobj;
+ const char *bracket;
isc_textregion_t r;
+ unsigned long max = 0;
INSIST(i < n);
typeobj = cfg_listelt_value(element2);
str = cfg_obj_asstring(typeobj);
DE_CONST(str, r.base);
- r.length = strlen(str);
- result = dns_rdatatype_fromtext(&types[i++], &r);
+ bracket = strchr(str, '(' /*)*/);
+ if (bracket != NULL) {
+ char *end = NULL;
+ r.length = bracket - str;
+ max = strtoul(bracket + 1, &end, 10);
+ if (max > 0xffff || end[0] != /*(*/ ')' ||
+ end[1] != 0) {
+ cfg_obj_log(identity, named_g_lctx,
+ ISC_LOG_ERROR,
+ "'%s' is not a valid count",
+ bracket);
+ isc_mem_put(mctx, types,
+ n * sizeof(*types));
+ goto cleanup;
+ }
+ } else {
+ r.length = strlen(str);
+ }
+ types[i].max = max;
+
+ result = dns_rdatatype_fromtext(&types[i++].type, &r);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(identity, named_g_lctx,
ISC_LOG_ERROR,
- "'%s' is not a valid type", str);
- isc_mem_put(mctx, types,
- n * sizeof(dns_rdatatype_t));
+ "'%.*s' is not a valid type",
+ (int)r.length, str);
+ isc_mem_put(mctx, types, n * sizeof(types));
goto cleanup;
}
}
table, grant, dns_fixedname_name(&fident), mtype,
dns_fixedname_name(&fname), n, types);
if (types != NULL) {
- isc_mem_put(mctx, types, n * sizeof(dns_rdatatype_t));
+ isc_mem_put(mctx, types, n * sizeof(*types));
}
if (result != ISC_R_SUCCESS) {
goto cleanup;
* update-policy { grant <session-keyname> zonesub any; };
*/
if (autoddns) {
- dns_rdatatype_t any = dns_rdatatype_any;
+ dns_ssuruletype_t any = { dns_rdatatype_any, 0 };
if (named_g_server->session_keyname == NULL) {
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
--- /dev/null
+/*
+ * 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.
+ */
+
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * tcp-self . "ptr(10 )";
+ };
+};
--- /dev/null
+/*
+ * 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.
+ */
+
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * tcp-self . ptr(1);
+ };
+};
#include <dns/rbt.h>
#include <dns/rdataclass.h>
#include <dns/rdatatype.h>
+#include <dns/result.h>
#include <dns/rrl.h>
#include <dns/secalg.h>
#include <dns/ssu.h>
element2 = cfg_list_next(element2))
{
const cfg_obj_t *typeobj;
+ const char *bracket;
typeobj = cfg_listelt_value(element2);
DE_CONST(cfg_obj_asstring(typeobj), r.base);
- r.length = strlen(r.base);
+
+ bracket = strchr(r.base, '(' /*)*/);
+ if (bracket != NULL) {
+ char *end = NULL;
+ unsigned long max;
+
+ r.length = bracket - r.base;
+ max = strtoul(bracket + 1, &end, 10);
+ if (max > 0xffff || end[0] != /*(*/ ')' ||
+ end[1] != 0) {
+ cfg_obj_log(typeobj, logctx,
+ ISC_LOG_ERROR,
+ "'%s' is not a valid count",
+ bracket);
+ result = DNS_R_SYNTAX;
+ }
+ } else {
+ r.length = strlen(r.base);
+ }
tresult = dns_rdatatype_fromtext(&type, &r);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(typeobj, logctx, ISC_LOG_ERROR,
- "'%s' is not a valid type", r.base);
+ "'%.*s' is not a valid type",
+ (int)r.length, r.base);
result = tresult;
}
}
dns_ssumatchtype_dlz = 16 /* intentionally higher than _max */
} dns_ssumatchtype_t;
+typedef struct dns_ssuruletype {
+ dns_rdatatype_t type; /* type allowed */
+ unsigned int max; /* maximum number of records allowed. */
+} dns_ssuruletype_t;
+
isc_result_t
dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **table);
/*%<
dns_ssutable_addrule(dns_ssutable_t *table, bool grant,
const dns_name_t *identity, dns_ssumatchtype_t matchtype,
const dns_name_t *name, unsigned int ntypes,
- dns_rdatatype_t *types);
+ dns_ssuruletype_t *types);
/*%<
* Adds a new rule to a simple-secure-update rule table. The rule
* either grants or denies update privileges of an identity (or set of
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_rdatatype_t **types);
+dns_ssurule_types(const dns_ssurule_t *rule, dns_ssuruletype_t **types);
isc_result_t
dns_ssutable_firstrule(const dns_ssutable_t *table, dns_ssurule_t **rule);
dns_name_t *identity; /*%< the identity to match */
dns_name_t *name; /*%< the name being updated */
unsigned int ntypes; /*%< number of data types covered */
- dns_rdatatype_t *types; /*%< the data types. Can include */
+ dns_ssuruletype_t *types; /*%< the data types. Can include */
/* ANY. if NULL, defaults to all */
/* types except SIG, SOA, and NS */
ISC_LINK(dns_ssurule_t) link;
dns_ssurule_t *rule = ISC_LIST_HEAD(table->rules);
if (rule->identity != NULL) {
dns_name_free(rule->identity, mctx);
- isc_mem_put(mctx, rule->identity, sizeof(dns_name_t));
+ isc_mem_put(mctx, rule->identity,
+ sizeof(*rule->identity));
}
if (rule->name != NULL) {
dns_name_free(rule->name, mctx);
- isc_mem_put(mctx, rule->name, sizeof(dns_name_t));
+ isc_mem_put(mctx, rule->name, sizeof(*rule->name));
}
if (rule->types != NULL) {
isc_mem_put(mctx, rule->types,
- rule->ntypes * sizeof(dns_rdatatype_t));
+ rule->ntypes * sizeof(*rule->types));
}
ISC_LIST_UNLINK(table->rules, rule, link);
rule->magic = 0;
dns_ssutable_addrule(dns_ssutable_t *table, bool grant,
const dns_name_t *identity, dns_ssumatchtype_t matchtype,
const dns_name_t *name, unsigned int ntypes,
- dns_rdatatype_t *types) {
+ dns_ssuruletype_t *types) {
dns_ssurule_t *rule;
isc_mem_t *mctx;
}
mctx = table->mctx;
- rule = isc_mem_get(mctx, sizeof(dns_ssurule_t));
+ rule = isc_mem_get(mctx, sizeof(*rule));
rule->identity = NULL;
rule->name = NULL;
rule->grant = grant;
- rule->identity = isc_mem_get(mctx, sizeof(dns_name_t));
+ rule->identity = isc_mem_get(mctx, sizeof(*rule->identity));
dns_name_init(rule->identity, NULL);
dns_name_dup(identity, mctx, rule->identity);
- rule->name = isc_mem_get(mctx, sizeof(dns_name_t));
+ rule->name = isc_mem_get(mctx, sizeof(*rule->name));
dns_name_init(rule->name, NULL);
dns_name_dup(name, mctx, rule->name);
rule->ntypes = ntypes;
if (ntypes > 0) {
- rule->types = isc_mem_get(mctx,
- ntypes * sizeof(dns_rdatatype_t));
- memmove(rule->types, types, ntypes * sizeof(dns_rdatatype_t));
+ rule->types = isc_mem_get(mctx, ntypes * sizeof(*rule->types));
+ memmove(rule->types, types, ntypes * sizeof(*rule->types));
} else {
rule->types = NULL;
}
}
} else {
for (i = 0; i < rule->ntypes; i++) {
- if (rule->types[i] == dns_rdatatype_any ||
- rule->types[i] == type) {
+ if (rule->types[i].type == dns_rdatatype_any ||
+ rule->types[i].type == type) {
break;
}
}
}
unsigned int
-dns_ssurule_types(const dns_ssurule_t *rule, dns_rdatatype_t **types) {
+dns_ssurule_types(const dns_ssurule_t *rule, dns_ssuruletype_t **types) {
REQUIRE(VALID_SSURULE(rule));
REQUIRE(types != NULL && *types != NULL);
*types = rule->types;
rule->identity = NULL;
rule->name = NULL;
- rule->types = NULL;
rule->grant = true;
rule->matchtype = dns_ssumatchtype_dlz;
rule->ntypes = 0;