From 66398a877a19b56496f706fd131046a5ad257ce8 Mon Sep 17 00:00:00 2001 From: Davi Arnaut <Davi.Arnaut@Sun.COM> Date: Fri, 12 Jun 2009 18:11:19 -0300 Subject: [PATCH] Bug#45100: Incomplete DROP USER in case of SQL_MODE = 'PAD_CHAR_TO_FULL_LENGTH' The SQL-mode PAD_CHAR_TO_FULL_LENGTH could prevent a DROP USER statement from privileges associated with the user being dropped. What ocurred was that reading from the User and Host fields of the tables tables_priv or columns_priv would yield values padded with spaces, causing a failure to match a specified user or host ('user' != 'user '); The solution is to disregard the PAD_CHAR_TO_FULL_LENGTH mode when iterating over and matching values in the privileges tables for a DROP USER statement. mysql-test/r/sql_mode.result: Add test case result for Bug#45100. mysql-test/t/sql_mode.test: Add test case for Bug#45100. sql/sql_acl.cc: Clear MODE_PAD_CHAR_TO_FULL_LENGTH before dropping privileges. --- mysql-test/r/sql_mode.result | 21 +++++++++++++++++++++ mysql-test/t/sql_mode.test | 36 ++++++++++++++++++++++++++++++++++++ sql/sql_acl.cc | 4 ++++ 3 files changed, 61 insertions(+) diff --git a/mysql-test/r/sql_mode.result b/mysql-test/r/sql_mode.result index 401340f204..0b0d5a38d0 100644 --- a/mysql-test/r/sql_mode.result +++ b/mysql-test/r/sql_mode.result @@ -506,3 +506,24 @@ mysqltest_32753@localhost set session sql_mode=@OLD_SQL_MODE; flush privileges; drop user mysqltest_32753@localhost; +DROP TABLE IF EXISTS t1,t2; +CREATE USER 'user_PCTFL'@'localhost' identified by 'PWD'; +CREATE USER 'user_no_PCTFL'@'localhost' identified by 'PWD'; +CREATE TABLE t1 (f1 BIGINT); +CREATE TABLE t2 (f1 CHAR(3) NOT NULL, f2 CHAR(20)); +GRANT ALL ON t1 TO 'user_PCTFL'@'localhost','user_no_PCTFL'@'localhost'; +GRANT SELECT(f1) ON t2 TO 'user_PCTFL'@'localhost','user_no_PCTFL'@'localhost'; +SET @OLD_SQL_MODE = @@SESSION.SQL_MODE; +SET SESSION SQL_MODE = 'PAD_CHAR_TO_FULL_LENGTH'; +DROP USER 'user_PCTFL'@'localhost'; +SET SESSION SQL_MODE = @OLD_SQL_MODE; +DROP USER 'user_no_PCTFL'@'localhost'; +FLUSH PRIVILEGES; +SELECT * FROM mysql.db WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL'; +Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Execute_priv Event_priv Trigger_priv +SELECT * FROM mysql.tables_priv WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL'; +Host Db User Table_name Grantor Timestamp Table_priv Column_priv +SELECT * FROM mysql.columns_priv WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL'; +Host Db User Table_name Column_name Timestamp Column_priv +DROP TABLE t1; +DROP TABLE t2; diff --git a/mysql-test/t/sql_mode.test b/mysql-test/t/sql_mode.test index acc9cc7979..4a9f34443c 100644 --- a/mysql-test/t/sql_mode.test +++ b/mysql-test/t/sql_mode.test @@ -308,3 +308,39 @@ flush privileges; --connection default drop user mysqltest_32753@localhost; + +# +# Bug#45100: Incomplete DROP USER in case of SQL_MODE = 'PAD_CHAR_TO_FULL_LENGTH' +# + +--disable_warnings +DROP TABLE IF EXISTS t1,t2; +--enable_warnings + +# Generate some prerequisites +CREATE USER 'user_PCTFL'@'localhost' identified by 'PWD'; +CREATE USER 'user_no_PCTFL'@'localhost' identified by 'PWD'; + +CREATE TABLE t1 (f1 BIGINT); +CREATE TABLE t2 (f1 CHAR(3) NOT NULL, f2 CHAR(20)); + +# Grant privilege on a TABLE +GRANT ALL ON t1 TO 'user_PCTFL'@'localhost','user_no_PCTFL'@'localhost'; +# Grant privilege on some COLUMN of a table +GRANT SELECT(f1) ON t2 TO 'user_PCTFL'@'localhost','user_no_PCTFL'@'localhost'; + +SET @OLD_SQL_MODE = @@SESSION.SQL_MODE; +SET SESSION SQL_MODE = 'PAD_CHAR_TO_FULL_LENGTH'; +DROP USER 'user_PCTFL'@'localhost'; +SET SESSION SQL_MODE = @OLD_SQL_MODE; +DROP USER 'user_no_PCTFL'@'localhost'; + +FLUSH PRIVILEGES; + +SELECT * FROM mysql.db WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL'; +SELECT * FROM mysql.tables_priv WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL'; +SELECT * FROM mysql.columns_priv WHERE Host = 'localhost' AND User LIKE 'user_%PCTFL'; + +# Cleanup +DROP TABLE t1; +DROP TABLE t2; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index be52fae200..79fc5d816f 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -5696,6 +5696,7 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list) List_iterator <LEX_USER> user_list(list); TABLE_LIST tables[GRANT_TABLES]; bool some_users_deleted= FALSE; + ulong old_sql_mode= thd->variables.sql_mode; DBUG_ENTER("mysql_drop_user"); /* @@ -5709,6 +5710,8 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list) if ((result= open_grant_tables(thd, tables))) DBUG_RETURN(result != 1); + thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH; + rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); @@ -5741,6 +5744,7 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list) rw_unlock(&LOCK_grant); close_thread_tables(thd); + thd->variables.sql_mode= old_sql_mode; DBUG_RETURN(result); } -- 2.30.9