From 28ae1bf24e631d2f946424fb927524133f666122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Wed, 20 Jun 2018 13:13:11 +0300 Subject: [PATCH 1/4] MXS-1932: Ignore hidden files in maxscale.cnf.d All files that are hidden (i.e. start with a period) are now ignored by the configuration file processing. --- server/core/config.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/core/config.cc b/server/core/config.cc index d24602d40..15f1bb7c0 100644 --- a/server/core/config.cc +++ b/server/core/config.cc @@ -695,7 +695,7 @@ int config_cb(const char* fpath, const struct stat *sb, int typeflag, struct FTW const char* filename = fpath + ftwbuf->base; const char* dot = strrchr(filename, '.'); - if (dot) // that must have a suffix, + if (dot && *filename != '.') // that have a suffix and are not hidden, { const char* suffix = dot + 1; From 7a0a6c3af10fa48321637b6763cfc823a82733f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Wed, 20 Jun 2018 13:37:21 +0300 Subject: [PATCH 2/4] MXS-1932: Add test case Added test case that reproduces the problem and verifies that it is fixed. --- maxscale-system-test/CMakeLists.txt | 4 +++ maxscale-system-test/mxs1932_hidden_cnf.cpp | 39 +++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 maxscale-system-test/mxs1932_hidden_cnf.cpp diff --git a/maxscale-system-test/CMakeLists.txt b/maxscale-system-test/CMakeLists.txt index 1740ba870..0e91a1242 100644 --- a/maxscale-system-test/CMakeLists.txt +++ b/maxscale-system-test/CMakeLists.txt @@ -941,6 +941,10 @@ add_test_executable(mxs1836_show_eventTimes.cpp mxs1836_show_eventTimes mxs1836_ # https://jira.mariadb.org/browse/MXS-1889 add_test_executable(mxs1889.cpp mxs1889 mxs1889 LABELS REPL_BACKEND) +# MXS-1932: Hidden files are not ignored +# https://jira.mariadb.org/browse/MXS-1932 +add_test_executable(mxs1932_hidden_cnf.cpp mxs1932_hidden_cnf replication LABELS REPL_BACKEND) + configure_file(templates.h.in templates.h @ONLY) include(CTest) diff --git a/maxscale-system-test/mxs1932_hidden_cnf.cpp b/maxscale-system-test/mxs1932_hidden_cnf.cpp new file mode 100644 index 000000000..4816cb369 --- /dev/null +++ b/maxscale-system-test/mxs1932_hidden_cnf.cpp @@ -0,0 +1,39 @@ +/** + * MXS-1932: Hidden files are not ignored + * + * https://jira.mariadb.org/browse/MXS-1932 + */ + +#include "testconnections.h" + +#include +#include + +using namespace std; + +int main(int argc, char** argv) +{ + TestConnections::skip_maxscale_start(true); + TestConnections test(argc, argv); + + ofstream cnf("hidden.cnf"); + cnf << "[something]" << endl; + cnf << "type=turbocharger" << endl; + cnf << "target=maxscale" << endl; + cnf << "speed=maximum" << endl; + cnf.close(); + + test.maxscales->copy_to_node_legacy("hidden.cnf", "~"); + test.maxscales->ssh_node_f(0, true, + "mkdir -p /etc/maxscale.cnf.d/;" + "mv %s/hidden.cnf /etc/maxscale.cnf.d/.hidden.cnf;" + "chown -R maxscale:maxscale /etc/maxscale.cnf.d/", + test.maxscales->access_homedir[0]); + + test.assert(test.maxscales->restart_maxscale() == 0, "Starting MaxScale should suceed"); + + test.maxscales->ssh_node_f(0, true, "rm -r /etc/maxscale.cnf.d/"); + remove("hidden.cnf"); + + return test.global_result; +} From 0914f671750f1d75e8760edcb4401b2b7243224e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Wed, 20 Jun 2018 13:57:28 +0300 Subject: [PATCH 3/4] MXS-872: Document new grant requirement The user now requires SELECT privileges on the mysql.roles_mapping table. Currently this is a mandatory grant but it needs to be made into an optional requirement. This allows upgrades from 2.2.9 to 2.2.10 without needing new grants. --- Documentation/Getting-Started/Configuration-Guide.md | 1 + Documentation/Tutorials/Connection-Routing-Tutorial.md | 1 + Documentation/Tutorials/MaxScale-Tutorial.md | 1 + Documentation/Tutorials/Read-Write-Splitting-Tutorial.md | 1 + 4 files changed, 4 insertions(+) diff --git a/Documentation/Getting-Started/Configuration-Guide.md b/Documentation/Getting-Started/Configuration-Guide.md index e90ffb047..2793c862e 100644 --- a/Documentation/Getting-Started/Configuration-Guide.md +++ b/Documentation/Getting-Started/Configuration-Guide.md @@ -897,6 +897,7 @@ name and grants suitable for database name authorization. GRANT SELECT ON mysql.user TO 'maxscale'@'maxscalehost'; GRANT SELECT ON mysql.db TO 'maxscale'@'maxscalehost'; GRANT SELECT ON mysql.tables_priv TO 'maxscale'@'maxscalehost'; +GRANT SELECT ON mysql.roles_mapping TO 'maxscale'@'maxscalehost'; GRANT SHOW DATABASES ON *.* TO 'maxscale'@'maxscalehost'; ``` diff --git a/Documentation/Tutorials/Connection-Routing-Tutorial.md b/Documentation/Tutorials/Connection-Routing-Tutorial.md index 4ed6947f1..608884ac5 100644 --- a/Documentation/Tutorials/Connection-Routing-Tutorial.md +++ b/Documentation/Tutorials/Connection-Routing-Tutorial.md @@ -97,6 +97,7 @@ CREATE USER 'maxscale'@'%' IDENTIFIED BY 'maxscale_pw'; GRANT SELECT ON mysql.user TO 'maxscale'@'%'; GRANT SELECT ON mysql.db TO 'maxscale'@'%'; GRANT SELECT ON mysql.tables_priv TO 'maxscale'@'%'; +GRANT SELECT ON mysql.roles_mapping TO 'maxscale'@'%'; GRANT SHOW DATABASES ON *.* TO 'maxscale'@'%'; ``` diff --git a/Documentation/Tutorials/MaxScale-Tutorial.md b/Documentation/Tutorials/MaxScale-Tutorial.md index fc9770216..6cb09c4fb 100644 --- a/Documentation/Tutorials/MaxScale-Tutorial.md +++ b/Documentation/Tutorials/MaxScale-Tutorial.md @@ -32,6 +32,7 @@ CREATE USER 'maxscale'@'%' IDENTIFIED BY 'maxscale_pw'; GRANT SELECT ON mysql.user TO 'maxscale'@'%'; GRANT SELECT ON mysql.db TO 'maxscale'@'%'; GRANT SELECT ON mysql.tables_priv TO 'maxscale'@'%'; +GRANT SELECT ON mysql.roles_mapping TO 'maxscale'@'%'; GRANT SHOW DATABASES ON *.* TO 'maxscale'@'%'; ``` diff --git a/Documentation/Tutorials/Read-Write-Splitting-Tutorial.md b/Documentation/Tutorials/Read-Write-Splitting-Tutorial.md index c5321ce2b..df2ca623c 100644 --- a/Documentation/Tutorials/Read-Write-Splitting-Tutorial.md +++ b/Documentation/Tutorials/Read-Write-Splitting-Tutorial.md @@ -79,6 +79,7 @@ CREATE USER 'maxscale'@'%' IDENTIFIED BY 'maxscale_pw'; GRANT SELECT ON mysql.user TO 'maxscale'@'%'; GRANT SELECT ON mysql.db TO 'maxscale'@'%'; GRANT SELECT ON mysql.tables_priv TO 'maxscale'@'%'; +GRANT SELECT ON mysql.roles_mapping TO 'maxscale'@'%'; GRANT SHOW DATABASES ON *.* TO 'maxscale'@'%'; ``` From 14e03613a06d2a3f10926bd77846c2f35b9b405f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Wed, 20 Jun 2018 14:24:28 +0300 Subject: [PATCH 4/4] MXS-872: Use the new query only when privileges are OK If the service user does not have adequate grants to the mysql tables, the legacy query is used. This prevents an upgrade failure when the user was lacking the new privileges. --- .../modules/authenticator/MySQLAuth/dbusers.c | 35 ++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/server/modules/authenticator/MySQLAuth/dbusers.c b/server/modules/authenticator/MySQLAuth/dbusers.c index e1c6bf04a..498a9716f 100644 --- a/server/modules/authenticator/MySQLAuth/dbusers.c +++ b/server/modules/authenticator/MySQLAuth/dbusers.c @@ -113,9 +113,9 @@ static char* get_mariadb_users_query(bool include_root) return rval; } -static char* get_users_query(const char *server_version, uint64_t version, bool include_root) +static char* get_users_query(const char *server_version, bool include_root, bool is_mariadb) { - if (version >= 100101) // 10.1.1 or newer, supports default roles + if (is_mariadb) // 10.1.1 or newer, supports default roles { return get_mariadb_users_query(include_root); } @@ -794,6 +794,31 @@ static bool get_hostname(DCB *dcb, char *client_hostname, size_t size) return lookup_result == 0; } +static bool roles_are_available(MYSQL* conn, SERVICE* service, SERVER* server) +{ + bool rval = false; + + if (server->version >= 100101) + { + static bool log_missing_privs = true; + + if (mxs_mysql_query(conn, "SELECT 1 FROM mysql.roles_mapping LIMIT 1") == 0) + { + mysql_free_result(mysql_store_result(conn)); + rval = true; + } + else if (log_missing_privs) + { + log_missing_privs = false; + MXS_WARNING("The user for service '%s' is missing the SELECT grant on " + "`mysql.roles_mapping`. Use of default roles is disabled " + "until the missing privileges are added.", service->name); + } + } + + return rval; +} + int get_users_from_server(MYSQL *con, SERVER_REF *server_ref, SERVICE *service, SERV_LISTENER *listener) { if (server_ref->server->version_string[0] == 0) @@ -801,9 +826,9 @@ int get_users_from_server(MYSQL *con, SERVER_REF *server_ref, SERVICE *service, mxs_mysql_set_server_version(con, server_ref->server); } - char *query = get_users_query(server_ref->server->version_string, - server_ref->server->version, - service->enable_root); + char *query = get_users_query(server_ref->server->version_string, service->enable_root, + roles_are_available(con, service, server_ref->server)); + MYSQL_AUTH *instance = (MYSQL_AUTH*)listener->auth_instance; sqlite3* handle = get_handle(instance); bool anon_user = false;