Пример #1
0
/*%
 * destroy an instance of the driver.  Remember, only 1 copy of the driver's
 * code is ever loaded, the driver has to remember which context it's
 * operating in.  This is done via use of the dbdata argument.
 * so we really only need to clean it up since we are not using driverarg.
 */
static void
postgres_destroy(void *driverarg, void *dbdata)
{

#ifdef ISC_PLATFORM_USETHREADS

	UNUSED(driverarg);
	/* cleanup the list of DBI's */
	postgres_destroy_dblist((db_list_t *) dbdata);

#else /* ISC_PLATFORM_USETHREADS */

	dbinstance_t *dbi;

	UNUSED(driverarg);

	dbi = (dbinstance_t *) dbdata;

	/* release DB connection */
	if (dbi->dbconn != NULL)
		PQfinish((PGconn *) dbi->dbconn);

	/* destroy single DB instance */
	destroy_sqldbinstance(dbi);

#endif /* ISC_PLATFORM_USETHREADS */
}
Пример #2
0
void
dlz_ldap_destroy(void *driverarg, void *dbdata) {
	UNUSED(driverarg);

	if (dbdata != NULL) {
#ifdef ISC_PLATFORM_USETHREADS
		/* cleanup the list of DBI's */
		ldap_destroy_dblist((db_list_t *)
				    ((ldap_instance_t *)dbdata)->db);

#else /* ISC_PLATFORM_USETHREADS */
		if (((ldap_instance_t *)dbdata)->db->dbconn != NULL)
			ldap_unbind_s((LDAP *)
				      ((ldap_instance_t *)dbdata)->db->dbconn);

		/* destroy single DB instance */
		destroy_sqldbinstance(((ldap_instance_t *)dbdata)->db);
#endif /* ISC_PLATFORM_USETHREADS */

		if (((ldap_instance_t *)dbdata)->hosts != NULL)
			isc_mem_free(ns_g_mctx,
				     ((ldap_instance_t *)dbdata)->hosts);

		if (((ldap_instance_t *)dbdata)->user != NULL)
			isc_mem_free(ns_g_mctx,
				     ((ldap_instance_t *)dbdata)->user);

		if (((ldap_instance_t *)dbdata)->cred != NULL)
			isc_mem_free(ns_g_mctx,
				     ((ldap_instance_t *)dbdata)->cred);

		isc_mem_put(ns_g_mctx, dbdata, sizeof(ldap_instance_t));
	}
}
Пример #3
0
static void
mysql_destroy(void *driverarg, void *dbdata)
{
	dbinstance_t *dbi;

	UNUSED(driverarg);

	dbi = (dbinstance_t *) dbdata;

	/* release DB connection */
	if (dbi->dbconn != NULL)
		mysql_close((MYSQL *) dbi->dbconn);

	/* destroy DB instance */
	destroy_sqldbinstance(dbi);
}
Пример #4
0
/*%
 * Properly cleans up a list of database instances.
 * This function is only used when the driver is compiled for
 * multithreaded operation.
 */
static void
ldap_destroy_dblist(db_list_t *dblist) {
	dbinstance_t *ndbi = NULL;
	dbinstance_t *dbi = NULL;

	/* get the first DBI in the list */
	ndbi = ISC_LIST_HEAD(*dblist);

	/* loop through the list */
	while (ndbi != NULL) {
		dbi = ndbi;
		/* get the next DBI in the list */
		ndbi = ISC_LIST_NEXT(dbi, link);
		/* release DB connection */
		if (dbi->dbconn != NULL)
			ldap_unbind_s((LDAP *) dbi->dbconn);
		/* release all memory that comprised a DBI */
		destroy_sqldbinstance(dbi);
	}
	/* release memory for the list structure */
	isc_mem_put(ns_g_mctx, dblist, sizeof(db_list_t));
}
Пример #5
0
/*%
 * create an instance of the driver.  Remember, only 1 copy of the driver's
 * code is ever loaded, the driver has to remember which context it's
 * operating in.  This is done via use of the dbdata argument which is
 * passed into all query functions.
 */
