mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge mysql.com:/home/mysql_src/mysql-5.0
into mysql.com:/home/mysql_src/mysql-5.1-merge-of-5.0 (not all files are good, I'll fix; I'll ask some devs to check their part)
This commit is contained in:
155
sql/sql_parse.cc
155
sql/sql_parse.cc
@ -188,6 +188,18 @@ inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
|
||||
#endif
|
||||
|
||||
|
||||
static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
|
||||
{
|
||||
for (TABLE_LIST *table= tables; table; table= table->next_global)
|
||||
{
|
||||
DBUG_ASSERT(table->db && table->table_name);
|
||||
if (table->updating &&
|
||||
!find_temporary_table(thd, table->db, table->table_name))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static HASH hash_user_connections;
|
||||
|
||||
static int get_or_create_user_conn(THD *thd, const char *user,
|
||||
@ -2360,7 +2372,7 @@ mysql_execute_command(THD *thd)
|
||||
mysql_reset_errors(thd, 0);
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
if (thd->slave_thread)
|
||||
if (unlikely(thd->slave_thread))
|
||||
{
|
||||
/*
|
||||
Check if statment should be skipped because of slave filtering
|
||||
@ -2399,16 +2411,20 @@ mysql_execute_command(THD *thd)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
#endif /* HAVE_REPLICATION */
|
||||
|
||||
/*
|
||||
When option readonly is set deny operations which change tables.
|
||||
Except for the replication thread and the 'super' users.
|
||||
When option readonly is set deny operations which change non-temporary
|
||||
tables. Except for the replication thread and the 'super' users.
|
||||
*/
|
||||
if (opt_readonly &&
|
||||
!(thd->slave_thread ||
|
||||
(thd->security_ctx->master_access & SUPER_ACL)) &&
|
||||
uc_update_queries[lex->sql_command])
|
||||
!(thd->security_ctx->master_access & SUPER_ACL) &&
|
||||
uc_update_queries[lex->sql_command] &&
|
||||
!((lex->sql_command == SQLCOM_CREATE_TABLE) &&
|
||||
(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) &&
|
||||
((lex->sql_command != SQLCOM_UPDATE_MULTI) &&
|
||||
some_non_temp_table_to_be_updated(thd, all_tables)))
|
||||
{
|
||||
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
|
||||
DBUG_RETURN(-1);
|
||||
@ -3198,13 +3214,24 @@ end_with_restore_list:
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
/* Check slave filtering rules */
|
||||
if (thd->slave_thread && all_tables_not_ok(thd, all_tables))
|
||||
if (unlikely(thd->slave_thread))
|
||||
{
|
||||
/* we warn the slave SQL thread */
|
||||
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
|
||||
if (all_tables_not_ok(thd, all_tables))
|
||||
{
|
||||
/* we warn the slave SQL thread */
|
||||
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* HAVE_REPLICATION */
|
||||
if (opt_readonly &&
|
||||
!(thd->security_ctx->master_access & SUPER_ACL) &&
|
||||
some_non_temp_table_to_be_updated(thd, all_tables))
|
||||
{
|
||||
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
|
||||
break;
|
||||
}
|
||||
#endif /* HAVE_REPLICATION */
|
||||
|
||||
res= mysql_multi_update(thd, all_tables,
|
||||
&select_lex->item_list,
|
||||
@ -4061,7 +4088,7 @@ end_with_restore_list:
|
||||
|
||||
if (!lex->sphead->m_db.str || !lex->sphead->m_db.str[0])
|
||||
{
|
||||
if (! thd->db)
|
||||
if (!thd->db)
|
||||
{
|
||||
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
|
||||
delete lex->sphead;
|
||||
@ -4280,18 +4307,6 @@ end_with_restore_list:
|
||||
So just execute the statement.
|
||||
*/
|
||||
res= sp->execute_procedure(thd, &lex->value_list);
|
||||
if (mysql_bin_log.is_open() &&
|
||||
(sp->m_chistics->daccess == SP_CONTAINS_SQL ||
|
||||
sp->m_chistics->daccess == SP_MODIFIES_SQL_DATA))
|
||||
{
|
||||
if (res)
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_FAILED_ROUTINE_BREAK_BINLOG,
|
||||
ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
|
||||
else
|
||||
thd->clear_error();
|
||||
}
|
||||
|
||||
/*
|
||||
If warnings have been cleared, we have to clear total_warn_count
|
||||
too, otherwise the clients get confused.
|
||||
@ -4350,7 +4365,8 @@ end_with_restore_list:
|
||||
if (end_active_trans(thd))
|
||||
goto error;
|
||||
memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics));
|
||||
if (!trust_routine_creators && mysql_bin_log.is_open() &&
|
||||
if ((sp->m_type == TYPE_ENUM_FUNCTION) &&
|
||||
!trust_function_creators && mysql_bin_log.is_open() &&
|
||||
!sp->m_chistics->detistic &&
|
||||
(chistics.daccess == SP_CONTAINS_SQL ||
|
||||
chistics.daccess == SP_MODIFIES_SQL_DATA))
|
||||
@ -4361,6 +4377,12 @@ end_with_restore_list:
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Note that if you implement the capability of ALTER FUNCTION to
|
||||
alter the body of the function, this command should be made to
|
||||
follow the restrictions that log-bin-trust-function-creators=0
|
||||
already puts on CREATE FUNCTION.
|
||||
*/
|
||||
if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
|
||||
result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics);
|
||||
else
|
||||
@ -5033,7 +5055,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
|
||||
the given table list refers to the list for prelocking (contains tables
|
||||
of other queries). For simple queries first_not_own_table is 0.
|
||||
*/
|
||||
for (; tables != first_not_own_table; tables= tables->next_global)
|
||||
for (; tables && tables != first_not_own_table; tables= tables->next_global)
|
||||
{
|
||||
if (tables->schema_table &&
|
||||
(want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
|
||||
@ -7437,32 +7459,81 @@ Item *negate_expression(THD *thd, Item *expr)
|
||||
return new Item_func_not(expr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Assign as view definer current user
|
||||
|
||||
Set the specified definer to the default value, which is the current user in
|
||||
the thread. Also check that the current user satisfies to the definers
|
||||
requirements.
|
||||
|
||||
SYNOPSIS
|
||||
default_view_definer()
|
||||
sctx current security context
|
||||
definer structure where it should be assigned
|
||||
|
||||
get_default_definer()
|
||||
thd [in] thread handler
|
||||
definer [out] definer
|
||||
|
||||
RETURN
|
||||
FALSE OK
|
||||
TRUE Error
|
||||
error status, that is:
|
||||
- FALSE -- on success;
|
||||
- TRUE -- on error (current user can not be a definer).
|
||||
*/
|
||||
|
||||
bool default_view_definer(Security_context *sctx, st_lex_user *definer)
|
||||
|
||||
bool get_default_definer(THD *thd, LEX_USER *definer)
|
||||
{
|
||||
definer->user.str= sctx->priv_user;
|
||||
definer->user.length= strlen(sctx->priv_user);
|
||||
/* Check that current user has non-empty host name. */
|
||||
|
||||
if (!*sctx->priv_host)
|
||||
const Security_context *sctx= thd->security_ctx;
|
||||
|
||||
if (sctx->priv_host[0] == 0)
|
||||
{
|
||||
my_error(ER_NO_VIEW_USER, MYF(0));
|
||||
my_error(ER_MALFORMED_DEFINER, MYF(0));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
definer->host.str= sctx->priv_host;
|
||||
definer->host.length= strlen(sctx->priv_host);
|
||||
/* Fill in. */
|
||||
|
||||
definer->user.str= (char *) sctx->priv_user;
|
||||
definer->user.length= strlen(definer->user.str);
|
||||
|
||||
definer->host.str= (char *) sctx->priv_host;
|
||||
definer->host.length= strlen(definer->host.str);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Create definer with the given user and host names. Also check that the user
|
||||
and host names satisfy definers requirements.
|
||||
|
||||
SYNOPSIS
|
||||
create_definer()
|
||||
thd [in] thread handler
|
||||
user_name [in] user name
|
||||
host_name [in] host name
|
||||
|
||||
RETURN
|
||||
On success, return a valid pointer to the created and initialized
|
||||
LEX_STRING, which contains definer information.
|
||||
On error, return 0.
|
||||
*/
|
||||
|
||||
LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
|
||||
{
|
||||
LEX_USER *definer;
|
||||
|
||||
/* Check that specified host name is valid. */
|
||||
|
||||
if (host_name->length == 0)
|
||||
{
|
||||
my_error(ER_MALFORMED_DEFINER, MYF(0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create and initialize. */
|
||||
|
||||
if (! (definer= (LEX_USER*) thd->alloc(sizeof (LEX_USER))))
|
||||
return 0;
|
||||
|
||||
definer->user= *user_name;
|
||||
definer->host= *host_name;
|
||||
|
||||
return definer;
|
||||
}
|
||||
|
Reference in New Issue
Block a user