]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
allow per type record counts to be specified
authorMark Andrews <marka@isc.org>
Wed, 3 Jul 2019 06:42:15 +0000 (16:42 +1000)
committerMark Andrews <marka@isc.org>
Wed, 13 May 2020 05:35:28 +0000 (15:35 +1000)
bin/named/zoneconf.c
bin/tests/system/checkconf/bad-update-policy16.conf [new file with mode: 0644]
bin/tests/system/checkconf/good-update-policy13.conf [new file with mode: 0644]
lib/bind9/check.c
lib/dns/include/dns/ssu.h
lib/dns/ssu.c

index 7cad6c6b7a2aa26ff21ea8675513064f578da742..785d392e7b28b2015a2e86e23e0eb627aa47904d 100644 (file)
@@ -237,7 +237,7 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone,
                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);
@@ -290,7 +290,7 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone,
                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;
@@ -298,22 +298,43 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone,
                     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;
                        }
                }
@@ -323,7 +344,7 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone,
                        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;
@@ -336,7 +357,7 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone,
         * 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,
diff --git a/bin/tests/system/checkconf/bad-update-policy16.conf b/bin/tests/system/checkconf/bad-update-policy16.conf
new file mode 100644 (file)
index 0000000..6870e65
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * 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 )";
+       };
+};
diff --git a/bin/tests/system/checkconf/good-update-policy13.conf b/bin/tests/system/checkconf/good-update-policy13.conf
new file mode 100644 (file)
index 0000000..e67e01f
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * 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);
+       };
+};
index fdb0f42378ee14244db71490d8144eca0305e1c4..9e761f4832eefe0716ebf14bbf9d8f31c1cc2b31 100644 (file)
@@ -45,6 +45,7 @@
 #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>
@@ -1850,15 +1851,35 @@ check_update_policy(const cfg_obj_t *policy, isc_log_t *logctx) {
                     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;
                        }
                }
index e2ead5bc0530b038c49a8c813263e5a202a06832..19f49f0b5b1bd7cd7636f12018dac3b14a8f85ab 100644 (file)
@@ -47,6 +47,11 @@ typedef enum {
        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);
 /*%<
@@ -103,7 +108,7 @@ isc_result_t
 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
@@ -191,7 +196,7 @@ 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_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);
index 47758b8cf63b12fa3e5d1dd5b699d0689e6844e6..c2647b6619641eaa33ba72873b24b5edaab9f14a 100644 (file)
@@ -44,7 +44,7 @@ struct dns_ssurule {
        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;
@@ -86,15 +86,16 @@ destroy(dns_ssutable_t *table) {
                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;
@@ -133,7 +134,7 @@ isc_result_t
 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;
 
@@ -149,7 +150,7 @@ dns_ssutable_addrule(dns_ssutable_t *table, bool grant,
        }
 
        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;
@@ -157,11 +158,11 @@ dns_ssutable_addrule(dns_ssutable_t *table, bool grant,
 
        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);
 
@@ -169,9 +170,8 @@ dns_ssutable_addrule(dns_ssutable_t *table, bool grant,
 
        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;
        }
@@ -513,8 +513,8 @@ dns_ssutable_checkrules(dns_ssutable_t *table, const dns_name_t *signer,
                        }
                } 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;
                                }
                        }
@@ -553,7 +553,7 @@ dns_ssurule_name(const dns_ssurule_t *rule) {
 }
 
 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;
@@ -599,7 +599,6 @@ dns_ssutable_createdlz(isc_mem_t *mctx, dns_ssutable_t **tablep,
 
        rule->identity = NULL;
        rule->name = NULL;
-       rule->types = NULL;
        rule->grant = true;
        rule->matchtype = dns_ssumatchtype_dlz;
        rule->ntypes = 0;