static isc_result_t
postgres_create(const char *dlzname, unsigned int argc, char *argv[],
		void *driverarg, void **dbdata)
{
	isc_result_t result;
	dbinstance_t *dbi = NULL;
	unsigned int j;

#ifdef ISC_PLATFORM_USETHREADS
	/* if multi-threaded, we need a few extra variables. */
	int dbcount;
	db_list_t *dblist = NULL;
	int i;
	char *endp;

#endif /* ISC_PLATFORM_USETHREADS */

	UNUSED(driverarg);
	UNUSED(dlzname);

/* seed random # generator */
	srand( (unsigned)time( NULL ) );


#ifdef ISC_PLATFORM_USETHREADS
	/* if debugging, let user know we are multithreaded. */
	isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
		      DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
		      "Postgres driver running multithreaded");
#else /* ISC_PLATFORM_USETHREADS */
	/* if debugging, let user know we are single threaded. */
	isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
		      DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
		      "Postgres driver running single threaded");
#endif /* ISC_PLATFORM_USETHREADS */

	/* verify we have at least 5 arg's passed to the driver */
	if (argc < 5) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "Postgres driver requires at least "
			      "4 command line args.");
		return (ISC_R_FAILURE);
	}

	/* no more than 8 arg's should be passed to the driver */
	if (argc > 8) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "Postgres driver cannot accept more than "
			      "7 command line args.");
		return (ISC_R_FAILURE);
	}

	/* multithreaded build can have multiple DB connections */
#ifdef ISC_PLATFORM_USETHREADS

	/* check how many db connections we should create */
	dbcount = strtol(argv[1], &endp, 10);
	if (*endp != '\0' || dbcount < 0) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "Postgres driver database connection count "
			      "must be positive.");
		return (ISC_R_FAILURE);
	}

	/* allocate memory for database connection list */
	dblist = isc_mem_get(ns_g_mctx, sizeof(db_list_t));
	if (dblist == NULL)
		return (ISC_R_NOMEMORY);

	/* initialize DB connection list */
	ISC_LIST_INIT(*dblist);

	/*
	 * create the appropriate number of database instances (DBI)
	 * append each new DBI to the end of the list
	 */
	for (i=0; i < dbcount; i++) {

#endif /* ISC_PLATFORM_USETHREADS */

		/* how many queries were passed in from config file? */
		switch(argc) {
		case 5:
			result = build_sqldbinstance(ns_g_mctx, NULL, NULL,
						     NULL, argv[3], argv[4],
						     NULL, &dbi);
			break;
		case 6:
			result = build_sqldbinstance(ns_g_mctx, NULL, NULL,
						     argv[5], argv[3], argv[4],
						     NULL, &dbi);
			break;
		case 7:
			result = build_sqldbinstance(ns_g_mctx, argv[6], NULL,
						     argv[5], argv[3], argv[4],
						     NULL, &dbi);
			break;
		case 8:
			result = build_sqldbinstance(ns_g_mctx, argv[6],
						     argv[7], argv[5], argv[3],
						     argv[4], NULL, &dbi);
			break;
		default:
			/* not really needed, should shut up compiler. */
			result = ISC_R_FAILURE;
		}


		if (result == ISC_R_SUCCESS) {
			isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
				      DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
				      "Postgres driver created database "
				      "instance object.");
		} else { /* unsuccessful?, log err msg and cleanup. */
			isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
				      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
				      "Postgres driver could not create "
				      "database instance object.");
			goto cleanup;
		}

#ifdef ISC_PLATFORM_USETHREADS

		/* when multithreaded, build a list of DBI's */
		ISC_LINK_INIT(dbi, link);
		ISC_LIST_APPEND(*dblist, dbi, link);

#endif

		/* create and set db connection */
		dbi->dbconn = PQconnectdb(argv[2]);
		/*
		 * if db connection cannot be created, log err msg and
		 * cleanup.
		 */
		if (dbi->dbconn == NULL) {
			isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
				      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
				      "Postgres driver could not allocate "
				      "memory for database connection");
			goto cleanup;
		}

		/* if we cannot connect the first time, try 3 more times. */
		for (j = 0;
		     PQstatus((PGconn *) dbi->dbconn) != CONNECTION_OK &&
			     j < 3;
		     j++)
			PQreset((PGconn *) dbi->dbconn);


