Commit bbe1d370 authored by gkodinov/kgeorge@magare.gmz's avatar gkodinov/kgeorge@magare.gmz
Browse files

Merge gkodinov@bk-internal.mysql.com:/home/bk/mysql-5.0-opt

into  magare.gmz:/home/kgeorge/mysql/autopush/B30468-5.0-opt
parents 4cd18bde fb3b1217
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -421,4 +421,22 @@ revoke all privileges, grant option from mysqltest_1@localhost;
revoke all privileges, grant option from mysqltest_2@localhost;
drop user mysqltest_1@localhost;
drop user mysqltest_2@localhost;
CREATE DATABASE db1;
USE db1;
CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 VALUES (1,1),(2,2);
CREATE TABLE t2 (b INT, c INT);
INSERT INTO t2 VALUES (1,100),(2,200);
GRANT SELECT ON t1 TO mysqltest1@localhost;
GRANT SELECT (b) ON t2 TO mysqltest1@localhost;
USE db1;
SELECT c FROM t2;
ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for column 'c' in table 't2'
SELECT * FROM t2;
ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for column 'c' in table 't2'
SELECT * FROM t1 JOIN t2 USING (b);
ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for column 'c' in table 't2'
DROP TABLE db1.t1, db1.t2;
DROP USER mysqltest1@localhost;
DROP DATABASE db1;
End of 5.0 tests
+32 −0
Original line number Diff line number Diff line
@@ -585,5 +585,37 @@ drop user mysqltest_1@localhost;
drop user mysqltest_2@localhost;


#
# Bug #30468: column level privileges not respected when joining tables
#
CREATE DATABASE db1;

USE db1;
CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 VALUES (1,1),(2,2);

CREATE TABLE t2 (b INT, c INT);
INSERT INTO t2 VALUES (1,100),(2,200);

GRANT SELECT ON t1 TO mysqltest1@localhost; 
GRANT SELECT (b) ON t2 TO mysqltest1@localhost;

connect (conn1,localhost,mysqltest1,,);
connection conn1;
USE db1;
--error ER_COLUMNACCESS_DENIED_ERROR
SELECT c FROM t2;
--error ER_COLUMNACCESS_DENIED_ERROR
SELECT * FROM t2;
--error ER_COLUMNACCESS_DENIED_ERROR
SELECT * FROM t1 JOIN t2 USING (b);

connection default;
disconnect conn1;
DROP TABLE db1.t1, db1.t2;
DROP USER mysqltest1@localhost;
DROP DATABASE db1;


--echo End of 5.0 tests
+66 −35
Original line number Diff line number Diff line
@@ -3835,24 +3835,50 @@ bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
}


bool check_grant_all_columns(THD *thd, ulong want_access, GRANT_INFO *grant,
                             const char* db_name, const char *table_name,
                             Field_iterator *fields)
/** 
  @brief check if a query can access a set of columns

  @param  thd  the current thread
  @param  want_access_arg  the privileges requested
  @param  fields an iterator over the fields of a table reference.
  @return Operation status
    @retval 0 Success
    @retval 1 Falure
  @details This function walks over the columns of a table reference 
   The columns may originate from different tables, depending on the kind of
   table reference, e.g. join.
   For each table it will retrieve the grant information and will use it
   to check the required access privileges for the fields requested from it.
*/    
bool check_grant_all_columns(THD *thd, ulong want_access_arg, 
                             Field_iterator_table_ref *fields)
{
  Security_context *sctx= thd->security_ctx;
  GRANT_TABLE *grant_table;
  GRANT_COLUMN *grant_column;
  ulong want_access= want_access_arg;
  const char *table_name= NULL;

  want_access &= ~grant->privilege;
  if (!want_access)
    return 0;				// Already checked
  if (!grant_option)
    goto err2;
  if (grant_option)
  {
    const char* db_name; 
    GRANT_INFO *grant;
    GRANT_TABLE *grant_table;

    rw_rdlock(&LOCK_grant);

  /* reload table if someone has modified any grants */
    for (; !fields->end_of_fields(); fields->next())
    {
      const char *field_name= fields->name();

      if (table_name != fields->table_name())
      {
        table_name= fields->table_name();
        db_name= fields->db_name();
        grant= fields->grant();
        /* get a fresh one for each table */
        want_access= want_access_arg & ~grant->privilege;
        if (want_access)
        {
          /* reload table if someone has modified any grants */
          if (grant->version != grant_version)
          {
            grant->grant_table=
@@ -3861,24 +3887,29 @@ bool check_grant_all_columns(THD *thd, ulong want_access, GRANT_INFO *grant,
                                table_name, 0);	/* purecov: inspected */
            grant->version= grant_version;	/* purecov: inspected */
          }
  /* The following should always be true */
  if (!(grant_table= grant->grant_table))
    goto err;					/* purecov: inspected */

  for (; !fields->end_of_fields(); fields->next())
          DBUG_ASSERT ((grant_table= grant->grant_table) != NULL);
        }
      }

      if (want_access)
      {
    const char *field_name= fields->name();
    grant_column= column_hash_search(grant_table, field_name,
        GRANT_COLUMN *grant_column= 
          column_hash_search(grant_table, field_name,
                             (uint) strlen(field_name));
        if (!grant_column || (~grant_column->rights & want_access))
          goto err;
      }
    }
    rw_unlock(&LOCK_grant);
    return 0;

err:
    rw_unlock(&LOCK_grant);
err2:
  }
  else
    table_name= fields->table_name();

  char command[128];
  get_privilege_desc(command, sizeof(command), want_access);
  my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
+2 −3
Original line number Diff line number Diff line
@@ -205,9 +205,8 @@ bool check_grant_column (THD *thd, GRANT_INFO *grant,
			 const char *name, uint length, Security_context *sctx);
bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
                                     const char *name, uint length);
bool check_grant_all_columns(THD *thd, ulong want_access, GRANT_INFO *grant,
                             const char* db_name, const char *table_name,
                             Field_iterator *fields);
bool check_grant_all_columns(THD *thd, ulong want_access, 
                             Field_iterator_table_ref *fields);
bool check_grant_routine(THD *thd, ulong want_access,
			 TABLE_LIST *procs, bool is_proc, bool no_error);
bool check_grant_db(THD *thd,const char *db);
+1 −4
Original line number Diff line number Diff line
@@ -5414,10 +5414,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
        !any_privileges)
    {
      field_iterator.set(tables);
      if (check_grant_all_columns(thd, SELECT_ACL, field_iterator.grant(),
                                  field_iterator.db_name(),
                                  field_iterator.table_name(),
                                  &field_iterator))
      if (check_grant_all_columns(thd, SELECT_ACL, &field_iterator))
        DBUG_RETURN(TRUE);
    }
#endif
Loading