1/* $NetBSD: instance.c,v 1.5 2022/09/23 12:15:25 christos Exp $ */ 2 3/* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 AND ISC 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/* 17 * Copyright (C) 2009-2015 Red Hat 18 * 19 * Permission to use, copy, modify, and/or distribute this software for any 20 * purpose with or without fee is hereby granted, provided that the above 21 * copyright notice and this permission notice appear in all copies. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS" AND AUTHORS DISCLAIMS ALL WARRANTIES WITH 24 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 25 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 26 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 27 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 28 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 29 * PERFORMANCE OF THIS SOFTWARE. 30 */ 31 32/* 33 * Driver instance object. 34 * 35 * One instance is equivalent to dynamic-db section in named.conf. 36 * This module parses arguments and provide high-level operations 37 * instance init/zone load/instance destroy. 38 */ 39 40#include "instance.h" 41 42#include <isc/task.h> 43#include <isc/util.h> 44 45#include <dns/db.h> 46#include <dns/dyndb.h> 47#include <dns/fixedname.h> 48#include <dns/name.h> 49#include <dns/view.h> 50#include <dns/zone.h> 51 52#include "db.h" 53#include "log.h" 54#include "util.h" 55#include "zone.h" 56 57/* 58 * Parse parameters and convert them to zone names. Caller has to deallocate 59 * resulting DNS names. 60 * 61 * @param[in] argv NULL-terminated string array of length 2 (excluding NULL) 62 * Each string has to be a valid DNS name. 63 * @param[out] z1 Zone name from argv[0] 64 * @param[out] z2 Zone name from argv[1] 65 */ 66static isc_result_t 67parse_params(isc_mem_t *mctx, int argc, char **argv, dns_name_t *z1, 68 dns_name_t *z2) { 69 isc_result_t result; 70 int i; 71 72 REQUIRE(argv != NULL); 73 REQUIRE(z1 != NULL); 74 REQUIRE(z2 != NULL); 75 76 for (i = 0; i < argc; i++) { 77 log_info("param: '%s'", argv[i]); 78 } 79 log_info("number of params: %d", i); 80 81 if (argc != 2) { 82 log_error("exactly two parameters " 83 "(absolute zone names) are required"); 84 result = ISC_R_FAILURE; 85 goto cleanup; 86 } 87 result = dns_name_fromstring2(z1, argv[0], dns_rootname, 0, mctx); 88 if (result != ISC_R_SUCCESS) { 89 log_write(ISC_LOG_ERROR, 90 "parse_params: dns_name_fromstring2 -> %s", 91 isc_result_totext(result)); 92 goto cleanup; 93 } 94 result = dns_name_fromstring2(z2, argv[1], dns_rootname, 0, mctx); 95 if (result != ISC_R_SUCCESS) { 96 log_write(ISC_LOG_ERROR, 97 "parse_params: dns_name_fromstring2 -> %s", 98 isc_result_totext(result)); 99 goto cleanup; 100 } 101 102 result = ISC_R_SUCCESS; 103 104cleanup: 105 return (result); 106} 107 108/* 109 * Initialize new driver instance. It will not create zones until 110 * load_sample_instance_zones() is called. 111 */ 112isc_result_t 113new_sample_instance(isc_mem_t *mctx, const char *db_name, int argc, char **argv, 114 const dns_dyndbctx_t *dctx, 115 sample_instance_t **sample_instp) { 116 isc_result_t result; 117 sample_instance_t *inst = NULL; 118 119 REQUIRE(sample_instp != NULL && *sample_instp == NULL); 120 121 CHECKED_MEM_GET_PTR(mctx, inst); 122 ZERO_PTR(inst); 123 isc_mem_attach(mctx, &inst->mctx); 124 125 inst->db_name = isc_mem_strdup(mctx, db_name); 126 127 inst->zone1_name = dns_fixedname_initname(&inst->zone1_fn); 128 inst->zone2_name = dns_fixedname_initname(&inst->zone2_fn); 129 130 result = parse_params(mctx, argc, argv, inst->zone1_name, 131 inst->zone2_name); 132 if (result != ISC_R_SUCCESS) { 133 log_write(ISC_LOG_ERROR, 134 "new_sample_instance: parse_params -> %s", 135 isc_result_totext(result)); 136 goto cleanup; 137 } 138 139 dns_view_attach(dctx->view, &inst->view); 140 dns_zonemgr_attach(dctx->zmgr, &inst->zmgr); 141 isc_task_attach(dctx->task, &inst->task); 142 143 /* Register new DNS DB implementation. */ 144 result = dns_db_register(db_name, create_db, inst, mctx, &inst->db_imp); 145 if (result != ISC_R_SUCCESS) { 146 log_write(ISC_LOG_ERROR, 147 "new_sample_instance: dns_db_register -> %s", 148 isc_result_totext(result)); 149 goto cleanup; 150 } 151 152 *sample_instp = inst; 153 result = ISC_R_SUCCESS; 154 155cleanup: 156 if (result != ISC_R_SUCCESS) { 157 destroy_sample_instance(&inst); 158 } 159 return (result); 160} 161 162/* 163 * Create empty zones, add fake SOA, NS, and A records, load fake zones 164 * and add them to inst->view. 165 */ 166isc_result_t 167load_sample_instance_zones(sample_instance_t *inst) { 168 isc_result_t result; 169 170 result = create_zone(inst, inst->zone1_name, &inst->zone1); 171 if (result != ISC_R_SUCCESS) { 172 log_write(ISC_LOG_ERROR, 173 "load_sample_instance_zones: create_zone -> %s", 174 isc_result_totext(result)); 175 goto cleanup; 176 } 177 result = activate_zone(inst, inst->zone1); 178 if (result != ISC_R_SUCCESS) { 179 log_write(ISC_LOG_ERROR, 180 "load_sample_instance_zones: activate_zone -> %s", 181 isc_result_totext(result)); 182 goto cleanup; 183 } 184 185 result = create_zone(inst, inst->zone2_name, &inst->zone2); 186 if (result != ISC_R_SUCCESS) { 187 log_write(ISC_LOG_ERROR, 188 "load_sample_instance_zones: create_zone -> %s", 189 isc_result_totext(result)); 190 goto cleanup; 191 } 192 result = activate_zone(inst, inst->zone2); 193 if (result != ISC_R_SUCCESS) { 194 log_write(ISC_LOG_ERROR, 195 "load_sample_instance_zones: activate_zone -> %s", 196 isc_result_totext(result)); 197 goto cleanup; 198 } 199 200cleanup: 201 return (result); 202} 203 204void 205destroy_sample_instance(sample_instance_t **instp) { 206 sample_instance_t *inst; 207 REQUIRE(instp != NULL); 208 209 inst = *instp; 210 *instp = NULL; 211 if (inst == NULL) { 212 return; 213 } 214 215 if (inst->db_name != NULL) { 216 isc_mem_free(inst->mctx, inst->db_name); 217 } 218 if (inst->zone1 != NULL) { 219 dns_zone_detach(&inst->zone1); 220 } 221 if (inst->zone2 != NULL) { 222 dns_zone_detach(&inst->zone2); 223 } 224 if (inst->db_imp != NULL) { 225 dns_db_unregister(&inst->db_imp); 226 } 227 228 dns_view_detach(&inst->view); 229 dns_zonemgr_detach(&inst->zmgr); 230 isc_task_detach(&inst->task); 231 232 MEM_PUT_AND_DETACH(inst); 233} 234