MXS-2111: Use authentication_string when password is empty

If the password field in mysql.user is empty, it is possible that the
actual password is stored in the authentication_string field. Most of the
time this happens due to MDEV-16774 which causes the password to be stored
in the authentication_string field.

Also added a test case that verifies the problem and that it is fixed by
this commit.
This commit is contained in:
Markus Mäkelä 2018-10-26 15:12:54 +03:00
parent 2594a0d913
commit 93b9ed744f
No known key found for this signature in database
GPG Key ID: 72D48FCE664F7B19
3 changed files with 41 additions and 2 deletions

View File

@ -981,6 +981,9 @@ add_test_executable(mxs2043_select_for_update.cpp mxs2043_select_for_update repl
# MXS-2054: Hybrid clusters
add_test_executable(mxs2054_hybrid_cluster.cpp mxs2054_hybrid_cluster mxs2054_hybrid_cluster LABELS REPL_BACKEND)
# MXS-2111: mysql.user sometimes has SHA1 in authentication_string instead of password
add_test_executable(mxs2111_auth_string.cpp mxs2111_auth_string replication LABELS REPL_BACKEND)
# MXS-2115: Automatic version_string detection
add_test_executable(mxs2115_version_string.cpp mxs2115_version_string replication LABELS REPL_BACKEND)

View File

@ -0,0 +1,32 @@
/**
* MXS-2111: The password is stored in `authentication_string` instead of `password` due to MDEV-16774
*/
#include "testconnections.h"
int main(int argc, char **argv)
{
TestConnections::require_repl_version("10.2.0");
TestConnections test(argc, argv);
auto batch = [&](std::vector<std::string> queries){
test.maxscales->connect();
for (const auto& a: queries)
{
test.try_query(test.maxscales->conn_rwsplit[0], "%s", a.c_str());
}
test.maxscales->disconnect();
};
batch({"CREATE USER 'test' IDENTIFIED BY 'test'",
"GRANT SELECT ON *.* TO test",
"SET PASSWORD FOR 'test' = PASSWORD('test')"});
MYSQL* conn = open_conn(test.maxscales->rwsplit_port[0], test.maxscales->IP[0], "test", "test");
test.try_query(conn, "SELECT 1");
mysql_close(conn);
batch({"DROP USER 'test'"});
return test.global_result;
}

View File

@ -56,11 +56,15 @@
const char* mariadb_102_users_query =
// `t` is users that are not roles
"WITH RECURSIVE t AS ( "
" SELECT u.user, u.host, d.db, u.select_priv, u.password AS password, u.is_role, u.default_role"
" SELECT u.user, u.host, d.db, u.select_priv, "
" IF(u.password <> '', u.password, u.authentication_string) AS password, "
" u.is_role, u.default_role"
" FROM mysql.user AS u LEFT JOIN mysql.db AS d "
" ON (u.user = d.user AND u.host = d.host) "
" UNION "
" SELECT u.user, u.host, t.db, u.select_priv, u.password AS password, u.is_role, u.default_role "
" SELECT u.user, u.host, t.db, u.select_priv, "
" IF(u.password <> '', u.password, u.authentication_string), "
" u.is_role, u.default_role "
" FROM mysql.user AS u LEFT JOIN mysql.tables_priv AS t "
" ON (u.user = t.user AND u.host = t.host)"
"), users AS ("