Commit 59589b31 authored by unknown's avatar unknown

Fix for bug #9838: INFORMATION_SCHEMA.COLUMNS columns of granted views missing


sql/sql_acl.cc:
  Fix for bug #9838: INFORMATION_SCHEMA.COLUMNS columns of granted views missing
    -increase grant_version in acl_init, mysql_table_grant
    -table privileges should be taken into account when we calculate column
     grants
sql/sql_show.cc:
  Fix for bug #9838: INFORMATION_SCHEMA.COLUMNS columns of granted views missing
       use 'base_name', 'file_name' because 'tables->db', 'tables->tables' could be invalid in
       case of view(derived tables).
parent bfeb5aea
...@@ -3,6 +3,8 @@ Variable_name Value ...@@ -3,6 +3,8 @@ Variable_name Value
skip_show_database OFF skip_show_database OFF
grant select, update, execute on test.* to mysqltest_2@localhost; grant select, update, execute on test.* to mysqltest_2@localhost;
grant select, update on test.* to mysqltest_1@localhost; grant select, update on test.* to mysqltest_1@localhost;
create user mysqltest_3@localhost;
create user mysqltest_3;
select * from information_schema.SCHEMATA where schema_name > 'm'; select * from information_schema.SCHEMATA where schema_name > 'm';
CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH CATALOG_NAME SCHEMA_NAME DEFAULT_CHARACTER_SET_NAME DEFAULT_COLLATION_NAME SQL_PATH
NULL mysql latin1 latin1_swedish_ci NULL NULL mysql latin1 latin1_swedish_ci NULL
...@@ -154,7 +156,9 @@ NULL mysqltest t1 a 1 NULL YES int NULL NULL 11 0 NULL NULL int(11) select,ins ...@@ -154,7 +156,9 @@ NULL mysqltest t1 a 1 NULL YES int NULL NULL 11 0 NULL NULL int(11) select,ins
show columns from mysqltest.t1 where field like "%a%"; show columns from mysqltest.t1 where field like "%a%";
Field Type Null Key Default Extra Field Type Null Key Default Extra
a int(11) YES NULL a int(11) YES NULL
create view mysqltest.v1 (c) as select a from mysqltest.t1;
grant select (a) on mysqltest.t1 to mysqltest_2@localhost; grant select (a) on mysqltest.t1 to mysqltest_2@localhost;
grant select on mysqltest.v1 to mysqltest_3;
select table_name, column_name, privileges from information_schema.columns select table_name, column_name, privileges from information_schema.columns
where table_schema = 'mysqltest' and table_name = 't1'; where table_schema = 'mysqltest' and table_name = 't1';
table_name column_name privileges table_name column_name privileges
...@@ -163,7 +167,11 @@ show columns from mysqltest.t1; ...@@ -163,7 +167,11 @@ show columns from mysqltest.t1;
Field Type Null Key Default Extra Field Type Null Key Default Extra
a int(11) YES NULL a int(11) YES NULL
b varchar(30) YES MUL NULL b varchar(30) YES MUL NULL
drop view v1; select table_name, column_name, privileges from information_schema.columns
where table_schema = 'mysqltest' and table_name = 'v1';
table_name column_name privileges
v1 c select
drop view v1, mysqltest.v1;
drop tables mysqltest.t4, mysqltest.t1, t2, t3; drop tables mysqltest.t4, mysqltest.t1, t2, t3;
drop database mysqltest; drop database mysqltest;
select * from information_schema.CHARACTER_SETS select * from information_schema.CHARACTER_SETS
...@@ -376,10 +384,10 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRAN ...@@ -376,10 +384,10 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRAN
'mysqltest_1'@'localhost' NULL test t1 a INSERT NO 'mysqltest_1'@'localhost' NULL test t1 a INSERT NO
'mysqltest_1'@'localhost' NULL test t1 a UPDATE NO 'mysqltest_1'@'localhost' NULL test t1 a UPDATE NO
'mysqltest_1'@'localhost' NULL test t1 a REFERENCES NO 'mysqltest_1'@'localhost' NULL test t1 a REFERENCES NO
delete from mysql.user where user='mysqltest_1' or user='mysqltest_2'; delete from mysql.user where user like 'mysqltest%';
delete from mysql.db where user='mysqltest_1' or user='mysqltest_2'; delete from mysql.db where user like 'mysqltest%';
delete from mysql.tables_priv where user='mysqltest_1' or user='mysqltest_2'; delete from mysql.tables_priv where user like 'mysqltest%';
delete from mysql.columns_priv where user='mysqltest_1' or user='mysqltest_2'; delete from mysql.columns_priv where user like 'mysqltest%';
flush privileges; flush privileges;
drop table t1; drop table t1;
create table t1 (a int null, primary key(a)); create table t1 (a int null, primary key(a));
......
...@@ -7,6 +7,9 @@ ...@@ -7,6 +7,9 @@
show variables where variable_name like "skip_show_database"; show variables where variable_name like "skip_show_database";
grant select, update, execute on test.* to mysqltest_2@localhost; grant select, update, execute on test.* to mysqltest_2@localhost;
grant select, update on test.* to mysqltest_1@localhost; grant select, update on test.* to mysqltest_1@localhost;
create user mysqltest_3@localhost;
create user mysqltest_3;
select * from information_schema.SCHEMATA where schema_name > 'm'; select * from information_schema.SCHEMATA where schema_name > 'm';
select schema_name from information_schema.schemata; select schema_name from information_schema.schemata;
...@@ -53,15 +56,21 @@ select * from information_schema.COLUMNS where table_name="t1" ...@@ -53,15 +56,21 @@ select * from information_schema.COLUMNS where table_name="t1"
and column_name= "a"; and column_name= "a";
show columns from mysqltest.t1 where field like "%a%"; show columns from mysqltest.t1 where field like "%a%";
create view mysqltest.v1 (c) as select a from mysqltest.t1;
grant select (a) on mysqltest.t1 to mysqltest_2@localhost; grant select (a) on mysqltest.t1 to mysqltest_2@localhost;
grant select on mysqltest.v1 to mysqltest_3;
connect (user3,localhost,mysqltest_2,,); connect (user3,localhost,mysqltest_2,,);
connection user3; connection user3;
select table_name, column_name, privileges from information_schema.columns select table_name, column_name, privileges from information_schema.columns
where table_schema = 'mysqltest' and table_name = 't1'; where table_schema = 'mysqltest' and table_name = 't1';
show columns from mysqltest.t1; show columns from mysqltest.t1;
connect (user4,localhost,mysqltest_3,,mysqltest);
connection user4;
select table_name, column_name, privileges from information_schema.columns
where table_schema = 'mysqltest' and table_name = 'v1';
connection default; connection default;
drop view v1; drop view v1, mysqltest.v1;
drop tables mysqltest.t4, mysqltest.t1, t2, t3; drop tables mysqltest.t4, mysqltest.t1, t2, t3;
drop database mysqltest; drop database mysqltest;
...@@ -176,10 +185,10 @@ select * from information_schema.USER_PRIVILEGES where grantee like '%mysqltest_ ...@@ -176,10 +185,10 @@ select * from information_schema.USER_PRIVILEGES where grantee like '%mysqltest_
select * from information_schema.SCHEMA_PRIVILEGES where grantee like '%mysqltest_1%'; select * from information_schema.SCHEMA_PRIVILEGES where grantee like '%mysqltest_1%';
select * from information_schema.TABLE_PRIVILEGES where grantee like '%mysqltest_1%'; select * from information_schema.TABLE_PRIVILEGES where grantee like '%mysqltest_1%';
select * from information_schema.COLUMN_PRIVILEGES where grantee like '%mysqltest_1%'; select * from information_schema.COLUMN_PRIVILEGES where grantee like '%mysqltest_1%';
delete from mysql.user where user='mysqltest_1' or user='mysqltest_2'; delete from mysql.user where user like 'mysqltest%';
delete from mysql.db where user='mysqltest_1' or user='mysqltest_2'; delete from mysql.db where user like 'mysqltest%';
delete from mysql.tables_priv where user='mysqltest_1' or user='mysqltest_2'; delete from mysql.tables_priv where user like 'mysqltest%';
delete from mysql.columns_priv where user='mysqltest_1' or user='mysqltest_2'; delete from mysql.columns_priv where user like 'mysqltest%';
flush privileges; flush privileges;
drop table t1; drop table t1;
......
...@@ -63,8 +63,7 @@ static bool allow_all_hosts=1; ...@@ -63,8 +63,7 @@ static bool allow_all_hosts=1;
static HASH acl_check_hosts, column_priv_hash, proc_priv_hash; static HASH acl_check_hosts, column_priv_hash, proc_priv_hash;
static DYNAMIC_ARRAY acl_wild_hosts; static DYNAMIC_ARRAY acl_wild_hosts;
static hash_filo *acl_cache; static hash_filo *acl_cache;
static uint grant_version=0; static uint grant_version=0; /* Version of priv tables. incremented by acl_init */
static uint priv_version=0; /* Version of priv tables. incremented by acl_init */
static ulong get_access(TABLE *form,uint fieldnr, uint *next_field=0); static ulong get_access(TABLE *form,uint fieldnr, uint *next_field=0);
static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b); static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b);
static ulong get_sort(uint count,...); static ulong get_sort(uint count,...);
...@@ -153,7 +152,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) ...@@ -153,7 +152,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
DBUG_RETURN(0); /* purecov: tested */ DBUG_RETURN(0); /* purecov: tested */
} }
priv_version++; /* Privileges updated */ grant_version++; /* Privileges updated */
mysql_proc_table_exists= 1; // Assume mysql.proc exists mysql_proc_table_exists= 1; // Assume mysql.proc exists
/* /*
...@@ -2721,6 +2720,7 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, ...@@ -2721,6 +2720,7 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
rw_wrlock(&LOCK_grant); rw_wrlock(&LOCK_grant);
MEM_ROOT *old_root= thd->mem_root; MEM_ROOT *old_root= thd->mem_root;
thd->mem_root= &memex; thd->mem_root= &memex;
grant_version++;
while ((Str = str_list++)) while ((Str = str_list++))
{ {
...@@ -3689,9 +3689,9 @@ ulong get_column_grant(THD *thd, GRANT_INFO *grant, ...@@ -3689,9 +3689,9 @@ ulong get_column_grant(THD *thd, GRANT_INFO *grant,
grant_column= column_hash_search(grant_table, field_name, grant_column= column_hash_search(grant_table, field_name,
(uint) strlen(field_name)); (uint) strlen(field_name));
if (!grant_column) if (!grant_column)
priv= grant->privilege; priv= (grant->privilege | grant_table->privs);
else else
priv= grant->privilege | grant_column->rights; priv= (grant->privilege | grant_table->privs | grant_column->rights);
} }
rw_unlock(&LOCK_grant); rw_unlock(&LOCK_grant);
return priv; return priv;
......
...@@ -2303,8 +2303,8 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables, ...@@ -2303,8 +2303,8 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables,
uint col_access; uint col_access;
check_access(thd,SELECT_ACL | EXTRA_ACL, base_name, check_access(thd,SELECT_ACL | EXTRA_ACL, base_name,
&tables->grant.privilege, 0, 0); &tables->grant.privilege, 0, 0);
col_access= get_column_grant(thd, &tables->grant, tables->db, col_access= get_column_grant(thd, &tables->grant,
tables->table_name, base_name, file_name,
field->field_name) & COL_ACLS; field->field_name) & COL_ACLS;
if (lex->orig_sql_command != SQLCOM_SHOW_FIELDS && !col_access) if (lex->orig_sql_command != SQLCOM_SHOW_FIELDS && !col_access)
continue; continue;
......
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