summaryrefslogtreecommitdiff
path: root/sql/sql_parse.cc
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2013-01-25 00:17:39 +0100
committerSergei Golubchik <sergii@pisem.net>2013-01-25 00:17:39 +0100
commitbfc71e63a77972fa4ab934855b6ab712bea323a1 (patch)
treedee331666634538a0855e3f0a3674285b2978b10 /sql/sql_parse.cc
parent8127e631de90dddc25b3cdffe59e147333eb6c74 (diff)
downloadmariadb-git-bfc71e63a77972fa4ab934855b6ab712bea323a1.tar.gz
MDEV-3915 COM_CHANGE_USER allows fast password brute-forcing
allow only three failed change_user per connection. successful change_user do NOT reset the counter tests/mysql_client_test.c: make --error to work for --change_user errors
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r--sql/sql_parse.cc17
1 files changed, 16 insertions, 1 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index be0e2db43c6..0c47b7a8bb3 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1144,6 +1144,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
uint save_db_length= thd->db_length;
char *save_db= thd->db;
+ int rc;
USER_CONN *save_user_connect= thd->user_connect;
Security_context save_security_ctx= *thd->security_ctx;
CHARSET_INFO *save_character_set_client=
@@ -1157,7 +1158,19 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->security_ctx->user= 0;
thd->user_connect= 0;
- if (acl_authenticate(thd, 0, packet_length))
+ /*
+ to limit COM_CHANGE_USER ability to brute-force passwords,
+ we only allow three unsuccessful COM_CHANGE_USER per connection.
+ */
+ if (thd->failed_com_change_user >= 3)
+ {
+ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
+ rc= 1;
+ }
+ else
+ rc= acl_authenticate(thd, 0, packet_length);
+
+ if (rc)
{
/* Free user if allocated by acl_authenticate */
x_free(thd->security_ctx->user);
@@ -1170,6 +1183,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->variables.collation_connection= save_collation_connection;
thd->variables.character_set_results= save_character_set_results;
thd->update_charset();
+ thd->failed_com_change_user++;
+ my_sleep(1000000);
}
else
{