Commit 40a6160f authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-7574 Security definer views don't work with CONNECT ODBC tables

Instead of checking user's privileges with check_access(),
use the cached value in table->grant.privilege instead -
it is correctly set to the invoker or definer, depending
on SQL SECURITY mode.

Continue to use check_access() for DDLs when
table->grant.privilege may be not set (but these cases are
only possible on tables, never for views).

(patch originally by Alexander Barkov)
parent 121f3e4c
...@@ -4020,7 +4020,27 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn) ...@@ -4020,7 +4020,27 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn)
case TAB_MAC: case TAB_MAC:
case TAB_WMI: case TAB_WMI:
case TAB_OEM: case TAB_OEM:
#ifdef NO_EMBEDDED_ACCESS_CHECKS
return false;
#endif
/*
If table or table->mdl_ticket is NULL - it's a DLL, e.g. CREATE TABLE.
if the table has an MDL_EXCLUSIVE lock - it's a DDL too, e.g. the
insert step of CREATE ... SELECT.
Otherwise it's a DML, the table was normally opened, locked,
privilege were already checked, and table->grant.privilege is set.
With SQL SECURITY DEFINER, table->grant.privilege has definer's privileges.
*/
if (!table || !table->mdl_ticket || table->mdl_ticket->get_type() == MDL_EXCLUSIVE)
return check_access(thd, FILE_ACL, db, NULL, NULL, 0, 0); return check_access(thd, FILE_ACL, db, NULL, NULL, 0, 0);
if (table->grant.privilege & FILE_ACL)
return false;
status_var_increment(thd->status_var.access_denied_errors);
my_error(access_denied_error_code(thd->password), MYF(0),
thd->security_ctx->priv_user, thd->security_ctx->priv_host,
(thd->password ? ER(ER_YES) : ER(ER_NO)));
return true;
// This is temporary until a solution is found // This is temporary until a solution is found
case TAB_TBL: case TAB_TBL:
...@@ -6159,10 +6179,6 @@ bool ha_connect::FileExists(const char *fn, bool bf) ...@@ -6159,10 +6179,6 @@ bool ha_connect::FileExists(const char *fn, bool bf)
int n; int n;
struct stat info; struct stat info;
if (check_access(ha_thd(), FILE_ACL, table->s->db.str,
NULL, NULL, 0, 0))
return true;
#if defined(__WIN__) #if defined(__WIN__)
s= "\\"; s= "\\";
#else // !__WIN__ #else // !__WIN__
......
...@@ -46,7 +46,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO) ...@@ -46,7 +46,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user(); SELECT user();
user() user()
root@localhost root@localhost
CREATE VIEW v1 AS SELECT * FROM t1; CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user(); SELECT user();
user() user()
user@localhost user@localhost
...@@ -130,7 +130,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO) ...@@ -130,7 +130,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user(); SELECT user();
user() user()
root@localhost root@localhost
CREATE VIEW v1 AS SELECT * FROM t1; CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user(); SELECT user();
user() user()
user@localhost user@localhost
...@@ -224,7 +224,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO) ...@@ -224,7 +224,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user(); SELECT user();
user() user()
root@localhost root@localhost
CREATE VIEW v1 AS SELECT * FROM t1; CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user(); SELECT user();
user() user()
user@localhost user@localhost
...@@ -318,7 +318,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO) ...@@ -318,7 +318,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user(); SELECT user();
user() user()
root@localhost root@localhost
CREATE VIEW v1 AS SELECT * FROM t1; CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user(); SELECT user();
user() user()
user@localhost user@localhost
...@@ -412,7 +412,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO) ...@@ -412,7 +412,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user(); SELECT user();
user() user()
root@localhost root@localhost
CREATE VIEW v1 AS SELECT * FROM t1; CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user(); SELECT user();
user() user()
user@localhost user@localhost
...@@ -506,7 +506,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO) ...@@ -506,7 +506,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user(); SELECT user();
user() user()
root@localhost root@localhost
CREATE VIEW v1 AS SELECT * FROM t1; CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user(); SELECT user();
user() user()
user@localhost user@localhost
......
This diff is collapsed.
...@@ -59,7 +59,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO) ...@@ -59,7 +59,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user(); SELECT user();
user() user()
root@localhost root@localhost
CREATE VIEW v1 AS SELECT * FROM t1; CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user(); SELECT user();
user() user()
user@localhost user@localhost
......
...@@ -40,7 +40,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO) ...@@ -40,7 +40,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user(); SELECT user();
user() user()
root@localhost root@localhost
CREATE VIEW v1 AS SELECT * FROM t1; CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user(); SELECT user();
user() user()
user@localhost user@localhost
......
...@@ -49,10 +49,11 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO) ...@@ -49,10 +49,11 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1; CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO) ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE # Testing a VIEW created with FILE privileges but accessed with no FILE
# using SQL SECIRITY INVOKER
SELECT user(); SELECT user();
user() user()
root@localhost root@localhost
CREATE VIEW v1 AS SELECT * FROM t1; CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user(); SELECT user();
user() user()
user@localhost user@localhost
...@@ -64,6 +65,19 @@ UPDATE v1 SET a=123; ...@@ -64,6 +65,19 @@ UPDATE v1 SET a=123;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO) ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1; DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO) ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
# using SQL SECIRITY DEFINER
DROP VIEW v1;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY DEFINER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost
SELECT * FROM v1 WHERE a='test1';
a
test1
SELECT user(); SELECT user();
user() user()
root@localhost root@localhost
......
...@@ -63,7 +63,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO) ...@@ -63,7 +63,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user(); SELECT user();
user() user()
root@localhost root@localhost
CREATE VIEW v1 AS SELECT * FROM t1; CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user(); SELECT user();
user() user()
user@localhost user@localhost
......
...@@ -53,7 +53,7 @@ CREATE VIEW v1 AS SELECT * FROM t1; ...@@ -53,7 +53,7 @@ CREATE VIEW v1 AS SELECT * FROM t1;
--echo # Testing a VIEW created with FILE privileges but accessed with no FILE --echo # Testing a VIEW created with FILE privileges but accessed with no FILE
--connection default --connection default
SELECT user(); SELECT user();
CREATE VIEW v1 AS SELECT * FROM t1; CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
--connection user --connection user
SELECT user(); SELECT user();
--error ER_ACCESS_DENIED_ERROR --error ER_ACCESS_DENIED_ERROR
......
...@@ -49,7 +49,7 @@ CREATE VIEW v1 AS SELECT * FROM t1; ...@@ -49,7 +49,7 @@ CREATE VIEW v1 AS SELECT * FROM t1;
--echo # Testing a VIEW created with FILE privileges but accessed with no FILE --echo # Testing a VIEW created with FILE privileges but accessed with no FILE
--connection default --connection default
SELECT user(); SELECT user();
CREATE VIEW v1 AS SELECT * FROM t1; CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
--connection user --connection user
SELECT user(); SELECT user();
--error ER_ACCESS_DENIED_ERROR --error ER_ACCESS_DENIED_ERROR
......
This diff is collapsed.
...@@ -54,7 +54,7 @@ CREATE VIEW v1 AS SELECT * FROM t1; ...@@ -54,7 +54,7 @@ CREATE VIEW v1 AS SELECT * FROM t1;
--echo # Testing a VIEW created with FILE privileges but accessed with no FILE --echo # Testing a VIEW created with FILE privileges but accessed with no FILE
--connection default --connection default
SELECT user(); SELECT user();
CREATE VIEW v1 AS SELECT * FROM t1; CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
--connection user --connection user
SELECT user(); SELECT user();
--error ER_ACCESS_DENIED_ERROR --error ER_ACCESS_DENIED_ERROR
......
...@@ -54,7 +54,7 @@ CREATE VIEW v1 AS SELECT * FROM t1; ...@@ -54,7 +54,7 @@ CREATE VIEW v1 AS SELECT * FROM t1;
--echo # Testing a VIEW created with FILE privileges but accessed with no FILE --echo # Testing a VIEW created with FILE privileges but accessed with no FILE
--connection default --connection default
SELECT user(); SELECT user();
CREATE VIEW v1 AS SELECT * FROM t1; CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
--connection user --connection user
SELECT user(); SELECT user();
--error ER_ACCESS_DENIED_ERROR --error ER_ACCESS_DENIED_ERROR
......
...@@ -56,9 +56,10 @@ ALTER TABLE t1 READONLY=1; ...@@ -56,9 +56,10 @@ ALTER TABLE t1 READONLY=1;
CREATE VIEW v1 AS SELECT * FROM t1; CREATE VIEW v1 AS SELECT * FROM t1;
--echo # Testing a VIEW created with FILE privileges but accessed with no FILE --echo # Testing a VIEW created with FILE privileges but accessed with no FILE
--echo # using SQL SECIRITY INVOKER
--connection default --connection default
SELECT user(); SELECT user();
CREATE VIEW v1 AS SELECT * FROM t1; CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
--connection user --connection user
SELECT user(); SELECT user();
--error ER_ACCESS_DENIED_ERROR --error ER_ACCESS_DENIED_ERROR
...@@ -70,6 +71,17 @@ UPDATE v1 SET a=123; ...@@ -70,6 +71,17 @@ UPDATE v1 SET a=123;
--error ER_ACCESS_DENIED_ERROR --error ER_ACCESS_DENIED_ERROR
DELETE FROM v1; DELETE FROM v1;
--echo # Testing a VIEW created with FILE privileges but accessed with no FILE
--echo # using SQL SECIRITY DEFINER
--connection default
DROP VIEW v1;
SELECT user();
CREATE SQL SECURITY DEFINER VIEW v1 AS SELECT * FROM t1;
--connection user
SELECT user();
SELECT * FROM v1 WHERE a='test1';
--disconnect user --disconnect user
--connection default --connection default
SELECT user(); SELECT user();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment