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
a2425837
Commit
a2425837
authored
Nov 30, 2002
by
peter@mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
SCRUM: Montymise code
fix mysql_change_user() for old clients
parent
54ff0efe
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
388 additions
and
377 deletions
+388
-377
include/mysql_com.h
include/mysql_com.h
+6
-0
libmysql/libmysql.c
libmysql/libmysql.c
+130
-127
scripts/mysql_fix_privilege_tables.sh
scripts/mysql_fix_privilege_tables.sh
+9
-1
sql/mini_client.cc
sql/mini_client.cc
+11
-10
sql/mysqld.cc
sql/mysqld.cc
+3
-0
sql/password.c
sql/password.c
+23
-29
sql/sql_acl.cc
sql/sql_acl.cc
+85
-85
sql/sql_class.h
sql/sql_class.h
+4
-1
sql/sql_parse.cc
sql/sql_parse.cc
+117
-124
No files found.
include/mysql_com.h
View file @
a2425837
...
...
@@ -29,6 +29,7 @@
#define LOCAL_HOST "localhost"
#define LOCAL_HOST_NAMEDPIPE "."
#if defined(__WIN__) && !defined( _CUSTOMCONFIG_)
#define MYSQL_NAMEDPIPE "MySQL"
#define MYSQL_SERVICENAME "MySql"
...
...
@@ -44,6 +45,11 @@ enum enum_server_command
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 PRI_KEY_FLAG 2
/* Field is part of a primary key */
#define UNIQUE_KEY_FLAG 4
/* Field is part of a unique key */
...
...
libmysql/libmysql.c
View file @
a2425837
...
...
@@ -232,9 +232,9 @@ my_bool my_connect(my_socket s, const struct sockaddr *name,
FD_ZERO
(
&
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
* 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
* failure to reflect the time remaining
*/
...
...
@@ -346,23 +346,23 @@ 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
net Pointer of net structure
connect_timeout Timeout of connection
*/
#ifdef HAVE_SMEM
HANDLE
create_shared_memory
(
MYSQL
*
mysql
,
NET
*
net
,
uint
connect_timeout
)
{
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
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_map is pointer on shared memory for client
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_read
=
NULL
;
HANDLE
handle_file_map
=
NULL
;
ulong
connect_number
;
ulong
connect_number
;
char
connect_number_char
[
22
],
*
p
;
char
tmp
[
64
];
char
*
suffix_pos
;
char
*
suffix_pos
;
DWORD
error_allow
=
0
;
DWORD
error_code
=
0
;
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
);
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
;
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
))
==
NULL
)
{
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
))
==
NULL
)
{
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
)))
==
NULL
)
{
error_allow
=
CR_SHARED_MEMORY_CONNECT_MAP_ERROR
;
goto
err
;
...
...
@@ -424,7 +424,7 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
/*
Send to server request of connection
*/
if
(
!
SetEvent
(
event_connect_request
))
if
(
!
SetEvent
(
event_connect_request
))
{
error_allow
=
CR_SHARED_MEMORY_CONNECT_SET_ERROR
;
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
)
{
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
)
{
...
...
@@ -496,13 +496,13 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
*/
SetEvent
(
event_server_read
);
err2:
if
(
error_allow
==
0
)
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
);
}
else
event_server_read
,
event_client_wrote
,
event_client_read
);
}
else
{
error_code
=
GetLastError
();
if
(
event_server_read
)
CloseHandle
(
event_server_read
);
...
...
@@ -518,7 +518,7 @@ err:
if
(
event_connect_answer
)
CloseHandle
(
event_connect_answer
);
if
(
handle_connect_map
)
UnmapViewOfFile
(
handle_connect_map
);
if
(
handle_connect_file_map
)
CloseHandle
(
handle_connect_file_map
);
if
(
error_allow
)
if
(
error_allow
)
{
net
->
last_errno
=
error_allow
;
if
(
error_allow
==
CR_SHARED_MEMORY_EVENT_ERROR
)
...
...
@@ -526,7 +526,7 @@ err:
else
sprintf
(
net
->
last_error
,
ER
(
net
->
last_errno
),
error_code
);
return
(
INVALID_HANDLE_VALUE
);
}
}
return
(
handle_map
);
};
#endif
...
...
@@ -554,7 +554,7 @@ net_safe_read(MYSQL *mysql)
DBUG_PRINT
(
"error"
,(
"Wrong connection or packet. fd: %s len: %d"
,
vio_description
(
net
->
vio
),
len
));
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_SERVER_LOST
);
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
));
options
->
shared_memory_base_name
=
my_strdup
(
opt_arg
,
MYF
(
MY_WME
));
#endif
break
;
break
;
default:
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
->
length
=
(
uint
)
uint3korr
(
row
->
data
[
2
]);
field
->
type
=
(
enum
enum_field_types
)
(
uchar
)
row
->
data
[
3
][
0
];
if
(
server_capabilities
&
CLIENT_LONG_FLAG
)
{
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
,
unsigned
long
length
)
{
...
...
@@ -1391,7 +1391,7 @@ void STDCALL mysql_disable_rpl_parse(MYSQL* mysql)
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
)
{
return
mysql
->
options
.
rpl_parse
;
...
...
@@ -1408,7 +1408,7 @@ void STDCALL mysql_disable_reads_from_master(MYSQL* mysql)
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
)
{
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
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
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
*/
if
(
mysql_query
(
mysql
,
"SHOW SLAVE STATUS"
)
||
...
...
@@ -1602,7 +1602,7 @@ STDCALL mysql_rpl_query_type(const char* q, int len)
case
'a'
:
/* alter */
return
MYSQL_RPL_MASTER
;
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
;
case
's'
:
/* select or show */
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
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
(
!
((
mysql
)
->
client_flag
&
CLIENT_IGNORE_SIGPIPE
))
(
void
)
signal
(
SIGPIPE
,
pipe_sig_handler
);
...
...
@@ -1658,7 +1658,7 @@ mysql_init(MYSQL *mysql)
#endif
#ifdef HAVE_SMEM
mysql
->
options
.
shared_memory_base_name
=
(
char
*
)
def_shared_memory_base_name
;
#endif
#endif
return
mysql
;
}
...
...
@@ -1716,9 +1716,9 @@ static void mysql_once_init()
my_bool
STDCALL
mysql_ssl_set
(
MYSQL
*
mysql
__attribute__
((
unused
))
,
const
char
*
key
__attribute__
((
unused
)),
const
char
*
key
__attribute__
((
unused
)),
const
char
*
cert
__attribute__
((
unused
)),
const
char
*
ca
__attribute__
((
unused
)),
const
char
*
ca
__attribute__
((
unused
)),
const
char
*
capath
__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
*
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
;
uint32
ip_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
)
&&
(
!
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
)
{
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
)
have_tcpip
));
if
(
mysql
->
options
.
protocol
==
MYSQL_PROTOCOL_MEMORY
)
goto
error
;
/*
goto
error
;
/*
Try also with PIPE or TCP/IP
*/
}
}
else
{
mysql
->
options
.
protocol
=
MYSQL_PROTOCOL_MEMORY
;
...
...
@@ -1935,9 +1935,9 @@ Try also with PIPE or TCP/IP
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
goto
error
;
/*
Try also with TCP/IP
*/
}
else
...
...
@@ -2028,7 +2028,7 @@ Try also with PIPE or TCP/IP
vio_poll_read
(
net
->
vio
,
mysql
->
options
.
connect_timeout
))
{
net
->
last_errno
=
CR_SERVER_LOST
;
strmov
(
net
->
last_error
,
ER
(
net
->
last_errno
));
strmov
(
net
->
last_error
,
ER
(
net
->
last_errno
));
goto
error
;
}
if
((
pkt_length
=
net_safe_read
(
mysql
))
==
packet_error
)
...
...
@@ -2100,7 +2100,7 @@ Try also with PIPE or TCP/IP
}
goto
error
;
}
/* Save connection information */
if
(
!
user
)
user
=
""
;
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
))
{
net
->
last_errno
=
CR_SERVER_LOST
;
strmov
(
net
->
last_error
,
ER
(
net
->
last_errno
));
strmov
(
net
->
last_error
,
ER
(
net
->
last_errno
));
goto
error
;
}
/* Do the SSL layering. */
...
...
@@ -2192,7 +2192,7 @@ Try also with PIPE or TCP/IP
options
->
ssl_cipher
)))
{
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
;
}
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
;
strmov
(
net
->
last_error
,
ER
(
net
->
last_errno
));
goto
error
;
goto
error
;
}
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 */
else
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_
#include "_cust_libmysql.h";
#endif
...
...
@@ -2232,7 +2232,7 @@ Try also with PIPE or TCP/IP
end
=
scramble
(
strend
(
buff
+
5
)
+
1
,
mysql
->
scramble_buff
,
"
\1
~MySQL#!
\2
"
,
(
my_bool
)
(
mysql
->
protocol_version
==
9
));
}
else
/* For empty password*/
else
/* For empty password*/
{
end
=
strend
(
buff
+
5
)
+
1
;
*
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
,
(
my_bool
)
(
mysql
->
protocol_version
==
9
));
/* Add database if needed */
/* Add database if needed */
if
(
db
&&
(
mysql
->
server_capabilities
&
CLIENT_CONNECT_WITH_DB
))
{
end
=
strmake
(
end
+
1
,
db
,
NAME_LEN
);
mysql
->
db
=
my_strdup
(
db
,
MYF
(
MY_WME
));
db
=
0
;
}
/* Write authentication package */
/* Write authentication package */
if
(
my_net_write
(
net
,
buff
,(
ulong
)
(
end
-
buff
))
||
net_flush
(
net
))
{
net
->
last_errno
=
CR_SERVER_LOST
;
strmov
(
net
->
last_error
,
ER
(
net
->
last_errno
));
net
->
last_errno
=
CR_SERVER_LOST
;
strmov
(
net
->
last_error
,
ER
(
net
->
last_errno
));
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
)
goto
error
;
...
...
@@ -2269,46 +2269,47 @@ Try also with PIPE or TCP/IP
if
(
pkt_length
==
24
)
/* We have new hash back */
{
/* 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 */
password_hash_stage1
(
buff
,
passwd
);
/* 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
,
20
);
memcpy
(
password_hash
,
buff
,
SCRAMBLE41_LENGTH
);
/* Finally hash complete password using hash we got from server */
password_hash_stage2
(
password_hash
,
net
->
read_pos
);
/* Decypt and store scramble 4 = hash for stage2 */
password_crypt
(
net
->
read_pos
+
4
,
mysql
->
scramble_buff
,
password_hash
,
20
);
mysql
->
scramble_buff
[
20
]
=
0
;
password_crypt
(
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
,
20
);
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
(
net
->
read_pos
+
4
,
mysql
->
scramble_buff
,
password_hash
,
20
);
mysql
->
scramble_buff
[
20
]
=
0
;
/* Finally scramble decoded scramble with password */
scramble
(
buff
,
mysql
->
scramble_buff
,
passwd
,
(
my_bool
)
(
mysql
->
protocol_version
==
9
));
}
password_crypt
(
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
,
20
)
||
net_flush
(
net
))
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
));
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 */
/* 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 */
/* End of authentication part of handshake */
if
(
client_flag
&
CLIENT_COMPRESS
)
/* We will use compression */
net
->
compress
=
1
;
if
(
db
&&
mysql_select_db
(
mysql
,
db
))
...
...
@@ -2395,7 +2396,7 @@ static my_bool mysql_reconnect(MYSQL *mysql)
mysql
->
free_me
=
0
;
mysql_close
(
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
);
mysql
->
affected_rows
=
~
(
my_ulonglong
)
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
)
{
char
buff
[
512
],
*
end
=
buff
;
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
;
DBUG_ENTER
(
"mysql_change_user"
);
if
(
!
user
)
user
=
""
;
if
(
!
passwd
)
passwd
=
""
;
/* Store user into the buffer */
end
=
strmov
(
end
,
user
)
+
1
;
/*
/*
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
*/
...
...
@@ -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 */
end
=
scramble
(
end
,
mysql
->
scramble_buff
,
"
\1
~MySQL#!
\2
"
,
(
my_bool
)
(
mysql
->
protocol_version
==
9
));
}
else
/* For empty password*/
(
my_bool
)
(
mysql
->
protocol_version
==
9
));
}
else
/* For empty password*/
*
end
=
0
;
/* Store zero length scramble */
}
/* Real scramble is sent only for servers. This is to be blocked by option */
else
end
=
scramble
(
end
,
mysql
->
scramble_buff
,
passwd
,
(
my_bool
)
(
mysql
->
protocol_version
==
9
));
/* Add database if needed */
/* Add database if needed */
end
=
strmov
(
end
+
1
,
db
?
db
:
""
);
/* Write authentication package */
/* 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 */
/* We shall only query sever if it expect us to do so */
if
(
(
pkt_length
=
net_safe_read
(
mysql
))
==
packet_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 */
{
/* 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 */
password_hash_stage1
(
buff
,
passwd
);
/* 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
,
20
);
memcpy
(
password_hash
,
buff
,
SCRAMBLE41_LENGTH
);
/* Finally hash complete password using hash we got from server */
password_hash_stage2
(
password_hash
,
net
->
read_pos
);
/* Decypt and store scramble 4 = hash for stage2 */
password_crypt
(
net
->
read_pos
+
4
,
mysql
->
scramble_buff
,
password_hash
,
20
);
mysql
->
scramble_buff
[
20
]
=
0
;
password_crypt
(
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
,
20
);
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
(
net
->
read_pos
+
4
,
mysql
->
scramble_buff
,
password_hash
,
20
);
mysql
->
scramble_buff
[
20
]
=
0
;
/* Finally scramble decoded scramble with password */
password_crypt
(
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
));
}
(
my_bool
)
(
mysql
->
protocol_version
==
9
));
}
/* 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
;
strmov
(
net
->
last_error
,
ER
(
net
->
last_errno
));
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 */
/* Read What server thinks about out new auth message report */
if
(
net_safe_read
(
mysql
)
==
packet_error
)
goto
error
;
}
}
my_free
(
mysql
->
user
,
MYF
(
MY_ALLOW_ZERO_PTR
));
my_free
(
mysql
->
passwd
,
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
->
db
=
db
?
my_strdup
(
db
,
MYF
(
MY_WME
))
:
0
;
DBUG_RETURN
(
0
);
error:
DBUG_RETURN
(
1
);
}
...
...
@@ -2598,7 +2601,7 @@ mysql_close(MYSQL *mysql)
{
next_element
=
element
->
next
;
stmt_close
((
MYSQL_STMT
*
)
element
->
data
,
0
);
}
}
}
if
(
mysql
!=
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.
Needs to be followed by mysql_read_query_result() when we want to
finish processing it.
*/
*/
int
STDCALL
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_PRINT
(
"enter"
,(
"type: %d, buffer:%lx, length: %d"
,
param
->
buffer_type
,
param
->
buffer
?
param
->
buffer
:
"0"
,
*
param
->
length
));
if
(
param
->
is_null
||
param
->
buffer_type
==
MYSQL_TYPE_NULL
)
store_param_null
(
net
,
param
);
else
{
/* Allocate for worst case (long string) */
/* Allocate for worst case (long string) */
if
((
my_realloc_str
(
net
,
9
+
*
param
->
length
)))
DBUG_RETURN
(
1
);
(
*
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
);
DBUG_RETURN
(
1
);
}
/*
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
*/
if
(
!
param
->
length
)
param
->
length
=
&
param
->
bind_length
;
/* Setup data copy functions for the different supported types */
switch
(
param
->
buffer_type
)
{
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
)
{
short
value
=
*
(
short
*
)
row
;
int2store
(
param
->
buffer
,
value
);
int2store
(
param
->
buffer
,
value
);
*
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
),
param
->
buffer_type
,
param
->
param_number
);
DBUG_RETURN
(
1
);
}
}
if
(
!
param
->
length
)
param
->
length
=
&
param
->
bind_length
;
}
...
...
@@ -4479,10 +4482,10 @@ stmt_fetch_row(MYSQL_STMT *stmt, uchar **row)
{
MYSQL_BIND
*
bind
,
*
end
;
uchar
*
null_ptr
=
(
uchar
*
)
*
row
,
bit
;
*
row
+=
(
stmt
->
field_count
+
7
)
/
8
;
*
row
+=
(
stmt
->
field_count
+
7
)
/
8
;
bit
=
1
;
/* Copy complete row to application buffers */
for
(
bind
=
stmt
->
bind
,
end
=
(
MYSQL_BIND
*
)
bind
+
stmt
->
field_count
;
bind
<
end
;
...
...
@@ -4505,7 +4508,7 @@ stmt_fetch_row(MYSQL_STMT *stmt, uchar **row)
}
static
int
read_binary_data
(
MYSQL
*
mysql
)
{
{
if
(
packet_error
==
net_safe_read
(
mysql
))
return
-
1
;
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
(
0
);
}
DBUG_PRINT
(
"info"
,
(
"end of data"
));
DBUG_PRINT
(
"info"
,
(
"end of data"
));
mysql
->
status
=
MYSQL_STATUS_READY
;
if
(
res
<
0
)
/* Network error */
{
set_stmt_errmsg
(
stmt
,(
char
*
)
mysql
->
net
.
last_error
,
...
...
scripts/mysql_fix_privilege_tables.sh
View file @
a2425837
...
...
@@ -170,12 +170,20 @@ fi
@bindir@/mysql
-f
--user
=
root
--password
=
"
$root_password
"
--host
=
"
$host
"
mysql
<<
END_OF_DATA
alter table user
change password password char(45) not null,
add max_questions int(11) NOT NULL AFTER x509_subject,
add max_updates int(11) unsigned NOT NULL AFTER max_questions,
add max_connections int(11) unsigned NOT NULL AFTER max_updates;
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
#
...
...
sql/mini_client.cc
View file @
a2425837
...
...
@@ -490,7 +490,7 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
uint
net_read_timeout
)
{
char
buff
[
NAME_LEN
+
USERNAME_LENGTH
+
100
],
*
end
,
*
host_info
;
char
password_hash
[
20
];
char
password_hash
[
SCRAMBLE41_LENGTH
];
my_socket
sock
;
ulong
ip_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 */
password_hash_stage1
(
buff
,
passwd
);
/* 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 */
password_hash_stage2
(
password_hash
,(
char
*
)
net
->
read_pos
);
/* Decypt and store scramble 4 = hash for stage2 */
password_crypt
((
char
*
)
net
->
read_pos
+
4
,
mysql
->
scramble_buff
,
password_hash
,
20
);
mysql
->
scramble_buff
[
20
]
=
0
;
password_crypt
((
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
,
20
);
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
((
char
*
)
net
->
read_pos
+
4
,
mysql
->
scramble_buff
,
password_hash
,
20
);
mysql
->
scramble_buff
[
20
]
=
0
;
password_crypt
((
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
));
scramble
(
buff
,
mysql
->
scramble_buff
,
passwd
,
0
);
}
/* 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
;
strmov
(
net
->
last_error
,
ER
(
net
->
last_errno
));
...
...
sql/mysqld.cc
View file @
a2425837
...
...
@@ -2496,6 +2496,9 @@ static void create_new_thread(THD *thd)
for
(
uint
i
=
0
;
i
<
8
;
i
++
)
// Generate password teststring
thd
->
scramble
[
i
]
=
(
char
)
(
rnd
(
&
sql_rand
)
*
94
+
33
);
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
...
...
sql/password.c
View file @
a2425837
...
...
@@ -66,7 +66,6 @@
#define PVERSION41_CHAR '*'
/* 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
*/
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
;
while
(
from
<
from_end
)
{
*
to
=*
from
^*
password
;
from
++
;
to
++
;
password
++
;
}
while
(
from
<
from_end
)
*
to
++=
*
(
from
++
)
^*
(
password
++
);
}
...
...
@@ -286,7 +280,9 @@ void password_hash_stage2(char *to,const char *salt)
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 */
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
;
*
res
=
salt
;
res
++
;
bzero
(
res
,
5
*
sizeof
(
res
[
0
]));
/* Process password of known length*/
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
*/
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
tmpsalt
[
8
];
/* Temporary value to convert salt to string form */
int
i
;
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*/
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 */
get_salt_from_bin_password
(
salt_candidate
,
buffer
,
salt
[
0
]);
/* Now we shall get exactly the same password as we have stored for user */
for
(
i
=
1
;
i
<
6
;
i
++
)
if
(
salt
[
i
]
!=
salt_candidate
[
i
])
return
1
;
/* Now we shall get exactly the same password as we have stored for user */
for
(
salt_end
=
salt
+
5
;
salt
<
salt_end
;
)
if
(
*++
salt
!=
*++
sc
)
return
1
;
/* Or password correct*/
return
0
;
}
...
...
@@ -400,11 +399,9 @@ my_bool validate_password(const char* password, const char* message, ulong* salt
password length >0
*/
in
line
in
t
get_password_length
(
my_bool
force_old_scramble
)
int
get_password_length
(
my_bool
force_old_scramble
)
{
if
(
force_old_scramble
)
return
16
;
else
return
SHA1_HASH_SIZE
*
2
+
4
+
1
;
return
(
force_old_scramble
)
?
16
:
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
*/
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
;
return
0
;
}
...
...
@@ -467,7 +464,6 @@ inline uint char_val(char X)
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
[
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 */
{
salt_end
=
salt
+
6
;
salt_end
=
salt
+
5
;
sprintf
(
hash
,
"%04x"
,(
unsigned
short
)
salt
[
0
]);
salt
++
;
/* position to the second element */
while
(
salt
<
salt_end
)
/* Iterate over these elements*/
{
val
=*
salt
;
for
(
t
=
3
;
t
>=
0
;
t
--
)
val
=*
(
++
salt
)
;
for
(
t
=
3
;
t
>=
0
;
t
--
)
{
bin_password
[
t
]
=
val
%
256
;
val
>>=
8
;
/* Scroll 8 bits to get next part*/
}
bin_password
+=
4
;
/* Get to next 4 chars*/
salt
++
;
}
}
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
)
{
char
buffer
[
20
];
/* Buffer for various needs */
char
buffer
[
SCRAMBLE41_LENGTH
];
/* Buffer for various needs */
ulong
salt
[
6
];
/* Salt (large for safety) */
/* At first hash password to the string stored in password */
make_scrambled_password
(
buffer
,
passwd
,
1
,(
struct
rand_struct
*
)
NULL
);
...
...
sql/sql_acl.cc
View file @
a2425837
...
...
@@ -102,10 +102,10 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
if
(
dont_read_acl_tables
)
{
DBUG_RETURN
(
0
);
/* purecov: tested */
}
}
priv_version
++
;
/* Priveleges updated */
/*
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 */
}
}
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
.
sort
=
get_sort
(
2
,
user
.
host
.
hostname
,
user
.
user
);
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
);
end_read_record
(
&
read_record_info
);
freeze_size
(
&
acl_users
);
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
));
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
*/
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*/
char
bin_password
[
20
];
char
bin_password
[
SCRAMBLE41_LENGTH
];
/* Generate new long scramble for the thread */
create_random_string
(
20
,
&
thd
->
rand
,
thd
->
scramble
);
thd
->
scramble
[
20
]
=
0
;
create_random_string
(
SCRAMBLE41_LENGTH
,
&
thd
->
rand
,
thd
->
scramble
);
thd
->
scramble
[
SCRAMBLE41_LENGTH
]
=
0
;
/* 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
);
/* 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).
Required before connecting to MySQL
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;
*/
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
;
bool
password_correct
=
0
;
ACL_USER
*
acl_user
=
NULL
;
DBUG_ENTER
(
"acl_getroot"
);
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 */
}
VOID
(
pthread_mutex_lock
(
&
acl_cache
->
lock
));
/*
Get possible access from user_list. This is or'ed to others not
fully specified
If we have cached user use it, in other case look it up.
*/
if
(
stage
&&
(
*
cur_priv_version
==
priv_version
))
acl_user
=*
hint_user
;
else
else
for
(
uint
i
=
0
;
i
<
acl_users
.
elements
;
i
++
)
{
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
))
{
/* Found mathing user */
/* Found mathing user */
acl_user
=
acl_user_search
;
/* Store it as a cache */
*
hint_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 should present for both or absend for both */
if
(
!
acl_user
->
password
&&
!*
password
||
(
acl_user
->
password
&&
*
password
))
{
{
/* Quick check and accept for empty passwords*/
if
(
!
acl_user
->
password
&&
!*
password
)
password_correct
=
1
;
else
/* Normal password presents */
{
{
/* New version password is checked differently */
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
))
password_correct
=
1
;
}
}
else
/* First stage - just prepare scramble */
prepare_scramble
(
thd
,
acl_user
,
prepared_scramble
);
}
/* 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
,
(
my_bool
)
old_ver
))
password_correct
=
1
;
else
/* Password incorrect */
else
/* Password incorrect */
/* At the first stage - prepare scramble */
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
(
!
password_correct
)
goto
unlock_and_exit
;
if
(
!
password_correct
)
goto
unlock_and_exit
;
/* OK. User found and password checked continue validation */
#ifdef HAVE_OPENSSL
Vio
*
vio
=
thd
->
net
.
vio
;
/*
In this point we know that user is allowed to connect
from given host by given username/password pair. Now
we check if SSL is required, if user is using SSL and
if X509 certificate attributes are OK
In this point we know that user is allowed to connect
from given host by given username/password pair. Now
we check if SSL is required, if user is using SSL and
if X509 certificate attributes are OK
*/
switch
(
acl_user
->
ssl_type
)
{
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
;
case
SSL_TYPE_X509
:
/* Client should have any valid certificate. */
/*
Connections with non-valid certificates are dropped already
in sslaccept() anyway, so we do not check validity here.
Connections with non-valid certificates are dropped already
in sslaccept() anyway, so we do not check validity here.
*/
if
(
SSL_get_peer_certificate
(
vio
->
ssl_
))
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_
);
DBUG_PRINT
(
"info"
,(
"checkpoint 2"
));
/* If X509 issuer is speified, we check it... */
if
(
acl_user
->
x509_issuer
)
if
(
acl_user
->
x509_issuer
)
{
DBUG_PRINT
(
"info"
,(
"checkpoint 3"
));
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
;
if
(
!
acl_user
->
user
)
*
priv_user
=
(
char
*
)
""
;
// Change to anonymous user /* purecov: inspected */
unlock_and_exit:
VOID
(
pthread_mutex_unlock
(
&
acl_cache
->
lock
));
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
,
const
char
*
password
,
const
char
*
password
,
enum
SSL_type
ssl_type
,
const
char
*
ssl_cipher
,
const
char
*
x509_issuer
,
const
char
*
x509_subject
,
USER_RESOURCES
*
mqh
,
USER_RESOURCES
*
mqh
,
ulong
privileges
)
{
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 */
{
acl_user
->
password
=
0
;
acl_user
->
pversion
=
0
;
// just initialize
}
acl_user
->
pversion
=
0
;
// just initialize
}
else
{
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
,
const
char
*
password
,
const
char
*
password
,
enum
SSL_type
ssl_type
,
const
char
*
ssl_cipher
,
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
])
wildstr
++
;
if
(
my_toupper
(
cs
,
*
wildstr
++
)
!=
if
(
my_toupper
(
cs
,
*
wildstr
++
)
!=
my_toupper
(
cs
,
*
str
++
))
DBUG_RETURN
(
1
);
}
if
(
!
*
wildstr
)
DBUG_RETURN
(
*
str
!=
0
);
...
...
@@ -1091,7 +1091,7 @@ bool check_change_password(THD *thd, const char *host, const char *user)
RETURN VALUES
0 ok
1 ERROR; In this case the error is sent to the client.
*/
*/
bool
change_password
(
THD
*
thd
,
const
char
*
host
,
const
char
*
user
,
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 */
length
=
(
uint
)
strlen
(
new_password
);
if
(
length
!=
45
)
new_password
[
length
&
16
]
=
0
;
...
...
@@ -1133,8 +1133,8 @@ bool change_password(THD *thd, const char *host, const char *user,
if
(
!
new_password
[
0
])
acl_user
->
password
=
0
;
else
acl_user
->
password
=
(
char
*
)
""
;
// Point at something
acl_user
->
password
=
(
char
*
)
""
;
// Point at something
acl_cache
->
clear
(
1
);
// Clear locked hostname cache
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
.
length
!=
HASH_PASSWORD_LENGTH
)
if
((
combo
.
password
.
length
!=
HASH_PASSWORD_LENGTH
)
&&
combo
.
password
.
length
!=
HASH_OLD_PASSWORD_LENGTH
)
{
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
;
}
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
->
file
->
index_init
(
0
);
...
...
@@ -1742,9 +1742,9 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip,
}
else
{
if
((
host
&&
!
wild_case_compare
(
system_charset_info
,
if
((
host
&&
!
wild_case_compare
(
system_charset_info
,
host
,
grant_table
->
host
))
||
(
ip
&&
!
wild_case_compare
(
system_charset_info
,
(
ip
&&
!
wild_case_compare
(
system_charset_info
,
ip
,
grant_table
->
host
)))
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
);
if
(
len
<
grant_table
->
key_length
&&
!
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
->
ip
&&
!
wild_case_compare
(
system_charset_info
,
(
thd
->
ip
&&
!
wild_case_compare
(
system_charset_info
,
thd
->
ip
,
grant_table
->
host
))))
{
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
;
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
))
break
;
}
if
(
counter
==
acl_users
.
elements
)
if
(
counter
==
acl_users
.
elements
)
{
my_printf_error
(
ER_NONEXISTING_GRANT
,
ER
(
ER_NONEXISTING_GRANT
),
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
);
else
if
(
!
(
want_access
&
~
GRANT_ACL
))
global
.
append
(
"USAGE"
,
5
);
else
else
{
bool
found
=
0
;
ulong
j
,
test_access
=
want_access
&
~
GRANT_ACL
;
for
(
counter
=
0
,
j
=
SELECT_ACL
;
j
<=
GLOBAL_ACLS
;
counter
++
,
j
<<=
1
)
{
if
(
test_access
&
j
)
if
(
test_access
&
j
)
{
if
(
found
)
global
.
append
(
", "
,
2
);
...
...
@@ -2852,7 +2852,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
}
}
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
(
lex_user
->
host
.
str
,
lex_user
->
host
.
length
);
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
.
connections
))
{
global
.
append
(
" WITH"
,
5
);
global
.
append
(
" WITH"
,
5
);
if
(
want_access
&
GRANT_ACL
)
global
.
append
(
" GRANT OPTION"
,
13
);
global
.
append
(
" GRANT OPTION"
,
13
);
if
(
acl_user
->
user_resource
.
questions
)
{
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
))
{
want_access
=
acl_db
->
access
;
if
(
want_access
)
if
(
want_access
)
{
String
db
(
buff
,
sizeof
(
buff
),
system_charset_info
);
db
.
length
(
0
);
...
...
@@ -2976,10 +2976,10 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
db
.
append
(
" ON `"
,
5
);
db
.
append
(
acl_db
->
db
);
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
(
lex_user
->
host
.
str
,
lex_user
->
host
.
length
);
db
.
append
(
'\''
);
db
.
append
(
'\''
);
if
(
want_access
&
GRANT_ACL
)
db
.
append
(
" WITH GRANT OPTION"
,
18
);
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
++
)
{
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
))
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
)))
global
.
append
(
"ALL PRIVILEGES"
,
14
);
else
else
{
int
found
=
0
;
ulong
j
,
test_access
=
(
want_access
|
grant_table
->
cols
)
&
~
GRANT_ACL
;
for
(
counter
=
0
,
j
=
SELECT_ACL
;
j
<=
TABLE_ACLS
;
counter
++
,
j
<<=
1
)
{
if
(
test_access
&
j
)
if
(
test_access
&
j
)
{
if
(
found
)
global
.
append
(
", "
,
2
);
found
=
1
;
global
.
append
(
command_array
[
counter
],
command_lengths
[
counter
]);
if
(
grant_table
->
cols
)
if
(
grant_table
->
cols
)
{
uint
found_col
=
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
*
)
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
);
found_col
=
1
;
...
...
@@ -3064,12 +3064,12 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
global
.
append
(
"."
,
1
);
global
.
append
(
grant_table
->
tname
);
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
(
lex_user
->
host
.
str
,
lex_user
->
host
.
length
);
global
.
append
(
lex_user
->
host
.
str
,
lex_user
->
host
.
length
);
global
.
append
(
'\''
);
if
(
want_access
&
GRANT_ACL
)
global
.
append
(
" WITH GRANT OPTION"
,
18
);
global
.
append
(
" WITH GRANT OPTION"
,
18
);
thd
->
packet
.
length
(
0
);
net_store_data
(
&
thd
->
packet
,
global
.
ptr
(),
global
.
length
());
if
(
my_net_write
(
&
thd
->
net
,(
char
*
)
thd
->
packet
.
ptr
(),
...
...
sql/sql_class.h
View file @
a2425837
...
...
@@ -499,7 +499,10 @@ public:
uint
check_loops_counter
;
//last id used to check loops
/* variables.transaction_isolation is reset to this after each commit */
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
bool
slave_thread
;
bool
set_query_id
,
locked
,
count_cuted_fields
,
some_tables_deleted
;
...
...
sql/sql_parse.cc
View file @
a2425837
...
...
@@ -44,8 +44,6 @@
#else
#define MIN_HANDSHAKE_SIZE 6
#endif
/* HAVE_OPENSSL */
#define SCRAMBLE_LENGTH 8
#define SCRAMBLE41_LENGTH 20
#define MEM_ROOT_BLOCK_SIZE 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
,
const
char
*
host
,
USER_RESOURCES
*
mqh
)
USER_RESOURCES
*
mqh
)
{
int
return_val
=
0
;
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
->
questions
=
uc
->
updates
=
uc
->
conn_per_hour
=
0
;
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
->
intime
=
thd
->
thr_create_time
;
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:
(
void
)
pthread_mutex_unlock
(
&
LOCK_user_conn
);
return
return_val
;
}
...
...
@@ -189,16 +187,16 @@ end:
*/
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
had_password
,
uint
*
cur_priv_version
,
bool
had_password
,
uint
*
cur_priv_version
,
ACL_USER
**
hint_user
)
{
thd
->
db
=
0
;
thd
->
db_length
=
0
;
USER_RESOURCES
ur
;
/* We shall avoid dupplicate user allocations here */
/* We shall avoid dupplicate user allocations here */
if
(
!
(
thd
->
user
))
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
&
CLIENT_LONG_PASSWORD
),
&
ur
,
crypted_scramble
,
stage
,
cur_priv_version
,
hint_user
);
DBUG_PRINT
(
"info"
,
(
"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
->
host_or_ip
,
thd
->
priv_user
,
had_password
?
"yes"
:
"no"
,
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
(
do_send_error
)
...
...
@@ -233,11 +231,11 @@ 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
}
else
}
else
return
(
-
1
);
// do not report error in special handshake
}
if
(
check_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
)
&&
get_or_create_user_conn
(
thd
,
user
,
thd
->
host_or_ip
,
&
ur
))
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
))
return
-
1
;
if
(
db
&&
db
[
0
])
{
bool
error
=
test
(
mysql_change_db
(
thd
,
db
));
if
(
error
&&
thd
->
user_connect
)
decrease_user_connections
(
thd
->
user_connect
);
return
error
;
return
error
;
}
else
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
));
}
void
init_max_user_conn
(
void
)
void
init_max_user_conn
(
void
)
{
(
void
)
hash_init
(
&
hash_user_connections
,
system_charset_info
,
max_connections
,
0
,
0
,
...
...
@@ -309,7 +307,7 @@ static int check_for_max_user_connections(THD *thd, USER_CONN *uc)
{
int
error
=
0
;
DBUG_ENTER
(
"check_for_max_user_connections"
);
if
(
max_user_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
;
goto
end
;
}
uc
->
connections
++
;
uc
->
connections
++
;
if
(
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
);
if
(
lu
)
// for GRANT
if
(
lu
)
// for GRANT
{
USER_CONN
*
uc
;
uint
temp_len
=
lu
->
user
.
length
+
lu
->
host
.
length
+
2
;
...
...
@@ -530,9 +528,9 @@ check_connections(THD *thd)
ulong
pkt_len
=
0
;
{
/* 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
;
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
;
if
(
opt_using_transactions
)
...
...
@@ -555,7 +553,7 @@ check_connections(THD *thd)
int2store
(
end
+
3
,
thd
->
server_status
);
bzero
(
end
+
5
,
13
);
end
+=
18
;
// At this point we write connection message and read reply
if
(
net_write_command
(
net
,(
uchar
)
protocol_version
,
""
,
0
,
buff
,
(
uint
)
(
end
-
buff
))
||
...
...
@@ -588,7 +586,7 @@ check_connections(THD *thd)
DBUG_PRINT
(
"error"
,
(
"Failed to read user information (pkt_len= %lu)"
,
pkt_len
));
inc_host_errors
(
&
thd
->
remote
.
sin_addr
);
return
(
ER_HANDSHAKE_ERROR
);
return
(
ER_HANDSHAKE_ERROR
);
}
DBUG_PRINT
(
"info"
,
(
"Reading user information over SSL layer"
));
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
*
passwd
=
strend
(
user
)
+
1
;
char
*
db
=
0
;
if
(
thd
->
client_capabilities
&
CLIENT_CONNECT_WITH_DB
)
db
=
strend
(
passwd
)
+
1
;
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
(
passwd
[
0
]
&&
strlen
(
passwd
)
!=
SCRAMBLE_LENGTH
)
return
ER_HANDSHAKE_ERROR
;
if
(
thd
->
client_capabilities
&
CLIENT_INTERACTIVE
)
thd
->
variables
.
net_wait_timeout
=
thd
->
variables
.
net_interactive_timeout
;
if
((
thd
->
client_capabilities
&
CLIENT_TRANSACTIONS
)
&&
opt_using_transactions
)
thd
->
net
.
return_status
=
&
thd
->
server_status
;
net
->
read_timeout
=
(
uint
)
thd
->
variables
.
net_read_timeout
;
char
prepared_scramble
[
SCRAMBLE41_LENGTH
+
4
];
/* Buffer for scramble and hash */
ACL_USER
*
cached_user
;
uint
cur_priv_version
;
/* 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
,
prepared_scramble
,
0
,
using_password
,
&
cur_priv_version
,
&
cached_user
)
<
0
)
{
{
/* If The client is old we just have to return error */
if
(
simple_connect
)
return
-
1
;
return
-
1
;
/* 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
]
=
0
;
if
(
user
)
{
strncpy
(
tmp_user
,
user
,
USERNAME_LENGTH
+
1
);
/* Extra safety if we have too long data */
tmp_user
[
USERNAME_LENGTH
]
=
0
;
}
else
tmp_user
[
0
]
=
0
;
strmake
(
tmp_user
,
user
,
USERNAME_LENGTH
);
tmp_db
[
0
]
=
0
;
if
(
db
)
{
strncpy
(
tmp_db
,
db
,
NAME_LEN
+
1
);
tmp_db
[
NAME_LEN
]
=
0
;
}
else
tmp_db
[
0
]
=
0
;
strmake
(
tmp_db
,
db
,
NAME_LEN
);
/* Write hash and encrypted scramble to client */
if
(
my_net_write
(
net
,
prepared_scramble
,
SCRAMBLE41_LENGTH
+
4
)
||
net_flush
(
net
))
if
(
my_net_write
(
net
,
prepared_scramble
,
SCRAMBLE41_LENGTH
+
4
)
||
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
)
}
/* Reading packet back */
if
((
pkt_len
=
my_net_read
(
net
))
==
packet_error
)
{
inc_host_errors
(
&
thd
->
remote
.
sin_addr
);
return
ER_HANDSHAKE_ERROR
;
}
/* We have to get very specific packet size */
if
(
pkt_len
!=
SCRAMBLE41_LENGTH
)
/* We have to get very specific packet size */
if
(
pkt_len
!=
SCRAMBLE41_LENGTH
)
{
inc_host_errors
(
&
thd
->
remote
.
sin_addr
);
return
ER_HANDSHAKE_ERROR
;
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
,
/* 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
,
&
cached_user
))
return
-
1
;
...
...
@@ -796,7 +786,7 @@ pthread_handler_decl(handle_one_connection,arg)
send_error
(
thd
,
net
->
last_errno
,
NullS
);
statistic_increment
(
aborted_threads
,
&
LOCK_status
);
}
end_thread:
close_connection
(
net
);
end_thread
(
thd
,
1
);
...
...
@@ -854,7 +844,7 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg)
while
(
fgets
(
buff
,
thd
->
net
.
max_packet
,
file
))
{
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
]
==
';'
))
length
--
;
buff
[
length
]
=
0
;
...
...
@@ -1043,7 +1033,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
char
*
user
=
(
char
*
)
packet
;
char
*
passwd
=
strend
(
user
)
+
1
;
char
*
db
=
strend
(
passwd
)
+
1
;
/* Save user and privileges */
uint
save_master_access
=
thd
->
master_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
;
bool
simple_connect
;
bool
using_password
;
ulong
pkt_len
=
0
;
/* Length of reply packet */
/* Small check for incomming packet */
if
((
uint
)
((
uchar
*
)
db
-
net
->
read_pos
)
>
packet_length
)
goto
restore_user_err
;
/* Now we shall basically perform authentication again */
/* 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
;
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 */
uint
cur_priv_version
;
/* Cached grant version */
/* Simple connect only for old clients. New clients always use sec. auth*/
simple_connect
=
(
!
(
thd
->
client_capabilities
&
CLIENT_SECURE_CONNECTION
));
/* Store information if we used password. passwd will be dammaged */
using_password
=
test
(
passwd
[
0
]);
/*
Check user permissions. If password failure we'll get scramble back
Do not retry if we already have sent error (result>0)
*/
if
(
simple_connect
)
/* Restore scramble for old clients */
memcpy
(
thd
->
scramble
,
thd
->
old_scramble
,
9
);
/*
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
,
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
(
simple_connect
)
goto
restore_user
;
/* Error is already reported */
/* Store current used and database as they are erased with next packet */
char
tmp_user
[
USERNAME_LENGTH
+
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
);
/* Extra safety if we have too long data */
tmp_user
[
USERNAME_LENGTH
]
=
0
;
}
tmp_user
[
USERNAME_LENGTH
]
=
0
;
}
else
tmp_user
[
0
]
=
0
;
tmp_user
[
0
]
=
0
;
if
(
db
)
{
strncpy
(
tmp_db
,
db
,
NAME_LEN
+
1
);
tmp_db
[
NAME_LEN
]
=
0
;
}
else
}
else
tmp_db
[
0
]
=
0
;
/* Write hash and encrypted scramble to client */
if
(
my_net_write
(
net
,
prepared_scramble
,
SCRAMBLE41_LENGTH
+
4
)
||
net_flush
(
net
))
goto
restore_user_err
;
/* Reading packet back */
if
((
pkt_len
=
my_net_read
(
net
))
==
packet_error
)
if
(
my_net_write
(
net
,
prepared_scramble
,
SCRAMBLE41_LENGTH
+
4
)
||
net_flush
(
net
))
goto
restore_user_err
;
/* We have to get very specific packet size */
if
(
pkt_len
!=
SCRAMBLE41_LENGTH
)
/* Reading packet back */
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
;
/* Final attempt to check the user based on reply */
if
(
check_user
(
thd
,
COM_CONNECT
,
tmp_user
,
(
char
*
)
net
->
read_pos
,
/* Final attempt to check the user based on reply */
if
(
check_user
(
thd
,
COM_CONNECT
,
tmp_user
,
(
char
*
)
net
->
read_pos
,
tmp_db
,
0
,
1
,
prepared_scramble
,
1
,
using_password
,
&
cur_priv_version
,
&
cached_user
))
goto
restore_user
;
...
...
@@ -1137,11 +1130,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
x_free
((
gptr
)
save_user
);
thd
->
password
=
using_password
;
break
;
/* Bad luck we shall restore old user */
restore_user_err:
send_error
(
thd
,
ER_UNKNOWN_COM_ERROR
);
restore_user:
x_free
(
thd
->
user
);
x_free
(
thd
->
db
);
...
...
@@ -1150,10 +1143,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd
->
db
=
save_db
;
thd
->
db_length
=
save_db_length
;
thd
->
user
=
save_user
;
thd
->
priv_user
=
save_priv_user
;
thd
->
priv_user
=
save_priv_user
;
break
;
}
case
COM_EXECUTE
:
{
mysql_stmt_execute
(
thd
,
packet
);
...
...
@@ -1444,7 +1437,7 @@ bool alloc_query(THD *thd, char *packet, ulong packet_length)
packet_length
--
;
}
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
--
;
...
...
@@ -1496,7 +1489,7 @@ mysql_execute_command(THD *thd)
if
(
thd
->
slave_thread
)
{
/*
/*
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
*/
...
...
@@ -1515,7 +1508,7 @@ mysql_execute_command(THD *thd)
}
#endif
}
/*
TODO: make derived tables processing 'inside' SELECT processing.
TODO: solve problem with depended derived tables in subselects
...
...
@@ -1532,13 +1525,13 @@ mysql_execute_command(THD *thd)
(
SELECT_LEX_UNIT
*
)
cursor
->
derived
,
cursor
)))
{
{
if
(
res
<
0
||
thd
->
net
.
report_error
)
send_error
(
thd
,
thd
->
killed
?
ER_SERVER_SHUTDOWN
:
0
);
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
))
||
(
table_rules_on
&&
tables
&&
thd
->
slave_thread
&&
!
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
->
select_limit_cnt
=
(
ha_rows
)
(
unit
->
global_parameters
->
select_limit
+
unit
->
global_parameters
->
offset_limit
);
if
(
unit
->
select_limit_cnt
<
if
(
unit
->
select_limit_cnt
<
(
ha_rows
)
unit
->
global_parameters
->
select_limit
)
unit
->
select_limit_cnt
=
HA_POS_ERROR
;
// no limit
if
(
unit
->
select_limit_cnt
==
HA_POS_ERROR
)
...
...
@@ -1714,7 +1707,7 @@ mysql_execute_command(THD *thd)
res
=
show_binlog_info
(
thd
);
break
;
}
case
SQLCOM_LOAD_MASTER_DATA
:
// sync with master
if
(
check_global_access
(
thd
,
SUPER_ACL
))
goto
error
;
...
...
@@ -1723,7 +1716,7 @@ mysql_execute_command(THD *thd)
else
res
=
load_master_data
(
thd
);
break
;
#ifdef HAVE_INNOBASE_DB
case
SQLCOM_SHOW_INNODB_STATUS
:
{
...
...
@@ -1899,7 +1892,7 @@ mysql_execute_command(THD *thd)
select_lex
->
db
=
tables
->
db
;
if
(
check_access
(
thd
,
ALTER_ACL
,
tables
->
db
,
&
tables
->
grant
.
privilege
)
||
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
*
)
lex
->
create_info
.
merge_list
.
first
))
goto
error
;
/* purecov: inspected */
...
...
@@ -1981,7 +1974,7 @@ mysql_execute_command(THD *thd)
res
=
show_binlogs
(
thd
);
break
;
}
#endif
#endif
case
SQLCOM_SHOW_CREATE
:
#ifdef DONT_ALLOW_SHOW_COMMANDS
send_error
(
thd
,
ER_NOT_ALLOWED_COMMAND
);
/* purecov: inspected */
...
...
@@ -2611,7 +2604,7 @@ mysql_execute_command(THD *thd)
if
(
user
->
password
.
str
&&
(
strcmp
(
thd
->
user
,
user
->
user
.
str
)
||
user
->
host
.
str
&&
my_strcasecmp
(
system_charset_info
,
my_strcasecmp
(
system_charset_info
,
user
->
host
.
str
,
thd
->
host_or_ip
)))
{
if
(
check_access
(
thd
,
UPDATE_ACL
,
"mysql"
,
0
,
1
))
...
...
@@ -3012,7 +3005,7 @@ mysql_init_query(THD *thd)
lex
->
select_lex
.
init_query
();
lex
->
value_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
->
select_lex
.
master
=
&
lex
->
unit
;
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
->
olap
=
lex
->
describe
=
0
;
lex
->
derived_tables
=
false
;
thd
->
check_loops_counter
=
thd
->
select_number
=
thd
->
check_loops_counter
=
thd
->
select_number
=
lex
->
select_lex
.
select_number
=
1
;
thd
->
free_list
=
0
;
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
();
DBUG_ASSERT
(
select_lex
->
linkage
!=
GLOBAL_OPTIONS_TYPE
);
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
->
exchange
=
0
;
lex
->
result
=
0
;
...
...
@@ -3067,7 +3060,7 @@ mysql_new_select(LEX *lex, bool move_down)
}
else
select_lex
->
include_neighbour
(
lex
->
current_select
);
select_lex
->
master_unit
()
->
global_parameters
=
select_lex
;
DBUG_ASSERT
(
lex
->
current_select
->
linkage
!=
GLOBAL_OPTIONS_TYPE
);
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_str
=
thd
->
memdup
(
alias_str
,
table
->
table
.
length
+
1
)))
DBUG_RETURN
(
0
);
if
(
!
(
ptr
=
(
TABLE_LIST
*
)
thd
->
calloc
(
sizeof
(
TABLE_LIST
))))
DBUG_RETURN
(
0
);
/* purecov: inspected */
if
(
table
->
db
.
str
)
if
(
table
->
db
.
str
)
{
ptr
->
db
=
table
->
db
.
str
;
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_length
=
0
;
}
ptr
->
alias
=
alias_str
;
if
(
lower_case_table_names
)
{
...
...
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