Commit 46540a72 authored by Nikita Malyavin's avatar Nikita Malyavin

MDEV-12320 configurable default authentication plugin for the server

* Add a new cmdline-only variable "default_auth_plugin".
* A default plugin is locked at the server init and unlocked at the deinit
  stages. This means that mysql_native_password and old_password_plugin, when
  default, are locked/unlocked twice.
parent 9a9d93e0
......@@ -229,6 +229,9 @@ The following specify which files/extra groups are read (specified before remain
--deadlock-timeout-short=#
Short timeout for the two-step deadlock detection (in
microseconds)
--default-auth-plugin[=name]
Default plugin, that will be tried first when
authenticating new connections
--default-password-lifetime=#
This defines the global password expiration policy. 0
means automatic password expiration is disabled. If the
......@@ -1656,6 +1659,7 @@ deadlock-search-depth-long 15
deadlock-search-depth-short 4
deadlock-timeout-long 50000000
deadlock-timeout-short 10000
default-auth-plugin mysql_native_password
default-password-lifetime 0
default-regex-flags
default-storage-engine myisam
......
......@@ -18,6 +18,10 @@ connect(localhost,test1,wrong_pwd,test,MASTER_MYPORT,MASTER_MYSOCK);
connect con3, localhost, test1, wrong_pwd;
ERROR 28000: Access denied for user 'test1'@'localhost' (using password: NO)
connection default;
select "change_user success" as "result";
result
change_user success
ERROR 28000: Access denied for user 'test1'@'localhost' (using password: NO)
create function have_ssl() returns char(3)
return (select if(variable_value > '','yes','no') as 'have_ssl'
from information_schema.session_status
......
[normal]
[default]
--default-auth-plugin=parsec
......@@ -26,6 +26,14 @@ connect con3, localhost, test1, wrong_pwd;
connection default;
change_user test1,pwd,;
select "change_user success" as "result";
change_user root,,test;
--replace_result $MASTER_MYSOCK MASTER_MYSOCK $MASTER_MYPORT MASTER_MYPORT
--error ER_ACCESS_DENIED_ERROR
change_user test1,bad_pwd,test;
create function have_ssl() returns char(3)
return (select if(variable_value > '','yes','no') as 'have_ssl'
from information_schema.session_status
......
......@@ -842,6 +842,16 @@ NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME DEFAULT_AUTH_PLUGIN
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE VARCHAR
VARIABLE_COMMENT Default plugin, that will be tried first when authenticating new connections
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST NULL
READ_ONLY YES
COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME DEFAULT_MASTER_CONNECTION
VARIABLE_SCOPE SESSION ONLY
VARIABLE_TYPE VARCHAR
......
......@@ -80,7 +80,7 @@ const char *safe_vio_type_name(Vio *vio)
#include "sql_acl_getsort.ic"
static Lex_ident_plugin native_password_plugin_name=
Lex_ident_plugin native_password_plugin_name=
"mysql_native_password"_Lex_ident_plugin;
......@@ -88,9 +88,8 @@ static Lex_ident_plugin old_password_plugin_name=
"mysql_old_password"_Lex_ident_plugin;
/// @todo make it configurable
LEX_CSTRING *default_auth_plugin_name= &native_password_plugin_name;
plugin_ref default_auth_plugin;
const char *default_auth_plugin_name= native_password_plugin_name.str;
/*
Wildcard host, matches any hostname
*/
......@@ -2543,9 +2542,20 @@ bool acl_init(bool dont_read_acl_tables)
old_password_plugin= my_plugin_lock_by_name(0,
&old_password_plugin_name, MYSQL_AUTHENTICATION_PLUGIN);
Lex_cstring_strlen def_plugin_name(default_auth_plugin_name);
default_auth_plugin= my_plugin_lock_by_name(NULL, &def_plugin_name,
MYSQL_AUTHENTICATION_PLUGIN);
if (!native_password_plugin || !old_password_plugin)
DBUG_RETURN(1);
if (!default_auth_plugin)
{
sql_print_error("Default plugin %s could not be loaded",
default_auth_plugin_name);
DBUG_RETURN(1);
}
if (dont_read_acl_tables)
{
DBUG_RETURN(0); /* purecov: tested */
......@@ -2945,6 +2955,7 @@ void acl_free(bool end)
acl_cache->clear(1); /* purecov: inspected */
else
{
plugin_unlock(0, default_auth_plugin);
plugin_unlock(0, native_password_plugin);
plugin_unlock(0, old_password_plugin);
delete acl_cache;
......@@ -13480,7 +13491,6 @@ static bool send_server_handshake_packet(MPVIO_EXT *mpvio,
THD *thd= mpvio->auth_info.thd;
char *buff= (char *) my_alloca(1 + SERVER_VERSION_LENGTH + 1 + data_len + 64);
char scramble_buf[SCRAMBLE_LENGTH];
char *end= buff;
DBUG_ENTER("send_server_handshake_packet");
......@@ -14641,47 +14651,50 @@ static void make_ssl_info(THD *thd, LEX_CSTRING salt, char *info)
#endif
}
static int do_auth_once(THD *thd, const LEX_CSTRING *auth_plugin_name,
static int do_auth_once(THD *thd, plugin_ref plugin,
MPVIO_EXT *mpvio)
{
int res= CR_OK;
bool unlock_plugin= false;
plugin_ref plugin= get_auth_plugin(thd, *auth_plugin_name, &unlock_plugin);
mpvio->plugin= plugin;
mpvio->auth_info.user_name= NULL;
if (plugin)
{
st_mysql_auth *info= (st_mysql_auth *) plugin_decl(plugin)->info;
switch (info->interface_version >> 8) {
case 0x02:
res= info->authenticate_user(mpvio, &mpvio->auth_info);
break;
case 0x01:
{
MYSQL_SERVER_AUTH_INFO_0x0100 compat;
compat.downgrade(&mpvio->auth_info);
res= info->authenticate_user(mpvio, (MYSQL_SERVER_AUTH_INFO *)&compat);
compat.upgrade(&mpvio->auth_info);
}
break;
default: DBUG_ASSERT(0);
int res= CR_OK;
st_mysql_auth *info= (st_mysql_auth *) plugin_decl(plugin)->info;
switch (info->interface_version >> 8) {
case 0x02:
res= info->authenticate_user(mpvio, &mpvio->auth_info);
break;
case 0x01:
{
MYSQL_SERVER_AUTH_INFO_0x0100 compat;
compat.downgrade(&mpvio->auth_info);
res= info->authenticate_user(mpvio, (MYSQL_SERVER_AUTH_INFO *)&compat);
compat.upgrade(&mpvio->auth_info);
}
if (unlock_plugin)
plugin_unlock(thd, plugin);
break;
default: DBUG_ASSERT(0);
}
else
return res;
}
static int do_auth_once(THD *thd, const LEX_CSTRING *auth_plugin_name,
MPVIO_EXT *mpvio)
{
bool unlock_plugin= false;
plugin_ref plugin= get_auth_plugin(thd, *auth_plugin_name, &unlock_plugin);
if (unlikely(!plugin))
{
/* Server cannot load the required plugin. */
Host_errors errors;
errors.m_no_auth_plugin= 1;
inc_host_errors(mpvio->auth_info.thd->security_ctx->ip, &errors);
my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), auth_plugin_name->str);
res= CR_ERROR;
return CR_ERROR;
}
int res= do_auth_once(thd, plugin, mpvio);
if (unlock_plugin)
plugin_unlock(thd, plugin);
return res;
}
......@@ -14785,7 +14798,7 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len)
the correct plugin.
*/
res= do_auth_once(thd, default_auth_plugin_name, &mpvio);
res= do_auth_once(thd, default_auth_plugin, &mpvio);
}
PSI_CALL_set_connection_type(vio_type(thd->net.vio));
......
......@@ -4538,6 +4538,14 @@ static Sys_var_plugin Sys_enforce_storage_engine(
DEFAULT(&enforced_storage_engine), NO_MUTEX_GUARD, NOT_IN_BINLOG,
ON_CHECK(check_has_super));
extern const char *default_auth_plugin_name;
extern LEX_CSTRING native_password_plugin_name;
static Sys_var_charptr Sys_default_auth_plugin(
"default_auth_plugin", "Default plugin, that will be tried first when authenticating new connections",
READ_ONLY GLOBAL_VAR(default_auth_plugin_name), CMD_LINE(OPT_ARG),
DEFAULT(native_password_plugin_name.str),
NO_MUTEX_GUARD, NOT_IN_BINLOG);
#ifdef HAVE_REPLICATION
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment