MySQL Auth with dbname check

MySQL Auth with dbname check

Unknown database ‘xxxxx’ is returned to client

Proper error number is still missing and also com_change_user need to
be fixed
This commit is contained in:
MassimilianoPinto 2014-10-16 19:17:15 +02:00
parent a82d18f517
commit 2dfa01fccc
5 changed files with 69 additions and 39 deletions

View File

@ -64,7 +64,7 @@ static int uh_cmpfun( void* v1, void* v2);
static void *uh_keydup(void* key);
static void uh_keyfree( void* key);
static int uh_hfun( void* key);
void *mysql_users_fetch(USERS *users, MYSQL_USER_HOST *key);
char *mysql_users_fetch(USERS *users, MYSQL_USER_HOST *key);
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);
static int getDatabases(SERVICE *);
@ -188,7 +188,11 @@ int add_mysql_users_with_host_ipv4(USERS *users, char *user, char *host, char *p
int found_any=0;
int ret = 0;
fprintf(stderr, "Current %s@%s has anydb access %s OR specific db %s\n", user, host, anydb, db);
//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) {
return ret;
}
/* prepare the user@host data struct */
memset(&serv_addr, 0, sizeof(serv_addr));
@ -219,10 +223,11 @@ int add_mysql_users_with_host_ipv4(USERS *users, char *user, char *host, char *p
found_any = 1;
} else {
char *tmp;
strcpy(ret_ip, host);
strncpy(ret_ip, host, INET_ADDRSTRLEN);
tmp = ret_ip+strlen(ret_ip)-1;
/* start from Class C */
while(tmp > ret_ip) {
if (*tmp == '%') {
/* set only the last IPv4 byte to 1
@ -254,10 +259,10 @@ int add_mysql_users_with_host_ipv4(USERS *users, char *user, char *host, char *p
}
/* add user@host as key and passwd as value in the MySQL users hash table */
if (mysql_users_add(users, &key, passwd))
if (mysql_users_add(users, &key, passwd)) {
ret = 1;
if (ret == 1)
fprintf(stderr, "Added user %s@%i with db [%s]\n", key.user, key.ipv4.sin_addr.s_addr, key.resource);
}
}
free(key.user);
@ -698,7 +703,7 @@ int add;
* @param key The key with user@host
* @return The authentication data or NULL on error
*/
void *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)
return NULL;

View File

@ -220,9 +220,9 @@ GWPROTOCOL *funcs;
dbnames_loaded = mysql_users_load_dbs(service);
LOGIF(LM, (skygw_log_write(
LOGFILE_MESSAGE,
"Loaded %d MySQL Databases.",
dbnames_loaded)));
LOGFILE_MESSAGE,
"Loaded %d MySQL Databases.",
dbnames_loaded)));
} else {
/* Generic users table */
service->users = users_alloc();

View File

@ -54,9 +54,23 @@ int set_and_get_single_mysql_users_ipv4(char *username, unsigned long ipv4, char
char ret_ip[200]="";
char *fetch_data;
char *db="";
DCB *dcb;
SERVICE *service;
unsigned long fix_ipv4;
dcb = dcb_alloc(DCB_ROLE_INTERNAL);
if (dcb == NULL) {
fprintf(stderr, "dcb_alloc() failed\n");
return 1;
}
if ((service = (SERVICE *)calloc(1, sizeof(SERVICE))) == NULL) {
fprintf(stderr, "service_alloc() failed\n");
dcb_free(dcb);
return 1;
}
if (ipv4 > UINT_MAX) {
fix_ipv4 = UINT_MAX;
} else {
@ -82,6 +96,8 @@ int set_and_get_single_mysql_users_ipv4(char *username, unsigned long ipv4, char
if (!mysql_users_add(mysql_users, &key, password)) {
fprintf(stderr, "Failed adding %s@%s(%lu)\n", username, ret_ip, fix_ipv4);
users_free(mysql_users);
free(service);
dcb_free(dcb);
return 1;
}
@ -97,6 +113,8 @@ int set_and_get_single_mysql_users_ipv4(char *username, unsigned long ipv4, char
fetch_data = mysql_users_fetch(mysql_users, &find_key);
users_free(mysql_users);
free(service);
dcb_free(dcb);
if (!fetch_data)
return 1;
@ -166,22 +184,23 @@ int set_and_get_single_mysql_users(char *username, char *hostname, char *passwor
int set_and_get_mysql_users_wildcards(char *username, char *hostname, char *password, char *from, char *anydb, char *db, char *db_from) {
USERS *mysql_users;
int ret;
int ret = -1;
int rc = -1;
struct sockaddr_in client_addr;
DCB *dcb;
SERVICE *service;
MYSQL_session data;
MYSQL_session *data;
dcb = dcb_alloc(DCB_ROLE_INTERNAL);
if (dcb == NULL) {
fprintf(stderr, "dcb_alloc() failed\n");
return 1;
return ret;
}
if ((service = (SERVICE *)calloc(1, sizeof(SERVICE))) == NULL) {
fprintf(stderr, "service_alloc() failed\n");
dcb_free(dcb);
return 1;
return ret;
}
memset(&client_addr, 0, sizeof(client_addr));
@ -191,10 +210,18 @@ int set_and_get_mysql_users_wildcards(char *username, char *hostname, char *pass
fprintf(stderr, "setipaddress failed for host [%s]\n", from);
free(service);
dcb_free(dcb);
return 1;
return ret;
}
}
if ((data = (MYSQL_session *) calloc(1, sizeof(MYSQL_session))) == NULL) {
fprintf(stderr, "MYSQL_session alloc failed\n");
free(service);
dcb_free(dcb);
return ret;
}
/* client IPv4 in raw data*/
memcpy(&dcb->ipv4, (struct sockaddr_in *)&client_addr, sizeof(struct sockaddr_in));
@ -205,14 +232,15 @@ int set_and_get_mysql_users_wildcards(char *username, char *hostname, char *pass
service->users = mysql_users;
if (db_from != NULL)
strcpy(data.db, db_from);
strcpy(data->db, db_from);
else
strcpy(data.db, "");
strcpy(data->db, "");
dcb->data = &data;
/* freed by dcb_free(dcb) */
dcb->data = data;
// the routine returns 1 on success
if (anydb) {
if (anydb != NULL) {
if (strcmp(anydb, "N") == 0) {
ret = add_mysql_users_with_host_ipv4(mysql_users, username, hostname, password, anydb, db);
} else if (strcmp(anydb, "Y") == 0) {
@ -223,25 +251,19 @@ int set_and_get_mysql_users_wildcards(char *username, char *hostname, char *pass
} else {
ret = add_mysql_users_with_host_ipv4(mysql_users, username, hostname, password, "N", NULL);
}
if (!ret) {
if (ret == 0) {
fprintf(stderr, "add_mysql_users_with_host_ipv4 (%s@%s, %s) FAILED\n", username, hostname, password);
users_free(mysql_users);
free(service);
dcb_free(dcb);
return 1;
} else {
char db_passwd[100]="";
unsigned char db_passwd[100]="";
dcb->remote=strdup(from);
//fprintf(stderr, "add_mysql_users_with_host_ipv4 passed(%s@%s, %s) OK\n", username, hostname, password);
fprintf(stderr, "Checking '%s' @ '%s' against (%s@%s)\n", username, from, username, hostname);
//fprintf(stderr, "Checking '%s' @ '%s' against (%s@%s)\n", username, from, username, hostname);
// returns 0 on success
ret = gw_find_mysql_user_password_sha1(username, db_passwd, dcb);
ret = gw_find_mysql_user_password_sha1(username, db_passwd, dcb);
}
users_free(mysql_users);
@ -309,7 +331,7 @@ int main() {
if (!ret) fprintf(stderr, "\t-- Expecting ok\n");
assert(ret == 0);
ret = set_and_get_mysql_users_wildcards("pippo", "192.168.1.%", "foo", "192.168.2.2", NULL, NULL, NULL);
ret = set_and_get_mysql_users_wildcards("pippo", "192.168.4.%", "ffoo", "192.168.2.2", NULL, NULL, NULL);
if (ret) fprintf(stderr, "\t-- Expecting no match\n");
assert(ret == 1);
@ -321,7 +343,6 @@ int main() {
if (!ret) fprintf(stderr, "\t-- Expecting ok\n");
assert(ret == 0);
fprintf(stderr, "Adding pippo, 192.%%.%%.%%, foo, 192.0.0.2, Y, NULL, cossa\n");
ret = set_and_get_mysql_users_wildcards("pippo", "192.%.%.%", "foo", "192.0.0.2", "Y", NULL, "cossa");
if (!ret) fprintf(stderr, "\t-- Expecting ok\n");
assert(ret == 0);
@ -383,8 +404,6 @@ int main() {
if (!ret) fprintf(stderr, "\t-- Expecting ok\n");
assert(ret == 0);
fprintf(stderr, "----------------\n");
fprintf(stderr, "<<< Test completed\n");

View File

@ -63,6 +63,6 @@ extern int reload_mysql_users(SERVICE *service);
extern int mysql_users_add(USERS *users, MYSQL_USER_HOST *key, char *auth);
extern int add_mysql_users_with_host_ipv4(USERS *users, char *user, char *host, char *passwd, char *anydb, char *db);
extern USERS *mysql_users_alloc();
extern void *mysql_users_fetch(USERS *users, MYSQL_USER_HOST *key);
extern char *mysql_users_fetch(USERS *users, MYSQL_USER_HOST *key);
extern int replace_mysql_users(SERVICE *service);
#endif

View File

@ -497,7 +497,7 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
i++;
}
if (!db_exists) {
if (!db_exists && auth_ret == 0) {
auth_ret = 2;
}
}
@ -735,18 +735,23 @@ int gw_read_client_event(
char* fail_str;
protocol->protocol_auth_state = MYSQL_AUTH_FAILED;
fail_str = create_auth_fail_str(read_buffer,
dcb->remote,
(char*)((MYSQL_session *)dcb->data)->client_sha1);
if (auth_val == 2) {
char *dberr;
dberr= calloc(1, 100);
sprintf(dberr, "Unknown database '%s'", (char*)((MYSQL_session *)dcb->data)->db);
mysql_send_auth_error(
dcb,
2,
0,
"Database not existent");
dberr);
free(dberr);
} else {
/** Send error 1045 to client */
fail_str = create_auth_fail_str(read_buffer,
dcb->remote,
(char*)((MYSQL_session *)dcb->data)->client_sha1);
mysql_send_auth_error(
dcb,
2,
@ -761,6 +766,7 @@ int gw_read_client_event(
"state = MYSQL_AUTH_FAILED.",
protocol->owner_dcb->fd,
pthread_self())));
free(fail_str);
dcb_close(dcb);
}