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:
@ -981,6 +981,9 @@ add_test_executable(mxs2043_select_for_update.cpp mxs2043_select_for_update repl
|
|||||||
# MXS-2054: Hybrid clusters
|
# MXS-2054: Hybrid clusters
|
||||||
add_test_executable(mxs2054_hybrid_cluster.cpp mxs2054_hybrid_cluster mxs2054_hybrid_cluster LABELS REPL_BACKEND)
|
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
|
# MXS-2115: Automatic version_string detection
|
||||||
add_test_executable(mxs2115_version_string.cpp mxs2115_version_string replication LABELS REPL_BACKEND)
|
add_test_executable(mxs2115_version_string.cpp mxs2115_version_string replication LABELS REPL_BACKEND)
|
||||||
|
|
||||||
|
32
maxscale-system-test/mxs2111_auth_string.cpp
Normal file
32
maxscale-system-test/mxs2111_auth_string.cpp
Normal 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;
|
||||||
|
}
|
@ -56,11 +56,15 @@
|
|||||||
const char* mariadb_102_users_query =
|
const char* mariadb_102_users_query =
|
||||||
// `t` is users that are not roles
|
// `t` is users that are not roles
|
||||||
"WITH RECURSIVE t AS ( "
|
"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 "
|
" FROM mysql.user AS u LEFT JOIN mysql.db AS d "
|
||||||
" ON (u.user = d.user AND u.host = d.host) "
|
" ON (u.user = d.user AND u.host = d.host) "
|
||||||
" UNION "
|
" 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 "
|
" FROM mysql.user AS u LEFT JOIN mysql.tables_priv AS t "
|
||||||
" ON (u.user = t.user AND u.host = t.host)"
|
" ON (u.user = t.user AND u.host = t.host)"
|
||||||
"), users AS ("
|
"), users AS ("
|
||||||
|
Reference in New Issue
Block a user