diff options
author | evgen@moonbone.local <> | 2005-09-20 21:36:43 +0400 |
---|---|---|
committer | evgen@moonbone.local <> | 2005-09-20 21:36:43 +0400 |
commit | 6383ab91dbc4206af1aa24cd2f9679d95c812fc9 (patch) | |
tree | 903a191807713d3c51d10dae2b978acc6c7d06ca | |
parent | 388cf622eedda42762afa99ae48fb7b2287ffe18 (diff) | |
parent | b7c42a65d11448f88168388f73f94b5d7a69b638 (diff) | |
download | mariadb-git-6383ab91dbc4206af1aa24cd2f9679d95c812fc9.tar.gz |
Merge epotemkin@bk-internal.mysql.com:/home/bk/mysql-5.0
into moonbone.local:/work/12812-bug-5.0-mysql
-rw-r--r-- | mysql-test/r/sp.result | 12 | ||||
-rw-r--r-- | mysql-test/t/sp.test | 21 | ||||
-rw-r--r-- | sql/item_func.cc | 89 | ||||
-rw-r--r-- | sql/item_func.h | 6 |
4 files changed, 119 insertions, 9 deletions
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index aedaaad9398..82dda16933f 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -3206,6 +3206,18 @@ set f1= concat( 'hello', f1 ); return f1; end| 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| create procedure bug12849_1(inout x char) select x into x| set @var='a'| diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index b6a8eb6518a..afcbd98277a 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -4038,6 +4038,27 @@ end| 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 # 'INOUT' parameter # diff --git a/sql/item_func.cc b/sql/item_func.cc index 518fb011e0f..de221621ac0 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4723,14 +4723,8 @@ Item_func_sp::execute(Item **itp) } #ifndef NO_EMBEDDED_ACCESS_CHECKS - if (check_routine_access(thd, EXECUTE_ACL, - m_sp->m_db.str, m_sp->m_name.str, 0, 0)) + if (check_access(EXECUTE_ACL, 0, &save_ctx)) 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 /* 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)); #ifndef NO_EMBEDDED_ACCESS_CHECKS -error_check_ctx: sp_restore_security_context(thd, m_sp, &save_ctx); #endif @@ -4857,3 +4850,83 @@ Item_func_sp::tmp_table_field(TABLE *t_arg) 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; +} diff --git a/sql/item_func.h b/sql/item_func.h index 019abb0c072..adc1dd1b1be 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -55,7 +55,7 @@ public: NOT_FUNC, NOT_ALL_FUNC, NOW_FUNC, TRIG_COND_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, OPTIMIZE_EQUAL }; enum Type type() const { return FUNC_ITEM; } @@ -1365,6 +1365,7 @@ public: class sp_head; class sp_name; +struct st_sp_security_context; class Item_func_sp :public Item_func { @@ -1434,7 +1435,10 @@ public: { context= (Name_resolution_context *)cntx; return FALSE; } 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); }; |