1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

Merge revisions from maria/5.5 (5.5.41)

bzr merge -r4393 lp:maria/5.5
This commit is contained in:
Nirbhay Choubey
2014-12-22 20:09:25 -05:00
68 changed files with 1796 additions and 256 deletions

View File

@ -5866,6 +5866,115 @@ bool check_global_access(THD *thd, ulong want_access, bool no_errors)
#endif
}
/**
Checks foreign key's parent table access.
@param thd [in] Thread handler
@param create_info [in] Create information (like MAX_ROWS, ENGINE or
temporary table flag)
@param alter_info [in] Initial list of columns and indexes for the
table to be created
@retval
false ok.
@retval
true error or access denied. Error is sent to client in this case.
*/
bool check_fk_parent_table_access(THD *thd,
HA_CREATE_INFO *create_info,
Alter_info *alter_info)
{
Key *key;
List_iterator<Key> key_iterator(alter_info->key_list);
while ((key= key_iterator++))
{
if (key->type == Key::FOREIGN_KEY)
{
TABLE_LIST parent_table;
bool is_qualified_table_name;
Foreign_key *fk_key= (Foreign_key *)key;
LEX_STRING db_name;
LEX_STRING table_name= { fk_key->ref_table->table.str,
fk_key->ref_table->table.length };
const ulong privileges= (SELECT_ACL | INSERT_ACL | UPDATE_ACL |
DELETE_ACL | REFERENCES_ACL);
// Check if tablename is valid or not.
DBUG_ASSERT(table_name.str != NULL);
if (check_table_name(table_name.str, table_name.length, false))
{
my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name.str);
return true;
}
if (fk_key->ref_table->db.str)
{
is_qualified_table_name= true;
db_name.str= (char *) thd->memdup(fk_key->ref_table->db.str,
fk_key->ref_table->db.length+1);
db_name.length= fk_key->ref_table->db.length;
// Check if database name is valid or not.
if (fk_key->ref_table->db.str && check_db_name(&db_name))
{
my_error(ER_WRONG_DB_NAME, MYF(0), db_name.str);
return true;
}
}
else if (thd->lex->copy_db_to(&db_name.str, &db_name.length))
return true;
else
is_qualified_table_name= false;
// if lower_case_table_names is set then convert tablename to lower case.
if (lower_case_table_names)
{
table_name.str= (char *) thd->memdup(fk_key->ref_table->table.str,
fk_key->ref_table->table.length+1);
table_name.length= my_casedn_str(files_charset_info, table_name.str);
}
parent_table.init_one_table(db_name.str, db_name.length,
table_name.str, table_name.length,
table_name.str, TL_IGNORE);
/*
Check if user has any of the "privileges" at table level on
"parent_table".
Having privilege on any of the parent_table column is not
enough so checking whether user has any of the "privileges"
at table level only here.
*/
if (check_some_access(thd, privileges, &parent_table) ||
parent_table.grant.want_privilege)
{
if (is_qualified_table_name)
{
const size_t qualified_table_name_len= NAME_LEN + 1 + NAME_LEN + 1;
char *qualified_table_name= (char *) thd->alloc(qualified_table_name_len);
my_snprintf(qualified_table_name, qualified_table_name_len, "%s.%s",
db_name.str, table_name.str);
table_name.str= qualified_table_name;
}
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
"REFERENCES",
thd->security_ctx->priv_user,
thd->security_ctx->host_or_ip,
table_name.str);
return true;
}
}
}
return false;
}
/****************************************************************************
Check stack size; Send error if there isn't enough stack to continue
****************************************************************************/
@ -7948,8 +8057,11 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
if (check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE))
goto err;
}
error= FALSE;
if (check_fk_parent_table_access(thd, &lex->create_info, &lex->alter_info))
goto err;
error= FALSE;
err:
DBUG_RETURN(error);
}