xref: /minix3/external/bsd/bind/dist/contrib/sdb/bdb/bdb.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
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