Make WordPress Core

Changeset 30384


Ignore:
Timestamp:
11/19/2014 05:39:52 AM (12 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.