10    Security in COM

To make it possible to implement an object that could perform privileged operations without compromising security COM supports two main areas of security:

Launch Security controls which objects a client is allowed to instantiate. Call Security dictates how security operates at the call level between an established connection from a client to a server. While anyone can get interface pointers from the class table, they cannot use them if they do not have call permissions.

COM provides a default security model, but also defines call-level interfaces that external security providers can implement to control object security.

It is also possible to have a server run as a given user account, through setting the RunAs named-value. This can be used to restrict or enhance available operations. The remainder of this section describes the capabilities of COM security in greater detail.

10.1    Launch Security

Activation security controls which classes a client is allowed to launch and retrieve objects from. Launch 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 (as described in Instance Creation Helper Functions), the SCM of the machine checks the request against activation security information stored within its registry.

There are two machine-wide secure settings in the registry, to which only machine administrators and the system have full access. All other users have only read-access. These are EnableDCOM and DefaultLaunchPermission. The EnableDCOM allows or disallows remote clients to launch class code and connect to objects for the system, and DefaultLaunchPermission, as the name implies, sets the default Access Control List (ACL) of who has permission to classes on the system.

You can override the default for any given class by assigning the desired permissions to the LaunchPermission key.

On platforms which do not support launch security, such as Windows 95 and the Macintosh, COM will never launch a process. Remote clients can still make connections to COM servers, however, as long as the process is already running, CoRegisterClassObject() has been called, and the EnableRemoteConnect registry key has been set to ``Y''. Also, remote connects are allowed on file moniker binds.

10.2    Call Security

COM provides two mechanisms to secure calls. The first is done automatically by the COM infrastructure. 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. The second is a set of functions and interfaces that applications may use to do their own security checking, and provide more fine-grained security. Furthermore, the two mechanisms are not exclusive: an application may ask COM to perform automatic security checking and also perform its own.

COM call security services are divided into three categories:

If you are using the default security values for a process for authentication and authorization, no security initialization call is necessary. If, however, you want to set other values for that process, you would call CoInitializeSecurity(). This both initializes and registers these values. The values set in this call then become the default values for that process. The proxy interfaces allow the client to control the security on calls to individual interfaces.

The IClientSecurity() interface is implemented locally to the client by the interface remoting layer. The client calls its methods to control the security of individual interface proxies on the object prior to making a call on one of the interfaces. Generally, clients using the default implementation instead call the helper functions that access that implementation and simplify the code: CoQueryProxyBlanket(), CoSetProxyBlanket(), and CoCopyProxy(). Calling IClientSecurity() directly is slightly more efficient then calling the helper functions. IClientSecurity() works with all authentication services (NTLMSSP, DCE, Kerberos). Some custom marshaled objects might not support IClientSecurity().

The server APIs and interfaces allow the server to retrieve security information about a call and to impersonate the caller. The IServerSecurity() interface is implemented for all providers, but may be absent for some custom-marshaled interfaces. Helper functions are also available that rely on the IServerSecurity() interface implementation: CoQueryClientBlanket(), CoImpersonateClient(), and CoRevertToSelf().

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 may 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. CoInitializeSecurity() allows the client 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.

Implementations of QueryInterace must never check ACLs. COM requires that an object which supports a particular IID always return success when queried for that IID. Aside from the requirement, checking ACLs on QueryInterface() does not provide any real security. If client A legally has access to interface IFoo, A can hand it directly to 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. For more information on implementing QueryInterface(), see IUnknown::QueryInterface().

Machine administrators and the system only have full access to the portion of the registry that contains the default machine-wide call security settings. All other uses have read access only. These named values are used for classes that do not call CoInitializeSecurity(), and are as follows:

To set access to objects of a specific class, there is the single named-value, AccessPermission.

10.3    Security Related Interface Descriptions

10.3.1    IClientSecurity

IClientSecurity() gives the client control over the call-security of individual interfaces on a remote object.

All proxies generated by the COM MIDL compiler support the IClientSecurity() interface automatically. If a call to QueryInterface() for IClientSecurity() fails, either the object is implemented in-process or it is remoted by a custom marshaler which does not support security (a custom marshaler may support security by offering the IClientSecurity() interface to the client). The proxies passed as parameters to an IClientSecurity() method must be from the same object as the IClientSecurity() interface. That is, each object has a distinct IClientSecurity() interface: calling IClientSecurity() on one object and passing a proxy to another object will not work.

When to Implement

The system proxy manager provides an implementation to objects, so you would typically not implement this interface.

If, however, you are defining objects that support custom marshaling, you may choose to implement IClientSecurity() on the objects' custom proxy to maintain a consistent programming model for the objects' client applications. You may also choose to support this interface on in-process objects.

When to Use

Call the methods of this interface to examine or modify the security settings of a particular connection to an out-of-process object. For example, you might temporarily establish a higher security level--one with complex encryption -- only for the period when sensitive information or data is being sent to the object. Alternately, you might establish different proxies to the same object with different security levels and use them to support different clients that are calling your object, or to support different operations within your application.

Table 10-1:  IClientSecurity Methods in VTable Order

IUnknown() Methods Description
QueryInterface() Returns pointers to supported interfaces.
AddRef() Increments the reference count.
Release() Decrements the reference count.

Table 10-2:  IClientSecurity Methods

IClientSecurity() Methods Description
IClientSecurity::QueryBlanket() Retrieves authentication information.
IClientSecurity::SetBlanket() Sets the authentication information that will be used to make calls on the specified proxy.
IClientSecurity::CopyProxy() Makes a copy of the specified proxy.

See Also

Security in COM  

IClientSecurity::CopyProxy()

NAME

IClientSecurity::CopyProxy() - Makes a private copy of the specified proxy.

Synopsis

#include <objidl.h>

HRESULT CopyProxy(
        IUnknown * punkProxy ,
        IUnknown ** ppunkCopy );

Description

IClientSecurity::CopyProxy() makes a private copy of the specified proxy for the calling client. Its authentication information may be changed through a call to IClientSecurity::SetBlanket() without affecting any other clients of the original proxy. The copy has the default values for the authentication information. The copy has one reference and must be released.

The helper function CoCopyProxy() encapsulates a QueryInterface() call on the proxy for a pointer to IClientSecurity(), and with that pointer calls IClientSecurity::CopyProxy(), and then releases the IClientSecurity() pointer.

Local interfaces may not be copied. IUnknown() and IClientSecurity() are examples of existing local interfaces.

Copies of the same proxy have a special relationship with respect to QueryInterface(). Given a proxy, a, of the IA interface of a remote object, suppose a copy of a is created, called b. In this case, calling QueryInterface() from the b proxy for IID_IA will not retrieve the IA interface on b, but the one on a, the original proxy with the ``default'' security settings for the IA interface.

Parameters

punkProxy

[in] Points to the IUnknown() interface on the proxy to be copied. May not be NULL.

ppunkCopy

[out] On successful return, points to the location of the IUnknown() pointer to the copy of the proxy. It may not be NULL.

Return Values

S_OK

Success.

E_INVALIDARG

One or more arguments are invalid.

See Also

CoCopyProxy()  

IClientSecurity::QueryBlanket()

NAME

IClientSecurity::QueryBlanket() - Retrieves authentication information.

Synopsis

#include <objidl.h>

HRESULT QueryBlanket(
        void * pProxy,
        DWORD * pAuthnSvc,
        DWORD * pAuthzSvc,
        OLECHAR ** pServerPrincName,
        DWORD * pAuthnLevel,
        DWORD * pImpLevel,
        RPC_AUTH_IDENTITY_HANDLE ** ppAuthInfo,
        DWORD ** pCapabilities );

Description

IClientSecurity::QueryBlanket() is called by the client to retrieve the authentication information COM will use on calls made from the specified interface proxy. With a pointer to an interface on the proxy, the client would first call QueryInterface() for a pointer to IClientSecurity(); then, with this pointer, the client would call IClientSecurity::QueryBlanket(), followed by releasing the pointer. This sequence of calls is encapsulated in the helper function CoQueryProxyBlanket().

In pProxy, you pass an interface pointer. However, you cannot pass a pointer to an interface that does not use a proxy. Thus you can't pass a pointer to an interface that has the local keyword in its interface definition since no proxy is created for such an interface. IUnknown() is the exception to this rule.

Parameters

pProxy

[in] Pointer to the proxy to query.

pAuthnSvc

[out] Pointer to a DWORD value defining the current authentication service. This will be a single value taken from the list of RPC_C_AUTHN_xxx constants. May be NULL, in which case the current authentication service is not retrieved.

pAuthzSvc

[out] Pointer to a DWORD value defining the current authorization service. This will be a single value taken from the list of RPC_C_AUTHZ_xxx constants. May be NULL, in which case the current authorization service is not retrieved.

pServerPrincName

[out] Pointer to the current principal name. The string will be allocated by the one called using CoTaskMemAlloc() and must be freed by the caller using CoTaskMemFree() when they are done with it. May be NULL, in which case the principal name is not retrieved.

pAuthnLevel

[out] Pointer to a DWORD value defining the current authentication level. This will be a single value taken from the list of RPC_C_AUTHN_LEVEL_xxx constants. May be NULL, in which case the current authentication level is not retrieved.

pImpLevel

[out] Pointer to a DWORD value defining the current impersonation level. This will be a single value taken from the list of RPC_C_IMP_LEVEL_xxx constants. May be NULL, in which case the current authentication level is not retrieved.

ppAuthInfo

[out] Pointer to the pointer value passed to IClientSecurity::SetBlanket() indicating the identity of the client. Because this points to the value itself and is not a copy, it should not be manipulated. May be NULL, in which case the information is not retrieved.

pCapabilities

[out] Pointer to a DWORD of flags indicating further capabilities of the proxy. Currently, no flags are defined for this parameter and it will only return zero. May be NULL, in which case the flags indicating further capabilities are not retrieved.

Return Values

S_OK

Success.

E_INVALIDARG

One or more arguments are invalid.

E_OUTOFMEMORY

Insufficient memory to create the pServerPrincName out-parameter.

See Also

CoQueryProxyBlanket()  

IClientSecurity::SetBlanket()

NAME

IClientSecurity::SetBlanket() - Sets the authentication information that will be used to make calls on the specified proxy.

Synopsis

#include <objidl.h>

HRESULT SetBlanket(
        void * pProxy,
        DWORD dwAuthnSvc,
        DWORD dwAuthzSvc,
        WCHAR * pServerPrincName,
        DWORD dwAuthnLevel,
        DWORD dwImpLevel,
        RPC_AUTH_IDENTITY_HANDLE * pAuthInfo,
        DWORD dwCapabilities );

Description

IClientSecurity::SetBlanket() sets the authentication information that will be used to make calls on the specified proxy. The values specified here override the values chosen by automatic security. Calling this method changes the security values for all other users of the specified proxy. Call IClientSecurity::CopyProxy() to make a private copy of the proxy.

By default, COM will choose the first available authentication service and authorization service available on both the client and server machines and the principal name which the server registered for that authentication service. Currently, COM will not try another authentication service if the first fails.

If pAuthInfo is NULL, it defaults to the current process token. dwAuthnLevel and dwImpLevel default to the values specified to CoInitializeSecurity(). If CoInitializeSecurity() is not called, the defaults are taken from the registry. The initial value for dwAuthnLevel on a proxy will be the higher of the value set on the client's call to CoInitializeSecurity() and the server's call to CoInitializeSecurity() .

Security information cannot be set on local interfaces. For example, it is illegal to set security on the IClientSecurity() interface. However, since that interface is supported locally, there is no need for security. IUnknown() is a special case. There are several cases. First, IUnknown() cannot be copied. Thus all users of an object get the same security. Second, SetBlanket can be used to set the security used for calls to QueryInterface(). However, since QueryInterface() is heavily cached, the server might not see the call. Third, AddRef() and Release() always use the security set with CoInitializeSecurity(), never the values set with SetBlanket.

Parameters

pProxy

[in] Indicates the proxy to set.

dwAuthnSvc

[in] A single DWORD value from the list of RPC_C_AUTHN_xxx constants indicating the authentication service to use. It may be RPC_C_AUTHN_NONE if no authentication is required.

dwAuthzSvc

[in] A single DWORD value from the list of RPC_C_AUTHZ_xxx constants indicating the authorization service to use.

pServerPrincName

[in] Pointer to a WCHAR string that indicates the server principal name to use with the authentication service. If you are using RPC_C_AUTHN_WINNT, the principal name must be NULL.

dwAuthnLevel

[in] A single DWORD value from the list of RPC_C_AUTHN_LEVEL_xxx constants indicating the authentication level to use.

dwImpLevel

[in] A single DWORD value from the list of RPC_C_IMP_LEVEL_xxx constants indicating the impersonation level to use. Currently, only RPC_C_IMP_LEVEL_IMPERSONATE and RPC_C_IMP_LEVEL_IDENTIFY are supported by NTLMSSP.

