28
votes

BLUF

Our application is attempting to write a file to a UNC folder using an ASP.NET web service running under .NET 4.5, IIS 7.5, and Windows Server 2008 R2. However, any attempt to write the file to the desired location results in an access denied exception.

The task seems simple however me and my team have been troubleshooting this for a while now and we are stumped as to what may be causing the error. Below are the details of our setup and what we have tried and found so far. Names have been changed to protect the innocent.

Environment Setup

The web server, mywebserver, has a website named My.Site.Com with a corresponding application pool named My.Site.Com. The application pool is configured as shown below.

 .NET Framework Version     : v4.0
 Enable 32-bit Applications : False
 Managed Pipeline Mode      : Integrated
 Name                       : My.Site.Com
 Identity                   : ApplicationPoolIdentity
 Load User Profile          : False

The UNC path we are attempting to write to is \myotherserver\mydirectories\output where mydirectories is the actual share. On this share a domain group named mygroup-www has been granted full permissions to the share and all subfolders. The machine account (i.e., mywebserver) is a member of this mygroup-www group.

NOTE: For the moment, this UNC path actually lives on the same machine, mywebserver. However, this will eventually be moved to a machine other than mywebserver in our test environment and in the production environment when that it is ready. Currently, I only have the one test environment to troubleshoot with.

The error can be replicated by executing the following code.

[WebMethod]
[ScriptMethod(UseHttpGet = false, ResponseFormat = ResponseFormat.Json)]
public string ExportReport(int reportId)
{
    try
    {
        string output = ConfigHelper.OutputPath + "test.html"; // UNC path
        string url = ConfigHelper.VirtualPath + "test.html";
        string[] lines = { "Hello", "World!" };
        File.WriteAllLines(output, lines);                     // Access Denied!
        return url;
    }
    catch (System.Exception ex)
    {
        Logger.ErrorException("Error exporting report", ex);
        throw;
    }
}

Troubleshooting

Failed Attempts

We tried various combinations of group/user permissions on the folders (listed below). When running these tests we also ran Process Monitor. For each configuration we saw the same result. The w3wp.exe process attempted to create the file in the desired location but reported a result of ACCESS DENIED. The user of each configuration was IIS APPPOOL\My.Site.Com as expected.

  1. Granting mydomain\mymachine$ full permissions to \myotherserver\mydirectories
  2. Granting mydomain\mymachine$ full permissions to \myotherserver\mydirectories\output

NOTE: I have also tried modifying the code so that it would read a simple file from \myotherserver\mydirectories\output. When attempting to read the file, the process fails with an ACCESS DENIED message as it did when writing the file.

Successful Attempts

We also tried several configurations that worked.

Grant the local IIS APPPOOL\My.Site.Com permissions

The first configuration to work was to grant the IIS APPPOOL\My.Site.Com full permissions to \myotherserver\mydirectories The file was successfully written however the process's user was quite unexpectedly a domain account that was set up for a web application on the same machine in another website. This remains very confusing but worked as the 'other' account also has write permissions to the share.

This won't work in production as we cannot use local accounts to grant access to networked resources but is an interesting data point nonetheless.

Change the App Pool Identity to Domain User

The second configuration that worked was to change the My.Site.Com application pool's identify to domain account that had full permissions to \myotherserver\mydirectories. This was a 'vanilla' domain account that was manually created by us. We did not capture what the user of the process was but that may be another useful data point.

This option may be possible, however it breaks away from best practices with IIS 7.5 and may not be allowed in our production environment due to fairly stringent IT policies.

Run the Site On My Development Machine

The third test was to run the site locally on my development machine, mydevmachine. My local IIS configuration is identical to mywebserver with the exception that I am running Windows 7 instead of Windows Server 2008. I granted full permissions for mydomain\mydevmachine to the \myotherserver\mydirectories and ran the application. The file was successfully written. According to Process Monitor the user for the process was correctly set to IIS APPPOOL\My.Site.Com.

Conclusion

We would like to enable write access as designed using the machine account of mywebserver. We have read ApplicationPoolIdentity user cannot modify files in shared folder in Windows Server 2008 and Permissions for Shared Folder for IIS 7 Application Pool Identity Across Domain and Application Pool Identities.

According to this information we should be able use the machine account to grant read and write access to networked resources such as the UNC path. In fact, I can do this in the desired manner when running the web site from my development machine.

There are a couple thoughts that come to mind. Perhaps there is something wrong with the machine account of the test web server. Or perhaps that 'other' software is interfering with the process somehow.

Any thoughts as to what may be causing this issue? What else should we do to troubleshoot?

3
I assume that if you set the pool identity to Networkservice it can reach the share? That will rule out any issue with the machineaccount$. Next, can you remove the rights of that 'other' domain account on the share and see if your first successful scenario still works? My suspicion is that the virtual pool account is in some sort of hardened configuration on the server which blocks it from reaching outside. That could explain why your dev machine works. You can keep your tests simple for now by just trying to read a file.Amit Naidu
I'm having the exact same problem. +1 for question and +1 form comment from @AmitNaidu I tried that on mine and indeed using the NetworkService I can reach the share. However, how do we change the App Pool Identity to not have a "hardened configuration"? OP, did you ever get this to work?akousmata
@akousmata, that was just my first guess because I have seen some restrictive GPOs which may interfere with network access. But I no longer think that was the OP's issue. His symptoms closely fit the bug I described in my answer. Have you eliminated that possibility already? It's easy to verify with a simple reboot of the IIS server. If so, then you will need to dig further using procmon. Your configuration could also be different from OP's, e.g. he wasn't using impersonation and you might be.Amit Naidu
@akousmata, unfortunately I was never able to determine that my particular scenario was caused by the issue described by Amit as our environments were refreshed and the issue was no longer surfacing. Even so, I suspect that our issue was the one described in Amit's answer. That, or some flaky network issues in our environment which do cause some seemingly random authentication issues (not unheard of in our environment).Ryan Taylor
Rebooting the server fixed it. Will apply the hotfix if we see it again.akousmata

3 Answers

21
votes
  1. Reboot your 'mywebserver'.

  2. Marvel at the now mysteriously functional ApplicationPoolIdentity.

  3. Install MS HotFix KB2545850 and learn the details about this bug in KB2672809 which also shows the steps to reproduce and demonstrate this apparently random problem. Direct download link here.

  4. Speculate why Microsoft has not managed to release a normal windows update for this in the 3 years since that hotfix was published. While people still continue running into it and pulling their hair out because of this obscure problem.

  5. Learn about the other folks who have shared and enjoyed this gift from MS that still continues to keep on giving:

Your Windows 7 dev machine probably worked fine because it reboots more often than the server. Congrats on your very well written and thorough bug report. I rarely see that here.

2
votes

I had similar problem accessing a network share using AppPoolIdentity in an ASP.NET application (access denied). Using NetworkService account or other domain account worked but these were not the best solution. I performed almost all the tests you did but finally found something that worked.

I figured out that the Network Service account was not used when accessing the shares, just like you did (i expected domain\machine$ account)

This worked for us: On your IIS web site, go to Authentication and change the Anonymous Authentication item to "Application Pool Identity". It's by default set to "IUSR". This solved our problem.

Also maybe activating ASP.NET impersonation (still in Authentication menu) may help.

Thibault

0
votes

I have faced same issue, I resolved by creating one domain account for each environemt (QA, STAGE, PRODUCTION). In Application pool identity I have set custom account and I used domain user for respective account. Now It gives me the ability to write and read the files from UNC Path.