diff options
author | unknown <gkodinov/kgeorge@magare.gmz> | 2007-09-27 12:32:59 +0300 |
---|---|---|
committer | unknown <gkodinov/kgeorge@magare.gmz> | 2007-09-27 12:32:59 +0300 |
commit | 2e57478d9278b7b84b6bbbe6368a4fd8f68039c4 (patch) | |
tree | 72a3e5f03123ab2e82f6a6914420c1fd8ba57fe2 | |
parent | 4f6658967b40f88cbf0742066888d626812fec56 (diff) | |
parent | 500d856faf5dca0eb2731617fb11c09b83e3ef0d (diff) | |
download | mariadb-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.result | 18 | ||||
-rw-r--r-- | mysql-test/t/grant2.test | 32 | ||||
-rw-r--r-- | sql/sql_acl.cc | 81 | ||||
-rw-r--r-- | sql/sql_acl.h | 5 | ||||
-rw-r--r-- | sql/sql_base.cc | 5 | ||||
-rw-r--r-- | sql/sql_insert.cc | 8 |
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, |