Make WordPress Core

Ticket #10205: 10205.3.diff

File 10205.3.diff, 4.5 KB (added by dd32, 11 years ago)

Patch that checks the file ownership, and writability of files during a FTP Upgrade, allowing for Direct upgrades to be used when the system has previously determined (by FTP) that it's going to be OK. Mostly for cases where fileowner() and getmyuid() are not available.

  • src/wp-admin/includes/file.php

     
    833833function get_filesystem_method($args = array(), $context = false) {
    834834        $method = defined('FS_METHOD') ? FS_METHOD : false; //Please ensure that this is either 'direct', 'ssh', 'ftpext' or 'ftpsockets'
    835835
     836        if ( !$context )
     837                $context = WP_CONTENT_DIR;
     838
    836839        if ( ! $method && function_exists('getmyuid') && function_exists('fileowner') ){
    837                 if ( !$context )
    838                         $context = WP_CONTENT_DIR;
    839840                $context = trailingslashit($context);
    840841                $temp_file_name = $context . 'temp-write-test-' . time();
    841842                $temp_handle = @fopen($temp_file_name, 'w');
     
    847848                }
    848849        }
    849850
     851        if ( ! $method && get_site_option( 'fs_direct_ok' ) && is_writable( $context ) && is_writable( __FILE__ ) )
     852                $method = 'direct';
     853
    850854        if ( ! $method && isset($args['connection_type']) && 'ssh' == $args['connection_type'] && extension_loaded('ssh2') && function_exists('stream_get_contents') ) $method = 'ssh2';
    851855        if ( ! $method && extension_loaded('ftp') ) $method = 'ftpext';
    852856        if ( ! $method && ( extension_loaded('sockets') || function_exists('fsockopen') ) ) $method = 'ftpsockets'; //Sockets: Socket extension; PHP Mode: FSockopen / fwrite / fread
  • src/wp-admin/includes/update-core.php

     
    901901        exit();
    902902}
    903903add_action( '_core_updated_successfully', '_redirect_to_about_wordpress' );
     904
     905function _check_if_fs_direct_is_ok_in_future() {
     906        global $wp_filesystem;
     907
     908        // If we're already using direct, nevermind!
     909        if ( 'direct' == $wp_filesystem->method || 'direct' == get_filesystem_method() )
     910                return;
     911
     912        $working_dir_local = WP_CONTENT_DIR . '/upgrade/';
     913        // If we can't write to the created Working dir or ABSPATH, it doesn't matter to us ultimately
     914        if ( ! is_writable( $working_dir_local ) || ! is_writable( ABSPATH ) )
     915                return;
     916
     917        // Find the upgrade working directory.
     918        $working_dir_ftp = $wp_filesystem->wp_content_dir();
     919        if ( ! $working_dir_ftp )
     920                return;
     921
     922        $working_dir_ftp .= 'upgrade/';
     923
     924        // Random Filenames for usage below
     925        $random_filename = wp_unique_filename( $working_dir_local, 'test1.file' );
     926        $random_filename2 = wp_unique_filename( $working_dir_local, 'test2.file' );
     927        // Some random content that shouldn't match eachother
     928        $random_content  = wp_generate_password() . '1';
     929        $random_content2 = wp_generate_password() . '2';
     930
     931        // Create file1 via local file operations
     932        $local_file_result = file_put_contents( $working_dir_local . $random_filename, $random_content );
     933
     934        // Create file2 via FTP
     935        $remote_file_result = $wp_filesystem->put_contents( $working_dir_ftp . $random_filename2, $random_content );
     936
     937        // Write to random file1 by FTP
     938        $local_file_writable_by_ftp = $wp_filesystem->put_contents( $working_dir_ftp . $random_filename, $random_content2 );
     939
     940        // Write to random file2 by local file operations
     941        $remote_file_writable_by_local = file_put_contents( $working_dir_local . $random_filename2, $random_content2 );
     942
     943        // Verify contents of file1 and file2 match expected
     944        $contents_OK1 = ( $random_content2 == file_get_contents( $working_dir_local . $random_filename ) );
     945        $contents_OK2 = ( $random_content2 == file_get_contents( $working_dir_local . $random_filename2 ) );
     946
     947        // Verify FTP ownership of the two test files match (created via FTP, and via local file operations)
     948        $listing = $wp_filesystem->dirlist( $working_dir_ftp );
     949        $file_owner_matches = $listing && isset( $listing[ $random_filename ] ) && isset( $listing[ $random_filename2 ] ) && $listing[ $random_filename ]['owner'] === $listing[ $random_filename2 ]['owner'];
     950
     951        // Remove temporary files
     952        @unlink( $working_dir_local . $random_filename  );
     953        @unlink( $working_dir_local . $random_filename2 );
     954        $wp_filesystem->delete( $working_dir_ftp . $random_filename  );
     955        $wp_filesystem->delete( $working_dir_ftp . $random_filename2 );
     956
     957        $success = $local_file_result && $remote_file_result &&
     958                $local_file_writable_by_ftp && $remote_file_writable_by_local &&
     959                $contents_OK1 && $contents_OK2 &&
     960                $file_owner_matches;
     961
     962        update_site_option( 'fs_direct_ok', $success );
     963
     964}
     965// Attach to the upgrade-complete handler or something
     966add_action( '_core_updated_successfully', '_check_if_fs_direct_is_ok_in_future', 1 );
     967 No newline at end of file