diff --git a/mysql-test/main/partition_grant.result b/mysql-test/main/partition_grant.result index c269896975db8..aeb0be8c8df7a 100644 --- a/mysql-test/main/partition_grant.result +++ b/mysql-test/main/partition_grant.result @@ -25,7 +25,6 @@ connection default; revoke alter on mysqltest_1.* from mysqltest_1@localhost; connect conn3,localhost,mysqltest_1,,mysqltest_1; alter table t1 drop partition p3; -ERROR 42000: ALTER command denied to user 'mysqltest_1'@'localhost' for table `mysqltest_1`.`t1` disconnect conn3; connection default; revoke select,alter,drop on mysqltest_1.* from mysqltest_1@localhost; @@ -49,3 +48,48 @@ drop table t1; drop user mysqltest_1@localhost; drop schema mysqltest_1; End of 5.1 tests +# +# MDEV-39028: DROP PARTITION should only require DROP privilege +# +CREATE DATABASE mysqltest_2; +USE mysqltest_2; +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),(3); +CREATE USER mysqltest_2@localhost; +# Test with only DROP privilege (should succeed) +GRANT DROP ON mysqltest_2.* TO mysqltest_2@localhost; +connect conn_drop,localhost,mysqltest_2,,mysqltest_2; +SHOW GRANTS FOR CURRENT_USER; +Grants for mysqltest_2@localhost +GRANT USAGE ON *.* TO `mysqltest_2`@`localhost` +GRANT DROP ON `mysqltest_2`.* TO `mysqltest_2`@`localhost` +ALTER TABLE t1 DROP PARTITION p1; +disconnect conn_drop; +connection default; +REVOKE DROP ON mysqltest_2.* FROM mysqltest_2@localhost; +# Test with only ALTER privilege (should fail) +GRANT ALTER ON mysqltest_2.* TO mysqltest_2@localhost; +connect conn_alter,localhost,mysqltest_2,,mysqltest_2; +SHOW GRANTS FOR CURRENT_USER; +Grants for mysqltest_2@localhost +GRANT USAGE ON *.* TO `mysqltest_2`@`localhost` +GRANT ALTER ON `mysqltest_2`.* TO `mysqltest_2`@`localhost` +ALTER TABLE t1 DROP PARTITION p2; +ERROR 42000: DROP command denied to user 'mysqltest_2'@'localhost' for table `mysqltest_2`.`t1` +disconnect conn_alter; +connection default; +REVOKE ALTER ON mysqltest_2.* FROM mysqltest_2@localhost; +# Test with no privileges (should fail) +GRANT SELECT ON mysqltest_2.* TO mysqltest_2@localhost; +connect conn_none,localhost,mysqltest_2,,mysqltest_2; +ALTER TABLE t1 DROP PARTITION p3; +ERROR 42000: DROP command denied to user 'mysqltest_2'@'localhost' for table `mysqltest_2`.`t1` +disconnect conn_none; +connection default; +DROP TABLE t1; +DROP USER mysqltest_2@localhost; +DROP DATABASE mysqltest_2; diff --git a/mysql-test/main/partition_grant.test b/mysql-test/main/partition_grant.test index a5df218bb1038..45ce64fef8333 100644 --- a/mysql-test/main/partition_grant.test +++ b/mysql-test/main/partition_grant.test @@ -46,7 +46,6 @@ 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; @@ -80,3 +79,56 @@ drop user mysqltest_1@localhost; drop schema mysqltest_1; --echo End of 5.1 tests + +--echo # +--echo # MDEV-39028: DROP PARTITION should only require DROP privilege +--echo # + +CREATE DATABASE mysqltest_2; +USE mysqltest_2; + +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),(3); + +CREATE USER mysqltest_2@localhost; + +--echo # Test with only DROP privilege (should succeed) +GRANT DROP ON mysqltest_2.* TO mysqltest_2@localhost; + +connect (conn_drop,localhost,mysqltest_2,,mysqltest_2); +SHOW GRANTS FOR CURRENT_USER; +ALTER TABLE t1 DROP PARTITION p1; +disconnect conn_drop; + +connection default; +REVOKE DROP ON mysqltest_2.* FROM mysqltest_2@localhost; + +--echo # Test with only ALTER privilege (should fail) +GRANT ALTER ON mysqltest_2.* TO mysqltest_2@localhost; + +connect (conn_alter,localhost,mysqltest_2,,mysqltest_2); +SHOW GRANTS FOR CURRENT_USER; +--error ER_TABLEACCESS_DENIED_ERROR +ALTER TABLE t1 DROP PARTITION p2; +disconnect conn_alter; + +connection default; +REVOKE ALTER ON mysqltest_2.* FROM mysqltest_2@localhost; + +--echo # Test with no privileges (should fail) +GRANT SELECT ON mysqltest_2.* TO mysqltest_2@localhost; + +connect (conn_none,localhost,mysqltest_2,,mysqltest_2); +--error ER_TABLEACCESS_DENIED_ERROR +ALTER TABLE t1 DROP PARTITION p3; +disconnect conn_none; + +connection default; + +DROP TABLE t1; +DROP USER mysqltest_2@localhost; +DROP DATABASE mysqltest_2; diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc index 9e4bc4c2d349e..d5bd26ca2f4bd 100644 --- a/sql/sql_alter.cc +++ b/sql/sql_alter.cc @@ -542,11 +542,12 @@ bool Sql_cmd_alter_table::execute(THD *thd) DBUG_RETURN(TRUE); } /* - We also require DROP priv for ALTER TABLE ... DROP PARTITION, as well - as for RENAME TO, as being done by SQLCOM_RENAME_TABLE + DROP PARTITION only requires DROP privilege (not ALTER), consistent + with TRUNCATE PARTITION, but RENAME TO requires both ALTER and DROP */ - if ((alter_info.partition_flags & ALTER_PARTITION_DROP) || - (alter_info.flags & ALTER_RENAME)) + if (alter_info.partition_flags & ALTER_PARTITION_DROP) + priv_needed= DROP_ACL; + else if (alter_info.flags & ALTER_RENAME) priv_needed|= DROP_ACL; /* Must be set in the parser */