summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorevgen@sunlight.local <>2006-08-15 21:45:24 +0400
committerevgen@sunlight.local <>2006-08-15 21:45:24 +0400
commitdd9a07706b9c463c9ab887232ef4873f49a39cd5 (patch)
treea81bf82a292cd0862ecfaedcf0c1317a9ccdb0a7
parent5f3d231f5706d43572a1f90873db6ee98226bfcb (diff)
downloadmariadb-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.result19
-rw-r--r--mysql-test/t/view.test30
-rw-r--r--sql/mysql_priv.h1
-rw-r--r--sql/sql_base.cc9
-rw-r--r--sql/sql_delete.cc4
-rw-r--r--sql/sql_insert.cc2
-rw-r--r--sql/sql_load.cc1
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/sql_update.cc4
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))