Make WordPress Core

Changeset 30384


Ignore:
Timestamp:
11/19/2014 05:39:52 AM (10 years ago)
Author:
dd32
Message:

Background Updates: Introduce support to take advantage of Group Writable (or World Writable) to Core Background updates.
This is only enabled when new files will not be installed during the update (as indicated by the WordPress.org API), and does not apply to Plugin/Theme/Translation Background Updates.

Additionally, the code to determine if the 'direct' filesystem transport should be used has been tweaked for wider support (where getmyuid() was unavailalbe) which fixes #10424

See #10205, #30245

Location:
trunk/src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/class-wp-upgrader-skins.php

    r30170 r30384  
    4141    }
    4242
    43     public function request_filesystem_credentials($error = false) {
     43    public function request_filesystem_credentials( $error = false, $context = false, $allow_relaxed_file_ownership = false ) {
    4444        $url = $this->options['url'];
    45         $context = $this->options['context'];
    46         if ( !empty($this->options['nonce']) )
     45        if ( ! $context ) {
     46            $context = $this->options['context'];
     47        }
     48        if ( !empty($this->options['nonce']) ) {
    4749            $url = wp_nonce_url($url, $this->options['nonce']);
    48         return request_filesystem_credentials($url, '', $error, $context); //Possible to bring inline, Leaving as is for now.
     50        }
     51
     52        $extra_fields = array();
     53
     54        return request_filesystem_credentials( $url, '', $error, $context, $extra_fields, $allow_relaxed_file_ownership );
    4955    }
    5056
     
    700706    protected $messages = array();
    701707
    702     public function request_filesystem_credentials( $error = false, $context = '' ) {
    703         if ( $context )
     708    public function request_filesystem_credentials( $error = false, $context = '', $allow_relaxed_file_ownership = false ) {
     709        if ( $context ) {
    704710            $this->options['context'] = $context;
     711        }
    705712        // TODO: fix up request_filesystem_credentials(), or split it, to allow us to request a no-output version
    706713        // This will output a credentials form in event of failure, We don't want that, so just hide with a buffer
    707714        ob_start();
    708         $result = parent::request_filesystem_credentials( $error );
     715        $result = parent::request_filesystem_credentials( $error, $context, $allow_relaxed_file_ownership );
    709716        ob_end_clean();
    710717        return $result;
  • trunk/src/wp-admin/includes/class-wp-upgrader.php

    r30171 r30384  
    6262    }
    6363
    64     public function fs_connect( $directories = array() ) {
     64    public function fs_connect( $directories = array(), $allow_relaxed_file_ownership = false ) {
    6565        global $wp_filesystem;
    6666
    67         if ( false === ($credentials = $this->skin->request_filesystem_credentials()) )
     67        if ( false === ( $credentials = $this->skin->request_filesystem_credentials( false, $directories[0], $allow_relaxed_file_ownership ) ) ) {
    6868            return false;
    69 
    70         if ( ! WP_Filesystem($credentials) ) {
     69        }
     70
     71        if ( ! WP_Filesystem( $credentials, $directories[0], $allow_relaxed_file_ownership ) ) {
    7172            $error = true;
    7273            if ( is_object($wp_filesystem) && $wp_filesystem->errors->get_error_code() )
    7374                $error = $wp_filesystem->errors;
    74             $this->skin->request_filesystem_credentials($error); //Failed to connect, Error and request again
     75            // Failed to connect, Error and request again
     76            $this->skin->request_filesystem_credentials( $error, $directories[0], $allow_relaxed_file_ownership );
    7577            return false;
    7678        }
     
    14571459            'attempt_rollback' => false,
    14581460            'do_rollback'      => false,
     1461            'allow_relaxed_file_ownership' => false,
    14591462        );
    14601463        $parsed_args = wp_parse_args( $args, $defaults );
     
    14671470            return new WP_Error('up_to_date', $this->strings['up_to_date']);
    14681471
    1469         $res = $this->fs_connect( array(ABSPATH, WP_CONTENT_DIR) );
     1472        $res = $this->fs_connect( array( ABSPATH, WP_CONTENT_DIR ), $parsed_args['allow_relaxed_file_ownership'] );
    14701473        if ( ! $res || is_wp_error( $res ) ) {
    14711474            return $res;
     
    19121915            return false;
    19131916
     1917        // Only relax the filesystem checks when the update doesn't include new files
     1918        $allow_relaxed_file_ownership = false;
     1919        if ( 'core' == $type && isset( $item->new_files ) && ! $item->new_files ) {
     1920            $allow_relaxed_file_ownership = true;
     1921        }
     1922
    19141923        // If we can't do an auto core update, we may still be able to email the user.
    1915         if ( ! $skin->request_filesystem_credentials( false, $context ) || $this->is_vcs_checkout( $context ) ) {
     1924        if ( ! $skin->request_filesystem_credentials( false, $context, $allow_relaxed_file_ownership ) || $this->is_vcs_checkout( $context ) ) {
    19161925            if ( 'core' == $type )
    19171926                $this->send_core_update_notification_email( $item );
     
    20732082        }
    20742083
     2084        $allow_relaxed_file_ownership = false;
     2085        if ( 'core' == $type && isset( $item->new_files ) && ! $item->new_files ) {
     2086            $allow_relaxed_file_ownership = true;
     2087        }
     2088
    20752089        // Boom, This sites about to get a whole new splash of paint!
    20762090        $upgrade_result = $upgrader->upgrade( $upgrader_item, array(
     
    20802094            // Only available for core updates.
    20812095            'attempt_rollback'   => true,
     2096            // Allow relaxed file ownership in some scenarios
     2097            'allow_relaxed_file_ownership' => $allow_relaxed_file_ownership,
     2098           
    20822099        ) );
    20832100
  • trunk/src/wp-admin/includes/file.php

    r30203 r30384  
    810810 * @param array $args (optional) Connection args, These are passed directly to the WP_Filesystem_*() classes.
    811811 * @param string $context (optional) Context for get_filesystem_method(), See function declaration for more information.
     812 * @param bool $allow_relaxed_file_ownership Whether to allow Group/World writable.
    812813 * @return null|boolean false on failure, true on success
    813814 */
    814 function WP_Filesystem( $args = false, $context = false ) {
     815function WP_Filesystem( $args = false, $context = false, $allow_relaxed_file_ownership = false ) {
    815816    global $wp_filesystem;
    816817
    817818    require_once(ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php');
    818819
    819     $method = get_filesystem_method($args, $context);
     820    $method = get_filesystem_method( $args, $context, $allow_relaxed_file_ownership );
    820821
    821822    if ( ! $method )
     
    880881 * @param array $args Connection details.
    881882 * @param string $context Full path to the directory that is tested for being writable.
     883 * @param bool $allow_relaxed_file_ownership Whether to allow Group/World writable.
    882884 * @return string The transport to use, see description for valid return values.
    883885 */
    884 function get_filesystem_method($args = array(), $context = false) {
     886function get_filesystem_method( $args = array(), $context = false, $allow_relaxed_file_ownership = false ) {
    885887    $method = defined('FS_METHOD') ? FS_METHOD : false; // Please ensure that this is either 'direct', 'ssh2', 'ftpext' or 'ftpsockets'
    886888
    887     if ( ! $method && function_exists('getmyuid') && function_exists('fileowner') ){
    888         if ( !$context )
    889             $context = WP_CONTENT_DIR;
    890 
    891         // If the directory doesn't exist (wp-content/languages) then use the parent directory as we'll create it.
    892         if ( WP_LANG_DIR == $context && ! is_dir( $context ) )
    893             $context = dirname( $context );
    894 
    895         $context = trailingslashit($context);
     889    if ( ! $context ) {
     890        $context = WP_CONTENT_DIR;
     891    }
     892
     893    // If the directory doesn't exist (wp-content/languages) then use the parent directory as we'll create it.
     894    if ( WP_LANG_DIR == $context && ! is_dir( $context ) ) {
     895        $context = dirname( $context );
     896    }
     897
     898    $context = trailingslashit( $context );
     899
     900    if ( ! $method ) {
     901
    896902        $temp_file_name = $context . 'temp-write-test-' . time();
    897903        $temp_handle = @fopen($temp_file_name, 'w');
    898904        if ( $temp_handle ) {
    899             if ( getmyuid() == @fileowner($temp_file_name) )
     905
     906            // Attempt to determine the file owner of the WordPress files, and that of newly created files
     907            $wp_file_owner = $temp_file_owner = false;
     908            if ( function_exists('fileowner') ) {
     909                $wp_file_owner = @fileowner( __FILE__ );
     910                $temp_file_owner = @fileowner( $temp_file_name );
     911            }
     912
     913            if ( $wp_file_owner !== false && $wp_file_owner === $temp_file_owner ) {
     914                // WordPress is creating files as the same owner as the WordPress files,
     915                // this means it's safe to modify & create new files via PHP.
    900916                $method = 'direct';
     917            } else if ( $allow_relaxed_file_ownership ) {
     918                // The $context directory is writable, and $allow_relaxed_file_ownership is set, this means we can modify files
     919                // safely in this directory. This mode doesn't create new files, only alter existing ones.
     920                $method = 'direct';
     921            }
     922
    901923            @fclose($temp_handle);
    902924            @unlink($temp_file_name);
     
    913935     * @since 2.6.0
    914936     *
    915      * @param string $method Filesystem method to return.
    916      * @param array  $args   An array of connection details for the method.
     937     * @param string $method  Filesystem method to return.
     938     * @param array  $args    An array of connection details for the method.
     939     * @param string $context Full path to the directory that is tested for being writable.
     940     * @param bool   $allow_relaxed_file_ownership Whether to allow Group/World writable.
    917941     */
    918     return apply_filters( 'filesystem_method', $method, $args );
     942    return apply_filters( 'filesystem_method', $method, $args, $context, $allow_relaxed_file_ownership );
    919943}
    920944
     
    934958 * @param string $context The directory which is needed access to, The write-test will be performed on this directory by get_filesystem_method()
    935959 * @param string $extra_fields Extra POST fields which should be checked for to be included in the post.
     960 * @param bool $allow_relaxed_file_ownership Whether to allow Group/World writable.
    936961 * @return boolean False on failure. True on success.
    937962 */
    938 function request_filesystem_credentials($form_post, $type = '', $error = false, $context = false, $extra_fields = null) {
     963function request_filesystem_credentials($form_post, $type = '', $error = false, $context = false, $extra_fields = null, $allow_relaxed_file_ownership = false ) {
    939964
    940965    /**
     
    953978     * @param string $context      Full path to the directory that is tested for
    954979     *                             being writable.
     980     * @param bool $allow_relaxed_file_ownership Whether to allow Group/World writable.
    955981     * @param array  $extra_fields Extra POST fields.
    956982     */
    957     $req_cred = apply_filters( 'request_filesystem_credentials', '', $form_post, $type, $error, $context, $extra_fields );
     983    $req_cred = apply_filters( 'request_filesystem_credentials', '', $form_post, $type, $error, $context, $extra_fields, $allow_relaxed_file_ownership );
    958984    if ( '' !== $req_cred )
    959985        return $req_cred;
    960986
    961     if ( empty($type) )
    962         $type = get_filesystem_method(array(), $context);
     987    if ( empty($type) ) {
     988        $type = get_filesystem_method( array(), $context, $allow_relaxed_file_ownership );
     989    }
    963990
    964991    if ( 'direct' == $type )
  • trunk/src/wp-admin/update-core.php

    r29825 r30384  
    382382        return;
    383383
     384    // Allow relaxed file ownership writes for User-initiated upgrades when the API specifies
     385    // that it's safe to do so. This only happens when there are no new files to create.
     386    $allow_relaxed_file_ownership = ! $reinstall && isset( $update->new_files ) && ! $update->new_files;
     387
    384388?>
    385389    <div class="wrap">
     
    387391<?php
    388392
    389     if ( false === ( $credentials = request_filesystem_credentials( $url, '', false, ABSPATH ) ) ) {
     393    if ( false === ( $credentials = request_filesystem_credentials( $url, '', false, ABSPATH, array(), $allow_relaxed_file_ownership ) ) ) {
    390394        echo '</div>';
    391395        return;
    392396    }
    393397
    394     if ( ! WP_Filesystem( $credentials, ABSPATH ) ) {
     398    if ( ! WP_Filesystem( $credentials, ABSPATH, $allow_relaxed_file_ownership ) ) {
    395399        // Failed to connect, Error and request again
    396         request_filesystem_credentials( $url, '', true, ABSPATH );
     400        request_filesystem_credentials( $url, '', true, ABSPATH, array(), $allow_relaxed_file_ownership );
    397401        echo '</div>';
    398402        return;
     
    412416
    413417    $upgrader = new Core_Upgrader();
    414     $result = $upgrader->upgrade( $update );
     418    $result = $upgrader->upgrade( $update, array(
     419        'allow_relaxed_file_ownership' => $allow_relaxed_file_ownership
     420    ) );
    415421
    416422    if ( is_wp_error($result) ) {
  • trunk/src/wp-includes/update.php

    r30055 r30384  
    143143        }
    144144        $offer = (object) array_intersect_key( $offer, array_fill_keys( array( 'response', 'download', 'locale',
    145             'packages', 'current', 'version', 'php_version', 'mysql_version', 'new_bundled', 'partial_version', 'notify_email', 'support_email' ), '' ) );
     145            'packages', 'current', 'version', 'php_version', 'mysql_version', 'new_bundled', 'partial_version', 'notify_email', 'support_email', 'new_files' ), '' ) );
    146146    }
    147147
Note: See TracChangeset for help on using the changeset viewer.