From 4e07c3313c9c09236d0a7089499863ebf6493b4a Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 20 Oct 2016 21:26:06 +0300 Subject: [PATCH] Move dbusers.c out of the core The dbusers.c was a MySQL protocol specific file which was used directly by some of the modules. Added a new return value for the loadusers authenticator entry point which allows fatal failures to occur when users are loaded. Currently this is only taken into notice when the service is first started. If a listener later returns a fatal error, it is only logged but the service stays in operation. Moved the MySQLAuth authenticator sources and the tests that relate to this module into a subdirectory in the authenticator directory. Eventually, all authenticators could have a subdirectory of their own. --- include/maxscale/gw_authenticator.h | 7 +- include/maxscale/protocol/mysql.h | 9 +- include/maxscale/service.h | 9 + server/core/CMakeLists.txt | 2 +- server/core/authenticator.c | 4 +- server/core/config.c | 1 - server/core/listener.c | 6 +- server/core/mysql_binlog.c | 1 - server/core/server.c | 3 +- server/core/service.c | 122 ++++++++------ server/core/test/CMakeLists.txt | 3 - server/modules/authenticator/CMakeLists.txt | 5 +- .../authenticator/MySQLAuth/CMakeLists.txt | 10 ++ .../authenticator/MySQLAuth}/dbusers.c | 2 +- .../authenticator/MySQLAuth}/dbusers.h | 16 +- .../{ => MySQLAuth}/mysql_auth.c | 11 +- .../MySQLAuth}/test_mysql_users.c | 2 +- server/modules/routing/avro/avro_client.c | 1 - server/modules/routing/avro/avrorouter.h | 1 - server/modules/routing/binlog/blr.c | 156 ------------------ server/modules/routing/binlog/blr_slave.c | 27 +-- server/modules/routing/debugcli/debugcmd.c | 1 - server/modules/routing/maxinfo/maxinfo.c | 80 --------- 23 files changed, 127 insertions(+), 352 deletions(-) create mode 100644 server/modules/authenticator/MySQLAuth/CMakeLists.txt rename server/{core => modules/authenticator/MySQLAuth}/dbusers.c (99%) rename {include/maxscale => server/modules/authenticator/MySQLAuth}/dbusers.h (76%) rename server/modules/authenticator/{ => MySQLAuth}/mysql_auth.c (99%) rename server/{core/test => modules/authenticator/MySQLAuth}/test_mysql_users.c (99%) diff --git a/include/maxscale/gw_authenticator.h b/include/maxscale/gw_authenticator.h index a78523ff3..deafd14b7 100644 --- a/include/maxscale/gw_authenticator.h +++ b/include/maxscale/gw_authenticator.h @@ -72,7 +72,7 @@ struct servlistener; * destroy Destroy the unique DCB data returned by the `create` * entry point. * - * loadUsers Load or update authenticator user data + * loadusers Load or update authenticator user data * @endverbatim * * This forms the "module object" for authenticator modules within the gateway. @@ -102,7 +102,8 @@ typedef struct gw_authenticator /** Return values for the loadusers entry point */ #define MXS_AUTH_LOADUSERS_OK 0 /**< Users loaded successfully */ -#define MXS_AUTH_LOADUSERS_ERROR 1 /**< Failed to load users */ +#define MXS_AUTH_LOADUSERS_ERROR 1 /**< Temporary error, service is started */ +#define MXS_AUTH_LOADUSERS_FATAL 2 /**< Fatal error, service is not started */ /** * Authentication states @@ -136,7 +137,7 @@ typedef enum bool authenticator_init(void **instance, const char *authenticator, const char *options); -char* get_default_authenticator(const char *protocol); +const char* get_default_authenticator(const char *protocol); MXS_END_DECLS diff --git a/include/maxscale/protocol/mysql.h b/include/maxscale/protocol/mysql.h index 254478e21..3fc66cc49 100644 --- a/include/maxscale/protocol/mysql.h +++ b/include/maxscale/protocol/mysql.h @@ -59,7 +59,6 @@ #include #include #include -#include #include #include #include @@ -93,6 +92,7 @@ MXS_BEGIN_DECLS #define GW_MYSQL_SCRAMBLE_SIZE 20 #define GW_SCRAMBLE_LENGTH_323 8 +/** Name of the default server side authentication plugin */ #define DEFAULT_MYSQL_AUTH_PLUGIN "mysql_native_password" /** All authentication responses are at least this many bytes long */ @@ -105,7 +105,12 @@ MXS_BEGIN_DECLS # define MYSQL_SCRAMBLE_LEN GW_MYSQL_SCRAMBLE_SIZE #endif -#define MYSQL_HOSTNAME_MAXLEN 60 +/* Max length of fields in the mysql.user table */ +#define MYSQL_USER_MAXLEN 128 +#define MYSQL_PASSWORD_LEN 41 +#define MYSQL_HOST_MAXLEN 60 +#define MYSQL_DATABASE_MAXLEN 128 +#define MYSQL_TABLE_MAXLEN 64 #define GW_NOINTR_CALL(A) do { errno = 0; A; } while (errno == EINTR) #define SMALL_CHUNK 1024 diff --git a/include/maxscale/service.h b/include/maxscale/service.h index fa401628d..6cb80793b 100644 --- a/include/maxscale/service.h +++ b/include/maxscale/service.h @@ -114,6 +114,15 @@ typedef struct server_ref_t */ #define SERVICE_PARAM_UNINIT -1 +/* Refresh rate limits for load users from database */ +#define USERS_REFRESH_TIME 30 /* Allowed time interval (in seconds) after last update*/ +#define USERS_REFRESH_MAX_PER_TIME 4 /* Max number of load calls within the time interval */ + +/** Default timeout values used by the connections which fetch user authentication data */ +#define DEFAULT_AUTH_CONNECT_TIMEOUT 3 +#define DEFAULT_AUTH_READ_TIMEOUT 1 +#define DEFAULT_AUTH_WRITE_TIMEOUT 2 + /** * Defines a service within the gateway. * diff --git a/server/core/CMakeLists.txt b/server/core/CMakeLists.txt index 3c7c630b8..6131c33b6 100644 --- a/server/core/CMakeLists.txt +++ b/server/core/CMakeLists.txt @@ -1,4 +1,4 @@ -add_library(maxscale-common SHARED adminusers.c alloc.c authenticator.c atomic.c buffer.c config.c dbusers.c dcb.c filter.c externcmd.c gwbitmask.c gwdirs.c hashtable.c hint.c housekeeper.c listmanager.c load_utils.c log_manager.cc maxscale_pcre2.c memlog.c misc.c mlist.c modutil.c monitor.c queuemanager.c query_classifier.c poll.c random_jkiss.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c skygw_utils.cc statistics.c listener.c gw_ssl.c mysql_utils.c mysql_binlog.c) +add_library(maxscale-common SHARED adminusers.c alloc.c authenticator.c atomic.c buffer.c config.c dcb.c filter.c externcmd.c gwbitmask.c gwdirs.c hashtable.c hint.c housekeeper.c listmanager.c load_utils.c log_manager.cc maxscale_pcre2.c memlog.c misc.c mlist.c modutil.c monitor.c queuemanager.c query_classifier.c poll.c random_jkiss.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c skygw_utils.cc statistics.c listener.c gw_ssl.c mysql_utils.c mysql_binlog.c) target_link_libraries(maxscale-common ${MARIADB_CONNECTOR_LIBRARIES} ${LZMA_LINK_FLAGS} ${PCRE2_LIBRARIES} ${CURL_LIBRARIES} ssl pthread crypt dl crypto inih z rt m stdc++) diff --git a/server/core/authenticator.c b/server/core/authenticator.c index 30b766e29..761103a1d 100644 --- a/server/core/authenticator.c +++ b/server/core/authenticator.c @@ -89,14 +89,14 @@ bool authenticator_init(void** dest, const char *authenticator, const char *opti * @return The default authenticator for the protocol or NULL if the protocol * does not provide one */ -char* get_default_authenticator(const char *protocol) +const char* get_default_authenticator(const char *protocol) { char *rval = NULL; GWPROTOCOL *protofuncs = (GWPROTOCOL*)load_module(protocol, MODULE_PROTOCOL); if (protofuncs && protofuncs->auth_default) { - rval = MXS_STRDUP(protofuncs->auth_default()); + rval = protofuncs->auth_default(); } return rval; diff --git a/server/core/config.c b/server/core/config.c index ce3fbf2f9..e8c4ef03d 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -72,7 +72,6 @@ #include #include #include -#include #include #include #define PCRE2_CODE_UNIT_WIDTH 8 diff --git a/server/core/listener.c b/server/core/listener.c index a7de9403e..075ae8eff 100644 --- a/server/core/listener.c +++ b/server/core/listener.c @@ -71,7 +71,8 @@ listener_alloc(struct service* service, char* name, char *protocol, char *addres { authenticator = MXS_STRDUP(authenticator); } - else if ((authenticator = get_default_authenticator(protocol)) == NULL) + else if ((authenticator = (char*)get_default_authenticator(protocol)) == NULL || + (authenticator = MXS_STRDUP(authenticator)) == NULL) { MXS_ERROR("No authenticator defined for listener '%s' and could not get " "default authenticator for protocol '%s'.", name, protocol); @@ -83,6 +84,9 @@ listener_alloc(struct service* service, char* name, char *protocol, char *addres { MXS_ERROR("Failed to initialize authenticator module '%s' for " "listener '%s'.", authenticator, name); + MXS_FREE(address); + MXS_FREE(authenticator); + return NULL; } protocol = MXS_STRDUP(protocol); diff --git a/server/core/mysql_binlog.c b/server/core/mysql_binlog.c index 15e2a1f1c..0087bf19b 100644 --- a/server/core/mysql_binlog.c +++ b/server/core/mysql_binlog.c @@ -22,7 +22,6 @@ #include #include #include -#include #include /** diff --git a/server/core/server.c b/server/core/server.c index 101b5b5f0..632aa4a94 100644 --- a/server/core/server.c +++ b/server/core/server.c @@ -69,7 +69,8 @@ server_alloc(char *servname, char *protocol, unsigned short port, char *authenti { authenticator = MXS_STRDUP(authenticator); } - else if ((authenticator = get_default_authenticator(protocol)) == NULL) + else if ((authenticator = (char*)get_default_authenticator(protocol)) == NULL || + (authenticator = MXS_STRDUP(authenticator)) == NULL) { MXS_ERROR("No authenticator defined for server at %s:%u and no default " "authenticator for protocol '%s'.", servname, port, protocol); diff --git a/server/core/service.c b/server/core/service.c index a6a5e167c..ceaeac0cb 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -53,7 +53,6 @@ #include #include #include -#include #include #include #include @@ -210,6 +209,16 @@ service_isvalid(SERVICE *service) return rval; } +static inline void close_port(SERV_LISTENER *port) +{ + port->service->state = SERVICE_STATE_FAILED; + if (port->listener) + { + dcb_close(port->listener); + port->listener = NULL; + } +} + /** * Start an individual port/protocol pair * @@ -232,7 +241,9 @@ serviceStartPort(SERVICE *service, SERV_LISTENER *port) { /* Should never happen, this guarantees it can't */ MXS_ERROR("Attempt to start port with null or incomplete service"); - goto retblock; + close_port(port); + ss_dassert(false); + return 0; } port->listener = dcb_alloc(DCB_ROLE_SERVICE_LISTENER, port); @@ -240,7 +251,8 @@ serviceStartPort(SERVICE *service, SERV_LISTENER *port) if (port->listener == NULL) { MXS_ERROR("Failed to create listener for service %s.", service->name); - goto retblock; + close_port(port); + return 0; } port->listener->service = service; @@ -252,13 +264,10 @@ serviceStartPort(SERVICE *service, SERV_LISTENER *port) if ((funcs = (GWPROTOCOL *)load_module(port->protocol, MODULE_PROTOCOL)) == NULL) { - dcb_close(port->listener); - port->listener = NULL; - MXS_ERROR("Unable to load protocol module %s. Listener " - "for service %s not started.", - port->protocol, - service->name); - goto retblock; + MXS_ERROR("Unable to load protocol module %s. Listener for service %s not started.", + port->protocol, service->name); + close_port(port); + return 0; } memcpy(&(port->listener->func), funcs, sizeof(GWPROTOCOL)); @@ -280,8 +289,7 @@ serviceStartPort(SERVICE *service, SERV_LISTENER *port) { MXS_ERROR("Failed to load authenticator module '%s' for listener '%s'", authenticator_name, port->name); - dcb_close(port->listener); - port->listener = NULL; + close_port(port); return 0; } @@ -302,11 +310,24 @@ serviceStartPort(SERVICE *service, SERV_LISTENER *port) } /** Load the authentication users before before starting the listener */ - if (port->listener->authfunc.loadusers && - port->listener->authfunc.loadusers(port) != MXS_AUTH_LOADUSERS_OK) + if (port->listener->authfunc.loadusers) { - MXS_ERROR("[%s] Failed to load users for listener '%s', authentication might not work.", - service->name, port->name); + switch (port->listener->authfunc.loadusers(port)) + { + case MXS_AUTH_LOADUSERS_FATAL: + MXS_ERROR("[%s] Fatal error when loading users for listener '%s', " + "service is not started.", service->name, port->name); + close_port(port); + return 0; + + case MXS_AUTH_LOADUSERS_ERROR: + MXS_WARNING("[%s] Failed to load users for listener '%s', authentication" + " might not work.", service->name, port->name); + break; + + default: + break; + } } /** @@ -327,24 +348,16 @@ serviceStartPort(SERVICE *service, SERV_LISTENER *port) } else { - MXS_ERROR("Failed to create session to service %s.", - service->name); - dcb_close(port->listener); - port->listener = NULL; - goto retblock; + MXS_ERROR("[%s] Failed to create listener session.", service->name); + close_port(port); } } else { - MXS_ERROR("Unable to start to listen port %d for %s %s.", - port->port, - port->protocol, - service->name); - dcb_close(port->listener); - port->listener = NULL; + MXS_ERROR("[%s] Failed to listen on %s", service->name, config_bind); + close_port(port); } -retblock: return listeners; } @@ -369,7 +382,11 @@ int serviceStartAllPorts(SERVICE* service) port = port->next; } - if (listeners) + if (service->state == SERVICE_STATE_FAILED) + { + listeners = 0; + } + else if (listeners) { service->state = SERVICE_STATE_STARTED; service->stats.started = time(0); @@ -457,29 +474,20 @@ int serviceStart(SERVICE *service) { int listeners = 0; + char **router_options = copy_string_array(service->routerOptions); - if (check_service_permissions(service)) + if ((service->router_instance = service->router->createInstance(service, router_options))) { - char **router_options = copy_string_array(service->routerOptions); - if ((service->router_instance = service->router->createInstance( - service, router_options))) - { - listeners += serviceStartAllPorts(service); - } - else - { - MXS_ERROR("%s: Failed to create router instance for service. Service not started.", - service->name); - service->state = SERVICE_STATE_FAILED; - } - free_string_array(router_options); + listeners = serviceStartAllPorts(service); } else { - MXS_ERROR("%s: Inadequate user permissions for service. Service not started.", - service->name); + MXS_ERROR("%s: Failed to create router instance. Service not started.", service->name); service->state = SERVICE_STATE_FAILED; } + + free_string_array(router_options); + return listeners; } @@ -1461,12 +1469,26 @@ int service_refresh_users(SERVICE *service) for (SERV_LISTENER *port = service->ports; port; port = port->next) { - if (port->listener->authfunc.loadusers && - port->listener->authfunc.loadusers(port) != MXS_AUTH_LOADUSERS_OK) + /** Load the authentication users before before starting the listener */ + if (port->listener->authfunc.loadusers) { - MXS_ERROR("[%s] Failed to load users for listener '%s', authentication might not work.", - service->name, port->name); - ret = 1; + switch (port->listener->authfunc.loadusers(port)) + { + case MXS_AUTH_LOADUSERS_FATAL: + MXS_ERROR("[%s] Fatal error when loading users for listener '%s'," + " authentication will not work.", service->name, port->name); + ret = 1; + break; + + case MXS_AUTH_LOADUSERS_ERROR: + MXS_WARNING("[%s] Failed to load users for listener '%s', authentication" + " might not work.", service->name, port->name); + ret = 1; + break; + + default: + break; + } } } } diff --git a/server/core/test/CMakeLists.txt b/server/core/test/CMakeLists.txt index b16fd2542..f12f22ca5 100644 --- a/server/core/test/CMakeLists.txt +++ b/server/core/test/CMakeLists.txt @@ -9,7 +9,6 @@ add_executable(test_log testlog.c) add_executable(test_logorder testlogorder.c) add_executable(test_logthrottling testlogthrottling.cc) add_executable(test_modutil testmodutil.c) -add_executable(test_mysql_users test_mysql_users.c) add_executable(test_poll testpoll.c) add_executable(test_queuemanager testqueuemanager.c) add_executable(test_server testserver.c) @@ -30,7 +29,6 @@ target_link_libraries(test_log maxscale-common) target_link_libraries(test_logorder maxscale-common) target_link_libraries(test_logthrottling maxscale-common) target_link_libraries(test_modutil maxscale-common) -target_link_libraries(test_mysql_users MySQLAuth MySQLCommon maxscale-common) target_link_libraries(test_poll maxscale-common) target_link_libraries(test_queuemanager maxscale-common) target_link_libraries(test_server maxscale-common) @@ -53,7 +51,6 @@ add_test(TestLogThrottling test_logthrottling) add_test(TestMaxScalePCRE2 testmaxscalepcre2) add_test(TestMemlog testmemlog) add_test(TestModutil test_modutil) -add_test(TestMySQLUsers test_mysql_users) add_test(NAME TestMaxPasswd COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/testmaxpasswd.sh) add_test(TestPoll test_poll) add_test(TestQueueManager test_queuemanager) diff --git a/server/modules/authenticator/CMakeLists.txt b/server/modules/authenticator/CMakeLists.txt index a7f6da3e1..1f339f7ce 100644 --- a/server/modules/authenticator/CMakeLists.txt +++ b/server/modules/authenticator/CMakeLists.txt @@ -1,7 +1,4 @@ -add_library(MySQLAuth SHARED mysql_auth.c) -target_link_libraries(MySQLAuth maxscale-common MySQLCommon) -set_target_properties(MySQLAuth PROPERTIES VERSION "1.0.0") -install_module(MySQLAuth core) +add_subdirectory(MySQLAuth) add_library(MySQLBackendAuth SHARED mysql_backend_auth.c) target_link_libraries(MySQLBackendAuth maxscale-common MySQLCommon) diff --git a/server/modules/authenticator/MySQLAuth/CMakeLists.txt b/server/modules/authenticator/MySQLAuth/CMakeLists.txt new file mode 100644 index 000000000..b27f39766 --- /dev/null +++ b/server/modules/authenticator/MySQLAuth/CMakeLists.txt @@ -0,0 +1,10 @@ +add_library(MySQLAuth SHARED mysql_auth.c dbusers.c) +target_link_libraries(MySQLAuth maxscale-common MySQLCommon) +set_target_properties(MySQLAuth PROPERTIES VERSION "1.0.0") +install_module(MySQLAuth core) + +if (BUILD_TESTS) + add_executable(test_mysql_users test_mysql_users.c) + target_link_libraries(test_mysql_users MySQLAuth MySQLCommon maxscale-common) + add_test(TestMySQLUsers test_mysql_users) +endif() diff --git a/server/core/dbusers.c b/server/modules/authenticator/MySQLAuth/dbusers.c similarity index 99% rename from server/core/dbusers.c rename to server/modules/authenticator/MySQLAuth/dbusers.c index 4098474e2..0859deaaf 100644 --- a/server/core/dbusers.c +++ b/server/modules/authenticator/MySQLAuth/dbusers.c @@ -42,7 +42,7 @@ #include #include #include -#include +#include "dbusers.h" #include #include #include diff --git a/include/maxscale/dbusers.h b/server/modules/authenticator/MySQLAuth/dbusers.h similarity index 76% rename from include/maxscale/dbusers.h rename to server/modules/authenticator/MySQLAuth/dbusers.h index 22b7bc2d0..35d6c998f 100644 --- a/include/maxscale/dbusers.h +++ b/server/modules/authenticator/MySQLAuth/dbusers.h @@ -32,25 +32,11 @@ #include #include +#include #include MXS_BEGIN_DECLS -/* Refresh rate limits for load users from database */ -#define USERS_REFRESH_TIME 30 /* Allowed time interval (in seconds) after last update*/ -#define USERS_REFRESH_MAX_PER_TIME 4 /* Max number of load calls within the time interval */ - -/** Default timeout values used by the connections which fetch user authentication data */ -#define DEFAULT_AUTH_CONNECT_TIMEOUT 3 -#define DEFAULT_AUTH_READ_TIMEOUT 1 -#define DEFAULT_AUTH_WRITE_TIMEOUT 2 - -/* Max length of fields in the mysql.user table */ -#define MYSQL_USER_MAXLEN 128 -#define MYSQL_PASSWORD_LEN 41 -#define MYSQL_HOST_MAXLEN 60 -#define MYSQL_DATABASE_MAXLEN 128 -#define MYSQL_TABLE_MAXLEN 64 /** Cache directory and file names */ static const char DBUSERS_DIR[] = "cache"; diff --git a/server/modules/authenticator/mysql_auth.c b/server/modules/authenticator/MySQLAuth/mysql_auth.c similarity index 99% rename from server/modules/authenticator/mysql_auth.c rename to server/modules/authenticator/MySQLAuth/mysql_auth.c index 4c002ae53..a7942783d 100644 --- a/server/modules/authenticator/mysql_auth.c +++ b/server/modules/authenticator/MySQLAuth/mysql_auth.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include "dbusers.h" #include #include #include @@ -884,13 +884,20 @@ static bool add_service_user(SERV_LISTENER *port) * This function loads MySQL users from the backend database. * * @param port Listener definition - * @return AUTH_LOADUSERS_OK on success, AUTH_LOADUSERS_ERROR on error + * @return MXS_AUTH_LOADUSERS_OK on success, MXS_AUTH_LOADUSERS_ERROR and + * MXS_AUTH_LOADUSERS_FATAL on fatal error */ static int mysql_auth_load_users(SERV_LISTENER *port) { int rc = MXS_AUTH_LOADUSERS_OK; SERVICE *service = port->listener->service; MYSQL_AUTH *instance = (MYSQL_AUTH*)port->auth_instance; + + if (port->users == NULL && !check_service_permissions(port->service)) + { + return MXS_AUTH_LOADUSERS_FATAL; + } + int loaded = replace_mysql_users(port); char path[PATH_MAX]; diff --git a/server/core/test/test_mysql_users.c b/server/modules/authenticator/MySQLAuth/test_mysql_users.c similarity index 99% rename from server/core/test/test_mysql_users.c rename to server/modules/authenticator/MySQLAuth/test_mysql_users.c index 49f980f53..1a30b5e03 100644 --- a/server/core/test/test_mysql_users.c +++ b/server/modules/authenticator/MySQLAuth/test_mysql_users.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include "dbusers.h" #include #include #include diff --git a/server/modules/routing/avro/avro_client.c b/server/modules/routing/avro/avro_client.c index cc0293b70..1caa06221 100644 --- a/server/modules/routing/avro/avro_client.c +++ b/server/modules/routing/avro/avro_client.c @@ -40,7 +40,6 @@ #include "avrorouter.h" #include #include -#include extern char *blr_extract_column(GWBUF *buf, int col); extern uint32_t extract_field(uint8_t *src, int bits); diff --git a/server/modules/routing/avro/avrorouter.h b/server/modules/routing/avro/avrorouter.h index 1b9accbe9..6bdeecceb 100644 --- a/server/modules/routing/avro/avrorouter.h +++ b/server/modules/routing/avro/avrorouter.h @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/server/modules/routing/binlog/blr.c b/server/modules/routing/binlog/blr.c index 213b9eb87..350c04609 100644 --- a/server/modules/routing/binlog/blr.c +++ b/server/modules/routing/binlog/blr.c @@ -103,7 +103,6 @@ static void errorReply(ROUTER *instance, static uint64_t getCapabilities(); static int blr_handler_config(void *userdata, const char *section, const char *name, const char *value); static int blr_handle_config_item(const char *name, const char *value, ROUTER_INSTANCE *inst); -static int blr_set_service_mysql_user(SERVICE *service); static int blr_load_dbusers(const ROUTER_INSTANCE *router); static int blr_check_binlog(ROUTER_INSTANCE *router); int blr_read_events_all_events(ROUTER_INSTANCE *router, int fix, int debug); @@ -578,18 +577,6 @@ createInstance(SERVICE *service, char **options) } } - /* Allocate dbusers for this router here instead of serviceStartPort() */ - for (SERV_LISTENER *port = service->ports; port; port = port->next) - { - if ((port->users = mysql_users_alloc()) == NULL) - { - MXS_ERROR("%s: Error allocating dbusers in createInstance", - inst->service->name); - free_instance(inst); - return NULL; - } - } - /* Dynamically allocate master_host server struct, not written in any cnf file */ if (service->dbref == NULL) { @@ -674,19 +661,10 @@ createInstance(SERVICE *service, char **options) inst->service->name, inst->binlogdir); } - /* Set service user or load db users */ - blr_set_service_mysql_user(inst->service); - } else { inst->master_state = BLRM_UNCONNECTED; - - /* Try loading dbusers */ - if (inst->service->ports) - { - blr_load_dbusers(inst); - } } /** @@ -2134,140 +2112,6 @@ blr_handle_config_item(const char *name, const char *value, ROUTER_INSTANCE *ins return 1; } -/** - * Add the service user to mysql dbusers (service->users) - * via mysql_users_alloc and add_mysql_users_with_host_ipv4 - * User is added for '%' and 'localhost' hosts - * - * @param service The current service - * @return 0 on success, 1 on failure - */ -static int -blr_set_service_mysql_user(SERVICE *service) -{ - char *dpwd = NULL; - char *newpasswd = NULL; - char *service_user = NULL; - char *service_passwd = NULL; - - if (serviceGetUser(service, &service_user, &service_passwd) == 0) - { - MXS_ERROR("failed to get service user details for service %s", - service->name); - - return 1; - } - - dpwd = decryptPassword(service->credentials.authdata); - - if (!dpwd) - { - MXS_ERROR("decrypt password failed for service user %s, service %s", - service_user, - service->name); - - return 1; - } - - newpasswd = create_hex_sha1_sha1_passwd(dpwd); - - if (!newpasswd) - { - MXS_ERROR("create hex_sha1_sha1_password failed for service user %s", - service_user); - - MXS_FREE(dpwd); - return 1; - } - - /** Add the service user for % and localhost to all listeners so that - * it can always be used. */ - for (SERV_LISTENER *port = service->ports; port; port = port->next) - { - add_mysql_users_with_host_ipv4(port->users, service->credentials.name, - "%", newpasswd, "Y", ""); - add_mysql_users_with_host_ipv4(port->users, service->credentials.name, - "localhost", newpasswd, "Y", ""); - } - - MXS_FREE(newpasswd); - MXS_FREE(dpwd); - - return 0; -} - -/** - * Load mysql dbusers into (service->users) - * - * @param router The router instance - * @return -1 on failure, 0 for no users found, > 0 for found users - */ -static int -blr_load_dbusers(const ROUTER_INSTANCE *router) -{ - int loaded_total = 0; - SERVICE *service; - char path[PATH_MAX]; - service = router->service; - - for (SERV_LISTENER *port = service->ports; port; port = port->next) - { - sprintf(path, "%s/%s/%s/", router->binlogdir, BLR_DBUSERS_DIR, port->name); - - if (mxs_mkdir_all(path, 0775)) - { - strcat(path, BLR_DBUSERS_FILE); - } - - /* Try loading dbusers from configured backends */ - int loaded = load_mysql_users(port); - - if (loaded < 0) - { - MXS_ERROR("Unable to load users for service %s", service->name); - - /* Try loading authentication data from file cache */ - loaded = dbusers_load(port->users, path); - - if (loaded != -1) - { - MXS_ERROR("Service %s, Listener %s, Using cached credential information file %s.", - service->name, port->name, path); - } - else - { - MXS_ERROR("Service %s, Listener %s, Unable to read cache credential" - " information from %s. No database user added to service users table.", - service->name, port->name, path); - } - } - else - { - /* don't update cache if no user was loaded */ - if (loaded == 0) - { - MXS_ERROR("Service %s, Listener %s: failed to load any user information." - " Authentication will probably fail as a result.", - service->name, port->name); - } - else - { - /* update cached data */ - dbusers_save(port->users, path); - } - } - loaded_total += loaded; - } - - /* At service start last update is set to USERS_REFRESH_TIME seconds earlier. - * This way MaxScale could try reloading users' just after startup - */ - service->rate_limit.last = time(NULL) - USERS_REFRESH_TIME; - service->rate_limit.nloads = 1; - - return loaded_total; -} - /** * Extract a numeric field from a packet of the specified number of bits * diff --git a/server/modules/routing/binlog/blr_slave.c b/server/modules/routing/binlog/blr_slave.c index b958f5cd3..09613fcba 100644 --- a/server/modules/routing/binlog/blr_slave.c +++ b/server/modules/routing/binlog/blr_slave.c @@ -432,7 +432,7 @@ blr_slave_query(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, GWBUF *queue) else if (strcasecmp(word, "USER()") == 0) { /* Return user@host */ - char user_host[MYSQL_USER_MAXLEN + 1 + MYSQL_HOSTNAME_MAXLEN + 1] = ""; + char user_host[MYSQL_USER_MAXLEN + 1 + MYSQL_HOST_MAXLEN + 1] = ""; MXS_FREE(query_text); snprintf(user_host, sizeof(user_host), @@ -3401,8 +3401,6 @@ blr_stop_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave) static int blr_start_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave) { - int loaded; - /* if unconfigured return an error */ if (router->master_state == BLRM_UNCONFIGURED) { @@ -3532,28 +3530,7 @@ blr_start_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave) router->current_pos, router->binlog_position); /* Try reloading new users and update cached credentials */ - loaded = service_refresh_users(router->service); - - if (loaded == 0) - { - for (SERV_LISTENER *port = router->service->ports; port; port = port->next) - { - char path[PATH_MAX]; - sprintf(path, "%s/%s/%s/", router->binlogdir, BLR_DBUSERS_DIR, port->name); - - if (mxs_mkdir_all(path, 0775)) - { - strcat(path, BLR_DBUSERS_FILE); - dbusers_save(port->users, path); - } - } - } - else - { - MXS_NOTICE("Service %s: user credentials could not be refreshed. " - "Will use existing cached credentials (%s/%s) if possible.", - router->service->name, router->binlogdir, BLR_DBUSERS_DIR); - } + service_refresh_users(router->service); return blr_slave_send_ok(router, slave); } diff --git a/server/modules/routing/debugcli/debugcmd.c b/server/modules/routing/debugcli/debugcmd.c index 14d25249d..950f0882a 100644 --- a/server/modules/routing/debugcli/debugcmd.c +++ b/server/modules/routing/debugcli/debugcmd.c @@ -63,7 +63,6 @@ #include #include #include -#include #include #include #include diff --git a/server/modules/routing/maxinfo/maxinfo.c b/server/modules/routing/maxinfo/maxinfo.c index 574cd8418..d0fb26388 100644 --- a/server/modules/routing/maxinfo/maxinfo.c +++ b/server/modules/routing/maxinfo/maxinfo.c @@ -50,7 +50,6 @@ #include #include #include -#include MODULE_INFO info = @@ -69,7 +68,6 @@ static int maxinfo_statistics(INFO_INSTANCE *, INFO_SESSION *, GWBUF *); static int maxinfo_ping(INFO_INSTANCE *, INFO_SESSION *, GWBUF *); static int maxinfo_execute_query(INFO_INSTANCE *, INFO_SESSION *, char *); static int handle_url(INFO_INSTANCE *instance, INFO_SESSION *router_session, GWBUF *queue); -static int maxinfo_add_mysql_user(SERVICE *service); /* The router entry points */ @@ -182,13 +180,6 @@ createInstance(SERVICE *service, char **options) instances = inst; spinlock_release(&instlock); - /* - * The following add the service user to service->users via mysql_users_alloc() - * password to be used. - */ - - maxinfo_add_mysql_user(service); - return (ROUTER *)inst; } @@ -736,74 +727,3 @@ handle_url(INFO_INSTANCE *instance, INFO_SESSION *session, GWBUF *queue) gwbuf_free(queue); return 1; } - -/** - * Add the service user to the service->users - * via mysql_users_alloc and add_mysql_users_with_host_ipv4 - * User is added for '%' and 'localhost' hosts - * - * @param service The service for this router - * @return 0 on success, 1 on failure - */ -static int -maxinfo_add_mysql_user(SERVICE *service) -{ - int rval = 1; - char *service_user = NULL; - char *service_passwd = NULL; - - if (serviceGetUser(service, &service_user, &service_passwd) == 0) - { - MXS_ERROR("maxinfo: failed to get service user details"); - return 1; - } - - char *dpwd = decryptPassword(service->credentials.authdata); - - if (!dpwd) - { - MXS_ERROR("maxinfo: decrypt password failed for service user %s", service_user); - return 1; - } - - SERV_LISTENER *port = service->ports; - - while (port) - { - while (port && strcmp(port->protocol, "MySQLClient")) - { - port = port->next; - } - - if (port) - { - port->users = (void *)mysql_users_alloc(); - - char *newpasswd = create_hex_sha1_sha1_passwd(dpwd); - - if (!newpasswd) - { - MXS_ERROR("maxinfo: create hex_sha1_sha1_password failed for " - "service user %s", service_user); - users_free(port->users); - break; - } - - /* add service user for % and localhost */ - add_mysql_users_with_host_ipv4(port->users, service->credentials.name, - "%", newpasswd, "Y", ""); - add_mysql_users_with_host_ipv4(port->users, service->credentials.name, - "localhost", newpasswd, "Y", ""); - rval = 0; - MXS_FREE(newpasswd); - - /** Continue processing listeners in case there are multiple - * MySQLClient listeners*/ - port = port->next; - } - } - - MXS_FREE(dpwd); - - return rval; -}