From 2bbde22d8485463704a4be3494094a03c1888e21 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Mar 2005 08:16:56 +0200 Subject: [PATCH] Fixed two bugs in MySQL ACL. First one is related to Bug#7905. One should not be allowed to create new user with password without UPDATE privilege to MySQL database. Furthermore, executing the same GRANT statement twice would actually crash the server and corrupt privilege database. Other bug was that one could update a column, using the existing value as basis to calculate the new value (e.g. UPDATE t1 SET a=a+1) without SELECT privilege to the field (a in the above example) Fixed tests grant.pl and grant2, which were wrong. --- mysql-test/r/grant2.result | 1 + mysql-test/t/grant2.test | 1 + sql/sql_acl.cc | 11 ----------- sql/sql_parse.cc | 18 ++++++++++++++++++ sql/sql_update.cc | 2 +- tests/grant.pl | 4 ++-- 6 files changed, 23 insertions(+), 14 deletions(-) diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index 821f67536f3..e6c78fdfdd4 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -23,6 +23,7 @@ grant select on `my\_1`.* to mysqltest_4@localhost with grant option; ERROR 42000: 'mysqltest_1'@'localhost' is not allowed to create new users grant select on `my\_1`.* to mysqltest_4@localhost identified by 'mypass' with grant option; +ERROR 42000: Access denied for user 'mysqltest_1'@'localhost' to database 'mysql' show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test index 3b1200f8a6e..58f91fddcc2 100644 --- a/mysql-test/t/grant2.test +++ b/mysql-test/t/grant2.test @@ -36,6 +36,7 @@ set @@sql_mode='NO_AUTO_CREATE_USER'; select @@sql_mode; --error 1211 grant select on `my\_1`.* to mysqltest_4@localhost with grant option; +--error 1044 grant select on `my\_1`.* to mysqltest_4@localhost identified by 'mypass' with grant option; disconnect user1; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 3759840d3bb..c51e5e00aa1 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1642,17 +1642,6 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, } else { - /* - Check that the user isn't trying to change a password for another - user if he doesn't have UPDATE privilege to the MySQL database - */ - DBUG_ASSERT(combo.host.str != 0); - if (thd->user && combo.password.str && - (strcmp(thd->user,combo.user.str) || - my_strcasecmp(system_charset_info, - combo.host.str, thd->host_or_ip)) && - check_access(thd, UPDATE_ACL, "mysql",0,1,0)) - goto end; old_row_exists = 1; store_record(table,record[1]); // Save copy for update if (combo.password.str) // If password given diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4b069dd56e8..898dbc05a9a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3626,6 +3626,24 @@ unsent_create_error: first_table ? 0 : 1, 0)) goto error; + if (thd->user) // If not replication + { + LEX_USER *user; + List_iterator user_list(lex->users_list); + while ((user=user_list++)) + { + if (user->password.str && + strcmp(thd->user, user->user.str) || + user->host.str && + my_strcasecmp(system_charset_info, + user->host.str, thd->host_or_ip)) + { + if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 0)) + goto error; + break; // We are allowed to do changes + } + } + } if (specialflag & SPECIAL_NO_RESOLVE) { LEX_USER *user; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index e215141ff0a..3ee656b00ce 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -219,7 +219,7 @@ int mysql_update(THD *thd, #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Check values */ table_list->grant.want_privilege= table->grant.want_privilege= - (SELECT_ACL & ~~table->grant.privilege); + (SELECT_ACL & ~table->grant.privilege); #endif if (setup_fields(thd, 0, table_list, values, 1, 0, 0)) { diff --git a/tests/grant.pl b/tests/grant.pl index cd6a2eb80de..4f2bd1a61cb 100644 --- a/tests/grant.pl +++ b/tests/grant.pl @@ -201,7 +201,7 @@ safe_query("select * from mysql.db where user = '$opt_user'"); safe_query("grant CREATE,UPDATE,DROP on $opt_database.* to $user"); user_connect(0); user_query("create table $opt_database.test2 (a int not null)"); -user_query("update test,test2 SET test.a=1 where 1"); +user_query("update test,test2 SET test.a=1 where 1",1); user_query("update test,test2 SET test.a=test2.a where 1",1); safe_query("grant SELECT on $opt_database.* to $user"); user_connect(0); @@ -375,7 +375,7 @@ user_query("delete from $opt_database.test where a=2"); user_query("delete from $opt_database.test where A=2"); user_query("update test set b=5 where b>0"); user_query("update test set a=11 where b>5",1); -user_query("update test,test2 SET test.b=5 where b>0"); +user_query("update test,test2 SET test.b=5 where b>0",1); user_query("update test,test2 SET test.a=11 where b>0",1); user_query("update test,test2 SET test.b=test2.a where b>0",1); user_query("update test,test2 SET test.b=11 where test2.a>0",1);