[MDEV-5155] com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource cannot connect to MariaDB with password Created: 2013-10-18 Updated: 2018-01-19 Resolved: 2018-01-19 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Authentication and Privilege System |
| Affects Version/s: | 10.0.4, 5.2.14, 5.3.12, 5.5.33a, 10.0, 10.1 |
| Fix Version/s: | N/A |
| Type: | Bug | Priority: | Minor |
| Reporter: | Tóth István | Assignee: | Unassigned |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | upstream, verified | ||
| Environment: |
Debian 6 x86_64, Connector/J 5.1.20 |
||
| Attachments: |
|
| Description |
|
My application runs on the Resin application server, and uses JDBC Connection pooling. After upgrading The application server is resin 4.0.18, the JDBC connector is Connector/J 5.1.20 I have done some debugging, and the problem seems to be that when the Connection pool hands a connection to the application, it performs a 'change user' command to reset the connection, and MariaDB cannot authenticate this command the way MySQL can. When the user has no password set, the JDBC pooling + MariaDB connection works. Specifically, MySQL and MariaDB behaves the same way, until the client issues a 'change user' request. My test setup: Client workstation: 10.6.118.61 The test cases: server: MySQL server server: MariaDB server server: MariaDB server server: MySQL server server: MariaDB server I have attached the packet capture files for all five test cases. |
| Comments |
| Comment by Tóth István [ 2013-10-18 ] |
|
standalone test case |
| Comment by Tóth István [ 2013-10-18 ] |
|
I have also managed to create a standalone test case. If you point it to a Mysql db, it connects, if you point it to MariaDB, it fails. |
| Comment by Tóth István [ 2013-10-26 ] |
|
I did some more debugging. The connection failure is caused by Mariadb not sending the scramble with the According to http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchRequest the auth plugin data is not optional (even though a scramble may already have been sent during the initial connect.), and Connector/J 5.1.20 has the same expectation. The attached patch (against 5.5) makes sure that scramble is always sent when replying to a change user command. This patch fixes the attached test case. |
| Comment by Tóth István [ 2013-10-26 ] |
|
Proposed fix |
| Comment by Elena Stepanova [ 2013-10-28 ] |
|
Hi, Thanks for the analysis, but I have a question about the test case you provided before we can proceed. |
| Comment by Tóth István [ 2013-10-28 ] |
|
You are right on both cases. The 'badpassword' in the examples is the actual (working) password, though in hindsight it was not a good choice for clarity. All the java test case does is try to get java.sql.Connection object via the com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource object, thus emulating, in the simplest possible way, the operation of a java Connection pooling library that uses the ConnectionPoolDataSource interface. To use the test case, simply edit the .java file, substitute a known working server, db, username, and password (i.e. one that works from the same host via the mysql cli) and run it. The corrent behaviour is getting a connection, printing some data about, and then exiting (as it happens with MySql). The java code in itself is not interesting, it is just a simple way to issue a "change user" command to the database, If you wrote some C code that logs in to the DB server, then issues the "change user" command, the bug would trigger the same way. If you are not familiar with Java, I can give you the exact command sequence to compile and run the test. |
| Comment by Elena Stepanova [ 2013-10-28 ] |
|
Thanks, I'm no expert in Java, but to this extent I'm passable. So, it was my theory at the beginning that the user/password/database combination is supposed to exist, and i created it, and the test went equally okay both with MySQL and MariaDB: elenst@ubuntu12-04:~/mdev5155$ java MariaDBTestCase That made me doubt that I understood the idea of your test correctly. Although, I have JDBC of 5.1.16-2, maybe it's the difference. I'll try 5.1.20. |
| Comment by Tóth István [ 2013-10-28 ] |
|
Very strange. I could reproduce the failure on two different computers, with three different MariaDB builds (debian, fedora, and source) |
| Comment by Elena Stepanova [ 2013-10-28 ] |
|
Yes, here is the setup on MySQL side: MariaDB [test]> create database db; MariaDB [test]> grant all on db.* to stoty@localhost identified by 'badpassword'; Authentication via MySQL client also works as expected (fails without a password, passes with the password): elenst@ubuntu12-04:/data/releases/mariadb-5.5.33a-linux-x86_64$ bin/mysql -ustoty db Copyright (c) 2000, 2013, Oracle, Monty Program Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [db]> The test case output: elenst@ubuntu12-04:~/mdev5155$ java MariaDBTestCase The only difference on the test side is the server name: elenst@ubuntu12-04:~/mdev5155$ diff -u orig/MariaDBTestCase.java MariaDBTestCase.java // Setting up the DataSource object
It's still with 5.1.16 though, I don't rule out that there is a difference. I'll try it out shortly. |
| Comment by Tóth István [ 2013-10-28 ] |
|
I've tried it also, 5.1.16 indeed works. |
| Comment by Elena Stepanova [ 2013-10-28 ] |
|
Right, I can also reproduce it with 5.1.26. java.sql.SQLException: Access denied for user 'stoty'@'localhost' (using password: NO) The suggested patch fixes it for 5.1.26, but unfortunately breaks it for 5.1.16: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Got packets out of order Nevertheless, the problem does exist. |
| Comment by Elena Stepanova [ 2013-10-28 ] |
|
Reproducible with the provided test case (replace server1 with whatever you have, I used 127.0.0.1) and with Connector/J 5.1.26, apparently with 5.1.20 too. |
| Comment by Tóth István [ 2013-10-28 ] |
|
proposed patch V2 |
| Comment by Tóth István [ 2013-10-28 ] |
|
I have attached a new version of the patch, that sends the scramble only if the change user packet does not have contain a password. With this patch, the test case connects with both 5.1.16 and 5.1.20 driver. |
| Comment by Sergei Golubchik [ 2013-11-09 ] |
|
5.1.20 (that's where capture files come from, right?) breaks the protocol. In This was fixed as a part of http://bugs.mysql.com/bug.php?id=41752, according to the changelog in 5.1.22. Because of that bug, the server was sending AuthSwitchRequest packet (to tell A protocol specifies, indeed, that the auth plugin data is not optional. But http://bazaar.launchpad.net/~mysql/mysql-server/5.5/view/head:/sql-common/client.c#L4289 So, MySQL implementation of server-side mysql_native_password had a bug of Now, without AuthSwitchRequest it doesn't work either, because Connector/J But with MySQL it works, because of the same bug — MySQL always sends I'll report a bug to MySQL about it. |
| Comment by Tóth István [ 2013-11-12 ] |
|
Yes, the attached dumps are recoring 5.1.20 behaviour. I have attached a patch against Connector/J 5.1.27 that makes it behave according to your description of the protocol. |
| Comment by Tóth István [ 2013-11-12 ] |
|
tenative patch for Connector/J 5.1.27 |
| Comment by Tóth István [ 2013-11-13 ] |
|
I have successfully tested the patch against Mysql 5.5.31 as well. |
| Comment by Sergei Golubchik [ 2013-11-13 ] |
|
Yes, I've already reported a bug at bugs.mysql.com, let's hope it'll be fixed in the next release. |
| Comment by Elena Stepanova [ 2015-04-04 ] |
|
Still reproducible with Connector/J 5.1.32 and MariaDB 10.1 (10.1.4 pre-release). |
| Comment by Daniel Black [ 2017-12-30 ] |
|
upstream bug reports a fix in Connector/J 5.1.36 (untested by me) |
| Comment by Daniel Black [ 2018-01-19 ] |
|
Fixed in upstream jdbc connector. |