diff options
author | evgen@sunlight.local <> | 2006-08-15 21:45:24 +0400 |
---|---|---|
committer | evgen@sunlight.local <> | 2006-08-15 21:45:24 +0400 |
commit | dd9a07706b9c463c9ab887232ef4873f49a39cd5 (patch) | |
tree | a81bf82a292cd0862ecfaedcf0c1317a9ccdb0a7 | |
parent | 5f3d231f5706d43572a1f90873db6ee98226bfcb (diff) | |
download | mariadb-git-dd9a07706b9c463c9ab887232ef4873f49a39cd5.tar.gz |
Fixed bug#21261: Wrong access rights was required for an insert into a view
SELECT right instead of INSERT right was required for an insert into to a view.
This wrong behaviour appeared after the fix for bug #20989. Its intention was
to ask only SELECT right for all tables except the very first for a complex
INSERT query. But that patch has done it in a wrong way and lead to asking
a wrong access right for an insert into a view.
The setup_tables_and_check_access() function now accepts two want_access
parameters. One will be used for the first table and the second for other
tables.
-rw-r--r-- | mysql-test/r/view.result | 19 | ||||
-rw-r--r-- | mysql-test/t/view.test | 30 | ||||
-rw-r--r-- | sql/mysql_priv.h | 1 | ||||
-rw-r--r-- | sql/sql_base.cc | 9 | ||||
-rw-r--r-- | sql/sql_delete.cc | 4 | ||||
-rw-r--r-- | sql/sql_insert.cc | 2 | ||||
-rw-r--r-- | sql/sql_load.cc | 1 | ||||
-rw-r--r-- | sql/sql_select.cc | 2 | ||||
-rw-r--r-- | sql/sql_update.cc | 4 |
9 files changed, 64 insertions, 8 deletions
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 534065a33b6..2a02ac78752 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -2850,3 +2850,22 @@ Tables_in_test t1 DROP TABLE t1; DROP VIEW IF EXISTS v1; +CREATE DATABASE bug21261DB; +CREATE TABLE t1 (x INT); +CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT x FROM t1; +GRANT INSERT, UPDATE ON v1 TO 'user21261'@'localhost'; +GRANT INSERT, UPDATE ON t1 TO 'user21261'@'localhost'; +CREATE TABLE t2 (y INT); +GRANT SELECT ON t2 TO 'user21261'@'localhost'; +INSERT INTO v1 (x) VALUES (5); +UPDATE v1 SET x=1; +GRANT SELECT ON v1 TO 'user21261'@'localhost'; +UPDATE v1,t2 SET x=1 WHERE x=y; +SELECT * FROM t1; +x +1 +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user21261'@'localhost'; +DROP USER 'user21261'@'localhost'; +DROP VIEW v1; +DROP TABLE t1; +DROP DATABASE bug21261DB; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 5cb85ca6c9b..8a2b170ecb8 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -2718,3 +2718,33 @@ DROP TABLE t1; --disable_warnings DROP VIEW IF EXISTS v1; --enable_warnings + +# +# Bug #21261: Wrong access rights was required for an insert to a view +# +CREATE DATABASE bug21261DB; +CONNECT (root,localhost,root,,bug21261DB); +CONNECTION root; + +CREATE TABLE t1 (x INT); +CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT x FROM t1; +GRANT INSERT, UPDATE ON v1 TO 'user21261'@'localhost'; +GRANT INSERT, UPDATE ON t1 TO 'user21261'@'localhost'; +CREATE TABLE t2 (y INT); +GRANT SELECT ON t2 TO 'user21261'@'localhost'; + +CONNECT (user21261, localhost, user21261,, bug21261DB); +CONNECTION user21261; +INSERT INTO v1 (x) VALUES (5); +UPDATE v1 SET x=1; +CONNECTION root; +GRANT SELECT ON v1 TO 'user21261'@'localhost'; +CONNECTION user21261; +UPDATE v1,t2 SET x=1 WHERE x=y; +CONNECTION root; +SELECT * FROM t1; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user21261'@'localhost'; +DROP USER 'user21261'@'localhost'; +DROP VIEW v1; +DROP TABLE t1; +DROP DATABASE bug21261DB; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index c776fc72b16..c032b9feeed 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -974,6 +974,7 @@ bool setup_tables_and_check_access (THD *thd, TABLE_LIST *tables, Item **conds, TABLE_LIST **leaves, bool select_insert, + ulong want_access_first, ulong want_access); int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields, List<Item> *sum_func_list, uint wild_num); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 1bdc0103853..3a12477bc15 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -4563,9 +4563,11 @@ bool setup_tables_and_check_access(THD *thd, TABLE_LIST *tables, Item **conds, TABLE_LIST **leaves, bool select_insert, + ulong want_access_first, ulong want_access) { TABLE_LIST *leaves_tmp = NULL; + bool first_table= true; if (setup_tables (thd, context, from_clause, tables, conds, &leaves_tmp, select_insert)) @@ -4575,13 +4577,16 @@ bool setup_tables_and_check_access(THD *thd, *leaves = leaves_tmp; for (; leaves_tmp; leaves_tmp= leaves_tmp->next_leaf) + { if (leaves_tmp->belong_to_view && - check_single_table_access(thd, want_access, leaves_tmp)) + check_single_table_access(thd, first_table ? want_access_first : + want_access, leaves_tmp)) { tables->hide_view_error(thd); return TRUE; } - + first_table= false; + } return FALSE; } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index b608773bf6e..e420022b8a1 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -350,7 +350,7 @@ bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds) &thd->lex->select_lex.top_join_list, table_list, conds, &select_lex->leaf_tables, FALSE, - DELETE_ACL) || + DELETE_ACL, SELECT_ACL) || setup_conds(thd, table_list, select_lex->leaf_tables, conds) || setup_ftfuncs(select_lex)) DBUG_RETURN(TRUE); @@ -413,7 +413,7 @@ bool mysql_multi_delete_prepare(THD *thd) &thd->lex->select_lex.top_join_list, lex->query_tables, &lex->select_lex.where, &lex->select_lex.leaf_tables, FALSE, - DELETE_ACL)) + DELETE_ACL, SELECT_ACL)) DBUG_RETURN(TRUE); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 57805da608b..c08deedea72 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -847,7 +847,7 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list, &thd->lex->select_lex.top_join_list, table_list, where, &thd->lex->select_lex.leaf_tables, - select_insert, SELECT_ACL)) + select_insert, INSERT_ACL, SELECT_ACL)) DBUG_RETURN(TRUE); if (insert_into_view && !fields.elements) diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 40e1e6b07aa..b1ba2e96651 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -157,6 +157,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, &thd->lex->select_lex.top_join_list, table_list, &unused_conds, &thd->lex->select_lex.leaf_tables, FALSE, + INSERT_ACL | UPDATE_ACL, INSERT_ACL | UPDATE_ACL)) DBUG_RETURN(-1); if (!table_list->table || // do not suport join view diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2f16b350d04..995ce30226e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -344,7 +344,7 @@ JOIN::prepare(Item ***rref_pointer_array, setup_tables_and_check_access(thd, &select_lex->context, join_list, tables_list, &conds, &select_lex->leaf_tables, FALSE, - SELECT_ACL)) || + SELECT_ACL, SELECT_ACL)) || setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) || select_lex->setup_ref_array(thd, og_num) || setup_fields(thd, (*rref_pointer_array), fields_list, 1, diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 9a207845893..84b22c56cf9 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -627,7 +627,7 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list, &select_lex->top_join_list, table_list, conds, &select_lex->leaf_tables, - FALSE, UPDATE_ACL) || + FALSE, UPDATE_ACL, SELECT_ACL) || setup_conds(thd, table_list, select_lex->leaf_tables, conds) || select_lex->setup_ref_array(thd, order_num) || setup_order(thd, select_lex->ref_pointer_array, @@ -722,7 +722,7 @@ reopen_tables: &lex->select_lex.top_join_list, table_list, &lex->select_lex.where, &lex->select_lex.leaf_tables, FALSE, - UPDATE_ACL)) + UPDATE_ACL, SELECT_ACL)) DBUG_RETURN(TRUE); if (setup_fields_with_no_wrap(thd, 0, *fields, 1, 0, 0)) |