tags:

views:

2387

answers:

4

Running into a problem where on certain servers we get an error that the directory name is invalid when using Path.GetTempFileName. Further investigation shows that it is trying to write a file to c:\Documents and Setting\computername\aspnet\local settings\temp (found by using Path.GetTempPath). This folder exists so I'm assuming this must be a permissions issue with respect to the asp.net account.

I've been told by some that Path.GetTempFileName should be pointing to C:\Windows\Microsoft.NET\Framework\v2.0.50727\temporaryasp.net files.

I've also been told that this problem may be due to the order in which IIS and .NET where installed on the server. I've done the typical 'aspnet_regiis -i' and checked security on the folders etc. At this point I'm stuck.

Can anyone shed some light on this?

Update:Turns out that providing 'IUSR_ComputerName' access to the folder does the trick. Is that the correct procedure? I don't seem to recall doing that in the past, and obviously, want to follow best practices to maintain security. This is, after all, part of a file upload process.

A: 

You can use Path.GetTempPath() to find out which directory to which it's trying to write.

Mark Cidade
+2  A: 

Could be because IIS_WPG does not have access to a temp folder. If you think it is a permission issue, run a Procmon on asp.net worker process and check for AccessDenied errors.

Gulzar
+3  A: 

This is probably a combination of impersonation and a mismatch of different authentication methods occurring.

There are many pieces; I'll try to go over them one by one.

Impersonation is a technique to "temporarily" switch the user account under which a thread is running. Essentially, the thread briefly gains the same rights and access -- no more, no less -- as the account that is being impersonated. As soon as the thread is done creating the web page, it "reverts" back to the original account and gets ready for the next call. This technique is used to access resources that only the user logged into your web site has access to. Hold onto the concept for a minute.

Now, by default ASP.NET runs a web site under a local account called ASPNET. Again, by default, only the ASPNET account and members of the Administrators group can write to that folder. Your temporary folder is under that account's purview. This is the second piece of the puzzle.

Impersonation doesn't happen on its own. It needs to be turn on intentionally in your web.config.

<identity impersonate="true" />

If the setting is missing or set to false, your code will execute pure and simply under the ASPNET account mentioned above. Given your error message, I'm positive that you have impersonation=true. There is nothing wrong with that! Impersonation has advantages and disadvantages that go beyond this discussion.

There is one question left: when you use impersonation, which account gets impersonated?

Unless you specify the account in the web.config (full syntax of the identity element here), the account impersonated is the one that the IIS handed over to ASP.NET. And that depends on how the user has authenticated (or not) into the site. That is your third and final piece.

The IUSR_ComputerName account is a low-rights account created by IIS. By default, this account is the account under which a web call runs if the user could not be authenticated. That is, the user comes in as an "anonymous".

In summary, this is what is happening to you:

Your user is trying to access the web site, and IIS could not authenticate the person for some reason. Because Anonymous access is ON, (or you would not see IUSRComputerName accessing the temp folder), IIS allows the user in anyway, but as a generic user. Your ASP.NET code runs and impersonates this generic IUSR___ComputerName "guest" account; only now the code doesn't have access to the things that the ASPNET account had access to, including its own temporary folder.

Granting IUSR_ComputerName WRITE access to the folder makes your symptoms go away.

But that just the symptoms. You need to review why is the person coming as "Anonymous/Guest"?

There are two likely scenarios:

a) You intended to use IIS for authentication, but the authentication settings in IIS for some of your servers are wrong.

In that case, you need to disable Anonymous access on those servers so that the usual authentication mechanisms take place. Note that you might still need to grant to your users access to that temporary folder, or use another folder instead, one to which your users already have access.

I have worked with this scenario many times, and quite frankly it gives you less headaches to forgo the Temp folder; create a dedicated folder in the server, set the proper permissions, and set its location in web.config.

b) You didn't want to authenticate people anyway, or you wanted to use ASP.NET Forms Authentication (which uses IIS's Anonymous access to bypass checks in IIS and lets ASP.NET handle the authentication directly)

This case is a bit more complicated.

You should go to IIS and disable all forms of authentication other than "Anonymous Access". Note that you can't do that in the developer's box, because the debugger needs Integrated Authentication to be enabled. So your debugging box will behave a bit different than the real server; just be aware of that.

Then, you need to decide whether you should turn impersonation OFF, or conversely, to specify the account to impersonate in the web.config. Do the first if your web server doesn't need outside resources (like a database). Do the latter if your web site does need to run under an account that has access to a database (or some other outside resource).

You have two more alternatives to specify the account to impersonate. One, you could go to IIS and change the "anonymous" account to be one with access to the resource instead of the one IIS manages for you. The second alternative is to stash the account and password encrypted in the registry. That step is a bit complicated and also goes beyond the scope of this discussion.

Good luck!

Euro Micelli
A: 

In internet i have been read a lot of times about people dont want to use Path.GetTempFileName Because they says that could return a Already Existing file o when it changes the File Extension the File Exist, then, they generate a file based on a GUID, well, this Function turns off that Problem:

VB.net

Public Shared Function GetTempFileName(ByVal extensionWithDot As String) As String
    Dim tempFileName As String
    Do
        tempFileName = Path.GetTempFileName
        If extensionWithDot IsNot Nothing Then
            tempFileName = tempFileName.Replace(Path.GetExtension(tempFileName), extensionWithDot)
        End If
    Loop While File.Exists(tempFileName)
    Return tempFileName
End Function

C#:

public static string GetTempFileName(string extensionWithDot)
{
    string tempFileName = null;
    do {
        tempFileName = Path.GetTempFileName;
        if (extensionWithDot != null) {
            tempFileName = tempFileName.Replace(Path.GetExtension(tempFileName), extensionWithDot);
        }
    }
    while (File.Exists(tempFileName));
    return tempFileName;
}
Braian Bressan