Figure 2   Authentication Level Settings

Value
Authentication Level
Flag
Description
0
Default
RPC_C_AUTHN_LEVEL_DEFAULT
The authentication level is chosen automatically using the normal security blanket negotiation algorithm of COM+.
1
None
RPC_C_AUTHN_LEVEL_NONE
No authentication.
2
Connect
RPC_C_AUTHN_LEVEL_CONNECT
Authenticates the client only when the client first connects to the server.
3
Call
RPC_C_AUTHN_LEVEL_CALL
Authenticates the client at the beginning of each remote call.
4
Packet
RPC_C_AUTHN_LEVEL_PKT
Authenticates that all of the data received is from the expected client.
5
Packet Integrity
RPC_C_AUTHN_LEVEL_PKT_INTEGRITY
Authenticates all of the data integrity and verifies that it has not been modified when transferred between the client and the server.
6
Packet Privacy
RPC_C_AUTHN_LEVEL_PKT_PRIVACY
Authenticates, verifies, and privacy-encrypts the arguments passed to every remote call.


Figure 3   Impersonation Level Settings

Value
Impersonation Level
Flag
Description
0
Default
RPC_C_IMP_LEVEL_DEFAULT
The impersonation level is chosen automatically using the normal security blanket negotiation algorithm of COM+.
1
Anonymous
RPC_C_IMP_LEVEL_ANONYMOUS
The client is anonymous to the server. The server cannot obtain the client's identification information, and it cannot impersonate the client. (Not supported.)
2
Identify
RPC_C_IMP_LEVEL_IDENTIFY
The server can obtain the client's identification information. The server can impersonate the client for ACL checking, but it cannot access system objects as the client.
3
Impersonate
RPC_C_IMP_LEVEL_IMPERSONATE
The server can impersonate the client's security context while acting on behalf of the client. This level of impersonation can only be used to access resources on the server's machine.
4
Delegate
RPC_C_IMP_LEVEL_DELEGATE
The server can impersonate the client's security context when making outgoing calls to other servers (on other machines) on behalf of the client.


Figure 7   Authentication for Client Calls

RPC_C_AUTHN_xxx Flag
Description
RPC_C_AUTHN_NONE
No authentication.
RPC_C_AUTHN_DCE_PRIVATE
Distributed Computing Environment (DCE) private key authentication.
RPC_C_AUTHN_DCE_PUBLIC
DCE public key authentication.
RPC_C_AUTHN_GSS_NEGOTIATE
Snego security support provider.
RPC_C_AUTHN_WINNT
NTLM SSP.
RPC_C_AUTHN_GSS_KERBEROS
Kerberos authentication.
RPC_C_AUTHN_DEFAULT
COM+ uses its normal security blanket negotiation algorithm to pick an authentication service.
RPC_C_AUTHN_GSS_CHANNEL
Secure Sockets Layer (SSL).


Figure 9   EOLE_AUTHENTICATION_CAPABILITIES

Enumeration
Description
EOAC_NONE
No capability flags.
EOAC_DEFAULT
Tells COM+ to pick the capabilities using its normal security blanket negotiation algorithm.
EOAC_MUTUAL_AUTH
Not used. Mutual authentication is supported automatically by some authorization services.
EOAC_STATIC_CLOAKING
Tells COM+ that calls should be made under the identity of the client thread token. The client's identity is determined during the first call on a proxy, and whenever the IClient­Security::SetBlanket method is called.
EOAC_DYNAMIC_CLOAKING
Tells COM+ that calls should be made under the identity of the client thread token. The client's identity is determined during every call on a proxy. EOAC_SECURE_REFS Causes COM+ to perform additional callbacks to authenticate distributed reference count calls, to ensure that objects are not released maliciously.
EOAC_SECURE_REFS
Causes COM+ to perform additional callbacks to authenticate distributed reference count calls, to ensure that objects are not released maliciously.
EOAC_ACCESS_CONTROL
CoInitializeSecurity expects pSecDesc to point to an implementation of the IAccess­Control interface. COM+ will use this pointer to call the IAccessControl::IsAccessAllowed method when performing security checks.
EOAC_APPID
CoInitializeSecurity expects pSecDesc to point to a GUID that is installed in the HKEY_CLASSES_ROOT\AppID section of the registry. CoInitializeSecurity uses the security information read from the registry.
EOAC_DISABLE_AAA
Causes any activation where a server process would be launched under the caller's identity (activate-as-activator, also known as launching user in the Distributed COM Configuration utility) to fail with E_ACCESSDENIED. This value allows an application that runs under a privileged account (such as LocalSystem) to prevent its identity from being used to launch untrusted components.


Figure 11   Specifying Activation Credentials


