1*00b67f09SDavid van Moolenbroek /* $NetBSD: dlz_bdb_driver.c,v 1.5 2014/12/10 04:37:55 christos Exp $ */
2*00b67f09SDavid van Moolenbroek
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl.
5*00b67f09SDavid van Moolenbroek *
6*00b67f09SDavid van Moolenbroek * Permission to use, copy, modify, and distribute this software for any
7*00b67f09SDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the
8*00b67f09SDavid van Moolenbroek * above copyright notice and this permission notice appear in all
9*00b67f09SDavid van Moolenbroek * copies.
10*00b67f09SDavid van Moolenbroek *
11*00b67f09SDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET
12*00b67f09SDavid van Moolenbroek * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
13*00b67f09SDavid van Moolenbroek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
14*00b67f09SDavid van Moolenbroek * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
15*00b67f09SDavid van Moolenbroek * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
16*00b67f09SDavid van Moolenbroek * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
17*00b67f09SDavid van Moolenbroek * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
18*00b67f09SDavid van Moolenbroek * USE OR PERFORMANCE OF THIS SOFTWARE.
19*00b67f09SDavid van Moolenbroek *
20*00b67f09SDavid van Moolenbroek * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was
21*00b67f09SDavid van Moolenbroek * conceived and contributed by Rob Butler.
22*00b67f09SDavid van Moolenbroek *
23*00b67f09SDavid van Moolenbroek * Permission to use, copy, modify, and distribute this software for any
24*00b67f09SDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the
25*00b67f09SDavid van Moolenbroek * above copyright notice and this permission notice appear in all
26*00b67f09SDavid van Moolenbroek * copies.
27*00b67f09SDavid van Moolenbroek *
28*00b67f09SDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER
29*00b67f09SDavid van Moolenbroek * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
30*00b67f09SDavid van Moolenbroek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
31*00b67f09SDavid van Moolenbroek * ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
32*00b67f09SDavid van Moolenbroek * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
33*00b67f09SDavid van Moolenbroek * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
34*00b67f09SDavid van Moolenbroek * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
35*00b67f09SDavid van Moolenbroek * USE OR PERFORMANCE OF THIS SOFTWARE.
36*00b67f09SDavid van Moolenbroek */
37*00b67f09SDavid van Moolenbroek
38*00b67f09SDavid van Moolenbroek /*
39*00b67f09SDavid van Moolenbroek * Copyright (C) 1999-2001 Internet Software Consortium.
40*00b67f09SDavid van Moolenbroek *
41*00b67f09SDavid van Moolenbroek * Permission to use, copy, modify, and distribute this software for any
42*00b67f09SDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the above
43*00b67f09SDavid van Moolenbroek * copyright notice and this permission notice appear in all copies.
44*00b67f09SDavid van Moolenbroek *
45*00b67f09SDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
46*00b67f09SDavid van Moolenbroek * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
47*00b67f09SDavid van Moolenbroek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
48*00b67f09SDavid van Moolenbroek * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
49*00b67f09SDavid van Moolenbroek * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
50*00b67f09SDavid van Moolenbroek * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
51*00b67f09SDavid van Moolenbroek * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
52*00b67f09SDavid van Moolenbroek * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
53*00b67f09SDavid van Moolenbroek */
54*00b67f09SDavid van Moolenbroek
55*00b67f09SDavid van Moolenbroek #ifdef DLZ_BDB
56*00b67f09SDavid van Moolenbroek
57*00b67f09SDavid van Moolenbroek #include <config.h>
58*00b67f09SDavid van Moolenbroek #include <stdio.h>
59*00b67f09SDavid van Moolenbroek #include <string.h>
60*00b67f09SDavid van Moolenbroek #include <stdlib.h>
61*00b67f09SDavid van Moolenbroek
62*00b67f09SDavid van Moolenbroek #include <dns/log.h>
63*00b67f09SDavid van Moolenbroek #include <dns/sdlz.h>
64*00b67f09SDavid van Moolenbroek #include <dns/result.h>
65*00b67f09SDavid van Moolenbroek
66*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
67*00b67f09SDavid van Moolenbroek #include <isc/print.h>
68*00b67f09SDavid van Moolenbroek #include <isc/result.h>
69*00b67f09SDavid van Moolenbroek #include <isc/util.h>
70*00b67f09SDavid van Moolenbroek
71*00b67f09SDavid van Moolenbroek #include <named/globals.h>
72*00b67f09SDavid van Moolenbroek
73*00b67f09SDavid van Moolenbroek #include <dlz/dlz_bdb_driver.h>
74*00b67f09SDavid van Moolenbroek
75*00b67f09SDavid van Moolenbroek #include <db.h>
76*00b67f09SDavid van Moolenbroek
77*00b67f09SDavid van Moolenbroek static dns_sdlzimplementation_t *dlz_bdb = NULL;
78*00b67f09SDavid van Moolenbroek
79*00b67f09SDavid van Moolenbroek /* should the bdb driver use threads. */
80*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_USETHREADS
81*00b67f09SDavid van Moolenbroek #define bdb_threads DB_THREAD
82*00b67f09SDavid van Moolenbroek #else
83*00b67f09SDavid van Moolenbroek #define bdb_threads 0
84*00b67f09SDavid van Moolenbroek #endif
85*00b67f09SDavid van Moolenbroek
86*00b67f09SDavid van Moolenbroek /* BDB database names */
87*00b67f09SDavid van Moolenbroek #define dlz_data "dns_data"
88*00b67f09SDavid van Moolenbroek #define dlz_zone "dns_zone"
89*00b67f09SDavid van Moolenbroek #define dlz_host "dns_host"
90*00b67f09SDavid van Moolenbroek #define dlz_client "dns_client"
91*00b67f09SDavid van Moolenbroek
92*00b67f09SDavid van Moolenbroek /*%
93*00b67f09SDavid van Moolenbroek * This structure contains all the Berkeley DB handles
94*00b67f09SDavid van Moolenbroek * for this instance of the BDB driver.
95*00b67f09SDavid van Moolenbroek */
96*00b67f09SDavid van Moolenbroek
97*00b67f09SDavid van Moolenbroek typedef struct bdb_instance {
98*00b67f09SDavid van Moolenbroek DB_ENV *dbenv; /*%< BDB environment */
99*00b67f09SDavid van Moolenbroek DB *data; /*%< dns_data database handle */
100*00b67f09SDavid van Moolenbroek DB *zone; /*%< zone database handle */
101*00b67f09SDavid van Moolenbroek DB *host; /*%< host database handle */
102*00b67f09SDavid van Moolenbroek DB *client; /*%< client database handle */
103*00b67f09SDavid van Moolenbroek isc_mem_t *mctx; /*%< memory context */
104*00b67f09SDavid van Moolenbroek
105*00b67f09SDavid van Moolenbroek } bdb_instance_t;
106*00b67f09SDavid van Moolenbroek
107*00b67f09SDavid van Moolenbroek typedef struct parsed_data {
108*00b67f09SDavid van Moolenbroek char *zone;
109*00b67f09SDavid van Moolenbroek char *host;
110*00b67f09SDavid van Moolenbroek char *type;
111*00b67f09SDavid van Moolenbroek int ttl;
112*00b67f09SDavid van Moolenbroek char *data;
113*00b67f09SDavid van Moolenbroek } parsed_data_t;
114*00b67f09SDavid van Moolenbroek
115*00b67f09SDavid van Moolenbroek
116*00b67f09SDavid van Moolenbroek /* forward reference */
117*00b67f09SDavid van Moolenbroek
118*00b67f09SDavid van Moolenbroek static isc_result_t
119*00b67f09SDavid van Moolenbroek bdb_findzone(void *driverarg, void *dbdata, const char *name,
120*00b67f09SDavid van Moolenbroek dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo);
121*00b67f09SDavid van Moolenbroek
122*00b67f09SDavid van Moolenbroek /*%
123*00b67f09SDavid van Moolenbroek * Parses the DBT from the Berkeley DB into a parsed_data record
124*00b67f09SDavid van Moolenbroek * The parsed_data record should be allocated before and passed into the
125*00b67f09SDavid van Moolenbroek * bdb_parse_data function. The char (type & data) fields should not
126*00b67f09SDavid van Moolenbroek * be "free"d as that memory is part of the DBT data field. It will be
127*00b67f09SDavid van Moolenbroek * "free"d when the DBT is freed.
128*00b67f09SDavid van Moolenbroek */
129*00b67f09SDavid van Moolenbroek
130*00b67f09SDavid van Moolenbroek static isc_result_t
bdb_parse_data(char * in,parsed_data_t * pd)131*00b67f09SDavid van Moolenbroek bdb_parse_data(char *in, parsed_data_t *pd) {
132*00b67f09SDavid van Moolenbroek
133*00b67f09SDavid van Moolenbroek char *endp, *ttlStr;
134*00b67f09SDavid van Moolenbroek char *tmp = in;
135*00b67f09SDavid van Moolenbroek char *lastchar = (char *) &tmp[strlen(tmp) + 1];
136*00b67f09SDavid van Moolenbroek
137*00b67f09SDavid van Moolenbroek /*%
138*00b67f09SDavid van Moolenbroek * String should be formated as:
139*00b67f09SDavid van Moolenbroek * zone(a space)host(a space)ttl(a space)type(a space)remaining data
140*00b67f09SDavid van Moolenbroek * examples:
141*00b67f09SDavid van Moolenbroek * example.com www 10 A 127.0.0.1
142*00b67f09SDavid van Moolenbroek * example.com mail 10 A 127.0.0.2
143*00b67f09SDavid van Moolenbroek * example.com @ 10 MX 20 mail.example.com
144*00b67f09SDavid van Moolenbroek */
145*00b67f09SDavid van Moolenbroek
146*00b67f09SDavid van Moolenbroek /* save pointer to zone */
147*00b67f09SDavid van Moolenbroek pd->zone = tmp;
148*00b67f09SDavid van Moolenbroek
149*00b67f09SDavid van Moolenbroek /* find space after zone and change it to a '\0' */
150*00b67f09SDavid van Moolenbroek tmp = strchr(tmp, ' ');
151*00b67f09SDavid van Moolenbroek /* verify we found a space */
152*00b67f09SDavid van Moolenbroek if (tmp == NULL)
153*00b67f09SDavid van Moolenbroek return ISC_R_FAILURE;
154*00b67f09SDavid van Moolenbroek /* change the space to a null (string terminator) */
155*00b67f09SDavid van Moolenbroek tmp[0] = '\0';
156*00b67f09SDavid van Moolenbroek /* make sure it is safe to increment pointer */
157*00b67f09SDavid van Moolenbroek if (++tmp > lastchar)
158*00b67f09SDavid van Moolenbroek return ISC_R_FAILURE;
159*00b67f09SDavid van Moolenbroek
160*00b67f09SDavid van Moolenbroek /* save pointer to host */
161*00b67f09SDavid van Moolenbroek pd->host = tmp;
162*00b67f09SDavid van Moolenbroek
163*00b67f09SDavid van Moolenbroek /* find space after type and change it to a '\0' */
164*00b67f09SDavid van Moolenbroek tmp = strchr(tmp, ' ');
165*00b67f09SDavid van Moolenbroek /* verify we found a space */
166*00b67f09SDavid van Moolenbroek if (tmp == NULL)
167*00b67f09SDavid van Moolenbroek return ISC_R_FAILURE;
168*00b67f09SDavid van Moolenbroek /* change the space to a null (string terminator) */
169*00b67f09SDavid van Moolenbroek tmp[0] = '\0';
170*00b67f09SDavid van Moolenbroek /* make sure it is safe to increment pointer */
171*00b67f09SDavid van Moolenbroek if (++tmp > lastchar)
172*00b67f09SDavid van Moolenbroek return ISC_R_FAILURE;
173*00b67f09SDavid van Moolenbroek
174*00b67f09SDavid van Moolenbroek /* save pointer to dns type */
175*00b67f09SDavid van Moolenbroek pd->type = tmp;
176*00b67f09SDavid van Moolenbroek
177*00b67f09SDavid van Moolenbroek /* find space after type and change it to a '\0' */
178*00b67f09SDavid van Moolenbroek tmp = strchr(tmp, ' ');
179*00b67f09SDavid van Moolenbroek /* verify we found a space */
180*00b67f09SDavid van Moolenbroek if (tmp == NULL)
181*00b67f09SDavid van Moolenbroek return ISC_R_FAILURE;
182*00b67f09SDavid van Moolenbroek /* change the space to a null (string terminator) */
183*00b67f09SDavid van Moolenbroek tmp[0] = '\0';
184*00b67f09SDavid van Moolenbroek /* make sure it is safe to increment pointer */
185*00b67f09SDavid van Moolenbroek if (++tmp > lastchar)
186*00b67f09SDavid van Moolenbroek return ISC_R_FAILURE;
187*00b67f09SDavid van Moolenbroek
188*00b67f09SDavid van Moolenbroek /* save pointer to dns ttl */
189*00b67f09SDavid van Moolenbroek ttlStr = tmp;
190*00b67f09SDavid van Moolenbroek
191*00b67f09SDavid van Moolenbroek /* find space after ttl and change it to a '\0' */
192*00b67f09SDavid van Moolenbroek tmp = strchr(tmp, ' ');
193*00b67f09SDavid van Moolenbroek /* verify we found a space */
194*00b67f09SDavid van Moolenbroek if (tmp == NULL)
195*00b67f09SDavid van Moolenbroek return ISC_R_FAILURE;
196*00b67f09SDavid van Moolenbroek /* change the space to a null (string terminator) */
197*00b67f09SDavid van Moolenbroek tmp[0] = '\0';
198*00b67f09SDavid van Moolenbroek /* make sure it is safe to increment pointer */
199*00b67f09SDavid van Moolenbroek if (++tmp > lastchar)
200*00b67f09SDavid van Moolenbroek return ISC_R_FAILURE;
201*00b67f09SDavid van Moolenbroek
202*00b67f09SDavid van Moolenbroek /* save pointer to remainder of DNS data */
203*00b67f09SDavid van Moolenbroek pd->data = tmp;
204*00b67f09SDavid van Moolenbroek
205*00b67f09SDavid van Moolenbroek /* convert ttl string to integer */
206*00b67f09SDavid van Moolenbroek pd->ttl = strtol(ttlStr, &endp, 10);
207*00b67f09SDavid van Moolenbroek if (*endp != '\0' || pd->ttl < 0) {
208*00b67f09SDavid van Moolenbroek isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
209*00b67f09SDavid van Moolenbroek DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
210*00b67f09SDavid van Moolenbroek "BDB driver ttl must be a postive number");
211*00b67f09SDavid van Moolenbroek return ISC_R_FAILURE;
212*00b67f09SDavid van Moolenbroek }
213*00b67f09SDavid van Moolenbroek
214*00b67f09SDavid van Moolenbroek /* if we get this far everything should have worked. */
215*00b67f09SDavid van Moolenbroek return ISC_R_SUCCESS;
216*00b67f09SDavid van Moolenbroek }
217*00b67f09SDavid van Moolenbroek
218*00b67f09SDavid van Moolenbroek /*
219*00b67f09SDavid van Moolenbroek * DLZ methods
220*00b67f09SDavid van Moolenbroek */
221*00b67f09SDavid van Moolenbroek
222*00b67f09SDavid van Moolenbroek static isc_result_t
bdb_allowzonexfr(void * driverarg,void * dbdata,const char * name,const char * client)223*00b67f09SDavid van Moolenbroek bdb_allowzonexfr(void *driverarg, void *dbdata, const char *name,
224*00b67f09SDavid van Moolenbroek const char *client)
225*00b67f09SDavid van Moolenbroek {
226*00b67f09SDavid van Moolenbroek isc_result_t result;
227*00b67f09SDavid van Moolenbroek bdb_instance_t *db = (bdb_instance_t *) dbdata;
228*00b67f09SDavid van Moolenbroek DBC *client_cursor = NULL;
229*00b67f09SDavid van Moolenbroek DBT key, data;
230*00b67f09SDavid van Moolenbroek
231*00b67f09SDavid van Moolenbroek /* check to see if we are authoritative for the zone first. */
232*00b67f09SDavid van Moolenbroek result = bdb_findzone(driverarg, dbdata, name, NULL, NULL);
233*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
234*00b67f09SDavid van Moolenbroek return (ISC_R_NOTFOUND);
235*00b67f09SDavid van Moolenbroek
236*00b67f09SDavid van Moolenbroek memset(&key, 0, sizeof(DBT));
237*00b67f09SDavid van Moolenbroek key.flags = DB_DBT_MALLOC;
238*00b67f09SDavid van Moolenbroek key.data = strdup(name);
239*00b67f09SDavid van Moolenbroek if (key.data == NULL) {
240*00b67f09SDavid van Moolenbroek result = ISC_R_NOMEMORY;
241*00b67f09SDavid van Moolenbroek goto xfr_cleanup;
242*00b67f09SDavid van Moolenbroek }
243*00b67f09SDavid van Moolenbroek key.size = strlen(key.data);
244*00b67f09SDavid van Moolenbroek
245*00b67f09SDavid van Moolenbroek memset(&data, 0, sizeof(DBT));
246*00b67f09SDavid van Moolenbroek data.flags = DB_DBT_MALLOC;
247*00b67f09SDavid van Moolenbroek data.data = strdup(client);
248*00b67f09SDavid van Moolenbroek if (data.data == NULL) {
249*00b67f09SDavid van Moolenbroek result = ISC_R_NOMEMORY;
250*00b67f09SDavid van Moolenbroek goto xfr_cleanup;
251*00b67f09SDavid van Moolenbroek }
252*00b67f09SDavid van Moolenbroek data.size = strlen(data.data);
253*00b67f09SDavid van Moolenbroek
254*00b67f09SDavid van Moolenbroek /* get a cursor to loop through zone data */
255*00b67f09SDavid van Moolenbroek if (db->client->cursor(db->client, NULL, &client_cursor, 0) != 0) {
256*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
257*00b67f09SDavid van Moolenbroek goto xfr_cleanup;
258*00b67f09SDavid van Moolenbroek }
259*00b67f09SDavid van Moolenbroek
260*00b67f09SDavid van Moolenbroek switch(client_cursor->c_get(client_cursor, &key, &data, DB_GET_BOTH)) {
261*00b67f09SDavid van Moolenbroek case DB_NOTFOUND:
262*00b67f09SDavid van Moolenbroek case DB_SECONDARY_BAD:
263*00b67f09SDavid van Moolenbroek result = ISC_R_NOTFOUND;
264*00b67f09SDavid van Moolenbroek break;
265*00b67f09SDavid van Moolenbroek case 0:
266*00b67f09SDavid van Moolenbroek result = ISC_R_SUCCESS;
267*00b67f09SDavid van Moolenbroek break;
268*00b67f09SDavid van Moolenbroek default:
269*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
270*00b67f09SDavid van Moolenbroek }
271*00b67f09SDavid van Moolenbroek
272*00b67f09SDavid van Moolenbroek xfr_cleanup:
273*00b67f09SDavid van Moolenbroek
274*00b67f09SDavid van Moolenbroek /* free any memory duplicate string in the key field */
275*00b67f09SDavid van Moolenbroek if (key.data != NULL)
276*00b67f09SDavid van Moolenbroek free(key.data);
277*00b67f09SDavid van Moolenbroek
278*00b67f09SDavid van Moolenbroek /* free any memory allocated to the data field. */
279*00b67f09SDavid van Moolenbroek if (data.data != NULL)
280*00b67f09SDavid van Moolenbroek free(data.data);
281*00b67f09SDavid van Moolenbroek
282*00b67f09SDavid van Moolenbroek /* get rid of zone_cursor */
283*00b67f09SDavid van Moolenbroek if (client_cursor != NULL)
284*00b67f09SDavid van Moolenbroek client_cursor->c_close(client_cursor);
285*00b67f09SDavid van Moolenbroek
286*00b67f09SDavid van Moolenbroek return result;
287*00b67f09SDavid van Moolenbroek
288*00b67f09SDavid van Moolenbroek }
289*00b67f09SDavid van Moolenbroek
290*00b67f09SDavid van Moolenbroek static isc_result_t
bdb_allnodes(const char * zone,void * driverarg,void * dbdata,dns_sdlzallnodes_t * allnodes)291*00b67f09SDavid van Moolenbroek bdb_allnodes(const char *zone, void *driverarg, void *dbdata,
292*00b67f09SDavid van Moolenbroek dns_sdlzallnodes_t *allnodes)
293*00b67f09SDavid van Moolenbroek {
294*00b67f09SDavid van Moolenbroek
295*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_NOTFOUND;
296*00b67f09SDavid van Moolenbroek bdb_instance_t *db = (bdb_instance_t *) dbdata;
297*00b67f09SDavid van Moolenbroek DBC *zone_cursor = NULL;
298*00b67f09SDavid van Moolenbroek DBT key, data;
299*00b67f09SDavid van Moolenbroek int flags;
300*00b67f09SDavid van Moolenbroek int bdbres;
301*00b67f09SDavid van Moolenbroek parsed_data_t pd;
302*00b67f09SDavid van Moolenbroek char *tmp = NULL, *tmp_zone;
303*00b67f09SDavid van Moolenbroek
304*00b67f09SDavid van Moolenbroek UNUSED(driverarg);
305*00b67f09SDavid van Moolenbroek
306*00b67f09SDavid van Moolenbroek memset(&key, 0, sizeof(DBT));
307*00b67f09SDavid van Moolenbroek memset(&data, 0, sizeof(DBT));
308*00b67f09SDavid van Moolenbroek
309*00b67f09SDavid van Moolenbroek key.data = tmp_zone = strdup(zone);
310*00b67f09SDavid van Moolenbroek
311*00b67f09SDavid van Moolenbroek if (key.data == NULL)
312*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
313*00b67f09SDavid van Moolenbroek
314*00b67f09SDavid van Moolenbroek key.size = strlen(key.data);
315*00b67f09SDavid van Moolenbroek
316*00b67f09SDavid van Moolenbroek /* get a cursor to loop through zone data */
317*00b67f09SDavid van Moolenbroek if (db->zone->cursor(db->zone, NULL, &zone_cursor, 0) != 0) {
318*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
319*00b67f09SDavid van Moolenbroek goto allnodes_cleanup;
320*00b67f09SDavid van Moolenbroek }
321*00b67f09SDavid van Moolenbroek
322*00b67f09SDavid van Moolenbroek flags = DB_SET;
323*00b67f09SDavid van Moolenbroek
324*00b67f09SDavid van Moolenbroek while ((bdbres = zone_cursor->c_get(zone_cursor, &key, &data,
325*00b67f09SDavid van Moolenbroek flags)) == 0) {
326*00b67f09SDavid van Moolenbroek
327*00b67f09SDavid van Moolenbroek flags = DB_NEXT_DUP;
328*00b67f09SDavid van Moolenbroek
329*00b67f09SDavid van Moolenbroek tmp = realloc(tmp, data.size + 1);
330*00b67f09SDavid van Moolenbroek if (tmp == NULL)
331*00b67f09SDavid van Moolenbroek goto allnodes_cleanup;
332*00b67f09SDavid van Moolenbroek
333*00b67f09SDavid van Moolenbroek strncpy(tmp, data.data, data.size);
334*00b67f09SDavid van Moolenbroek tmp[data.size] = '\0';
335*00b67f09SDavid van Moolenbroek
336*00b67f09SDavid van Moolenbroek if (bdb_parse_data(tmp, &pd) != ISC_R_SUCCESS)
337*00b67f09SDavid van Moolenbroek goto allnodes_cleanup;
338*00b67f09SDavid van Moolenbroek
339*00b67f09SDavid van Moolenbroek result = dns_sdlz_putnamedrr(allnodes, pd.host, pd.type,
340*00b67f09SDavid van Moolenbroek pd.ttl, pd.data);
341*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
342*00b67f09SDavid van Moolenbroek goto allnodes_cleanup;
343*00b67f09SDavid van Moolenbroek
344*00b67f09SDavid van Moolenbroek } /* end while loop */
345*00b67f09SDavid van Moolenbroek
346*00b67f09SDavid van Moolenbroek allnodes_cleanup:
347*00b67f09SDavid van Moolenbroek
348*00b67f09SDavid van Moolenbroek if (tmp != NULL)
349*00b67f09SDavid van Moolenbroek free(tmp);
350*00b67f09SDavid van Moolenbroek
351*00b67f09SDavid van Moolenbroek /* free any memory duplicate string in the key field */
352*00b67f09SDavid van Moolenbroek if (tmp_zone != NULL)
353*00b67f09SDavid van Moolenbroek free(tmp_zone);
354*00b67f09SDavid van Moolenbroek
355*00b67f09SDavid van Moolenbroek /* get rid of zone_cursor */
356*00b67f09SDavid van Moolenbroek if (zone_cursor != NULL)
357*00b67f09SDavid van Moolenbroek zone_cursor->c_close(zone_cursor);
358*00b67f09SDavid van Moolenbroek
359*00b67f09SDavid van Moolenbroek return result;
360*00b67f09SDavid van Moolenbroek
361*00b67f09SDavid van Moolenbroek }
362*00b67f09SDavid van Moolenbroek
363*00b67f09SDavid van Moolenbroek /*%
364*00b67f09SDavid van Moolenbroek * Performs BDB cleanup.
365*00b67f09SDavid van Moolenbroek * Used by bdb_create if there is an error starting up.
366*00b67f09SDavid van Moolenbroek * Used by bdb_destroy when the driver is shutting down.
367*00b67f09SDavid van Moolenbroek */
368*00b67f09SDavid van Moolenbroek
369*00b67f09SDavid van Moolenbroek static void
bdb_cleanup(bdb_instance_t * db)370*00b67f09SDavid van Moolenbroek bdb_cleanup(bdb_instance_t *db) {
371*00b67f09SDavid van Moolenbroek
372*00b67f09SDavid van Moolenbroek isc_mem_t *mctx;
373*00b67f09SDavid van Moolenbroek
374*00b67f09SDavid van Moolenbroek /* close databases */
375*00b67f09SDavid van Moolenbroek if (db->data != NULL)
376*00b67f09SDavid van Moolenbroek db->data->close(db->data, 0);
377*00b67f09SDavid van Moolenbroek if (db->host != NULL)
378*00b67f09SDavid van Moolenbroek db->host->close(db->host, 0);
379*00b67f09SDavid van Moolenbroek if (db->zone != NULL)
380*00b67f09SDavid van Moolenbroek db->zone->close(db->zone, 0);
381*00b67f09SDavid van Moolenbroek if (db->client != NULL)
382*00b67f09SDavid van Moolenbroek db->client->close(db->client, 0);
383*00b67f09SDavid van Moolenbroek
384*00b67f09SDavid van Moolenbroek /* close environment */
385*00b67f09SDavid van Moolenbroek if (db->dbenv != NULL)
386*00b67f09SDavid van Moolenbroek db->dbenv->close(db->dbenv, 0);
387*00b67f09SDavid van Moolenbroek
388*00b67f09SDavid van Moolenbroek /* cleanup memory */
389*00b67f09SDavid van Moolenbroek if (db->mctx != NULL) {
390*00b67f09SDavid van Moolenbroek /* save mctx for later */
391*00b67f09SDavid van Moolenbroek mctx = db->mctx;
392*00b67f09SDavid van Moolenbroek /* return, and detach the memory */
393*00b67f09SDavid van Moolenbroek isc_mem_put(mctx, db, sizeof(bdb_instance_t));
394*00b67f09SDavid van Moolenbroek isc_mem_detach(&mctx);
395*00b67f09SDavid van Moolenbroek }
396*00b67f09SDavid van Moolenbroek }
397*00b67f09SDavid van Moolenbroek
398*00b67f09SDavid van Moolenbroek static isc_result_t
bdb_findzone(void * driverarg,void * dbdata,const char * name,dns_clientinfomethods_t * methods,dns_clientinfo_t * clientinfo)399*00b67f09SDavid van Moolenbroek bdb_findzone(void *driverarg, void *dbdata, const char *name,
400*00b67f09SDavid van Moolenbroek dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo)
401*00b67f09SDavid van Moolenbroek {
402*00b67f09SDavid van Moolenbroek
403*00b67f09SDavid van Moolenbroek isc_result_t result;
404*00b67f09SDavid van Moolenbroek bdb_instance_t *db = (bdb_instance_t *) dbdata;
405*00b67f09SDavid van Moolenbroek DBC *zone_cursor = NULL;
406*00b67f09SDavid van Moolenbroek DBT key, data;
407*00b67f09SDavid van Moolenbroek
408*00b67f09SDavid van Moolenbroek UNUSED(driverarg);
409*00b67f09SDavid van Moolenbroek UNUSED(methods);
410*00b67f09SDavid van Moolenbroek UNUSED(clientinfo);
411*00b67f09SDavid van Moolenbroek
412*00b67f09SDavid van Moolenbroek memset(&key, 0, sizeof(DBT));
413*00b67f09SDavid van Moolenbroek memset(&data, 0, sizeof(DBT));
414*00b67f09SDavid van Moolenbroek data.flags = DB_DBT_MALLOC;
415*00b67f09SDavid van Moolenbroek
416*00b67f09SDavid van Moolenbroek key.data = strdup(name);
417*00b67f09SDavid van Moolenbroek
418*00b67f09SDavid van Moolenbroek if (key.data == NULL)
419*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
420*00b67f09SDavid van Moolenbroek
421*00b67f09SDavid van Moolenbroek key.size = strlen(key.data);
422*00b67f09SDavid van Moolenbroek
423*00b67f09SDavid van Moolenbroek /* get a cursor to loop through zone data */
424*00b67f09SDavid van Moolenbroek if (db->zone->cursor(db->zone, NULL, &zone_cursor, 0) != 0) {
425*00b67f09SDavid van Moolenbroek result = ISC_R_NOTFOUND;
426*00b67f09SDavid van Moolenbroek goto findzone_cleanup;
427*00b67f09SDavid van Moolenbroek }
428*00b67f09SDavid van Moolenbroek
429*00b67f09SDavid van Moolenbroek switch(zone_cursor->c_get(zone_cursor, &key, &data, DB_SET)) {
430*00b67f09SDavid van Moolenbroek case DB_NOTFOUND:
431*00b67f09SDavid van Moolenbroek case DB_SECONDARY_BAD:
432*00b67f09SDavid van Moolenbroek result = ISC_R_NOTFOUND;
433*00b67f09SDavid van Moolenbroek break;
434*00b67f09SDavid van Moolenbroek case 0:
435*00b67f09SDavid van Moolenbroek result = ISC_R_SUCCESS;
436*00b67f09SDavid van Moolenbroek break;
437*00b67f09SDavid van Moolenbroek default:
438*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
439*00b67f09SDavid van Moolenbroek }
440*00b67f09SDavid van Moolenbroek
441*00b67f09SDavid van Moolenbroek findzone_cleanup:
442*00b67f09SDavid van Moolenbroek
443*00b67f09SDavid van Moolenbroek /* free any memory duplicate string in the key field */
444*00b67f09SDavid van Moolenbroek if (key.data != NULL)
445*00b67f09SDavid van Moolenbroek free(key.data);
446*00b67f09SDavid van Moolenbroek
447*00b67f09SDavid van Moolenbroek /* free any memory allocated to the data field. */
448*00b67f09SDavid van Moolenbroek if (data.data != NULL)
449*00b67f09SDavid van Moolenbroek free(data.data);
450*00b67f09SDavid van Moolenbroek
451*00b67f09SDavid van Moolenbroek /* get rid of zone_cursor */
452*00b67f09SDavid van Moolenbroek if (zone_cursor != NULL)
453*00b67f09SDavid van Moolenbroek zone_cursor->c_close(zone_cursor);
454*00b67f09SDavid van Moolenbroek
455*00b67f09SDavid van Moolenbroek return result;
456*00b67f09SDavid van Moolenbroek }
457*00b67f09SDavid van Moolenbroek
458*00b67f09SDavid van Moolenbroek static isc_result_t
bdb_lookup(const char * zone,const char * name,void * driverarg,void * dbdata,dns_sdlzlookup_t * lookup,dns_clientinfomethods_t * methods,dns_clientinfo_t * clientinfo)459*00b67f09SDavid van Moolenbroek bdb_lookup(const char *zone, const char *name, void *driverarg,
460*00b67f09SDavid van Moolenbroek void *dbdata, dns_sdlzlookup_t *lookup,
461*00b67f09SDavid van Moolenbroek dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo)
462*00b67f09SDavid van Moolenbroek {
463*00b67f09SDavid van Moolenbroek
464*00b67f09SDavid van Moolenbroek isc_result_t result = ISC_R_NOTFOUND;
465*00b67f09SDavid van Moolenbroek bdb_instance_t *db = (bdb_instance_t *) dbdata;
466*00b67f09SDavid van Moolenbroek DBC *zone_cursor = NULL;
467*00b67f09SDavid van Moolenbroek DBC *host_cursor = NULL;
468*00b67f09SDavid van Moolenbroek DBC *join_cursor = NULL;
469*00b67f09SDavid van Moolenbroek DBT key, data;
470*00b67f09SDavid van Moolenbroek DBC *cur_arr[3];
471*00b67f09SDavid van Moolenbroek int bdbres;
472*00b67f09SDavid van Moolenbroek parsed_data_t pd;
473*00b67f09SDavid van Moolenbroek char *tmp_zone, *tmp_host = NULL;
474*00b67f09SDavid van Moolenbroek char *tmp = NULL;
475*00b67f09SDavid van Moolenbroek
476*00b67f09SDavid van Moolenbroek UNUSED(driverarg);
477*00b67f09SDavid van Moolenbroek UNUSED(methods);
478*00b67f09SDavid van Moolenbroek UNUSED(clientinfo);
479*00b67f09SDavid van Moolenbroek
480*00b67f09SDavid van Moolenbroek memset(&key, 0, sizeof(DBT));
481*00b67f09SDavid van Moolenbroek memset(&data, 0, sizeof(DBT));
482*00b67f09SDavid van Moolenbroek
483*00b67f09SDavid van Moolenbroek /* set zone key */
484*00b67f09SDavid van Moolenbroek key.data = tmp_zone = strdup(zone);
485*00b67f09SDavid van Moolenbroek if (key.data == NULL) {
486*00b67f09SDavid van Moolenbroek result = ISC_R_NOMEMORY;
487*00b67f09SDavid van Moolenbroek goto lookup_cleanup;
488*00b67f09SDavid van Moolenbroek }
489*00b67f09SDavid van Moolenbroek key.size = strlen(key.data);
490*00b67f09SDavid van Moolenbroek
491*00b67f09SDavid van Moolenbroek /* get a cursor to loop through zone data */
492*00b67f09SDavid van Moolenbroek if (db->zone->cursor(db->zone, NULL, &zone_cursor, 0) != 0) {
493*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
494*00b67f09SDavid van Moolenbroek goto lookup_cleanup;
495*00b67f09SDavid van Moolenbroek }
496*00b67f09SDavid van Moolenbroek
497*00b67f09SDavid van Moolenbroek /* initialize zone_cursor with zone_key */
498*00b67f09SDavid van Moolenbroek if (zone_cursor->c_get(zone_cursor, &key, &data, DB_SET) != 0) {
499*00b67f09SDavid van Moolenbroek result = ISC_R_NOTFOUND;
500*00b67f09SDavid van Moolenbroek goto lookup_cleanup;
501*00b67f09SDavid van Moolenbroek }
502*00b67f09SDavid van Moolenbroek
503*00b67f09SDavid van Moolenbroek /* set host key */
504*00b67f09SDavid van Moolenbroek key.data = tmp_host = strdup(name);
505*00b67f09SDavid van Moolenbroek if (key.data == NULL) {
506*00b67f09SDavid van Moolenbroek result = ISC_R_NOMEMORY;
507*00b67f09SDavid van Moolenbroek goto lookup_cleanup;
508*00b67f09SDavid van Moolenbroek }
509*00b67f09SDavid van Moolenbroek key.size = strlen(key.data);
510*00b67f09SDavid van Moolenbroek
511*00b67f09SDavid van Moolenbroek /* get a cursor to loop through host data */
512*00b67f09SDavid van Moolenbroek if (db->host->cursor(db->host, NULL, &host_cursor, 0) != 0) {
513*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
514*00b67f09SDavid van Moolenbroek goto lookup_cleanup;
515*00b67f09SDavid van Moolenbroek }
516*00b67f09SDavid van Moolenbroek
517*00b67f09SDavid van Moolenbroek /* initialize host_cursor with host_key */
518*00b67f09SDavid van Moolenbroek if (host_cursor->c_get(host_cursor, &key, &data, DB_SET) != 0) {
519*00b67f09SDavid van Moolenbroek result = ISC_R_NOTFOUND;
520*00b67f09SDavid van Moolenbroek goto lookup_cleanup;
521*00b67f09SDavid van Moolenbroek }
522*00b67f09SDavid van Moolenbroek
523*00b67f09SDavid van Moolenbroek cur_arr[0] = zone_cursor;
524*00b67f09SDavid van Moolenbroek cur_arr[1] = host_cursor;
525*00b67f09SDavid van Moolenbroek cur_arr[2] = NULL;
526*00b67f09SDavid van Moolenbroek
527*00b67f09SDavid van Moolenbroek db->data->join(db->data, cur_arr, &join_cursor, 0);
528*00b67f09SDavid van Moolenbroek
529*00b67f09SDavid van Moolenbroek while ((bdbres = join_cursor->c_get(join_cursor, &key,
530*00b67f09SDavid van Moolenbroek &data, 0)) == 0) {
531*00b67f09SDavid van Moolenbroek
532*00b67f09SDavid van Moolenbroek tmp = realloc(tmp, data.size + 1);
533*00b67f09SDavid van Moolenbroek if (tmp == NULL)
534*00b67f09SDavid van Moolenbroek goto lookup_cleanup;
535*00b67f09SDavid van Moolenbroek
536*00b67f09SDavid van Moolenbroek strncpy(tmp, data.data, data.size);
537*00b67f09SDavid van Moolenbroek tmp[data.size] = '\0';
538*00b67f09SDavid van Moolenbroek
539*00b67f09SDavid van Moolenbroek if (bdb_parse_data(tmp, &pd) != ISC_R_SUCCESS)
540*00b67f09SDavid van Moolenbroek goto lookup_cleanup;
541*00b67f09SDavid van Moolenbroek
542*00b67f09SDavid van Moolenbroek result = dns_sdlz_putrr(lookup, pd.type, pd.ttl, pd.data);
543*00b67f09SDavid van Moolenbroek
544*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
545*00b67f09SDavid van Moolenbroek goto lookup_cleanup;
546*00b67f09SDavid van Moolenbroek } /* end while loop */
547*00b67f09SDavid van Moolenbroek
548*00b67f09SDavid van Moolenbroek lookup_cleanup:
549*00b67f09SDavid van Moolenbroek
550*00b67f09SDavid van Moolenbroek if (tmp != NULL)
551*00b67f09SDavid van Moolenbroek free(tmp);
552*00b67f09SDavid van Moolenbroek if (tmp_zone != NULL)
553*00b67f09SDavid van Moolenbroek free(tmp_zone);
554*00b67f09SDavid van Moolenbroek if (tmp_host != NULL)
555*00b67f09SDavid van Moolenbroek free(tmp_host);
556*00b67f09SDavid van Moolenbroek
557*00b67f09SDavid van Moolenbroek /* get rid of the joined cusor */
558*00b67f09SDavid van Moolenbroek if (join_cursor != NULL)
559*00b67f09SDavid van Moolenbroek join_cursor->c_close(join_cursor);
560*00b67f09SDavid van Moolenbroek
561*00b67f09SDavid van Moolenbroek /* get rid of zone_cursor */
562*00b67f09SDavid van Moolenbroek if (zone_cursor != NULL)
563*00b67f09SDavid van Moolenbroek zone_cursor->c_close(zone_cursor);
564*00b67f09SDavid van Moolenbroek
565*00b67f09SDavid van Moolenbroek /* get rid of host_cursor */
566*00b67f09SDavid van Moolenbroek if (host_cursor != NULL)
567*00b67f09SDavid van Moolenbroek host_cursor->c_close(host_cursor);
568*00b67f09SDavid van Moolenbroek
569*00b67f09SDavid van Moolenbroek return result;
570*00b67f09SDavid van Moolenbroek }
571*00b67f09SDavid van Moolenbroek
572*00b67f09SDavid van Moolenbroek
573*00b67f09SDavid van Moolenbroek /*% Initializes, sets flags and then opens Berkeley databases. */
574*00b67f09SDavid van Moolenbroek
575*00b67f09SDavid van Moolenbroek static isc_result_t
bdb_opendb(DB_ENV * db_env,DBTYPE db_type,DB ** db,const char * db_name,char * db_file,int flags)576*00b67f09SDavid van Moolenbroek bdb_opendb(DB_ENV *db_env, DBTYPE db_type, DB **db, const char *db_name,
577*00b67f09SDavid van Moolenbroek char *db_file, int flags) {
578*00b67f09SDavid van Moolenbroek
579*00b67f09SDavid van Moolenbroek int result;
580*00b67f09SDavid van Moolenbroek
581*00b67f09SDavid van Moolenbroek /* Initialize the database. */
582*00b67f09SDavid van Moolenbroek if ((result = db_create(db, db_env, 0)) != 0) {
583*00b67f09SDavid van Moolenbroek isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
584*00b67f09SDavid van Moolenbroek DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
585*00b67f09SDavid van Moolenbroek "BDB could not initialize %s database. "
586*00b67f09SDavid van Moolenbroek "BDB error: %s",
587*00b67f09SDavid van Moolenbroek db_name, db_strerror(result));
588*00b67f09SDavid van Moolenbroek return ISC_R_FAILURE;
589*00b67f09SDavid van Moolenbroek }
590*00b67f09SDavid van Moolenbroek
591*00b67f09SDavid van Moolenbroek /* set database flags. */
592*00b67f09SDavid van Moolenbroek if ((result = (*db)->set_flags(*db, flags)) != 0) {
593*00b67f09SDavid van Moolenbroek isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
594*00b67f09SDavid van Moolenbroek DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
595*00b67f09SDavid van Moolenbroek "BDB could not set flags for %s database. "
596*00b67f09SDavid van Moolenbroek "BDB error: %s",
597*00b67f09SDavid van Moolenbroek db_name, db_strerror(result));
598*00b67f09SDavid van Moolenbroek return ISC_R_FAILURE;
599*00b67f09SDavid van Moolenbroek }
600*00b67f09SDavid van Moolenbroek
601*00b67f09SDavid van Moolenbroek /* open the database. */
602*00b67f09SDavid van Moolenbroek if ((result = (*db)->open(*db, NULL, db_file, db_name, db_type,
603*00b67f09SDavid van Moolenbroek DB_RDONLY | bdb_threads, 0)) != 0) {
604*00b67f09SDavid van Moolenbroek isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
605*00b67f09SDavid van Moolenbroek DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
606*00b67f09SDavid van Moolenbroek "BDB could not open %s database in %s. "
607*00b67f09SDavid van Moolenbroek "BDB error: %s",
608*00b67f09SDavid van Moolenbroek db_name, db_file, db_strerror(result));
609*00b67f09SDavid van Moolenbroek return ISC_R_FAILURE;
610*00b67f09SDavid van Moolenbroek }
611*00b67f09SDavid van Moolenbroek
612*00b67f09SDavid van Moolenbroek return ISC_R_SUCCESS;
613*00b67f09SDavid van Moolenbroek }
614*00b67f09SDavid van Moolenbroek
615*00b67f09SDavid van Moolenbroek static isc_result_t
bdb_create(const char * dlzname,unsigned int argc,char * argv[],void * driverarg,void ** dbdata)616*00b67f09SDavid van Moolenbroek bdb_create(const char *dlzname, unsigned int argc, char *argv[],
617*00b67f09SDavid van Moolenbroek void *driverarg, void **dbdata)
618*00b67f09SDavid van Moolenbroek {
619*00b67f09SDavid van Moolenbroek isc_result_t result;
620*00b67f09SDavid van Moolenbroek int bdbres;
621*00b67f09SDavid van Moolenbroek bdb_instance_t *db = NULL;
622*00b67f09SDavid van Moolenbroek
623*00b67f09SDavid van Moolenbroek UNUSED(dlzname);
624*00b67f09SDavid van Moolenbroek UNUSED(driverarg);
625*00b67f09SDavid van Moolenbroek
626*00b67f09SDavid van Moolenbroek /* verify we have 3 arg's passed to the driver */
627*00b67f09SDavid van Moolenbroek if (argc != 3) {
628*00b67f09SDavid van Moolenbroek isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
629*00b67f09SDavid van Moolenbroek DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
630*00b67f09SDavid van Moolenbroek "Berkeley DB driver requires at least "
631*00b67f09SDavid van Moolenbroek "2 command line args.");
632*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
633*00b67f09SDavid van Moolenbroek }
634*00b67f09SDavid van Moolenbroek
635*00b67f09SDavid van Moolenbroek /* allocate and zero memory for driver structure */
636*00b67f09SDavid van Moolenbroek db = isc_mem_get(ns_g_mctx, sizeof(bdb_instance_t));
637*00b67f09SDavid van Moolenbroek if (db == NULL) {
638*00b67f09SDavid van Moolenbroek isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
639*00b67f09SDavid van Moolenbroek DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
640*00b67f09SDavid van Moolenbroek "Could not allocate memory for "
641*00b67f09SDavid van Moolenbroek "database instance object.");
642*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
643*00b67f09SDavid van Moolenbroek }
644*00b67f09SDavid van Moolenbroek memset(db, 0, sizeof(bdb_instance_t));
645*00b67f09SDavid van Moolenbroek
646*00b67f09SDavid van Moolenbroek /* attach to the memory context */
647*00b67f09SDavid van Moolenbroek isc_mem_attach(ns_g_mctx, &db->mctx);
648*00b67f09SDavid van Moolenbroek
649*00b67f09SDavid van Moolenbroek /* create BDB environment
650*00b67f09SDavid van Moolenbroek * Basically BDB allocates and assigns memory to db->dbenv
651*00b67f09SDavid van Moolenbroek */
652*00b67f09SDavid van Moolenbroek bdbres = db_env_create(&db->dbenv, 0);
653*00b67f09SDavid van Moolenbroek if (bdbres != 0) {
654*00b67f09SDavid van Moolenbroek isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
655*00b67f09SDavid van Moolenbroek DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
656*00b67f09SDavid van Moolenbroek "BDB environment could not be created. "
657*00b67f09SDavid van Moolenbroek "BDB error: %s",
658*00b67f09SDavid van Moolenbroek db_strerror(bdbres));
659*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
660*00b67f09SDavid van Moolenbroek goto init_cleanup;
661*00b67f09SDavid van Moolenbroek }
662*00b67f09SDavid van Moolenbroek
663*00b67f09SDavid van Moolenbroek /* open BDB environment */
664*00b67f09SDavid van Moolenbroek bdbres = db->dbenv->open(db->dbenv, argv[1],
665*00b67f09SDavid van Moolenbroek DB_INIT_CDB | DB_INIT_MPOOL |
666*00b67f09SDavid van Moolenbroek bdb_threads | DB_CREATE,
667*00b67f09SDavid van Moolenbroek 0);
668*00b67f09SDavid van Moolenbroek if (bdbres != 0) {
669*00b67f09SDavid van Moolenbroek isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
670*00b67f09SDavid van Moolenbroek DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
671*00b67f09SDavid van Moolenbroek "BDB environment at '%s' could not be opened. "
672*00b67f09SDavid van Moolenbroek "BDB error: %s",
673*00b67f09SDavid van Moolenbroek argv[1], db_strerror(bdbres));
674*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
675*00b67f09SDavid van Moolenbroek goto init_cleanup;
676*00b67f09SDavid van Moolenbroek }
677*00b67f09SDavid van Moolenbroek
678*00b67f09SDavid van Moolenbroek /* open dlz_data database. */
679*00b67f09SDavid van Moolenbroek result = bdb_opendb(db->dbenv, DB_UNKNOWN, &db->data,
680*00b67f09SDavid van Moolenbroek dlz_data, argv[2], 0);
681*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
682*00b67f09SDavid van Moolenbroek goto init_cleanup;
683*00b67f09SDavid van Moolenbroek
684*00b67f09SDavid van Moolenbroek /* open dlz_host database. */
685*00b67f09SDavid van Moolenbroek result = bdb_opendb(db->dbenv, DB_UNKNOWN, &db->host,
686*00b67f09SDavid van Moolenbroek dlz_host, argv[2],
687*00b67f09SDavid van Moolenbroek DB_DUP | DB_DUPSORT);
688*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
689*00b67f09SDavid van Moolenbroek goto init_cleanup;
690*00b67f09SDavid van Moolenbroek
691*00b67f09SDavid van Moolenbroek /* open dlz_zone database. */
692*00b67f09SDavid van Moolenbroek result = bdb_opendb(db->dbenv, DB_UNKNOWN, &db->zone,
693*00b67f09SDavid van Moolenbroek dlz_zone, argv[2],
694*00b67f09SDavid van Moolenbroek DB_DUP | DB_DUPSORT);
695*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
696*00b67f09SDavid van Moolenbroek goto init_cleanup;
697*00b67f09SDavid van Moolenbroek
698*00b67f09SDavid van Moolenbroek /* open dlz_client database. */
699*00b67f09SDavid van Moolenbroek result = bdb_opendb(db->dbenv, DB_UNKNOWN, &db->client,
700*00b67f09SDavid van Moolenbroek dlz_client, argv[2], DB_DUP | DB_DUPSORT);
701*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
702*00b67f09SDavid van Moolenbroek goto init_cleanup;
703*00b67f09SDavid van Moolenbroek
704*00b67f09SDavid van Moolenbroek /* associate the host secondary database with the primary database */
705*00b67f09SDavid van Moolenbroek bdbres = db->data->associate(db->data, NULL, db->host, NULL, 0);
706*00b67f09SDavid van Moolenbroek if (bdbres != 0) {
707*00b67f09SDavid van Moolenbroek isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
708*00b67f09SDavid van Moolenbroek DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
709*00b67f09SDavid van Moolenbroek "BDB could not associate %s database with %s. "
710*00b67f09SDavid van Moolenbroek "BDB error: %s",
711*00b67f09SDavid van Moolenbroek dlz_host, dlz_data, db_strerror(bdbres));
712*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
713*00b67f09SDavid van Moolenbroek goto init_cleanup;
714*00b67f09SDavid van Moolenbroek }
715*00b67f09SDavid van Moolenbroek
716*00b67f09SDavid van Moolenbroek /* associate the zone secondary database with the primary database */
717*00b67f09SDavid van Moolenbroek bdbres = db->data->associate(db->data, NULL, db->zone, NULL, 0);
718*00b67f09SDavid van Moolenbroek if (bdbres != 0) {
719*00b67f09SDavid van Moolenbroek isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
720*00b67f09SDavid van Moolenbroek DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
721*00b67f09SDavid van Moolenbroek "BDB could not associate %s database with %s. "
722*00b67f09SDavid van Moolenbroek "BDB error: %s",
723*00b67f09SDavid van Moolenbroek dlz_zone, dlz_data, db_strerror(bdbres));
724*00b67f09SDavid van Moolenbroek result = ISC_R_FAILURE;
725*00b67f09SDavid van Moolenbroek goto init_cleanup;
726*00b67f09SDavid van Moolenbroek }
727*00b67f09SDavid van Moolenbroek
728*00b67f09SDavid van Moolenbroek *dbdata = db;
729*00b67f09SDavid van Moolenbroek
730*00b67f09SDavid van Moolenbroek return(ISC_R_SUCCESS);
731*00b67f09SDavid van Moolenbroek
732*00b67f09SDavid van Moolenbroek init_cleanup:
733*00b67f09SDavid van Moolenbroek
734*00b67f09SDavid van Moolenbroek bdb_cleanup(db);
735*00b67f09SDavid van Moolenbroek return result;
736*00b67f09SDavid van Moolenbroek }
737*00b67f09SDavid van Moolenbroek
738*00b67f09SDavid van Moolenbroek static void
bdb_destroy(void * driverarg,void * dbdata)739*00b67f09SDavid van Moolenbroek bdb_destroy(void *driverarg, void *dbdata)
740*00b67f09SDavid van Moolenbroek {
741*00b67f09SDavid van Moolenbroek UNUSED(driverarg);
742*00b67f09SDavid van Moolenbroek
743*00b67f09SDavid van Moolenbroek bdb_cleanup((bdb_instance_t *) dbdata);
744*00b67f09SDavid van Moolenbroek }
745*00b67f09SDavid van Moolenbroek
746*00b67f09SDavid van Moolenbroek /* bdb_authority not needed as authority data is returned by lookup */
747*00b67f09SDavid van Moolenbroek static dns_sdlzmethods_t dlz_bdb_methods = {
748*00b67f09SDavid van Moolenbroek bdb_create,
749*00b67f09SDavid van Moolenbroek bdb_destroy,
750*00b67f09SDavid van Moolenbroek bdb_findzone,
751*00b67f09SDavid van Moolenbroek bdb_lookup,
752*00b67f09SDavid van Moolenbroek NULL,
753*00b67f09SDavid van Moolenbroek bdb_allnodes,
754*00b67f09SDavid van Moolenbroek bdb_allowzonexfr,
755*00b67f09SDavid van Moolenbroek NULL,
756*00b67f09SDavid van Moolenbroek NULL,
757*00b67f09SDavid van Moolenbroek NULL,
758*00b67f09SDavid van Moolenbroek NULL,
759*00b67f09SDavid van Moolenbroek NULL,
760*00b67f09SDavid van Moolenbroek NULL,
761*00b67f09SDavid van Moolenbroek NULL,
762*00b67f09SDavid van Moolenbroek };
763*00b67f09SDavid van Moolenbroek
764*00b67f09SDavid van Moolenbroek /*%
765*00b67f09SDavid van Moolenbroek * Wrapper around dns_sdlzregister().
766*00b67f09SDavid van Moolenbroek */
767*00b67f09SDavid van Moolenbroek isc_result_t
dlz_bdb_init(void)768*00b67f09SDavid van Moolenbroek dlz_bdb_init(void) {
769*00b67f09SDavid van Moolenbroek isc_result_t result;
770*00b67f09SDavid van Moolenbroek
771*00b67f09SDavid van Moolenbroek /*
772*00b67f09SDavid van Moolenbroek * Write debugging message to log
773*00b67f09SDavid van Moolenbroek */
774*00b67f09SDavid van Moolenbroek isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
775*00b67f09SDavid van Moolenbroek DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
776*00b67f09SDavid van Moolenbroek "Registering DLZ bdb driver.");
777*00b67f09SDavid van Moolenbroek
778*00b67f09SDavid van Moolenbroek result = dns_sdlzregister("bdb", &dlz_bdb_methods, NULL,
779*00b67f09SDavid van Moolenbroek DNS_SDLZFLAG_RELATIVEOWNER |
780*00b67f09SDavid van Moolenbroek DNS_SDLZFLAG_RELATIVERDATA |
781*00b67f09SDavid van Moolenbroek DNS_SDLZFLAG_THREADSAFE,
782*00b67f09SDavid van Moolenbroek ns_g_mctx, &dlz_bdb);
783*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
784*00b67f09SDavid van Moolenbroek UNEXPECTED_ERROR(__FILE__, __LINE__,
785*00b67f09SDavid van Moolenbroek "dns_sdlzregister() failed: %s",
786*00b67f09SDavid van Moolenbroek isc_result_totext(result));
787*00b67f09SDavid van Moolenbroek result = ISC_R_UNEXPECTED;
788*00b67f09SDavid van Moolenbroek }
789*00b67f09SDavid van Moolenbroek
790*00b67f09SDavid van Moolenbroek
791*00b67f09SDavid van Moolenbroek return result;
792*00b67f09SDavid van Moolenbroek }
793*00b67f09SDavid van Moolenbroek
794*00b67f09SDavid van Moolenbroek /*%
795*00b67f09SDavid van Moolenbroek * Wrapper around dns_sdlzunregister().
796*00b67f09SDavid van Moolenbroek */
797*00b67f09SDavid van Moolenbroek void
dlz_bdb_clear(void)798*00b67f09SDavid van Moolenbroek dlz_bdb_clear(void) {
799*00b67f09SDavid van Moolenbroek
800*00b67f09SDavid van Moolenbroek /*
801*00b67f09SDavid van Moolenbroek * Write debugging message to log
802*00b67f09SDavid van Moolenbroek */
803*00b67f09SDavid van Moolenbroek isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
804*00b67f09SDavid van Moolenbroek DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
805*00b67f09SDavid van Moolenbroek "Unregistering DLZ bdb driver.");
806*00b67f09SDavid van Moolenbroek
807*00b67f09SDavid van Moolenbroek if (dlz_bdb != NULL)
808*00b67f09SDavid van Moolenbroek dns_sdlzunregister(&dlz_bdb);
809*00b67f09SDavid van Moolenbroek }
810*00b67f09SDavid van Moolenbroek
811*00b67f09SDavid van Moolenbroek #endif
812