=== modified file 'mysql-test/suite/backup/r/backup_securefilepriv.result' --- mysql-test/suite/backup/r/backup_securefilepriv.result 2008-10-07 17:15:44 +0000 +++ mysql-test/suite/backup/r/backup_securefilepriv.result 2009-02-04 21:34:02 +0000 @@ -8,14 +8,14 @@ INSERT INTO mysqltest.t1 VALUES (1),(2), Starting tests -Backup to path specified by --secure-file-priv option +Backup to path specified by --secure-backup-file-priv option (MYSQLTEST_VARDIR/master-data/securefilepriv_path) BACKUP DATABASE mysqltest TO 'securefilepriv_path/bup_sfp1.bak'; backup_id # Ensure backup image file went to the correct location -Backup to subpath of path specified by --secure-file-priv option +Backup to subpath of path specified by --secure-backup-file-priv option (MYSQLTEST_VARDIR/master-data/securefilepriv_path/subpath) BACKUP DATABASE mysqltest TO 'securefilepriv_path/subpath/bup_sfp2.bak'; backup_id @@ -26,7 +26,7 @@ Change backupdir to securefilepriv_path/ (MYSQLTEST_VARDIR/master-data/securefilepriv_path/subpath) SET @@global.backupdir = 'securefilepriv_path/subpath'; -Backup to subpath of path specified by --secure-file-priv option, +Backup to subpath of path specified by --secure-backup-file-priv option, no dir in backup file name (MYSQLTEST_VARDIR/master-data/securefilepriv_path/subpath) BACKUP DATABASE mysqltest TO 'bup_sfp3.bak'; @@ -34,7 +34,7 @@ backup_id # Ensure backup image file went to the correct location -Backup to path specified by --secure-file-priv, +Backup to path specified by --secure-backup-file-priv, relative path in backup file name (MYSQLTEST_VARDIR/master-data/securefilepriv_path) BACKUP DATABASE mysqltest TO '../bup_sfp4.bak'; @@ -42,17 +42,17 @@ backup_id # Ensure backup image file went to the correct location -Backup to relative path outside path specified by --secure-file-priv +Backup to relative path outside path specified by --secure-backup-file-priv option should fail BACKUP DATABASE mysqltest TO '../../bup_sfp_fail1.bak'; -ERROR HY000: The MySQL server is running with the --secure-file-priv option so it cannot execute this statement +ERROR HY000: The MySQL server is running with the --secure-backup-file-priv option so it cannot execute this statement Reset backupdir to MYSQLTEST_VARDIR/master-data/ SET @@global.backupdir = @@global.datadir; -Backup to other path than specified by --secure-file-priv should fail +Backup to other path than specified by --secure-backup-file-priv should fail BACKUP DATABASE mysqltest TO 'bup_sfp_fail2.bak'; -ERROR HY000: The MySQL server is running with the --secure-file-priv option so it cannot execute this statement +ERROR HY000: The MySQL server is running with the --secure-backup-file-priv option so it cannot execute this statement Cleanup === modified file 'mysql-test/suite/backup/t/backup_securefilepriv-master.opt' --- mysql-test/suite/backup/t/backup_securefilepriv-master.opt 2008-10-07 17:15:44 +0000 +++ mysql-test/suite/backup/t/backup_securefilepriv-master.opt 2009-02-04 21:31:38 +0000 @@ -1 +1 @@ ---secure-file-priv=$MYSQLTEST_VARDIR/master-data/securefilepriv_path +--secure-backup-file-priv=$MYSQLTEST_VARDIR/master-data/securefilepriv_path === modified file 'mysql-test/suite/backup/t/backup_securefilepriv.test' --- mysql-test/suite/backup/t/backup_securefilepriv.test 2008-10-07 17:15:44 +0000 +++ mysql-test/suite/backup/t/backup_securefilepriv.test 2009-02-04 21:31:38 +0000 @@ -1,8 +1,8 @@ # # Purpose: Backup images should only be allowed to be written to the -# path specified by --secure-file-priv option or a sub-path of it. +# path specified by --secure-backup-file-priv option or a sub-path of it. # -# See backup_securefilepriv-master.opt for --secure-file-priv command line option +# See backup_securefilepriv-master.opt for --secure-backup-file-priv command line option # # backupdir is MYSQLTEST_VARDIR/master-data/ # secure-file-priv is MYSQLTEST_VARDIR/master-data/securefilepriv_path/ @@ -36,7 +36,7 @@ INSERT INTO mysqltest.t1 VALUES (1),(2), --echo Starting tests --echo ---echo Backup to path specified by --secure-file-priv option +--echo Backup to path specified by --secure-backup-file-priv option --echo (MYSQLTEST_VARDIR/master-data/securefilepriv_path) --replace_column 1 # BACKUP DATABASE mysqltest TO 'securefilepriv_path/bup_sfp1.bak'; @@ -48,7 +48,7 @@ BACKUP DATABASE mysqltest TO 'securefile --remove_file $MYSQLTEST_VARDIR/master-data/securefilepriv_path/bup_sfp1.bak --echo ---echo Backup to subpath of path specified by --secure-file-priv option +--echo Backup to subpath of path specified by --secure-backup-file-priv option --echo (MYSQLTEST_VARDIR/master-data/securefilepriv_path/subpath) --replace_column 1 # BACKUP DATABASE mysqltest TO 'securefilepriv_path/subpath/bup_sfp2.bak'; @@ -65,7 +65,7 @@ BACKUP DATABASE mysqltest TO 'securefile SET @@global.backupdir = 'securefilepriv_path/subpath'; --echo ---echo Backup to subpath of path specified by --secure-file-priv option, +--echo Backup to subpath of path specified by --secure-backup-file-priv option, --echo no dir in backup file name --echo (MYSQLTEST_VARDIR/master-data/securefilepriv_path/subpath) --replace_column 1 # @@ -78,7 +78,7 @@ BACKUP DATABASE mysqltest TO 'bup_sfp3.b --remove_file $MYSQLTEST_VARDIR/master-data/securefilepriv_path/subpath/bup_sfp3.bak --echo ---echo Backup to path specified by --secure-file-priv, +--echo Backup to path specified by --secure-backup-file-priv, --echo relative path in backup file name --echo (MYSQLTEST_VARDIR/master-data/securefilepriv_path) --replace_column 1 # @@ -93,7 +93,7 @@ BACKUP DATABASE mysqltest TO '../bup_sfp # Tests that fail --echo ---echo Backup to relative path outside path specified by --secure-file-priv +--echo Backup to relative path outside path specified by --secure-backup-file-priv --echo option should fail --error ER_OPTION_PREVENTS_STATEMENT BACKUP DATABASE mysqltest TO '../../bup_sfp_fail1.bak'; @@ -103,7 +103,7 @@ BACKUP DATABASE mysqltest TO '../../bup_ SET @@global.backupdir = @@global.datadir; --echo ---echo Backup to other path than specified by --secure-file-priv should fail +--echo Backup to other path than specified by --secure-backup-file-priv should fail --error ER_OPTION_PREVENTS_STATEMENT BACKUP DATABASE mysqltest TO 'bup_sfp_fail2.bak'; === modified file 'sql/backup/kernel.cc' --- sql/backup/kernel.cc 2009-02-03 07:48:09 +0000 +++ sql/backup/kernel.cc 2009-02-04 21:28:25 +0000 @@ -1397,7 +1397,7 @@ int Backup_restore_ctx::report_stream_op int error= 0; switch (my_open_status) { case ER_OPTION_PREVENTS_STATEMENT: - error= report_error(ER_OPTION_PREVENTS_STATEMENT, "--secure-file-priv"); + error= report_error(ER_OPTION_PREVENTS_STATEMENT, "--secure-backup-file-priv"); break; case ER_BACKUP_WRITE_LOC: /* === modified file 'sql/backup/stream.cc' --- sql/backup/stream.cc 2008-12-18 21:46:36 +0000 +++ sql/backup/stream.cc 2009-02-04 21:28:58 +0000 @@ -202,23 +202,27 @@ Stream::Stream(Logger &log, ::String *pa } /** - Check if secure-file-priv option has been set and if so, whether + Check if secure-backup-file-priv option has been set and if so, whether or not backup tries to write to the path (or a sub-path) specified - by secure-file-priv. + by secure-backup-file-priv. Reports error ER_OPTION_PREVENTS_STATEMENT if backup tries to write - to a different path than specified by secure-file-priv. + to a different path than specified by secure-backup-file-priv. @retval TRUE backup is allowed to write to this path @retval FALSE backup is not allowed to write to this path. Side effect: error is reported */ bool Stream::test_secure_file_priv_access(char *path) { - bool has_access = !opt_secure_file_priv || // option not specified, or - !strncmp(opt_secure_file_priv, path, // path is (subpath of) - strlen(opt_secure_file_priv)); // secure-file-priv option + bool has_access = !opt_secure_backup_file_priv || + // option not specified, or + !strncmp(opt_secure_backup_file_priv, path, + // path is (subpath of) + strlen(opt_secure_backup_file_priv)); + // secure-backup-file-priv option if (!has_access) - m_log.report_error(ER_OPTION_PREVENTS_STATEMENT, "--secure-file-priv"); + m_log.report_error(ER_OPTION_PREVENTS_STATEMENT, + "--secure-backup-file-priv"); return has_access; } @@ -227,7 +231,7 @@ bool Stream::test_secure_file_priv_acces Open a stream. @retval 0 if stream was successfully opened - @retval ER_OPTION_PREVENTS_STATEMENT if secure-file-priv option + @retval ER_OPTION_PREVENTS_STATEMENT if secure-backup-file-priv option prevented stream open from this path @retval -1 if open failed for another reason */ @@ -353,7 +357,7 @@ bool Output_stream::init() Open and initialize backup stream for writing. @retval 0 operation succeeded - @retval ER_OPTION_PREVENTS_STATEMENT secure-file-priv option + @retval ER_OPTION_PREVENTS_STATEMENT secure-backup-file-priv option prevented stream open from this path @retval ER_BACKUP_WRITE_LOC open failed for another reason @@ -559,7 +563,7 @@ bool Input_stream::init() m_header_buf member and examined by check_magic_and_version(). @retval 0 operation succeeded - @retval ER_OPTION_PREVENTS_STATEMENT secure-file-priv option + @retval ER_OPTION_PREVENTS_STATEMENT secure-backup-file-priv option prevented stream open from this path @retval ER_BACKUP_READ_LOC open failed for another reason === modified file 'sql/mysql_priv.h' --- sql/mysql_priv.h 2009-01-21 15:06:10 +0000 +++ sql/mysql_priv.h 2009-02-04 21:22:34 +0000 @@ -2012,6 +2012,7 @@ extern my_bool opt_readonly, lower_case_ 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 char* opt_secure_backup_file_priv; extern my_bool opt_log_slow_admin_statements, opt_log_slow_slave_statements; extern my_bool sp_automatic_privileges, opt_noacl; extern my_bool opt_old_style_user_limits, trust_function_creators; === modified file 'sql/mysqld.cc' --- sql/mysqld.cc 2009-01-21 15:06:10 +0000 +++ sql/mysqld.cc 2009-02-04 21:22:34 +0000 @@ -502,6 +502,7 @@ my_bool opt_readonly, use_temp_pool, rel my_bool opt_sync_frm, opt_allow_suspicious_udfs; my_bool opt_secure_auth= 0; char* opt_secure_file_priv= 0; +char* opt_secure_backup_file_priv= 0; my_bool opt_log_slow_admin_statements= 0; my_bool opt_log_slow_slave_statements= 0; my_bool lower_case_file_system= 0; @@ -1397,6 +1398,7 @@ void clean_up(bool print_message) x_free(opt_bin_logname); x_free(opt_relay_logname); x_free(opt_secure_file_priv); + x_free(opt_secure_backup_file_priv); bitmap_free(&temp_pool); free_max_user_conn(); #ifdef HAVE_REPLICATION @@ -5901,6 +5903,7 @@ enum options_mysqld OPT_THREAD_HANDLING, OPT_INNODB_ROLLBACK_ON_TIMEOUT, OPT_SECURE_FILE_PRIV, + OPT_SECURE_BACKUP_FILE_PRIV, OPT_MIN_EXAMINED_ROW_LIMIT, OPT_LOG_SLOW_SLAVE_STATEMENTS, #if defined(ENABLED_DEBUG_SYNC) @@ -6605,6 +6608,10 @@ Can't be set to 1 if --log-slave-updates "Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files within specified directory", (uchar**) &opt_secure_file_priv, (uchar**) &opt_secure_file_priv, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"secure-backup-file-priv", OPT_SECURE_BACKUP_FILE_PRIV, + "Limit BACKUP and RESTORE to files within specified directory", + (uchar**) &opt_secure_backup_file_priv, (uchar**) &opt_secure_backup_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.", (uchar**) &server_id, (uchar**) &server_id, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 0, @@ -7918,6 +7925,7 @@ static int mysql_init_variables(void) opt_tc_log_file= (char *)"tc.log"; // no hostname in tc_log file name ! opt_secure_auth= 0; opt_secure_file_priv= 0; + opt_secure_backup_file_priv= 0; opt_bootstrap= opt_myisam_logical_log= 0; mqh_used= 0; segfaulted= kill_in_progress= 0; @@ -8972,6 +8980,17 @@ static void fix_paths(void) my_free(opt_secure_file_priv, MYF(0)); opt_secure_file_priv= my_strdup(buff, MYF(MY_FAE)); } + + /* + Convert the secure-backup-file-priv option to system format, allowing + a quick strcmp to check if read or write is in an allowed dir + */ + if (opt_secure_backup_file_priv) + { + convert_dirname(buff, opt_secure_backup_file_priv, NullS); + my_free(opt_secure_backup_file_priv, MYF(0)); + opt_secure_backup_file_priv= my_strdup(buff, MYF(MY_FAE)); + } } === modified file 'sql/set_var.cc' --- sql/set_var.cc 2009-01-21 15:06:10 +0000 +++ sql/set_var.cc 2009-02-04 21:22:34 +0000 @@ -601,6 +601,8 @@ sys_query_cache_wlock_invalidate(&vars, static sys_var_bool_ptr sys_secure_auth(&vars, "secure_auth", &opt_secure_auth); static sys_var_const_str_ptr sys_secure_file_priv(&vars, "secure_file_priv", &opt_secure_file_priv); +static sys_var_const_str_ptr sys_secure_backup_file_priv(&vars, "secure_backup_file_priv", + &opt_secure_backup_file_priv); static sys_var_long_ptr sys_server_id(&vars, "server_id", &server_id, fix_server_id); static sys_var_bool_ptr sys_slave_compressed_protocol(&vars, "slave_compressed_protocol", &opt_slave_compressed_protocol);