Skip to content

Commit

Permalink
MDEV-7574 Security definer views don't work with CONNECT ODBC tables
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
vuvova committed Jul 27, 2015
1 parent 121f3e4 commit 40a6160
Show file tree
Hide file tree
Showing 13 changed files with 1,620 additions and 20 deletions.
26 changes: 21 additions & 5 deletions storage/connect/ha_connect.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4020,7 +4020,27 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn)
case TAB_MAC:
case TAB_WMI:
case TAB_OEM:
return check_access(thd, FILE_ACL, db, NULL, NULL, 0, 0);
#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);
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
case TAB_TBL:
Expand Down Expand Up @@ -6159,10 +6179,6 @@ bool ha_connect::FileExists(const char *fn, bool bf)
int n;
struct stat info;

if (check_access(ha_thd(), FILE_ACL, table->s->db.str,
NULL, NULL, 0, 0))
return true;

#if defined(__WIN__)
s= "\\";
#else // !__WIN__
Expand Down
12 changes: 6 additions & 6 deletions storage/connect/mysql-test/connect/r/grant.result
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user();
user()
root@localhost
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost
Expand Down Expand Up @@ -130,7 +130,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user();
user()
root@localhost
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost
Expand Down Expand Up @@ -224,7 +224,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user();
user()
root@localhost
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost
Expand Down Expand Up @@ -318,7 +318,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user();
user()
root@localhost
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost
Expand Down Expand Up @@ -412,7 +412,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user();
user()
root@localhost
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost
Expand Down Expand Up @@ -506,7 +506,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user();
user()
root@localhost
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost
Expand Down
690 changes: 690 additions & 0 deletions storage/connect/mysql-test/connect/r/grant2.result

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion storage/connect/mysql-test/connect/r/ini_grant.result
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user();
user()
root@localhost
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost
Expand Down
2 changes: 1 addition & 1 deletion storage/connect/mysql-test/connect/r/mysql_grant.result
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user();
user()
root@localhost
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost
Expand Down
16 changes: 15 additions & 1 deletion storage/connect/mysql-test/connect/r/odbc_sqlite3_grant.result
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,11 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
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 INVOKER
SELECT user();
user()
root@localhost
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost
Expand All @@ -64,6 +65,19 @@ UPDATE v1 SET a=123;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
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();
user()
root@localhost
Expand Down
2 changes: 1 addition & 1 deletion storage/connect/mysql-test/connect/r/xml_grant.result
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT user();
user()
root@localhost
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
SELECT user();
user()
user@localhost
Expand Down
2 changes: 1 addition & 1 deletion storage/connect/mysql-test/connect/t/grant.inc
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ CREATE VIEW v1 AS SELECT * FROM t1;
--echo # Testing a VIEW created with FILE privileges but accessed with no FILE
--connection default
SELECT user();
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
--connection user
SELECT user();
--error ER_ACCESS_DENIED_ERROR
Expand Down
2 changes: 1 addition & 1 deletion storage/connect/mysql-test/connect/t/grant.test
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ CREATE VIEW v1 AS SELECT * FROM t1;
--echo # Testing a VIEW created with FILE privileges but accessed with no FILE
--connection default
SELECT user();
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
--connection user
SELECT user();
--error ER_ACCESS_DENIED_ERROR
Expand Down
Loading

0 comments on commit 40a6160

Please sign in to comment.