|
Packit |
5ce601 |
/*
|
|
Packit |
5ce601 |
* Copyright (C) 2002 Nuno M. Rodrigues.
|
|
Packit |
5ce601 |
*
|
|
Packit |
5ce601 |
* Permission to use, copy, modify, and distribute this software for any
|
|
Packit |
5ce601 |
* purpose with or without fee is hereby granted, provided that the above
|
|
Packit |
5ce601 |
* copyright notice and this permission notice appear in all copies.
|
|
Packit |
5ce601 |
*
|
|
Packit |
5ce601 |
* THE SOFTWARE IS PROVIDED "AS IS" AND NUNO M. RODRIGUES
|
|
Packit |
5ce601 |
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
|
Packit |
5ce601 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
|
Packit |
5ce601 |
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
Packit |
5ce601 |
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
|
|
Packit |
5ce601 |
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
|
Packit |
5ce601 |
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
|
Packit |
5ce601 |
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
Packit |
5ce601 |
*/
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
/*
|
|
Packit |
5ce601 |
* BIND 9.1.x simple database driver
|
|
Packit |
5ce601 |
* implementation, using Berkeley DB.
|
|
Packit |
5ce601 |
*/
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
#include <errno.h>
|
|
Packit |
5ce601 |
#include <stdio.h>
|
|
Packit |
5ce601 |
#include <string.h>
|
|
Packit |
5ce601 |
#include <stdlib.h>
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
#include <isc/file.h>
|
|
Packit |
5ce601 |
#include <isc/log.h>
|
|
Packit |
5ce601 |
#include <isc/lib.h>
|
|
Packit |
5ce601 |
#include <isc/mem.h>
|
|
Packit |
5ce601 |
#include <isc/msgs.h>
|
|
Packit |
5ce601 |
#include <isc/msgcat.h>
|
|
Packit |
5ce601 |
#include <isc/region.h>
|
|
Packit |
5ce601 |
#include <isc/result.h>
|
|
Packit |
5ce601 |
#include <isc/types.h>
|
|
Packit |
5ce601 |
#include <isc/util.h>
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
#include <dns/sdb.h>
|
|
Packit |
5ce601 |
#include <dns/log.h>
|
|
Packit |
5ce601 |
#include <dns/lib.h>
|
|
Packit |
5ce601 |
#include <dns/ttl.h>
|
|
Packit |
5ce601 |
|
|
Packit Service |
4060ac |
#include "bdb.h"
|
|
Packit |
5ce601 |
#include <named/globals.h>
|
|
Packit |
5ce601 |
#include <named/config.h>
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
#include <db.h>
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
#define DRIVERNAME "bdb"
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
static dns_sdbimplementation_t *bdb_imp;
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
static isc_result_t
|
|
Packit |
5ce601 |
bdb_create(const char *zone, int argc, char **argv,
|
|
Packit |
5ce601 |
void *unused, void **dbdata)
|
|
Packit |
5ce601 |
{
|
|
Packit |
5ce601 |
int ret;
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
UNUSED(zone);
|
|
Packit |
5ce601 |
UNUSED(unused);
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
if (argc < 1)
|
|
Packit |
5ce601 |
return ISC_R_FAILURE; /* database path must be given */
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
if (db_create((DB **)dbdata, NULL, 0) != 0) {
|
|
Packit |
5ce601 |
/*
|
|
Packit |
5ce601 |
* XXX Should use dns_msgcat et al
|
|
Packit |
5ce601 |
* but seems to be unavailable.
|
|
Packit |
5ce601 |
*/
|
|
Packit |
5ce601 |
isc_log_iwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
|
|
Packit |
5ce601 |
DNS_LOGMODULE_SDB, ISC_LOG_CRITICAL, isc_msgcat,
|
|
Packit |
5ce601 |
ISC_MSGSET_GENERAL, ISC_MSG_FATALERROR,
|
|
Packit |
5ce601 |
"db_create");
|
|
Packit |
5ce601 |
return ISC_R_FAILURE;
|
|
Packit |
5ce601 |
}
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
if (isc_file_exists(*argv) != true) {
|
|
Packit |
5ce601 |
isc_log_iwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
|
|
Packit |
5ce601 |
DNS_LOGMODULE_SDB, ISC_LOG_CRITICAL, isc_msgcat,
|
|
Packit |
5ce601 |
ISC_MSGSET_GENERAL, ISC_MSG_FATALERROR,
|
|
Packit |
5ce601 |
"isc_file_exists: %s", *argv);
|
|
Packit |
5ce601 |
return ISC_R_FAILURE;
|
|
Packit |
5ce601 |
}
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
if ((ret = (*(DB **)dbdata)->open(*(DB **)dbdata, *argv, NULL, DB_HASH,
|
|
Packit |
5ce601 |
DB_RDONLY, 0)) != 0) {
|
|
Packit |
5ce601 |
isc_log_iwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
|
|
Packit |
5ce601 |
DNS_LOGMODULE_SDB, ISC_LOG_CRITICAL,
|
|
Packit |
5ce601 |
isc_msgcat, ISC_MSGSET_GENERAL,
|
|
Packit |
5ce601 |
ISC_MSG_FATALERROR, "DB->open: %s",
|
|
Packit |
5ce601 |
db_strerror(ret));
|
|
Packit |
5ce601 |
return ISC_R_FAILURE;
|
|
Packit |
5ce601 |
}
|
|
Packit |
5ce601 |
return ISC_R_SUCCESS;
|
|
Packit |
5ce601 |
}
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
static isc_result_t
|
|
Packit |
5ce601 |
#ifdef DNS_CLIENTINFO_VERSION
|
|
Packit |
5ce601 |
bdb_lookup(const char *zone, const char *name, void *dbdata,
|
|
Packit |
5ce601 |
dns_sdblookup_t *l, dns_clientinfomethods_t *methods,
|
|
Packit |
5ce601 |
dns_clientinfo_t *clientinfo)
|
|
Packit |
5ce601 |
#else
|
|
Packit |
5ce601 |
bdb_lookup(const char *zone, const char *name, void *dbdata,
|
|
Packit |
5ce601 |
dns_sdblookup_t *l)
|
|
Packit |
5ce601 |
#endif /* DNS_CLIENTINFO_VERSION */
|
|
Packit |
5ce601 |
{
|
|
Packit |
5ce601 |
int ret;
|
|
Packit |
5ce601 |
char *type, *rdata;
|
|
Packit |
5ce601 |
dns_ttl_t ttl;
|
|
Packit |
5ce601 |
isc_consttextregion_t ttltext;
|
|
Packit |
5ce601 |
DBC *c;
|
|
Packit |
5ce601 |
DBT key, data;
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
UNUSED(zone);
|
|
Packit |
5ce601 |
#ifdef DNS_CLIENTINFO_VERSION
|
|
Packit |
5ce601 |
UNUSED(methods);
|
|
Packit |
5ce601 |
UNUSED(clientinfo);
|
|
Packit |
5ce601 |
#endif /* DNS_CLIENTINFO_VERSION */
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
if ((ret = ((DB *)dbdata)->cursor((DB *)dbdata, NULL, &c, 0)) != 0) {
|
|
Packit |
5ce601 |
isc_log_iwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
|
|
Packit |
5ce601 |
DNS_LOGMODULE_SDB, ISC_LOG_ERROR,
|
|
Packit |
5ce601 |
isc_msgcat, ISC_MSGSET_GENERAL,
|
|
Packit |
5ce601 |
ISC_MSG_FAILED, "DB->cursor: %s",
|
|
Packit |
5ce601 |
db_strerror(ret));
|
|
Packit |
5ce601 |
return ISC_R_FAILURE;
|
|
Packit |
5ce601 |
}
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
memset(&key, 0, sizeof(DBT));
|
|
Packit |
5ce601 |
memset(&data, 0, sizeof(DBT));
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
(const char *)key.data = name;
|
|
Packit |
5ce601 |
key.size = strlen(name);
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
ret = c->c_get(c, &key, &data, DB_SET);
|
|
Packit |
5ce601 |
while (ret == 0) {
|
|
Packit |
5ce601 |
((char *)key.data)[key.size] = 0;
|
|
Packit |
5ce601 |
((char *)data.data)[data.size] = 0;
|
|
Packit |
5ce601 |
ttltext.base = strtok((char *)data.data, " ");
|
|
Packit |
5ce601 |
ttltext.length = strlen(ttltext.base);
|
|
Packit |
5ce601 |
dns_ttl_fromtext((isc_textregion_t *)&ttltext, &ttl);
|
|
Packit |
5ce601 |
type = strtok(NULL, " ");
|
|
Packit |
5ce601 |
rdata = type + strlen(type) + 1;
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
if (dns_sdb_putrr(l, type, ttl, rdata) != ISC_R_SUCCESS) {
|
|
Packit |
5ce601 |
isc_log_iwrite(dns_lctx,
|
|
Packit |
5ce601 |
DNS_LOGCATEGORY_DATABASE,
|
|
Packit |
5ce601 |
DNS_LOGMODULE_SDB, ISC_LOG_ERROR,
|
|
Packit |
5ce601 |
isc_msgcat, ISC_MSGSET_GENERAL,
|
|
Packit |
5ce601 |
ISC_MSG_FAILED, "dns_sdb_putrr");
|
|
Packit |
5ce601 |
return ISC_R_FAILURE;
|
|
Packit |
5ce601 |
}
|
|
Packit |
5ce601 |
ret = c->c_get(c, &key, &data, DB_NEXT_DUP);
|
|
Packit |
5ce601 |
}
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
c->c_close(c);
|
|
Packit |
5ce601 |
return ISC_R_SUCCESS;
|
|
Packit |
5ce601 |
}
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
static isc_result_t
|
|
Packit |
5ce601 |
bdb_allnodes(const char *zone, void *dbdata, dns_sdballnodes_t *n)
|
|
Packit |
5ce601 |
{
|
|
Packit |
5ce601 |
int ret;
|
|
Packit |
5ce601 |
char *type, *rdata;
|
|
Packit |
5ce601 |
dns_ttl_t ttl;
|
|
Packit |
5ce601 |
isc_consttextregion_t ttltext;
|
|
Packit |
5ce601 |
DBC *c;
|
|
Packit |
5ce601 |
DBT key, data;
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
UNUSED(zone);
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
if ((ret = ((DB *)dbdata)->cursor((DB *)dbdata, NULL, &c, 0)) != 0) {
|
|
Packit |
5ce601 |
isc_log_iwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE,
|
|
Packit |
5ce601 |
DNS_LOGMODULE_SDB, ISC_LOG_ERROR,
|
|
Packit |
5ce601 |
isc_msgcat, ISC_MSGSET_GENERAL,
|
|
Packit |
5ce601 |
ISC_MSG_FAILED, "DB->cursor: %s",
|
|
Packit |
5ce601 |
db_strerror(ret));
|
|
Packit |
5ce601 |
return ISC_R_FAILURE;
|
|
Packit |
5ce601 |
}
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
memset(&key, 0, sizeof(DBT));
|
|
Packit |
5ce601 |
memset(&data, 0, sizeof(DBT));
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
while (c->c_get(c, &key, &data, DB_NEXT) == 0) {
|
|
Packit |
5ce601 |
((char *)key.data)[key.size] = 0;
|
|
Packit |
5ce601 |
((char *)data.data)[data.size] = 0;
|
|
Packit |
5ce601 |
ttltext.base = strtok((char *)data.data, " ");
|
|
Packit |
5ce601 |
ttltext.length = strlen(ttltext.base);
|
|
Packit |
5ce601 |
dns_ttl_fromtext((isc_textregion_t *)&ttltext, &ttl);
|
|
Packit |
5ce601 |
type = strtok(NULL, " ");
|
|
Packit |
5ce601 |
rdata = type + strlen(type) + 1;
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
if (dns_sdb_putnamedrr(n, key.data, type, ttl, rdata) !=
|
|
Packit |
5ce601 |
ISC_R_SUCCESS) {
|
|
Packit |
5ce601 |
isc_log_iwrite(dns_lctx,
|
|
Packit |
5ce601 |
DNS_LOGCATEGORY_DATABASE,
|
|
Packit |
5ce601 |
DNS_LOGMODULE_SDB, ISC_LOG_ERROR,
|
|
Packit |
5ce601 |
isc_msgcat, ISC_MSGSET_GENERAL,
|
|
Packit |
5ce601 |
ISC_MSG_FAILED, "dns_sdb_putnamedrr");
|
|
Packit |
5ce601 |
return ISC_R_FAILURE;
|
|
Packit |
5ce601 |
}
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
}
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
c->c_close(c);
|
|
Packit |
5ce601 |
return ISC_R_SUCCESS;
|
|
Packit |
5ce601 |
}
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
static isc_result_t
|
|
Packit |
5ce601 |
bdb_destroy(const char *zone, void *unused, void **dbdata)
|
|
Packit |
5ce601 |
{
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
UNUSED(zone);
|
|
Packit |
5ce601 |
UNUSED(unused);
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
(*(DB **)dbdata)->close(*(DB **)dbdata, 0);
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
return ISC_R_SUCCESS;
|
|
Packit |
5ce601 |
}
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
isc_result_t
|
|
Packit |
5ce601 |
bdb_init(void)
|
|
Packit |
5ce601 |
{
|
|
Packit |
5ce601 |
static dns_sdbmethods_t bdb_methods = {
|
|
Packit |
5ce601 |
bdb_lookup,
|
|
Packit |
5ce601 |
NULL,
|
|
Packit |
5ce601 |
bdb_allnodes,
|
|
Packit |
5ce601 |
bdb_create,
|
|
Packit |
5ce601 |
bdb_destroy,
|
|
Packit |
5ce601 |
NULL /* lookup2 */
|
|
Packit |
5ce601 |
};
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
return dns_sdb_register(DRIVERNAME, &bdb_methods, NULL, 0, ns_g_mctx,
|
|
Packit |
5ce601 |
&bdb_imp);
|
|
Packit |
5ce601 |
}
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
void
|
|
Packit |
5ce601 |
bdb_clear(void)
|
|
Packit |
5ce601 |
{
|
|
Packit |
5ce601 |
|
|
Packit |
5ce601 |
if (bdb_imp != NULL)
|
|
Packit |
5ce601 |
dns_sdb_unregister(&bdb_imp);
|
|
Packit |
5ce601 |
}
|