+4885. [security] update-policy rules that otherwise ignore the name
+ field now require that it be set to "." to ensure
+ that any type list present is properly interpreted.
+ [RT #47126]
+
4882. [bug] Address potential memory leak in
dns_update_signaturesinc. [RT #47084]
const char *str;
isc_boolean_t grant = ISC_FALSE;
isc_boolean_t usezone = ISC_FALSE;
- unsigned int mtype = DNS_SSUMATCHTYPE_NAME;
+ dns_ssumatchtype_t mtype = DNS_SSUMATCHTYPE_NAME;
dns_fixedname_t fname, fident;
isc_buffer_t b;
dns_rdatatype_t *types;
INSIST(0);
str = cfg_obj_asstring(matchtype);
- if (strcasecmp(str, "name") == 0)
- mtype = DNS_SSUMATCHTYPE_NAME;
- else if (strcasecmp(str, "subdomain") == 0)
- mtype = DNS_SSUMATCHTYPE_SUBDOMAIN;
- else if (strcasecmp(str, "wildcard") == 0)
- mtype = DNS_SSUMATCHTYPE_WILDCARD;
- else if (strcasecmp(str, "self") == 0)
- mtype = DNS_SSUMATCHTYPE_SELF;
- else if (strcasecmp(str, "selfsub") == 0)
- mtype = DNS_SSUMATCHTYPE_SELFSUB;
- else if (strcasecmp(str, "selfwild") == 0)
- mtype = DNS_SSUMATCHTYPE_SELFWILD;
- else if (strcasecmp(str, "ms-self") == 0)
- mtype = DNS_SSUMATCHTYPE_SELFMS;
- else if (strcasecmp(str, "krb5-self") == 0)
- mtype = DNS_SSUMATCHTYPE_SELFKRB5;
- else if (strcasecmp(str, "ms-subdomain") == 0)
- mtype = DNS_SSUMATCHTYPE_SUBDOMAINMS;
- else if (strcasecmp(str, "krb5-subdomain") == 0)
- mtype = DNS_SSUMATCHTYPE_SUBDOMAINKRB5;
- else if (strcasecmp(str, "tcp-self") == 0)
- mtype = DNS_SSUMATCHTYPE_TCPSELF;
- else if (strcasecmp(str, "6to4-self") == 0)
- mtype = DNS_SSUMATCHTYPE_6TO4SELF;
- else if (strcasecmp(str, "zonesub") == 0) {
- mtype = DNS_SSUMATCHTYPE_SUBDOMAIN;
+ CHECK(dns_ssu_mtypefromstring(str, &mtype));
+ if (mtype == dns_ssumatchtype_subdomain) {
usezone = ISC_TRUE;
- } else if (strcasecmp(str, "external") == 0)
- mtype = DNS_SSUMATCHTYPE_EXTERNAL;
- else
- INSIST(0);
+ }
dns_fixedname_init(&fident);
str = cfg_obj_asstring(identity);
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * self TXT;
+ };
+};
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * selfsub TXT;
+ };
+};
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * selfwild TXT;
+ };
+};
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * ms-self TXT;
+ };
+};
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * krb5-self TXT;
+ };
+};
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * ms-subdomain TXT;
+ };
+};
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * krb5-subdomain TXT;
+ };
+};
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * tcp-self TXT;
+ };
+};
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * 6to4-self TXT;
+ };
+};
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * self * TXT;
+ };
+};
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * krb5-subdomain . TXT;
+ };
+};
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * tcp-self . TXT;
+ };
+};
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * 6to4-self . TXT;
+ };
+};
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * self . TXT;
+ };
+};
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * selfsub . TXT;
+ };
+};
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * selfsub * TXT;
+ };
+};
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * selfwild * TXT;
+ };
+};
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * selfwild . TXT;
+ };
+};
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * krb5-self . TXT;
+ };
+};
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * ms-self . TXT;
+ };
+};
--- /dev/null
+zone "example.com" {
+ type master;
+ file "example.com.db";
+ update-policy {
+ grant * ms-subdomain . TXT;
+ };
+};
for bad in bad*.conf
do
- n=`expr $n + 1`
- echo "I: checking that named-checkconf detects error in $bad ($n)"
- ret=0
- $CHECKCONF $bad > checkconf.out 2>&1
- if [ $? != 1 ]; then ret=1; fi
- grep "^$bad:[0-9]*: " checkconf.out > /dev/null || ret=1
- if [ $ret != 0 ]; then echo "I:failed"; fi
- status=`expr $status + $ret`
+ n=`expr $n + 1`
+ echo "I: checking that named-checkconf detects error in $bad ($n)"
+ ret=0
+ $CHECKCONF $bad > checkconf.out 2>&1
+ if [ $? != 1 ]; then ret=1; fi
+ grep "^$bad:[0-9]*: " checkconf.out > /dev/null || ret=1
+ case $bad in
+ bad-update-policy[123].conf)
+ pat="identity and name fields are not the same"
+ grep "$pat" checkconf.out > /dev/null || ret=1
+ ;;
+ bad-update-policy*.conf)
+ pat="name field not set to placeholder value"
+ grep "$pat" checkconf.out > /dev/null || ret=1
+ ;;
+ esac
+ if [ $ret != 0 ]; then echo "I:failed"; fi
+ status=`expr $status + $ret`
done
for good in good-*.conf
<replaceable>identity</replaceable> field.
The <replaceable>name</replaceable> field
is ignored, but should be the same as the
- <replaceable>identity</replaceable> field.
+ <replaceable>identity</replaceable> field or
+ "."
The <varname>self</varname> nametype is
most useful when allowing using one key per
name to update, where the key has the same
and converts it machine.realm allowing the machine
to update machine.realm. The REALM to be matched
is specified in the <replaceable>identity</replaceable>
- field.
+ field. The name field should be set to "."
</para>
</entry>
</row>
and converts it machine.realm allowing the machine
to update machine.realm. The REALM to be matched
is specified in the <replaceable>identity</replaceable>
- field.
+ field. The name field should be set to "."
</para>
</entry>
</row>
converts it to machine.realm allowing the machine
to update subdomains of machine.realm. The REALM
to be matched is specified in the
- <replaceable>identity</replaceable> field.
+ <replaceable>identity</replaceable> field. The
+ name field should be set to "."
</para>
</entry>
</row>
Allow updates that have been sent via TCP and
for which the standard mapping from the initiating
IP address into the IN-ADDR.ARPA and IP6.ARPA
- namespaces match the name to be updated.
+ namespaces match the name to be updated. The
+ name field should be set to "."
</para>
<note>
It is theoretically possible to spoof these TCP
#include <dns/rdatatype.h>
#include <dns/rrl.h>
#include <dns/secalg.h>
+#include <dns/ssu.h>
#include <dst/dst.h>
isc_result_t tresult;
const cfg_listelt_t *element;
const cfg_listelt_t *element2;
- dns_fixedname_t fixed;
+ dns_fixedname_t fixed_id, fixed_name;
+ dns_name_t *id, *name;
const char *str;
- isc_buffer_t b;
/* Check for "update-policy local;" */
if (cfg_obj_isstring(policy) &&
const cfg_obj_t *matchtype = cfg_tuple_get(stmt, "matchtype");
const cfg_obj_t *dname = cfg_tuple_get(stmt, "name");
const cfg_obj_t *typelist = cfg_tuple_get(stmt, "types");
+ dns_ssumatchtype_t mtype;
+
+ dns_fixedname_init(&fixed_id);
+ dns_fixedname_init(&fixed_name);
+ id = dns_fixedname_name(&fixed_id);
+ name = dns_fixedname_name(&fixed_name);
+
+ tresult = dns_ssu_mtypefromstring(cfg_obj_asstring(matchtype),
+ &mtype);
+ if (tresult != ISC_R_SUCCESS) {
+ cfg_obj_log(identity, logctx, ISC_LOG_ERROR,
+ "has a bad match-type");
+ }
- dns_fixedname_init(&fixed);
str = cfg_obj_asstring(identity);
- isc_buffer_constinit(&b, str, strlen(str));
- isc_buffer_add(&b, strlen(str));
- tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
- dns_rootname, 0, NULL);
+ tresult = dns_name_fromstring(id, str, 1, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(identity, logctx, ISC_LOG_ERROR,
"'%s' is not a valid name", str);
result = tresult;
}
+ /*
+ * There is no name field for subzone.
+ */
if (tresult == ISC_R_SUCCESS &&
- strcasecmp(cfg_obj_asstring(matchtype), "zonesub") != 0) {
- dns_fixedname_init(&fixed);
+ mtype != dns_ssumatchtype_subdomain)
+ {
str = cfg_obj_asstring(dname);
- isc_buffer_constinit(&b, str, strlen(str));
- isc_buffer_add(&b, strlen(str));
- tresult = dns_name_fromtext(dns_fixedname_name(&fixed),
- &b, dns_rootname, 0, NULL);
+ tresult = dns_name_fromstring(name, str, 0, NULL);
if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(dname, logctx, ISC_LOG_ERROR,
"'%s' is not a valid name", str);
}
if (tresult == ISC_R_SUCCESS &&
- strcasecmp(cfg_obj_asstring(matchtype), "wildcard") == 0 &&
- !dns_name_iswildcard(dns_fixedname_name(&fixed))) {
+ mtype == dns_ssumatchtype_wildcard &&
+ !dns_name_iswildcard(name))
+ {
cfg_obj_log(identity, logctx, ISC_LOG_ERROR,
"'%s' is not a wildcard", str);
result = ISC_R_FAILURE;
}
+ /*
+ * For some match types, the name should be a placeholder
+ * value, either "." or the same as identity.
+ */
+ switch (mtype) {
+ case dns_ssumatchtype_self:
+ case dns_ssumatchtype_selfsub:
+ case dns_ssumatchtype_selfwild:
+ if (tresult == ISC_R_SUCCESS &&
+ (!dns_name_equal(id, name) &&
+ !dns_name_equal(dns_rootname, name))) {
+ cfg_obj_log(identity, logctx, ISC_LOG_ERROR,
+ "identity and name fields are not "
+ "the same");
+ result = ISC_R_FAILURE;
+ }
+ break;
+ case dns_ssumatchtype_selfkrb5:
+ case dns_ssumatchtype_selfms:
+ case dns_ssumatchtype_subdomainms:
+ case dns_ssumatchtype_subdomainkrb5:
+ case dns_ssumatchtype_tcpself:
+ case dns_ssumatchtype_6to4self:
+ if (tresult == ISC_R_SUCCESS &&
+ !dns_name_equal(dns_rootname, name)) {
+ cfg_obj_log(identity, logctx, ISC_LOG_ERROR,
+ "name field not set to "
+ "placeholder value '.'");
+ result = ISC_R_FAILURE;
+ }
+ break;
+ case dns_ssumatchtype_name:
+ case dns_ssumatchtype_subdomain:
+ case dns_ssumatchtype_wildcard:
+ case dns_ssumatchtype_external:
+ case dns_ssumatchtype_local:
+ break;
+ default:
+ INSIST(0);
+ }
+
for (element2 = cfg_list_first(typelist);
element2 != NULL;
element2 = cfg_list_next(element2))
ISC_LANG_BEGINDECLS
-#define DNS_SSUMATCHTYPE_NAME 0
-#define DNS_SSUMATCHTYPE_SUBDOMAIN 1
-#define DNS_SSUMATCHTYPE_WILDCARD 2
-#define DNS_SSUMATCHTYPE_SELF 3
-#define DNS_SSUMATCHTYPE_SELFSUB 4
-#define DNS_SSUMATCHTYPE_SELFWILD 5
-#define DNS_SSUMATCHTYPE_SELFKRB5 6
-#define DNS_SSUMATCHTYPE_SELFMS 7
-#define DNS_SSUMATCHTYPE_SUBDOMAINMS 8
-#define DNS_SSUMATCHTYPE_SUBDOMAINKRB5 9
-#define DNS_SSUMATCHTYPE_TCPSELF 10
-#define DNS_SSUMATCHTYPE_6TO4SELF 11
-#define DNS_SSUMATCHTYPE_EXTERNAL 12
-#define DNS_SSUMATCHTYPE_LOCAL 13
-#define DNS_SSUMATCHTYPE_MAX 13 /* max value */
-
-#define DNS_SSUMATCHTYPE_DLZ 14 /* intentionally higher than _MAX */
+typedef enum {
+ dns_ssumatchtype_name = 0,
+ dns_ssumatchtype_subdomain = 1,
+ dns_ssumatchtype_wildcard = 2,
+ dns_ssumatchtype_self = 3,
+ dns_ssumatchtype_selfsub = 4,
+ dns_ssumatchtype_selfwild = 5,
+ dns_ssumatchtype_selfkrb5 = 6,
+ dns_ssumatchtype_selfms = 7,
+ dns_ssumatchtype_subdomainms = 8,
+ dns_ssumatchtype_subdomainkrb5 = 9,
+ dns_ssumatchtype_tcpself = 10,
+ dns_ssumatchtype_6to4self = 11,
+ dns_ssumatchtype_external = 12,
+ dns_ssumatchtype_local = 13,
+ dns_ssumatchtype_max = 13, /* max value */
+
+ dns_ssumatchtype_dlz = 14 /* intentionally higher than _max */
+} dns_ssumatchtype_t;
+
+#define DNS_SSUMATCHTYPE_NAME dns_ssumatchtype_name
+#define DNS_SSUMATCHTYPE_SUBDOMAIN dns_ssumatchtype_subdomain
+#define DNS_SSUMATCHTYPE_WILDCARD dns_ssumatchtype_wildcard
+#define DNS_SSUMATCHTYPE_SELF dns_ssumatchtype_self
+#define DNS_SSUMATCHTYPE_SELFSUB dns_ssumatchtype_selfsub
+#define DNS_SSUMATCHTYPE_SELFWILD dns_ssumatchtype_selfwild
+#define DNS_SSUMATCHTYPE_SELFKRB5 dns_ssumatchtype_selfkrb5
+#define DNS_SSUMATCHTYPE_SELFMS dns_ssumatchtype_selfms
+#define DNS_SSUMATCHTYPE_SUBDOMAINMS dns_ssumatchtype_subdomainms
+#define DNS_SSUMATCHTYPE_SUBDOMAINKRB5 dns_ssumatchtype_subdomainkrb5
+#define DNS_SSUMATCHTYPE_TCPSELF dns_ssumatchtype_tcpself
+#define DNS_SSUMATCHTYPE_6TO4SELF dns_ssumatchtype_6to4self
+#define DNS_SSUMATCHTYPE_EXTERNAL dns_ssumatchtype_external
+#define DNS_SSUMATCHTYPE_LOCAL dns_ssumatchtype_local
+#define DNS_SSUMATCHTYPE_MAX dns_ssumatchtype_max /* max value */
+
+#define DNS_SSUMATCHTYPE_DLZ dns_ssumatchtype_dlz /* intentionally higher than _MAX */
isc_result_t
dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **table);
*\li #ISC_R_NOMORE
*/
-
-/*%<
- * Check a policy rule via an external application
- */
isc_boolean_t
dns_ssu_external_match(dns_name_t *identity, dns_name_t *signer,
dns_name_t *name, isc_netaddr_t *tcpaddr,
dns_rdatatype_t type, const dst_key_t *key,
isc_mem_t *mctx);
+/*%<
+ * Check a policy rule via an external application
+ */
+
+isc_result_t
+dns_ssu_mtypefromstring(const char *str, dns_ssumatchtype_t *mtype);
+/*%<
+ * Set 'mtype' from 'str'
+ *
+ * Requires:
+ *\li 'str' is not NULL.
+ *\li 'mtype' is not NULL,
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOTFOUND
+ */
ISC_LANG_ENDDECLS
*tablep = table;
return (ISC_R_SUCCESS);
}
+
+isc_result_t
+dns_ssu_mtypefromstring(const char *str, dns_ssumatchtype_t *mtype) {
+
+ REQUIRE(str != NULL);
+ REQUIRE(mtype != NULL);
+
+ if (strcasecmp(str, "name") == 0) {
+ *mtype = dns_ssumatchtype_name;
+ } else if (strcasecmp(str, "subdomain") == 0) {
+ *mtype = dns_ssumatchtype_subdomain;
+ } else if (strcasecmp(str, "wildcard") == 0) {
+ *mtype = dns_ssumatchtype_wildcard;
+ } else if (strcasecmp(str, "self") == 0) {
+ *mtype = dns_ssumatchtype_self;
+ } else if (strcasecmp(str, "selfsub") == 0) {
+ *mtype = dns_ssumatchtype_selfsub;
+ } else if (strcasecmp(str, "selfwild") == 0) {
+ *mtype = dns_ssumatchtype_selfwild;
+ } else if (strcasecmp(str, "ms-self") == 0) {
+ *mtype = dns_ssumatchtype_selfms;
+ } else if (strcasecmp(str, "krb5-self") == 0) {
+ *mtype = dns_ssumatchtype_selfkrb5;
+ } else if (strcasecmp(str, "ms-subdomain") == 0) {
+ *mtype = dns_ssumatchtype_subdomainms;
+ } else if (strcasecmp(str, "krb5-subdomain") == 0) {
+ *mtype = dns_ssumatchtype_subdomainkrb5;
+ } else if (strcasecmp(str, "tcp-self") == 0) {
+ *mtype = dns_ssumatchtype_tcpself;
+ } else if (strcasecmp(str, "6to4-self") == 0) {
+ *mtype = dns_ssumatchtype_6to4self;
+ } else if (strcasecmp(str, "zonesub") == 0) {
+ *mtype = dns_ssumatchtype_subdomain;
+ } else if (strcasecmp(str, "external") == 0) {
+ *mtype = dns_ssumatchtype_external;
+ } else {
+ return (ISC_R_NOTFOUND);
+ }
+ return (ISC_R_SUCCESS);
+}
dns_soa_setretry
dns_soa_setserial
dns_ssu_external_match
+dns_ssu_mtypefromstring
dns_ssutable_addrule
dns_ssutable_attach
dns_ssutable_checkrules