/* * This database operates on absolute names. * * Queries are converted into SQL queries and issued synchronously. Errors * are handled really badly. */ static isc_result_t pgsqldb_lookup(const char *zone, const char *name, void *dbdata, dns_sdblookup_t *lookup) { isc_result_t result; struct dbinfo *dbi = dbdata; PGresult *res; char str[1500]; char *canonname; int i; UNUSED(zone); canonname = isc_mem_get(ns_g_mctx, strlen(name) * 2 + 1); if (canonname == NULL) return (ISC_R_NOMEMORY); quotestring(name, canonname); snprintf(str, sizeof(str), "SELECT TTL,RDTYPE,RDATA FROM \"%s\" WHERE " "lower(NAME) = lower('%s')", dbi->table, canonname); isc_mem_put(ns_g_mctx, canonname, strlen(name) * 2 + 1); result = maybe_reconnect(dbi); if (result != ISC_R_SUCCESS) return (result); res = PQexec(dbi->conn, str); if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) { PQclear(res); return (ISC_R_FAILURE); } if (PQntuples(res) == 0) { PQclear(res); return (ISC_R_NOTFOUND); } for (i = 0; i < PQntuples(res); i++) { char *ttlstr = PQgetvalue(res, i, 0); char *type = PQgetvalue(res, i, 1); char *data = PQgetvalue(res, i, 2); dns_ttl_t ttl; char *endp; ttl = strtol(ttlstr, &endp, 10); if (*endp != '\0') { PQclear(res); return (DNS_R_BADTTL); } result = dns_sdb_putrr(lookup, type, ttl, data); if (result != ISC_R_SUCCESS) { PQclear(res); return (ISC_R_FAILURE); } } PQclear(res); return (ISC_R_SUCCESS); }
/* * Issue an SQL query to return all nodes in the database and fill the * allnodes structure. */ static isc_result_t pgsqldb_allnodes(const char *zone, void *dbdata, dns_sdballnodes_t *allnodes) { struct dbinfo *dbi = dbdata; PGresult *res; isc_result_t result; char str[1500]; int i; UNUSED(zone); snprintf(str, sizeof(str), "SELECT TTL,NAME,RDTYPE,RDATA FROM \"%s\" ORDER BY NAME", dbi->table); result = maybe_reconnect(dbi); if (result != ISC_R_SUCCESS) return (result); res = PQexec(dbi->conn, str); if (!res || PQresultStatus(res) != PGRES_TUPLES_OK ) { PQclear(res); return (ISC_R_FAILURE); } if (PQntuples(res) == 0) { PQclear(res); return (ISC_R_NOTFOUND); } for (i = 0; i < PQntuples(res); i++) { char *ttlstr = PQgetvalue(res, i, 0); char *name = PQgetvalue(res, i, 1); char *type = PQgetvalue(res, i, 2); char *data = PQgetvalue(res, i, 3); dns_ttl_t ttl; char *endp; ttl = strtol(ttlstr, &endp, 10); if (*endp != '\0') { PQclear(res); return (DNS_R_BADTTL); } result = dns_sdb_putnamedrr(allnodes, name, type, ttl, data); if (result != ISC_R_SUCCESS) { PQclear(res); return (ISC_R_FAILURE); } } PQclear(res); return (ISC_R_SUCCESS); }