static isc_result_t stub_dlz_allnodes(const char *zone, void *driverarg, void *dbdata, dns_sdlzallnodes_t *allnodes) { config_data_t *cd; isc_result_t result; UNUSED(zone); UNUSED(driverarg); cd = (config_data_t *) dbdata; result = dns_sdlz_putnamedrr(allnodes, cd->myname, "soa", 86400, "web root.localhost. " "0 28800 7200 604800 86400"); if (result != ISC_R_SUCCESS) return (ISC_R_FAILURE); result = dns_sdlz_putnamedrr(allnodes, "ns", "ns", 86400, cd->myname); if (result != ISC_R_SUCCESS) return (ISC_R_FAILURE); result = dns_sdlz_putnamedrr(allnodes, cd->myname, "a", 1, cd->myip); if (result != ISC_R_SUCCESS) return (ISC_R_FAILURE); return (ISC_R_SUCCESS); }
/*% * If the client is allowed to perform a zone transfer, the next order of * business is to get all the nodes in the zone, so bind can respond to the * query. */ static isc_result_t postgres_allnodes(const char *zone, void *driverarg, void *dbdata, dns_sdlzallnodes_t *allnodes) { isc_result_t result; PGresult *rs = NULL; unsigned int i; unsigned int rows; unsigned int fields; unsigned int j; unsigned int len; char *tmpString; char *endp; int ttl; UNUSED(driverarg); /* run the query and get the result set from the database. */ result = postgres_get_resultset(zone, NULL, NULL, ALLNODES, dbdata, &rs); /* if we get "not implemented", send it along */ if (result == ISC_R_NOTIMPLEMENTED) return result; /* if we didn't get a result set, log an err msg. */ if (result != ISC_R_SUCCESS) { if (rs != NULL) PQclear(rs); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Postgres driver unable to return " "result set for all nodes query"); return (ISC_R_FAILURE); } rows = PQntuples(rs); /* how many rows in result set */ fields = PQnfields(rs); /* how many columns in result set */ for (i=0; i < rows; i++) { if (fields < 4) { /* gotta have at least 4 columns */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Postgres driver too few fields " "returned by all nodes query"); } /* convert text to int, make sure it worked right */ ttl = strtol(PQgetvalue(rs, i, 0), &endp, 10); if (*endp != '\0' || ttl < 0) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Postgres driver ttl must be " "a postive number"); } if (fields == 4) { /* tell Bind about it. */ result = dns_sdlz_putnamedrr(allnodes, PQgetvalue(rs, i, 2), PQgetvalue(rs, i, 1), ttl, PQgetvalue(rs, i, 3)); } else { /* * more than 4 fields, concatonat the last * ones together. figure out how long to make * string */ for (j=3, len=0; j < fields; j++) { len += strlen(PQgetvalue(rs, i, j)) + 1; } /* allocate memory, allow for NULL to term string */ tmpString = isc_mem_allocate(ns_g_mctx, len + 1); if (tmpString == NULL) { /* we need more ram. */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Postgres driver unable to " "allocate memory for " "temporary string"); PQclear(rs); return (ISC_R_FAILURE); } /* copy this field to tmpString */ strcpy(tmpString, PQgetvalue(rs, i, 3)); /* concatonate the rest, with spaces between */ for (j=4; j < fields; j++) { strcat(tmpString, " "); strcat(tmpString, PQgetvalue(rs, i, j)); } /* tell Bind about it. */ result = dns_sdlz_putnamedrr(allnodes, PQgetvalue(rs, i, 2), PQgetvalue(rs, i, 1), ttl, tmpString); isc_mem_free(ns_g_mctx, tmpString); } /* if we weren't successful, log err msg */ if (result != ISC_R_SUCCESS) { PQclear(rs); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "dns_sdlz_putnamedrr returned error. " "Error code was: %s", isc_result_totext(result)); return (ISC_R_FAILURE); } } /* free result set memory */ PQclear(rs); /* if we did return results, we are successful */ if (rows > 0) return (ISC_R_SUCCESS); /* empty result set, no data found */ return (ISC_R_NOTFOUND); }
/*% * If the client is allowed to perform a zone transfer, the next order of * business is to get all the nodes in the zone, so bind can respond to the * query. */ static isc_result_t mysql_allnodes(const char *zone, void *driverarg, void *dbdata, dns_sdlzallnodes_t *allnodes) { isc_result_t result; MYSQL_RES *rs = NULL; MYSQL_ROW row; unsigned int fields; unsigned int j; unsigned int len; char *tmpString; char *endp; int ttl; UNUSED(driverarg); /* run the query and get the result set from the database. */ result = mysql_get_resultset(zone, NULL, NULL, ALLNODES, dbdata, &rs); /* if we get "not implemented", send it along */ if (result == ISC_R_NOTIMPLEMENTED) return result; /* if we didn't get a result set, log an err msg. */ if (result != ISC_R_SUCCESS) { if (rs != NULL) mysql_free_result(rs); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "mysql driver unable to return " "result set for all nodes query"); return (ISC_R_FAILURE); } result = ISC_R_NOTFOUND; row = mysql_fetch_row(rs); /* get a row from the result set */ fields = mysql_num_fields(rs); /* how many columns in result set */ while (row != NULL) { if (fields < 4) { /* gotta have at least 4 columns */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "mysql driver too few fields returned " "by all nodes query"); } /* convert text to int, make sure it worked right */ ttl = strtol(safeGet(row[0]), &endp, 10); if (*endp != '\0' || ttl < 0) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "mysql driver ttl must be " "a postive number"); } if (fields == 4) { /* tell Bind about it. */ result = dns_sdlz_putnamedrr(allnodes, safeGet(row[2]), safeGet(row[1]), ttl, safeGet(row[3])); } else { /* * more than 4 fields, concatenate the last * ones together. figure out how long to make * string. */ for (j=3, len=0; j < fields; j++) { len += strlen(safeGet(row[j])) + 1; } /* allocate memory, allow for NULL to term string */ tmpString = isc_mem_allocate(ns_g_mctx, len + 1); if (tmpString == NULL) { /* we need more ram. */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "mysql driver unable " "to allocate memory for " "temporary string"); mysql_free_result(rs); return (ISC_R_FAILURE); } /* copy this field to tmpString */ strcpy(tmpString, safeGet(row[3])); /* concatonate the rest, with spaces between */ for (j=4; j < fields; j++) { strcat(tmpString, " "); strcat(tmpString, safeGet(row[j])); } /* tell Bind about it. */ result = dns_sdlz_putnamedrr(allnodes, safeGet(row[2]), safeGet(row[1]), ttl, tmpString); isc_mem_free(ns_g_mctx, tmpString); } /* if we weren't successful, log err msg */ if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "dns_sdlz_putnamedrr returned error. " "Error code was: %s", isc_result_totext(result)); result = ISC_R_FAILURE; break; } /* get next row from the result set */ row = mysql_fetch_row(rs); } /* free result set memory */ mysql_free_result(rs); return result; }
static isc_result_t odbc_allnodes(const char *zone, void *driverarg, void *dbdata, dns_sdlzallnodes_t *allnodes) { isc_result_t result; dbinstance_t *dbi = NULL; SQLHSTMT *stmnt; SQLSMALLINT fields; char *data; char *type; char *ttl_s; int ttl; char *host; char *endp; UNUSED(driverarg); /* run the query and get the result set from the database. */ result = odbc_get_resultset(zone, NULL, NULL, ALLNODES, dbdata, &dbi); /* if we get "not implemented", send it along */ if (result == ISC_R_NOTIMPLEMENTED) return result; /* if we didn't get a result set, log an err msg. */ if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Odbc driver unable to return " "result set for all nodes query"); return (ISC_R_FAILURE); } stmnt = ((odbc_db_t *) (dbi->dbconn))->stmnt; /* get number of columns */ if (!sqlOK(SQLNumResultCols(stmnt, &fields))) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Odbc driver unable to process result set"); result = ISC_R_FAILURE; goto allnodes_cleanup; } if (fields < 4) { /* gotta have at least 4 columns */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Odbc driver too few fields returned by " "all nodes query"); result = ISC_R_FAILURE; goto allnodes_cleanup; } /* get things ready for processing */ result = ISC_R_FAILURE; while (sqlOK(SQLFetch(stmnt))) { /* set to null for next pass through */ data = host = type = ttl_s = NULL; /* * attempt to get DNS ttl, type, host, data then tell * Bind about them */ if ((result = odbc_getField(stmnt, 1, &ttl_s)) == ISC_R_SUCCESS && (result = odbc_getField(stmnt, 2, &type)) == ISC_R_SUCCESS && (result = odbc_getField(stmnt, 3, &host)) == ISC_R_SUCCESS && (result = odbc_getManyFields(stmnt, 4, fields, &data)) == ISC_R_SUCCESS) { /* convert ttl string to int */ ttl = strtol(ttl_s, &endp, 10); /* failure converting ttl. */ if (*endp != '\0' || ttl < 0) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "Odbc driver ttl must be " "a postive number"); result = ISC_R_FAILURE; } else { /* successful converting TTL, tell Bind */ result = dns_sdlz_putnamedrr(allnodes, host, type, ttl, data); } } /* closes big if () */ /* clean up mem */ if (ttl_s != NULL) isc_mem_free(ns_g_mctx, ttl_s); if (type != NULL) isc_mem_free(ns_g_mctx, type); if (host != NULL) isc_mem_free(ns_g_mctx, host); if (data != NULL) isc_mem_free(ns_g_mctx, data); /* if we weren't successful, log err msg */ if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "dns_sdlz_putnamedrr returned error. " "Error code was: %s", isc_result_totext(result)); result = ISC_R_FAILURE; goto allnodes_cleanup; } } /* closes while loop */ allnodes_cleanup: /* close cursor */ SQLCloseCursor(((odbc_db_t *) (dbi->dbconn))->stmnt); #ifdef ISC_PLATFORM_USETHREADS /* free lock on dbi so someone else can use it. */ isc_mutex_unlock(&dbi->instance_lock); #endif return result; }
static isc_result_t bdbhpt_allnodes(const char *zone, void *driverarg, void *dbdata, dns_sdlzallnodes_t *allnodes) { isc_result_t result = ISC_R_NOTFOUND; bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata; DBC *xfr_cursor = NULL; DBC *dns_cursor = NULL; DBT xfr_key, xfr_data, dns_key, dns_data; int xfr_flags; int dns_flags; int bdbhptres; bdbhpt_parsed_data_t pd; char *tmp = NULL, *tmp_zone, *tmp_zone_host = NULL; UNUSED(driverarg); memset(&xfr_key, 0, sizeof(DBT)); memset(&xfr_data, 0, sizeof(DBT)); memset(&dns_key, 0, sizeof(DBT)); memset(&dns_data, 0, sizeof(DBT)); xfr_key.data = tmp_zone = strdup(zone); if (xfr_key.data == NULL) return (ISC_R_NOMEMORY); xfr_key.size = strlen(xfr_key.data); /* get a cursor to loop through dns_xfr table */ if (db->xfr->cursor(db->xfr, NULL, &xfr_cursor, 0) != 0) { result = ISC_R_FAILURE; goto allnodes_cleanup; } /* get a cursor to loop through dns_data table */ if (db->data->cursor(db->data, NULL, &dns_cursor, 0) != 0) { result = ISC_R_FAILURE; goto allnodes_cleanup; } xfr_flags = DB_SET; /* loop through xfr table for specified zone. */ while ((bdbhptres = xfr_cursor->c_get(xfr_cursor, &xfr_key, &xfr_data, xfr_flags)) == 0) { xfr_flags = DB_NEXT_DUP; /* +1 to allow for space between zone and host names */ dns_key.size = xfr_data.size + xfr_key.size + 1; /* +1 to allow for null term at end of string. */ dns_key.data = tmp_zone_host = malloc(dns_key.size + 1); if (dns_key.data == NULL) goto allnodes_cleanup; /* * construct search key for dns_data. * zone_name(a space)host_name */ strcpy(dns_key.data, zone); strcat(dns_key.data, " "); strncat(dns_key.data, xfr_data.data, xfr_data.size); dns_flags = DB_SET; while ((bdbhptres = dns_cursor->c_get(dns_cursor, &dns_key, &dns_data, dns_flags)) == 0) { dns_flags = DB_NEXT_DUP; /* +1 to allow for null term at end of string. */ tmp = realloc(tmp, dns_data.size + 1); if (tmp == NULL) goto allnodes_cleanup; /* copy data to tmp string, and append null term. */ strncpy(tmp, dns_data.data, dns_data.size); tmp[dns_data.size] = '\0'; /* split string into dns data parts. */ if (bdbhpt_parse_data(tmp, &pd) != ISC_R_SUCCESS) goto allnodes_cleanup; result = dns_sdlz_putnamedrr(allnodes, pd.host, pd.type, pd.ttl, pd.data); if (result != ISC_R_SUCCESS) goto allnodes_cleanup; } /* end inner while loop */ /* clean up memory */ if (tmp_zone_host != NULL) { free(tmp_zone_host); tmp_zone_host = NULL; } } /* end outer while loop */ allnodes_cleanup: /* free any memory */ if (tmp != NULL) free(tmp); if (tmp_zone_host != NULL) free(tmp_zone_host); if (tmp_zone != NULL) free(tmp_zone); /* get rid of cursors */ if (xfr_cursor != NULL) xfr_cursor->c_close(xfr_cursor); if (dns_cursor != NULL) dns_cursor->c_close(dns_cursor); return result; }
static isc_result_t ldap_process_results(LDAP *dbc, LDAPMessage *msg, char ** attrs, void *ptr, isc_boolean_t allnodes) { isc_result_t result = ISC_R_SUCCESS; int i = 0; int j; int len; char *attribute = NULL; LDAPMessage *entry; char *endp = NULL; char *host = NULL; char *type = NULL; char *data = NULL; char **vals = NULL; int ttl; /* make sure there are at least some attributes to process. */ REQUIRE(attrs != NULL || attrs[0] != NULL); /* get the first entry to process */ entry = ldap_first_entry(dbc, msg); if (entry == NULL) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_INFO, "LDAP no entries to process."); return (ISC_R_FAILURE); } /* loop through all entries returned */ while (entry != NULL) { /* reset for this loop */ ttl = 0; len = 0; i = 0; attribute = attrs[i]; /* determine how much space we need for data string */ for (j = 0; attrs[j] != NULL; j++) { /* get the list of values for this attribute. */ vals = ldap_get_values(dbc, entry, attrs[j]); /* skip empty attributes. */ if (vals == NULL || ldap_count_values(vals) < 1) continue; /* * we only use the first value. this driver * does not support multi-valued attributes. */ len = len + strlen(vals[0]) + 1; /* free vals for next loop */ ldap_value_free(vals); } /* end for (j = 0; attrs[j] != NULL, j++) loop */ /* allocate memory for data string */ data = isc_mem_allocate(ns_g_mctx, len + 1); if (data == NULL) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "LDAP driver unable to allocate memory " "while processing results"); result = ISC_R_FAILURE; goto cleanup; } /* * Make sure data is null termed at the beginning so * we can check if any data was stored to it later. */ data[0] = '\0'; /* reset j to re-use below */ j = 0; /* loop through the attributes in the order specified. */ while (attribute != NULL) { /* get the list of values for this attribute. */ vals = ldap_get_values(dbc, entry, attribute); /* skip empty attributes. */ if (vals == NULL || vals[0] == NULL) { /* increment attibute pointer */ attribute = attrs[++i]; /* start loop over */ continue; } /* * j initially = 0. Increment j each time we * set a field that way next loop will set * next field. */ switch(j) { case 0: j++; /* * convert text to int, make sure it * worked right */ ttl = strtol(vals[0], &endp, 10); if (*endp != '\0' || ttl < 0) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "LDAP driver ttl must " "be a postive number"); goto cleanup; } break; case 1: j++; type = isc_mem_strdup(ns_g_mctx, vals[0]); break; case 2: j++; if (allnodes == isc_boolean_true) { host = isc_mem_strdup(ns_g_mctx, vals[0]); } else { strcpy(data, vals[0]); } break; case 3: j++; if (allnodes == isc_boolean_true) { strcpy(data, vals[0]); } else { strcat(data, " "); strcat(data, vals[0]); } break; default: strcat(data, " "); strcat(data, vals[0]); break; } /* end switch(j) */ /* free values */ ldap_value_free(vals); vals = NULL; /* increment attibute pointer */ attribute = attrs[++i]; } /* end while (attribute != NULL) */ if (type == NULL) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "LDAP driver unable " "to retrieve DNS type"); result = ISC_R_FAILURE; goto cleanup; } if (strlen(data) < 1) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "LDAP driver unable " "to retrieve DNS data"); result = ISC_R_FAILURE; goto cleanup; } if (allnodes == isc_boolean_true) { if (strcasecmp(host, "~") == 0) result = dns_sdlz_putnamedrr( (dns_sdlzallnodes_t *) ptr, "*", type, ttl, data); else result = dns_sdlz_putnamedrr( (dns_sdlzallnodes_t *) ptr, host, type, ttl, data); if (result != ISC_R_SUCCESS) isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "dlz-ldap: putnamedrr failed " "for \"%s %s %u %s\", %s", host, type, ttl, data, isc_result_totext(result)); } else { result = dns_sdlz_putrr((dns_sdlzlookup_t *) ptr, type, ttl, data); if (result != ISC_R_SUCCESS) isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "dlz-ldap: putrr failed " "for \"%s %u %s\", %s", type, ttl, data, isc_result_totext(result)); } if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "LDAP driver failed " "while sending data to BIND."); goto cleanup; } /* free memory for type, data and host for next loop */ isc_mem_free(ns_g_mctx, type); isc_mem_free(ns_g_mctx, data); if (host != NULL) isc_mem_free(ns_g_mctx, host); /* get the next entry to process */ entry = ldap_next_entry(dbc, entry); } /* end while (entry != NULL) */ cleanup: /* de-allocate memory */ if (vals != NULL) ldap_value_free(vals); if (host != NULL) isc_mem_free(ns_g_mctx, host); if (type != NULL) isc_mem_free(ns_g_mctx, type); if (data != NULL) isc_mem_free(ns_g_mctx, data); return (result); }
static isc_result_t bdb_allnodes(const char *zone, void *driverarg, void *dbdata, dns_sdlzallnodes_t *allnodes) { isc_result_t result = ISC_R_NOTFOUND; bdb_instance_t *db = (bdb_instance_t *) dbdata; DBC *zone_cursor = NULL; DBT key, data; int flags; int bdbres; parsed_data_t pd; char *tmp = NULL, *tmp_zone; UNUSED(driverarg); memset(&key, 0, sizeof(DBT)); memset(&data, 0, sizeof(DBT)); key.data = tmp_zone = strdup(zone); if (key.data == NULL) return (ISC_R_NOMEMORY); key.size = strlen(key.data); /* get a cursor to loop through zone data */ if (db->zone->cursor(db->zone, NULL, &zone_cursor, 0) != 0) { result = ISC_R_FAILURE; goto allnodes_cleanup; } flags = DB_SET; while ((bdbres = zone_cursor->c_get(zone_cursor, &key, &data, flags)) == 0) { flags = DB_NEXT_DUP; tmp = realloc(tmp, data.size + 1); if (tmp == NULL) goto allnodes_cleanup; strncpy(tmp, data.data, data.size); tmp[data.size] = '\0'; if (bdb_parse_data(tmp, &pd) != ISC_R_SUCCESS) goto allnodes_cleanup; result = dns_sdlz_putnamedrr(allnodes, pd.host, pd.type, pd.ttl, pd.data); if (result != ISC_R_SUCCESS) goto allnodes_cleanup; } /* end while loop */ allnodes_cleanup: if (tmp != NULL) free(tmp); /* free any memory duplicate string in the key field */ if (tmp_zone != NULL) free(tmp_zone); /* get rid of zone_cursor */ if (zone_cursor != NULL) zone_cursor->c_close(zone_cursor); return result; }