Skip to Content.
Sympa Menu

freetds - [freetds] Can't login to SQL Server using TDSVER 7.2 when user's default database is mirrored

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • 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;
}



Archive powered by MHonArc 2.6.24.

Top of Page