Commit b337ac28 authored by Georgi Kodinov's avatar Georgi Kodinov

Bug #41354: Access control is bypassed when all columns

of a view are selected by * wildcard

Backported a part of the fix for 36086 to 5.0
parent ce78a8bd
...@@ -919,4 +919,30 @@ c4 ...@@ -919,4 +919,30 @@ c4
DROP DATABASE mysqltest1; DROP DATABASE mysqltest1;
DROP DATABASE mysqltest2; DROP DATABASE mysqltest2;
DROP USER mysqltest_u1@localhost; DROP USER mysqltest_u1@localhost;
CREATE DATABASE db1;
USE db1;
CREATE TABLE t1(f1 INT, f2 INT);
CREATE VIEW v1 AS SELECT f1, f2 FROM t1;
GRANT SELECT (f1) ON t1 TO foo;
GRANT SELECT (f1) ON v1 TO foo;
USE db1;
SELECT f1 FROM t1;
f1
SELECT f2 FROM t1;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'f2' in table 't1'
SELECT * FROM t1;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 't1'
SELECT f1 FROM v1;
f1
SELECT f2 FROM v1;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'f2' in table 'v1'
SELECT * FROM v1;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 'v1'
USE test;
REVOKE SELECT (f1) ON db1.t1 FROM foo;
REVOKE SELECT (f1) ON db1.v1 FROM foo;
DROP USER foo;
DROP VIEW db1.v1;
DROP TABLE db1.t1;
DROP DATABASE db1;
End of 5.0 tests. End of 5.0 tests.
...@@ -1185,4 +1185,44 @@ DROP DATABASE mysqltest1; ...@@ -1185,4 +1185,44 @@ DROP DATABASE mysqltest1;
DROP DATABASE mysqltest2; DROP DATABASE mysqltest2;
DROP USER mysqltest_u1@localhost; DROP USER mysqltest_u1@localhost;
#
# Bug #41354: Access control is bypassed when all columns of a view are
# selected by * wildcard
CREATE DATABASE db1;
USE db1;
CREATE TABLE t1(f1 INT, f2 INT);
CREATE VIEW v1 AS SELECT f1, f2 FROM t1;
GRANT SELECT (f1) ON t1 TO foo;
GRANT SELECT (f1) ON v1 TO foo;
connect (addconfoo, localhost, foo,,);
connection addconfoo;
USE db1;
SELECT f1 FROM t1;
--error ER_COLUMNACCESS_DENIED_ERROR
SELECT f2 FROM t1;
--error ER_TABLEACCESS_DENIED_ERROR
SELECT * FROM t1;
SELECT f1 FROM v1;
--error ER_COLUMNACCESS_DENIED_ERROR
SELECT f2 FROM v1;
--error ER_TABLEACCESS_DENIED_ERROR
SELECT * FROM v1;
connection default;
USE test;
disconnect addconfoo;
REVOKE SELECT (f1) ON db1.t1 FROM foo;
REVOKE SELECT (f1) ON db1.v1 FROM foo;
DROP USER foo;
DROP VIEW db1.v1;
DROP TABLE db1.t1;
DROP DATABASE db1;
--echo End of 5.0 tests. --echo End of 5.0 tests.
...@@ -3866,6 +3866,11 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg, ...@@ -3866,6 +3866,11 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg,
Security_context *sctx= thd->security_ctx; Security_context *sctx= thd->security_ctx;
ulong want_access= want_access_arg; ulong want_access= want_access_arg;
const char *table_name= NULL; const char *table_name= NULL;
/*
Flag that gets set if privilege checking has to be performed on column
level.
*/
bool using_column_privileges= FALSE;
if (grant_option) if (grant_option)
{ {
...@@ -3909,6 +3914,8 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg, ...@@ -3909,6 +3914,8 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg,
GRANT_COLUMN *grant_column= GRANT_COLUMN *grant_column=
column_hash_search(grant_table, field_name, column_hash_search(grant_table, field_name,
(uint) strlen(field_name)); (uint) strlen(field_name));
if (grant_column)
using_column_privileges= TRUE;
if (!grant_column || (~grant_column->rights & want_access)) if (!grant_column || (~grant_column->rights & want_access))
goto err; goto err;
} }
...@@ -3924,12 +3931,21 @@ err: ...@@ -3924,12 +3931,21 @@ err:
char command[128]; char command[128];
get_privilege_desc(command, sizeof(command), want_access); get_privilege_desc(command, sizeof(command), want_access);
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), /*
command, Do not give an error message listing a column name unless the user has
sctx->priv_user, privilege to see all columns.
sctx->host_or_ip, */
fields->name(), if (using_column_privileges)
table_name); my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
command, sctx->priv_user,
sctx->host_or_ip, table_name);
else
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
command,
sctx->priv_user,
sctx->host_or_ip,
fields->name(),
table_name);
return 1; return 1;
} }
......
...@@ -5479,7 +5479,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, ...@@ -5479,7 +5479,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
/* Ensure that we have access rights to all fields to be inserted. */ /* Ensure that we have access rights to all fields to be inserted. */
if (!((table && (table->grant.privilege & SELECT_ACL) || if (!((table && !tables->view && (table->grant.privilege & SELECT_ACL) ||
tables->view && (tables->grant.privilege & SELECT_ACL))) && tables->view && (tables->grant.privilege & SELECT_ACL))) &&
!any_privileges) !any_privileges)
{ {
......
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