Fix/Tricks for plugin auto-update on WordPress 2.5

[READ THIS FIRST!!!  Update 6/13/2009: If you’ve come here looking to get plugin updates to work and you’re using WordPress 2.8, you really want to start with this more recent post on the topic and then come back for the permission information.]

One of the neat features of WordPress 2.5 is the click to install plugin upgrades, assuming the plugin is registered in the WordPress Plugin Directory. If certain conditions are correct on the server it can do it in place, otherwise it tries to do it via FTP.

To make it so wordpress could upgrade them on the server without FTP requires doing some permission changes. You should be aware, the changes I made allow the web server (Apache) to be able to write to the plugin directory. This creates some security exposure. Since I do nightly backups, for me this is an acceptable risk. You may make a different call.

The way I’ve done it also assumes you have admin rights on the unix box or you’re friendly with (s)he who does. Without admin rights to do the group ownership changes, you’re stuck having to make files writable by the world, and that’s not something I’d do. Luckily, I hold the power on the box(es) I care about.

The changes I made were as follows:

chgrp -R apache wp-content/plugins
find wp-content/plugins -type d | xargs chmod g+ws
find wp-content/plugins -type f | xargs chmod g+w

After doing that, I fired off upgrading the google-sitemap-generator plugin, as that was out of date. It brought me to a screen asking for FTP information, which means the server-side update failed. That sent me to the code. After walking the code I found two things:

  1. Without WP_TEMP_DIR specified in your config, the upgrade will use wp-content as a temp directory.
  2. A bug/feature of the code that prevents it from work.

To get around #1, I defined WP_TEMP_DIR in my wp-config so it looked like this:

define('WP_TEMP_DIR', ABSPATH . 'wp-content/tmp');

I then created a tmp directory and set its permissions inline with what I have above.

mkdir wp-content/tmp
chgrp apache wp-content/tmp
chmod 2775 wp-content/tmp

As I called #2 above, I’m not sure if its a bug or a feature. One of the sanity checks that wordpress does to see if it can do the update is to make sure it can write into the temp directory and if the current process owns the resultant file. I’m thinking its a bug because it looks like they expected the PHP function call used to be reasonable rather than suffer from the occasional brain-dead PHPism.

The sanity check uses getmyuid() which anyone with unix coding experience would assume its the user id of the running process. Not so! If you read the PHP documentation, it actually returns the UID of who owns the script file. Since my user owns the file, but the script is being executed by apache’s user, it ends up returning the wrong information. In reading the code, and guessing its intent, what they actually wanted to use was either posix_getuid() or posix_geteuid(). Once I switched to using posix_getuid() everything worked as expected.

To make this change, open up wp-admin/includes/file.php in your editor of choice and go to somewhere around line 323. You’ll want to change the line that looks like this:

if ( getmyuid() == fileowner($tempFile) ) {

To look something like this:

if ( posix_getuid() == fileowner($tempFile) ) {

And boom, I have working click to upgrade for plugins.

As a note, I have no idea if this will work on Windows or not as I’m not up with the permissions there or if the posix_ functions are available on that platform.

24 thoughts on “Fix/Tricks for plugin auto-update on WordPress 2.5”

  1. Thanks for this post! It helped me solve the same problem I was having on a Windows box. The WP_TEMP_DIR option works. Just make sure that it is defined after ABSPATH in the WP-CONFIG file. And then create the temp folder of choice and give it write/delete permissions. In addition the WP-CONTENT folder needs to be given write/delete permission too.

    Unfortunately, I believe following these steps via a typical web host’s control panel pretty much makes important sections of WordPress open to the world. Not a good thing. But knowing what’s going on now might lead me to a better solution. Or I could just switch to Linux 🙂

  2. Hi, I hope you can help me with a little problem. I used your solution on my page. The only thing is, i could not execute the shell comments.

    The Files wich are uploaded by the plugin-update-function set the user nobody as owner of the upgraded files. Is there a chance that it is set to the ftp user i use by login?

  3. LastOne,

    This sounds like a question for your ISP. Unless you’re admin enough to do the ownership changes yourself, it probably won’t go. (And I doubt any ISP will do it for you.) One workaround I am loath to mention is to make the directories world writable, which would work, but open you up to anyone else on the box monkeying with your stuff.

  4. I came across this fix independently after searching the path that the check took. I submitted a ticket on the wordpress trac, maybe we can get this fixed once and for all.

  5. “posix_getuid()” instead of “getmyuid()” did the trick (my wp-content folder was already apache-owned)

    thanks!
    -prash

  6. Thanks a lot for this trick !

    I’m actually using wordpress 2.6.3, and there’ still the same “bug” by using getmyuid() instead of posix_getuid() …

    ( In the /wp-admin/includes/file.php, it’s around line 451 )

    Hopefull 2.7 will take care of this 😛

  7. It appears 2.7 hasn’t taken care of this. I’m still having the problem. I follow the steps outlined and before I get to the step to change the file.php file, I no longer get the FTP request box, but then I get the following:
    “Downloading update from http://downloads.wordpress.org/plugin/akismet.zip
    Download failed.: Could not create Temporary file
    Plugin upgrade Failed”

    If I make the change to file.php, then I go back to it asking me for the FTP information 🙁

    I’m frustrated with this! Two of the WP blogs on my VPS update just fine, the rest of them do not. I’m still trying to figure out what the difference is.

  8. Thanks a lot. For all WordPress 2.7 users: Obviously there are changes on line number 628 in the file “wp-admin/includes/file.php”

    The temp file is now called “$temp_file” and not “$tempFile” anymore as described here. So please make sure not to copy & past but only to replace the function “getmyuid” with “posix_getuid”

    Cheers, David

  9. Yes – this looks like what I need too! Should save me a whole lot of time as the plugins I use seem to be updated every other day 🙂 we’re running about 40 WordPress installs now too – so thanks – I’d pretty much got to the final step, but there’s no way I’d have figured that out, so thanks for posting this.

  10. I got impatient… so I just edited wp-admin/includes/file.php and took $method=’direct’ outside the loop… everything works fine now! (tried the posix_getuid stuff first to no avail)

  11. Thank you!

    I changed getmyuid() to posix_getuid()

    on line 628

    of /wp-admin/includes/file.php

    Seems to done the trick.

  12. The change to getmyuid() to posix_getuid() does the trick for me on 2.7.1.

    But when the plugin is downloaded, I click Activate – and get a blank page. – Going Back to the list of plugins, the new plugin IS actaully activated…

    The page just does not display automatically like it did – with teh confirmation of the plugin activation.

    Anyone else seeing this? 🙂

  13. Thanks for the help. Just ran into this for the first time and your fix worked… with one extra step.

    It got me past the connection information but was having trouble creating folders, so I needed to create the folder ‘wp-content/upgrade’ as well.

    The part that bothers me is that none of it would work without all three folders ‘plugins’, ‘tmp’, and ‘upgrade’ all being 777. Is that a problem?

  14. I had the same problem and the following seemed to fix it. “Note that your files all need to be owned by the user under which your Apache server executes, or you will receive a dialog box asking for “connection information,” and you will find that no matter what you enter, it won’t work. ”

    from http://codex.wordpress.org/Upgrading_WordPress

  15. “Without WP_TEMP_DIR specified in your config, the upgrade will use wp-content as a temp directory.”…

    Thanks – that was the info I was looking for – changing folder permissions to “777” temporarily did the trick…

  16. Wish I would have read Mathew’s comment before following the full directions, but thanks for posting this solution! It worked for me!

Leave a Reply