Bug#25092566: CREATE TABLE WITH DATA DIRECTORY CLAUSE DOES NOT REQUIRE SPECIAL
PRIVILEGES Require FILE privilege when creating tables using external data directory or index directory.
This commit is contained in:
parent
53230ba274
commit
42732cc195
@ -4,6 +4,8 @@ DROP DATABASE IF EXISTS mysqltest2;
|
||||
# test.t1 have partitions in mysqltest2-directory!
|
||||
# user root:
|
||||
CREATE USER mysqltest_1@localhost;
|
||||
# Need FILE permission to use external datadir or indexdir.
|
||||
GRANT FILE ON *.* TO mysqltest_1@localhost;
|
||||
CREATE DATABASE mysqltest2;
|
||||
USE mysqltest2;
|
||||
CREATE TABLE t1 (a INT) ENGINE = MyISAM;
|
||||
|
@ -32,6 +32,8 @@ DROP DATABASE IF EXISTS mysqltest2;
|
||||
-- echo # test.t1 have partitions in mysqltest2-directory!
|
||||
-- echo # user root:
|
||||
CREATE USER mysqltest_1@localhost;
|
||||
-- echo # Need FILE permission to use external datadir or indexdir.
|
||||
GRANT FILE ON *.* TO mysqltest_1@localhost;
|
||||
CREATE DATABASE mysqltest2;
|
||||
USE mysqltest2;
|
||||
CREATE TABLE t1 (a INT) ENGINE = MyISAM;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
/* Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -2550,6 +2550,30 @@ void partition_info::print_debug(const char *str, uint *value)
|
||||
DBUG_PRINT("info", ("parser: %s", str));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
bool has_external_data_or_index_dir(partition_info &pi)
|
||||
{
|
||||
List_iterator<partition_element> part_it(pi.partitions);
|
||||
for (partition_element *part= part_it++; part; part= part_it++)
|
||||
{
|
||||
if (part->data_file_name != NULL || part->index_file_name != NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
List_iterator<partition_element> subpart_it(part->subpartitions);
|
||||
for (const partition_element *subpart= subpart_it++;
|
||||
subpart;
|
||||
subpart= subpart_it++)
|
||||
{
|
||||
if (subpart->data_file_name != NULL || subpart->index_file_name != NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#else /* WITH_PARTITION_STORAGE_ENGINE */
|
||||
/*
|
||||
For builds without partitioning we need to define these functions
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef PARTITION_INFO_INCLUDED
|
||||
#define PARTITION_INFO_INCLUDED
|
||||
|
||||
/* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
/* Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -349,4 +349,15 @@ void init_all_partitions_iterator(partition_info *part_info,
|
||||
part_iter->get_next= get_next_partition_id_range;
|
||||
}
|
||||
|
||||
/**
|
||||
Predicate which returns true if any partition or subpartition uses
|
||||
an external data directory or external index directory.
|
||||
|
||||
@param pi partitioning information
|
||||
@retval true if any partition or subpartition has an external
|
||||
data directory or external index directory.
|
||||
@retval false otherwise
|
||||
*/
|
||||
bool has_external_data_or_index_dir(partition_info &pi);
|
||||
|
||||
#endif /* PARTITION_INFO_INCLUDED */
|
||||
|
@ -35,6 +35,9 @@
|
||||
#include "sql_insert.h" // mysql_insert
|
||||
#include "sql_update.h" // mysql_update, mysql_multi_update
|
||||
#include "sql_partition.h" // struct partition_info
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
#include "partition_info.h" // has_external_data_or_index_dir
|
||||
#endif /* WITH_PARTITION_STORAGE_ENGINE */
|
||||
#include "sql_db.h" // mysql_change_db, mysql_create_db,
|
||||
// mysql_rm_db, mysql_upgrade_db,
|
||||
// mysql_alter_db,
|
||||
@ -2413,7 +2416,6 @@ case SQLCOM_PREPARE:
|
||||
copy.
|
||||
*/
|
||||
Alter_info alter_info(lex->alter_info, thd->mem_root);
|
||||
|
||||
if (thd->is_fatal_error)
|
||||
{
|
||||
/* If out of memory when creating a copy of alter_info. */
|
||||
@ -2421,6 +2423,15 @@ case SQLCOM_PREPARE:
|
||||
goto end_with_restore_list;
|
||||
}
|
||||
|
||||
if (((lex->create_info.used_fields & HA_CREATE_USED_DATADIR) != 0 ||
|
||||
(lex->create_info.used_fields & HA_CREATE_USED_INDEXDIR) != 0) &&
|
||||
check_access(thd, FILE_ACL, NULL, NULL, NULL, FALSE, FALSE))
|
||||
{
|
||||
res= 1;
|
||||
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "FILE");
|
||||
goto end_with_restore_list;
|
||||
}
|
||||
|
||||
if ((res= create_table_precheck(thd, select_tables, create_table)))
|
||||
goto end_with_restore_list;
|
||||
|
||||
@ -2458,6 +2469,12 @@ case SQLCOM_PREPARE:
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
{
|
||||
partition_info *part_info= thd->lex->part_info;
|
||||
if (part_info != NULL && has_external_data_or_index_dir(*part_info) &&
|
||||
check_access(thd, FILE_ACL, NULL, NULL, NULL, FALSE, FALSE))
|
||||
{
|
||||
res= -1;
|
||||
goto end_with_restore_list;
|
||||
}
|
||||
if (part_info && !(part_info= thd->lex->part_info->get_clone(true)))
|
||||
{
|
||||
res= -1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user