Commit 9955388a authored by unknown's avatar unknown
Browse files

Bug#20543 select on information_schema strange warnings, view, different schemas/users

The fix is: if user has privileges to view fields and user has any
(insert,select,delete,update) privileges on underlying view 
then 'show fields' and select from I_S.COLUMNS table are sucsessful.


mysql-test/r/information_schema_db.result:
  Bug#20543 select on information_schema strange warnings, view, different schemas/users
  test result
mysql-test/t/information_schema_db.test:
  Bug#20543 select on information_schema strange warnings, view, different schemas/users
  test case
sql/sql_acl.cc:
  Bug#20543 select on information_schema strange warnings, view, different schemas/users
  checked that user has privileges on underlying view and if it's true
  set allowed_show to true for top view.
sql/sql_show.cc:
  Bug#20543 select on information_schema strange warnings, view, different schemas/users
  removed unnecessary rights check.'tables->allowed_show' check is used instead
sql/sql_view.cc:
  Bug#20543 select on information_schema strange warnings, view, different schemas/users
  skip the check of SHOW_VIEW_ACL privilege on underlying view. It is done later during
  execution of find_field_in_table_ref function.
sql/table.h:
  Bug#20543 select on information_schema strange warnings, view, different schemas/users
  'allowed_show' is set during rights check for view. If true then user has privileges 
  for 'show create view', etc
parent 31325319
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
@@ -97,3 +97,49 @@ v2 VIEW View 'test.v2' references invalid table(s) or column(s) or function(s) o
drop function f1;
drop function f2;
drop view v1, v2;
create database testdb_1;
create user testdb_1@localhost;
grant all on testdb_1.* to testdb_1@localhost with grant option;
create user testdb_2@localhost;
grant all on test.* to testdb_2@localhost with grant option;
use testdb_1;
create table t1 (f1 char(4));
create view v1 as select f1 from t1;
grant insert on v1 to testdb_2@localhost;
create table t3 (f1 char(4), f2 char(4));
create view v3 as select f1,f2 from t3;
grant insert(f1), insert(f2) on v3 to testdb_2@localhost;
create view v2 as select f1 from testdb_1.v1;
create view v4 as select f1,f2 from testdb_1.v3;
revoke insert(f1) on v3 from testdb_2@localhost;
show create view v4;
ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show fields from v4;
ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show fields from v2;
Field	Type	Null	Key	Default	Extra
f1	char(4)	YES		NULL	
show fields from testdb_1.v1;
Field	Type	Null	Key	Default	Extra
f1	char(4)	YES		NULL	
show create view v2;
View	Create View
v2	CREATE ALGORITHM=UNDEFINED DEFINER=`testdb_2`@`localhost` SQL SECURITY DEFINER VIEW `test`.`v2` AS select `v1`.`f1` AS `f1` from `testdb_1`.`v1`
show create view testdb_1.v1;
ERROR 42000: SHOW VIEW command denied to user 'testdb_2'@'localhost' for table 'v1'
select table_name from information_schema.columns a 
where a.table_name = 'v2';
table_name
v2
select view_definition from information_schema.views a 
where a.table_name = 'v2';
view_definition
/* ALGORITHM=UNDEFINED */ select `v1`.`f1` AS `f1` from `testdb_1`.`v1`
select view_definition from information_schema.views a 
where a.table_name = 'testdb_1.v1';
view_definition
select * from v2;
ERROR HY000: View 'test.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
drop view testdb_1.v1,v2, testdb_1.v3, v4;
drop database testdb_1;
drop user testdb_1@localhost;
+56 −0
Original line number Diff line number Diff line
@@ -98,3 +98,59 @@ where table_schema='test';
drop function f1;
drop function f2;
drop view v1, v2;

#
# Bug#20543: select on information_schema strange warnings, view, different
#             schemas/users
#
#
create database testdb_1;
create user testdb_1@localhost;
grant all on testdb_1.* to testdb_1@localhost with grant option;

create user testdb_2@localhost;
grant all on test.* to testdb_2@localhost with grant option;

