Can’t install new plugins because of the error “Could not create directory”

A faculty member is having difficulties with a instructional wordpress install. Fixing individual permission problems has been hit and miss, and have become a perennial pain, so I’ll ask here. What can I do to make WP Just Work? The kinds of errors they get:

Installing Plugin: Lightbox 2 2.9.2
Downloading install package from
http://downloads.wordpress.org/plugin/lightbox-2.2.9.2.zip…
Unpacking the package… Could not
create directory.
/home/CIM140/public_html/wordpress/wp-content/upgrade/lightbox-2.tmp

Read More

When I su as www-data (the user apache runs as in Ubuntu), I can make that directory just fine. My test wp instance installs this plugin just fine, so I’m at a loss as to why it fails for them.

Related posts

Leave a Reply

6 comments

  1. @pwnguin,

    I had the same problems running mod_php with WordPress and I finally figured it out.

    # chown www-data:www-data  /home/CIM140/public_html/wordpress/ -R
    

    As long as YOU control the box this won’t cause any security issues.


    EDIT:

    You might also need to change your umask to 022 so new directories created by WordPress will have 755 permissions and files will have 644 permissions.

    Another option is to override default file permissions in wp-config.php:

    define('FS_CHMOD_DIR', (0755 & ~ umask()));
    define('FS_CHMOD_FILE', (0644 & ~ umask()));
    

    You can also force the filesystem method for updates.

    • (Primary Preference) “Direct” forces it to use Direct File I/O requests from within PHP, this is fraught with opening up security issues on poorly configured hosts, This is chosen automatically when appropriate.
    • (Secondary Preference) “ssh” is to force the usage of the SSH PHP Extension.
    • (3rd Preference) “ftpext” is to force the usage of the FTP PHP Extension for FTP Access, and finally
    • (4th Preference) “ftpsockets” utilises the PHP Sockets Class for FTP Access.

    These can be defined in wp-config.php with: define('FS_METHOD', 'ftpext');

    You can get all the currently defined constants by executing the print_r(@get_defined_constants()); command in php.

  2. For me (on Ubuntu) I had to add umask 002 to /etc/apache2/envvars in order to get WordPress to upload plugins/images with 775 permissions instead of 755 (i.e. allow anyone besides Apache and root to change the uploaded files)

  3. In order to understand why you’re having these problems, you need to understand the underlying concepts of ownership.

    Basically, you know that apache is running as the www-data user. This is why setting everything to be owned by that user works, because WordPress is verifying that it can create files as the user that owns its own files. So, what you’re doing is to make everything owned by the user that owns the files.

    If you have full and total control of the machine, this is fine. On the other hand, if it’s a shared hosting server, then you have created a security hole.

    Normally, web servers run as some user (like www-data) which then runs code by other users (like “otto”, my user account). In this situation, the webserver would not have the ability to create files as “otto”, and thus would not be able to properly create files as my account. Thus, this check by WordPress as to creating properly owned files and thus being able to install plugins or update files would fail, correctly, because having my files owned by the shared webserver user would be a security risk.

    In such a case, WordPress should correctly prompt me for FTP credentials, or something to that effect. These would be a way to work around the user account issue by authenticating as the user that should be writing the files, and then writing them as that user.

    Now, you’re trying to solve this problem by changing all the WordPress files to be owned by the same account that the webserver writes the files as. The more normal approach for this is to change how the webserver writes files, to allow the PHP process to be “owned” by the user account that it is running the files as.

    The general answer to this is “suphp”. This version of PHP sets the user that the PHP process runs as to the same user as the owner of the PHP files it is running. This is safer on shared hosting setups, because it ensures that a PHP process being run by the shared webserver runs as the owner of the PHP files, and thus can’t read other users accounts and the like.

    On Ubuntu, I believe this is the general way to do it:

    Install suphp:

    $ sudo apt-get install libapache2-mod-suphp
    

    Disable the old mod_php

    $ sudo a2dismod php5 
    

    Restart Apache

    $ sudo /etc/init.d/apache2 restart
    

    And voila. Now, have your WordPress PHP files owned by the Normal owner of them. No special tricks, no changing permissions or ownership or anything like that. Since the PHP process will run as the owner of those files, then it will be able to write to them as that owner. Directories should be 755, files should be 644 (note, suphp doesn’t like when files are writable by group, so 755/644 is the correct permission set).

  4. I have sometimes had sites where correcting the directory and file permissions was not enough to fix this problem. I’ve then discovered that one or more directories have the immutable flag set. This can be easily solved by running chattr -R /var/www/sub.domain.tld as root.

  5. You need to give write permissions to the relevant directories. Ideally, you should do it only for the relevant file or folder and then revert the permissions back so as to not leave your site vulnerable.

    You can fix this using the following commands from the command line (assuming that you are in the WordPress root folder):

    # cd wp-content
    # chmod -R a+w plugins
    # chmod -R a+w themes
    # chmod -R a+w upgrade
    

    The safest solution is to add apache to the same group as the owner of the WordPress installation and change all group permissions to writeable.