Commit fef41669 authored by Sergei Golubchik's avatar Sergei Golubchik

Don't allow authentication clauses for roles, in particular:

  GRANT ... IDENTIFIED BY [ PASSWORD ] ...
  GRANT ... IDENTIFIED VIA ... [ USING ... ]
  GRANT ... REQUIRE ...
  GRANT ... MAX_xxx ...
  SET PASSWORD FOR ... = ...
parent d5c97122
......@@ -36,7 +36,7 @@ select @@sql_mode;
@@sql_mode
NO_AUTO_CREATE_USER
grant select on `my\_1`.* to mysqltest_4@localhost with grant option;
ERROR 42000: Can't find any matching row in the user table
ERROR 28000: Can't find any matching row in the user table
grant select on `my\_1`.* to mysqltest_4@localhost identified by 'mypass'
with grant option;
show grants for mysqltest_1@localhost;
......
......@@ -303,7 +303,7 @@ grant_user test_plugin_server plug_dest
CREATE USER plug_dest;
DROP USER plug_dest;
GRANT ALL PRIVILEGES ON test_user_db.* TO plug_dest;
ERROR 42000: Can't find any matching row in the user table
ERROR 28000: Can't find any matching row in the user table
DROP USER grant_user;
GRANT INSERT ON test_user_db.* TO grant_user IDENTIFIED WITH test_plugin_server AS 'plug_dest';
SELECT user,plugin,authentication_string FROM mysql.user WHERE user != 'root';
......
create role r1;
grant select on *.* to r1 identified by 'foobar';
ERROR 28000: Can't find any matching row in the user table
grant select on *.* to r1 identified by '';
ERROR 28000: Can't find any matching row in the user table
grant select on mysql.user to r1 identified by password '00000000000000000000000000000000000000000';
ERROR 28000: Can't find any matching row in the user table
grant select on *.* to r1 identified via plugin;
ERROR 28000: Can't find any matching row in the user table
grant select on mysql.user to r1 identified via plugin using 'param';
ERROR 28000: Can't find any matching row in the user table
grant select on *.* to r1 require subject 'foobar';
ERROR 28000: Can't find any matching row in the user table
grant select on mysql.user to r1 require issuer 'foobar';
ERROR 28000: Can't find any matching row in the user table
grant select on *.* to r1 require cipher 'foobar';
ERROR 28000: Can't find any matching row in the user table
grant select on mysql.user to r1 require ssl;
ERROR 28000: Can't find any matching row in the user table
grant select on *.* to r1 require x509;
ERROR 28000: Can't find any matching row in the user table
grant select on mysql.user to r1 require none;
ERROR 28000: Can't find any matching row in the user table
grant select on *.* to r1 with max_queries_per_hour 10;
ERROR 28000: Can't find any matching row in the user table
grant select on mysql.user to r1 with max_updates_per_hour 10;
ERROR 28000: Can't find any matching row in the user table
grant select on *.* to r1 with max_connections_per_hour 10;
ERROR 28000: Can't find any matching row in the user table
grant select on mysql.user to r1 with max_user_connections 10;
ERROR 28000: Can't find any matching row in the user table
set password for r1 = '00000000000000000000000000000000000000000';
ERROR 28000: Can't find any matching row in the user table
drop role r1;
#
# setting authentication for roles
#
--source include/not_embedded.inc
#identified by [password]...
#identified with ... [using ...]
#require [subject][issuer][cipher][ssl][x509]
# max_queries_per_hour | max_updates_per_hour | max_connections_per_hour | max_user_connections
#set password for ... = ...
create role r1;
--error ER_PASSWORD_NO_MATCH
grant select on *.* to r1 identified by 'foobar';
--error ER_PASSWORD_NO_MATCH
grant select on *.* to r1 identified by '';
--error ER_PASSWORD_NO_MATCH
grant select on mysql.user to r1 identified by password '00000000000000000000000000000000000000000';
--error ER_PASSWORD_NO_MATCH
grant select on *.* to r1 identified via plugin;
--error ER_PASSWORD_NO_MATCH
grant select on mysql.user to r1 identified via plugin using 'param';
--error ER_PASSWORD_NO_MATCH
grant select on *.* to r1 require subject 'foobar';
--error ER_PASSWORD_NO_MATCH
grant select on mysql.user to r1 require issuer 'foobar';
--error ER_PASSWORD_NO_MATCH
grant select on *.* to r1 require cipher 'foobar';
--error ER_PASSWORD_NO_MATCH
grant select on mysql.user to r1 require ssl;
--error ER_PASSWORD_NO_MATCH
grant select on *.* to r1 require x509;
--error ER_PASSWORD_NO_MATCH
grant select on mysql.user to r1 require none;
--error ER_PASSWORD_NO_MATCH
grant select on *.* to r1 with max_queries_per_hour 10;
--error ER_PASSWORD_NO_MATCH
grant select on mysql.user to r1 with max_updates_per_hour 10;
--error ER_PASSWORD_NO_MATCH
grant select on *.* to r1 with max_connections_per_hour 10;
--error ER_PASSWORD_NO_MATCH
grant select on mysql.user to r1 with max_user_connections 10;
--error ER_PASSWORD_NO_MATCH
set password for r1 = '00000000000000000000000000000000000000000';
drop role r1;
......@@ -3065,7 +3065,7 @@ ER_PASSWORD_NOT_ALLOWED 42000
spa "Tu debes de tener permiso para actualizar tablas en la base de datos mysql para cambiar las claves para otros"
swe "För att ändra lösenord för andra måste du ha rättigheter att uppdatera mysql-databasen"
ukr "Ви повині мати право на оновлення таблиць у базі данних mysql, аби мати можливість змінювати пароль іншим"
ER_PASSWORD_NO_MATCH 42000
ER_PASSWORD_NO_MATCH 28000
cze "V tabulce user nen-Bí žádný odpovídající řádek"
dan "Kan ikke finde nogen tilsvarende poster i bruger tabellen"
nla "Kan geen enkele passende rij vinden in de gebruikers tabel"
......@@ -6565,7 +6565,7 @@ ER_NO_SUCH_QUERY
ER_INVALID_ROLE OP000
eng "Invalid role specification %`s."
rum "Rolul %`s este invalid."
ER_INVALID_CURRENT_USER
ER_INVALID_CURRENT_USER 0L000
eng "The current user is invalid."
rum "Utilizatorul curent este invalid."
ER_CANNOT_GRANT_ROLE
......
......@@ -5289,6 +5289,38 @@ static int merge_role_privileges(ACL_ROLE *role __attribute__((unused)),
End of the role privilege propagation and graph traversal code
******************************************************************/
bool copy_and_check_auth(LEX_USER *to, LEX_USER *from, LEX *lex)
{
if (to != from)
{
/* preserve authentication information, if LEX_USER was reallocated */
to->password= from->password;
to->plugin= from->plugin;
to->auth= from->auth;
}
/*
Note, that no password is null_lex_str, while no plugin is empty_lex_str.
See sql_yacc.yy
*/
bool has_auth= to->password.str || to->plugin.length || to->auth.length ||
lex->ssl_type != SSL_TYPE_NOT_SPECIFIED || lex->ssl_cipher ||
lex->x509_issuer || lex->x509_subject ||
lex->mqh.specified_limits;
/*
Specifying authentication clauses forces the name to be interpreted
as a user, not a role. See also check_change_password()
*/
if (to->is_role() && has_auth)
{
my_error(ER_PASSWORD_NO_MATCH, MYF(0));
return true;
}
return false;
}
/*
Store table level and column level grants in the privilege tables
......@@ -5462,6 +5494,9 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
continue;
}
/* Create user if needed */
if (copy_and_check_auth(Str, tmp_Str, thd->lex))
error= -1;
else
error=replace_user_table(thd, tables[0].table, *Str,
0, revoke_grant, create_new_users,
test(thd->variables.sql_mode &
......@@ -6102,14 +6137,10 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
result= TRUE;
continue;
}
/*
No User, but a password?
They did GRANT ... TO CURRENT_USER() IDENTIFIED BY ... !
Get the current user, and shallow-copy the new password to them!
*/
if (tmp_Str->user.str == current_user.str && tmp_Str->password.str)
Str->password= tmp_Str->password;
if (copy_and_check_auth(Str, tmp_Str, thd->lex))
result= -1;
else
if (replace_user_table(thd, tables[0].table, *Str,
(!db ? rights : 0), revoke_grant, create_new_users,
test(thd->variables.sql_mode &
......
......@@ -13222,6 +13222,8 @@ user:
if (!($$=(LEX_USER*)thd->calloc(sizeof(LEX_USER))))
MYSQL_YYABORT;
$$->user= current_user;
$$->plugin= empty_lex_str;
$$->auth= empty_lex_str;
}
;
......
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