mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 04:22:27 +01:00
Merged fix for bug #36544 "DROP USER does not remove stored
function privileges" into 5.5 tree. Did after-merge fixes.
This commit is contained in:
commit
03e27ac161
7 changed files with 451 additions and 55 deletions
|
@ -1326,6 +1326,199 @@ DROP DATABASE mysqltest2;
|
|||
DROP USER testuser@localhost;
|
||||
use test;
|
||||
|
||||
#
|
||||
# Test for bug #36544 "DROP USER does not remove stored function
|
||||
# privileges".
|
||||
#
|
||||
create database mysqltest1;
|
||||
create function mysqltest1.f1() returns int return 0;
|
||||
create procedure mysqltest1.p1() begin end;
|
||||
#
|
||||
# 1) Check that DROP USER properly removes privileges on both
|
||||
# stored procedures and functions.
|
||||
#
|
||||
create user mysqluser1@localhost;
|
||||
grant execute on function mysqltest1.f1 to mysqluser1@localhost;
|
||||
grant execute on procedure mysqltest1.p1 to mysqluser1@localhost;
|
||||
# Quick test that granted privileges are properly reflected
|
||||
# in privilege tables and in in-memory structures.
|
||||
show grants for mysqluser1@localhost;
|
||||
Grants for mysqluser1@localhost
|
||||
GRANT USAGE ON *.* TO 'mysqluser1'@'localhost'
|
||||
GRANT EXECUTE ON PROCEDURE `mysqltest1`.`p1` TO 'mysqluser1'@'localhost'
|
||||
GRANT EXECUTE ON FUNCTION `mysqltest1`.`f1` TO 'mysqluser1'@'localhost'
|
||||
select db, routine_name, routine_type, proc_priv from mysql.procs_priv where user='mysqluser1' and host='localhost';
|
||||
db routine_name routine_type proc_priv
|
||||
mysqltest1 f1 FUNCTION Execute
|
||||
mysqltest1 p1 PROCEDURE Execute
|
||||
#
|
||||
# Create connection 'bug_36544_con1' as 'mysqluser1@localhost'.
|
||||
call mysqltest1.p1();
|
||||
select mysqltest1.f1();
|
||||
mysqltest1.f1()
|
||||
0
|
||||
#
|
||||
# Switch to connection 'default'.
|
||||
drop user mysqluser1@localhost;
|
||||
#
|
||||
# Test that dropping of user is properly reflected in
|
||||
# both privilege tables and in in-memory structures.
|
||||
#
|
||||
# Switch to connection 'bug36544_con1'.
|
||||
# The connection cold be alive but should not be able to
|
||||
# access to any of the stored routines.
|
||||
call mysqltest1.p1();
|
||||
ERROR 42000: execute command denied to user 'mysqluser1'@'localhost' for routine 'mysqltest1.p1'
|
||||
select mysqltest1.f1();
|
||||
ERROR 42000: execute command denied to user 'mysqluser1'@'localhost' for routine 'mysqltest1.f1'
|
||||
#
|
||||
# Switch to connection 'default'.
|
||||
#
|
||||
# Now create user with the same name and check that he
|
||||
# has not inherited privileges.
|
||||
create user mysqluser1@localhost;
|
||||
show grants for mysqluser1@localhost;
|
||||
Grants for mysqluser1@localhost
|
||||
GRANT USAGE ON *.* TO 'mysqluser1'@'localhost'
|
||||
select db, routine_name, routine_type, proc_priv from mysql.procs_priv where user='mysqluser1' and host='localhost';
|
||||
db routine_name routine_type proc_priv
|
||||
#
|
||||
# Create connection 'bug_36544_con2' as 'mysqluser1@localhost'.
|
||||
# Newly created user should not be able to access any of the routines.
|
||||
call mysqltest1.p1();
|
||||
ERROR 42000: execute command denied to user 'mysqluser1'@'localhost' for routine 'mysqltest1.p1'
|
||||
select mysqltest1.f1();
|
||||
ERROR 42000: execute command denied to user 'mysqluser1'@'localhost' for routine 'mysqltest1.f1'
|
||||
#
|
||||
# Switch to connection 'default'.
|
||||
#
|
||||
# 2) Check that RENAME USER properly updates privileges on both
|
||||
# stored procedures and functions.
|
||||
#
|
||||
grant execute on function mysqltest1.f1 to mysqluser1@localhost;
|
||||
grant execute on procedure mysqltest1.p1 to mysqluser1@localhost;
|
||||
#
|
||||
# Create one more user to make in-memory hashes non-trivial.
|
||||
# User names 'mysqluser11' and 'mysqluser10' were selected
|
||||
# to trigger bug discovered during code inspection.
|
||||
create user mysqluser11@localhost;
|
||||
grant execute on function mysqltest1.f1 to mysqluser11@localhost;
|
||||
grant execute on procedure mysqltest1.p1 to mysqluser11@localhost;
|
||||
# Also create a couple of tables to test for another bug
|
||||
# discovered during code inspection (again table names were
|
||||
# chosen especially to trigger the bug).
|
||||
create table mysqltest1.t11 (i int);
|
||||
create table mysqltest1.t22 (i int);
|
||||
grant select on mysqltest1.t22 to mysqluser1@localhost;
|
||||
grant select on mysqltest1.t11 to mysqluser1@localhost;
|
||||
# Quick test that granted privileges are properly reflected
|
||||
# in privilege tables and in in-memory structures.
|
||||
show grants for mysqluser1@localhost;
|
||||
Grants for mysqluser1@localhost
|
||||
GRANT USAGE ON *.* TO 'mysqluser1'@'localhost'
|
||||
GRANT SELECT ON `mysqltest1`.`t11` TO 'mysqluser1'@'localhost'
|
||||
GRANT SELECT ON `mysqltest1`.`t22` TO 'mysqluser1'@'localhost'
|
||||
GRANT EXECUTE ON PROCEDURE `mysqltest1`.`p1` TO 'mysqluser1'@'localhost'
|
||||
GRANT EXECUTE ON FUNCTION `mysqltest1`.`f1` TO 'mysqluser1'@'localhost'
|
||||
select db, routine_name, routine_type, proc_priv from mysql.procs_priv where user='mysqluser1' and host='localhost';
|
||||
db routine_name routine_type proc_priv
|
||||
mysqltest1 f1 FUNCTION Execute
|
||||
mysqltest1 p1 PROCEDURE Execute
|
||||
select db, table_name, table_priv from mysql.tables_priv where user='mysqluser1' and host='localhost';
|
||||
db table_name table_priv
|
||||
mysqltest1 t11 Select
|
||||
mysqltest1 t22 Select
|
||||
#
|
||||
# Switch to connection 'bug36544_con2'.
|
||||
call mysqltest1.p1();
|
||||
select mysqltest1.f1();
|
||||
mysqltest1.f1()
|
||||
0
|
||||
select * from mysqltest1.t11;
|
||||
i
|
||||
select * from mysqltest1.t22;
|
||||
i
|
||||
#
|
||||
# Switch to connection 'default'.
|
||||
rename user mysqluser1@localhost to mysqluser10@localhost;
|
||||
#
|
||||
# Test that there are no privileges left for mysqluser1.
|
||||
#
|
||||
# Switch to connection 'bug36544_con2'.
|
||||
# The connection cold be alive but should not be able to
|
||||
# access to any of the stored routines or tables.
|
||||
call mysqltest1.p1();
|
||||
ERROR 42000: execute command denied to user 'mysqluser1'@'localhost' for routine 'mysqltest1.p1'
|
||||
select mysqltest1.f1();
|
||||
ERROR 42000: execute command denied to user 'mysqluser1'@'localhost' for routine 'mysqltest1.f1'
|
||||
select * from mysqltest1.t11;
|
||||
ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 't11'
|
||||
select * from mysqltest1.t22;
|
||||
ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 't22'
|
||||
#
|
||||
# Switch to connection 'default'.
|
||||
#
|
||||
# Now create user with the old name and check that he
|
||||
# has not inherited privileges.
|
||||
create user mysqluser1@localhost;
|
||||
show grants for mysqluser1@localhost;
|
||||
Grants for mysqluser1@localhost
|
||||
GRANT USAGE ON *.* TO 'mysqluser1'@'localhost'
|
||||
select db, routine_name, routine_type, proc_priv from mysql.procs_priv where user='mysqluser1' and host='localhost';
|
||||
db routine_name routine_type proc_priv
|
||||
select db, table_name, table_priv from mysql.tables_priv where user='mysqluser1' and host='localhost';
|
||||
db table_name table_priv
|
||||
#
|
||||
# Create connection 'bug_36544_con3' as 'mysqluser1@localhost'.
|
||||
# Newly created user should not be able to access to any of the
|
||||
# stored routines or tables.
|
||||
call mysqltest1.p1();
|
||||
ERROR 42000: execute command denied to user 'mysqluser1'@'localhost' for routine 'mysqltest1.p1'
|
||||
select mysqltest1.f1();
|
||||
ERROR 42000: execute command denied to user 'mysqluser1'@'localhost' for routine 'mysqltest1.f1'
|
||||
select * from mysqltest1.t11;
|
||||
ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 't11'
|
||||
select * from mysqltest1.t22;
|
||||
ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 't22'
|
||||
#
|
||||
# Switch to connection 'default'.
|
||||
#
|
||||
# Now check that privileges became associated with a new user
|
||||
# name - mysqluser10.
|
||||
#
|
||||
show grants for mysqluser10@localhost;
|
||||
Grants for mysqluser10@localhost
|
||||
GRANT USAGE ON *.* TO 'mysqluser10'@'localhost'
|
||||
GRANT SELECT ON `mysqltest1`.`t22` TO 'mysqluser10'@'localhost'
|
||||
GRANT SELECT ON `mysqltest1`.`t11` TO 'mysqluser10'@'localhost'
|
||||
GRANT EXECUTE ON PROCEDURE `mysqltest1`.`p1` TO 'mysqluser10'@'localhost'
|
||||
GRANT EXECUTE ON FUNCTION `mysqltest1`.`f1` TO 'mysqluser10'@'localhost'
|
||||
select db, routine_name, routine_type, proc_priv from mysql.procs_priv where user='mysqluser10' and host='localhost';
|
||||
db routine_name routine_type proc_priv
|
||||
mysqltest1 f1 FUNCTION Execute
|
||||
mysqltest1 p1 PROCEDURE Execute
|
||||
select db, table_name, table_priv from mysql.tables_priv where user='mysqluser10' and host='localhost';
|
||||
db table_name table_priv
|
||||
mysqltest1 t11 Select
|
||||
mysqltest1 t22 Select
|
||||
#
|
||||
# Create connection 'bug_36544_con4' as 'mysqluser10@localhost'.
|
||||
call mysqltest1.p1();
|
||||
select mysqltest1.f1();
|
||||
mysqltest1.f1()
|
||||
0
|
||||
select * from mysqltest1.t11;
|
||||
i
|
||||
select * from mysqltest1.t22;
|
||||
i
|
||||
#
|
||||
# Switch to connection 'default'.
|
||||
#
|
||||
# Clean-up.
|
||||
drop user mysqluser1@localhost;
|
||||
drop user mysqluser10@localhost;
|
||||
drop user mysqluser11@localhost;
|
||||
drop database mysqltest1;
|
||||
End of 5.0 tests
|
||||
set names utf8;
|
||||
grant select on test.* to юзер_юзер@localhost;
|
||||
|
@ -1422,11 +1615,7 @@ fn2()
|
|||
2
|
||||
DROP USER 'userbug33464'@'localhost';
|
||||
DROP FUNCTION fn1;
|
||||
Warnings:
|
||||
Warning 1403 There is no such grant defined for user 'userbug33464' on host 'localhost' on routine 'fn1'
|
||||
DROP FUNCTION fn2;
|
||||
Warnings:
|
||||
Warning 1403 There is no such grant defined for user 'userbug33464' on host 'localhost' on routine 'fn2'
|
||||
DROP PROCEDURE sp3;
|
||||
DROP USER 'userbug33464'@'localhost';
|
||||
USE test;
|
||||
|
|
|
@ -128,8 +128,6 @@ root@localhost db_storedproc_1
|
|||
drop user 'user_1'@'localhost';
|
||||
DROP PROCEDURE sp3;
|
||||
DROP FUNCTION fn1;
|
||||
Warnings:
|
||||
Warning 1403 There is no such grant defined for user 'user_1' on host 'localhost' on routine 'fn1'
|
||||
|
||||
Testcase 3.1.6.4:
|
||||
-----------------
|
||||
|
|
|
@ -129,8 +129,6 @@ root@localhost db_storedproc_1
|
|||
drop user 'user_1'@'localhost';
|
||||
DROP PROCEDURE sp3;
|
||||
DROP FUNCTION fn1;
|
||||
Warnings:
|
||||
Warning 1403 There is no such grant defined for user 'user_1' on host 'localhost' on routine 'fn1'
|
||||
|
||||
Testcase 3.1.6.4:
|
||||
-----------------
|
||||
|
|
|
@ -129,8 +129,6 @@ root@localhost db_storedproc_1
|
|||
drop user 'user_1'@'localhost';
|
||||
DROP PROCEDURE sp3;
|
||||
DROP FUNCTION fn1;
|
||||
Warnings:
|
||||
Warning 1403 There is no such grant defined for user 'user_1' on host 'localhost' on routine 'fn1'
|
||||
|
||||
Testcase 3.1.6.4:
|
||||
-----------------
|
||||
|
|
|
@ -149,10 +149,6 @@ USE db_storedproc_1;
|
|||
|
||||
drop user 'user_1'@'localhost';
|
||||
DROP PROCEDURE sp3;
|
||||
# This drop function shouldn't generated a warning as the
|
||||
# privileges should have been removed when the user was
|
||||
# dropped. Reported as Bug#36544 DROP USER does not remove
|
||||
# stored function privileges
|
||||
DROP FUNCTION fn1;
|
||||
|
||||
|
||||
|
|
|
@ -1396,6 +1396,183 @@ DROP USER testuser@localhost;
|
|||
use test;
|
||||
--echo
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Test for bug #36544 "DROP USER does not remove stored function
|
||||
--echo # privileges".
|
||||
--echo #
|
||||
create database mysqltest1;
|
||||
create function mysqltest1.f1() returns int return 0;
|
||||
create procedure mysqltest1.p1() begin end;
|
||||
--echo #
|
||||
--echo # 1) Check that DROP USER properly removes privileges on both
|
||||
--echo # stored procedures and functions.
|
||||
--echo #
|
||||
create user mysqluser1@localhost;
|
||||
grant execute on function mysqltest1.f1 to mysqluser1@localhost;
|
||||
grant execute on procedure mysqltest1.p1 to mysqluser1@localhost;
|
||||
|
||||
--echo # Quick test that granted privileges are properly reflected
|
||||
--echo # in privilege tables and in in-memory structures.
|
||||
show grants for mysqluser1@localhost;
|
||||
select db, routine_name, routine_type, proc_priv from mysql.procs_priv where user='mysqluser1' and host='localhost';
|
||||
--echo #
|
||||
--echo # Create connection 'bug_36544_con1' as 'mysqluser1@localhost'.
|
||||
--connect (bug36544_con1,localhost,mysqluser1,,)
|
||||
call mysqltest1.p1();
|
||||
select mysqltest1.f1();
|
||||
|
||||
--echo #
|
||||
--echo # Switch to connection 'default'.
|
||||
--connection default
|
||||
drop user mysqluser1@localhost;
|
||||
|
||||
--echo #
|
||||
--echo # Test that dropping of user is properly reflected in
|
||||
--echo # both privilege tables and in in-memory structures.
|
||||
--echo #
|
||||
--echo # Switch to connection 'bug36544_con1'.
|
||||
--connection bug36544_con1
|
||||
--echo # The connection cold be alive but should not be able to
|
||||
--echo # access to any of the stored routines.
|
||||
--error ER_PROCACCESS_DENIED_ERROR
|
||||
call mysqltest1.p1();
|
||||
--error ER_PROCACCESS_DENIED_ERROR
|
||||
select mysqltest1.f1();
|
||||
--disconnect bug36544_con1
|
||||
|
||||
--echo #
|
||||
--echo # Switch to connection 'default'.
|
||||
--connection default
|
||||
--echo #
|
||||
--echo # Now create user with the same name and check that he
|
||||
--echo # has not inherited privileges.
|
||||
create user mysqluser1@localhost;
|
||||
show grants for mysqluser1@localhost;
|
||||
select db, routine_name, routine_type, proc_priv from mysql.procs_priv where user='mysqluser1' and host='localhost';
|
||||
--echo #
|
||||
--echo # Create connection 'bug_36544_con2' as 'mysqluser1@localhost'.
|
||||
--connect (bug36544_con2,localhost,mysqluser1,,)
|
||||
--echo # Newly created user should not be able to access any of the routines.
|
||||
--error ER_PROCACCESS_DENIED_ERROR
|
||||
call mysqltest1.p1();
|
||||
--error ER_PROCACCESS_DENIED_ERROR
|
||||
select mysqltest1.f1();
|
||||
--echo #
|
||||
--echo # Switch to connection 'default'.
|
||||
--connection default
|
||||
|
||||
--echo #
|
||||
--echo # 2) Check that RENAME USER properly updates privileges on both
|
||||
--echo # stored procedures and functions.
|
||||
--echo #
|
||||
grant execute on function mysqltest1.f1 to mysqluser1@localhost;
|
||||
grant execute on procedure mysqltest1.p1 to mysqluser1@localhost;
|
||||
--echo #
|
||||
--echo # Create one more user to make in-memory hashes non-trivial.
|
||||
--echo # User names 'mysqluser11' and 'mysqluser10' were selected
|
||||
--echo # to trigger bug discovered during code inspection.
|
||||
create user mysqluser11@localhost;
|
||||
grant execute on function mysqltest1.f1 to mysqluser11@localhost;
|
||||
grant execute on procedure mysqltest1.p1 to mysqluser11@localhost;
|
||||
--echo # Also create a couple of tables to test for another bug
|
||||
--echo # discovered during code inspection (again table names were
|
||||
--echo # chosen especially to trigger the bug).
|
||||
create table mysqltest1.t11 (i int);
|
||||
create table mysqltest1.t22 (i int);
|
||||
grant select on mysqltest1.t22 to mysqluser1@localhost;
|
||||
grant select on mysqltest1.t11 to mysqluser1@localhost;
|
||||
|
||||
--echo # Quick test that granted privileges are properly reflected
|
||||
--echo # in privilege tables and in in-memory structures.
|
||||
show grants for mysqluser1@localhost;
|
||||
select db, routine_name, routine_type, proc_priv from mysql.procs_priv where user='mysqluser1' and host='localhost';
|
||||
select db, table_name, table_priv from mysql.tables_priv where user='mysqluser1' and host='localhost';
|
||||
--echo #
|
||||
--echo # Switch to connection 'bug36544_con2'.
|
||||
--connection bug36544_con2
|
||||
call mysqltest1.p1();
|
||||
select mysqltest1.f1();
|
||||
select * from mysqltest1.t11;
|
||||
select * from mysqltest1.t22;
|
||||
|
||||
--echo #
|
||||
--echo # Switch to connection 'default'.
|
||||
--connection default
|
||||
rename user mysqluser1@localhost to mysqluser10@localhost;
|
||||
|
||||
--echo #
|
||||
--echo # Test that there are no privileges left for mysqluser1.
|
||||
--echo #
|
||||
--echo # Switch to connection 'bug36544_con2'.
|
||||
--connection bug36544_con2
|
||||
--echo # The connection cold be alive but should not be able to
|
||||
--echo # access to any of the stored routines or tables.
|
||||
--error ER_PROCACCESS_DENIED_ERROR
|
||||
call mysqltest1.p1();
|
||||
--error ER_PROCACCESS_DENIED_ERROR
|
||||
select mysqltest1.f1();
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
select * from mysqltest1.t11;
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
select * from mysqltest1.t22;
|
||||
--disconnect bug36544_con2
|
||||
|
||||
--echo #
|
||||
--echo # Switch to connection 'default'.
|
||||
--connection default
|
||||
--echo #
|
||||
--echo # Now create user with the old name and check that he
|
||||
--echo # has not inherited privileges.
|
||||
create user mysqluser1@localhost;
|
||||
show grants for mysqluser1@localhost;
|
||||
select db, routine_name, routine_type, proc_priv from mysql.procs_priv where user='mysqluser1' and host='localhost';
|
||||
select db, table_name, table_priv from mysql.tables_priv where user='mysqluser1' and host='localhost';
|
||||
--echo #
|
||||
--echo # Create connection 'bug_36544_con3' as 'mysqluser1@localhost'.
|
||||
--connect (bug36544_con3,localhost,mysqluser1,,)
|
||||
--echo # Newly created user should not be able to access to any of the
|
||||
--echo # stored routines or tables.
|
||||
--error ER_PROCACCESS_DENIED_ERROR
|
||||
call mysqltest1.p1();
|
||||
--error ER_PROCACCESS_DENIED_ERROR
|
||||
select mysqltest1.f1();
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
select * from mysqltest1.t11;
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
select * from mysqltest1.t22;
|
||||
--disconnect bug36544_con3
|
||||
|
||||
--echo #
|
||||
--echo # Switch to connection 'default'.
|
||||
--connection default
|
||||
--echo #
|
||||
--echo # Now check that privileges became associated with a new user
|
||||
--echo # name - mysqluser10.
|
||||
--echo #
|
||||
show grants for mysqluser10@localhost;
|
||||
select db, routine_name, routine_type, proc_priv from mysql.procs_priv where user='mysqluser10' and host='localhost';
|
||||
select db, table_name, table_priv from mysql.tables_priv where user='mysqluser10' and host='localhost';
|
||||
--echo #
|
||||
--echo # Create connection 'bug_36544_con4' as 'mysqluser10@localhost'.
|
||||
--connect (bug36544_con4,localhost,mysqluser10,,)
|
||||
call mysqltest1.p1();
|
||||
select mysqltest1.f1();
|
||||
select * from mysqltest1.t11;
|
||||
select * from mysqltest1.t22;
|
||||
--disconnect bug36544_con4
|
||||
|
||||
--echo #
|
||||
--echo # Switch to connection 'default'.
|
||||
--connection default
|
||||
--echo #
|
||||
--echo # Clean-up.
|
||||
drop user mysqluser1@localhost;
|
||||
drop user mysqluser10@localhost;
|
||||
drop user mysqluser11@localhost;
|
||||
drop database mysqltest1;
|
||||
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
||||
#
|
||||
|
|
122
sql/sql_acl.cc
122
sql/sql_acl.cc
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2000-2003 MySQL AB
|
||||
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
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
|
||||
|
@ -5377,18 +5377,15 @@ static int handle_grant_table(TABLE_LIST *tables, uint table_no, bool drop,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Handle an in-memory privilege structure.
|
||||
|
||||
SYNOPSIS
|
||||
handle_grant_struct()
|
||||
struct_no The number of the structure to handle (0..3).
|
||||
drop If user_from is to be dropped.
|
||||
user_from The the user to be searched/dropped/renamed.
|
||||
user_to The new name for the user if to be renamed,
|
||||
NULL otherwise.
|
||||
@param struct_no The number of the structure to handle (0..4).
|
||||
@param drop If user_from is to be dropped.
|
||||
@param user_from The the user to be searched/dropped/renamed.
|
||||
@param user_to The new name for the user if to be renamed, NULL otherwise.
|
||||
|
||||
DESCRIPTION
|
||||
@note
|
||||
Scan through all elements in an in-memory grant structure and apply
|
||||
the requested operation.
|
||||
Delete from grant structure if drop is true.
|
||||
|
@ -5398,12 +5395,12 @@ static int handle_grant_table(TABLE_LIST *tables, uint table_no, bool drop,
|
|||
0 acl_users
|
||||
1 acl_dbs
|
||||
2 column_priv_hash
|
||||
3 procs_priv_hash
|
||||
3 proc_priv_hash
|
||||
4 func_priv_hash
|
||||
|
||||
RETURN
|
||||
> 0 At least one element matched.
|
||||
0 OK, but no element matched.
|
||||
-1 Wrong arguments to function
|
||||
@retval > 0 At least one element matched.
|
||||
@retval 0 OK, but no element matched.
|
||||
@retval -1 Wrong arguments to function.
|
||||
*/
|
||||
|
||||
static int handle_grant_struct(uint struct_no, bool drop,
|
||||
|
@ -5417,6 +5414,7 @@ static int handle_grant_struct(uint struct_no, bool drop,
|
|||
ACL_USER *acl_user= NULL;
|
||||
ACL_DB *acl_db= NULL;
|
||||
GRANT_NAME *grant_name= NULL;
|
||||
HASH *grant_name_hash= NULL;
|
||||
DBUG_ENTER("handle_grant_struct");
|
||||
DBUG_PRINT("info",("scan struct: %u search: '%s'@'%s'",
|
||||
struct_no, user_from->user.str, user_from->host.str));
|
||||
|
@ -5436,9 +5434,15 @@ static int handle_grant_struct(uint struct_no, bool drop,
|
|||
break;
|
||||
case 2:
|
||||
elements= column_priv_hash.records;
|
||||
grant_name_hash= &column_priv_hash;
|
||||
break;
|
||||
case 3:
|
||||
elements= proc_priv_hash.records;
|
||||
grant_name_hash= &proc_priv_hash;
|
||||
break;
|
||||
case 4:
|
||||
elements= func_priv_hash.records;
|
||||
grant_name_hash= &func_priv_hash;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
|
@ -5468,16 +5472,13 @@ static int handle_grant_struct(uint struct_no, bool drop,
|
|||
break;
|
||||
|
||||
case 2:
|
||||
grant_name= (GRANT_NAME*) hash_element(&column_priv_hash, idx);
|
||||
case 3:
|
||||
case 4:
|
||||
grant_name= (GRANT_NAME*) hash_element(grant_name_hash, idx);
|
||||
user= grant_name->user;
|
||||
host= grant_name->host.hostname;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
grant_name= (GRANT_NAME*) hash_element(&proc_priv_hash, idx);
|
||||
user= grant_name->user;
|
||||
host= grant_name->host.hostname;
|
||||
break;
|
||||
default:
|
||||
MY_ASSERT_UNREACHABLE();
|
||||
}
|
||||
|
@ -5507,14 +5508,25 @@ static int handle_grant_struct(uint struct_no, bool drop,
|
|||
break;
|
||||
|
||||
case 2:
|
||||
hash_delete(&column_priv_hash, (uchar*) grant_name);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
hash_delete(&proc_priv_hash, (uchar*) grant_name);
|
||||
case 4:
|
||||
hash_delete(grant_name_hash, (uchar*) grant_name);
|
||||
break;
|
||||
}
|
||||
elements--;
|
||||
/*
|
||||
- If we are iterating through an array then we just have moved all
|
||||
elements after the current element one position closer to its head.
|
||||
This means that we have to take another look at the element at
|
||||
current position as it is a new element from the array's tail.
|
||||
- If we are iterating through a hash the current element was replaced
|
||||
with one of elements from the tail. So we also have to take a look
|
||||
at the new element in current position.
|
||||
Note that in our HASH implementation hash_delete() won't move any
|
||||
elements with position after current one to position before the
|
||||
current (i.e. from the tail to the head), so it is safe to continue
|
||||
iteration without re-starting.
|
||||
*/
|
||||
idx--;
|
||||
}
|
||||
else if ( user_to )
|
||||
|
@ -5532,22 +5544,41 @@ static int handle_grant_struct(uint struct_no, bool drop,
|
|||
|
||||
case 2:
|
||||
case 3:
|
||||
/*
|
||||
Update the grant structure with the new user name and
|
||||
host name
|
||||
*/
|
||||
grant_name->set_user_details(user_to->host.str, grant_name->db,
|
||||
user_to->user.str, grant_name->tname,
|
||||
TRUE);
|
||||
case 4:
|
||||
{
|
||||
/*
|
||||
Save old hash key and its length to be able properly update
|
||||
element position in hash.
|
||||
*/
|
||||
char *old_key= grant_name->hash_key;
|
||||
size_t old_key_length= grant_name->key_length;
|
||||
|
||||
/*
|
||||
Since username is part of the hash key, when the user name
|
||||
is renamed, the hash key is changed. Update the hash to
|
||||
ensure that the position matches the new hash key value
|
||||
*/
|
||||
hash_update(&column_priv_hash, (uchar*) grant_name,
|
||||
(uchar*) grant_name->hash_key, grant_name->key_length);
|
||||
break;
|
||||
/*
|
||||
Update the grant structure with the new user name and host name.
|
||||
*/
|
||||
grant_name->set_user_details(user_to->host.str, grant_name->db,
|
||||
user_to->user.str, grant_name->tname,
|
||||
TRUE);
|
||||
|
||||
/*
|
||||
Since username is part of the hash key, when the user name
|
||||
is renamed, the hash key is changed. Update the hash to
|
||||
ensure that the position matches the new hash key value
|
||||
*/
|
||||
hash_update(grant_name_hash, (uchar*) grant_name, (uchar*) old_key,
|
||||
old_key_length);
|
||||
/*
|
||||
hash_update() operation could have moved element from the tail
|
||||
of the hash to the current position. So we need to take a look
|
||||
at the element in current position once again.
|
||||
Thanks to the fact that hash_update() for our HASH implementation
|
||||
won't move any elements from the tail of the hash to the positions
|
||||
before the current one (a.k.a. head) it is safe to continue
|
||||
iteration without restarting.
|
||||
*/
|
||||
idx--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -5633,7 +5664,7 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop,
|
|||
}
|
||||
}
|
||||
|
||||
/* Handle procedures table. */
|
||||
/* Handle stored routines table. */
|
||||
if ((found= handle_grant_table(tables, 4, drop, user_from, user_to)) < 0)
|
||||
{
|
||||
/* Handle of table failed, don't touch in-memory array. */
|
||||
|
@ -5650,6 +5681,15 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop,
|
|||
if (! drop && ! user_to)
|
||||
goto end;
|
||||
}
|
||||
/* Handle funcs array. */
|
||||
if (((handle_grant_struct(4, drop, user_from, user_to) && ! result) ||
|
||||
found) && ! result)
|
||||
{
|
||||
result= 1; /* At least one record/element found. */
|
||||
/* If search is requested, we do not need to search further. */
|
||||
if (! drop && ! user_to)
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle tables table. */
|
||||
|
|
Loading…
Reference in a new issue