#ifdef ISC_PLATFORM_USETHREADS

		/*
		 * if multi threaded, let user know which connection
		 * failed.  user could be attempting to create 10 db
		 * connections and for some reason the db backend only
		 * allows 9
		 */
		if (PQstatus((PGconn *) dbi->dbconn) != CONNECTION_OK) {
			isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
				      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
				      "Postgres driver failed to create "
				      "database connection number %u "
				      "after 4 attempts",
				      i + 1);
			goto cleanup;
		}

		/* set DBI = null for next loop through. */
		dbi = NULL;
	}	/* end for loop */

		/* set dbdata to the list we created. */
	*dbdata = dblist;

#else /* ISC_PLATFORM_USETHREADS */
	/* if single threaded, just let user know we couldn't connect. */
	if (PQstatus((PGconn *) dbi->dbconn) != CONNECTION_OK) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "Postgres driver failed to create database "
			      "connection after 4 attempts");
		goto cleanup;
	}

	/*
	 * single threaded build can only use 1 db connection, return
	 * it via dbdata
	 */
	*dbdata = dbi;

#endif /* ISC_PLATFORM_USETHREADS */

	/* hey, we got through all of that ok, return success. */
	return(ISC_R_SUCCESS);

 cleanup:

#ifdef ISC_PLATFORM_USETHREADS
	/*
	 * if multithreaded, we could fail because only 1 connection
	 * couldn't be made.  We should cleanup the other successful
	 * connections properly.
	 */
	postgres_destroy_dblist(dblist);

#else /* ISC_PLATFORM_USETHREADS */
	if (dbi != NULL)
		destroy_sqldbinstance(dbi);

#endif /* ISC_PLATFORM_USETHREADS */
	return(ISC_R_FAILURE);
}
Пример #6
0
/*%
 * create an instance of the driver.  Remember, only 1 copy of the driver's
 * code is ever loaded, the driver has to remember which context it's
 * operating in.  This is done via use of the dbdata argument which is
 * passed into all query functions.
 */
