Commit d40acb4d authored by unknown's avatar unknown

Use the hostname with which the user authenticated when determining which

user to update with 'SET PASSWORD = ...'. (Bug #12302)


mysql-test/r/grant2.result:
  Add new results
mysql-test/t/grant2.test:
  Add new tests
sql/set_var.cc:
  Pass priv_host into check_change_password().
sql/sql_acl.cc:
  Add exact flag for find_acl_user, so we can specify that we want
  an exact match on the hostname.
parent b977af8a
...@@ -94,5 +94,31 @@ i ...@@ -94,5 +94,31 @@ i
2 2
3 3
REVOKE ALL ON mysqltest_1.t1 FROM mysqltest_1@'127.0.0.0/255.0.0.0'; REVOKE ALL ON mysqltest_1.t1 FROM mysqltest_1@'127.0.0.0/255.0.0.0';
delete from mysql.user where user like 'mysqltest\_1';
flush privileges;
drop table mysqltest_1.t1; drop table mysqltest_1.t1;
grant all on mysqltest_1.* to mysqltest_1@'127.0.0.1';
select current_user();
current_user()
mysqltest_1@127.0.0.1
set password = password('changed');
select host, length(password) from mysql.user where user like 'mysqltest\_1';
host length(password)
127.0.0.1 41
revoke all on mysqltest_1.* from mysqltest_1@'127.0.0.1';
delete from mysql.user where user like 'mysqltest\_1';
flush privileges;
grant all on mysqltest_1.* to mysqltest_1@'127.0.0.0/255.0.0.0';
select current_user();
current_user()
mysqltest_1@127.0.0.0/255.0.0.0
set password = password('changed');
select host, length(password) from mysql.user where user like 'mysqltest\_1';
host length(password)
127.0.0.0/255.0.0.0 41
revoke all on mysqltest_1.* from mysqltest_1@'127.0.0.0/255.0.0.0';
delete from mysql.user where user like 'mysqltest\_1';
flush privileges;
drop database mysqltest_1; drop database mysqltest_1;
set password = password("changed");
ERROR 42000: Access denied for user ''@'localhost' to database 'mysql'
...@@ -122,7 +122,45 @@ select * from t1; ...@@ -122,7 +122,45 @@ select * from t1;
disconnect n1; disconnect n1;
connection default; connection default;
REVOKE ALL ON mysqltest_1.t1 FROM mysqltest_1@'127.0.0.0/255.0.0.0'; REVOKE ALL ON mysqltest_1.t1 FROM mysqltest_1@'127.0.0.0/255.0.0.0';
delete from mysql.user where user like 'mysqltest\_1';
flush privileges;
drop table mysqltest_1.t1; drop table mysqltest_1.t1;
#
# Bug #12302: 'SET PASSWORD = ...' didn't work if connecting hostname !=
# hostname the current user is authenticated as. Note that a test for this
# was also added to the test above.
#
grant all on mysqltest_1.* to mysqltest_1@'127.0.0.1';
connect (b12302,127.0.0.1,mysqltest_1,,mysqltest_1,$MASTER_MYPORT,);
connection b12302;
select current_user();
set password = password('changed');
disconnect b12302;
connection default;
select host, length(password) from mysql.user where user like 'mysqltest\_1';
revoke all on mysqltest_1.* from mysqltest_1@'127.0.0.1';
delete from mysql.user where user like 'mysqltest\_1';
flush privileges;
grant all on mysqltest_1.* to mysqltest_1@'127.0.0.0/255.0.0.0';
connect (b12302_2,127.0.0.1,mysqltest_1,,mysqltest_1,$MASTER_MYPORT,);
connection b12302_2;
select current_user();
set password = password('changed');
disconnect b12302_2;
connection default;
select host, length(password) from mysql.user where user like 'mysqltest\_1';
revoke all on mysqltest_1.* from mysqltest_1@'127.0.0.0/255.0.0.0';
delete from mysql.user where user like 'mysqltest\_1';
flush privileges;
drop database mysqltest_1; drop database mysqltest_1;
# But anonymous users can't change their password
connect (n5,localhost,test,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
connection n5;
--error 1044
set password = password("changed");
disconnect n5;
connection default;
# End of 4.1 tests # End of 4.1 tests
...@@ -2944,7 +2944,18 @@ int set_var_password::check(THD *thd) ...@@ -2944,7 +2944,18 @@ int set_var_password::check(THD *thd)
{ {
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!user->host.str) if (!user->host.str)
user->host.str= (char*) thd->host_or_ip; {
if (thd->priv_host != 0)
{
user->host.str= (char *) thd->priv_host;
user->host.length= strlen(thd->priv_host);
}
else
{
user->host.str= (char *)"%";
user->host.length= 1;
}
}
/* Returns 1 as the function sends error to client */ /* Returns 1 as the function sends error to client */
return check_change_password(thd, user->host.str, user->user.str, return check_change_password(thd, user->host.str, user->user.str,
password, strlen(password)) ? 1 : 0; password, strlen(password)) ? 1 : 0;
......
...@@ -67,7 +67,8 @@ static ulong get_access(TABLE *form,uint fieldnr, uint *next_field=0); ...@@ -67,7 +67,8 @@ static ulong get_access(TABLE *form,uint fieldnr, uint *next_field=0);
static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b); static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b);
static ulong get_sort(uint count,...); static ulong get_sort(uint count,...);
static void init_check_host(void); static void init_check_host(void);
static ACL_USER *find_acl_user(const char *host, const char *user); static ACL_USER *find_acl_user(const char *host, const char *user,
my_bool exact);
static bool update_user_table(THD *thd, const char *host, const char *user, static bool update_user_table(THD *thd, const char *host, const char *user,
const char *new_password, uint new_password_len); const char *new_password, uint new_password_len);
static void update_hostname(acl_host_and_ip *host, const char *hostname); static void update_hostname(acl_host_and_ip *host, const char *hostname);
...@@ -1188,7 +1189,7 @@ bool check_change_password(THD *thd, const char *host, const char *user, ...@@ -1188,7 +1189,7 @@ bool check_change_password(THD *thd, const char *host, const char *user,
} }
if (!thd->slave_thread && if (!thd->slave_thread &&
(strcmp(thd->user,user) || (strcmp(thd->user,user) ||
my_strcasecmp(&my_charset_latin1, host, thd->host_or_ip))) my_strcasecmp(&my_charset_latin1, host, thd->priv_host)))
{ {
if (check_access(thd, UPDATE_ACL, "mysql",0,1,0)) if (check_access(thd, UPDATE_ACL, "mysql",0,1,0))
return(1); return(1);
...@@ -1240,7 +1241,7 @@ bool change_password(THD *thd, const char *host, const char *user, ...@@ -1240,7 +1241,7 @@ bool change_password(THD *thd, const char *host, const char *user,
VOID(pthread_mutex_lock(&acl_cache->lock)); VOID(pthread_mutex_lock(&acl_cache->lock));
ACL_USER *acl_user; ACL_USER *acl_user;
if (!(acl_user= find_acl_user(host, user))) if (!(acl_user= find_acl_user(host, user, TRUE)))
{ {
VOID(pthread_mutex_unlock(&acl_cache->lock)); VOID(pthread_mutex_unlock(&acl_cache->lock));
send_error(thd, ER_PASSWORD_NO_MATCH); send_error(thd, ER_PASSWORD_NO_MATCH);
...@@ -1282,7 +1283,7 @@ bool change_password(THD *thd, const char *host, const char *user, ...@@ -1282,7 +1283,7 @@ bool change_password(THD *thd, const char *host, const char *user,
*/ */
static ACL_USER * static ACL_USER *
find_acl_user(const char *host, const char *user) find_acl_user(const char *host, const char *user, my_bool exact)
{ {
DBUG_ENTER("find_acl_user"); DBUG_ENTER("find_acl_user");
DBUG_PRINT("enter",("host: '%s' user: '%s'",host,user)); DBUG_PRINT("enter",("host: '%s' user: '%s'",host,user));
...@@ -1298,7 +1299,9 @@ find_acl_user(const char *host, const char *user) ...@@ -1298,7 +1299,9 @@ find_acl_user(const char *host, const char *user)
if (!acl_user->user && !user[0] || if (!acl_user->user && !user[0] ||
acl_user->user && !strcmp(user,acl_user->user)) acl_user->user && !strcmp(user,acl_user->user))
{ {
if (compare_hostname(&acl_user->host,host,host)) if (exact ? !my_strcasecmp(&my_charset_latin1, host,
acl_user->host.hostname) :
compare_hostname(&acl_user->host,host,host))
{ {
DBUG_RETURN(acl_user); DBUG_RETURN(acl_user);
} }
...@@ -1689,7 +1692,7 @@ static int replace_db_table(TABLE *table, const char *db, ...@@ -1689,7 +1692,7 @@ static int replace_db_table(TABLE *table, const char *db,
} }
/* Check if there is such a user in user table in memory? */ /* Check if there is such a user in user table in memory? */
if (!find_acl_user(combo.host.str,combo.user.str)) if (!find_acl_user(combo.host.str,combo.user.str, FALSE))
{ {
my_error(ER_PASSWORD_NO_MATCH,MYF(0)); my_error(ER_PASSWORD_NO_MATCH,MYF(0));
DBUG_RETURN(-1); DBUG_RETURN(-1);
...@@ -2151,7 +2154,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, ...@@ -2151,7 +2154,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
The following should always succeed as new users are created before The following should always succeed as new users are created before
this function is called! this function is called!
*/ */
if (!find_acl_user(combo.host.str,combo.user.str)) if (!find_acl_user(combo.host.str,combo.user.str, FALSE))
{ {
my_error(ER_PASSWORD_NO_MATCH,MYF(0)); /* purecov: deadcode */ my_error(ER_PASSWORD_NO_MATCH,MYF(0)); /* purecov: deadcode */
DBUG_RETURN(-1); /* purecov: deadcode */ DBUG_RETURN(-1); /* purecov: deadcode */
...@@ -3448,7 +3451,7 @@ void get_privilege_desc(char *to, uint max_length, ulong access) ...@@ -3448,7 +3451,7 @@ void get_privilege_desc(char *to, uint max_length, ulong access)
void get_mqh(const char *user, const char *host, USER_CONN *uc) void get_mqh(const char *user, const char *host, USER_CONN *uc)
{ {
ACL_USER *acl_user; ACL_USER *acl_user;
if (initialized && (acl_user= find_acl_user(host,user))) if (initialized && (acl_user= find_acl_user(host,user, FALSE)))
uc->user_resources= acl_user->user_resource; uc->user_resources= acl_user->user_resource;
else else
bzero((char*) &uc->user_resources, sizeof(uc->user_resources)); bzero((char*) &uc->user_resources, sizeof(uc->user_resources));
......
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