Loading mysql-test/r/sp-security.result +17 −0 Original line number Diff line number Diff line Loading @@ -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; mysql-test/t/sp-security.test +36 −0 Original line number Diff line number Diff line Loading @@ -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; sql/item_func.cc +15 −14 Original line number Diff line number Diff line Loading @@ -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= sp_find_function(thd, m_name, TRUE))) if (! m_sp && ! (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); } 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 Loading @@ -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; Loading @@ -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); } Loading sql/protocol.cc +5 −0 Original line number Diff line number Diff line Loading @@ -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); Loading sql/sql_class.h +3 −3 Original line number Diff line number Diff line Loading @@ -1420,10 +1420,10 @@ class THD :public ilink, }; #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 Loading Loading
mysql-test/r/sp-security.result +17 −0 Original line number Diff line number Diff line Loading @@ -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;
mysql-test/t/sp-security.test +36 −0 Original line number Diff line number Diff line Loading @@ -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;
sql/item_func.cc +15 −14 Original line number Diff line number Diff line Loading @@ -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= sp_find_function(thd, m_name, TRUE))) if (! m_sp && ! (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); } 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 Loading @@ -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; Loading @@ -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); } Loading
sql/protocol.cc +5 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
sql/sql_class.h +3 −3 Original line number Diff line number Diff line Loading @@ -1420,10 +1420,10 @@ class THD :public ilink, }; #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 Loading