mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
SCRUM: Montymise code
fix mysql_change_user() for old clients include/mysql_com.h: Mover global defines here libmysql/libmysql.c: Remove end spaces from all lines scripts/mysql_fix_privilege_tables.sh: Move password modification to separate alter table sql/mini_client.cc: Defines, fold long lines sql/mysqld.cc: Backup old scramble for mysql_change_user to work from old clients sql/password.c: Several minor optimizations sql/sql_acl.cc: Remove ending spaces sql/sql_class.h: Add old scramble for mysql_change_user to work with old clients sql/sql_parse.cc: Remove end spaces.
This commit is contained in:
@ -29,6 +29,7 @@
|
|||||||
#define LOCAL_HOST "localhost"
|
#define LOCAL_HOST "localhost"
|
||||||
#define LOCAL_HOST_NAMEDPIPE "."
|
#define LOCAL_HOST_NAMEDPIPE "."
|
||||||
|
|
||||||
|
|
||||||
#if defined(__WIN__) && !defined( _CUSTOMCONFIG_)
|
#if defined(__WIN__) && !defined( _CUSTOMCONFIG_)
|
||||||
#define MYSQL_NAMEDPIPE "MySQL"
|
#define MYSQL_NAMEDPIPE "MySQL"
|
||||||
#define MYSQL_SERVICENAME "MySql"
|
#define MYSQL_SERVICENAME "MySql"
|
||||||
@ -44,6 +45,11 @@ enum enum_server_command
|
|||||||
COM_PREPARE, COM_EXECUTE, COM_LONG_DATA, COM_CLOSE_STMT
|
COM_PREPARE, COM_EXECUTE, COM_LONG_DATA, COM_CLOSE_STMT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define SCRAMBLE_LENGTH 8
|
||||||
|
#define SCRAMBLE41_LENGTH 20
|
||||||
|
|
||||||
|
|
||||||
#define NOT_NULL_FLAG 1 /* Field can't be NULL */
|
#define NOT_NULL_FLAG 1 /* Field can't be NULL */
|
||||||
#define PRI_KEY_FLAG 2 /* Field is part of a primary key */
|
#define PRI_KEY_FLAG 2 /* Field is part of a primary key */
|
||||||
#define UNIQUE_KEY_FLAG 4 /* Field is part of a unique key */
|
#define UNIQUE_KEY_FLAG 4 /* Field is part of a unique key */
|
||||||
|
@ -232,9 +232,9 @@ my_bool my_connect(my_socket s, const struct sockaddr *name,
|
|||||||
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
|
||||||
*/
|
*/
|
||||||
@ -346,23 +346,23 @@ 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)
|
||||||
{
|
{
|
||||||
ulong smem_buffer_length = shared_memory_buffer_length + 4;
|
ulong smem_buffer_length = shared_memory_buffer_length + 4;
|
||||||
/*
|
/*
|
||||||
event_connect_request is event object for start connection actions
|
event_connect_request is event object for start connection actions
|
||||||
event_connect_answer is event object for confirm, that server put data
|
event_connect_answer is event object for confirm, that server put data
|
||||||
handle_connect_file_map is file-mapping object, use for create shared memory
|
handle_connect_file_map is file-mapping object, use for create shared memory
|
||||||
handle_connect_map is pointer on shared memory
|
handle_connect_map is pointer on shared memory
|
||||||
handle_map is pointer on shared memory for client
|
handle_map is pointer on shared memory for client
|
||||||
event_server_wrote,
|
event_server_wrote,
|
||||||
@ -382,10 +382,10 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
|
|||||||
HANDLE event_client_wrote = NULL;
|
HANDLE event_client_wrote = NULL;
|
||||||
HANDLE event_client_read = NULL;
|
HANDLE event_client_read = NULL;
|
||||||
HANDLE handle_file_map = NULL;
|
HANDLE handle_file_map = NULL;
|
||||||
ulong connect_number;
|
ulong connect_number;
|
||||||
char connect_number_char[22], *p;
|
char connect_number_char[22], *p;
|
||||||
char tmp[64];
|
char tmp[64];
|
||||||
char *suffix_pos;
|
char *suffix_pos;
|
||||||
DWORD error_allow = 0;
|
DWORD error_allow = 0;
|
||||||
DWORD error_code = 0;
|
DWORD error_code = 0;
|
||||||
char *shared_memory_base_name = mysql->options.shared_memory_base_name;
|
char *shared_memory_base_name = mysql->options.shared_memory_base_name;
|
||||||
@ -399,24 +399,24 @@ 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)) == NULL)
|
||||||
{
|
{
|
||||||
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)) == NULL)
|
||||||
{
|
{
|
||||||
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)) == NULL)
|
||||||
{
|
{
|
||||||
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))) == NULL)
|
||||||
{
|
{
|
||||||
error_allow = CR_SHARED_MEMORY_CONNECT_MAP_ERROR;
|
error_allow = CR_SHARED_MEMORY_CONNECT_MAP_ERROR;
|
||||||
goto err;
|
goto err;
|
||||||
@ -424,7 +424,7 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
|
|||||||
/*
|
/*
|
||||||
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;
|
||||||
@ -456,7 +456,7 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
|
|||||||
if ((handle_file_map = OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)) == NULL)
|
if ((handle_file_map = OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)) == NULL)
|
||||||
{
|
{
|
||||||
error_allow = CR_SHARED_MEMORY_FILE_MAP_ERROR;
|
error_allow = CR_SHARED_MEMORY_FILE_MAP_ERROR;
|
||||||
goto err2;
|
goto err2;
|
||||||
}
|
}
|
||||||
if ((handle_map = MapViewOfFile(handle_file_map,FILE_MAP_WRITE,0,0,smem_buffer_length)) == NULL)
|
if ((handle_map = MapViewOfFile(handle_file_map,FILE_MAP_WRITE,0,0,smem_buffer_length)) == NULL)
|
||||||
{
|
{
|
||||||
@ -496,13 +496,13 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
|
|||||||
*/
|
*/
|
||||||
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_wrote,
|
||||||
event_server_read,event_client_wrote,event_client_read);
|
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) CloseHandle(event_server_read);
|
||||||
@ -518,7 +518,7 @@ err:
|
|||||||
if (event_connect_answer) CloseHandle(event_connect_answer);
|
if (event_connect_answer) CloseHandle(event_connect_answer);
|
||||||
if (handle_connect_map) UnmapViewOfFile(handle_connect_map);
|
if (handle_connect_map) UnmapViewOfFile(handle_connect_map);
|
||||||
if (handle_connect_file_map) CloseHandle(handle_connect_file_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;
|
||||||
if (error_allow == CR_SHARED_MEMORY_EVENT_ERROR)
|
if (error_allow == CR_SHARED_MEMORY_EVENT_ERROR)
|
||||||
@ -526,7 +526,7 @@ err:
|
|||||||
else
|
else
|
||||||
sprintf(net->last_error,ER(net->last_errno),error_code);
|
sprintf(net->last_error,ER(net->last_errno),error_code);
|
||||||
return(INVALID_HANDLE_VALUE);
|
return(INVALID_HANDLE_VALUE);
|
||||||
}
|
}
|
||||||
return(handle_map);
|
return(handle_map);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
@ -554,7 +554,7 @@ net_safe_read(MYSQL *mysql)
|
|||||||
DBUG_PRINT("error",("Wrong connection or packet. fd: %s len: %d",
|
DBUG_PRINT("error",("Wrong connection or packet. fd: %s len: %d",
|
||||||
vio_description(net->vio),len));
|
vio_description(net->vio),len));
|
||||||
end_server(mysql);
|
end_server(mysql);
|
||||||
net->last_errno=(net->last_errno == ER_NET_PACKET_TOO_LARGE ?
|
net->last_errno=(net->last_errno == ER_NET_PACKET_TOO_LARGE ?
|
||||||
CR_NET_PACKET_TOO_LARGE:
|
CR_NET_PACKET_TOO_LARGE:
|
||||||
CR_SERVER_LOST);
|
CR_SERVER_LOST);
|
||||||
strmov(net->last_error,ER(net->last_errno));
|
strmov(net->last_error,ER(net->last_errno));
|
||||||
@ -1095,7 +1095,7 @@ static void mysql_read_default_options(struct st_mysql_options *options,
|
|||||||
my_free(options->shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
|
my_free(options->shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
options->shared_memory_base_name=my_strdup(opt_arg,MYF(MY_WME));
|
options->shared_memory_base_name=my_strdup(opt_arg,MYF(MY_WME));
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DBUG_PRINT("warning",("unknown option: %s",option[0]));
|
DBUG_PRINT("warning",("unknown option: %s",option[0]));
|
||||||
}
|
}
|
||||||
@ -1161,7 +1161,7 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
|
|||||||
field->name= strdup_root(alloc,(char*) row->data[1]);
|
field->name= strdup_root(alloc,(char*) row->data[1]);
|
||||||
field->length= (uint) uint3korr(row->data[2]);
|
field->length= (uint) uint3korr(row->data[2]);
|
||||||
field->type= (enum enum_field_types) (uchar) row->data[3][0];
|
field->type= (enum enum_field_types) (uchar) row->data[3][0];
|
||||||
|
|
||||||
if (server_capabilities & CLIENT_LONG_FLAG)
|
if (server_capabilities & CLIENT_LONG_FLAG)
|
||||||
{
|
{
|
||||||
field->flags= uint2korr(row->data[4]);
|
field->flags= uint2korr(row->data[4]);
|
||||||
@ -1346,7 +1346,7 @@ my_bool STDCALL mysql_master_send_query(MYSQL *mysql, const char *q,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* perform query on slave */
|
/* perform query on slave */
|
||||||
my_bool STDCALL mysql_slave_query(MYSQL *mysql, const char *q,
|
my_bool STDCALL mysql_slave_query(MYSQL *mysql, const char *q,
|
||||||
unsigned long length)
|
unsigned long length)
|
||||||
{
|
{
|
||||||
@ -1391,7 +1391,7 @@ void STDCALL mysql_disable_rpl_parse(MYSQL* mysql)
|
|||||||
mysql->options.rpl_parse = 0;
|
mysql->options.rpl_parse = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the value of the parse flag */
|
/* get the value of the parse flag */
|
||||||
int STDCALL mysql_rpl_parse_enabled(MYSQL* mysql)
|
int STDCALL mysql_rpl_parse_enabled(MYSQL* mysql)
|
||||||
{
|
{
|
||||||
return mysql->options.rpl_parse;
|
return mysql->options.rpl_parse;
|
||||||
@ -1408,7 +1408,7 @@ void STDCALL mysql_disable_reads_from_master(MYSQL* mysql)
|
|||||||
mysql->options.no_master_reads = 1;
|
mysql->options.no_master_reads = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the value of the master read flag */
|
/* get the value of the master read flag */
|
||||||
my_bool STDCALL mysql_reads_from_master_enabled(MYSQL* mysql)
|
my_bool STDCALL mysql_reads_from_master_enabled(MYSQL* mysql)
|
||||||
{
|
{
|
||||||
return !(mysql->options.no_master_reads);
|
return !(mysql->options.no_master_reads);
|
||||||
@ -1537,7 +1537,7 @@ my_bool STDCALL mysql_rpl_probe(MYSQL* mysql)
|
|||||||
the most reliable way to do this is to run SHOW SLAVE STATUS and see
|
the most reliable way to do this is to run SHOW SLAVE STATUS and see
|
||||||
if we have a non-empty master host. This is still not fool-proof -
|
if we have a non-empty master host. This is still not fool-proof -
|
||||||
it is not a sin to have a master that has a dormant slave thread with
|
it is not a sin to have a master that has a dormant slave thread with
|
||||||
a non-empty master host. However, it is more reliable to check
|
a non-empty master host. However, it is more reliable to check
|
||||||
for empty master than whether the slave thread is actually running
|
for empty master than whether the slave thread is actually running
|
||||||
*/
|
*/
|
||||||
if (mysql_query(mysql, "SHOW SLAVE STATUS") ||
|
if (mysql_query(mysql, "SHOW SLAVE STATUS") ||
|
||||||
@ -1602,7 +1602,7 @@ STDCALL mysql_rpl_query_type(const char* q, int len)
|
|||||||
case 'a': /* alter */
|
case 'a': /* alter */
|
||||||
return MYSQL_RPL_MASTER;
|
return MYSQL_RPL_MASTER;
|
||||||
case 'c': /* create or check */
|
case 'c': /* create or check */
|
||||||
return my_tolower(system_charset_info,q[1]) == 'h' ? MYSQL_RPL_ADMIN :
|
return my_tolower(system_charset_info,q[1]) == 'h' ? MYSQL_RPL_ADMIN :
|
||||||
MYSQL_RPL_MASTER;
|
MYSQL_RPL_MASTER;
|
||||||
case 's': /* select or show */
|
case 's': /* select or show */
|
||||||
return my_tolower(system_charset_info,q[1]) == 'h' ? MYSQL_RPL_ADMIN :
|
return my_tolower(system_charset_info,q[1]) == 'h' ? MYSQL_RPL_ADMIN :
|
||||||
@ -1643,7 +1643,7 @@ mysql_init(MYSQL *mysql)
|
|||||||
By default, we are a replication pivot. The caller must reset it
|
By default, we are a replication pivot. The caller must reset it
|
||||||
after we return if this is not the case.
|
after we return if this is not the case.
|
||||||
*/
|
*/
|
||||||
mysql->rpl_pivot = 1;
|
mysql->rpl_pivot = 1;
|
||||||
#if defined(SIGPIPE) && defined(THREAD) && !defined(__WIN__)
|
#if defined(SIGPIPE) && defined(THREAD) && !defined(__WIN__)
|
||||||
if (!((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE))
|
if (!((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE))
|
||||||
(void) signal(SIGPIPE,pipe_sig_handler);
|
(void) signal(SIGPIPE,pipe_sig_handler);
|
||||||
@ -1658,7 +1658,7 @@ mysql_init(MYSQL *mysql)
|
|||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SMEM
|
#ifdef HAVE_SMEM
|
||||||
mysql->options.shared_memory_base_name=(char*)def_shared_memory_base_name;
|
mysql->options.shared_memory_base_name=(char*)def_shared_memory_base_name;
|
||||||
#endif
|
#endif
|
||||||
return mysql;
|
return mysql;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1716,9 +1716,9 @@ static void mysql_once_init()
|
|||||||
|
|
||||||
my_bool STDCALL
|
my_bool STDCALL
|
||||||
mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
|
mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
|
||||||
const char *key __attribute__((unused)),
|
const char *key __attribute__((unused)),
|
||||||
const char *cert __attribute__((unused)),
|
const char *cert __attribute__((unused)),
|
||||||
const char *ca __attribute__((unused)),
|
const char *ca __attribute__((unused)),
|
||||||
const char *capath __attribute__((unused)),
|
const char *capath __attribute__((unused)),
|
||||||
const char *cipher __attribute__((unused)))
|
const char *cipher __attribute__((unused)))
|
||||||
{
|
{
|
||||||
@ -1795,7 +1795,7 @@ 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[20]; /* Used for tmp storage of stage1 hash */
|
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;
|
||||||
@ -1861,7 +1861,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
|||||||
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",
|
||||||
@ -1871,11 +1871,11 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
|||||||
(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
|
||||||
{
|
{
|
||||||
mysql->options.protocol=MYSQL_PROTOCOL_MEMORY;
|
mysql->options.protocol=MYSQL_PROTOCOL_MEMORY;
|
||||||
@ -1935,9 +1935,9 @@ Try also with PIPE or TCP/IP
|
|||||||
if (mysql->options.protocol == MYSQL_PROTOCOL_PIPE ||
|
if (mysql->options.protocol == MYSQL_PROTOCOL_PIPE ||
|
||||||
(host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
|
(host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
|
||||||
(unix_socket && !strcmp(unix_socket,MYSQL_NAMEDPIPE)))
|
(unix_socket && !strcmp(unix_socket,MYSQL_NAMEDPIPE)))
|
||||||
goto error;
|
goto error;
|
||||||
/*
|
/*
|
||||||
Try also with TCP/IP
|
Try also with TCP/IP
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2028,7 +2028,7 @@ Try also with PIPE or TCP/IP
|
|||||||
vio_poll_read(net->vio, mysql->options.connect_timeout))
|
vio_poll_read(net->vio, mysql->options.connect_timeout))
|
||||||
{
|
{
|
||||||
net->last_errno= CR_SERVER_LOST;
|
net->last_errno= CR_SERVER_LOST;
|
||||||
strmov(net->last_error,ER(net->last_errno));
|
strmov(net->last_error,ER(net->last_errno));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if ((pkt_length=net_safe_read(mysql)) == packet_error)
|
if ((pkt_length=net_safe_read(mysql)) == packet_error)
|
||||||
@ -2100,7 +2100,7 @@ Try also with PIPE or TCP/IP
|
|||||||
}
|
}
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save connection information */
|
/* Save connection information */
|
||||||
if (!user) user="";
|
if (!user) user="";
|
||||||
if (!passwd) passwd="";
|
if (!passwd) passwd="";
|
||||||
@ -2180,7 +2180,7 @@ Try also with PIPE or TCP/IP
|
|||||||
if (my_net_write(net,buff,(uint) (2)) || net_flush(net))
|
if (my_net_write(net,buff,(uint) (2)) || net_flush(net))
|
||||||
{
|
{
|
||||||
net->last_errno= CR_SERVER_LOST;
|
net->last_errno= CR_SERVER_LOST;
|
||||||
strmov(net->last_error,ER(net->last_errno));
|
strmov(net->last_error,ER(net->last_errno));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
/* Do the SSL layering. */
|
/* Do the SSL layering. */
|
||||||
@ -2192,7 +2192,7 @@ Try also with PIPE or TCP/IP
|
|||||||
options->ssl_cipher)))
|
options->ssl_cipher)))
|
||||||
{
|
{
|
||||||
net->last_errno= CR_SSL_CONNECTION_ERROR;
|
net->last_errno= CR_SSL_CONNECTION_ERROR;
|
||||||
strmov(net->last_error,ER(net->last_errno));
|
strmov(net->last_error,ER(net->last_errno));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
DBUG_PRINT("info", ("IO layer change in progress..."));
|
DBUG_PRINT("info", ("IO layer change in progress..."));
|
||||||
@ -2201,7 +2201,7 @@ Try also with PIPE or TCP/IP
|
|||||||
{
|
{
|
||||||
net->last_errno= CR_SSL_CONNECTION_ERROR;
|
net->last_errno= CR_SSL_CONNECTION_ERROR;
|
||||||
strmov(net->last_error,ER(net->last_errno));
|
strmov(net->last_error,ER(net->last_errno));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
DBUG_PRINT("info", ("IO layer change done!"));
|
DBUG_PRINT("info", ("IO layer change done!"));
|
||||||
}
|
}
|
||||||
@ -2215,7 +2215,7 @@ Try also with PIPE or TCP/IP
|
|||||||
strmake(buff+5,user,32); /* Max user name */
|
strmake(buff+5,user,32); /* Max user name */
|
||||||
else
|
else
|
||||||
read_user_name((char*) buff+5);
|
read_user_name((char*) buff+5);
|
||||||
/* We have to handle different version of handshake here */
|
/* We have to handle different version of handshake here */
|
||||||
#ifdef _CUSTOMCONFIG_
|
#ifdef _CUSTOMCONFIG_
|
||||||
#include "_cust_libmysql.h";
|
#include "_cust_libmysql.h";
|
||||||
#endif
|
#endif
|
||||||
@ -2232,7 +2232,7 @@ Try also with PIPE or TCP/IP
|
|||||||
end=scramble(strend(buff+5)+1, mysql->scramble_buff,"\1~MySQL#!\2",
|
end=scramble(strend(buff+5)+1, mysql->scramble_buff,"\1~MySQL#!\2",
|
||||||
(my_bool) (mysql->protocol_version == 9));
|
(my_bool) (mysql->protocol_version == 9));
|
||||||
}
|
}
|
||||||
else /* For empty password*/
|
else /* For empty password*/
|
||||||
{
|
{
|
||||||
end=strend(buff+5)+1;
|
end=strend(buff+5)+1;
|
||||||
*end=0; /* Store zero length scramble */
|
*end=0; /* Store zero length scramble */
|
||||||
@ -2243,23 +2243,23 @@ Try also with PIPE or TCP/IP
|
|||||||
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))
|
||||||
{
|
{
|
||||||
end=strmake(end+1,db,NAME_LEN);
|
end=strmake(end+1,db,NAME_LEN);
|
||||||
mysql->db=my_strdup(db,MYF(MY_WME));
|
mysql->db=my_strdup(db,MYF(MY_WME));
|
||||||
db=0;
|
db=0;
|
||||||
}
|
}
|
||||||
/* Write authentication package */
|
/* Write authentication package */
|
||||||
if (my_net_write(net,buff,(ulong) (end-buff)) || net_flush(net))
|
if (my_net_write(net,buff,(ulong) (end-buff)) || net_flush(net))
|
||||||
{
|
{
|
||||||
net->last_errno= CR_SERVER_LOST;
|
net->last_errno= CR_SERVER_LOST;
|
||||||
strmov(net->last_error,ER(net->last_errno));
|
strmov(net->last_error,ER(net->last_errno));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We shall only query sever if it expect us to do so */
|
/* We shall only query sever if it expect us to do so */
|
||||||
|
|
||||||
if ( (pkt_length=net_safe_read(mysql)) == packet_error)
|
if ( (pkt_length=net_safe_read(mysql)) == packet_error)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@ -2269,46 +2269,47 @@ Try also with PIPE or TCP/IP
|
|||||||
if (pkt_length==24) /* We have new hash back */
|
if (pkt_length==24) /* We have new hash back */
|
||||||
{
|
{
|
||||||
/* Old passwords will have zero at the first byte of hash */
|
/* Old passwords will have zero at the first byte of hash */
|
||||||
if (net->read_pos[0])
|
if (net->read_pos[0])
|
||||||
{
|
{
|
||||||
/* Build full password hash as it is required to decode scramble */
|
/* Build full password hash as it is required to decode scramble */
|
||||||
password_hash_stage1(buff, passwd);
|
password_hash_stage1(buff, passwd);
|
||||||
/* Store copy as we'll need it later */
|
/* Store copy as we'll need it later */
|
||||||
memcpy(password_hash,buff,20);
|
memcpy(password_hash,buff,SCRAMBLE41_LENGTH);
|
||||||
/* Finally hash complete password using hash we got from server */
|
/* Finally hash complete password using hash we got from server */
|
||||||
password_hash_stage2(password_hash,net->read_pos);
|
password_hash_stage2(password_hash,net->read_pos);
|
||||||
/* Decypt and store scramble 4 = hash for stage2 */
|
/* Decypt and store scramble 4 = hash for stage2 */
|
||||||
password_crypt(net->read_pos+4,mysql->scramble_buff,password_hash,20);
|
password_crypt(net->read_pos+4,mysql->scramble_buff,password_hash,
|
||||||
mysql->scramble_buff[20]=0;
|
SCRAMBLE41_LENGTH);
|
||||||
|
mysql->scramble_buff[SCRAMBLE41_LENGTH]=0;
|
||||||
/* Encode scramble with password. Recycle buffer */
|
/* Encode scramble with password. Recycle buffer */
|
||||||
password_crypt(mysql->scramble_buff,buff,buff,20);
|
password_crypt(mysql->scramble_buff,buff,buff,SCRAMBLE41_LENGTH);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Create password to decode scramble */
|
/* Create password to decode scramble */
|
||||||
create_key_from_old_password(passwd,password_hash);
|
create_key_from_old_password(passwd,password_hash);
|
||||||
/* Decypt and store scramble 4 = hash for stage2 */
|
/* Decypt and store scramble 4 = hash for stage2 */
|
||||||
password_crypt(net->read_pos+4,mysql->scramble_buff,password_hash,20);
|
password_crypt(net->read_pos+4,mysql->scramble_buff,password_hash,
|
||||||
mysql->scramble_buff[20]=0;
|
SCRAMBLE41_LENGTH);
|
||||||
/* Finally scramble decoded scramble with password */
|
mysql->scramble_buff[SCRAMBLE41_LENGTH]=0;
|
||||||
scramble(buff, mysql->scramble_buff, passwd,
|
/* Finally scramble decoded scramble with password */
|
||||||
(my_bool) (mysql->protocol_version == 9));
|
scramble(buff, mysql->scramble_buff, passwd,0);
|
||||||
}
|
}
|
||||||
/* Write second package of authentication */
|
/* Write second package of authentication */
|
||||||
if (my_net_write(net,buff,20) || net_flush(net))
|
if (my_net_write(net,buff,SCRAMBLE41_LENGTH) || net_flush(net))
|
||||||
{
|
{
|
||||||
net->last_errno= CR_SERVER_LOST;
|
net->last_errno= CR_SERVER_LOST;
|
||||||
strmov(net->last_error,ER(net->last_errno));
|
strmov(net->last_error,ER(net->last_errno));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
/* Read What server thinks about out new auth message report */
|
/* Read What server thinks about out new auth message report */
|
||||||
if (net_safe_read(mysql) == packet_error)
|
if (net_safe_read(mysql) == packet_error)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End of authentication part of handshake */
|
/* 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 (db && mysql_select_db(mysql,db))
|
if (db && mysql_select_db(mysql,db))
|
||||||
@ -2395,7 +2396,7 @@ static my_bool mysql_reconnect(MYSQL *mysql)
|
|||||||
mysql->free_me=0;
|
mysql->free_me=0;
|
||||||
mysql_close(mysql);
|
mysql_close(mysql);
|
||||||
*mysql=tmp_mysql;
|
*mysql=tmp_mysql;
|
||||||
mysql_fix_pointers(mysql, &tmp_mysql); /* adjust connection pointers */
|
mysql_fix_pointers(mysql, &tmp_mysql); /* adjust connection pointers */
|
||||||
net_clear(&mysql->net);
|
net_clear(&mysql->net);
|
||||||
mysql->affected_rows= ~(my_ulonglong) 0;
|
mysql->affected_rows= ~(my_ulonglong) 0;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
@ -2403,28 +2404,28 @@ static my_bool mysql_reconnect(MYSQL *mysql)
|
|||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
Change user and database
|
Change user and database
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
|
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;
|
ulong pkt_length;
|
||||||
char password_hash[20]; /* Used for tmp storage of stage1 hash */
|
char password_hash[SCRAMBLE41_LENGTH]; /* Used for tmp storage of stage1 hash */
|
||||||
NET *net= &mysql->net;
|
NET *net= &mysql->net;
|
||||||
|
|
||||||
DBUG_ENTER("mysql_change_user");
|
DBUG_ENTER("mysql_change_user");
|
||||||
|
|
||||||
if (!user)
|
if (!user)
|
||||||
user="";
|
user="";
|
||||||
if (!passwd)
|
if (!passwd)
|
||||||
passwd="";
|
passwd="";
|
||||||
|
|
||||||
/* Store user into the buffer */
|
/* Store user into the buffer */
|
||||||
end=strmov(end,user)+1;
|
end=strmov(end,user)+1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
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
|
||||||
*/
|
*/
|
||||||
@ -2434,24 +2435,24 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
|
|||||||
{
|
{
|
||||||
/* Use something for not empty password not to match it against empty one */
|
/* Use something for not empty password not to match it against empty one */
|
||||||
end=scramble(end, mysql->scramble_buff,"\1~MySQL#!\2",
|
end=scramble(end, mysql->scramble_buff,"\1~MySQL#!\2",
|
||||||
(my_bool) (mysql->protocol_version == 9));
|
(my_bool) (mysql->protocol_version == 9));
|
||||||
}
|
}
|
||||||
else /* For empty password*/
|
else /* For empty password*/
|
||||||
*end=0; /* Store zero length scramble */
|
*end=0; /* Store zero length scramble */
|
||||||
}
|
}
|
||||||
/* Real scramble is sent only for servers. This is to be blocked by option */
|
/* Real scramble is sent only for servers. This is to be blocked by option */
|
||||||
else
|
else
|
||||||
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 */
|
/* We shall only query sever if it expect us to do so */
|
||||||
if ( (pkt_length=net_safe_read(mysql)) == packet_error)
|
if ( (pkt_length=net_safe_read(mysql)) == packet_error)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@ -2461,44 +2462,46 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
|
|||||||
if (pkt_length==24) /* We have new hash back */
|
if (pkt_length==24) /* We have new hash back */
|
||||||
{
|
{
|
||||||
/* Old passwords will have zero at the first byte of hash */
|
/* Old passwords will have zero at the first byte of hash */
|
||||||
if (net->read_pos[0])
|
if (net->read_pos[0])
|
||||||
{
|
{
|
||||||
/* Build full password hash as it is required to decode scramble */
|
/* Build full password hash as it is required to decode scramble */
|
||||||
password_hash_stage1(buff, passwd);
|
password_hash_stage1(buff, passwd);
|
||||||
/* Store copy as we'll need it later */
|
/* Store copy as we'll need it later */
|
||||||
memcpy(password_hash,buff,20);
|
memcpy(password_hash,buff,SCRAMBLE41_LENGTH);
|
||||||
/* Finally hash complete password using hash we got from server */
|
/* Finally hash complete password using hash we got from server */
|
||||||
password_hash_stage2(password_hash,net->read_pos);
|
password_hash_stage2(password_hash,net->read_pos);
|
||||||
/* Decypt and store scramble 4 = hash for stage2 */
|
/* Decypt and store scramble 4 = hash for stage2 */
|
||||||
password_crypt(net->read_pos+4,mysql->scramble_buff,password_hash,20);
|
password_crypt(net->read_pos+4,mysql->scramble_buff,password_hash,
|
||||||
mysql->scramble_buff[20]=0;
|
SCRAMBLE41_LENGTH);
|
||||||
|
mysql->scramble_buff[SCRAMBLE41_LENGTH]=0;
|
||||||
/* Encode scramble with password. Recycle buffer */
|
/* Encode scramble with password. Recycle buffer */
|
||||||
password_crypt(mysql->scramble_buff,buff,buff,20);
|
password_crypt(mysql->scramble_buff,buff,buff,SCRAMBLE41_LENGTH);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Create password to decode scramble */
|
/* Create password to decode scramble */
|
||||||
create_key_from_old_password(passwd,password_hash);
|
create_key_from_old_password(passwd,password_hash);
|
||||||
/* Decypt and store scramble 4 = hash for stage2 */
|
/* Decypt and store scramble 4 = hash for stage2 */
|
||||||
password_crypt(net->read_pos+4,mysql->scramble_buff,password_hash,20);
|
password_crypt(net->read_pos+4,mysql->scramble_buff,password_hash,
|
||||||
mysql->scramble_buff[20]=0;
|
SCRAMBLE41_LENGTH);
|
||||||
/* Finally scramble decoded scramble with password */
|
mysql->scramble_buff[SCRAMBLE41_LENGTH]=0;
|
||||||
|
/* Finally scramble decoded scramble with password */
|
||||||
scramble(buff, mysql->scramble_buff, passwd,
|
scramble(buff, mysql->scramble_buff, passwd,
|
||||||
(my_bool) (mysql->protocol_version == 9));
|
(my_bool) (mysql->protocol_version == 9));
|
||||||
}
|
}
|
||||||
/* Write second package of authentication */
|
/* Write second package of authentication */
|
||||||
if (my_net_write(net,buff,20) || net_flush(net))
|
if (my_net_write(net,buff,SCRAMBLE41_LENGTH) || net_flush(net))
|
||||||
{
|
{
|
||||||
net->last_errno= CR_SERVER_LOST;
|
net->last_errno= CR_SERVER_LOST;
|
||||||
strmov(net->last_error,ER(net->last_errno));
|
strmov(net->last_error,ER(net->last_errno));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
/* Read What server thinks about out new auth message report */
|
/* Read What server thinks about out new auth message report */
|
||||||
if (net_safe_read(mysql) == packet_error)
|
if (net_safe_read(mysql) == packet_error)
|
||||||
goto 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));
|
||||||
@ -2507,10 +2510,10 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
|
|||||||
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2598,7 +2601,7 @@ mysql_close(MYSQL *mysql)
|
|||||||
{
|
{
|
||||||
next_element= element->next;
|
next_element= element->next;
|
||||||
stmt_close((MYSQL_STMT *)element->data, 0);
|
stmt_close((MYSQL_STMT *)element->data, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mysql != mysql->master)
|
if (mysql != mysql->master)
|
||||||
mysql_close(mysql->master);
|
mysql_close(mysql->master);
|
||||||
@ -2686,7 +2689,7 @@ STDCALL mysql_add_slave(MYSQL* mysql, const char* host,
|
|||||||
Send the query and return so we can do something else.
|
Send the query and return so we can do something else.
|
||||||
Needs to be followed by mysql_read_query_result() when we want to
|
Needs to be followed by mysql_read_query_result() when we want to
|
||||||
finish processing it.
|
finish processing it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int STDCALL
|
int STDCALL
|
||||||
mysql_send_query(MYSQL* mysql, const char* query, ulong length)
|
mysql_send_query(MYSQL* mysql, const char* query, ulong length)
|
||||||
@ -4024,12 +4027,12 @@ static my_bool store_param(MYSQL_STMT *stmt, MYSQL_BIND *param)
|
|||||||
DBUG_ENTER("store_param");
|
DBUG_ENTER("store_param");
|
||||||
DBUG_PRINT("enter",("type: %d, buffer:%lx, length: %d", param->buffer_type,
|
DBUG_PRINT("enter",("type: %d, buffer:%lx, length: %d", param->buffer_type,
|
||||||
param->buffer ? param->buffer : "0", *param->length));
|
param->buffer ? param->buffer : "0", *param->length));
|
||||||
|
|
||||||
if (param->is_null || param->buffer_type == MYSQL_TYPE_NULL)
|
if (param->is_null || param->buffer_type == MYSQL_TYPE_NULL)
|
||||||
store_param_null(net, param);
|
store_param_null(net, param);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Allocate for worst case (long string) */
|
/* Allocate for worst case (long string) */
|
||||||
if ((my_realloc_str(net, 9 + *param->length)))
|
if ((my_realloc_str(net, 9 + *param->length)))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
(*param->store_param_func)(net, param);
|
(*param->store_param_func)(net, param);
|
||||||
@ -4205,14 +4208,14 @@ my_bool STDCALL mysql_bind_param(MYSQL_STMT *stmt, MYSQL_BIND * bind)
|
|||||||
param->param_number);
|
param->param_number);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If param->length is not given, change it to point to bind_length.
|
If param->length is not given, change it to point to bind_length.
|
||||||
This way we can always use *param->length to get the length of data
|
This way we can always use *param->length to get the length of data
|
||||||
*/
|
*/
|
||||||
if (!param->length)
|
if (!param->length)
|
||||||
param->length= ¶m->bind_length;
|
param->length= ¶m->bind_length;
|
||||||
|
|
||||||
/* Setup data copy functions for the different supported types */
|
/* Setup data copy functions for the different supported types */
|
||||||
switch (param->buffer_type) {
|
switch (param->buffer_type) {
|
||||||
case MYSQL_TYPE_NULL:
|
case MYSQL_TYPE_NULL:
|
||||||
@ -4358,7 +4361,7 @@ static void fetch_result_tinyint(MYSQL_BIND *param, uchar **row)
|
|||||||
static void fetch_result_short(MYSQL_BIND *param, uchar **row)
|
static void fetch_result_short(MYSQL_BIND *param, uchar **row)
|
||||||
{
|
{
|
||||||
short value= *(short *)row;
|
short value= *(short *)row;
|
||||||
int2store(param->buffer, value);
|
int2store(param->buffer, value);
|
||||||
*row+=2;
|
*row+=2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4462,7 +4465,7 @@ my_bool STDCALL mysql_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
|
|||||||
sprintf(stmt->last_error, ER(stmt->last_errno= CR_UNSUPPORTED_PARAM_TYPE),
|
sprintf(stmt->last_error, ER(stmt->last_errno= CR_UNSUPPORTED_PARAM_TYPE),
|
||||||
param->buffer_type, param->param_number);
|
param->buffer_type, param->param_number);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
if (!param->length)
|
if (!param->length)
|
||||||
param->length= ¶m->bind_length;
|
param->length= ¶m->bind_length;
|
||||||
}
|
}
|
||||||
@ -4479,10 +4482,10 @@ stmt_fetch_row(MYSQL_STMT *stmt, uchar **row)
|
|||||||
{
|
{
|
||||||
MYSQL_BIND *bind, *end;
|
MYSQL_BIND *bind, *end;
|
||||||
uchar *null_ptr= (uchar*) *row, bit;
|
uchar *null_ptr= (uchar*) *row, bit;
|
||||||
|
|
||||||
*row+= (stmt->field_count+7)/8;
|
*row+= (stmt->field_count+7)/8;
|
||||||
bit=1;
|
bit=1;
|
||||||
|
|
||||||
/* Copy complete row to application buffers */
|
/* Copy complete row to application buffers */
|
||||||
for (bind= stmt->bind, end= (MYSQL_BIND *) bind + stmt->field_count;
|
for (bind= stmt->bind, end= (MYSQL_BIND *) bind + stmt->field_count;
|
||||||
bind < end;
|
bind < end;
|
||||||
@ -4505,7 +4508,7 @@ stmt_fetch_row(MYSQL_STMT *stmt, uchar **row)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int read_binary_data(MYSQL *mysql)
|
static int read_binary_data(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
if (packet_error == net_safe_read(mysql))
|
if (packet_error == net_safe_read(mysql))
|
||||||
return -1;
|
return -1;
|
||||||
if (mysql->net.read_pos[0])
|
if (mysql->net.read_pos[0])
|
||||||
@ -4532,9 +4535,9 @@ int STDCALL mysql_fetch(MYSQL_STMT *stmt)
|
|||||||
DBUG_RETURN((int) stmt_fetch_row(stmt,(uchar **) &mysql->net.read_pos+1));
|
DBUG_RETURN((int) stmt_fetch_row(stmt,(uchar **) &mysql->net.read_pos+1));
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
DBUG_PRINT("info", ("end of data"));
|
DBUG_PRINT("info", ("end of data"));
|
||||||
mysql->status= MYSQL_STATUS_READY;
|
mysql->status= MYSQL_STATUS_READY;
|
||||||
|
|
||||||
if (res < 0) /* Network error */
|
if (res < 0) /* Network error */
|
||||||
{
|
{
|
||||||
set_stmt_errmsg(stmt,(char *)mysql->net.last_error,
|
set_stmt_errmsg(stmt,(char *)mysql->net.last_error,
|
||||||
|
@ -170,12 +170,20 @@ fi
|
|||||||
|
|
||||||
@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
|
@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
|
||||||
alter table user
|
alter table user
|
||||||
change password password char(45) not null,
|
|
||||||
add max_questions int(11) NOT NULL AFTER x509_subject,
|
add max_questions int(11) NOT NULL AFTER x509_subject,
|
||||||
add max_updates int(11) unsigned NOT NULL AFTER max_questions,
|
add max_updates int(11) unsigned NOT NULL AFTER max_questions,
|
||||||
add max_connections int(11) unsigned NOT NULL AFTER max_updates;
|
add max_connections int(11) unsigned NOT NULL AFTER max_updates;
|
||||||
END_OF_DATA
|
END_OF_DATA
|
||||||
|
|
||||||
|
# Increase password length to handle new passwords
|
||||||
|
|
||||||
|
@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
|
||||||
|
alter table user
|
||||||
|
change password password char(45) not null;
|
||||||
|
END_OF_DATA
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Add Create_tmp_table_priv and Lock_tables_priv to db and host
|
# Add Create_tmp_table_priv and Lock_tables_priv to db and host
|
||||||
#
|
#
|
||||||
|
@ -490,7 +490,7 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
|
|||||||
uint net_read_timeout)
|
uint net_read_timeout)
|
||||||
{
|
{
|
||||||
char buff[NAME_LEN+USERNAME_LENGTH+100],*end,*host_info;
|
char buff[NAME_LEN+USERNAME_LENGTH+100],*end,*host_info;
|
||||||
char password_hash[20];
|
char password_hash[SCRAMBLE41_LENGTH];
|
||||||
my_socket sock;
|
my_socket sock;
|
||||||
ulong ip_addr;
|
ulong ip_addr;
|
||||||
struct sockaddr_in sock_addr;
|
struct sockaddr_in sock_addr;
|
||||||
@ -856,28 +856,29 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
|
|||||||
/* Build full password hash as it is required to decode scramble */
|
/* Build full password hash as it is required to decode scramble */
|
||||||
password_hash_stage1(buff, passwd);
|
password_hash_stage1(buff, passwd);
|
||||||
/* Store copy as we'll need it later */
|
/* Store copy as we'll need it later */
|
||||||
memcpy(password_hash,buff,20);
|
memcpy(password_hash,buff,SCRAMBLE41_LENGTH);
|
||||||
/* Finally hash complete password using hash we got from server */
|
/* Finally hash complete password using hash we got from server */
|
||||||
password_hash_stage2(password_hash,(char*)net->read_pos);
|
password_hash_stage2(password_hash,(char*)net->read_pos);
|
||||||
/* Decypt and store scramble 4 = hash for stage2 */
|
/* Decypt and store scramble 4 = hash for stage2 */
|
||||||
password_crypt((char*)net->read_pos+4,mysql->scramble_buff,password_hash,20);
|
password_crypt((char*)net->read_pos+4,mysql->scramble_buff,password_hash,
|
||||||
mysql->scramble_buff[20]=0;
|
SCRAMBLE41_LENGTH);
|
||||||
|
mysql->scramble_buff[SCRAMBLE41_LENGTH]=0;
|
||||||
/* Encode scramble with password. Recycle buffer */
|
/* Encode scramble with password. Recycle buffer */
|
||||||
password_crypt(mysql->scramble_buff,buff,buff,20);
|
password_crypt(mysql->scramble_buff,buff,buff,SCRAMBLE41_LENGTH);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Create password to decode scramble */
|
/* Create password to decode scramble */
|
||||||
create_key_from_old_password(passwd,password_hash);
|
create_key_from_old_password(passwd,password_hash);
|
||||||
/* Decypt and store scramble 4 = hash for stage2 */
|
/* Decypt and store scramble 4 = hash for stage2 */
|
||||||
password_crypt((char*)net->read_pos+4,mysql->scramble_buff,password_hash,20);
|
password_crypt((char*)net->read_pos+4,mysql->scramble_buff,password_hash,
|
||||||
mysql->scramble_buff[20]=0;
|
SCRAMBLE41_LENGTH);
|
||||||
|
mysql->scramble_buff[SCRAMBLE41_LENGTH]=0;
|
||||||
/* Finally scramble decoded scramble with password */
|
/* Finally scramble decoded scramble with password */
|
||||||
scramble(buff, mysql->scramble_buff, passwd,
|
scramble(buff, mysql->scramble_buff, passwd,0);
|
||||||
(my_bool) (mysql->protocol_version == 9));
|
|
||||||
}
|
}
|
||||||
/* Write second package of authentication */
|
/* Write second package of authentication */
|
||||||
if (my_net_write(net,buff,20) || net_flush(net))
|
if (my_net_write(net,buff,SCRAMBLE41_LENGTH) || net_flush(net))
|
||||||
{
|
{
|
||||||
net->last_errno= CR_SERVER_LOST;
|
net->last_errno= CR_SERVER_LOST;
|
||||||
strmov(net->last_error,ER(net->last_errno));
|
strmov(net->last_error,ER(net->last_errno));
|
||||||
|
@ -2496,6 +2496,9 @@ static void create_new_thread(THD *thd)
|
|||||||
for (uint i=0; i < 8 ; i++) // Generate password teststring
|
for (uint i=0; i < 8 ; i++) // Generate password teststring
|
||||||
thd->scramble[i]= (char) (rnd(&sql_rand)*94+33);
|
thd->scramble[i]= (char) (rnd(&sql_rand)*94+33);
|
||||||
thd->scramble[8]=0;
|
thd->scramble[8]=0;
|
||||||
|
// Back it up as old clients may need it
|
||||||
|
memcpy(thd->old_scramble,thd->scramble,9);
|
||||||
|
|
||||||
|
|
||||||
thd->real_id=pthread_self(); // Keep purify happy
|
thd->real_id=pthread_self(); // Keep purify happy
|
||||||
|
|
||||||
|
@ -66,7 +66,6 @@
|
|||||||
#define PVERSION41_CHAR '*'
|
#define PVERSION41_CHAR '*'
|
||||||
|
|
||||||
/* Scramble length for new password version */
|
/* Scramble length for new password version */
|
||||||
#define SCRAMBLE41_LENGTH 20
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -175,17 +174,12 @@ void create_random_string(int length,struct rand_struct *rand_st,char* target)
|
|||||||
none
|
none
|
||||||
*/
|
*/
|
||||||
|
|
||||||
inline void password_crypt(const char* from,char* to, const char* password,int length)
|
void password_crypt(const char* from,char* to, const char* password,int length)
|
||||||
{
|
{
|
||||||
const char *from_end=from+length;
|
const char *from_end=from+length;
|
||||||
|
|
||||||
while(from<from_end)
|
while (from < from_end)
|
||||||
{
|
*to++= *(from++) ^* (password++);
|
||||||
*to=*from^*password;
|
|
||||||
from++;
|
|
||||||
to++;
|
|
||||||
password++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -286,7 +280,9 @@ void password_hash_stage2(char *to,const char *salt)
|
|||||||
none
|
none
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void make_scrambled_password(char *to,const char *password,my_bool force_old_scramble,struct rand_struct *rand_st)
|
void make_scrambled_password(char *to,const char *password,
|
||||||
|
my_bool force_old_scramble,
|
||||||
|
struct rand_struct *rand_st)
|
||||||
{
|
{
|
||||||
ulong hash_res[2]; /* Used for pre 4.1 password hashing */
|
ulong hash_res[2]; /* Used for pre 4.1 password hashing */
|
||||||
unsigned short salt; /* Salt for 4.1 version password */
|
unsigned short salt; /* Salt for 4.1 version password */
|
||||||
@ -336,7 +332,6 @@ void get_salt_from_bin_password(ulong *res,unsigned char *password,ulong salt)
|
|||||||
unsigned char* password_end=password+SCRAMBLE41_LENGTH;
|
unsigned char* password_end=password+SCRAMBLE41_LENGTH;
|
||||||
*res=salt;
|
*res=salt;
|
||||||
res++;
|
res++;
|
||||||
bzero(res,5*sizeof(res[0]));
|
|
||||||
|
|
||||||
/* Process password of known length*/
|
/* Process password of known length*/
|
||||||
while (password<password_end)
|
while (password<password_end)
|
||||||
@ -364,12 +359,14 @@ void get_salt_from_bin_password(ulong *res,unsigned char *password,ulong salt)
|
|||||||
!0 for invalid password
|
!0 for invalid password
|
||||||
*/
|
*/
|
||||||
|
|
||||||
my_bool validate_password(const char* password, const char* message, ulong* salt)
|
my_bool validate_password(const char* password, const char* message,
|
||||||
|
ulong* salt)
|
||||||
{
|
{
|
||||||
char buffer[SCRAMBLE41_LENGTH]; /* Used for password validation */
|
char buffer[SCRAMBLE41_LENGTH]; /* Used for password validation */
|
||||||
char tmpsalt[8]; /* Temporary value to convert salt to string form */
|
char tmpsalt[8]; /* Temporary value to convert salt to string form */
|
||||||
int i;
|
|
||||||
ulong salt_candidate[6]; /* Computed candidate salt */
|
ulong salt_candidate[6]; /* Computed candidate salt */
|
||||||
|
ulong* sc=salt_candidate; /* we need to be able to increment */
|
||||||
|
ulong* salt_end;
|
||||||
|
|
||||||
/* Now we shall get stage1 encrypted password in buffer*/
|
/* Now we shall get stage1 encrypted password in buffer*/
|
||||||
password_crypt(password,buffer,message,SCRAMBLE41_LENGTH);
|
password_crypt(password,buffer,message,SCRAMBLE41_LENGTH);
|
||||||
@ -381,9 +378,11 @@ my_bool validate_password(const char* password, const char* message, ulong* salt
|
|||||||
/* Convert password to salt to compare */
|
/* Convert password to salt to compare */
|
||||||
get_salt_from_bin_password(salt_candidate,buffer,salt[0]);
|
get_salt_from_bin_password(salt_candidate,buffer,salt[0]);
|
||||||
|
|
||||||
/* Now we shall get exactly the same password as we have stored for user */
|
/* Now we shall get exactly the same password as we have stored for user */
|
||||||
for(i=1;i<6;i++)
|
for (salt_end=salt+5 ; salt < salt_end; )
|
||||||
if (salt[i]!=salt_candidate[i]) return 1;
|
if (*++salt != *++sc)
|
||||||
|
return 1;
|
||||||
|
|
||||||
/* Or password correct*/
|
/* Or password correct*/
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -400,11 +399,9 @@ my_bool validate_password(const char* password, const char* message, ulong* salt
|
|||||||
password length >0
|
password length >0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
inline int get_password_length(my_bool force_old_scramble)
|
int get_password_length(my_bool force_old_scramble)
|
||||||
{
|
{
|
||||||
if (force_old_scramble)
|
return (force_old_scramble) ? 16 : SHA1_HASH_SIZE*2+4+1;
|
||||||
return 16;
|
|
||||||
else return SHA1_HASH_SIZE*2+4+1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -420,9 +417,9 @@ inline int get_password_length(my_bool force_old_scramble)
|
|||||||
!0 password version char for newer passwords
|
!0 password version char for newer passwords
|
||||||
*/
|
*/
|
||||||
|
|
||||||
inline char get_password_version(const char* password)
|
char get_password_version(const char* password)
|
||||||
{
|
{
|
||||||
if (password==NULL) return 0;
|
if (password==NULL) return 0;
|
||||||
if (password[0]==PVERSION41_CHAR) return PVERSION41_CHAR;
|
if (password[0]==PVERSION41_CHAR) return PVERSION41_CHAR;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -467,7 +464,6 @@ inline uint char_val(char X)
|
|||||||
|
|
||||||
void get_salt_from_password(ulong *res,const char *password)
|
void get_salt_from_password(ulong *res,const char *password)
|
||||||
{
|
{
|
||||||
bzero(res,6*sizeof(res[0]));
|
|
||||||
if (password) /* zero salt corresponds to empty password */
|
if (password) /* zero salt corresponds to empty password */
|
||||||
{
|
{
|
||||||
if (password[0]==PVERSION41_CHAR) /* if new password */
|
if (password[0]==PVERSION41_CHAR) /* if new password */
|
||||||
@ -553,19 +549,17 @@ void get_hash_and_password(ulong* salt, uint8 pversion, char* hash, unsigned cha
|
|||||||
|
|
||||||
if (pversion) /* New password version assumed */
|
if (pversion) /* New password version assumed */
|
||||||
{
|
{
|
||||||
salt_end=salt+6;
|
salt_end=salt+5;
|
||||||
sprintf(hash,"%04x",(unsigned short)salt[0]);
|
sprintf(hash,"%04x",(unsigned short)salt[0]);
|
||||||
salt++; /* position to the second element */
|
|
||||||
while (salt<salt_end) /* Iterate over these elements*/
|
while (salt<salt_end) /* Iterate over these elements*/
|
||||||
{
|
{
|
||||||
val=*salt;
|
val=*(++salt);
|
||||||
for(t=3;t>=0;t--)
|
for (t=3; t>=0; t--)
|
||||||
{
|
{
|
||||||
bin_password[t]=val%256;
|
bin_password[t]=val%256;
|
||||||
val>>=8; /* Scroll 8 bits to get next part*/
|
val>>=8; /* Scroll 8 bits to get next part*/
|
||||||
}
|
}
|
||||||
bin_password+=4; /* Get to next 4 chars*/
|
bin_password+=4; /* Get to next 4 chars*/
|
||||||
salt++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -611,7 +605,7 @@ void get_hash_and_password(ulong* salt, uint8 pversion, char* hash, unsigned cha
|
|||||||
|
|
||||||
void create_key_from_old_password(const char* passwd, char* key)
|
void create_key_from_old_password(const char* passwd, char* key)
|
||||||
{
|
{
|
||||||
char buffer[20]; /* Buffer for various needs */
|
char buffer[SCRAMBLE41_LENGTH]; /* Buffer for various needs */
|
||||||
ulong salt[6]; /* Salt (large for safety) */
|
ulong salt[6]; /* Salt (large for safety) */
|
||||||
/* At first hash password to the string stored in password */
|
/* At first hash password to the string stored in password */
|
||||||
make_scrambled_password(buffer,passwd,1,(struct rand_struct *)NULL);
|
make_scrambled_password(buffer,passwd,1,(struct rand_struct *)NULL);
|
||||||
|
170
sql/sql_acl.cc
170
sql/sql_acl.cc
@ -102,10 +102,10 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
|
|||||||
if (dont_read_acl_tables)
|
if (dont_read_acl_tables)
|
||||||
{
|
{
|
||||||
DBUG_RETURN(0); /* purecov: tested */
|
DBUG_RETURN(0); /* purecov: tested */
|
||||||
}
|
}
|
||||||
|
|
||||||
priv_version++; /* Priveleges updated */
|
priv_version++; /* Priveleges updated */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
To be able to run this from boot, we allocate a temporary THD
|
To be able to run this from boot, we allocate a temporary THD
|
||||||
*/
|
*/
|
||||||
@ -205,7 +205,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
|
|||||||
continue; /* purecov: tested */
|
continue; /* purecov: tested */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
get_salt_from_password(user.salt,user.password);
|
get_salt_from_password(user.salt,user.password);
|
||||||
user.access=get_access(table,3) & GLOBAL_ACLS;
|
user.access=get_access(table,3) & GLOBAL_ACLS;
|
||||||
user.sort=get_sort(2,user.host.hostname,user.user);
|
user.sort=get_sort(2,user.host.hostname,user.user);
|
||||||
user.hostname_length= (user.host.hostname ?
|
user.hostname_length= (user.host.hostname ?
|
||||||
@ -263,7 +263,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
|
|||||||
sizeof(ACL_USER),(qsort_cmp) acl_compare);
|
sizeof(ACL_USER),(qsort_cmp) acl_compare);
|
||||||
end_read_record(&read_record_info);
|
end_read_record(&read_record_info);
|
||||||
freeze_size(&acl_users);
|
freeze_size(&acl_users);
|
||||||
|
|
||||||
init_read_record(&read_record_info,thd,table=tables[2].table,NULL,1,0);
|
init_read_record(&read_record_info,thd,table=tables[2].table,NULL,1,0);
|
||||||
VOID(my_init_dynamic_array(&acl_dbs,sizeof(ACL_DB),50,100));
|
VOID(my_init_dynamic_array(&acl_dbs,sizeof(ACL_DB),50,100));
|
||||||
while (!(read_record_info.read_record(&read_record_info)))
|
while (!(read_record_info.read_record(&read_record_info)))
|
||||||
@ -452,17 +452,17 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b)
|
|||||||
Prepare crypted scramble to be sent to the client
|
Prepare crypted scramble to be sent to the client
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void prepare_scramble(THD* thd, ACL_USER *acl_user,char* prepared_scramble)
|
void prepare_scramble(THD *thd, ACL_USER *acl_user,char* prepared_scramble)
|
||||||
{
|
{
|
||||||
/* Binary password format to be used for generation*/
|
/* Binary password format to be used for generation*/
|
||||||
char bin_password[20];
|
char bin_password[SCRAMBLE41_LENGTH];
|
||||||
/* Generate new long scramble for the thread */
|
/* Generate new long scramble for the thread */
|
||||||
create_random_string(20,&thd->rand,thd->scramble);
|
create_random_string(SCRAMBLE41_LENGTH,&thd->rand,thd->scramble);
|
||||||
thd->scramble[20]=0;
|
thd->scramble[SCRAMBLE41_LENGTH]=0;
|
||||||
/* Get binary form, First 4 bytes of prepared scramble is salt */
|
/* Get binary form, First 4 bytes of prepared scramble is salt */
|
||||||
get_hash_and_password(acl_user->salt,acl_user->pversion,prepared_scramble,(unsigned char*)bin_password);
|
get_hash_and_password(acl_user->salt,acl_user->pversion,prepared_scramble,(unsigned char*)bin_password);
|
||||||
/* Finally encrypt password to get prepared scramble */
|
/* Finally encrypt password to get prepared scramble */
|
||||||
password_crypt(thd->scramble,prepared_scramble+4,bin_password,20);
|
password_crypt(thd->scramble,prepared_scramble+4,bin_password,SCRAMBLE41_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -472,11 +472,11 @@ 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;
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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,
|
||||||
@ -488,7 +488,7 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
|||||||
*priv_user=(char*) user;
|
*priv_user=(char*) user;
|
||||||
bool password_correct=0;
|
bool password_correct=0;
|
||||||
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));
|
||||||
@ -498,18 +498,18 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
|||||||
DBUG_RETURN((ulong) ~NO_ACCESS); /* purecov: tested */
|
DBUG_RETURN((ulong) ~NO_ACCESS); /* purecov: tested */
|
||||||
}
|
}
|
||||||
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
|
||||||
|
|
||||||
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=*hint_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*);
|
||||||
@ -517,30 +517,30 @@ 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;
|
*hint_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))
|
(acl_user->password && *password))
|
||||||
{
|
{
|
||||||
/* Quick check and accept for empty passwords*/
|
/* Quick check and accept for empty passwords*/
|
||||||
if (!acl_user->password && !*password)
|
if (!acl_user->password && !*password)
|
||||||
password_correct=1;
|
password_correct=1;
|
||||||
else /* Normal password presents */
|
else /* Normal password presents */
|
||||||
{
|
{
|
||||||
/* New version password is checked differently */
|
/* New version password is checked differently */
|
||||||
if (acl_user->pversion)
|
if (acl_user->pversion)
|
||||||
{
|
{
|
||||||
@ -548,40 +548,40 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
|||||||
{
|
{
|
||||||
if (!validate_password(password,message,acl_user->salt))
|
if (!validate_password(password,message,acl_user->salt))
|
||||||
password_correct=1;
|
password_correct=1;
|
||||||
}
|
}
|
||||||
else /* First stage - just prepare scramble */
|
else /* First stage - just prepare scramble */
|
||||||
prepare_scramble(thd,acl_user,prepared_scramble);
|
prepare_scramble(thd,acl_user,prepared_scramble);
|
||||||
}
|
}
|
||||||
/* Old way to check password */
|
/* Old way to check password */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Checking the scramble at any stage. First - old clients */
|
/* Checking the scramble at any stage. First - old clients */
|
||||||
if (!check_scramble(password,message,acl_user->salt,
|
if (!check_scramble(password,message,acl_user->salt,
|
||||||
(my_bool) old_ver))
|
(my_bool) old_ver))
|
||||||
password_correct=1;
|
password_correct=1;
|
||||||
else /* Password incorrect */
|
else /* Password incorrect */
|
||||||
/* At the first stage - prepare scramble */
|
/* At the first stage - prepare scramble */
|
||||||
if (!stage)
|
if (!stage)
|
||||||
prepare_scramble(thd,acl_user,prepared_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 */
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
Vio *vio=thd->net.vio;
|
Vio *vio=thd->net.vio;
|
||||||
/*
|
/*
|
||||||
In this point we know that user is allowed to connect
|
In this point we know that user is allowed to connect
|
||||||
from given host by given username/password pair. Now
|
from given host by given username/password pair. Now
|
||||||
we check if SSL is required, if user is using SSL and
|
we check if SSL is required, if user is using SSL and
|
||||||
if X509 certificate attributes are OK
|
if X509 certificate attributes are OK
|
||||||
*/
|
*/
|
||||||
switch (acl_user->ssl_type) {
|
switch (acl_user->ssl_type) {
|
||||||
case SSL_TYPE_NOT_SPECIFIED: // Impossible
|
case SSL_TYPE_NOT_SPECIFIED: // Impossible
|
||||||
@ -594,8 +594,8 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
|||||||
break;
|
break;
|
||||||
case SSL_TYPE_X509: /* Client should have any valid certificate. */
|
case SSL_TYPE_X509: /* Client should have any valid certificate. */
|
||||||
/*
|
/*
|
||||||
Connections with non-valid certificates are dropped already
|
Connections with non-valid certificates are dropped already
|
||||||
in sslaccept() anyway, so we do not check validity here.
|
in sslaccept() anyway, so we do not check validity here.
|
||||||
*/
|
*/
|
||||||
if (SSL_get_peer_certificate(vio->ssl_))
|
if (SSL_get_peer_certificate(vio->ssl_))
|
||||||
user_access=acl_user->access;
|
user_access=acl_user->access;
|
||||||
@ -624,7 +624,7 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
|||||||
X509* cert=SSL_get_peer_certificate(vio->ssl_);
|
X509* cert=SSL_get_peer_certificate(vio->ssl_);
|
||||||
DBUG_PRINT("info",("checkpoint 2"));
|
DBUG_PRINT("info",("checkpoint 2"));
|
||||||
/* If X509 issuer is speified, we check it... */
|
/* If X509 issuer is speified, we check it... */
|
||||||
if (acl_user->x509_issuer)
|
if (acl_user->x509_issuer)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info",("checkpoint 3"));
|
DBUG_PRINT("info",("checkpoint 3"));
|
||||||
char *ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
|
char *ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
|
||||||
@ -660,7 +660,7 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
|||||||
*mqh=acl_user->user_resource;
|
*mqh=acl_user->user_resource;
|
||||||
if (!acl_user->user)
|
if (!acl_user->user)
|
||||||
*priv_user=(char*) ""; // Change to anonymous user /* purecov: inspected */
|
*priv_user=(char*) ""; // Change to anonymous user /* purecov: inspected */
|
||||||
|
|
||||||
unlock_and_exit:
|
unlock_and_exit:
|
||||||
VOID(pthread_mutex_unlock(&acl_cache->lock));
|
VOID(pthread_mutex_unlock(&acl_cache->lock));
|
||||||
DBUG_RETURN(user_access);
|
DBUG_RETURN(user_access);
|
||||||
@ -675,12 +675,12 @@ static byte* check_get_key(ACL_USER *buff,uint *length,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void acl_update_user(const char *user, const char *host,
|
static void acl_update_user(const char *user, const char *host,
|
||||||
const char *password,
|
const char *password,
|
||||||
enum SSL_type ssl_type,
|
enum SSL_type ssl_type,
|
||||||
const char *ssl_cipher,
|
const char *ssl_cipher,
|
||||||
const char *x509_issuer,
|
const char *x509_issuer,
|
||||||
const char *x509_subject,
|
const char *x509_subject,
|
||||||
USER_RESOURCES *mqh,
|
USER_RESOURCES *mqh,
|
||||||
ulong privileges)
|
ulong privileges)
|
||||||
{
|
{
|
||||||
for (uint i=0 ; i < acl_users.elements ; i++)
|
for (uint i=0 ; i < acl_users.elements ; i++)
|
||||||
@ -716,8 +716,8 @@ static void acl_update_user(const char *user, const char *host,
|
|||||||
if (!password[0]) /* If password is empty set it to null */
|
if (!password[0]) /* If password is empty set it to null */
|
||||||
{
|
{
|
||||||
acl_user->password=0;
|
acl_user->password=0;
|
||||||
acl_user->pversion=0; // just initialize
|
acl_user->pversion=0; // just initialize
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
acl_user->password=(char*) ""; // Just point at something
|
acl_user->password=(char*) ""; // Just point at something
|
||||||
@ -733,7 +733,7 @@ static void acl_update_user(const char *user, const char *host,
|
|||||||
|
|
||||||
|
|
||||||
static void acl_insert_user(const char *user, const char *host,
|
static void acl_insert_user(const char *user, const char *host,
|
||||||
const char *password,
|
const char *password,
|
||||||
enum SSL_type ssl_type,
|
enum SSL_type ssl_type,
|
||||||
const char *ssl_cipher,
|
const char *ssl_cipher,
|
||||||
const char *x509_issuer,
|
const char *x509_issuer,
|
||||||
@ -926,7 +926,7 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr)
|
|||||||
{
|
{
|
||||||
if (*wildstr == wild_prefix && wildstr[1])
|
if (*wildstr == wild_prefix && wildstr[1])
|
||||||
wildstr++;
|
wildstr++;
|
||||||
if (my_toupper(cs, *wildstr++) !=
|
if (my_toupper(cs, *wildstr++) !=
|
||||||
my_toupper(cs, *str++)) DBUG_RETURN(1);
|
my_toupper(cs, *str++)) DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
if (! *wildstr ) DBUG_RETURN (*str != 0);
|
if (! *wildstr ) DBUG_RETURN (*str != 0);
|
||||||
@ -1091,7 +1091,7 @@ bool check_change_password(THD *thd, const char *host, const char *user)
|
|||||||
RETURN VALUES
|
RETURN VALUES
|
||||||
0 ok
|
0 ok
|
||||||
1 ERROR; In this case the error is sent to the client.
|
1 ERROR; In this case the error is sent to the client.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool change_password(THD *thd, const char *host, const char *user,
|
bool change_password(THD *thd, const char *host, const char *user,
|
||||||
char *new_password)
|
char *new_password)
|
||||||
@ -1107,7 +1107,7 @@ bool change_password(THD *thd, const char *host, const char *user,
|
|||||||
|
|
||||||
/* 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)
|
||||||
new_password[length & 16]=0;
|
new_password[length & 16]=0;
|
||||||
|
|
||||||
@ -1133,8 +1133,8 @@ bool change_password(THD *thd, const char *host, const char *user,
|
|||||||
if (!new_password[0])
|
if (!new_password[0])
|
||||||
acl_user->password=0;
|
acl_user->password=0;
|
||||||
else
|
else
|
||||||
acl_user->password=(char*) ""; // Point at something
|
acl_user->password=(char*) ""; // Point at something
|
||||||
|
|
||||||
acl_cache->clear(1); // Clear locked hostname cache
|
acl_cache->clear(1); // Clear locked hostname cache
|
||||||
VOID(pthread_mutex_unlock(&acl_cache->lock));
|
VOID(pthread_mutex_unlock(&acl_cache->lock));
|
||||||
|
|
||||||
@ -1321,7 +1321,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
|||||||
|
|
||||||
if (combo.password.str && combo.password.str[0])
|
if (combo.password.str && combo.password.str[0])
|
||||||
{
|
{
|
||||||
if ((combo.password.length != HASH_PASSWORD_LENGTH)
|
if ((combo.password.length != HASH_PASSWORD_LENGTH)
|
||||||
&& combo.password.length != HASH_OLD_PASSWORD_LENGTH)
|
&& combo.password.length != HASH_OLD_PASSWORD_LENGTH)
|
||||||
{
|
{
|
||||||
my_error(ER_PASSWORD_NO_MATCH,MYF(0));
|
my_error(ER_PASSWORD_NO_MATCH,MYF(0));
|
||||||
@ -1329,7 +1329,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
|||||||
}
|
}
|
||||||
password=combo.password.str;
|
password=combo.password.str;
|
||||||
}
|
}
|
||||||
|
|
||||||
table->field[0]->store(combo.host.str,combo.host.length, system_charset_info);
|
table->field[0]->store(combo.host.str,combo.host.length, system_charset_info);
|
||||||
table->field[1]->store(combo.user.str,combo.user.length, system_charset_info);
|
table->field[1]->store(combo.user.str,combo.user.length, system_charset_info);
|
||||||
table->file->index_init(0);
|
table->file->index_init(0);
|
||||||
@ -1742,9 +1742,9 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((host && !wild_case_compare(system_charset_info,
|
if ((host && !wild_case_compare(system_charset_info,
|
||||||
host,grant_table->host)) ||
|
host,grant_table->host)) ||
|
||||||
(ip && !wild_case_compare(system_charset_info,
|
(ip && !wild_case_compare(system_charset_info,
|
||||||
ip,grant_table->host)))
|
ip,grant_table->host)))
|
||||||
found=grant_table; // Host ok
|
found=grant_table; // Host ok
|
||||||
}
|
}
|
||||||
@ -2676,9 +2676,9 @@ bool check_grant_db(THD *thd,const char *db)
|
|||||||
GRANT_TABLE *grant_table = (GRANT_TABLE*) hash_element(&hash_tables,idx);
|
GRANT_TABLE *grant_table = (GRANT_TABLE*) hash_element(&hash_tables,idx);
|
||||||
if (len < grant_table->key_length &&
|
if (len < grant_table->key_length &&
|
||||||
!memcmp(grant_table->hash_key,helping,len) &&
|
!memcmp(grant_table->hash_key,helping,len) &&
|
||||||
(thd->host && !wild_case_compare(system_charset_info,
|
(thd->host && !wild_case_compare(system_charset_info,
|
||||||
thd->host,grant_table->host) ||
|
thd->host,grant_table->host) ||
|
||||||
(thd->ip && !wild_case_compare(system_charset_info,
|
(thd->ip && !wild_case_compare(system_charset_info,
|
||||||
thd->ip,grant_table->host))))
|
thd->ip,grant_table->host))))
|
||||||
{
|
{
|
||||||
error=0; // Found match
|
error=0; // Found match
|
||||||
@ -2764,7 +2764,7 @@ static uint command_lengths[]=
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
||||||
{
|
{
|
||||||
ulong want_access;
|
ulong want_access;
|
||||||
uint counter,index;
|
uint counter,index;
|
||||||
@ -2803,7 +2803,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
!my_strcasecmp(system_charset_info, lex_user->host.str, host))
|
!my_strcasecmp(system_charset_info, lex_user->host.str, host))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (counter == acl_users.elements)
|
if (counter == acl_users.elements)
|
||||||
{
|
{
|
||||||
my_printf_error(ER_NONEXISTING_GRANT,ER(ER_NONEXISTING_GRANT),
|
my_printf_error(ER_NONEXISTING_GRANT,ER(ER_NONEXISTING_GRANT),
|
||||||
MYF(0),lex_user->user.str,lex_user->host.str);
|
MYF(0),lex_user->user.str,lex_user->host.str);
|
||||||
@ -2836,13 +2836,13 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
global.append("ALL PRIVILEGES",14);
|
global.append("ALL PRIVILEGES",14);
|
||||||
else if (!(want_access & ~GRANT_ACL))
|
else if (!(want_access & ~GRANT_ACL))
|
||||||
global.append("USAGE",5);
|
global.append("USAGE",5);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool found=0;
|
bool found=0;
|
||||||
ulong j,test_access= want_access & ~GRANT_ACL;
|
ulong j,test_access= want_access & ~GRANT_ACL;
|
||||||
for (counter=0, j = SELECT_ACL;j <= GLOBAL_ACLS;counter++,j <<= 1)
|
for (counter=0, j = SELECT_ACL;j <= GLOBAL_ACLS;counter++,j <<= 1)
|
||||||
{
|
{
|
||||||
if (test_access & j)
|
if (test_access & j)
|
||||||
{
|
{
|
||||||
if (found)
|
if (found)
|
||||||
global.append(", ",2);
|
global.append(", ",2);
|
||||||
@ -2852,7 +2852,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
global.append (" ON *.* TO '",12);
|
global.append (" ON *.* TO '",12);
|
||||||
global.append(lex_user->user.str,lex_user->user.length);
|
global.append(lex_user->user.str,lex_user->user.length);
|
||||||
global.append ("'@'",3);
|
global.append ("'@'",3);
|
||||||
global.append(lex_user->host.str,lex_user->host.length);
|
global.append(lex_user->host.str,lex_user->host.length);
|
||||||
global.append ('\'');
|
global.append ('\'');
|
||||||
@ -2901,9 +2901,9 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
(acl_user->user_resource.questions | acl_user->user_resource.updates |
|
(acl_user->user_resource.questions | acl_user->user_resource.updates |
|
||||||
acl_user->user_resource.connections))
|
acl_user->user_resource.connections))
|
||||||
{
|
{
|
||||||
global.append(" WITH",5);
|
global.append(" WITH",5);
|
||||||
if (want_access & GRANT_ACL)
|
if (want_access & GRANT_ACL)
|
||||||
global.append(" GRANT OPTION",13);
|
global.append(" GRANT OPTION",13);
|
||||||
if (acl_user->user_resource.questions)
|
if (acl_user->user_resource.questions)
|
||||||
{
|
{
|
||||||
char buff[22], *p; // just as in int2str
|
char buff[22], *p; // just as in int2str
|
||||||
@ -2950,7 +2950,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
!my_strcasecmp(system_charset_info, lex_user->host.str, host))
|
!my_strcasecmp(system_charset_info, lex_user->host.str, host))
|
||||||
{
|
{
|
||||||
want_access=acl_db->access;
|
want_access=acl_db->access;
|
||||||
if (want_access)
|
if (want_access)
|
||||||
{
|
{
|
||||||
String db(buff,sizeof(buff),system_charset_info);
|
String db(buff,sizeof(buff),system_charset_info);
|
||||||
db.length(0);
|
db.length(0);
|
||||||
@ -2976,10 +2976,10 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
db.append (" ON `",5);
|
db.append (" ON `",5);
|
||||||
db.append(acl_db->db);
|
db.append(acl_db->db);
|
||||||
db.append ("`.* TO '",8);
|
db.append ("`.* TO '",8);
|
||||||
db.append(lex_user->user.str,lex_user->user.length);
|
db.append(lex_user->user.str,lex_user->user.length);
|
||||||
db.append ("'@'",3);
|
db.append ("'@'",3);
|
||||||
db.append(lex_user->host.str, lex_user->host.length);
|
db.append(lex_user->host.str, lex_user->host.length);
|
||||||
db.append ('\'');
|
db.append ('\'');
|
||||||
if (want_access & GRANT_ACL)
|
if (want_access & GRANT_ACL)
|
||||||
db.append(" WITH GRANT OPTION",18);
|
db.append(" WITH GRANT OPTION",18);
|
||||||
thd->packet.length(0);
|
thd->packet.length(0);
|
||||||
@ -2998,7 +2998,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
for (index=0 ; index < hash_tables.records ; index++)
|
for (index=0 ; index < hash_tables.records ; index++)
|
||||||
{
|
{
|
||||||
const char *user,*host;
|
const char *user,*host;
|
||||||
GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&hash_tables,index);
|
GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&hash_tables,index);
|
||||||
|
|
||||||
if (!(user=grant_table->user))
|
if (!(user=grant_table->user))
|
||||||
user="";
|
user="";
|
||||||
@ -3017,21 +3017,21 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
|
|
||||||
if (test_all_bits(grant_table->privs,(TABLE_ACLS & ~GRANT_ACL)))
|
if (test_all_bits(grant_table->privs,(TABLE_ACLS & ~GRANT_ACL)))
|
||||||
global.append("ALL PRIVILEGES",14);
|
global.append("ALL PRIVILEGES",14);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int found=0;
|
int found=0;
|
||||||
ulong j,test_access= (want_access | grant_table->cols) & ~GRANT_ACL;
|
ulong j,test_access= (want_access | grant_table->cols) & ~GRANT_ACL;
|
||||||
|
|
||||||
for (counter=0, j = SELECT_ACL;j <= TABLE_ACLS; counter++,j <<= 1)
|
for (counter=0, j = SELECT_ACL;j <= TABLE_ACLS; counter++,j <<= 1)
|
||||||
{
|
{
|
||||||
if (test_access & j)
|
if (test_access & j)
|
||||||
{
|
{
|
||||||
if (found)
|
if (found)
|
||||||
global.append(", ",2);
|
global.append(", ",2);
|
||||||
found = 1;
|
found = 1;
|
||||||
global.append(command_array[counter],command_lengths[counter]);
|
global.append(command_array[counter],command_lengths[counter]);
|
||||||
|
|
||||||
if (grant_table->cols)
|
if (grant_table->cols)
|
||||||
{
|
{
|
||||||
uint found_col=0;
|
uint found_col=0;
|
||||||
for (uint col_index=0 ;
|
for (uint col_index=0 ;
|
||||||
@ -3040,9 +3040,9 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
{
|
{
|
||||||
GRANT_COLUMN *grant_column = (GRANT_COLUMN*)
|
GRANT_COLUMN *grant_column = (GRANT_COLUMN*)
|
||||||
hash_element(&grant_table->hash_columns,col_index);
|
hash_element(&grant_table->hash_columns,col_index);
|
||||||
if (grant_column->rights & j)
|
if (grant_column->rights & j)
|
||||||
{
|
{
|
||||||
if (!found_col)
|
if (!found_col)
|
||||||
{
|
{
|
||||||
global.append(" (",2);
|
global.append(" (",2);
|
||||||
found_col=1;
|
found_col=1;
|
||||||
@ -3064,12 +3064,12 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
|||||||
global.append(".",1);
|
global.append(".",1);
|
||||||
global.append(grant_table->tname);
|
global.append(grant_table->tname);
|
||||||
global.append(" TO '",5);
|
global.append(" TO '",5);
|
||||||
global.append(lex_user->user.str,lex_user->user.length);
|
global.append(lex_user->user.str,lex_user->user.length);
|
||||||
global.append("'@'",3);
|
global.append("'@'",3);
|
||||||
global.append(lex_user->host.str,lex_user->host.length);
|
global.append(lex_user->host.str,lex_user->host.length);
|
||||||
global.append('\'');
|
global.append('\'');
|
||||||
if (want_access & GRANT_ACL)
|
if (want_access & GRANT_ACL)
|
||||||
global.append(" WITH GRANT OPTION",18);
|
global.append(" WITH GRANT OPTION",18);
|
||||||
thd->packet.length(0);
|
thd->packet.length(0);
|
||||||
net_store_data(&thd->packet,global.ptr(),global.length());
|
net_store_data(&thd->packet,global.ptr(),global.length());
|
||||||
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),
|
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),
|
||||||
|
@ -499,7 +499,10 @@ public:
|
|||||||
uint check_loops_counter; //last id used to check loops
|
uint check_loops_counter; //last id used to check loops
|
||||||
/* variables.transaction_isolation is reset to this after each commit */
|
/* variables.transaction_isolation is reset to this after each commit */
|
||||||
enum_tx_isolation session_tx_isolation;
|
enum_tx_isolation session_tx_isolation;
|
||||||
char scramble[21]; // extend scramble to handle new auth
|
// extend scramble to handle new auth
|
||||||
|
char scramble[SCRAMBLE41_LENGTH+1];
|
||||||
|
// old scramble is needed to handle old clients
|
||||||
|
char old_scramble[SCRAMBLE_LENGTH+1];
|
||||||
uint8 query_cache_type; // type of query cache processing
|
uint8 query_cache_type; // type of query cache processing
|
||||||
bool slave_thread;
|
bool slave_thread;
|
||||||
bool set_query_id,locked,count_cuted_fields,some_tables_deleted;
|
bool set_query_id,locked,count_cuted_fields,some_tables_deleted;
|
||||||
|
247
sql/sql_parse.cc
247
sql/sql_parse.cc
@ -44,8 +44,6 @@
|
|||||||
#else
|
#else
|
||||||
#define MIN_HANDSHAKE_SIZE 6
|
#define MIN_HANDSHAKE_SIZE 6
|
||||||
#endif /* HAVE_OPENSSL */
|
#endif /* HAVE_OPENSSL */
|
||||||
#define SCRAMBLE_LENGTH 8
|
|
||||||
#define SCRAMBLE41_LENGTH 20
|
|
||||||
|
|
||||||
#define MEM_ROOT_BLOCK_SIZE 8192
|
#define MEM_ROOT_BLOCK_SIZE 8192
|
||||||
#define MEM_ROOT_PREALLOC 8192
|
#define MEM_ROOT_PREALLOC 8192
|
||||||
@ -129,7 +127,7 @@ extern pthread_mutex_t LOCK_user_conn;
|
|||||||
|
|
||||||
static int get_or_create_user_conn(THD *thd, const char *user,
|
static int get_or_create_user_conn(THD *thd, const char *user,
|
||||||
const char *host,
|
const char *host,
|
||||||
USER_RESOURCES *mqh)
|
USER_RESOURCES *mqh)
|
||||||
{
|
{
|
||||||
int return_val=0;
|
int return_val=0;
|
||||||
uint temp_len, user_len, host_len;
|
uint temp_len, user_len, host_len;
|
||||||
@ -163,7 +161,7 @@ static int get_or_create_user_conn(THD *thd, const char *user,
|
|||||||
uc->connections = 1;
|
uc->connections = 1;
|
||||||
uc->questions=uc->updates=uc->conn_per_hour=0;
|
uc->questions=uc->updates=uc->conn_per_hour=0;
|
||||||
uc->user_resources=*mqh;
|
uc->user_resources=*mqh;
|
||||||
if (max_user_connections && mqh->connections > max_user_connections)
|
if (max_user_connections && mqh->connections > max_user_connections)
|
||||||
uc->user_resources.connections = max_user_connections;
|
uc->user_resources.connections = max_user_connections;
|
||||||
uc->intime=thd->thr_create_time;
|
uc->intime=thd->thr_create_time;
|
||||||
if (hash_insert(&hash_user_connections, (byte*) uc))
|
if (hash_insert(&hash_user_connections, (byte*) uc))
|
||||||
@ -178,7 +176,7 @@ static int get_or_create_user_conn(THD *thd, const char *user,
|
|||||||
end:
|
end:
|
||||||
(void) pthread_mutex_unlock(&LOCK_user_conn);
|
(void) pthread_mutex_unlock(&LOCK_user_conn);
|
||||||
return return_val;
|
return return_val;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -189,16 +187,16 @@ end:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
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 do_send_error, char* crypted_scramble,int stage,
|
bool do_send_error, char* crypted_scramble,int stage,
|
||||||
bool had_password,uint *cur_priv_version,
|
bool had_password,uint *cur_priv_version,
|
||||||
ACL_USER** hint_user)
|
ACL_USER** hint_user)
|
||||||
{
|
{
|
||||||
thd->db=0;
|
thd->db=0;
|
||||||
thd->db_length=0;
|
thd->db_length=0;
|
||||||
USER_RESOURCES ur;
|
USER_RESOURCES ur;
|
||||||
|
|
||||||
/* We shall avoid dupplicate user allocations here */
|
/* We shall avoid dupplicate user allocations here */
|
||||||
if (!(thd->user))
|
if (!(thd->user))
|
||||||
if (!(thd->user = my_strdup(user, MYF(0))))
|
if (!(thd->user = my_strdup(user, MYF(0))))
|
||||||
{
|
{
|
||||||
@ -211,15 +209,15 @@ static int check_user(THD *thd,enum_server_command command, const char *user,
|
|||||||
!(thd->client_capabilities &
|
!(thd->client_capabilities &
|
||||||
CLIENT_LONG_PASSWORD),&ur,crypted_scramble,
|
CLIENT_LONG_PASSWORD),&ur,crypted_scramble,
|
||||||
stage,cur_priv_version,hint_user);
|
stage,cur_priv_version,hint_user);
|
||||||
|
|
||||||
DBUG_PRINT("info",
|
DBUG_PRINT("info",
|
||||||
("Capabilities: %d packet_length: %d Host: '%s' User: '%s' Using password: %s Access: %u db: '%s'",
|
("Capabilities: %d packet_length: %d Host: '%s' User: '%s' Using password: %s Access: %u db: '%s'",
|
||||||
thd->client_capabilities, thd->max_client_packet_length,
|
thd->client_capabilities, thd->max_client_packet_length,
|
||||||
thd->host_or_ip, thd->priv_user,
|
thd->host_or_ip, thd->priv_user,
|
||||||
had_password ? "yes": "no",
|
had_password ? "yes": "no",
|
||||||
thd->master_access, thd->db ? thd->db : "*none*"));
|
thd->master_access, thd->db ? thd->db : "*none*"));
|
||||||
|
|
||||||
/* in case we're going to retry we should not send error message at this point */
|
/* in case we're going to retry we should not send error message at this point */
|
||||||
if (thd->master_access & NO_ACCESS)
|
if (thd->master_access & NO_ACCESS)
|
||||||
{
|
{
|
||||||
if (do_send_error)
|
if (do_send_error)
|
||||||
@ -233,11 +231,11 @@ 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
|
return(1); // Error already given
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return(-1); // do not report error in special handshake
|
return(-1); // do not report error in special handshake
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_count)
|
if (check_count)
|
||||||
{
|
{
|
||||||
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
||||||
@ -262,16 +260,16 @@ static int check_user(THD *thd,enum_server_command command, const char *user,
|
|||||||
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;
|
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;
|
return -1;
|
||||||
|
|
||||||
if (db && db[0])
|
if (db && db[0])
|
||||||
{
|
{
|
||||||
bool error=test(mysql_change_db(thd,db));
|
bool 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;
|
return error;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
send_ok(thd); // Ready to handle questions
|
send_ok(thd); // Ready to handle questions
|
||||||
@ -296,7 +294,7 @@ extern "C" void free_user(struct user_conn *uc)
|
|||||||
my_free((char*) uc,MYF(0));
|
my_free((char*) uc,MYF(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_max_user_conn(void)
|
void init_max_user_conn(void)
|
||||||
{
|
{
|
||||||
(void) hash_init(&hash_user_connections,system_charset_info,max_connections,
|
(void) hash_init(&hash_user_connections,system_charset_info,max_connections,
|
||||||
0,0,
|
0,0,
|
||||||
@ -309,7 +307,7 @@ static int check_for_max_user_connections(THD *thd, USER_CONN *uc)
|
|||||||
{
|
{
|
||||||
int error=0;
|
int error=0;
|
||||||
DBUG_ENTER("check_for_max_user_connections");
|
DBUG_ENTER("check_for_max_user_connections");
|
||||||
|
|
||||||
if (max_user_connections &&
|
if (max_user_connections &&
|
||||||
(max_user_connections <= (uint) uc->connections))
|
(max_user_connections <= (uint) uc->connections))
|
||||||
{
|
{
|
||||||
@ -317,7 +315,7 @@ static int check_for_max_user_connections(THD *thd, USER_CONN *uc)
|
|||||||
error=1;
|
error=1;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
uc->connections++;
|
uc->connections++;
|
||||||
if (uc->user_resources.connections &&
|
if (uc->user_resources.connections &&
|
||||||
uc->conn_per_hour++ >= uc->user_resources.connections)
|
uc->conn_per_hour++ >= uc->user_resources.connections)
|
||||||
{
|
{
|
||||||
@ -441,7 +439,7 @@ static void reset_mqh(THD *thd, LEX_USER *lu, bool get_them=false)
|
|||||||
{
|
{
|
||||||
|
|
||||||
(void) pthread_mutex_lock(&LOCK_user_conn);
|
(void) pthread_mutex_lock(&LOCK_user_conn);
|
||||||
if (lu) // for GRANT
|
if (lu) // for GRANT
|
||||||
{
|
{
|
||||||
USER_CONN *uc;
|
USER_CONN *uc;
|
||||||
uint temp_len=lu->user.length+lu->host.length+2;
|
uint temp_len=lu->user.length+lu->host.length+2;
|
||||||
@ -530,9 +528,9 @@ check_connections(THD *thd)
|
|||||||
ulong pkt_len=0;
|
ulong pkt_len=0;
|
||||||
{
|
{
|
||||||
/* buff[] needs to big enough to hold the server_version variable */
|
/* buff[] needs to big enough to hold the server_version variable */
|
||||||
char buff[SERVER_VERSION_LENGTH +
|
char buff[SERVER_VERSION_LENGTH +
|
||||||
SCRAMBLE_LENGTH+64],*end;
|
SCRAMBLE_LENGTH+64],*end;
|
||||||
int client_flags = CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB |
|
int client_flags = CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB |
|
||||||
CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION;
|
CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION;
|
||||||
|
|
||||||
if (opt_using_transactions)
|
if (opt_using_transactions)
|
||||||
@ -555,7 +553,7 @@ check_connections(THD *thd)
|
|||||||
int2store(end+3,thd->server_status);
|
int2store(end+3,thd->server_status);
|
||||||
bzero(end+5,13);
|
bzero(end+5,13);
|
||||||
end+=18;
|
end+=18;
|
||||||
|
|
||||||
// At this point we write connection message and read reply
|
// At this point we write connection message and read reply
|
||||||
if (net_write_command(net,(uchar) protocol_version, "", 0, buff,
|
if (net_write_command(net,(uchar) protocol_version, "", 0, buff,
|
||||||
(uint) (end-buff)) ||
|
(uint) (end-buff)) ||
|
||||||
@ -588,7 +586,7 @@ check_connections(THD *thd)
|
|||||||
DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
|
DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
|
||||||
pkt_len));
|
pkt_len));
|
||||||
inc_host_errors(&thd->remote.sin_addr);
|
inc_host_errors(&thd->remote.sin_addr);
|
||||||
return(ER_HANDSHAKE_ERROR);
|
return(ER_HANDSHAKE_ERROR);
|
||||||
}
|
}
|
||||||
DBUG_PRINT("info", ("Reading user information over SSL layer"));
|
DBUG_PRINT("info", ("Reading user information over SSL layer"));
|
||||||
if ((pkt_len=my_net_read(net)) == packet_error ||
|
if ((pkt_len=my_net_read(net)) == packet_error ||
|
||||||
@ -615,81 +613,73 @@ check_connections(THD *thd)
|
|||||||
char *user= (char*) net->read_pos+5;
|
char *user= (char*) net->read_pos+5;
|
||||||
char *passwd= strend(user)+1;
|
char *passwd= strend(user)+1;
|
||||||
char *db=0;
|
char *db=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 (passwd[0] && strlen(passwd)!=SCRAMBLE_LENGTH)
|
||||||
return ER_HANDSHAKE_ERROR;
|
return ER_HANDSHAKE_ERROR;
|
||||||
|
|
||||||
if (thd->client_capabilities & CLIENT_INTERACTIVE)
|
if (thd->client_capabilities & CLIENT_INTERACTIVE)
|
||||||
thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout;
|
thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout;
|
||||||
if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
|
if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
|
||||||
opt_using_transactions)
|
opt_using_transactions)
|
||||||
thd->net.return_status= &thd->server_status;
|
thd->net.return_status= &thd->server_status;
|
||||||
net->read_timeout=(uint) thd->variables.net_read_timeout;
|
net->read_timeout=(uint) thd->variables.net_read_timeout;
|
||||||
|
|
||||||
char prepared_scramble[SCRAMBLE41_LENGTH+4]; /* Buffer for scramble and hash */
|
char prepared_scramble[SCRAMBLE41_LENGTH+4]; /* Buffer for scramble and hash */
|
||||||
|
|
||||||
ACL_USER* cached_user;
|
ACL_USER* cached_user;
|
||||||
uint cur_priv_version;
|
uint cur_priv_version;
|
||||||
|
|
||||||
/* 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 */
|
/* Store information if we used password. passwd will be dammaged */
|
||||||
bool using_password=test(passwd[0]);
|
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 (check_user(thd,COM_CONNECT, user, passwd, db, 1, simple_connect,
|
||||||
prepared_scramble,0,using_password,&cur_priv_version,&cached_user)<0)
|
prepared_scramble,0,using_password,&cur_priv_version,&cached_user)<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;
|
||||||
|
|
||||||
/* 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]=0;
|
||||||
if (user)
|
if (user)
|
||||||
{
|
strmake(tmp_user,user,USERNAME_LENGTH);
|
||||||
strncpy(tmp_user,user,USERNAME_LENGTH+1);
|
|
||||||
/* Extra safety if we have too long data */
|
tmp_db[0]=0;
|
||||||
tmp_user[USERNAME_LENGTH]=0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
tmp_user[0]=0;
|
|
||||||
if (db)
|
if (db)
|
||||||
{
|
strmake(tmp_db,db,NAME_LEN);
|
||||||
strncpy(tmp_db,db,NAME_LEN+1);
|
|
||||||
tmp_db[NAME_LEN]=0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
tmp_db[0]=0;
|
|
||||||
|
|
||||||
/* Write hash and encrypted scramble to client */
|
/* Write hash and encrypted scramble to client */
|
||||||
if (my_net_write(net,prepared_scramble,SCRAMBLE41_LENGTH+4)
|
if (my_net_write(net,prepared_scramble,SCRAMBLE41_LENGTH+4)
|
||||||
|| net_flush(net))
|
|| net_flush(net))
|
||||||
{
|
|
||||||
inc_host_errors(&thd->remote.sin_addr);
|
|
||||||
return ER_HANDSHAKE_ERROR;
|
|
||||||
}
|
|
||||||
/* Reading packet back */
|
|
||||||
if ((pkt_len=my_net_read(net)) == packet_error)
|
|
||||||
{
|
{
|
||||||
inc_host_errors(&thd->remote.sin_addr);
|
inc_host_errors(&thd->remote.sin_addr);
|
||||||
return ER_HANDSHAKE_ERROR;
|
return ER_HANDSHAKE_ERROR;
|
||||||
}
|
}
|
||||||
/* We have to get very specific packet size */
|
/* Reading packet back */
|
||||||
if (pkt_len!=SCRAMBLE41_LENGTH)
|
if ((pkt_len=my_net_read(net)) == packet_error)
|
||||||
{
|
{
|
||||||
inc_host_errors(&thd->remote.sin_addr);
|
inc_host_errors(&thd->remote.sin_addr);
|
||||||
return ER_HANDSHAKE_ERROR;
|
return ER_HANDSHAKE_ERROR;
|
||||||
}
|
}
|
||||||
/* Final attempt to check the user based on reply */
|
/* We have to get very specific packet size */
|
||||||
if (check_user(thd,COM_CONNECT, tmp_user, (char*)net->read_pos,
|
if (pkt_len!=SCRAMBLE41_LENGTH)
|
||||||
|
{
|
||||||
|
inc_host_errors(&thd->remote.sin_addr);
|
||||||
|
return ER_HANDSHAKE_ERROR;
|
||||||
|
}
|
||||||
|
/* Final attempt to check the user based on reply */
|
||||||
|
if (check_user(thd,COM_CONNECT, tmp_user, (char*)net->read_pos,
|
||||||
tmp_db, 1, 1,prepared_scramble,1,using_password,&cur_priv_version,
|
tmp_db, 1, 1,prepared_scramble,1,using_password,&cur_priv_version,
|
||||||
&cached_user))
|
&cached_user))
|
||||||
return -1;
|
return -1;
|
||||||
@ -796,7 +786,7 @@ pthread_handler_decl(handle_one_connection,arg)
|
|||||||
send_error(thd,net->last_errno,NullS);
|
send_error(thd,net->last_errno,NullS);
|
||||||
statistic_increment(aborted_threads,&LOCK_status);
|
statistic_increment(aborted_threads,&LOCK_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
end_thread:
|
end_thread:
|
||||||
close_connection(net);
|
close_connection(net);
|
||||||
end_thread(thd,1);
|
end_thread(thd,1);
|
||||||
@ -854,7 +844,7 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg)
|
|||||||
while (fgets(buff, thd->net.max_packet, file))
|
while (fgets(buff, thd->net.max_packet, file))
|
||||||
{
|
{
|
||||||
uint length=(uint) strlen(buff);
|
uint length=(uint) strlen(buff);
|
||||||
while (length && (my_isspace(system_charset_info, buff[length-1]) ||
|
while (length && (my_isspace(system_charset_info, buff[length-1]) ||
|
||||||
buff[length-1] == ';'))
|
buff[length-1] == ';'))
|
||||||
length--;
|
length--;
|
||||||
buff[length]=0;
|
buff[length]=0;
|
||||||
@ -1043,7 +1033,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
char *user= (char*) packet;
|
char *user= (char*) packet;
|
||||||
char *passwd= strend(user)+1;
|
char *passwd= strend(user)+1;
|
||||||
char *db= strend(passwd)+1;
|
char *db= strend(passwd)+1;
|
||||||
|
|
||||||
/* Save user and privileges */
|
/* Save user and privileges */
|
||||||
uint save_master_access=thd->master_access;
|
uint save_master_access=thd->master_access;
|
||||||
uint save_db_access= thd->db_access;
|
uint save_db_access= thd->db_access;
|
||||||
@ -1055,43 +1045,46 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
USER_CONN *save_uc= thd->user_connect;
|
USER_CONN *save_uc= thd->user_connect;
|
||||||
bool simple_connect;
|
bool simple_connect;
|
||||||
bool using_password;
|
bool using_password;
|
||||||
|
|
||||||
ulong pkt_len=0; /* Length of reply packet */
|
ulong pkt_len=0; /* Length of reply packet */
|
||||||
|
|
||||||
/* 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)
|
||||||
goto restore_user_err;
|
goto restore_user_err;
|
||||||
|
|
||||||
/* Now we shall basically perform authentication again */
|
/* Now we shall basically perform authentication again */
|
||||||
|
|
||||||
/* 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 (passwd[0] && strlen(passwd)!=SCRAMBLE_LENGTH)
|
||||||
goto restore_user_err;
|
goto restore_user_err;
|
||||||
|
|
||||||
char prepared_scramble[SCRAMBLE41_LENGTH+4];/* Buffer for scramble,hash */
|
char prepared_scramble[SCRAMBLE41_LENGTH+4];/* Buffer for scramble,hash */
|
||||||
ACL_USER* cached_user; /* Cached user */
|
ACL_USER* cached_user; /* Cached user */
|
||||||
uint cur_priv_version; /* Cached grant version */
|
uint cur_priv_version; /* Cached grant version */
|
||||||
|
|
||||||
/* Simple connect only for old clients. New clients always use sec. auth*/
|
/* Simple connect only for old clients. New clients always use sec. auth*/
|
||||||
simple_connect=(!(thd->client_capabilities & CLIENT_SECURE_CONNECTION));
|
simple_connect=(!(thd->client_capabilities & CLIENT_SECURE_CONNECTION));
|
||||||
|
|
||||||
/* Store information if we used password. passwd will be dammaged */
|
/* Store information if we used password. passwd will be dammaged */
|
||||||
using_password=test(passwd[0]);
|
using_password=test(passwd[0]);
|
||||||
|
|
||||||
/*
|
if (simple_connect) /* Restore scramble for old clients */
|
||||||
Check user permissions. If password failure we'll get scramble back
|
memcpy(thd->scramble,thd->old_scramble,9);
|
||||||
Do not retry if we already have sent error (result>0)
|
|
||||||
*/
|
/*
|
||||||
|
Check user permissions. If password failure we'll get scramble back
|
||||||
|
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 (check_user(thd,COM_CHANGE_USER, user, passwd, db, 0, simple_connect,
|
||||||
prepared_scramble,0,using_password,&cur_priv_version,&cached_user)<0)
|
prepared_scramble,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 */
|
||||||
|
|
||||||
char tmp_user[USERNAME_LENGTH+1];
|
char tmp_user[USERNAME_LENGTH+1];
|
||||||
char tmp_db[NAME_LEN+1];
|
char tmp_db[NAME_LEN+1];
|
||||||
|
|
||||||
@ -1099,33 +1092,33 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
{
|
{
|
||||||
strncpy(tmp_user,user,USERNAME_LENGTH+1);
|
strncpy(tmp_user,user,USERNAME_LENGTH+1);
|
||||||
/* Extra safety if we have too long data */
|
/* Extra safety if we have too long data */
|
||||||
tmp_user[USERNAME_LENGTH]=0;
|
tmp_user[USERNAME_LENGTH]=0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tmp_user[0]=0;
|
tmp_user[0]=0;
|
||||||
if (db)
|
if (db)
|
||||||
{
|
{
|
||||||
strncpy(tmp_db,db,NAME_LEN+1);
|
strncpy(tmp_db,db,NAME_LEN+1);
|
||||||
tmp_db[NAME_LEN]=0;
|
tmp_db[NAME_LEN]=0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tmp_db[0]=0;
|
tmp_db[0]=0;
|
||||||
|
|
||||||
/* Write hash and encrypted scramble to client */
|
/* Write hash and encrypted scramble to client */
|
||||||
if (my_net_write(net,prepared_scramble,SCRAMBLE41_LENGTH+4)
|
if (my_net_write(net,prepared_scramble,SCRAMBLE41_LENGTH+4)
|
||||||
|| net_flush(net))
|
|| net_flush(net))
|
||||||
goto restore_user_err;
|
|
||||||
|
|
||||||
/* Reading packet back */
|
|
||||||
if ((pkt_len=my_net_read(net)) == packet_error)
|
|
||||||
goto restore_user_err;
|
goto restore_user_err;
|
||||||
|
|
||||||
/* We have to get very specific packet size */
|
/* Reading packet back */
|
||||||
if (pkt_len!=SCRAMBLE41_LENGTH)
|
if ((pkt_len=my_net_read(net)) == packet_error)
|
||||||
|
goto restore_user_err;
|
||||||
|
|
||||||
|
/* We have to get very specific packet size */
|
||||||
|
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_CONNECT, tmp_user, (char*)net->read_pos,
|
if (check_user(thd,COM_CONNECT, tmp_user, (char*)net->read_pos,
|
||||||
tmp_db, 0, 1,prepared_scramble,1,using_password,&cur_priv_version,
|
tmp_db, 0, 1,prepared_scramble,1,using_password,&cur_priv_version,
|
||||||
&cached_user))
|
&cached_user))
|
||||||
goto restore_user;
|
goto restore_user;
|
||||||
@ -1137,11 +1130,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
x_free((gptr) save_user);
|
x_free((gptr) save_user);
|
||||||
thd->password=using_password;
|
thd->password=using_password;
|
||||||
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);
|
||||||
x_free(thd->db);
|
x_free(thd->db);
|
||||||
@ -1150,10 +1143,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
thd->db=save_db;
|
thd->db=save_db;
|
||||||
thd->db_length=save_db_length;
|
thd->db_length=save_db_length;
|
||||||
thd->user=save_user;
|
thd->user=save_user;
|
||||||
thd->priv_user=save_priv_user;
|
thd->priv_user=save_priv_user;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case COM_EXECUTE:
|
case COM_EXECUTE:
|
||||||
{
|
{
|
||||||
mysql_stmt_execute(thd, packet);
|
mysql_stmt_execute(thd, packet);
|
||||||
@ -1444,7 +1437,7 @@ bool alloc_query(THD *thd, char *packet, ulong packet_length)
|
|||||||
packet_length--;
|
packet_length--;
|
||||||
}
|
}
|
||||||
char *pos=packet+packet_length; // Point at end null
|
char *pos=packet+packet_length; // Point at end null
|
||||||
while (packet_length > 0 &&
|
while (packet_length > 0 &&
|
||||||
(pos[-1] == ';' || my_isspace(system_charset_info,pos[-1])))
|
(pos[-1] == ';' || my_isspace(system_charset_info,pos[-1])))
|
||||||
{
|
{
|
||||||
pos--;
|
pos--;
|
||||||
@ -1496,7 +1489,7 @@ mysql_execute_command(THD *thd)
|
|||||||
|
|
||||||
if (thd->slave_thread)
|
if (thd->slave_thread)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Skip if we are in the slave thread, some table rules have been
|
Skip if we are in the slave thread, some table rules have been
|
||||||
given and the table list says the query should not be replicated
|
given and the table list says the query should not be replicated
|
||||||
*/
|
*/
|
||||||
@ -1515,7 +1508,7 @@ mysql_execute_command(THD *thd)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: make derived tables processing 'inside' SELECT processing.
|
TODO: make derived tables processing 'inside' SELECT processing.
|
||||||
TODO: solve problem with depended derived tables in subselects
|
TODO: solve problem with depended derived tables in subselects
|
||||||
@ -1532,13 +1525,13 @@ mysql_execute_command(THD *thd)
|
|||||||
(SELECT_LEX_UNIT *)
|
(SELECT_LEX_UNIT *)
|
||||||
cursor->derived,
|
cursor->derived,
|
||||||
cursor)))
|
cursor)))
|
||||||
{
|
{
|
||||||
if (res < 0 || thd->net.report_error)
|
if (res < 0 || thd->net.report_error)
|
||||||
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0);
|
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0);
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((&lex->select_lex != lex->all_selects_list &&
|
if ((&lex->select_lex != lex->all_selects_list &&
|
||||||
lex->unit.create_total_list(thd, lex, &tables)) ||
|
lex->unit.create_total_list(thd, lex, &tables)) ||
|
||||||
(table_rules_on && tables && thd->slave_thread &&
|
(table_rules_on && tables && thd->slave_thread &&
|
||||||
!tables_ok(thd,tables)))
|
!tables_ok(thd,tables)))
|
||||||
@ -1568,7 +1561,7 @@ mysql_execute_command(THD *thd)
|
|||||||
unit->offset_limit_cnt= (ha_rows) unit->global_parameters->offset_limit;
|
unit->offset_limit_cnt= (ha_rows) unit->global_parameters->offset_limit;
|
||||||
unit->select_limit_cnt= (ha_rows) (unit->global_parameters->select_limit+
|
unit->select_limit_cnt= (ha_rows) (unit->global_parameters->select_limit+
|
||||||
unit->global_parameters->offset_limit);
|
unit->global_parameters->offset_limit);
|
||||||
if (unit->select_limit_cnt <
|
if (unit->select_limit_cnt <
|
||||||
(ha_rows) unit->global_parameters->select_limit)
|
(ha_rows) unit->global_parameters->select_limit)
|
||||||
unit->select_limit_cnt= HA_POS_ERROR; // no limit
|
unit->select_limit_cnt= HA_POS_ERROR; // no limit
|
||||||
if (unit->select_limit_cnt == HA_POS_ERROR)
|
if (unit->select_limit_cnt == HA_POS_ERROR)
|
||||||
@ -1714,7 +1707,7 @@ mysql_execute_command(THD *thd)
|
|||||||
res = show_binlog_info(thd);
|
res = show_binlog_info(thd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SQLCOM_LOAD_MASTER_DATA: // sync with master
|
case SQLCOM_LOAD_MASTER_DATA: // sync with master
|
||||||
if (check_global_access(thd, SUPER_ACL))
|
if (check_global_access(thd, SUPER_ACL))
|
||||||
goto error;
|
goto error;
|
||||||
@ -1723,7 +1716,7 @@ mysql_execute_command(THD *thd)
|
|||||||
else
|
else
|
||||||
res = load_master_data(thd);
|
res = load_master_data(thd);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef HAVE_INNOBASE_DB
|
#ifdef HAVE_INNOBASE_DB
|
||||||
case SQLCOM_SHOW_INNODB_STATUS:
|
case SQLCOM_SHOW_INNODB_STATUS:
|
||||||
{
|
{
|
||||||
@ -1899,7 +1892,7 @@ mysql_execute_command(THD *thd)
|
|||||||
select_lex->db=tables->db;
|
select_lex->db=tables->db;
|
||||||
if (check_access(thd,ALTER_ACL,tables->db,&tables->grant.privilege) ||
|
if (check_access(thd,ALTER_ACL,tables->db,&tables->grant.privilege) ||
|
||||||
check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv) ||
|
check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv) ||
|
||||||
check_merge_table_access(thd, tables->db,
|
check_merge_table_access(thd, tables->db,
|
||||||
(TABLE_LIST *)
|
(TABLE_LIST *)
|
||||||
lex->create_info.merge_list.first))
|
lex->create_info.merge_list.first))
|
||||||
goto error; /* purecov: inspected */
|
goto error; /* purecov: inspected */
|
||||||
@ -1981,7 +1974,7 @@ mysql_execute_command(THD *thd)
|
|||||||
res = show_binlogs(thd);
|
res = show_binlogs(thd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
case SQLCOM_SHOW_CREATE:
|
case SQLCOM_SHOW_CREATE:
|
||||||
#ifdef DONT_ALLOW_SHOW_COMMANDS
|
#ifdef DONT_ALLOW_SHOW_COMMANDS
|
||||||
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
|
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
|
||||||
@ -2611,7 +2604,7 @@ mysql_execute_command(THD *thd)
|
|||||||
if (user->password.str &&
|
if (user->password.str &&
|
||||||
(strcmp(thd->user,user->user.str) ||
|
(strcmp(thd->user,user->user.str) ||
|
||||||
user->host.str &&
|
user->host.str &&
|
||||||
my_strcasecmp(system_charset_info,
|
my_strcasecmp(system_charset_info,
|
||||||
user->host.str, thd->host_or_ip)))
|
user->host.str, thd->host_or_ip)))
|
||||||
{
|
{
|
||||||
if (check_access(thd, UPDATE_ACL, "mysql",0,1))
|
if (check_access(thd, UPDATE_ACL, "mysql",0,1))
|
||||||
@ -3012,7 +3005,7 @@ mysql_init_query(THD *thd)
|
|||||||
lex->select_lex.init_query();
|
lex->select_lex.init_query();
|
||||||
lex->value_list.empty();
|
lex->value_list.empty();
|
||||||
lex->param_list.empty();
|
lex->param_list.empty();
|
||||||
lex->unit.global_parameters= lex->unit.slave= lex->current_select=
|
lex->unit.global_parameters= lex->unit.slave= lex->current_select=
|
||||||
lex->all_selects_list= &lex->select_lex;
|
lex->all_selects_list= &lex->select_lex;
|
||||||
lex->select_lex.master= &lex->unit;
|
lex->select_lex.master= &lex->unit;
|
||||||
lex->select_lex.prev= &lex->unit.slave;
|
lex->select_lex.prev= &lex->unit.slave;
|
||||||
@ -3020,7 +3013,7 @@ mysql_init_query(THD *thd)
|
|||||||
lex->select_lex.link_prev= (st_select_lex_node**)&(lex->all_selects_list);
|
lex->select_lex.link_prev= (st_select_lex_node**)&(lex->all_selects_list);
|
||||||
lex->olap=lex->describe=0;
|
lex->olap=lex->describe=0;
|
||||||
lex->derived_tables= false;
|
lex->derived_tables= false;
|
||||||
thd->check_loops_counter= thd->select_number=
|
thd->check_loops_counter= thd->select_number=
|
||||||
lex->select_lex.select_number= 1;
|
lex->select_lex.select_number= 1;
|
||||||
thd->free_list= 0;
|
thd->free_list= 0;
|
||||||
thd->total_warn_count=0; // Warnings for this query
|
thd->total_warn_count=0; // Warnings for this query
|
||||||
@ -3037,7 +3030,7 @@ mysql_init_select(LEX *lex)
|
|||||||
SELECT_LEX *select_lex= lex->current_select->select_lex();
|
SELECT_LEX *select_lex= lex->current_select->select_lex();
|
||||||
DBUG_ASSERT(select_lex->linkage != GLOBAL_OPTIONS_TYPE);
|
DBUG_ASSERT(select_lex->linkage != GLOBAL_OPTIONS_TYPE);
|
||||||
select_lex->init_select();
|
select_lex->init_select();
|
||||||
select_lex->master_unit()->select_limit= select_lex->select_limit=
|
select_lex->master_unit()->select_limit= select_lex->select_limit=
|
||||||
lex->thd->variables.select_limit;
|
lex->thd->variables.select_limit;
|
||||||
lex->exchange= 0;
|
lex->exchange= 0;
|
||||||
lex->result= 0;
|
lex->result= 0;
|
||||||
@ -3067,7 +3060,7 @@ mysql_new_select(LEX *lex, bool move_down)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
select_lex->include_neighbour(lex->current_select);
|
select_lex->include_neighbour(lex->current_select);
|
||||||
|
|
||||||
select_lex->master_unit()->global_parameters= select_lex;
|
select_lex->master_unit()->global_parameters= select_lex;
|
||||||
DBUG_ASSERT(lex->current_select->linkage != GLOBAL_OPTIONS_TYPE);
|
DBUG_ASSERT(lex->current_select->linkage != GLOBAL_OPTIONS_TYPE);
|
||||||
select_lex->include_global((st_select_lex_node**)&lex->all_selects_list);
|
select_lex->include_global((st_select_lex_node**)&lex->all_selects_list);
|
||||||
@ -3577,10 +3570,10 @@ TABLE_LIST *st_select_lex::add_table_to_list(Table_ident *table,
|
|||||||
if (!alias) /* Alias is case sensitive */
|
if (!alias) /* Alias is case sensitive */
|
||||||
if (!(alias_str=thd->memdup(alias_str,table->table.length+1)))
|
if (!(alias_str=thd->memdup(alias_str,table->table.length+1)))
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
|
if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
|
||||||
DBUG_RETURN(0); /* purecov: inspected */
|
DBUG_RETURN(0); /* purecov: inspected */
|
||||||
if (table->db.str)
|
if (table->db.str)
|
||||||
{
|
{
|
||||||
ptr->db= table->db.str;
|
ptr->db= table->db.str;
|
||||||
ptr->db_length= table->db.length;
|
ptr->db_length= table->db.length;
|
||||||
@ -3596,7 +3589,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(Table_ident *table,
|
|||||||
ptr->db= empty_c_string;
|
ptr->db= empty_c_string;
|
||||||
ptr->db_length= 0;
|
ptr->db_length= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr->alias= alias_str;
|
ptr->alias= alias_str;
|
||||||
if (lower_case_table_names)
|
if (lower_case_table_names)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user