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);
}
Example #3
0
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);
}
Example #4
0
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;
}
Example #7
0
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;
}