Added db names as hashtable
Added db names as hashtable
This commit is contained in:
@ -68,6 +68,7 @@ char *mysql_users_fetch(USERS *users, MYSQL_USER_HOST *key);
|
|||||||
char *mysql_format_user_entry(void *data);
|
char *mysql_format_user_entry(void *data);
|
||||||
int add_mysql_users_with_host_ipv4(USERS *users, char *user, char *host, char *passwd, char *anydb, char *db);
|
int add_mysql_users_with_host_ipv4(USERS *users, char *user, char *host, char *passwd, char *anydb, char *db);
|
||||||
static int getDatabases(SERVICE *);
|
static int getDatabases(SERVICE *);
|
||||||
|
HASHTABLE *resource_alloc();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the user/passwd form mysql.user table into the service users' hashtable
|
* Load the user/passwd form mysql.user table into the service users' hashtable
|
||||||
@ -188,8 +189,6 @@ int add_mysql_users_with_host_ipv4(USERS *users, char *user, char *host, char *p
|
|||||||
int found_any=0;
|
int found_any=0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
//fprintf(stderr, "Current %s@%s has anydb access %s OR specific db %s\n", user, host, anydb, db);
|
|
||||||
|
|
||||||
if (users == NULL || user == NULL || host == NULL) {
|
if (users == NULL || user == NULL || host == NULL) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -206,6 +205,10 @@ int add_mysql_users_with_host_ipv4(USERS *users, char *user, char *host, char *p
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* for anydb == Y key.resource is '\0' as set by memset */
|
/* for anydb == Y key.resource is '\0' as set by memset */
|
||||||
|
if (anydb == NULL) {
|
||||||
|
key.resource = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
if (strcmp(anydb, "N") == 0) {
|
if (strcmp(anydb, "N") == 0) {
|
||||||
if (db)
|
if (db)
|
||||||
key.resource = strdup(db);
|
key.resource = strdup(db);
|
||||||
@ -214,6 +217,7 @@ int add_mysql_users_with_host_ipv4(USERS *users, char *user, char *host, char *p
|
|||||||
} else {
|
} else {
|
||||||
key.resource = strdup("");
|
key.resource = strdup("");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* handle ANY, Class C,B,A */
|
/* handle ANY, Class C,B,A */
|
||||||
|
|
||||||
@ -286,20 +290,15 @@ getDatabases(SERVICE *service)
|
|||||||
MYSQL *con = NULL;
|
MYSQL *con = NULL;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
MYSQL_RES *result = NULL;
|
MYSQL_RES *result = NULL;
|
||||||
int num_fields = 0;
|
|
||||||
char *service_user = NULL;
|
char *service_user = NULL;
|
||||||
char *service_passwd = NULL;
|
char *service_passwd = NULL;
|
||||||
char *dpwd;
|
char *dpwd;
|
||||||
int total_users = 0;
|
|
||||||
SERVER *server;
|
SERVER *server;
|
||||||
char *users_query;
|
|
||||||
unsigned char hash[SHA_DIGEST_LENGTH]="";
|
|
||||||
char *users_data = NULL;
|
|
||||||
int ndbs = 0;
|
int ndbs = 0;
|
||||||
/* last byte is for Select_priv=Y|N */
|
|
||||||
int users_data_row_len = MYSQL_USER_MAXLEN + MYSQL_HOST_MAXLEN + MYSQL_PASSWORD_LEN + sizeof(char);
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
char *get_showdbs_priv_query="SELECT * FROM ( (SELECT COUNT(1) AS ndbs FROM INFORMATION_SCHEMA.SCHEMATA) AS tbl1, (SELECT GRANTEE,PRIVILEGE_TYPE from INFORMATION_SCHEMA.USER_PRIVILEGES WHERE privilege_type='SHOW DATABASES' AND REPLACE(GRANTEE, \"\'\",\"\")=CURRENT_USER()) AS tbl2)";
|
||||||
|
|
||||||
serviceGetUser(service, &service_user, &service_passwd);
|
serviceGetUser(service, &service_user, &service_passwd);
|
||||||
if (service_user == NULL || service_passwd == NULL)
|
if (service_user == NULL || service_passwd == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
@ -346,14 +345,14 @@ getDatabases(SERVICE *service)
|
|||||||
{
|
{
|
||||||
LOGIF(LE, (skygw_log_write_flush(
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
LOGFILE_ERROR,
|
LOGFILE_ERROR,
|
||||||
"Error : Unable to get user data from backend database "
|
"Error : Unable to load db names from backend database "
|
||||||
"for service %s. Missing server information.",
|
"for service %s. Missing server information.",
|
||||||
service->name)));
|
service->name)));
|
||||||
mysql_close(con);
|
mysql_close(con);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mysql_query(con, "select count(1) from information_schema.SCHEMATA")) {
|
if (mysql_query(con, get_showdbs_priv_query)) {
|
||||||
LOGIF(LE, (skygw_log_write_flush(
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
LOGFILE_ERROR,
|
LOGFILE_ERROR,
|
||||||
"Error : Loading database names for service %s encountered "
|
"Error : Loading database names for service %s encountered "
|
||||||
@ -363,6 +362,7 @@ getDatabases(SERVICE *service)
|
|||||||
mysql_close(con);
|
mysql_close(con);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = mysql_store_result(con);
|
result = mysql_store_result(con);
|
||||||
|
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
@ -375,30 +375,33 @@ getDatabases(SERVICE *service)
|
|||||||
mysql_close(con);
|
mysql_close(con);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
num_fields = mysql_num_fields(result);
|
|
||||||
|
/* Result has only one row */
|
||||||
row = mysql_fetch_row(result);
|
row = mysql_fetch_row(result);
|
||||||
|
|
||||||
|
if (row) {
|
||||||
ndbs = atoi(row[0]);
|
ndbs = atoi(row[0]);
|
||||||
|
} else {
|
||||||
|
ndbs = 0;
|
||||||
|
|
||||||
mysql_free_result(result);
|
|
||||||
|
|
||||||
fprintf(stderr, "Found %i schemas\n", ndbs);
|
|
||||||
|
|
||||||
if (!ndbs) {
|
|
||||||
LOGIF(LE, (skygw_log_write_flush(
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
LOGFILE_ERROR,
|
LOGFILE_ERROR,
|
||||||
"Error : Counting users for service %s returned 0",
|
"Warning: Loading DB names for service [%s] returned 0 rows."
|
||||||
service->name)));
|
" SHOW DATABASES grant to user [%s] is required for MaxScale DB Name Authentication",
|
||||||
|
service->name,
|
||||||
|
service_user)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free resut set */
|
||||||
|
mysql_free_result(result);
|
||||||
|
|
||||||
|
if (!ndbs) {
|
||||||
|
/* return if no db names are available */
|
||||||
mysql_close(con);
|
mysql_close(con);
|
||||||
return -1;
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
service->resources = (char **) calloc(ndbs+1, sizeof(char *));
|
|
||||||
for (i = 0; i < ndbs; i++) {
|
|
||||||
service->resources[i] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
service->resources[i] = NULL;
|
|
||||||
|
|
||||||
if (mysql_query(con, "SHOW DATABASES")) {
|
if (mysql_query(con, "SHOW DATABASES")) {
|
||||||
LOGIF(LE, (skygw_log_write_flush(
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
@ -407,6 +410,7 @@ getDatabases(SERVICE *service)
|
|||||||
"error: %s.",
|
"error: %s.",
|
||||||
service->name,
|
service->name,
|
||||||
mysql_error(con))));
|
mysql_error(con))));
|
||||||
|
|
||||||
mysql_close(con);
|
mysql_close(con);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -420,19 +424,33 @@ getDatabases(SERVICE *service)
|
|||||||
"error: %s.",
|
"error: %s.",
|
||||||
service->name,
|
service->name,
|
||||||
mysql_error(con))));
|
mysql_error(con))));
|
||||||
|
|
||||||
|
/* cleanup the hashtable */
|
||||||
mysql_close(con);
|
mysql_close(con);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
num_fields = mysql_num_fields(result);
|
|
||||||
|
|
||||||
|
/* Now populate service->resources hashatable with db names */
|
||||||
|
//service->resources = (char **) calloc(ndbs+1, sizeof(char *));
|
||||||
|
service->resources = resource_alloc();
|
||||||
|
|
||||||
|
// if calloc fails, return -1
|
||||||
|
|
||||||
|
//for (i = 0; i < ndbs; i++) {
|
||||||
|
// service->resources[i] = NULL;
|
||||||
|
//}
|
||||||
i = 0;
|
i = 0;
|
||||||
while ((row = mysql_fetch_row(result))) {
|
while ((row = mysql_fetch_row(result))) {
|
||||||
service->resources[i] = strndup(row[0], MYSQL_DATABASE_MAXLEN);
|
//service->resources[i] = strndup(row[0], MYSQL_DATABASE_MAXLEN);
|
||||||
fprintf(stderr, "Found a Database[%i]:[%s]\n", i, service->resources[i]);
|
fprintf(stderr, "Found a Database[%i]:[%s]\n", i, row[0]);
|
||||||
|
resource_add(service->resources, row[0], "");
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mysql_free_result(result);
|
||||||
|
mysql_close(con);
|
||||||
|
|
||||||
return ndbs;
|
return ndbs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,38 +468,33 @@ getUsers(SERVICE *service, USERS *users)
|
|||||||
MYSQL *con = NULL;
|
MYSQL *con = NULL;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
MYSQL_RES *result = NULL;
|
MYSQL_RES *result = NULL;
|
||||||
int num_fields = 0;
|
|
||||||
char *service_user = NULL;
|
char *service_user = NULL;
|
||||||
char *service_passwd = NULL;
|
char *service_passwd = NULL;
|
||||||
char *dpwd;
|
char *dpwd;
|
||||||
int total_users = 0;
|
int total_users = 0;
|
||||||
SERVER *server;
|
SERVER *server;
|
||||||
char *users_query;
|
char *users_query;
|
||||||
char *dbs_query;
|
|
||||||
unsigned char hash[SHA_DIGEST_LENGTH]="";
|
unsigned char hash[SHA_DIGEST_LENGTH]="";
|
||||||
char *users_data = NULL;
|
char *users_data = NULL;
|
||||||
int nusers = 0;
|
int nusers = 0;
|
||||||
/* last byte is for Select_priv=Y|N */
|
/* last byte is for Select_priv=Y|N */
|
||||||
int users_data_row_len = MYSQL_USER_MAXLEN + MYSQL_HOST_MAXLEN + MYSQL_PASSWORD_LEN + sizeof(char);
|
int users_data_row_len = MYSQL_USER_MAXLEN + MYSQL_HOST_MAXLEN + MYSQL_PASSWORD_LEN + sizeof(char);
|
||||||
|
int dbnames_loaded = 0;
|
||||||
|
|
||||||
/* enable_root for MySQL protocol module means load the root user credentials from backend databases */
|
|
||||||
/*
|
|
||||||
if(service->enable_root) {
|
|
||||||
users_query = LOAD_MYSQL_USERS_QUERY " ORDER BY HOST DESC";
|
|
||||||
} else {
|
|
||||||
users_query = LOAD_MYSQL_USERS_QUERY USERS_QUERY_NO_ROOT " ORDER BY HOST DESC";
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if(service->enable_root) {
|
|
||||||
users_query = LOAD_MYSQL_USERS_WITH_DB_QUERY;
|
|
||||||
} else {
|
|
||||||
users_query = LOAD_MYSQL_USERS_WITH_DB_QUERY_NO_ROOT;
|
|
||||||
}
|
|
||||||
|
|
||||||
serviceGetUser(service, &service_user, &service_passwd);
|
serviceGetUser(service, &service_user, &service_passwd);
|
||||||
|
|
||||||
if (service_user == NULL || service_passwd == NULL)
|
if (service_user == NULL || service_passwd == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* load all mysql database names */
|
||||||
|
dbnames_loaded = mysql_users_load_dbs(service);
|
||||||
|
|
||||||
|
LOGIF(LM, (skygw_log_write(
|
||||||
|
LOGFILE_MESSAGE,
|
||||||
|
"Loaded %d MySQL Database Names.",
|
||||||
|
dbnames_loaded)));
|
||||||
|
|
||||||
con = mysql_init(NULL);
|
con = mysql_init(NULL);
|
||||||
|
|
||||||
if (con == NULL) {
|
if (con == NULL) {
|
||||||
@ -507,6 +520,7 @@ getUsers(SERVICE *service, USERS *users)
|
|||||||
*/
|
*/
|
||||||
server = service->databases;
|
server = service->databases;
|
||||||
dpwd = decryptPassword(service_passwd);
|
dpwd = decryptPassword(service_passwd);
|
||||||
|
|
||||||
while (server != NULL && (mysql_real_connect(con,
|
while (server != NULL && (mysql_real_connect(con,
|
||||||
server->name,
|
server->name,
|
||||||
service_user,
|
service_user,
|
||||||
@ -525,7 +539,7 @@ getUsers(SERVICE *service, USERS *users)
|
|||||||
LOGIF(LE, (skygw_log_write_flush(
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
LOGFILE_ERROR,
|
LOGFILE_ERROR,
|
||||||
"Error : Unable to get user data from backend database "
|
"Error : Unable to get user data from backend database "
|
||||||
"for service %s. Missing server information.",
|
"for service [%s]. Missing server information.",
|
||||||
service->name)));
|
service->name)));
|
||||||
mysql_close(con);
|
mysql_close(con);
|
||||||
return -1;
|
return -1;
|
||||||
@ -534,8 +548,8 @@ getUsers(SERVICE *service, USERS *users)
|
|||||||
if (mysql_query(con, MYSQL_USERS_COUNT)) {
|
if (mysql_query(con, MYSQL_USERS_COUNT)) {
|
||||||
LOGIF(LE, (skygw_log_write_flush(
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
LOGFILE_ERROR,
|
LOGFILE_ERROR,
|
||||||
"Error : Loading users for service %s encountered "
|
"Error : Loading users for service [%s] encountered "
|
||||||
"error: %s.",
|
"error: [%s].",
|
||||||
service->name,
|
service->name,
|
||||||
mysql_error(con))));
|
mysql_error(con))));
|
||||||
mysql_close(con);
|
mysql_close(con);
|
||||||
@ -546,14 +560,14 @@ getUsers(SERVICE *service, USERS *users)
|
|||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
LOGIF(LE, (skygw_log_write_flush(
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
LOGFILE_ERROR,
|
LOGFILE_ERROR,
|
||||||
"Error : Loading users for service %s encountered "
|
"Error : Loading users for service [%s] encountered "
|
||||||
"error: %s.",
|
"error: [%s].",
|
||||||
service->name,
|
service->name,
|
||||||
mysql_error(con))));
|
mysql_error(con))));
|
||||||
mysql_close(con);
|
mysql_close(con);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
num_fields = mysql_num_fields(result);
|
|
||||||
row = mysql_fetch_row(result);
|
row = mysql_fetch_row(result);
|
||||||
|
|
||||||
nusers = atoi(row[0]);
|
nusers = atoi(row[0]);
|
||||||
@ -569,17 +583,70 @@ getUsers(SERVICE *service, USERS *users)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "---> result from dbnames_loaded = [%i]\n", dbnames_loaded);
|
||||||
|
|
||||||
|
/* enable_root for MySQL protocol module means load the root user credentials from backend databases */
|
||||||
|
if (dbnames_loaded > 0) {
|
||||||
|
fprintf(stderr, "Loading dbnames_loaded = [%i]\n", dbnames_loaded);
|
||||||
|
if(service->enable_root) {
|
||||||
|
users_query = LOAD_MYSQL_USERS_WITH_DB_QUERY;
|
||||||
|
} else {
|
||||||
|
users_query = LOAD_MYSQL_USERS_WITH_DB_QUERY_NO_ROOT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(service->enable_root) {
|
||||||
|
users_query = LOAD_MYSQL_USERS_QUERY " ORDER BY HOST DESC";
|
||||||
|
} else {
|
||||||
|
users_query = LOAD_MYSQL_USERS_QUERY USERS_QUERY_NO_ROOT " ORDER BY HOST DESC";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if there is a Table access denied, try first removing dbanme from user selection */
|
||||||
|
if (mysql_query(con, users_query)) {
|
||||||
|
/* if not ER_TABLEACCESS_DENIED_ERROR) exit */
|
||||||
|
if (1142 != mysql_errno(con)) {
|
||||||
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
|
LOGFILE_ERROR,
|
||||||
|
"Error : Loading users with dbnames for service [%s] encountered "
|
||||||
|
"error: [%s], MySQL errno %i",
|
||||||
|
service->name,
|
||||||
|
mysql_error(con),
|
||||||
|
mysql_errno(con))));
|
||||||
|
|
||||||
|
mysql_close(con);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
/* ER_TABLEACCESS_DENIED_ERROR, try mysql.user only query without DB names */
|
||||||
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
|
LOGFILE_ERROR,
|
||||||
|
"Warning: Loading DB grants failed: GRANT is required on [mysql.db] to user [%s]. Try loading DB users for service [%s] without DB name MaxScale Authentication", service_user, service->name)));
|
||||||
|
|
||||||
|
if(service->enable_root) {
|
||||||
|
users_query = LOAD_MYSQL_USERS_QUERY " ORDER BY HOST DESC";
|
||||||
|
} else {
|
||||||
|
users_query = LOAD_MYSQL_USERS_QUERY USERS_QUERY_NO_ROOT " ORDER BY HOST DESC";
|
||||||
|
}
|
||||||
|
|
||||||
if (mysql_query(con, users_query)) {
|
if (mysql_query(con, users_query)) {
|
||||||
LOGIF(LE, (skygw_log_write_flush(
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
LOGFILE_ERROR,
|
LOGFILE_ERROR,
|
||||||
"Error : Loading users for service %s encountered "
|
"Error : Loading users for service [%s] encountered "
|
||||||
"error: %s.",
|
"error: [%s], code %i",
|
||||||
service->name,
|
service->name,
|
||||||
mysql_error(con))));
|
mysql_error(con),
|
||||||
|
mysql_errno(con))));
|
||||||
|
|
||||||
mysql_close(con);
|
mysql_close(con);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* users loaded but without dbnames */
|
||||||
|
dbnames_loaded = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
result = mysql_store_result(con);
|
result = mysql_store_result(con);
|
||||||
|
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
@ -589,30 +656,39 @@ getUsers(SERVICE *service, USERS *users)
|
|||||||
"error: %s.",
|
"error: %s.",
|
||||||
service->name,
|
service->name,
|
||||||
mysql_error(con))));
|
mysql_error(con))));
|
||||||
|
|
||||||
|
mysql_free_result(result);
|
||||||
mysql_close(con);
|
mysql_close(con);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
num_fields = mysql_num_fields(result);
|
|
||||||
|
|
||||||
users_data = (char *)calloc(nusers, (users_data_row_len * sizeof(char)) + 1);
|
users_data = (char *)calloc(nusers, (users_data_row_len * sizeof(char)) + 1);
|
||||||
|
|
||||||
if(users_data == NULL)
|
if(users_data == NULL) {
|
||||||
|
mysql_free_result(result);
|
||||||
|
mysql_close(con);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
while ((row = mysql_fetch_row(result))) {
|
while ((row = mysql_fetch_row(result))) {
|
||||||
/**
|
/**
|
||||||
* Six fields should be returned.
|
* Up to six fields could be returned.
|
||||||
* user,host,passwd,concat(),anydb,db
|
* user,host,passwd,concat(),anydb,db
|
||||||
* passwd+1 (escaping the first byte that is '*')
|
* passwd+1 (escaping the first byte that is '*')
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
|
if (dbnames_loaded)
|
||||||
rc = add_mysql_users_with_host_ipv4(users, row[0], row[1], strlen(row[2]) ? row[2]+1 : row[2], row[4], row[5]);
|
rc = add_mysql_users_with_host_ipv4(users, row[0], row[1], strlen(row[2]) ? row[2]+1 : row[2], row[4], row[5]);
|
||||||
|
else
|
||||||
|
rc = add_mysql_users_with_host_ipv4(users, row[0], row[1], strlen(row[2]) ? row[2]+1 : row[2], "Y", NULL);
|
||||||
|
|
||||||
if (rc == 1) {
|
if (rc == 1) {
|
||||||
LOGIF(LD, (skygw_log_write_flush(
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
LOGFILE_DEBUG,
|
LOGFILE_ERROR,
|
||||||
"%lu [mysql_users_add()] Added user %s@%s",
|
"%lu [mysql_users_add()] Added user %s@%s",
|
||||||
pthread_self(),
|
pthread_self(),
|
||||||
row[0],
|
row[0],
|
||||||
@ -704,12 +780,9 @@ int add;
|
|||||||
* @return The authentication data or NULL on error
|
* @return The authentication data or NULL on error
|
||||||
*/
|
*/
|
||||||
char *mysql_users_fetch(USERS *users, MYSQL_USER_HOST *key) {
|
char *mysql_users_fetch(USERS *users, MYSQL_USER_HOST *key) {
|
||||||
MYSQL_USER_HOST *entry;
|
|
||||||
if (key == NULL)
|
if (key == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
atomic_add(&users->stats.n_fetches, 1);
|
atomic_add(&users->stats.n_fetches, 1);
|
||||||
|
|
||||||
return hashtable_fetch(users->data, key);
|
return hashtable_fetch(users->data, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -877,9 +950,62 @@ char *mysql_format_user_entry(void *data)
|
|||||||
strcat(mysql_user, " db: ANY");
|
strcat(mysql_user, " db: ANY");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
strcat(mysql_user, " no db");
|
//strcat(mysql_user, " no db");
|
||||||
}
|
}
|
||||||
|
|
||||||
return mysql_user;
|
return mysql_user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
resource_hash(char *key)
|
||||||
|
{
|
||||||
|
return (*key + *(key + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
resource_free(HASHTABLE *resources)
|
||||||
|
{
|
||||||
|
hashtable_free(resources);
|
||||||
|
}
|
||||||
|
|
||||||
|
HASHTABLE *
|
||||||
|
resource_alloc()
|
||||||
|
{
|
||||||
|
HASHTABLE *resources;
|
||||||
|
|
||||||
|
if ((resources = hashtable_alloc(10, resource_hash, strcmp)) == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
hashtable_memory_fns(resources, (HASHMEMORYFN)strdup, (HASHMEMORYFN)strdup, (HASHMEMORYFN)free, (HASHMEMORYFN)free);
|
||||||
|
|
||||||
|
return resources;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
resource_add(HASHTABLE *resources, char *key, char *value)
|
||||||
|
{
|
||||||
|
return hashtable_add(resources, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
resource_delete(HASHTABLE *resources, char *key)
|
||||||
|
{
|
||||||
|
return hashtable_delete(resources, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
char
|
||||||
|
*resource_fetch(HASHTABLE *resources, char *key)
|
||||||
|
{
|
||||||
|
return hashtable_fetch(resources, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
resource_update(HASHTABLE *resources, char *key, char *value)
|
||||||
|
{
|
||||||
|
if (hashtable_delete(resources, key) == 0)
|
||||||
|
return 0;
|
||||||
|
return hashtable_add(resources, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -199,11 +199,14 @@ GWPROTOCOL *funcs;
|
|||||||
}
|
}
|
||||||
if (strcmp(port->protocol, "MySQLClient") == 0) {
|
if (strcmp(port->protocol, "MySQLClient") == 0) {
|
||||||
int loaded;
|
int loaded;
|
||||||
int dbnames_loaded;
|
|
||||||
|
|
||||||
/* Allocate specific data for MySQL users */
|
/*
|
||||||
|
* Allocate specific data for MySQL users
|
||||||
|
* including hosts and db names
|
||||||
|
*/
|
||||||
service->users = mysql_users_alloc();
|
service->users = mysql_users_alloc();
|
||||||
loaded = load_mysql_users(service);
|
loaded = load_mysql_users(service);
|
||||||
|
|
||||||
/* At service start last update is set to USERS_REFRESH_TIME seconds earlier.
|
/* At service start last update is set to USERS_REFRESH_TIME seconds earlier.
|
||||||
* This way MaxScale could try reloading users' just after startup
|
* This way MaxScale could try reloading users' just after startup
|
||||||
*/
|
*/
|
||||||
@ -215,14 +218,6 @@ GWPROTOCOL *funcs;
|
|||||||
LOGFILE_MESSAGE,
|
LOGFILE_MESSAGE,
|
||||||
"Loaded %d MySQL Users.",
|
"Loaded %d MySQL Users.",
|
||||||
loaded)));
|
loaded)));
|
||||||
|
|
||||||
/* load all mysql database names */
|
|
||||||
dbnames_loaded = mysql_users_load_dbs(service);
|
|
||||||
|
|
||||||
LOGIF(LM, (skygw_log_write(
|
|
||||||
LOGFILE_MESSAGE,
|
|
||||||
"Loaded %d MySQL Databases.",
|
|
||||||
dbnames_loaded)));
|
|
||||||
} else {
|
} else {
|
||||||
/* Generic users table */
|
/* Generic users table */
|
||||||
service->users = users_alloc();
|
service->users = users_alloc();
|
||||||
|
|||||||
@ -23,6 +23,7 @@
|
|||||||
#include <dcb.h>
|
#include <dcb.h>
|
||||||
#include <server.h>
|
#include <server.h>
|
||||||
#include <filter.h>
|
#include <filter.h>
|
||||||
|
#include <hashtable.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,6 +46,7 @@
|
|||||||
* 29/05/14 Mark Riddoch Filter API mechanism
|
* 29/05/14 Mark Riddoch Filter API mechanism
|
||||||
* 26/06/14 Mark Riddoch Added WeightBy support
|
* 26/06/14 Mark Riddoch Added WeightBy support
|
||||||
* 09/09/14 Massimiliano Pinto Added service option for localhost authentication
|
* 09/09/14 Massimiliano Pinto Added service option for localhost authentication
|
||||||
|
* 09/10/14 Massimiliano Pinto Added service resources via hashtable
|
||||||
*
|
*
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
@ -124,7 +126,7 @@ typedef struct service {
|
|||||||
struct users *users; /**< The user data for this service */
|
struct users *users; /**< The user data for this service */
|
||||||
int enable_root; /**< Allow root user access */
|
int enable_root; /**< Allow root user access */
|
||||||
int localhost_match_wildcard_host; /**< Match localhost against wildcard */
|
int localhost_match_wildcard_host; /**< Match localhost against wildcard */
|
||||||
char **resources; /** resource list, todo: use hashtables */
|
HASHTABLE *resources; /**< hastable for service resources, i.e. database names */
|
||||||
CONFIG_PARAMETER*
|
CONFIG_PARAMETER*
|
||||||
svc_config_param; /*< list of config params and values */
|
svc_config_param; /*< list of config params and values */
|
||||||
int svc_config_version; /*< Version number of configuration */
|
int svc_config_version; /*< Version number of configuration */
|
||||||
|
|||||||
@ -1246,6 +1246,12 @@ static int gw_change_user(
|
|||||||
|
|
||||||
if (strlen(database)) {
|
if (strlen(database)) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
if (backend->session->client->service->resources) {
|
||||||
|
if (hashtable_fetch(backend->session->client->service->resources, database)) {
|
||||||
|
db_exists = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
while(backend->session->client->service->resources[i]) {
|
while(backend->session->client->service->resources[i]) {
|
||||||
if (strncmp(database, backend->session->client->service->resources[i], MYSQL_DATABASE_MAXLEN) == 0) {
|
if (strncmp(database, backend->session->client->service->resources[i], MYSQL_DATABASE_MAXLEN) == 0) {
|
||||||
db_exists = 1;
|
db_exists = 1;
|
||||||
@ -1253,7 +1259,7 @@ static int gw_change_user(
|
|||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
if (!db_exists && auth_ret == 0) {
|
if (!db_exists && auth_ret == 0) {
|
||||||
auth_ret = 2;
|
auth_ret = 2;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -495,6 +495,12 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
|
|||||||
|
|
||||||
if (database && strlen(database)) {
|
if (database && strlen(database)) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
if (dcb->service->resources) {
|
||||||
|
if (hashtable_fetch(dcb->service->resources, database)) {
|
||||||
|
db_exists = 1;
|
||||||
|
}
|
||||||
|
/* fetch dbname */
|
||||||
|
/*
|
||||||
while(dcb->service->resources[i]) {
|
while(dcb->service->resources[i]) {
|
||||||
if (strncmp(database, dcb->service->resources[i], MYSQL_DATABASE_MAXLEN) == 0) {
|
if (strncmp(database, dcb->service->resources[i], MYSQL_DATABASE_MAXLEN) == 0) {
|
||||||
db_exists = 1;
|
db_exists = 1;
|
||||||
@ -502,6 +508,11 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
|
|||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
} else {
|
||||||
|
/* if database names are not loaded we take dbname as existent */
|
||||||
|
db_exists = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!db_exists && auth_ret == 0) {
|
if (!db_exists && auth_ret == 0) {
|
||||||
auth_ret = 2;
|
auth_ret = 2;
|
||||||
|
|||||||
Reference in New Issue
Block a user