summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2020-04-28 09:16:33 +0200
committerOleksandr Byelkin <sanja@mariadb.com>2020-04-28 09:16:33 +0200
commitd08860b28f3645bb59275941e56d63bef7ea3e05 (patch)
treea456998d5d4e031d3176b7b9bea5740fe5377adb
parentac2604f923f5bd81920c5edd2c572a88778026dc (diff)
downloadmariadb-git-bb-5.5-MDEV-22374.tar.gz
MDEV-22374: VIEW with security definer require FILE privilege from definer not invoker in case of INTO OUTFILEbb-5.5-MDEV-22374
Check INTO OUTFILE clause always from invoker.
-rw-r--r--mysql-test/r/view_grant.result21
-rw-r--r--mysql-test/t/view_grant.test33
-rw-r--r--sql/sql_parse.cc18
3 files changed, 63 insertions, 9 deletions
diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result
index b2d3a0b8ca4..37dc6adc978 100644
--- a/mysql-test/r/view_grant.result
+++ b/mysql-test/r/view_grant.result
@@ -1587,3 +1587,24 @@ USE test;
DROP DATABASE mysqltest1;
DROP USER 'mysqluser1'@'%';
DROP USER 'mysqluser2'@'%';
+#
+# MDEV-22374: VIEW with security definer require FILE privilege from definer
+# not invoker in case of INTO OUTFILE
+#
+create user test@localhost;
+grant select on test.* to test@localhost;
+create table t1 (a int);
+create definer=test@localhost sql security definer view v1 as select * from t1;
+# check that ot works without view
+select * INTO OUTFILE '../..//tmp/test_out_txt' from t1;
+# check that ot works without file
+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;
+drop view v1;
+drop table t1;
+drop user test@localhost;
+# End of 5.5 tests
diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test
index ee7374e06f4..6e31f9f9f95 100644
--- a/mysql-test/t/view_grant.test
+++ b/mysql-test/t/view_grant.test
@@ -2055,3 +2055,36 @@ DROP USER 'mysqluser2'@'%';
# Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc
+
+--echo #
+--echo # MDEV-22374: VIEW with security definer require FILE privilege from definer
+--echo # not invoker in case of INTO OUTFILE
+--echo #
+
+
+create user test@localhost;
+grant select on test.* to test@localhost;
+
+create table t1 (a int);
+create definer=test@localhost sql security definer view v1 as select * from t1;
+
+--echo # check that ot works without view
+select * INTO OUTFILE '../..//tmp/test_out_txt' from t1;
+--echo # check that ot works without file
+select * from v1;
+
+remove_file $MYSQLTEST_VARDIR/tmp/test_out_txt;
+
+--echo # 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;
+remove_file $MYSQLTEST_VARDIR/tmp/test_out_txt;
+select * INTO OUTFILE '../..//tmp/test_out_txt' from (select * from v1) as dv1;
+remove_file $MYSQLTEST_VARDIR/tmp/test_out_txt;
+select * INTO OUTFILE '../..//tmp/test_out_txt' from v1;
+
+remove_file $MYSQLTEST_VARDIR/tmp/test_out_txt;
+drop view v1;
+drop table t1;
+drop user test@localhost;
+
+--echo # 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);
+ }
if (res)
break;