Bug #30774 Username argument to SQLConnect used incorrectly in C/ODBC 3.51.19
Submitted: 3 Sep 2007 20:00 Modified: 13 Sep 2007 11:32
Reporter: Tom Donovan (Candidate Quality Contributor) Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / ODBC Severity:S2 (Serious)
Version:3.51.19 OS:Microsoft Windows (win2k sp4)
Assigned to: Jim Winstead CPU Architecture:Any

[3 Sep 2007 20:00] Tom Donovan
Description:
The username and password passed to SQLConnect may be used incorrectly.  
Observerd on win2k-sp4 with Connect/ODBC 3.51.19 to MySQL 5.0.48.  
The problem does not happen with 3.51.12.

Opening a datasource named 'mySQLodbc' with username 'root' and a blank password produces this error with 3.51.19:

HY000 [MySQL][ODBC 3.51 Driver]Access denied for user 'root1'@'localhost' (using password: NO)

Note that the character '1' has incorrectly been appended to the username.
No error is observed with 3.51.12.

How to repeat:
/* repro program */
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
main(int argc, char **argv) {
    SQLRETURN rc;
    SQLHANDLE henv;
    SQLHANDLE hdbc;
    char *datasource="mySQLodbc";
    char *user      ="root";
    char *password  ="";
    SQLCHAR out[1024];
    SQLSMALLINT outlen;
    SQLCHAR buffer[512];
    SQLCHAR sqlstate[128];
    SQLINTEGER native;
    SQLSMALLINT reslength;
    int i;

    rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
    rc = SQLSetEnvAttr(henv,SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, 0);
    rc = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
    rc = SQLConnect(hdbc, datasource, (SQLSMALLINT) strlen(datasource),user, (SQLSMALLINT) strlen(user),password, (SQLSMALLINT) strlen(password));
    for (i=1 ; (rc = SQLGetDiagRec(SQL_HANDLE_DBC, hdbc, i, sqlstate, &native, buffer, sizeof(buffer), &reslength))==0 ; i++) {
        printf("\t %s %s\n", sqlstate, buffer);
    }
    rc = SQLDisconnect(hdbc);
    rc = SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
    rc = SQLFreeHandle(SQL_HANDLE_ENV, henv);
}

Suggested fix:
SQLConnect in driver/connect.c line 285 does not use the cbDSN, cbUID and cbAuth arguments, but expects the szDSN, szUID, and szAuth to be NULL-terminated.

This is incorrect per http://msdn2.microsoft.com/en-us/library//ms711810.aspx

Running the test program with a debug build of 3.51.19 shows that the argument cbUID = 4 on entry to myodbc3!SQLConnect when the error occurs.  If the szUID argument had been correctly truncated, the username would be 'root' instead of 'root1'.
[4 Sep 2007 1:49] Tom Donovan
Looking again, szDSN and cbDSN are handled correctly.  
Only the cbUID and cbAuth string lengths are ignored in 3.51.19.
[4 Sep 2007 10:45] Susanne Ebrecht
Hi Tom,

thanks for sending the bug report. We will fix it soon.

Regards,

Susanne
[4 Sep 2007 20:08] Jim Winstead
Use lengths passed to SQLConnect

Attachment: bug30774.patch (text/plain), 2.56 KiB.

[5 Sep 2007 17:46] Bogdan Degtyariov
Susanne,

probably your Unix server had been configured so, that all users from localhost were able to connect. The test case worked well without patch when I granted access to all localhost connections in Windows. I see no other possibilities of successful connecting in Linux when the username is malformed etc.
The problem with ignoring the lengths of the parameters in SQLConnect seems to be existing for ages. 
Thanks Jim for his patch.
[5 Sep 2007 17:51] Jim Winstead
The fix for this bug has been committed to the repository, and will be in the next release (3.51.20).
[13 Sep 2007 11:32] MC Brown
A note has been added to the 3.51.20 changelog: 

The specified length of the username and authentication parameters to SQLConnect() were not being honored.