From cb0ac44e1f5dc2d9649970912a5c34bb9fae9183 Mon Sep 17 00:00:00 2001 From: Esa Korhonen Date: Thu, 19 Apr 2018 16:14:32 +0300 Subject: [PATCH] MXS-1758 Support anonymous user with proxy grant for PAM This allows using user group mapping with PAM authenticator. --- .../PAM/PAMAuth/pam_client_session.cc | 15 +++- .../authenticator/PAM/PAMAuth/pam_instance.cc | 73 ++++++++++++++++++- .../authenticator/PAM/PAMAuth/pam_instance.hh | 1 + 3 files changed, 85 insertions(+), 4 deletions(-) diff --git a/server/modules/authenticator/PAM/PAMAuth/pam_client_session.cc b/server/modules/authenticator/PAM/PAMAuth/pam_client_session.cc index 229f0bb65..e25d4909f 100644 --- a/server/modules/authenticator/PAM/PAMAuth/pam_client_session.cc +++ b/server/modules/authenticator/PAM/PAMAuth/pam_client_session.cc @@ -238,14 +238,25 @@ void PamClientSession::get_pam_user_services(const DCB* dcb, const MYSQL_session ") ORDER BY authentication_string;"; MXS_DEBUG("PAM services search sql: '%s'.", services_query.c_str()); char *err; - if (sqlite3_exec(m_dbhandle, services_query.c_str(), user_services_cb, - services_out, &err) != SQLITE_OK) + if (sqlite3_exec(m_dbhandle, services_query.c_str(), user_services_cb, services_out, &err) != SQLITE_OK) { MXS_ERROR("Failed to execute query: '%s'", err); sqlite3_free(err); } MXS_DEBUG("User '%s' matched %lu rows in %s db.", session->user, services_out->size(), m_instance.m_tablename.c_str()); + + if (services_out->empty()) + { + // No service found for user with correct username & password. Check if anonymous user exists. + const string anon_query = string("SELECT authentication_string FROM ") + m_instance.m_tablename + + " WHERE " + FIELD_USER + " = '' AND " + FIELD_HOST + " = '%';"; + if (sqlite3_exec(m_dbhandle, anon_query.c_str(), user_services_cb, services_out, &err) != SQLITE_OK) + { + MXS_ERROR("Failed to execute query: '%s'", err); + sqlite3_free(err); + } + } } /** diff --git a/server/modules/authenticator/PAM/PAMAuth/pam_instance.cc b/server/modules/authenticator/PAM/PAMAuth/pam_instance.cc index 23d2c6adc..9a41fe013 100644 --- a/server/modules/authenticator/PAM/PAMAuth/pam_instance.cc +++ b/server/modules/authenticator/PAM/PAMAuth/pam_instance.cc @@ -216,8 +216,11 @@ int PamInstance::load_users(SERVICE* service) row[3] && strcasecmp(row[3], "Y") == 0, row[4]); } - rval = MXS_AUTH_LOADUSERS_OK; mysql_free_result(res); + if (query_anon_proxy_user(servers->server, mysql)) + { + rval = MXS_AUTH_LOADUSERS_OK; + } } } mysql_close(mysql); @@ -286,4 +289,70 @@ json_t* PamInstance::diagnostic_json() } return rval; -} \ No newline at end of file +} + +bool PamInstance::query_anon_proxy_user(SERVER* server, MYSQL* conn) +{ + bool success = true; + bool anon_user_found = false; + string anon_pam_service; + const char ANON_USER_QUERY[] = "SELECT authentication_string FROM mysql.user WHERE " + "(plugin = 'pam' AND user = '' AND host = '%');"; + const char ANON_GRANT_QUERY[] = "SHOW GRANTS FOR ''@'%';"; + const char GRANT_PROXY[] = "GRANT PROXY ON"; + + // Query for the anonymous user which is used with group mappings + if (mysql_query(conn, ANON_USER_QUERY)) + { + MXS_ERROR("Failed to query server '%s' for the anonymous PAM user: '%s'.", + server->unique_name, mysql_error(conn)); + success = false; + } + else + { + MYSQL_RES *res = mysql_store_result(conn); + if (res) + { + MYSQL_ROW row = mysql_fetch_row(res); + if (row) + { + anon_user_found = true; + if (row[0]) + { + anon_pam_service = row[0]; + } + } + mysql_free_result(res); + } + + if (anon_user_found) + { + // Check that the anon user has a proxy grant + if (mysql_query(conn, ANON_GRANT_QUERY)) + { + MXS_ERROR("Failed to query server '%s' for the grants of the anonymous PAM user: '%s'.", + server->unique_name, mysql_error(conn)); + success = false; + } + else + { + if ((res = mysql_store_result(conn))) + { + MYSQL_ROW row; + while ((row = mysql_fetch_row(res))) + { + if (row[0] && strncmp(row[0], GRANT_PROXY, sizeof(GRANT_PROXY) - 1) == 0) + { + MXS_NOTICE("Anonymous PAM user with proxy grant found. User account mapping " + "enabled."); + add_pam_user("", "%", NULL, false, anon_pam_service.c_str()); + } + } + mysql_free_result(res); + } + } + } + } + + return success; +} diff --git a/server/modules/authenticator/PAM/PAMAuth/pam_instance.hh b/server/modules/authenticator/PAM/PAMAuth/pam_instance.hh index 69ad0d737..ea845a97e 100644 --- a/server/modules/authenticator/PAM/PAMAuth/pam_instance.hh +++ b/server/modules/authenticator/PAM/PAMAuth/pam_instance.hh @@ -36,6 +36,7 @@ private: void add_pam_user(const char *user, const char *host, const char *db, bool anydb, const char *pam_service); void delete_old_users(); + bool query_anon_proxy_user(SERVER* server, MYSQL* conn); sqlite3 * const m_dbhandle; /**< SQLite3 database handle */ };