Commit a57e7732 authored by unknown's avatar unknown
Browse files

Security patch to remove wrong error when one had a global update/delete...

Security patch to remove wrong error when one had a global update/delete privilige and a database specific SELECT privilege. 


sql/sql_acl.cc:
  Security patch
sql/sql_base.cc:
  Security patch
sql/sql_parse.cc:
  Security patch
tests/grant.pl:
  Test of security patch
tests/grant.res:
  Test of security patch
parent d4b465e2
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -2127,6 +2127,8 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name,
  uint want_access=table->grant.want_privilege;
  if (!want_access)
    return 0;					// Already checked
  if (!grant_option)
    goto err2;

  pthread_mutex_lock(&LOCK_grant);

@@ -2160,6 +2162,7 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name,
  /* We must use my_printf_error() here! */
err:
  pthread_mutex_unlock(&LOCK_grant);
err2:
  if (!show_tables)
  {
    const char *command="";
+4 −5
Original line number Diff line number Diff line
@@ -1643,8 +1643,8 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables)
      {
	found_table=1;
	Field *find=find_field_in_table(thd,tables->table,name,length,
					grant_option && 
					tables->table->grant.want_privilege,
					test(tables->table->grant.
					     want_privilege),
					1);
	if (find)
	{
@@ -1684,8 +1684,7 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables)
  for (; tables ; tables=tables->next)
  {
    Field *field=find_field_in_table(thd,tables->table,name,length,
				     grant_option &&
				     tables->table->grant.want_privilege,
				     test(tables->table->grant.want_privilege),
				     allow_rowid);
    if (field)
    {
+11 −1
Original line number Diff line number Diff line
@@ -2155,7 +2155,17 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv,

  if ((thd->master_access & want_access) == want_access)
  {
    *save_priv=thd->master_access | thd->db_access;
    /*
      If we don't have a global SELECT privilege, we have to get the database
      specific access rights to be able to handle queries of type
      UPDATE t1 SET a=1 WHERE b > 0
    */
    db_access= thd->db_access;
    if (!(thd->master_access & SELECT_ACL) &&
	(db && (!thd->db || strcmp(db,thd->db))))
      db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
			thd->priv_user, db); /* purecov: inspected */
    *save_priv=thd->master_access | db_access;
    return FALSE;
  }
  if ((want_access & ~thd->master_access) & ~(DB_ACLS | EXTRA_ACL) ||
+13 −0
Original line number Diff line number Diff line
@@ -214,8 +214,21 @@ user_query("update $opt_database.test set b=b+1",1);
safe_query("grant SELECT on *.* to $user");
user_connect(0);
user_query("update $opt_database.test set b=b+1");
user_query("update $opt_database.test set b=b+1 where a > 0");
safe_query("revoke SELECT on *.* from $user");
safe_query("grant SELECT on $opt_database.* to $user");
user_connect(0);
user_query("update $opt_database.test set b=b+1");
user_query("update $opt_database.test set b=b+1 where a > 0");
safe_query("grant UPDATE on *.* to $user");
user_connect(0);
user_query("update $opt_database.test set b=b+1");
user_query("update $opt_database.test set b=b+1 where a > 0");
safe_query("revoke UPDATE on *.* from $user");
safe_query("revoke SELECT on $opt_database.* from $user");
user_connect(0);
user_query("update $opt_database.test set b=b+1 where a > 0",1);
user_query("update $opt_database.test set b=b+1",1);

# Add one privilege at a time until the user has all privileges
user_query("select * from test",1);
+15 −0
Original line number Diff line number Diff line
@@ -195,8 +195,23 @@ Error in execute: select command denied to user: 'grant_user@localhost' for colu
grant SELECT on *.* to grant_user@localhost
Connecting grant_user
update grant_test.test set b=b+1
update grant_test.test set b=b+1 where a > 0
revoke SELECT on *.* from grant_user@localhost
grant SELECT on grant_test.* to grant_user@localhost
Connecting grant_user
update grant_test.test set b=b+1
update grant_test.test set b=b+1 where a > 0
grant UPDATE on *.* to grant_user@localhost
Connecting grant_user
update grant_test.test set b=b+1
update grant_test.test set b=b+1 where a > 0
revoke UPDATE on *.* from grant_user@localhost
revoke SELECT on grant_test.* from grant_user@localhost
Connecting grant_user
update grant_test.test set b=b+1 where a > 0
Error in execute: select command denied to user: 'grant_user@localhost' for column 'a' in table 'test'
update grant_test.test set b=b+1
Error in execute: select command denied to user: 'grant_user@localhost' for column 'b' in table 'test'
select * from test
Error in execute: select command denied to user: 'grant_user@localhost' for table 'test'
grant select on grant_test.test to grant_user@localhost