mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
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
This commit is contained in:
@ -2118,8 +2118,8 @@ bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool check_grant_column (THD *thd,TABLE *table, const char *name,
|
bool check_grant_column(THD *thd,TABLE *table, const char *name,
|
||||||
uint length, uint show_tables)
|
uint length, uint show_tables)
|
||||||
{
|
{
|
||||||
GRANT_TABLE *grant_table;
|
GRANT_TABLE *grant_table;
|
||||||
GRANT_COLUMN *grant_column;
|
GRANT_COLUMN *grant_column;
|
||||||
@ -2127,6 +2127,8 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name,
|
|||||||
uint want_access=table->grant.want_privilege;
|
uint want_access=table->grant.want_privilege;
|
||||||
if (!want_access)
|
if (!want_access)
|
||||||
return 0; // Already checked
|
return 0; // Already checked
|
||||||
|
if (!grant_option)
|
||||||
|
goto err2;
|
||||||
|
|
||||||
pthread_mutex_lock(&LOCK_grant);
|
pthread_mutex_lock(&LOCK_grant);
|
||||||
|
|
||||||
@ -2158,8 +2160,9 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* We must use my_printf_error() here! */
|
/* We must use my_printf_error() here! */
|
||||||
err:
|
err:
|
||||||
pthread_mutex_unlock(&LOCK_grant);
|
pthread_mutex_unlock(&LOCK_grant);
|
||||||
|
err2:
|
||||||
if (!show_tables)
|
if (!show_tables)
|
||||||
{
|
{
|
||||||
const char *command="";
|
const char *command="";
|
||||||
|
@ -1616,7 +1616,7 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
|
|||||||
else
|
else
|
||||||
thd->dupp_field=field;
|
thd->dupp_field=field;
|
||||||
}
|
}
|
||||||
if (check_grants && check_grant_column(thd,table,name,length))
|
if (check_grants && check_grant_column(thd,table,name,length))
|
||||||
return WRONG_GRANT;
|
return WRONG_GRANT;
|
||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
@ -1643,8 +1643,8 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables)
|
|||||||
{
|
{
|
||||||
found_table=1;
|
found_table=1;
|
||||||
Field *find=find_field_in_table(thd,tables->table,name,length,
|
Field *find=find_field_in_table(thd,tables->table,name,length,
|
||||||
grant_option &&
|
test(tables->table->grant.
|
||||||
tables->table->grant.want_privilege,
|
want_privilege),
|
||||||
1);
|
1);
|
||||||
if (find)
|
if (find)
|
||||||
{
|
{
|
||||||
@ -1684,8 +1684,7 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables)
|
|||||||
for (; tables ; tables=tables->next)
|
for (; tables ; tables=tables->next)
|
||||||
{
|
{
|
||||||
Field *field=find_field_in_table(thd,tables->table,name,length,
|
Field *field=find_field_in_table(thd,tables->table,name,length,
|
||||||
grant_option &&
|
test(tables->table->grant.want_privilege),
|
||||||
tables->table->grant.want_privilege,
|
|
||||||
allow_rowid);
|
allow_rowid);
|
||||||
if (field)
|
if (field)
|
||||||
{
|
{
|
||||||
|
@ -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)
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if ((want_access & ~thd->master_access) & ~(DB_ACLS | EXTRA_ACL) ||
|
if ((want_access & ~thd->master_access) & ~(DB_ACLS | EXTRA_ACL) ||
|
||||||
|
@ -214,8 +214,21 @@ user_query("update $opt_database.test set b=b+1",1);
|
|||||||
safe_query("grant SELECT on *.* to $user");
|
safe_query("grant SELECT on *.* to $user");
|
||||||
user_connect(0);
|
user_connect(0);
|
||||||
user_query("update $opt_database.test set b=b+1");
|
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("revoke SELECT on *.* from $user");
|
||||||
|
safe_query("grant SELECT on $opt_database.* to $user");
|
||||||
user_connect(0);
|
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
|
# Add one privilege at a time until the user has all privileges
|
||||||
user_query("select * from test",1);
|
user_query("select * from test",1);
|
||||||
|
@ -195,8 +195,23 @@ Error in execute: select command denied to user: 'grant_user@localhost' for colu
|
|||||||
grant SELECT on *.* to grant_user@localhost
|
grant SELECT on *.* to grant_user@localhost
|
||||||
Connecting grant_user
|
Connecting grant_user
|
||||||
update grant_test.test set b=b+1
|
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
|
revoke SELECT on *.* from grant_user@localhost
|
||||||
|
grant SELECT on grant_test.* to grant_user@localhost
|
||||||
Connecting grant_user
|
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
|
select * from test
|
||||||
Error in execute: select command denied to user: 'grant_user@localhost' for table '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
|
grant select on grant_test.test to grant_user@localhost
|
||||||
|
Reference in New Issue
Block a user