Resolving Permissions Problems for WordPress on IIS7

I am running WordPress on Win2k8/IIS7 (using httpcache, fastCgi & UrlRewriter 2.0) installed via WPI. Everything seems to be working fine (uploads, posting via Live Writer, comments, plugins, pretty URLs).

I am trying to update WordPress to the latest version, but I get an error like this:

Read More

Download failed. Destination directory for file streaming does not
exist or is not writable

This is the same error that I get when trying to download a theme or update a plugin.

There are no errors in the event log and WordPress isn’t really telling me which directory it’s looking for, what user it thinks it’s using or what permission it is lacking.

I have double (and triple) checked that the IIS App Pool user is explicitly set, and that the directory has modify permissions for that user, and finally that those permissions have been propogated down to sub folders.

At the advice of Dr. Google, I have also added the following settings to the config file:

/** Absolute path to the WordPress directory. */
if ( !defined('ABSPATH') )
    define('ABSPATH', dirname(__FILE__) . '/');

/** Sets up WordPress vars and included files. */
require_once(ABSPATH . 'wp-settings.php');

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

Am I missing a config option or a setting? Does WordPress require the sacrifice of a small kitten and/or an Algerian degu?

Related posts

Leave a Reply

2 comments

  1. From the PHP manual on IIS7 installation (emphasis mine):

    Impersonation and file system access

    It is recommended to enable FastCGI impersonation in PHP when using
    IIS. This is controlled by the fastcgi.impersonate directive in
    php.ini file
    . When impersonation is enabled, PHP will perform all the
    file system operations on behalf of the user account that has been
    determined by IIS authentication.
    This ensures that even if the same
    PHP process is shared across different IIS web sites, the PHP scripts
    in those web sites will not be able to access each other’s files as
    long as different user accounts are used for IIS authentication on
    each web site.

    For example IIS 7, in its default configuration, has anonymous
    authentication enabled with built-in user account IUSR used as a
    default identity. This means that in order for IIS to execute PHP
    scripts, it is necessary to grant IUSR account read permission on
    those scripts.
    If PHP applications need to perform write operations on
    certain files or write files into some folders then IUSR account
    should have write permission to those.

    As discussed in the “Should I impersonate PHP via FastCGI?” question on ServerFault, there are security concerns if you would grant the anonymous user write access rights on your server. For instance, if you have also enabled the WebDAV module, anyone could write to your directories using this protocol!

    Therefore my recommendations are:

    1. Ensure all your sites have their own unique Application Pool assigned.
    2. In the Advanced Settings under Processing Model for the application pool, set the built-in account as ApplicationPoolIdentity.
    3. Disable impersonation in php.ini with fastcgi.impersonate = 0, so PHP runs under the Application Pool Identity as set in IIS.
    4. Set read/write permissions on your folders using the automatically generated application pool user account (e.g. “IIS AppPoolMyAppPoolName”).

    This way, all PHP scripts are ensured to run under a system account, tied to the Application Pool of the site (isolating it from other sites), and cannot accidentally get too public access via impersonation.

  2. Correct me if I’m wrong but I believe the following configuration provides the same benefits, and also honors PHP’s desired setting of fastcgi.impersonate=1.

    Steps 1,2 and 4 are the same – step 3 is different.

    1. Ensure each site has its own application pool (same as above)
    2. Under Advanced Settings > Processing Model > Application Pool Identity (same as above)
    3. IIS > Authentication > Anonymous Authentication > Application Pool Identity (not IUSR)
    4. Set read/write permissions using IIS AppPoolMyAppPoolName (same as above)

    We do not grant IUSR or IIS_IUSRS access to the webroot. All permissions are assigned to IIS AppPoolMyAppPoolName