Configuring Application Pool Identity in IIS 6.0 (IIS 6.0)
When you run IIS in worker process isolation mode, applications can be configured to run in separate application pools. An application pool is a configuration that links one or more applications to a set of one or more worker processes. The application pool identity is the name of the account under which the worker process of the application pool runs.
This feature of IIS 6.0 is available only when IIS is running in worker process isolation mode.
In earlier versions of IIS, worker processes ran as the LocalSystem account. Because the LocalSystem account has access to almost all resources of the operating system, this had serious security implications. IIS 6.0 strengthens security because the worker process runs under the new built-in Network Service account by default. IIS 6.0 also allows you to configure the account under which worker processes will run. You have the option of using one of the following three predefined accounts, or creating your own account:
For example, suppose an ISP wants to allow customers to upload CGI applications and then add them to an application pool. The ISP can run CGI-enabled applications in a separate application pool under the Network Service user account, which has lower user rights, to reduce the risk that these applications will be used to attack the server.
The IIS_WPG user group is new in IIS 6.0. It provides the minimum set of privileges and permissions required to start and run a worker process on a Web server. On a clean installation of IIS 6.0, the IIS_WPG group contains the Network Service, Local Service, LocalSystem, and IWAM_ComputerName accounts.
To designate a specific user account as a worker process identity for a Web site, make the user account a member of the IIS_WPG group. This is a convenient way to configure a custom identity for a worker process without manually assigning privileges and permissions.
All worker process identities must be members of the IIS_WPG group. If the worker process identity is not in the IIS_WPG group and does not have the appropriate privileges and permissions, the associated worker process will not start. In addition, the worker process identity might not be able to launch a worker process after a modification to the operating system, such as an upgrade or service pack.
By default, the IIS_WPG group does not have the right to start CGI processes. If you create a configurable account and add it to the IIS_WPG group as a worker process identity, you must also assign this new account the following two user rights to start CGI processes: Adjust memory quotas for a process and Replace a process level token.
When you install IIS 6.0, the setup process adds an ACL to the wwwroot directory of the default Web site. This ACL gives the IIS_WPG group permission to access that directory, which means that all worker process identities in the IIS_WPG group can access the contents of this directory on the default Web site. However, you should not give this group access by ACLs to content for a specific Web site. Instead, to isolate applications, do one of the following:
For information about changing the account under which an application pool runs by using IIS Manager, see Configuring Application Pool Identity with IIS 6.0.
You can change the worker process identity programmatically by using the Microsoft® Visual Basic® Scripting Edition (VBScript) development system sample script provided in Listing 5.2. Listing 5.2 provides a customizable VBScript-based file that creates an application that runs in an application pool under the supplied identity. Then the script starts Task Manager to show the worker process, and it attempts to access the newly created application using Internet Explorer. When the script is complete, you should see, in Task Manager, a new worker process that serves the request and that runs under the supplied identity.
Listing 5.2 Sample Script for Configuring Worker Process Identity
' VBScript source code option explicit if WScript.Arguments.Count < 4 OR WScript.Arguments.Count > 5 then WScript.Echo "Usage:" WScript.Echo WScript.ScriptFullName & " username password AppPoolName vdirname <physical path for vdir>" WScript.Quit end if dim basepath : basepath = "IIS://localhost/w3svc/1/root" dim username : username = WScript.Arguments(0) dim password : password = WScript.Arguments(1) dim AppPoolName : AppPoolName = WScript.Arguments(2) dim vdirname : vdirname = WScript.Arguments(3) dim VDirPhysicalPath if WScript.Arguments.Count < 5 then VDirPhysicalPath = "c:\inetpub\wwwroot" else VDirPhysicalPath = WScript.Arguments(4) end if if CreateNewUser(username, password) = false then WScript.Echo "Error creating user " & username & ". " WScript.Quit end if if AddUserToIIS_WPG(username) = false then WScript.Echo "Error adding user " & username & " IIS_WPG. " WScript.Quit end if if CreateNewAppPool(username, password, AppPoolName) = false then WScript.Echo "Error creating AppPool " & AppPoolName & " running as user " & username & ". " WScript.Quit end if if CreateNewVDir(vdirname, vdirphysicalpath) = false then WScript.Echo "Error creating new virtual directory " & vdirname & ". " WScript.Quit end if if AssignAppPool(vdirname, AppPoolName) = false then WScript.Echo "Error assigning Application Pool " & AppPoolName & " to vdir " & vdirname & ". " WScript.Quit end if dim wsh : set wsh = CreateObject("WScript.Shell") WScript.Echo "Waiting for iisreset to return" wsh.Run "iisreset /restart",,true wsh.Run "http://localhost/" & vdirname wsh.Run "taskmgr" function AssignAppPool(vdirname, AppPoolName) dim vdirobj set vdirobj = GetObject(basepath & "/" & vdirname) vdirobj.AppPoolId = AppPoolName vdirobj.SetInfo if err = 0 then AssignAppPool = true else AssignAppPool = false end if end function function CreateNewVDir (vdirname, vdirphysicalpath) dim VdirObj, VRoot set VRoot = GetObject(basepath) set VdirObj = VRoot.Create("IIsWebVirtualDir", vdirname) VdirObj.AccessRead = True VdirObj.AccessScript = True VdirObj.Put "Path", vdirphysicalpath VdirObj.SetInfo vdirobj.AppCreate true vdirobj.SetInfo if err = 0 then CreateNewVDir = True else CreateNewVdir = false end if end function function CreateNewAppPool(username, password, AppPoolName) dim AppPools, newAppPool set AppPools = GetObject("IIS://localhost/w3svc/AppPools") set newAppPool = AppPools.Create("IIsApplicationPool", AppPoolName) newAppPool.WamUserName = username newAppPool.WamUserPass = password newAppPool.LogonMethod =1 newAppPool.AppPoolIdentityType=3 newAppPool.SetInfo if err = 0 then CreateNewAppPool = True else CreateNewAppPool = false end if end function function AddUserToIIS_WPG (username) dim nw : set nw = CreateObject("WScript.Network") dim computername : computername = nw.Computername dim MyUser dim IIS_WPG set IIS_WPG = GetObject("WinNT://" & computername & "/IIS_WPG,group") set MyUser = GetObject("WinNT://" & computername & "/" & username & ",user") if not IIS_WPG.IsMember(MyUser.AdsPath) then IIS_WPG.Add(MyUser.AdsPath) end if if err = 0 then AddUserToIIS_WPG = True else AddUserToIIS_WPG = false end if end function function CreateNewUser(username, password) dim nw : set nw = CreateObject("WScript.Network") dim computername : computername = nw.Computername dim container : set container = GetObject("WinNT://" & computername) dim newuser : set newuser = container.Create( "user", username) newuser.SetPassword(password) newuser.SetInfo if err = 0 then CreateNewUser = True else WScript.Echo "Error: " & err.Description & " - " & err.number CreateNewUser = false end if end function