summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/grant.result3
-rw-r--r--mysql-test/r/grant3.result122
-rw-r--r--mysql-test/t/grant.test3
-rw-r--r--mysql-test/t/grant3.test100
-rw-r--r--sql/sql_acl.cc41
5 files changed, 259 insertions, 10 deletions
diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result
index a4c51cca277..855352a2195 100644
--- a/mysql-test/r/grant.result
+++ b/mysql-test/r/grant.result
@@ -1121,6 +1121,9 @@ SELECT * FROM test.t1;
f1 f2
1 1
2 2
+REVOKE UPDATE (f1) ON `test`.`t1` FROM 'mysqltest_1'@'localhost';
+REVOKE SELECT ON `test`.* FROM 'mysqltest_1'@'localhost';
+REVOKE ALL ON db27878.* FROM 'mysqltest_1'@'localhost';
DROP DATABASE db27878;
use test;
DROP TABLE t1;
diff --git a/mysql-test/r/grant3.result b/mysql-test/r/grant3.result
index 6193c4fd49d..cc7f46855b2 100644
--- a/mysql-test/r/grant3.result
+++ b/mysql-test/r/grant3.result
@@ -16,3 +16,125 @@ 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;
+grant select on test.* to CUser@localhost;
+grant select on test.* to CUser@LOCALHOST;
+flush privileges;
+SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
+user host
+CUser LOCALHOST
+CUser localhost
+SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
+user host db select_priv
+CUser LOCALHOST test Y
+CUser localhost test Y
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST';
+flush privileges;
+SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
+user host
+CUser LOCALHOST
+CUser localhost
+SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
+user host db select_priv
+CUser localhost test Y
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost';
+flush privileges;
+SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
+user host
+CUser LOCALHOST
+CUser localhost
+SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
+user host db select_priv
+DROP USER CUser@localhost;
+DROP USER CUser@LOCALHOST;
+create table t1 (a int);
+grant select on test.t1 to CUser@localhost;
+grant select on test.t1 to CUser@LOCALHOST;
+flush privileges;
+SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
+user host
+CUser LOCALHOST
+CUser localhost
+SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
+user host db Table_name Table_priv Column_priv
+CUser LOCALHOST test t1 Select
+CUser localhost test t1 Select
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST';
+flush privileges;
+SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
+user host
+CUser LOCALHOST
+CUser localhost
+SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
+user host db Table_name Table_priv Column_priv
+CUser localhost test t1 Select
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost';
+flush privileges;
+SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
+user host
+CUser LOCALHOST
+CUser localhost
+SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
+user host db Table_name Table_priv Column_priv
+DROP USER CUser@localhost;
+DROP USER CUser@LOCALHOST;
+grant select(a) on test.t1 to CUser@localhost;
+grant select(a) on test.t1 to CUser@LOCALHOST;
+flush privileges;
+SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
+user host
+CUser LOCALHOST
+CUser localhost
+SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
+user host db Table_name Table_priv Column_priv
+CUser LOCALHOST test t1 Select
+CUser localhost test t1 Select
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST';
+flush privileges;
+SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
+user host
+CUser LOCALHOST
+CUser localhost
+SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
+user host db Table_name Table_priv Column_priv
+CUser localhost test t1 Select
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost';
+flush privileges;
+SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
+user host
+CUser LOCALHOST
+CUser localhost
+SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
+user host db Table_name Table_priv Column_priv
+DROP USER CUser@localhost;
+DROP USER CUser@LOCALHOST;
+drop table t1;
+grant select on test.* to CUser2@localhost;
+grant select on test.* to CUser2@LOCALHOST;
+flush privileges;
+SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
+user host
+CUser2 LOCALHOST
+CUser2 localhost
+SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
+user host db select_priv
+CUser2 LOCALHOST test Y
+CUser2 localhost test Y
+REVOKE SELECT ON test.* FROM 'CUser2'@'LOCALHOST';
+flush privileges;
+SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
+user host
+CUser2 LOCALHOST
+CUser2 localhost
+SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
+user host db select_priv
+CUser2 localhost test Y
+REVOKE SELECT ON test.* FROM 'CUser2'@'localhost';
+flush privileges;
+SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
+user host
+CUser2 LOCALHOST
+CUser2 localhost
+SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
+user host db select_priv
+DROP USER CUser2@localhost;
+DROP USER CUser2@LOCALHOST;
diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test
index 32eb262fd51..1d11a669811 100644
--- a/mysql-test/t/grant.test
+++ b/mysql-test/t/grant.test
@@ -1144,6 +1144,9 @@ UPDATE v1 SET f2 = 4;
SELECT * FROM test.t1;
disconnect user1;
connection default;
+REVOKE UPDATE (f1) ON `test`.`t1` FROM 'mysqltest_1'@'localhost';
+REVOKE SELECT ON `test`.* FROM 'mysqltest_1'@'localhost';
+REVOKE ALL ON db27878.* FROM 'mysqltest_1'@'localhost';
DROP DATABASE db27878;
use test;
DROP TABLE t1;
diff --git a/mysql-test/t/grant3.test b/mysql-test/t/grant3.test
index 115586e807d..fac577ef0ff 100644
--- a/mysql-test/t/grant3.test
+++ b/mysql-test/t/grant3.test
@@ -34,3 +34,103 @@ 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;
+
+#
+# Bug: #19828 Case sensitivity in Grant/Revoke
+#
+
+grant select on test.* to CUser@localhost;
+grant select on test.* to CUser@LOCALHOST;
+flush privileges;
+
+SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
+SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST';
+flush privileges;
+
+SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
+SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost';
+flush privileges;
+
+SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
+SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2;
+
+DROP USER CUser@localhost;
+DROP USER CUser@LOCALHOST;
+
+#### table grants
+create table t1 (a int);
+grant select on test.t1 to CUser@localhost;
+grant select on test.t1 to CUser@LOCALHOST;
+flush privileges;
+
+SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
+SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST';
+flush privileges;
+
+SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
+SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost';
+flush privileges;
+
+SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
+SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
+
+DROP USER CUser@localhost;
+DROP USER CUser@LOCALHOST;
+
+### column grants
+
+grant select(a) on test.t1 to CUser@localhost;
+grant select(a) on test.t1 to CUser@LOCALHOST;
+flush privileges;
+
+SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
+SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST';
+flush privileges;
+
+SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
+SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost';
+flush privileges;
+
+SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2;
+SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2;
+
+DROP USER CUser@localhost;
+DROP USER CUser@LOCALHOST;
+
+drop table t1;
+
+# revoke on a specific DB only
+
+grant select on test.* to CUser2@localhost;
+grant select on test.* to CUser2@LOCALHOST;
+flush privileges;
+
+SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
+SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
+
+REVOKE SELECT ON test.* FROM 'CUser2'@'LOCALHOST';
+flush privileges;
+
+SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
+SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
+
+REVOKE SELECT ON test.* FROM 'CUser2'@'localhost';
+flush privileges;
+
+SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2;
+SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2;
+
+DROP USER CUser2@localhost;
+DROP USER CUser2@LOCALHOST;
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index f9bd2c6ba0d..6bc6cce5e72 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1132,7 +1132,7 @@ static void acl_update_db(const char *user, const char *host, const char *db,
{
if (!acl_db->host.hostname && !host[0] ||
acl_db->host.hostname &&
- !my_strcasecmp(system_charset_info, host, acl_db->host.hostname))
+ !strcmp(host, acl_db->host.hostname))
{
if (!acl_db->db && !db[0] ||
acl_db->db && !strcmp(db,acl_db->db))
@@ -4344,6 +4344,13 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
if (!(host=acl_db->host.hostname))
host= "";
+ /*
+ We do not make SHOW GRANTS case-sensitive here (like REVOKE),
+ but make it case-insensitive because that's the way they are
+ actually applied, and showing fewer privileges than are applied
+ would be wrong from a security point of view.
+ */
+
if (!strcmp(lex_user->user.str,user) &&
!my_strcasecmp(system_charset_info, lex_user->host.str, host))
{
@@ -4379,8 +4386,8 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
db.append(lex_user->user.str, lex_user->user.length,
system_charset_info);
db.append (STRING_WITH_LEN("'@'"));
- db.append(lex_user->host.str, lex_user->host.length,
- system_charset_info);
+ // host and lex_user->host are equal except for case
+ db.append(host, strlen(host), system_charset_info);
db.append ('\'');
if (want_access & GRANT_ACL)
db.append(STRING_WITH_LEN(" WITH GRANT OPTION"));
@@ -4407,6 +4414,13 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
if (!(host= grant_table->host.hostname))
host= "";
+ /*
+ We do not make SHOW GRANTS case-sensitive here (like REVOKE),
+ but make it case-insensitive because that's the way they are
+ actually applied, and showing fewer privileges than are applied
+ would be wrong from a security point of view.
+ */
+
if (!strcmp(lex_user->user.str,user) &&
!my_strcasecmp(system_charset_info, lex_user->host.str, host))
{
@@ -4487,8 +4501,8 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
global.append(lex_user->user.str, lex_user->user.length,
system_charset_info);
global.append(STRING_WITH_LEN("'@'"));
- global.append(lex_user->host.str,lex_user->host.length,
- system_charset_info);
+ // host and lex_user->host are equal except for case
+ global.append(host, strlen(host), system_charset_info);
global.append('\'');
if (table_access & GRANT_ACL)
global.append(STRING_WITH_LEN(" WITH GRANT OPTION"));
@@ -4543,6 +4557,13 @@ static int show_routine_grants(THD* thd, LEX_USER *lex_user, HASH *hash,
if (!(host= grant_proc->host.hostname))
host= "";
+ /*
+ We do not make SHOW GRANTS case-sensitive here (like REVOKE),
+ but make it case-insensitive because that's the way they are
+ actually applied, and showing fewer privileges than are applied
+ would be wrong from a security point of view.
+ */
+
if (!strcmp(lex_user->user.str,user) &&
!my_strcasecmp(system_charset_info, lex_user->host.str, host))
{
@@ -4586,8 +4607,8 @@ static int show_routine_grants(THD* thd, LEX_USER *lex_user, HASH *hash,
global.append(lex_user->user.str, lex_user->user.length,
system_charset_info);
global.append(STRING_WITH_LEN("'@'"));
- global.append(lex_user->host.str,lex_user->host.length,
- system_charset_info);
+ // host and lex_user->host are equal except for case
+ global.append(host, strlen(host), system_charset_info);
global.append('\'');
if (proc_access & GRANT_ACL)
global.append(STRING_WITH_LEN(" WITH GRANT OPTION"));
@@ -5541,7 +5562,7 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
host= "";
if (!strcmp(lex_user->user.str,user) &&
- !my_strcasecmp(system_charset_info, lex_user->host.str, host))
+ !strcmp(lex_user->host.str, host))
{
if (!replace_db_table(tables[1].table, acl_db->db, *lex_user, ~(ulong)0, 1))
{
@@ -5572,7 +5593,7 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
host= "";
if (!strcmp(lex_user->user.str,user) &&
- !my_strcasecmp(system_charset_info, lex_user->host.str, host))
+ !strcmp(lex_user->host.str, host))
{
if (replace_table_table(thd,grant_table,tables[2].table,*lex_user,
grant_table->db,
@@ -5618,7 +5639,7 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
host= "";
if (!strcmp(lex_user->user.str,user) &&
- !my_strcasecmp(system_charset_info, lex_user->host.str, host))
+ !strcmp(lex_user->host.str, host))
{
if (!replace_routine_table(thd,grant_proc,tables[4].table,*lex_user,
grant_proc->db,