pAuthInfo

[in] Pointer to an RPC_AUTH_IDENTITY_HANDLE value that establishes the identity of the client. It is authentication-service specific. Some authentication services allow the application to pass in a different user name and password. COM keeps a pointer to the memory passed in until COM is uninitialized or a new value is set. If NULL is specified COM uses the current identity (the process token ). For NTLMSSP the structure is SEC_WINNT_AUTH_IDENTITY_W. The format of this structure depends on the provider of the authentication service.

dwCapabilities

[in] A DWORD defining flags to establish indicating the further capabilities of this proxy. Currently, no capability flags are defined.

The caller should specify EOAC_NONE. EOAC_MUTUAL_AUTH is defined and may be used by other security providers, but is not supported by NTLMSSP. Thus, NTLMSSP will accept this flag without generating an error but without providing mutual authentication.

Return Values

S_OK

Success, append the headers.

E_INVALIDARG

One or more arguments is invalid.

See Also

CoSetProxyBlanket(), CoQueryProxyBlanket(), RPC_C_AUTHN_xxx, RPC_C_AUTHZ_xxx, RPC_C_AUTHN_LEVEL_xxx, RPC_C_IMP_LEVEL_xxx

10.3.2    IServerSecurity

Used by a server to help identify the client and to manage impersonation of the client. IServerSecurity:QueryBlanket and IServerSecurity::ImpersonateClient() may only be called before the ORPC call completes. The interface pointer must be released when it is no longer needed.

When a client calls a server, the server can call CoGetCallContext() until the server sends the reply back to the client. The pointer to the instance of IServerSecurity() returned by CoGetCallContext() is automaticly deleted when the server sends the reply back to the client.

When to Implement

The stub managment code in the system provides an implementation of IServerSecurity() for objects by default as part of each incoming call, so typically you would not implement this interface.

You may choose to implement IServerSecurity() on the custom stubs of objects that support custom marshaling to maintain a consistent programming model for their objects.

When to Use

The methods of the IServerSecurity() interface are called by the server/object to examine or alter the security level of the connection between the caller and this particular object. Its most common use is for impersonation (IServerSecurity::ImpersonateClient() and ::RevertToSelf), where the server impersonates the client to test the privilege level of the calling client with an AccessCheck call. The information obtained through IServerSecurity() also allows an object to implement its own security framework, perhaps not based on the Access Control Lists (ACLs) that impersonation is geared toward. A different implementation could base its security framework on the client name or other information available through a call to the QueryBlanket method.

Table 10-3:  IServerSecurity Methods in VTable Order

IUnknown() Methods Description
QueryInterface() Returns pointers to supported interfaces.
AddRef() Increments the reference count.
Release() Decrements the reference count.

Table 10-4:  IServerSecurity Methods

IServerSecurity() Methods Description
QueryBlanket Called by the server to find out about the client that invoked one of its methods.
ImpersonateClient Allows a server to impersonate a client for the duration of a call.
RevertToSelf Restores the authentication information on a thread to the process's identity.
IsImpersonating Indicates whether the server is currently impersonating the client.

See Also

Security in COM  

IServerSecurity::QueryBlanket()

NAME

IServerSecurity::QueryBlanket() - Called by the server to find out about the client that invoked one of its methods.

Synopsis

#include <objidl.h>

HRESULT QueryBlanket(
        DWORD* pAuthnSvc,
        DWORD* pAuthzSvc,
        OLECHAR ** pServerPrincNam,
        DWORD * pAuthnLevel,
        DWORD * pImpLevel,
        RPC_AUTHZ_HANDLE * pPrivs,
        DWORD ** pCapabilities );

Description

IServerSecurity::QueryBlanket() is used by the server to find out about the client that invoked one of its methods. To get a pointer to IServerSecurity() for the current call on the current thread, call CoGetCallContext(), specifying IID_IServerSecurity. This interface pointer may only be used in the same apartment as the call for the duration of the call.

Parameters

pAuthnSvc

[out] Pointer to the current authentication service. This will be a single value taken from the list of RPC_C_AUTHN_xxx constants. May be NULL, in which case the current authentication service is not returned.

pAuthzSvc

[out] Pointer to the current authorization service. This will be a single value taken from the list of RPC_C_AUTHZ_xxx constants. May be NULL, in which case the current authorization service is not returned.

pServerPrincName

[out] Pointer to the current principal name. The string will be allocated by the callee using CoTaskMemAlloc(), and must be freed by the caller using CoTaskMemFree() when they are done with it. May be NULL, in which case the principal name is not returned.

pAuthnLevel

[out] Pointer to the current authentication level. This will be a single value taken from the list of RPC_C_AUTHN_LEVEL_xxx constants. May be NULL, in which case the current authorization level is not returned.

pImpLevel

[out] Must be NULL; the current authentication level is not supplied.

pPrivs

[out] Pointer to a string identifying the client. For NTLMSSP the string is of the form domain\user. This is not a copy, and so should not be modified or freed, and is not valid after the ORPC call completes.

pCapabilities

[out] Pointer to return flags indicating further capabilities of the call. Currently, no flags are defined for this parameter and it will only return EOAC_NONE. May be NULL, in which case the flags indicating further capabilities are not returned.

Return Values

This method supports the standard return values E_INVALIDARG and E_OUTOFMEMORY, as well as the following:

S_OK

Success.

See Also

CoGetCallContext()  

IServerSecurity::ImpersonateClient()

NAME

IServerSecurity::ImpersonateClient() - Allows a server to impersonate a client for the duration of a call.

Synopsis

#include <objidl.h>

HRESULT ImpersonateClient(
         );

Description

IServerSecurity::ImpersonateClient() allows a server to impersonate a client for the duration of a call. What the server may do depends on the impersonation level, specified through one of the RPC_C_IMP_LEVEL_xxx constants. The server may impersonate the client on any secure call at identify, impersonate, or delegate level. At identify level, the server may only find out the client name and perform ACL checks; it may not access system objects as the client. At delegate level, the server may make off-machine calls while impersonating the client. The impersonation information only lasts until the end of the current method call. At that time, IServerSecurity::RevertToSelf() will automatically be called if necessary.

Traditionally, impersonation information is not nested - the last call to any Win32 impersonation mechanism overrides any previous impersonation. However, in the apartment model, impersonation is maintained during nested calls. Thus if the server A receives a call from B, impersonates, calls C, receives a call from D, impersonates, reverts, and receives the reply from C, the impersonation will be set back to B, not A.

