Added database errmsg to change_user
Added database errmsg to change_user
This commit is contained in:
@ -66,7 +66,7 @@ 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, int dbmatch);
|
||||
|
||||
|
||||
#if defined(NOT_USED)
|
||||
@ -1191,6 +1191,7 @@ static int gw_change_user(
|
||||
uint8_t *auth_token = NULL;
|
||||
int rv = -1;
|
||||
int auth_ret = 1;
|
||||
int db_exists = 0;
|
||||
|
||||
current_session = (MYSQL_session *)in_session->client->data;
|
||||
backend_protocol = backend->protocol;
|
||||
@ -1217,6 +1218,10 @@ static int gw_change_user(
|
||||
memcpy(auth_token, client_auth_packet, auth_token_len);
|
||||
client_auth_packet += auth_token_len;
|
||||
}
|
||||
|
||||
// get db name
|
||||
strcpy(database, (char *)client_auth_packet);
|
||||
|
||||
// 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);
|
||||
@ -1233,17 +1238,33 @@ static int gw_change_user(
|
||||
if (auth_token)
|
||||
free(auth_token);
|
||||
|
||||
if (auth_ret != 0) {
|
||||
/*< vraa : errorHandle */
|
||||
if (strlen(database)) {
|
||||
int i = 0;
|
||||
while(backend->session->client->service->resources[i]) {
|
||||
if (strncmp(database, backend->session->client->service->resources[i], MYSQL_DATABASE_MAXLEN) == 0) {
|
||||
db_exists = 1;
|
||||
}
|
||||
|
||||
// send the error packet
|
||||
mysql_send_auth_error(backend->session->client, 1, 0, "Authorization failed on change_user");
|
||||
i++;
|
||||
}
|
||||
|
||||
if (!db_exists && auth_ret == 0) {
|
||||
auth_ret = 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (auth_ret != 0) {
|
||||
|
||||
char *message = create_auth_failed_msg(queue, "ipaddr", client_sha1, auth_ret);
|
||||
/* send the error packet */
|
||||
mysql_send_auth_error(backend->session->client, 1, 0, message);
|
||||
fprintf(stderr, "ERROR change user for [%s] to [%s]\n", username, database);
|
||||
//mysql_send_auth_error(backend->session->client, 1, 0, "Authorization failed on change_user");
|
||||
|
||||
free(message);
|
||||
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);
|
||||
|
||||
/*<
|
||||
|
@ -70,7 +70,7 @@ 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);
|
||||
|
||||
/*
|
||||
* The "module object" for the mysqld client protocol module.
|
||||
@ -394,6 +394,7 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
|
||||
uint8_t *stage1_hash = NULL;
|
||||
int auth_ret = -1;
|
||||
MYSQL_session *client_data = NULL;
|
||||
int db_exists = 0;
|
||||
|
||||
CHK_DCB(dcb);
|
||||
|
||||
@ -447,11 +448,15 @@ 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,
|
||||
(char *)(client_auth_packet + 4 + 4 + 4 + 1 + 23 + strlen(username) +
|
||||
1 + 1 + auth_token_len), MYSQL_DATABASE_MAXLEN);
|
||||
fprintf(stderr, "---- Database name passed [%s], flag [%i]\n", database, connect_with_db);
|
||||
}
|
||||
|
||||
/* allocate memory for token only if auth_token_len > 0 */
|
||||
@ -482,13 +487,14 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "--- Authentication reply is [%i]\n", auth_ret);
|
||||
|
||||
/* let's free the auth_token now */
|
||||
if (auth_token)
|
||||
free(auth_token);
|
||||
|
||||
if (database) {
|
||||
if (database && strlen(database)) {
|
||||
int i = 0;
|
||||
int db_exists = 0;
|
||||
while(dcb->service->resources[i]) {
|
||||
if (strncmp(database, dcb->service->resources[i], MYSQL_DATABASE_MAXLEN) == 0) {
|
||||
db_exists = 1;
|
||||
@ -510,50 +516,6 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
|
||||
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,
|
||||
@ -757,6 +719,7 @@ int gw_read_client_event(
|
||||
2,
|
||||
0,
|
||||
fail_str);
|
||||
free(fail_str);
|
||||
}
|
||||
|
||||
LOGIF(LD, (skygw_log_write(
|
||||
@ -767,7 +730,6 @@ int gw_read_client_event(
|
||||
protocol->owner_dcb->fd,
|
||||
pthread_self())));
|
||||
|
||||
free(fail_str);
|
||||
dcb_close(dcb);
|
||||
}
|
||||
read_buffer = gwbuf_consume(read_buffer, nbytes_read);
|
||||
@ -780,7 +742,8 @@ int gw_read_client_event(
|
||||
uint8_t* payload = NULL;
|
||||
bool stmt_input; /*< router input type */
|
||||
|
||||
ss_dassert(nbytes_read >= 5);
|
||||
fprintf(stderr, "NBYTES %i\n", nbytes_read);
|
||||
//ss_dassert(nbytes_read >= 5);
|
||||
|
||||
session = dcb->session;
|
||||
ss_dassert( session!= NULL);
|
||||
|
@ -49,6 +49,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);
|
||||
@ -1117,15 +1118,15 @@ int gw_send_change_user_to_backend(
|
||||
|
||||
if (curr_passwd != NULL) {
|
||||
bytes += GW_MYSQL_SCRAMBLE_SIZE;
|
||||
bytes++;
|
||||
} else {
|
||||
bytes++;
|
||||
}
|
||||
// the NULL
|
||||
bytes++;
|
||||
|
||||
if (curr_db != NULL) {
|
||||
bytes += strlen(curr_db);
|
||||
bytes++;
|
||||
}
|
||||
// the NULL
|
||||
bytes++;
|
||||
|
||||
// the charset
|
||||
bytes += 2;
|
||||
@ -1177,6 +1178,9 @@ 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!!!!
|
||||
@ -1979,3 +1983,66 @@ void protocol_set_response_status (
|
||||
spinlock_release(&p->protocol_lock);
|
||||
}
|
||||
|
||||
char* create_auth_failed_msg(
|
||||
GWBUF* readbuf,
|
||||
char* hostaddr,
|
||||
uint8_t* sha1, int dbmatch)
|
||||
{
|
||||
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 + strlen(" to database ") + strlen("''") + strlen("datbase") +1);
|
||||
|
||||
if (errstr != NULL)
|
||||
{
|
||||
sprintf(errstr, ferrstr, uname, hostaddr, (*sha1 == '\0' ? "NO" : "YES"));
|
||||
strcat(errstr, " to database 'database'");
|
||||
}
|
||||
|
||||
return errstr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user