maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #02734
Re: Review of 5.2 pluggable-auth tree
Hi, Monty!
On Mar 26, Sergei Golubchik wrote:
>
> Hi, Monty!
>
> See the answers below:
> (no reply means "ok, changed")
>
> On Mar 25, Michael Widenius wrote:
And here's a patch that implements your review comments.
Regards,
Sergei
=== modified file 'client/mysql.cc'
*** client/mysql.cc 2010-03-15 17:35:32 +0000
--- client/mysql.cc 2010-03-26 11:32:46 +0000
***************
*** 4273,4296 ****
const char *prompt,
char *buf, int buf_len)
{
! int ch;
! char *s=buf, *end=buf+buf_len-1;
! fputs("[mysql] ", stdout);
fputs(prompt, stdout);
fputs(" ", stdout);
if (type == 2) /* password */
{
s= get_tty_password("");
! strncpy(buf, s, buf_len);
my_free(s, MYF(0));
}
else
{
! for (ch= fgetc(stdin); s < end && ch != '\n' && ch != EOF; ch= fgetc(stdin))
! *s++= ch;
! *s=0;
}
return buf;
--- 4273,4296 ----
const char *prompt,
char *buf, int buf_len)
{
! char *s=buf;
! fputs("[mariadb] ", stdout);
fputs(prompt, stdout);
fputs(" ", stdout);
if (type == 2) /* password */
{
s= get_tty_password("");
! strnmov(buf, s, buf_len);
! buf[buf_len-1]= 0;
my_free(s, MYF(0));
}
else
{
! fgets(buf, buf_len-1, stdin);
! if (buf[0] && (s= strend(buf))[-1] == '\n')
! s[-1]= 0;
}
return buf;
=== modified file 'libmysqld/lib_sql.cc'
*** libmysqld/lib_sql.cc 2010-03-15 17:35:32 +0000
--- libmysqld/lib_sql.cc 2010-03-26 11:32:46 +0000
***************
*** 415,421 ****
int emb_read_change_user_result(MYSQL *mysql)
{
mysql->net.read_pos= (uchar*)""; // fake an OK packet
! return mysql_errno(mysql) ? packet_error : 1;
}
MYSQL_METHODS embedded_methods=
--- 415,421 ----
int emb_read_change_user_result(MYSQL *mysql)
{
mysql->net.read_pos= (uchar*)""; // fake an OK packet
! return mysql_errno(mysql) ? packet_error : 1 /* length of the OK packet */;
}
MYSQL_METHODS embedded_methods=
=== modified file 'plugin/auth/auth_socket.c'
*** plugin/auth/auth_socket.c 2010-03-11 12:33:22 +0000
--- plugin/auth/auth_socket.c 2010-03-26 11:32:46 +0000
***************
*** 1,5 ****
/* Copyright (C) 2010 Monty Program Ab
! /* Copyright (C) 2010 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
--- 1,5 ----
/* Copyright (C) 2010 Monty Program Ab
! /* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
=== modified file 'plugin/auth/dialog.c'
*** plugin/auth/dialog.c 2010-03-11 12:33:22 +0000
--- plugin/auth/dialog.c 2010-03-26 11:32:46 +0000
***************
*** 1,5 ****
/* Copyright (C) 2010 Monty Program Ab
! /* Copyright (C) 2010 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
--- 1,5 ----
/* Copyright (C) 2010 Monty Program Ab
! /* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
***************
*** 236,242 ****
We send the "password", assuming the client knows what its doing.
(in other words, the dialog plugin should be only set as a default
authentication plugin on the client if the first question
! asks for a password - which will be sent in cleat text, by the way)
*/
reply= mysql->passwd;
}
--- 236,242 ----
We send the "password", assuming the client knows what its doing.
(in other words, the dialog plugin should be only set as a default
authentication plugin on the client if the first question
! asks for a password - which will be sent in clear text, by the way)
*/
reply= mysql->passwd;
}
=== modified file 'sql-common/client.c'
*** sql-common/client.c 2010-03-11 12:33:22 +0000
--- sql-common/client.c 2010-03-26 11:32:46 +0000
***************
*** 109,114 ****
#include <sql_common.h>
#include <mysql/client_plugin.h>
uint mysql_port=0;
char *mysql_unix_port= 0;
const char *unknown_sqlstate= "HY000";
--- 109,117 ----
#include <sql_common.h>
#include <mysql/client_plugin.h>
+ #define native_password_plugin_name "mysql_native_password"
+ #define old_password_plugin_name "mysql_old_password"
+
uint mysql_port=0;
char *mysql_unix_port= 0;
const char *unknown_sqlstate= "HY000";
***************
*** 1047,1059 ****
return 0;
}
! #define extension_free(OPTS, X) \
if ((OPTS)->extension) \
my_free((OPTS)->extension->X, MYF(MY_ALLOW_ZERO_PTR)); \
else \
(OPTS)->extension= (struct st_mysql_options_extention *) \
my_malloc(sizeof(struct st_mysql_options_extention), \
! MYF(MY_WME | MY_ZEROFILL));
void mysql_read_default_options(struct st_mysql_options *options,
const char *filename,const char *group)
--- 1050,1063 ----
return 0;
}
! #define extension_set_string(OPTS, X, STR) \
if ((OPTS)->extension) \
my_free((OPTS)->extension->X, MYF(MY_ALLOW_ZERO_PTR)); \
else \
(OPTS)->extension= (struct st_mysql_options_extention *) \
my_malloc(sizeof(struct st_mysql_options_extention), \
! MYF(MY_WME | MY_ZEROFILL)); \
! (OPTS)->extension->X= my_strdup((STR), MYF(MY_WME));
void mysql_read_default_options(struct st_mysql_options *options,
const char *filename,const char *group)
***************
*** 1243,1254 ****
options->report_data_truncation= opt_arg ? test(atoi(opt_arg)) : 1;
break;
case OPT_plugin_dir:
! extension_free(options, plugin_dir);
! options->extension->plugin_dir= my_strdup(opt_arg, MYF(MY_WME));
break;
case OPT_default_auth:
! extension_free(options, default_auth);
! options->extension->default_auth= my_strdup(opt_arg, MYF(MY_WME));
break;
default:
DBUG_PRINT("warning",("unknown option: %s",option[0]));
--- 1247,1256 ----
options->report_data_truncation= opt_arg ? test(atoi(opt_arg)) : 1;
break;
case OPT_plugin_dir:
! extension_set_string(options, plugin_dir, opt_arg);
break;
case OPT_default_auth:
! extension_set_string(options, default_auth, opt_arg);
break;
default:
DBUG_PRINT("warning",("unknown option: %s",option[0]));
***************
*** 1892,1897 ****
/*********** client side authentication support **************************/
typedef struct st_mysql_client_plugin_AUTHENTICATION auth_plugin_t;
/* this is a "superset" of MYSQL_PLUGIN_VIO, in C++ I use inheritance */
typedef struct {
--- 1894,1937 ----
/*********** client side authentication support **************************/
typedef struct st_mysql_client_plugin_AUTHENTICATION auth_plugin_t;
+ static int client_mpvio_write_packet(struct st_plugin_vio*, const uchar*, int);
+ static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql);
+ static int old_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql);
+
+ static auth_plugin_t native_password_client_plugin=
+ {
+ MYSQL_CLIENT_AUTHENTICATION_PLUGIN,
+ MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION,
+ native_password_plugin_name,
+ "R.J.Silk, Sergei Golubchik",
+ "Native MySQL authentication",
+ {1, 0, 0},
+ NULL,
+ NULL,
+ native_password_auth_client
+ };
+
+ static auth_plugin_t old_password_client_plugin=
+ {
+ MYSQL_CLIENT_AUTHENTICATION_PLUGIN,
+ MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION,
+ old_password_plugin_name,
+ "R.J.Silk, Sergei Golubchik",
+ "Old MySQL-3.23 authentication",
+ {1, 0, 0},
+ NULL,
+ NULL,
+ old_password_auth_client
+ };
+
+ struct st_mysql_client_plugin *mysql_client_builtins[]=
+ {
+ (struct st_mysql_client_plugin *)&native_password_client_plugin,
+ (struct st_mysql_client_plugin *)&old_password_client_plugin,
+ 0
+ };
+
+
/* this is a "superset" of MYSQL_PLUGIN_VIO, in C++ I use inheritance */
typedef struct {
***************
*** 1906,1918 ****
uchar *pkt; /**< pointer into NET::buff */
uint pkt_len;
} cached_server_reply;
! int packets_read, packets_written; /**< counters for send/received packets */
! int mysql_change_user; /**< if it's mysql_change_user() */
int last_read_packet_len; /**< the length of the last *read* packet */
} MCPVIO_EXT;
-
- #define native_password_plugin_name "mysql_native_password"
- #define old_password_plugin_name "mysql_old_password"
/**
sends a COM_CHANGE_USER command with a caller provided payload
--- 1946,1955 ----
uchar *pkt; /**< pointer into NET::buff */
uint pkt_len;
} cached_server_reply;
! uint packets_read, packets_written; /**< counters for send/received packets */
! my_bool mysql_change_user; /**< if it's mysql_change_user() */
int last_read_packet_len; /**< the length of the last *read* packet */
} MCPVIO_EXT;
/**
sends a COM_CHANGE_USER command with a caller provided payload
***************
*** 2124,2130 ****
goto error;
}
}
! #endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
DBUG_PRINT("info",("Server version = '%s' capabilites: %lu status: %u client_flag: %lu",
mysql->server_version, mysql->server_capabilities,
--- 2161,2167 ----
goto error;
}
}
! #endif /* HAVE_OPENSSL */
DBUG_PRINT("info",("Server version = '%s' capabilites: %lu status: %u client_flag: %lu",
mysql->server_version, mysql->server_capabilities,
***************
*** 2187,2194 ****
}
- static int client_mpvio_write_packet(struct st_plugin_vio*, const uchar*, int);
-
/**
vio->read_packet() callback method for client authentication plugins
--- 2224,2229 ----
}
/**
vio->read_packet() callback method for client authentication plugins
***************
*** 2202,2208 ****
MYSQL *mysql= mpvio->mysql;
ulong pkt_len;
! if (mpvio->packets_read == 0 && !mpvio->cached_server_reply.pkt)
{
/*
the server handshake packet came from the wrong plugin,
--- 2237,2252 ----
MYSQL *mysql= mpvio->mysql;
ulong pkt_len;
! /* there are cached data left, feed it to a plugin */
! if (mpvio->cached_server_reply.pkt)
! {
! *buf= mpvio->cached_server_reply.pkt;
! mpvio->cached_server_reply.pkt= 0;
! mpvio->packets_read++;
! return mpvio->cached_server_reply.pkt_len;
! }
!
! if (mpvio->packets_read == 0)
{
/*
the server handshake packet came from the wrong plugin,
***************
*** 2214,2228 ****
return (int)packet_error;
}
- /* there are cached data left, feed it to a plugin */
- if (mpvio->cached_server_reply.pkt)
- {
- *buf= mpvio->cached_server_reply.pkt;
- mpvio->cached_server_reply.pkt= 0;
- mpvio->packets_read++;
- return mpvio->cached_server_reply.pkt_len;
- }
-
/* otherwise read the data */
pkt_len= (*mysql->methods->read_change_user_result)(mysql);
mpvio->last_read_packet_len= pkt_len;
--- 2258,2263 ----
return (int)packet_error;
}
/* otherwise read the data */
pkt_len= (*mysql->methods->read_change_user_result)(mysql);
mpvio->last_read_packet_len= pkt_len;
***************
*** 2236,2241 ****
the server sends \1\255 or \1\254 instead of just \255 or \254 -
for us to not confuse it with an error or "change plugin" packets.
We remove this escaping \1 here.
*/
if (pkt_len && **buf == 1)
{
--- 2271,2278 ----
the server sends \1\255 or \1\254 instead of just \255 or \254 -
for us to not confuse it with an error or "change plugin" packets.
We remove this escaping \1 here.
+
+ See also server_mpvio_write_packet() where the escaping is done.
*/
if (pkt_len && **buf == 1)
{
***************
*** 2368,2381 ****
/* determine the default/initial plugin to use */
if (mysql->options.extension && mysql->options.extension->default_auth &&
mysql->server_capabilities & CLIENT_PLUGIN_AUTH)
auth_plugin_name= mysql->options.extension->default_auth;
- else
- auth_plugin_name= mysql->server_capabilities & CLIENT_PROTOCOL_41 ?
- native_password_plugin_name : old_password_plugin_name;
-
if (!(auth_plugin= (auth_plugin_t*) mysql_client_find_plugin(mysql,
auth_plugin_name, MYSQL_CLIENT_AUTHENTICATION_PLUGIN)))
return 1; /* oops, not found */
mysql->net.last_errno= 0; /* just in case */
--- 2405,2422 ----
/* determine the default/initial plugin to use */
if (mysql->options.extension && mysql->options.extension->default_auth &&
mysql->server_capabilities & CLIENT_PLUGIN_AUTH)
+ {
auth_plugin_name= mysql->options.extension->default_auth;
if (!(auth_plugin= (auth_plugin_t*) mysql_client_find_plugin(mysql,
auth_plugin_name, MYSQL_CLIENT_AUTHENTICATION_PLUGIN)))
return 1; /* oops, not found */
+ }
+ else
+ {
+ auth_plugin= mysql->server_capabilities & CLIENT_PROTOCOL_41 ?
+ &native_password_client_plugin : &old_password_client_plugin;
+ auth_plugin_name= auth_plugin->name;
+ }
mysql->net.last_errno= 0; /* just in case */
***************
*** 2436,2451 ****
{
/* The server asked to use a different authentication plugin */
if (pkt_length == 1)
! { /* old "use short scramble" packet */
auth_plugin_name= old_password_plugin_name;
mpvio.cached_server_reply.pkt= (uchar*)mysql->scramble;
mpvio.cached_server_reply.pkt_len= SCRAMBLE_LENGTH + 1;
}
else
! { /* new "use different plugin" packet */
uint len;
auth_plugin_name= (char*)mysql->net.read_pos + 1;
! len= strlen(auth_plugin_name);
mpvio.cached_server_reply.pkt_len= pkt_length - len - 2;
mpvio.cached_server_reply.pkt= mysql->net.read_pos + len + 2;
}
--- 2477,2494 ----
{
/* The server asked to use a different authentication plugin */
if (pkt_length == 1)
! {
! /* old "use short scramble" packet */
auth_plugin_name= old_password_plugin_name;
mpvio.cached_server_reply.pkt= (uchar*)mysql->scramble;
mpvio.cached_server_reply.pkt_len= SCRAMBLE_LENGTH + 1;
}
else
! {
! /* new "use different plugin" packet */
uint len;
auth_plugin_name= (char*)mysql->net.read_pos + 1;
! len= strlen(auth_plugin_name); /* safe as my_net_read always appends \0 */
mpvio.cached_server_reply.pkt_len= pkt_length - len - 2;
mpvio.cached_server_reply.pkt= mysql->net.read_pos + len + 2;
}
***************
*** 2496,2503 ****
{
char buff[NAME_LEN+USERNAME_LENGTH+100];
int scramble_data_len, pkt_scramble_len;
! char *end,*host_info, *server_version_end, *pkt_end, *scramble_data;
! char *scramble_plugin;
my_socket sock;
in_addr_t ip_addr;
struct sockaddr_in sock_addr;
--- 2539,2546 ----
{
char buff[NAME_LEN+USERNAME_LENGTH+100];
int scramble_data_len, pkt_scramble_len;
! char *end, *host_info=0, *server_version_end, *pkt_end;
! char *scramble_data, *scramble_plugin;
my_socket sock;
in_addr_t ip_addr;
struct sockaddr_in sock_addr;
***************
*** 2898,2903 ****
{
scramble_data_len= pkt_scramble_len;
scramble_plugin= scramble_data + scramble_data_len;
}
else
{
--- 2941,2948 ----
{
scramble_data_len= pkt_scramble_len;
scramble_plugin= scramble_data + scramble_data_len;
+ if (scramble_data + scramble_data_len > pkt_end)
+ scramble_data_len= pkt_end - scramble_data;
}
else
{
***************
*** 3665,3676 ****
mysql->options.client_flag&= ~CLIENT_SSL_VERIFY_SERVER_CERT;
break;
case MYSQL_PLUGIN_DIR:
! extension_free(&mysql->options, plugin_dir);
! mysql->options.extension->plugin_dir= my_strdup(arg, MYF(MY_WME));
break;
case MYSQL_DEFAULT_AUTH:
! extension_free(&mysql->options, default_auth);
! mysql->options.extension->default_auth= my_strdup(arg, MYF(MY_WME));
break;
default:
DBUG_RETURN(1);
--- 3710,3719 ----
mysql->options.client_flag&= ~CLIENT_SSL_VERIFY_SERVER_CERT;
break;
case MYSQL_PLUGIN_DIR:
! extension_set_string(&mysql->options, plugin_dir, arg);
break;
case MYSQL_DEFAULT_AUTH:
! extension_set_string(&mysql->options, default_auth, arg);
break;
default:
DBUG_RETURN(1);
***************
*** 3876,3911 ****
return CR_OK;
}
- static auth_plugin_t native_password_client_plugin=
- {
- MYSQL_CLIENT_AUTHENTICATION_PLUGIN,
- MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION,
- native_password_plugin_name,
- "R.J.Silk, Sergei Golubchik",
- "Native MySQL authentication",
- {1, 0, 0},
- NULL,
- NULL,
- native_password_auth_client
- };
-
- static auth_plugin_t old_password_client_plugin=
- {
- MYSQL_CLIENT_AUTHENTICATION_PLUGIN,
- MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION,
- old_password_plugin_name,
- "R.J.Silk, Sergei Golubchik",
- "Old MySQL-3.23 authentication",
- {1, 0, 0},
- NULL,
- NULL,
- old_password_auth_client
- };
-
- struct st_mysql_client_plugin *mysql_client_builtins[]=
- {
- (struct st_mysql_client_plugin *)&native_password_client_plugin,
- (struct st_mysql_client_plugin *)&old_password_client_plugin,
- 0
- };
-
--- 3919,3921 ----
return CR_OK;
}
=== modified file 'sql-common/client_plugin.c'
*** sql-common/client_plugin.c 2010-03-11 12:33:22 +0000
--- sql-common/client_plugin.c 2010-03-26 11:32:46 +0000
***************
*** 1,5 ****
/* Copyright (C) 2010 Monty Program Ab
! /* Copyright (C) 2010 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
--- 1,5 ----
/* Copyright (C) 2010 Monty Program Ab
! /* Copyright (C) 2010 Sergei Golubchik and Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
***************
*** 209,226 ****
char *plugs, *free_env, *s= getenv("LIBMYSQL_PLUGINS");
/* no plugins to load */
! if(!s)
return;
free_env= plugs= my_strdup(s, MYF(MY_WME));
- s= NULL;
do {
if ((s= strchr(plugs, ';')))
*s= '\0';
mysql_load_plugin(mysql, plugs, -1, 0);
! if(s)
! plugs= ++s;
} while (s);
my_free(free_env, MYF(0));
--- 209,224 ----
char *plugs, *free_env, *s= getenv("LIBMYSQL_PLUGINS");
/* no plugins to load */
! if (!s)
return;
free_env= plugs= my_strdup(s, MYF(MY_WME));
do {
if ((s= strchr(plugs, ';')))
*s= '\0';
mysql_load_plugin(mysql, plugs, -1, 0);
! plugs= s + 1;
} while (s);
my_free(free_env, MYF(0));
=== modified file 'sql/mysqld.cc'
*** sql/mysqld.cc 2010-03-15 17:35:32 +0000
--- sql/mysqld.cc 2010-03-26 11:32:46 +0000
***************
*** 3491,3497 ****
if (init_errmessage()) /* Read error messages from file */
return 1;
init_client_errs();
! mysql_library_init(un,us,ed); /* for replication */
lex_init();
if (item_create_init())
return 1;
--- 3491,3497 ----
if (init_errmessage()) /* Read error messages from file */
return 1;
init_client_errs();
! mysql_library_init(never,never,never); /* for replication */
lex_init();
if (item_create_init())
return 1;
=== modified file 'sql/sql_acl.cc'
*** sql/sql_acl.cc 2010-03-22 18:09:47 +0000
--- sql/sql_acl.cc 2010-03-26 11:32:46 +0000
***************
*** 664,671 ****
user.user ? user.user : "",
user.host.hostname ? user.host.hostname : "");
}
user.plugin.str= tmpstr;
user.plugin.length= strlen(tmpstr);
user.auth_string.str= get_field(&mem, table->field[next_field++]);
if (!user.auth_string.str)
user.auth_string.str= const_cast<char*>("");
--- 664,681 ----
user.user ? user.user : "",
user.host.hostname ? user.host.hostname : "");
}
+ if (my_strcasecmp(system_charset_info, tmpstr,
+ native_password_plugin_name.str) == 0)
+ user.plugin= native_password_plugin_name;
+ else
+ if (my_strcasecmp(system_charset_info, tmpstr,
+ old_password_plugin_name.str) == 0)
+ user.plugin= old_password_plugin_name;
+ else
+ {
user.plugin.str= tmpstr;
user.plugin.length= strlen(tmpstr);
+ }
user.auth_string.str= get_field(&mem, table->field[next_field++]);
if (!user.auth_string.str)
user.auth_string.str= const_cast<char*>("");
***************
*** 6828,6839 ****
/* few defines to have less ifdef's in the code below */
#ifdef EMBEDDED_LIBRARY
#ifdef NO_EMBEDDED_ACCESS_CHECKS
#define initialized 0
#define decrease_user_connections(X) /* nothing */
#define check_for_max_user_connections(X,Y) 0
#endif
- #undef HAVE_OPENSSL
#endif
#ifndef HAVE_OPENSSL
#define ssl_acceptor_fd 0
--- 6838,6849 ----
/* few defines to have less ifdef's in the code below */
#ifdef EMBEDDED_LIBRARY
+ #undef HAVE_OPENSSL
#ifdef NO_EMBEDDED_ACCESS_CHECKS
#define initialized 0
#define decrease_user_connections(X) /* nothing */
#define check_for_max_user_connections(X,Y) 0
#endif
#endif
#ifndef HAVE_OPENSSL
#define ssl_acceptor_fd 0
***************
*** 6929,6934 ****
const char *data, uint data_len)
{
DBUG_ASSERT(mpvio->status == MPVIO_EXT::FAILURE);
THD *thd= mpvio->thd;
char *buff= (char *)my_alloca(1 + SERVER_VERSION_LENGTH + data_len + 64);
--- 6939,6945 ----
const char *data, uint data_len)
{
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);
***************
*** 7018,7025 ****
return res;
}
! static uchar switch_plugin_request_buf[]= { 254 };
/**
sends a "change plugin" packet, requesting a client to restart authentication
--- 7029,7059 ----
return res;
}
+ static bool secure_auth(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)
! {
! my_error(ER_SERVER_IS_IN_SECURE_AUTH_MODE, MYF(0),
! thd->security_ctx->user,
! thd->security_ctx->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);
! }
! else
! {
! my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
! general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
! }
! return 1;
! }
/**
sends a "change plugin" packet, requesting a client to restart authentication
***************
*** 7049,7054 ****
DBUG_ASSERT(mpvio->packets_written == 1);
DBUG_ASSERT(mpvio->packets_read == 1);
NET *net= &mpvio->thd->net;
mpvio->status= MPVIO_EXT::FAILURE; // the status is no longer RESTART
--- 7083,7090 ----
DBUG_ASSERT(mpvio->packets_written == 1);
DBUG_ASSERT(mpvio->packets_read == 1);
NET *net= &mpvio->thd->net;
+ static uchar switch_plugin_request_buf[]= { 254 };
+
mpvio->status= MPVIO_EXT::FAILURE; // the status is no longer RESTART
***************
*** 7061,7074 ****
we send an old "short 4.0 scramble request", if we need to request a
client to use 4.0 auth plugin (short scramble) and the scramble was
already sent to the client
*/
bool switch_from_long_to_short_scramble=
! my_strcasecmp(system_charset_info, native_password_plugin_name.str,
! mpvio->cached_client_reply.plugin) == 0 &&
client_auth_plugin == old_password_plugin_name.str;
if (switch_from_long_to_short_scramble)
! return my_net_write(net, switch_plugin_request_buf, 1) ||
net_flush(net);
/*
--- 7097,7114 ----
we send an old "short 4.0 scramble request", if we need to request a
client to use 4.0 auth plugin (short scramble) and the scramble was
already sent to the client
+
+ below, cached_client_reply.plugin is the plugin name that client has used,
+ client_auth_plugin is derived from mysql.user table, for the given
+ user account, it's the plugin that the client need to use to login.
*/
bool switch_from_long_to_short_scramble=
! native_password_plugin_name.str == mpvio->cached_client_reply.plugin &&
client_auth_plugin == old_password_plugin_name.str;
if (switch_from_long_to_short_scramble)
! return secure_auth(mpvio->thd) ||
! my_net_write(net, switch_plugin_request_buf, 1) ||
net_flush(net);
/*
***************
*** 7077,7084 ****
ask an old 4.0 client to use the new 4.1 authentication protocol.
*/
bool switch_from_short_to_long_scramble=
! my_strcasecmp(system_charset_info, old_password_plugin_name.str,
! mpvio->cached_client_reply.plugin) == 0 &&
client_auth_plugin == native_password_plugin_name.str;
if (switch_from_short_to_long_scramble)
--- 7117,7123 ----
ask an old 4.0 client to use the new 4.1 authentication protocol.
*/
bool switch_from_short_to_long_scramble=
! old_password_plugin_name.str == mpvio->cached_client_reply.plugin &&
client_auth_plugin == native_password_plugin_name.str;
if (switch_from_short_to_long_scramble)
***************
*** 7111,7122 ****
static bool find_mpvio_user(MPVIO_EXT *mpvio, Security_context *sctx)
{
pthread_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)))
{
mpvio->acl_user= acl_user_tmp->copy(mpvio->thd->mem_root);
break;
--- 7150,7163 ----
static bool find_mpvio_user(MPVIO_EXT *mpvio, Security_context *sctx)
{
+ DBUG_ASSERT(mpvio->acl_user == 0);
+
pthread_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))
{
mpvio->acl_user= acl_user_tmp->copy(mpvio->thd->mem_root);
break;
***************
*** 7131,7142 ****
}
/* user account requires non-default plugin and the client is too old */
! if (my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
! native_password_plugin_name.str) &&
! my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
! old_password_plugin_name.str) &&
!(mpvio->thd->client_capabilities & CLIENT_PLUGIN_AUTH))
{
my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
general_log_print(mpvio->thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
return 1;
--- 7172,7185 ----
}
/* 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))
{
+ 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));
return 1;
***************
*** 7203,7219 ****
char *ptr= db + db_len + 1;
- /* Convert database and user names to utf8 */
- db_buff[db_len= copy_and_convert(db_buff, sizeof(db_buff)-1,
- system_charset_info, db, db_len,
- thd->charset(), &dummy_errors)]= 0;
- db= db_buff;
-
- user_buff[user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
- system_charset_info, user, user_len,
- thd->charset(), &dummy_errors)]= '\0';
- user= user_buff;
-
if (ptr+1 < end)
{
uint cs_number= uint2korr(ptr);
--- 7246,7251 ----
char *ptr= db + db_len + 1;
if (ptr+1 < end)
{
uint cs_number= uint2korr(ptr);
***************
*** 7221,7234 ****
thd->update_charset();
}
! if (!(sctx->user= my_strdup(user, MYF(MY_WME))))
return 1;
/* Clear variables that are allocated */
thd->user_connect= 0;
strmake(sctx->priv_user, sctx->user, USERNAME_LENGTH);
! if (thd->make_lex_string(&mpvio->db, db, db_len, 0) == 0)
return 1; /* The error is set by make_lex_string(). */
/*
--- 7253,7274 ----
thd->update_charset();
}
! /* 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);
!
! user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
! system_charset_info, user, user_len,
! thd->charset(), &dummy_errors);
!
! if (!(sctx->user= my_strndup(user_buff, user_len, MYF(MY_WME))))
return 1;
/* Clear variables that are allocated */
thd->user_connect= 0;
strmake(sctx->priv_user, sctx->user, USERNAME_LENGTH);
! if (thd->make_lex_string(&mpvio->db, db_buff, db_len, 0) == 0)
return 1; /* The error is set by make_lex_string(). */
/*
***************
*** 7260,7265 ****
}
}
else
if (thd->client_capabilities & CLIENT_SECURE_CONNECTION)
client_plugin= native_password_plugin_name.str;
else
--- 7300,7306 ----
}
}
else
+ {
if (thd->client_capabilities & CLIENT_SECURE_CONNECTION)
client_plugin= native_password_plugin_name.str;
else
***************
*** 7274,7279 ****
if (mpvio->acl_user->auth_string.length == 0)
mpvio->acl_user->plugin= old_password_plugin_name;
}
/* remember the data part of the packet, to present it to plugin in read_packet() */
mpvio->cached_client_reply.pkt= passwd;
--- 7315,7321 ----
if (mpvio->acl_user->auth_string.length == 0)
mpvio->acl_user->plugin= old_password_plugin_name;
}
+ }
/* remember the data part of the packet, to present it to plugin in read_packet() */
mpvio->cached_client_reply.pkt= passwd;
***************
*** 7362,7368 ****
char *user= end;
char *passwd= strend(user)+1;
! uint user_len= passwd - user - 1;
char *db= passwd;
char db_buff[NAME_LEN + 1]; // buffer to store db in utf8
char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
--- 7404,7410 ----
char *user= end;
char *passwd= strend(user)+1;
! uint user_len= passwd - user - 1, db_len;
char *db= passwd;
char db_buff[NAME_LEN + 1]; // buffer to store db in utf8
char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
***************
*** 7380,7389 ****
*/
uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
(uchar)(*passwd++) : strlen(passwd);
! db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
! db + passwd_len + 1 : 0;
/* strlen() can't be easily deleted without changing protocol */
! uint db_len= db ? strlen(db) : 0;
if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)
return packet_error;
--- 7422,7439 ----
*/
uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
(uchar)(*passwd++) : strlen(passwd);
!
! if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
! {
! db= db + passwd_len + 1;
/* strlen() can't be easily deleted without changing protocol */
! db_len= strlen(db);
! }
! else
! {
! db= 0;
! db_len= 0;
! }
if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)
return packet_error;
***************
*** 7393,7414 ****
/* Since 4.1 all database names are stored in utf8 */
if (db)
{
! db_buff[db_len= copy_and_convert(db_buff, sizeof(db_buff)-1,
! system_charset_info,
! db, db_len,
! thd->charset(), &dummy_errors)]= 0;
db= db_buff;
}
! user_buff[user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
system_charset_info, user, user_len,
! thd->charset(), &dummy_errors)]= '\0';
user= user_buff;
/* If username starts and ends in "'", chop them off */
if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'')
{
- user[user_len-1]= 0;
user++;
user_len-= 2;
}
--- 7443,7461 ----
/* Since 4.1 all database names are stored in utf8 */
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_buff;
}
! user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
system_charset_info, user, user_len,
! thd->charset(), &dummy_errors);
user= user_buff;
/* If username starts and ends in "'", chop them off */
if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'')
{
user++;
user_len-= 2;
}
***************
*** 7419,7425 ****
return packet_error; /* The error is set by make_lex_string(). */
if (sctx->user)
x_free(sctx->user);
! if (!(sctx->user= my_strdup(user, MYF(MY_WME))))
return packet_error; /* The error is set by my_strdup(). */
/*
--- 7466,7472 ----
return packet_error; /* The error is set by make_lex_string(). */
if (sctx->user)
x_free(sctx->user);
! if (!(sctx->user= my_strndup(user, user_len, MYF(MY_WME))))
return packet_error; /* The error is set by my_strdup(). */
/*
***************
*** 7446,7451 ****
return packet_error;
}
else
if (thd->client_capabilities & CLIENT_SECURE_CONNECTION)
client_plugin= native_password_plugin_name.str;
else
--- 7493,7499 ----
return packet_error;
}
else
+ {
if (thd->client_capabilities & CLIENT_SECURE_CONNECTION)
client_plugin= native_password_plugin_name.str;
else
***************
*** 7460,7465 ****
if (mpvio->acl_user->auth_string.length == 0)
mpvio->acl_user->plugin= old_password_plugin_name;
}
/*
if the acl_user needs a different plugin to authenticate
--- 7508,7514 ----
if (mpvio->acl_user->auth_string.length == 0)
mpvio->acl_user->plugin= old_password_plugin_name;
}
+ }
/*
if the acl_user needs a different plugin to authenticate
***************
*** 7574,7580 ****
{
/*
plugin wants to read the data without sending anything first.
! send an empty packet, to start a handshake
*/
if (server_mpvio_write_packet(mpvio, 0, 0))
pkt_len= packet_error;
--- 7624,7630 ----
{
/*
plugin wants to read the data without sending anything first.
! send an empty packet to force a server handshake packet to be sent
*/
if (server_mpvio_write_packet(mpvio, 0, 0))
pkt_len= packet_error;
***************
*** 7661,7667 ****
}
! static int acl_check_ssl(THD *thd, ACL_USER *acl_user)
{
#if defined(HAVE_OPENSSL)
Vio *vio=thd->net.vio;
--- 7711,7717 ----
}
! static bool acl_check_ssl(THD *thd, ACL_USER *acl_user)
{
#if defined(HAVE_OPENSSL)
Vio *vio=thd->net.vio;
***************
*** 7766,7771 ****
return 1;
}
/**
Perform the handshake, authorize the client and update thd sctx variables.
--- 7816,7871 ----
return 1;
}
+ static int do_auth_once(THD *thd, LEX_STRING *auth_plugin_name,
+ MPVIO_EXT *mpvio)
+ {
+ int res= CR_OK, old_status= MPVIO_EXT::FAILURE;
+ bool unlock_plugin= false;
+ plugin_ref plugin;
+
+ if (auth_plugin_name->str == native_password_plugin_name.str)
+ plugin= native_password_plugin;
+ else
+ #ifndef EMBEDDED_LIBRARY
+ if (auth_plugin_name->str == old_password_plugin_name.str)
+ plugin= old_password_plugin;
+ else
+ if ((plugin= my_plugin_lock_by_name(thd, auth_plugin_name,
+ MYSQL_AUTHENTICATION_PLUGIN)))
+ unlock_plugin= true;
+ #endif
+
+ mpvio->plugin= plugin;
+ old_status= mpvio->status;
+
+ if (plugin)
+ {
+ st_mysql_auth *auth= (st_mysql_auth*)plugin_decl(plugin)->info;
+ res= auth->authenticate_user(mpvio, &mpvio->auth_info);
+
+ if (unlock_plugin)
+ plugin_unlock(thd, plugin);
+ }
+ else
+ {
+ /* Server cannot load the required plugin. */
+ my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), auth_plugin_name->str);
+ res= CR_ERROR;
+ }
+
+ /*
+ If the status was MPVIO_EXT::RESTART before the authenticate_user() call
+ it can never be MPVIO_EXT::RESTART after the call, because any call
+ to write_packet() or read_packet() will reset the status.
+
+ But (!) if a plugin never called a read_packet() or write_packet(), the
+ status will stay unchanged. We'll fix it, by resetting the status here.
+ */
+ if (old_status == MPVIO_EXT::RESTART && mpvio->status == MPVIO_EXT::RESTART)
+ mpvio->status= MPVIO_EXT::FAILURE; // reset to the default
+
+ return res;
+ }
/**
Perform the handshake, authorize the client and update thd sctx variables.
***************
*** 7782,7798 ****
@retval 1 error
*/
! int acl_authenticate(THD *thd, uint connect_errors, uint com_change_user_pkt_len)
{
! DBUG_ENTER("acl_authenticate");
! int res= CR_OK, old_status= MPVIO_EXT::FAILURE;
! plugin_ref plugin;
MPVIO_EXT mpvio;
- st_mysql_auth *auth;
LEX_STRING *auth_plugin_name= default_auth_plugin_name;
- bool unlock_plugin;
enum enum_server_command command= com_change_user_pkt_len ? COM_CHANGE_USER
: COM_CONNECT;
compile_time_assert(MYSQL_USERNAME_LENGTH == USERNAME_LENGTH);
--- 7882,7895 ----
@retval 1 error
*/
! bool acl_authenticate(THD *thd, uint connect_errors, uint com_change_user_pkt_len)
{
! int res= CR_OK;
MPVIO_EXT mpvio;
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);
***************
*** 7804,7812 ****
mpvio.connect_errors= connect_errors;
mpvio.status= MPVIO_EXT::FAILURE;
! if (com_change_user_pkt_len == 0)
! thd->scramble[SCRAMBLE_LENGTH]= 1; // it means - there is no scramble yet
! else
{
mpvio.packets_written++; // pretend that a server handshake packet was sent
mpvio.packets_read++; // take COM_CHANGE_USER packet into account
--- 7901,7907 ----
mpvio.connect_errors= connect_errors;
mpvio.status= MPVIO_EXT::FAILURE;
! 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
***************
*** 7816,7882 ****
DBUG_ASSERT(mpvio.status == MPVIO_EXT::RESTART ||
mpvio.status == MPVIO_EXT::SUCCESS);
- /*
- we skip the first step of the authentication -
- the one that starts a default plugin, sends the handshake packet with the
- scramble and reads the packet with the user name.
- in COM_CHANGE_USER the client already has the scramble and we already
- know the user name
- */
- goto skip_first;
}
-
- retry:
- unlock_plugin= false;
- if (auth_plugin_name->str == native_password_plugin_name.str)
- plugin= native_password_plugin;
else
- #ifndef EMBEDDED_LIBRARY
- if (auth_plugin_name->str == old_password_plugin_name.str)
- plugin= old_password_plugin;
- else
- if ((plugin= my_plugin_lock_by_name(thd, auth_plugin_name,
- MYSQL_AUTHENTICATION_PLUGIN)))
- unlock_plugin= true;
- else
- #endif
{
! /* Server cannot load required plugin. */
! my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), auth_plugin_name->str);
! DBUG_RETURN(1);
! }
- mpvio.plugin= plugin;
- auth= (st_mysql_auth*)plugin_decl(plugin)->info;
-
- old_status= mpvio.status;
- res= auth->authenticate_user(&mpvio, &mpvio.auth_info);
-
- if (unlock_plugin)
- plugin_unlock(thd, plugin);
-
- skip_first:
/*
! restart the authentication, if needed.
! Note, that we only trust RESTART status if it wasn't set before
! the authentication. If it was - it can never be set after the call, as
! any read_packet() or write_packet() would've reset it. So, if it's
! was set before authenticate_user() and we see it here, it simply means
! that there was a restart, but a plugin never called read_packet() or
! write_packet() and what we see is the old status from before the
! authenticate_user() call.
*/
if (mpvio.status == MPVIO_EXT::RESTART)
{
- if (old_status == MPVIO_EXT::RESTART)
- mpvio.status= MPVIO_EXT::FAILURE; // reset to the default
- else
- {
DBUG_ASSERT(mpvio.acl_user);
auth_plugin_name= &mpvio.acl_user->plugin;
! goto retry;
! }
}
Security_context *sctx= thd->security_ctx;
--- 7911,7943 ----
DBUG_ASSERT(mpvio.status == MPVIO_EXT::RESTART ||
mpvio.status == MPVIO_EXT::SUCCESS);
}
else
{
! /* mark the thd as having no scramble yet */
! thd->scramble[SCRAMBLE_LENGTH]= 1;
/*
! perform the first authentication attempt, with the default plugin.
! This sends the server handshake packet, reads the client reply
! with a user name, and performs the authentication if everyone has used
! the correct plugin.
! */
! res= do_auth_once(thd, auth_plugin_name, &mpvio);
! }
! /*
! retry the authentication, if - after receiving the user name -
! we found that we need to switch to a non-default plugin
*/
if (mpvio.status == MPVIO_EXT::RESTART)
{
DBUG_ASSERT(mpvio.acl_user);
+ DBUG_ASSERT(command == COM_CHANGE_USER ||
+ my_strcasecmp(system_charset_info, auth_plugin_name->str,
+ mpvio.acl_user->plugin.str));
auth_plugin_name= &mpvio.acl_user->plugin;
! res= do_auth_once(thd, auth_plugin_name, &mpvio);
}
Security_context *sctx= thd->security_ctx;
***************
*** 7995,8002 ****
/* mysql_change_db() has pushed the error message. */
if (thd->user_connect)
{
- decrease_user_connections(thd->user_connect);
status_var_increment(thd->status_var.access_denied_errors);
thd->user_connect= 0;
}
DBUG_RETURN(1);
--- 8056,8063 ----
/* mysql_change_db() has pushed the error message. */
if (thd->user_connect)
{
status_var_increment(thd->status_var.access_denied_errors);
+ decrease_user_connections(thd->user_connect);
thd->user_connect= 0;
}
DBUG_RETURN(1);
***************
*** 8036,8059 ****
MPVIO_EXT *mpvio=(MPVIO_EXT*)vio;
THD *thd=mpvio->thd;
! /*
! let's check if the client has got the scramble already.
! That could've happened if another plugin has started the authentication,
! has sent the scramble, but after reading the user name the server has found
! that this particular user should be handled by this particular plugin.
! */
!
if (thd->scramble[SCRAMBLE_LENGTH])
! {
! /* no scramble was sent to the client yet, do it now */
! create_random_string(thd->scramble,
! pkt_len= SCRAMBLE_LENGTH, &thd->rand);
! pkt= (uchar*)thd->scramble;
! if (mpvio->write_packet(mpvio, pkt, pkt_len + 1))
return CR_ERROR;
- }
! /* ok, the client has got the scramble. read the reply and authenticate */
/*
<digression>
--- 8097,8111 ----
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);
!
! /* send it to the client */
! if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1))
return CR_ERROR;
! /* reply and authenticate */
/*
<digression>
***************
*** 8085,8091 ****
plugins are involved.
Anyway, it still looks simple from a plugin point of view:
! "the client has got the scramble, read the reply and authenticate".
All the magic is transparently handled by the server.
</digression>
*/
--- 8137,8143 ----
plugins are involved.
Anyway, it still looks simple from a plugin point of view:
! "send the scramble, read the reply and authenticate".
All the magic is transparently handled by the server.
</digression>
*/
***************
*** 8120,8136 ****
MPVIO_EXT *mpvio=(MPVIO_EXT*)vio;
THD *thd=mpvio->thd;
if (thd->scramble[SCRAMBLE_LENGTH])
! {
! /* no scramble was sent to the client yet, do it now */
! create_random_string(thd->scramble,
! pkt_len= SCRAMBLE_LENGTH, &thd->rand);
! pkt= (uchar*)thd->scramble;
! if (mpvio->write_packet(mpvio, pkt, pkt_len))
return CR_ERROR;
- }
! /* ok, the client has got the scramble. read the reply and authenticate */
if ((pkt_len= mpvio->read_packet(mpvio, &pkt)) < 0)
return CR_ERROR;
--- 8172,8186 ----
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);
!
! /* send it to the client */
! if (mpvio->write_packet(mpvio, (uchar*)thd->scramble, SCRAMBLE_LENGTH + 1))
return CR_ERROR;
! /* read the reply and authenticate */
if ((pkt_len= mpvio->read_packet(mpvio, &pkt)) < 0)
return CR_ERROR;
***************
*** 8149,8176 ****
if (pkt_len == 0) /* no password */
return info->auth_string[0] ? CR_ERROR : CR_OK;
! /*
! 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 (opt_secure_auth)
! {
! if (thd->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);
! general_log_print(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE),
! thd->security_ctx->user,
! thd->security_ctx->host_or_ip);
! }
! else
! {
! my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
! general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
! }
return CR_ERROR;
- }
info->password_used = 1;
--- 8199,8206 ----
if (pkt_len == 0) /* no password */
return info->auth_string[0] ? CR_ERROR : CR_OK;
! if (secure_auth(thd))
return CR_ERROR;
info->password_used = 1;
=== modified file 'sql/sql_acl.h'
*** sql/sql_acl.h 2010-02-19 08:18:09 +0000
--- sql/sql_acl.h 2010-03-26 11:32:46 +0000
***************
*** 169,175 ****
void acl_free(bool end=0);
ulong acl_get(const char *host, const char *ip,
const char *user, const char *db, my_bool db_is_pattern);
! int acl_authenticate(THD *thd, uint connect_errors, uint com_change_user_pkt_len);
bool acl_getroot(Security_context *sctx, char *user, char *host,
char *ip, char *db);
bool acl_check_host(const char *host, const char *ip);
--- 169,175 ----
void acl_free(bool end=0);
ulong acl_get(const char *host, const char *ip,
const char *user, const char *db, my_bool db_is_pattern);
! bool acl_authenticate(THD *thd, uint connect_errors, uint com_change_user_pkt_len);
bool acl_getroot(Security_context *sctx, char *user, char *host,
char *ip, char *db);
bool acl_check_host(const char *host, const char *ip);
=== modified file 'sql/sql_parse.cc'
*** sql/sql_parse.cc 2010-03-19 20:29:42 +0000
--- sql/sql_parse.cc 2010-03-26 11:32:46 +0000
***************
*** 1115,1122 ****
x_free(thd->security_ctx->user);
*thd->security_ctx= save_security_ctx;
thd->user_connect= save_user_connect;
! thd->db= save_db;
! thd->db_length= save_db_length;
thd->variables.character_set_client= save_character_set_client;
thd->variables.collation_connection= save_collation_connection;
thd->variables.character_set_results= save_character_set_results;
--- 1115,1121 ----
x_free(thd->security_ctx->user);
*thd->security_ctx= save_security_ctx;
thd->user_connect= save_user_connect;
! thd->reset_db(save_db, save_db_length);
thd->variables.character_set_client= save_character_set_client;
thd->variables.collation_connection= save_collation_connection;
thd->variables.character_set_results= save_character_set_results;
References