Bug #58877 MySqlProviderServices.DbDatabaseExists fails due to lost password in connstring
Submitted: 10 Dec 2010 20:49 Modified: 14 Dec 2010 11:55
Reporter: Chris Thornett Email Updates:
Status: Not a Bug Impact on me:
None 
Category:Connector / NET Severity:S2 (Serious)
Version:6.3.5.0 OS:Microsoft Windows (XP)
Assigned to: CPU Architecture:Any
Tags: .Net4, entity framework

[10 Dec 2010 20:49] Chris Thornett
Description:
Using Mysql Connector/Net 6.3.5.0 with .Net 4 framework

If MySqlProviderServices.DbDatabaseExists is called on a connection that has already been opened and closed, it fails with a MySqlException "Access denied for user xxx (using password: NO)"

This appears to be because it uses the connection.ConnectionString property of the connection object to determine how to connect to the database; and somewhere in the process of MySqlConnection.Open(), this property is changed, eliminating the 'password' clause. So when it DbDatabaseExists creates a new connection object, it does so without the password.

Microsoft's Entity Framework CTP4 seems to require these steps to be taken in this order - see http://blogs.msdn.com/b/adonet/archive/2010/07/14/ctp4codefirstwalkthrough.aspx

How to repeat:
using System;
using MySql.Data.MySqlClient;
using System.Diagnostics;
using System.Data;
using System.Data.Common;

namespace Testing
{
    public class ConnectionTest
    {
        public static void Main()
        {
            string initialConnectionString = "server=localhost;database=test;uid=root;password=mypass;";

            var connection = new MySql.Data.MySqlClient.MySqlConnection(initialConnectionString);
            Debug.Assert(connection.ConnectionString.Contains("password"),"The password is present",connection.ConnectionString);

            DbProviderServices providerService = DbProviderServices.GetProviderServices(connection);

            connection.Open();
            Debug.Assert(connection.State == ConnectionState.Open, "Connected ok");
            Debug.Assert( ! connection.ConnectionString.Contains("password"), "The password has now disappeared", connection.ConnectionString); 

            connection.Close();

            connection.Open();
            Debug.Assert(connection.State == ConnectionState.Open, "Still connected ok");
            connection.Close();

            //this line throws a MysqlException
            providerService.DatabaseExists(connection, null, null);
        }
    }
}

Suggested fix:
DbDatabaseExists needs to be able to get the full connection details from MysqlConnection, somehow.
[14 Dec 2010 10:03] Tonci Grgin
.NET FW in use by the test

Attachment: Bug58877.png (image/png, text), 24.03 KiB.

[14 Dec 2010 10:04] Tonci Grgin
Hi Chris and thanks for your report.

As can be seen, I "run" your code under .NET FW 4.0 but the DbProviderServices can not be resolved. So please provide functioning test case that I can use.
[14 Dec 2010 10:23] Chris Thornett
Hi, thanks for the response.

I didn't mention the References for the above test case.
They are:
    <Reference Include="MySql.Data, Version=6.3.5.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL" />
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Data.Entity" />

I expect System.Data.Entity is what you were missing.

My envirionment.version is 4.0.30319.1

Would it help if I uploaded a zip of the project?
[14 Dec 2010 10:30] Tonci Grgin
Sure Chris, please do.
[14 Dec 2010 10:51] Chris Thornett
I have also installed Microsoft ADO.NET Entity Framework Feature Community Technology Preview 5 
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=35adb688-f8a7-4d28-86b1-b62353...

but I don't believe that makes a difference - it behaves the same if I uninstall it.
[14 Dec 2010 11:47] Tonci Grgin
Verified just like described with attached test case.

One note, there is a stray connection.Close() at the end of test:
    Debug.Assert(connection.State == ConnectionState.Open, "Still connected ok");
    connection.Close();
, comment it out.
[14 Dec 2010 11:52] Tonci Grgin
Chris, my bad... This is not a bug cause if you want to persist sensitive info you should add "Persist Security Info=true" to your connection string.

Of course, your assertion Debug.Assert(!connection.ConnectionString.Contains("password"), ... will fail but the test case will work.
[14 Dec 2010 11:55] Chris Thornett
> This is not a bug cause if you want to persist sensitive info you should add "Persist Security Info=true" to your connection string.

Ah, I didn't know about that parameter.

Thanks very much for taking the time to look at this issue!