Commit 4342dfab 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 18242cfc
...@@ -194,3 +194,20 @@ use test; ...@@ -194,3 +194,20 @@ use test;
drop database sptest; drop database sptest;
delete from mysql.user where user='usera' or user='userb' or user='userc'; 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'; 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; ...@@ -304,3 +304,39 @@ drop database sptest;
delete from mysql.user where user='usera' or user='userb' or user='userc'; 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'; 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) ...@@ -4807,42 +4807,37 @@ Item_func_sp::execute(Item **itp)
DBUG_ENTER("Item_func_sp::execute"); DBUG_ENTER("Item_func_sp::execute");
THD *thd= current_thd; THD *thd= current_thd;
ulong old_client_capabilites; ulong old_client_capabilites;
int res; int res= -1;
bool save_in_sub_stmt= thd->transaction.in_sub_stmt; bool save_in_sub_stmt= thd->transaction.in_sub_stmt;
my_bool nsok;
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
st_sp_security_context save_ctx; st_sp_security_context save_ctx;
#endif #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);
{ goto error;
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str);
DBUG_RETURN(-1);
}
} }
old_client_capabilites= thd->client_capabilities; old_client_capabilites= thd->client_capabilities;
thd->client_capabilities &= ~CLIENT_MULTI_RESULTS; thd->client_capabilities &= ~CLIENT_MULTI_RESULTS;
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
my_bool nsok= thd->net.no_send_ok; nsok= thd->net.no_send_ok;
thd->net.no_send_ok= TRUE; thd->net.no_send_ok= TRUE;
#endif #endif
res= -1;
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_routine_access(thd, EXECUTE_ACL, if (check_routine_access(thd, EXECUTE_ACL,
m_sp->m_db.str, m_sp->m_name.str, 0, 0)) 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); sp_change_security_context(thd, m_sp, &save_ctx);
if (save_ctx.changed && if (save_ctx.changed &&
check_routine_access(thd, EXECUTE_ACL, check_routine_access(thd, EXECUTE_ACL,
m_sp->m_db.str, m_sp->m_name.str, 0, 0)) m_sp->m_db.str, m_sp->m_name.str, 0, 0))
{ goto error_check;
sp_restore_security_context(thd, m_sp, &save_ctx);
thd->client_capabilities|= old_client_capabilites & CLIENT_MULTI_RESULTS;
DBUG_RETURN(-1);
}
#endif #endif
/* /*
Like for SPs, we don't binlog the substatements. If the statement which Like for SPs, we don't binlog the substatements. If the statement which
...@@ -4850,6 +4845,7 @@ Item_func_sp::execute(Item **itp) ...@@ -4850,6 +4845,7 @@ Item_func_sp::execute(Item **itp)
it's not (e.g. SELECT myfunc()) it won't be binlogged (documented known it's not (e.g. SELECT myfunc()) it won't be binlogged (documented known
problem). problem).
*/ */
tmp_disable_binlog(thd); /* don't binlog the substatements */ tmp_disable_binlog(thd); /* don't binlog the substatements */
thd->transaction.in_sub_stmt= TRUE; thd->transaction.in_sub_stmt= TRUE;
...@@ -4864,16 +4860,21 @@ Item_func_sp::execute(Item **itp) ...@@ -4864,16 +4860,21 @@ Item_func_sp::execute(Item **itp)
ER_FAILED_ROUTINE_BREAK_BINLOG, ER_FAILED_ROUTINE_BREAK_BINLOG,
ER(ER_FAILED_ROUTINE_BREAK_BINLOG)); ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
error_check_ctx:
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
sp_restore_security_context(thd, m_sp, &save_ctx); sp_restore_security_context(thd, m_sp, &save_ctx);
#endif #endif
thd->client_capabilities|= old_client_capabilites & CLIENT_MULTI_RESULTS;
error_check:
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
thd->net.no_send_ok= nsok; thd->net.no_send_ok= nsok;
#endif #endif
thd->client_capabilities|= old_client_capabilites & CLIENT_MULTI_RESULTS; thd->client_capabilities|= old_client_capabilites & CLIENT_MULTI_RESULTS;
error:
DBUG_RETURN(res); DBUG_RETURN(res);
} }
......
...@@ -294,7 +294,12 @@ send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message) ...@@ -294,7 +294,12 @@ send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message)
DBUG_ENTER("send_ok"); DBUG_ENTER("send_ok");
if (net->no_send_ok || !net->vio) // hack for re-parsing queries 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; DBUG_VOID_RETURN;
}
buff[0]=0; // No fields buff[0]=0; // No fields
pos=net_store_length(buff+1,(ulonglong) affected_rows); pos=net_store_length(buff+1,(ulonglong) affected_rows);
......
...@@ -1433,10 +1433,10 @@ class THD :public ilink, ...@@ -1433,10 +1433,10 @@ class THD :public ilink,
}; };
#define tmp_disable_binlog(A) \ #define tmp_disable_binlog(A) \
ulong save_options= (A)->options; \ {ulong tmp_disable_binlog__save_options= (A)->options; \
(A)->options&= ~OPTION_BIN_LOG; (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 */ /* Flags for the THD::system_thread (bitmap) variable */
#define SYSTEM_THREAD_DELAYED_INSERT 1 #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