What User Identity does IIS use to run code like ISAPI and CGI, Part 2
I seem to have forgotten to describe how the following aspect of IIS functions in the prior post because I was concentrated on clarifying something else (that your Windows logon is NOT the same as logon via IIS). Thus, I got the following followup:
Question:
I am confused with your explanation in the 3 paragraph from bottom.
I thought that the configured Authentication has bearing only only whether the user is authenticated and permitted to access the resources (provided his identity has appropriate authorizations).
The identity under which the ISAPI DLL would run would be governed by the process identity of INETINFO.exe or W3wp.exe. This inturn is determined by the App pool account.
Pls. correct me if my understanding is incorrect.
thanks
Answer:
Yes, you are describing one of many common misunderstanding about the user identity IIS uses to executes requests and run code like ISAPI and CGI.
Overall, the desired IIS behavior is to run user applications as the authenticated user identity, whatever it is.
Authentication controls the protocols that IIS will use to negotiate user identity with the client. At the end of Authentication, IIS expects to either reject with a 401 because the client failed to provide sufficient/correct user identification, or IIS will have a NT User Token that represents the user principle.
Then, IIS will use this NT User Token to perform all Authorization (access checks) against the requested resource.
Since anonymous authentication does not negotiate any user principle, it means that this authentication process MUST use some other pre-determined username/password. This is why IIS creates the IUSR_machine account and why you want to keep the username/password in sync within the metabase. If this username/password is incorrect, IIS will be unable to allow anonymous access because it cannot login the user identity to get a NT User Token to process the request, and it will return a 401.1.
After Authentication and Authorization finishes, IIS has two NT user tokens with which it can choose to execute this request with:
- The NT User Token obtained through the Authentication process
- The Process Identity
By design, IIS executes code in the following way:
- For ISAPI Filter DLL, the code is executed using the process identity. IIS will not impersonate user identity prior to invoking its entrypoints. This makes a lot of sense because impersonation is expensive and ISAPI Filter runs during request processing itself - and IIS certainly does not impersonate unnecessarily.
- For ISAPI Extension DLL, the code is executed by impersonating the NT User Token obtained through Authentication. This allows ISAPI applications like ASP and ASP.Net to offer security checks based on the remote user's identity - a powerful integration feature.
- For CGI EXE, it depends on the value of the "CreateProcessAsUser" metabase property applicable to the URL. It defaults to TRUE and means to create the CGI process using the NT User Token obtained through Authentication. If FALSE, then the Process Identity is used instead.
Now, how the ISAPI and CGI chooses to execute code afterwards, that behavior is completely arbitrary and outside of IIS control. For example:
- ASP chooses to keep the impersonated identity and use it to execute the page and access resources
- ASP.Net allows configuration via the <identity> element. You can tell ASP.Net to keep the impersonated identity, strip it off and use the Process Identity, or impersonate a totally new username/password to execute code
Finally, ISAPIs like ASP and ASP.Net are application frameworks that allow arbitrary user code to run, so some of that user code CAN change the impersonation token of a thread (which subsequently changes the identity used to execute other code on that thread [until the thread token is reset, of course - but this is no longer documented nor reliable behavior]). Thus, it is also possible for some COM components instantiated in your ASP page or global.asa file, or Managed code classes calling RevertToSelf() or otherwise stripping/resetting the impersonation token, to change the effective user identity that executes code on the server.
//David
Comments
Anonymous
June 29, 2005
What User Identity does IIS use to run code like ISAPI and CGI.Anonymous
July 15, 2005
One of the most common questions asked about IIS on the newsgroups as well as Microsoft Product Support...Anonymous
July 20, 2005
One of the most common questions asked about IIS on the newsgroups as well as Microsoft Product Support...Anonymous
August 23, 2005
The comment has been removedAnonymous
February 27, 2006
Great info. I do have a question for you. If the IUSR_Machinename account is out of sync with the OS how do you correct this issue?
Thanks in advance and thanks for the article!
MartinAnonymous
February 27, 2006
The comment has been removedAnonymous
March 09, 2006
Thanks for your answer to my question and I did do what you sugested. This is how I know the password is out of sync.
What I really want to know is how do I tell IIS to get the new password for the IUSR accnt or how do I manually reset it.
I'm a programmer and create a number of sites on several different servers. Usally when a site is created IIS populates the ananymous access option with the ISUR accnt and correct password. In the case of this server it doesn't.
For the sanity of myself and other programmers in the company it would be benifitial if all the servers behaved consistently.
Thanks again.
MartinAnonymous
March 09, 2006
Martin - You cannot tell IIS to get the new password because it does not "own" the account. IIS can create the account when it doesn't exist, so it can obviously set the password and synchronize at that point. This is how it usually works and no one has to do anything. However, if you subsequently change things, either by changing the password for the user account or if you configure a different anonymous user, you are obviously responsible for synchronizing it at all places.
At this point, it sounds like you either have:
1. W3SVC/AnonymousUser* is out of sync with the NT user account on that server
2. Your creation of websites is explicitly setting AnonymousUser* that is out of sync with that server
For #1, my previous comment should allow you to address your issue. For #2, you need to fix your website creation code to use the right password.
Personally, I suggest #1, where your site creation code does not set AnonymousUser* and let the local inheritance automatically work out... unless for some reason you need to explicitly control the anonymous user account... in which case you must do the work of #2.
//DavidAnonymous
April 10, 2006
The comment has been removedAnonymous
April 10, 2006
Laxmikanth - Actually, your question illustrates the detailed understanding one must have to distinguish when code is run "by ASP" or "by something else".
The difference here is NOT in the user impersonation done by the Worker Process but rather how CreateProcess() and the code it invokes interprets it.
1. The Run() method of the Windows Scripting Host "WScript.Shell" object uses CreateProcess() to launch the command (you can easily figure this out by attaching a debugger with public symbols, setting breakpoints on CreateProcess*, and watching what gets hit)
2. Here is documentation for CreateProcess() http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/createprocess.asp
3. Note that the documentation states:
If the calling process is impersonating another user, the new process uses the token for the calling process, not the impersonation token. To run the new process in the security context of the user represented by the impersonation token, use the CreateProcessAsUser or CreateProcessWithLogonW function.
Thus, it is the Process Identity, not Impersonated Identity, which is used to run the STSADM.EXE. Thus, when you configure the AppPool as Network Service, it should not work, regardless of impersonated identity.
As for why it "worked" when the Process Identity is not a local administrator - I am not sure, but it is easy to attach a debugger and use lsaexts.dumpToken() to figure out the difference.
In any case, the difference is not in how IIS performs the Impersonation (there's only one way to do it) but rather in how invoked code use and interpret the Impersonation.
//DavidAnonymous
April 11, 2006
David,
Thanks for your quick and prompt respone.
I believe I do not understand your response completely, but I would take time to read through it and discuss with my friends.
I shall write back to you in case of further questions.
Once again, thanks a ton for your prompt response.Anonymous
April 21, 2006
Sigh... security continues to befuddle users... because why would you change the Service User Account&nbsp;from...Anonymous
April 28, 2006
I finally have enough blog entries about various portions of IIS6 request processing that I can stitch...Anonymous
May 11, 2006
Every once in a while, I see users asking about how to automate Office applications on the server, either...Anonymous
May 21, 2006
David - you seem like the right resource for this question. I have a client who has created their own Web site. This was built over time from simple HTML pages and eventually grew into ASP pages and the like. They use a database for authentication of users and save the user token in a cookie. I don't believe this to be relevant except that I want you to understand they do NOT use NT Authentication for users and will not in the forseeable future.
There is one page in their site that programatically creates, modifies, or deletes files on the site. Currently, the IUSR_account has fill rights to the site directory (create, modify, ...). I would like to set the IUSR_account rights to something lower and have this single page run as a different user.
How can this be done?Anonymous
May 25, 2006
The comment has been removedAnonymous
June 08, 2006
Michael - I suggest configuring a dedicated user account for use as Anonymous user account for that specific page, and give this user account full rights on the necessary directories/files to create/modify/delete files.
Now, you may choose to limit the privileges of this particular user (user privileges are different from account rights to resources) as well as configure which part of the URL namespace has this anonymous user applicable. Of course, this approach has other security ramifications (such as repudiation), but that is really a flaw within this custom authorization scheme.
//DavidAnonymous
June 08, 2006
The comment has been removedAnonymous
June 28, 2006
The comment has been removedAnonymous
June 28, 2006
Chris - the 502 error ("The specified CGI application misbehaved by not returning a complete set of HTTP headers") has to do with the response generated by the .pl script. It usually has nothing to do with the topic of this blog entry - user identity - unless the script blows up when running as the wrong user identity and generates a non-HTTP response -- which would then show up as a 502.
The most important thing to diagnosing a 502 is to determine what the CGI script sent as the response. This can be done either by:
1. running the .pl script from the commandline as the appropriate user account and with the proper CGI environment variables set.
2. renaming the .pl to have a nph- prefix and make a request with a raw HTTP Client like WFetch to view the actual response generated by the .pl script as IIS runs it.
#2 is the more realistic and my preferred verification method. It does require renaming a file and using a raw HTTP Client like WFetch from the IIS6 Resource Kit, but it is worth it because some CGI errors can only be debugged this way.
//DavidAnonymous
June 28, 2006
The comment has been removedAnonymous
June 28, 2006
Chris - NT4 was also insecure and allowed Everyone Full Control, so the fact that it "works" on it does not mean it was anywhere near secure enough to work on Windows Server 2003 and IIS6.
I would not assume that the problem is related to the "lock down of IUSR in IIS6" unless I see evidence. Guessing based on what you have read, without concrete evidence, is ineffective troubleshooting.
I suggest starting from what you do observe - a 502 response - and work backwards from there because everything is then based on fact. 502 tells you that executing the CGI did not generate a proper response. There is no way that I jump from there to assuming that something is wrong with the anonymous user account and start acting on that assumption. I would try to isolate that response and examine what is not "proper" about it before making further assessments.
If the response does not conform to CGI specifications, which IIS6 now checks (while previous IIS versions did not check), then that indicates a problem with the .pl script that needs to be fixed. Remember, just because it worked on IIS4 does not mean it is correct.
If the response looks like an error response because of insufficient privileges, then depending on the authentication protocol, that suggests a problem with remote authenticated account. If anonymous protocol was chosen, then it is the anonymous user account that you configured. Domain IUSR and local IUSR are two totally different accounts (and Guest is a totally different account with different lockdown) with different names and possibly passwords, so I would never assume they give the same behavior when used by your script.
My guess is that the latter is happening for local IUSR/Guest and is probably "by-design" - because it sounds like the .pl script is designed to work with the old domain IUSR.
It is always your responsibility to figure out the correct user and privileges required by your application. If you don't know, then you need to learn how to figure it out.
//DavidAnonymous
August 18, 2006
It's a 10K entry!
//DavidAnonymous
August 24, 2006
After getting pass the 403.1 error in running perl scripts, I'm now getting a 502 error. File Monitor was able to tell me the error was caused by the script not finding the perl56.dll file. I'm not sure why, but the script is looking for the dll file in the site's root folder. I can get around this problem by copy/paste the dll file to the root, but that's obviously not the way to solve this. I was wondering if you have any suggestions?Anonymous
August 25, 2006
The comment has been removedAnonymous
August 27, 2006
Mark - Your question is not really related to IIS.
IIS just loads the ISAPI DLL or executes the CGI EXE. Any additional dependencies is the responsibility of the ISAPI/CGI itself.
For example, if it is a runtime DLL loading dependency, then it is really PERL not installed correctly - which I can only suggest to contact the Perl support groups for advice.
//DavidAnonymous
August 27, 2006
The comment has been removedAnonymous
April 24, 2007
Can you further clarify the identity used when using an ISAPI extension such as PHP and you're using the default Application Pool identity of "NETWORK SERVICE"? The article seems to imply it should be using the app pool id as it's identity but it looks like its still using the IUSR id. When trying to call a PHP page anonymously (with anonymous access on for the website), I get the following from Authentication & Access Control Monitoring: ProcIdentity="NT AUTHORITYNETWORK SERVICE" ThreadIdentity="XXXXIUSR_YYYYYYY" I want to tie down file access and ACLS for the PHP installation to the Service not the IUSR!Anonymous
April 24, 2007
Addendum.... not the right log entries... To summarise.. looks like the verification of the PHP DLL is done using the NETWORK SERVICE. This works because NTFS perms have been set, but then subsequent access is using the IUSR id. GRR. Any help would be appreciated.Anonymous
June 19, 2007
Hello, I'm working on an ASP website with IIS 6 and Windows Server 2003. Something weird is happening and you seem like the one to help. I get page cannot be displayed on any attempt to call a shell command from the asp page. I've set all (I*) users in with full permissions. The funny thing is that when I remote login it works fine. Could you help? Thanks, JohnAnonymous
August 28, 2007
Hi, My .NET application uses word automation to create new documents. With Word Identity as 'Interactive user', my application works fine on the development machine. When I deploy it on the client server, it gives error saying the 'Configured identity is incorrect'. How do I configure IIS to run for Interactive user? Thanks, PritiAnonymous
November 17, 2007
Anonymous - For PHP ISAPI EXTENSION, what you observed is exactly correct and what you configured. IIS runs ISAPI Extension with the impersonated identity, which you've configured as IUSR for Anonymous authentication. IIS verifies PHP ISAPI DLL using process identity since it does the impersonation right before executing the ISAPI Extension DLL, while verification happens way earlier. There is no way for you to tie down PHP ISAPI access to just the process identity. It is not how IIS works. //DavidAnonymous
May 08, 2008
Hello David, I am Andre from the Netherlands. I just want to say that you helped me out wiht this great site. So, thank you. Best regards, AndreAnonymous
July 11, 2008
Hi, i discovered, that using FastCGI, PHP run's under the process identity. With fastcgi.impersonate = 1 in PHP.INI you can selectively switch back to the anonymous / authenticated user. I'm going to try this on one of my production Servers. @David: Thank you so much for this great blog. I learned so much from your postings!Anonymous
January 07, 2010
Does anyone know where I can find more literatures on how to configure impersonation account on IIS? I read all explanation but needs a little example. thanks