summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/partition_info.cc29
-rw-r--r--sql/sql_parse.cc34
-rw-r--r--sql/sql_parse.h1
-rw-r--r--sql/sql_table.cc53
5 files changed, 53 insertions, 66 deletions
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 19d01e61771..d8e603d3009 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -8065,7 +8065,7 @@ static int get_options(int *argc_ptr, char ***argv_ptr)
global_system_variables.sql_mode=
expand_sql_mode(global_system_variables.sql_mode);
-#if defined(HAVE_BROKEN_REALPATH)
+#if !defined(HAVE_REALPATH) || defined(HAVE_BROKEN_REALPATH)
my_use_symdir=0;
my_disable_symlinks=1;
have_symlink=SHOW_OPTION_NO;
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 028afd7899e..934f4e970cb 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -1582,29 +1582,21 @@ bool check_partition_dirs(partition_info *part_info)
partition_element *subpart_elem;
while ((subpart_elem= sub_it++))
{
- if (test_if_data_home_dir(subpart_elem->data_file_name))
- goto dd_err;
- if (test_if_data_home_dir(subpart_elem->index_file_name))
- goto id_err;
+ if (error_if_data_home_dir(subpart_elem->data_file_name,
+ "DATA DIRECTORY") ||
+ error_if_data_home_dir(subpart_elem->index_file_name,
+ "INDEX DIRECTORY"))
+ return 1;
}
}
else
{
- if (test_if_data_home_dir(part_elem->data_file_name))
- goto dd_err;
- if (test_if_data_home_dir(part_elem->index_file_name))
- goto id_err;
+ if (error_if_data_home_dir(part_elem->data_file_name, "DATA DIRECTORY") ||
+ error_if_data_home_dir(part_elem->index_file_name, "INDEX DIRECTORY"))
+ return 1;
}
}
return 0;
-
-dd_err:
- my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECTORY");
- return 1;
-
-id_err:
- my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECTORY");
- return 1;
}
@@ -2286,4 +2278,9 @@ void partition_info::print_debug(const char *str, uint *value)
{
}
+bool check_partition_dirs(partition_info *part_info)
+{
+ return 0;
+}
+
#endif /* WITH_PARTITION_STORAGE_ENGINE */
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index e866d2b74ef..62e5a99f941 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -7683,6 +7683,7 @@ bool check_string_char_length(LEX_STRING *str, const char *err_msg,
return TRUE;
}
+C_MODE_START
/*
Check if path does not contain mysql data home directory
@@ -7695,7 +7696,6 @@ bool check_string_char_length(LEX_STRING *str, const char *err_msg,
0 ok
1 error ; Given path contains data directory
*/
-C_MODE_START
int test_if_data_home_dir(const char *dir)
{
@@ -7706,6 +7706,22 @@ int test_if_data_home_dir(const char *dir)
if (!dir)
DBUG_RETURN(0);
+ /*
+ data_file_name and index_file_name include the table name without
+ extension. Mostly this does not refer to an existing file. When
+ comparing data_file_name or index_file_name against the data
+ directory, we try to resolve all symbolic links. On some systems,
+ we use realpath(3) for the resolution. This returns ENOENT if the
+ resolved path does not refer to an existing file. my_realpath()
+ does then copy the requested path verbatim, without symlink
+ resolution. Thereafter the comparison can fail even if the
+ requested path is within the data directory. E.g. if symlinks to
+ another file system are used. To make realpath(3) return the
+ resolved path, we strip the table name and compare the directory
+ path only. If the directory doesn't exist either, table creation
+ will fail anyway.
+ */
+
(void) fn_format(path, dir, "", "",
(MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
dir_len= strlen(path);
@@ -7739,6 +7755,22 @@ int test_if_data_home_dir(const char *dir)
C_MODE_END
+int error_if_data_home_dir(const char *path, const char *what)
+{
+ size_t dirlen;
+ char dirpath[FN_REFLEN];
+ if (path)
+ {
+ dirname_part(dirpath, path, &dirlen);
+ if (test_if_data_home_dir(dirpath))
+ {
+ my_error(ER_WRONG_ARGUMENTS, MYF(0), what);
+ return 1;
+ }
+ }
+ return 0;
+}
+
/**
Check that host name string is valid.
diff --git a/sql/sql_parse.h b/sql/sql_parse.h
index 6d47e648be2..25c41cc624c 100644
--- a/sql/sql_parse.h
+++ b/sql/sql_parse.h
@@ -34,6 +34,7 @@ enum enum_mysql_completiontype {
};
extern "C" int test_if_data_home_dir(const char *dir);
+int error_if_data_home_dir(const char *path, const char *what);
bool multi_update_precheck(THD *thd, TABLE_LIST *tables);
bool multi_delete_precheck(THD *thd, TABLE_LIST *tables);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 8f2320b9b30..a8f071558bf 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4346,55 +4346,7 @@ bool mysql_create_table_no_lock(THD *thd,
if (!file)
goto err;
-#ifdef HAVE_READLINK
- {
- size_t dirlen;
- char dirpath[FN_REFLEN];
-
- /*
- data_file_name and index_file_name include the table name without
- extension. Mostly this does not refer to an existing file. When
- comparing data_file_name or index_file_name against the data
- directory, we try to resolve all symbolic links. On some systems,
- we use realpath(3) for the resolution. This returns ENOENT if the
- resolved path does not refer to an existing file. my_realpath()
- does then copy the requested path verbatim, without symlink
- resolution. Thereafter the comparison can fail even if the
- requested path is within the data directory. E.g. if symlinks to
- another file system are used. To make realpath(3) return the
- resolved path, we strip the table name and compare the directory
- path only. If the directory doesn't exist either, table creation
- will fail anyway.
- */
- if (create_info->data_file_name)
- {
- dirname_part(dirpath, create_info->data_file_name, &dirlen);
- if (test_if_data_home_dir(dirpath))
- {
- my_error(ER_WRONG_ARGUMENTS, MYF(0), "DATA DIRECTORY");
- goto err;
- }
- }
- if (create_info->index_file_name)
- {
- dirname_part(dirpath, create_info->index_file_name, &dirlen);
- if (test_if_data_home_dir(dirpath))
- {
- my_error(ER_WRONG_ARGUMENTS, MYF(0), "INDEX DIRECTORY");
- goto err;
- }
- }
- }
-
-#ifdef WITH_PARTITION_STORAGE_ENGINE
- if (check_partition_dirs(thd->lex->part_info))
- {
- goto err;
- }
-#endif /* WITH_PARTITION_STORAGE_ENGINE */
-
if (!my_use_symdir || (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE))
-#endif /* HAVE_READLINK */
{
if (create_info->data_file_name)
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
@@ -4406,6 +4358,11 @@ bool mysql_create_table_no_lock(THD *thd,
"INDEX DIRECTORY");
create_info->data_file_name= create_info->index_file_name= 0;
}
+ else
+ if (error_if_data_home_dir(create_info->data_file_name, "DATA DIRECTORY") ||
+ error_if_data_home_dir(create_info->index_file_name, "INDEX DIRECTORY")||
+ check_partition_dirs(thd->lex->part_info))
+ goto err;
/* Check if table exists */
if (create_info->tmp_table())