mirror of
https://github.com/MariaDB/server.git
synced 2025-08-05 13:16:09 +03:00
Merge epotemkin@bk-internal.mysql.com:/home/bk/mysql-5.0
into moonbone.local:/work/12812-bug-5.0-mysql
This commit is contained in:
@@ -3206,6 +3206,18 @@ set f1= concat( 'hello', f1 );
|
|||||||
return f1;
|
return f1;
|
||||||
end|
|
end|
|
||||||
drop function bug9048|
|
drop function bug9048|
|
||||||
|
drop function if exists bug12812|
|
||||||
|
create function bug12812() returns char(2)
|
||||||
|
begin
|
||||||
|
return 'ok';
|
||||||
|
end;
|
||||||
|
create user user_bug12812@localhost IDENTIFIED BY 'ABC'|
|
||||||
|
SELECT test.bug12812()|
|
||||||
|
ERROR 42000: execute command denied to user 'user_bug12812'@'localhost' for routine 'test.bug12812'
|
||||||
|
CREATE VIEW v1 AS SELECT test.bug12812()|
|
||||||
|
ERROR 42000: execute command denied to user 'user_bug12812'@'localhost' for routine 'test.bug12812'
|
||||||
|
DROP USER user_bug12812@localhost|
|
||||||
|
drop function bug12812|
|
||||||
drop procedure if exists bug12849_1|
|
drop procedure if exists bug12849_1|
|
||||||
create procedure bug12849_1(inout x char) select x into x|
|
create procedure bug12849_1(inout x char) select x into x|
|
||||||
set @var='a'|
|
set @var='a'|
|
||||||
|
@@ -4038,6 +4038,27 @@ end|
|
|||||||
drop function bug9048|
|
drop function bug9048|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
# BUG#12812 create view calling a function works without execute right
|
||||||
|
# on function
|
||||||
|
--disable_warnings
|
||||||
|
drop function if exists bug12812|
|
||||||
|
--enable_warnings
|
||||||
|
create function bug12812() returns char(2)
|
||||||
|
begin
|
||||||
|
return 'ok';
|
||||||
|
end;
|
||||||
|
create user user_bug12812@localhost IDENTIFIED BY 'ABC'|
|
||||||
|
--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
|
||||||
|
connect (test_user_12812,localhost,user_bug12812,ABC,test)|
|
||||||
|
--error 1370
|
||||||
|
SELECT test.bug12812()|
|
||||||
|
--error 1370
|
||||||
|
CREATE VIEW v1 AS SELECT test.bug12812()|
|
||||||
|
# Cleanup
|
||||||
|
connection default|
|
||||||
|
disconnect test_user_12812|
|
||||||
|
DROP USER user_bug12812@localhost|
|
||||||
|
drop function bug12812|
|
||||||
# Bug #12849 Stored Procedure: Crash on procedure call with CHAR type
|
# Bug #12849 Stored Procedure: Crash on procedure call with CHAR type
|
||||||
# 'INOUT' parameter
|
# 'INOUT' parameter
|
||||||
#
|
#
|
||||||
|
@@ -4723,14 +4723,8 @@ Item_func_sp::execute(Item **itp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
if (check_routine_access(thd, EXECUTE_ACL,
|
if (check_access(EXECUTE_ACL, 0, &save_ctx))
|
||||||
m_sp->m_db.str, m_sp->m_name.str, 0, 0))
|
|
||||||
goto error;
|
goto error;
|
||||||
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))
|
|
||||||
goto error_check_ctx;
|
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
Disable the binlogging if this is not a SELECT statement. If this is a
|
Disable the binlogging if this is not a SELECT statement. If this is a
|
||||||
@@ -4749,7 +4743,6 @@ Item_func_sp::execute(Item **itp)
|
|||||||
ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
|
ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
|
||||||
|
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
error_check_ctx:
|
|
||||||
sp_restore_security_context(thd, m_sp, &save_ctx);
|
sp_restore_security_context(thd, m_sp, &save_ctx);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -4857,3 +4850,83 @@ Item_func_sp::tmp_table_field(TABLE *t_arg)
|
|||||||
|
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check access rigths to function
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
check_access()
|
||||||
|
want_access requested access
|
||||||
|
report_error whether to set error to thd->net.report_error
|
||||||
|
sp_ctx sp security context for switching
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 Access granted
|
||||||
|
1 Requested access can't be granted or function doesn't exists
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
Checks if requested access to function can be granted to user.
|
||||||
|
If function isn't found yet, it searches function first.
|
||||||
|
If function can't be found or user don't have requested access
|
||||||
|
and report_error is true error is raised.
|
||||||
|
If security context sp_ctx is provided and access can be granted then
|
||||||
|
switch back to previous context isn't performed.
|
||||||
|
In case of access error or if context is not provided then check_access()
|
||||||
|
switches back to previous security context.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
Item_func_sp::check_access(ulong want_access, bool report_error, st_sp_security_context *sp_ctx)
|
||||||
|
{
|
||||||
|
bool res;
|
||||||
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
|
THD *thd= current_thd;
|
||||||
|
st_sp_security_context save_ctx, *curr_ctx= sp_ctx?sp_ctx:&save_ctx;
|
||||||
|
bool ctx_switched= 0;
|
||||||
|
res= 1;
|
||||||
|
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);
|
||||||
|
if (report_error)
|
||||||
|
thd->net.report_error= 1;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_routine_access(thd, want_access,
|
||||||
|
m_sp->m_db.str, m_sp->m_name.str, 0, 0))
|
||||||
|
{
|
||||||
|
if (report_error)
|
||||||
|
thd->net.report_error= 1;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp_change_security_context(thd, m_sp, curr_ctx);
|
||||||
|
ctx_switched= curr_ctx->changed;
|
||||||
|
if (curr_ctx->changed &&
|
||||||
|
check_routine_access(thd, want_access,
|
||||||
|
m_sp->m_db.str, m_sp->m_name.str, 0, 0))
|
||||||
|
{
|
||||||
|
if (report_error)
|
||||||
|
thd->net.report_error= 1;
|
||||||
|
goto error_check_ctx;
|
||||||
|
}
|
||||||
|
res= 0;
|
||||||
|
error_check_ctx:
|
||||||
|
if (ctx_switched && (res || !sp_ctx))
|
||||||
|
sp_restore_security_context(thd, m_sp, curr_ctx);
|
||||||
|
error:
|
||||||
|
#else
|
||||||
|
res= 0;
|
||||||
|
#endif
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool
|
||||||
|
Item_func_sp::fix_fields(THD *thd, Item **ref)
|
||||||
|
{
|
||||||
|
bool res;
|
||||||
|
DBUG_ASSERT(fixed == 0);
|
||||||
|
res= Item_func::fix_fields(thd, ref);
|
||||||
|
if (!res && check_access(EXECUTE_ACL, 1, NULL))
|
||||||
|
res= 1;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
@@ -55,7 +55,7 @@ public:
|
|||||||
NOT_FUNC, NOT_ALL_FUNC,
|
NOT_FUNC, NOT_ALL_FUNC,
|
||||||
NOW_FUNC, TRIG_COND_FUNC,
|
NOW_FUNC, TRIG_COND_FUNC,
|
||||||
GUSERVAR_FUNC, COLLATE_FUNC,
|
GUSERVAR_FUNC, COLLATE_FUNC,
|
||||||
EXTRACT_FUNC, CHAR_TYPECAST_FUNC };
|
EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP };
|
||||||
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
|
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
|
||||||
OPTIMIZE_EQUAL };
|
OPTIMIZE_EQUAL };
|
||||||
enum Type type() const { return FUNC_ITEM; }
|
enum Type type() const { return FUNC_ITEM; }
|
||||||
@@ -1365,6 +1365,7 @@ public:
|
|||||||
|
|
||||||
class sp_head;
|
class sp_head;
|
||||||
class sp_name;
|
class sp_name;
|
||||||
|
struct st_sp_security_context;
|
||||||
|
|
||||||
class Item_func_sp :public Item_func
|
class Item_func_sp :public Item_func
|
||||||
{
|
{
|
||||||
@@ -1434,7 +1435,10 @@ public:
|
|||||||
{ context= (Name_resolution_context *)cntx; return FALSE; }
|
{ context= (Name_resolution_context *)cntx; return FALSE; }
|
||||||
|
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
|
bool check_access(ulong want_access, bool report_error, st_sp_security_context *sp_ctx);
|
||||||
|
virtual enum Functype functype() const { return FUNC_SP; }
|
||||||
|
|
||||||
|
bool fix_fields(THD *thd, Item **ref);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user