From a6afab6a55026bf4d8fce13d5ab44decf92ffe68 Mon Sep 17 00:00:00 2001 From: "jimw@mysql.com" <> Date: Tue, 15 Feb 2005 13:36:46 -0800 Subject: [PATCH] Always lowercase database names from 'host' and 'db' grant tables when they are loaded and lower_case_table_names is set, but issue a warning when it is done. (Bug #7989) --- mysql-test/r/lowercase_table_grant.result | 23 ++++++++++++ mysql-test/t/lowercase_table_grant-master.opt | 1 + mysql-test/t/lowercase_table_grant.test | 25 +++++++++++++ sql/sql_acl.cc | 37 +++++++++++++++++++ 4 files changed, 86 insertions(+) create mode 100644 mysql-test/r/lowercase_table_grant.result create mode 100644 mysql-test/t/lowercase_table_grant-master.opt create mode 100644 mysql-test/t/lowercase_table_grant.test diff --git a/mysql-test/r/lowercase_table_grant.result b/mysql-test/r/lowercase_table_grant.result new file mode 100644 index 00000000000..3889bd418db --- /dev/null +++ b/mysql-test/r/lowercase_table_grant.result @@ -0,0 +1,23 @@ +use mysql; +create database MYSQLtest; +grant all on MySQLtest.* to mysqltest_1@localhost; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT ALL PRIVILEGES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' +select * from db where user = 'mysqltest_1'; +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 +localhost mysqltest mysqltest_1 Y Y Y Y Y Y N Y Y Y Y Y +update db set db = 'MYSQLtest' where db = 'mysqltest' and user = 'mysqltest_1' and host = 'localhost'; +flush privileges; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT ALL PRIVILEGES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' +select * from db where user = 'mysqltest_1'; +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 +localhost MYSQLtest mysqltest_1 Y Y Y Y Y Y N Y Y Y Y Y +delete from db where db = 'MYSQLtest' and user = 'mysqltest_1' and host = 'localhost'; +flush privileges; +drop user mysqltest_1@localhost; +drop database MYSQLtest; diff --git a/mysql-test/t/lowercase_table_grant-master.opt b/mysql-test/t/lowercase_table_grant-master.opt new file mode 100644 index 00000000000..c718e2feb1b --- /dev/null +++ b/mysql-test/t/lowercase_table_grant-master.opt @@ -0,0 +1 @@ +--lower_case_table_names diff --git a/mysql-test/t/lowercase_table_grant.test b/mysql-test/t/lowercase_table_grant.test new file mode 100644 index 00000000000..5ac35c81c21 --- /dev/null +++ b/mysql-test/t/lowercase_table_grant.test @@ -0,0 +1,25 @@ +# Test of grants when lower_case_table_names is on +use mysql; + +# mixed-case database name for testing +create database MYSQLtest; + +# check that database name gets forced to lowercase +grant all on MySQLtest.* to mysqltest_1@localhost; +show grants for mysqltest_1@localhost; + +# now force it to mixed case, but see that it is lowercased in the acl cache +select * from db where user = 'mysqltest_1'; +update db set db = 'MYSQLtest' where db = 'mysqltest' and user = 'mysqltest_1' and host = 'localhost'; +flush privileges; +show grants for mysqltest_1@localhost; +select * from db where user = 'mysqltest_1'; + +# clear out the user we created +# +# can't use REVOKE because of the mixed-case database name +delete from db where db = 'MYSQLtest' and user = 'mysqltest_1' and host = 'localhost'; +flush privileges; +drop user mysqltest_1@localhost; + +drop database MYSQLtest; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 7c17a4ef275..92d6f471a1e 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -139,6 +139,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) MYSQL_LOCK *lock; my_bool return_val=1; bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE; + char tmp_name[NAME_LEN+1]; DBUG_ENTER("acl_init"); @@ -197,6 +198,24 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) ACL_HOST host; update_hostname(&host.host,get_field(&mem, table->field[0])); host.db= get_field(&mem, table->field[1]); + if (lower_case_table_names) + { + /* + We make a temporary copy of the database, force it to lower case, + and then copy it back over the original name. We can't just update + the host.db pointer, because tmp_name is allocated on the stack. + */ + (void)strmov(tmp_name, host.db); + my_casedn_str(files_charset_info, tmp_name); + if (strcmp(host.db, tmp_name) != 0) + { + sql_print_warning("'host' entry '%s|%s' had database in mixed " + "case that has been forced to lowercase because " + "lower_case_table_names is set.", + host.host.hostname, host.db); + (void)strmov(host.db, tmp_name); + } + } host.access= get_access(table,2); host.access= fix_rights_for_db(host.access); host.sort= get_sort(2,host.host.hostname,host.db); @@ -380,6 +399,24 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) } db.access=get_access(table,3); db.access=fix_rights_for_db(db.access); + if (lower_case_table_names) + { + /* + We make a temporary copy of the database, force it to lower case, + and then copy it back over the original name. We can't just update + the db.db pointer, because tmp_name is allocated on the stack. + */ + (void)strmov(tmp_name, db.db); + my_casedn_str(files_charset_info, tmp_name); + if (strcmp(db.db, tmp_name) != 0) + { + sql_print_warning("'db' entry '%s %s@%s' had database in mixed " + "case that has been forced to lowercase because " + "lower_case_table_names is set.", + db.db, db.user, db.host.hostname, db.host.hostname); + (void)strmov(db.db, tmp_name); + } + } db.sort=get_sort(3,db.host.hostname,db.db,db.user); #ifndef TO_BE_REMOVED if (table->fields <= 9)