Fixed problem when connecting to user without a password.
Fixed problem with LIKE and BINARY BitKeeper/etc/ignore: added scripts/fill_help_tables client/mysqltest.c: Better error messages libmysql/libmysql.c: Simple code cleanup Simplified connect() and change_user() by using sub function libmysqld/lib_sql.cc: Ensure that new fields in MYSQL_FIELD structure is used mysql-test/r/rpl_user_variables.result: Cleaned up test mysql-test/r/type_blob.result: New test mysql-test/t/rpl_user_variables.test: Cleaned up test mysql-test/t/type_blob.test: New test sql/item.cc: Fixed that Item_ref returns the right character set sql/item_cmpfunc.cc: Fixed problem with LIKE and BINARY sql/item_func.cc: Don't store end ASCII(0) for string user variables (Made some other code easier) sql/log_event.cc: Don't store end ASCII(0) for string user variables. Fixed comment style Some optimizations sql/log_event.h: Optimized type sql/mini_client.cc: Indentation changes sql/mysql_priv.h: Made is_update_query extern sql/protocol.cc: Simple code cleanup sql/sql_acl.cc: Code cleanup Fixed problem when connecting to user without a password. sql/sql_lex.h: Fixed problem with uninitialized memory sql/sql_parse.cc: Fixed problem with user without passwords Fixed some connect problems. sql/time.cc: removed reference to uninitialized memory
This commit is contained in:
parent
86ec3c8f08
commit
5a12dff30b
@ -597,3 +597,4 @@ vio/test-sslclient
|
|||||||
vio/test-sslserver
|
vio/test-sslserver
|
||||||
vio/viotest-ssl
|
vio/viotest-ssl
|
||||||
scripts/fill_help_tables.sql
|
scripts/fill_help_tables.sql
|
||||||
|
scripts/fill_help_tables
|
||||||
|
@ -991,7 +991,8 @@ int do_sync_with_master2(const char* p)
|
|||||||
mysql_errno(mysql), mysql_error(mysql));
|
mysql_errno(mysql), mysql_error(mysql));
|
||||||
|
|
||||||
if (!(last_result = res = mysql_store_result(mysql)))
|
if (!(last_result = res = mysql_store_result(mysql)))
|
||||||
die("line %u: mysql_store_result() returned NULL", start_lineno);
|
die("line %u: mysql_store_result() returned NULL for '%s'", start_lineno,
|
||||||
|
query_buf);
|
||||||
if (!(row = mysql_fetch_row(res)))
|
if (!(row = mysql_fetch_row(res)))
|
||||||
die("line %u: empty result in %s", start_lineno, query_buf);
|
die("line %u: empty result in %s", start_lineno, query_buf);
|
||||||
if (!row[0])
|
if (!row[0])
|
||||||
@ -1021,17 +1022,19 @@ int do_save_master_pos()
|
|||||||
MYSQL_RES* res;
|
MYSQL_RES* res;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
MYSQL* mysql = &cur_con->mysql;
|
MYSQL* mysql = &cur_con->mysql;
|
||||||
|
const char *query;
|
||||||
int rpl_parse;
|
int rpl_parse;
|
||||||
|
|
||||||
rpl_parse = mysql_rpl_parse_enabled(mysql);
|
rpl_parse = mysql_rpl_parse_enabled(mysql);
|
||||||
mysql_disable_rpl_parse(mysql);
|
mysql_disable_rpl_parse(mysql);
|
||||||
|
|
||||||
if (mysql_query(mysql, "show master status"))
|
if (mysql_query(mysql, query= "show master status"))
|
||||||
die("At line %u: failed in show master status: %d: %s", start_lineno,
|
die("At line %u: failed in show master status: %d: %s", start_lineno,
|
||||||
mysql_errno(mysql), mysql_error(mysql));
|
mysql_errno(mysql), mysql_error(mysql));
|
||||||
|
|
||||||
if (!(last_result =res = mysql_store_result(mysql)))
|
if (!(last_result =res = mysql_store_result(mysql)))
|
||||||
die("line %u: mysql_store_result() retuned NULL", start_lineno);
|
die("line %u: mysql_store_result() retuned NULL for '%s'", start_lineno,
|
||||||
|
query);
|
||||||
if (!(row = mysql_fetch_row(res)))
|
if (!(row = mysql_fetch_row(res)))
|
||||||
die("line %u: empty result in show master status", start_lineno);
|
die("line %u: empty result in show master status", start_lineno);
|
||||||
strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1);
|
strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1);
|
||||||
|
@ -215,31 +215,32 @@ my_bool my_connect(my_socket s, const struct sockaddr *name,
|
|||||||
if (res == 0) /* Connected quickly! */
|
if (res == 0) /* Connected quickly! */
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
/* Otherwise, our connection is "in progress." We can use
|
/*
|
||||||
* the select() call to wait up to a specified period of time
|
Otherwise, our connection is "in progress." We can use
|
||||||
* for the connection to suceed. If select() returns 0
|
the select() call to wait up to a specified period of time
|
||||||
* (after waiting howevermany seconds), our socket never became
|
for the connection to succeed. If select() returns 0
|
||||||
* writable (host is probably unreachable.) Otherwise, if
|
(after waiting howevermany seconds), our socket never became
|
||||||
* select() returns 1, then one of two conditions exist:
|
writable (host is probably unreachable.) Otherwise, if
|
||||||
*
|
select() returns 1, then one of two conditions exist:
|
||||||
* 1. An error occured. We use getsockopt() to check for this.
|
|
||||||
* 2. The connection was set up sucessfully: getsockopt() will
|
1. An error occured. We use getsockopt() to check for this.
|
||||||
* return 0 as an error.
|
2. The connection was set up sucessfully: getsockopt() will
|
||||||
*
|
return 0 as an error.
|
||||||
* Thanks goes to Andrew Gierth <andrew@erlenstar.demon.co.uk>
|
|
||||||
* who posted this method of timing out a connect() in
|
Thanks goes to Andrew Gierth <andrew@erlenstar.demon.co.uk>
|
||||||
* comp.unix.programmer on August 15th, 1997.
|
who posted this method of timing out a connect() in
|
||||||
*/
|
comp.unix.programmer on August 15th, 1997.
|
||||||
|
*/
|
||||||
|
|
||||||
FD_ZERO(&sfds);
|
FD_ZERO(&sfds);
|
||||||
FD_SET(s, &sfds);
|
FD_SET(s, &sfds);
|
||||||
/*
|
/*
|
||||||
* select could be interrupted by a signal, and if it is,
|
select could be interrupted by a signal, and if it is,
|
||||||
* the timeout should be adjusted and the select restarted
|
the timeout should be adjusted and the select restarted
|
||||||
* to work around OSes that don't restart select and
|
to work around OSes that don't restart select and
|
||||||
* implementations of select that don't adjust tv upon
|
implementations of select that don't adjust tv upon
|
||||||
* failure to reflect the time remaining
|
failure to reflect the time remaining
|
||||||
*/
|
*/
|
||||||
start_time = time(NULL);
|
start_time = time(NULL);
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
@ -258,10 +259,11 @@ my_bool my_connect(my_socket s, const struct sockaddr *name,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* select() returned something more interesting than zero, let's
|
/*
|
||||||
* see if we have any errors. If the next two statements pass,
|
select() returned something more interesting than zero, let's
|
||||||
* we've got an open socket!
|
see if we have any errors. If the next two statements pass,
|
||||||
*/
|
we've got an open socket!
|
||||||
|
*/
|
||||||
|
|
||||||
s_err=0;
|
s_err=0;
|
||||||
if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
|
if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
|
||||||
@ -276,6 +278,7 @@ my_bool my_connect(my_socket s, const struct sockaddr *name,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create a named pipe connection
|
Create a named pipe connection
|
||||||
*/
|
*/
|
||||||
@ -348,15 +351,17 @@ HANDLE create_named_pipe(NET *net, uint connect_timeout, char **arg_host,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create new shared memory connection, return handler of connection
|
Create new shared memory connection, return handler of connection
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
create_shared_memory()
|
create_shared_memory()
|
||||||
mysql Pointer of mysql structure
|
mysql Pointer of mysql structure
|
||||||
net Pointer of net structure
|
net Pointer of net structure
|
||||||
connect_timeout Timeout of connection
|
connect_timeout Timeout of connection
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_SMEM
|
#ifdef HAVE_SMEM
|
||||||
HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
|
HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
|
||||||
{
|
{
|
||||||
@ -401,58 +406,60 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
|
|||||||
*/
|
*/
|
||||||
suffix_pos = strxmov(tmp,shared_memory_base_name,"_",NullS);
|
suffix_pos = strxmov(tmp,shared_memory_base_name,"_",NullS);
|
||||||
strmov(suffix_pos, "CONNECT_REQUEST");
|
strmov(suffix_pos, "CONNECT_REQUEST");
|
||||||
if ((event_connect_request = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL)
|
if (!(event_connect_request= OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)))
|
||||||
{
|
{
|
||||||
error_allow = CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR;
|
error_allow = CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
strmov(suffix_pos, "CONNECT_ANSWER");
|
strmov(suffix_pos, "CONNECT_ANSWER");
|
||||||
if ((event_connect_answer = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL)
|
if (!(event_connect_answer= OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)))
|
||||||
{
|
{
|
||||||
error_allow = CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR;
|
error_allow = CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
strmov(suffix_pos, "CONNECT_DATA");
|
strmov(suffix_pos, "CONNECT_DATA");
|
||||||
if ((handle_connect_file_map = OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)) == NULL)
|
if (!(handle_connect_file_map= OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)))
|
||||||
{
|
{
|
||||||
error_allow = CR_SHARED_MEMORY_CONNECT_FILE_MAP_ERROR;
|
error_allow = CR_SHARED_MEMORY_CONNECT_FILE_MAP_ERROR;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if ((handle_connect_map = MapViewOfFile(handle_connect_file_map,FILE_MAP_WRITE,0,0,sizeof(DWORD))) == NULL)
|
if (!(handle_connect_map= MapViewOfFile(handle_connect_file_map,
|
||||||
|
FILE_MAP_WRITE,0,0,sizeof(DWORD))))
|
||||||
{
|
{
|
||||||
error_allow = CR_SHARED_MEMORY_CONNECT_MAP_ERROR;
|
error_allow = CR_SHARED_MEMORY_CONNECT_MAP_ERROR;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Send to server request of connection
|
Send to server request of connection
|
||||||
*/
|
*/
|
||||||
if (!SetEvent(event_connect_request))
|
if (!SetEvent(event_connect_request))
|
||||||
{
|
{
|
||||||
error_allow = CR_SHARED_MEMORY_CONNECT_SET_ERROR;
|
error_allow = CR_SHARED_MEMORY_CONNECT_SET_ERROR;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Wait of answer from server
|
Wait of answer from server
|
||||||
*/
|
*/
|
||||||
if (WaitForSingleObject(event_connect_answer,connect_timeout*1000) != WAIT_OBJECT_0)
|
if (WaitForSingleObject(event_connect_answer,connect_timeout*1000) !=
|
||||||
|
WAIT_OBJECT_0)
|
||||||
{
|
{
|
||||||
error_allow = CR_SHARED_MEMORY_CONNECT_ABANDODED_ERROR;
|
error_allow = CR_SHARED_MEMORY_CONNECT_ABANDODED_ERROR;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Get number of connection
|
Get number of connection
|
||||||
*/
|
*/
|
||||||
connect_number = uint4korr(handle_connect_map);/*WAX2*/
|
connect_number = uint4korr(handle_connect_map);/*WAX2*/
|
||||||
p = int2str(connect_number, connect_number_char, 10);
|
p= int2str(connect_number, connect_number_char, 10);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The name of event and file-mapping events create agree next rule:
|
The name of event and file-mapping events create agree next rule:
|
||||||
shared_memory_base_name+unique_part+number_of_connection
|
shared_memory_base_name+unique_part+number_of_connection
|
||||||
Where:
|
Where:
|
||||||
shared_memory_base_name is uniquel value for each server
|
shared_memory_base_name is uniquel value for each server
|
||||||
unique_part is uniquel value for each object (events and file-mapping)
|
unique_part is uniquel value for each object (events and file-mapping)
|
||||||
number_of_connection is number of connection between server and client
|
number_of_connection is number of connection between server and client
|
||||||
*/
|
*/
|
||||||
suffix_pos = strxmov(tmp,shared_memory_base_name,"_",connect_number_char,
|
suffix_pos = strxmov(tmp,shared_memory_base_name,"_",connect_number_char,
|
||||||
"_",NullS);
|
"_",NullS);
|
||||||
strmov(suffix_pos, "DATA");
|
strmov(suffix_pos, "DATA");
|
||||||
@ -495,33 +502,46 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
|
|||||||
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
|
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
|
||||||
goto err2;
|
goto err2;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Set event that server should send data
|
Set event that server should send data
|
||||||
*/
|
*/
|
||||||
SetEvent(event_server_read);
|
SetEvent(event_server_read);
|
||||||
|
|
||||||
err2:
|
err2:
|
||||||
if (error_allow == 0)
|
if (error_allow == 0)
|
||||||
{
|
{
|
||||||
net->vio = vio_new_win32shared_memory(net,handle_file_map,handle_map,event_server_wrote,
|
net->vio= vio_new_win32shared_memory(net,handle_file_map,handle_map,
|
||||||
event_server_read,event_client_wrote,event_client_read);
|
event_server_wrote,
|
||||||
|
event_server_read,event_client_wrote,
|
||||||
|
event_client_read);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error_code = GetLastError();
|
error_code = GetLastError();
|
||||||
if (event_server_read) CloseHandle(event_server_read);
|
if (event_server_read)
|
||||||
if (event_server_wrote) CloseHandle(event_server_wrote);
|
CloseHandle(event_server_read);
|
||||||
if (event_client_read) CloseHandle(event_client_read);
|
if (event_server_wrote)
|
||||||
if (event_client_wrote) CloseHandle(event_client_wrote);
|
CloseHandle(event_server_wrote);
|
||||||
if (handle_map) UnmapViewOfFile(handle_map);
|
if (event_client_read)
|
||||||
if (handle_file_map) CloseHandle(handle_file_map);
|
CloseHandle(event_client_read);
|
||||||
|
if (event_client_wrote)
|
||||||
|
CloseHandle(event_client_wrote);
|
||||||
|
if (handle_map)
|
||||||
|
UnmapViewOfFile(handle_map);
|
||||||
|
if (handle_file_map)
|
||||||
|
CloseHandle(handle_file_map);
|
||||||
}
|
}
|
||||||
err:
|
err:
|
||||||
if (error_allow) error_code = GetLastError();
|
if (error_allow)
|
||||||
if (event_connect_request) CloseHandle(event_connect_request);
|
error_code = GetLastError();
|
||||||
if (event_connect_answer) CloseHandle(event_connect_answer);
|
if (event_connect_request)
|
||||||
if (handle_connect_map) UnmapViewOfFile(handle_connect_map);
|
CloseHandle(event_connect_request);
|
||||||
if (handle_connect_file_map) CloseHandle(handle_connect_file_map);
|
if (event_connect_answer)
|
||||||
|
CloseHandle(event_connect_answer);
|
||||||
|
if (handle_connect_map)
|
||||||
|
UnmapViewOfFile(handle_connect_map);
|
||||||
|
if (handle_connect_file_map)
|
||||||
|
CloseHandle(handle_connect_file_map);
|
||||||
if (error_allow)
|
if (error_allow)
|
||||||
{
|
{
|
||||||
net->last_errno=error_allow;
|
net->last_errno=error_allow;
|
||||||
@ -532,11 +552,12 @@ err:
|
|||||||
return(INVALID_HANDLE_VALUE);
|
return(INVALID_HANDLE_VALUE);
|
||||||
}
|
}
|
||||||
return(handle_map);
|
return(handle_map);
|
||||||
};
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
read a packet from server. Give error message if socket was down
|
Read a packet from server. Give error message if socket was down
|
||||||
or packet is an error message
|
or packet is an error message
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
@ -1796,10 +1817,11 @@ void STDCALL mysql_once_init(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
|
/*
|
||||||
Fill in SSL part of MYSQL structure and set 'use_ssl' flag.
|
Fill in SSL part of MYSQL structure and set 'use_ssl' flag.
|
||||||
NB! Errors are not reported until you do mysql_real_connect.
|
NB! Errors are not reported until you do mysql_real_connect.
|
||||||
**************************************************************************/
|
*/
|
||||||
|
|
||||||
#define strdup_if_not_null(A) (A) == 0 ? 0 : my_strdup((A),MYF(MY_WME))
|
#define strdup_if_not_null(A) (A) == 0 ? 0 : my_strdup((A),MYF(MY_WME))
|
||||||
|
|
||||||
@ -1822,10 +1844,10 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/*
|
||||||
Free strings in the SSL structure and clear 'use_ssl' flag.
|
Free strings in the SSL structure and clear 'use_ssl' flag.
|
||||||
NB! Errors are not reported until you do mysql_real_connect.
|
NB! Errors are not reported until you do mysql_real_connect.
|
||||||
**************************************************************************/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
static void
|
static void
|
||||||
@ -1847,6 +1869,75 @@ mysql_ssl_free(MYSQL *mysql __attribute__((unused)))
|
|||||||
}
|
}
|
||||||
#endif /* HAVE_OPENSSL */
|
#endif /* HAVE_OPENSSL */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Handle password authentication
|
||||||
|
*/
|
||||||
|
|
||||||
|
static my_bool mysql_autenticate(MYSQL *mysql, const char *passwd)
|
||||||
|
{
|
||||||
|
ulong pkt_length;
|
||||||
|
NET *net= &mysql->net;
|
||||||
|
char buff[SCRAMBLE41_LENGTH];
|
||||||
|
char password_hash[SCRAMBLE41_LENGTH]; /* Used for storage of stage1 hash */
|
||||||
|
|
||||||
|
/* We shall only query server if it expect us to do so */
|
||||||
|
if ((pkt_length=net_safe_read(mysql)) == packet_error)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
This should always happen with new server unless empty password
|
||||||
|
OK/Error packets have zero as the first char
|
||||||
|
*/
|
||||||
|
if (pkt_length == 24 && net->read_pos[0])
|
||||||
|
{
|
||||||
|
/* Old passwords will have '*' at the first byte of hash */
|
||||||
|
if (net->read_pos[0] != '*')
|
||||||
|
{
|
||||||
|
/* Build full password hash as it is required to decode scramble */
|
||||||
|
password_hash_stage1(buff, passwd);
|
||||||
|
/* Store copy as we'll need it later */
|
||||||
|
memcpy(password_hash,buff,SCRAMBLE41_LENGTH);
|
||||||
|
/* Finally hash complete password using hash we got from server */
|
||||||
|
password_hash_stage2(password_hash,(const char*) net->read_pos);
|
||||||
|
/* Decypt and store scramble 4 = hash for stage2 */
|
||||||
|
password_crypt((const char*) net->read_pos+4,mysql->scramble_buff,
|
||||||
|
password_hash, SCRAMBLE41_LENGTH);
|
||||||
|
mysql->scramble_buff[SCRAMBLE41_LENGTH]=0;
|
||||||
|
/* Encode scramble with password. Recycle buffer */
|
||||||
|
password_crypt(mysql->scramble_buff,buff,buff,SCRAMBLE41_LENGTH);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Create password to decode scramble */
|
||||||
|
create_key_from_old_password(passwd,password_hash);
|
||||||
|
/* Decypt and store scramble 4 = hash for stage2 */
|
||||||
|
password_crypt((const char*) net->read_pos+4,mysql->scramble_buff,
|
||||||
|
password_hash, SCRAMBLE41_LENGTH);
|
||||||
|
mysql->scramble_buff[SCRAMBLE41_LENGTH]=0;
|
||||||
|
/* Finally scramble decoded scramble with password */
|
||||||
|
scramble(buff, mysql->scramble_buff, passwd,0);
|
||||||
|
}
|
||||||
|
/* Write second package of authentication */
|
||||||
|
if (my_net_write(net,buff,SCRAMBLE41_LENGTH) || net_flush(net))
|
||||||
|
{
|
||||||
|
net->last_errno= CR_SERVER_LOST;
|
||||||
|
strmov(net->last_error,ER(net->last_errno));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
/* Read what server thinks about out new auth message report */
|
||||||
|
if (net_safe_read(mysql) == packet_error)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
Connect to sql server
|
Connect to sql server
|
||||||
If host == 0 then use localhost
|
If host == 0 then use localhost
|
||||||
@ -1884,7 +1975,6 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
|||||||
{
|
{
|
||||||
char buff[NAME_LEN+USERNAME_LENGTH+100],charset_name_buff[16];
|
char buff[NAME_LEN+USERNAME_LENGTH+100],charset_name_buff[16];
|
||||||
char *end,*host_info,*charset_name;
|
char *end,*host_info,*charset_name;
|
||||||
char password_hash[SCRAMBLE41_LENGTH]; /* tmp storage stage1 hash */
|
|
||||||
my_socket sock;
|
my_socket sock;
|
||||||
uint32 ip_addr;
|
uint32 ip_addr;
|
||||||
struct sockaddr_in sock_addr;
|
struct sockaddr_in sock_addr;
|
||||||
@ -1930,7 +2020,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
|||||||
passwd=mysql->options.password;
|
passwd=mysql->options.password;
|
||||||
#ifndef DONT_USE_MYSQL_PWD
|
#ifndef DONT_USE_MYSQL_PWD
|
||||||
if (!passwd)
|
if (!passwd)
|
||||||
passwd=getenv("MYSQL_PWD"); /* get it from environment (haneke) */
|
passwd=getenv("MYSQL_PWD"); /* get it from environment */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (!db || !db[0])
|
if (!db || !db[0])
|
||||||
@ -1940,30 +2030,29 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
|||||||
if (!unix_socket)
|
if (!unix_socket)
|
||||||
unix_socket=mysql->options.unix_socket;
|
unix_socket=mysql->options.unix_socket;
|
||||||
|
|
||||||
mysql->reconnect=1; /* Reconnect as default */
|
mysql->reconnect=1; /* Reconnect as default */
|
||||||
mysql->server_status=SERVER_STATUS_AUTOCOMMIT;
|
mysql->server_status=SERVER_STATUS_AUTOCOMMIT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Grab a socket and connect it to the server
|
Grab a socket and connect it to the server
|
||||||
*/
|
*/
|
||||||
#if defined(HAVE_SMEM)
|
#if defined(HAVE_SMEM)
|
||||||
if ((!mysql->options.protocol || mysql->options.protocol == MYSQL_PROTOCOL_MEMORY)&&
|
if ((!mysql->options.protocol ||
|
||||||
|
mysql->options.protocol == MYSQL_PROTOCOL_MEMORY) &&
|
||||||
(!host || !strcmp(host,LOCAL_HOST)))
|
(!host || !strcmp(host,LOCAL_HOST)))
|
||||||
{
|
{
|
||||||
if ((create_shared_memory(mysql,net, mysql->options.connect_timeout)) ==
|
if ((create_shared_memory(mysql,net, mysql->options.connect_timeout)) ==
|
||||||
INVALID_HANDLE_VALUE)
|
INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("error",
|
DBUG_PRINT("error",
|
||||||
("host: '%s' socket: '%s' shared memory: %s have_tcpip: %d",
|
("host: '%s' socket: '%s' shared memory: %s have_tcpip: %d",
|
||||||
host ? host : "<null>",
|
host ? host : "<null>",
|
||||||
unix_socket ? unix_socket : "<null>",
|
unix_socket ? unix_socket : "<null>",
|
||||||
(int) mysql->options.shared_memory_base_name,
|
(int) mysql->options.shared_memory_base_name,
|
||||||
(int) have_tcpip));
|
(int) have_tcpip));
|
||||||
if (mysql->options.protocol == MYSQL_PROTOCOL_MEMORY)
|
if (mysql->options.protocol == MYSQL_PROTOCOL_MEMORY)
|
||||||
goto error;
|
goto error;
|
||||||
/*
|
/* Try also with PIPE or TCP/IP */
|
||||||
Try also with PIPE or TCP/IP
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1974,70 +2063,76 @@ Try also with PIPE or TCP/IP
|
|||||||
host_info=(char*) ER(CR_SHARED_MEMORY_CONNECTION);
|
host_info=(char*) ER(CR_SHARED_MEMORY_CONNECTION);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
#endif //HAVE_SMEM
|
#endif /* HAVE_SMEM */
|
||||||
#if defined(HAVE_SYS_UN_H)
|
#if defined(HAVE_SYS_UN_H)
|
||||||
if ((!mysql->options.protocol || mysql->options.protocol == MYSQL_PROTOCOL_SOCKET)&&
|
if ((!mysql->options.protocol ||
|
||||||
(!host || !strcmp(host,LOCAL_HOST)) && (unix_socket || mysql_unix_port))
|
mysql->options.protocol == MYSQL_PROTOCOL_SOCKET)&&
|
||||||
{
|
(!host || !strcmp(host,LOCAL_HOST)) &&
|
||||||
host=LOCAL_HOST;
|
(unix_socket || mysql_unix_port))
|
||||||
if (!unix_socket)
|
|
||||||
unix_socket=mysql_unix_port;
|
|
||||||
host_info=(char*) ER(CR_LOCALHOST_CONNECTION);
|
|
||||||
DBUG_PRINT("info",("Using UNIX sock '%s'",unix_socket));
|
|
||||||
if ((sock = socket(AF_UNIX,SOCK_STREAM,0)) == SOCKET_ERROR)
|
|
||||||
{
|
{
|
||||||
net->last_errno=CR_SOCKET_CREATE_ERROR;
|
host=LOCAL_HOST;
|
||||||
sprintf(net->last_error,ER(net->last_errno),socket_errno);
|
if (!unix_socket)
|
||||||
goto error;
|
unix_socket=mysql_unix_port;
|
||||||
}
|
host_info=(char*) ER(CR_LOCALHOST_CONNECTION);
|
||||||
net->vio = vio_new(sock, VIO_TYPE_SOCKET, TRUE);
|
DBUG_PRINT("info",("Using UNIX sock '%s'",unix_socket));
|
||||||
bzero((char*) &UNIXaddr,sizeof(UNIXaddr));
|
if ((sock = socket(AF_UNIX,SOCK_STREAM,0)) == SOCKET_ERROR)
|
||||||
UNIXaddr.sun_family = AF_UNIX;
|
{
|
||||||
strmov(UNIXaddr.sun_path, unix_socket);
|
net->last_errno=CR_SOCKET_CREATE_ERROR;
|
||||||
if (my_connect(sock,(struct sockaddr *) &UNIXaddr, sizeof(UNIXaddr),
|
sprintf(net->last_error,ER(net->last_errno),socket_errno);
|
||||||
mysql->options.connect_timeout))
|
goto error;
|
||||||
{
|
}
|
||||||
DBUG_PRINT("error",("Got error %d on connect to local server",socket_errno));
|
net->vio = vio_new(sock, VIO_TYPE_SOCKET, TRUE);
|
||||||
net->last_errno=CR_CONNECTION_ERROR;
|
bzero((char*) &UNIXaddr,sizeof(UNIXaddr));
|
||||||
sprintf(net->last_error,ER(net->last_errno),unix_socket,socket_errno);
|
UNIXaddr.sun_family = AF_UNIX;
|
||||||
goto error;
|
strmov(UNIXaddr.sun_path, unix_socket);
|
||||||
|
if (my_connect(sock,(struct sockaddr *) &UNIXaddr, sizeof(UNIXaddr),
|
||||||
|
mysql->options.connect_timeout))
|
||||||
|
{
|
||||||
|
DBUG_PRINT("error",("Got error %d on connect to local server",
|
||||||
|
socket_errno));
|
||||||
|
net->last_errno=CR_CONNECTION_ERROR;
|
||||||
|
sprintf(net->last_error,ER(net->last_errno),unix_socket,socket_errno);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mysql->options.protocol=MYSQL_PROTOCOL_SOCKET;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mysql->options.protocol=MYSQL_PROTOCOL_SOCKET;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#elif defined(__WIN__)
|
#elif defined(__WIN__)
|
||||||
if ((!mysql->options.protocol || mysql->options.protocol == MYSQL_PROTOCOL_PIPE)&&
|
|
||||||
((unix_socket || !host && is_NT() ||
|
|
||||||
host && !strcmp(host,LOCAL_HOST_NAMEDPIPE) ||!have_tcpip))&&(!net->vio))
|
|
||||||
{
|
|
||||||
sock=0;
|
|
||||||
if ((hPipe=create_named_pipe(net, mysql->options.connect_timeout,
|
|
||||||
(char**) &host, (char**) &unix_socket)) ==
|
|
||||||
INVALID_HANDLE_VALUE)
|
|
||||||
{
|
{
|
||||||
DBUG_PRINT("error",
|
if ((!mysql->options.protocol ||
|
||||||
("host: '%s' socket: '%s' have_tcpip: %d",
|
mysql->options.protocol == MYSQL_PROTOCOL_PIPE)&&
|
||||||
host ? host : "<null>",
|
((unix_socket || !host && is_NT() ||
|
||||||
unix_socket ? unix_socket : "<null>",
|
host && !strcmp(host,LOCAL_HOST_NAMEDPIPE) ||! have_tcpip))&&
|
||||||
(int) have_tcpip));
|
(!net->vio))
|
||||||
if (mysql->options.protocol == MYSQL_PROTOCOL_PIPE ||
|
{
|
||||||
(host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
|
sock=0;
|
||||||
(unix_socket && !strcmp(unix_socket,MYSQL_NAMEDPIPE)))
|
if ((hPipe=create_named_pipe(net, mysql->options.connect_timeout,
|
||||||
goto error;
|
(char**) &host, (char**) &unix_socket)) ==
|
||||||
/*
|
INVALID_HANDLE_VALUE)
|
||||||
Try also with TCP/IP
|
{
|
||||||
*/
|
DBUG_PRINT("error",
|
||||||
|
("host: '%s' socket: '%s' have_tcpip: %d",
|
||||||
|
host ? host : "<null>",
|
||||||
|
unix_socket ? unix_socket : "<null>",
|
||||||
|
(int) have_tcpip));
|
||||||
|
if (mysql->options.protocol == MYSQL_PROTOCOL_PIPE ||
|
||||||
|
(host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
|
||||||
|
(unix_socket && !strcmp(unix_socket,MYSQL_NAMEDPIPE)))
|
||||||
|
goto error;
|
||||||
|
/* Try also with TCP/IP */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
net->vio=vio_new_win32pipe(hPipe);
|
||||||
|
sprintf(host_info=buff, ER(CR_NAMEDPIPE_CONNECTION), host,
|
||||||
|
unix_socket);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
net->vio=vio_new_win32pipe(hPipe);
|
|
||||||
sprintf(host_info=buff, ER(CR_NAMEDPIPE_CONNECTION), host,
|
|
||||||
unix_socket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
if ((!mysql->options.protocol || mysql->options.protocol == MYSQL_PROTOCOL_TCP)&&(!net->vio))
|
if ((!mysql->options.protocol ||
|
||||||
|
mysql->options.protocol == MYSQL_PROTOCOL_TCP)&&(!net->vio))
|
||||||
{
|
{
|
||||||
unix_socket=0; /* This is not used */
|
unix_socket=0; /* This is not used */
|
||||||
if (!port)
|
if (!port)
|
||||||
@ -2058,7 +2153,7 @@ Try also with PIPE or TCP/IP
|
|||||||
sock_addr.sin_family = AF_INET;
|
sock_addr.sin_family = AF_INET;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The server name may be a host name or IP address
|
The server name may be a host name or IP address
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((int) (ip_addr = inet_addr(host)) != (int) INADDR_NONE)
|
if ((int) (ip_addr = inet_addr(host)) != (int) INADDR_NONE)
|
||||||
@ -2084,22 +2179,22 @@ Try also with PIPE or TCP/IP
|
|||||||
}
|
}
|
||||||
sock_addr.sin_port = (ushort) htons((ushort) port);
|
sock_addr.sin_port = (ushort) htons((ushort) port);
|
||||||
if (my_connect(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr),
|
if (my_connect(sock,(struct sockaddr *) &sock_addr, sizeof(sock_addr),
|
||||||
mysql->options.connect_timeout))
|
mysql->options.connect_timeout))
|
||||||
{
|
{
|
||||||
DBUG_PRINT("error",("Got error %d on connect to '%s'",socket_errno,host));
|
DBUG_PRINT("error",("Got error %d on connect to '%s'",socket_errno,
|
||||||
|
host));
|
||||||
net->last_errno= CR_CONN_HOST_ERROR;
|
net->last_errno= CR_CONN_HOST_ERROR;
|
||||||
sprintf(net->last_error ,ER(CR_CONN_HOST_ERROR), host, socket_errno);
|
sprintf(net->last_error ,ER(CR_CONN_HOST_ERROR), host, socket_errno);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (!net->vio)
|
||||||
if (!net->vio)
|
{
|
||||||
{
|
DBUG_PRINT("error",("Unknow protocol %d ",mysql->options.protocol));
|
||||||
DBUG_PRINT("error",("Unknow protocol %d ",mysql->options.protocol));
|
net->last_errno= CR_CONN_UNKNOW_PROTOCOL;
|
||||||
net->last_errno= CR_CONN_UNKNOW_PROTOCOL;
|
sprintf(net->last_error ,ER(CR_CONN_UNKNOW_PROTOCOL));
|
||||||
sprintf(net->last_error ,ER(CR_CONN_UNKNOW_PROTOCOL));
|
goto error;
|
||||||
goto error;
|
}
|
||||||
};
|
|
||||||
|
|
||||||
if (!net->vio || my_net_init(net, net->vio))
|
if (!net->vio || my_net_init(net, net->vio))
|
||||||
{
|
{
|
||||||
@ -2167,7 +2262,6 @@ Try also with PIPE or TCP/IP
|
|||||||
if (!(mysql->charset =
|
if (!(mysql->charset =
|
||||||
get_charset((uint8) mysql->server_language, MYF(0))))
|
get_charset((uint8) mysql->server_language, MYF(0))))
|
||||||
mysql->charset = default_charset_info; /* shouldn't be fatal */
|
mysql->charset = default_charset_info; /* shouldn't be fatal */
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mysql->charset=default_charset_info;
|
mysql->charset=default_charset_info;
|
||||||
@ -2232,7 +2326,7 @@ Try also with PIPE or TCP/IP
|
|||||||
client_flag|=CLIENT_CONNECT_WITH_DB;
|
client_flag|=CLIENT_CONNECT_WITH_DB;
|
||||||
/* Remove options that server doesn't support */
|
/* Remove options that server doesn't support */
|
||||||
client_flag= ((client_flag &
|
client_flag= ((client_flag &
|
||||||
~(CLIENT_COMPRESS | CLIENT_SSL | CLIENT_PROTOCOL_41)) |
|
~(CLIENT_COMPRESS | CLIENT_SSL | CLIENT_PROTOCOL_41)) |
|
||||||
(client_flag & mysql->server_capabilities));
|
(client_flag & mysql->server_capabilities));
|
||||||
|
|
||||||
#ifndef HAVE_COMPRESS
|
#ifndef HAVE_COMPRESS
|
||||||
@ -2308,7 +2402,7 @@ Try also with PIPE or TCP/IP
|
|||||||
/*
|
/*
|
||||||
We always start with old type handshake the only difference is message sent
|
We always start with old type handshake the only difference is message sent
|
||||||
If server handles secure connection type we'll not send the real scramble
|
If server handles secure connection type we'll not send the real scramble
|
||||||
*/
|
*/
|
||||||
if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
|
if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
|
||||||
{
|
{
|
||||||
if (passwd[0])
|
if (passwd[0])
|
||||||
@ -2319,17 +2413,17 @@ Try also with PIPE or TCP/IP
|
|||||||
end+=SCRAMBLE_LENGTH;
|
end+=SCRAMBLE_LENGTH;
|
||||||
*end=0;
|
*end=0;
|
||||||
}
|
}
|
||||||
else /* For empty password*/
|
else /* For empty password*/
|
||||||
{
|
{
|
||||||
end=strend(end)+1;
|
end=strend(end)+1;
|
||||||
*end=0; /* Store zero length scramble */
|
*end=0; /* Store zero length scramble */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Real scramble is only sent to old servers. This can be blocked
|
Real scramble is only sent to old servers. This can be blocked
|
||||||
by calling mysql_options(MYSQL *, MYSQL_SECURE_CONNECT, (char*) &1);
|
by calling mysql_options(MYSQL *, MYSQL_SECURE_CONNECT, (char*) &1);
|
||||||
*/
|
*/
|
||||||
end=scramble(strend(end)+1, mysql->scramble_buff, passwd,
|
end=scramble(strend(end)+1, mysql->scramble_buff, passwd,
|
||||||
(my_bool) (mysql->protocol_version == 9));
|
(my_bool) (mysql->protocol_version == 9));
|
||||||
@ -2349,59 +2443,9 @@ Try also with PIPE or TCP/IP
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We shall only query sever if it expect us to do so */
|
if (mysql_autenticate(mysql, passwd))
|
||||||
|
|
||||||
if ( (pkt_length=net_safe_read(mysql)) == packet_error)
|
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
|
|
||||||
{
|
|
||||||
/* This should always happen with new server unless empty password */
|
|
||||||
if (pkt_length==24 && net->read_pos[0])
|
|
||||||
/* OK/Error packets have zero as the first char */
|
|
||||||
{
|
|
||||||
/* Old passwords will have '*' at the first byte of hash */
|
|
||||||
if (net->read_pos[0] != '*')
|
|
||||||
{
|
|
||||||
/* Build full password hash as it is required to decode scramble */
|
|
||||||
password_hash_stage1(buff, passwd);
|
|
||||||
/* Store copy as we'll need it later */
|
|
||||||
memcpy(password_hash,buff,SCRAMBLE41_LENGTH);
|
|
||||||
/* Finally hash complete password using hash we got from server */
|
|
||||||
password_hash_stage2(password_hash,(const char*) net->read_pos);
|
|
||||||
/* Decypt and store scramble 4 = hash for stage2 */
|
|
||||||
password_crypt((const char*) net->read_pos+4,mysql->scramble_buff,
|
|
||||||
password_hash, SCRAMBLE41_LENGTH);
|
|
||||||
mysql->scramble_buff[SCRAMBLE41_LENGTH]=0;
|
|
||||||
/* Encode scramble with password. Recycle buffer */
|
|
||||||
password_crypt(mysql->scramble_buff,buff,buff,SCRAMBLE41_LENGTH);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Create password to decode scramble */
|
|
||||||
create_key_from_old_password(passwd,password_hash);
|
|
||||||
/* Decypt and store scramble 4 = hash for stage2 */
|
|
||||||
password_crypt((const char*) net->read_pos+4,mysql->scramble_buff,
|
|
||||||
password_hash, SCRAMBLE41_LENGTH);
|
|
||||||
mysql->scramble_buff[SCRAMBLE41_LENGTH]=0;
|
|
||||||
/* Finally scramble decoded scramble with password */
|
|
||||||
scramble(buff, mysql->scramble_buff, passwd,0);
|
|
||||||
}
|
|
||||||
/* Write second package of authentication */
|
|
||||||
if (my_net_write(net,buff,SCRAMBLE41_LENGTH) || net_flush(net))
|
|
||||||
{
|
|
||||||
net->last_errno= CR_SERVER_LOST;
|
|
||||||
strmov(net->last_error,ER(net->last_errno));
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
/* Read What server thinks about out new auth message report */
|
|
||||||
if (net_safe_read(mysql) == packet_error)
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* End of authentication part of handshake */
|
|
||||||
|
|
||||||
if (client_flag & CLIENT_COMPRESS) /* We will use compression */
|
if (client_flag & CLIENT_COMPRESS) /* We will use compression */
|
||||||
net->compress=1;
|
net->compress=1;
|
||||||
if (mysql->options.max_allowed_packet)
|
if (mysql->options.max_allowed_packet)
|
||||||
@ -2521,10 +2565,6 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
|
|||||||
const char *passwd, const char *db)
|
const char *passwd, const char *db)
|
||||||
{
|
{
|
||||||
char buff[512],*end=buff;
|
char buff[512],*end=buff;
|
||||||
ulong pkt_length;
|
|
||||||
char password_hash[SCRAMBLE41_LENGTH]; /* Used for tmp storage of stage1 hash */
|
|
||||||
NET *net= &mysql->net;
|
|
||||||
|
|
||||||
DBUG_ENTER("mysql_change_user");
|
DBUG_ENTER("mysql_change_user");
|
||||||
|
|
||||||
if (!user)
|
if (!user)
|
||||||
@ -2553,83 +2593,36 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
|
|||||||
*end=0; /* Store zero length scramble */
|
*end=0; /* Store zero length scramble */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
Real scramble is only sent to old servers. This can be blocked
|
Real scramble is only sent to old servers. This can be blocked
|
||||||
by calling mysql_options(MYSQL *, MYSQL_SECURE_CONNECT, (char*) &1);
|
by calling mysql_options(MYSQL *, MYSQL_SECURE_CONNECT, (char*) &1);
|
||||||
*/
|
*/
|
||||||
end=scramble(end, mysql->scramble_buff, passwd,
|
end=scramble(end, mysql->scramble_buff, passwd,
|
||||||
(my_bool) (mysql->protocol_version == 9));
|
(my_bool) (mysql->protocol_version == 9));
|
||||||
|
}
|
||||||
/* Add database if needed */
|
/* Add database if needed */
|
||||||
end=strmov(end+1,db ? db : "");
|
end=strmov(end+1,db ? db : "");
|
||||||
|
|
||||||
/* Write authentication package */
|
/* Write authentication package */
|
||||||
|
|
||||||
simple_command(mysql,COM_CHANGE_USER, buff,(ulong) (end-buff),1);
|
simple_command(mysql,COM_CHANGE_USER, buff,(ulong) (end-buff),1);
|
||||||
|
|
||||||
/* We shall only query sever if it expect us to do so */
|
if (mysql_autenticate(mysql, passwd))
|
||||||
if ( (pkt_length=net_safe_read(mysql)) == packet_error)
|
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
|
/* Free old connect information */
|
||||||
{
|
|
||||||
/* This should always happen with new server unless empty password */
|
|
||||||
if (pkt_length==24 && net->read_pos[0])
|
|
||||||
/* Err/OK messages has first character=0 */
|
|
||||||
{
|
|
||||||
/* Old passwords will have zero at the first byte of hash */
|
|
||||||
if (net->read_pos[0] != '*')
|
|
||||||
{
|
|
||||||
/* Build full password hash as it is required to decode scramble */
|
|
||||||
password_hash_stage1(buff, passwd);
|
|
||||||
/* Store copy as we'll need it later */
|
|
||||||
memcpy(password_hash,buff,SCRAMBLE41_LENGTH);
|
|
||||||
/* Finally hash complete password using hash we got from server */
|
|
||||||
password_hash_stage2(password_hash, (const char*) net->read_pos);
|
|
||||||
/* Decypt and store scramble 4 = hash for stage2 */
|
|
||||||
password_crypt((const char*) net->read_pos+4, mysql->scramble_buff,
|
|
||||||
password_hash, SCRAMBLE41_LENGTH);
|
|
||||||
mysql->scramble_buff[SCRAMBLE41_LENGTH]=0;
|
|
||||||
/* Encode scramble with password. Recycle buffer */
|
|
||||||
password_crypt(mysql->scramble_buff,buff,buff,SCRAMBLE41_LENGTH);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Create password to decode scramble */
|
|
||||||
create_key_from_old_password(passwd,password_hash);
|
|
||||||
/* Decypt and store scramble 4 = hash for stage2 */
|
|
||||||
password_crypt((const char*) net->read_pos+4,mysql->scramble_buff,
|
|
||||||
password_hash, SCRAMBLE41_LENGTH);
|
|
||||||
mysql->scramble_buff[SCRAMBLE41_LENGTH]=0;
|
|
||||||
/* Finally scramble decoded scramble with password */
|
|
||||||
scramble(buff, mysql->scramble_buff, passwd,
|
|
||||||
(my_bool) (mysql->protocol_version == 9));
|
|
||||||
}
|
|
||||||
/* Write second package of authentication */
|
|
||||||
if (my_net_write(net,buff,SCRAMBLE41_LENGTH) || net_flush(net))
|
|
||||||
{
|
|
||||||
net->last_errno= CR_SERVER_LOST;
|
|
||||||
strmov(net->last_error,ER(net->last_errno));
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
/* Read What server thinks about out new auth message report */
|
|
||||||
if (net_safe_read(mysql) == packet_error)
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
|
my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR));
|
my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
|
my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
|
|
||||||
|
/* alloc new connect information */
|
||||||
mysql->user= my_strdup(user,MYF(MY_WME));
|
mysql->user= my_strdup(user,MYF(MY_WME));
|
||||||
mysql->passwd=my_strdup(passwd,MYF(MY_WME));
|
mysql->passwd=my_strdup(passwd,MYF(MY_WME));
|
||||||
mysql->db= db ? my_strdup(db,MYF(MY_WME)) : 0;
|
mysql->db= db ? my_strdup(db,MYF(MY_WME)) : 0;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -5102,6 +5095,7 @@ static void fetch_result_datetime(MYSQL_BIND *param, uchar **row)
|
|||||||
*row+= read_binary_datetime(tm, row);
|
*row+= read_binary_datetime(tm, row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void fetch_result_str(MYSQL_BIND *param, uchar **row)
|
static void fetch_result_str(MYSQL_BIND *param, uchar **row)
|
||||||
{
|
{
|
||||||
ulong length= net_field_length(row);
|
ulong length= net_field_length(row);
|
||||||
@ -5110,7 +5104,7 @@ static void fetch_result_str(MYSQL_BIND *param, uchar **row)
|
|||||||
/* Add an end null if there is room in the buffer */
|
/* Add an end null if there is room in the buffer */
|
||||||
if (copy_length != param->buffer_length)
|
if (copy_length != param->buffer_length)
|
||||||
*(param->buffer+copy_length)= '\0';
|
*(param->buffer+copy_length)= '\0';
|
||||||
*param->length= length; // return total length
|
*param->length= length; /* return total length */
|
||||||
*row+= length;
|
*row+= length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,13 +373,22 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
|
|||||||
Send_field server_field;
|
Send_field server_field;
|
||||||
item->make_field(&server_field);
|
item->make_field(&server_field);
|
||||||
|
|
||||||
|
client_field->db= strdup_root(alloc, server_field.db_name);
|
||||||
client_field->table= strdup_root(alloc, server_field.table_name);
|
client_field->table= strdup_root(alloc, server_field.table_name);
|
||||||
client_field->name= strdup_root(alloc,server_field.col_name);
|
client_field->name= strdup_root(alloc, server_field.col_name);
|
||||||
|
client_field->org_table= strdup_root(alloc, server_field.org_table_name);
|
||||||
|
client_field->org_name= strdup_root(alloc, server_field.org_col_name);
|
||||||
client_field->length= server_field.length;
|
client_field->length= server_field.length;
|
||||||
client_field->type= server_field.type;
|
client_field->type= server_field.type;
|
||||||
client_field->flags= server_field.flags;
|
client_field->flags= server_field.flags;
|
||||||
client_field->decimals= server_field.decimals;
|
client_field->decimals= server_field.decimals;
|
||||||
|
client_field->db_length= strlen(client_field->db);
|
||||||
|
client_field->table_length= strlen(client_field->table);
|
||||||
|
client_field->name_length= strlen(client_field->name);
|
||||||
|
client_field->org_name_length= strlen(client_field->org_name);
|
||||||
|
client_field->org_table_length= strlen(client_field->org_table);
|
||||||
|
client_field->charsetnr= server_field.charsetnr;
|
||||||
|
|
||||||
if (INTERNAL_NUM_FIELD(client_field))
|
if (INTERNAL_NUM_FIELD(client_field))
|
||||||
client_field->flags|= NUM_FLAG;
|
client_field->flags|= NUM_FLAG;
|
||||||
|
|
||||||
|
@ -4,9 +4,6 @@ reset master;
|
|||||||
reset slave;
|
reset slave;
|
||||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
start slave;
|
start slave;
|
||||||
stop slave;
|
|
||||||
reset master;
|
|
||||||
drop table if exists t1;
|
|
||||||
create table t1(n char(30));
|
create table t1(n char(30));
|
||||||
set @i1:=12345678901234, @i2:=-12345678901234, @i3:=0, @i4:=-1;
|
set @i1:=12345678901234, @i2:=-12345678901234, @i3:=0, @i4:=-1;
|
||||||
set @s1:='This is a test', @r1:=12.5, @r2:=-12.5;
|
set @s1:='This is a test', @r1:=12.5, @r2:=-12.5;
|
||||||
@ -23,7 +20,6 @@ set @q:='abc';
|
|||||||
insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'));
|
insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'));
|
||||||
set @a:=5;
|
set @a:=5;
|
||||||
insert into t1 values (@a),(@a);
|
insert into t1 values (@a),(@a);
|
||||||
start slave;
|
|
||||||
select * from t1;
|
select * from t1;
|
||||||
n
|
n
|
||||||
12345678901234
|
12345678901234
|
||||||
@ -59,20 +55,20 @@ slave-bin.000001 396 User var 2 396 @r1=12.5
|
|||||||
slave-bin.000001 439 User var 2 439 @r2=-12.5
|
slave-bin.000001 439 User var 2 439 @r2=-12.5
|
||||||
slave-bin.000001 482 Query 1 482 use `test`; insert into t1 values (@r1), (@r2)
|
slave-bin.000001 482 Query 1 482 use `test`; insert into t1 values (@r1), (@r2)
|
||||||
slave-bin.000001 551 User var 2 551 @s1='This is a test'
|
slave-bin.000001 551 User var 2 551 @s1='This is a test'
|
||||||
slave-bin.000001 601 User var 2 601 @s2=''
|
slave-bin.000001 600 User var 2 600 @s2=''
|
||||||
slave-bin.000001 637 User var 2 637 @s3='abc'def'
|
slave-bin.000001 635 User var 2 635 @s3='abc'def'
|
||||||
slave-bin.000001 680 User var 2 680 @s4='abc\def'
|
slave-bin.000001 677 User var 2 677 @s4='abc\def'
|
||||||
slave-bin.000001 723 User var 2 723 @s5='abc'def'
|
slave-bin.000001 719 User var 2 719 @s5='abc'def'
|
||||||
slave-bin.000001 766 Query 1 766 use `test`; insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5)
|
slave-bin.000001 761 Query 1 761 use `test`; insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5)
|
||||||
slave-bin.000001 856 User var 2 856 @n1=NULL
|
slave-bin.000001 851 User var 2 851 @n1=NULL
|
||||||
slave-bin.000001 882 Query 1 882 use `test`; insert into t1 values (@n1)
|
slave-bin.000001 877 Query 1 877 use `test`; insert into t1 values (@n1)
|
||||||
slave-bin.000001 944 Query 1 944 use `test`; insert into t1 values (@n2)
|
slave-bin.000001 939 Query 1 939 use `test`; insert into t1 values (@n2)
|
||||||
slave-bin.000001 1006 Query 1 1006 use `test`; insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1)
|
slave-bin.000001 1001 Query 1 1001 use `test`; insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1)
|
||||||
slave-bin.000001 1094 User var 2 1094 @a='2'
|
slave-bin.000001 1089 User var 2 1089 @a='2'
|
||||||
slave-bin.000001 1130 Query 1 1130 use `test`; insert into t1 values (@a+(@b:=@a+1))
|
slave-bin.000001 1124 Query 1 1124 use `test`; insert into t1 values (@a+(@b:=@a+1))
|
||||||
slave-bin.000001 1202 User var 2 1202 @q='abc'
|
slave-bin.000001 1196 User var 2 1196 @q='abc'
|
||||||
slave-bin.000001 1240 Query 1 1240 use `test`; insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'))
|
slave-bin.000001 1233 Query 1 1233 use `test`; insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'))
|
||||||
slave-bin.000001 1344 User var 2 1344 @a=5
|
slave-bin.000001 1337 User var 2 1337 @a=5
|
||||||
slave-bin.000001 1386 Query 1 1386 use `test`; insert into t1 values (@a),(@a)
|
slave-bin.000001 1379 Query 1 1379 use `test`; insert into t1 values (@a),(@a)
|
||||||
drop table t1;
|
drop table t1;
|
||||||
stop slave;
|
stop slave;
|
||||||
|
@ -130,6 +130,10 @@ select d from t1 having d like "%HELLO%";
|
|||||||
d
|
d
|
||||||
HELLO
|
HELLO
|
||||||
HELLO MY
|
HELLO MY
|
||||||
|
select d from t1 having d like "%HE%LLO%";
|
||||||
|
d
|
||||||
|
HELLO
|
||||||
|
HELLO MY
|
||||||
select t from t1 order by t;
|
select t from t1 order by t;
|
||||||
t
|
t
|
||||||
NULL
|
NULL
|
||||||
|
@ -1,14 +1,8 @@
|
|||||||
|
#
|
||||||
|
# Test of replicating user variables
|
||||||
|
#
|
||||||
source include/master-slave.inc;
|
source include/master-slave.inc;
|
||||||
connection master;
|
|
||||||
save_master_pos;
|
|
||||||
connection slave;
|
|
||||||
sync_with_master;
|
|
||||||
stop slave;
|
|
||||||
reset master;
|
|
||||||
connection master;
|
|
||||||
--disable_warnings
|
|
||||||
drop table if exists t1;
|
|
||||||
--enable_warnings
|
|
||||||
create table t1(n char(30));
|
create table t1(n char(30));
|
||||||
set @i1:=12345678901234, @i2:=-12345678901234, @i3:=0, @i4:=-1;
|
set @i1:=12345678901234, @i2:=-12345678901234, @i3:=0, @i4:=-1;
|
||||||
set @s1:='This is a test', @r1:=12.5, @r2:=-12.5;
|
set @s1:='This is a test', @r1:=12.5, @r2:=-12.5;
|
||||||
@ -27,7 +21,6 @@ set @a:=5;
|
|||||||
insert into t1 values (@a),(@a);
|
insert into t1 values (@a),(@a);
|
||||||
save_master_pos;
|
save_master_pos;
|
||||||
connection slave;
|
connection slave;
|
||||||
start slave;
|
|
||||||
sync_with_master;
|
sync_with_master;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
show binlog events from 141;
|
show binlog events from 141;
|
||||||
|
@ -87,6 +87,7 @@ select b from t1 where b like "%HELLO%";
|
|||||||
select d from t1 where d like "%HELLO%";
|
select d from t1 where d like "%HELLO%";
|
||||||
select c from t1 having c like "%HELLO%";
|
select c from t1 having c like "%HELLO%";
|
||||||
select d from t1 having d like "%HELLO%";
|
select d from t1 having d like "%HELLO%";
|
||||||
|
select d from t1 having d like "%HE%LLO%";
|
||||||
select t from t1 order by t;
|
select t from t1 order by t;
|
||||||
select c from t1 order by c;
|
select c from t1 order by c;
|
||||||
select b from t1 order by b;
|
select b from t1 order by b;
|
||||||
|
@ -1203,18 +1203,22 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
|||||||
max_length= (*ref)->max_length;
|
max_length= (*ref)->max_length;
|
||||||
maybe_null= (*ref)->maybe_null;
|
maybe_null= (*ref)->maybe_null;
|
||||||
decimals= (*ref)->decimals;
|
decimals= (*ref)->decimals;
|
||||||
|
set_charset((*ref)->charset());
|
||||||
fixed= 1;
|
fixed= 1;
|
||||||
|
|
||||||
if (ref && (*ref)->check_cols(1))
|
if (ref && (*ref)->check_cols(1))
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Item_default_value::eq(const Item *item, bool binary_cmp) const
|
bool Item_default_value::eq(const Item *item, bool binary_cmp) const
|
||||||
{
|
{
|
||||||
return item->type() == DEFAULT_VALUE_ITEM &&
|
return item->type() == DEFAULT_VALUE_ITEM &&
|
||||||
((Item_default_value *)item)->arg->eq(arg, binary_cmp);
|
((Item_default_value *)item)->arg->eq(arg, binary_cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Item_default_value::fix_fields(THD *thd, struct st_table_list *table_list, Item **items)
|
bool Item_default_value::fix_fields(THD *thd, struct st_table_list *table_list, Item **items)
|
||||||
{
|
{
|
||||||
if (!arg)
|
if (!arg)
|
||||||
|
@ -1129,11 +1129,16 @@ void in_string::set(uint pos,Item *item)
|
|||||||
String *res=item->val_str(str);
|
String *res=item->val_str(str);
|
||||||
if (res && res != str)
|
if (res && res != str)
|
||||||
*str= *res;
|
*str= *res;
|
||||||
// BAR TODO: I'm not sure this is absolutely correct
|
|
||||||
if (!str->charset())
|
if (!str->charset())
|
||||||
str->set_charset(default_charset_info);
|
{
|
||||||
|
CHARSET_INFO *cs;
|
||||||
|
if (!(cs= item->charset()))
|
||||||
|
cs= default_charset_info; // Should never happen for STR items
|
||||||
|
str->set_charset(cs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
byte *in_string::get_value(Item *item)
|
byte *in_string::get_value(Item *item)
|
||||||
{
|
{
|
||||||
return (byte*) item->val_str(&tmp);
|
return (byte*) item->val_str(&tmp);
|
||||||
@ -1692,6 +1697,7 @@ longlong Item_func_isnull::val_int()
|
|||||||
return args[0]->is_null() ? 1: 0;
|
return args[0]->is_null() ? 1: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
longlong Item_func_isnotnull::val_int()
|
longlong Item_func_isnotnull::val_int()
|
||||||
{
|
{
|
||||||
return args[0]->is_null() ? 0 : 1;
|
return args[0]->is_null() ? 0 : 1;
|
||||||
@ -1713,9 +1719,6 @@ longlong Item_func_like::val_int()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
null_value=0;
|
null_value=0;
|
||||||
if ((res->charset()->state & MY_CS_BINSORT) ||
|
|
||||||
(res2->charset()->state & MY_CS_BINSORT))
|
|
||||||
set_charset(&my_charset_bin);
|
|
||||||
if (canDoTurboBM)
|
if (canDoTurboBM)
|
||||||
return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
|
return turboBM_matches(res->ptr(), res->length()) ? 1 : 0;
|
||||||
return my_wildcmp(charset(),
|
return my_wildcmp(charset(),
|
||||||
@ -1748,10 +1751,19 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref)
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO--we could do it for non-const, but we'd have to
|
Comparision is by default done according to character set of LIKE
|
||||||
recompute the tables for each row--probably not worth it.
|
|
||||||
*/
|
*/
|
||||||
if (args[1]->const_item() && !(specialflag & SPECIAL_NO_NEW_FUNC))
|
if (binary_cmp)
|
||||||
|
set_charset(&my_charset_bin);
|
||||||
|
else
|
||||||
|
set_charset(args[1]->charset());
|
||||||
|
|
||||||
|
/*
|
||||||
|
We could also do boyer-more for non-const items, but as we would have to
|
||||||
|
recompute the tables for each row it's not worth it.
|
||||||
|
*/
|
||||||
|
if (args[1]->const_item() && !use_strnxfrm(charset()) &&
|
||||||
|
!(specialflag & SPECIAL_NO_NEW_FUNC))
|
||||||
{
|
{
|
||||||
String* res2 = args[1]->val_str(&tmp_value2);
|
String* res2 = args[1]->val_str(&tmp_value2);
|
||||||
if (!res2)
|
if (!res2)
|
||||||
|
@ -2083,7 +2083,8 @@ longlong
|
|||||||
Item_func_set_user_var::val_int()
|
Item_func_set_user_var::val_int()
|
||||||
{
|
{
|
||||||
longlong value=args[0]->val_int();
|
longlong value=args[0]->val_int();
|
||||||
update_hash((void*) &value,sizeof(longlong),INT_RESULT, default_charset_info);
|
update_hash((void*) &value, sizeof(longlong), INT_RESULT,
|
||||||
|
default_charset_info);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2092,9 +2093,10 @@ Item_func_set_user_var::val_str(String *str)
|
|||||||
{
|
{
|
||||||
String *res=args[0]->val_str(str);
|
String *res=args[0]->val_str(str);
|
||||||
if (!res) // Null value
|
if (!res) // Null value
|
||||||
update_hash((void*) 0, 0, STRING_RESULT, default_charset_info);
|
update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin);
|
||||||
else
|
else
|
||||||
update_hash(res->c_ptr(),res->length()+1,STRING_RESULT,res->charset());
|
update_hash((void*) res->ptr(), res->length(), STRING_RESULT,
|
||||||
|
res->charset());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2129,13 +2131,13 @@ Item_func_get_user_var::val_str(String *str)
|
|||||||
return NULL;
|
return NULL;
|
||||||
switch (entry->type) {
|
switch (entry->type) {
|
||||||
case REAL_RESULT:
|
case REAL_RESULT:
|
||||||
str->set(*(double*) entry->value,decimals,thd_charset());
|
str->set(*(double*) entry->value,decimals, &my_charset_bin);
|
||||||
break;
|
break;
|
||||||
case INT_RESULT:
|
case INT_RESULT:
|
||||||
str->set(*(longlong*) entry->value,thd_charset());
|
str->set(*(longlong*) entry->value, &my_charset_bin);
|
||||||
break;
|
break;
|
||||||
case STRING_RESULT:
|
case STRING_RESULT:
|
||||||
if (str->copy(entry->value, entry->length-1, entry->var_charset))
|
if (str->copy(entry->value, entry->length, entry->var_charset))
|
||||||
{
|
{
|
||||||
null_value=1;
|
null_value=1;
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -2191,8 +2193,6 @@ longlong Item_func_get_user_var::val_int()
|
|||||||
return LL(0); // Impossible
|
return LL(0); // Impossible
|
||||||
}
|
}
|
||||||
|
|
||||||
/* From sql_parse.cc */
|
|
||||||
extern bool is_update_query(enum enum_sql_command command);
|
|
||||||
|
|
||||||
void Item_func_get_user_var::fix_length_and_dec()
|
void Item_func_get_user_var::fix_length_and_dec()
|
||||||
{
|
{
|
||||||
@ -2207,13 +2207,15 @@ void Item_func_get_user_var::fix_length_and_dec()
|
|||||||
if (opt_bin_log && is_update_query(thd->lex.sql_command) &&
|
if (opt_bin_log && is_update_query(thd->lex.sql_command) &&
|
||||||
var_entry->used_query_id != thd->query_id)
|
var_entry->used_query_id != thd->query_id)
|
||||||
{
|
{
|
||||||
|
uint size;
|
||||||
/*
|
/*
|
||||||
First we need to store value of var_entry, when the next situation appers:
|
First we need to store value of var_entry, when the next situation
|
||||||
|
appers:
|
||||||
> set @a:=1;
|
> set @a:=1;
|
||||||
> insert into t1 values (@a), (@a:=@a+1), (@a:=@a+1);
|
> insert into t1 values (@a), (@a:=@a+1), (@a:=@a+1);
|
||||||
We have to write to binlog value @a= 1;
|
We have to write to binlog value @a= 1;
|
||||||
*/
|
*/
|
||||||
uint size= ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)) + var_entry->length;
|
size= ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)) + var_entry->length;
|
||||||
if (!(user_var_event= (BINLOG_USER_VAR_EVENT *) thd->alloc(size)))
|
if (!(user_var_event= (BINLOG_USER_VAR_EVENT *) thd->alloc(size)))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
@ -2240,6 +2242,7 @@ void Item_func_get_user_var::fix_length_and_dec()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
thd->fatal_error();
|
thd->fatal_error();
|
||||||
return;
|
return;
|
||||||
@ -2247,7 +2250,9 @@ err:
|
|||||||
|
|
||||||
|
|
||||||
bool Item_func_get_user_var::const_item() const
|
bool Item_func_get_user_var::const_item() const
|
||||||
{ return var_entry && current_thd->query_id != var_entry->update_query_id; }
|
{
|
||||||
|
return var_entry && current_thd->query_id != var_entry->update_query_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
enum Item_result Item_func_get_user_var::result_type() const
|
enum Item_result Item_func_get_user_var::result_type() const
|
||||||
@ -2275,14 +2280,9 @@ bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const
|
|||||||
if (this == item)
|
if (this == item)
|
||||||
return 1; // Same item is same.
|
return 1; // Same item is same.
|
||||||
/* Check if other type is also a get_user_var() object */
|
/* Check if other type is also a get_user_var() object */
|
||||||
#ifdef FIX_THIS
|
|
||||||
if (item->eq == &Item_func_get_user_var::eq)
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
if (item->type() != FUNC_ITEM ||
|
if (item->type() != FUNC_ITEM ||
|
||||||
((Item_func*) item)->func_name() != func_name())
|
((Item_func*) item)->func_name() != func_name())
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
|
||||||
Item_func_get_user_var *other=(Item_func_get_user_var*) item;
|
Item_func_get_user_var *other=(Item_func_get_user_var*) item;
|
||||||
return (name.length == other->name.length &&
|
return (name.length == other->name.length &&
|
||||||
!memcmp(name.str, other->name.str, name.length));
|
!memcmp(name.str, other->name.str, name.length));
|
||||||
|
126
sql/log_event.cc
126
sql/log_event.cc
@ -1899,19 +1899,10 @@ int Intvar_log_event::exec_event(struct st_relay_log_info* rli)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/****************************************************************************
|
||||||
*****************************************************************************
|
Rand_log_event methods
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
Rand_log_event methods
|
|
||||||
|
|
||||||
*****************************************************************************
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Rand_log_event::pack_info()
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||||
void Rand_log_event::pack_info(Protocol *protocol)
|
void Rand_log_event::pack_info(Protocol *protocol)
|
||||||
{
|
{
|
||||||
@ -1924,11 +1915,7 @@ void Rand_log_event::pack_info(Protocol *protocol)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Rand_log_event::Rand_log_event()
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
Rand_log_event::Rand_log_event(const char* buf, bool old_format)
|
Rand_log_event::Rand_log_event(const char* buf, bool old_format)
|
||||||
:Log_event(buf, old_format)
|
:Log_event(buf, old_format)
|
||||||
{
|
{
|
||||||
@ -1937,11 +1924,7 @@ Rand_log_event::Rand_log_event(const char* buf, bool old_format)
|
|||||||
seed2 = uint8korr(buf+RAND_SEED2_OFFSET);
|
seed2 = uint8korr(buf+RAND_SEED2_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Rand_log_event::write_data()
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
int Rand_log_event::write_data(IO_CACHE* file)
|
int Rand_log_event::write_data(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
char buf[16];
|
char buf[16];
|
||||||
@ -1950,11 +1933,7 @@ int Rand_log_event::write_data(IO_CACHE* file)
|
|||||||
return my_b_safe_write(file, (byte*) buf, sizeof(buf));
|
return my_b_safe_write(file, (byte*) buf, sizeof(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Rand_log_event::print()
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
#ifdef MYSQL_CLIENT
|
#ifdef MYSQL_CLIENT
|
||||||
void Rand_log_event::print(FILE* file, bool short_form, char* last_db)
|
void Rand_log_event::print(FILE* file, bool short_form, char* last_db)
|
||||||
{
|
{
|
||||||
@ -1970,11 +1949,7 @@ void Rand_log_event::print(FILE* file, bool short_form, char* last_db)
|
|||||||
}
|
}
|
||||||
#endif // MYSQL_CLIENT
|
#endif // MYSQL_CLIENT
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Rand_log_event::exec_event()
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||||
int Rand_log_event::exec_event(struct st_relay_log_info* rli)
|
int Rand_log_event::exec_event(struct st_relay_log_info* rli)
|
||||||
{
|
{
|
||||||
@ -1986,19 +1961,10 @@ int Rand_log_event::exec_event(struct st_relay_log_info* rli)
|
|||||||
#endif // !MYSQL_CLIENT
|
#endif // !MYSQL_CLIENT
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/***************************************************************************
|
||||||
*****************************************************************************
|
User_var_log_event methods
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
User_var_log_event methods
|
|
||||||
|
|
||||||
*****************************************************************************
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
User_var_log_event::pack_info()
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||||
void User_var_log_event::pack_info(Protocol* protocol)
|
void User_var_log_event::pack_info(Protocol* protocol)
|
||||||
{
|
{
|
||||||
@ -2019,8 +1985,8 @@ void User_var_log_event::pack_info(Protocol* protocol)
|
|||||||
double real_val;
|
double real_val;
|
||||||
float8get(real_val, val);
|
float8get(real_val, val);
|
||||||
buf= my_malloc(val_offset + FLOATING_POINT_BUFFER, MYF(MY_WME));
|
buf= my_malloc(val_offset + FLOATING_POINT_BUFFER, MYF(MY_WME));
|
||||||
event_len += my_sprintf(buf + val_offset,
|
event_len+= my_sprintf(buf + val_offset,
|
||||||
(buf + val_offset, "%.14g", real_val));
|
(buf + val_offset, "%.14g", real_val));
|
||||||
break;
|
break;
|
||||||
case INT_RESULT:
|
case INT_RESULT:
|
||||||
buf= my_malloc(val_offset + 22, MYF(MY_WME));
|
buf= my_malloc(val_offset + 22, MYF(MY_WME));
|
||||||
@ -2032,11 +1998,11 @@ void User_var_log_event::pack_info(Protocol* protocol)
|
|||||||
only. But be carefull this is may be incorrect in other cases as
|
only. But be carefull this is may be incorrect in other cases as
|
||||||
string may contain \ and '.
|
string may contain \ and '.
|
||||||
*/
|
*/
|
||||||
buf= my_malloc(val_offset + 2 + val_len, MYF(MY_WME));
|
event_len= val_offset + 2 + val_len;
|
||||||
|
buf= my_malloc(event_len, MYF(MY_WME));
|
||||||
buf[val_offset]= '\'';
|
buf[val_offset]= '\'';
|
||||||
memcpy(buf + val_offset + 1, val, val_len);
|
memcpy(buf + val_offset + 1, val, val_len);
|
||||||
buf[val_offset + val_len]= '\'';
|
buf[val_offset + val_len + 1]= '\'';
|
||||||
event_len= val_offset + 1 + val_len;
|
|
||||||
break;
|
break;
|
||||||
case ROW_RESULT:
|
case ROW_RESULT:
|
||||||
DBUG_ASSERT(1);
|
DBUG_ASSERT(1);
|
||||||
@ -2050,18 +2016,16 @@ void User_var_log_event::pack_info(Protocol* protocol)
|
|||||||
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
|
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
|
||||||
}
|
}
|
||||||
#endif // !MYSQL_CLIENT
|
#endif // !MYSQL_CLIENT
|
||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
User_var_log_event::User_var_log_event()
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
User_var_log_event::User_var_log_event(const char* buf, bool old_format)
|
User_var_log_event::User_var_log_event(const char* buf, bool old_format)
|
||||||
:Log_event(buf, old_format)
|
:Log_event(buf, old_format)
|
||||||
{
|
{
|
||||||
buf+= (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
|
buf+= (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
|
||||||
name_len= uint4korr(buf);
|
name_len= uint4korr(buf);
|
||||||
name= (char *) buf + UV_NAME_LEN_SIZE;
|
name= (char *) buf + UV_NAME_LEN_SIZE;
|
||||||
is_null= buf[UV_NAME_LEN_SIZE + name_len];
|
buf+= UV_NAME_LEN_SIZE + name_len;
|
||||||
|
is_null= (bool) *buf;
|
||||||
if (is_null)
|
if (is_null)
|
||||||
{
|
{
|
||||||
type= STRING_RESULT;
|
type= STRING_RESULT;
|
||||||
@ -2070,22 +2034,16 @@ User_var_log_event::User_var_log_event(const char* buf, bool old_format)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
type= (Item_result) buf[UV_VAL_IS_NULL + UV_NAME_LEN_SIZE + name_len];
|
type= (Item_result) buf[UV_VAL_IS_NULL];
|
||||||
charset_number= uint4korr(buf + UV_NAME_LEN_SIZE + name_len +
|
charset_number= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE);
|
||||||
UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE);
|
val_len= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
|
||||||
val_len= uint4korr(buf + UV_NAME_LEN_SIZE + name_len +
|
|
||||||
UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
|
|
||||||
UV_CHARSET_NUMBER_SIZE);
|
UV_CHARSET_NUMBER_SIZE);
|
||||||
val= (char *) buf + UV_NAME_LEN_SIZE + name_len + UV_VAL_IS_NULL +
|
val= (char *) (buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
|
||||||
UV_VAL_TYPE_SIZE + UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE;
|
UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
User_var_log_event::write_data()
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
int User_var_log_event::write_data(IO_CACHE* file)
|
int User_var_log_event::write_data(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
char buf[UV_NAME_LEN_SIZE];
|
char buf[UV_NAME_LEN_SIZE];
|
||||||
@ -2224,19 +2182,9 @@ int User_var_log_event::exec_event(struct st_relay_log_info* rli)
|
|||||||
#endif // !MYSQL_CLIENT
|
#endif // !MYSQL_CLIENT
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/****************************************************************************
|
||||||
*****************************************************************************
|
Slave_log_event methods
|
||||||
|
****************************************************************************/
|
||||||
Slave_log_event methods
|
|
||||||
|
|
||||||
*****************************************************************************
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Slave_log_event::pack_info()
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
#ifdef HAVE_REPLICATION
|
#ifdef HAVE_REPLICATION
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
@ -2255,11 +2203,7 @@ void Slave_log_event::pack_info(Protocol *protocol)
|
|||||||
}
|
}
|
||||||
#endif // !MYSQL_CLIENT
|
#endif // !MYSQL_CLIENT
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Slave_log_event::Slave_log_event()
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
Slave_log_event::Slave_log_event(THD* thd_arg,
|
Slave_log_event::Slave_log_event(THD* thd_arg,
|
||||||
struct st_relay_log_info* rli)
|
struct st_relay_log_info* rli)
|
||||||
@ -2296,21 +2240,13 @@ Slave_log_event::Slave_log_event(THD* thd_arg,
|
|||||||
}
|
}
|
||||||
#endif // !MYSQL_CLIENT
|
#endif // !MYSQL_CLIENT
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Slave_log_event dtor
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
Slave_log_event::~Slave_log_event()
|
Slave_log_event::~Slave_log_event()
|
||||||
{
|
{
|
||||||
my_free(mem_pool, MYF(MY_ALLOW_ZERO_PTR));
|
my_free(mem_pool, MYF(MY_ALLOW_ZERO_PTR));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Slave_log_event::print()
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
#ifdef MYSQL_CLIENT
|
#ifdef MYSQL_CLIENT
|
||||||
void Slave_log_event::print(FILE* file, bool short_form, char* last_db)
|
void Slave_log_event::print(FILE* file, bool short_form, char* last_db)
|
||||||
{
|
{
|
||||||
@ -2325,21 +2261,13 @@ master_log: '%s' master_pos: %s\n",
|
|||||||
}
|
}
|
||||||
#endif // MYSQL_CLIENT
|
#endif // MYSQL_CLIENT
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Slave_log_event::get_data_size()
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
int Slave_log_event::get_data_size()
|
int Slave_log_event::get_data_size()
|
||||||
{
|
{
|
||||||
return master_host_len + master_log_len + 1 + SL_MASTER_HOST_OFFSET;
|
return master_host_len + master_log_len + 1 + SL_MASTER_HOST_OFFSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Slave_log_event::write_data()
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
int Slave_log_event::write_data(IO_CACHE* file)
|
int Slave_log_event::write_data(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
int8store(mem_pool + SL_MASTER_POS_OFFSET, master_pos);
|
int8store(mem_pool + SL_MASTER_POS_OFFSET, master_pos);
|
||||||
@ -2348,11 +2276,7 @@ int Slave_log_event::write_data(IO_CACHE* file)
|
|||||||
return my_b_safe_write(file, (byte*)mem_pool, get_data_size());
|
return my_b_safe_write(file, (byte*)mem_pool, get_data_size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Slave_log_event::init_from_mem_pool()
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
void Slave_log_event::init_from_mem_pool(int data_size)
|
void Slave_log_event::init_from_mem_pool(int data_size)
|
||||||
{
|
{
|
||||||
master_pos = uint8korr(mem_pool + SL_MASTER_POS_OFFSET);
|
master_pos = uint8korr(mem_pool + SL_MASTER_POS_OFFSET);
|
||||||
@ -2369,11 +2293,7 @@ void Slave_log_event::init_from_mem_pool(int data_size)
|
|||||||
master_log_len = strlen(master_log);
|
master_log_len = strlen(master_log);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Slave_log_event::Slave_log_event()
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
Slave_log_event::Slave_log_event(const char* buf, int event_len)
|
Slave_log_event::Slave_log_event(const char* buf, int event_len)
|
||||||
:Log_event(buf,0),mem_pool(0),master_host(0)
|
:Log_event(buf,0),mem_pool(0),master_host(0)
|
||||||
{
|
{
|
||||||
@ -2387,11 +2307,7 @@ Slave_log_event::Slave_log_event(const char* buf, int event_len)
|
|||||||
init_from_mem_pool(event_len);
|
init_from_mem_pool(event_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Slave_log_event::exec_event()
|
|
||||||
|
|
||||||
****************************************************************************/
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
int Slave_log_event::exec_event(struct st_relay_log_info* rli)
|
int Slave_log_event::exec_event(struct st_relay_log_info* rli)
|
||||||
{
|
{
|
||||||
|
@ -635,7 +635,7 @@ public:
|
|||||||
ulong val_len;
|
ulong val_len;
|
||||||
Item_result type;
|
Item_result type;
|
||||||
uint charset_number;
|
uint charset_number;
|
||||||
byte is_null;
|
bool is_null;
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
User_var_log_event(THD* thd_arg, char *name_arg, uint name_len_arg,
|
User_var_log_event(THD* thd_arg, char *name_arg, uint name_len_arg,
|
||||||
char *val_arg, ulong val_len_arg, Item_result type_arg,
|
char *val_arg, ulong val_len_arg, Item_result type_arg,
|
||||||
|
@ -830,13 +830,15 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
Real scramble is only sent to old servers. This can be blocked
|
Real scramble is only sent to old servers. This can be blocked
|
||||||
by calling mysql_options(MYSQL *, MYSQL_SECURE_CONNECT, (char*) &1);
|
by calling mysql_options(MYSQL *, MYSQL_SECURE_CONNECT, (char*) &1);
|
||||||
*/
|
*/
|
||||||
end=scramble(strend(buff+5)+1, mysql->scramble_buff, passwd,
|
end=scramble(strend(buff+5)+1, mysql->scramble_buff, passwd,
|
||||||
(my_bool) (mysql->protocol_version == 9));
|
(my_bool) (mysql->protocol_version == 9));
|
||||||
|
|
||||||
|
}
|
||||||
/* Add database if needed */
|
/* Add database if needed */
|
||||||
if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
|
if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
|
||||||
{
|
{
|
||||||
|
@ -346,6 +346,7 @@ int quick_rm_table(enum db_type base,const char *db,
|
|||||||
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list);
|
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list);
|
||||||
bool mysql_change_db(THD *thd,const char *name);
|
bool mysql_change_db(THD *thd,const char *name);
|
||||||
void mysql_parse(THD *thd,char *inBuf,uint length);
|
void mysql_parse(THD *thd,char *inBuf,uint length);
|
||||||
|
bool is_update_query(enum enum_sql_command command);
|
||||||
void free_items(Item *item);
|
void free_items(Item *item);
|
||||||
bool alloc_query(THD *thd, char *packet, ulong packet_length);
|
bool alloc_query(THD *thd, char *packet, ulong packet_length);
|
||||||
void mysql_init_select(LEX *lex);
|
void mysql_init_select(LEX *lex);
|
||||||
|
@ -295,11 +295,12 @@ void
|
|||||||
send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message)
|
send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message)
|
||||||
{
|
{
|
||||||
NET *net= &thd->net;
|
NET *net= &thd->net;
|
||||||
if (net->no_send_ok || !net->vio) // hack for re-parsing queries
|
|
||||||
return;
|
|
||||||
|
|
||||||
char buff[MYSQL_ERRMSG_SIZE+10],*pos;
|
char buff[MYSQL_ERRMSG_SIZE+10],*pos;
|
||||||
DBUG_ENTER("send_ok");
|
DBUG_ENTER("send_ok");
|
||||||
|
|
||||||
|
if (net->no_send_ok || !net->vio) // hack for re-parsing queries
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
|
||||||
buff[0]=0; // No fields
|
buff[0]=0; // No fields
|
||||||
pos=net_store_length(buff+1,(ulonglong) affected_rows);
|
pos=net_store_length(buff+1,(ulonglong) affected_rows);
|
||||||
pos=net_store_length(pos, (ulonglong) id);
|
pos=net_store_length(pos, (ulonglong) id);
|
||||||
|
@ -485,7 +485,7 @@ void prepare_scramble(THD *thd, ACL_USER *acl_user,char* prepared_scramble)
|
|||||||
Get master privilges for user (priviliges for all tables).
|
Get master privilges for user (priviliges for all tables).
|
||||||
Required before connecting to MySQL
|
Required before connecting to MySQL
|
||||||
|
|
||||||
as we have 2 stage handshake now we cache user not to lookup
|
As we have 2 stage handshake now we cache user not to lookup
|
||||||
it second time. At the second stage we do not lookup user in case
|
it second time. At the second stage we do not lookup user in case
|
||||||
we already know it;
|
we already know it;
|
||||||
|
|
||||||
@ -494,14 +494,13 @@ void prepare_scramble(THD *thd, ACL_USER *acl_user,char* prepared_scramble)
|
|||||||
ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
||||||
const char *password,const char *message,char **priv_user,
|
const char *password,const char *message,char **priv_user,
|
||||||
bool old_ver, USER_RESOURCES *mqh, char *prepared_scramble,
|
bool old_ver, USER_RESOURCES *mqh, char *prepared_scramble,
|
||||||
uint *cur_priv_version,ACL_USER** hint_user)
|
uint *cur_priv_version, ACL_USER **cached_user)
|
||||||
{
|
{
|
||||||
ulong user_access=NO_ACCESS;
|
ulong user_access=NO_ACCESS;
|
||||||
*priv_user= (char*) user;
|
*priv_user= (char*) user;
|
||||||
bool password_correct= 0;
|
bool password_correct= 0;
|
||||||
int stage= (*hint_user != NULL); /* NULL passed as first stage */
|
int stage= (*cached_user != NULL); /* NULL passed as first stage */
|
||||||
ACL_USER *acl_user= NULL;
|
ACL_USER *acl_user= NULL;
|
||||||
|
|
||||||
DBUG_ENTER("acl_getroot");
|
DBUG_ENTER("acl_getroot");
|
||||||
|
|
||||||
bzero(mqh,sizeof(USER_RESOURCES));
|
bzero(mqh,sizeof(USER_RESOURCES));
|
||||||
@ -512,7 +511,6 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
|||||||
}
|
}
|
||||||
VOID(pthread_mutex_lock(&acl_cache->lock));
|
VOID(pthread_mutex_lock(&acl_cache->lock));
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get possible access from user_list. This is or'ed to others not
|
Get possible access from user_list. This is or'ed to others not
|
||||||
fully specified
|
fully specified
|
||||||
@ -520,9 +518,10 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
|||||||
If we have cached user use it, in other case look it up.
|
If we have cached user use it, in other case look it up.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (stage && (*cur_priv_version==priv_version))
|
if (stage && (*cur_priv_version == priv_version))
|
||||||
acl_user=*hint_user;
|
acl_user= *cached_user;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
for (uint i=0 ; i < acl_users.elements ; i++)
|
for (uint i=0 ; i < acl_users.elements ; i++)
|
||||||
{
|
{
|
||||||
ACL_USER *acl_user_search=dynamic_element(&acl_users,i,ACL_USER*);
|
ACL_USER *acl_user_search=dynamic_element(&acl_users,i,ACL_USER*);
|
||||||
@ -531,60 +530,59 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
|||||||
if (compare_hostname(&acl_user_search->host,host,ip))
|
if (compare_hostname(&acl_user_search->host,host,ip))
|
||||||
{
|
{
|
||||||
/* Found mathing user */
|
/* Found mathing user */
|
||||||
acl_user=acl_user_search;
|
acl_user= acl_user_search;
|
||||||
/* Store it as a cache */
|
/* Store it as a cache */
|
||||||
*hint_user=acl_user;
|
*cached_user= acl_user;
|
||||||
*cur_priv_version=priv_version;
|
*cur_priv_version= priv_version;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Now we have acl_user found and may start our checks */
|
/* Now we have acl_user found and may start our checks */
|
||||||
|
|
||||||
if (acl_user)
|
if (acl_user)
|
||||||
{
|
{
|
||||||
/* Password should present for both or absend for both */
|
/* Password should present for both or absend for both */
|
||||||
if (!acl_user->password && !*password ||
|
if (!acl_user->password && !*password)
|
||||||
(acl_user->password && *password))
|
password_correct=1;
|
||||||
|
else if (!acl_user->password || !*password)
|
||||||
{
|
{
|
||||||
/* Quick check and accept for empty passwords*/
|
*cached_user= 0; // Impossible to connect
|
||||||
if (!acl_user->password && !*password)
|
}
|
||||||
password_correct=1;
|
else
|
||||||
else /* Normal password presents */
|
{
|
||||||
|
/* New version password is checked differently */
|
||||||
|
if (acl_user->pversion)
|
||||||
{
|
{
|
||||||
/* New version password is checked differently */
|
if (stage) /* We check password only on the second stage */
|
||||||
if (acl_user->pversion)
|
{
|
||||||
{
|
if (!validate_password(password,message,acl_user->salt))
|
||||||
if (stage) /* We check password only on the second stage */
|
password_correct=1;
|
||||||
{
|
}
|
||||||
if (!validate_password(password,message,acl_user->salt))
|
else /* First stage - just prepare scramble */
|
||||||
password_correct=1;
|
prepare_scramble(thd,acl_user,prepared_scramble);
|
||||||
}
|
}
|
||||||
else /* First stage - just prepare scramble */
|
/* Old way to check password */
|
||||||
prepare_scramble(thd,acl_user,prepared_scramble);
|
else
|
||||||
}
|
{
|
||||||
/* Old way to check password */
|
/* Checking the scramble at any stage. First - old clients */
|
||||||
else
|
if (!check_scramble(password,message,acl_user->salt,
|
||||||
{
|
(my_bool) old_ver))
|
||||||
/* Checking the scramble at any stage. First - old clients */
|
password_correct=1;
|
||||||
if (!check_scramble(password,message,acl_user->salt,
|
else if (!stage) /* Here if password incorrect */
|
||||||
(my_bool) old_ver))
|
{
|
||||||
password_correct=1;
|
/* At the first stage - prepare scramble */
|
||||||
else if (!stage) /* Here if password incorrect */
|
prepare_scramble(thd,acl_user,prepared_scramble);
|
||||||
{
|
}
|
||||||
/* At the first stage - prepare scramble */
|
|
||||||
prepare_scramble(thd,acl_user,prepared_scramble);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If user not found password_correct will also be zero */
|
/* If user not found password_correct will also be zero */
|
||||||
if (!password_correct)
|
if (!password_correct)
|
||||||
goto unlock_and_exit;
|
goto unlock_and_exit;
|
||||||
|
|
||||||
/* OK. User found and password checked continue validation */
|
/* OK. User found and password checked continue validation */
|
||||||
|
|
||||||
@ -1120,7 +1118,10 @@ bool change_password(THD *thd, const char *host, const char *user,
|
|||||||
if (check_change_password(thd, host, user))
|
if (check_change_password(thd, host, user))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
/* password should always be 0,16 or 45 chars; simple hack to avoid cracking */
|
/*
|
||||||
|
password should always be 0,16 or 45 chars;
|
||||||
|
Simple hack to avoid cracking
|
||||||
|
*/
|
||||||
length=(uint) strlen(new_password);
|
length=(uint) strlen(new_password);
|
||||||
|
|
||||||
if (length!=45)
|
if (length!=45)
|
||||||
|
@ -225,7 +225,7 @@ public:
|
|||||||
return (void*) sql_calloc((uint) size);
|
return (void*) sql_calloc((uint) size);
|
||||||
}
|
}
|
||||||
static void operator delete(void *ptr,size_t size) {}
|
static void operator delete(void *ptr,size_t size) {}
|
||||||
st_select_lex_node() {}
|
st_select_lex_node(): linkage(UNSPECIFIED_TYPE) {}
|
||||||
virtual ~st_select_lex_node() {}
|
virtual ~st_select_lex_node() {}
|
||||||
inline st_select_lex_node* get_master() { return master; }
|
inline st_select_lex_node* get_master() { return master; }
|
||||||
virtual void init_query();
|
virtual void init_query();
|
||||||
|
131
sql/sql_parse.cc
131
sql/sql_parse.cc
@ -181,32 +181,57 @@ end:
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Check if user is ok
|
Check if user is ok
|
||||||
Updates:
|
|
||||||
thd->user, thd->master_access, thd->priv_user, thd->db, thd->db_access
|
SYNOPSIS
|
||||||
|
check_user()
|
||||||
|
thd Thread handle
|
||||||
|
command Command for connection (for log)
|
||||||
|
user Name of user trying to connect
|
||||||
|
passwd Scrambled password sent from client
|
||||||
|
db Database to connect to
|
||||||
|
check_count If set to 1, don't allow too many connection
|
||||||
|
simple_connect If 1 then client is of old type and we should connect
|
||||||
|
using the old method (no challange)
|
||||||
|
do_send_error Set to 1 if we should send error to user
|
||||||
|
prepared_scramble Buffer to store hash password of new connection
|
||||||
|
had_password Set to 1 if the user gave a password
|
||||||
|
cur_priv_version Check flag to know if someone flushed the privileges
|
||||||
|
since last code
|
||||||
|
hint_user Pointer used by acl_getroot() to remmeber user for
|
||||||
|
next call
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok
|
||||||
|
thd->user, thd->master_access, thd->priv_user, thd->db and
|
||||||
|
thd->db_access are updated
|
||||||
|
1 Access denied; Error sent to client
|
||||||
|
-1 If do_send_error == 1: Failed connect, error sent to client
|
||||||
|
If do_send_error == 0: Prepare for stage of connect
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int check_user(THD *thd,enum_server_command command, const char *user,
|
static int check_user(THD *thd,enum_server_command command, const char *user,
|
||||||
const char *passwd, const char *db, bool check_count,
|
const char *passwd, const char *db, bool check_count,
|
||||||
bool simple_connect, bool do_send_error,
|
bool simple_connect, bool do_send_error,
|
||||||
char *crypted_scramble, bool had_password,
|
char *prepared_scramble, bool had_password,
|
||||||
uint *cur_priv_version, ACL_USER** hint_user)
|
uint *cur_priv_version, ACL_USER** hint_user)
|
||||||
{
|
{
|
||||||
thd->db=0;
|
thd->db=0;
|
||||||
thd->db_length=0;
|
thd->db_length=0;
|
||||||
USER_RESOURCES ur;
|
USER_RESOURCES ur;
|
||||||
|
DBUG_ENTER("check_user");
|
||||||
|
|
||||||
/* We shall avoid dupplicate user allocations here */
|
/* We shall avoid dupplicate user allocations here */
|
||||||
if (!thd->user && !(thd->user = my_strdup(user, MYF(0))))
|
if (!thd->user && !(thd->user = my_strdup(user, MYF(0))))
|
||||||
{
|
{
|
||||||
send_error(thd,ER_OUT_OF_RESOURCES);
|
send_error(thd,ER_OUT_OF_RESOURCES);
|
||||||
return 1;
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
thd->master_access=acl_getroot(thd, thd->host, thd->ip, thd->user,
|
thd->master_access=acl_getroot(thd, thd->host, thd->ip, thd->user,
|
||||||
passwd, thd->scramble, &thd->priv_user,
|
passwd, thd->scramble, &thd->priv_user,
|
||||||
(protocol_version == 9 ||
|
(protocol_version == 9 ||
|
||||||
!(thd->client_capabilities &
|
!(thd->client_capabilities &
|
||||||
CLIENT_LONG_PASSWORD)),
|
CLIENT_LONG_PASSWORD)),
|
||||||
&ur,crypted_scramble,
|
&ur,prepared_scramble,
|
||||||
cur_priv_version,hint_user);
|
cur_priv_version,hint_user);
|
||||||
|
|
||||||
DBUG_PRINT("info",
|
DBUG_PRINT("info",
|
||||||
@ -222,8 +247,9 @@ static int check_user(THD *thd,enum_server_command command, const char *user,
|
|||||||
*/
|
*/
|
||||||
if (thd->master_access & NO_ACCESS)
|
if (thd->master_access & NO_ACCESS)
|
||||||
{
|
{
|
||||||
if (do_send_error)
|
if (do_send_error || !had_password || !*hint_user)
|
||||||
{
|
{
|
||||||
|
DBUG_PRINT("info",("Access denied"));
|
||||||
/*
|
/*
|
||||||
Old client should get nicer error message if password version is
|
Old client should get nicer error message if password version is
|
||||||
not supported
|
not supported
|
||||||
@ -244,10 +270,10 @@ static int check_user(THD *thd,enum_server_command command, const char *user,
|
|||||||
thd->host_or_ip,
|
thd->host_or_ip,
|
||||||
had_password ? ER(ER_YES) : ER(ER_NO));
|
had_password ? ER(ER_YES) : ER(ER_NO));
|
||||||
}
|
}
|
||||||
return(1); // Error already given
|
DBUG_RETURN(1); // Error already given
|
||||||
}
|
}
|
||||||
else
|
DBUG_PRINT("info",("Prepare for second part of handshake"));
|
||||||
return(-1); // do not report error in special handshake
|
DBUG_RETURN(-1); // no report error in special handshake
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_count)
|
if (check_count)
|
||||||
@ -259,7 +285,7 @@ static int check_user(THD *thd,enum_server_command command, const char *user,
|
|||||||
if (tmp)
|
if (tmp)
|
||||||
{ // Too many connections
|
{ // Too many connections
|
||||||
send_error(thd, ER_CON_COUNT_ERROR);
|
send_error(thd, ER_CON_COUNT_ERROR);
|
||||||
return(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mysql_log.write(thd,command,
|
mysql_log.write(thd,command,
|
||||||
@ -273,21 +299,20 @@ static int check_user(THD *thd,enum_server_command command, const char *user,
|
|||||||
/* Don't allow user to connect if he has done too many queries */
|
/* Don't allow user to connect if he has done too many queries */
|
||||||
if ((ur.questions || ur.updates || ur.connections) &&
|
if ((ur.questions || ur.updates || ur.connections) &&
|
||||||
get_or_create_user_conn(thd,user,thd->host_or_ip,&ur))
|
get_or_create_user_conn(thd,user,thd->host_or_ip,&ur))
|
||||||
return -1;
|
DBUG_RETURN(1);
|
||||||
if (thd->user_connect && thd->user_connect->user_resources.connections &&
|
if (thd->user_connect && thd->user_connect->user_resources.connections &&
|
||||||
check_for_max_user_connections(thd, thd->user_connect))
|
check_for_max_user_connections(thd, thd->user_connect))
|
||||||
return -1;
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
if (db && db[0])
|
if (db && db[0])
|
||||||
{
|
{
|
||||||
bool error=test(mysql_change_db(thd,db));
|
int error= test(mysql_change_db(thd,db));
|
||||||
if (error && thd->user_connect)
|
if (error && thd->user_connect)
|
||||||
decrease_user_connections(thd->user_connect);
|
decrease_user_connections(thd->user_connect);
|
||||||
return error;
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
else
|
send_ok(thd); // Ready to handle questions
|
||||||
send_ok(thd); // Ready to handle questions
|
DBUG_RETURN(0); // ok
|
||||||
return 0; // ok
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -492,24 +517,35 @@ static void reset_mqh(THD *thd, LEX_USER *lu, bool get_them= 0)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check connnetion and get priviliges
|
Check connnectionn and get priviliges
|
||||||
Returns 0 on ok, -1 < if error is given > 0 on error.
|
|
||||||
|
SYNOPSIS
|
||||||
|
check_connections
|
||||||
|
thd Thread handle
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok
|
||||||
|
-1 Error, which is sent to user
|
||||||
|
> 0 Error code (not sent to user)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
static int
|
static int
|
||||||
check_connections(THD *thd)
|
check_connections(THD *thd)
|
||||||
{
|
{
|
||||||
|
int res;
|
||||||
uint connect_errors=0;
|
uint connect_errors=0;
|
||||||
|
uint cur_priv_version;
|
||||||
|
bool using_password;
|
||||||
NET *net= &thd->net;
|
NET *net= &thd->net;
|
||||||
char *end, *user, *passwd, *db;
|
char *end, *user, *passwd, *db;
|
||||||
char prepared_scramble[SCRAMBLE41_LENGTH+4]; /* Buffer for scramble&hash */
|
char prepared_scramble[SCRAMBLE41_LENGTH+4]; /* Buffer for scramble&hash */
|
||||||
ACL_USER* cached_user=NULL; /* Initialise to NULL for first stage */
|
ACL_USER* cached_user=NULL; /* Initialise to NULL for first stage */
|
||||||
uint cur_priv_version;
|
|
||||||
DBUG_PRINT("info",("New connection received on %s",
|
DBUG_PRINT("info",("New connection received on %s",
|
||||||
vio_description(net->vio)));
|
vio_description(net->vio)));
|
||||||
|
|
||||||
/* Remove warning from valgrind. TODO: Fix it in password.c */
|
/* Remove warning from valgrind. TODO: Fix it in password.c */
|
||||||
bzero((char*) prepared_scramble, sizeof(prepared_scramble));
|
bzero((char*) &prepared_scramble[0], sizeof(prepared_scramble));
|
||||||
if (!thd->host) // If TCP/IP connection
|
if (!thd->host) // If TCP/IP connection
|
||||||
{
|
{
|
||||||
char ip[30];
|
char ip[30];
|
||||||
@ -648,11 +684,12 @@ check_connections(THD *thd)
|
|||||||
user= end;
|
user= end;
|
||||||
passwd= strend(user)+1;
|
passwd= strend(user)+1;
|
||||||
db=0;
|
db=0;
|
||||||
|
using_password= test(passwd[0]);
|
||||||
if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
|
if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
|
||||||
db=strend(passwd)+1;
|
db=strend(passwd)+1;
|
||||||
|
|
||||||
/* We can get only old hash at this point */
|
/* We can get only old hash at this point */
|
||||||
if (passwd[0] && strlen(passwd)!=SCRAMBLE_LENGTH)
|
if (using_password && strlen(passwd) != SCRAMBLE_LENGTH)
|
||||||
return ER_HANDSHAKE_ERROR;
|
return ER_HANDSHAKE_ERROR;
|
||||||
|
|
||||||
if (thd->client_capabilities & CLIENT_INTERACTIVE)
|
if (thd->client_capabilities & CLIENT_INTERACTIVE)
|
||||||
@ -665,24 +702,23 @@ check_connections(THD *thd)
|
|||||||
/* Simple connect only for old clients. New clients always use secure auth */
|
/* Simple connect only for old clients. New clients always use secure auth */
|
||||||
bool simple_connect=(!(thd->client_capabilities & CLIENT_SECURE_CONNECTION));
|
bool simple_connect=(!(thd->client_capabilities & CLIENT_SECURE_CONNECTION));
|
||||||
|
|
||||||
/* Store information if we used password. passwd will be dammaged */
|
|
||||||
bool using_password=test(passwd[0]);
|
|
||||||
|
|
||||||
/* Check user permissions. If password failure we'll get scramble back */
|
/* Check user permissions. If password failure we'll get scramble back */
|
||||||
if (check_user(thd, COM_CONNECT, user, passwd, db, 1, simple_connect,
|
if ((res=check_user(thd, COM_CONNECT, user, passwd, db, 1, simple_connect,
|
||||||
simple_connect, prepared_scramble, using_password,
|
simple_connect, prepared_scramble, using_password,
|
||||||
&cur_priv_version,
|
&cur_priv_version,
|
||||||
&cached_user)<0)
|
&cached_user)) < 0)
|
||||||
{
|
{
|
||||||
/* Store current used and database as they are erased with next packet */
|
/* Store current used and database as they are erased with next packet */
|
||||||
char tmp_user[USERNAME_LENGTH+1];
|
char tmp_user[USERNAME_LENGTH+1];
|
||||||
char tmp_db[NAME_LEN+1];
|
char tmp_db[NAME_LEN+1];
|
||||||
|
|
||||||
tmp_user[0]= tmp_db[0]= 0;
|
/* If the client is old we just have to return error */
|
||||||
/* If The client is old we just have to return error */
|
|
||||||
if (simple_connect)
|
if (simple_connect)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
DBUG_PRINT("info",("password challenge"));
|
||||||
|
|
||||||
|
tmp_user[0]= tmp_db[0]= 0;
|
||||||
if (user)
|
if (user)
|
||||||
strmake(tmp_user,user,USERNAME_LENGTH);
|
strmake(tmp_user,user,USERNAME_LENGTH);
|
||||||
if (db)
|
if (db)
|
||||||
@ -714,10 +750,13 @@ check_connections(THD *thd)
|
|||||||
&cached_user))
|
&cached_user))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
else if (res)
|
||||||
|
return -1; // Error sent from check_user()
|
||||||
thd->password=using_password;
|
thd->password=using_password;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pthread_handler_decl(handle_one_connection,arg)
|
pthread_handler_decl(handle_one_connection,arg)
|
||||||
{
|
{
|
||||||
THD *thd=(THD*) arg;
|
THD *thd=(THD*) arg;
|
||||||
@ -1014,14 +1053,15 @@ bool do_command(THD *thd)
|
|||||||
net->read_timeout=old_timeout; // restore it
|
net->read_timeout=old_timeout; // restore it
|
||||||
DBUG_RETURN(dispatch_command(command,thd, packet+1, (uint) packet_length));
|
DBUG_RETURN(dispatch_command(command,thd, packet+1, (uint) packet_length));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* EMBEDDED_LIBRARY */
|
#endif /* EMBEDDED_LIBRARY */
|
||||||
|
|
||||||
|
|
||||||
bool dispatch_command(enum enum_server_command command, THD *thd,
|
bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||||
char* packet, uint packet_length)
|
char* packet, uint packet_length)
|
||||||
{
|
{
|
||||||
|
int res;
|
||||||
NET *net= &thd->net;
|
NET *net= &thd->net;
|
||||||
bool error=0;
|
bool error= 0;
|
||||||
/*
|
/*
|
||||||
Commands which will always take a long time should be marked with
|
Commands which will always take a long time should be marked with
|
||||||
this so that they will not get logged to the slow query log
|
this so that they will not get logged to the slow query log
|
||||||
@ -1098,6 +1138,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
uint cur_priv_version; /* Cached grant version */
|
uint cur_priv_version; /* Cached grant version */
|
||||||
ulong pkt_len=0; /* Length of reply packet */
|
ulong pkt_len=0; /* Length of reply packet */
|
||||||
|
|
||||||
|
bzero((char*) prepared_scramble, sizeof(prepared_scramble));
|
||||||
/* Small check for incomming packet */
|
/* Small check for incomming packet */
|
||||||
|
|
||||||
if ((uint) ((uchar*) db - net->read_pos) > packet_length)
|
if ((uint) ((uchar*) db - net->read_pos) > packet_length)
|
||||||
@ -1124,13 +1165,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
Check user permissions. If password failure we'll get scramble back
|
Check user permissions. If password failure we'll get scramble back
|
||||||
Do not retry if we already have sent error (result>0)
|
Do not retry if we already have sent error (result>0)
|
||||||
*/
|
*/
|
||||||
if (check_user(thd,COM_CHANGE_USER, user, passwd, db, 0, simple_connect,
|
if ((res=check_user(thd,COM_CHANGE_USER, user, passwd, db, 0,
|
||||||
simple_connect, prepared_scramble, using_password, &cur_priv_version,
|
simple_connect, simple_connect, prepared_scramble,
|
||||||
&cached_user) < 0)
|
using_password, &cur_priv_version, &cached_user)) < 0)
|
||||||
{
|
{
|
||||||
/* If The client is old we just have to have auth failure */
|
/* If the client is old we just have to have auth failure */
|
||||||
if (simple_connect)
|
if (simple_connect)
|
||||||
goto restore_user; /* Error is already reported */
|
goto restore_user; /* Error is already reported */
|
||||||
|
|
||||||
/* Store current used and database as they are erased with next packet */
|
/* Store current used and database as they are erased with next packet */
|
||||||
tmp_user[0]= tmp_db[0]= 0;
|
tmp_user[0]= tmp_db[0]= 0;
|
||||||
@ -1149,16 +1190,18 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
goto restore_user_err;
|
goto restore_user_err;
|
||||||
|
|
||||||
/* We have to get very specific packet size */
|
/* We have to get very specific packet size */
|
||||||
if (pkt_len!=SCRAMBLE41_LENGTH)
|
if (pkt_len != SCRAMBLE41_LENGTH)
|
||||||
goto restore_user;
|
goto restore_user;
|
||||||
|
|
||||||
/* Final attempt to check the user based on reply */
|
/* Final attempt to check the user based on reply */
|
||||||
if (check_user(thd,COM_CHANGE_USER, tmp_user, (char*) net->read_pos,
|
if (check_user(thd,COM_CHANGE_USER, tmp_user, (char*) net->read_pos,
|
||||||
tmp_db, 0, 0, 1, prepared_scramble, using_password,
|
tmp_db, 0, 0, 1, prepared_scramble, using_password,
|
||||||
&cur_priv_version,
|
&cur_priv_version, &cached_user))
|
||||||
&cached_user))
|
|
||||||
goto restore_user;
|
goto restore_user;
|
||||||
}
|
}
|
||||||
|
else if (res)
|
||||||
|
goto restore_user;
|
||||||
|
|
||||||
/* Finally we've authenticated new user */
|
/* Finally we've authenticated new user */
|
||||||
if (max_connections && save_uc)
|
if (max_connections && save_uc)
|
||||||
decrease_user_connections(save_uc);
|
decrease_user_connections(save_uc);
|
||||||
@ -1168,10 +1211,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* Bad luck we shall restore old user */
|
/* Bad luck we shall restore old user */
|
||||||
restore_user_err:
|
restore_user_err:
|
||||||
send_error(thd, ER_UNKNOWN_COM_ERROR);
|
send_error(thd, ER_UNKNOWN_COM_ERROR);
|
||||||
|
|
||||||
restore_user:
|
restore_user:
|
||||||
x_free(thd->user);
|
x_free(thd->user);
|
||||||
thd->master_access=save_master_access;
|
thd->master_access=save_master_access;
|
||||||
thd->db_access=save_db_access;
|
thd->db_access=save_db_access;
|
||||||
|
@ -639,9 +639,11 @@ bool str_to_time(const char *str,uint length,TIME *l_time)
|
|||||||
for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++)
|
for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++)
|
||||||
value=value*10L + (long) (*str - '0');
|
value=value*10L + (long) (*str - '0');
|
||||||
|
|
||||||
if (*str == ' ')
|
/* Move to last space */
|
||||||
|
if (str != end && *str == ' ')
|
||||||
{
|
{
|
||||||
while (++str != end && str[0] == ' ') ;
|
while (++str != end && str[0] == ' ')
|
||||||
|
{}
|
||||||
str--;
|
str--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user