static isc_result_t stub_dlz_lookup(const char *zone, const char *name, void *driverarg, void *dbdata, dns_sdlzlookup_t *lookup, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo) { isc_result_t result; config_data_t *cd; UNUSED(zone); UNUSED(driverarg); UNUSED(methods); UNUSED(clientinfo); cd = (config_data_t *) dbdata; if (strcmp(name, cd->myname) == 0) { result = dns_sdlz_putrr(lookup, "a", 1, cd->myip); if (result != ISC_R_SUCCESS) return (ISC_R_FAILURE); return (ISC_R_SUCCESS); } return (ISC_R_FAILURE); }
static isc_result_t stub_dlz_authority(const char *zone, void *driverarg, void *dbdata, dns_sdlzlookup_t *lookup) { isc_result_t result; config_data_t *cd; UNUSED(driverarg); cd = (config_data_t *) dbdata; if (strcmp(zone, cd->myzone) == 0) { result = dns_sdlz_putsoa(lookup, cd->myname, "root.localhost.", 0); if (result != ISC_R_SUCCESS) return (ISC_R_FAILURE); result = dns_sdlz_putrr(lookup, "ns", 86400, cd->myname); if (result != ISC_R_SUCCESS) return (ISC_R_FAILURE); return (ISC_R_SUCCESS); } return (ISC_R_NOTFOUND); }
static isc_result_t postgres_process_rs(dns_sdlzlookup_t *lookup, PGresult *rs) { isc_result_t result; unsigned int i; unsigned int rows; unsigned int fields; unsigned int j; unsigned int len; char *tmpString; char *endp; int ttl; rows = PQntuples(rs); /* how many rows in result set */ fields = PQnfields(rs); /* how many columns in result set */ for (i=0; i < rows; i++) { switch(fields) { case 1: /* * one column in rs, it's the data field. use * default type of A record, and default TTL * of 86400 */ result = dns_sdlz_putrr(lookup, "a", 86400, PQgetvalue(rs, i, 0)); break; case 2: /* two columns, data field, and data type. * use default TTL of 86400. */ result = dns_sdlz_putrr(lookup, PQgetvalue(rs, i, 0), 86400, PQgetvalue(rs, i, 1)); break; case 3: /* three columns, all data no defaults. * 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 positive number"); } result = dns_sdlz_putrr(lookup, PQgetvalue(rs, i, 1), ttl, PQgetvalue(rs, i, 2)); break; default: /* * more than 3 fields, concatenate the last * ones together. figure out how long to make * string */ for (j=2, len=0; j < fields; j++) { len += strlen(PQgetvalue(rs, i, j)) + 1; } /* * allocate string memory, allow for NULL to * term string */ tmpString = isc_mem_allocate(ns_g_mctx, len + 1); if (tmpString == NULL) { /* major bummer, 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); /* Yeah, I'd say! */ } /* copy field to tmpString */ strcpy(tmpString, PQgetvalue(rs, i, 2)); /* * concat the rest of fields together, space * between each one. */ for (j=3; j < fields; j++) { strcat(tmpString, " "); strcat(tmpString, PQgetvalue(rs, i, j)); } /* 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"); } /* ok, now tell Bind about it. */ result = dns_sdlz_putrr(lookup, PQgetvalue(rs, i, 1), ttl, tmpString); /* done, get rid of this thing. */ isc_mem_free(ns_g_mctx, tmpString); } /* I sure hope we were successful */ if (result != ISC_R_SUCCESS) { /* nope, get rid of the Result set, and log a msg */ PQclear(rs); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "dns_sdlz_putrr 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); }
static isc_result_t mysql_process_rs(dns_sdlzlookup_t *lookup, MYSQL_RES *rs) { isc_result_t result = ISC_R_NOTFOUND; MYSQL_ROW row; unsigned int fields; unsigned int j; unsigned int len; char *tmpString; char *endp; int ttl; 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) { switch(fields) { case 1: /* * one column in rs, it's the data field. use * default type of A record, and default TTL * of 86400 */ result = dns_sdlz_putrr(lookup, "a", 86400, safeGet(row[0])); break; case 2: /* * two columns, data field, and data type. * use default TTL of 86400. */ result = dns_sdlz_putrr(lookup, safeGet(row[0]), 86400, safeGet(row[1])); break; case 3: /* * three columns, all data no defaults. * 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"); } result = dns_sdlz_putrr(lookup, safeGet(row[1]), ttl, safeGet(row[2])); break; default: /* * more than 3 fields, concatenate the last * ones together. figure out how long to make * string. */ for (j=2, len=0; j < fields; j++) { len += strlen(safeGet(row[j])) + 1; } /* * allocate string memory, allow for NULL to * term string */ tmpString = isc_mem_allocate(ns_g_mctx, len + 1); if (tmpString == NULL) { /* major bummer, 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); /* Yeah, I'd say! */ } /* copy field to tmpString */ strcpy(tmpString, safeGet(row[2])); /* * concat the rest of fields together, space * between each one. */ for (j=3; j < fields; j++) { strcat(tmpString, " "); strcat(tmpString, safeGet(row[j])); } /* 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"); } /* ok, now tell Bind about it. */ result = dns_sdlz_putrr(lookup, safeGet(row[1]), ttl, tmpString); /* done, get rid of this thing. */ isc_mem_free(ns_g_mctx, tmpString); } /* I sure hope we were successful */ if (result != ISC_R_SUCCESS) { /* nope, get rid of the Result set, and log a msg */ mysql_free_result(rs); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "dns_sdlz_putrr returned error. " "Error code was: %s", isc_result_totext(result)); return (ISC_R_FAILURE); } row = mysql_fetch_row(rs); /* get next row */ } /* free result set memory */ mysql_free_result(rs); /* return result code */ return result; }
static isc_result_t odbc_process_rs(dns_sdlzlookup_t *lookup, dbinstance_t *dbi) { isc_result_t result; SQLSMALLINT fields; SQLHSTMT *stmnt; char *ttl_s; char *type; char *data; char *endp; int ttl; REQUIRE(dbi != NULL); 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 process_rs_cleanup; } /* get things ready for processing */ result = ISC_R_FAILURE; while (sqlOK(SQLFetch(stmnt))) { /* set to null for next pass through */ data = type = ttl_s = NULL; switch(fields) { case 1: /* * one column in rs, it's the data field. use * default type of A record, and default TTL * of 86400. attempt to get data, & tell bind * about it. */ if ((result = odbc_getField(stmnt, 1, &data)) == ISC_R_SUCCESS) { result = dns_sdlz_putrr(lookup, "a", 86400, data); } break; case 2: /* * two columns, data field, and data type. * use default TTL of 86400. attempt to get * DNS type & data, then tell bind about it. */ if ((result = odbc_getField(stmnt, 1, &type)) == ISC_R_SUCCESS && (result = odbc_getField(stmnt, 2, &data)) == ISC_R_SUCCESS) { result = dns_sdlz_putrr(lookup, type, 86400, data); } break; default: /* * 3 fields or more, concatenate the last ones * together. attempt to get DNS ttl, type, * 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_getManyFields(stmnt, 3, fields, &data)) == ISC_R_SUCCESS) { /* try to 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 everything */ result = dns_sdlz_putrr(lookup, type, ttl, data); } } /* closes bid if () */ } /* closes switch(fields) */ /* 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 (data != NULL) isc_mem_free(ns_g_mctx, data); /* I sure hope we were successful */ if (result != ISC_R_SUCCESS) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "dns_sdlz_putrr returned error. " "Error code was: %s", isc_result_totext(result)); result = ISC_R_FAILURE; goto process_rs_cleanup; } } /* closes while loop */ process_rs_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_lookup(const char *zone, const char *name, void *driverarg, void *dbdata, dns_sdlzlookup_t *lookup, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo) { isc_result_t result = ISC_R_NOTFOUND; bdbhpt_instance_t *db = (bdbhpt_instance_t *) dbdata; DBC *data_cursor = NULL; DBT key, data; int bdbhptres; int flags; bdbhpt_parsed_data_t pd; char *tmp = NULL; char *keyStr = NULL; UNUSED(driverarg); UNUSED(methods); UNUSED(clientinfo); memset(&key, 0, sizeof(DBT)); memset(&data, 0, sizeof(DBT)); key.size = strlen(zone) + strlen(name) + 1; /* allocate mem for key */ key.data = keyStr = malloc((key.size + 1) * sizeof(char)); if (keyStr == NULL) return ISC_R_NOMEMORY; strcpy(keyStr, zone); strcat(keyStr, " "); strcat(keyStr, name); /* get a cursor to loop through data */ if (db->data->cursor(db->data, NULL, &data_cursor, 0) != 0) { result = ISC_R_FAILURE; goto lookup_cleanup; } result = ISC_R_NOTFOUND; flags = DB_SET; while ((bdbhptres = data_cursor->c_get(data_cursor, &key, &data, flags)) == 0) { flags = DB_NEXT_DUP; tmp = realloc(tmp, data.size + 1); if (tmp == NULL) goto lookup_cleanup; strncpy(tmp, data.data, data.size); tmp[data.size] = '\0'; if (bdbhpt_parse_data(tmp, &pd) != ISC_R_SUCCESS) goto lookup_cleanup; result = dns_sdlz_putrr(lookup, pd.type, pd.ttl, pd.data); if (result != ISC_R_SUCCESS) goto lookup_cleanup; } /* end while loop */ lookup_cleanup: /* get rid of cursor */ if (data_cursor != NULL) data_cursor->c_close(data_cursor); if (keyStr != NULL) free(keyStr); if (tmp != NULL) free(tmp); 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_lookup(const char *zone, const char *name, void *driverarg, void *dbdata, dns_sdlzlookup_t *lookup, dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo) { isc_result_t result = ISC_R_NOTFOUND; bdb_instance_t *db = (bdb_instance_t *) dbdata; DBC *zone_cursor = NULL; DBC *host_cursor = NULL; DBC *join_cursor = NULL; DBT key, data; DBC *cur_arr[3]; int bdbres; parsed_data_t pd; char *tmp_zone, *tmp_host = NULL; char *tmp = NULL; UNUSED(driverarg); UNUSED(methods); UNUSED(clientinfo); memset(&key, 0, sizeof(DBT)); memset(&data, 0, sizeof(DBT)); /* set zone key */ key.data = tmp_zone = strdup(zone); if (key.data == NULL) { result = ISC_R_NOMEMORY; goto lookup_cleanup; } 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 lookup_cleanup; } /* initialize zone_cursor with zone_key */ if (zone_cursor->c_get(zone_cursor, &key, &data, DB_SET) != 0) { result = ISC_R_NOTFOUND; goto lookup_cleanup; } /* set host key */ key.data = tmp_host = strdup(name); if (key.data == NULL) { result = ISC_R_NOMEMORY; goto lookup_cleanup; } key.size = strlen(key.data); /* get a cursor to loop through host data */ if (db->host->cursor(db->host, NULL, &host_cursor, 0) != 0) { result = ISC_R_FAILURE; goto lookup_cleanup; } /* initialize host_cursor with host_key */ if (host_cursor->c_get(host_cursor, &key, &data, DB_SET) != 0) { result = ISC_R_NOTFOUND; goto lookup_cleanup; } cur_arr[0] = zone_cursor; cur_arr[1] = host_cursor; cur_arr[2] = NULL; db->data->join(db->data, cur_arr, &join_cursor, 0); while ((bdbres = join_cursor->c_get(join_cursor, &key, &data, 0)) == 0) { tmp = realloc(tmp, data.size + 1); if (tmp == NULL) goto lookup_cleanup; strncpy(tmp, data.data, data.size); tmp[data.size] = '\0'; if (bdb_parse_data(tmp, &pd) != ISC_R_SUCCESS) goto lookup_cleanup; result = dns_sdlz_putrr(lookup, pd.type, pd.ttl, pd.data); if (result != ISC_R_SUCCESS) goto lookup_cleanup; } /* end while loop */ lookup_cleanup: if (tmp != NULL) free(tmp); if (tmp_zone != NULL) free(tmp_zone); if (tmp_host != NULL) free(tmp_host); /* get rid of the joined cusor */ if (join_cursor != NULL) join_cursor->c_close(join_cursor); /* get rid of zone_cursor */ if (zone_cursor != NULL) zone_cursor->c_close(zone_cursor); /* get rid of host_cursor */ if (host_cursor != NULL) host_cursor->c_close(host_cursor); return result; }