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