Commit 82091c84 authored by unknown's avatar unknown
Browse files

Fix for bug#7214: information_schema: unauthorized user can see metadata

    the fix for 'columns' table only
    Rights check for 'routines' table is already done
    (see WL2131 Access control for SHOW ... PROCEDURE|FUNCTION ...)
    rename 'testtets' database to 'mysqltest' to keep number of
      DBs which created by mysql-test as small as possible


mysql-test/r/information_schema.result:
  Fix for bug#7214: information_schema: unauthorized user can see metadata
mysql-test/t/information_schema.test:
  Fix for bug#7214: information_schema: unauthorized user can see metadata
sql/sql_show.cc:
  Fix for bug#7214: information_schema: unauthorized user can see metadata
parent 2c8de426
Loading
Loading
Loading
Loading
+27 −18
Original line number Diff line number Diff line
@@ -22,11 +22,11 @@ mysql
test
show databases where `database` = 't%';
Database
create database testtets;
create table testtets.t1(a int, b VARCHAR(30), KEY string_data (b));
create database mysqltest;
create table mysqltest.t1(a int, b VARCHAR(30), KEY string_data (b));
create table test.t2(a int);
create table t3(a int, KEY a_data (a));
create table testtets.t4(a int);
create table mysqltest.t4(a int);
create view v1 (c) as select table_name from information_schema.TABLES;
select * from v1;
c
@@ -62,11 +62,11 @@ time_zone_name
time_zone_transition
time_zone_transition_type
user
t1
t4
t2
t3
v1
t1
t4
select c,table_name from v1 
left join information_schema.TABLES v2 on (v1.c=v2.table_name)
where v1.c like "t%";
@@ -80,10 +80,10 @@ time_zone_leap_second time_zone_leap_second
time_zone_name	time_zone_name
time_zone_transition	time_zone_transition
time_zone_transition_type	time_zone_transition_type
t2	t2
t3	t3
t1	t1
t4	t4
t2	t2
t3	t3
select c, v2.table_name from v1
right join information_schema.TABLES v2 on (v1.c=v2.table_name)
where v1.c like "t%";
@@ -97,18 +97,18 @@ time_zone_leap_second time_zone_leap_second
time_zone_name	time_zone_name
time_zone_transition	time_zone_transition
time_zone_transition_type	time_zone_transition_type
t2	t2
t3	t3
t1	t1
t4	t4
t2	t2
t3	t3
select table_name from information_schema.TABLES
where table_schema = "testtets" and table_name like "t%";
where table_schema = "mysqltest" and table_name like "t%";
table_name
t1
t4
select * from information_schema.STATISTICS where TABLE_SCHEMA = "testtets";
select * from information_schema.STATISTICS where TABLE_SCHEMA = "mysqltest";
TABLE_CATALOG	TABLE_SCHEMA	TABLE_NAME	NON_UNIQUE	INDEX_SCHEMA	INDEX_NAME	SEQ_IN_INDEX	COLUMN_NAME	COLLATION	CARDINALITY	SUB_PART	PACKED	NULLABLE	INDEX_TYPE	COMMENT
NULL	testtets	t1	1	testtets	string_data	1	b	A	NULL	NULL	NULL	YES	BTREE	
NULL	mysqltest	t1	1	mysqltest	string_data	1	b	A	NULL	NULL	NULL	YES	BTREE	
show keys from t3 where Key_name = "a_data";
Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment
t3	1	a_data	1	a	A	NULL	NULL	NULL	YES	BTREE	
@@ -133,13 +133,22 @@ c varchar(64) utf8_general_ci NO select,insert,update,references
select * from information_schema.COLUMNS where table_name="t1"
and column_name= "a";
TABLE_CATALOG	TABLE_SCHEMA	TABLE_NAME	COLUMN_NAME	ORDINAL_POSITION	COLUMN_DEFAULT	IS_NULLABLE	DATA_TYPE	CHARACTER_MAXIMUM_LENGTH	CHARACTER_OCTET_LENGTH	NUMERIC_PRECISION	NUMERIC_SCALE	CHARACTER_SET_NAME	COLLATION_NAME	COLUMN_TYPE	COLUMN_KEY	EXTRA	PRIVILEGES	COLUMN_COMMENT
NULL	testtets	t1	a	1	NULL	YES	int	NULL	NULL	11	0	NULL	NULL	int(11)			select,insert,update,references	
show columns from testtets.t1 where field like "%a%";
NULL	mysqltest	t1	a	1	NULL	YES	int	NULL	NULL	11	0	NULL	NULL	int(11)			select,insert,update,references	
show columns from mysqltest.t1 where field like "%a%";
Field	Type	Null	Key	Default	Extra
a	int(11)	YES		NULL	
grant select (a) on mysqltest.t1 to mysqltest_2@localhost;
select table_name, column_name, privileges from information_schema.columns 
where table_schema = 'mysqltest' and table_name = 't1';
table_name	column_name	privileges
t1	a	select
show columns from mysqltest.t1;
Field	Type	Null	Key	Default	Extra
a	int(11)	YES		NULL	
b	varchar(30)	YES	MUL	NULL	
drop view v1;
drop tables testtets.t4, testtets.t1, t2, t3;
drop database testtets;
drop tables mysqltest.t4, mysqltest.t1, t2, t3;
drop database mysqltest;
select * from information_schema.CHARACTER_SETS
where CHARACTER_SET_NAME like 'latin1%';
CHARACTER_SET_NAME	DEFAULT_COLLATE_NAME	DESCRIPTION	MAXLEN
@@ -352,8 +361,8 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRAN
'mysqltest_1'@'localhost'	NULL	test	t1	a	REFERENCES	NO
delete from mysql.user where user='mysqltest_1' or user='mysqltest_2';
delete from mysql.db where user='mysqltest_1' or user='mysqltest_2';
delete from mysql.tables_priv where user='mysqltest_1';
delete from mysql.columns_priv where user='mysqltest_1';
delete from mysql.tables_priv where user='mysqltest_1' or user='mysqltest_2';
delete from mysql.columns_priv where user='mysqltest_1' or user='mysqltest_2';
flush privileges;
drop table t1;
create table t1 (a int null, primary key(a));
+18 −11
Original line number Diff line number Diff line
@@ -17,11 +17,11 @@ show databases where `database` = 't%';
# Test for information_schema.tables &
# show tables

