summaryrefslogtreecommitdiff
path: root/sql/sql_acl.cc
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2013-01-25 11:24:42 +0100
committerSergei Golubchik <sergii@pisem.net>2013-01-25 11:24:42 +0100
commit672b293860318b290374757f9b6a7f90b8942570 (patch)
tree6e1b4784e1d01890a1f9c5e3b88fe54ee773ba6b /sql/sql_acl.cc
parent32151409c13ddc09ebda7cd02fdfe40db290503e (diff)
parentde10e214115ecc89087386ecad8bddee2a1e1608 (diff)
downloadmariadb-git-672b293860318b290374757f9b6a7f90b8942570.tar.gz
5.3 merge
client/mysqltest.cc: make --error to work for --change_user errors
Diffstat (limited to 'sql/sql_acl.cc')
-rw-r--r--sql/sql_acl.cc50
1 files changed, 42 insertions, 8 deletions
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index f38f29898d3..04d797b3ba1 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -7987,6 +7987,7 @@ struct MPVIO_EXT :public MYSQL_PLUGIN_VIO
} cached_server_packet;
int packets_read, packets_written; ///< counters for send/received packets
uint connect_errors; ///< if there were connect errors for this host
+ bool make_it_fail;
/** when plugin returns a failure this tells us what really happened */
enum { SUCCESS, FAILURE, RESTART } status;
};
@@ -8252,14 +8253,14 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio,
/**
Finds acl entry in user database for authentication purposes.
- Finds a user and copies it into mpvio. Reports an authentication
- failure if a user is not found.
+ Finds a user and copies it into mpvio. Creates a fake user
+ if no matching user account is found.
@note find_acl_user is not the same, because it doesn't take into
account the case when user is not empty, but acl_user->user is empty
@retval 0 found
- @retval 1 not found
+ @retval 1 error
*/
static bool find_mpvio_user(MPVIO_EXT *mpvio)
{
@@ -8282,8 +8283,27 @@ static bool find_mpvio_user(MPVIO_EXT *mpvio)
if (!mpvio->acl_user)
{
- login_failed_error(mpvio->thd);
- DBUG_RETURN (1);
+ /*
+ A matching user was not found. Fake it. Take any user, make the
+ authentication fail later.
+ This way we get a realistically looking failure, with occasional
+ "change auth plugin" requests even for nonexistent users. The ratio
+ of "change auth plugin" request will be the same for real and
+ nonexistent users.
+ Note, that we cannot pick any user at random, it must always be
+ the same user account for the incoming sctx->user name.
+ */
+ ulong nr1=1, nr2=4;
+ CHARSET_INFO *cs= &my_charset_latin1;
+ cs->coll->hash_sort(cs, (uchar*) sctx->user, strlen(sctx->user), &nr1, &nr2);
+
+ mysql_mutex_lock(&acl_cache->lock);
+ uint i= nr1 % acl_users.elements;
+ ACL_USER *acl_user_tmp= dynamic_element(&acl_users, i, ACL_USER*);
+ mpvio->acl_user= acl_user_tmp->copy(mpvio->thd->mem_root);
+ mysql_mutex_unlock(&acl_cache->lock);
+
+ mpvio->make_it_fail= true;
}
/* user account requires non-default plugin and the client is too old */
@@ -8410,6 +8430,7 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length)
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ thd->password= passwd_len > 0;
if (find_mpvio_user(mpvio))
DBUG_RETURN(1);
@@ -8705,8 +8726,8 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
mpvio->cached_server_packet.pkt_len))
return packet_error;
- passwd_len= my_net_read(&mpvio->thd->net);
- passwd= (char*)mpvio->thd->net.read_pos;
+ passwd_len= my_net_read(&thd->net);
+ passwd= (char*)thd->net.read_pos;
}
*buff= (uchar*) passwd;
@@ -8808,6 +8829,10 @@ static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf)
*buf= (uchar*) mpvio->cached_client_reply.pkt;
mpvio->cached_client_reply.pkt= 0;
mpvio->packets_read++;
+
+ if (mpvio->make_it_fail)
+ goto err;
+
DBUG_RETURN ((int) mpvio->cached_client_reply.pkt_len);
}
@@ -8842,6 +8867,9 @@ static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf)
else
*buf= mpvio->thd->net.read_pos;
+ if (mpvio->make_it_fail)
+ goto err;
+
DBUG_RETURN((int)pkt_len);
err:
@@ -8849,7 +8877,12 @@ err:
{
inc_host_errors(mpvio->thd->security_ctx->ip);
if (!mpvio->thd->is_error())
- my_error(ER_HANDSHAKE_ERROR, MYF(0));
+ {
+ if (mpvio->make_it_fail)
+ login_failed_error(mpvio->thd);
+ else
+ my_error(ER_HANDSHAKE_ERROR, MYF(0));
+ }
}
DBUG_RETURN(-1);
}
@@ -9054,6 +9087,7 @@ bool acl_authenticate(THD *thd, uint connect_errors,
mpvio.thd= thd;
mpvio.connect_errors= connect_errors;
mpvio.status= MPVIO_EXT::FAILURE;
+ mpvio.make_it_fail= false;
mpvio.auth_info.host_or_ip= thd->security_ctx->host_or_ip;
mpvio.auth_info.host_or_ip_length=
(unsigned int) strlen(thd->security_ctx->host_or_ip);