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