From 336da6e2709dac5f065a14cebadeb2c97eaf1f47 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 16:18:37 +0200 Subject: [PATCH] cleanup --- sql/mysqld.cc | 2 +- sql/partition_info.cc | 29 +++++++++++------------ sql/sql_parse.cc | 34 ++++++++++++++++++++++++++- sql/sql_parse.h | 1 + sql/sql_table.cc | 53 ++++--------------------------------------- 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())