Commit 88253542 authored by Satya B's avatar Satya B

Fix for Bug #41597 - After rename of user, there are additional grants when

                     grants are reapplied.


After renaming a user and trying to re-apply grants results in additional
grants.

This is because we use username as part of the key for GRANT_TABLE structure.
When the user is renamed, we only change the username stored and the hash key
still contains the old user name and this results in the extra privileges

Fixed by rebuilding the hash key and updating the column_priv_hash structure
when the user is renamed

mysql-test/r/grant3.result:
  Bug #41597 - After rename of user, there are additional grants when 
               grants are reapplied.
  
  Testcase for BUG#41597
mysql-test/t/grant3.test:
  Bug #41597 - After rename of user, there are additional grants when 
               grants are reapplied.
  
  Testcase for BUG#41597
sql/sql_acl.cc:
  Bug #41597 - After rename of user, there are additional grants when 
               grants are reapplied.
  
  Fixed handle_grant_struct() to update the hash key when the user is renamed.
  Added to set_user_details() method to GRANT_NAME class
parent 128e676c
......@@ -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
......@@ -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
......
......@@ -2096,6 +2096,8 @@ class GRANT_NAME :public Sql_alloc
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 @@ class GRANT_TABLE :public GRANT_NAME
};
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;
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment