mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
WL#2486 - natural/using joins according to SQL:2003
Post-review fixes that simplify the way access rights are checked during name resolution and factor out all entry points to check access rights into one single function.
This commit is contained in:
137
sql/sql_base.cc
137
sql/sql_base.cc
@ -2683,47 +2683,6 @@ static void update_field_dependencies(THD *thd, Field *field, TABLE *table)
|
||||
}
|
||||
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
/*
|
||||
Check column rights in given security context
|
||||
|
||||
SYNOPSIS
|
||||
check_grant_column_in_sctx()
|
||||
thd thread handler
|
||||
grant grant information structure
|
||||
db db name
|
||||
table table name
|
||||
name column name
|
||||
length column name length
|
||||
check_grants need to check grants
|
||||
sctx 0 or security context
|
||||
|
||||
RETURN
|
||||
FALSE OK
|
||||
TRUE access denied
|
||||
*/
|
||||
|
||||
static bool check_grant_column_in_sctx(THD *thd, GRANT_INFO *grant,
|
||||
const char *db, const char *table,
|
||||
const char *name, uint length,
|
||||
bool check_grants,
|
||||
Security_context *sctx)
|
||||
{
|
||||
if (!check_grants)
|
||||
return FALSE;
|
||||
Security_context *save_security_ctx= thd->security_ctx;
|
||||
bool res;
|
||||
if (sctx)
|
||||
{
|
||||
thd->security_ctx= sctx;
|
||||
}
|
||||
res= check_grant_column(thd, grant, db, table, name, length);
|
||||
thd->security_ctx= save_security_ctx;
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Find a field by name in a view that uses merge algorithm.
|
||||
|
||||
@ -2736,7 +2695,6 @@ static bool check_grant_column_in_sctx(THD *thd, GRANT_INFO *grant,
|
||||
item_name name of item if it will be created (VIEW)
|
||||
ref expression substituted in VIEW should be passed
|
||||
using this reference (return view_ref_found)
|
||||
check_grants do check columns grants for view?
|
||||
register_tree_change TRUE if ref is not stack variable and we
|
||||
need register changes in item tree
|
||||
|
||||
@ -2750,7 +2708,7 @@ static Field *
|
||||
find_field_in_view(THD *thd, TABLE_LIST *table_list,
|
||||
const char *name, uint length,
|
||||
const char *item_name, Item **ref,
|
||||
bool check_grants, bool register_tree_change)
|
||||
bool register_tree_change)
|
||||
{
|
||||
DBUG_ENTER("find_field_in_view");
|
||||
DBUG_PRINT("enter",
|
||||
@ -2766,14 +2724,6 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list,
|
||||
{
|
||||
if (!my_strcasecmp(system_charset_info, field_it.name(), name))
|
||||
{
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (check_grant_column_in_sctx(thd, &table_list->grant,
|
||||
table_list->view_db.str,
|
||||
table_list->view_name.str, name, length,
|
||||
check_grants,
|
||||
table_list->security_ctx))
|
||||
DBUG_RETURN(WRONG_GRANT);
|
||||
#endif
|
||||
// in PS use own arena or data will be freed after prepare
|
||||
if (register_tree_change)
|
||||
arena= thd->activate_stmt_arena_if_needed(&backup);
|
||||
@ -2822,7 +2772,6 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list,
|
||||
length [in] length of name
|
||||
ref [in/out] if 'name' is resolved to a view field, ref is
|
||||
set to point to the found view field
|
||||
check_grants [in] do check columns grants?
|
||||
register_tree_change [in] TRUE if ref is not stack variable and we
|
||||
need register changes in item tree
|
||||
actual_table [out] the original table reference where the field
|
||||
@ -2843,8 +2792,7 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list,
|
||||
|
||||
static Field *
|
||||
find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
|
||||
uint length, Item **ref, bool check_grants,
|
||||
bool register_tree_change,
|
||||
uint length, Item **ref, bool register_tree_change,
|
||||
TABLE_LIST **actual_table)
|
||||
{
|
||||
List_iterator_fast<Natural_join_column>
|
||||
@ -2869,11 +2817,6 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (check_grants && nj_col->check_grants(thd, name, length))
|
||||
DBUG_RETURN(WRONG_GRANT);
|
||||
#endif
|
||||
|
||||
if (nj_col->view_field)
|
||||
{
|
||||
Item *item;
|
||||
@ -2929,7 +2872,6 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
|
||||
table table where to search for the field
|
||||
name name of field
|
||||
length length of name
|
||||
check_grants do check columns grants?
|
||||
allow_rowid do allow finding of "_rowid" field?
|
||||
cached_field_index_ptr cached position in field list (used to speedup
|
||||
lookup for fields in prepared tables)
|
||||
@ -2941,9 +2883,7 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
|
||||
|
||||
Field *
|
||||
find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
|
||||
bool check_grants, bool allow_rowid,
|
||||
uint *cached_field_index_ptr,
|
||||
Security_context *sctx)
|
||||
bool allow_rowid, uint *cached_field_index_ptr)
|
||||
{
|
||||
Field **field_ptr, *field;
|
||||
uint cached_field_index= *cached_field_index_ptr;
|
||||
@ -2982,13 +2922,6 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
|
||||
|
||||
update_field_dependencies(thd, field, table);
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (check_grant_column_in_sctx(thd, &table->grant,
|
||||
table->s->db, table->s->table_name,
|
||||
name, length,
|
||||
check_grants, sctx))
|
||||
field= WRONG_GRANT;
|
||||
#endif
|
||||
DBUG_RETURN(field);
|
||||
}
|
||||
|
||||
@ -3007,8 +2940,7 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
|
||||
table_name [in] optional table name that qualifies the field
|
||||
ref [in/out] if 'name' is resolved to a view field, ref
|
||||
is set to point to the found view field
|
||||
check_grants_table [in] do check columns grants for table?
|
||||
check_grants_view [in] do check columns grants for view?
|
||||
check_privileges [in] check privileges
|
||||
allow_rowid [in] do allow finding of "_rowid" field?
|
||||
cached_field_index_ptr [in] cached position in field list (used to
|
||||
speedup lookup for fields in prepared tables)
|
||||
@ -3041,8 +2973,8 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
|
||||
const char *name, uint length,
|
||||
const char *item_name, const char *db_name,
|
||||
const char *table_name, Item **ref,
|
||||
bool check_grants_table, bool check_grants_view,
|
||||
bool allow_rowid, uint *cached_field_index_ptr,
|
||||
bool check_privileges, bool allow_rowid,
|
||||
uint *cached_field_index_ptr,
|
||||
bool register_tree_change, TABLE_LIST **actual_table)
|
||||
{
|
||||
Field *fld;
|
||||
@ -3087,8 +3019,7 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
|
||||
if (table_list->field_translation)
|
||||
{
|
||||
/* 'table_list' is a view or an information schema table. */
|
||||
if ((fld= find_field_in_view(thd, table_list, name, length, item_name,
|
||||
ref, check_grants_view,
|
||||
if ((fld= find_field_in_view(thd, table_list, name, length, item_name, ref,
|
||||
register_tree_change)))
|
||||
*actual_table= table_list;
|
||||
}
|
||||
@ -3097,20 +3028,9 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
|
||||
/* 'table_list' is a stored table. */
|
||||
DBUG_ASSERT(table_list->table);
|
||||
if ((fld= find_field_in_table(thd, table_list->table, name, length,
|
||||
check_grants_table, allow_rowid,
|
||||
cached_field_index_ptr,
|
||||
table_list->security_ctx)))
|
||||
allow_rowid,
|
||||
cached_field_index_ptr)))
|
||||
*actual_table= table_list;
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
/* check for views with temporary table algorithm */
|
||||
if (check_grants_view && table_list->view &&
|
||||
fld && fld != WRONG_GRANT &&
|
||||
check_grant_column(thd, &table_list->grant,
|
||||
table_list->view_db.str,
|
||||
table_list->view_name.str,
|
||||
name, length))
|
||||
fld= WRONG_GRANT;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3129,9 +3049,8 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
|
||||
{
|
||||
if ((fld= find_field_in_table_ref(thd, table, name, length, item_name,
|
||||
db_name, table_name, ref,
|
||||
check_grants_table,
|
||||
check_grants_view,
|
||||
allow_rowid, cached_field_index_ptr,
|
||||
check_privileges, allow_rowid,
|
||||
cached_field_index_ptr,
|
||||
register_tree_change, actual_table)))
|
||||
DBUG_RETURN(fld);
|
||||
}
|
||||
@ -3144,11 +3063,16 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
|
||||
directly the top-most NATURAL/USING join.
|
||||
*/
|
||||
fld= find_field_in_natural_join(thd, table_list, name, length, ref,
|
||||
/* TIMOUR_TODO: check this with Sanja */
|
||||
check_grants_table || check_grants_view,
|
||||
register_tree_change, actual_table);
|
||||
}
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
/* Check if there are sufficient access rights to the found field. */
|
||||
if (fld && check_privileges &&
|
||||
check_column_grant_in_table_ref(thd, *actual_table, name, length))
|
||||
fld= WRONG_GRANT;
|
||||
#endif
|
||||
|
||||
DBUG_RETURN(fld);
|
||||
}
|
||||
|
||||
@ -3230,21 +3154,11 @@ find_field_in_tables(THD *thd, Item_ident *item,
|
||||
*/
|
||||
if (table_ref->table && !table_ref->view)
|
||||
found= find_field_in_table(thd, table_ref->table, name, length,
|
||||
test(table_ref->table->
|
||||
grant.want_privilege) &&
|
||||
check_privileges,
|
||||
1, &(item->cached_field_index),
|
||||
table_ref->security_ctx);
|
||||
TRUE, &(item->cached_field_index));
|
||||
else
|
||||
found= find_field_in_table_ref(thd, table_ref, name, length, item->name,
|
||||
NULL, NULL, ref,
|
||||
(table_ref->table &&
|
||||
test(table_ref->table->grant.
|
||||
want_privilege) &&
|
||||
check_privileges),
|
||||
(test(table_ref->grant.want_privilege) &&
|
||||
check_privileges),
|
||||
1, &(item->cached_field_index),
|
||||
NULL, NULL, ref, check_privileges,
|
||||
TRUE, &(item->cached_field_index),
|
||||
register_tree_change,
|
||||
&actual_table);
|
||||
if (found)
|
||||
@ -3286,14 +3200,7 @@ find_field_in_tables(THD *thd, Item_ident *item,
|
||||
{
|
||||
Field *cur_field= find_field_in_table_ref(thd, cur_table, name, length,
|
||||
item->name, db, table_name, ref,
|
||||
(cur_table->table &&
|
||||
test(cur_table->table->grant.
|
||||
want_privilege) &&
|
||||
check_privileges),
|
||||
(test(cur_table->grant.
|
||||
want_privilege)
|
||||
&& check_privileges),
|
||||
allow_rowid,
|
||||
check_privileges, allow_rowid,
|
||||
&(item->cached_field_index),
|
||||
register_tree_change,
|
||||
&actual_table);
|
||||
|
Reference in New Issue
Block a user