diff options
author | Alexander Nozdrin <alexander.nozdrin@oracle.com> | 2010-12-15 19:00:01 +0300 |
---|---|---|
committer | Alexander Nozdrin <alexander.nozdrin@oracle.com> | 2010-12-15 19:00:01 +0300 |
commit | 1bd81f6b817cc9b8e0b61d126b7ad159117e1b29 (patch) | |
tree | 4800cdc564de2fe83f1a8c4b5dd4d9b57417628d /sql/sql_base.cc | |
parent | 3190d454236c73184b41dcbd7a296069ac2d115b (diff) | |
download | mariadb-git-1bd81f6b817cc9b8e0b61d126b7ad159117e1b29.tar.gz |
Patch for Bug#57952 (privilege change is not taken into account by EXECUTE).
The user-visible problem was that changes to column-level privileges,
happened in between of PREPARE and EXECUTE of a prepared statement, were
neglected. I.e. a prepared statement could be executed with the
column-level privileges as of PREPARE-time. The problem existed for
column-level privileges only.
A similar problem existed for stored programs: the changes between
executions didn't have an effect.
Technically the thing is that table references are cached in
Prepared_statement::prepare() call. In subsequent
Prepared_statement::execute() calls those cached values are used.
There are two functions to get a field by name: find_field_in_table() and
find_field_in_table_ref(). On prepare-phase find_field_in_table_ref() is
called, on execute-phase -- find_field_in_table() because the table is
cached. find_field_in_table() does not check column-level privileges and
expects the caller to do that. The problem was that this check was
forgotten.
The fix is to check them there as it happens in find_field_in_table_ref().
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r-- | sql/sql_base.cc | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 88d1e8879d1..669229a8404 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3657,6 +3657,8 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name, /* Find field by name in a base table or a view with temp table algorithm. + The caller is expected to check column-level privileges. + SYNOPSIS find_field_in_table() thd thread handler @@ -3753,6 +3755,8 @@ find_field_in_table(THD *thd, TABLE *table, const char *name, uint length, This procedure detects the type of the table reference 'table_list' and calls the corresponding search routine. + The routine checks column-level privieleges for the found field. + RETURN 0 field is not found view_ref_found found value in VIEW (real result is in *ref) @@ -3944,8 +3948,16 @@ find_field_in_tables(THD *thd, Item_ident *item, when table_ref->field_translation != NULL. */ if (table_ref->table && !table_ref->view) + { found= find_field_in_table(thd, table_ref->table, name, length, TRUE, &(item->cached_field_index)); +#ifndef NO_EMBEDDED_ACCESS_CHECKS + /* Check if there are sufficient access rights to the found field. */ + if (found && check_privileges && + check_column_grant_in_table_ref(thd, table_ref, name, length)) + found= WRONG_GRANT; +#endif + } else found= find_field_in_table_ref(thd, table_ref, name, length, item->name, NULL, NULL, ref, check_privileges, |