summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <gkodinov/kgeorge@magare.gmz>2007-09-27 12:32:59 +0300
committerunknown <gkodinov/kgeorge@magare.gmz>2007-09-27 12:32:59 +0300
commit2e57478d9278b7b84b6bbbe6368a4fd8f68039c4 (patch)
tree72a3e5f03123ab2e82f6a6914420c1fd8ba57fe2
parent4f6658967b40f88cbf0742066888d626812fec56 (diff)
parent500d856faf5dca0eb2731617fb11c09b83e3ef0d (diff)
downloadmariadb-git-2e57478d9278b7b84b6bbbe6368a4fd8f68039c4.tar.gz
merged the fix for bug 30468 to 5.1-opt
mysql-test/t/grant2.test: Auto merged sql/sql_acl.h: Auto merged sql/sql_base.cc: Auto merged
-rw-r--r--mysql-test/r/grant2.result18
-rw-r--r--mysql-test/t/grant2.test32
-rw-r--r--sql/sql_acl.cc81
-rw-r--r--sql/sql_acl.h5
-rw-r--r--sql/sql_base.cc5
-rw-r--r--sql/sql_insert.cc8
6 files changed, 111 insertions, 38 deletions
diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result
index 21bad4fddcb..b94de265d0c 100644
--- a/mysql-test/r/grant2.result
+++ b/mysql-test/r/grant2.result
@@ -422,4 +422,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
diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test
index f6075ba2ee4..0f0c92e82eb 100644
--- a/mysql-test/t/grant2.test
+++ b/mysql-test/t/grant2.test
@@ -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
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 7e017d7d028..68da03dda01 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -3991,47 +3991,76 @@ 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
+ const char* db_name;
+ GRANT_INFO *grant;
+ GRANT_TABLE *grant_table;
rw_rdlock(&LOCK_grant);
- /* reload table if someone has modified any grants */
-
- if (grant->version != grant_version)
- {
- grant->grant_table=
- table_hash_search(sctx->host, sctx->ip, db_name,
- sctx->priv_user,
- 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())
{
const char *field_name= fields->name();
- grant_column= column_hash_search(grant_table, field_name,
- (uint) strlen(field_name));
- if (!grant_column || (~grant_column->rights & want_access))
- goto err;
+
+ 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=
+ table_hash_search(sctx->host, sctx->ip, db_name,
+ sctx->priv_user,
+ table_name, 0); /* purecov: inspected */
+ grant->version= grant_version; /* purecov: inspected */
+ }
+
+ DBUG_ASSERT ((grant_table= grant->grant_table) != NULL);
+ }
+ }
+
+ if (want_access)
+ {
+ 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);
+
char command[128];
get_privilege_desc(command, sizeof(command), want_access);
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
diff --git a/sql/sql_acl.h b/sql/sql_acl.h
index cba283ec65b..a279c26c2e4 100644
--- a/sql/sql_acl.h
+++ b/sql/sql_acl.h
@@ -244,9 +244,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);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 337fde53dac..387bdfc2f12 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -6553,10 +6553,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
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 459eefbf760..0da90083af4 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -189,11 +189,9 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
return -1;
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- Field_iterator_table field_it;
- field_it.set_table(table);
- if (check_grant_all_columns(thd, INSERT_ACL, &table->grant,
- table->s->db.str, table->s->table_name.str,
- &field_it))
+ Field_iterator_table_ref field_it;
+ field_it.set(table_list);
+ if (check_grant_all_columns(thd, INSERT_ACL, &field_it))
return -1;
#endif
clear_timestamp_auto_bits(table->timestamp_field_type,