1*00b67f09SDavid van Moolenbroek /* $NetBSD: pgsqldb.c,v 1.4 2014/12/10 04:37:57 christos Exp $ */
2*00b67f09SDavid van Moolenbroek
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek * Copyright (C) 2004, 2007, 2011, 2014 Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek * Copyright (C) 2000, 2001 Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek *
7*00b67f09SDavid van Moolenbroek * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek *
11*00b67f09SDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek */
19*00b67f09SDavid van Moolenbroek
20*00b67f09SDavid van Moolenbroek /* Id: pgsqldb.c,v 1.17 2011/10/11 23:46:45 tbox Exp */
21*00b67f09SDavid van Moolenbroek
22*00b67f09SDavid van Moolenbroek #include <config.h>
23*00b67f09SDavid van Moolenbroek
24*00b67f09SDavid van Moolenbroek #include <stdio.h>
25*00b67f09SDavid van Moolenbroek #include <string.h>
26*00b67f09SDavid van Moolenbroek #include <stdlib.h>
27*00b67f09SDavid van Moolenbroek
28*00b67f09SDavid van Moolenbroek #include <pgsql/libpq-fe.h>
29*00b67f09SDavid van Moolenbroek
30*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
31*00b67f09SDavid van Moolenbroek #include <isc/print.h>
32*00b67f09SDavid van Moolenbroek #include <isc/result.h>
33*00b67f09SDavid van Moolenbroek #include <isc/util.h>
34*00b67f09SDavid van Moolenbroek
35*00b67f09SDavid van Moolenbroek #include <dns/sdb.h>
36*00b67f09SDavid van Moolenbroek #include <dns/result.h>
37*00b67f09SDavid van Moolenbroek
38*00b67f09SDavid van Moolenbroek #include <named/globals.h>
39*00b67f09SDavid van Moolenbroek
40*00b67f09SDavid van Moolenbroek #include "pgsqldb.h"
41*00b67f09SDavid van Moolenbroek
42*00b67f09SDavid van Moolenbroek /*
43*00b67f09SDavid van Moolenbroek * A simple database driver that interfaces to a PostgreSQL database. This
44*00b67f09SDavid van Moolenbroek * is not complete, and not designed for general use. It opens one
45*00b67f09SDavid van Moolenbroek * connection to the database per zone, which is inefficient. It also may
46*00b67f09SDavid van Moolenbroek * not handle quoting correctly.
47*00b67f09SDavid van Moolenbroek *
48*00b67f09SDavid van Moolenbroek * The table must contain the fields "name", "rdtype", and "rdata", and
49*00b67f09SDavid van Moolenbroek * is expected to contain a properly constructed zone. The program "zonetodb"
50*00b67f09SDavid van Moolenbroek * creates such a table.
51*00b67f09SDavid van Moolenbroek */
52*00b67f09SDavid van Moolenbroek
53*00b67f09SDavid van Moolenbroek static dns_sdbimplementation_t *pgsqldb = NULL;
54*00b67f09SDavid van Moolenbroek
55*00b67f09SDavid van Moolenbroek struct dbinfo {
56*00b67f09SDavid van Moolenbroek PGconn *conn;
57*00b67f09SDavid van Moolenbroek char *database;
58*00b67f09SDavid van Moolenbroek char *table;
59*00b67f09SDavid van Moolenbroek char *host;
60*00b67f09SDavid van Moolenbroek char *user;
61*00b67f09SDavid van Moolenbroek char *passwd;
62*00b67f09SDavid van Moolenbroek };
63*00b67f09SDavid van Moolenbroek
64*00b67f09SDavid van Moolenbroek static void
65*00b67f09SDavid van Moolenbroek pgsqldb_destroy(const char *zone, void *driverdata, void **dbdata);
66*00b67f09SDavid van Moolenbroek
67*00b67f09SDavid van Moolenbroek /*
68*00b67f09SDavid van Moolenbroek * Canonicalize a string before writing it to the database.
69*00b67f09SDavid van Moolenbroek * "dest" must be an array of at least size 2*strlen(source) + 1.
70*00b67f09SDavid van Moolenbroek */
71*00b67f09SDavid van Moolenbroek static void
quotestring(const char * source,char * dest)72*00b67f09SDavid van Moolenbroek quotestring(const char *source, char *dest) {
73*00b67f09SDavid van Moolenbroek while (*source != 0) {
74*00b67f09SDavid van Moolenbroek if (*source == '\'')
75*00b67f09SDavid van Moolenbroek *dest++ = '\'';
76*00b67f09SDavid van Moolenbroek /* SQL doesn't treat \ as special, but PostgreSQL does */
77*00b67f09SDavid van Moolenbroek else if (*source == '\\')
78*00b67f09SDavid van Moolenbroek *dest++ = '\\';
79*00b67f09SDavid van Moolenbroek *dest++ = *source++;
80*00b67f09SDavid van Moolenbroek }
81*00b67f09SDavid van Moolenbroek *dest++ = 0;
82*00b67f09SDavid van Moolenbroek }
83*00b67f09SDavid van Moolenbroek
84*00b67f09SDavid van Moolenbroek /*
85*00b67f09SDavid van Moolenbroek * Connect to the database.
86*00b67f09SDavid van Moolenbroek */
87*00b67f09SDavid van Moolenbroek static isc_result_t
db_connect(struct dbinfo * dbi)88*00b67f09SDavid van Moolenbroek db_connect(struct dbinfo *dbi) {
89*00b67f09SDavid van Moolenbroek dbi->conn = PQsetdbLogin(dbi->host, NULL, NULL, NULL, dbi->database,
90*00b67f09SDavid van Moolenbroek dbi->user, dbi->passwd);
91*00b67f09SDavid van Moolenbroek
92*00b67f09SDavid van Moolenbroek if (PQstatus(dbi->conn) == CONNECTION_OK)
93*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
94*00b67f09SDavid van Moolenbroek else
95*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
96*00b67f09SDavid van Moolenbroek }
97*00b67f09SDavid van Moolenbroek
98*00b67f09SDavid van Moolenbroek /*
99*00b67f09SDavid van Moolenbroek * Check to see if the connection is still valid. If not, attempt to
100*00b67f09SDavid van Moolenbroek * reconnect.
101*00b67f09SDavid van Moolenbroek */
102*00b67f09SDavid van Moolenbroek static isc_result_t
maybe_reconnect(struct dbinfo * dbi)103*00b67f09SDavid van Moolenbroek maybe_reconnect(struct dbinfo *dbi) {
104*00b67f09SDavid van Moolenbroek if (PQstatus(dbi->conn) == CONNECTION_OK)
105*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
106*00b67f09SDavid van Moolenbroek
107*00b67f09SDavid van Moolenbroek return (db_connect(dbi));
108*00b67f09SDavid van Moolenbroek }
109*00b67f09SDavid van Moolenbroek
110*00b67f09SDavid van Moolenbroek /*
111*00b67f09SDavid van Moolenbroek * This database operates on absolute names.
112*00b67f09SDavid van Moolenbroek *
113*00b67f09SDavid van Moolenbroek * Queries are converted into SQL queries and issued synchronously. Errors
114*00b67f09SDavid van Moolenbroek * are handled really badly.
115*00b67f09SDavid van Moolenbroek */
116*00b67f09SDavid van Moolenbroek #ifdef DNS_CLIENTINFO_VERSION
117*00b67f09SDavid van Moolenbroek static isc_result_t
pgsqldb_lookup(const char * zone,const char * name,void * dbdata,dns_sdblookup_t * lookup,dns_clientinfomethods_t * methods,dns_clientinfo_t * clientinfo)118*00b67f09SDavid van Moolenbroek pgsqldb_lookup(const char *zone, const char *name, void *dbdata,
119*00b67f09SDavid van Moolenbroek dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods,
120*00b67f09SDavid van Moolenbroek dns_clientinfo_t *clientinfo)
121*00b67f09SDavid van Moolenbroek #else
122*00b67f09SDavid van Moolenbroek static isc_result_t
123*00b67f09SDavid van Moolenbroek pgsqldb_lookup(const char *zone, const char *name, void *dbdata,
124*00b67f09SDavid van Moolenbroek dns_sdblookup_t *lookup)
125*00b67f09SDavid van Moolenbroek #endif /* DNS_CLIENTINFO_VERSION */
126*00b67f09SDavid van Moolenbroek {
127*00b67f09SDavid van Moolenbroek isc_result_t result;
128*00b67f09SDavid van Moolenbroek struct dbinfo *dbi = dbdata;
129*00b67f09SDavid van Moolenbroek PGresult *res;
130*00b67f09SDavid van Moolenbroek char str[1500];
131*00b67f09SDavid van Moolenbroek char *canonname;
132*00b67f09SDavid van Moolenbroek int i;
133*00b67f09SDavid van Moolenbroek
134*00b67f09SDavid van Moolenbroek UNUSED(zone);
135*00b67f09SDavid van Moolenbroek #ifdef DNS_CLIENTINFO_VERSION
136*00b67f09SDavid van Moolenbroek UNUSED(methods);
137*00b67f09SDavid van Moolenbroek UNUSED(clientinfo);
138*00b67f09SDavid van Moolenbroek #endif /* DNS_CLIENTINFO_VERSION */
139*00b67f09SDavid van Moolenbroek
140*00b67f09SDavid van Moolenbroek canonname = isc_mem_get(ns_g_mctx, strlen(name) * 2 + 1);
141*00b67f09SDavid van Moolenbroek if (canonname == NULL)
142*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
143*00b67f09SDavid van Moolenbroek quotestring(name, canonname);
144*00b67f09SDavid van Moolenbroek snprintf(str, sizeof(str),
145*00b67f09SDavid van Moolenbroek "SELECT TTL,RDTYPE,RDATA FROM \"%s\" WHERE "
146*00b67f09SDavid van Moolenbroek "lower(NAME) = lower('%s')", dbi->table, canonname);
147*00b67f09SDavid van Moolenbroek isc_mem_put(ns_g_mctx, canonname, strlen(name) * 2 + 1);
148*00b67f09SDavid van Moolenbroek
149*00b67f09SDavid van Moolenbroek result = maybe_reconnect(dbi);
150*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
151*00b67f09SDavid van Moolenbroek return (result);
152*00b67f09SDavid van Moolenbroek
153*00b67f09SDavid van Moolenbroek res = PQexec(dbi->conn, str);
154*00b67f09SDavid van Moolenbroek if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) {
155*00b67f09SDavid van Moolenbroek PQclear(res);
156*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
157*00b67f09SDavid van Moolenbroek }
158*00b67f09SDavid van Moolenbroek if (PQntuples(res) == 0) {
159*00b67f09SDavid van Moolenbroek PQclear(res);
160*00b67f09SDavid van Moolenbroek return (ISC_R_NOTFOUND);
161*00b67f09SDavid van Moolenbroek }
162*00b67f09SDavid van Moolenbroek
163*00b67f09SDavid van Moolenbroek for (i = 0; i < PQntuples(res); i++) {
164*00b67f09SDavid van Moolenbroek char *ttlstr = PQgetvalue(res, i, 0);
165*00b67f09SDavid van Moolenbroek char *type = PQgetvalue(res, i, 1);
166*00b67f09SDavid van Moolenbroek char *data = PQgetvalue(res, i, 2);
167*00b67f09SDavid van Moolenbroek dns_ttl_t ttl;
168*00b67f09SDavid van Moolenbroek char *endp;
169*00b67f09SDavid van Moolenbroek ttl = strtol(ttlstr, &endp, 10);
170*00b67f09SDavid van Moolenbroek if (*endp != '\0') {
171*00b67f09SDavid van Moolenbroek PQclear(res);
172*00b67f09SDavid van Moolenbroek return (DNS_R_BADTTL);
173*00b67f09SDavid van Moolenbroek }
174*00b67f09SDavid van Moolenbroek result = dns_sdb_putrr(lookup, type, ttl, data);
175*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
176*00b67f09SDavid van Moolenbroek PQclear(res);
177*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
178*00b67f09SDavid van Moolenbroek }
179*00b67f09SDavid van Moolenbroek }
180*00b67f09SDavid van Moolenbroek
181*00b67f09SDavid van Moolenbroek PQclear(res);
182*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
183*00b67f09SDavid van Moolenbroek }
184*00b67f09SDavid van Moolenbroek
185*00b67f09SDavid van Moolenbroek /*
186*00b67f09SDavid van Moolenbroek * Issue an SQL query to return all nodes in the database and fill the
187*00b67f09SDavid van Moolenbroek * allnodes structure.
188*00b67f09SDavid van Moolenbroek */
189*00b67f09SDavid van Moolenbroek static isc_result_t
pgsqldb_allnodes(const char * zone,void * dbdata,dns_sdballnodes_t * allnodes)190*00b67f09SDavid van Moolenbroek pgsqldb_allnodes(const char *zone, void *dbdata, dns_sdballnodes_t *allnodes) {
191*00b67f09SDavid van Moolenbroek struct dbinfo *dbi = dbdata;
192*00b67f09SDavid van Moolenbroek PGresult *res;
193*00b67f09SDavid van Moolenbroek isc_result_t result;
194*00b67f09SDavid van Moolenbroek char str[1500];
195*00b67f09SDavid van Moolenbroek int i;
196*00b67f09SDavid van Moolenbroek
197*00b67f09SDavid van Moolenbroek UNUSED(zone);
198*00b67f09SDavid van Moolenbroek
199*00b67f09SDavid van Moolenbroek snprintf(str, sizeof(str),
200*00b67f09SDavid van Moolenbroek "SELECT TTL,NAME,RDTYPE,RDATA FROM \"%s\" ORDER BY NAME",
201*00b67f09SDavid van Moolenbroek dbi->table);
202*00b67f09SDavid van Moolenbroek
203*00b67f09SDavid van Moolenbroek result = maybe_reconnect(dbi);
204*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
205*00b67f09SDavid van Moolenbroek return (result);
206*00b67f09SDavid van Moolenbroek
207*00b67f09SDavid van Moolenbroek res = PQexec(dbi->conn, str);
208*00b67f09SDavid van Moolenbroek if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ) {
209*00b67f09SDavid van Moolenbroek PQclear(res);
210*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
211*00b67f09SDavid van Moolenbroek }
212*00b67f09SDavid van Moolenbroek if (PQntuples(res) == 0) {
213*00b67f09SDavid van Moolenbroek PQclear(res);
214*00b67f09SDavid van Moolenbroek return (ISC_R_NOTFOUND);
215*00b67f09SDavid van Moolenbroek }
216*00b67f09SDavid van Moolenbroek
217*00b67f09SDavid van Moolenbroek for (i = 0; i < PQntuples(res); i++) {
218*00b67f09SDavid van Moolenbroek char *ttlstr = PQgetvalue(res, i, 0);
219*00b67f09SDavid van Moolenbroek char *name = PQgetvalue(res, i, 1);
220*00b67f09SDavid van Moolenbroek char *type = PQgetvalue(res, i, 2);
221*00b67f09SDavid van Moolenbroek char *data = PQgetvalue(res, i, 3);
222*00b67f09SDavid van Moolenbroek dns_ttl_t ttl;
223*00b67f09SDavid van Moolenbroek char *endp;
224*00b67f09SDavid van Moolenbroek ttl = strtol(ttlstr, &endp, 10);
225*00b67f09SDavid van Moolenbroek if (*endp != '\0') {
226*00b67f09SDavid van Moolenbroek PQclear(res);
227*00b67f09SDavid van Moolenbroek return (DNS_R_BADTTL);
228*00b67f09SDavid van Moolenbroek }
229*00b67f09SDavid van Moolenbroek result = dns_sdb_putnamedrr(allnodes, name, type, ttl, data);
230*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS) {
231*00b67f09SDavid van Moolenbroek PQclear(res);
232*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
233*00b67f09SDavid van Moolenbroek }
234*00b67f09SDavid van Moolenbroek }
235*00b67f09SDavid van Moolenbroek
236*00b67f09SDavid van Moolenbroek PQclear(res);
237*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
238*00b67f09SDavid van Moolenbroek }
239*00b67f09SDavid van Moolenbroek
240*00b67f09SDavid van Moolenbroek /*
241*00b67f09SDavid van Moolenbroek * Create a connection to the database and save any necessary information
242*00b67f09SDavid van Moolenbroek * in dbdata.
243*00b67f09SDavid van Moolenbroek *
244*00b67f09SDavid van Moolenbroek * argv[0] is the name of the database
245*00b67f09SDavid van Moolenbroek * argv[1] is the name of the table
246*00b67f09SDavid van Moolenbroek * argv[2] (if present) is the name of the host to connect to
247*00b67f09SDavid van Moolenbroek * argv[3] (if present) is the name of the user to connect as
248*00b67f09SDavid van Moolenbroek * argv[4] (if present) is the name of the password to connect with
249*00b67f09SDavid van Moolenbroek */
250*00b67f09SDavid van Moolenbroek static isc_result_t
pgsqldb_create(const char * zone,int argc,char ** argv,void * driverdata,void ** dbdata)251*00b67f09SDavid van Moolenbroek pgsqldb_create(const char *zone, int argc, char **argv,
252*00b67f09SDavid van Moolenbroek void *driverdata, void **dbdata)
253*00b67f09SDavid van Moolenbroek {
254*00b67f09SDavid van Moolenbroek struct dbinfo *dbi;
255*00b67f09SDavid van Moolenbroek isc_result_t result;
256*00b67f09SDavid van Moolenbroek
257*00b67f09SDavid van Moolenbroek UNUSED(zone);
258*00b67f09SDavid van Moolenbroek UNUSED(driverdata);
259*00b67f09SDavid van Moolenbroek
260*00b67f09SDavid van Moolenbroek if (argc < 2)
261*00b67f09SDavid van Moolenbroek return (ISC_R_FAILURE);
262*00b67f09SDavid van Moolenbroek
263*00b67f09SDavid van Moolenbroek dbi = isc_mem_get(ns_g_mctx, sizeof(struct dbinfo));
264*00b67f09SDavid van Moolenbroek if (dbi == NULL)
265*00b67f09SDavid van Moolenbroek return (ISC_R_NOMEMORY);
266*00b67f09SDavid van Moolenbroek dbi->conn = NULL;
267*00b67f09SDavid van Moolenbroek dbi->database = NULL;
268*00b67f09SDavid van Moolenbroek dbi->table = NULL;
269*00b67f09SDavid van Moolenbroek dbi->host = NULL;
270*00b67f09SDavid van Moolenbroek dbi->user = NULL;
271*00b67f09SDavid van Moolenbroek dbi->passwd = NULL;
272*00b67f09SDavid van Moolenbroek
273*00b67f09SDavid van Moolenbroek #define STRDUP_OR_FAIL(target, source) \
274*00b67f09SDavid van Moolenbroek do { \
275*00b67f09SDavid van Moolenbroek target = isc_mem_strdup(ns_g_mctx, source); \
276*00b67f09SDavid van Moolenbroek if (target == NULL) { \
277*00b67f09SDavid van Moolenbroek result = ISC_R_NOMEMORY; \
278*00b67f09SDavid van Moolenbroek goto cleanup; \
279*00b67f09SDavid van Moolenbroek } \
280*00b67f09SDavid van Moolenbroek } while (/*CONSTCOND*/0);
281*00b67f09SDavid van Moolenbroek
282*00b67f09SDavid van Moolenbroek STRDUP_OR_FAIL(dbi->database, argv[0]);
283*00b67f09SDavid van Moolenbroek STRDUP_OR_FAIL(dbi->table, argv[1]);
284*00b67f09SDavid van Moolenbroek if (argc > 2)
285*00b67f09SDavid van Moolenbroek STRDUP_OR_FAIL(dbi->host, argv[2]);
286*00b67f09SDavid van Moolenbroek if (argc > 3)
287*00b67f09SDavid van Moolenbroek STRDUP_OR_FAIL(dbi->user, argv[3]);
288*00b67f09SDavid van Moolenbroek if (argc > 4)
289*00b67f09SDavid van Moolenbroek STRDUP_OR_FAIL(dbi->passwd, argv[4]);
290*00b67f09SDavid van Moolenbroek
291*00b67f09SDavid van Moolenbroek result = db_connect(dbi);
292*00b67f09SDavid van Moolenbroek if (result != ISC_R_SUCCESS)
293*00b67f09SDavid van Moolenbroek goto cleanup;
294*00b67f09SDavid van Moolenbroek
295*00b67f09SDavid van Moolenbroek *dbdata = dbi;
296*00b67f09SDavid van Moolenbroek return (ISC_R_SUCCESS);
297*00b67f09SDavid van Moolenbroek
298*00b67f09SDavid van Moolenbroek cleanup:
299*00b67f09SDavid van Moolenbroek pgsqldb_destroy(zone, driverdata, (void **)&dbi);
300*00b67f09SDavid van Moolenbroek return (result);
301*00b67f09SDavid van Moolenbroek }
302*00b67f09SDavid van Moolenbroek
303*00b67f09SDavid van Moolenbroek /*
304*00b67f09SDavid van Moolenbroek * Close the connection to the database.
305*00b67f09SDavid van Moolenbroek */
306*00b67f09SDavid van Moolenbroek static void
pgsqldb_destroy(const char * zone,void * driverdata,void ** dbdata)307*00b67f09SDavid van Moolenbroek pgsqldb_destroy(const char *zone, void *driverdata, void **dbdata) {
308*00b67f09SDavid van Moolenbroek struct dbinfo *dbi = *dbdata;
309*00b67f09SDavid van Moolenbroek
310*00b67f09SDavid van Moolenbroek UNUSED(zone);
311*00b67f09SDavid van Moolenbroek UNUSED(driverdata);
312*00b67f09SDavid van Moolenbroek
313*00b67f09SDavid van Moolenbroek if (dbi->conn != NULL)
314*00b67f09SDavid van Moolenbroek PQfinish(dbi->conn);
315*00b67f09SDavid van Moolenbroek if (dbi->database != NULL)
316*00b67f09SDavid van Moolenbroek isc_mem_free(ns_g_mctx, dbi->database);
317*00b67f09SDavid van Moolenbroek if (dbi->table != NULL)
318*00b67f09SDavid van Moolenbroek isc_mem_free(ns_g_mctx, dbi->table);
319*00b67f09SDavid van Moolenbroek if (dbi->host != NULL)
320*00b67f09SDavid van Moolenbroek isc_mem_free(ns_g_mctx, dbi->host);
321*00b67f09SDavid van Moolenbroek if (dbi->user != NULL)
322*00b67f09SDavid van Moolenbroek isc_mem_free(ns_g_mctx, dbi->user);
323*00b67f09SDavid van Moolenbroek if (dbi->passwd != NULL)
324*00b67f09SDavid van Moolenbroek isc_mem_free(ns_g_mctx, dbi->passwd);
325*00b67f09SDavid van Moolenbroek if (dbi->database != NULL)
326*00b67f09SDavid van Moolenbroek isc_mem_free(ns_g_mctx, dbi->database);
327*00b67f09SDavid van Moolenbroek isc_mem_put(ns_g_mctx, dbi, sizeof(struct dbinfo));
328*00b67f09SDavid van Moolenbroek }
329*00b67f09SDavid van Moolenbroek
330*00b67f09SDavid van Moolenbroek /*
331*00b67f09SDavid van Moolenbroek * Since the SQL database corresponds to a zone, the authority data should
332*00b67f09SDavid van Moolenbroek * be returned by the lookup() function. Therefore the authority() function
333*00b67f09SDavid van Moolenbroek * is NULL.
334*00b67f09SDavid van Moolenbroek */
335*00b67f09SDavid van Moolenbroek static dns_sdbmethods_t pgsqldb_methods = {
336*00b67f09SDavid van Moolenbroek pgsqldb_lookup,
337*00b67f09SDavid van Moolenbroek NULL, /* authority */
338*00b67f09SDavid van Moolenbroek pgsqldb_allnodes,
339*00b67f09SDavid van Moolenbroek pgsqldb_create,
340*00b67f09SDavid van Moolenbroek pgsqldb_destroy,
341*00b67f09SDavid van Moolenbroek NULL /* lookup2 */
342*00b67f09SDavid van Moolenbroek };
343*00b67f09SDavid van Moolenbroek
344*00b67f09SDavid van Moolenbroek /*
345*00b67f09SDavid van Moolenbroek * Wrapper around dns_sdb_register().
346*00b67f09SDavid van Moolenbroek */
347*00b67f09SDavid van Moolenbroek isc_result_t
pgsqldb_init(void)348*00b67f09SDavid van Moolenbroek pgsqldb_init(void) {
349*00b67f09SDavid van Moolenbroek unsigned int flags;
350*00b67f09SDavid van Moolenbroek flags = 0;
351*00b67f09SDavid van Moolenbroek return (dns_sdb_register("pgsql", &pgsqldb_methods, NULL, flags,
352*00b67f09SDavid van Moolenbroek ns_g_mctx, &pgsqldb));
353*00b67f09SDavid van Moolenbroek }
354*00b67f09SDavid van Moolenbroek
355*00b67f09SDavid van Moolenbroek /*
356*00b67f09SDavid van Moolenbroek * Wrapper around dns_sdb_unregister().
357*00b67f09SDavid van Moolenbroek */
358*00b67f09SDavid van Moolenbroek void
pgsqldb_clear(void)359*00b67f09SDavid van Moolenbroek pgsqldb_clear(void) {
360*00b67f09SDavid van Moolenbroek if (pgsqldb != NULL)
361*00b67f09SDavid van Moolenbroek dns_sdb_unregister(&pgsqldb);
362*00b67f09SDavid van Moolenbroek }
363