Commit ba80708f authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-6960 Server crashes in check_alter_user on setting a default role via PS

There were two issues:

* set_var_default_role::user was overwritten with a new value,
  allocated in the thd->mem_root, which is reset between executions.
  That was causing the crash. Solved by introducing set_var_default_role::real_user

* when privilege tables were opened on EXECUTE, the reprepare_observer
  would abort the statement (as privilege tables are opened using
  the local TABLE_LIST that doesn't preserve metadata from PREPARE, so
  reprepare_observer thought they're changed). This issue also applied
  to SET PASSWORD. Solved by disabling reprepare_observer.
parent 7951bb16
create role r1;
prepare stmt from "set password = '11111111111111111111111111111111111111111'";
execute stmt;
prepare stmt from "set default role r1";
execute stmt;
set password = '';
set default role NONE;
drop role r1;
#
# MDEV-6960 Server crashes in check_alter_user on setting a default role via PS
#
--source include/not_embedded.inc
create role r1;
prepare stmt from "set password = '11111111111111111111111111111111111111111'";
execute stmt;
prepare stmt from "set default role r1";
execute stmt;
set password = '';
set default role NONE;
drop role r1;
...@@ -860,7 +860,11 @@ int set_var_password::check(THD *thd) ...@@ -860,7 +860,11 @@ int set_var_password::check(THD *thd)
int set_var_password::update(THD *thd) int set_var_password::update(THD *thd)
{ {
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
return change_password(thd, user); Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer;
thd->m_reprepare_observer= 0;
int res= change_password(thd, user);
thd->m_reprepare_observer= save_reprepare_observer;
return res;
#else #else
return 0; return 0;
#endif #endif
...@@ -896,8 +900,8 @@ int set_var_role::update(THD *thd) ...@@ -896,8 +900,8 @@ int set_var_role::update(THD *thd)
int set_var_default_role::check(THD *thd) int set_var_default_role::check(THD *thd)
{ {
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
user= get_current_user(thd, user); real_user= get_current_user(thd, user);
int status= acl_check_set_default_role(thd, user->host.str, user->user.str); int status= acl_check_set_default_role(thd, real_user->host.str, real_user->user.str);
return status; return status;
#else #else
return 0; return 0;
...@@ -907,7 +911,11 @@ int set_var_default_role::check(THD *thd) ...@@ -907,7 +911,11 @@ int set_var_default_role::check(THD *thd)
int set_var_default_role::update(THD *thd) int set_var_default_role::update(THD *thd)
{ {
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
return acl_set_default_role(thd, user->host.str, user->user.str, role.str); Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer;
thd->m_reprepare_observer= 0;
int res= acl_set_default_role(thd, real_user->host.str, real_user->user.str, role.str);
thd->m_reprepare_observer= save_reprepare_observer;
return res;
#else #else
return 0; return 0;
#endif #endif
......
...@@ -344,7 +344,7 @@ public: ...@@ -344,7 +344,7 @@ public:
class set_var_default_role: public set_var_base class set_var_default_role: public set_var_base
{ {
LEX_USER *user; LEX_USER *user, *real_user;
LEX_STRING role; LEX_STRING role;
public: public:
set_var_default_role(LEX_USER *user_arg, LEX_STRING role_arg) : set_var_default_role(LEX_USER *user_arg, LEX_STRING role_arg) :
......
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