Normal Users On Terminal Server Fail To Run .Net Framework Applications

Yesterday I spent a couple of hours running through a live debug via Office Live Meeting (OLM) to narrow down a customer’s issue. The customer was attempting to run a .Net control from his web pages. These work fine if the user is an admin or a normal user logged in directly to a Windows 2000 SP4 machine however if the account is a normal user and if they are using Remote Desktop (Terminal Server Client) to connect to the server the control will not load. Other CLR/.Net applications fail to load as well.

The problem is that we get an Access Denied error when we call into CreateFileMapping when creating a block of memory for IPC. The call returns a NULL with a GetLastError of 5. This failure bubbles back up and causes the CLR to fail to load. A global is set so that the operation is not retired until the browser is restarted.

This problem occurs if all the following are true:
1. You log on to the Terminal server as a limited user (a user without administrator rights).

2. The Terminal server is running Microsoft Windows 2000 Service Pack 4 (SP4) and has the .NET Framework 1.0 installed with or without any Framework SP (in my case we had SP3 installed).

3. The .NET Framework 1.1 or later has not been installed on the machine.


To work around this problem without installing the 1.1 framework:

1. On the Windows 2000 SP4-based Terminal server, locate the following registry subkey:

            HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Kernel

2. Add the following registry values:
                        Value name: "ObUnsecureGlobalNames"
                        Value type: "REG_MULTI_SZ"
                        Value data: "Cor_Private_IPCBlock"
                        Value data: "netfxcustomerfcounters.1.0"
                        Value data: "SharedPerfIPCBlock"


3. Restart the server.


Issues similar to this one are documented in the following KBs:

823485 Errors occur when you use a .NET Framework 1.0-based program on a...

823502 Cannot Create a New Visual Studio .NET Project on a Windows 2000

The 1.1 Framework creates these registry entries when it is installed so installing the 1.1 or 2.0 framework as the KBs suggests will resolve the issue however may create a new one. The CLR shim mscoree.dll will attempt to always load the latest version of the CLR installed on the machine when loading an assembly through a COM interop such as what we are doing here when IE is loading our control. If the control is not compatible with the latest version it may fail to load or work properly. For more information on how to configure the loading of a specific version of the CLR go here.

The registry key “ObUnsecureGlobalNames” holds a list of object names. If an object is listed in the key, calls to ObpIsUnsecureName against that object will return TRUE. This is a way around for normal users who do not have the SeCreateGlobalPrivilege right which is typically required to create global objects. If the name is unsecured (i.e. listed in this registry value), access to and the creation of such objects in terminal server sessions is permitted.