/* * lookup () does not return SOA or NS records, so authority() must be defined. */ static isc_result_t dirdb_authority(const char *zone, void *dbdata, dns_sdblookup_t *lookup) { isc_result_t result; UNUSED(zone); UNUSED(dbdata); result = dns_sdb_putsoa(lookup, "ns", "hostmaster", 0); INSIST(result == ISC_R_SUCCESS); result = dns_sdb_putrr(lookup, "ns", 86400, "ns1"); INSIST(result == ISC_R_SUCCESS); result = dns_sdb_putrr(lookup, "ns", 86400, "ns2"); INSIST(result == ISC_R_SUCCESS); return (ISC_R_SUCCESS); }
static isc_result_t builtin_authority(const char *zone, void *dbdata, dns_sdblookup_t *lookup) { isc_result_t result; const char *contact = "hostmaster"; const char *server = "@"; builtin_t *b = (builtin_t *) dbdata; UNUSED(zone); UNUSED(dbdata); if (b == &empty_builtin) { server = "."; contact = "."; } else { if (b->server != NULL) server = b->server; if (b->contact != NULL) contact = b->contact; } result = dns_sdb_putsoa(lookup, server, contact, 0); if (result != ISC_R_SUCCESS) return (ISC_R_FAILURE); result = dns_sdb_putrr(lookup, "ns", 0, server); if (result != ISC_R_SUCCESS) return (ISC_R_FAILURE); return (ISC_R_SUCCESS); }
static int sqlitedb_lookup_cb(void *p, int cc, char **cv, char **cn) { lookup_parm_t *parm = p; dns_ttl_t ttl; char *endp; /* FIXME - check these(num/names); I'm assuming a mapping for now */ char *ttlstr = cv[0]; char *type = cv[1]; char *data = cv[2]; UNUSED(cc); UNUSED(cn); ttl = strtol(ttlstr, &endp, 10); if (*endp) { parm->result = DNS_R_BADTTL; return 1; } parm->result = dns_sdb_putrr(parm->lookup, type, ttl, data); if (parm->result != ISC_R_SUCCESS) return 1; (parm->i)++; return 0; }
/* * 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); }
bdb_lookup(const char *zone, const char *name, void *dbdata, dns_sdblookup_t *l) #endif /* DNS_CLIENTINFO_VERSION */ { int ret; char *type, *rdata; dns_ttl_t ttl; isc_consttextregion_t ttltext; DBC *c; DBT key, data; UNUSED(zone); #ifdef DNS_CLIENTINFO_VERSION UNUSED(methods); UNUSED(clientinfo); #endif /* DNS_CLIENTINFO_VERSION */ if ((ret = ((DB *)dbdata)->cursor((DB *)dbdata, NULL, &c, 0)) != 0) { isc_log_iwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_SDB, ISC_LOG_ERROR, isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "DB->cursor: %s", db_strerror(ret)); return ISC_R_FAILURE; } memset(&key, 0, sizeof(DBT)); memset(&data, 0, sizeof(DBT)); (const char *)key.data = name; key.size = strlen(name); ret = c->c_get(c, &key, &data, DB_SET); while (ret == 0) { ((char *)key.data)[key.size] = 0; ((char *)data.data)[data.size] = 0; ttltext.base = strtok((char *)data.data, " "); ttltext.length = strlen(ttltext.base); dns_ttl_fromtext((isc_textregion_t *)&ttltext, &ttl); type = strtok(NULL, " "); rdata = type + strlen(type) + 1; if (dns_sdb_putrr(l, type, ttl, rdata) != ISC_R_SUCCESS) { isc_log_iwrite(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_SDB, ISC_LOG_ERROR, isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "dns_sdb_putrr"); return ISC_R_FAILURE; } ret = c->c_get(c, &key, &data, DB_NEXT_DUP); } c->c_close(c); return ISC_R_SUCCESS; }
static isc_result_t timedb_lookup(const char *zone, const char *name, void *dbdata, dns_sdblookup_t *lookup) #endif /* DNS_CLIENTINFO_VERSION */ { isc_result_t result; UNUSED(zone); UNUSED(dbdata); #ifdef DNS_CLIENTINFO_VERSION UNUSED(methods); UNUSED(clientinfo); #endif /* DNS_CLIENTINFO_VERSION */ if (strcmp(name, "@") == 0 || strcmp(name, "time") == 0) { time_t now = time(NULL); char buf[100]; int n; /* * Call ctime to create the string, put it in quotes, and * remove the trailing newline. */ n = snprintf(buf, sizeof(buf), "\"%s", ctime(&now)); if (n < 0) return (ISC_R_FAILURE); buf[n - 1] = '\"'; result = dns_sdb_putrr(lookup, "txt", 1, buf); if (result != ISC_R_SUCCESS) return (ISC_R_FAILURE); } else if (strcmp(name, "clock") == 0) { result = dns_sdb_putrr(lookup, "cname", 1, "time"); if (result != ISC_R_SUCCESS) return (ISC_R_FAILURE); } else if (strcmp(name, "current") == 0) { result = dns_sdb_putrr(lookup, "dname", 1, "@"); if (result != ISC_R_SUCCESS) return (ISC_R_FAILURE); } else return (ISC_R_NOTFOUND); return (ISC_R_SUCCESS); }
/* * lookup() does not return SOA or NS records, so authority() must be defined. */ static isc_result_t timedb_authority(const char *zone, void *dbdata, dns_sdblookup_t *lookup) { isc_result_t result; UNUSED(zone); UNUSED(dbdata); result = dns_sdb_putsoa(lookup, "localhost.", "root.localhost.", 0); if (result != ISC_R_SUCCESS) return (ISC_R_FAILURE); result = dns_sdb_putrr(lookup, "ns", 86400, "ns1.localdomain."); if (result != ISC_R_SUCCESS) return (ISC_R_FAILURE); result = dns_sdb_putrr(lookup, "ns", 86400, "ns2.localdomain."); if (result != ISC_R_SUCCESS) return (ISC_R_FAILURE); return (ISC_R_SUCCESS); }
/* * This database operates on relative names. * * Any name will be interpreted as a pathname offset from the directory * specified in the configuration file. */ static isc_result_t dirdb_lookup(const char *zone, const char *name, void *dbdata, dns_sdblookup_t *lookup) { char filename[255]; char filename2[255]; char buf[1024]; struct stat statbuf; isc_result_t result; int n; UNUSED(zone); UNUSED(dbdata); if (strcmp(name, "@") == 0) snprintf(filename, sizeof(filename), "%s", (char *)dbdata); else snprintf(filename, sizeof(filename), "%s/%s", (char *)dbdata, name); CHECKN(lstat(filename, &statbuf)); if (S_ISDIR(statbuf.st_mode)) CHECK(dns_sdb_putrr(lookup, "txt", 3600, "dir")); else if (S_ISCHR(statbuf.st_mode) || S_ISBLK(statbuf.st_mode)) { CHECKN(snprintf(buf, sizeof(buf), "\"%sdev\" \"major %d\" \"minor %d\"", S_ISCHR(statbuf.st_mode) ? "chr" : "blk", major(statbuf.st_rdev), minor(statbuf.st_rdev))); CHECK(dns_sdb_putrr(lookup, "txt", 3600, buf)); } else if (S_ISFIFO(statbuf.st_mode)) CHECK(dns_sdb_putrr(lookup, "txt", 3600, "pipe")); else if (S_ISSOCK(statbuf.st_mode)) CHECK(dns_sdb_putrr(lookup, "txt", 3600, "socket")); else if (S_ISLNK(statbuf.st_mode)) { CHECKN(readlink(filename, filename2, sizeof(filename2) - 1)); buf[n] = 0; CHECKN(snprintf(buf, sizeof(buf), "\"symlink\" \"%s\"", filename2)); CHECK(dns_sdb_putrr(lookup, "txt", 3600, buf)); } else if (!S_ISREG(statbuf.st_mode)) CHECK(dns_sdb_putrr(lookup, "txt", 3600, "unknown")); else { CHECKN(snprintf(buf, sizeof(buf), "\"file\" \"size = %u\"", (unsigned int)statbuf.st_size)); CHECK(dns_sdb_putrr(lookup, "txt", 3600, buf)); } return (ISC_R_SUCCESS); }
static isc_result_t tcldb_lookup(const char *zone, const char *name, void *dbdata, dns_sdblookup_t *lookup) #endif /* DNS_CLIENTINFO_VERSION */ { isc_result_t result = ISC_R_SUCCESS; int tclres; int rrc; /* RR count */ char **rrv; /* RR vector */ int i; char *cmdv[3]; char *cmd; #ifdef DNS_CLIENTINFO_VERSION UNUSED(methods); UNUSED(clientinfo); #endif /* DNS_CLIENTINFO_VERSION */ tcldb_driver_t *driver = (tcldb_driver_t *) dbdata; cmdv[0] = "lookup"; cmdv[1] = zone; cmdv[2] = name; cmd = Tcl_Merge(3, cmdv); tclres = Tcl_Eval(driver->interp, cmd); Tcl_Free(cmd); if (tclres != TCL_OK) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_SDB, ISC_LOG_ERROR, "zone '%s': tcl lookup function failed: %s", zone, driver->interp->result); return (ISC_R_FAILURE); } if (strcmp(driver->interp->result, "NXDOMAIN") == 0) { result = ISC_R_NOTFOUND; goto fail; } tclres = Tcl_SplitList(driver->interp, driver->interp->result, &rrc, &rrv); if (tclres != TCL_OK) goto malformed; for (i = 0; i < rrc; i++) { isc_result_t tmpres; int fieldc; /* Field count */ char **fieldv; /* Field vector */ tclres = Tcl_SplitList(driver->interp, rrv[i], &fieldc, &fieldv); if (tclres != TCL_OK) { tmpres = ISC_R_FAILURE; goto failrr; } if (fieldc != 3) goto malformed; tmpres = dns_sdb_putrr(lookup, fieldv[0], atoi(fieldv[1]), fieldv[2]); Tcl_Free((char *) fieldv); failrr: if (tmpres != ISC_R_SUCCESS) result = tmpres; } Tcl_Free((char *) rrv); if (result == ISC_R_SUCCESS) return (result); malformed: isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_SDB, ISC_LOG_ERROR, "zone '%s': " "malformed return value from tcl lookup function: %s", zone, driver->interp->result); result = ISC_R_FAILURE; fail: return (result); }
static isc_result_t ldapdb_search(const char *zone, const char *name, void *dbdata, void *retdata, void *methods, void *clientinfo) #endif /* DNS_CLIENTINFO_VERSION */ { struct ldapdb_data *data = dbdata; isc_result_t result = ISC_R_NOTFOUND; LDAP **ldp; LDAPMessage *res, *e; char *fltr, *a, **vals = NULL, **names = NULL; char type[64]; #ifdef LDAPDB_RFC1823API void *ptr; #else BerElement *ptr; #endif int i, j, errno, msgid; UNUSED(methods); UNUSED(clientinfo); ldp = ldapdb_getconn(data); if (ldp == NULL) return (ISC_R_FAILURE); if (*ldp == NULL) { ldapdb_bind(data, ldp); if (*ldp == NULL) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, "LDAP sdb zone '%s': bind failed", zone); return (ISC_R_FAILURE); } } if (name == NULL) { fltr = data->filterall; } else { if (strlen(name) > MAXNAMELEN) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, "LDAP sdb zone '%s': name %s too long", zone, name); return (ISC_R_FAILURE); } sprintf(data->filtername, "%s))", name); fltr = data->filterone; } msgid = ldap_search(*ldp, data->base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0); if (msgid == -1) { ldapdb_bind(data, ldp); if (*ldp != NULL) msgid = ldap_search(*ldp, data->base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0); } if (*ldp == NULL || msgid == -1) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, "LDAP sdb zone '%s': search failed, filter %s", zone, fltr); return (ISC_R_FAILURE); } /* Get the records one by one as they arrive and return them to bind */ while ((errno = ldap_result(*ldp, msgid, 0, NULL, &res)) != LDAP_RES_SEARCH_RESULT ) { LDAP *ld = *ldp; int ttl = data->defaultttl; /* not supporting continuation references at present */ if (errno != LDAP_RES_SEARCH_ENTRY) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, "LDAP sdb zone '%s': ldap_result returned %d", zone, errno); ldap_msgfree(res); return (ISC_R_FAILURE); } /* only one entry per result message */ e = ldap_first_entry(ld, res); if (e == NULL) { ldap_msgfree(res); isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, "LDAP sdb zone '%s': ldap_first_entry failed", zone); return (ISC_R_FAILURE); } if (name == NULL) { names = ldap_get_values(ld, e, "relativeDomainName"); if (names == NULL) continue; } vals = ldap_get_values(ld, e, "dNSTTL"); if (vals != NULL) { ttl = atoi(vals[0]); ldap_value_free(vals); } for (a = ldap_first_attribute(ld, e, &ptr); a != NULL; a = ldap_next_attribute(ld, e, ptr)) { char *s; for (s = a; *s; s++) *s = toupper(*s); s = strstr(a, "RECORD"); if ((s == NULL) || (s == a) || (s - a >= (signed int)sizeof(type))) { #ifndef LDAPDB_RFC1823API ldap_memfree(a); #endif continue; } strncpy(type, a, s - a); type[s - a] = '\0'; vals = ldap_get_values(ld, e, a); if (vals != NULL) { for (i = 0; vals[i] != NULL; i++) { if (name != NULL) { result = dns_sdb_putrr(retdata, type, ttl, vals[i]); } else { for (j = 0; names[j] != NULL; j++) { result = dns_sdb_putnamedrr(retdata, names[j], type, ttl, vals[i]); if (result != ISC_R_SUCCESS) break; } } ; if (result != ISC_R_SUCCESS) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR, "LDAP sdb zone '%s': dns_sdb_put... failed for %s", zone, vals[i]); ldap_value_free(vals); #ifndef LDAPDB_RFC1823API ldap_memfree(a); if (ptr != NULL) ber_free(ptr, 0); #endif if (name == NULL) ldap_value_free(names); ldap_msgfree(res); return (ISC_R_FAILURE); } } ldap_value_free(vals); } #ifndef LDAPDB_RFC1823API ldap_memfree(a); #endif } #ifndef LDAPDB_RFC1823API if (ptr != NULL) ber_free(ptr, 0); #endif if (name == NULL) ldap_value_free(names); /* free this result */ ldap_msgfree(res); } /* free final result */ ldap_msgfree(res); return (result); }