void dns_tkeyctx_destroy(dns_tkeyctx_t **tctxp) { isc_mem_t *mctx; dns_tkeyctx_t *tctx; REQUIRE(tctxp != NULL && *tctxp != NULL); tctx = *tctxp; mctx = tctx->mctx; if (tctx->dhkey != NULL) dst_key_free(&tctx->dhkey); if (tctx->domain != NULL) { if (dns_name_dynamic(tctx->domain)) dns_name_free(tctx->domain, mctx); isc_mem_put(mctx, tctx->domain, sizeof(dns_name_t)); } if (tctx->gssapi_keytab != NULL) { isc_mem_free(mctx, tctx->gssapi_keytab); } if (tctx->gsscred != NULL) dst_gssapi_releasecred(&tctx->gsscred); isc_entropy_detach(&tctx->ectx); isc_mem_put(mctx, tctx, sizeof(dns_tkeyctx_t)); isc_mem_detach(&mctx); *tctxp = NULL; }
static void levent_destroy(isc_event_t *event) { dns_lookupevent_t *levent; isc_mem_t *mctx; REQUIRE(event->ev_type == DNS_EVENT_LOOKUPDONE); mctx = event->ev_destroy_arg; levent = (dns_lookupevent_t *)event; if (levent->name != NULL) { if (dns_name_dynamic(levent->name)) dns_name_free(levent->name, mctx); isc_mem_put(mctx, levent->name, sizeof(dns_name_t)); } if (levent->rdataset != NULL) { dns_rdataset_disassociate(levent->rdataset); isc_mem_put(mctx, levent->rdataset, sizeof(dns_rdataset_t)); } if (levent->sigrdataset != NULL) { dns_rdataset_disassociate(levent->sigrdataset); isc_mem_put(mctx, levent->sigrdataset, sizeof(dns_rdataset_t)); } if (levent->node != NULL) dns_db_detachnode(levent->db, &levent->node); if (levent->db != NULL) dns_db_detach(&levent->db); isc_mem_put(mctx, event, event->ev_size); }
void ns_config_putipandkeylist(isc_mem_t *mctx, isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp, dns_name_t ***keysp, isc_uint32_t count) { unsigned int i; dns_name_t **keys; REQUIRE(addrsp != NULL && *addrsp != NULL); REQUIRE(dscpsp == NULL || *dscpsp != NULL); REQUIRE(keysp != NULL && *keysp != NULL); keys = *keysp; isc_mem_put(mctx, *addrsp, count * sizeof(isc_sockaddr_t)); if (dscpsp != NULL) isc_mem_put(mctx, *dscpsp, count * sizeof(isc_dscp_t)); for (i = 0; i < count; i++) { if (keys[i] == NULL) continue; if (dns_name_dynamic(keys[i])) dns_name_free(keys[i], mctx); isc_mem_put(mctx, keys[i], sizeof(dns_name_t)); } isc_mem_put(mctx, *keysp, count * sizeof(dns_name_t *)); *addrsp = NULL; if (dscpsp != NULL) *dscpsp = NULL; *keysp = NULL; }
isc_result_t isc__rdatalist_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_t *nsec, dns_rdataset_t *nsecsig) { dns_rdataclass_t rdclass = rdataset->rdclass; dns_rdataset_t *tnsec = NULL; dns_rdataset_t *tnsecsig = NULL; dns_name_t *noqname = rdataset->private6; REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0); (void)dns_name_dynamic(noqname); /* Sanity Check. */ for (rdataset = ISC_LIST_HEAD(noqname->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (rdataset->rdclass != rdclass) continue; if (rdataset->type == dns_rdatatype_nsec) tnsec = rdataset; if (rdataset->type == dns_rdatatype_rrsig && rdataset->covers == dns_rdatatype_nsec) tnsecsig = rdataset; } if (tnsec == NULL || tnsecsig == NULL) return (ISC_R_NOTFOUND); dns_name_clone(noqname, name); dns_rdataset_clone(tnsec, nsec); dns_rdataset_clone(tnsecsig, nsecsig); return (ISC_R_SUCCESS); }
isc_result_t ldapdb_create(isc_mem_t *mctx, dns_name_t *name, dns_dbtype_t type, dns_rdataclass_t rdclass, unsigned int argc, char *argv[], void *driverarg, dns_db_t **dbp) { ldapdb_t *ldapdb = NULL; isc_result_t result; isc_boolean_t lock_ready = ISC_FALSE; UNUSED(driverarg); /* Currently we don't need any data */ /* Database instance name. */ REQUIRE(argc == LDAP_DB_ARGC); REQUIRE(type == LDAP_DB_TYPE); REQUIRE(rdclass == LDAP_DB_RDATACLASS); REQUIRE(dbp != NULL && *dbp == NULL); CHECKED_MEM_GET_PTR(mctx, ldapdb); ZERO_PTR(ldapdb); isc_mem_attach(mctx, &ldapdb->common.mctx); CHECK(isc_mutex_init(&ldapdb->newversion_lock)); lock_ready = ISC_TRUE; dns_name_init(&ldapdb->common.origin, NULL); isc_ondestroy_init(&ldapdb->common.ondest); ldapdb->common.magic = DNS_DB_MAGIC; ldapdb->common.impmagic = LDAPDB_MAGIC; ldapdb->common.methods = &ldapdb_methods; ldapdb->common.attributes = 0; ldapdb->common.rdclass = rdclass; CHECK(dns_name_dupwithoffsets(name, mctx, &ldapdb->common.origin)); CHECK(isc_refcount_init(&ldapdb->refs, 1)); CHECK(manager_get_ldap_instance(argv[0], &ldapdb->ldap_inst)); CHECK(dns_db_create(mctx, "rbt", name, dns_dbtype_zone, dns_rdataclass_in, 0, NULL, &ldapdb->rbtdb)); *dbp = (dns_db_t *)ldapdb; return ISC_R_SUCCESS; cleanup: if (ldapdb != NULL) { if (lock_ready == ISC_TRUE) RUNTIME_CHECK(isc_mutex_destroy(&ldapdb->newversion_lock) == ISC_R_SUCCESS); if (dns_name_dynamic(&ldapdb->common.origin)) dns_name_free(&ldapdb->common.origin, mctx); isc_mem_putanddetach(&ldapdb->common.mctx, ldapdb, sizeof(*ldapdb)); } return result; }
static isc_result_t build_event(dns_lookup_t *lookup) { dns_name_t *name = NULL; dns_rdataset_t *rdataset = NULL; dns_rdataset_t *sigrdataset = NULL; isc_result_t result; name = isc_mem_get(lookup->mctx, sizeof(dns_name_t)); if (name == NULL) { result = ISC_R_NOMEMORY; goto fail; } dns_name_init(name, NULL); result = dns_name_dup(dns_fixedname_name(&lookup->name), lookup->mctx, name); if (result != ISC_R_SUCCESS) goto fail; if (dns_rdataset_isassociated(&lookup->rdataset)) { rdataset = isc_mem_get(lookup->mctx, sizeof(dns_rdataset_t)); if (rdataset == NULL) { result = ISC_R_NOMEMORY; goto fail; } dns_rdataset_init(rdataset); dns_rdataset_clone(&lookup->rdataset, rdataset); } if (dns_rdataset_isassociated(&lookup->sigrdataset)) { sigrdataset = isc_mem_get(lookup->mctx, sizeof(dns_rdataset_t)); if (sigrdataset == NULL) { result = ISC_R_NOMEMORY; goto fail; } dns_rdataset_init(sigrdataset); dns_rdataset_clone(&lookup->sigrdataset, sigrdataset); } lookup->event->name = name; lookup->event->rdataset = rdataset; lookup->event->sigrdataset = sigrdataset; return (ISC_R_SUCCESS); fail: if (name != NULL) { if (dns_name_dynamic(name)) dns_name_free(name, lookup->mctx); isc_mem_put(lookup->mctx, name, sizeof(dns_name_t)); } if (rdataset != NULL) { if (dns_rdataset_isassociated(rdataset)) dns_rdataset_disassociate(rdataset); isc_mem_put(lookup->mctx, rdataset, sizeof(dns_rdataset_t)); } return (result); }
/* * Forget a view's list of policy zones. */ void dns_rpz_view_destroy(dns_view_t *view) { dns_rpz_zone_t *zone; REQUIRE(view != NULL); while (!ISC_LIST_EMPTY(view->rpz_zones)) { zone = ISC_LIST_HEAD(view->rpz_zones); ISC_LIST_UNLINK(view->rpz_zones, zone, link); if (dns_name_dynamic(&zone->origin)) dns_name_free(&zone->origin, view->mctx); if (dns_name_dynamic(&zone->nsdname)) dns_name_free(&zone->nsdname, view->mctx); if (dns_name_dynamic(&zone->cname)) dns_name_free(&zone->cname, view->mctx); isc_mem_put(view->mctx, zone, sizeof(*zone)); } }
static isc_result_t dns_ecdb_create(isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type, dns_rdataclass_t rdclass, unsigned int argc, char *argv[], void *driverarg, dns_db_t **dbp) { dns_ecdb_t *ecdb; isc_result_t result; REQUIRE(mctx != NULL); REQUIRE(origin == dns_rootname); REQUIRE(type == dns_dbtype_cache); REQUIRE(dbp != NULL && *dbp == NULL); UNUSED(argc); UNUSED(argv); UNUSED(driverarg); ecdb = isc_mem_get(mctx, sizeof(*ecdb)); if (ecdb == NULL) return (ISC_R_NOMEMORY); ecdb->common.attributes = DNS_DBATTR_CACHE; ecdb->common.rdclass = rdclass; ecdb->common.methods = &ecdb_methods; dns_name_init(&ecdb->common.origin, NULL); result = dns_name_dupwithoffsets(origin, mctx, &ecdb->common.origin); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, ecdb, sizeof(*ecdb)); return (result); } result = isc_mutex_init(&ecdb->lock); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_mutex_init() failed: %s", isc_result_totext(result)); if (dns_name_dynamic(&ecdb->common.origin)) dns_name_free(&ecdb->common.origin, mctx); isc_mem_put(mctx, ecdb, sizeof(*ecdb)); return (ISC_R_UNEXPECTED); } ecdb->references = 1; ISC_LIST_INIT(ecdb->nodes); ecdb->common.mctx = NULL; isc_mem_attach(mctx, &ecdb->common.mctx); ecdb->common.impmagic = ECDB_MAGIC; ecdb->common.magic = DNS_DB_MAGIC; *dbp = (dns_db_t *)ecdb; return (ISC_R_SUCCESS); }
static void destroy_ecdb(dns_ecdb_t **ecdbp) { dns_ecdb_t *ecdb = *ecdbp; isc_mem_t *mctx = ecdb->common.mctx; if (dns_name_dynamic(&ecdb->common.origin)) dns_name_free(&ecdb->common.origin, mctx); DESTROYLOCK(&ecdb->lock); ecdb->common.impmagic = 0; ecdb->common.magic = 0; isc_mem_putanddetach(&mctx, ecdb, sizeof(*ecdb)); *ecdbp = NULL; }
isc_result_t isc__rdatalist_getclosest(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_t *neg, dns_rdataset_t *negsig) { dns_rdataclass_t rdclass = rdataset->rdclass; dns_rdataset_t *tneg = NULL; dns_rdataset_t *tnegsig = NULL; dns_name_t *closest = rdataset->private7; REQUIRE((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) != 0); (void)dns_name_dynamic(closest); /* Sanity Check. */ for (rdataset = ISC_LIST_HEAD(closest->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (rdataset->rdclass != rdclass) continue; if (rdataset->type == dns_rdatatype_nsec || rdataset->type == dns_rdatatype_nsec3) tneg = rdataset; } if (tneg == NULL) return (ISC_R_NOTFOUND); for (rdataset = ISC_LIST_HEAD(closest->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (rdataset->type == dns_rdatatype_rrsig && rdataset->covers == tneg->type) tnegsig = rdataset; } if (tnegsig == NULL) return (ISC_R_NOTFOUND); dns_name_clone(closest, name); dns_rdataset_clone(tneg, neg); dns_rdataset_clone(tnegsig, negsig); return (ISC_R_SUCCESS); }
isc_result_t dns_ssutable_addrule(dns_ssutable_t *table, isc_boolean_t grant, dns_name_t *identity, unsigned int matchtype, dns_name_t *name, unsigned int ntypes, dns_rdatatype_t *types) { dns_ssurule_t *rule; isc_mem_t *mctx; isc_result_t result; REQUIRE(VALID_SSUTABLE(table)); REQUIRE(dns_name_isabsolute(identity)); REQUIRE(dns_name_isabsolute(name)); REQUIRE(matchtype <= DNS_SSUMATCHTYPE_MAX); if (matchtype == DNS_SSUMATCHTYPE_WILDCARD) REQUIRE(dns_name_iswildcard(name)); if (ntypes > 0) REQUIRE(types != NULL); mctx = table->mctx; rule = isc_mem_get(mctx, sizeof(dns_ssurule_t)); if (rule == NULL) return (ISC_R_NOMEMORY); rule->identity = NULL; rule->name = NULL; rule->types = NULL; rule->grant = grant; rule->identity = isc_mem_get(mctx, sizeof(dns_name_t)); if (rule->identity == NULL) { result = ISC_R_NOMEMORY; goto failure; } dns_name_init(rule->identity, NULL); result = dns_name_dup(identity, mctx, rule->identity); if (result != ISC_R_SUCCESS) goto failure; rule->name = isc_mem_get(mctx, sizeof(dns_name_t)); if (rule->name == NULL) { result = ISC_R_NOMEMORY; goto failure; } dns_name_init(rule->name, NULL); result = dns_name_dup(name, mctx, rule->name); if (result != ISC_R_SUCCESS) goto failure; rule->matchtype = matchtype; rule->ntypes = ntypes; if (ntypes > 0) { rule->types = isc_mem_get(mctx, ntypes * sizeof(dns_rdatatype_t)); if (rule->types == NULL) { result = ISC_R_NOMEMORY; goto failure; } memmove(rule->types, types, ntypes * sizeof(dns_rdatatype_t)); } else rule->types = NULL; rule->magic = SSURULEMAGIC; ISC_LIST_INITANDAPPEND(table->rules, rule, link); return (ISC_R_SUCCESS); failure: if (rule->identity != NULL) { if (dns_name_dynamic(rule->identity)) dns_name_free(rule->identity, mctx); isc_mem_put(mctx, rule->identity, sizeof(dns_name_t)); } if (rule->name != NULL) { if (dns_name_dynamic(rule->name)) dns_name_free(rule->name, mctx); isc_mem_put(mctx, rule->name, sizeof(dns_name_t)); } if (rule->types != NULL) isc_mem_put(mctx, rule->types, ntypes * sizeof(dns_rdatatype_t)); isc_mem_put(mctx, rule, sizeof(dns_ssurule_t)); return (result); }
isc_result_t dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm, dst_key_t *dstkey, isc_boolean_t generated, dns_name_t *creator, isc_stdtime_t inception, isc_stdtime_t expire, isc_mem_t *mctx, dns_tsig_keyring_t *ring, dns_tsigkey_t **key) { dns_tsigkey_t *tkey; isc_result_t ret; unsigned int refs = 0; REQUIRE(key == NULL || *key == NULL); REQUIRE(name != NULL); REQUIRE(algorithm != NULL); REQUIRE(mctx != NULL); REQUIRE(key != NULL || ring != NULL); tkey = (dns_tsigkey_t *) isc_mem_get(mctx, sizeof(dns_tsigkey_t)); if (tkey == NULL) return (ISC_R_NOMEMORY); dns_name_init(&tkey->name, NULL); ret = dns_name_dup(name, mctx, &tkey->name); if (ret != ISC_R_SUCCESS) goto cleanup_key; (void)dns_name_downcase(&tkey->name, &tkey->name, NULL); if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME)) { tkey->algorithm = DNS_TSIG_HMACMD5_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACMD5) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA1_NAME)) { tkey->algorithm = DNS_TSIG_HMACSHA1_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA1) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA224_NAME)) { tkey->algorithm = DNS_TSIG_HMACSHA224_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA224) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA256_NAME)) { tkey->algorithm = DNS_TSIG_HMACSHA256_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA256) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA384_NAME)) { tkey->algorithm = DNS_TSIG_HMACSHA384_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA384) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA512_NAME)) { tkey->algorithm = DNS_TSIG_HMACSHA512_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA512) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPI_NAME)) { tkey->algorithm = DNS_TSIG_GSSAPI_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_GSSAPI) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPIMS_NAME)) { tkey->algorithm = DNS_TSIG_GSSAPIMS_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_GSSAPI) { ret = DNS_R_BADALG; goto cleanup_name; } } else { if (dstkey != NULL) { ret = DNS_R_BADALG; goto cleanup_name; } tkey->algorithm = isc_mem_get(mctx, sizeof(dns_name_t)); if (tkey->algorithm == NULL) { ret = ISC_R_NOMEMORY; goto cleanup_name; } dns_name_init(tkey->algorithm, NULL); ret = dns_name_dup(algorithm, mctx, tkey->algorithm); if (ret != ISC_R_SUCCESS) goto cleanup_algorithm; (void)dns_name_downcase(tkey->algorithm, tkey->algorithm, NULL); } if (creator != NULL) { tkey->creator = isc_mem_get(mctx, sizeof(dns_name_t)); if (tkey->creator == NULL) { ret = ISC_R_NOMEMORY; goto cleanup_algorithm; } dns_name_init(tkey->creator, NULL); ret = dns_name_dup(creator, mctx, tkey->creator); if (ret != ISC_R_SUCCESS) { isc_mem_put(mctx, tkey->creator, sizeof(dns_name_t)); goto cleanup_algorithm; } } else tkey->creator = NULL; tkey->key = NULL; if (dstkey != NULL) dst_key_attach(dstkey, &tkey->key); tkey->ring = ring; if (key != NULL) refs = 1; if (ring != NULL) refs++; ret = isc_refcount_init(&tkey->refs, refs); if (ret != ISC_R_SUCCESS) goto cleanup_creator; tkey->generated = generated; tkey->inception = inception; tkey->expire = expire; tkey->mctx = NULL; isc_mem_attach(mctx, &tkey->mctx); ISC_LINK_INIT(tkey, link); tkey->magic = TSIG_MAGIC; if (ring != NULL) { ret = keyring_add(ring, name, tkey); if (ret != ISC_R_SUCCESS) goto cleanup_refs; } /* * Ignore this if it's a GSS key, since the key size is meaningless. */ if (dstkey != NULL && dst_key_size(dstkey) < 64 && !dns_name_equal(algorithm, DNS_TSIG_GSSAPI_NAME) && !dns_name_equal(algorithm, DNS_TSIG_GSSAPIMS_NAME)) { char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(name, namestr, sizeof(namestr)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_TSIG, ISC_LOG_INFO, "the key '%s' is too short to be secure", namestr); } if (key != NULL) *key = tkey; return (ISC_R_SUCCESS); cleanup_refs: tkey->magic = 0; while (refs-- > 0) isc_refcount_decrement(&tkey->refs, NULL); isc_refcount_destroy(&tkey->refs); cleanup_creator: if (tkey->key != NULL) dst_key_free(&tkey->key); if (tkey->creator != NULL) { dns_name_free(tkey->creator, mctx); isc_mem_put(mctx, tkey->creator, sizeof(dns_name_t)); } cleanup_algorithm: if (algname_is_allocated(tkey->algorithm)) { if (dns_name_dynamic(tkey->algorithm)) dns_name_free(tkey->algorithm, mctx); isc_mem_put(mctx, tkey->algorithm, sizeof(dns_name_t)); } cleanup_name: dns_name_free(&tkey->name, mctx); cleanup_key: isc_mem_put(mctx, tkey, sizeof(dns_tsigkey_t)); return (ret); }
isc_result_t dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm, dst_key_t *dstkey, isc_boolean_t generated, dns_name_t *creator, isc_stdtime_t inception, isc_stdtime_t expire, isc_mem_t *mctx, dns_tsig_keyring_t *ring, dns_tsigkey_t **key) { dns_tsigkey_t *tkey; isc_result_t ret; unsigned int refs = 0; REQUIRE(key == NULL || *key == NULL); REQUIRE(name != NULL); REQUIRE(algorithm != NULL); REQUIRE(mctx != NULL); tkey = (dns_tsigkey_t *) isc_mem_get(mctx, sizeof(dns_tsigkey_t)); if (tkey == NULL) return (ISC_R_NOMEMORY); dns_name_init(&tkey->name, NULL); ret = dns_name_dup(name, mctx, &tkey->name); if (ret != ISC_R_SUCCESS) goto cleanup_key; (void)dns_name_downcase(&tkey->name, &tkey->name, NULL); if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME)) { tkey->algorithm = DNS_TSIG_HMACMD5_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACMD5) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPI_NAME)) { tkey->algorithm = DNS_TSIG_GSSAPI_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_GSSAPI) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPIMS_NAME)) { tkey->algorithm = DNS_TSIG_GSSAPIMS_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_GSSAPI) { ret = DNS_R_BADALG; goto cleanup_name; } } else { if (key != NULL) { ret = DNS_R_BADALG; goto cleanup_name; } tkey->algorithm = isc_mem_get(mctx, sizeof(dns_name_t)); if (tkey->algorithm == NULL) { ret = ISC_R_NOMEMORY; goto cleanup_name; } dns_name_init(tkey->algorithm, NULL); ret = dns_name_dup(algorithm, mctx, tkey->algorithm); if (ret != ISC_R_SUCCESS) goto cleanup_algorithm; (void)dns_name_downcase(tkey->algorithm, tkey->algorithm, NULL); } if (creator != NULL) { tkey->creator = isc_mem_get(mctx, sizeof(dns_name_t)); if (tkey->creator == NULL) { ret = ISC_R_NOMEMORY; goto cleanup_algorithm; } dns_name_init(tkey->creator, NULL); ret = dns_name_dup(creator, mctx, tkey->creator); if (ret != ISC_R_SUCCESS) { isc_mem_put(mctx, tkey->creator, sizeof(dns_name_t)); goto cleanup_algorithm; } } else tkey->creator = NULL; tkey->key = dstkey; tkey->ring = ring; if (ring != NULL) { RWLOCK(&ring->lock, isc_rwlocktype_write); ret = dns_rbt_addname(ring->keys, name, tkey); if (ret != ISC_R_SUCCESS) { RWUNLOCK(&ring->lock, isc_rwlocktype_write); goto cleanup_algorithm; } refs++; RWUNLOCK(&ring->lock, isc_rwlocktype_write); } if (key != NULL) refs++; isc_refcount_init(&tkey->refs, refs); tkey->generated = generated; tkey->inception = inception; tkey->expire = expire; tkey->mctx = mctx; tkey->magic = TSIG_MAGIC; if (dstkey != NULL && dst_key_size(dstkey) < 64) { char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(name, namestr, sizeof(namestr)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_TSIG, ISC_LOG_INFO, "the key '%s' is too short to be secure", namestr); } if (key != NULL) *key = tkey; return (ISC_R_SUCCESS); cleanup_algorithm: if (algname_is_allocated(tkey->algorithm)) { if (dns_name_dynamic(tkey->algorithm)) dns_name_free(tkey->algorithm, mctx); isc_mem_put(mctx, tkey->algorithm, sizeof(dns_name_t)); } cleanup_name: dns_name_free(&tkey->name, mctx); cleanup_key: isc_mem_put(mctx, tkey, sizeof(dns_tsigkey_t)); return (ret); }
/* * Driver-specific implementation of dns_db_create(). * * @param[in] argv Database-specific parameters from dns_db_create(). * @param[in] driverarg Driver-specific parameter from dns_db_register(). */ isc_result_t create_db(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type, dns_rdataclass_t rdclass, unsigned int argc, char *argv[], void *driverarg, dns_db_t **dbp) { sampledb_t *sampledb = NULL; isc_result_t result; dns_dbversion_t *version = NULL; struct in_addr a_addr; REQUIRE(type == dns_dbtype_zone); REQUIRE(rdclass == dns_rdataclass_in); REQUIRE(argc == 0); REQUIRE(argv != NULL); REQUIRE(driverarg != NULL); /* pointer to driver instance */ REQUIRE(dbp != NULL && *dbp == NULL); UNUSED(driverarg); /* no driver-specific configuration */ a_addr.s_addr = 0x0100007fU; CHECKED_MEM_GET_PTR(mctx, sampledb); ZERO_PTR(sampledb); isc_mem_attach(mctx, &sampledb->common.mctx); dns_name_init(&sampledb->common.origin, NULL); isc_ondestroy_init(&sampledb->common.ondest); sampledb->common.magic = DNS_DB_MAGIC; sampledb->common.impmagic = SAMPLEDB_MAGIC; sampledb->common.methods = &sampledb_methods; sampledb->common.attributes = 0; sampledb->common.rdclass = rdclass; CHECK(dns_name_dupwithoffsets(origin, mctx, &sampledb->common.origin)); CHECK(isc_refcount_init(&sampledb->refs, 1)); /* Translate instance name to instance pointer. */ sampledb->inst = driverarg; /* Create internal instance of RBT DB implementation from BIND. */ CHECK(dns_db_create(mctx, "rbt", origin, dns_dbtype_zone, dns_rdataclass_in, 0, NULL, &sampledb->rbtdb)); /* Create fake SOA, NS, and A records to make database loadable. */ CHECK(dns_db_newversion(sampledb->rbtdb, &version)); CHECK(add_soa(sampledb->rbtdb, version, origin, origin, origin)); CHECK(add_ns(sampledb->rbtdb, version, origin, origin)); CHECK(add_a(sampledb->rbtdb, version, origin, a_addr)); dns_db_closeversion(sampledb->rbtdb, &version, ISC_TRUE); *dbp = (dns_db_t *)sampledb; return (ISC_R_SUCCESS); cleanup: if (sampledb != NULL) { if (dns_name_dynamic(&sampledb->common.origin)) dns_name_free(&sampledb->common.origin, mctx); isc_mem_putanddetach(&sampledb->common.mctx, sampledb, sizeof(*sampledb)); } return (result); }
/** * Convert LDAP DN to absolute DNS names. * * @param[in] dn LDAP DN with one or two idnsName components at the * beginning. * @param[out] target Absolute DNS name derived from the first two idnsNames. * @param[out] origin Absolute DNS name derived from the last idnsName * component of DN, i.e. zone. Can be NULL. * @param[out] iszone ISC_TRUE if DN points to zone object, ISC_FALSE otherwise. * * @code * Examples: * dn = "idnsName=foo.bar, idnsName=example.org., cn=dns, dc=example, dc=org" * target = "foo.bar.example.org." * origin = "example.org." * * dn = "idnsname=89, idnsname=4.34.10.in-addr.arpa, cn=dns, dc=example, dc=org" * target = "89.4.34.10.in-addr.arpa." * origin = "4.34.10.in-addr.arpa." * * dn = "idnsname=third.test., idnsname=test., cn=dns, dc=example, dc=org" * target = "third.test." * origin = "test." * @endcode */ isc_result_t dn_to_dnsname(isc_mem_t *mctx, const char *dn_str, dns_name_t *target, dns_name_t *otarget, isc_boolean_t *iszone) { LDAPDN dn = NULL; LDAPRDN rdn = NULL; LDAPAVA *attr = NULL; int idx; int ret; DECLARE_BUFFERED_NAME(name); DECLARE_BUFFERED_NAME(origin); isc_buffer_t name_buf; isc_buffer_t origin_buf; isc_result_t result; REQUIRE(dn_str != NULL); REQUIRE(target != NULL); INIT_BUFFERED_NAME(name); INIT_BUFFERED_NAME(origin); isc_buffer_initnull(&name_buf); isc_buffer_initnull(&origin_buf); /* Example DN: cn=a+sn=b, ou=people */ ret = ldap_str2dn(dn_str, &dn, LDAP_DN_FORMAT_LDAPV3); if (ret != LDAP_SUCCESS || dn == NULL) { log_bug("ldap_str2dn failed: %u", ret); CLEANUP_WITH(ISC_R_UNEXPECTED); } /* iterate over DN components: e.g. cn=a+sn=b */ for (idx = 0; dn[idx] != NULL; idx++) { rdn = dn[idx]; /* "iterate" over RDN components: e.g. cn=a */ INSIST(rdn[0] != NULL); /* RDN without (attr=value)?! */ if (rdn[1] != NULL) { log_bug("multi-valued RDNs are not supported"); CLEANUP_WITH(ISC_R_NOTIMPLEMENTED); } /* attribute in current RDN component */ attr = rdn[0]; if ((attr->la_flags & LDAP_AVA_STRING) == 0) { log_error("non-string attribute detected: position %u", idx); CLEANUP_WITH(ISC_R_NOTIMPLEMENTED); } if (strncasecmp("idnsName", attr->la_attr.bv_val, attr->la_attr.bv_len) == 0) { if (idx == 0) { isc_buffer_init(&name_buf, attr->la_value.bv_val, attr->la_value.bv_len); isc_buffer_add(&name_buf, attr->la_value.bv_len); } else if (idx == 1) { isc_buffer_init(&origin_buf, attr->la_value.bv_val, attr->la_value.bv_len); isc_buffer_add(&origin_buf, attr->la_value.bv_len); } else { /* more than two idnsNames?! */ break; } } else { /* no match - idx holds position */ break; } } /* filter out unsupported cases */ if (idx <= 0) { log_error("no idnsName component found in DN"); CLEANUP_WITH(ISC_R_UNEXPECTEDEND); } else if (idx == 1) { /* zone only */ if (iszone != NULL) *iszone = ISC_TRUE; CHECK(dns_name_copy(dns_rootname, &origin, NULL)); CHECK(dns_name_fromtext(&name, &name_buf, dns_rootname, 0, NULL)); } else if (idx == 2) { /* owner and zone */ if (iszone != NULL) *iszone = ISC_FALSE; CHECK(dns_name_fromtext(&origin, &origin_buf, dns_rootname, 0, NULL)); CHECK(dns_name_fromtext(&name, &name_buf, &origin, 0, NULL)); if (dns_name_issubdomain(&name, &origin) == ISC_FALSE) { log_error("out-of-zone data: first idnsName is not a " "subdomain of the other"); CLEANUP_WITH(DNS_R_BADOWNERNAME); } else if (dns_name_equal(&name, &origin) == ISC_TRUE) { log_error("attempt to redefine zone apex: first " "idnsName equals to zone name"); CLEANUP_WITH(DNS_R_BADOWNERNAME); } } else { log_error("unsupported number of idnsName components in DN: " "%u components found", idx); CLEANUP_WITH(ISC_R_NOTIMPLEMENTED); } cleanup: if (result == ISC_R_SUCCESS) result = dns_name_dupwithoffsets(&name, mctx, target); else log_error_r("failed to convert DN '%s' to DNS name", dn_str); if (result == ISC_R_SUCCESS && otarget != NULL) result = dns_name_dupwithoffsets(&origin, mctx, otarget); if (result != ISC_R_SUCCESS) { if (dns_name_dynamic(target)) dns_name_free(target, mctx); if (otarget) { if (dns_name_dynamic(otarget)) dns_name_free(otarget, mctx); } } if (dn != NULL) ldap_dnfree(dn); return result; }
isc_result_t ns_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list, isc_mem_t *mctx, isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp, dns_name_t ***keysp, isc_uint32_t *countp) { isc_uint32_t addrcount = 0, dscpcount = 0, keycount = 0, i = 0; isc_uint32_t listcount = 0, l = 0, j; isc_uint32_t stackcount = 0, pushed = 0; isc_result_t result; const cfg_listelt_t *element; const cfg_obj_t *addrlist; const cfg_obj_t *portobj; const cfg_obj_t *dscpobj; in_port_t port; isc_dscp_t dscp = -1; dns_fixedname_t fname; isc_sockaddr_t *addrs = NULL; isc_dscp_t *dscps = NULL; dns_name_t **keys = NULL; struct { const char *name; } *lists = NULL; struct { const cfg_listelt_t *element; in_port_t port; isc_dscp_t dscp; } *stack = NULL; REQUIRE(addrsp != NULL && *addrsp == NULL); REQUIRE(dscpsp != NULL && *dscpsp == NULL); REQUIRE(keysp != NULL && *keysp == NULL); REQUIRE(countp != NULL); /* * Get system defaults. */ result = ns_config_getport(config, &port); if (result != ISC_R_SUCCESS) goto cleanup; result = ns_config_getdscp(config, &dscp); if (result != ISC_R_SUCCESS) goto cleanup; newlist: addrlist = cfg_tuple_get(list, "addresses"); portobj = cfg_tuple_get(list, "port"); dscpobj = cfg_tuple_get(list, "dscp"); if (cfg_obj_isuint32(portobj)) { isc_uint32_t val = cfg_obj_asuint32(portobj); if (val > ISC_UINT16_MAX) { cfg_obj_log(portobj, ns_g_lctx, ISC_LOG_ERROR, "port '%u' out of range", val); result = ISC_R_RANGE; goto cleanup; } port = (in_port_t) val; } if (dscpobj != NULL && cfg_obj_isuint32(dscpobj)) { if (cfg_obj_asuint32(dscpobj) > 63) { cfg_obj_log(dscpobj, ns_g_lctx, ISC_LOG_ERROR, "dscp value '%u' is out of range", cfg_obj_asuint32(dscpobj)); result = ISC_R_RANGE; goto cleanup; } dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj); } result = ISC_R_NOMEMORY; element = cfg_list_first(addrlist); resume: for ( ; element != NULL; element = cfg_list_next(element)) { const cfg_obj_t *addr; const cfg_obj_t *key; const char *keystr; isc_buffer_t b; addr = cfg_tuple_get(cfg_listelt_value(element), "masterselement"); key = cfg_tuple_get(cfg_listelt_value(element), "key"); if (!cfg_obj_issockaddr(addr)) { const char *listname = cfg_obj_asstring(addr); isc_result_t tresult; /* Grow lists? */ if (listcount == l) { void * tmp; isc_uint32_t newlen = listcount + 16; size_t newsize, oldsize; newsize = newlen * sizeof(*lists); oldsize = listcount * sizeof(*lists); tmp = isc_mem_get(mctx, newsize); if (tmp == NULL) goto cleanup; if (listcount != 0) { memmove(tmp, lists, oldsize); isc_mem_put(mctx, lists, oldsize); } lists = tmp; listcount = newlen; } /* Seen? */ for (j = 0; j < l; j++) if (strcasecmp(lists[j].name, listname) == 0) break; if (j < l) continue; tresult = get_masters_def(config, listname, &list); if (tresult == ISC_R_NOTFOUND) { cfg_obj_log(addr, ns_g_lctx, ISC_LOG_ERROR, "masters \"%s\" not found", listname); result = tresult; goto cleanup; } if (tresult != ISC_R_SUCCESS) goto cleanup; lists[l++].name = listname; /* Grow stack? */ if (stackcount == pushed) { void * tmp; isc_uint32_t newlen = stackcount + 16; size_t newsize, oldsize; newsize = newlen * sizeof(*stack); oldsize = stackcount * sizeof(*stack); tmp = isc_mem_get(mctx, newsize); if (tmp == NULL) goto cleanup; if (stackcount != 0) { memmove(tmp, stack, oldsize); isc_mem_put(mctx, stack, oldsize); } stack = tmp; stackcount = newlen; } /* * We want to resume processing this list on the * next element. */ stack[pushed].element = cfg_list_next(element); stack[pushed].port = port; stack[pushed].dscp = dscp; pushed++; goto newlist; } if (i == addrcount) { void * tmp; isc_uint32_t newlen = addrcount + 16; size_t newsize, oldsize; newsize = newlen * sizeof(isc_sockaddr_t); oldsize = addrcount * sizeof(isc_sockaddr_t); tmp = isc_mem_get(mctx, newsize); if (tmp == NULL) goto cleanup; if (addrcount != 0) { memmove(tmp, addrs, oldsize); isc_mem_put(mctx, addrs, oldsize); } addrs = tmp; addrcount = newlen; newsize = newlen * sizeof(isc_dscp_t); oldsize = dscpcount * sizeof(isc_dscp_t); tmp = isc_mem_get(mctx, newsize); if (tmp == NULL) goto cleanup; if (dscpcount != 0) { memmove(tmp, dscps, oldsize); isc_mem_put(mctx, dscps, oldsize); } dscps = tmp; dscpcount = newlen; newsize = newlen * sizeof(dns_name_t *); oldsize = keycount * sizeof(dns_name_t *); tmp = isc_mem_get(mctx, newsize); if (tmp == NULL) goto cleanup; if (keycount != 0) { memmove(tmp, keys, oldsize); isc_mem_put(mctx, keys, oldsize); } keys = tmp; keycount = newlen; } addrs[i] = *cfg_obj_assockaddr(addr); if (isc_sockaddr_getport(&addrs[i]) == 0) isc_sockaddr_setport(&addrs[i], port); dscps[i] = cfg_obj_getdscp(addr); if (dscps[i] == -1) dscps[i] = dscp; keys[i] = NULL; i++; /* Increment here so that cleanup on error works. */ if (!cfg_obj_isstring(key)) continue; keys[i - 1] = isc_mem_get(mctx, sizeof(dns_name_t)); if (keys[i - 1] == NULL) goto cleanup; dns_name_init(keys[i - 1], NULL); keystr = cfg_obj_asstring(key); isc_buffer_constinit(&b, keystr, strlen(keystr)); isc_buffer_add(&b, strlen(keystr)); dns_fixedname_init(&fname); result = dns_name_fromtext(dns_fixedname_name(&fname), &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_name_dup(dns_fixedname_name(&fname), mctx, keys[i - 1]); if (result != ISC_R_SUCCESS) goto cleanup; } if (pushed != 0) { pushed--; element = stack[pushed].element; port = stack[pushed].port; dscp = stack[pushed].dscp; goto resume; } if (i < addrcount) { void * tmp; size_t newsize, oldsize; newsize = i * sizeof(isc_sockaddr_t); oldsize = addrcount * sizeof(isc_sockaddr_t); if (i != 0) { tmp = isc_mem_get(mctx, newsize); if (tmp == NULL) goto cleanup; memmove(tmp, addrs, newsize); } else tmp = NULL; isc_mem_put(mctx, addrs, oldsize); addrs = tmp; addrcount = i; newsize = i * sizeof(isc_dscp_t); oldsize = dscpcount * sizeof(isc_dscp_t); if (i != 0) { tmp = isc_mem_get(mctx, newsize); if (tmp == NULL) goto cleanup; memmove(tmp, dscps, newsize); } else tmp = NULL; isc_mem_put(mctx, dscps, oldsize); dscps = tmp; dscpcount = i; newsize = i * sizeof(dns_name_t *); oldsize = keycount * sizeof(dns_name_t *); if (i != 0) { tmp = isc_mem_get(mctx, newsize); if (tmp == NULL) goto cleanup; memmove(tmp, keys, newsize); } else tmp = NULL; isc_mem_put(mctx, keys, oldsize); keys = tmp; keycount = i; } if (lists != NULL) isc_mem_put(mctx, lists, listcount * sizeof(*lists)); if (stack != NULL) isc_mem_put(mctx, stack, stackcount * sizeof(*stack)); INSIST(keycount == addrcount); *addrsp = addrs; *dscpsp = dscps; *keysp = keys; *countp = addrcount; return (ISC_R_SUCCESS); cleanup: if (addrs != NULL) isc_mem_put(mctx, addrs, addrcount * sizeof(isc_sockaddr_t)); if (dscps != NULL) isc_mem_put(mctx, dscps, dscpcount * sizeof(isc_dscp_t)); if (keys != NULL) { for (j = 0; j < i; j++) { if (keys[j] == NULL) continue; if (dns_name_dynamic(keys[j])) dns_name_free(keys[j], mctx); isc_mem_put(mctx, keys[j], sizeof(dns_name_t)); } isc_mem_put(mctx, keys, keycount * sizeof(dns_name_t *)); } if (lists != NULL) isc_mem_put(mctx, lists, listcount * sizeof(*lists)); if (stack != NULL) isc_mem_put(mctx, stack, stackcount * sizeof(*stack)); return (result); }