diff --git a/mysql-test/suite/sql_sequence/alter.result b/mysql-test/suite/sql_sequence/alter.result index 1d734100d74..283253b585a 100644 --- a/mysql-test/suite/sql_sequence/alter.result +++ b/mysql-test/suite/sql_sequence/alter.result @@ -238,3 +238,41 @@ select next value for t1; next value for t1 90 drop sequence t1; + +GRANT + +create database s_db; +create sequence s_db.s1; +grant select on s_db.s1 to normal_1@'%' identified by 'pass'; +connect m_normal_1, localhost, normal_1, pass, s_db; +select * from s1; +next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count +1 1 9223372036854775806 1 1 1000 0 0 +select nextval(s1); +ERROR 42000: INSERT command denied to user 'normal_1'@'localhost' for table 's1' +show create sequence s1; +Table Create Table +s1 CREATE SEQUENCE `s1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=MyISAM +alter sequence s1 restart 50; +ERROR 42000: ALTER command denied to user 'normal_1'@'localhost' for table 's1' +connection default; +grant insert on s_db.s1 to normal_1@'%'; +connection m_normal_1; +select nextval(s1); +nextval(s1) +1 +alter sequence s1 restart 50; +ERROR 42000: ALTER command denied to user 'normal_1'@'localhost' for table 's1' +connection default; +grant alter on s_db.s1 to normal_1@'%'; +connection m_normal_1; +alter sequence s1 restart 50; +select nextval(s1); +nextval(s1) +50 +drop sequence s1; +ERROR 42000: DROP command denied to user 'normal_1'@'localhost' for table 's1' +connection default; +disconnect m_normal_1; +drop database s_db; +drop user normal_1@'%'; diff --git a/mysql-test/suite/sql_sequence/alter.test b/mysql-test/suite/sql_sequence/alter.test index fd1809ccd2f..a05a3e2e78b 100644 --- a/mysql-test/suite/sql_sequence/alter.test +++ b/mysql-test/suite/sql_sequence/alter.test @@ -139,3 +139,37 @@ select next value for t1; alter sequence t1 restart with 90; select next value for t1; drop sequence t1; + +--echo +--echo GRANT +--echo + +create database s_db; +create sequence s_db.s1; +grant select on s_db.s1 to normal_1@'%' identified by 'pass'; + +connect(m_normal_1, localhost, normal_1, pass, s_db); +select * from s1; +--error ER_TABLEACCESS_DENIED_ERROR +select nextval(s1); +show create sequence s1; +--error ER_TABLEACCESS_DENIED_ERROR +alter sequence s1 restart 50; +connection default; +grant insert on s_db.s1 to normal_1@'%'; +connection m_normal_1; +select nextval(s1); +--error ER_TABLEACCESS_DENIED_ERROR +alter sequence s1 restart 50; +connection default; +grant alter on s_db.s1 to normal_1@'%'; +connection m_normal_1; +alter sequence s1 restart 50; +select nextval(s1); +--error ER_TABLEACCESS_DENIED_ERROR +drop sequence s1; + +connection default; +disconnect m_normal_1; +drop database s_db; +drop user normal_1@'%'; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 01927d18995..e61940ea82d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -7580,10 +7580,18 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, sctx= t_ref->security_ctx ? t_ref->security_ctx : thd->security_ctx; ulong orig_want_access= original_want_access; - if (t_ref->sequence) + /* + If sequence is used as part of NEXT VALUE, PREVIUS VALUE or SELECT, + we need to modify the requested access rights depending on how the + sequence is used. + */ + if (t_ref->sequence & + (orig_want_access & + (SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL))) { - /* We want to have either SELECT or INSERT rights to sequences depending - on how they are accessed + /* + We want to have either SELECT or INSERT rights to sequences depending + on how they are accessed */ orig_want_access= ((t_ref->lock_type == TL_WRITE_ALLOW_WRITE) ? INSERT_ACL : SELECT_ACL); diff --git a/sql/sql_sequence.cc b/sql/sql_sequence.cc index f19dd540c4e..53c9c160593 100644 --- a/sql/sql_sequence.cc +++ b/sql/sql_sequence.cc @@ -849,7 +849,7 @@ bool Sql_cmd_alter_sequence::execute(THD *thd) 0, 0)) DBUG_RETURN(TRUE); /* purecov: inspected */ - if (check_grant(thd, ALTER_ACL, first_table, FALSE, UINT_MAX, FALSE)) + if (check_grant(thd, ALTER_ACL, first_table, FALSE, 1, FALSE)) DBUG_RETURN(TRUE); /* purecov: inspected */ if (lex->check_exists)