ssu.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004-2008, 2010, 2011, 2013, 2014  Internet Systems Consortium, Inc. ("ISC")
00003  * Copyright (C) 2000, 2001, 2003  Internet Software Consortium.
00004  *
00005  * Permission to use, copy, modify, and/or distribute this software for any
00006  * purpose with or without fee is hereby granted, provided that the above
00007  * copyright notice and this permission notice appear in all copies.
00008  *
00009  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00010  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00011  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00012  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00013  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00014  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00015  * PERFORMANCE OF THIS SOFTWARE.
00016  */
00017 
00018 /*! \file */
00019 /*
00020  * $Id: ssu.c,v 1.38 2011/01/06 23:47:00 tbox Exp $
00021  * Principal Author: Brian Wellington
00022  */
00023 
00024 #include <config.h>
00025 
00026 #include <isc/magic.h>
00027 #include <isc/mem.h>
00028 #include <isc/netaddr.h>
00029 #include <isc/result.h>
00030 #include <isc/string.h>
00031 #include <isc/util.h>
00032 
00033 #include <dns/dlz.h>
00034 #include <dns/fixedname.h>
00035 #include <dns/name.h>
00036 #include <dns/ssu.h>
00037 
00038 #include <dst/gssapi.h>
00039 #include <dst/dst.h>
00040 
00041 #define SSUTABLEMAGIC           ISC_MAGIC('S', 'S', 'U', 'T')
00042 #define VALID_SSUTABLE(table)   ISC_MAGIC_VALID(table, SSUTABLEMAGIC)
00043 
00044 #define SSURULEMAGIC            ISC_MAGIC('S', 'S', 'U', 'R')
00045 #define VALID_SSURULE(table)    ISC_MAGIC_VALID(table, SSURULEMAGIC)
00046 
00047 struct dns_ssurule {
00048         unsigned int magic;
00049         isc_boolean_t grant;    /*%< is this a grant or a deny? */
00050         unsigned int matchtype; /*%< which type of pattern match? */
00051         dns_name_t *identity;   /*%< the identity to match */
00052         dns_name_t *name;       /*%< the name being updated */
00053         unsigned int ntypes;    /*%< number of data types covered */
00054         dns_rdatatype_t *types; /*%< the data types.  Can include ANY, */
00055                                 /*%< defaults to all but SIG,SOA,NS if NULL */
00056         ISC_LINK(dns_ssurule_t) link;
00057 };
00058 
00059 struct dns_ssutable {
00060         unsigned int magic;
00061         isc_mem_t *mctx;
00062         unsigned int references;
00063         isc_mutex_t lock;
00064         dns_dlzdb_t *dlzdatabase;
00065         ISC_LIST(dns_ssurule_t) rules;
00066 };
00067 
00068 isc_result_t
00069 dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **tablep) {
00070         isc_result_t result;
00071         dns_ssutable_t *table;
00072 
00073         REQUIRE(tablep != NULL && *tablep == NULL);
00074         REQUIRE(mctx != NULL);
00075 
00076         table = isc_mem_get(mctx, sizeof(dns_ssutable_t));
00077         if (table == NULL)
00078                 return (ISC_R_NOMEMORY);
00079         result = isc_mutex_init(&table->lock);
00080         if (result != ISC_R_SUCCESS) {
00081                 isc_mem_put(mctx, table, sizeof(dns_ssutable_t));
00082                 return (result);
00083         }
00084         table->references = 1;
00085         table->mctx = NULL;
00086         isc_mem_attach(mctx, &table->mctx);
00087         ISC_LIST_INIT(table->rules);
00088         table->magic = SSUTABLEMAGIC;
00089         *tablep = table;
00090         return (ISC_R_SUCCESS);
00091 }
00092 
00093 static inline void
00094 destroy(dns_ssutable_t *table) {
00095         isc_mem_t *mctx;
00096 
00097         REQUIRE(VALID_SSUTABLE(table));
00098 
00099         mctx = table->mctx;
00100         while (!ISC_LIST_EMPTY(table->rules)) {
00101                 dns_ssurule_t *rule = ISC_LIST_HEAD(table->rules);
00102                 if (rule->identity != NULL) {
00103                         dns_name_free(rule->identity, mctx);
00104                         isc_mem_put(mctx, rule->identity, sizeof(dns_name_t));
00105                 }
00106                 if (rule->name != NULL) {
00107                         dns_name_free(rule->name, mctx);
00108                         isc_mem_put(mctx, rule->name, sizeof(dns_name_t));
00109                 }
00110                 if (rule->types != NULL)
00111                         isc_mem_put(mctx, rule->types,
00112                                     rule->ntypes * sizeof(dns_rdatatype_t));
00113                 ISC_LIST_UNLINK(table->rules, rule, link);
00114                 rule->magic = 0;
00115                 isc_mem_put(mctx, rule, sizeof(dns_ssurule_t));
00116         }
00117         DESTROYLOCK(&table->lock);
00118         table->magic = 0;
00119         isc_mem_putanddetach(&table->mctx, table, sizeof(dns_ssutable_t));
00120 }
00121 
00122 void
00123 dns_ssutable_attach(dns_ssutable_t *source, dns_ssutable_t **targetp) {
00124         REQUIRE(VALID_SSUTABLE(source));
00125         REQUIRE(targetp != NULL && *targetp == NULL);
00126 
00127         LOCK(&source->lock);
00128 
00129         INSIST(source->references > 0);
00130         source->references++;
00131         INSIST(source->references != 0);
00132 
00133         UNLOCK(&source->lock);
00134 
00135         *targetp = source;
00136 }
00137 
00138 void
00139 dns_ssutable_detach(dns_ssutable_t **tablep) {
00140         dns_ssutable_t *table;
00141         isc_boolean_t done = ISC_FALSE;
00142 
00143         REQUIRE(tablep != NULL);
00144         table = *tablep;
00145         REQUIRE(VALID_SSUTABLE(table));
00146 
00147         LOCK(&table->lock);
00148 
00149         INSIST(table->references > 0);
00150         if (--table->references == 0)
00151                 done = ISC_TRUE;
00152         UNLOCK(&table->lock);
00153 
00154         *tablep = NULL;
00155 
00156         if (done)
00157                 destroy(table);
00158 }
00159 
00160 isc_result_t
00161 dns_ssutable_addrule(dns_ssutable_t *table, isc_boolean_t grant,
00162                      dns_name_t *identity, unsigned int matchtype,
00163                      dns_name_t *name, unsigned int ntypes,
00164                      dns_rdatatype_t *types)
00165 {
00166         dns_ssurule_t *rule;
00167         isc_mem_t *mctx;
00168         isc_result_t result;
00169 
00170         REQUIRE(VALID_SSUTABLE(table));
00171         REQUIRE(dns_name_isabsolute(identity));
00172         REQUIRE(dns_name_isabsolute(name));
00173         REQUIRE(matchtype <= DNS_SSUMATCHTYPE_MAX);
00174         if (matchtype == DNS_SSUMATCHTYPE_WILDCARD)
00175                 REQUIRE(dns_name_iswildcard(name));
00176         if (ntypes > 0)
00177                 REQUIRE(types != NULL);
00178 
00179         mctx = table->mctx;
00180         rule = isc_mem_get(mctx, sizeof(dns_ssurule_t));
00181         if (rule == NULL)
00182                 return (ISC_R_NOMEMORY);
00183 
00184         rule->identity = NULL;
00185         rule->name = NULL;
00186         rule->types = NULL;
00187 
00188         rule->grant = grant;
00189 
00190         rule->identity = isc_mem_get(mctx, sizeof(dns_name_t));
00191         if (rule->identity == NULL) {
00192                 result = ISC_R_NOMEMORY;
00193                 goto failure;
00194         }
00195         dns_name_init(rule->identity, NULL);
00196         result = dns_name_dup(identity, mctx, rule->identity);
00197         if (result != ISC_R_SUCCESS)
00198                 goto failure;
00199 
00200         rule->name = isc_mem_get(mctx, sizeof(dns_name_t));
00201         if (rule->name == NULL) {
00202                 result = ISC_R_NOMEMORY;
00203                 goto failure;
00204         }
00205         dns_name_init(rule->name, NULL);
00206         result = dns_name_dup(name, mctx, rule->name);
00207         if (result != ISC_R_SUCCESS)
00208                 goto failure;
00209 
00210         rule->matchtype = matchtype;
00211 
00212         rule->ntypes = ntypes;
00213         if (ntypes > 0) {
00214                 rule->types = isc_mem_get(mctx,
00215                                           ntypes * sizeof(dns_rdatatype_t));
00216                 if (rule->types == NULL) {
00217                         result = ISC_R_NOMEMORY;
00218                         goto failure;
00219                 }
00220                 memmove(rule->types, types, ntypes * sizeof(dns_rdatatype_t));
00221         } else
00222                 rule->types = NULL;
00223 
00224         rule->magic = SSURULEMAGIC;
00225         ISC_LIST_INITANDAPPEND(table->rules, rule, link);
00226 
00227         return (ISC_R_SUCCESS);
00228 
00229  failure:
00230         if (rule->identity != NULL) {
00231                 if (dns_name_dynamic(rule->identity))
00232                         dns_name_free(rule->identity, mctx);
00233                 isc_mem_put(mctx, rule->identity, sizeof(dns_name_t));
00234         }
00235         if (rule->name != NULL) {
00236                 if (dns_name_dynamic(rule->name))
00237                         dns_name_free(rule->name, mctx);
00238                 isc_mem_put(mctx, rule->name, sizeof(dns_name_t));
00239         }
00240         if (rule->types != NULL)
00241                 isc_mem_put(mctx, rule->types,
00242                             ntypes * sizeof(dns_rdatatype_t));
00243         isc_mem_put(mctx, rule, sizeof(dns_ssurule_t));
00244 
00245         return (result);
00246 }
00247 
00248 static inline isc_boolean_t
00249 isusertype(dns_rdatatype_t type) {
00250         return (ISC_TF(type != dns_rdatatype_ns &&
00251                        type != dns_rdatatype_soa &&
00252                        type != dns_rdatatype_rrsig));
00253 }
00254 
00255 static void
00256 reverse_from_address(dns_name_t *tcpself, isc_netaddr_t *tcpaddr) {
00257         char buf[16 * 4 + sizeof("IP6.ARPA.")];
00258         isc_result_t result;
00259         unsigned char *ap;
00260         isc_buffer_t b;
00261         unsigned long l;
00262 
00263         switch (tcpaddr->family) {
00264         case AF_INET:
00265                 l = ntohl(tcpaddr->type.in.s_addr);
00266                 result = isc_string_printf(buf, sizeof(buf),
00267                                            "%lu.%lu.%lu.%lu.IN-ADDR.ARPA.",
00268                                            (l >> 0) & 0xff, (l >> 8) & 0xff,
00269                                            (l >> 16) & 0xff, (l >> 24) & 0xff);
00270                 RUNTIME_CHECK(result == ISC_R_SUCCESS);
00271                 break;
00272         case AF_INET6:
00273                 ap = tcpaddr->type.in6.s6_addr;
00274                 result = isc_string_printf(buf, sizeof(buf),
00275                                            "%x.%x.%x.%x.%x.%x.%x.%x."
00276                                            "%x.%x.%x.%x.%x.%x.%x.%x."
00277                                            "%x.%x.%x.%x.%x.%x.%x.%x."
00278                                            "%x.%x.%x.%x.%x.%x.%x.%x."
00279                                            "IP6.ARPA.",
00280                                            ap[15] & 0x0f, (ap[15] >> 4) & 0x0f,
00281                                            ap[14] & 0x0f, (ap[14] >> 4) & 0x0f,
00282                                            ap[13] & 0x0f, (ap[13] >> 4) & 0x0f,
00283                                            ap[12] & 0x0f, (ap[12] >> 4) & 0x0f,
00284                                            ap[11] & 0x0f, (ap[11] >> 4) & 0x0f,
00285                                            ap[10] & 0x0f, (ap[10] >> 4) & 0x0f,
00286                                            ap[9] & 0x0f, (ap[9] >> 4) & 0x0f,
00287                                            ap[8] & 0x0f, (ap[8] >> 4) & 0x0f,
00288                                            ap[7] & 0x0f, (ap[7] >> 4) & 0x0f,
00289                                            ap[6] & 0x0f, (ap[6] >> 4) & 0x0f,
00290                                            ap[5] & 0x0f, (ap[5] >> 4) & 0x0f,
00291                                            ap[4] & 0x0f, (ap[4] >> 4) & 0x0f,
00292                                            ap[3] & 0x0f, (ap[3] >> 4) & 0x0f,
00293                                            ap[2] & 0x0f, (ap[2] >> 4) & 0x0f,
00294                                            ap[1] & 0x0f, (ap[1] >> 4) & 0x0f,
00295                                            ap[0] & 0x0f, (ap[0] >> 4) & 0x0f);
00296                 RUNTIME_CHECK(result == ISC_R_SUCCESS);
00297                 break;
00298         default:
00299                 INSIST(0);
00300         }
00301         isc_buffer_init(&b, buf, strlen(buf));
00302         isc_buffer_add(&b, strlen(buf));
00303         result = dns_name_fromtext(tcpself, &b, dns_rootname, 0, NULL);
00304         RUNTIME_CHECK(result == ISC_R_SUCCESS);
00305 }
00306 
00307 static void
00308 stf_from_address(dns_name_t *stfself, isc_netaddr_t *tcpaddr) {
00309         char buf[sizeof("X.X.X.X.Y.Y.Y.Y.2.0.0.2.IP6.ARPA.")];
00310         isc_result_t result;
00311         unsigned char *ap;
00312         isc_buffer_t b;
00313         unsigned long l;
00314 
00315         switch(tcpaddr->family) {
00316         case AF_INET:
00317                 l = ntohl(tcpaddr->type.in.s_addr);
00318                 result = isc_string_printf(buf, sizeof(buf),
00319                                            "%lx.%lx.%lx.%lx.%lx.%lx.%lx.%lx"
00320                                            "2.0.0.2.IP6.ARPA.",
00321                                            l & 0xf, (l >> 4) & 0xf,
00322                                            (l >> 8) & 0xf, (l >> 12) & 0xf,
00323                                            (l >> 16) & 0xf, (l >> 20) & 0xf,
00324                                            (l >> 24) & 0xf, (l >> 28) & 0xf);
00325                 RUNTIME_CHECK(result == ISC_R_SUCCESS);
00326                 break;
00327         case AF_INET6:
00328                 ap = tcpaddr->type.in6.s6_addr;
00329                 result = isc_string_printf(buf, sizeof(buf),
00330                                            "%x.%x.%x.%x.%x.%x.%x.%x."
00331                                            "%x.%x.%x.%x.IP6.ARPA.",
00332                                            ap[5] & 0x0f, (ap[5] >> 4) & 0x0f,
00333                                            ap[4] & 0x0f, (ap[4] >> 4) & 0x0f,
00334                                            ap[3] & 0x0f, (ap[3] >> 4) & 0x0f,
00335                                            ap[2] & 0x0f, (ap[2] >> 4) & 0x0f,
00336                                            ap[1] & 0x0f, (ap[1] >> 4) & 0x0f,
00337                                            ap[0] & 0x0f, (ap[0] >> 4) & 0x0f);
00338                 RUNTIME_CHECK(result == ISC_R_SUCCESS);
00339                 break;
00340         default:
00341                 INSIST(0);
00342         }
00343         isc_buffer_init(&b, buf, strlen(buf));
00344         isc_buffer_add(&b, strlen(buf));
00345         result = dns_name_fromtext(stfself, &b, dns_rootname, 0, NULL);
00346         RUNTIME_CHECK(result == ISC_R_SUCCESS);
00347 }
00348 
00349 isc_boolean_t
00350 dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer,
00351                         dns_name_t *name, isc_netaddr_t *tcpaddr,
00352                         dns_rdatatype_t type,
00353                         const dst_key_t *key)
00354 {
00355         dns_ssurule_t *rule;
00356         unsigned int i;
00357         dns_fixedname_t fixed;
00358         dns_name_t *wildcard;
00359         dns_name_t *tcpself;
00360         dns_name_t *stfself;
00361         isc_result_t result;
00362 
00363         REQUIRE(VALID_SSUTABLE(table));
00364         REQUIRE(signer == NULL || dns_name_isabsolute(signer));
00365         REQUIRE(dns_name_isabsolute(name));
00366 
00367         if (signer == NULL && tcpaddr == NULL)
00368                 return (ISC_FALSE);
00369 
00370         for (rule = ISC_LIST_HEAD(table->rules);
00371              rule != NULL;
00372              rule = ISC_LIST_NEXT(rule, link))
00373         {
00374                 switch (rule->matchtype) {
00375                 case DNS_SSUMATCHTYPE_NAME:
00376                 case DNS_SSUMATCHTYPE_SUBDOMAIN:
00377                 case DNS_SSUMATCHTYPE_WILDCARD:
00378                 case DNS_SSUMATCHTYPE_SELF:
00379                 case DNS_SSUMATCHTYPE_SELFSUB:
00380                 case DNS_SSUMATCHTYPE_SELFWILD:
00381                         if (signer == NULL)
00382                                 continue;
00383                         if (dns_name_iswildcard(rule->identity)) {
00384                                 if (!dns_name_matcheswildcard(signer,
00385                                                               rule->identity))
00386                                         continue;
00387                         } else {
00388                                 if (!dns_name_equal(signer, rule->identity))
00389                                         continue;
00390                         }
00391                         break;
00392                 case DNS_SSUMATCHTYPE_SELFKRB5:
00393                 case DNS_SSUMATCHTYPE_SELFMS:
00394                 case DNS_SSUMATCHTYPE_SUBDOMAINKRB5:
00395                 case DNS_SSUMATCHTYPE_SUBDOMAINMS:
00396                         if (signer == NULL)
00397                                 continue;
00398                         break;
00399                 case DNS_SSUMATCHTYPE_TCPSELF:
00400                 case DNS_SSUMATCHTYPE_6TO4SELF:
00401                         if (tcpaddr == NULL)
00402                                 continue;
00403                         break;
00404                 }
00405 
00406                 switch (rule->matchtype) {
00407                 case DNS_SSUMATCHTYPE_NAME:
00408                         if (!dns_name_equal(name, rule->name))
00409                                 continue;
00410                         break;
00411                 case DNS_SSUMATCHTYPE_SUBDOMAIN:
00412                         if (!dns_name_issubdomain(name, rule->name))
00413                                 continue;
00414                         break;
00415                 case DNS_SSUMATCHTYPE_WILDCARD:
00416                         if (!dns_name_matcheswildcard(name, rule->name))
00417                                 continue;
00418                         break;
00419                 case DNS_SSUMATCHTYPE_SELF:
00420                         if (!dns_name_equal(signer, name))
00421                                 continue;
00422                         break;
00423                 case DNS_SSUMATCHTYPE_SELFSUB:
00424                         if (!dns_name_issubdomain(name, signer))
00425                                 continue;
00426                         break;
00427                 case DNS_SSUMATCHTYPE_SELFWILD:
00428                         dns_fixedname_init(&fixed);
00429                         wildcard = dns_fixedname_name(&fixed);
00430                         result = dns_name_concatenate(dns_wildcardname, signer,
00431                                                       wildcard, NULL);
00432                         if (result != ISC_R_SUCCESS)
00433                                 continue;
00434                         if (!dns_name_matcheswildcard(name, wildcard))
00435                                 continue;
00436                         break;
00437                 case DNS_SSUMATCHTYPE_SELFKRB5:
00438                         if (!dst_gssapi_identitymatchesrealmkrb5(signer, name,
00439                                                                rule->identity))
00440                                 continue;
00441                         break;
00442                 case DNS_SSUMATCHTYPE_SELFMS:
00443                         if (!dst_gssapi_identitymatchesrealmms(signer, name,
00444                                                                rule->identity))
00445                                 continue;
00446                         break;
00447                 case DNS_SSUMATCHTYPE_SUBDOMAINKRB5:
00448                         if (!dns_name_issubdomain(name, rule->name))
00449                                 continue;
00450                         if (!dst_gssapi_identitymatchesrealmkrb5(signer, NULL,
00451                                                                rule->identity))
00452                                 continue;
00453                         break;
00454                 case DNS_SSUMATCHTYPE_SUBDOMAINMS:
00455                         if (!dns_name_issubdomain(name, rule->name))
00456                                 continue;
00457                         if (!dst_gssapi_identitymatchesrealmms(signer, NULL,
00458                                                                rule->identity))
00459                                 continue;
00460                         break;
00461                 case DNS_SSUMATCHTYPE_TCPSELF:
00462                         dns_fixedname_init(&fixed);
00463                         tcpself = dns_fixedname_name(&fixed);
00464                         reverse_from_address(tcpself, tcpaddr);
00465                         if (dns_name_iswildcard(rule->identity)) {
00466                                 if (!dns_name_matcheswildcard(tcpself,
00467                                                               rule->identity))
00468                                         continue;
00469                         } else {
00470                                 if (!dns_name_equal(tcpself, rule->identity))
00471                                         continue;
00472                         }
00473                         if (!dns_name_equal(tcpself, name))
00474                                 continue;
00475                         break;
00476                 case DNS_SSUMATCHTYPE_6TO4SELF:
00477                         dns_fixedname_init(&fixed);
00478                         stfself = dns_fixedname_name(&fixed);
00479                         stf_from_address(stfself, tcpaddr);
00480                         if (dns_name_iswildcard(rule->identity)) {
00481                                 if (!dns_name_matcheswildcard(stfself,
00482                                                               rule->identity))
00483                                         continue;
00484                         } else {
00485                                 if (!dns_name_equal(stfself, rule->identity))
00486                                         continue;
00487                         }
00488                         if (!dns_name_equal(stfself, name))
00489                                 continue;
00490                         break;
00491                 case DNS_SSUMATCHTYPE_EXTERNAL:
00492                         if (!dns_ssu_external_match(rule->identity, signer,
00493                                                     name, tcpaddr, type, key,
00494                                                     table->mctx))
00495                                 continue;
00496                         break;
00497                 case DNS_SSUMATCHTYPE_DLZ:
00498                         if (!dns_dlz_ssumatch(table->dlzdatabase, signer,
00499                                               name, tcpaddr, type, key))
00500                                 continue;
00501                         break;
00502                 }
00503 
00504                 if (rule->ntypes == 0) {
00505                         /*
00506                          * If this is a DLZ rule, then the DLZ ssu
00507                          * checks will have already checked
00508                          * the type.
00509                          */
00510                         if (rule->matchtype != DNS_SSUMATCHTYPE_DLZ &&
00511                             !isusertype(type))
00512                                 continue;
00513                 } else {
00514                         for (i = 0; i < rule->ntypes; i++) {
00515                                 if (rule->types[i] == dns_rdatatype_any ||
00516                                     rule->types[i] == type)
00517                                         break;
00518                         }
00519                         if (i == rule->ntypes)
00520                                 continue;
00521                 }
00522                 return (rule->grant);
00523         }
00524 
00525         return (ISC_FALSE);
00526 }
00527 
00528 isc_boolean_t
00529 dns_ssurule_isgrant(const dns_ssurule_t *rule) {
00530         REQUIRE(VALID_SSURULE(rule));
00531         return (rule->grant);
00532 }
00533 
00534 dns_name_t *
00535 dns_ssurule_identity(const dns_ssurule_t *rule) {
00536         REQUIRE(VALID_SSURULE(rule));
00537         return (rule->identity);
00538 }
00539 
00540 unsigned int
00541 dns_ssurule_matchtype(const dns_ssurule_t *rule) {
00542         REQUIRE(VALID_SSURULE(rule));
00543         return (rule->matchtype);
00544 }
00545 
00546 dns_name_t *
00547 dns_ssurule_name(const dns_ssurule_t *rule) {
00548         REQUIRE(VALID_SSURULE(rule));
00549         return (rule->name);
00550 }
00551 
00552 unsigned int
00553 dns_ssurule_types(const dns_ssurule_t *rule, dns_rdatatype_t **types) {
00554         REQUIRE(VALID_SSURULE(rule));
00555         REQUIRE(types != NULL && *types != NULL);
00556         *types = rule->types;
00557         return (rule->ntypes);
00558 }
00559 
00560 isc_result_t
00561 dns_ssutable_firstrule(const dns_ssutable_t *table, dns_ssurule_t **rule) {
00562         REQUIRE(VALID_SSUTABLE(table));
00563         REQUIRE(rule != NULL && *rule == NULL);
00564         *rule = ISC_LIST_HEAD(table->rules);
00565         return (*rule != NULL ? ISC_R_SUCCESS : ISC_R_NOMORE);
00566 }
00567 
00568 isc_result_t
00569 dns_ssutable_nextrule(dns_ssurule_t *rule, dns_ssurule_t **nextrule) {
00570         REQUIRE(VALID_SSURULE(rule));
00571         REQUIRE(nextrule != NULL && *nextrule == NULL);
00572         *nextrule = ISC_LIST_NEXT(rule, link);
00573         return (*nextrule != NULL ? ISC_R_SUCCESS : ISC_R_NOMORE);
00574 }
00575 
00576 /*
00577  * Create a specialised SSU table that points at an external DLZ database
00578  */
00579 isc_result_t
00580 dns_ssutable_createdlz(isc_mem_t *mctx, dns_ssutable_t **tablep,
00581                        dns_dlzdb_t *dlzdatabase)
00582 {
00583         isc_result_t result;
00584         dns_ssurule_t *rule;
00585         dns_ssutable_t *table = NULL;
00586 
00587         REQUIRE(tablep != NULL && *tablep == NULL);
00588 
00589         result = dns_ssutable_create(mctx, &table);
00590         if (result != ISC_R_SUCCESS)
00591                 return (result);
00592 
00593         table->dlzdatabase = dlzdatabase;
00594 
00595         rule = isc_mem_get(table->mctx, sizeof(dns_ssurule_t));
00596         if (rule == NULL) {
00597                 dns_ssutable_detach(&table);
00598                 return (ISC_R_NOMEMORY);
00599         }
00600 
00601         rule->identity = NULL;
00602         rule->name = NULL;
00603         rule->types = NULL;
00604         rule->grant = ISC_TRUE;
00605         rule->matchtype = DNS_SSUMATCHTYPE_DLZ;
00606         rule->ntypes = 0;
00607         rule->types = NULL;
00608         rule->magic = SSURULEMAGIC;
00609 
00610         ISC_LIST_INITANDAPPEND(table->rules, rule, link);
00611         *tablep = table;
00612         return (ISC_R_SUCCESS);
00613 }

Generated on Tue Apr 28 17:41:01 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha