From fbbb797dc82c983715269ee689a4fdf87a8adeeb Mon Sep 17 00:00:00 2001 From: "jimw@mysql.com" <> Date: Tue, 7 Mar 2006 12:42:23 -0800 Subject: [PATCH] Bug #17139: Partitions: unprivileged user can effectively drop table Now the DROP privilege is also required on a table in order to be able to drop a partition from the table using ALTER TABLE. --- mysql-test/r/partition_grant.result | 23 +++++++++++++ mysql-test/t/partition_grant.test | 51 +++++++++++++++++++++++++++++ sql/sql_parse.cc | 9 +++-- 3 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 mysql-test/r/partition_grant.result create mode 100644 mysql-test/t/partition_grant.test diff --git a/mysql-test/r/partition_grant.result b/mysql-test/r/partition_grant.result new file mode 100644 index 00000000000..da0e00c9858 --- /dev/null +++ b/mysql-test/r/partition_grant.result @@ -0,0 +1,23 @@ +drop schema if exists mysqltest_1; +create schema mysqltest_1; +use mysqltest_1; +create table t1 (a int) partition by list (a) (partition p1 values in (1), partition p2 values in (2), partition p3 values in (3)); +insert into t1 values (1),(2); +grant select,alter on mysqltest_1.* to mysqltest_1@localhost; +show grants for current_user; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT SELECT, ALTER ON `mysqltest_1`.* TO 'mysqltest_1'@'localhost' +alter table t1 add b int; +alter table t1 drop partition p2; +ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 't1' +grant drop on mysqltest_1.* to mysqltest_1@localhost; +alter table t1 drop partition p2; +revoke alter on mysqltest_1.* from mysqltest_1@localhost; +alter table t1 drop partition p3; +ERROR 42000: ALTER command denied to user 'mysqltest_1'@'localhost' for table 't1' +revoke select,alter,drop on mysqltest_1.* from mysqltest_1@localhost; +drop user mysqltest_1@localhost; +drop table t1; +drop schema mysqltest_1; +End of 5.1 tests diff --git a/mysql-test/t/partition_grant.test b/mysql-test/t/partition_grant.test new file mode 100644 index 00000000000..e2e80a7ca04 --- /dev/null +++ b/mysql-test/t/partition_grant.test @@ -0,0 +1,51 @@ +-- source include/have_partition.inc +# Grant tests not performed with embedded server +-- source include/not_embedded.inc + +--disable_warnings +drop schema if exists mysqltest_1; +--enable_warnings + + +# +# Bug #17139: ALTER TABLE ... DROP PARTITION should require DROP privilege +# + +create schema mysqltest_1; +use mysqltest_1; + +create table t1 (a int) partition by list (a) (partition p1 values in (1), partition p2 values in (2), partition p3 values in (3)); +insert into t1 values (1),(2); + +grant select,alter on mysqltest_1.* to mysqltest_1@localhost; + +connect (conn1,localhost,mysqltest_1,,mysqltest_1); +show grants for current_user; +alter table t1 add b int; +--error ER_TABLEACCESS_DENIED_ERROR +alter table t1 drop partition p2; +disconnect conn1; + +connection default; +grant drop on mysqltest_1.* to mysqltest_1@localhost; + +connect (conn2,localhost,mysqltest_1,,mysqltest_1); +alter table t1 drop partition p2; +disconnect conn2; + +connection default; +revoke alter on mysqltest_1.* from mysqltest_1@localhost; + +connect (conn3,localhost,mysqltest_1,,mysqltest_1); +--error ER_TABLEACCESS_DENIED_ERROR +alter table t1 drop partition p3; +disconnect conn3; + +connection default; + +revoke select,alter,drop on mysqltest_1.* from mysqltest_1@localhost; +drop user mysqltest_1@localhost; +drop table t1; +drop schema mysqltest_1; + +--echo End of 5.1 tests diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4ee47a574b1..a170a554884 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2975,6 +2975,11 @@ end_with_restore_list: #else { ulong priv=0; + ulong priv_needed= ALTER_ACL; + /* We also require DROP priv for ALTER TABLE ... DROP PARTITION */ + if (lex->alter_info.flags & ALTER_DROP_PARTITION) + priv_needed|= DROP_ACL; + if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN)) { my_error(ER_WRONG_TABLE_NAME, MYF(0), lex->name); @@ -2999,7 +3004,7 @@ end_with_restore_list: else select_lex->db= first_table->db; } - if (check_access(thd, ALTER_ACL, first_table->db, + if (check_access(thd, priv_needed, first_table->db, &first_table->grant.privilege, 0, 0, test(first_table->schema_table)) || check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv,0,0, @@ -3010,7 +3015,7 @@ end_with_restore_list: goto error; /* purecov: inspected */ if (grant_option) { - if (check_grant(thd, ALTER_ACL, all_tables, 0, UINT_MAX, 0)) + if (check_grant(thd, priv_needed, all_tables, 0, UINT_MAX, 0)) goto error; if (lex->name && !test_all_bits(priv,INSERT_ACL | CREATE_ACL)) { // Rename of table