Commit a10ce662 authored by dlenev@mysql.com's avatar dlenev@mysql.com

Merge bk-internal.mysql.com:/home/bk/mysql-4.1

into mysql.com:/home/dlenev/src/mysql-4.1-secfix
parents 0130f466 75d81662
SET NAMES binary; SET NAMES binary;
drop database if exists mysqltest;
delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.user where user like 'mysqltest\_%';
delete from mysql.db 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; flush privileges;
grant all privileges on `my\_%`.* to mysqltest_1@localhost with grant option; grant all privileges on `my\_%`.* to mysqltest_1@localhost with grant option;
select current_user(); select current_user();
...@@ -25,3 +28,27 @@ ERROR 42000: There is no such grant defined for user 'mysqltest_3' on host 'loca ...@@ -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.user where user like 'mysqltest\_%';
delete from mysql.db where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%';
flush privileges; 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;
...@@ -6,13 +6,21 @@ SET NAMES binary; ...@@ -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 # 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; grant all privileges on `my\_%`.* to mysqltest_1@localhost with grant option;
connect (user1,localhost,mysqltest_1,,); connect (user1,localhost,mysqltest_1,,);
connection user1; connection user1;
...@@ -31,3 +39,33 @@ delete from mysql.user where user like 'mysqltest\_%'; ...@@ -31,3 +39,33 @@ delete from mysql.user where user like 'mysqltest\_%';
delete from mysql.db where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%';
flush privileges; 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;
...@@ -374,7 +374,7 @@ int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count); ...@@ -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 insert_select_precheck(THD *thd, TABLE_LIST *tables);
int update_precheck(THD *thd, TABLE_LIST *tables); int update_precheck(THD *thd, TABLE_LIST *tables);
int delete_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, int create_table_precheck(THD *thd, TABLE_LIST *tables,
TABLE_LIST *create_table); TABLE_LIST *create_table);
Item *negate_expression(THD *thd, Item *expr); Item *negate_expression(THD *thd, Item *expr);
......
...@@ -2682,12 +2682,11 @@ unsent_create_error: ...@@ -2682,12 +2682,11 @@ unsent_create_error:
case SQLCOM_REPLACE: case SQLCOM_REPLACE:
case SQLCOM_INSERT: case SQLCOM_INSERT:
{ {
my_bool update= (lex->value_list.elements ? UPDATE_ACL : 0); if ((res= insert_precheck(thd, tables)))
if ((res= insert_precheck(thd, tables, update)))
break; break;
res = mysql_insert(thd,tables,lex->field_list,lex->many_values, res = mysql_insert(thd,tables,lex->field_list,lex->many_values,
select_lex->item_list, lex->value_list, select_lex->item_list, lex->value_list,
(update ? DUP_UPDATE : lex->duplicates)); lex->duplicates);
if (thd->net.report_error) if (thd->net.report_error)
res= -1; res= -1;
break; break;
...@@ -5366,13 +5365,14 @@ int delete_precheck(THD *thd, TABLE_LIST *tables) ...@@ -5366,13 +5365,14 @@ int delete_precheck(THD *thd, TABLE_LIST *tables)
-1 error (message is not sent to user) -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; LEX *lex= thd->lex;
DBUG_ENTER("insert_precheck"); DBUG_ENTER("insert_precheck");
ulong privilege= (lex->duplicates == DUP_REPLACE ? ulong privilege= INSERT_ACL |
INSERT_ACL | DELETE_ACL : INSERT_ACL | update); (lex->duplicates == DUP_REPLACE ? DELETE_ACL : 0) |
(lex->duplicates == DUP_UPDATE ? UPDATE_ACL : 0);
if (check_one_table_access(thd, privilege, tables)) if (check_one_table_access(thd, privilege, tables))
DBUG_RETURN(1); DBUG_RETURN(1);
......
...@@ -895,10 +895,9 @@ static int mysql_test_insert(Prepared_statement *stmt, ...@@ -895,10 +895,9 @@ static int mysql_test_insert(Prepared_statement *stmt,
int res= -1; int res= -1;
TABLE_LIST *insert_table_list= TABLE_LIST *insert_table_list=
(TABLE_LIST*) lex->select_lex.table_list.first; (TABLE_LIST*) lex->select_lex.table_list.first;
my_bool update= (lex->value_list.elements ? UPDATE_ACL : 0);
DBUG_ENTER("mysql_test_insert"); DBUG_ENTER("mysql_test_insert");
if ((res= insert_precheck(thd, table_list, update))) if ((res= insert_precheck(thd, table_list)))
DBUG_RETURN(res); DBUG_RETURN(res);
/* /*
...@@ -1388,8 +1387,7 @@ static int send_prepare_results(Prepared_statement *stmt, bool text_protocol) ...@@ -1388,8 +1387,7 @@ static int send_prepare_results(Prepared_statement *stmt, bool text_protocol)
res= mysql_test_insert(stmt, tables, lex->field_list, res= mysql_test_insert(stmt, tables, lex->field_list,
lex->many_values, lex->many_values,
select_lex->item_list, lex->value_list, select_lex->item_list, lex->value_list,
(lex->value_list.elements ? lex->duplicates);
DUP_UPDATE : lex->duplicates));
break; break;
case SQLCOM_UPDATE: case SQLCOM_UPDATE:
......
...@@ -4136,14 +4136,18 @@ expr_or_default: ...@@ -4136,14 +4136,18 @@ expr_or_default:
opt_insert_update: opt_insert_update:
/* empty */ /* empty */
| ON DUPLICATE_SYM | ON DUPLICATE_SYM
{ /* for simplisity, let's forget about {
INSERT ... SELECT ... UPDATE LEX *lex= Lex;
for a moment */ /*
if (Lex->sql_command != SQLCOM_INSERT) For simplicity, let's forget about INSERT ... SELECT ... UPDATE
for a moment.
*/
if (lex->sql_command != SQLCOM_INSERT)
{ {
yyerror(ER(ER_SYNTAX_ERROR)); yyerror(ER(ER_SYNTAX_ERROR));
YYABORT; YYABORT;
} }
lex->duplicates= DUP_UPDATE;
} }
KEY_SYM UPDATE_SYM update_list KEY_SYM UPDATE_SYM update_list
; ;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment