#At file:///home/kgeorge/mysql/work/wl1054-next-mr/ based on revid:georgi.kodinov@stripped
2971 Georgi Kodinov 2010-07-30
WL1054: Addressed code review remarks.
* Taken out the thd object from the mpvio and used mpvio for encapsulation of
state data.
* Fixed a memory leak in handling the external user variable
modified:
include/mysql/plugin_auth.h
sql/sql_acl.cc
sql/sql_audit.h
sql/sql_class.cc
sql/sql_connect.cc
sql/sql_connect.h
=== modified file 'include/mysql/plugin_auth.h'
--- a/include/mysql/plugin_auth.h 2010-06-04 10:51:12 +0000
+++ b/include/mysql/plugin_auth.h 2010-07-30 15:43:16 +0000
@@ -39,7 +39,7 @@ typedef struct st_mysql_server_auth_info
User name as sent by the client and shown in USER().
NULL if the client packet with the user name was not received yet.
*/
- const char *user_name;
+ char *user_name;
/**
Length of user_name
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2010-07-26 09:08:37 +0000
+++ b/sql/sql_acl.cc 2010-07-30 15:43:16 +0000
@@ -7772,6 +7772,23 @@ get_cached_table_access(GRANT_INTERNAL_I
#define sslaccept(A,B,C) 1
#endif
+
+class Thd_charset_adapter
+{
+ THD *thd;
+public:
+ Thd_charset_adapter(THD *thd_arg) : thd (thd_arg) {}
+ bool init_client_charset(uint cs_number)
+ {
+ thd_init_client_charset(thd, cs_number);
+ thd->update_charset();
+ return thd->is_error();
+ }
+
+ CHARSET_INFO *charset() { return thd->charset(); }
+};
+
+
/**
The internal version of what plugins know as MYSQL_PLUGIN_VIO,
basically the context of the authentication session
@@ -7779,8 +7796,7 @@ get_cached_table_access(GRANT_INTERNAL_I
struct MPVIO_EXT : public MYSQL_PLUGIN_VIO
{
MYSQL_SERVER_AUTH_INFO auth_info;
- THD *thd;
- ACL_USER *acl_user; ///< a copy, independent from acl_users array
+ const ACL_USER *acl_user;
plugin_ref plugin; ///< what plugin we're under
LEX_STRING db; ///< db name from the handshake packet
/** when restarting a plugin this caches the last client reply */
@@ -7797,21 +7813,51 @@ struct MPVIO_EXT : public MYSQL_PLUGIN_V
uint connect_errors; ///< if there were connect errors for this host
/** when plugin returns a failure this tells us what really happened */
enum { SUCCESS, FAILURE, RESTART } status;
+
+ /* encapsulation members */
+ ulong client_capabilities;
+ char *scramble;
+ MEM_ROOT *mem_root;
+ struct rand_struct *rand;
+ my_thread_id thread_id;
+ uint *server_status;
+ NET *net;
+ ulong max_client_packet_length;
+ char *priv_user;
+ char *ip;
+ char *host;
+ Thd_charset_adapter *charset_adapter;
+ LEX_STRING acl_user_plugin;
};
+static LEX_STRING *
+make_lex_string_root(MEM_ROOT *mem_root,
+ LEX_STRING *lex_str, const char* str, uint length,
+ bool allocate_lex_string)
+{
+ if (allocate_lex_string)
+ if (!(lex_str= (LEX_STRING *)alloc_root(mem_root, sizeof(LEX_STRING))))
+ return 0;
+ if (!(lex_str->str= strmake_root(mem_root, str, length)))
+ return 0;
+ lex_str->length= length;
+ return lex_str;
+}
+
/**
a helper function to report an access denied error in all the proper places
*/
-static void login_failed_error(THD *thd, int passwd_used)
+static void login_failed_error(MPVIO_EXT *mpvio, int passwd_used)
{
+ THD *thd= current_thd;
if (passwd_used == 2)
{
my_error(ER_ACCESS_DENIED_NO_PASSWORD_ERROR, MYF(0),
- thd->main_security_ctx.user,
- thd->main_security_ctx.host_or_ip);
+ mpvio->auth_info.user_name,
+ mpvio->auth_info.host_or_ip);
general_log_print(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_NO_PASSWORD_ERROR),
- thd->main_security_ctx.user,
- thd->main_security_ctx.host_or_ip);
+ mpvio->auth_info.user_name,
+ mpvio->auth_info.host_or_ip);
/*
Log access denied messages to the error log when log-warnings = 2
so that the overhead of the general query log is not required to track
@@ -7820,19 +7866,19 @@ static void login_failed_error(THD *thd,
if (global_system_variables.log_warnings > 1)
{
sql_print_warning(ER(ER_ACCESS_DENIED_NO_PASSWORD_ERROR),
- thd->main_security_ctx.user,
- thd->main_security_ctx.host_or_ip);
+ mpvio->auth_info.user_name,
+ mpvio->auth_info.host_or_ip);
}
}
else
{
my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
- thd->main_security_ctx.user,
- thd->main_security_ctx.host_or_ip,
+ mpvio->auth_info.user_name,
+ mpvio->auth_info.host_or_ip,
passwd_used ? ER(ER_YES) : ER(ER_NO));
general_log_print(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR),
- thd->main_security_ctx.user,
- thd->main_security_ctx.host_or_ip,
+ mpvio->auth_info.user_name,
+ mpvio->auth_info.host_or_ip,
passwd_used ? ER(ER_YES) : ER(ER_NO));
/*
Log access denied messages to the error log when log-warnings = 2
@@ -7842,8 +7888,8 @@ static void login_failed_error(THD *thd,
if (global_system_variables.log_warnings > 1)
{
sql_print_warning(ER(ER_ACCESS_DENIED_ERROR),
- thd->main_security_ctx.user,
- thd->main_security_ctx.host_or_ip,
+ mpvio->auth_info.user_name,
+ mpvio->auth_info.host_or_ip,
passwd_used ? ER(ER_YES) : ER(ER_NO));
}
}
@@ -7880,7 +7926,6 @@ static bool send_server_handshake_packet
DBUG_ASSERT(mpvio->status == MPVIO_EXT::FAILURE);
DBUG_ASSERT(data_len <= 255);
- THD *thd= mpvio->thd;
char *buff= (char *)my_alloca(1 + SERVER_VERSION_LENGTH + data_len + 64);
char scramble_buf[SCRAMBLE_LENGTH];
char *end= buff;
@@ -7888,11 +7933,23 @@ static bool send_server_handshake_packet
DBUG_ENTER ("send_server_handshake_packet");
*end++= protocol_version;
- thd->client_capabilities= CLIENT_BASIC_FLAGS;
+ mpvio->client_capabilities= CLIENT_BASIC_FLAGS;
+
+ if (opt_using_transactions)
+ mpvio->client_capabilities|= CLIENT_TRANSACTIONS;
+
+ mpvio->client_capabilities|= CAN_CLIENT_COMPRESS;
+
+ if (ssl_acceptor_fd)
+ {
+ mpvio->client_capabilities |= CLIENT_SSL;
+ mpvio->client_capabilities |= CLIENT_SSL_VERIFY_SERVER_CERT;
+ }
if (data_len)
{
- mpvio->cached_server_packet.pkt= (char*)thd->memdup(data, data_len);
+ mpvio->cached_server_packet.pkt= (char*)memdup_root(mpvio->mem_root,
+ data, data_len);
mpvio->cached_server_packet.pkt_len= data_len;
}
@@ -7918,25 +7975,14 @@ static bool send_server_handshake_packet
native_password_plugin will have to send it in a separate packet,
adding one more round trip.
*/
- create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
- data= thd->scramble;
+ create_random_string(mpvio->scramble, SCRAMBLE_LENGTH, mpvio->rand);
+ data= mpvio->scramble;
}
data_len= SCRAMBLE_LENGTH;
}
- if (opt_using_transactions)
- thd->client_capabilities|= CLIENT_TRANSACTIONS;
-
- thd->client_capabilities|= CAN_CLIENT_COMPRESS;
-
- if (ssl_acceptor_fd)
- {
- thd->client_capabilities |= CLIENT_SSL;
- thd->client_capabilities |= CLIENT_SSL_VERIFY_SERVER_CERT;
- }
-
end= strnmov(end, server_version, SERVER_VERSION_LENGTH) + 1;
- int4store((uchar*) end, mpvio->thd->thread_id);
+ int4store((uchar*) end, mpvio->thread_id);
end+= 4;
/*
@@ -7948,11 +7994,11 @@ static bool send_server_handshake_packet
end+= SCRAMBLE_LENGTH_323;
*end++= 0;
- int2store(end, thd->client_capabilities);
+ int2store(end, mpvio->client_capabilities);
/* write server characteristics: up to 16 bytes allowed */
end[2]=(char) default_charset_info->number;
- int2store(end+3, mpvio->thd->server_status);
- int2store(end+5, thd->client_capabilities >> 16);
+ int2store(end+3, mpvio->server_status[0]);
+ int2store(end+5, mpvio->client_capabilities >> 16);
end[7]= data_len;
bzero(end+8, 10);
end+= 18;
@@ -7963,28 +8009,31 @@ static bool send_server_handshake_packet
end= strmake(end, plugin_name(mpvio->plugin)->str,
plugin_name(mpvio->plugin)->length);
- int res= my_net_write(&mpvio->thd->net, (uchar*) buff, (size_t) (end-buff)) ||
- net_flush(&mpvio->thd->net);
+ int res= my_net_write(mpvio->net, (uchar*) buff, (size_t) (end-buff)) ||
+ net_flush(mpvio->net);
my_afree(buff);
DBUG_RETURN (res);
}
-static bool secure_auth(THD *thd)
+static bool secure_auth(MPVIO_EXT *mpvio)
{
+ THD *thd;
if (!opt_secure_auth)
return 0;
/*
If the server is running in secure auth mode, short scrambles are
forbidden. Extra juggling to report the same error as the old code.
*/
- if (thd->client_capabilities & CLIENT_PROTOCOL_41)
+
+ thd= current_thd;
+ if (mpvio->client_capabilities & CLIENT_PROTOCOL_41)
{
my_error(ER_SERVER_IS_IN_SECURE_AUTH_MODE, MYF(0),
- thd->security_ctx->user,
- thd->security_ctx->host_or_ip);
+ mpvio->auth_info.user_name,
+ mpvio->auth_info.host_or_ip);
general_log_print(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE),
- thd->security_ctx->user,
- thd->security_ctx->host_or_ip);
+ mpvio->auth_info.user_name,
+ mpvio->auth_info.host_or_ip);
}
else
{
@@ -8020,7 +8069,7 @@ static bool send_plugin_request_packet(M
{
DBUG_ASSERT(mpvio->packets_written == 1);
DBUG_ASSERT(mpvio->packets_read == 1);
- NET *net= &mpvio->thd->net;
+ NET *net= mpvio->net;
static uchar switch_plugin_request_buf[]= { 254 };
DBUG_ENTER ("send_plugin_request_packet");
@@ -8045,7 +8094,7 @@ static bool send_plugin_request_packet(M
client_auth_plugin == old_password_plugin_name.str;
if (switch_from_long_to_short_scramble)
- DBUG_RETURN (secure_auth(mpvio->thd) ||
+ DBUG_RETURN (secure_auth(mpvio) ||
my_net_write(net, switch_plugin_request_buf, 1) ||
net_flush(net));
@@ -8061,7 +8110,7 @@ static bool send_plugin_request_packet(M
if (switch_from_short_to_long_scramble)
{
my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
- general_log_print(mpvio->thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
+ general_log_print(current_thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
DBUG_RETURN (1);
}
@@ -8086,19 +8135,28 @@ static bool send_plugin_request_packet(M
@retval 0 found
@retval 1 not found
*/
-static bool find_mpvio_user(MPVIO_EXT *mpvio, Security_context *sctx)
+static bool find_mpvio_user(MPVIO_EXT *mpvio)
{
DBUG_ENTER ("find_mpvio_user");
- DBUG_PRINT ("info", ("entry: %s", sctx->user));
+ DBUG_PRINT ("info", ("entry: %s", mpvio->auth_info.user_name));
DBUG_ASSERT(mpvio->acl_user == 0);
mysql_mutex_lock(&acl_cache->lock);
for (uint i=0 ; i < acl_users.elements ; i++)
{
ACL_USER *acl_user_tmp= dynamic_element(&acl_users,i,ACL_USER*);
- if ((!acl_user_tmp->user || !strcmp(sctx->user, acl_user_tmp->user)) &&
- compare_hostname(&acl_user_tmp->host, sctx->host, sctx->ip))
+ if ((!acl_user_tmp->user ||
+ !strcmp(mpvio->auth_info.user_name, acl_user_tmp->user)) &&
+ compare_hostname(&acl_user_tmp->host, mpvio->host, mpvio->ip))
{
- mpvio->acl_user= acl_user_tmp->copy(mpvio->thd->mem_root);
+ mpvio->acl_user= acl_user_tmp->copy(mpvio->mem_root);
+ if (acl_user_tmp->plugin.str == native_password_plugin_name.str ||
+ acl_user_tmp->plugin.str == old_password_plugin_name.str)
+ mpvio->acl_user_plugin= acl_user_tmp->plugin;
+ else
+ make_lex_string_root(mpvio->mem_root,
+ &mpvio->acl_user_plugin,
+ acl_user_tmp->plugin.str,
+ acl_user_tmp->plugin.length, 0);
break;
}
}
@@ -8106,26 +8164,24 @@ static bool find_mpvio_user(MPVIO_EXT *m
if (!mpvio->acl_user)
{
- login_failed_error(mpvio->thd, 0);
+ login_failed_error(mpvio, 0);
DBUG_RETURN (1);
}
/* user account requires non-default plugin and the client is too old */
if (mpvio->acl_user->plugin.str != native_password_plugin_name.str &&
mpvio->acl_user->plugin.str != old_password_plugin_name.str &&
- !(mpvio->thd->client_capabilities & CLIENT_PLUGIN_AUTH))
+ !(mpvio->client_capabilities & CLIENT_PLUGIN_AUTH))
{
DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
native_password_plugin_name.str));
DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
old_password_plugin_name.str));
my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
- general_log_print(mpvio->thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
+ general_log_print(current_thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
DBUG_RETURN (1);
}
- mpvio->auth_info.user_name= sctx->user;
- mpvio->auth_info.user_name_length= (unsigned int) strlen(sctx->user);
mpvio->auth_info.auth_string= mpvio->acl_user->auth_string.str;
mpvio->auth_info.auth_string_length=
(unsigned long) mpvio->acl_user->auth_string.length;
@@ -8144,9 +8200,7 @@ static bool find_mpvio_user(MPVIO_EXT *m
/* the packet format is described in send_change_user_packet() */
static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length)
{
- THD *thd= mpvio->thd;
- NET *net= &thd->net;
- Security_context *sctx= thd->security_ctx;
+ NET *net= mpvio->net;
char *user= (char*) net->read_pos;
char *end= user + packet_length;
@@ -8175,7 +8229,7 @@ static bool parse_com_change_user_packet
Cast *passwd to an unsigned char, so that it doesn't extend the sign for
*passwd > 127 and become 2**32-127+ after casting to uint.
*/
- uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
+ uint passwd_len= (mpvio->client_capabilities & CLIENT_SECURE_CONNECTION ?
(uchar)(*passwd++) : strlen(passwd));
db+= passwd_len + 1;
@@ -8195,38 +8249,34 @@ static bool parse_com_change_user_packet
if (ptr+1 < end)
{
- uint cs_number= uint2korr(ptr);
- thd_init_client_charset(thd, cs_number);
- thd->update_charset();
+ if (mpvio->charset_adapter->init_client_charset(uint2korr(ptr)))
+ DBUG_RETURN(1);
}
+
/* Convert database and user names to utf8 */
db_len= copy_and_convert(db_buff, sizeof(db_buff)-1, system_charset_info,
- db, db_len, thd->charset(), &dummy_errors);
+ db, db_len, mpvio->charset_adapter->charset(),
+ &dummy_errors);
db_buff[db_len]= 0;
user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
system_charset_info, user, user_len,
- thd->charset(), &dummy_errors);
+ mpvio->charset_adapter->charset(),
+ &dummy_errors);
user_buff[user_len]= 0;
- if (!(sctx->user= my_strndup(user_buff, user_len, MYF(MY_WME))))
+ /* we should not free mpvio->user here: it's saved by dispatch_command() */
+ if (!(mpvio->auth_info.user_name= my_strndup(user_buff, user_len, MYF(MY_WME))))
return 1;
+ mpvio->auth_info.user_name_length= user_len;
- /* Clear variables that are allocated */
- thd->user_connect= 0;
- strmake(sctx->priv_user, sctx->user, USERNAME_LENGTH);
+ strmake(mpvio->priv_user, mpvio->auth_info.user_name, USERNAME_LENGTH);
- if (thd->make_lex_string(&mpvio->db, db_buff, db_len, 0) == 0)
+ if (make_lex_string_root(mpvio->mem_root,
+ &mpvio->db, db_buff, db_len, 0) == 0)
DBUG_RETURN (1); /* The error is set by make_lex_string(). */
- /*
- Clear thd->db as it points to something, that will be freed when
- connection is closed. We don't want to accidentally free a wrong
- pointer if connect failed.
- */
- thd->reset_db(NULL, 0);
-
if (!initialized)
{
// if mysqld's been started with --skip-grant-tables option
@@ -8235,11 +8285,11 @@ static bool parse_com_change_user_packet
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (find_mpvio_user(mpvio, sctx))
+ if (find_mpvio_user(mpvio))
DBUG_RETURN (1);
char *client_plugin;
- if (thd->client_capabilities & CLIENT_PLUGIN_AUTH)
+ if (mpvio->client_capabilities & CLIENT_PLUGIN_AUTH)
{
client_plugin= ptr + 2;
if (client_plugin >= end)
@@ -8250,7 +8300,7 @@ static bool parse_com_change_user_packet
}
else
{
- if (thd->client_capabilities & CLIENT_SECURE_CONNECTION)
+ if (mpvio->client_capabilities & CLIENT_SECURE_CONNECTION)
client_plugin= native_password_plugin_name.str;
else
{
@@ -8262,7 +8312,7 @@ static bool parse_com_change_user_packet
and client plugins don't match.
*/
if (mpvio->acl_user->auth_string.length == 0)
- mpvio->acl_user->plugin= old_password_plugin_name;
+ mpvio->acl_user_plugin= old_password_plugin_name;
}
}
@@ -8285,8 +8335,7 @@ static ulong parse_client_handshake_pack
uchar **buff, ulong pkt_len)
{
#ifndef EMBEDDED_LIBRARY
- THD *thd= mpvio->thd;
- NET *net= &thd->net;
+ NET *net= mpvio->net;
char *end;
DBUG_ASSERT(mpvio->status == MPVIO_EXT::FAILURE);
@@ -8295,33 +8344,31 @@ static ulong parse_client_handshake_pack
return packet_error;
if (mpvio->connect_errors)
- reset_host_errors(thd->main_security_ctx.ip);
+ reset_host_errors(mpvio->ip);
ulong client_capabilities= uint2korr(net->read_pos);
if (client_capabilities & CLIENT_PROTOCOL_41)
{
client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
- thd->max_client_packet_length= uint4korr(net->read_pos+4);
+ mpvio->max_client_packet_length= uint4korr(net->read_pos+4);
DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
- thd_init_client_charset(thd, (uint) net->read_pos[8]);
- thd->update_charset();
+ if (mpvio->charset_adapter->init_client_charset((uint) net->read_pos[8]))
+ return packet_error;
end= (char*) net->read_pos+32;
}
else
{
- thd->max_client_packet_length= uint3korr(net->read_pos+2);
+ mpvio->max_client_packet_length= uint3korr(net->read_pos+2);
end= (char*) net->read_pos+5;
}
/* Disable those bits which are not supported by the client. */
- thd->client_capabilities&= client_capabilities;
+ mpvio->client_capabilities&= client_capabilities;
- if (thd->client_capabilities & CLIENT_IGNORE_SPACE)
- thd->variables.sql_mode|= MODE_IGNORE_SPACE;
#if defined(HAVE_OPENSSL)
- DBUG_PRINT("info", ("client capabilities: %lu", thd->client_capabilities));
- if (thd->client_capabilities & CLIENT_SSL)
+ DBUG_PRINT("info", ("client capabilities: %lu", mpvio->client_capabilities));
+ if (mpvio->client_capabilities & CLIENT_SSL)
{
char error_string[1024] __attribute__((unused));
@@ -8350,11 +8397,9 @@ static ulong parse_client_handshake_pack
if (end >= (char*) net->read_pos+ pkt_len +2)
return packet_error;
- if (thd->client_capabilities & CLIENT_INTERACTIVE)
- thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout;
- if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
+ if ((mpvio->client_capabilities & CLIENT_TRANSACTIONS) &&
opt_using_transactions)
- net->return_status= &thd->server_status;
+ net->return_status= mpvio->server_status;
char *user= end;
char *passwd= strend(user)+1;
@@ -8374,10 +8419,10 @@ static ulong parse_client_handshake_pack
Cast *passwd to an unsigned char, so that it doesn't extend the sign for
*passwd > 127 and become 2**32-127+ after casting to uint.
*/
- uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
+ uint passwd_len= mpvio->client_capabilities & CLIENT_SECURE_CONNECTION ?
(uchar)(*passwd++) : strlen(passwd);
- if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
+ if (mpvio->client_capabilities & CLIENT_CONNECT_WITH_DB)
{
db= db + passwd_len + 1;
/* strlen() can't be easily deleted without changing protocol */
@@ -8398,14 +8443,16 @@ static ulong parse_client_handshake_pack
if (db)
{
db_len= copy_and_convert(db_buff, sizeof(db_buff)-1, system_charset_info,
- db, db_len, thd->charset(), &dummy_errors);
+ db, db_len, mpvio->charset_adapter->charset(),
+ &dummy_errors);
db= db_buff;
db_buff[db_len]= 0;
}
user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
system_charset_info, user, user_len,
- thd->charset(), &dummy_errors);
+ mpvio->charset_adapter->charset(),
+ &dummy_errors);
user= user_buff;
user_buff[user_len]= 0;
@@ -8417,21 +8464,14 @@ static ulong parse_client_handshake_pack
user_len-= 2;
}
- Security_context *sctx= thd->security_ctx;
-
- if (thd->make_lex_string(&mpvio->db, db, db_len, 0) == 0)
+ if (make_lex_string_root(mpvio->mem_root,
+ &mpvio->db, db, db_len, 0) == 0)
return packet_error; /* The error is set by make_lex_string(). */
- if (sctx->user)
- my_free(sctx->user);
- if (!(sctx->user= my_strndup(user, user_len, MYF(MY_WME))))
+ if (mpvio->auth_info.user_name)
+ my_free(mpvio->auth_info.user_name);
+ if (!(mpvio->auth_info.user_name= my_strndup(user, user_len, MYF(MY_WME))))
return packet_error; /* The error is set by my_strdup(). */
-
- /*
- Clear thd->db as it points to something, that will be freed when
- connection is closed. We don't want to accidentally free a wrong
- pointer if connect failed.
- */
- thd->reset_db(NULL, 0);
+ mpvio->auth_info.user_name_length= user_len;
if (!initialized)
{
@@ -8440,10 +8480,10 @@ static ulong parse_client_handshake_pack
return packet_error;
}
- if (find_mpvio_user(mpvio, sctx))
+ if (find_mpvio_user(mpvio))
return packet_error;
- if (thd->client_capabilities & CLIENT_PLUGIN_AUTH)
+ if (mpvio->client_capabilities & CLIENT_PLUGIN_AUTH)
{
if ((client_plugin + strlen(client_plugin)) >
(char *)net->read_pos + pkt_len)
@@ -8451,7 +8491,7 @@ static ulong parse_client_handshake_pack
}
else
{
- if (thd->client_capabilities & CLIENT_SECURE_CONNECTION)
+ if (mpvio->client_capabilities & CLIENT_SECURE_CONNECTION)
client_plugin= native_password_plugin_name.str;
else
{
@@ -8463,7 +8503,7 @@ static ulong parse_client_handshake_pack
and client plugins don't match.
*/
if (mpvio->acl_user->auth_string.length == 0)
- mpvio->acl_user->plugin= old_password_plugin_name;
+ mpvio->acl_user_plugin= old_password_plugin_name;
}
}
@@ -8476,7 +8516,7 @@ static ulong parse_client_handshake_pack
restarted and a server auth plugin will read the data that the client
has just send. Cache them to return in the next server_mpvio_read_packet().
*/
- if (my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
+ if (my_strcasecmp(system_charset_info, mpvio->acl_user_plugin.str,
plugin_name(mpvio->plugin)->str) != 0)
{
mpvio->cached_client_reply.pkt= passwd;
@@ -8504,8 +8544,8 @@ static ulong parse_client_handshake_pack
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(mpvio->net);
+ passwd = (char*)mpvio->net->read_pos;
}
*buff= (uchar*)passwd;
@@ -8547,13 +8587,13 @@ static int server_mpvio_write_packet(MYS
We'll escape these bytes with \1. Consequently, we
have to escape \1 byte too.
*/
- res= net_write_command(&mpvio->thd->net, 1, (uchar*)"", 0,
+ res= net_write_command(mpvio->net, 1, (uchar*)"", 0,
packet, packet_len);
}
else
{
- res= my_net_write(&mpvio->thd->net, packet, packet_len) ||
- net_flush(&mpvio->thd->net);
+ res= my_net_write(mpvio->net, packet, packet_len) ||
+ net_flush(mpvio->net);
}
mpvio->packets_written++;
DBUG_RETURN (res);
@@ -8584,7 +8624,7 @@ static int server_mpvio_read_packet(MYSQ
if (server_mpvio_write_packet(mpvio, 0, 0))
pkt_len= packet_error;
else
- pkt_len= my_net_read(&mpvio->thd->net);
+ pkt_len= my_net_read(mpvio->net);
}
else
if (mpvio->cached_client_reply.pkt)
@@ -8617,10 +8657,10 @@ static int server_mpvio_read_packet(MYSQ
if (server_mpvio_write_packet(mpvio, 0, 0))
pkt_len= packet_error;
else
- pkt_len= my_net_read(&mpvio->thd->net);
+ pkt_len= my_net_read(mpvio->net);
}
else
- pkt_len= my_net_read(&mpvio->thd->net);
+ pkt_len= my_net_read(mpvio->net);
if (pkt_len == packet_error)
goto err;
@@ -8638,16 +8678,15 @@ static int server_mpvio_read_packet(MYSQ
goto err;
}
else
- *buf = mpvio->thd->net.read_pos;
+ *buf = mpvio->net->read_pos;
DBUG_RETURN ((int)pkt_len);
err:
- if (mpvio->status == MPVIO_EXT::FAILURE && !mpvio->thd->is_error())
+ if (mpvio->status == MPVIO_EXT::FAILURE)
{
- inc_host_errors(mpvio->thd->security_ctx->ip);
- my_error(ER_HANDSHAKE_ERROR, MYF(0),
- mpvio->thd->security_ctx->host_or_ip);
+ inc_host_errors(mpvio->ip);
+ my_error(ER_HANDSHAKE_ERROR, MYF(0), mpvio->auth_info.host_or_ip);
}
DBUG_RETURN (-1);
}
@@ -8660,10 +8699,10 @@ static void server_mpvio_info(MYSQL_PLUG
MYSQL_PLUGIN_VIO_INFO *info)
{
MPVIO_EXT *mpvio= (MPVIO_EXT*)vio;
- mpvio_info(mpvio->thd->net.vio, info);
+ mpvio_info(mpvio->net->vio, info);
}
-static bool acl_check_ssl(THD *thd, ACL_USER *acl_user)
+static bool acl_check_ssl(THD *thd, const ACL_USER *acl_user)
{
#if defined(HAVE_OPENSSL)
Vio *vio=thd->net.vio;
@@ -8769,7 +8808,7 @@ static bool acl_check_ssl(THD *thd, ACL_
}
-static int do_auth_once(THD *thd, LEX_STRING *auth_plugin_name,
+static int do_auth_once(THD *thd, const LEX_STRING *auth_plugin_name,
MPVIO_EXT *mpvio)
{
int res= CR_OK, old_status= MPVIO_EXT::FAILURE;
@@ -8822,6 +8861,49 @@ static int do_auth_once(THD *thd, LEX_ST
}
+static void
+server_mpvio_initialize(THD *thd, MPVIO_EXT *mpvio, uint connect_errors,
+ Thd_charset_adapter *charset_adapter)
+{
+ bzero(mpvio, sizeof(MPVIO_EXT));
+ mpvio->read_packet= server_mpvio_read_packet;
+ mpvio->write_packet= server_mpvio_write_packet;
+ mpvio->info= server_mpvio_info;
+ 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);
+ mpvio->auth_info.user_name= thd->security_ctx->user;
+ mpvio->auth_info.user_name_length= thd->security_ctx->user ?
+ (unsigned int) strlen(thd->security_ctx->user) : 0;
+ mpvio->connect_errors= connect_errors;
+ mpvio->status= MPVIO_EXT::FAILURE;
+
+ mpvio->client_capabilities= thd->client_capabilities;
+ mpvio->mem_root= thd->mem_root;
+ mpvio->scramble= thd->scramble;
+ mpvio->rand= &thd->rand;
+ mpvio->thread_id= thd->thread_id;
+ mpvio->server_status= &thd->server_status;
+ mpvio->net= &thd->net;
+ mpvio->priv_user= thd->security_ctx->priv_user;
+ mpvio->ip= thd->security_ctx->ip;
+ mpvio->host= thd->security_ctx->host;
+ mpvio->charset_adapter= charset_adapter;
+}
+
+
+static void
+server_mpvio_update_thd(THD *thd, MPVIO_EXT *mpvio)
+{
+ thd->client_capabilities= mpvio->client_capabilities;
+ thd->max_client_packet_length= mpvio->max_client_packet_length;
+ if (mpvio->client_capabilities & CLIENT_INTERACTIVE)
+ thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout;
+ thd->security_ctx->user= mpvio->auth_info.user_name;
+ if (thd->client_capabilities & CLIENT_IGNORE_SPACE)
+ thd->variables.sql_mode|= MODE_IGNORE_SPACE;
+}
+
/**
Perform the handshake, authorize the client and update thd sctx variables.
@@ -8841,32 +8923,39 @@ acl_authenticate(THD *thd, uint connect_
{
int res= CR_OK;
MPVIO_EXT mpvio;
- LEX_STRING *auth_plugin_name= default_auth_plugin_name;
+ Thd_charset_adapter charset_adapter(thd);
+
+ const LEX_STRING *auth_plugin_name= default_auth_plugin_name;
enum enum_server_command command= com_change_user_pkt_len ? COM_CHANGE_USER
: COM_CONNECT;
DBUG_ENTER ("acl_authenticate");
compile_time_assert(MYSQL_USERNAME_LENGTH == USERNAME_LENGTH);
- bzero(&mpvio, sizeof(mpvio));
- mpvio.read_packet= server_mpvio_read_packet;
- mpvio.write_packet= server_mpvio_write_packet;
- mpvio.info= server_mpvio_info;
- mpvio.thd= thd;
- mpvio.auth_info.host_or_ip= thd->main_security_ctx.host_or_ip;
- mpvio.auth_info.host_or_ip_length=
- (unsigned int) strlen (thd->main_security_ctx.host_or_ip);
- mpvio.connect_errors= connect_errors;
- mpvio.status= MPVIO_EXT::FAILURE;
+ server_mpvio_initialize(thd, &mpvio, connect_errors, &charset_adapter);
DBUG_PRINT ("info", ("com_change_user_pkt_len=%u", com_change_user_pkt_len));
+
+ /*
+ Clear thd->db as it points to something, that will be freed when
+ connection is closed. We don't want to accidentally free a wrong
+ pointer if connect failed.
+ */
+ thd->reset_db(NULL, 0);
+
if (command == COM_CHANGE_USER)
{
mpvio.packets_written++; // pretend that a server handshake packet was sent
mpvio.packets_read++; // take COM_CHANGE_USER packet into account
+ /* Clear variables that are allocated */
+ thd->user_connect= 0;
+
if (parse_com_change_user_packet(&mpvio, com_change_user_pkt_len))
+ {
+ server_mpvio_update_thd(thd, &mpvio);
DBUG_RETURN(1);
+ }
DBUG_ASSERT(mpvio.status == MPVIO_EXT::RESTART ||
mpvio.status == MPVIO_EXT::SUCCESS);
@@ -8874,7 +8963,7 @@ acl_authenticate(THD *thd, uint connect_
else
{
/* mark the thd as having no scramble yet */
- thd->scramble[SCRAMBLE_LENGTH]= 1;
+ mpvio.scramble[SCRAMBLE_LENGTH]= 1;
/*
perform the first authentication attempt, with the default plugin.
@@ -8883,7 +8972,7 @@ acl_authenticate(THD *thd, uint connect_
the correct plugin.
*/
- res= do_auth_once (thd, auth_plugin_name, &mpvio);
+ res= do_auth_once(thd, auth_plugin_name, &mpvio);
}
/*
@@ -8900,8 +8989,10 @@ acl_authenticate(THD *thd, uint connect_
res= do_auth_once (thd, auth_plugin_name, &mpvio);
}
+ server_mpvio_update_thd(thd, &mpvio);
+
Security_context *sctx= thd->security_ctx;
- ACL_USER *acl_user= mpvio.acl_user;
+ const ACL_USER *acl_user= mpvio.acl_user;
thd->password= mpvio.auth_info.password_used; // remember for error messages
@@ -8911,18 +9002,19 @@ acl_authenticate(THD *thd, uint connect_
if sctx->user is unset it's protocol failure, bad packet.
*/
- if (sctx->user)
+ if (mpvio.auth_info.user_name)
{
- if (strcmp(sctx->priv_user, sctx->user))
+ if (strcmp(mpvio.auth_info.authenticated_as, mpvio.auth_info.user_name))
{
general_log_print(thd, command, "%s@%s as %s on %s",
- sctx->user, sctx->host_or_ip,
- sctx->priv_user[0] ? sctx->priv_user : "anonymous",
+ mpvio.auth_info.user_name, mpvio.auth_info.host_or_ip,
+ mpvio.auth_info.authenticated_as ?
+ mpvio.auth_info.authenticated_as : "anonymous",
mpvio.db.str ? mpvio.db.str : (char*) "");
}
else
general_log_print(thd, command, (char*) "%s@%s on %s",
- sctx->user, sctx->host_or_ip,
+ mpvio.auth_info.user_name, mpvio.auth_info.host_or_ip,
mpvio.db.str ? mpvio.db.str : (char*) "");
}
@@ -8931,7 +9023,7 @@ acl_authenticate(THD *thd, uint connect_
DBUG_ASSERT(mpvio.status == MPVIO_EXT::FAILURE);
if (!thd->is_error())
- login_failed_error(thd, thd->password);
+ login_failed_error(&mpvio, mpvio.auth_info.password_used);
DBUG_RETURN (1);
}
@@ -8943,19 +9035,19 @@ acl_authenticate(THD *thd, uint connect_
bool is_proxy_user= FALSE;
const char *auth_user = mpvio.acl_user->user ? mpvio.acl_user->user : "";
/* check if the user is allowed to proxy as another user */
- if (acl_find_proxy_user (auth_user, sctx->host, sctx->ip,
- mpvio.auth_info.authenticated_as,
- &is_proxy_user))
+ if (acl_find_proxy_user(auth_user, sctx->host, sctx->ip,
+ mpvio.auth_info.authenticated_as,
+ &is_proxy_user))
{
if (!thd->is_error())
- login_failed_error(thd, thd->password);
+ login_failed_error(&mpvio, mpvio.auth_info.password_used);
DBUG_RETURN(1);
}
if (is_proxy_user)
- my_snprintf (sctx->proxy_user, sizeof (sctx->proxy_user) - 1,
- "'%s'@'%s'", auth_user,
- acl_user->host.hostname ? acl_user->host.hostname : "");
+ my_snprintf(sctx->proxy_user, sizeof (sctx->proxy_user) - 1,
+ "'%s'@'%s'", auth_user,
+ acl_user->host.hostname ? acl_user->host.hostname : "");
#endif
sctx->master_access= acl_user->access;
@@ -8973,7 +9065,8 @@ acl_authenticate(THD *thd, uint connect_
*/
if (acl_check_ssl(thd, acl_user))
{
- login_failed_error(thd, thd->password);
+ if (!thd->is_error())
+ login_failed_error(&mpvio, thd->password);
DBUG_RETURN (1);
}
@@ -9047,7 +9140,7 @@ acl_authenticate(THD *thd, uint connect_
}
if (mpvio.auth_info.external_user[0])
- sctx->external_user= my_strdup (mpvio.auth_info.external_user, MYF(0));
+ sctx->external_user= my_strdup(mpvio.auth_info.external_user, MYF(0));
if (res == CR_OK_HANDSHAKE_COMPLETE)
thd->stmt_da->disable_status();
@@ -9082,16 +9175,15 @@ static int native_password_authenticate(
uchar *pkt;
int pkt_len;
MPVIO_EXT *mpvio=(MPVIO_EXT*)vio;
- THD *thd=mpvio->thd;
DBUG_ENTER ("native_password_authenticate");
/* generate the scramble, or reuse the old one */
- if (thd->scramble[SCRAMBLE_LENGTH])
- create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
+ if (mpvio->scramble[SCRAMBLE_LENGTH])
+ create_random_string(mpvio->scramble, SCRAMBLE_LENGTH, mpvio->rand);
/* send it to the client */
- if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1))
+ if (mpvio->write_packet(mpvio, (uchar*)mpvio->scramble, SCRAMBLE_LENGTH + 1))
return CR_ERROR;
/* reply and authenticate */
@@ -9149,12 +9241,12 @@ static int native_password_authenticate(
if (!mpvio->acl_user->salt_len)
DBUG_RETURN(CR_ERROR);
- DBUG_RETURN (check_scramble(pkt, thd->scramble, mpvio->acl_user->salt) ?
+ DBUG_RETURN (check_scramble(pkt, mpvio->scramble, mpvio->acl_user->salt) ?
CR_ERROR : CR_OK);
}
- inc_host_errors(mpvio->thd->main_security_ctx.ip);
- my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
+ inc_host_errors(mpvio->ip);
+ my_error(ER_HANDSHAKE_ERROR, MYF(0), mpvio->auth_info.host_or_ip);
DBUG_RETURN (CR_ERROR);
}
@@ -9164,14 +9256,13 @@ static int old_password_authenticate(MYS
uchar *pkt;
int pkt_len;
MPVIO_EXT *mpvio=(MPVIO_EXT*)vio;
- THD *thd=mpvio->thd;
/* generate the scramble, or reuse the old one */
- if (thd->scramble[SCRAMBLE_LENGTH])
- create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
+ if (mpvio->scramble[SCRAMBLE_LENGTH])
+ create_random_string(mpvio->scramble, SCRAMBLE_LENGTH, mpvio->rand);
/* send it to the client */
- if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1))
+ if (mpvio->write_packet(mpvio, (uchar*)mpvio->scramble, SCRAMBLE_LENGTH + 1))
return CR_ERROR;
/* read the reply and authenticate */
@@ -9193,7 +9284,7 @@ static int old_password_authenticate(MYS
if (pkt_len == 0) /* no password */
return info->auth_string[0] ? CR_ERROR : CR_OK;
- if (secure_auth(thd))
+ if (secure_auth(mpvio))
return CR_ERROR;
info->password_used = 1;
@@ -9203,12 +9294,12 @@ static int old_password_authenticate(MYS
if (!mpvio->acl_user->salt_len)
return CR_ERROR;
- return check_scramble_323(pkt, thd->scramble,
+ return check_scramble_323(pkt, mpvio->scramble,
(ulong *)mpvio->acl_user->salt) ? CR_ERROR : CR_OK;
}
- inc_host_errors(mpvio->thd->main_security_ctx.ip);
- my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
+ inc_host_errors(mpvio->ip);
+ my_error(ER_HANDSHAKE_ERROR, MYF(0), mpvio->auth_info.host_or_ip);
return CR_ERROR;
}
=== modified file 'sql/sql_audit.h'
--- a/sql/sql_audit.h 2010-07-02 18:15:21 +0000
+++ b/sql/sql_audit.h 2010-07-30 15:43:16 +0000
@@ -40,7 +40,7 @@ static inline uint make_user_name(THD *t
{
Security_context *sctx= thd->security_ctx;
return strxnmov(buf, MAX_USER_HOST_SIZE,
- sctx->priv_user ? sctx->priv_user : "", "[",
+ sctx->priv_user[0] ? sctx->priv_user : "", "[",
sctx->user ? sctx->user : "", "] @ ",
sctx->host ? sctx->host : "", " [",
sctx->ip ? sctx->ip : "", "]", NullS) - buf;
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2010-07-26 09:08:37 +0000
+++ b/sql/sql_class.cc 2010-07-30 15:43:16 +0000
@@ -2952,7 +2952,7 @@ void THD::set_status_var_init()
void Security_context::init()
{
- host= user= ip= 0;
+ host= user= ip= external_user= 0;
host_or_ip= "connecting host";
priv_user[0]= priv_host[0]= '\0';
master_access= 0;
@@ -2976,6 +2976,12 @@ void Security_context::destroy()
user= NULL;
}
+ if (external_user)
+ {
+ my_free(external_user);
+ user= NULL;
+ }
+
my_free(ip);
ip= NULL;
}
=== modified file 'sql/sql_connect.cc'
--- a/sql/sql_connect.cc 2010-07-26 09:08:37 +0000
+++ b/sql/sql_connect.cc 2010-07-30 15:43:16 +0000
@@ -63,7 +63,7 @@ static HASH hash_user_connections;
int get_or_create_user_conn(THD *thd, const char *user,
const char *host,
- USER_RESOURCES *mqh)
+ const USER_RESOURCES *mqh)
{
int return_val= 0;
size_t temp_len, user_len;
=== modified file 'sql/sql_connect.h'
--- a/sql/sql_connect.h 2010-07-26 09:08:37 +0000
+++ b/sql/sql_connect.h 2010-07-30 15:43:16 +0000
@@ -41,7 +41,7 @@ int check_user(THD *thd, enum enum_serve
bool check_count);
int get_or_create_user_conn(THD *thd, const char *user,
- const char *host, USER_RESOURCES *mqh);
+ const char *host, const USER_RESOURCES *mqh);
int check_for_max_user_connections(THD *thd, USER_CONN *uc);
#endif /* SQL_CONNECT_INCLUDED */
Attachment: [text/bzr-bundle] bzr/georgi.kodinov@oracle.com-20100730154316-su90esbjxmnnea91.bundle
| Thread |
|---|
| • bzr commit into mysql-next-mr-wl1054 branch (Georgi.Kodinov:2971) | Georgi Kodinov | 30 Jul |