1 /* $NetBSD: ssu.h,v 1.8 2025/01/26 16:25:28 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 #pragma once 17 18 /*! \file dns/ssu.h */ 19 20 #include <stdbool.h> 21 22 #include <isc/lang.h> 23 24 #include <dns/acl.h> 25 #include <dns/types.h> 26 27 #include <dst/dst.h> 28 29 ISC_LANG_BEGINDECLS 30 31 typedef enum { 32 dns_ssumatchtype_name = 0, 33 dns_ssumatchtype_subdomain = 1, 34 dns_ssumatchtype_wildcard = 2, 35 dns_ssumatchtype_self = 3, 36 dns_ssumatchtype_selfsub = 4, 37 dns_ssumatchtype_selfwild = 5, 38 dns_ssumatchtype_selfkrb5 = 6, 39 dns_ssumatchtype_selfms = 7, 40 dns_ssumatchtype_subdomainms = 8, 41 dns_ssumatchtype_subdomainkrb5 = 9, 42 dns_ssumatchtype_tcpself = 10, 43 dns_ssumatchtype_6to4self = 11, 44 dns_ssumatchtype_external = 12, 45 dns_ssumatchtype_local = 13, 46 dns_ssumatchtype_selfsubms = 14, 47 dns_ssumatchtype_selfsubkrb5 = 15, 48 dns_ssumatchtype_subdomainselfkrb5rhs = 16, 49 dns_ssumatchtype_subdomainselfmsrhs = 17, 50 dns_ssumatchtype_max = 17, /* max value */ 51 52 dns_ssumatchtype_dlz = 18 /* intentionally higher than _max */ 53 } dns_ssumatchtype_t; 54 55 typedef struct dns_ssuruletype { 56 dns_rdatatype_t type; /* type allowed */ 57 unsigned int max; /* maximum number of records allowed. */ 58 } dns_ssuruletype_t; 59 60 void 61 dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **table); 62 /*%< 63 * Creates a table that will be used to store simple-secure-update rules. 64 * Note: all locking must be provided by the client. 65 * 66 * Requires: 67 *\li 'mctx' is a valid memory context 68 *\li 'table' is not NULL, and '*table' is NULL 69 * 70 * Returns: 71 *\li ISC_R_SUCCESS 72 *\li ISC_R_NOMEMORY 73 */ 74 75 void 76 dns_ssutable_createdlz(isc_mem_t *mctx, dns_ssutable_t **tablep, 77 dns_dlzdb_t *dlzdatabase); 78 /*%< 79 * Create an SSU table that contains a dlzdatabase pointer, and a 80 * single rule with matchtype dns_ssumatchtype_dlz. This type of SSU 81 * table is used by writeable DLZ drivers to offload authorization for 82 * updates to the driver. 83 */ 84 85 void 86 dns_ssutable_attach(dns_ssutable_t *source, dns_ssutable_t **targetp); 87 /*%< 88 * Attach '*targetp' to 'source'. 89 * 90 * Requires: 91 *\li 'source' is a valid SSU table 92 *\li 'targetp' points to a NULL dns_ssutable_t *. 93 * 94 * Ensures: 95 *\li *targetp is attached to source. 96 */ 97 98 void 99 dns_ssutable_detach(dns_ssutable_t **tablep); 100 /*%< 101 * Detach '*tablep' from its simple-secure-update rule table. 102 * 103 * Requires: 104 *\li 'tablep' points to a valid dns_ssutable_t 105 * 106 * Ensures: 107 *\li *tablep is NULL 108 *\li If '*tablep' is the last reference to the SSU table, all 109 * resources used by the table will be freed. 110 */ 111 112 void 113 dns_ssutable_addrule(dns_ssutable_t *table, bool grant, 114 const dns_name_t *identity, dns_ssumatchtype_t matchtype, 115 const dns_name_t *name, unsigned int ntypes, 116 dns_ssuruletype_t *types); 117 /*%< 118 * Adds a new rule to a simple-secure-update rule table. The rule 119 * either grants or denies update privileges of an identity (or set of 120 * identities) to modify a name (or set of names) or certain types present 121 * at that name. 122 * 123 * Notes: 124 *\li If 'matchtype' is of SELF type, this rule only matches if the 125 * name to be updated matches the signing identity. 126 * 127 *\li If 'ntypes' is 0, this rule applies to all types except 128 * NS, SOA, RRSIG, and NSEC. 129 * 130 *\li If 'types' includes ANY, this rule applies to all types 131 * except NSEC. 132 * 133 * Requires: 134 *\li 'table' is a valid SSU table 135 *\li 'identity' is a valid absolute name 136 *\li 'matchtype' must be one of the defined constants. 137 *\li 'name' is a valid absolute name 138 *\li If 'ntypes' > 0, 'types' must not be NULL 139 * 140 * Returns: 141 *\li ISC_R_SUCCESS 142 *\li ISC_R_NOMEMORY 143 */ 144 145 bool 146 dns_ssutable_checkrules(dns_ssutable_t *table, const dns_name_t *signer, 147 const dns_name_t *name, const isc_netaddr_t *addr, 148 bool tcp, dns_aclenv_t *env, dns_rdatatype_t type, 149 const dns_name_t *target, const dst_key_t *key, 150 const dns_ssurule_t **rulep); 151 /*%< 152 * Checks that the attempted update of (name, type) is allowed according 153 * to the rules specified in the simple-secure-update rule table. If 154 * no rules are matched, access is denied. 155 * 156 * Notes: 157 * In dns_ssutable_checkrules(), 'addr' should only be 158 * set if the request received via TCP. This provides a 159 * weak assurance that the request was not spoofed. 160 * 'addr' is to to validate dns_ssumatchtype_tcpself 161 * and dns_ssumatchtype_6to4self rules. 162 * 163 * In dns_ssutable_checkrules2(), 'addr' can also be passed for 164 * UDP requests and TCP is specified via the 'tcp' parameter. 165 * In addition to dns_ssumatchtype_tcpself and 166 * tcp_ssumatchtype_6to4self rules, the address 167 * also be used to check dns_ssumatchtype_local rules. 168 * If 'addr' is set then 'env' must also be set so that 169 * requests from non-localhost addresses can be rejected. 170 * 171 * For dns_ssumatchtype_tcpself the addresses are mapped to 172 * the standard reverse names under IN-ADDR.ARPA and IP6.ARPA. 173 * RFC 1035, Section 3.5, "IN-ADDR.ARPA domain" and RFC 3596, 174 * Section 2.5, "IP6.ARPA Domain". 175 * 176 * For dns_ssumatchtype_6to4self, IPv4 address are converted 177 * to a 6to4 prefix (48 bits) per the rules in RFC 3056. Only 178 * the top 48 bits of the IPv6 address are mapped to the reverse 179 * name. This is independent of whether the most significant 16 180 * bits match 2002::/16, assigned for 6to4 prefixes, or not. 181 * 182 * Requires: 183 *\li 'table' is a valid SSU table 184 *\li 'signer' is NULL or a valid absolute name 185 *\li 'addr' is NULL or a valid network address. 186 *\li 'aclenv' is NULL or a valid ACL environment. 187 *\li 'name' is a valid absolute name 188 *\li if 'addr' is not NULL, 'env' is not NULL. 189 */ 190 191 /*% Accessor functions to extract rule components */ 192 bool 193 dns_ssurule_isgrant(const dns_ssurule_t *rule); 194 195 /*% Accessor functions to extract rule components */ 196 dns_name_t * 197 dns_ssurule_identity(const dns_ssurule_t *rule); 198 199 /*% Accessor functions to extract rule components */ 200 unsigned int 201 dns_ssurule_matchtype(const dns_ssurule_t *rule); 202 203 /*% Accessor functions to extract rule components */ 204 dns_name_t * 205 dns_ssurule_name(const dns_ssurule_t *rule); 206 207 /*% Accessor functions to extract rule components */ 208 unsigned int 209 dns_ssurule_types(const dns_ssurule_t *rule, dns_ssuruletype_t **types); 210 211 unsigned int 212 dns_ssurule_max(const dns_ssurule_t *rule, dns_rdatatype_t type); 213 /*%< 214 * Returns the maximum number of records configured for type `type`. 215 * If no maximum has been configured for `type` but one has been 216 * configured for ANY, return that value instead. Otherwise, return 217 * zero, which implies "unlimited". 218 */ 219 220 isc_result_t 221 dns_ssutable_firstrule(const dns_ssutable_t *table, dns_ssurule_t **rule); 222 /*%< 223 * Initiates a rule iterator. There is no need to maintain any state. 224 * 225 * Returns: 226 *\li #ISC_R_SUCCESS 227 *\li #ISC_R_NOMORE 228 */ 229 230 isc_result_t 231 dns_ssutable_nextrule(dns_ssurule_t *rule, dns_ssurule_t **nextrule); 232 /*%< 233 * Returns the next rule in the table. 234 * 235 * Returns: 236 *\li #ISC_R_SUCCESS 237 *\li #ISC_R_NOMORE 238 */ 239 240 bool 241 dns_ssu_external_match(const dns_name_t *identity, const dns_name_t *signer, 242 const dns_name_t *name, const isc_netaddr_t *tcpaddr, 243 dns_rdatatype_t type, const dst_key_t *key, 244 isc_mem_t *mctx); 245 /*%< 246 * Check a policy rule via an external application 247 */ 248 249 isc_result_t 250 dns_ssu_mtypefromstring(const char *str, dns_ssumatchtype_t *mtype); 251 /*%< 252 * Set 'mtype' from 'str' 253 * 254 * Requires: 255 *\li 'str' is not NULL. 256 *\li 'mtype' is not NULL, 257 * 258 * Returns: 259 *\li #ISC_R_SUCCESS 260 *\li #ISC_R_NOTFOUND 261 */ 262 263 ISC_LANG_ENDDECLS 264