MXS-2562: Fix out-of-order error during COM_CHANGE_USER
If an error is generated while a COM_CHANGE_USER is being done, it would always use the sequence number 1. To properly handle this case and send the correct sequence number, the COM_CHANGE_USER progress needs to be tracked at the session level. The information needs to be shared between the backend and client protocols as the final OK to the COM_CHANGE_USER, with the sequence number 3, is the one that the backend server returns. Only after this response has been received and routed to the client can the COM_CHANGE_USER processing stop.
This commit is contained in:
@ -142,14 +142,15 @@ typedef enum
|
|||||||
*/
|
*/
|
||||||
typedef struct mysql_session
|
typedef struct mysql_session
|
||||||
{
|
{
|
||||||
uint8_t client_sha1[MYSQL_SCRAMBLE_LEN]; /*< SHA1(password) */
|
uint8_t client_sha1[MYSQL_SCRAMBLE_LEN]; /*< SHA1(password) */
|
||||||
char user[MYSQL_USER_MAXLEN + 1]; /*< username */
|
char user[MYSQL_USER_MAXLEN + 1]; /*< username */
|
||||||
char db[MYSQL_DATABASE_MAXLEN + 1]; /*< database */
|
char db[MYSQL_DATABASE_MAXLEN + 1]; /*< database */
|
||||||
int auth_token_len; /*< token length */
|
int auth_token_len; /*< token length */
|
||||||
uint8_t* auth_token; /*< token */
|
uint8_t* auth_token; /*< token */
|
||||||
bool correct_authenticator; /*< is session using mysql_native_password? */
|
bool correct_authenticator; /*< is session using mysql_native_password? */
|
||||||
uint8_t next_sequence; /*< Next packet sequence */
|
uint8_t next_sequence; /*< Next packet sequence */
|
||||||
bool auth_switch_sent; /*< Expecting a response to AuthSwitchRequest? */
|
bool auth_switch_sent; /*< Expecting a response to AuthSwitchRequest? */
|
||||||
|
bool changing_user; /*< True if a COM_CHANGE_USER is in progress */
|
||||||
} MYSQL_session;
|
} MYSQL_session;
|
||||||
|
|
||||||
/** Protocol packing macros. */
|
/** Protocol packing macros. */
|
||||||
|
|||||||
@ -916,6 +916,9 @@ static int gw_read_and_write(DCB* dcb)
|
|||||||
*/
|
*/
|
||||||
GWBUF_DATA(read_buffer)[3] = 0x3;
|
GWBUF_DATA(read_buffer)[3] = 0x3;
|
||||||
proto->changing_user = false;
|
proto->changing_user = false;
|
||||||
|
|
||||||
|
auto s = (MYSQL_session*)session->client_dcb->data;
|
||||||
|
s->changing_user = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1594,7 +1594,15 @@ static int gw_client_hangup_event(DCB* dcb)
|
|||||||
errmsg += ": " + extra;
|
errmsg += ": " + extra;
|
||||||
}
|
}
|
||||||
|
|
||||||
modutil_send_mysql_err_packet(dcb, 1, 0, 1927, "08S01", errmsg.c_str());
|
int seqno = 1;
|
||||||
|
|
||||||
|
if (dcb->data && ((MYSQL_session*)dcb->data)->changing_user)
|
||||||
|
{
|
||||||
|
// In case a COM_CHANGE_USER is in progress, we need to send the error with the seqno 3
|
||||||
|
seqno = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
modutil_send_mysql_err_packet(dcb, seqno, 0, 1927, "08S01", errmsg.c_str());
|
||||||
}
|
}
|
||||||
dcb_close(dcb);
|
dcb_close(dcb);
|
||||||
}
|
}
|
||||||
@ -1797,6 +1805,10 @@ static int route_by_statement(MXS_SESSION* session, uint64_t capabilities, GWBUF
|
|||||||
|
|
||||||
if (!proto->changing_user && proto->current_command == MXS_COM_CHANGE_USER)
|
if (!proto->changing_user && proto->current_command == MXS_COM_CHANGE_USER)
|
||||||
{
|
{
|
||||||
|
// Track the COM_CHANGE_USER progress at the session level
|
||||||
|
auto s = (MYSQL_session*)session->client_dcb->data;
|
||||||
|
s->changing_user = true;
|
||||||
|
|
||||||
changed_user = true;
|
changed_user = true;
|
||||||
send_auth_switch_request_packet(session->client_dcb);
|
send_auth_switch_request_packet(session->client_dcb);
|
||||||
|
|
||||||
|
|||||||
@ -38,7 +38,7 @@ uint8_t null_client_sha1[MYSQL_SCRAMBLE_LEN] = "";
|
|||||||
MYSQL_session* mysql_session_alloc()
|
MYSQL_session* mysql_session_alloc()
|
||||||
{
|
{
|
||||||
MYSQL_session* ses = (MYSQL_session*)MXS_CALLOC(1, sizeof(MYSQL_session));
|
MYSQL_session* ses = (MYSQL_session*)MXS_CALLOC(1, sizeof(MYSQL_session));
|
||||||
|
ses->changing_user = false;
|
||||||
return ses;
|
return ses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user