Rajiv Dulepet
Introduction
Registry
Activation Security
Call Security
Common Scenarios
References
The Component Object Model (COM) can make distributed applications secure without any security-specific coding or design in either the client or the component. Just as the COM programming model hides a component's location, it also hides the security requirements of a component. The same binary code that works in a single-machine environment, in which security may be of no concern, can be used securely in a distributed environment.
COM provides two distinguishable categories of security. The first is termed activation security, and it controls which objects a client is allowed to instantiate. The second form is call security, which dictates how security operates at the per-call level on an established connection from a client to a server object.
This article describes the exact capabilities of COM security in greater detail.
Entries in the system registry can affect how COM security allows the activation and calling of objects by a remote client. COM provides mechanisms to externally configure security settings for objects and clients. In the current implementations of COM, all security policies are enforced at the process level. All objects in a process share the same security policies unless they programmatically override them. (Details on call security are provided later in this document.) To match this process-wide security configuration, COM introduces the concept of an application identifier, or APPID.
To change the security settings for the server, you can either edit System Registry entries directly or use the DCOMCNFG or OLE/COM Object Viewer utility.
APPIDs group the configuration options for one or more COM objects into one centralized location in the registry. COM objects hosted by the same executable must map to the same APPID. In-process COM objects on a single machine that are run remotely can be forced into the same surrogate process by assigning the same APPID to their Class ID (CLSID) entries.
DCOMCNFG is a utility you can use to configure various COM-specific settings in the registry. This configuration utility, dcomcnfg.exe, is included in the Microsoft® Windows NT® operating system and is used to configure applications to use COM. The dcomcnfg.exe utility is not added to the Start menu or any groups during installation of Windows NT version 4.0. An administrator must start it from the Run command on the Start menu.
DCOMCONFG must be used to configure an application's COM properties before the application can use COM to communicate over the network. The DCOMCONFG utility can be used to:
Both the computers that are running the client and the server applications must be configured for a distributed environment with the DCOMCONFG utility:
When DCOMCNFG starts, it displays the Distributed COM Configuration Properties dialog box. This dialog box has three tabs: Default Security, Default Properties, and Applications.
You can use the Default Security tab to specify default permissions for objects on the system. This tab has three sections: Access, Launch, and Configuration. To change a section's defaults, click the corresponding Edit Default button. These default security settings are stored in the registry under HKEY_LOCAL_MACHINE\Software\Microsoft\OLE.
Figure 1. The Default Security tab
On the Default Properties tab, you must select the Enable Distributed COM on This Computer check box if you want clients on other machines to access COM objects running on this machine. Selecting this option sets the HKEY_LOCAL_MACHINE\Software\Microsoft\OLE\EnableDCOM value to Y.
Figure 2. The Default Properties tab
You can change the settings for a particular object from the Applications tab. To do so, you select the application from the list and click the Properties button. This action displays the Object Properties dialog box for the selected application.
Figure 3. The Applications tab
The Object Properties dialog box has four tabs:
Figure 4. The Object Properties dialog box
The OLE/COM Object Viewer (OLEView) is an administration and testing tool for developers and power users. It is the second way to configure security options for a component. With the OLE/COM Object Viewer, you can:
Figure 5. The OLE/COM Object Viewer
OLEView provides more information than DCOMCNFG, and you can use it for all the settings done by DCOMCNFG except one: OLEView has no way to set the COM server to "RunAs" a certain user. The other major difference between DCOMCNFG and OLEView is that DCOMCNFG shows only the servers with APPIDs. OLEView allows the component to use Default Access and Launch permissions, but unlike DCOMCNFG it doesn't allow the user to modify the Default settings.
In essence, OLEView provides all the functionality provided by clicking the Properties button in the Application tab of DCOMCNFG except for RunAs identity, and it also provides a subset of the Default Properties and Default Security tabs of DCOMCNFG.
Activation security controls which classes a client is allowed to launch and retrieve objects from. The Service Control Manager of a particular machine automatically applies activation security. Upon receipt of a request from a remote client to activate an object (see the client activation services outlined earlier in this document), the Service Control Manager of the machine checks the request against the following information stored within its registry:
These settings are described in the following sections.
The following named values, which appear under HKEY_LOCAL_MACHINE\Software\Microsoft\OLE, control the global activation policies of the machine. Only machine administrators and the system have full access to this portion of the registry. All other users have read-only access.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole]
"EnableDCOM"="Y"
"DefaultLaunchPermission" = hex: [self-relative security descriptor]
The EnableDCOM named value allows or disallows remote clients to launch class code and connect to objects for the system. The DefaultLaunchPermission named value, as the name implies, sets the default access control list (ACL) to specify who has access to classes on the system.
The following key may be added under any class's APPID key (HKEY_CLASSES_ROOT\APPID\{...}) to limit activation by remote clients of specific classes. By definition, Launch security needs to be enforced by the COM libraries themselves, since the object that could potentially perform this check has not been instantiated yet. For this reason, launch security can only be externally configured and cannot be controlled programmatically.
Activation security is automatically applied by the Service Control Manager (SCM) of a particular machine. Upon receipt of a request from a remote client to activate an object, the SCM on the server machine checks the request against the HKEY_CLASSES_ROOT\AppID\{...}\LaunchPermission key, which contains data describing the access control list (ACL). If the user's access control entry (ACE) is not contained within the ACL, access is denied. If the APPID does not have a LaunchPermission key, the SCM checks the request against the ACL in the DefaultLaunchPermission key under HKEY_LOCAL_MACHINE\Software\Microsoft\OLE.
Launch security affords administrators granular control over who can instantiate COM objects for use by others and therefore protects business processes (as an example) from malicious or accidental initialization. For example, you may want to restrict instantiation of accounts-payable processes to employees in the Accounting group, or you may want to develop a COM server as a Windows NT service that can be started only by a specific service account.
Using the DCOM Configuration utility included with Windows NT (dcomcnfg.exe), an administrator can control activation security at both the machine level and the object level. In addition to launch security, an administrator can control who can access a particular object (access security) and who can alter registry settings related to a particular object (configuration access).
If an account may both launch and access an object, the account must appear on both the Launch and Access security access lists. DCOMCNFG does not enforce this constraint.
COM provides two mechanisms to secure calls. The first is similar to DCE RPC: COM provides functions and interfaces that applications can use to do their own security checking. The second mechanism is run automatically by COM. If the application provides some setup information, COM will make all the necessary checks to secure the application's objects. This automatic mechanism does security checking for the process, not for individual objects or methods. Applications requiring more fine-grained security can perform their own security checking. The two mechanisms are not exclusive: an application can ask COM to perform automatic security checking and also perform its own.
COM call-security services are divided into three categories: general functions called by both clients and servers, new interfaces on client proxies, and server-side functions and call-context interfaces. The general functions initialize the automatic security mechanism and register authentication services. The proxy interfaces allow the client to control security on calls to individual interfaces. The server functions and interfaces allow the server to retrieve security information about a call and to impersonate the caller.
In a typical scenario, the client queries an existing object for IClientSecurity, which is implemented locally by the interface remoting layer. The client uses IClientSecurity to control the security of individual interface proxies on the object, prior to making a call on one of the interfaces. When a call arrives at the server, the server can call CoGetCallContext to retrieve an IServerSecurity interface. IServerSecurity allows the server to check the client's authentication and to impersonate the client, if needed. The IServerSecurity object is valid for the duration of the call. The client can call CoInitializeSecurity to establish default call security for the process, avoiding the use of IClientSecurity on individual proxies. CoInitializeSecurity allows a server to register automatic authentication services for the process. Registering authentication services with CoRegisterAuthenticationServices does not prevent calls from arriving with no authentication service or with an unregistered authentication service.
Implementations of QueryInterface must never check ACLs. COM requires that an object that supports a particular IID always return success when queried for that IID. Even if COM did not enforce that requirement, checking ACLs on QueryInterface would not provide any real security. If Client A legally has access to interface IFoo, Client A can hand a pointer to IFoo directly to Client B without any calls back to the server. Additionally, COM caches interface pointers and will not call QueryInterface on the server every time a client does a query.
Each time a proxy is created, COM sets the security information to default values, which are the values used for automatic security.
The flow of control looks something like this for client/server negotiation:
The following named values appear in HKEY_LOCAL_MACHINE\Software\Microsoft\OLE and control COM call-level security capabilities in applications that do not call CoInitializeSecurity. Only machine administrators and the system have full access to this portion of the registry. All other users have read-only access.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Ole]
"DefaultAccessPermission" = hex: [self-relative security descriptor]
"LegacyImpersonationLevel" = dword:2
"LegacyAuthenticationLevel" = dword:2
"LegacyMutualAuthentication"=dword:2
"LegacySecureReferences{ XE "LegacySecureReferences"}"=dword:2
The following named values can be added under any class's APPID key (HKEY_CLASSES_ROOT\APPID\{...}) to limit access to objects of a specific class.
This named value is of type REG_BINARY. It contains data describing the ACL of the principals that can access instances of this class. Upon receiving a request to connect to an existing object of this class, the ACL is checked while impersonating the caller. If the access check fails, the connection is disallowed. If this named value does not exist, the machine-wide DefaultAccessPermission ACL is tested in an identical manner (see above) as a default to determine if the connection is to be allowed.
This section illustrates how COM security can be used in some common scenarios.
When a Windows 95 COM server is used to serve objects to remote clients, make sure to:
The authentication level is negotiated as follows: If you have a Windows 95 client with authentication level Connect and a Windows NT server object with authentication level Encrypt, COM will try to use Encrypt for calls in both directions. Since Windows 95 cannot receive calls at Encrypt, the Windows NT computer cannot call the Windows 95 machine. Thus both the client and server have to set the authentication level to the lowest value allowable for any call in any direction.
Similarly, if you have two processes, one with a logon token and the other with an impersonation token, and you set the authentication level to none in the second, it still won't be able to call the first if its authentication level is not none.
Please refer to "FAQ: COM Security Frequently Asked Questions," Knowledge Base article #Q158508, in the MSDN™ Library.
Three named values in the registry apply to legacy code written before DCOM. These named values exist under the HKEY_LOCAL_MACHINE\Software\Microsoft\OLE\legacy key, and COM uses them to determine what parameters to pass to CoInitializeSecurity on the server's behalf:
Launching a COM object on a computer running the Windows NT 4.0 operating system requires certain permissions. This is not normally an issue for most interactive users, because the default permissions for launching and accessing COM objects on Windows NT allow access to anyone interactively logged on to the local machine. A Microsoft Internet Information Server (IIS) application, whether it is running in the context of the IUSR_<servername> account or as an impersonated user account from Basic or NTLM authentication, is not interactively logged on. Therefore, the default permissions for launching and accessing COM objects will not allow an ISAPI extension dynamic-link library (DLL), computer graphics interface (CGI) application, or Internet script to launch these objects successfully by default.
With the DCOMCNFG utility on Windows NT 4.0, you can set the default permissions for all COM objects on your machine. You can use DCOMCNFG to provide COM access to the IUSR_<servername> account, as well as to all user accounts that might be impersonated by your IIS configuration. You can even grant permissions to the "Everyone" group.
However, providing global access to all COM objects may not be in your best interests, so you can use DCOMCNFG to specify permissions for specific applications. In this way, you can provide access only to the applications you will need to access from your IIS application. COM applications can also determine what permissions are associated with launching and accessing themselves. To do so from inside your COM server, see the documentation for the CoInitializeSecurity function new to Windows NT 4.0, as well as that for CoCreateInstanceEx (in particular, the COSERVERINFO and COAUTHINFO structures) for manipulating COM access from the client side.
For more information on launching COM servers from ISAPI applications, see the "References" section of the article.
COM requires all of the permissions discussed above. In addition, it needs to access resources across the network. If a request is received using anonymous authentication, the IUSR_<servername> account username and password credentials will be used to connect to the remote COM server. Unless your IIS server machine is also a domain controller, the remote machine by default will not be able to determine who the IUSR_<servername> account is. (It exists only on the local IIS server machine.) Adding access and launch permissions to the group "Everyone" does not help in this case, because COM will not map access by an unknown account to the guest account in the same way that the LAN Manager service does for file sharing. The COM server machine must explicitly know the account that is being used.
When IIS applications are accessing resources (including COM resources) on remote machines, all the machines involved must participate in a domain relationship. Then, in Internet Manager, you can change your anonymous account to an account in the local or trusted domain. Now all machines in the domain structure will recognize the account and can explicitly add and delete access to their network resources for that account or for any groups that account is a member.
Be aware that if basic authentication is used for an IIS request, access to network resources (including COM servers) will be provided in the context of the user whose credentials were passed with the request. If the user specified does not have permissions to launch or access the COM server, the request will fail.
If the IIS request is validated using NTLM authentication, the impersonation level does not imply knowledge of the user name and password credentials. Therefore, access to network resources, regardless of the permissions on the resource, will be denied (with the exception of null session resources).
Please refer to "HOWTO: Launching OLE Servers from ISAPI Extensions," Knowledge Base article #Q156223, in the MSDN™ Library.
Since Microsoft Visual Basic® and Microsoft Internet Explorer COM clients cannot call CoInitializeSecurity, you need to set the default authentication level to "None."
In this section we will use the Sales Training Roadmap sample application to demonstrate how call-level security functions are used. In this application, the engineers and managers have a training plan. The application has the following characteristics and rules:
The application is implemented as a Training COM object connected to a Microsoft SQL Server™ database. The implementation consists of one COM object with three interfaces: IEngineer, IManager, and IDatabase. IDatabase is an internal interface and is not accessible by the client. The object runs as an out-of-process server accessed by remote clients. Users are identified by their Windows NT logon ID. The out-of-process server is started as a Windows NT Service running as "System".
interface IEngineer {
HRESULT Read ( ... ); /* Read one's training plan. */
HRESULT Submit ( ... ); /* Submit a new training plan. */
};
interface IManager {
HRESULT Read ( ... ); /* Read anyone's training plan. */
HRESULT Approve ( ... ); /* Approve a training plan. */
};
interface IDatabase {
HRESULT ReadRecord ( ... ); /* Read a database record. */
HRESULT WriteRecord ( ... ); /* Write a database record. */
};
The following describes one possible use of COM security for the training scenario. In this example, we will look only at security on the Training class.
\CLSID\{5cb31e10-2b5f- ... }\AccessPermission
\CLSID\{5cb31e10-2b5f- ... }\LaunchPermission = Y
These registry entries and ACLs prevent anyone but an Engineer or Manager from activating or accessing a Training object or its interfaces.
CoInitializeSecurity (
/* Specifies access security for this process */
pDefaultAccessACL,
RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, /* Insure data is not changed */
RPC_C_IMP_LEVEL_IMPERSONATE, /* Allow impersonation. */
NULL);
To implement security at the interface level, the following must be coded on the server side.
CoGetCallContext (IID_ServerSecurity, pSSecurity);
pSSecurity->QueryBlanket (NULL, NULL, pszPrinciple, NULL, NULL, NULL, NULL);
/* From here we want to take the principal name (which is the login of the client) and call whatever interface(s) necessary to determine if the client is in the appropriate group to call the interface. Something along the lines of: */
if (IsPrincipleInGroup (pszPrincple, "MANAGER") == FALSE)
return E_SECURITY_VIOLATION;
The following topics are all available in the MSDN Library.
Component Object Model (COM) Specification 0.9 (Specifications bin)
"DCOM Architecture" by Markus Horstmann and Mary Kirtland.
ActiveX SDK (SDK Documentation bin).
"FAQ: COM Security Frequently Asked Questions," Knowledge Base article #Q158508.
Microsoft Transaction Server 2.0 (SDK Documentation, Platform Documentation, COM and ActiveX Object Services).