mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
Fixed bug mdev-13453 Executing a query via CTE requires more permissions
than the query itself ACL checks were not properly supported for tables used in CTE specifications. This patch fixes the problem.
This commit is contained in:
parent
24184938ad
commit
3afc9629fd
5 changed files with 123 additions and 1 deletions
|
@ -1147,3 +1147,61 @@ SELECT * FROM cte_test;
|
|||
a
|
||||
1
|
||||
DROP VIEW cte_test;
|
||||
#
|
||||
# MDEV-13453: privileges checking for CTE
|
||||
#
|
||||
create database db;
|
||||
use db;
|
||||
create table t1 (i int);
|
||||
insert into t1
|
||||
values (3), (7), (1), (4), (2), (3), (1);
|
||||
create table t2 (a int, b int);
|
||||
insert into t2
|
||||
values (3,10), (7,11), (1,17), (4,15), (2,11), (3,10), (1,15);
|
||||
create user foo@localhost;
|
||||
grant SELECT on db.t1 to foo@localhost;
|
||||
grant SELECT(a) on db.t2 to foo@localhost;
|
||||
connect con1,localhost,foo,,;
|
||||
use db;
|
||||
with cte as (select * from t1 where i < 4)
|
||||
select * from cte;
|
||||
i
|
||||
3
|
||||
1
|
||||
2
|
||||
3
|
||||
1
|
||||
with cte as (select * from t1 where i < 4 group by i)
|
||||
select * from cte;
|
||||
i
|
||||
1
|
||||
2
|
||||
3
|
||||
with cte as (select * from t1 where i < 4)
|
||||
select * from cte cte1 where i < 2 union select * from cte cte2 where i > 2;
|
||||
i
|
||||
1
|
||||
3
|
||||
with cte as (select * from t1 where i < 4 group by i)
|
||||
select * from cte cte1 where i < 2 union select * from cte cte2 where i > 2;
|
||||
i
|
||||
1
|
||||
3
|
||||
with cte as (select b from t2 where a < 4)
|
||||
select * from cte cte1 where b < 15 union select * from cte cte2 where b > 15;
|
||||
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'b' in table 't2'
|
||||
with cte as (select a from t2 where a < 4)
|
||||
select * from cte cte1 where a < 2 union select * from cte cte2 where a > 2;
|
||||
a
|
||||
1
|
||||
3
|
||||
connection default;
|
||||
revoke SELECT on db.t1 from foo@localhost;
|
||||
connection con1;
|
||||
with cte as (select * from t1 where i < 4)
|
||||
select * from cte;
|
||||
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 't1'
|
||||
disconnect con1;
|
||||
connection default;
|
||||
drop database db;
|
||||
drop user foo@localhost;
|
||||
|
|
|
@ -790,3 +790,54 @@ SHOW CREATE VIEW cte_test;
|
|||
SELECT * FROM cte_test;
|
||||
|
||||
DROP VIEW cte_test;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-13453: privileges checking for CTE
|
||||
--echo #
|
||||
|
||||
create database db;
|
||||
use db;
|
||||
create table t1 (i int);
|
||||
insert into t1
|
||||
values (3), (7), (1), (4), (2), (3), (1);
|
||||
|
||||
create table t2 (a int, b int);
|
||||
insert into t2
|
||||
values (3,10), (7,11), (1,17), (4,15), (2,11), (3,10), (1,15);
|
||||
|
||||
create user foo@localhost;
|
||||
grant SELECT on db.t1 to foo@localhost;
|
||||
grant SELECT(a) on db.t2 to foo@localhost;
|
||||
|
||||
--connect (con1,localhost,foo,,)
|
||||
use db;
|
||||
with cte as (select * from t1 where i < 4)
|
||||
select * from cte;
|
||||
with cte as (select * from t1 where i < 4 group by i)
|
||||
select * from cte;
|
||||
with cte as (select * from t1 where i < 4)
|
||||
select * from cte cte1 where i < 2 union select * from cte cte2 where i > 2;
|
||||
with cte as (select * from t1 where i < 4 group by i)
|
||||
select * from cte cte1 where i < 2 union select * from cte cte2 where i > 2;
|
||||
|
||||
--error ER_COLUMNACCESS_DENIED_ERROR
|
||||
with cte as (select b from t2 where a < 4)
|
||||
select * from cte cte1 where b < 15 union select * from cte cte2 where b > 15;
|
||||
with cte as (select a from t2 where a < 4)
|
||||
select * from cte cte1 where a < 2 union select * from cte cte2 where a > 2;
|
||||
|
||||
--connection default
|
||||
revoke SELECT on db.t1 from foo@localhost;
|
||||
|
||||
--connection con1
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
with cte as (select * from t1 where i < 4)
|
||||
select * from cte;
|
||||
|
||||
# Cleanup
|
||||
--disconnect con1
|
||||
|
||||
--connection default
|
||||
drop database db;
|
||||
drop user foo@localhost;
|
||||
|
|
|
@ -7557,6 +7557,10 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
|
|||
tl->correspondent_table ? tl->correspondent_table : tl;
|
||||
sctx= t_ref->security_ctx ? t_ref->security_ctx : thd->security_ctx;
|
||||
|
||||
if (tl->with ||
|
||||
(tl->with= tl->select_lex->find_table_def_in_with_clauses(tl)))
|
||||
continue;
|
||||
|
||||
const ACL_internal_table_access *access=
|
||||
get_cached_table_access(&t_ref->grant.m_internal,
|
||||
t_ref->get_db_name(),
|
||||
|
|
|
@ -823,9 +823,10 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd,
|
|||
tbl;
|
||||
tbl= tbl->next_global)
|
||||
{
|
||||
tbl->grant.privilege= with_table->grant.privilege;
|
||||
spec_tables_tail= tbl;
|
||||
}
|
||||
if (check_table_access(thd, SELECT_ACL, spec_tables, FALSE, UINT_MAX, FALSE))
|
||||
goto err;
|
||||
if (spec_tables)
|
||||
{
|
||||
if (with_table->next_global)
|
||||
|
|
|
@ -3443,6 +3443,14 @@ mysql_execute_command(THD *thd)
|
|||
ulong privileges_requested= lex->exchange ? SELECT_ACL | FILE_ACL :
|
||||
SELECT_ACL;
|
||||
|
||||
/*
|
||||
The same function must be called for DML commands
|
||||
when CTEs are supported in DML statements
|
||||
*/
|
||||
res= check_dependencies_in_with_clauses(thd->lex->with_clauses_list);
|
||||
if (res)
|
||||
break;
|
||||
|
||||
if (all_tables)
|
||||
res= check_table_access(thd,
|
||||
privileges_requested,
|
||||
|
|
Loading…
Reference in a new issue