create database testtets;
create table testtets.t1(a int, b VARCHAR(30), KEY string_data (b));
create database mysqltest;
create table mysqltest.t1(a int, b VARCHAR(30), KEY string_data (b));
create table test.t2(a int);
create table t3(a int, KEY a_data (a));
create table testtets.t4(a int);
create table mysqltest.t4(a int);
create view v1 (c) as select table_name from information_schema.TABLES;
select * from v1;
select c,table_name from v1 
@@ -33,9 +33,9 @@ right join information_schema.TABLES v2 on (v1.c=v2.table_name)
where v1.c like "t%";

select table_name from information_schema.TABLES
where table_schema = "testtets" and table_name like "t%";
where table_schema = "mysqltest" and table_name like "t%";

select * from information_schema.STATISTICS where TABLE_SCHEMA = "testtets";
select * from information_schema.STATISTICS where TABLE_SCHEMA = "mysqltest";
show keys from t3 where Key_name = "a_data";

show tables like 't%';
@@ -46,11 +46,19 @@ show full columns from mysql.db like "Insert%";
show full columns from v1;
select * from information_schema.COLUMNS where table_name="t1"
and column_name= "a";
show columns from testtets.t1 where field like "%a%";
show columns from mysqltest.t1 where field like "%a%";

grant select (a) on mysqltest.t1 to mysqltest_2@localhost;
connect (user3,localhost,mysqltest_2,,);
connection user3;
select table_name, column_name, privileges from information_schema.columns 
where table_schema = 'mysqltest' and table_name = 't1';
show columns from mysqltest.t1;
connection default;

