Loading mysql-test/r/grant2.result +27 −0 Original line number Diff line number Diff line SET NAMES binary; drop database if exists mysqltest; delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%'; delete from mysql.tables_priv where user like 'mysqltest\_%'; delete from mysql.columns_priv where user like 'mysqltest\_%'; flush privileges; grant all privileges on `my\_%`.* to mysqltest_1@localhost with grant option; select current_user(); Loading @@ -25,3 +28,27 @@ ERROR 42000: There is no such grant defined for user 'mysqltest_3' on host 'loca delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%'; flush privileges; create database mysqltest; grant INSERT, SELECT on mysqltest.* to mysqltest_1@localhost; flush privileges; use mysqltest; create table t1 (id int primary key, data varchar(255)); show grants for current_user(); Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' GRANT SELECT, INSERT ON `mysqltest`.* TO 'mysqltest_1'@'localhost' use mysqltest; insert into t1 values (1, 'I can''t change it!'); update t1 set data='I can change it!' where id = 1; ERROR 42000: Access denied for user 'mysqltest_1'@'localhost' to database 'mysqltest' insert into t1 values (1, 'XXX') on duplicate key update data= 'I can change it!'; ERROR 42000: Access denied for user 'mysqltest_1'@'localhost' to database 'mysqltest' select * from t1; id data 1 I can't change it! drop table t1; drop database mysqltest; use test; delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%'; flush privileges; mysql-test/t/grant2.test +41 −3 Original line number Diff line number Diff line Loading @@ -6,13 +6,21 @@ SET NAMES binary; # # prepare playground before tests --disable_warnings drop database if exists mysqltest; --enable_warnings delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%'; delete from mysql.tables_priv where user like 'mysqltest\_%'; delete from mysql.columns_priv where user like 'mysqltest\_%'; flush privileges; # # wild_compare fun # delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%'; flush privileges; grant all privileges on `my\_%`.* to mysqltest_1@localhost with grant option; connect (user1,localhost,mysqltest_1,,); connection user1; Loading @@ -31,3 +39,33 @@ delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%'; flush privileges; # # Bug #6173: One can circumvent missing UPDATE privilege if he has SELECT # and INSERT privilege for table with primary key # create database mysqltest; grant INSERT, SELECT on mysqltest.* to mysqltest_1@localhost; flush privileges; use mysqltest; create table t1 (id int primary key, data varchar(255)); connect (mrbad, localhost, mysqltest_1,,); connection mrbad; show grants for current_user(); use mysqltest; insert into t1 values (1, 'I can''t change it!'); --error 1044 update t1 set data='I can change it!' where id = 1; # This should not be allowed since it too require UPDATE privilege. --error 1044 insert into t1 values (1, 'XXX') on duplicate key update data= 'I can change it!'; select * from t1; connection default; drop table t1; drop database mysqltest; use test; delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%'; flush privileges; sql/mysql_priv.h +1 −1 Original line number Diff line number Diff line Loading @@ -374,7 +374,7 @@ int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count); int insert_select_precheck(THD *thd, TABLE_LIST *tables); int update_precheck(THD *thd, TABLE_LIST *tables); int delete_precheck(THD *thd, TABLE_LIST *tables); int insert_precheck(THD *thd, TABLE_LIST *tables, bool update); int insert_precheck(THD *thd, TABLE_LIST *tables); int create_table_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *create_table); Item *negate_expression(THD *thd, Item *expr); Loading sql/sql_parse.cc +6 −6 Original line number Diff line number Diff line Loading @@ -2682,12 +2682,11 @@ mysql_execute_command(THD *thd) case SQLCOM_REPLACE: case SQLCOM_INSERT: { my_bool update= (lex->value_list.elements ? UPDATE_ACL : 0); if ((res= insert_precheck(thd, tables, update))) if ((res= insert_precheck(thd, tables))) break; res = mysql_insert(thd,tables,lex->field_list,lex->many_values, select_lex->item_list, lex->value_list, (update ? DUP_UPDATE : lex->duplicates)); lex->duplicates); if (thd->net.report_error) res= -1; break; Loading Loading @@ -5366,13 +5365,14 @@ int delete_precheck(THD *thd, TABLE_LIST *tables) -1 error (message is not sent to user) */ int insert_precheck(THD *thd, TABLE_LIST *tables, bool update) int insert_precheck(THD *thd, TABLE_LIST *tables) { LEX *lex= thd->lex; DBUG_ENTER("insert_precheck"); ulong privilege= (lex->duplicates == DUP_REPLACE ? INSERT_ACL | DELETE_ACL : INSERT_ACL | update); ulong privilege= INSERT_ACL | (lex->duplicates == DUP_REPLACE ? DELETE_ACL : 0) | (lex->duplicates == DUP_UPDATE ? UPDATE_ACL : 0); if (check_one_table_access(thd, privilege, tables)) DBUG_RETURN(1); Loading sql/sql_prepare.cc +2 −4 Original line number Diff line number Diff line Loading @@ -895,10 +895,9 @@ static int mysql_test_insert(Prepared_statement *stmt, int res= -1; TABLE_LIST *insert_table_list= (TABLE_LIST*) lex->select_lex.table_list.first; my_bool update= (lex->value_list.elements ? UPDATE_ACL : 0); DBUG_ENTER("mysql_test_insert"); if ((res= insert_precheck(thd, table_list, update))) if ((res= insert_precheck(thd, table_list))) DBUG_RETURN(res); /* Loading Loading @@ -1388,8 +1387,7 @@ static int send_prepare_results(Prepared_statement *stmt, bool text_protocol) res= mysql_test_insert(stmt, tables, lex->field_list, lex->many_values, select_lex->item_list, lex->value_list, (lex->value_list.elements ? DUP_UPDATE : lex->duplicates)); lex->duplicates); break; case SQLCOM_UPDATE: Loading Loading
mysql-test/r/grant2.result +27 −0 Original line number Diff line number Diff line SET NAMES binary; drop database if exists mysqltest; delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%'; delete from mysql.tables_priv where user like 'mysqltest\_%'; delete from mysql.columns_priv where user like 'mysqltest\_%'; flush privileges; grant all privileges on `my\_%`.* to mysqltest_1@localhost with grant option; select current_user(); Loading @@ -25,3 +28,27 @@ ERROR 42000: There is no such grant defined for user 'mysqltest_3' on host 'loca delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%'; flush privileges; create database mysqltest; grant INSERT, SELECT on mysqltest.* to mysqltest_1@localhost; flush privileges; use mysqltest; create table t1 (id int primary key, data varchar(255)); show grants for current_user(); Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' GRANT SELECT, INSERT ON `mysqltest`.* TO 'mysqltest_1'@'localhost' use mysqltest; insert into t1 values (1, 'I can''t change it!'); update t1 set data='I can change it!' where id = 1; ERROR 42000: Access denied for user 'mysqltest_1'@'localhost' to database 'mysqltest' insert into t1 values (1, 'XXX') on duplicate key update data= 'I can change it!'; ERROR 42000: Access denied for user 'mysqltest_1'@'localhost' to database 'mysqltest' select * from t1; id data 1 I can't change it! drop table t1; drop database mysqltest; use test; delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%'; flush privileges;
mysql-test/t/grant2.test +41 −3 Original line number Diff line number Diff line Loading @@ -6,13 +6,21 @@ SET NAMES binary; # # prepare playground before tests --disable_warnings drop database if exists mysqltest; --enable_warnings delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%'; delete from mysql.tables_priv where user like 'mysqltest\_%'; delete from mysql.columns_priv where user like 'mysqltest\_%'; flush privileges; # # wild_compare fun # delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%'; flush privileges; grant all privileges on `my\_%`.* to mysqltest_1@localhost with grant option; connect (user1,localhost,mysqltest_1,,); connection user1; Loading @@ -31,3 +39,33 @@ delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%'; flush privileges; # # Bug #6173: One can circumvent missing UPDATE privilege if he has SELECT # and INSERT privilege for table with primary key # create database mysqltest; grant INSERT, SELECT on mysqltest.* to mysqltest_1@localhost; flush privileges; use mysqltest; create table t1 (id int primary key, data varchar(255)); connect (mrbad, localhost, mysqltest_1,,); connection mrbad; show grants for current_user(); use mysqltest; insert into t1 values (1, 'I can''t change it!'); --error 1044 update t1 set data='I can change it!' where id = 1; # This should not be allowed since it too require UPDATE privilege. --error 1044 insert into t1 values (1, 'XXX') on duplicate key update data= 'I can change it!'; select * from t1; connection default; drop table t1; drop database mysqltest; use test; delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%'; flush privileges;
sql/mysql_priv.h +1 −1 Original line number Diff line number Diff line Loading @@ -374,7 +374,7 @@ int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count); int insert_select_precheck(THD *thd, TABLE_LIST *tables); int update_precheck(THD *thd, TABLE_LIST *tables); int delete_precheck(THD *thd, TABLE_LIST *tables); int insert_precheck(THD *thd, TABLE_LIST *tables, bool update); int insert_precheck(THD *thd, TABLE_LIST *tables); int create_table_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *create_table); Item *negate_expression(THD *thd, Item *expr); Loading
sql/sql_parse.cc +6 −6 Original line number Diff line number Diff line Loading @@ -2682,12 +2682,11 @@ mysql_execute_command(THD *thd) case SQLCOM_REPLACE: case SQLCOM_INSERT: { my_bool update= (lex->value_list.elements ? UPDATE_ACL : 0); if ((res= insert_precheck(thd, tables, update))) if ((res= insert_precheck(thd, tables))) break; res = mysql_insert(thd,tables,lex->field_list,lex->many_values, select_lex->item_list, lex->value_list, (update ? DUP_UPDATE : lex->duplicates)); lex->duplicates); if (thd->net.report_error) res= -1; break; Loading Loading @@ -5366,13 +5365,14 @@ int delete_precheck(THD *thd, TABLE_LIST *tables) -1 error (message is not sent to user) */ int insert_precheck(THD *thd, TABLE_LIST *tables, bool update) int insert_precheck(THD *thd, TABLE_LIST *tables) { LEX *lex= thd->lex; DBUG_ENTER("insert_precheck"); ulong privilege= (lex->duplicates == DUP_REPLACE ? INSERT_ACL | DELETE_ACL : INSERT_ACL | update); ulong privilege= INSERT_ACL | (lex->duplicates == DUP_REPLACE ? DELETE_ACL : 0) | (lex->duplicates == DUP_UPDATE ? UPDATE_ACL : 0); if (check_one_table_access(thd, privilege, tables)) DBUG_RETURN(1); Loading
sql/sql_prepare.cc +2 −4 Original line number Diff line number Diff line Loading @@ -895,10 +895,9 @@ static int mysql_test_insert(Prepared_statement *stmt, int res= -1; TABLE_LIST *insert_table_list= (TABLE_LIST*) lex->select_lex.table_list.first; my_bool update= (lex->value_list.elements ? UPDATE_ACL : 0); DBUG_ENTER("mysql_test_insert"); if ((res= insert_precheck(thd, table_list, update))) if ((res= insert_precheck(thd, table_list))) DBUG_RETURN(res); /* Loading Loading @@ -1388,8 +1387,7 @@ static int send_prepare_results(Prepared_statement *stmt, bool text_protocol) res= mysql_test_insert(stmt, tables, lex->field_list, lex->many_values, select_lex->item_list, lex->value_list, (lex->value_list.elements ? DUP_UPDATE : lex->duplicates)); lex->duplicates); break; case SQLCOM_UPDATE: Loading