COAUTHIDENTITY AuthIdentity;
AuthIdentity.User = L"User";
AuthIdentity.UserLength = wcslen(L"User");
AuthIdentity.Domain = L"Domain";
AuthIdentity.DomainLength = wcslen(L"Domain");
AuthIdentity.Password = L"Password";
AuthIdentity.PasswordLength = wcslen(L"Password");
AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;

COAUTHINFO AuthInfo;
AuthInfo.dwAuthnSvc = RPC_C_AUTHN_GSS_KERBEROS;
AuthInfo.dwAuthzSvc = RPC_C_AUTHZ_NONE;
AuthInfo.pwszServerPrincName = L"Domain\\MachineName";
AuthInfo.dwAuthnLevel = RPC_C_AUTHN_LEVEL_CONNECT;
AuthInfo.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
AuthInfo.pAuthIdentityData = &AuthIdentity;
AuthInfo.dwCapabilities = EOAC_NONE;

COSERVERINFO ServerInfo;
ServerInfo.dwReserved1 = 0;
ServerInfo.pwszName = L"RemoteServerName";
ServerInfo.pAuthInfo = &AuthInfo;
ServerInfo.dwReserved2 = 0;

MULTI_QI qi;
qi.pIID = &IID_IUnknown;
qi.pItf = NULL;
qi.hr = 0;

HRESULT hr = CoCreateInstanceEx(CLSID_InsideCOM, NULL, 
    CLSCTX_REMOTE_SERVER, &ServerInfo, 1, &qi);

Figure 12   IServerSecurity


interface IServerSecurity : IUnknown
{
    // Called by the server to find out about the client that 
    // has invoked one of its methods
    HRESULT QueryBlanket(
        [out] DWORD    *pAuthnSvc,
        [out] DWORD    *pAuthzSvc,
        [out] OLECHAR **pServerPrincName,
        [out] DWORD    *pAuthnLevel,
        [out] DWORD    *pImpLevel,
        [out] void    **pPrivs,
        [out] DWORD    *pCapabilities);

    // Allows a server to impersonate a client for the duration 
    // of a call
    HRESULT ImpersonateClient();

    // Restores the authentication information on a thread to 
    // the process's identity
    HRESULT RevertToSelf();

    // Indicates whether the server is currently impersonating 
    // the client
    BOOL IsImpersonating();
}

Figure 13   IServerSecurity Helper Functions

Method
Equivalent API Function
QueryBlanket
CoQueryClientBlanket
ImpersonateClient
CoImpersonateClient
RevertToSelf
CoRevertToSelf
IsImpersonating
(none)


Figure 14   Using QueryBlanket


HRESULT CInsideCOM::Sum(int x, int y, int* retval)
{
    DWORD AuthnSvc;
    DWORD AuthzSvc;
    OLECHAR* ServerPrincName;
    DWORD AuthnLevel;
    RPC_AUTHZ_HANDLE Privs;
    DWORD Capabilities;

    hr = CoQueryClientBlanket(&AuthnSvc, &AuthzSvc, 
        &ServerPrincName, &AuthnLevel, NULL, &Privs, &Capabilities);

    // Code omitted here that displays the authentication and 
    // authorization packages...

    // Display the current principal name.
    wprintf(L"ServerPrincName %s\n", ServerPrincName);

    // Free the memory allocated by QueryBlanket.
    CoTaskMemFree(ServerPrincNam);

    // Code omitted here that displays the 
    // authentication level...

    // Display the domain\user information.
    wprintf(L"Privs %s\n", Privs);

    *retval = x + y;
    return S_OK;
}

Figure 15   IClientSecurity Interface


interface IClientSecurity : IUnknown
{
    // Retrieves the current authentication information
    HRESULT QueryBlanket(
        [in]  IUnknown *pProxy,
        [out] DWORD    *pAuthnSvc,
        [out] DWORD    *pAuthzSvc,
        [out] OLECHAR **pServerPrincName,
        [out] DWORD    *pAuthnLevel,
        [out] DWORD    *pImpLevel,
        [out] void    **pAuthInfo,
        [out] DWORD    *pCapabilites);

    // Sets the authentication information that will be used 
    // to make calls on the specified proxy
    HRESULT SetBlanket(
        [in] IUnknown *pProxy,
        [in] DWORD     AuthnSvc,
        [in] DWORD     AuthzSvc,
        [in] OLECHAR  *pServerPrincName,
        [in] DWORD     AuthnLevel,
        [in] DWORD     ImpLevel,
        [in] void     *pAuthInfo,
        [in] DWORD     Capabilities);

    // Makes a copy of the specified proxy
    HRESULT CopyProxy(
        [in]  IUnknown  *pProxy,
        [out] IUnknown **ppCopy);
}

Figure 16   IClientSecurity Helper Functions

Method
Equivalent API Function
QueryBlanket
CoQueryProxyBlanket
SetBlanket
CoSetProxyBlanket
CopyProxy
CoCopyProxy