Commit 7c40996c authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-12321 authentication plugin: SET PASSWORD support

Support SET PASSWORD for authentication plugins.

Authentication plugin API is extended with two optional methods:
* hash_password() is used to compute a password hash (or digest)
  from the plain-text password. This digest will be stored in mysql.user
  table
* preprocess_hash() is used to convert this digest into some memory
  representation that can be later used to authenticate a user.
  Build-in plugins convert the hash from hexadecimal or base64 to binary,
  to avoid doing it on every authentication attempt.

Note a change in behavior: when loading privileges (on startup or on
FLUSH PRIVILEGES) an account with an unknown plugin was loaded with a
warning (e.g. "Plugin 'foo' is not loaded"). But such an account could
not be used for authentication until the plugin is installed. Now an
account like that will not be loaded at all (with a warning, still).
Indeed, without plugin's preprocess_hash() method the server cannot know
how to load an account. Thus, if a new authentication plugin is
installed run-time, one might need FLUSH PRIVILEGES to activate all
existing accounts that were using this new plugin.
parent 14e181a4
......@@ -27,7 +27,7 @@
#include <mysql/plugin.h>
#define MYSQL_AUTHENTICATION_INTERFACE_VERSION 0x0201
#define MYSQL_AUTHENTICATION_INTERFACE_VERSION 0x0202
#include <mysql/plugin_auth_common.h>
......@@ -60,7 +60,8 @@ typedef struct st_mysql_server_auth_info
/**
A corresponding column value from the mysql.user table for the
matching account name
matching account name or the preprocessed value, if preprocess_hash
method is not NULL
*/
const char *auth_string;
......@@ -130,6 +131,47 @@ struct st_mysql_auth
used for authorization.
*/
int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info);
/**
Create a password hash (or digest) out of a plain-text password
Used in SET PASSWORD, GRANT, and CREATE USER to convert user specified
plain-text password into a value that will be stored in mysql.user table.
@see preprocess_hash
@param password plain-text password
@param password_length plain-text password length
@param hash the digest will be stored there
@param hash_length in: hash buffer size
out: the actual length of the hash
@return 0 for ok, 1 for error
Can be NULL.
*/
int (*hash_password)(const char *password, size_t password_length,
char *hash, size_t *hash_length);
/**
Prepare the password hash for authentication.
Password hash is stored in the authentication_string column of the
mysql.user table in a text form. If a plugin needs to preprocess the
value somehow before the authentication (e.g. convert from hex or base64
to binary), it can do it in this method. This way the conversion
will happen only once, not for every authentication attempt.
The value written to the out buffer will be cached and later made
available to the authenticate_user() method in the
MYSQL_SERVER_AUTH_INFO::auth_string[] buffer.
@return 0 for ok, 1 for error
Can be NULL, in this case the mysql.user.authentication_string value will
be given to the authenticate_user() method as is, unconverted.
*/
int (*preprocess_hash)(const char *hash, size_t hash_length,
unsigned char *out, size_t *out_length);
};
#ifdef __cplusplus
......
......@@ -561,4 +561,8 @@ struct st_mysql_auth
int interface_version;
const char *client_auth_plugin;
int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info);
int (*hash_password)(const char *password, size_t password_length,
char *hash, size_t *hash_length);
int (*preprocess_hash)(const char *hash, size_t hash_length,
unsigned char *out, size_t *out_length);
};
......@@ -7,11 +7,11 @@ localhost root Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
alter user CURRENT_USER;
select * from mysql.user where user = 'root' and host = 'localhost';
Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
localhost root Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y 0 0 0 0 N N 0.000000
localhost root Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y 0 0 0 0 mysql_native_password N N 0.000000
alter user CURRENT_USER();
select * from mysql.user where user = 'root' and host = 'localhost';
Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
localhost root Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y 0 0 0 0 N N 0.000000
localhost root Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y 0 0 0 0 mysql_native_password N N 0.000000
create user foo;
select * from mysql.user where user = 'foo';
Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
......@@ -61,13 +61,19 @@ select * from mysql.user where user = 'foo';
Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
% foo N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N N 0 0 0 0 mysql_native_password *88C89BE093D4ECF72D039F62EBB7477EA1FD4D63 N N 0.000000
alter user foo identified with 'somecoolplugin';
ERROR HY000: Operation ALTER USER failed for 'foo'@'%'
show warnings;
Level Code Message
Warning 1524 Plugin 'somecoolplugin' is not loaded
Error 1396 Operation ALTER USER failed for 'foo'@'%'
alter user foo identified with 'mysql_old_password';
select * from mysql.user where user = 'foo';
Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
% foo N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N N 0 0 0 0 somecoolplugin N N 0.000000
alter user foo identified with 'somecoolplugin' using 'somecoolpassphrase';
% foo N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N N 0 0 0 0 mysql_old_password N N 0.000000
alter user foo identified with 'mysql_old_password' using '0123456789ABCDEF';
select * from mysql.user where user = 'foo';
Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
% foo N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N N 0 0 0 0 somecoolplugin somecoolpassphrase N N 0.000000
% foo N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N N 0 0 0 0 mysql_old_password 0123456789ABCDEF N N 0.000000
# Test ssl related altering.
alter user foo identified by 'something' require SSL;
select * from mysql.user where user = 'foo';
......@@ -91,3 +97,4 @@ select * from mysql.user where user = 'foo';
Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Create_user_priv Event_priv Trigger_priv Create_tablespace_priv Delete_history_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections max_user_connections plugin authentication_string password_expired is_role default_role max_statement_time
% foo N N N N N N N N N N N N N N N Y N N N N N N N N N Y N N N N SPECIFIED text foo_issuer foo_subject 10 20 30 40 mysql_native_password *88C89BE093D4ECF72D039F62EBB7477EA1FD4D63 N N 0.000000
drop user foo;
update mysql.user set plugin='';
......@@ -53,10 +53,14 @@ select * from mysql.user where user = 'foo';
alter user foo identified by password '*88C89BE093D4ECF72D039F62EBB7477EA1FD4D63';
select * from mysql.user where user = 'foo';
--error ER_CANNOT_USER
alter user foo identified with 'somecoolplugin';
show warnings;
alter user foo identified with 'mysql_old_password';
select * from mysql.user where user = 'foo';
alter user foo identified with 'somecoolplugin' using 'somecoolpassphrase';
alter user foo identified with 'mysql_old_password' using '0123456789ABCDEF';
select * from mysql.user where user = 'foo';
--echo # Test ssl related altering.
......@@ -77,3 +81,5 @@ alter user foo with MAX_QUERIES_PER_HOUR 10
MAX_USER_CONNECTIONS 40;
select * from mysql.user where user = 'foo';
drop user foo;
update mysql.user set plugin='';
optimize table mysql.user;
Table Op Msg_type Msg_text
mysql.user optimize status OK
insert ignore mysql.user (user,plugin) values ('foo','bar'),('bar','bar'),('baz','bar');
insert ignore mysql.user (user,plugin) values ('foo','mysql_old_password'),('bar','mysql_old_password'),('baz','mysql_old_password');
Warnings:
Warning 1364 Field 'ssl_cipher' doesn't have a default value
Warning 1364 Field 'x509_issuer' doesn't have a default value
......@@ -10,15 +10,15 @@ Warning 1364 Field 'authentication_string' doesn't have a default value
flush privileges;
connect(localhost,u1,,test,MASTER_PORT,MASTER_SOCKET);
connect fail,localhost,u1;
ERROR HY000: Plugin 'bar' is not loaded
ERROR HY000: Server is running in --secure-auth mode, but 'u1'@'localhost' has a password in the old format; please change the password to the new format
connect(localhost,u2,,test,MASTER_PORT,MASTER_SOCKET);
connect fail,localhost,u2;
ERROR 28000: Access denied for user 'u2'@'localhost' (using password: NO)
connect(localhost,u2,password,test,MASTER_PORT,MASTER_SOCKET);
connect fail,localhost,u2,password;
ERROR 28000: Access denied for user 'u2'@'localhost' (using password: YES)
ERROR HY000: Plugin 'bar' is not loaded
ERROR HY000: Server is running in --secure-auth mode, but 'u1'@'localhost' has a password in the old format; please change the password to the new format
ERROR 28000: Access denied for user 'u2'@'localhost' (using password: NO)
ERROR 28000: Access denied for user 'u2'@'localhost' (using password: YES)
delete from mysql.user where plugin = 'bar';
delete from mysql.user where plugin = 'mysql_old_password';
flush privileges;
......@@ -7,11 +7,11 @@ source include/not_embedded.inc;
# the server requests a plugin
#
optimize table mysql.user;
insert ignore mysql.user (user,plugin) values ('foo','bar'),('bar','bar'),('baz','bar');
insert ignore mysql.user (user,plugin) values ('foo','mysql_old_password'),('bar','mysql_old_password'),('baz','mysql_old_password');
flush privileges;
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
--error ER_PLUGIN_IS_NOT_LOADED
--error ER_SERVER_IS_IN_SECURE_AUTH_MODE
connect (fail,localhost,u1);
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
......@@ -22,7 +22,7 @@ connect (fail,localhost,u2);
--error ER_ACCESS_DENIED_ERROR
connect (fail,localhost,u2,password);
--error ER_PLUGIN_IS_NOT_LOADED
--error ER_SERVER_IS_IN_SECURE_AUTH_MODE
change_user u1;
--error ER_ACCESS_DENIED_ERROR
......@@ -31,7 +31,7 @@ change_user u2;
--error ER_ACCESS_DENIED_ERROR
change_user u2,password;
delete from mysql.user where plugin = 'bar';
delete from mysql.user where plugin = 'mysql_old_password';
flush privileges;
update mysql.user set plugin='unix_socket';
flush privileges;
Warnings:
Warning 1524 Plugin 'unix_socket' is not loaded
Warning 1524 Plugin 'unix_socket' is not loaded
Warning 1524 Plugin 'unix_socket' is not loaded
Warning 1524 Plugin 'unix_socket' is not loaded
connect(localhost,USER,,test,MASTER_PORT,MASTER_SOCKET);
connect fail,localhost,$USER;
ERROR HY000: Plugin 'unix_socket' is not loaded
ERROR HY000: Plugin 'unix_socket' is not loaded
ERROR 28000: Access denied for user 'USER'@'localhost' (using password: NO)
ERROR 28000: Access denied for user 'USER'@'localhost' (using password: NO)
install plugin unix_socket soname 'auth_socket.so';
flush privileges;
connect(localhost,USER,,test,MASTER_PORT,MASTER_SOCKET);
ERROR 28000: Access denied for user 'USER'@'localhost'
ERROR 28000: Access denied for user 'USER'@'localhost'
......
......@@ -7,20 +7,26 @@
update mysql.user set plugin='unix_socket';
flush privileges;
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT $USER USER
--error ER_PLUGIN_IS_NOT_LOADED
# Make sure that the replace works, even if $USER is 'user' or something else
# that matches other parts of the error message.
let $replace=Access denied for user '$USER';
--echo connect(localhost,USER,,test,MASTER_PORT,MASTER_SOCKET);
--replace_result $replace "Access denied for user 'USER'"
--disable_query_log
--error ER_ACCESS_DENIED_ERROR
connect (fail,localhost,$USER);
--enable_query_log
--error ER_PLUGIN_IS_NOT_LOADED
--replace_result $replace "Access denied for user 'USER'"
--error ER_ACCESS_DENIED_ERROR
change_user $USER;
eval install plugin unix_socket soname '$AUTH_SOCKET_SO';
flush privileges;
# Make sure that the replace works, even if $USER is 'user' or something else
# that matches other parts of the error message.
--echo connect(localhost,USER,,test,MASTER_PORT,MASTER_SOCKET);
--let $replace=Access denied for user '$USER'
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT $replace "Access denied for user 'USER'"
--replace_result $replace "Access denied for user 'USER'"
--disable_query_log
--error ER_ACCESS_DENIED_NO_PASSWORD_ERROR
connect (fail,localhost,$USER);
......
......@@ -565,7 +565,7 @@ root localhost N
GRANT INSERT ON *.* TO CURRENT_USER();
SELECT user,host,password,plugin,authentication_string,insert_priv FROM user WHERE user=@u AND host=@h;
user host password plugin authentication_string insert_priv
root localhost Y
root localhost mysql_native_password Y
UPDATE user SET insert_priv='N' WHERE user=@u AND host=@h;
GRANT INSERT ON *.* TO CURRENT_USER() IDENTIFIED BY 'keksdose';
SELECT user,host,password,plugin,authentication_string,insert_priv FROM user WHERE user=@u AND host=@h;
......
......@@ -18,3 +18,84 @@ ERROR 42000: Access denied for user 'test'@'%' to database 'mysql'
connection default;
drop user test, foo;
drop role foo;
create user u1@h identified with 'mysql_native_password' using 'pwd';
ERROR HY000: Password hash should be a 41-digit hexadecimal number
create user u1@h identified with 'mysql_native_password' using password('pwd');
create user u2@h identified with 'mysql_native_password' using '*975B2CD4FF9AE554FE8AD33168FBFC326D2021DD';
create user u3@h identified with 'mysql_native_password';
set password for u3@h = 'pwd';
ERROR HY000: Password hash should be a 41-digit hexadecimal number
set password for u3@h = password('pwd');
create user u4@h identified with 'mysql_native_password';
set password for u4@h = '*975B2CD4FF9AE554FE8AD33168FBFC326D2021DD';
create user u5@h identified with 'mysql_old_password' using 'pwd';
ERROR HY000: Password hash should be a 16-digit hexadecimal number
create user u5@h identified with 'mysql_old_password' using password('pwd');
create user u6@h identified with 'mysql_old_password' using '78a302dd267f6044';
create user u7@h identified with 'mysql_old_password';
set password for u7@h = 'pwd';
ERROR HY000: Password hash should be a 41-digit hexadecimal number
set password for u7@h = old_password('pwd');
create user u8@h identified with 'mysql_old_password';
set password for u8@h = '78a302dd267f6044';
select user,host,password,plugin,authentication_string from mysql.user where host='h';
user host password plugin authentication_string
u1 h mysql_native_password *975B2CD4FF9AE554FE8AD33168FBFC326D2021DD
u2 h mysql_native_password *975B2CD4FF9AE554FE8AD33168FBFC326D2021DD
u3 h mysql_native_password *975B2CD4FF9AE554FE8AD33168FBFC326D2021DD
u4 h mysql_native_password *975B2CD4FF9AE554FE8AD33168FBFC326D2021DD
u5 h mysql_old_password 78a302dd267f6044
u6 h mysql_old_password 78a302dd267f6044
u7 h mysql_old_password 78a302dd267f6044
u8 h mysql_old_password 78a302dd267f6044
update mysql.user set authentication_string='bad' where user='u1';
update mysql.user set authentication_string='bad' where user='u5';
update mysql.user set plugin='nonexistent' where user='u8';
flush privileges;
Warnings:
Error 1372 Password hash should be a 41-digit hexadecimal number
Error 1372 Password hash should be a 16-digit hexadecimal number
Warning 1524 Plugin 'nonexistent' is not loaded
show create user u1@h;
ERROR 28000: Can't find any matching row in the user table
show create user u2@h;
CREATE USER for u2@h
CREATE USER 'u2'@'h' IDENTIFIED BY PASSWORD '*975B2CD4FF9AE554FE8AD33168FBFC326D2021DD'
show create user u3@h;
CREATE USER for u3@h
CREATE USER 'u3'@'h' IDENTIFIED BY PASSWORD '*975B2CD4FF9AE554FE8AD33168FBFC326D2021DD'
show create user u4@h;
CREATE USER for u4@h
CREATE USER 'u4'@'h' IDENTIFIED BY PASSWORD '*975B2CD4FF9AE554FE8AD33168FBFC326D2021DD'
show create user u5@h;
ERROR 28000: Can't find any matching row in the user table
show create user u6@h;
CREATE USER for u6@h
CREATE USER 'u6'@'h' IDENTIFIED BY PASSWORD '78a302dd267f6044'
show create user u7@h;
CREATE USER for u7@h
CREATE USER 'u7'@'h' IDENTIFIED BY PASSWORD '78a302dd267f6044'
show create user u8@h;
ERROR 28000: Can't find any matching row in the user table
grant select on *.* to u1@h;
ERROR 28000: Can't find any matching row in the user table
grant select on *.* to u2@h;
grant select on *.* to u3@h;
grant select on *.* to u4@h;
grant select on *.* to u5@h;
ERROR 28000: Can't find any matching row in the user table
grant select on *.* to u6@h;
grant select on *.* to u7@h;
grant select on *.* to u8@h;
ERROR 28000: Can't find any matching row in the user table
select user,select_priv,plugin,authentication_string from mysql.user where user like 'u_';
user select_priv plugin authentication_string
u1 N mysql_native_password bad
u2 Y mysql_native_password *975B2CD4FF9AE554FE8AD33168FBFC326D2021DD
u3 Y mysql_native_password *975B2CD4FF9AE554FE8AD33168FBFC326D2021DD
u4 Y mysql_native_password *975B2CD4FF9AE554FE8AD33168FBFC326D2021DD
u5 N mysql_old_password bad
u6 Y mysql_old_password 78a302dd267f6044
u7 Y mysql_old_password 78a302dd267f6044
u8 N nonexistent 78a302dd267f6044
drop user u1@h, u2@h, u3@h, u4@h, u5@h, u6@h, u7@h, u8@h;
......@@ -23,3 +23,63 @@ show grants for foo@'%'; # user
drop user test, foo;
drop role foo;
#
# MDEV-12321 authentication plugin: SET PASSWORD support
#
error ER_PASSWD_LENGTH;
create user u1@h identified with 'mysql_native_password' using 'pwd';
create user u1@h identified with 'mysql_native_password' using password('pwd');
let p=`select password('pwd')`;
eval create user u2@h identified with 'mysql_native_password' using '$p';
create user u3@h identified with 'mysql_native_password';
error ER_PASSWD_LENGTH;
set password for u3@h = 'pwd';
set password for u3@h = password('pwd');
create user u4@h identified with 'mysql_native_password';
eval set password for u4@h = '$p';
error ER_PASSWD_LENGTH;
create user u5@h identified with 'mysql_old_password' using 'pwd';
create user u5@h identified with 'mysql_old_password' using password('pwd');
let p=`select old_password('pwd')`;
eval create user u6@h identified with 'mysql_old_password' using '$p';
create user u7@h identified with 'mysql_old_password';
error ER_PASSWD_LENGTH;
set password for u7@h = 'pwd';
set password for u7@h = old_password('pwd');
create user u8@h identified with 'mysql_old_password';
eval set password for u8@h = '$p';
sorted_result;
select user,host,password,plugin,authentication_string from mysql.user where host='h';
# test with invalid entries
update mysql.user set authentication_string='bad' where user='u1';
update mysql.user set authentication_string='bad' where user='u5';
update mysql.user set plugin='nonexistent' where user='u8';
flush privileges;
# invalid entries are skipped, users don't exist
error ER_PASSWORD_NO_MATCH;
show create user u1@h;
show create user u2@h;
show create user u3@h;
show create user u4@h;
error ER_PASSWORD_NO_MATCH;
show create user u5@h;
show create user u6@h;
show create user u7@h;
error ER_PASSWORD_NO_MATCH;
show create user u8@h;
#grants don't work either
error ER_PASSWORD_NO_MATCH;
grant select on *.* to u1@h;
grant select on *.* to u2@h;
grant select on *.* to u3@h;
grant select on *.* to u4@h;
error ER_PASSWORD_NO_MATCH;
grant select on *.* to u5@h;
grant select on *.* to u6@h;
grant select on *.* to u7@h;
error ER_PASSWORD_NO_MATCH;
grant select on *.* to u8@h;
select user,select_priv,plugin,authentication_string from mysql.user where user like 'u_';
# but they still can be dropped
drop user u1@h, u2@h, u3@h, u4@h, u5@h, u6@h, u7@h, u8@h;
......@@ -149,11 +149,13 @@ new_user test_plugin_server new_dest
plug_dest mysql_native_password *939AEE68989794C0F408277411C26055CDF41119
UPDATE mysql.user SET plugin='new_plugin_server' WHERE user='new_user';
FLUSH PRIVILEGES;
Warnings:
Warning 1524 Plugin 'new_plugin_server' is not loaded
SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
user plugin authentication_string
new_user new_plugin_server new_dest
plug_dest mysql_native_password *939AEE68989794C0F408277411C26055CDF41119
ERROR HY000: Plugin 'new_plugin_server' is not loaded
ERROR 28000: Access denied for user 'new_user'@'localhost' (using password: YES)
UPDATE mysql.user SET plugin='test_plugin_server' WHERE user='new_user';
UPDATE mysql.user SET USER='new_dest' WHERE user='plug_dest';
FLUSH PRIVILEGES;
......
......@@ -141,7 +141,7 @@ FLUSH PRIVILEGES;
--sorted_result
SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
--disable_query_log
--error ER_PLUGIN_IS_NOT_LOADED
--error ER_ACCESS_DENIED_ERROR
connect(plug_user,localhost,new_user,new_dest);
--enable_query_log
UPDATE mysql.user SET plugin='test_plugin_server' WHERE user='new_user';
......
......@@ -10,10 +10,10 @@ create user foo2@test identified by 'password';
show create user foo2@test;
CREATE USER for foo2@test
CREATE USER 'foo2'@'test' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19'
alter user foo2@test identified with 'someplugin' as 'somepassword';
alter user foo2@test identified with 'mysql_old_password' as '0123456789ABCDEF';
show create user foo2@test;
CREATE USER for foo2@test
CREATE USER 'foo2'@'test' IDENTIFIED VIA someplugin USING 'somepassword'
CREATE USER 'foo2'@'test' IDENTIFIED BY PASSWORD '0123456789ABCDEF'
create user foo3@test require SSL;
show create user foo3@test;
CREATE USER for foo3@test
......
......@@ -9,7 +9,7 @@ show create user foo@test;
create user foo2@test identified by 'password';
show create user foo2@test;
alter user foo2@test identified with 'someplugin' as 'somepassword';
alter user foo2@test identified with 'mysql_old_password' as '0123456789ABCDEF';
show create user foo2@test;
create user foo3@test require SSL;
......
......@@ -711,9 +711,7 @@ disconnect con2;
DROP USER user2@localhost;
DROP DATABASE db1;
create user foo@local_ost;
create user foo@`local\_ost`;
update mysql.user set plugin='foobar' where host='local\\_ost';
flush privileges;
create user foo@`local\_ost` identified via mysql_old_password using '0123456789ABCDEF';
create database foodb;
grant create routine on foodb.* to foo@local_ost;
connect con1,localhost,foo;
......
......@@ -977,16 +977,7 @@ DROP DATABASE db1;
# Bug#27407480: AUTOMATIC_SP_PRIVILEGES REQUIRES NEED THE INSERT PRIVILEGES FOR MYSQL.USER TABLE
#
create user foo@local_ost;
#
# Create a user with an authentification plugin 'foobar'.
# Instead of using a normal "CREATE USER <user> IDENTIFIED VIA <plugin>"
# we do CREATE (without VIA) followed by UPDATE and FLUSH.
# This is to avoid installing a real plugin and thus avoid the test dependency.
# We won't login under this user in the below test, so this is fine.
#
create user foo@`local\_ost`;
update mysql.user set plugin='foobar' where host='local\\_ost';
flush privileges;
create user foo@`local\_ost` identified via mysql_old_password using '0123456789ABCDEF';
create database foodb;
grant create routine on foodb.* to foo@local_ost;
connect con1,localhost,foo;
......
......@@ -22,10 +22,10 @@ ed25519_password(NULL)
NULL
select * from information_schema.plugins where plugin_name='ed25519';
PLUGIN_NAME ed25519
PLUGIN_VERSION 1.0
PLUGIN_VERSION 1.1
PLUGIN_STATUS ACTIVE
PLUGIN_TYPE AUTHENTICATION
PLUGIN_TYPE_VERSION 2.1
PLUGIN_TYPE_VERSION 2.2
PLUGIN_LIBRARY auth_ed25519.so
PLUGIN_LIBRARY_VERSION 1.13
PLUGIN_AUTHOR Sergei Golubchik
......@@ -33,11 +33,30 @@ PLUGIN_DESCRIPTION Elliptic curve ED25519 based authentication
PLUGIN_LICENSE GPL
LOAD_OPTION ON
PLUGIN_MATURITY Stable
PLUGIN_AUTH_VERSION 1.0
PLUGIN_AUTH_VERSION 1.1
create user test1@localhost identified via ed25519 using 'ZIgUREUg5PVgQ6LskhXmO+eZLS0nC8be6HPjYWR4YJY';
show grants for test1@localhost;
Grants for test1@localhost
GRANT USAGE ON *.* TO 'test1'@'localhost' IDENTIFIED VIA ed25519 USING 'ZIgUREUg5PVgQ6LskhXmO+eZLS0nC8be6HPjYWR4YJY'
drop user test1@localhost;
create user test1@localhost identified via ed25519 using password('foo');
show grants for test1@localhost;
Grants for test1@localhost
GRANT USAGE ON *.* TO 'test1'@'localhost' IDENTIFIED VIA ed25519 USING 'vubFBzIrapbfHct1/J72dnUryz5VS7lA6XHH8sIx4TI'
select ed25519_password('foo');
ed25519_password('foo')
vubFBzIrapbfHct1/J72dnUryz5VS7lA6XHH8sIx4TI
set password for test1@localhost = password('bar');
show create user test1@localhost;
CREATE USER for test1@localhost
CREATE USER 'test1'@'localhost' IDENTIFIED VIA ed25519 USING 'pfzkeWMzkTefY1oshXS+/kATeN51M+4jxi3/cbyTd10'
select ed25519_password('bar');
ed25519_password('bar')
pfzkeWMzkTefY1oshXS+/kATeN51M+4jxi3/cbyTd10
set password for test1@localhost = 'ZIgUREUg5PVgQ6LskhXmO+eZLS0nC8be6HPjYWR4YJY';
show create user test1@localhost;
CREATE USER for test1@localhost
CREATE USER 'test1'@'localhost' IDENTIFIED VIA ed25519 USING 'ZIgUREUg5PVgQ6LskhXmO+eZLS0nC8be6HPjYWR4YJY'
connect(localhost,test1,public,test,PORT,SOCKET);
connect con1, localhost, test1, public;
ERROR 28000: Access denied for user 'test1'@'localhost' (using password: YES)
......
......@@ -157,6 +157,7 @@ set global strict_password_validation=1;
drop user foo1;
create role r1;
drop role r1;
flush privileges;
uninstall plugin simple_password_check;
create user foo1 identified by 'pwd';
drop user foo1;
......@@ -28,6 +28,15 @@ query_vertical select * from information_schema.plugins where plugin_name='ed255
let $pwd=`select ed25519_password("secret")`;
eval create user test1@localhost identified via ed25519 using '$pwd';
show grants for test1@localhost;
drop user test1@localhost;
create user test1@localhost identified via ed25519 using password('foo');
show grants for test1@localhost;
select ed25519_password('foo');
set password for test1@localhost = password('bar');
show create user test1@localhost;
select ed25519_password('bar');
eval set password for test1@localhost = '$pwd';
show create user test1@localhost;
replace_result $MASTER_MYPORT PORT $MASTER_MYSOCK SOCKET;
error ER_ACCESS_DENIED_ERROR;
......
......@@ -115,6 +115,8 @@ drop user foo1;
create role r1;
drop role r1;
flush privileges;
uninstall plugin simple_password_check;
create user foo1 identified by 'pwd';
......
......@@ -289,7 +289,6 @@ DROP TRIGGER tr1;
--echo
--echo
--echo ******************** EVENTS ********************
GRANT EVENT ON *.* TO 'root'@'localhost';
INSERT INTO t1 VALUES(1, 'test1');
CREATE EVENT e1 ON SCHEDULE EVERY '1' SECOND COMMENT 'e_second_comment' DO DELETE FROM t1;
--source suite/rpl/include/rpl_mixed_check_event.inc
......
......@@ -328,4 +328,5 @@ Grantor
root@localhost
connection master;
DROP USER user_bug27606@localhost;
update mysql.user set plugin='';
include/rpl_end.inc
......@@ -676,7 +676,6 @@ DROP TRIGGER tr1;
******************** EVENTS ********************
GRANT EVENT ON *.* TO 'root'@'localhost';
INSERT INTO t1 VALUES(1, 'test1');
CREATE EVENT e1 ON SCHEDULE EVERY '1' SECOND COMMENT 'e_second_comment' DO DELETE FROM t1;
SHOW EVENTS;
......@@ -1098,8 +1097,6 @@ master-bin.000001 # Query # # use `test_rpl`; DELETE FROM t2
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test_rpl`; DROP TRIGGER tr1
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test_rpl`; GRANT EVENT ON *.* TO 'root'@'localhost'
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test_rpl`; INSERT INTO t1 VALUES(1, 'test1')
master-bin.000001 # Xid # # COMMIT /* XID */
......
......@@ -363,5 +363,6 @@ SELECT Grantor FROM mysql.tables_priv WHERE User='user_bug27606';
--connection master
DROP USER user_bug27606@localhost;
update mysql.user set plugin='';
--source include/rpl_end.inc
......@@ -36,16 +36,6 @@ static int auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
int pkt_len;
unsigned long nonce[CRYPTO_LONGS + NONCE_LONGS];
unsigned char *pkt, *reply= (unsigned char*)nonce;
unsigned char pk[PASSWORD_LEN_BUF/4*3];
char pw[PASSWORD_LEN_BUF];
/* prepare the pk */
if (info->auth_string_length != PASSWORD_LEN)
return CR_AUTH_USER_CREDENTIALS;
memcpy(pw, info->auth_string, PASSWORD_LEN);
pw[PASSWORD_LEN]= '=';
if (my_base64_decode(pw, PASSWORD_LEN_BUF, pk, NULL, 0) != CRYPTO_PUBLICKEYBYTES)
return CR_AUTH_USER_CREDENTIALS;
info->password_used= PASSWORD_USED_YES;
......@@ -62,17 +52,46 @@ static int auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
return CR_AUTH_HANDSHAKE;
memcpy(reply, pkt, CRYPTO_BYTES);
if (crypto_sign_open(reply, CRYPTO_BYTES + NONCE_BYTES, pk))
if (crypto_sign_open(reply, CRYPTO_BYTES + NONCE_BYTES,
(unsigned char*)info->auth_string))
return CR_ERROR;
return CR_OK;
}
static int compute_password_digest(const char *pw, size_t pwlen,
char *d, size_t *dlen)
{
unsigned char pk[CRYPTO_PUBLICKEYBYTES];
if (*dlen < PASSWORD_LEN || pwlen == 0)
return 1;
*dlen= PASSWORD_LEN;
crypto_sign_keypair(pk, (unsigned char*)pw, pwlen);
my_base64_encode(pk, CRYPTO_PUBLICKEYBYTES, d);
return 0;
}
static int digest_to_binary(const char *d, size_t dlen,
unsigned char *b, size_t *blen)
{
char pw[PASSWORD_LEN_BUF];
if (*blen < CRYPTO_PUBLICKEYBYTES || dlen != PASSWORD_LEN)
return 1;
*blen= CRYPTO_PUBLICKEYBYTES;
memcpy(pw, d, PASSWORD_LEN);
pw[PASSWORD_LEN]= '=';
return my_base64_decode(pw, PASSWORD_LEN_BUF, b, 0, 0) != CRYPTO_PUBLICKEYBYTES;
}
static struct st_mysql_auth info =
{
MYSQL_AUTHENTICATION_INTERFACE_VERSION,
"client_ed25519",
auth
auth,
compute_password_digest,
digest_to_binary
};
static int init(void *p __attribute__((unused)))
......@@ -97,10 +116,10 @@ maria_declare_plugin(ed25519)
PLUGIN_LICENSE_GPL,
init,
deinit,
0x0100,
0x0101,
NULL,
NULL,
"1.0",
"1.1",
MariaDB_PLUGIN_MATURITY_STABLE
}
maria_declare_plugin_end;
......
......@@ -81,7 +81,8 @@ static struct st_mysql_auth two_handler=
{
MYSQL_AUTHENTICATION_INTERFACE_VERSION,
"dialog", /* requires dialog client plugin */
two_questions
two_questions,
NULL, NULL /* no PASSWORD() */
};
/* dialog demo where the number of questions is not known in advance */
......@@ -118,7 +119,8 @@ static struct st_mysql_auth three_handler=
{
MYSQL_AUTHENTICATION_INTERFACE_VERSION,
"dialog", /* requires dialog client plugin */
three_attempts
three_attempts,
NULL, NULL /* no PASSWORD() */
};
mysql_declare_plugin(dialog)
......
......@@ -136,7 +136,8 @@ static struct st_mysql_auth qa_auth_test_handler=
{
MYSQL_AUTHENTICATION_INTERFACE_VERSION,
"qa_auth_interface", /* requires test_plugin client's plugin */
qa_auth_interface
qa_auth_interface,
NULL, NULL /* no PASSWORD() */
};
mysql_declare_plugin(test_plugin)
......
......@@ -56,7 +56,8 @@ static struct st_mysql_auth qa_auth_test_handler=
{
MYSQL_AUTHENTICATION_INTERFACE_VERSION,
"qa_auth_interface", /* requires test_plugin client's plugin */
qa_auth_interface
qa_auth_interface,
NULL, NULL /* no PASSWORD() */
};
mysql_declare_plugin(test_plugin)
......
......@@ -69,7 +69,8 @@ static struct st_mysql_auth auth_test_handler=
{
MYSQL_AUTHENTICATION_INTERFACE_VERSION,
"auth_test_plugin", /* requires test_plugin client's plugin */
auth_test_plugin
auth_test_plugin,
NULL, NULL /* no PASSWORD() */
};
/**
......@@ -99,7 +100,8 @@ static struct st_mysql_auth auth_cleartext_handler=
{
MYSQL_AUTHENTICATION_INTERFACE_VERSION,
"mysql_clear_password", /* requires the clear text plugin */
auth_cleartext_plugin
auth_cleartext_plugin,
NULL, NULL /* no PASSWORD() */
};
mysql_declare_plugin(test_plugin)
......
......@@ -24,7 +24,8 @@ static struct st_mysql_auth info =
{
MYSQL_AUTHENTICATION_INTERFACE_VERSION,
"dialog",
pam_auth
pam_auth,
NULL, NULL /* no PASSWORD() */
};
static char use_cleartext_plugin;
......
......@@ -102,7 +102,8 @@ static struct st_mysql_auth socket_auth_handler=
{
MYSQL_AUTHENTICATION_INTERFACE_VERSION,
0,
socket_auth
socket_auth,
NULL, NULL /* no PASSWORD() */
};
maria_declare_plugin(auth_socket)
......
......@@ -6570,7 +6570,7 @@ ER_ACCESS_DENIED_NO_PASSWORD_ERROR 28000
ukr "Доступ заборонено для користувача: '%s'@'%s'"
ER_SET_PASSWORD_AUTH_PLUGIN
eng "SET PASSWORD has no significance for users authenticating via plugins"
eng "SET PASSWORD is ignored for users authenticating via %s plugin"
ER_GRANT_PLUGIN_USER_EXISTS
eng "GRANT with IDENTIFIED WITH is illegal because the user %-.*s already exists"
......
This diff is collapsed.
......@@ -2890,8 +2890,8 @@ create:
{
Lex->pop_select(); //main select
}
| create_or_replace USER_SYM opt_if_not_exists clear_privileges grant_list
opt_require_clause opt_resource_options
| create_or_replace USER_SYM opt_if_not_exists clear_privileges
grant_list opt_require_clause opt_resource_options
{
if (unlikely(Lex->set_command_with_check(SQLCOM_CREATE_USER,
$1 | $3)))
......@@ -16831,12 +16831,20 @@ grant_user:
$1->plugin= $4;
$1->auth= empty_clex_str;
}
| user IDENTIFIED_SYM via_or_with ident_or_text using_or_as TEXT_STRING_sys
| user IDENTIFIED_SYM via_or_with ident_or_text using_or_as
TEXT_STRING_sys
{
$$= $1;
$1->plugin= $4;
$1->auth= $6;
}
| user IDENTIFIED_SYM via_or_with ident_or_text using_or_as
PASSWORD_SYM '(' TEXT_STRING ')'
{
$$= $1;
$1->plugin= $4;
$1->pwtext= $8;
}
| user_or_role
{ $$= $1; }
;
......
......@@ -2389,8 +2389,8 @@ create:
{
Lex->pop_select(); //main select
}
| create_or_replace USER_SYM opt_if_not_exists clear_privileges grant_list
opt_require_clause opt_resource_options
| create_or_replace USER_SYM opt_if_not_exists clear_privileges
grant_list opt_require_clause opt_resource_options
{
if (unlikely(Lex->set_command_with_check(SQLCOM_CREATE_USER,
$1 | $3)))
......@@ -17184,12 +17184,20 @@ grant_user:
$1->plugin= $4;
$1->auth= empty_clex_str;
}
| user IDENTIFIED_SYM via_or_with ident_or_text using_or_as TEXT_STRING_sys
| user IDENTIFIED_SYM via_or_with ident_or_text using_or_as
TEXT_STRING_sys
{
$$= $1;
$1->plugin= $4;
$1->auth= $6;
}
| user IDENTIFIED_SYM via_or_with ident_or_text using_or_as
PASSWORD_SYM '(' TEXT_STRING ')'
{
$$= $1;
$1->plugin= $4;
$1->pwtext= $8;
}
| user_or_role
{ $$= $1; }
;
......
......@@ -679,7 +679,6 @@ DROP TRIGGER tr1;
******************** EVENTS ********************
GRANT EVENT ON *.* TO 'root'@'localhost';
INSERT INTO t1 VALUES(1, 'test1');
CREATE EVENT e1 ON SCHEDULE EVERY '1' SECOND COMMENT 'e_second_comment' DO DELETE FROM t1;
SHOW EVENTS;
......@@ -1101,8 +1100,6 @@ master-bin.000001 # Query # # use `test_rpl`; DELETE FROM t2
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test_rpl`; DROP TRIGGER tr1
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test_rpl`; GRANT EVENT ON *.* TO 'root'@'localhost'
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `test_rpl`; INSERT INTO t1 VALUES(1, 'test1')
master-bin.000001 # Xid # # COMMIT /* XID */
......
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