Opened 11 years ago
Last modified 5 years ago
#26802 accepted defect (bug)
WordPress FTP component fails to update core on IIS7+
Reported by: | WinWPAdmin | Owned by: | dd32 |
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | major | Version: | 3.7.1 |
Component: | Filesystem API | Keywords: | |
Focuses: | Cc: |
Description
Update fails with this error : Could not copy file.: wp-admin/update-core.php
Steps to reproduce :
- Clean install of Windows 2012R2 in a virtual machine
- PHP version 5.4.23 installed, configured, and tested as per Microsoft Instructions
- Granted FTP user full control of entire web root
- Granted web server user read access to web root
- Verified the ability to connect with a remote FTP client, create a folder, upload a file, delete the file, delete the folder
- Installed wordpress 3.7.1
- Logged into wordpress admin, clicked on 3.8 upgrade link
- prompted for FTP credentials, supplied same credentials as in my test above
- wordpress update failed with the following message
Downloading update from https://wordpress.org/wordpress-3.8-new-bundled.zip… Unpacking the update… Verifying the unpacked files… Preparing to install the latest version… Enabling Maintenance mode… Copying the required files… Disabling Maintenance mode… Could not copy file.: wp-admin/update-core.php Installation Failed
I then verified that the update could be done manually via an FTP client
- Manually downloaded wordpress-3.8-new-bundled.zip form wordpress.org
- Manually unzipped into temporary directory
- Manually uploaded contents of entire zip file to server
- ran wp-admin/update-core.php
- Updated the database as prompted
Wordpress successfully updated to 3.8 using this manual FTP upload method. The only difference is that I used my own FTP client (Filezilla) instead of the wordpress FTP component.
I think its fair to say at this point that there is a potential bug in the FTP component which manifests itself on IIS servers.
WWW, FTP, and PHP Log files are available upon request.
Attachments (3)
Change History (15)
#3
@
11 years ago
FTP Server (I'm assuming it's the built in Windows server?)
Correct, using the built in IIS FTP server. Tested on Windows 2008, 2008R2, and 2012R2
Is the PHP FTP Extension loaded? (Check phpinfo)
Under the ftp heading in phpinfo it says : FTP support enabled
Has it ever worked on this particular server? (ie. Have you performed an automatic update on this server in the past)
Not on this particular server, but FTP updates used to work on some of our production servers. I believe it stopped working sometime in the last 6 months.
Most windows configurations I've seen set the file permissions so that WordPress isn't forced to use FTP, AFAIK the Microsoft-suggested PHP installation methods also result in PHP being able to write to the filesystem
We try to lock down permissions a bit more so that anonymous users don't have write access to the entire web root.
I set each IIS site to run under its own application pool, and under authentication > anonymous authentication I set each site to authenticate as "application pool user" instead of as the generic IUSR account. In terms of NTFS permissions, I grant Administrator:FULL , SYSTEM:FULL, and "IIS AppPool\sitename" : READ read access to the web root and revoke all other permissions. I also grant the application pool user write access to the wp-content/uploads folder. Certain plugins require additional permissions to their own subdirectory so I either grant those as needed, or I grant write access to the entire wp-content folder if there are a lot of plugins needing write access.
In terms of PHP, I follow the default MS setup instructions, but I grant IIS_IUSRS read access to C:\PHP folder, and write access to C:\PHP\LOGS and C:\PHP\TEMP\Session and C:\PHP\TEMP\upload. This allows all application pool users to access the PHP executables, write php logs, and save session and uploads into a temp folder.
In essence this permission structure allows each site to run under its own credentials, but no IIS site has read permissions to another sites web root.
If I can be of any further assistance let me know.
#4
@
11 years ago
- Component changed from IIS to Filesystem
- Owner set to dd32
- Status changed from new to accepted
Awesome, thanks!
Nothing jumped out at me immediately in the logs, but since you're experiencing it on all 3 server versions, it shouldn't be too hard to duplicate that (I'll have to spin up a Windows Server VM first though, sometime next week hopefully)
#5
@
11 years ago
- Summary changed from Wordpress FTP component fails to update core on IIS7+ to WordPress FTP component fails to update core on IIS7+
#6
@
11 years ago
Thanks for looking into it, greatly appreciated.
I'd be happy to make configuration changes and upload logs as needed for testing. I've uploaded my php.ini in case you want to look that over as well.
Here are a few URLs for reference purposes.
PHP Installation
http://technet.microsoft.com/en-us/library/hh994592.aspx
I used the "manual method" of installing PHP instead of using the platform installer. The permission changes above to the PHP folder are my own.
Application Pool Identities Explained
http://technet.microsoft.com/en-us/library/dd163542.aspx
http://www.iis.net/learn/manage/configuring-security/application-pool-identities
If you need anything else on my end don't hesitate to ask.
#7
@
11 years ago
Attachment attachment:26802.diff added
I haven't yet been able to duplicate the reported issue, however this patch fixes a few somewhat related issues:
- If the Windows FTP server is set to use 4 digit dates (30-12-2013) then the parsing fails
- If the Windows FTP server is set to use unix format, the parsing fails (as we skip that branch for
$is_windows
) - The time calculations were not consistent (
01
+PM
rather than just13
) - The size of directories was reported as
<DIR>
edit: Note to self: This parse function was originally lifted from class-ftp.php, which suffers the same issues
The parsing fixes should fix a few cases of 'Could not find Content Directory (wp-content)' errors, but shouldn't affect copying files as this ticket suggests.
@WinWPAdmin I've also reached out to you by email with a request
#8
@
11 years ago
Upon looking through the FTP logs again I've spotted this:
STOR /wp-admin/update-core.php 550 32 3 98b6708b-a3c4-44c0-a642-f0c066459756 /wp-admin/update-core.php
The URL being requested will be wp-admin/update-core.php, which when it tries to update it via FTP it gets a 550 error (Access Is Denied). At that point WordPress stops attempting to upgrade.
I've managed to duplicate that error once, it appeared that the file is locked by the PHP process preventing it being modified while being used, a similar thing can happen on some windows systems with TortoiseSVN & SVN checkouts where the filesystem says "no, you can't delete that file, it's in use by tortoisesvn".
I also notice this during your manual FTP update:
STOR index.php 550 2148074264 0 badf0c5d-1d11-41a1-a780-bdf9f6495d00 /index.php STOR license.txt 550 2148074264 0 cd6acf6b-07f8-47e9-b9a8-1b3fba3d4a2b /license.txt STOR readme.html 550 2148074264 0 badf0c5d-1d11-41a1-a780-bdf9f6495d00 /readme.html
it retries these transfers multiple times which eventually succeed, which suggests to me that it might be a file-locking issue again, it's just that WordPress doesn't retry as much with as much delay as the FTP client is.
#9
@
11 years ago
@dd32 Thanks for the follow up, I have replied to your request by email as well.
I'll do some research on the file locking angle on this end in the mean time. I've seen references to that behavior - but typically that is when a certain version of WinCache is installed, and I have not used that extension.
#10
@
11 years ago
Just a small update :
On a whim, I installed WinCache on my test 2012R2 VM to see if that helped with the file locking issue. Was thinking perhaps if PHP/IIS cached the files, it would not lock them as aggressively. However, after installing WinCache and verifying that it was present in phpinfo, I still got the 'Could not copy file.: wp-admin/update-core.php' error.
I'll search around a bit more and see if I can dig anything up.
#11
@
9 years ago
Just an informative addition to this ticket:
This happens a lot on IIS web servers, unfortunately, and is always due to file locking by the worker process. Has been for years. This is why I set permissions to modify for my anonymous IUSR.
WinCache uses a just as aggressive locking mechanism, in the past a lot of errors were reported on https://forums.iis.net/1164.aspx.
Setting a different FS_METHOD
('ftpext' or 'ftpsockets', in stead of default 'direct') may resolve some locking issues though. See WordPress Upgrade Constants for more information. But it's been years since I've played with these settings.
#12
@
9 years ago
While I do have to admit that upgrading the WP core seems buggy sometimes I haven't been able to reproduce this error on my setup:
- PHP Version 5.6.8
- Microsoft-IIS/8.5
- WP Core: 3.7.1
- Upgraded to: 4.2.2
FS_METHOD: tried both the default (out of the box) settings and 'ftpext'.
All transfers seem to be going right, giving a 226 status code:
STOR /www/site/wp-content/upgrade/wordpress-4.tmp/wordpress/wp-includes/js/comment-reply.min.js 226 0 0 78 854 0 /www/site/wp-content/upgrade/wordpress-4.tmp/wordpress/wp-includes/js/comment-reply.min.js
I'll keep poking around this one for a while, hopefully I'll be able to break something consistently.
These are the steps I took in both cases:
- Download and install WP 3.7.1
- Make sure anonymous users have no write permissions on the entire WP install
- Log on to the backend and click the upgrade button for 4.2.2
- Provide my FTP server and FTP credentials
- After the initial update I get a message about the database-update. Click to proceed.
- Done.
The FTP Logs would be great to narrow down the cause here.
Information that's also required:
Most windows configurations I've seen set the file permissions so that WordPress isn't forced to use FTP, AFAIK the Microsoft-suggested PHP installation methods also result in PHP being able to write to the filesystem, so it might not have been raised before. If you could link to the configuration steps you took for PHP, that'd be helpful for someone trying to reproduce it.