freetds AT lists.ibiblio.org
Subject: FreeTDS Development Group
List archive
[freetds] Can't login to SQL Server using TDSVER 7.2 when user's default database is mirrored
- From: Matt Grimm <matt.t.grimm+freetds AT gmail.com>
- To: freetds AT lists.ibiblio.org
- Subject: [freetds] Can't login to SQL Server using TDSVER 7.2 when user's default database is mirrored
- Date: Thu, 5 Sep 2013 14:25:24 -0600
Hello,
I've discovered a login issue with FreeTDS connecting to SQL Server using
TDSVER 7.2 when the user's default database is a non-system database and is
mirrored to another server.
The problem exists under following conditions:
* OS is Linux, RHEL 5.4
* Driver manager is unixODBC 2.3.1
* FreeTDS version is 0.91 - 0.92.608 (have not tested other versions)
* TDSVER = 7.2 (7.1 and 8.0 are ok)
* SQL Server versions tested are 2005 and 2008
* Using SQL Server authentication (not domain credentials)
* A non-system default database (not "master") is assigned to the user
account on one server
* The database is mirrored to a secondary server
In this case, I /can/ login to the server on which the user account has the
system database "master" assigned as default. However, I /can't/ login to
the other server, where there is a user-defined default database assigned
that is also mirrored to a secondary server.
The exact symptoms vary between server versions:
SQL Server 2005 - 9.00.5266.00 (X64)
- Error message: "Bad token from the server: Datastream processing
out of sync".
SQL Server 2005 - 9.00.4266.00 (X64)
SQL Server 2008 (SP3) - 10.0.5788.0 (X64)
- Login hangs. See attachments for trace logs.
I'm attaching the trace logs from TDSDUMP. I scrubbed out the personally
identifying packet data, but if that's needed I can provide it privately.
I've also attached the basic C test script I'm using to troubleshoot this
issue.
Regards,
m.
Attachment:
mssql2005_1.dump
Description: Binary data
Attachment:
mssql2005_2.dump
Description: Binary data
Attachment:
mssql2008.dump
Description: Binary data
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
SQLHENV env; // ODBC environment handle
long errno; // Result of functions
SQLHDBC hdbc; // Connection handle
SQLHSTMT hstmt; // Statement handle
char stat[10]; // SQL status
SQLINTEGER err; // SQL error
SQLSMALLINT msglen; // SQL message length
char msg[200];
void
cleanup()
{
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, env);
}
void
handle_error()
{
printf("Error code: %d\n", errno);
SQLGetDiagRec(SQL_HANDLE_DBC, hdbc, 1, (SQLCHAR*) stat, &err, (SQLCHAR*) msg, 100, &msglen);
printf("SQL error: %s (%d)\n", msg, err);
cleanup();
exit(1);
}
int
main(int argc, char *argv[])
{
// Process command line arguments
if (argc < 4 || argc > 5) {
printf("usage: %s hostname username password [query]\n", argv[0]);
exit(1);
}
const char* hostname = argv[1];
const char* username = argv[2];
const char* password = argv[3];
const char* query = argc == 5 ? argv[4] : "select @@version";
// -------------------------------------------------------------------------
// Connect
printf("Connecting...");
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*) SQL_OV_ODBC3, 0);
SQLAllocHandle(SQL_HANDLE_DBC, env, &hdbc);
SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER*) 5, 0);
errno = SQLConnect(hdbc, (SQLCHAR*) hostname, SQL_NTS,
(SQLCHAR*) username, SQL_NTS,
(SQLCHAR*) password, SQL_NTS);
if (errno == SQL_SUCCESS || errno == SQL_SUCCESS_WITH_INFO) {
printf("done.\n");
}
else {
handle_error();
}
// -------------------------------------------------------------------------
// Execute query
printf("Executing stmt...");
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
errno = SQLExecDirect(hstmt, (SQLCHAR*) query, SQL_NTS);
if (errno == SQL_SUCCESS || errno == SQL_SUCCESS_WITH_INFO || errno == SQL_NO_DATA) {
printf("done.\n");
}
else {
handle_error();
}
// -------------------------------------------------------------------------
// Get first field from first row of result set
char buffer[512];
SQLFetch(hstmt);
SQLGetData(hstmt, 1, SQL_C_CHAR, buffer, sizeof(buffer), NULL);
printf("Result: %s\n", buffer);
cleanup();
return 0;
}
-
[freetds] Can't login to SQL Server using TDSVER 7.2 when user's default database is mirrored,
Matt Grimm, 09/05/2013
- Re: [freetds] Can't login to SQL Server using TDSVER 7.2 when user's default database is mirrored, James K. Lowden, 09/05/2013
Archive powered by MHonArc 2.6.24.