Distributed COM currently does not support dynamic impersonation. The only way to change the client token associated with remote COM calls is to use IClientSecurity::SetBlanket() on the proxy being called. Calling IServerSecurity::ImpersonateClient() to impersonate your client and then making a remote call to another server will not affect the token the second server sees when it impersonates on your call.

Return Values

This method supports the standard return value E_FAIL, as well as the following:

S_OK

Success.

See Also

CoImpersonateClient()  

IServerSecurity::RevertToSelf()

NAME

IServerSecurity::RevertToSelf() - Restores the authentication information on a thread to the process's identity.

Synopsis

#include <objidl.h>

HRESULT RevertToSelf(
         );

Description

IServerSecurity::RevertToSelf() restores the authentication information and reverts an impersonation on a thread to the process's identity. This method will only revert impersonation changes made by IServerSecurity::ImpersonateClient(). If the thread token is modified by other means (through the SetThreadToken or RpcImpersonateClient Win32 functions) the result of this function is undefined.

In the apartment model, CoRevertToSelf() (IServerSecurity::RevertToSelf()) affects only the current method invocation. If there are nested method invocations, they each may have their own impersonation and COM will correctly restore the impersonation before returning to them (regardless of whether or not CoRevertToSelf()/IServerSecurity::RevertToSelf() was called).

Return Values

This method supports the standard return value E_FAIL, as well as the following:

S_OK

Success.

See Also

CoRevertToSelf()  

IServerSecurity::IsImpersonating()

NAME

IServerSecurity::IsImpersonating() - Indicates whether IServerSecurity::ImpersonateClient() has been called without a matching call to IServerSecurity::RevertToSelf().

Synopsis

#include <objidl.h>

BOOL IsImpersonating(
         );

Return Values

TRUE

This thread has called IServerSecurity::ImpersonateClient() and is currently impersonating the client of this call.

FALSE

This thread is not currently impersonating the client of this call.

See Also

IServerSecurity::RevertToSelf().

10.4    Security Related API Descriptions

 

CoCopyProxy()

NAME

CoCopyProxy() - Makes a private copy of the specified proxy.

Synopsis

#include <objbase.h>

