summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/grant3.result38
-rw-r--r--mysql-test/t/grant3.test35
-rw-r--r--sql/sql_acl.cc46
3 files changed, 107 insertions, 12 deletions
diff --git a/mysql-test/r/grant3.result b/mysql-test/r/grant3.result
index f38848111ad..59c64ee84ae 100644
--- a/mysql-test/r/grant3.result
+++ b/mysql-test/r/grant3.result
@@ -154,4 +154,42 @@ SELECT * FROM mysqltest_1.t1;
a
DROP USER 'mysqltest1'@'%';
DROP DATABASE mysqltest_1;
+#
+# Bug#41597 - After rename of user, there are additional grants
+# when grants are reapplied.
+#
+CREATE DATABASE temp;
+CREATE TABLE temp.t1(a INT, b VARCHAR(10));
+INSERT INTO temp.t1 VALUES(1, 'name1');
+INSERT INTO temp.t1 VALUES(2, 'name2');
+INSERT INTO temp.t1 VALUES(3, 'name3');
+CREATE USER 'user1'@'%';
+RENAME USER 'user1'@'%' TO 'user2'@'%';
+# Show privileges after rename and BEFORE grant
+SHOW GRANTS FOR 'user2'@'%';
+Grants for user2@%
+GRANT USAGE ON *.* TO 'user2'@'%'
+GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO 'user2'@'%';
+# Show privileges after rename and grant
+SHOW GRANTS FOR 'user2'@'%';
+Grants for user2@%
+GRANT USAGE ON *.* TO 'user2'@'%'
+GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO 'user2'@'%'
+# Connect as the renamed user
+SHOW GRANTS;
+Grants for user2@%
+GRANT USAGE ON *.* TO 'user2'@'%'
+GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO 'user2'@'%'
+SELECT a FROM temp.t1;
+a
+1
+2
+3
+# Check for additional privileges by accessing a
+# non privileged column. We shouldn't be able to
+# access this column.
+SELECT b FROM temp.t1;
+ERROR 42000: SELECT command denied to user 'user2'@'localhost' for column 'b' in table 't1'
+DROP USER 'user2'@'%';
+DROP DATABASE temp;
End of 5.0 tests
diff --git a/mysql-test/t/grant3.test b/mysql-test/t/grant3.test
index 9a635048774..437fc9a278f 100644
--- a/mysql-test/t/grant3.test
+++ b/mysql-test/t/grant3.test
@@ -163,6 +163,41 @@ connection default;
DROP USER 'mysqltest1'@'%';
DROP DATABASE mysqltest_1;
+--echo #
+--echo # Bug#41597 - After rename of user, there are additional grants
+--echo # when grants are reapplied.
+--echo #
+
+CREATE DATABASE temp;
+CREATE TABLE temp.t1(a INT, b VARCHAR(10));
+INSERT INTO temp.t1 VALUES(1, 'name1');
+INSERT INTO temp.t1 VALUES(2, 'name2');
+INSERT INTO temp.t1 VALUES(3, 'name3');
+
+
+CREATE USER 'user1'@'%';
+RENAME USER 'user1'@'%' TO 'user2'@'%';
+--echo # Show privileges after rename and BEFORE grant
+SHOW GRANTS FOR 'user2'@'%';
+GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO 'user2'@'%';
+--echo # Show privileges after rename and grant
+SHOW GRANTS FOR 'user2'@'%';
+
+--echo # Connect as the renamed user
+connect (conn1, localhost, user2,,);
+connection conn1;
+SHOW GRANTS;
+SELECT a FROM temp.t1;
+--echo # Check for additional privileges by accessing a
+--echo # non privileged column. We shouldn't be able to
+--echo # access this column.
+--error ER_COLUMNACCESS_DENIED_ERROR
+SELECT b FROM temp.t1;
+disconnect conn1;
+
+connection default;
+DROP USER 'user2'@'%';
+DROP DATABASE temp;
--echo End of 5.0 tests
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index ea17a4227ef..8f1e2c70fe6 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -2096,6 +2096,8 @@ public:
GRANT_NAME (TABLE *form);
virtual ~GRANT_NAME() {};
virtual bool ok() { return privs != 0; }
+ void set_user_details(const char *h, const char *d,
+ const char *u, const char *t);
};
@@ -2113,27 +2115,36 @@ public:
};
-
-GRANT_NAME::GRANT_NAME(const char *h, const char *d,const char *u,
- const char *t, ulong p)
- :privs(p)
+void GRANT_NAME::set_user_details(const char *h, const char *d,
+ const char *u, const char *t)
{
/* Host given by user */
update_hostname(&host, strdup_root(&memex, h));
- db = strdup_root(&memex,d);
+ if (db != d)
+ {
+ db= strdup_root(&memex, d);
+ if (lower_case_table_names)
+ my_casedn_str(files_charset_info, db);
+ }
user = strdup_root(&memex,u);
sort= get_sort(3,host.hostname,db,user);
- tname= strdup_root(&memex,t);
- if (lower_case_table_names)
+ if (tname != t)
{
- my_casedn_str(files_charset_info, db);
- my_casedn_str(files_charset_info, tname);
+ tname= strdup_root(&memex, t);
+ if (lower_case_table_names)
+ my_casedn_str(files_charset_info, tname);
}
key_length =(uint) strlen(d)+(uint) strlen(u)+(uint) strlen(t)+3;
hash_key = (char*) alloc_root(&memex,key_length);
strmov(strmov(strmov(hash_key,user)+1,db)+1,tname);
}
+GRANT_NAME::GRANT_NAME(const char *h, const char *d,const char *u,
+ const char *t, ulong p)
+ :db(0), tname(0), privs(p)
+{
+ set_user_details(h, d, u, t);
+}
GRANT_TABLE::GRANT_TABLE(const char *h, const char *d,const char *u,
const char *t, ulong p, ulong c)
@@ -5183,9 +5194,20 @@ static int handle_grant_struct(uint struct_no, bool drop,
case 2:
case 3:
- grant_name->user= strdup_root(&mem, user_to->user.str);
- update_hostname(&grant_name->host,
- strdup_root(&mem, user_to->host.str));
+ /*
+ Update the grant structure with the new user name and
+ host name
+ */
+ grant_name->set_user_details(user_to->host.str, grant_name->db,
+ user_to->user.str, grant_name->tname);
+
+ /*
+ Since username is part of the hash key, when the user name
+ is renamed, the hash key is changed. Update the hash to
+ ensure that the position matches the new hash key value
+ */
+ hash_update(&column_priv_hash, (byte *)grant_name,
+ grant_name->hash_key, grant_name->key_length);
break;
}
}