From 72d48452d5ff60266114fdf8ac1e157cbc038f2f Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 16 Mar 2015 13:44:50 +0200 Subject: [PATCH] Fixed a bug with authentication data being loaded too many times. --- server/core/dbusers.c | 113 ++++++++++++++++++++++++++++++++++++++++-- server/core/service.c | 1 + 2 files changed, 110 insertions(+), 4 deletions(-) diff --git a/server/core/dbusers.c b/server/core/dbusers.c index 948a19efa..75715a809 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -146,7 +146,6 @@ HASHTABLE *oldresources; return 0; oldresources = service->resources; - service->resources = NULL; i = getUsers(service, newusers); @@ -184,7 +183,6 @@ HASHTABLE *oldresources; return -1; oldresources = service->resources; - service->resources = NULL; /* load db users ad db grants */ i = getUsers(service, newusers); @@ -326,6 +324,112 @@ int add_mysql_users_with_host_ipv4(USERS *users, char *user, char *host, char *p return ret; } +/** + * Add the database specific grants from mysql.db table into the service resources hashtable + * environment. + * + * @param service The current service + * @param users The users table into which to load the users + * @return -1 on any error or the number of users inserted (0 means no users at all) + */ +static int +addDatabases(SERVICE *service, MYSQL *con) +{ + MYSQL_ROW row; + MYSQL_RES *result = NULL; + char *service_user = NULL; + char *service_passwd = NULL; + int ndbs = 0; + + char *get_showdbs_priv_query = LOAD_MYSQL_DATABASE_NAMES; + + serviceGetUser(service, &service_user, &service_passwd); + + if (service_user == NULL || service_passwd == NULL) + return -1; + + if (mysql_query(con, get_showdbs_priv_query)) { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Loading database names for service %s encountered " + "error: %s.", + service->name, + mysql_error(con)))); + return -1; + } + + result = mysql_store_result(con); + + if (result == NULL) { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Loading database names for service %s encountered " + "error: %s.", + service->name, + mysql_error(con)))); + return -1; + } + + /* Result has only one row */ + row = mysql_fetch_row(result); + + if (row) { + ndbs = atoi(row[0]); + } else { + ndbs = 0; + + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "%s: Unable to load database grant information, MaxScale " + "authentication will proceed without including database " + "permissions. To correct this GRANT select permission " + "on mysql.db to the user %s.", + service->name, service_user))); + } + + /* free resut set */ + mysql_free_result(result); + + if (!ndbs) { + /* return if no db names are available */ + return 0; + } + + if (mysql_query(con, "SHOW DATABASES")) { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Loading database names for service %s encountered " + "error: %s.", + service->name, + mysql_error(con)))); + + return -1; + } + + result = mysql_store_result(con); + + if (result == NULL) { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Loading database names for service %s encountered " + "error: %s.", + service->name, + mysql_error(con)))); + + return -1; + } + + /* insert key and value "" */ + while ((row = mysql_fetch_row(result))) { + skygw_log_write(LOGFILE_DEBUG,"%s: Adding database %s to the resouce hash.",service->name,row[0]); + resource_add(service->resources, row[0], ""); + } + + mysql_free_result(result); + + return ndbs; +} + /** * Load the database specific grants from mysql.db table into the service resources hashtable * environment. @@ -422,7 +526,6 @@ getDatabases(SERVICE *service, MYSQL *con) } /* Now populate service->resources hashatable with db names */ - if(service->resources == NULL) service->resources = resource_alloc(); /* insert key and value "" */ @@ -497,6 +600,8 @@ getAllUsers(SERVICE *service, USERS *users) goto cleanup; } + service->resources = resource_alloc(); + while(server != NULL) { @@ -734,7 +839,7 @@ getAllUsers(SERVICE *service, USERS *users) if (db_grants) { /* load all mysql database names */ - dbnames = getDatabases(service, con); + dbnames = addDatabases(service, con); LOGIF(LD, (skygw_log_write( LOGFILE_DEBUG, diff --git a/server/core/service.c b/server/core/service.c index 1318070d6..603a4d7f3 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -132,6 +132,7 @@ SERVICE *service; service->name = strdup(servname); service->routerModule = strdup(router); service->users_from_all = false; + service->resources = NULL; if (service->name == NULL || service->routerModule == NULL) {