static isc_result_t
mysql_create(const char *dlzname, unsigned int argc, char *argv[],
	     void *driverarg, void **dbdata)
{
	isc_result_t result;
	dbinstance_t *dbi = NULL;
	char *tmp = NULL;
	char *dbname = NULL;
	char *host = NULL;
	char *user = NULL;
	char *pass = NULL;
	char *socket = NULL;
	int port;
	MYSQL *dbc;
	char *endp;
	int j;
	unsigned int flags = 0;
#if MYSQL_VERSION_ID >= 50000
        my_bool auto_reconnect = 1;
#endif

	UNUSED(driverarg);
	UNUSED(dlzname);

	/* verify we have at least 4 arg's passed to the driver */
	if (argc < 4) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "mysql driver requires "
			      "at least 4 command line args.");
		return (ISC_R_FAILURE);
	}

	/* no more than 8 arg's should be passed to the driver */
	if (argc > 8) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "mysql driver cannot accept "
			      "more than 7 command line args.");
		return (ISC_R_FAILURE);
	}

	/* parse connection string and get paramters. */

	/* get db name - required */
	dbname = getParameterValue(argv[1], "dbname=");
	if (dbname == NULL) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "mysql driver requires a dbname parameter.");
		result = ISC_R_FAILURE;
		goto full_cleanup;
	}

	/* get db port.  Not required, but must be > 0 if specified */
	tmp = getParameterValue(argv[1], "port=");
	if (tmp == NULL) {
		port = 0;
	} else {
		port = strtol(tmp, &endp, 10);
		if (*endp != '\0' || port < 0) {
			isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
				      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
				      "Mysql driver port "
				      "must be a positive number.");
			isc_mem_free(ns_g_mctx, tmp);
			result = ISC_R_FAILURE;
			goto full_cleanup;
		}
		isc_mem_free(ns_g_mctx, tmp);
	}

	/* how many queries were passed in from config file? */
	switch(argc) {
	case 4:
		result = build_sqldbinstance(ns_g_mctx, NULL, NULL, NULL,
					     argv[2], argv[3], NULL, &dbi);
		break;
	case 5:
		result = build_sqldbinstance(ns_g_mctx, NULL, NULL, argv[4],
					     argv[2], argv[3], NULL, &dbi);
		break;
	case 6:
		result = build_sqldbinstance(ns_g_mctx, argv[5], NULL, argv[4],
					     argv[2], argv[3], NULL, &dbi);
		break;
	case 7:
		result = build_sqldbinstance(ns_g_mctx, argv[5],
					     argv[6], argv[4],
					     argv[2], argv[3], NULL, &dbi);
		break;
	case 8:
		result = build_sqldbinstance(ns_g_mctx, argv[5],
					     argv[6], argv[4],
					     argv[2], argv[3], argv[7], &dbi);
		break;
	default:
		/* not really needed, should shut up compiler. */
		result = ISC_R_FAILURE;
	}

	/* unsuccessful?, log err msg and cleanup. */
	if (result != ISC_R_SUCCESS) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "mysql driver could not create "
			      "database instance object.");
		result = ISC_R_FAILURE;
		goto cleanup;
	}

	/* create and set db connection */
	dbi->dbconn = mysql_init(NULL);

	/* if db connection cannot be created, log err msg and cleanup. */
	if (dbi->dbconn == NULL) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "mysql driver could not allocate "
			      "memory for database connection");
		result = ISC_R_FAILURE;
		goto full_cleanup;
	}

	tmp = getParameterValue(argv[1], "compress=");
	if (tmp != NULL) {
		if (strcasecmp(tmp, "true") == 0)
			flags = CLIENT_COMPRESS;
		isc_mem_free(ns_g_mctx, tmp);
	}

	tmp = getParameterValue(argv[1], "ssl=");
	if (tmp != NULL) {
		if (strcasecmp(tmp, "true") == 0)
			flags = flags | CLIENT_SSL;
		isc_mem_free(ns_g_mctx, tmp);
	}

	tmp = getParameterValue(argv[1], "space=");
	if (tmp != NULL) {
		if (strcasecmp(tmp, "ignore") == 0)
			flags = flags | CLIENT_IGNORE_SPACE;
		isc_mem_free(ns_g_mctx, tmp);
	}

	dbc = NULL;
	host = getParameterValue(argv[1], "host=");
	user = getParameterValue(argv[1], "user="******"pass="******"socket=");

#if MYSQL_VERSION_ID >= 50000
	/* enable automatic reconnection. */
        if (mysql_options((MYSQL *) dbi->dbconn, MYSQL_OPT_RECONNECT,
			  &auto_reconnect) != 0) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_WARNING,
			      "mysql driver failed to set "
			      "MYSQL_OPT_RECONNECT option, continuing");
	}
