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

Matt Grimm <[email protected]>
Newsgroups gmane.comp.db.tds.freetds
Message-ID <CAG4_kQv=KDy-k+B5wroe+ABuNR-17MD_QzYkuE9soh_pn8Khxg@mail.gmail.com>
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.

_______________________________________________
FreeTDS mailing list
[email protected]
http://lists.ibiblio.org/mailman/listinfo/freetds
mssql2005_1.dump (application/octet-stream, 4.5 KB) - not displayed
mssql2005_2.dump (application/octet-stream, 2.8 KB) - not displayed
mssql2008.dump (application/octet-stream, 2.8 KB) - not displayed
tdstester.c (text/x-csrc, 2.6 KB)
#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;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.