Merge branch 'develop' into firewall

This commit is contained in:
Markus Makela
2014-10-29 13:21:55 +02:00
36 changed files with 6120 additions and 302 deletions

View File

@ -1168,7 +1168,11 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue)
}
if (queue->next != NULL)
{
queue = gwbuf_make_contiguous(queue);
}
if(modutil_extract_SQL(queue, &ptr, &length)){
my_session->was_query = true;

View File

@ -358,24 +358,30 @@ int length;
struct tm t;
struct timeval tv;
if (my_session->active && modutil_extract_SQL(queue, &ptr, &length))
if (my_session->active)
{
if ((my_instance->match == NULL ||
regexec(&my_instance->re, ptr, 0, NULL, 0) == 0) &&
(my_instance->nomatch == NULL ||
regexec(&my_instance->nore,ptr,0,NULL, 0) != 0))
if (queue->next != NULL)
{
gettimeofday(&tv, NULL);
localtime_r(&tv.tv_sec, &t);
fprintf(my_session->fp,
"%02d:%02d:%02d.%-3d %d/%02d/%d, ",
t.tm_hour, t.tm_min, t.tm_sec, (int)(tv.tv_usec / 1000),
t.tm_mday, t.tm_mon + 1, 1900 + t.tm_year);
fwrite(ptr, sizeof(char), length, my_session->fp);
fwrite("\n", sizeof(char), 1, my_session->fp);
queue = gwbuf_make_contiguous(queue);
}
if (modutil_extract_SQL(queue, &ptr, &length) != 0)
{
if ((my_instance->match == NULL ||
regexec(&my_instance->re, ptr, 0, NULL, 0) == 0) &&
(my_instance->nomatch == NULL ||
regexec(&my_instance->nore,ptr,0,NULL, 0) != 0))
{
gettimeofday(&tv, NULL);
localtime_r(&tv.tv_sec, &t);
fprintf(my_session->fp,
"%02d:%02d:%02d.%-3d %d/%02d/%d, ",
t.tm_hour, t.tm_min, t.tm_sec, (int)(tv.tv_usec / 1000),
t.tm_mday, t.tm_mon + 1, 1900 + t.tm_year);
fwrite(ptr, sizeof(char), length, my_session->fp);
fwrite("\n", sizeof(char), 1, my_session->fp);
}
}
}
/* Pass the query downstream */
return my_session->down.routeQuery(my_session->down.instance,
my_session->down.session, queue);

View File

@ -305,12 +305,17 @@ int length;
if (modutil_is_SQL(queue))
{
if (queue->next != NULL)
{
queue = gwbuf_make_contiguous(queue);
}
modutil_extract_SQL(queue, &sql, &length);
newsql = regex_replace(sql, length, &my_instance->re,
my_instance->replace);
if (newsql)
{
queue = modutil_replace_SQL(queue, newsql);
queue = gwbuf_make_contiguous(queue);
free(newsql);
my_session->replacements++;
}

View File

@ -455,21 +455,27 @@ TOPN_SESSION *my_session = (TOPN_SESSION *)session;
char *ptr;
int length;
if (my_session->active && modutil_extract_SQL(queue, &ptr, &length))
if (my_session->active)
{
if ((my_instance->match == NULL ||
regexec(&my_instance->re, ptr, 0, NULL, 0) == 0) &&
(my_instance->exclude == NULL ||
regexec(&my_instance->exre,ptr,0,NULL, 0) != 0))
if (queue->next != NULL)
{
my_session->n_statements++;
if (my_session->current)
free(my_session->current);
gettimeofday(&my_session->start, NULL);
my_session->current = strndup(ptr, length);
queue = gwbuf_make_contiguous(queue);
}
if (modutil_extract_SQL(queue, &ptr, &length) != 0)
{
if ((my_instance->match == NULL ||
regexec(&my_instance->re, ptr, 0, NULL, 0) == 0) &&
(my_instance->exclude == NULL ||
regexec(&my_instance->exre,ptr,0,NULL, 0) != 0))
{
my_session->n_statements++;
if (my_session->current)
free(my_session->current);
gettimeofday(&my_session->start, NULL);
my_session->current = strndup(ptr, length);
}
}
}
/* Pass the query downstream */
return my_session->down.routeQuery(my_session->down.instance,
my_session->down.session, queue);

View File

@ -454,7 +454,7 @@ size_t nrounds = 0;
* round.
*/
if (nrounds != 0 &&
((nrounds*MON_BASE_INTERVAL_MS)%handle->interval) >
((nrounds*MON_BASE_INTERVAL_MS)%handle->interval) >=
MON_BASE_INTERVAL_MS)
{
nrounds += 1;

View File

@ -618,7 +618,7 @@ size_t nrounds = 0;
* round.
*/
if (nrounds != 0 &&
((nrounds*MON_BASE_INTERVAL_MS)%handle->interval) >
((nrounds*MON_BASE_INTERVAL_MS)%handle->interval) >=
MON_BASE_INTERVAL_MS)
{
nrounds += 1;
@ -861,8 +861,8 @@ static void set_master_heartbeat(MYSQL_MONITOR *handle, MONITOR_SERVERS *databas
unsigned long id = handle->id;
time_t heartbeat;
time_t purge_time;
char heartbeat_insert_query[128]="";
char heartbeat_purge_query[128]="";
char heartbeat_insert_query[512]="";
char heartbeat_purge_query[512]="";
/* create the maxscale_schema database */
if (mysql_query(database->con, "CREATE DATABASE IF NOT EXISTS maxscale_schema")) {

View File

@ -452,7 +452,7 @@ size_t nrounds = 0;
* round.
*/
if (nrounds != 0 &&
((nrounds*MON_BASE_INTERVAL_MS)%handle->interval) >
((nrounds*MON_BASE_INTERVAL_MS)%handle->interval) >=
MON_BASE_INTERVAL_MS)
{
nrounds += 1;

View File

@ -20,6 +20,8 @@
#include <skygw_types.h>
#include <skygw_utils.h>
#include <log_manager.h>
#include <modutil.h>
/*
* MySQL Protocol module for handling the protocol between the gateway
* and the backend MySQL database.
@ -41,6 +43,7 @@
* 04/09/2013 Massimiliano Pinto Added dcb->session and dcb->session->client checks for NULL
* 12/09/2013 Massimiliano Pinto Added checks in gw_read_backend_event() for gw_read_backend_handshake
* 27/09/2013 Massimiliano Pinto Changed in gw_read_backend_event the check for dcb_read(), now is if rc < 0
* 24/10/2014 Massimiliano Pinto Added Mysql user@host @db authentication support
*
*/
#include <modinfo.h>
@ -66,7 +69,8 @@ static int backend_write_delayqueue(DCB *dcb);
static void backend_set_delayqueue(DCB *dcb, GWBUF *queue);
static int gw_change_user(DCB *backend_dcb, SERVER *server, SESSION *in_session, GWBUF *queue);
static GWBUF* process_response_data (DCB* dcb, GWBUF* readbuf, int nbytes_to_process);
extern char* create_auth_failed_msg( GWBUF* readbuf, char* hostaddr, uint8_t* sha1);
extern char* create_auth_fail_str(char *username, char *hostaddr, char *sha1, char *db);
#if defined(NOT_USED)
@ -1171,9 +1175,16 @@ static int backend_write_delayqueue(DCB *dcb)
return rc;
}
/**
* This routine handles the COM_CHANGE_USER command
*
* @param dcb The current backend DCB
* @param server The backend server pointer
* @param in_session The current session data (MYSQL_session)
* @param queue The GWBUF containing the COM_CHANGE_USER receveid
* @return 0 on success and 1 on failure
*/
static int gw_change_user(
DCB *backend,
SERVER *server,
@ -1185,6 +1196,7 @@ static int gw_change_user(
MySQLProtocol *client_protocol = NULL;
char username[MYSQL_USER_MAXLEN+1]="";
char database[MYSQL_DATABASE_MAXLEN+1]="";
char current_database[MYSQL_DATABASE_MAXLEN+1]="";
uint8_t client_sha1[MYSQL_SCRAMBLE_LEN]="";
uint8_t *client_auth_packet = GWBUF_DATA(queue);
unsigned int auth_token_len = 0;
@ -1196,18 +1208,18 @@ static int gw_change_user(
backend_protocol = backend->protocol;
client_protocol = in_session->client->protocol;
// now get the user, after 4 bytes header and 1 byte command
/* now get the user, after 4 bytes header and 1 byte command */
client_auth_packet += 5;
strcpy(username, (char *)client_auth_packet);
client_auth_packet += strlen(username) + 1;
// get the auth token len
/* get the auth token len */
memcpy(&auth_token_len, client_auth_packet, 1);
ss_dassert(auth_token_len >= 0);
client_auth_packet++;
// allocate memory for token only if auth_token_len > 0
/* allocate memory for token only if auth_token_len > 0 */
if (auth_token_len > 0) {
auth_token = (uint8_t *)malloc(auth_token_len);
ss_dassert(auth_token != NULL);
@ -1217,8 +1229,23 @@ static int gw_change_user(
memcpy(auth_token, client_auth_packet, auth_token_len);
client_auth_packet += auth_token_len;
}
// decode the token and check the password
// Note: if auth_token_len == 0 && auth_token == NULL, user is without password
/* get new database name */
strcpy(database, (char *)client_auth_packet);
/* save current_database name */
strcpy(current_database, current_session->db);
/*
* Now clear database name in dcb as we don't do local authentication on db name for change user.
* Local authentication only for user@host and if successful the database name change is sent to backend.
*/
strcpy(current_session->db, "");
/*
* decode the token and check the password.
* Note: if auth_token_len == 0 && auth_token == NULL, user is without password
*/
auth_ret = gw_check_mysql_scramble_data(backend->session->client, auth_token, auth_token_len, client_protocol->scramble, sizeof(client_protocol->scramble), username, client_sha1);
if (auth_ret != 0) {
@ -1229,24 +1256,37 @@ static int gw_change_user(
}
}
// let's free the auth_token now
/* copy back current datbase to client session */
strcpy(current_session->db, current_database);
/* let's free the auth_token now */
if (auth_token)
free(auth_token);
if (auth_ret != 0) {
/*< vraa : errorHandle */
char *password_set = NULL;
char *message = NULL;
if (auth_token_len > 0)
password_set = (char *)client_sha1;
else
password_set = "";
message=create_auth_fail_str(username,
backend->session->client->remote,
password_set,
"");
/* send the error packet */
modutil_send_mysql_err_packet(backend->session->client, 1, 0, 1045, "28000", message);
free(message);
// send the error packet
mysql_send_auth_error(backend->session->client, 1, 0, "Authorization failed on change_user");
rv = 1;
} else {
// get db name
strcpy(database, (char *)client_auth_packet);
rv = gw_send_change_user_to_backend(database, username, client_sha1, backend_protocol);
/*<
/*
* Now copy new data into user session
*/
strcpy(current_session->user, username);
@ -1254,6 +1294,7 @@ static int gw_change_user(
memcpy(current_session->client_sha1, client_sha1, sizeof(current_session->client_sha1));
}
gwbuf_free(queue);
return rv;
}

View File

@ -35,6 +35,7 @@
* 11/03/2014 Massimiliano Pinto Added: Unix socket support
* 07/05/2014 Massimiliano Pinto Added: specific version string in server handshake
* 09/09/2014 Massimiliano Pinto Added: 777 permission for socket path
* 13/10/2014 Massimiliano Pinto Added: dbname authentication check
*
*/
#include <skygw_utils.h>
@ -43,6 +44,7 @@
#include <gw.h>
#include <modinfo.h>
#include <sys/stat.h>
#include <modutil.h>
MODULE_INFO info = {
MODULE_API_PROTOCOL,
@ -68,8 +70,9 @@ int mysql_send_ok(DCB *dcb, int packet_number, int in_affected_rows, const char*
int MySQLSendHandshake(DCB* dcb);
static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue);
static int route_by_statement(SESSION *, GWBUF **);
static char* create_auth_fail_str(GWBUF* readbuf, char* hostaddr, char* sha1);
static char* get_username_from_auth(char* ptr, uint8_t* data);
extern char* get_username_from_auth(char* ptr, uint8_t* data);
extern int check_db_name_after_auth(DCB *, char *, int);
extern char* create_auth_fail_str(char *username, char *hostaddr, char *sha1, char *db);
/*
* The "module object" for the mysqld client protocol module.
@ -446,6 +449,9 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
client_auth_packet + 4 + 4 + 4 + 1 + 23 + strlen(username) + 1,
1);
/*
* Note: some clients may pass empty database, connect_with_db !=0 but database =""
*/
if (connect_with_db) {
database = client_data->db;
strncpy(database,
@ -461,7 +467,8 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
auth_token_len);
}
/* decode the token and check the password
/*
* Decode the token and check the password
* Note: if auth_token_len == 0 && auth_token == NULL, user is without password
*/
@ -472,6 +479,9 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
username,
stage1_hash);
/* check for database name match in resource hashtable */
auth_ret = check_db_name_after_auth(dcb, database, auth_ret);
/* On failed auth try to load users' table from backend database */
if (auth_ret != 0) {
if (!service_refresh_users(dcb->service)) {
@ -481,89 +491,22 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
}
}
/* let's free the auth_token now */
if (auth_token)
free(auth_token);
/* Do again the database check */
auth_ret = check_db_name_after_auth(dcb, database, auth_ret);
if (auth_ret == 0)
{
/* on succesful auth set user into dcb field */
if (auth_ret == 0) {
dcb->user = strdup(client_data->user);
}
/* let's free the auth_token now */
if (auth_token) {
free(auth_token);
}
return auth_ret;
}
/**
* Read username from MySQL authentication packet.
*
* @param ptr address where to write the result or NULL if memory
* is allocated here.
* @param data Address of MySQL packet.
*
* @return Pointer to a copy of the username. NULL if memory allocation
* failed or if username was empty.
*/
static char* get_username_from_auth(
char* ptr,
uint8_t* data)
{
char* first_letter;
char* rval;
first_letter = (char *)(data + 4 + 4 + 4 + 1 + 23);
if (first_letter == '\0')
{
rval = NULL;
goto retblock;
}
if (ptr == NULL)
{
if ((rval = (char *)malloc(MYSQL_USER_MAXLEN+1)) == NULL)
{
goto retblock;
}
}
else
{
rval = ptr;
}
snprintf(rval, MYSQL_USER_MAXLEN+1, "%s", first_letter);
retblock:
return rval;
}
static char* create_auth_fail_str(
GWBUF* readbuf,
char* hostaddr,
char* sha1)
{
char* errstr;
char* uname;
const char* ferrstr = "Access denied for user '%s'@'%s' (using password: %s)";
if ( (uname = get_username_from_auth(NULL, (uint8_t *)GWBUF_DATA(readbuf))) == NULL)
{
errstr = NULL;
goto retblock;
}
/** -4 comes from 2X'%s' minus terminating char */
errstr = (char *)malloc(strlen(uname)+strlen(ferrstr)+strlen(hostaddr)+strlen("YES")-6+1);
if (errstr != NULL)
{
sprintf(errstr, ferrstr, uname, hostaddr, (*sha1 == '\0' ? "NO" : "YES"));
}
free(uname);
retblock:
return errstr;
}
/**
* Write function for client DCB: writes data from MaxScale to Client
*
@ -715,19 +658,28 @@ int gw_read_client_event(
}
else
{
char* fail_str;
char* fail_str = NULL;
protocol->protocol_auth_state = MYSQL_AUTH_FAILED;
fail_str = create_auth_fail_str(read_buffer,
if (auth_val == 2) {
/** Send error 1049 to client */
int message_len = 25 + MYSQL_DATABASE_MAXLEN;
fail_str = calloc(1, message_len+1);
snprintf(fail_str, message_len, "Unknown database '%s'", (char*)((MYSQL_session *)dcb->data)->db);
modutil_send_mysql_err_packet(dcb, 2, 0, 1049, "42000", fail_str);
} else {
/** Send error 1045 to client */
fail_str = create_auth_fail_str((char *)((MYSQL_session *)dcb->data)->user,
dcb->remote,
(char*)((MYSQL_session *)dcb->data)->client_sha1);
/** Send error 1045 to client */
mysql_send_auth_error(
dcb,
2,
0,
fail_str);
(char*)((MYSQL_session *)dcb->data)->client_sha1,
(char*)((MYSQL_session *)dcb->data)->db);
modutil_send_mysql_err_packet(dcb, 2, 0, 1045, "28000", fail_str);
}
if (fail_str)
free(fail_str);
LOGIF(LD, (skygw_log_write(
LOGFILE_DEBUG,
@ -736,7 +688,7 @@ int gw_read_client_event(
"state = MYSQL_AUTH_FAILED.",
protocol->owner_dcb->fd,
pthread_self())));
free(fail_str);
dcb_close(dcb);
}
read_buffer = gwbuf_consume(read_buffer, nbytes_read);
@ -748,7 +700,7 @@ int gw_read_client_event(
uint8_t cap = 0;
uint8_t* payload = NULL;
bool stmt_input; /*< router input type */
ss_dassert(nbytes_read >= 5);
session = dcb->session;
@ -1617,4 +1569,3 @@ return_str:
}
#endif

View File

@ -32,8 +32,9 @@
* Setting to 1 allow localhost (127.0.0.1 or socket) to match the any host grant via
* user@%
* 29/09/2014 Massimiliano Pinto Added Mysql user@host authentication with wildcard in IPv4 hosts:
* x.y.z.%, x.y.%.%, x.%.%.%
* x.y.z.%, x.y.%.%, x.%.%.%
* 03/10/2014 Massimiliano Pinto Added netmask for wildcard in IPv4 hosts.
* 24/10/2014 Massimiliano Pinto Added Mysql user@host @db authentication support
*
*/
@ -49,6 +50,7 @@ extern int gw_read_backend_event(DCB* dcb);
extern int gw_write_backend_event(DCB *dcb);
extern int gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue);
extern int gw_error_backend_event(DCB *dcb);
char* get_username_from_auth(char* ptr, uint8_t* data);
static server_command_t* server_command_init(server_command_t* srvcmd,
mysql_server_cmd_t cmd);
@ -1002,7 +1004,7 @@ GWBUF* mysql_create_custom_error(
* @param packet_number
* @param in_affected_rows
* @param mysql_message
* @return packet length
* @return 1 Non-zero if data was sent
*
*/
int mysql_send_custom_error (
@ -1015,9 +1017,7 @@ int mysql_send_custom_error (
buf = mysql_create_custom_error(packet_number, in_affected_rows, mysql_message);
dcb->func.write(dcb, buf);
return GWBUF_LENGTH(buf);
return dcb->func.write(dcb, buf);
}
/**
@ -1137,6 +1137,11 @@ int gw_send_change_user_to_backend(
// allocating the GWBUF
buffer = gwbuf_alloc(bytes);
/**
* Set correct type to GWBUF so that it will be handled like session
* commands should
*/
buffer->gwbuf_type = GWBUF_TYPE_MYSQL|GWBUF_TYPE_SINGLE_STMT|GWBUF_TYPE_SESCMD;
payload = GWBUF_DATA(buffer);
// clearing data
@ -1177,7 +1182,10 @@ int gw_send_change_user_to_backend(
memcpy(payload, curr_db, strlen(curr_db));
payload += strlen(curr_db);
payload++;
}
} else {
// skip the NULL
payload++;
}
// set the charset, 2 bytes!!!!
*payload = '\x08';
@ -1236,6 +1244,12 @@ int gw_check_mysql_scramble_data(DCB *dcb, uint8_t *token, unsigned int token_le
ret_val = gw_find_mysql_user_password_sha1(username, password, dcb);
if (ret_val) {
/* if password was sent, fill stage1_hash with at least 1 byte in order
* to create rigth error message: (using password: YES|NO)
*/
if (token_len)
memcpy(stage1_hash, (char *)"_", 1);
return 1;
}
@ -1313,8 +1327,9 @@ int gw_check_mysql_scramble_data(DCB *dcb, uint8_t *token, unsigned int token_le
/**
* gw_find_mysql_user_password_sha1
*
* The routine fetches look for an user int the MaxScale users' table
* The routine fetches an user from the MaxScale users' table
* The users' table is dcb->service->users or a different one specified with void *repository
* The user lookup uses username,host and db name (if passed in connection or change user)
*
* If found the HEX password, representing sha1(sha1(password)), is converted in binary data and
* copied into gateway_password
@ -1331,13 +1346,16 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
struct sockaddr_in *client;
char *user_password = NULL;
MYSQL_USER_HOST key;
MYSQL_session *client_data = NULL;
client_data = (MYSQL_session *) dcb->data;
service = (SERVICE *) dcb->service;
client = (struct sockaddr_in *) &dcb->ipv4;
key.user = username;
memcpy(&key.ipv4, client, sizeof(struct sockaddr_in));
key.netmask = 32;
key.resource = client_data->db;
LOGIF(LD,
(skygw_log_write_flush(
@ -1382,7 +1400,7 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
key.netmask -= 8;
user_password = mysql_users_fetch(service->users, &key);
if (user_password) {
break;
}
@ -1396,7 +1414,7 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
if (user_password) {
break;
}
/* Class A check */
key.ipv4.sin_addr.s_addr &= 0x000000FF;
key.netmask -= 8;
@ -1426,7 +1444,7 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
if (!user_password) {
/*
* the user@% has not been found.
* user@% not found.
*/
LOGIF(LD,
@ -1969,3 +1987,138 @@ void protocol_set_response_status (
spinlock_release(&p->protocol_lock);
}
char* create_auth_failed_msg(
GWBUF* readbuf,
char* hostaddr,
uint8_t* sha1)
{
char* errstr;
char* uname=(char *)GWBUF_DATA(readbuf) + 5;
const char* ferrstr = "Access denied for user '%s'@'%s' (using password: %s)";
/** -4 comes from 2X'%s' minus terminating char */
errstr = (char *)malloc(strlen(uname)+strlen(ferrstr)+strlen(hostaddr)+strlen("YES")-6 + 1);
if (errstr != NULL)
{
sprintf(errstr, ferrstr, uname, hostaddr, (*sha1 == '\0' ? "NO" : "YES"));
}
return errstr;
}
/**
* Read username from MySQL authentication packet.
*
* Only for client to server packet, COM_CHANGE_USER packet has different format.
*
* @param ptr address where to write the result or NULL if memory
* is allocated here.
* @param data Address of MySQL packet.
*
* @return Pointer to a copy of the username. NULL if memory allocation
* failed or if username was empty.
*/
char* get_username_from_auth(
char* ptr,
uint8_t* data)
{
char* first_letter;
char* rval;
first_letter = (char *)(data + 4 + 4 + 4 + 1 + 23);
if (first_letter == '\0')
{
rval = NULL;
goto retblock;
}
if (ptr == NULL)
{
if ((rval = (char *)malloc(MYSQL_USER_MAXLEN+1)) == NULL)
{
goto retblock;
}
}
else
{
rval = ptr;
}
snprintf(rval, MYSQL_USER_MAXLEN+1, "%s", first_letter);
retblock:
return rval;
}
int check_db_name_after_auth(DCB *dcb, char *database, int auth_ret) {
int db_exists = -1;
/* check for dabase name and possible match in resource hashtable */
if (database && strlen(database)) {
/* if database names are loaded we can check if db name exists */
if (dcb->service->resources != NULL) {
if (hashtable_fetch(dcb->service->resources, database)) {
db_exists = 1;
} else {
db_exists = 0;
}
} else {
/* if database names are not loaded we don't allow connection with db name*/
db_exists = -1;
}
if (db_exists == 0 && auth_ret == 0) {
auth_ret = 2;
}
if (db_exists < 0 && auth_ret == 0) {
auth_ret = 1;
}
}
return auth_ret;
}
/**
* Create a message error string to send via MySQL ERR packet.
*
* @param username the MySQL user
* @param hostaddr the client IP
* @param sha1 authentication scramble data
* @param db the MySQL db to connect to
*
* @return Pointer to the allocated string or NULL on failure
*/
char *create_auth_fail_str(
char *username,
char *hostaddr,
char *sha1,
char *db)
{
char* errstr;
const char* ferrstr;
int db_len;
if (db != NULL)
db_len = strlen(db);
else
db_len = 0;
if (db_len>0)
ferrstr = "Access denied for user '%s'@'%s' (using password: %s) to database '%s'";
else
ferrstr = "Access denied for user '%s'@'%s' (using password: %s)";
errstr = (char *)malloc(strlen(username)+strlen(ferrstr)+strlen(hostaddr)+strlen("YES")-6 + db_len + ((db_len > 0) ? (strlen(" to database ") +2) : 0) + 1);
if (errstr != NULL) {
if (db_len>0)
sprintf(errstr, ferrstr, username, hostaddr, (*sha1 == '\0' ? "NO" : "YES"), db);
else
sprintf(errstr, ferrstr, username, hostaddr, (*sha1 == '\0' ? "NO" : "YES"));
}
return errstr;
}

View File

@ -29,7 +29,7 @@ UTILSPATH := $(ROOT_PATH)/utils
CC=cc
CFLAGS=-c -fPIC -I/usr/include -I../include -I../../include -I$(LOGPATH) \
-I$(UTILSPATH) -Wall -g
-I$(UTILSPATH) -I$(MYSQL_HEADERS) -Wall -g
include ../../../makefile.inc

View File

@ -1155,15 +1155,13 @@ static bool get_dcb(
rses->router->available_slaves = false;
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Warning : No slaves available "
"for the service %s.",
rses->router->service->name)));
"Warning : No slaves available "
"for the service %s.",
rses->router->service->name)));
}
btype = BE_MASTER;
if (BREF_IS_IN_USE(master_bref))
{
*p_dcb = master_bref->bref_dcb;
@ -1199,7 +1197,7 @@ static bool get_dcb(
LOGFILE_ERROR,
"At least one slave has become available for "
"the service %s.",
rses->router->service->name)));
rses->router->service->name)));
}
ss_dassert(succp);
}
@ -1920,8 +1918,8 @@ static int routeQuery(
}
else if (hint->type == HINT_PARAMETER &&
(strncasecmp((char *)hint->data,
"max_slave_replication_lag",
strlen("max_slave_replication_lag")) == 0))
"max_slave_replication_lag",
strlen("max_slave_replication_lag")) == 0))
{
int val = (int) strtol((char *)hint->value,
(char **)NULL, 10);
@ -2047,8 +2045,7 @@ static int routeQuery(
}
succp = false;
ret = 0;
}
}
}
if (succp) /*< Have DCB of the target backend */
@ -2340,21 +2337,28 @@ static void clientReply (
{
uint8_t* buf =
(uint8_t *)GWBUF_DATA((scur->scmd_cur_cmd->my_sescmd_buf));
size_t len = MYSQL_GET_PACKET_LEN(buf);
char* cmdstr = (char *)malloc(len+1);
/** data+termination character == len */
snprintf(cmdstr, len, "%s", &buf[5]);
uint8_t* replybuf = (uint8_t *)GWBUF_DATA(writebuf);
size_t len = MYSQL_GET_PACKET_LEN(buf);
size_t replylen = MYSQL_GET_PACKET_LEN(replybuf);
char* cmdstr = strndup(&((char *)buf)[5], len-4);
char* err = strndup(&((char *)replybuf)[8], 5);
char* replystr = strndup(&((char *)replybuf)[13],
replylen-4-5);
ss_dassert(len+4 == GWBUF_LENGTH(scur->scmd_cur_cmd->my_sescmd_buf));
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Failed to execute %s in %s:%d.",
"Error : Failed to execute %s in %s:%d. %s %s",
cmdstr,
bref->bref_backend->backend_server->name,
bref->bref_backend->backend_server->port)));
bref->bref_backend->backend_server->port,
err,
replystr)));
free(cmdstr);
free(err);
free(replystr);
}
if (GWBUF_IS_TYPE_SESCMD_RESPONSE(writebuf))
@ -3518,7 +3522,9 @@ static bool execute_sescmd_in_backend(
#endif /*< SS_DEBUG */
switch (scur->scmd_cur_cmd->my_sescmd_packet_type) {
case MYSQL_COM_CHANGE_USER:
rc = dcb->func.auth(
/** This makes it possible to handle replies correctly */
gwbuf_set_type(scur->scmd_cur_cmd->my_sescmd_buf, GWBUF_TYPE_SESCMD);
rc = dcb->func.auth(
dcb,
NULL,
dcb->session,