MXS-2064: Log workaround for grant problems with MariaDB 10.2.10

When the 10.2 users query is executed with a MariaDB server older than
10.2.11, the query will fail due to inadequate grants on the 'users' table
generated as a part of the CTE. To work around the issue, a SELECT grant
on the whole mysql database is required. Logging the server where the
query fails also helps resolve the problem by pointing out where the grant
needs to be added.
This commit is contained in:
Markus Mäkelä
2018-09-21 09:24:47 +03:00
parent e888bcac3b
commit 60915f847f

View File

@ -27,6 +27,7 @@
#include <maxscale/mysql_utils.h> #include <maxscale/mysql_utils.h>
#include <maxscale/paths.h> #include <maxscale/paths.h>
#include <maxscale/protocol/mysql.h> #include <maxscale/protocol/mysql.h>
#include <maxscale/pcre2.h>
#include <maxscale/router.h> #include <maxscale/router.h>
#include <maxscale/secrets.h> #include <maxscale/secrets.h>
#include <maxscale/service.h> #include <maxscale/service.h>
@ -860,6 +861,35 @@ static bool roles_are_available(MYSQL* conn, SERVICE* service, SERVER* server)
return rval; return rval;
} }
static void report_mdev13453_problem(MYSQL *con, SERVER *server)
{
if (server->version >= 100200 && server->version < 100211 &&
mxs_pcre2_simple_match("SELECT command denied to user .* for table 'users'",
mysql_error(con), 0, NULL) == MXS_PCRE2_MATCH)
{
char user[256] = "<failed to query user>"; // Enough for all user-hostname combinations
const char* quoted_user = "select concat(\"'\", user, \"'@'\", host, \"'\") as user "
"from mysql.user "
"where concat(user, \"@\", host) = current_user()";
MYSQL_RES *res;
if (mxs_mysql_query(con, quoted_user) == 0 && (res = mysql_store_result(con)))
{
MYSQL_ROW row = mysql_fetch_row(res);
if (row && row[0])
{
snprintf(user, sizeof(user), "%s", row[0]);
}
mysql_free_result(res);
}
MXS_ERROR("Due to MDEV-13453, the service user requires extra grants on the `mysql` database. "
"To fix the problem, add the following grant: GRANT SELECT ON `mysql`.* TO %s", user);
}
}
int get_users_from_server(MYSQL *con, SERVER_REF *server_ref, SERVICE *service, SERV_LISTENER *listener) int get_users_from_server(MYSQL *con, SERVER_REF *server_ref, SERVICE *service, SERV_LISTENER *listener)
{ {
if (server_ref->server->version_string[0] == 0) if (server_ref->server->version_string[0] == 0)
@ -917,7 +947,8 @@ int get_users_from_server(MYSQL *con, SERVER_REF *server_ref, SERVICE *service,
} }
else else
{ {
MXS_ERROR("Failed to load users: %s", mysql_error(con)); MXS_ERROR("Failed to load users from server '%s': %s", server_ref->server->name, mysql_error(con));
report_mdev13453_problem(con, server_ref->server);
} }
MXS_FREE(query); MXS_FREE(query);