Commit a5e742fe authored by unknown's avatar unknown

fixed environment restoring in case of error during SP function execution (BUG#9503)

#define macro improvement


mysql-test/r/sp-security.result:
  BUG#9503: reseting correct parameters of thread after error in SP function
mysql-test/t/sp-security.test:
  BUG#9503: reseting correct parameters of thread after error in SP function
sql/item_func.cc:
  fixed environment restoring in case of error during SP function execution
sql/protocol.cc:
  added debug print
sql/sql_class.h:
  fixed #defines to force them to be alvaise in piar, and variable name made more complex for accident repeating in other code
parent 6487eb81
......@@ -194,3 +194,20 @@ use test;
drop database sptest;
delete from mysql.user where user='usera' or user='userb' or user='userc';
delete from mysql.procs_priv where user='usera' or user='userb' or user='userc';
drop function if exists bug_9503;
create database mysqltest//
use mysqltest//
create table t1 (s1 int)//
grant select on t1 to user1@localhost//
create function bug_9503 () returns int sql security invoker begin declare v int;
select min(s1) into v from t1; return v; end//
use mysqltest;
select bug_9503();
ERROR 42000: execute command denied to user 'user1'@'localhost' for routine 'mysqltest.bug_9503'
grant execute on function bug_9503 to user1@localhost;
do 1;
use test;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1@localhost;
drop function bug_9503;
use test;
drop database mysqltest;
......@@ -304,3 +304,39 @@ drop database sptest;
delete from mysql.user where user='usera' or user='userb' or user='userc';
delete from mysql.procs_priv where user='usera' or user='userb' or user='userc';
#
# BUG#9503: reseting correct parameters of thread after error in SP function
#
connect (root,localhost,root,,test);
connection root;
--disable_warnings
drop function if exists bug_9503;
--enable_warnings
delimiter //;
create database mysqltest//
use mysqltest//
create table t1 (s1 int)//
grant select on t1 to user1@localhost//
create function bug_9503 () returns int sql security invoker begin declare v int;
select min(s1) into v from t1; return v; end//
delimiter ;//
connect (user1,localhost,user1,,test);
connection user1;
use mysqltest;
-- error 1370
select bug_9503();
connection root;
grant execute on function bug_9503 to user1@localhost;
connection user1;
do 1;
use test;
connection root;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1@localhost;
drop function bug_9503;
use test;
drop database mysqltest;
......@@ -4807,42 +4807,37 @@ Item_func_sp::execute(Item **itp)
DBUG_ENTER("Item_func_sp::execute");
THD *thd= current_thd;
ulong old_client_capabilites;
int res;
int res= -1;
bool save_in_sub_stmt= thd->transaction.in_sub_stmt;
my_bool nsok;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
st_sp_security_context save_ctx;
#endif
if (! m_sp)
if (! m_sp && ! (m_sp= sp_find_function(thd, m_name, TRUE)))
{
if (!(m_sp= sp_find_function(thd, m_name, TRUE)))
{
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str);
DBUG_RETURN(-1);
}
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str);
goto error;
}
old_client_capabilites= thd->client_capabilities;
thd->client_capabilities &= ~CLIENT_MULTI_RESULTS;
#ifndef EMBEDDED_LIBRARY
my_bool nsok= thd->net.no_send_ok;
nsok= thd->net.no_send_ok;
thd->net.no_send_ok= TRUE;
#endif
res= -1;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_routine_access(thd, EXECUTE_ACL,
m_sp->m_db.str, m_sp->m_name.str, 0, 0))
DBUG_RETURN(-1);
goto error_check;
sp_change_security_context(thd, m_sp, &save_ctx);
if (save_ctx.changed &&
check_routine_access(thd, EXECUTE_ACL,
m_sp->m_db.str, m_sp->m_name.str, 0, 0))
{
sp_restore_security_context(thd, m_sp, &save_ctx);
thd->client_capabilities|= old_client_capabilites & CLIENT_MULTI_RESULTS;
DBUG_RETURN(-1);
}
goto error_check;
#endif
/*
Like for SPs, we don't binlog the substatements. If the statement which
......@@ -4850,6 +4845,7 @@ Item_func_sp::execute(Item **itp)
it's not (e.g. SELECT myfunc()) it won't be binlogged (documented known
problem).
*/
tmp_disable_binlog(thd); /* don't binlog the substatements */
thd->transaction.in_sub_stmt= TRUE;
......@@ -4864,16 +4860,21 @@ Item_func_sp::execute(Item **itp)
ER_FAILED_ROUTINE_BREAK_BINLOG,
ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
error_check_ctx:
#ifndef NO_EMBEDDED_ACCESS_CHECKS
sp_restore_security_context(thd, m_sp, &save_ctx);
#endif
thd->client_capabilities|= old_client_capabilites & CLIENT_MULTI_RESULTS;
error_check:
#ifndef EMBEDDED_LIBRARY
thd->net.no_send_ok= nsok;
#endif
thd->client_capabilities|= old_client_capabilites & CLIENT_MULTI_RESULTS;
error:
DBUG_RETURN(res);
}
......
......@@ -294,7 +294,12 @@ send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message)
DBUG_ENTER("send_ok");
if (net->no_send_ok || !net->vio) // hack for re-parsing queries
{
DBUG_PRINT("info", ("no send ok: %s, vio present: %s",
(net->no_send_ok ? "YES" : "NO"),
(net->vio ? "YES" : "NO")));
DBUG_VOID_RETURN;
}
buff[0]=0; // No fields
pos=net_store_length(buff+1,(ulonglong) affected_rows);
......
......@@ -1433,10 +1433,10 @@ public:
};
#define tmp_disable_binlog(A) \
ulong save_options= (A)->options; \
(A)->options&= ~OPTION_BIN_LOG;
{ulong tmp_disable_binlog__save_options= (A)->options; \
(A)->options&= ~OPTION_BIN_LOG
#define reenable_binlog(A) (A)->options= save_options;
#define reenable_binlog(A) (A)->options= tmp_disable_binlog__save_options;}
/* Flags for the THD::system_thread (bitmap) variable */
#define SYSTEM_THREAD_DELAYED_INSERT 1
......
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