#endif

	for (j=0; dbc == NULL && j < 4; j++)
		dbc = mysql_real_connect((MYSQL *) dbi->dbconn, host,
					 user, pass, dbname, port, socket,
					 flags);

	/* let user know if we couldn't connect. */
	if (dbc == NULL) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "mysql driver failed to create "
			      "database connection after 4 attempts");
		result = ISC_R_FAILURE;
		goto full_cleanup;
	}

	/* return db connection via dbdata */
	*dbdata = dbi;

	result = ISC_R_SUCCESS;
	goto cleanup;

 full_cleanup:

	destroy_sqldbinstance(dbi);

 cleanup:

	if (dbname != NULL)
		isc_mem_free(ns_g_mctx, dbname);
	if (host != NULL)
		isc_mem_free(ns_g_mctx, host);
	if (user != NULL)
		isc_mem_free(ns_g_mctx, user);
	if (pass != NULL)
		isc_mem_free(ns_g_mctx, pass);
	if (socket != NULL)
		isc_mem_free(ns_g_mctx, socket);


	return result;
}
Пример #7
0
/*% constructs a sql dbinstance (DBI) */
isc_result_t
sdlzh_build_sqldbinstance(isc_mem_t *mctx, const char *allnodes_str,
			 const char *allowxfr_str, const char *authority_str,
			 const char *findzone_str, const char *lookup_str,
			 const char *countzone_str, dbinstance_t **dbi)
{

	isc_result_t result;
	dbinstance_t *db = NULL;

	REQUIRE(dbi != NULL && *dbi == NULL);
	REQUIRE(mctx != NULL);

	/* allocate and zero memory for driver structure */
	db = isc_mem_get(mctx, sizeof(dbinstance_t));
	if (db == NULL) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "Could not allocate memory for "
			      "database instance object.");
		return (ISC_R_NOMEMORY);
	}
	memset(db, 0, sizeof(dbinstance_t));
	db->dbconn = NULL;
	db->client = NULL;
	db->record = NULL;
	db->zone = NULL;
	db->mctx = NULL;
	db->query_buf = NULL;
	db->allnodes_q = NULL;
	db->allowxfr_q = NULL;
	db->authority_q = NULL;
	db->findzone_q = NULL;
	db->countzone_q = NULL;
	db->lookup_q = NULL;

	/* attach to the memory context */
	isc_mem_attach(mctx, &db->mctx);

	/* initialize the reference count mutex */
	result = isc_mutex_init(&db->instance_lock);
	if (result != ISC_R_SUCCESS) {
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "isc_mutex_init() failed: %s",
				 isc_result_totext(result));
		goto cleanup;
	}

	/* build the all nodes query list */
	result = build_querylist(mctx, allnodes_str, &db->zone,
				 &db->record, &db->client,
				 &db->allnodes_q, SDLZH_REQUIRE_ZONE);
	/* if unsuccessful, log err msg and cleanup */
	if (result != ISC_R_SUCCESS) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "Could not build all nodes query list");
		goto cleanup;
	}

	/* build the allow zone transfer query list */
	result = build_querylist(mctx, allowxfr_str, &db->zone,
				 &db->record, &db->client,
				 &db->allowxfr_q,
				 SDLZH_REQUIRE_ZONE | SDLZH_REQUIRE_CLIENT);
	/* if unsuccessful, log err msg and cleanup */
	if (result != ISC_R_SUCCESS) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "Could not build allow xfr query list");
		goto cleanup;
	}

	/* build the authority query, query list */
	result = build_querylist(mctx, authority_str, &db->zone,
				 &db->record, &db->client,
				 &db->authority_q, SDLZH_REQUIRE_ZONE);
	/* if unsuccessful, log err msg and cleanup */
	if (result != ISC_R_SUCCESS) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "Could not build authority query list");
		goto cleanup;
	}

	/* build findzone query, query list */
	result = build_querylist(mctx, findzone_str, &db->zone,
				 &db->record, &db->client,
				 &db->findzone_q, SDLZH_REQUIRE_ZONE);
	/* if unsuccessful, log err msg and cleanup */
	if (result != ISC_R_SUCCESS) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "Could not build find zone query list");
		goto cleanup;
	}

	/* build countzone query, query list */
	result = build_querylist(mctx, countzone_str, &db->zone,
				 &db->record, &db->client,
				 &db->countzone_q, SDLZH_REQUIRE_ZONE);
	/* if unsuccessful, log err msg and cleanup */
	if (result != ISC_R_SUCCESS) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "Could not build count zone query list");
		goto cleanup;
	}

	/* build lookup query, query list */
	result = build_querylist(mctx, lookup_str, &db->zone,
				 &db->record, &db->client,
				 &db->lookup_q, SDLZH_REQUIRE_RECORD);
	/* if unsuccessful, log err msg and cleanup */
	if (result != ISC_R_SUCCESS) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "Could not build lookup query list");
		goto cleanup;
	}

	/* pass back the db instance */
	*dbi = (dbinstance_t *) db;

	/* return success */
	return (ISC_R_SUCCESS);

 cleanup:
	/* destroy whatever was build of the db instance */
	destroy_sqldbinstance(db);
	/* return failure */
	return (ISC_R_FAILURE);
}
Пример #8
0
static void
destroy_odbc_instance(odbc_instance_t *odbc_inst) {

#ifdef ISC_PLATFORM_USETHREADS

	dbinstance_t *ndbi = NULL;
	dbinstance_t *dbi = NULL;

	/* get the first DBI in the list */
	ndbi = ISC_LIST_HEAD(*odbc_inst->db);

	/* loop through the list */
	while (ndbi != NULL) {
		dbi = ndbi;
		/* get the next DBI in the list */
		ndbi = ISC_LIST_NEXT(dbi, link);

		/* if we have a connection / statement object in memory */
		if (dbi->dbconn != NULL) {
			/* free statement handle */
			if (((odbc_db_t *) (dbi->dbconn))->stmnt != NULL) {
				SQLFreeHandle(SQL_HANDLE_STMT,
					      ((odbc_db_t *)
					       (dbi->dbconn))->stmnt);
				((odbc_db_t *) (dbi->dbconn))->stmnt = NULL;
			}

			/* disconnect from database & free connection handle */
			if (((odbc_db_t *) (dbi->dbconn))->dbc != NULL) {
				SQLDisconnect(((odbc_db_t *)
					       dbi->dbconn)->dbc);
				SQLFreeHandle(SQL_HANDLE_DBC,
					      ((odbc_db_t *)
					       (dbi->dbconn))->dbc);
				((odbc_db_t *) (dbi->dbconn))->dbc = NULL;
			}

			/* free memory that held connection & statement. */
			isc_mem_free(ns_g_mctx, dbi->dbconn);
		}
		/* release all memory that comprised a DBI */
		destroy_sqldbinstance(dbi);
	}
	/* release memory for the list structure */
	isc_mem_put(ns_g_mctx, odbc_inst->db, sizeof(db_list_t));

#else /* ISC_PLATFORM_USETHREADS */

	/* free statement handle */
	if (((odbc_db_t *) (odbc_inst->db->dbconn))->stmnt != NULL) {
		SQLFreeHandle(SQL_HANDLE_STMT,
			      ((odbc_db_t *) (odbc_inst->db->dbconn))->stmnt);
		((odbc_db_t *) (odbc_inst->db->dbconn))->stmnt = NULL;
	}

	/* disconnect from database, free connection handle */
	if (((odbc_db_t *) (odbc_inst->db->dbconn))->dbc != NULL) {
		SQLDisconnect(((odbc_db_t *) (odbc_inst->db->dbconn))->dbc);
		SQLFreeHandle(SQL_HANDLE_DBC,
			      ((odbc_db_t *) (odbc_inst->db->dbconn))->dbc);
		((odbc_db_t *) (odbc_inst->db->dbconn))->dbc = NULL;
	}
	/*	free mem for the odbc_db_t structure held in db */
	if (((odbc_db_t *) odbc_inst->db->dbconn) != NULL) {
		isc_mem_free(ns_g_mctx, odbc_inst->db->dbconn);
		odbc_inst->db->dbconn = NULL;
	}

	if (odbc_inst->db != NULL)
		destroy_sqldbinstance(odbc_inst->db);

#endif /* ISC_PLATFORM_USETHREADS */


	/* free sql environment */
	if (odbc_inst->sql_env != NULL)
		SQLFreeHandle(SQL_HANDLE_ENV, odbc_inst->sql_env);

	/* free ODBC instance strings */
	if (odbc_inst->dsn != NULL)
		isc_mem_free(ns_g_mctx, odbc_inst->dsn);
	if (odbc_inst->pass != NULL)
		isc_mem_free(ns_g_mctx, odbc_inst->pass);
	if (odbc_inst->user != NULL)
		isc_mem_free(ns_g_mctx, odbc_inst->user);

	/* free memory for odbc_inst */
	if (odbc_inst != NULL)
		isc_mem_put(ns_g_mctx, odbc_inst, sizeof(odbc_instance_t));

}