Commit 2d6d8e2a authored by malff/marcsql@weblab.(none)'s avatar malff/marcsql@weblab.(none)

Merge weblab.(none):/home/marcsql/TREE/mysql-5.1-base

into  weblab.(none):/home/marcsql/TREE/mysql-5.1-rt-merge
parents fc610365 d40de441
...@@ -830,11 +830,15 @@ static int get_options(int *argc, char ***argv) ...@@ -830,11 +830,15 @@ static int get_options(int *argc, char ***argv)
(hash_get_key) get_table_key, (hash_get_key) get_table_key,
(hash_free_key) free_table_ent, 0)) (hash_free_key) free_table_ent, 0))
return(EX_EOM); return(EX_EOM);
/* Don't copy cluster internal log tables */ /* Don't copy internal log tables */
if (my_hash_insert(&ignore_table, if (my_hash_insert(&ignore_table,
(byte*) my_strdup("mysql.apply_status", MYF(MY_WME))) || (byte*) my_strdup("mysql.apply_status", MYF(MY_WME))) ||
my_hash_insert(&ignore_table, my_hash_insert(&ignore_table,
(byte*) my_strdup("mysql.schema", MYF(MY_WME)))) (byte*) my_strdup("mysql.schema", MYF(MY_WME))) ||
my_hash_insert(&ignore_table,
(byte*) my_strdup("mysql.general_log", MYF(MY_WME))) ||
my_hash_insert(&ignore_table,
(byte*) my_strdup("mysql.slow_log", MYF(MY_WME))))
return(EX_EOM); return(EX_EOM);
if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option))) if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option)))
...@@ -3354,8 +3358,12 @@ static int dump_all_tables_in_db(char *database) ...@@ -3354,8 +3358,12 @@ static int dump_all_tables_in_db(char *database)
init_dynamic_string_checked(&query, "LOCK TABLES ", 256, 1024); init_dynamic_string_checked(&query, "LOCK TABLES ", 256, 1024);
for (numrows= 0 ; (table= getTableName(1)) ; numrows++) for (numrows= 0 ; (table= getTableName(1)) ; numrows++)
{ {
dynstr_append_checked(&query, quote_name(table, table_buff, 1)); char *end= strmov(afterdot, table);
dynstr_append_checked(&query, " READ /*!32311 LOCAL */,"); if (include_table(hash_key,end - hash_key))
{
dynstr_append_checked(&query, quote_name(table, table_buff, 1));
dynstr_append_checked(&query, " READ /*!32311 LOCAL */,");
}
} }
if (numrows && mysql_real_query(mysql, query.str, query.length-1)) if (numrows && mysql_real_query(mysql, query.str, query.length-1))
DB_error(mysql, "when using LOCK TABLES"); DB_error(mysql, "when using LOCK TABLES");
......
...@@ -34,7 +34,6 @@ id c ts ...@@ -34,7 +34,6 @@ id c ts
affected rows: 2 affected rows: 2
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce'; SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce';
db name status originator db name status originator
test justonce SLAVESIDE_DISABLED 1
DROP EVENT IF EXISTS test.slave_once; DROP EVENT IF EXISTS test.slave_once;
CREATE EVENT test.slave_once ON SCHEDULE EVERY 5 MINUTE DO CREATE EVENT test.slave_once ON SCHEDULE EVERY 5 MINUTE DO
INSERT INTO t1(c) VALUES ('from slave_once'); INSERT INTO t1(c) VALUES ('from slave_once');
...@@ -111,7 +110,6 @@ id c ts ...@@ -111,7 +110,6 @@ id c ts
affected rows: 2 affected rows: 2
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce'; SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce';
db name status originator db name status originator
test justonce SLAVESIDE_DISABLED 1
DROP EVENT IF EXISTS test.slave_once; DROP EVENT IF EXISTS test.slave_once;
CREATE EVENT test.slave_once ON SCHEDULE EVERY 5 MINUTE DO CREATE EVENT test.slave_once ON SCHEDULE EVERY 5 MINUTE DO
INSERT INTO t1(c) VALUES ('from slave_once'); INSERT INTO t1(c) VALUES ('from slave_once');
......
...@@ -6061,21 +6061,6 @@ SUM(f2) bug25373(f1) ...@@ -6061,21 +6061,6 @@ SUM(f2) bug25373(f1)
21.300000071526 NULL 21.300000071526 NULL
DROP FUNCTION bug25373| DROP FUNCTION bug25373|
DROP TABLE t3| DROP TABLE t3|
DROP DATABASE IF EXISTS mysqltest1|
DROP DATABASE IF EXISTS mysqltest2|
CREATE DATABASE mysqltest1|
CREATE DATABASE mysqltest2|
CREATE PROCEDURE mysqltest1.p1()
DROP DATABASE mysqltest2|
use mysqltest2|
CALL mysqltest1.p1()|
Warnings:
Note 1049 Unknown database 'mysqltest2'
SELECT DATABASE()|
DATABASE()
NULL
DROP DATABASE mysqltest1|
use test|
drop function if exists bug20777| drop function if exists bug20777|
drop table if exists examplebug20777| drop table if exists examplebug20777|
create function bug20777(f1 bigint unsigned) returns bigint unsigned create function bug20777(f1 bigint unsigned) returns bigint unsigned
...@@ -6160,30 +6145,55 @@ select bug20777(18446744073709551613)+1; ...@@ -6160,30 +6145,55 @@ select bug20777(18446744073709551613)+1;
bug20777(18446744073709551613)+1 bug20777(18446744073709551613)+1
18446744073709551614 18446744073709551614
drop function bug20777; drop function bug20777;
DROP FUNCTION IF EXISTS bug5274_f1|
DROP FUNCTION IF EXISTS bug5274_f2|
CREATE FUNCTION bug5274_f1(p1 CHAR) RETURNS CHAR
RETURN CONCAT(p1, p1)|
CREATE FUNCTION bug5274_f2() RETURNS CHAR
BEGIN
DECLARE v1 INT DEFAULT 0;
DECLARE v2 CHAR DEFAULT 'x';
WHILE v1 < 30 DO
SET v1 = v1 + 1;
SET v2 = bug5274_f1(v2);
END WHILE;
RETURN v2;
END|
SELECT bug5274_f2()|
bug5274_f2()
x
Warnings:
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
Warning 1265 Data truncated for column 'bug5274_f1' at row 1
DROP FUNCTION bug5274_f1|
DROP FUNCTION bug5274_f2|
End of 5.0 tests. End of 5.0 tests.
drop table t1,t2; drop table t1,t2;
CREATE TABLE t1 (a int auto_increment primary key) engine=MyISAM;
CREATE TABLE t2 (a int auto_increment primary key, b int) engine=innodb;
set @a=0;
CREATE function bug27354() RETURNS int deterministic
begin
insert into t1 values (null);
set @a=@a+1;
return @a;
end|
update t2 set b=1 where a=bug27354();
select count(t_1.a),count(t_2.a) from t1 as t_1, t2 as t_2 /* must be 0,0 */;
count(t_1.a) count(t_2.a)
0 0
insert into t2 values (1,1),(2,2),(3,3);
update t2 set b=-b where a=bug27354();
select * from t2 /* must return 1,-1 ... */;
a b
1 -1
2 -2
3 -3
select count(*) from t1 /* must be 3 */;
count(*)
3
drop table t1,t2;
drop function bug27354;
...@@ -1612,6 +1612,13 @@ drop view v1; ...@@ -1612,6 +1612,13 @@ drop view v1;
drop table t1; drop table t1;
drop database mysqldump_test_db; drop database mysqldump_test_db;
#
# BUG#26121 mysqldump includes LOCK TABLES general_log WRITE
#
--exec $MYSQL_DUMP --all-databases > $MYSQLTEST_VARDIR/tmp/bug26121.sql
--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug26121.sql
--remove_file $MYSQLTEST_VARDIR/tmp/bug26121.sql
--echo # --echo #
--echo # End of 5.1 tests --echo # End of 5.1 tests
--echo # --echo #
...@@ -7109,6 +7109,44 @@ select bug20777(18446744073709551613)+1; ...@@ -7109,6 +7109,44 @@ select bug20777(18446744073709551613)+1;
drop function bug20777; drop function bug20777;
delimiter |; delimiter |;
#
# BUG#5274: Stored procedure crash if length of CHAR variable too great.
#
# Prepare.
--disable_warnings
DROP FUNCTION IF EXISTS bug5274_f1|
DROP FUNCTION IF EXISTS bug5274_f2|
--enable_warnings
# Test.
CREATE FUNCTION bug5274_f1(p1 CHAR) RETURNS CHAR
RETURN CONCAT(p1, p1)|
CREATE FUNCTION bug5274_f2() RETURNS CHAR
BEGIN
DECLARE v1 INT DEFAULT 0;
DECLARE v2 CHAR DEFAULT 'x';
WHILE v1 < 30 DO
SET v1 = v1 + 1;
SET v2 = bug5274_f1(v2);
END WHILE;
RETURN v2;
END|
SELECT bug5274_f2()|
# Cleanup.
DROP FUNCTION bug5274_f1|
DROP FUNCTION bug5274_f2|
### ###
--echo End of 5.0 tests. --echo End of 5.0 tests.
......
This diff is collapsed.
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#define EVEX_GET_FIELD_FAILED -2 #define EVEX_GET_FIELD_FAILED -2
#define EVEX_COMPILE_ERROR -3
#define EVEX_BAD_PARAMS -5 #define EVEX_BAD_PARAMS -5
#define EVEX_MICROSECOND_UNSUP -6 #define EVEX_MICROSECOND_UNSUP -6
...@@ -169,8 +168,6 @@ public: ...@@ -169,8 +168,6 @@ public:
class Event_job_data : public Event_basic class Event_job_data : public Event_basic
{ {
public: public:
sp_head *sphead;
LEX_STRING body; LEX_STRING body;
LEX_STRING definer_user; LEX_STRING definer_user;
LEX_STRING definer_host; LEX_STRING definer_host;
...@@ -178,19 +175,17 @@ public: ...@@ -178,19 +175,17 @@ public:
ulong sql_mode; ulong sql_mode;
Event_job_data(); Event_job_data();
virtual ~Event_job_data();
virtual int virtual int
load_from_row(THD *thd, TABLE *table); load_from_row(THD *thd, TABLE *table);
int bool
execute(THD *thd, bool drop); execute(THD *thd, bool drop);
int
compile(THD *thd, MEM_ROOT *mem_root);
private: private:
int bool
get_fake_create_event(String *buf); construct_sp_sql(THD *thd, String *sp_sql);
bool
construct_drop_event_sql(THD *thd, String *sp_sql);
Event_job_data(const Event_job_data &); /* Prevent use of these */ Event_job_data(const Event_job_data &); /* Prevent use of these */
void operator=(Event_job_data &); void operator=(Event_job_data &);
......
...@@ -277,8 +277,7 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event) ...@@ -277,8 +277,7 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event)
{ {
/* needs to be first for thread_stack */ /* needs to be first for thread_stack */
char my_stack; char my_stack;
int ret; Event_job_data job_data;
Event_job_data *job_data= NULL;
bool res; bool res;
thd->thread_stack= &my_stack; // remember where our stack is thd->thread_stack= &my_stack; // remember where our stack is
...@@ -291,60 +290,43 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event) ...@@ -291,60 +290,43 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event)
if (res) if (res)
goto end; goto end;
if (!(job_data= new Event_job_data())) if ((res= db_repository->load_named_event(thd, event->dbname, event->name,
goto end; &job_data)))
else if ((ret= db_repository->
load_named_event(thd, event->dbname, event->name, job_data)))
{ {
DBUG_PRINT("error", ("Got %d from load_named_event", ret)); DBUG_PRINT("error", ("Got error from load_named_event"));
goto end; goto end;
} }
sql_print_information("Event Scheduler: " sql_print_information("Event Scheduler: "
"[%s.%s of %s] executing in thread %lu. ", "[%s].[%s.%s] started in thread %lu.",
job_data->dbname.str, job_data->name.str, job_data.definer.str,
job_data->definer.str, thd->thread_id); job_data.dbname.str, job_data.name.str,
thd->thread_id);
thd->enable_slow_log= TRUE; thd->enable_slow_log= TRUE;
ret= job_data->execute(thd, event->dropped); res= job_data.execute(thd, event->dropped);
print_warnings(thd, job_data); print_warnings(thd, &job_data);
switch (ret) { if (res)
case 0: sql_print_information("Event Scheduler: "
"[%s].[%s.%s] event execution failed.",
job_data.definer.str,
job_data.dbname.str, job_data.name.str);
else
sql_print_information("Event Scheduler: " sql_print_information("Event Scheduler: "
"[%s].[%s.%s] executed successfully in thread %lu.", "[%s].[%s.%s] executed successfully in thread %lu.",
job_data->definer.str, job_data.definer.str,
job_data->dbname.str, job_data->name.str, job_data.dbname.str, job_data.name.str,
thd->thread_id); thd->thread_id);
break;
case EVEX_COMPILE_ERROR:
sql_print_information("Event Scheduler: "
"[%s].[%s.%s] event compilation failed.",
job_data->definer.str,
job_data->dbname.str, job_data->name.str);
break;
default:
sql_print_information("Event Scheduler: "
"[%s].[%s.%s] event execution failed.",
job_data->definer.str,
job_data->dbname.str, job_data->name.str);
break;
}
end: end:
delete job_data;
DBUG_PRINT("info", ("Done with Event %s.%s", event->dbname.str, DBUG_PRINT("info", ("Done with Event %s.%s", event->dbname.str,
event->name.str)); event->name.str));
delete event; delete event;
deinit_event_thread(thd); deinit_event_thread(thd);
/*
Do not pthread_exit since we want local destructors for stack objects
to be invoked.
*/
} }
......
...@@ -424,7 +424,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, ...@@ -424,7 +424,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data,
if (event_queue) if (event_queue)
event_queue->create_event(thd, new_element, &created); event_queue->create_event(thd, new_element, &created);
/* Binlog the create event. */ /* Binlog the create event. */
if (mysql_bin_log.is_open() && (thd->query_length > 0)) DBUG_ASSERT(thd->query && thd->query_length);
if (mysql_bin_log.is_open())
{ {
thd->clear_error(); thd->clear_error();
thd->binlog_query(THD::MYSQL_QUERY_TYPE, thd->binlog_query(THD::MYSQL_QUERY_TYPE,
...@@ -549,7 +550,8 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, ...@@ -549,7 +550,8 @@ Events::update_event(THD *thd, Event_parse_data *parse_data,
event_queue->update_event(thd, parse_data->dbname, parse_data->name, event_queue->update_event(thd, parse_data->dbname, parse_data->name,
new_element); new_element);
/* Binlog the alter event. */ /* Binlog the alter event. */
if (mysql_bin_log.is_open() && (thd->query_length > 0)) DBUG_ASSERT(thd->query && thd->query_length);
if (mysql_bin_log.is_open())
{ {
thd->clear_error(); thd->clear_error();
thd->binlog_query(THD::MYSQL_QUERY_TYPE, thd->binlog_query(THD::MYSQL_QUERY_TYPE,
...@@ -628,7 +630,8 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) ...@@ -628,7 +630,8 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists)
if (event_queue) if (event_queue)
event_queue->drop_event(thd, dbname, name); event_queue->drop_event(thd, dbname, name);
/* Binlog the drop event. */ /* Binlog the drop event. */
if (mysql_bin_log.is_open() && (thd->query_length > 0)) DBUG_ASSERT(thd->query && thd->query_length);
if (mysql_bin_log.is_open())
{ {
thd->clear_error(); thd->clear_error();
thd->binlog_query(THD::MYSQL_QUERY_TYPE, thd->binlog_query(THD::MYSQL_QUERY_TYPE,
......
...@@ -5352,7 +5352,7 @@ Item_func_sp::fix_fields(THD *thd, Item **ref) ...@@ -5352,7 +5352,7 @@ Item_func_sp::fix_fields(THD *thd, Item **ref)
Security_context *save_secutiry_ctx; Security_context *save_secutiry_ctx;
res= set_routine_security_ctx(thd, m_sp, false, &save_secutiry_ctx); res= set_routine_security_ctx(thd, m_sp, false, &save_secutiry_ctx);
if (!res) if (!res)
sp_restore_security_context(thd, save_secutiry_ctx); m_sp->m_security_ctx.restore_security_context(thd, save_secutiry_ctx);
#endif /* ! NO_EMBEDDED_ACCESS_CHECKS */ #endif /* ! NO_EMBEDDED_ACCESS_CHECKS */
} }
......
...@@ -1245,7 +1245,11 @@ set_routine_security_ctx(THD *thd, sp_head *sp, bool is_proc, ...@@ -1245,7 +1245,11 @@ set_routine_security_ctx(THD *thd, sp_head *sp, bool is_proc,
Security_context **save_ctx) Security_context **save_ctx)
{ {
*save_ctx= 0; *save_ctx= 0;
if (sp_change_security_context(thd, sp, save_ctx)) if (sp->m_chistics->suid != SP_IS_NOT_SUID &&
sp->m_security_ctx.change_security_context(thd, &sp->m_definer_user,
&sp->m_definer_host,
&sp->m_db,
save_ctx))
return TRUE; return TRUE;
/* /*
...@@ -1262,7 +1266,7 @@ set_routine_security_ctx(THD *thd, sp_head *sp, bool is_proc, ...@@ -1262,7 +1266,7 @@ set_routine_security_ctx(THD *thd, sp_head *sp, bool is_proc,
check_routine_access(thd, EXECUTE_ACL, check_routine_access(thd, EXECUTE_ACL,
sp->m_db.str, sp->m_name.str, is_proc, FALSE)) sp->m_db.str, sp->m_name.str, is_proc, FALSE))
{ {
sp_restore_security_context(thd, *save_ctx); sp->m_security_ctx.restore_security_context(thd, *save_ctx);
*save_ctx= 0; *save_ctx= 0;
return TRUE; return TRUE;
} }
...@@ -1573,7 +1577,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, ...@@ -1573,7 +1577,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
sp_restore_security_context(thd, save_security_ctx); m_security_ctx.restore_security_context(thd, save_security_ctx);
#endif #endif
err_with_cleanup: err_with_cleanup:
...@@ -1791,7 +1795,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) ...@@ -1791,7 +1795,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (save_security_ctx) if (save_security_ctx)
sp_restore_security_context(thd, save_security_ctx); m_security_ctx.restore_security_context(thd, save_security_ctx);
#endif #endif
if (!save_spcont) if (!save_spcont)
...@@ -3431,44 +3435,6 @@ sp_instr_set_case_expr::opt_move(uint dst, List<sp_instr> *bp) ...@@ -3431,44 +3435,6 @@ sp_instr_set_case_expr::opt_move(uint dst, List<sp_instr> *bp)
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/*
Security context swapping
*/
#ifndef NO_EMBEDDED_ACCESS_CHECKS
bool
sp_change_security_context(THD *thd, sp_head *sp, Security_context **backup)
{
*backup= 0;
if (sp->m_chistics->suid != SP_IS_NOT_SUID &&
(strcmp(sp->m_definer_user.str,
thd->security_ctx->priv_user) ||
my_strcasecmp(system_charset_info, sp->m_definer_host.str,
thd->security_ctx->priv_host)))
{
if (acl_getroot_no_password(&sp->m_security_ctx, sp->m_definer_user.str,
sp->m_definer_host.str,
sp->m_definer_host.str,
sp->m_db.str))
{
my_error(ER_NO_SUCH_USER, MYF(0), sp->m_definer_user.str,
sp->m_definer_host.str);
return TRUE;
}
*backup= thd->security_ctx;
thd->security_ctx= &sp->m_security_ctx;
}
return FALSE;
}
void
sp_restore_security_context(THD *thd, Security_context *backup)
{
if (backup)
thd->security_ctx= backup;
}
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
/* /*
Structure that represent all instances of one table Structure that represent all instances of one table
......
...@@ -2125,6 +2125,102 @@ bool Security_context::set_user(char *user_arg) ...@@ -2125,6 +2125,102 @@ bool Security_context::set_user(char *user_arg)
return user == 0; return user == 0;
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/**
Initialize this security context from the passed in credentials
and activate it in the current thread.
@param[out] backup Save a pointer to the current security context
in the thread. In case of success it points to the
saved old context, otherwise it points to NULL.
During execution of a statement, multiple security contexts may
be needed:
- the security context of the authenticated user, used as the
default security context for all top-level statements
- in case of a view or a stored program, possibly the security
context of the definer of the routine, if the object is
defined with SQL SECURITY DEFINER option.
The currently "active" security context is parameterized in THD
member security_ctx. By default, after a connection is
established, this member points at the "main" security context
- the credentials of the authenticated user.
Later, if we would like to execute some sub-statement or a part
of a statement under credentials of a different user, e.g.
definer of a procedure, we authenticate this user in a local
instance of Security_context by means of this method (and
ultimately by means of acl_getroot_no_password), and make the
local instance active in the thread by re-setting
thd->security_ctx pointer.
Note, that the life cycle and memory management of the "main" and
temporary security contexts are different.
For the main security context, the memory for user/host/ip is
allocated on system heap, and the THD class frees this memory in
its destructor. The only case when contents of the main security
context may change during its life time is when someone issued
CHANGE USER command.
Memory management of a "temporary" security context is
responsibility of the module that creates it.
@retval TRUE there is no user with the given credentials. The erro
is reported in the thread.
@retval FALSE success
*/
bool
Security_context::
change_security_context(THD *thd,
LEX_STRING *definer_user,
LEX_STRING *definer_host,
LEX_STRING *db,
Security_context **backup)
{
bool needs_change;
DBUG_ENTER("Security_context::change_security_context");
DBUG_ASSERT(definer_user->str && definer_host->str);
*backup= NULL;
/*
The current security context may have NULL members
if we have just started the thread and not authenticated
any user. This use case is currently in events worker thread.
*/
needs_change= (thd->security_ctx->priv_user == NULL ||
strcmp(definer_user->str, thd->security_ctx->priv_user) ||
thd->security_ctx->priv_host == NULL ||
my_strcasecmp(system_charset_info, definer_host->str,
thd->security_ctx->priv_host));
if (needs_change)
{
if (acl_getroot_no_password(this, definer_user->str, definer_host->str,
definer_host->str, db->str))
{
my_error(ER_NO_SUCH_USER, MYF(0), definer_user->str,
definer_host->str);
DBUG_RETURN(TRUE);
}
*backup= thd->security_ctx;
thd->security_ctx= this;
}
DBUG_RETURN(FALSE);
}
void
Security_context::restore_security_context(THD *thd,
Security_context *backup)
{
if (backup)
thd->security_ctx= backup;
}
#endif
/**************************************************************************** /****************************************************************************
Handling of open and locked tables states. Handling of open and locked tables states.
......
...@@ -658,6 +658,18 @@ public: ...@@ -658,6 +658,18 @@ public:
} }
bool set_user(char *user_arg); bool set_user(char *user_arg);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
bool
change_security_context(THD *thd,
LEX_STRING *definer_user,
LEX_STRING *definer_host,
LEX_STRING *db,
Security_context **backup);
void
restore_security_context(THD *thd, Security_context *backup);
#endif
}; };
......
...@@ -1543,9 +1543,16 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event, ...@@ -1543,9 +1543,16 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event,
old_field= trigger_table->field; old_field= trigger_table->field;
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
Security_context *save_ctx; Security_context *sctx= &sp_trigger->m_security_ctx;
Security_context *save_ctx= NULL;
if (sp_change_security_context(thd, sp_trigger, &save_ctx))
if (sp_trigger->m_chistics->suid != SP_IS_NOT_SUID &&
sctx->change_security_context(thd,
&sp_trigger->m_definer_user,
&sp_trigger->m_definer_host,
&sp_trigger->m_db,
&save_ctx))
return TRUE; return TRUE;
/* /*
...@@ -1570,7 +1577,7 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event, ...@@ -1570,7 +1577,7 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event,
thd->security_ctx->priv_user, thd->security_ctx->host_or_ip, thd->security_ctx->priv_user, thd->security_ctx->host_or_ip,
trigger_table->s->table_name.str); trigger_table->s->table_name.str);
sp_restore_security_context(thd, save_ctx); sctx->restore_security_context(thd, save_ctx);
return TRUE; return TRUE;
} }
#endif // NO_EMBEDDED_ACCESS_CHECKS #endif // NO_EMBEDDED_ACCESS_CHECKS
...@@ -1582,7 +1589,7 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event, ...@@ -1582,7 +1589,7 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event,
thd->restore_sub_statement_state(&statement_state); thd->restore_sub_statement_state(&statement_state);
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
sp_restore_security_context(thd, save_ctx); sctx->restore_security_context(thd, save_ctx);
#endif // NO_EMBEDDED_ACCESS_CHECKS #endif // NO_EMBEDDED_ACCESS_CHECKS
} }
......
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