diff --git a/include/maxscale/protocol/mysql.h b/include/maxscale/protocol/mysql.h index e6a263e91..24d86aed1 100644 --- a/include/maxscale/protocol/mysql.h +++ b/include/maxscale/protocol/mysql.h @@ -485,4 +485,23 @@ mysql_server_cmd_t mxs_mysql_current_command(MXS_SESSION* session); void mysql_num_response_packets(GWBUF *buf, uint8_t cmd, int* npackets, size_t *nbytes); +/** + * @brief Return current database of the session + * + * If no active database is in use, the database is an empty string. + * + * @param session Session to inspect + * + * @return The current database + */ +const char* mxs_mysql_get_current_db(MXS_SESSION* session); + +/** + * @brief Set the currently active database for a session + * + * @param session Session to modify + * @param db The new database + */ +void mxs_mysql_set_current_db(MXS_SESSION* session, const char* db); + MXS_END_DECLS diff --git a/server/modules/filter/cache/CMakeLists.txt b/server/modules/filter/cache/CMakeLists.txt index 6c767beb7..83a04bb9a 100644 --- a/server/modules/filter/cache/CMakeLists.txt +++ b/server/modules/filter/cache/CMakeLists.txt @@ -17,7 +17,7 @@ if (JANSSON_FOUND) storagefactory.cc storagereal.cc ) - target_link_libraries(cache maxscale-common ${JANSSON_LIBRARIES}) + target_link_libraries(cache maxscale-common ${JANSSON_LIBRARIES} MySQLCommon) set_target_properties(cache PROPERTIES VERSION "1.0.0") set_target_properties(cache PROPERTIES LINK_FLAGS -Wl,-z,defs) install_module(cache core) diff --git a/server/modules/filter/cache/cachefiltersession.cc b/server/modules/filter/cache/cachefiltersession.cc index 5eb5f5d4f..46aeb24a4 100644 --- a/server/modules/filter/cache/cachefiltersession.cc +++ b/server/modules/filter/cache/cachefiltersession.cc @@ -205,15 +205,15 @@ CacheFilterSession* CacheFilterSession::Create(Cache* pCache, MXS_SESSION* pSess ss_dassert(pSession->client_dcb); ss_dassert(pSession->client_dcb->data); - MYSQL_session *pMysqlSession = (MYSQL_session*)pSession->client_dcb->data; + const char* zDb = mxs_mysql_get_current_db(pSession); char* zDefaultDb = NULL; - if (pMysqlSession->db[0] != 0) + if (zDb[0] != 0) { - zDefaultDb = MXS_STRDUP(pMysqlSession->db); + zDefaultDb = MXS_STRDUP(zDb); } - if ((pMysqlSession->db[0] == 0) || zDefaultDb) + if ((zDb[0] == 0) || zDefaultDb) { pCacheFilterSession = new (std::nothrow) CacheFilterSession(pSession, pCache, zDefaultDb); diff --git a/server/modules/filter/dbfwfilter/CMakeLists.txt b/server/modules/filter/dbfwfilter/CMakeLists.txt index 8f03ad2b0..21b0b0872 100644 --- a/server/modules/filter/dbfwfilter/CMakeLists.txt +++ b/server/modules/filter/dbfwfilter/CMakeLists.txt @@ -7,13 +7,13 @@ if(BISON_FOUND AND FLEX_FOUND) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) add_library(dbfwfilter SHARED dbfwfilter.c ${BISON_ruleparser_OUTPUTS} ${FLEX_token_OUTPUTS}) - target_link_libraries(dbfwfilter maxscale-common) + target_link_libraries(dbfwfilter maxscale-common MySQLCommon) set_target_properties(dbfwfilter PROPERTIES VERSION "1.0.0") install_module(dbfwfilter core) # The offline rule check utility add_executable(dbfwchk dbfw_rule_check.c ${BISON_ruleparser_OUTPUTS} ${FLEX_token_OUTPUTS}) - target_link_libraries(dbfwchk maxscale-common) + target_link_libraries(dbfwchk maxscale-common MySQLCommon) install_executable(dbfwchk core) else() diff --git a/server/modules/filter/dbfwfilter/dbfwfilter.c b/server/modules/filter/dbfwfilter/dbfwfilter.c index dc545695f..9035364c6 100644 --- a/server/modules/filter/dbfwfilter/dbfwfilter.c +++ b/server/modules/filter/dbfwfilter/dbfwfilter.c @@ -1745,7 +1745,7 @@ GWBUF* gen_dummy_error(FW_SESSION* session, char* msg) } dcb = session->session->client_dcb; - mysql_session = (MYSQL_session*) dcb->data; + const char* db = mxs_mysql_get_current_db(session->session); errlen = msg != NULL ? strlen(msg) : 0; errmsg = (char*) MXS_MALLOC((512 + errlen) * sizeof(char)); @@ -1755,14 +1755,14 @@ GWBUF* gen_dummy_error(FW_SESSION* session, char* msg) } - if (mysql_session->db[0] == '\0') + if (db[0] == '\0') { sprintf(errmsg, "Access denied for user '%s'@'%s'", dcb->user, dcb->remote); } else { sprintf(errmsg, "Access denied for user '%s'@'%s' to database '%s'", - dcb->user, dcb->remote, mysql_session->db); + dcb->user, dcb->remote, db); } if (msg != NULL) diff --git a/server/modules/filter/mqfilter/mqfilter.c b/server/modules/filter/mqfilter/mqfilter.c index 71622b4d3..779759deb 100644 --- a/server/modules/filter/mqfilter/mqfilter.c +++ b/server/modules/filter/mqfilter/mqfilter.c @@ -807,21 +807,15 @@ void pushMessage(MQ_INSTANCE *instance, amqp_basic_properties_t* prop, char* msg static MXS_FILTER_SESSION * newSession(MXS_FILTER *instance, MXS_SESSION *session) { - MYSQL_session *sessauth = session->client_dcb->data; - char *db = sessauth->db; - if (db) + const char *db = mxs_mysql_get_current_db(session); + char* my_db = NULL; + + if (*db) { - if (strnlen(db, 128) > 0) + my_db = MXS_STRDUP(my_db); + if (!my_db) { - db = MXS_STRDUP(db); - if (!db) - { - return NULL; - } - } - else - { - db = NULL; + return NULL; } } @@ -832,11 +826,11 @@ newSession(MXS_FILTER *instance, MXS_SESSION *session) my_session->was_query = false; my_session->uid = NULL; my_session->session = session; - my_session->db = db; + my_session->db = my_db; } else { - MXS_FREE(db); + MXS_FREE(my_db); } return (MXS_FILTER_SESSION*)my_session; diff --git a/server/modules/protocol/MySQL/mysql_common.c b/server/modules/protocol/MySQL/mysql_common.c index d0b67c604..3ea5ec1cc 100644 --- a/server/modules/protocol/MySQL/mysql_common.c +++ b/server/modules/protocol/MySQL/mysql_common.c @@ -1587,3 +1587,15 @@ mysql_server_cmd_t mxs_mysql_current_command(MXS_SESSION* session) MySQLProtocol* proto = (MySQLProtocol*)session->client_dcb->protocol; return proto->current_command; } + +const char* mxs_mysql_get_current_db(MXS_SESSION* session) +{ + MYSQL_session* data = (MYSQL_session*)session->client_dcb->data; + return data->db; +} + +void mxs_mysql_set_current_db(MXS_SESSION* session, const char* db) +{ + MYSQL_session* data = (MYSQL_session*)session->client_dcb->data; + snprintf(data->db, sizeof(data->db), "%s", db); +} diff --git a/server/modules/routing/readwritesplit/rwsplit_mysql.cc b/server/modules/routing/readwritesplit/rwsplit_mysql.cc index 1b911cb85..011e68710 100644 --- a/server/modules/routing/readwritesplit/rwsplit_mysql.cc +++ b/server/modules/routing/readwritesplit/rwsplit_mysql.cc @@ -380,8 +380,7 @@ bool execute_sescmd_in_backend(backend_ref_t *backend_ref) MYSQL_session* data; unsigned int qlen; - data = (MYSQL_session*)dcb->session->client_dcb->data; - *data->db = 0; + mxs_mysql_set_current_db(dcb->session, ""); tmpbuf = scur->scmd_cur_cmd->my_sescmd_buf; qlen = MYSQL_GET_PAYLOAD_LEN((unsigned char *) GWBUF_DATA(tmpbuf)); if (qlen) @@ -394,8 +393,10 @@ bool execute_sescmd_in_backend(backend_ref_t *backend_ref) qlen = MYSQL_DATABASE_MAXLEN; } - memcpy(data->db, (char*)GWBUF_DATA(tmpbuf) + 5, qlen); - data->db[qlen] = 0; + char db[qlen + 1]; + memcpy(db, (char*)GWBUF_DATA(tmpbuf) + 5, qlen); + db[qlen] = 0; + mxs_mysql_set_current_db(dcb->session, db); } } /** Fallthrough */ diff --git a/server/modules/routing/readwritesplit/rwsplit_tmp_table_multi.cc b/server/modules/routing/readwritesplit/rwsplit_tmp_table_multi.cc index ca00bb765..70f8dbeca 100644 --- a/server/modules/routing/readwritesplit/rwsplit_tmp_table_multi.cc +++ b/server/modules/routing/readwritesplit/rwsplit_tmp_table_multi.cc @@ -54,8 +54,8 @@ void check_drop_tmp_table(ROUTER_CLIENT_SES *router_cli_ses, GWBUF *querybuf) for (size_t i = 0; i < n_infos; i++) { - MYSQL_session* data = static_cast(router_cli_ses->client_dcb->data); - std::string table = info[i].database ? info[i].database : data->db; + const char* db = mxs_mysql_get_current_db(router_cli_ses->client_dcb->session); + std::string table = info[i].database ? info[i].database : db; table += "."; if (info[i].table) @@ -95,8 +95,8 @@ bool is_read_tmp_table(ROUTER_CLIENT_SES *router_cli_ses, for (size_t i = 0; i < n_infos; i++) { - MYSQL_session* data = static_cast(router_cli_ses->client_dcb->data); - std::string table = info[i].database ? info[i].database : data->db; + const char* db = mxs_mysql_get_current_db(router_cli_ses->client_dcb->session); + std::string table = info[i].database ? info[i].database : db; table += "."; if (info[i].table) @@ -142,8 +142,8 @@ void check_create_tmp_table(ROUTER_CLIENT_SES *router_cli_ses, if (tblname && *tblname) { - MYSQL_session* data = static_cast(router_cli_ses->client_dcb->data); - table += data->db; + const char* db = mxs_mysql_get_current_db(router_cli_ses->client_dcb->session); + table += db; table += "."; table += tblname; } diff --git a/server/modules/routing/schemarouter/CMakeLists.txt b/server/modules/routing/schemarouter/CMakeLists.txt index ef81f9e57..2d136dcba 100644 --- a/server/modules/routing/schemarouter/CMakeLists.txt +++ b/server/modules/routing/schemarouter/CMakeLists.txt @@ -1,5 +1,5 @@ add_library(schemarouter SHARED schemarouter.cc schemarouterinstance.cc schemaroutersession.cc shard_map.cc session_command.cc) -target_link_libraries(schemarouter maxscale-common) +target_link_libraries(schemarouter maxscale-common MySQLCommon) add_dependencies(schemarouter pcre2) set_target_properties(schemarouter PROPERTIES VERSION "1.0.0") install_module(schemarouter core) diff --git a/server/modules/routing/schemarouter/schemaroutersession.cc b/server/modules/routing/schemarouter/schemaroutersession.cc index e34415b6d..1c9d24fd1 100644 --- a/server/modules/routing/schemarouter/schemaroutersession.cc +++ b/server/modules/routing/schemarouter/schemaroutersession.cc @@ -46,28 +46,23 @@ SchemaRouterSession::SchemaRouterSession(MXS_SESSION* session, SchemaRouter* rou { char db[MYSQL_DATABASE_MAXLEN + 1] = ""; MySQLProtocol* protocol = (MySQLProtocol*)session->client_dcb->protocol; - MYSQL_session* data = (MYSQL_session*)session->client_dcb->data; bool using_db = false; bool have_db = false; + const char* current_db = mxs_mysql_get_current_db(session); /* To enable connecting directly to a sharded database we first need * to disable it for the client DCB's protocol so that we can connect to them*/ if (protocol->client_capabilities & GW_MYSQL_CAPABILITIES_CONNECT_WITH_DB && - (have_db = strnlen(data->db, MYSQL_DATABASE_MAXLEN) > 0)) + (have_db = *current_db)) { protocol->client_capabilities &= ~GW_MYSQL_CAPABILITIES_CONNECT_WITH_DB; - strcpy(db, data->db); - *data->db = 0; + strcpy(db, current_db); + mxs_mysql_set_current_db(session, ""); using_db = true; MXS_INFO("Client logging in directly to a database '%s', " "postponing until databases have been mapped.", db); } - if (!have_db) - { - MXS_INFO("Client'%s' connecting with empty database.", data->user); - } - if (using_db) { m_state |= INIT_USE_DB;