diff options
author | Harin Vadodaria <harin.vadodaria@oracle.com> | 2012-09-17 17:02:17 +0530 |
---|---|---|
committer | Harin Vadodaria <harin.vadodaria@oracle.com> | 2012-09-17 17:02:17 +0530 |
commit | 9d007e075d6b933df9dbd1a42d52ab00ee91827c (patch) | |
tree | f93a212d0e2ebb9df7496d6770ad8f758c446060 /sql/sql_connect.cc | |
parent | 5cbdb908270a052284155cd5b7eff7eacb177218 (diff) | |
download | mariadb-git-9d007e075d6b933df9dbd1a42d52ab00ee91827c.tar.gz |
Bug#11753779: MAX_CONNECT_ERRORS WORKS ONLY WHEN 1ST
INC_HOST_ERRORS() IS CALLED.
Issue : Sequence of calling inc_host_errors()
and reset_host_errors() required some
changes in order to maintain correct
connection error count.
Solution : Call to reset_host_errors() is shifted
to a location after which no calls to
inc_host_errors() are made.
Diffstat (limited to 'sql/sql_connect.cc')
-rw-r--r-- | sql/sql_connect.cc | 68 |
1 files changed, 60 insertions, 8 deletions
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 21e2701d06c..e7aa48c94f5 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -336,6 +336,7 @@ check_user(THD *thd, enum enum_server_command command, USER_RESOURCES ur; int res= acl_getroot(thd, &ur, passwd, passwd_len); + DBUG_EXECUTE_IF("password_format_mismatch",{res= -1;};); #ifndef EMBEDDED_LIBRARY if (res == -1) { @@ -346,6 +347,12 @@ check_user(THD *thd, enum enum_server_command command, in old format. */ NET *net= &thd->net; + DBUG_EXECUTE_IF("password_format_mismatch", + { + inc_host_errors(&thd->remote.sin_addr); + my_error(ER_HANDSHAKE_ERROR, MYF(0)); + DBUG_RETURN(1); + };); if (opt_secure_auth_local) { my_error(ER_SERVER_IS_IN_SECURE_AUTH_MODE, MYF(0), @@ -816,6 +823,8 @@ static int check_connection(THD *thd) size_t passwd_len; char *user; size_t user_len; + uint charset_code= 0; + size_t bytes_remaining_in_packet= 0; DBUG_PRINT("info", ("New connection received on %s", vio_description(net->vio))); @@ -832,6 +841,19 @@ static int check_connection(THD *thd) my_error(ER_BAD_HOST_ERROR, MYF(0)); return 1; } + /* BEGIN : DEBUG */ + DBUG_EXECUTE_IF("addr_fake_ipv4", + { + struct sockaddr *sa= (sockaddr *) &net->vio->remote; + sa->sa_family= AF_INET; + struct in_addr *ip4= &((struct sockaddr_in *)sa)->sin_addr; + /* See RFC 5737, 192.0.2.0/23 is reserved */ + const char* fake= "192.0.2.4"; + ip4->s_addr= inet_addr(fake); + strcpy(ip, fake); + };); + /* END : DEBUG */ + if (!(thd->main_security_ctx.ip= my_strdup(ip,MYF(MY_WME)))) return 1; /* The error is set by my_strdup(). */ thd->main_security_ctx.host_or_ip= thd->main_security_ctx.ip; @@ -927,32 +949,31 @@ static int check_connection(THD *thd) (uchar*) buff, (size_t) (end-buff)) || (pkt_len= my_net_read(net)) == packet_error) { - inc_host_errors(&thd->remote.sin_addr); - my_error(ER_HANDSHAKE_ERROR, MYF(0)); - return 1; + goto error; } } #ifdef _CUSTOMCONFIG_ #include "_cust_sql_parse.h" #endif - if (connect_errors) - reset_host_errors(&thd->remote.sin_addr); if (thd->packet.alloc(thd->variables.net_buffer_length)) return 1; /* The error is set by alloc(). */ - uint charset_code= 0; end= (char *)net->read_pos; /* In order to safely scan a head for '\0' string terminators we must keep track of how many bytes remain in the allocated buffer or we might read past the end of the buffer. */ - size_t bytes_remaining_in_packet= pkt_len; + bytes_remaining_in_packet= pkt_len; /* Peek ahead on the client capability packet and determine which version of the protocol should be used. */ + DBUG_EXECUTE_IF("host_error_packet_length", + { + bytes_remaining_in_packet= 0; + };); if (bytes_remaining_in_packet < 2) goto error; @@ -1011,6 +1032,10 @@ static int check_connection(THD *thd) skip_to_ssl: + DBUG_EXECUTE_IF("host_error_charset", + { + goto error; + };); DBUG_PRINT("info", ("client_character_set: %u", charset_code)); if (thd_init_client_charset(thd, charset_code)) goto error; @@ -1079,6 +1104,10 @@ skip_to_ssl: bytes_remaining_in_packet -= AUTH_PACKET_HEADER_SIZE_PROTO_40; } + DBUG_EXECUTE_IF("host_error_SSL_layering", + { + packet_has_required_size= 0; + };); if (!packet_has_required_size) goto error; } @@ -1104,6 +1133,11 @@ skip_to_ssl: get_string= get_40_protocol_string; user= get_string(&end, &bytes_remaining_in_packet, &user_len); + DBUG_EXECUTE_IF("host_error_user", + { + user= NULL; + };); + if (user == NULL) goto error; @@ -1131,6 +1165,11 @@ skip_to_ssl: passwd= get_string(&end, &bytes_remaining_in_packet, &passwd_len); } + DBUG_EXECUTE_IF("host_error_password", + { + passwd= NULL; + };); + if (passwd == NULL) goto error; @@ -1191,7 +1230,20 @@ skip_to_ssl: if (!(thd->main_security_ctx.user= my_strdup(user, MYF(MY_WME)))) return 1; /* The error is set by my_strdup(). */ - return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE); + + if (!check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE)) + { + /* + Call to reset_host_errors() should be made only when all sanity checks + are done and connection is going to be a successful. + */ + reset_host_errors(&thd->remote.sin_addr); + return 0; + } + else + { + return 1; + } error: inc_host_errors(&thd->remote.sin_addr); |