HRESULT CoCopyProxy((
        IUnknown * punkProxy,
        IUnknown ** ppunkCopy );

Description

CoCopyProxy() makes a private copy of the specified proxy. Typically, this is called when a client needs to change the authentication information of its proxy through a call to either CoSetClientBlanket or IClientSecurity::SetBlanket() without changing this information for other clients. CoSetClientBlanket affects all the users of an instance of a proxy, so creating a private copy of the proxy through a call to CoCopyProxy() eliminates the problem.

This function encapsulates the following sequence of common calls (error handling excluded):

    pProxy->QueryInterface(IID_IClientSecurity,(void**)&pcs);
    pcs->CopyProxy(punkProxy, ppunkCopy);
    pcs->Release();

Local interfaces may not be copied. IUnknown() and IClientSecurity() are examples of existing local interfaces.

Copies of the same proxy have a special relationship with respect to QueryInterface(). Given a proxy, a, of the IA interface of a remote object, suppose a copy of a is created, called b. In this case, calling QueryInterface() from the b proxy for IID_IA will not retrieve the IA interface on b, but the one on a, the original proxy with the ``default'' security settings for the IA interface.

Parameters

punkProxy

[in] Points to the IUnknown() interface on the proxy to be copied. May not be NULL.

ppunkCopy

[out] Address of IUnknown * pointer variable that receives the interface pointer to the copy of the proxy. It may not be NULL.

Return Values

S_OK

Success.

E_INVALIDARG

One or more arguments are invalid.

See Also

IClientSecurity::CopyProxy(), Security in COM  

CoGetCallContext()

NAME

CoGetCallContext() - Retrieves the context of the current call on the current thread.

Synopsis

#include <objbase.h>

HRESULT CoGetCallContext((
        REFIID riid,
        void ** ppv );

Description

CoGetCallContext() retrieves the context of the current call on the current thread. The riid parameter specifies the interface on the context to be retrieved. Currently, only IServerSecurity() is available from the default call context supported by standard marshaling.

This is one of the functions provided to give the server access to any contextual information of the caller and to encapsulate common sequences of security checking and caller impersonation.

Parameters

riid

[in] Interface identifier (IID) of the call context that is being requested. If you are using the default call context supported by standard marshaling, only IID_IServerSecurity is available.

ppv

[out] Address of pointer variable that receives the interface pointer requested in riid. Upon successful return, *ppv contains the requested interface pointer.

Return Values

S_OK

Success.

E_NOINTERFACE

The call context does not support the interface identified by riid.

See Also

IServerSecurity(), Security in COM  

CoImpersonateClient()

NAME

CoImpersonateClient() - Allows the server to impersonate the client of the current call for the duration of the call.

Synopsis

#include <objbase.h>

HRESULT CoImpersonateClient((
         );

Description

Allows the server to impersonate the client of the current call for the duration of the call. If you do not call CoRevertToSelf(), COM reverts automatically for you. This function will fail unless the object is being called with RPC_C_AUTHN_LEVEL_CONNECT or higher authentication in effect (any authentication level except RPC_C_AUTHN_LEVEL_NONE) This function encapsulates the following sequence of common calls (error handling excluded):

    CoGetCallContext(IID_IServerSecurity, (void**)&pss);
    pss->ImpersonateClient();
    pss->Release();

This helper function encapsulates the process of getting a pointer to an instance of IServerSecurity() that contains data about the current call, calling its ImpersonateClient method, and then releasing the pointer.

Return Values

This function supports the standard return value E_INVALIDARG, as well as the following:

S_OK

Indicates success.

See Also

IServerSecurity::ImpersonateClient(), Security in COM  

CoInitializeSecurity()

NAME

CoInitializeSecurity() - Registers security and sets the default security values for the process. For legacy applications, COM automatically calls this function with values from the registry. It is invoked once per process, rather than for each thread in the process. If you set registry values and then call CoInitializeSecurity(), the AppID registry values will be ignored, and the CoInitializeSecurity() values will be used.

Synopsis

#include <objbase.h>

HRESULT CoInitializeSecurity((
        PSECURITY_DESCRIPTOR pVoid,
        DWORD cAuthSvc,
        SOLE_AUTHENTICATION_SERVICE * asAuthSvc,
        void * pReserved1,
        DWORD dwAuthnLevel,
        DWORD dwImpLevel,
        RPC_AUTH_IDENTITY_HANDLE pAuthInfo,
        DWORD dwCapabilities,
        void * pvReserved2 );

Description

The CoInitializeSecurity() layer initializes the security layer and sets the specified values as the security default.

If the application does not call CoInitializeSecurity(), COM calls it automatically the first time an interface is marshaled or unmarshaled, registering the default security. No default security packages will be registered till then.

The first parameter, pVoid, can be one of three types of value, depending on the value of pCapabilities: a Win32 security descriptor, a pointer to a GUID specifying the AppID of the process, or an IAccessControl pointer.

If any capability flags other than EOAC_APPID or EOAC_ACCESS_CONTROL are called, pVoid must be a pointer to a Win32 SECURITY_DESCRIPTOR. A NULL DACL will allow calls from anyone. A DACL with no ACEs allows no access. For information on ACLs and ACEs, refer to the Win32 Programmers Reference section Access Control Model.

The owner and group of the SECURITY_DESCRIPTOR must be set--applications should call AccessCheck (not IsValidSecurityDescriptor) to ensure that their security descriptor is correctly formed prior to calling CoInitializeSecurity().

If the application passes a NULL security descriptor, COM will construct one that allows calls from the current user and local system. All new connections will be audited. Distributed COM will copy the security descriptor.

If mutual authentication is enabled all calls will fail unless the server identity is verified to match the principal name set on the proxy. Without mutual authentication, security only helps the server; the client has no idea who is handling his call. While CoInitializeSecurity() takes principal names as parameters, that does not mean that the server can register any arbitrary name. The security provider verifies that the server has a right to use the names registered.

Secure references cause DCOM to make extra callbacks to insure that objects are not released maliciously. When the EOAC_APPID flag is set, CoInitializeSecurity() looks for the authentication level under the AppID. If the authentication level is not found, it looks for the default authentication level. If the default authentication level is not found, it generates a default authentication level of connect. If the authentication level is not NONE, CoInitializeSecurity() looks for the access permission value under the AppID. If not found, it looks for the default access permission value. If not found, it generates a default access permission. All the other settings are determined the same way as for a legacy application. When the EOAC_APPID flag is set, all parameters to CoInitializeSecurity() except pVoid are ignored. If pVoid is NULL, CoInitializeSecurity() will look up the application.exe name in the registry and use the AppID stored there. Note that this gives the same security as if you did not call CoInitializeSecurity(). The IClientSecurity::SetBlanket() method and CoSetProxyBlanket() function return an error if you set any of the following flags in the capabilities: EOAC_SECURE_REFS, EOAC_ACCESS_CONTROL, or EOAC_APPID.

The CoInitializeSecurity() function returns an error if both the EOAC_APPID and EOAC_ACCESS_CONTROL flags are set.

When you set the cloaking capability through the EOAC_CLOAK capability flag, this picks up the token only on the first call to the proxy; dynamic cloaking, in which the token would be picked up on every call, is not supported.

See Also

RPC_C_IMP_LEVEL_xxx, RPC_C_AUTHN_LEVEL_xxx, Security in COM

Parameters

pVoid

[in] Defines the access permissions. If the capability flags (pCapabilities) are not EOAC_APPID or EOAC_ACCESS_CONTROL, must be a pointer to a Win32 security descriptor. If EOAC_APPID is specified, must be a pointer to a GUID that specifies the AppID of the process. In this case, all other parameters of the call are ignored, and registry values are used for security checks. If EOAC_ACCESS_CONTROL is specified, must be a pointer to an IAccessControl interface, which will be used to check access. See Description for more information. If NULL, no ACL checking will be done. If not NULL, COM will check ACLs on new connections. If not NULL, dwAuthnLevel cannot be RPC_C_AUTHN_LEVEL_NONE.

cAuthSvc

[in] Count of entries in asAuthSvc. Zero means register no services. A value of -1 tells COM to choose which authentication services to register.

asAuthSvc

[in] Array of authentication/authorization/principal names to register. These values are registered to allow incoming calls. After that they are ignored. The default authentication/authorization/principal for each proxy will be negotiated regardless of whether these are set. For example, if the application registers RPC_C_AUTHN_WINNT and receives an interface from a machine that only supports RPC_C_AUTHN_DEC_PUBLIC, COM will choose RPC_C_AUTHN_DEC_PUBLIC if this machine supports it.

pReserved1

[in] Reserved for future use; must be NULL.

dwAuthnLevel

[in] The default authentication level for proxies. On the server side, COM will fail calls that arrive at a lower level. All calls to AddRef() and Release() are made at this level.

dwImpLevel

[in] The default impersonation level for proxies. This value is not checked on the server side. AddRef() and Release() calls are made with this impersonation level so even security aware apps should set this carefully. Setting IUnknown() security only affects calls to QueryInterface(), not AddRef() or Release().

pAuthInfo

[in] Reserved for future use; must be NULL.

dwCapabilities

[in] Additional client and/or server-side capabilities. These flags are described in EOLE_AUTHENTICATION_CAPABILITIES. If EOLE_APPID is specified, pVoid must be a pointer to a GUID specifying the AppID of the process. If EOLE_ACCESS_CONTROL is set, pVoid must be a pointer to the IAccessControl interface on an access control object. For more information, see Description.

pReserved2

[in] Reserved for future use; must be zero.

Return Values

This function supports the standard return value E_INVALIDARG, as well as the following:

S_OK

Indicates success.

 

CoQueryAuthenticationServices()

NAME

CoQueryAuthenticationServices() - Retrieves a list of the authentication services registered when the process called CoInitializeSecurity().

Synopsis

#include <objbase.h>

HRESULT CoQueryAuthenticationServices((
        DWORD * pcAuthSvc,
        SOLE_AUTHENTICATION_SERVICE ** prgAuthSvc );

Description

CoQueryAuthenticationServices() retrieves a list of the authentication services currently registered. If the process calls CoInitializeSecurity(), these are the services registered through that call. If the application does not call it, CoInitializeSecurity() is called automatically by COM, registering the default security package, the first time an interface is marshaled or unmarshaled.

This function is primarily useful for custom marshalers, to determine which principal names an application can use.

Different authentication services support different levels of security. For example, NTLMSSP does not support delegation or mutual authentication while Kerberos does. The application is responsible only for registering authentication services that provide the features the application needs. This is the way to query which services have been registered with CoInitializeSecurity().

Parameters

pcAuthSvc

[out] Pointer to return the number of entries returned in the rgAuthSvc array. May not be NULL.

prgAuthSvc

[out] Pointer to an array of SOLE_AUTHENTICATION_SERVICE structures. The list is allocated through a call to CoTaskMemAlloc(). The caller must free the list when finished with it by calling CoTaskMemFree().

Return Values

This function supports the standard return values E_INVALIDARG and E_OUTOFMEMORY, as well as the following:

S_OK

Indicates success.

See Also

CoInitializeSecurity(), SOLE_AUTHENTICATION_SERVICE structure, Security in COM  

CoQueryClientBlanket()

NAME

CoQueryClientBlanket() - Called by the server to find out about the client that invoked the method executing on the current thread

Synopsis

#include <objbase.h>

HRESULT CoQueryClientBlanket((
        DWORD * pAuthnSvc,
        DWORD * pAuthzSvc,
        OLECHAR ** pServerPrincName,
        DWORD * pAuthnLevel,
        DWORD * pImpLevel,
        void ** ppPrivs,
        DWORD ** pCapabilities );

Description

CoQueryClientBlanket() is called by the server to get security information about the client that invoked the method executing on the current thread. This function encapsulates the following sequence of common calls (error handling excluded):

    CoGetCallContext(IID_IServerSecurity, (void**)&pss);
    pss->QueryBlanket(pAuthnSvc, pAuthzSvc, pServerPrincName, 
                pAuthnLevel, pImpLevel, pPrivs, pCapabilities);
    pss->Release();

Parameters

pAuthnSvc

[out] Pointer to a DWORD value defining the current authentication service. This will be a single value taken from the list of RPC_C_AUTHN_xxx constants. May be NULL, in which case the current authentication service is not returned.

pAuthzSvc

[out] Pointer to a DWORD value defining the current authorization service. This will be a single value taken from the list of RPC_C_AUTHZ_xxx constants. May be NULL, in which case the current authorization service is not returned.

pServerPrincName

[out] Pointer to the current principal name. The string will be allocated by the callee using CoTaskMemAlloc() and must be freed by the caller using CoTaskMemFree() when they are done with it. May be NULL, in which case the principal name is not returned.

pAuthnLevel

[out] Pointer to a DWORD value defining the current authentication level. This will be a single value taken from the list of RPC_C_AUTHN_LEVEL_xxx constants. May be NULL, in which case the current authentication level is not returned.

pImpLevel

[out] <Pointer to a DWORD value defining the current impersonation level. This will be a single value taken from the list of RPC_C_IMP_LEVEL_xxx constants. Must be NULL; the current impersonation level is never returned.

pPrivs

[out] Pointer to a unicode string identifying the client. This string is not a copy, the user must not change it or free it. The string is not valid past the end of the call. For NTLMSSP the string is of the form domain\user.

pCapabilities

[out] Pointer to flags indicating further capabilities of the call. Currently, no flags are defined for this parameter and the value retrieved is EOAC_NONE. May be NULL, in which case no value is retrieved. EOAC_MUTUAL_AUTH is defined but not used by NTLMSSP. Third party security providers may return that flag.

Return Values

S_OK

Success.

E_INVALIDARG

One or more arguments are invalid.

E_OUTOFMEMORY

Insufficient memory to create the pServerPrincName out-parameter.

See Also

IServerSecurity::QueryBlanket(), Security in COM  

CoQueryProxyBlanket()

NAME

CoQueryProxyBlanket() - Retrieves the authentication information the client uses to make calls on the specified proxy.

Synopsis

#include <objbase.h>

HRESULT CoQueryProxyBlanket((
        void * pProxy,
        DWORD * pAuthnSvc,
        DWORD * pAuthzSvc,
        OLECHAR ** pServerPrincName,
        DWORD * pAuthnLevel,
        DWORD * pImpLevel,
        RPC_AUTH_IDENTITY_HANDLE ** ppAuthInfo,
        DWORD ** pCapabilities );

Description

CoQueryProxyBlanket() is called by the client to retrieve the authentication information COM will use on calls made from the specified proxy. This function encapsulates the following sequence of common calls (error handling excluded):

pProxy->QueryInterface(IID_IClientSecurity,
(void**)&pcs);
pcs->QueryBlanket(pProxy, pAuthnSvc, pAuthzSvc, pServerPrincName,
                 pAuthnLevel, pImpLevel, ppAuthInfo, pCapabilities);
pcs->Release();

This sequence calls QueryInterface() on the proxy for IClientSecurity(), and with the resulting pointer, calls IClientSecurity::QueryBlanket(), and then releases the pointer.

In pProxy, you can pass any proxy, such as a proxy you get through a call to CoCreateInstance(), CoUnmarshalInterface(), or just passing an interface pointer as a parameter. It can be any interface. You cannot pass a pointer to something that is not a proxy. Thus you can't pass a pointer to an interface that has the local keyword in its interface definition since no proxy is created for such an interface. IUnknown() is the exception.

Parameters

pProxy

[in] Pointer to an interface on the proxy to query.

pAuthnSvc

[out] Pointer to a DWORD value defining the current authentication service. This will be a single value taken from the list of RPC_C_AUTHN_xxx constants. May be NULL, in which case the current authentication service is not retrieved.

pAuthzSvc

[out] Pointer to a DWORD value defining the current authorization service. This will be a single value taken from the list of RPC_C_AUTHZ_xxx constants. May be NULL, in which case the current authorization service is not retrieved.

pServerPrincName

[out] Pointer to the current principal name. The string will be allocated by the one called using CoTaskMemAlloc() and must be freed by the caller using CoTaskMemFree() when they are done with it. May be NULL, in which case the principal name is not retrieved.

pAuthnLevel

[out] Pointer to a DWORD value defining the current authentication level. This will be a single value taken from the list of RPC_C_AUTHN_LEVEL_xxx constants. May be NULL, in which case the current authentication level is not retrieved.

pImpLevel

[out] Pointer to a DWORD value defining the current impersonation level. This will be a single value taken from the list of RPC_C_IMP_LEVEL_xxx constants. May be NULL, in which case the current authentication level is not retrieved.

ppAuthInfo

[out] Pointer to the pointer value passed to IClientSecurity::SetBlanket() indicating the identity of the client. Because this points to the value itself and is not a copy, it should not be manipulated. May be NULL, in which case the information is not retrieved.

pCapabilities

[out] Pointer to a DWORD of flags indicating further capabilities of the proxy. Currently, no flags are defined for this parameter and it will only return EOAC_NONE. May be NULL, in which case the flags indicating further capabilities are not retrieved.

Return Values

S_OK

Success.

E_INVALIDARG

One or more arguments are invalid.

E_OUTOFMEMORY

Insufficient memory to create the pasAuthnSvc out-parameter.

See Also

IClientSecurity::QueryBlanket, Security in COM  

CoRevertToSelf()

NAME

CoRevertToSelf() - Restores the authentication information on a thread of execution to its previous identity.

Synopsis

#include <objbase.h>

HRESULT CoRevertToSelf((
         );

Description

CoRevertToSelf() restores the authentication information on a thread of execution to its previous identity after a previous server call to CoImpersonateClient(). This is a helper function that encapsulates the following common sequence of calls (error handling excluded):

    CoGetCallContext(IID_IServerSecurity, (void**)&pss);
    pss->RevertToSelf();
    pss->Release();

Return Values

This function supports the standard return value E_INVALIDARG, as well as the following:

S_OK

Indicates success.

See Also

IServerSecurity::RevertToSelf(), CoGetCallContext(), Security in COM  

CoSetProxyBlanket()

NAME

CoSetProxyBlanket() - Sets the authentication information that will be used to make calls on the specified proxy.

Synopsis

#include <objbase.h>

HRESULT CoSetProxyBlanket((
        void * pProxy,
        DWORD dwAuthnSvc,
        DWORD dwAuthzSvc,
        WCHAR * pServerPrincName,
        DWORD dwAuthnLevel,
        DWORD dwImpLevel,
        RPC_AUTH_IDENTITY_HANDLE * pAuthInfo,
        DWORD dwCapabilities );

Description

Sets the authentication information that will be used to make calls on the specified proxy. The IClientSecurity::SetBlanket() method and CoSetProxyBlanket() function return an error if you set any of the following flags in the capabilities: EOAC_SECURE_REFS, EOAC_ACCESS_CONTROL, or EOAC_APPID. This function encapsulates the following sequence of common calls (error handling excluded):

    pProxy->QueryInterface(IID_IClientSecurity,
(void**)&pcs);
    pcs->SetBlanket(pProxy, dwAuthnSvc, dwAuthzSvc, pServerPrincName,
        dwAuthnLevel, dwImpLevel, pAuthInfo, dwCapabilities);
    pcs->Release();

Parameters

pProxy

[in] Pointer to an interface on the proxy for which this authentication information is to be set.

dwAuthnSvc

[in] A single DWORD value from the list of RPC_C_AUTHN_xxx constants indicating the authentication service to use. It may be RPC_C_AUTHN_NONE if no authentication is required.

dwAuthzSvc

[in] A single DWORD value from the list of RPC_C_AUTHZ_xxx constants indicating the authorization service to use. If you are using the system default authentication service, use RPC_C_AUTHZ_NONE.

pServerPrincName

[in] Points to a WCHAR string that indicates the server principal name to use with the authentication service. If you are using RPC_C_AUTHN_WINNT, the principal name must be NULL.

dwAuthnLevel

[in] A single DWORD value from the list of RPC_C_AUTHN_LEVEL_xxx constants indicating the authentication level to use.

dwImpLevel

[in] A single DWORD value from the list of RPC_C_IMP_LEVEL_xxx constants indicating the impersonation level to use. Currently, only RPC_C_IMP_LEVEL_IMPERSONATE and RPC_C_IMP_LEVEL_IDENTIFY are supported.

pAuthInfo

[in] Establishes the identity of the client. It is authentication service specific. Some authentication services allow the application to pass in a different user name and password. COM keeps a pointer to the memory passed in until COM is uninitialized or a new value is set. If NULL is specified COM uses the current identity (the process token). For NTLMSSP the structure is SEC_WINNT_AUTH_IDENTITY_W.

dwCapabilities

[in] Flags to establish indicating the further capabilities of this proxy. Capability flags are defined in the EOLE_AUTHENTICATION_CAPABILITIES enumeration. Only EOAC_NONE or EOAC_CLOAKING should be used with this call. EOAC_MUTUAL_AUTH is accepted without error, but has no authentication effect. Other flags can be used only with CoInitializeSecurity(), and their use will generate an error.

The caller should specify EOAC_NONE. EOAC_MUTUAL_AUTH is defined and may be used by other security providers, but is not supported by NTLMSSP. Thus, NTLMSSP will accept this flag without generating an error but without providing mutual authentication.

Return Values

S_OK

Success, append the headers.

E_INVALIDARG

One or more arguments is invalid.

See Also

IClientSecurity::SetBlanket(), CoQueryClientBlanket(), Security in COM

10.5    Security Related Structure Definitions

10.5.1    COAUTHINFO

Determines the authentication settings used while making a remote activation request from the client scm to the server.

typedef struct _COAUTHINFO
{
    DWORD               dwAuthnSvc;
    DWORD               dwAuthzSvc;
    [string] WCHAR *    pwszServerPrincName;
    DWORD               dwAuthnLevel;
    DWORD               dwImpersonationLevel;
    AUTH_IDENTITY  *    pAuthIdentityData;
    DWORD               dwCapabilities;
} COAUTHINFO;

Members

dwAuthnSvc

[in] A single DWORD value from the list of RPC_C_AUTHN_xxx constants indicating the authentication service to use. It may be RPC_C_AUTHN_NONE if no authentication is required.

dwAuthzSvc

[in] A single DWORD value from the list of RPC_C_AUTHZ_xxx constants indicating the authorization service to use.

pwszServerPrincName

Pointer to a WCHAR string that indicates the server principal name to use with the authentication service. If you are using RPC_C_AUTHN_WINNT, the principal name must be NULL.

dwAuthnLevel

[in] A single DWORD value from the list of RPC_C_AUTHN_LEVEL_xxx constants indicating the authentication level to use.

dwImpersonationLevel

[in] A single DWORD value from the list of RPC_C_IMP_LEVEL_xxx constants indicating the impersonation level to use. Currently, only RPC_C_IMP_LEVEL_IMPERSONATE and RPC_C_IMP_LEVEL_IDENTIFY are supported.

pAuthIdentityData

Pointer to an AUTH_IDENTITY structure that establishes the identity of the client. It is authentication-service specific, as follows:

typedef struct _AUTH_IDENTITY 
{ 
  [size_is(UserLength+1)] USHORT *        User;
  ULONG                    UserLength; 
  [size_is(DomainLength+1)] USHORT *      Domain;
  ULONG                    DomainLength; 
  [size_is(PasswordLength+1)] USHORT *    Password;
  ULONG                    PasswordLength; 
  ULONG                    Flags;
} AUTH_IDENTITY;

dwCapabilities

[in] A DWORD defining flags to establish indicating the further capabilities of this proxy. Currently, no capability flags are defined.

Description

The values of the COAUTHINFO structure determine the authentication settings used while making a remote activation request from the client's scm to the server's scm. This structure is defined by default for NTLMSSP, and is described only for cases that need it to allow DCOM activations to work correctly with security providers other than NTLMSSP, or to specify additional security information used during remote activations for interoperability with alternate implementations of distributed COM.

See Also

COSERVERINFO

10.5.2    COSERVERINFO

Identifies a remote machine resource to the new or enhanced activation functions. The structure is defined as follows in the Wtypes.h header file:

typedef struct  _COSERVERINFO
    {
    DWORD dwReserved1;
    LPWSTR pwszName;
    COAUTHINFO  *pAuthInfo;
    DWORD dwReserved2;
    }   COSERVERINFO;

Members

dwReserved1

Reserved for future use. Must be 0.

pszName

Pointer to the name of the machine to be used.

pAuthInfo

A non-zero value, which is a pointer to a COAUTHINFO structure, would only be used when a security package other than NTLMSSP is being used.

dwReserved2

Reserved for future use. Must be 0.

Description

The COSERVERINFO structure is used primarily to identify a remote system in object creation functions. Machine resources are named using the naming scheme of the network transport. By default, all UNC (``\\server'' or ``server'') and DNS names (``server.com'', ``www.foo.com'', or ``135.5.33.19'') names are allowed.

If you are using the NTLMSSP security package, the default case, the pAuthinfo parameter should be set to zero. If you are a vendor supporting another security package, refer to COAUTHINFO. The mechanism described there is intended to allow DCOM activations to work correctly with security providers other than NTLMSSP, or to specify additional security information used during remote activations for interoperability with alternate implementations of DCOM. If pAuthInfo is set, those values will be used to specify the authentication settings for the remote call. These settings will be passed to RpcBindingSetAuthInfoEx.

If the pAuthInfo field is not specified, any values in the AppID section of the registry will be used to override the following default authentication settings:

Table 10-5:  Default NTLMSSP Authentication Settings

These Values: ...Will Override These Values:
dwAuthnSvc RPC_C_AUTHN_WINNT
dwAuthzSvc RPC_C_AUTHZ_NONE
pszServerPrincName NULL
dwAuthnLevel RPC_C_AUTHN_LEVEL_CONNECT
dwImpersonationLevel RPC_C_IMP_LEVEL_IMPERSONATE
pvAuthIdentityData NULL
dwCapabilities RPC_C_QOS_CAPABILITIES_DEFAULT

See Also

CLSCTX, CoGetClassObject(), CoGetInstanceFromFile(), CoGetInstanceFromIStorage(), CoCreateInstanceEx(), Locating a Remote Object

10.6    Security Related Enumeration Descriptions

10.6.1    RPC_C_AUTHN_XXX

These values, along with the RPC_C_AUTHZ_xxx values, are assigned to the SOLE_AUTHENICATION_SERVICE structure, which is retrieved by the CoQueryAuthenticationServices() function, and passed in to the CoInitializeSecurity() function.

RPC_C_AUTHN_NONE

No authentication.

RPC_C_AUTHN_DCE_PRIVATE

DCE private key authentication.

RPC_C_AUTHN_DCE_PUBLIC

DCE public key authentication.

RPC_C_AUTHN_DEC_PUBLIC

DEC public key authentication (reserved for future use).

RPC_C_AUTHN_WINNT

NT LM SSP (NT Security Service).

RPC_C_AUTHN_DEFAULT

The system default authentication service.

See Also

CoInitializeSecurity(), CoQueryAuthenticationServices()

10.6.2    RPC_C_AUTH_LEVEL_XXX

Used in the security functions and interfaces to specify the authentication level.

Values

RPC_C_AUTHN_LEVEL_NONE

Performs no authentication.

RPC_C_AUTHN_LEVEL_CONNECT

Authenticates only when the client establishes a relationship with the server. Datagram transports always use RPC_AUTHN_LEVEL_PKT instead.

RPC_C_AUTHN_LEVEL_CALL

Authenticates only at the beginning of each remote procedure call when the server receives the request. Datagram transports use RPC_C_AUTHN_LEVEL_PKT instead.

RPC_C_AUTHN_LEVEL_PKT

Authenticates that all data received is from the expected client.

RPC_C_AUTHN_LEVEL_PKT_INTEGRITY

Authenticates and verifies that none of the data transferred between client and server has been modified.

RPC_C_AUTHN_LEVEL_PKT_PRIVACY

Authenticates all previous levels and encrypts the argument value of each remote procedure call.

See Also

IClientSecurity(), IServerSecurity()

10.6.3    RPC_C_AUTHZ_XXX

These values define what the server authorizes, and are used by methods of the IClientSecurity() interface. Along with the RPC_C_AUTHN_xxx values, these are the values assigned to the SOLE_AUTHENTICATION_SERVICE structure, which is retrieved by the CoQueryAuthenticationServices() function, and passed in to the CoInitializeSecurity() function.

Values

RPC_C_AUTHZ_NONE

Server performs no authorization.

RPC_C_AUTHZ_NAME

Server performs authorization based on the client's principal name.

RPC_C_AUTHZ_DCE

Server performs authorization checking using the client's DCE privilege attribute certificate (PAC) information, which is sent to the server with each remote procedure call made using the binding handle. Generally, access is checked against DCE access control lists (ACLs).

See Also

SOLE_AUTHENTICATION_SERVICE

10.6.4    RPC_C_IMP_LEVEL_XXX

Used in the security functions and interfaces to specify the authentication level.

Values

RPC_C_IMP_LEVEL_ANONYMOUS

(Not supported in this release.) The client is anonymous to the server. The server process cannot obtain identification information about the client and it cannot impersonate the client.

RPC_C_IMP_LEVEL_IDENTIFY

The server can obtain the client's identity. The server can impersonate the client for ACL checking, but cannot access system objects as the client. This information is obtained when the connection is established, not on every call.

Notes

GetUserName will fail while impersonating at identify level. The workaround is to impersonate, OpenThreadToken, revert, call GetTokenInformation, and finally, call LookupAccountSid.

RPC_C_IMP_LEVEL_IMPERSONATE

The server process can impersonate the client's security context while acting on behalf of the client. This information is obtained when the connection is established, not on every call.

RPC_C_IMP_LEVEL_DELEGATE

(Not supported in this release.) The server process can impersonate the client's security context while acting on behalf of the client. The server process can also make outgoing calls to other servers while acting on behalf of the client. This information is obtained when the connection is established, not on every call.

See Also

CoInitializeSecurity()