diff options
author | unknown <msvensson@pilot.mysql.com> | 2007-02-14 14:51:49 +0100 |
---|---|---|
committer | unknown <msvensson@pilot.mysql.com> | 2007-02-14 14:51:49 +0100 |
commit | fe46b0ff6c862862efa5ad990f4941c03a25640e (patch) | |
tree | 8f6f0bf8705654adfef1b27bf5997db33482b106 /sql | |
parent | 581db6c18a7a7e566b489509cde5d7d0533f1d3f (diff) | |
parent | 555aed64aa38475f424a3620b79a3b5e9d0ddb67 (diff) | |
download | mariadb-git-fe46b0ff6c862862efa5ad990f4941c03a25640e.tar.gz |
Merge pilot.mysql.com:/home/msvensson/mysql/mysql-5.0-maint
into pilot.mysql.com:/home/msvensson/mysql/mysql-5.1-new-maint
mysql-test/mysql-test-run.pl:
Auto merged
mysql-test/r/loaddata.result:
Auto merged
mysql-test/r/query_cache.result:
Auto merged
mysql-test/r/type_blob.result:
Auto merged
mysql-test/t/loaddata.test:
Auto merged
mysql-test/t/query_cache.test:
Auto merged
mysql-test/t/type_blob.test:
Auto merged
sql/item_strfunc.cc:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/sql_class.cc:
Auto merged
sql/sql_load.cc:
Auto merged
sql/mysqld.cc:
Manual merge of OPT_SECUREE_FILE_PRIV
sql/set_var.cc:
Manual merge
sql/share/errmsg.txt:
Manual merge, change is already in 5.1
sql/sql_class.h:
Manual mergem change is already in 5.1
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_strfunc.cc | 5 | ||||
-rw-r--r-- | sql/mysql_priv.h | 1 | ||||
-rw-r--r-- | sql/mysqld.cc | 20 | ||||
-rw-r--r-- | sql/set_var.cc | 4 | ||||
-rw-r--r-- | sql/sql_class.cc | 12 | ||||
-rw-r--r-- | sql/sql_class.h | 2 | ||||
-rw-r--r-- | sql/sql_load.cc | 9 |
7 files changed, 48 insertions, 5 deletions
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index faea5380a66..78710c2cfeb 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2803,6 +2803,11 @@ String *Item_load_file::val_str(String *str) (void) fn_format(path, file_name->c_ptr(), mysql_real_data_home, "", MY_RELATIVE_PATH | MY_UNPACK_FILENAME); + /* Read only allowed from within dir specified by secure_file_priv */ + if (opt_secure_file_priv && + strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv))) + goto err; + if (!my_stat(path, &stat_info, MYF(0))) goto err; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 6174221c515..85ae3fc0f5f 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1604,6 +1604,7 @@ extern my_bool opt_slave_compressed_protocol, use_temp_pool; extern my_bool opt_readonly, lower_case_file_system; extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs; extern my_bool opt_secure_auth; +extern char* opt_secure_file_priv; extern my_bool opt_log_slow_admin_statements; extern my_bool sp_automatic_privileges, opt_noacl; extern my_bool opt_old_style_user_limits, trust_function_creators; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d9fab73a23c..cbba3a93458 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -430,6 +430,7 @@ extern enum ndb_distribution opt_ndb_distribution_id; my_bool opt_readonly, use_temp_pool, relay_log_purge; my_bool opt_sync_frm, opt_allow_suspicious_udfs; my_bool opt_secure_auth= 0; +char* opt_secure_file_priv= 0; my_bool opt_log_slow_admin_statements= 0; my_bool lower_case_file_system= 0; my_bool opt_large_pages= 0; @@ -1233,6 +1234,7 @@ void clean_up(bool print_message) #endif x_free(opt_bin_logname); x_free(opt_relay_logname); + x_free(opt_secure_file_priv); bitmap_free(&temp_pool); free_max_user_conn(); #ifdef HAVE_REPLICATION @@ -4895,7 +4897,8 @@ enum options_mysqld OPT_GENERAL_LOG, OPT_SLOW_LOG, OPT_MERGE, - OPT_INNODB_ROLLBACK_ON_TIMEOUT + OPT_INNODB_ROLLBACK_ON_TIMEOUT, + OPT_SECURE_FILE_PRIV }; @@ -5598,6 +5601,10 @@ Can't be set to 1 if --log-slave-updates is used.", {"secure-auth", OPT_SECURE_AUTH, "Disallow authentication for accounts that have old (pre-4.1) passwords.", (gptr*) &opt_secure_auth, (gptr*) &opt_secure_auth, 0, GET_BOOL, NO_ARG, my_bool(0), 0, 0, 0, 0, 0}, + {"secure-file-priv", OPT_SECURE_FILE_PRIV, + "Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files within specified directory", + (gptr*) &opt_secure_file_priv, (gptr*) &opt_secure_file_priv, 0, + GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"server-id", OPT_SERVER_ID, "Uniquely identifies the server instance in the community of replication partners.", (gptr*) &server_id, (gptr*) &server_id, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 0, @@ -6964,6 +6971,7 @@ static void mysql_init_variables(void) opt_logname= opt_update_logname= opt_binlog_index_name= opt_slow_logname= 0; opt_tc_log_file= (char *)"tc.log"; // no hostname in tc_log file name ! opt_secure_auth= 0; + opt_secure_file_priv= 0; opt_bootstrap= opt_myisam_log= 0; mqh_used= 0; segfaulted= kill_in_progress= 0; @@ -7984,6 +7992,16 @@ static void fix_paths(void) exit(1); } #endif /* HAVE_REPLICATION */ + /* + Convert the secure-file-priv option to system format, allowing + a quick strcmp to check if read or write is in an allowed dir + */ + if (opt_secure_file_priv) + { + convert_dirname(buff, opt_secure_file_priv, NullS); + my_free(opt_secure_file_priv, MYF(0)); + opt_secure_file_priv= my_strdup(buff, MYF(MY_FAE)); + } } diff --git a/sql/set_var.cc b/sql/set_var.cc index 55fbeac5622..8a31cdf32ce 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -411,6 +411,8 @@ sys_query_cache_wlock_invalidate("query_cache_wlock_invalidate", &SV::query_cache_wlock_invalidate); #endif /* HAVE_QUERY_CACHE */ sys_var_bool_ptr sys_secure_auth("secure_auth", &opt_secure_auth); +sys_var_const_str_ptr sys_secure_file_priv("secure_file_priv", + &opt_secure_file_priv); sys_var_long_ptr sys_server_id("server_id", &server_id, fix_server_id); sys_var_bool_ptr sys_slave_compressed_protocol("slave_compressed_protocol", &opt_slave_compressed_protocol); @@ -669,7 +671,6 @@ sys_var_have_variable sys_have_rtree_keys("have_rtree_keys", &have_rtree_keys); sys_var_have_variable sys_have_symlink("have_symlink", &have_symlink); /* Global read-only variable describing server license */ sys_var_const_str sys_license("license", STRINGIFY_ARG(LICENSE)); - /* Global variables which enable|disable logging */ sys_var_log_state sys_var_general_log("general_log", &opt_log, QUERY_LOG_GENERAL); @@ -959,6 +960,7 @@ SHOW_VAR init_vars[]= { #endif {sys_rpl_recovery_rank.name,(char*) &sys_rpl_recovery_rank, SHOW_SYS}, {"secure_auth", (char*) &sys_secure_auth, SHOW_SYS}, + {"secure_file_priv", (char*) &sys_secure_file_priv, SHOW_SYS}, #ifdef HAVE_SMEM {"shared_memory", (char*) &opt_enable_shared_memory, SHOW_MY_BOOL}, {"shared_memory_base_name", (char*) &shared_memory_base_name, SHOW_CHAR_PTR}, diff --git a/sql/sql_class.cc b/sql/sql_class.cc index d5f81168be3..f42610d4fda 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1179,7 +1179,7 @@ static File create_file(THD *thd, char *path, sql_exchange *exchange, IO_CACHE *cache) { File file; - uint option= MY_UNPACK_FILENAME; + uint option= MY_UNPACK_FILENAME | MY_RELATIVE_PATH; #ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS option|= MY_REPLACE_DIR; // Force use of db directory @@ -1193,7 +1193,15 @@ static File create_file(THD *thd, char *path, sql_exchange *exchange, } else (void) fn_format(path, exchange->file_name, mysql_real_data_home, "", option); - + + if (opt_secure_file_priv && + strncmp(opt_secure_file_priv, path, strlen(opt_secure_file_priv))) + { + /* Write only allowed to dir or subdir specified by secure_file_priv */ + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv"); + return -1; + } + if (!access(path, F_OK)) { my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name); diff --git a/sql/sql_class.h b/sql/sql_class.h index 7babe1eda24..727cff0c463 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1640,7 +1640,7 @@ public: /* - Used to hold information about file and file structure in exchainge + Used to hold information about file and file structure in exchange via non-DB file (...INTO OUTFILE..., ...LOAD DATA...) XXX: We never call destructor for objects of this class. */ diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 364fda2c94b..50a414b33bd 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -305,6 +305,15 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, if ((stat_info.st_mode & S_IFIFO) == S_IFIFO) is_fifo = 1; #endif + + if (opt_secure_file_priv && + strncmp(opt_secure_file_priv, name, strlen(opt_secure_file_priv))) + { + /* Read only allowed from within dir specified by secure_file_priv */ + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv"); + DBUG_RETURN(TRUE); + } + } if ((file=my_open(name,O_RDONLY,MYF(MY_WME))) < 0) DBUG_RETURN(TRUE); |