Commit 2d2d4df7 authored by unknown's avatar unknown
Browse files

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)


sql/sql_acl.cc:
  Lowercase database names in 'host' and 'db' grant tables when loading,
  but issue a warning to the log about them.
parent 1b46843c
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
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;
+1 −0
Original line number Diff line number Diff line
--lower_case_table_names
+25 −0
Original line number Diff line number Diff line
# 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;
+37 −0
Original line number Diff line number Diff line
@@ -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)