1*00b67f09SDavid van Moolenbroek /* $NetBSD: bdb.c,v 1.4 2014/12/10 04:37:56 christos Exp $ */
2*00b67f09SDavid van Moolenbroek
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek * Copyright (C) 2002 Nuno M. Rodrigues.
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 above
8*00b67f09SDavid van Moolenbroek * copyright notice and this permission notice appear in all copies.
9*00b67f09SDavid van Moolenbroek *
10*00b67f09SDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND NUNO M. RODRIGUES
11*00b67f09SDavid van Moolenbroek * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
12*00b67f09SDavid van Moolenbroek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
13*00b67f09SDavid van Moolenbroek * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
15*00b67f09SDavid van Moolenbroek * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
16*00b67f09SDavid van Moolenbroek * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
17*00b67f09SDavid van Moolenbroek * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek */
19*00b67f09SDavid van Moolenbroek
20*00b67f09SDavid van Moolenbroek /* Id: bdb.c,v 1.2 2011/10/11 00:09:02 each Exp */
21*00b67f09SDavid van Moolenbroek
22*00b67f09SDavid van Moolenbroek /*
23*00b67f09SDavid van Moolenbroek * BIND 9.1.x simple database driver
24*00b67f09SDavid van Moolenbroek * implementation, using Berkeley DB.
25*00b67f09SDavid van Moolenbroek */
26*00b67f09SDavid van Moolenbroek
27*00b67f09SDavid van Moolenbroek #include <errno.h>
28*00b67f09SDavid van Moolenbroek #include <stdio.h>
29*00b67f09SDavid van Moolenbroek #include <string.h>
30*00b67f09SDavid van Moolenbroek #include <stdlib.h>
31*00b67f09SDavid van Moolenbroek
32*00b67f09SDavid van Moolenbroek #include <isc/file.h>
33*00b67f09SDavid van Moolenbroek #include <isc/log.h>
34*00b67f09SDavid van Moolenbroek #include <isc/lib.h>
35*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
36*00b67f09SDavid van Moolenbroek #include <isc/msgs.h>
37*00b67f09SDavid van Moolenbroek #include <isc/msgcat.h>
38*00b67f09SDavid van Moolenbroek #include <isc/region.h>
39*00b67f09SDavid van Moolenbroek #include <isc/result.h>
40*00b67f09SDavid van Moolenbroek #include <isc/types.h>
41*00b67f09SDavid van Moolenbroek #include <isc/util.h>
42*00b67f09SDavid van Moolenbroek
43*00b67f09SDavid van Moolenbroek #include <dns/sdb.h>
44*00b67f09SDavid van Moolenbroek #include <dns/log.h>
45*00b67f09SDavid van Moolenbroek #include <dns/lib.h>
46*00b67f09SDavid van Moolenbroek #include <dns/ttl.h>
47*00b67f09SDavid van Moolenbroek
48*00b67f09SDavid van Moolenbroek #include <named/bdb.h>
49*00b67f09SDavid van Moolenbroek #include <named/globals.h>
50*00b67f09SDavid van Moolenbroek #include <named/config.h>
51*00b67f09SDavid van Moolenbroek
52*00b67f09SDavid van Moolenbroek #include <db.h>
53*00b67f09SDavid van Moolenbroek
54*00b67f09SDavid van Moolenbroek #define DRIVERNAME "bdb"
55*00b67f09SDavid van Moolenbroek
56*00b67f09SDavid van Moolenbroek static dns_sdbimplementation_t *bdb_imp;
57*00b67f09SDavid van Moolenbroek
58*00b67f09SDavid van Moolenbroek static isc_result_t
bdb_create(const char * zone,int argc,char ** argv,void * unused,void ** dbdata)59*00b67f09SDavid van Moolenbroek bdb_create(const char *zone, int argc, char **argv,
60*00b67f09SDavid van Moolenbroek void *unused, void **dbdata)
61*00b67f09SDavid van Moolenbroek {
62*00b67f09SDavid van Moolenbroek int ret;
63*00b67f09SDavid van Moolenbroek
64*00b67f09SDavid van Moolenbroek UNUSED(zone);
65*00b67f09SDavid van Moolenbroek UNUSED(unused);
66*00b67f09SDavid van Moolenbroek
67*00b67f09SDavid van Moolenbroek if (argc < 1)
68*00b67f09SDavid van Moolenbroek return ISC_R_FAILURE; /* database path must be given */
69*00b67f09SDavid van Moolenbroek
70*00b67f09SDavid van Moolenbroek if (db_create((DB **)dbdata, NULL, 0) != 0) {
71*00b67f09SDavid van Moolenbroek /*
72*00b67f09SDavid van Moolenbroek * XXX Should use dns_msgcat et al
73*00b67f09SDavid van Moolenbroek * but seems to be unavailable.
74*00b67f09SDavid van Moolenbroek */
75*00b67f09SDavid van Moolenbroek isc_log_iwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
76*00b67f09SDavid van Moolenbroek DNS_LOGMODULE_SDB, ISC_LOG_CRITICAL, isc_msgcat,
77*00b67f09SDavid van Moolenbroek ISC_MSGSET_GENERAL, ISC_MSG_FATALERROR,
78*00b67f09SDavid van Moolenbroek "db_create");
79*00b67f09SDavid van Moolenbroek return ISC_R_FAILURE;
80*00b67f09SDavid van Moolenbroek }
81*00b67f09SDavid van Moolenbroek
82*00b67f09SDavid van Moolenbroek if (isc_file_exists(*argv) != ISC_TRUE) {
83*00b67f09SDavid van Moolenbroek isc_log_iwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
84*00b67f09SDavid van Moolenbroek DNS_LOGMODULE_SDB, ISC_LOG_CRITICAL, isc_msgcat,
85*00b67f09SDavid van Moolenbroek ISC_MSGSET_GENERAL, ISC_MSG_FATALERROR,
86*00b67f09SDavid van Moolenbroek "isc_file_exists: %s", *argv);
87*00b67f09SDavid van Moolenbroek return ISC_R_FAILURE;
88*00b67f09SDavid van Moolenbroek }
89*00b67f09SDavid van Moolenbroek
90*00b67f09SDavid van Moolenbroek if ((ret = (*(DB **)dbdata)->open(*(DB **)dbdata, *argv, NULL, DB_HASH,
91*00b67f09SDavid van Moolenbroek DB_RDONLY, 0)) != 0) {
92*00b67f09SDavid van Moolenbroek isc_log_iwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
93*00b67f09SDavid van Moolenbroek DNS_LOGMODULE_SDB, ISC_LOG_CRITICAL,
94*00b67f09SDavid van Moolenbroek isc_msgcat, ISC_MSGSET_GENERAL,
95*00b67f09SDavid van Moolenbroek ISC_MSG_FATALERROR, "DB->open: %s",
96*00b67f09SDavid van Moolenbroek db_strerror(ret));
97*00b67f09SDavid van Moolenbroek return ISC_R_FAILURE;
98*00b67f09SDavid van Moolenbroek }
99*00b67f09SDavid van Moolenbroek return ISC_R_SUCCESS;
100*00b67f09SDavid van Moolenbroek }
101*00b67f09SDavid van Moolenbroek
102*00b67f09SDavid van Moolenbroek static isc_result_t
103*00b67f09SDavid van Moolenbroek #ifdef DNS_CLIENTINFO_VERSION
bdb_lookup(const char * zone,const char * name,void * dbdata,dns_sdblookup_t * l,dns_clientinfomethods_t * methods,dns_clientinfo_t * clientinfo)104*00b67f09SDavid van Moolenbroek bdb_lookup(const char *zone, const char *name, void *dbdata,
105*00b67f09SDavid van Moolenbroek dns_sdblookup_t *l, dns_clientinfomethods_t *methods,
106*00b67f09SDavid van Moolenbroek dns_clientinfo_t *clientinfo)
107*00b67f09SDavid van Moolenbroek #else
108*00b67f09SDavid van Moolenbroek bdb_lookup(const char *zone, const char *name, void *dbdata,
109*00b67f09SDavid van Moolenbroek dns_sdblookup_t *l)
110*00b67f09SDavid van Moolenbroek #endif /* DNS_CLIENTINFO_VERSION */
111*00b67f09SDavid van Moolenbroek {
112*00b67f09SDavid van Moolenbroek int ret;
113*00b67f09SDavid van Moolenbroek char *type, *rdata;
114*00b67f09SDavid van Moolenbroek dns_ttl_t ttl;
115*00b67f09SDavid van Moolenbroek isc_consttextregion_t ttltext;
116*00b67f09SDavid van Moolenbroek DBC *c;
117*00b67f09SDavid van Moolenbroek DBT key, data;
118*00b67f09SDavid van Moolenbroek
119*00b67f09SDavid van Moolenbroek UNUSED(zone);
120*00b67f09SDavid van Moolenbroek #ifdef DNS_CLIENTINFO_VERSION
121*00b67f09SDavid van Moolenbroek UNUSED(methods);
122*00b67f09SDavid van Moolenbroek UNUSED(clientinfo);
123*00b67f09SDavid van Moolenbroek #endif /* DNS_CLIENTINFO_VERSION */
124*00b67f09SDavid van Moolenbroek
125*00b67f09SDavid van Moolenbroek if ((ret = ((DB *)dbdata)->cursor((DB *)dbdata, NULL, &c, 0)) != 0) {
126*00b67f09SDavid van Moolenbroek isc_log_iwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
127*00b67f09SDavid van Moolenbroek DNS_LOGMODULE_SDB, ISC_LOG_ERROR,
128*00b67f09SDavid van Moolenbroek isc_msgcat, ISC_MSGSET_GENERAL,
129*00b67f09SDavid van Moolenbroek ISC_MSG_FAILED, "DB->cursor: %s",
130*00b67f09SDavid van Moolenbroek db_strerror(ret));
131*00b67f09SDavid van Moolenbroek return ISC_R_FAILURE;
132*00b67f09SDavid van Moolenbroek }
133*00b67f09SDavid van Moolenbroek
134*00b67f09SDavid van Moolenbroek memset(&key, 0, sizeof(DBT));
135*00b67f09SDavid van Moolenbroek memset(&data, 0, sizeof(DBT));
136*00b67f09SDavid van Moolenbroek
137*00b67f09SDavid van Moolenbroek (const char *)key.data = name;
138*00b67f09SDavid van Moolenbroek key.size = strlen(name);
139*00b67f09SDavid van Moolenbroek
140*00b67f09SDavid van Moolenbroek ret = c->c_get(c, &key, &data, DB_SET);
141*00b67f09SDavid van Moolenbroek while (ret == 0) {
142*00b67f09SDavid van Moolenbroek ((char *)key.data)[key.size] = 0;
143*00b67f09SDavid van Moolenbroek ((char *)data.data)[data.size] = 0;
144*00b67f09SDavid van Moolenbroek ttltext.base = strtok((char *)data.data, " ");
145*00b67f09SDavid van Moolenbroek ttltext.length = strlen(ttltext.base);
146*00b67f09SDavid van Moolenbroek dns_ttl_fromtext((isc_textregion_t *)&ttltext, &ttl);
147*00b67f09SDavid van Moolenbroek type = strtok(NULL, " ");
148*00b67f09SDavid van Moolenbroek rdata = type + strlen(type) + 1;
149*00b67f09SDavid van Moolenbroek
150*00b67f09SDavid van Moolenbroek if (dns_sdb_putrr(l, type, ttl, rdata) != ISC_R_SUCCESS) {
151*00b67f09SDavid van Moolenbroek isc_log_iwrite(dns_lctx,
152*00b67f09SDavid van Moolenbroek DNS_LOGCATEGORY_DATABASE,
153*00b67f09SDavid van Moolenbroek DNS_LOGMODULE_SDB, ISC_LOG_ERROR,
154*00b67f09SDavid van Moolenbroek isc_msgcat, ISC_MSGSET_GENERAL,
155*00b67f09SDavid van Moolenbroek ISC_MSG_FAILED, "dns_sdb_putrr");
156*00b67f09SDavid van Moolenbroek return ISC_R_FAILURE;
157*00b67f09SDavid van Moolenbroek }
158*00b67f09SDavid van Moolenbroek ret = c->c_get(c, &key, &data, DB_NEXT_DUP);
159*00b67f09SDavid van Moolenbroek }
160*00b67f09SDavid van Moolenbroek
161*00b67f09SDavid van Moolenbroek c->c_close(c);
162*00b67f09SDavid van Moolenbroek return ISC_R_SUCCESS;
163*00b67f09SDavid van Moolenbroek }
164*00b67f09SDavid van Moolenbroek
165*00b67f09SDavid van Moolenbroek static isc_result_t
bdb_allnodes(const char * zone,void * dbdata,dns_sdballnodes_t * n)166*00b67f09SDavid van Moolenbroek bdb_allnodes(const char *zone, void *dbdata, dns_sdballnodes_t *n)
167*00b67f09SDavid van Moolenbroek {
168*00b67f09SDavid van Moolenbroek int ret;
169*00b67f09SDavid van Moolenbroek char *type, *rdata;
170*00b67f09SDavid van Moolenbroek dns_ttl_t ttl;
171*00b67f09SDavid van Moolenbroek isc_consttextregion_t ttltext;
172*00b67f09SDavid van Moolenbroek DBC *c;
173*00b67f09SDavid van Moolenbroek DBT key, data;
174*00b67f09SDavid van Moolenbroek
175*00b67f09SDavid van Moolenbroek UNUSED(zone);
176*00b67f09SDavid van Moolenbroek
177*00b67f09SDavid van Moolenbroek if ((ret = ((DB *)dbdata)->cursor((DB *)dbdata, NULL, &c, 0)) != 0) {
178*00b67f09SDavid van Moolenbroek isc_log_iwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
179*00b67f09SDavid van Moolenbroek DNS_LOGMODULE_SDB, ISC_LOG_ERROR,
180*00b67f09SDavid van Moolenbroek isc_msgcat, ISC_MSGSET_GENERAL,
181*00b67f09SDavid van Moolenbroek ISC_MSG_FAILED, "DB->cursor: %s",
182*00b67f09SDavid van Moolenbroek db_strerror(ret));
183*00b67f09SDavid van Moolenbroek return ISC_R_FAILURE;
184*00b67f09SDavid van Moolenbroek }
185*00b67f09SDavid van Moolenbroek
186*00b67f09SDavid van Moolenbroek memset(&key, 0, sizeof(DBT));
187*00b67f09SDavid van Moolenbroek memset(&data, 0, sizeof(DBT));
188*00b67f09SDavid van Moolenbroek
189*00b67f09SDavid van Moolenbroek while (c->c_get(c, &key, &data, DB_NEXT) == 0) {
190*00b67f09SDavid van Moolenbroek ((char *)key.data)[key.size] = 0;
191*00b67f09SDavid van Moolenbroek ((char *)data.data)[data.size] = 0;
192*00b67f09SDavid van Moolenbroek ttltext.base = strtok((char *)data.data, " ");
193*00b67f09SDavid van Moolenbroek ttltext.length = strlen(ttltext.base);
194*00b67f09SDavid van Moolenbroek dns_ttl_fromtext((isc_textregion_t *)&ttltext, &ttl);
195*00b67f09SDavid van Moolenbroek type = strtok(NULL, " ");
196*00b67f09SDavid van Moolenbroek rdata = type + strlen(type) + 1;
197*00b67f09SDavid van Moolenbroek
198*00b67f09SDavid van Moolenbroek if (dns_sdb_putnamedrr(n, key.data, type, ttl, rdata) !=
199*00b67f09SDavid van Moolenbroek ISC_R_SUCCESS) {
200*00b67f09SDavid van Moolenbroek isc_log_iwrite(dns_lctx,
201*00b67f09SDavid van Moolenbroek DNS_LOGCATEGORY_DATABASE,
202*00b67f09SDavid van Moolenbroek DNS_LOGMODULE_SDB, ISC_LOG_ERROR,
203*00b67f09SDavid van Moolenbroek isc_msgcat, ISC_MSGSET_GENERAL,
204*00b67f09SDavid van Moolenbroek ISC_MSG_FAILED, "dns_sdb_putnamedrr");
205*00b67f09SDavid van Moolenbroek return ISC_R_FAILURE;
206*00b67f09SDavid van Moolenbroek }
207*00b67f09SDavid van Moolenbroek
208*00b67f09SDavid van Moolenbroek }
209*00b67f09SDavid van Moolenbroek
210*00b67f09SDavid van Moolenbroek c->c_close(c);
211*00b67f09SDavid van Moolenbroek return ISC_R_SUCCESS;
212*00b67f09SDavid van Moolenbroek }
213*00b67f09SDavid van Moolenbroek
214*00b67f09SDavid van Moolenbroek static isc_result_t
bdb_destroy(const char * zone,void * unused,void ** dbdata)215*00b67f09SDavid van Moolenbroek bdb_destroy(const char *zone, void *unused, void **dbdata)
216*00b67f09SDavid van Moolenbroek {
217*00b67f09SDavid van Moolenbroek
218*00b67f09SDavid van Moolenbroek UNUSED(zone);
219*00b67f09SDavid van Moolenbroek UNUSED(unused);
220*00b67f09SDavid van Moolenbroek
221*00b67f09SDavid van Moolenbroek (*(DB **)dbdata)->close(*(DB **)dbdata, 0);
222*00b67f09SDavid van Moolenbroek
223*00b67f09SDavid van Moolenbroek return ISC_R_SUCCESS;
224*00b67f09SDavid van Moolenbroek }
225*00b67f09SDavid van Moolenbroek
226*00b67f09SDavid van Moolenbroek isc_result_t
bdb_init(void)227*00b67f09SDavid van Moolenbroek bdb_init(void)
228*00b67f09SDavid van Moolenbroek {
229*00b67f09SDavid van Moolenbroek static dns_sdbmethods_t bdb_methods = {
230*00b67f09SDavid van Moolenbroek bdb_lookup,
231*00b67f09SDavid van Moolenbroek NULL,
232*00b67f09SDavid van Moolenbroek bdb_allnodes,
233*00b67f09SDavid van Moolenbroek bdb_create,
234*00b67f09SDavid van Moolenbroek bdb_destroy,
235*00b67f09SDavid van Moolenbroek NULL /* lookup2 */
236*00b67f09SDavid van Moolenbroek };
237*00b67f09SDavid van Moolenbroek
238*00b67f09SDavid van Moolenbroek return dns_sdb_register(DRIVERNAME, &bdb_methods, NULL, 0, ns_g_mctx,
239*00b67f09SDavid van Moolenbroek &bdb_imp);
240*00b67f09SDavid van Moolenbroek }
241*00b67f09SDavid van Moolenbroek
242*00b67f09SDavid van Moolenbroek void
bdb_clear(void)243*00b67f09SDavid van Moolenbroek bdb_clear(void)
244*00b67f09SDavid van Moolenbroek {
245*00b67f09SDavid van Moolenbroek
246*00b67f09SDavid van Moolenbroek if (bdb_imp != NULL)
247*00b67f09SDavid van Moolenbroek dns_sdb_unregister(&bdb_imp);
248*00b67f09SDavid van Moolenbroek }
249