summaryrefslogtreecommitdiff
path: root/mysql-test
diff options
context:
space:
mode:
authorDmitry Lenev <Dmitry.Lenev@oracle.com>2011-02-07 14:01:19 +0300
committerDmitry Lenev <Dmitry.Lenev@oracle.com>2011-02-07 14:01:19 +0300
commitb169b8d8530208f7655782841fdbe92a1b61f56d (patch)
tree3ffc50dff613ee7cb47da959a3db5b813e7bda41 /mysql-test
parente8ffaf4ae7f835534bf844410baa18d02f996cef (diff)
downloadmariadb-git-b169b8d8530208f7655782841fdbe92a1b61f56d.tar.gz
Fix for bug#36544 "DROP USER does not remove stored function
privileges". The first problem was that DROP USER didn't properly remove privileges on stored functions from in-memory structures. So the dropped user could have called stored functions on which he had privileges before being dropped while his connection was still around. Even worse if a new user with the same name was created he would inherit privileges on stored functions from the dropped user. Similar thing happened with old user name and function privileges during RENAME USER. This problem stemmed from the fact that the handle_grant_data() function which handled DROP/RENAME USER didn't take any measures to update in-memory hash with information about function privileges after updating them on disk. This patch solves this problem by adding code doing just that. The second problem was that RENAME USER didn't properly update in-memory structures describing table-level privileges and privileges on stored procedures. As result such privileges could have been lost after a rename (i.e. not associated with the new name of user) and inherited by a new user with the same name as the old name of the original user. This problem was caused by code handling RENAME USER in handle_grant_struct() which [sic!]: a) tried to update wrong (tables) hash when updating stored procedure privileges for new user name. b) passed wrong arguments to function performing the hash update and didn't take into account the way in which such update could have changed the order of the hash elements. This patch solves this problem by ensuring that a) the correct hash is updated, b) correct arguments are used for the hash_update() function and c) we take into account possible changes in the order of hash elements. mysql-test/r/grant.result: Added test coverage for bug#36544 "DROP USER does not remove stored function privileges". mysql-test/suite/funcs_1/r/innodb_storedproc_06.result: Since after fixing bug#36544 "DROP USER does not remove stored function privileges" in-memory structures are correctly updated by DROP USER, DROP FUNCTION performed after DROP USER for its definer no longer produces unwarranted warning/error messages. mysql-test/suite/funcs_1/r/memory_storedproc_06.result: Since after fixing bug#36544 "DROP USER does not remove stored function privileges" in-memory structures are correctly updated by DROP USER, DROP FUNCTION performed after DROP USER for its definer no longer produces unwarranted warning/error messages. mysql-test/suite/funcs_1/r/myisam_storedproc_06.result: Since after fixing bug#36544 "DROP USER does not remove stored function privileges" in-memory structures are correctly updated by DROP USER, DROP FUNCTION performed after DROP USER for its definer no longer produces unwarranted warning/error messages. mysql-test/t/grant.test: Added test coverage for bug#36544 "DROP USER does not remove stored function privileges". sql/sql_acl.cc: Changed handle_grant_data() to also update hash with function privileges. This allows DROP/RENAME USER correctly keep this in-memory structure up-to-date. To do this extended handle_grant_struct() to support updating of this hash. In addition fixed code in this function which is responsible for handling of column and routine hashes during RENAME USER, ensured that we correctly update these hashes after changing user name and that we don't skip elements while iterating through the hash and doing updates.
Diffstat (limited to 'mysql-test')
-rw-r--r--mysql-test/r/grant.result193
-rw-r--r--mysql-test/suite/funcs_1/r/innodb_storedproc_06.result4
-rw-r--r--mysql-test/suite/funcs_1/r/memory_storedproc_06.result4
-rw-r--r--mysql-test/suite/funcs_1/r/myisam_storedproc_06.result4
-rw-r--r--mysql-test/t/grant.test177
5 files changed, 370 insertions, 12 deletions
diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result
index e7ae6612746..bce330d380f 100644
--- a/mysql-test/r/grant.result
+++ b/mysql-test/r/grant.result
@@ -1230,4 +1230,197 @@ 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
diff --git a/mysql-test/suite/funcs_1/r/innodb_storedproc_06.result b/mysql-test/suite/funcs_1/r/innodb_storedproc_06.result
index 88bddf68e24..41d9fb0a1c7 100644
--- a/mysql-test/suite/funcs_1/r/innodb_storedproc_06.result
+++ b/mysql-test/suite/funcs_1/r/innodb_storedproc_06.result
@@ -131,10 +131,6 @@ root@localhost db_storedproc_1
drop user 'user_1'@'localhost';
DROP PROCEDURE sp3;
DROP FUNCTION fn1;
-Warnings:
-Error 1133 Can't find any matching row in the user table
-Error 1269 Can't revoke all privileges for one or more of the requested users
-Warning 1405 Failed to revoke all privileges to dropped routine
Testcase 3.1.6.4:
-----------------
diff --git a/mysql-test/suite/funcs_1/r/memory_storedproc_06.result b/mysql-test/suite/funcs_1/r/memory_storedproc_06.result
index 88bddf68e24..41d9fb0a1c7 100644
--- a/mysql-test/suite/funcs_1/r/memory_storedproc_06.result
+++ b/mysql-test/suite/funcs_1/r/memory_storedproc_06.result
@@ -131,10 +131,6 @@ root@localhost db_storedproc_1
drop user 'user_1'@'localhost';
DROP PROCEDURE sp3;
DROP FUNCTION fn1;
-Warnings:
-Error 1133 Can't find any matching row in the user table
-Error 1269 Can't revoke all privileges for one or more of the requested users
-Warning 1405 Failed to revoke all privileges to dropped routine
Testcase 3.1.6.4:
-----------------
diff --git a/mysql-test/suite/funcs_1/r/myisam_storedproc_06.result b/mysql-test/suite/funcs_1/r/myisam_storedproc_06.result
index 88bddf68e24..41d9fb0a1c7 100644
--- a/mysql-test/suite/funcs_1/r/myisam_storedproc_06.result
+++ b/mysql-test/suite/funcs_1/r/myisam_storedproc_06.result
@@ -131,10 +131,6 @@ root@localhost db_storedproc_1
drop user 'user_1'@'localhost';
DROP PROCEDURE sp3;
DROP FUNCTION fn1;
-Warnings:
-Error 1133 Can't find any matching row in the user table
-Error 1269 Can't revoke all privileges for one or more of the requested users
-Warning 1405 Failed to revoke all privileges to dropped routine
Testcase 3.1.6.4:
-----------------
diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test
index 21e3bbf5842..bf7b7ba4bb8 100644
--- a/mysql-test/t/grant.test
+++ b/mysql-test/t/grant.test
@@ -1267,6 +1267,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
disconnect master;