drop view v1;
drop tables testtets.t4, testtets.t1, t2, t3;
drop database testtets;
drop tables mysqltest.t4, mysqltest.t1, t2, t3;
drop database mysqltest;

# Test for information_schema.CHARACTER_SETS &
# SHOW CHARACTER SET
@@ -107,7 +115,6 @@ mysql.proc b where a.ROUTINE_NAME = convert(b.name using utf8);
select count(*) from information_schema.ROUTINES;

connect (user1,localhost,mysqltest_1,,);
connect (user3,localhost,mysqltest_2,,);
connection user1;
select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES;
--error 1305
@@ -166,8 +173,8 @@ select * from information_schema.TABLE_PRIVILEGES where grantee like '%mysqltest
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.db where user='mysqltest_1' or user='mysqltest_2';
delete from mysql.tables_priv where user='mysqltest_1';
delete from mysql.columns_priv where user='mysqltest_1';
delete from mysql.tables_priv where user='mysqltest_1' or user='mysqltest_2';
delete from mysql.columns_priv where user='mysqltest_1' or user='mysqltest_2';
flush privileges;
drop table t1;

+25 −20
Original line number Diff line number Diff line
@@ -2290,8 +2290,32 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables,
      char tmp[MAX_FIELD_WIDTH];
      char tmp1[MAX_FIELD_WIDTH];
      String type(tmp,sizeof(tmp), system_charset_info);
      char *end= tmp;
      count++;
      restore_record(table, s->default_values);

#ifndef NO_EMBEDDED_ACCESS_CHECKS
      uint col_access;
      check_access(thd,SELECT_ACL | EXTRA_ACL, base_name,
                   &tables->grant.privilege, 0, 0);
      col_access= get_column_grant(thd, &tables->grant, tables->db,
                                   tables->table_name,
                                   field->field_name) & COL_ACLS;
      if (lex->orig_sql_command != SQLCOM_SHOW_FIELDS  && !col_access)
        continue;
      for (uint bitnr=0; col_access ; col_access>>=1,bitnr++)
      {
        if (col_access & 1)
        {
          *end++=',';
          end=strmov(end,grant_types.type_names[bitnr]);
        }
      }
#else
      end=strmov(end,"");
#endif
      table->field[17]->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1), cs);

      table->field[1]->store(base_name, strlen(base_name), cs);
      table->field[2]->store(file_name, strlen(file_name), cs);
      table->field[3]->store(field->field_name, strlen(field->field_name),
@@ -2398,31 +2422,12 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables,
                   (field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
      table->field[15]->store((const char*) pos,
                              strlen((const char*) pos), cs);
      char *end= tmp;
      end= tmp;
      if (field->unireg_check == Field::NEXT_NUMBER)
        end=strmov(tmp,"auto_increment");
      table->field[16]->store(tmp, (uint) (end-tmp), cs);

      end=tmp;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
      uint col_access;
      check_access(thd,SELECT_ACL | EXTRA_ACL, base_name,
                   &tables->grant.privilege, 0, 0);
      col_access= get_column_grant(thd, &tables->grant, tables->db,
                                   tables->table_name,
                                   field->field_name) & COL_ACLS;
      for (uint bitnr=0; col_access ; col_access>>=1,bitnr++)
      {
        if (col_access & 1)
        {
          *end++=',';
          end=strmov(end,grant_types.type_names[bitnr]);
        }
      }
#else
      end=strmov(end,"");
#endif
      table->field[17]->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1), cs);
      table->field[18]->store(field->comment.str, field->comment.length, cs);
      if (schema_table_store_record(thd, table))
        DBUG_RETURN(1);