connect (testdb_1,localhost,testdb_1,,test);
use testdb_1;
create table t1 (f1 char(4));
create view v1 as select f1 from t1;
grant insert on v1 to testdb_2@localhost;

create table t3 (f1 char(4), f2 char(4));
create view v3 as select f1,f2 from t3;
grant insert(f1), insert(f2) on v3 to testdb_2@localhost;

connect (testdb_2,localhost,testdb_2,,test);
create view v2 as select f1 from testdb_1.v1;
create view v4 as select f1,f2 from testdb_1.v3;

connection testdb_1;
revoke insert(f1) on v3 from testdb_2@localhost;
connection testdb_2;

--error 1345
show create view v4;
--error 1345
show fields from v4;

show fields from v2;
show fields from testdb_1.v1;
show create view v2;
--error 1142
show create view testdb_1.v1;

select table_name from information_schema.columns a 
where a.table_name = 'v2';
select view_definition from information_schema.views a 
where a.table_name = 'v2';
select view_definition from information_schema.views a 
where a.table_name = 'testdb_1.v1';

--error 1356
select * from v2;

connection default;
drop view testdb_1.v1,v2, testdb_1.v3, v4;
drop database testdb_1;
drop user testdb_1@localhost;
+15 −0
Original line number Diff line number Diff line
@@ -3787,9 +3787,24 @@ bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
  if (table_ref->view || table_ref->field_translation)
  {
    /* View or derived information schema table. */
    ulong view_privs;
    grant= &(table_ref->grant);
    db_name= table_ref->view_db.str;
    table_name= table_ref->view_name.str;
    if (table_ref->belong_to_view && 
        (thd->lex->sql_command == SQLCOM_SHOW_FIELDS ||
         thd->lex->sql_command == SQLCOM_SHOW_CREATE))
    {
      view_privs= get_column_grant(thd, grant, db_name, table_name, name);
      if (view_privs & VIEW_ANY_ACL)
      {
        table_ref->belong_to_view->allowed_show= TRUE;
        return FALSE;
      }
      table_ref->belong_to_view->allowed_show= FALSE;
      my_message(ER_VIEW_NO_EXPLAIN, ER(ER_VIEW_NO_EXPLAIN), MYF(0));
      return TRUE;
    }
  }
  else
  {
+7 −20
Original line number Diff line number Diff line
@@ -3110,31 +3110,18 @@ static int get_schema_views_record(THD *thd, struct st_table_list *tables,
  if (tables->view)
  {
    Security_context *sctx= thd->security_ctx;
    ulong grant= SHOW_VIEW_ACL;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
    char *save_table_name= tables->table_name;
    if (!tables->allowed_show)
    {
      if (!my_strcasecmp(system_charset_info, tables->definer.user.str,
                         sctx->priv_user) &&
          !my_strcasecmp(system_charset_info, tables->definer.host.str,
                         sctx->priv_host))
      grant= SHOW_VIEW_ACL;
    else
    {
      tables->table_name= tables->view_name.str;
      if (check_access(thd, SHOW_VIEW_ACL , base_name,
                       &tables->grant.privilege, 0, 1,
                       test(tables->schema_table)))
        grant= get_table_grant(thd, tables);
      else
        grant= tables->grant.privilege;
        tables->allowed_show= TRUE;
    }
    tables->table_name= save_table_name;
#endif

    restore_record(table, s->default_values);
    table->field[1]->store(tables->view_db.str, tables->view_db.length, cs);
    table->field[2]->store(tables->view_name.str, tables->view_name.length, cs);
    if (grant & SHOW_VIEW_ACL)
    if (tables->allowed_show)
    {
      char buff[2048];
      String qwe_str(buff, sizeof(buff), cs);
+2 −1
Original line number Diff line number Diff line
@@ -934,7 +934,8 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
      }
    }
    else if (!table->prelocking_placeholder &&
             old_lex->sql_command == SQLCOM_SHOW_CREATE)
             old_lex->sql_command == SQLCOM_SHOW_CREATE &&
             !table->belong_to_view)
    {
      if (check_table_access(thd, SHOW_VIEW_ACL, table, 0))
        goto err;
Loading