COM security frequently asked questions
This article was previously published under Q158508
The COM/DCOM security model allows you to create security-enhanced distributed applications. You can apply COM security to existing (legacy) COM components through external configuration. You can apply COM security to new COM code through COM security APIs and interfaces. This document provides tips, techniques, and troubleshooting information for developers of security-enhanced COM components.
Table of Contents
General COM Security Issues
COM Security on Windows 95
Windows NT Security Issues
General COM Security IssuesQ1 How do I enable or disable DCOM?
A. The HKEY_LOCAL_MACHINE\Software\Microsoft\OLE registry key has "EnableDCOM" as a named value. By default this value is set to "Y." To disable DCOM, change this value to "N." You can do this in the OLE/COM Object Viewer with the File.System Configuration dialog box. Changing this value requires you to restart your computer.
If EnableDCOM is not set to "Y," then all cross-computer calls are rejected (the caller, typically, receives an RPC_S_SERVER_UNAVAILABLE return code).
On Windows 95, with DCOM support, there is an additional registry setting that enables or disables incoming remote connections. The registry key is HKEY_LOCAL_MACHINE\Software\Microsoft\OLE, and the named value is "EnableRemoteConnections." By default remote connections are disabled (the value is "N"). To enable remote connections to a Windows 95 computer, change this value to "Y." You can do this in the OLE/COM Object Viewer (OLEView) with the File.System Configuration dialog box. Changing this value requires a restart.
Q2 Why do I receive E_OUTOFMEMORY when trying to access a remote object?
A. DefaultAccessPermissions does not include the SID for the SYSTEM account. Use DCOMCNFG or the OLE/COM Object Viewer to add it.
E_OUTOFMEMORY is returned, instead of E_ACCESSDENIED, because of a bug in Windows NT 4.0. This will be fixed in future releases of DCOM.
This failure may occur both when trying to activate an object (through CoCreateInstanceEx, for example) and when receiving a pointer to a remote object (in the implementation of IConnectionPoint::Advise, for example). See the question that follows, "Why does IConnectionPoint::Advise not work?"
The DefaultAccessPermissions value on your system is probably missing the SYSTEM SID because some versions of OLEView's System Configuration dialog box do not correctly add SYSTEM if no default value has been already provided (DCOMCNFG writes it correctly). The fix to this is to use either DCOMCNFG or OLEView and add "SYSTEM" to the list of SIDs in the Default Access Permissions.
Versions of OLEView with a build number greater than 46 (see the About box) correctly add the SYSTEM SID. OLEView is available for download from:
Q3 Why does IConnectionPoint::Advise not work?
A. For IConnectionPoint::Advise (or for any other interface method that passes an IUnknown pointer) to work correctly, it must have the appropriate access permissions to the object to call QueryInterface on any remote interface.
You are probably not calling CoInitializeSecurity() in your client and are therefore picking up the default DCOM-supplied security blanket. The client application must initialize security so that the server process identity is permitted to call in the client process. For this, the client must call CoInitializeSecurity and specify a security descriptor containing an ACE for the server process identity with the COM_RIGHTS_EXECUTE right. If the client does not call CoInitializeSecurity, the callback to the client is governed by the default security blanket, that is, the default authentication level and (if the former is not RPC_C_AUTHN_LEVEL_NONE) the default access permissions of the client computer.
Because you are writing a real DCOM application, you must call CoInitializeSecurity() after you call CoInitalizeEx(), such as in the following example:
By doing this, you essentially allow anyone to call to the client process. If the server hands a reference to your sink to someone in a different location and he tries to call back, he will get in just fine. See information about the different authn and impersonation levels in the Win32 SDK Help to figure out what settings make the most sense for your application.
Note that both Microsoft Foundation Classes (MFC) and Active Template Library (ATL) have bugs in their IConnectionPoint::Advise implementation. They both do essentially the following:
The bug is that they must return whatever the QI call returned instead of mapping to CONNECT_E_CANNOTCONNECT or E_NOINTERFACE. The correct way to implement a connection point is roughly the following:
Q4 I receive E_ACCESSDENIED from CoCreateInstanceEx. Why? I am an administrator on my computer and on the second computer.
A. Windows NT security principles are identified with a two-level name made up of the security authority and then the user name. The security authority is either the workstation (for a standalone Windows NT Workstation environment) or the domain if your computer that runs Windows NT Workstation is a member of a domain (all computers running Windows NT Server are members of a domain by definition). Even when in a Windows NT Server domain, computers running Windows NT Workstation continue to be their own security authorities with (potentially) local-only accounts. However, they "trust" (can pass along security requests to) the domain controls of the domain where they reside.
For example, on a domain named "Test," my security identity would be "Test\MarkRy," even if I am logged on to my computer "Markry_Tecra." But if my computer is a standalone computer (or if I log on locally), my identity would be "Markry_Tecra\MarkRy." This is a completely different security principle. You may think of computers running Windows NT Workstation as domains of one. They either trust another Windows NT (real) domain and then refer security-related decisions about principles from that domain to it (in the case where they are members of a domain), or they do not (in the case of a standalone environment).
In your case, it sounds as though you have two standalone computers running Windows NT Workstation and, therefore, two completely different security principles. You log on to one as Computer1\RJF, and the other as Computer2\RJF. The fact that your account on each is an admin account does not matter because they are different accounts.
However, you can have two computers running Windows NT Workstation that are not in the same or trusting domains (and, therefore, cannot have the same principle logged on to both at the same time) to interact with enhanced security because Windows NT Workstation falls back to a "matching account names and passwords" mode. If you use the same ASCII names on the two computers running Windows NT Workstation and the accounts have the same passwords, then DCOM and other NT security (such as filesystem) must work as though you were really logged on to the two computers with the same account.
Here are some caveats to this fallback mode:
Q5 Are there any issues with running COM servers under the system account?
A. Localsystem is a privileged account locally, so you must not run any shareware applications there. However, it has no network credentials and cannot leave the computer through any security-enhanced Windows NT mechanism, including file system, named pipes, DCOM, or security-enhanced RPC.
Q6 Why does CoRegisterClassObject return CO_E_WRONG_SERVER_IDENTITY? When launching my ATL 1.1 server service as an .exe file, I receive CO_E_WRONG_SERVER_IDENTITY from CoRegisterClassObject. (The class is configured to run as a security ID different from the caller.) This seems to occur whether I skip the CoInitializeSecurity or not. It fails running as a service or as an .exe file.
A. Many services are debugged by running them as console applications in the interactive user identity. Because the service is already registered to run in a different identity (configurable by the Services control panel applet), OLE fails the CoRegisterClassObject and RunningObjectTable::Register(ROTFLAGS_ALLOWANYCLIENT) calls by returning CO_E_WRONG_SERVER_IDENTITY to enforce security and to prevent malicious servers from spoofing the server. To debug by running in the interactive user's identity, make the following changes in the server's registry entries to prevent these failures:
Q7 Does DCOM support delegate-level impersonation?
A. No. See question 8 for details.
Q8 LocalServer32 entries with UNC names cannot be remotely activated. Why? If I put a UNC in the LocalServer32 entry of a DCOM object, that object may no longer be launched from a remote computer. Is there a security patch or workaround other than the following one? DCOM tries to access the LocalServer32 executable from the System account (null session). If you configure the computer where the executable is located to permit null session access, then the problem disappears. Do this by setting the following registry value to 0:
This value is a DWORD and is documented in the "Server Service Entries" article of the DevNet CD. It requires a computer restart to take effect. This is apparently a bug in DCOM. DCOM uses the RunAs key to determine how to access the server executable and impersonate that user before trying any access.
A. It is not a bug in DCOM. Try it yourself: impersonate a user coming from a remote computer and then try any network-related operation that uses NT security. It does not work. If it did work, impersonation can form an endless chain. Allowing threads to impersonate you would be much more risky, as the threads may then open your e-mail folder on a remote computer, and may also change your password on the domain controllers.
Windows NT 5.0 supports full security delegation (what it would take to make chaining scenarios work) but only when several additional safeguards are in place, most notably the enforcement of *expirations* on delegated security rights (so at least you know that the right to do these kind of nasty things expires after several minutes or whatever you set). The other safeguard would be an extension to the ACL model that would permit you to distinguish between the "real" you and your delegates.
Q9 Why can my server not access network resources?
A. See question 10.
Q10 What are the limitations of RunAs the Launching User? I have a dual server that accesses files on its computer through a method call, ITest::Do(). When I deploy my server on Windows NT 4.0 Workstation and use the default security of Launching User, file access does not work when I call my method ITest:Do() remotely. It fails with an access permission.
I would expect identity "Launching User" if I had an administrator user on computer A and the same administrator user on computer B. Then the identity of my launched server would be that administrator user on computer B. However, it drops some rights because my file access fails. When I set the identity to RunAs with the administrator user on computer B, everything works. What is the difference?
A. Are the computers in a Windows NT domain using the SAME account? Or are they stand-alone computers running Windows NT Workstation, therefore using accounts with the same *name* but actually different accounts (because the security authorities are different)? Recall that each computer running Windows NT Workstation is a security authority, and an account MarkR on computer1 (computer1\MarkR) is a different account than account MarkR on computer 2 (computer2\MarkR)). These issues are covered in additional detail in question 4, titled "I receive E_ACCESSDENIED from CoCreateInstanceEx. Why?"
Also, is the NTFS file system access local to the computer where the server is running or is it remote? All remote filesystem accesses fail for any localservers launched as Launching User (except for those launched from in the interactive account) fail.
The "run as Launching User" feature of DCOM is quite limited and must typically be avoided. The Launching User mode requires that DCOM impersonate the caller before starting the localserver. The process that results does not have a full security token of the caller.
These limitations have to do with NT security limitations as discussed in question 7, "Does DCOM Support Delegation Level Impersonation?"
These limitations (both with security and with how DCOM is affected) will be removed, or at least greatly improved, in Windows NT 5.0.
Q11 Should I use AccessCheck or IsValidSecurityDescriptor?
A. AccessCheck actually checks for valid access rights. IsValidSecurityDescriptor verifies that the structure is correctly formed.
Q12 How can I receive a log of AccessCheck failures?
A. The Debug version of Ole32.dll (included in the checked build of Windows NT) prints messages to the debugger when AccessCheck calls fail. Future versions of DCOM will support auditing.
Q13 How can I troubleshoot activation problems?
A. If you have a sound card in your computer, enable the "process start" and "process stop" sounds. If you hear the process start sound when you do an activation, but you still receive an error (like E_ACCESSDENIED), you know that activation worked and your problem is related to call-level security. Remember that start permissions must always be more restrictive than access permissions. Look in the event log on the client and server computers.
Q14 Why do I receive a "User32.dll cannot be initialized" error message?
A. An application without permissions tried to access the desktop.
Q15 Why do I receive a "Shell32.dll cannot be initialized" error message?
A. The user did not log on to the computer, but an application tried to access the user profile. Some API calls require the running user profile to be present on the computer. The profile is not created until you log on.
Q16 How can I troubleshoot call-level problems?
A. If activation works, but calls fail, consider the following:
A. Consider the following:
A. A COM server that is an EXE must include the IUSR_computername Internet guest account in its start and access security permissions before it can be launched by an ISAPI extension DLL. Additionally, if the server is an EXE server that is not a Win32 service, it must be configured to run under a specific user account using the RunAs registry value. For additional information, click the following article number to view the article in the Microsoft Knowledge Base:
156223 HOWTO: Launching OLE servers from ISAPI extensions
COM Security on Windows 95This section discusses COM security issues relating to the DCOM enabled version of COM for Windows 95.
Q19 Where can I download DCOM for Windows 95?
A. You can download DCOM for Windows 95 from the COM/OLE developer site. For more information, visit the following Microsoft Developer Network (MSDN) Web site:
Q20 May I redistribute DCOM for Windows 95?
A. When the release version of DCOM for Windows 95 is available, you can redistribute a self-installing .exe file that updates the end users system with DCOM for Windows 95 and have your application's setup program spawn it.
Full details of how you must do this, including redistribution terms, are documented in the EULA agreement contained in the self-extracting .exe file.
Q21 What Security Features are in COM on Windows 95?
A. There were no security-enhancement issues related to COM on Windows 95 before the release of the DCOM-enabled version of COM for Windows. COM on Windows 95 had no security. The DCOM-enabled version of COM for Windows 95 includes a subset of the COM security that you find on Windows NT. The following items detail what is supported and what is not:
Windows NT Security Issues
The COM Security architecture leverages the design and ideas of the Windows NT security architecture.
Q22 Where can I find more information about Windows NT Security?
A. See the References section of this article.
For additional information, click the following article number to view the article in the Microsoft Knowledge Base:
156673 How to launch OLE servers from ISAPI extensionsWin32 Programmers Reference; search on Overview, System Services, and Security
MSDN Security API series; search on Windows NT Security in Theory and Practice, The Guts of Security, Security Bits and Pieces, and A Homegrown RPC Mechanism