> +create table t1 (a int);
|
> +create definer=test@localhost sql security definer view v1 as select * from t1;
|
> +# check that ot works without view
|
|
typo "it"
|
|
> +select * INTO OUTFILE '../..//tmp/test_out_txt' from t1;
|
> +# check that ot works without file
|
|
same
|
why "//" ?
|
|
> +select * from v1;
|
> +a
|
> +# rights for file should be taken from current user not view
|
> +select * INTO OUTFILE '../../tmp/test_out_txt' from (select count(*) from v1) as dv1;
|
> +select * INTO OUTFILE '../..//tmp/test_out_txt' from (select * from v1) as dv1;
|
> +select * INTO OUTFILE '../..//tmp/test_out_txt' from v1;
|
|
same
|
|
> +drop view v1;
|
|
please add reverse tests too:
|
|
+create sql security definer view v1 as select * from t1;
|
+connect(con1, localhost, test);
|
+error 1045;
|
+select * INTO OUTFILE '../..//tmp/test_out_txt' from t1;
|
+select * from v1;
|
+error 1045;
|
+select * INTO OUTFILE '../../tmp/test_out_txt' from (select count(*) from v1) as dv1;
|
+error 1045;
|
+select * INTO OUTFILE '../..//tmp/test_out_txt' from (select * from v1) as dv1;
|
+error 1045;
|
+select * INTO OUTFILE '../..//tmp/test_out_txt' from v1;
|
+connection default;
|
|
> +drop table t1;
|
> +drop user test@localhost;
|
> +# End of 5.5 tests
|
> diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
|
> index ae5a6b4cd35..515990c879f 100644
|
> --- a/sql/sql_parse.cc
|
> +++ b/sql/sql_parse.cc
|
> @@ -2206,15 +2206,15 @@ mysql_execute_command(THD *thd)
|
> lex->exchange != NULL implies SELECT .. INTO OUTFILE and this
|
> requires FILE_ACL access.
|
> */
|
> - ulong privileges_requested= lex->exchange ? SELECT_ACL | FILE_ACL :
|
> - SELECT_ACL;
|
> -
|
> - if (all_tables)
|
> - res= check_table_access(thd,
|
> - privileges_requested,
|
> - all_tables, FALSE, UINT_MAX, FALSE);
|
> - else
|
> - res= check_access(thd, privileges_requested, any_db, NULL, NULL, 0, 0);
|
> + if (lex->exchange)
|
> + res= check_access(thd, FILE_ACL, any_db, NULL, NULL, 0, 0);
|
> + if (!res)
|
> + {
|
> + if (all_tables)
|
> + res= check_table_access(thd, SELECT_ACL, all_tables, FALSE, UINT_MAX, FALSE);
|
> + else
|
> + res= check_access(thd, SELECT_ACL, any_db, NULL, NULL, 0, 0);
|
> + }
|
|
No, I think this special check for a special SELECT ... INTO OUTFILE
|
case is wrong. Why does the server even checks global privileges via
|
views? It should not do it, I think, not for FILE not for any other
|
global or db level privilege. I'd try something like
|
|
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
|
--- a/sql/sql_acl.cc
|
+++ b/sql/sql_acl.cc
|
@@ -4699,7 +4699,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST >
|
Save a copy of the privileges without the SHOW_VIEW_ACL attribute.
|
It will be checked during making view.
|
*/
|
- tl->grant.orig_want_privilege= (want_access & ~SHOW_VIEW_ACL);
|
+ tl->grant.orig_want_privilege= want_access & ~SHOW_VIEW_ACL & TABLE_ACLS;
|
}
|
|
mysql_rwlock_rdlock(&LOCK_grant);
|
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
|
--- a/sql/sql_parse.cc
|
+++ b/sql/sql_parse.cc
|
@@ -5204,7 +5204,8 @@ check_table_access(THD *thd, ulong requirements,TABLE_LIS>
|
Register access for view underlying table.
|
Remove SHOW_VIEW_ACL, because it will be checked during making view
|
*/
|
- table_ref->grant.orig_want_privilege= (want_access & ~SHOW_VIEW_ACL);
|
+ table_ref->grant.orig_want_privilege=
|
+ want_access & ~SHOW_VIEW_ACL & TABLE_ACLS;
|
|
if (table_ref->schema_table_reformed)
|
{
|
commit d08860b28f3645bb59275941e56d63bef7ea3e05 (HEAD
> bb-5.5MDEV-22374, origin/bb-5.5-MDEV-22374)Author: Oleksandr Byelkin <sanja@mariadb.com>
Date: Tue Apr 28 09:16:33 2020 +0200
MDEV-22374: VIEW with security definer require FILE privilege from definer not invoker in case of INTO OUTFILE
Check INTO OUTFILE clause always from invoker.