1 /* $NetBSD: instance.c,v 1.3 2019/01/09 16:55:02 christos Exp $ */ 2 3 /* 4 * Driver instance object. 5 * 6 * One instance is equivalent to dynamic-db section in named.conf. 7 * This module parses arguments and provide high-level operations 8 * instance init/zone load/instance destroy. 9 * 10 * Copyright (C) 2008-2015 Red Hat ; see COPYRIGHT for license 11 */ 12 13 #include <config.h> 14 15 #include <isc/task.h> 16 #include <isc/util.h> 17 18 #include <dns/db.h> 19 #include <dns/dyndb.h> 20 #include <dns/fixedname.h> 21 #include <dns/name.h> 22 #include <dns/view.h> 23 #include <dns/zone.h> 24 25 #include "db.h" 26 #include "util.h" 27 #include "instance.h" 28 #include "log.h" 29 #include "zone.h" 30 31 /* 32 * Parse parameters and convert them to zone names. Caller has to deallocate 33 * resulting DNS names. 34 * 35 * @param[in] argv NULL-terminated string array of length 2 (excluding NULL) 36 * Each string has to be a valid DNS name. 37 * @param[out] z1 Zone name from argv[0] 38 * @param[out] z2 Zone name from argv[1] 39 */ 40 static isc_result_t 41 parse_params(isc_mem_t *mctx, int argc, char **argv, 42 dns_name_t *z1, dns_name_t *z2) 43 { 44 isc_result_t result; 45 int i; 46 47 REQUIRE(argv != NULL); 48 REQUIRE(z1 != NULL); 49 REQUIRE(z2 != NULL); 50 51 for (i = 0; i < argc; i++) { 52 log_info("param: '%s'", argv[i]); 53 } 54 log_info("number of params: %d", i); 55 56 if (argc != 2) { 57 log_error("exactly two parameters " 58 "(absolute zone names) are required"); 59 result = ISC_R_FAILURE; 60 goto cleanup; 61 } 62 result = dns_name_fromstring2(z1, argv[0], dns_rootname, 0, mctx); 63 if (result != ISC_R_SUCCESS) { 64 log_write(ISC_LOG_ERROR, 65 "parse_params: dns_name_fromstring2 -> %s", 66 isc_result_totext(result)); 67 goto cleanup; 68 } 69 result = dns_name_fromstring2(z2, argv[1], dns_rootname, 0, mctx); 70 if (result != ISC_R_SUCCESS) { 71 log_write(ISC_LOG_ERROR, 72 "parse_params: dns_name_fromstring2 -> %s", 73 isc_result_totext(result)); 74 goto cleanup; 75 } 76 77 result = ISC_R_SUCCESS; 78 79 cleanup: 80 return (result); 81 } 82 83 /* 84 * Initialize new driver instance. It will not create zones until 85 * load_sample_instance_zones() is called. 86 */ 87 isc_result_t 88 new_sample_instance(isc_mem_t *mctx, const char *db_name, 89 int argc, char **argv, const dns_dyndbctx_t *dctx, 90 sample_instance_t **sample_instp) 91 { 92 isc_result_t result; 93 sample_instance_t *inst = NULL; 94 95 REQUIRE(sample_instp != NULL && *sample_instp == NULL); 96 97 CHECKED_MEM_GET_PTR(mctx, inst); 98 ZERO_PTR(inst); 99 isc_mem_attach(mctx, &inst->mctx); 100 101 inst->db_name = isc_mem_strdup(mctx, db_name); 102 if (inst->db_name == NULL) { 103 result = ISC_R_NOMEMORY; 104 goto cleanup; 105 } 106 107 inst->zone1_name = dns_fixedname_initname(&inst->zone1_fn); 108 inst->zone2_name = dns_fixedname_initname(&inst->zone2_fn); 109 110 result = parse_params(mctx, argc, argv, 111 inst->zone1_name, inst->zone2_name); 112 if (result != ISC_R_SUCCESS) { 113 log_write(ISC_LOG_ERROR, 114 "new_sample_instance: parse_params -> %s", 115 isc_result_totext(result)); 116 goto cleanup; 117 } 118 119 dns_view_attach(dctx->view, &inst->view); 120 dns_zonemgr_attach(dctx->zmgr, &inst->zmgr); 121 isc_task_attach(dctx->task, &inst->task); 122 123 /* Register new DNS DB implementation. */ 124 result = dns_db_register(db_name, create_db, inst, mctx, &inst->db_imp); 125 if (result != ISC_R_SUCCESS) { 126 log_write(ISC_LOG_ERROR, 127 "new_sample_instance: dns_db_register -> %s", 128 isc_result_totext(result)); 129 goto cleanup; 130 } 131 132 *sample_instp = inst; 133 result = ISC_R_SUCCESS; 134 135 cleanup: 136 if (result != ISC_R_SUCCESS) 137 destroy_sample_instance(&inst); 138 return (result); 139 } 140 141 /* 142 * Create empty zones, add fake SOA, NS, and A records, load fake zones 143 * and add them to inst->view. 144 */ 145 isc_result_t 146 load_sample_instance_zones(sample_instance_t *inst) { 147 isc_result_t result; 148 149 result = create_zone(inst, inst->zone1_name, &inst->zone1); 150 if (result != ISC_R_SUCCESS) { 151 log_write(ISC_LOG_ERROR, 152 "load_sample_instance_zones: create_zone -> %s", 153 isc_result_totext(result)); 154 goto cleanup; 155 } 156 result = activate_zone(inst, inst->zone1); 157 if (result != ISC_R_SUCCESS) { 158 log_write(ISC_LOG_ERROR, 159 "load_sample_instance_zones: activate_zone -> %s", 160 isc_result_totext(result)); 161 goto cleanup; 162 } 163 164 result = create_zone(inst, inst->zone2_name, &inst->zone2); 165 if (result != ISC_R_SUCCESS) { 166 log_write(ISC_LOG_ERROR, 167 "load_sample_instance_zones: create_zone -> %s", 168 isc_result_totext(result)); 169 goto cleanup; 170 } 171 result = activate_zone(inst, inst->zone2); 172 if (result != ISC_R_SUCCESS) { 173 log_write(ISC_LOG_ERROR, 174 "load_sample_instance_zones: activate_zone -> %s", 175 isc_result_totext(result)); 176 goto cleanup; 177 } 178 179 cleanup: 180 return (result); 181 } 182 183 void 184 destroy_sample_instance(sample_instance_t **instp) { 185 sample_instance_t *inst; 186 REQUIRE(instp != NULL); 187 188 inst = *instp; 189 if (inst == NULL) 190 return; 191 192 if (inst->db_name != NULL) 193 isc_mem_free(inst->mctx, inst->db_name); 194 if (inst->zone1 != NULL) 195 dns_zone_detach(&inst->zone1); 196 if (inst->zone2 != NULL) 197 dns_zone_detach(&inst->zone2); 198 if (inst->db_imp != NULL) 199 dns_db_unregister(&inst->db_imp); 200 201 dns_view_detach(&inst->view); 202 dns_zonemgr_detach(&inst->zmgr); 203 isc_task_detach(&inst->task); 204 205 MEM_PUT_AND_DETACH(inst); 206 207 *instp = NULL; 208 } 209