summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <monty@mashka.mysql.fi>2003-05-07 23:59:24 +0300
committerunknown <monty@mashka.mysql.fi>2003-05-07 23:59:24 +0300
commita57e7732897ee7973d82dccea0425c436845066a (patch)
treedaddc57eeedc8a9ecec290538f8ecd00e81c06bb
parentd4b465e2f3e871af1f5e7260055b4055bbe2a3f7 (diff)
downloadmariadb-git-a57e7732897ee7973d82dccea0425c436845066a.tar.gz
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
-rw-r--r--sql/sql_acl.cc9
-rw-r--r--sql/sql_base.cc9
-rw-r--r--sql/sql_parse.cc12
-rw-r--r--tests/grant.pl13
-rw-r--r--tests/grant.res15
5 files changed, 49 insertions, 9 deletions
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 05ec57b134a..f36e39b0645 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -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,
- uint length, uint show_tables)
+bool check_grant_column(THD *thd,TABLE *table, const char *name,
+ uint length, uint show_tables)
{
GRANT_TABLE *grant_table;
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;
if (!want_access)
return 0; // Already checked
+ if (!grant_option)
+ goto err2;
pthread_mutex_lock(&LOCK_grant);
@@ -2158,8 +2160,9 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name,
#endif
/* We must use my_printf_error() here! */
- err:
+err:
pthread_mutex_unlock(&LOCK_grant);
+err2:
if (!show_tables)
{
const char *command="";
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 46370949650..d28fedba25b 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1616,7 +1616,7 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
else
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 field;
}
@@ -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)
{
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 152d9c585ca..805063cb6dc 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -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) ||
diff --git a/tests/grant.pl b/tests/grant.pl
index bf67ce5e790..8ec83c85349 100644
--- a/tests/grant.pl
+++ b/tests/grant.pl
@@ -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);
diff --git a/tests/grant.res b/tests/grant.res
index 44e20db555f..086111ce567 100644
--- a/tests/grant.res
+++ b/tests/grant.res
@@ -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