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