Commit 42732cc1 authored by Dyre Tjeldvoll's avatar Dyre Tjeldvoll Committed by Gipson Pulla

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.
parent 53230ba2
...@@ -4,6 +4,8 @@ DROP DATABASE IF EXISTS mysqltest2; ...@@ -4,6 +4,8 @@ DROP DATABASE IF EXISTS mysqltest2;
# test.t1 have partitions in mysqltest2-directory! # test.t1 have partitions in mysqltest2-directory!
# user root: # user root:
CREATE USER mysqltest_1@localhost; CREATE USER mysqltest_1@localhost;
# Need FILE permission to use external datadir or indexdir.
GRANT FILE ON *.* TO mysqltest_1@localhost;
CREATE DATABASE mysqltest2; CREATE DATABASE mysqltest2;
USE mysqltest2; USE mysqltest2;
CREATE TABLE t1 (a INT) ENGINE = MyISAM; CREATE TABLE t1 (a INT) ENGINE = MyISAM;
......
...@@ -32,6 +32,8 @@ DROP DATABASE IF EXISTS mysqltest2; ...@@ -32,6 +32,8 @@ DROP DATABASE IF EXISTS mysqltest2;
-- echo # test.t1 have partitions in mysqltest2-directory! -- echo # test.t1 have partitions in mysqltest2-directory!
-- echo # user root: -- echo # user root:
CREATE USER mysqltest_1@localhost; 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; CREATE DATABASE mysqltest2;
USE mysqltest2; USE mysqltest2;
CREATE TABLE t1 (a INT) ENGINE = MyISAM; CREATE TABLE t1 (a INT) ENGINE = MyISAM;
......
/* 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 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 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) ...@@ -2550,6 +2550,30 @@ void partition_info::print_debug(const char *str, uint *value)
DBUG_PRINT("info", ("parser: %s", str)); DBUG_PRINT("info", ("parser: %s", str));
DBUG_VOID_RETURN; 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 */ #else /* WITH_PARTITION_STORAGE_ENGINE */
/* /*
For builds without partitioning we need to define these functions For builds without partitioning we need to define these functions
......
#ifndef PARTITION_INFO_INCLUDED #ifndef PARTITION_INFO_INCLUDED
#define 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 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 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, ...@@ -349,4 +349,15 @@ void init_all_partitions_iterator(partition_info *part_info,
part_iter->get_next= get_next_partition_id_range; 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 */ #endif /* PARTITION_INFO_INCLUDED */
...@@ -35,6 +35,9 @@ ...@@ -35,6 +35,9 @@
#include "sql_insert.h" // mysql_insert #include "sql_insert.h" // mysql_insert
#include "sql_update.h" // mysql_update, mysql_multi_update #include "sql_update.h" // mysql_update, mysql_multi_update
#include "sql_partition.h" // struct partition_info #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, #include "sql_db.h" // mysql_change_db, mysql_create_db,
// mysql_rm_db, mysql_upgrade_db, // mysql_rm_db, mysql_upgrade_db,
// mysql_alter_db, // mysql_alter_db,
...@@ -2413,7 +2416,6 @@ case SQLCOM_PREPARE: ...@@ -2413,7 +2416,6 @@ case SQLCOM_PREPARE:
copy. copy.
*/ */
Alter_info alter_info(lex->alter_info, thd->mem_root); Alter_info alter_info(lex->alter_info, thd->mem_root);
if (thd->is_fatal_error) if (thd->is_fatal_error)
{ {
/* If out of memory when creating a copy of alter_info. */ /* If out of memory when creating a copy of alter_info. */
...@@ -2421,6 +2423,15 @@ case SQLCOM_PREPARE: ...@@ -2421,6 +2423,15 @@ case SQLCOM_PREPARE:
goto end_with_restore_list; 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))) if ((res= create_table_precheck(thd, select_tables, create_table)))
goto end_with_restore_list; goto end_with_restore_list;
...@@ -2458,6 +2469,12 @@ case SQLCOM_PREPARE: ...@@ -2458,6 +2469,12 @@ case SQLCOM_PREPARE:
#ifdef WITH_PARTITION_STORAGE_ENGINE #ifdef WITH_PARTITION_STORAGE_ENGINE
{ {
partition_info *part_info= thd->lex->part_info; 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))) if (part_info && !(part_info= thd->lex->part_info->get_clone(true)))
{ {
res= -1; res= -1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment