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
Call 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.
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.
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:
General functions called by both clients and servers
Interfaces on client proxies and related helper functions
Server-side functions and call-context interfaces.
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:
* DefaultAccessPermission
* LegacyAuthenticationLevel
* LegacyImpersonationLevel
* LegacyMutualAuthentication
* LegacySecureReferences
To set access to objects of a specific class, there is the single named-value,
AccessPermission
.
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.
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.
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.
|
Description
|
QueryInterface()
|
Returns pointers to supported interfaces. |
AddRef()
|
Increments the reference count. |
Release()
|
Decrements the reference count. |
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. |
- Makes a private copy of the specified proxy.
IClientSecurity::CopyProxy()
HRESULT CopyProxy(
#include <objidl.h>
IUnknown * punkProxy ,
IUnknown ** ppunkCopy
);
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.
[in] Points to the
IUnknown()
interface on the
proxy to be copied.
May not be
NULL
.
[out] On successful return, points to the location of the
IUnknown()
pointer to the copy of the proxy.
It may not be
NULL
.
S_OK
Success.
E_INVALIDARG
One or more arguments are invalid.
- Retrieves authentication information.
IClientSecurity::QueryBlanket()
HRESULT QueryBlanket(
#include <objidl.h>
void * pProxy,
DWORD * pAuthnSvc,
DWORD * pAuthzSvc,
OLECHAR ** pServerPrincName,
DWORD * pAuthnLevel,
DWORD * pImpLevel,
RPC_AUTH_IDENTITY_HANDLE ** ppAuthInfo,
DWORD ** pCapabilities
);
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.
[in] Pointer to the proxy to query.
[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.
[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.
[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.
[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.
[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.
[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.
[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.
S_OK
Success.
E_INVALIDARG
One or more arguments are invalid.
E_OUTOFMEMORY
Insufficient memory to create the pServerPrincName out-parameter.
- Sets the authentication information that will be used to make
calls on the specified proxy.
IClientSecurity::SetBlanket()
HRESULT SetBlanket(
#include <objidl.h>
void * pProxy,
DWORD dwAuthnSvc,
DWORD dwAuthzSvc,
WCHAR * pServerPrincName,
DWORD dwAuthnLevel,
DWORD dwImpLevel,
RPC_AUTH_IDENTITY_HANDLE * pAuthInfo,
DWORD dwCapabilities
);
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
.
[in] Indicates the proxy to set.
[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.
[in] A single
DWORD
value from the list of
RPC_C_AUTHZ_
xxx
constants indicating
the
authorization
service to use.
[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
.
[in] A single
DWORD
value from the list of
RPC_C_AUTHN_LEVEL_
xxx
constants
indicating the authentication level to use.
[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.
[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.
[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.
S_OK
Success, append the headers.
E_INVALIDARG
One or more arguments is invalid.
CoSetProxyBlanket()
,
CoQueryProxyBlanket()
,
RPC_C_AUTHN_
xxx,
RPC_C_AUTHZ_
xxx,
RPC_C_AUTHN_LEVEL_
xxx,
RPC_C_IMP_LEVEL_
xxx
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.
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.
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.
|
Description |
QueryInterface() |
Returns pointers to supported interfaces. |
AddRef() |
Increments the reference count. |
Release() |
Decrements the reference count. |
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. |
- Called by the server to find out about the client that invoked
one of its methods.
IServerSecurity::QueryBlanket()
HRESULT QueryBlanket(
#include <objidl.h>
DWORD* pAuthnSvc,
DWORD* pAuthzSvc,
OLECHAR ** pServerPrincNam,
DWORD * pAuthnLevel,
DWORD * pImpLevel,
RPC_AUTHZ_HANDLE * pPrivs,
DWORD ** pCapabilities
);
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.
[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.
[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.
[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.
[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.
[out] Must be
NULL
; the current authentication level
is not supplied.
[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.
[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.
This method supports the standard return values
E_INVALIDARG
and
E_OUTOFMEMORY
, as well as the following:
S_OK
Success.
- Allows a server to impersonate a client for the duration of a
call.
IServerSecurity::ImpersonateClient()
HRESULT ImpersonateClient(
#include <objidl.h>
);
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.
This method supports the standard return value
E_FAIL
,
as well as the
following:
S_OK
Success.
- Restores the authentication information on a thread to the process's
identity.
IServerSecurity::RevertToSelf()
HRESULT RevertToSelf(
#include <objidl.h>
);
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).
This method supports the standard return value
E_FAIL
,
as well as the
following:
S_OK
Success.
- Indicates whether
IServerSecurity::IsImpersonating()
IServerSecurity::ImpersonateClient()
has been called without a matching call to
IServerSecurity::RevertToSelf()
.
BOOL IsImpersonating(
#include <objidl.h>
);
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.
IServerSecurity::RevertToSelf()
.
- Makes a private copy of the specified proxy.
CoCopyProxy()
HRESULT CoCopyProxy((
#include <objbase.h>
IUnknown * punkProxy,
IUnknown ** ppunkCopy
);
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.
[in] Points to the
IUnknown()
interface on the proxy
to be copied.
May not be
NULL
.
[out] Address of
IUnknown *
pointer variable that
receives the interface
pointer to the copy of the proxy.
It may not be
NULL
.
S_OK
Success.
E_INVALIDARG
One or more arguments are invalid.
IClientSecurity::CopyProxy()
,
Security in
COM
- Retrieves the context of the current call on the current thread.
CoGetCallContext()
HRESULT CoGetCallContext((
#include <objbase.h>
REFIID riid,
void ** ppv
);
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.
[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.
[out]
Address of pointer variable that receives the interface pointer requested
in
riid.
Upon successful return,
*
ppv
contains the requested interface pointer.
S_OK
Success.
E_NOINTERFACE
The call context does not support the interface identified by riid.
IServerSecurity()
,
Security in COM
- Allows the server to impersonate the client of the current call for the
duration of the call.
CoImpersonateClient()
HRESULT CoImpersonateClient((
#include <objbase.h>
);
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.
This function supports the standard return value
E_INVALIDARG
, as well
as the following:
S_OK
Indicates success.
IServerSecurity::ImpersonateClient()
,
Security
in COM
- 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()
CoInitializeSecurity()
,
the
AppID registry values will be ignored, and the
CoInitializeSecurity()
values will be used.
HRESULT CoInitializeSecurity((
#include <objbase.h>
PSECURITY_DESCRIPTOR pVoid,
DWORD cAuthSvc,
SOLE_AUTHENTICATION_SERVICE * asAuthSvc,
void * pReserved1,
DWORD dwAuthnLevel,
DWORD dwImpLevel,
RPC_AUTH_IDENTITY_HANDLE pAuthInfo,
DWORD dwCapabilities,
void * pvReserved2
);
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
[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
.
[in] Count of entries in asAuthSvc. Zero means register no services. A value of -1 tells COM to choose which authentication services to register.
[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.
[in] Reserved for future use; must be
NULL
.
[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.
[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()
.
[in] Reserved for future use; must be
NULL
.
[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.
[in] Reserved for future use; must be zero.
This function supports the standard return value
E_INVALIDARG
, as well
as the following:
S_OK
Indicates success.
- Retrieves a list of the authentication services registered when
the process
called
CoQueryAuthenticationServices()
CoInitializeSecurity()
.
HRESULT CoQueryAuthenticationServices((
#include <objbase.h>
DWORD * pcAuthSvc,
SOLE_AUTHENTICATION_SERVICE ** prgAuthSvc
);
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()
.
[out] Pointer to return the number of entries returned in the
rgAuthSvc
array.
May not be
NULL
.
[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()
.
This function supports the standard return values
E_INVALIDARG
and
E_OUTOFMEMORY
, as well as the following:
S_OK
Indicates success.
CoInitializeSecurity()
,
SOLE_AUTHENTICATION_SERVICE
structure,
Security in COM
- Called by the server to find out about the client that invoked the method
executing on the current thread
CoQueryClientBlanket()
HRESULT CoQueryClientBlanket((
#include <objbase.h>
DWORD * pAuthnSvc,
DWORD * pAuthzSvc,
OLECHAR ** pServerPrincName,
DWORD * pAuthnLevel,
DWORD * pImpLevel,
void ** ppPrivs,
DWORD ** pCapabilities
);
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();
[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.
[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.
[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.
[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.
[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.
[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.
[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.
S_OK
Success.
E_INVALIDARG
One or more arguments are invalid.
E_OUTOFMEMORY
Insufficient memory to create the pServerPrincName out-parameter.
IServerSecurity::QueryBlanket()
,
Security
in COM
- Retrieves the authentication information the client uses to make calls on
the specified proxy.
CoQueryProxyBlanket()
HRESULT CoQueryProxyBlanket((
#include <objbase.h>
void * pProxy,
DWORD * pAuthnSvc,
DWORD * pAuthzSvc,
OLECHAR ** pServerPrincName,
DWORD * pAuthnLevel,
DWORD * pImpLevel,
RPC_AUTH_IDENTITY_HANDLE ** ppAuthInfo,
DWORD ** pCapabilities
);
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.
[in] Pointer to an interface on the proxy to query.
[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.
[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.
[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.
[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.
[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.
[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.
[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.
S_OK
Success.
E_INVALIDARG
One or more arguments are invalid.
E_OUTOFMEMORY
Insufficient memory to create the pasAuthnSvc out-parameter.
IClientSecurity::QueryBlanket
, Security in COM
- Restores the authentication information on a thread of execution to its previous
identity.
CoRevertToSelf()
HRESULT CoRevertToSelf((
#include <objbase.h>
);
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();
This function supports the standard return value
E_INVALIDARG
, as well
as the following:
S_OK
Indicates success.
IServerSecurity::RevertToSelf()
,
CoGetCallContext()
,
Security in COM
- Sets the authentication information that will be used to make calls on the
specified proxy.
CoSetProxyBlanket()
HRESULT CoSetProxyBlanket((
#include <objbase.h>
void * pProxy,
DWORD dwAuthnSvc,
DWORD dwAuthzSvc,
WCHAR * pServerPrincName,
DWORD dwAuthnLevel,
DWORD dwImpLevel,
RPC_AUTH_IDENTITY_HANDLE * pAuthInfo,
DWORD dwCapabilities
);
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();
[in] Pointer to an interface on the proxy for which this authentication information is to be set.
[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.
[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
.
[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
.
[in] A single
DWORD
value from the list of
RPC_C_AUTHN_LEVEL_
xxx
constants
indicating the authentication level to use.
[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.
[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
.
[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.
S_OK
Success, append the headers.
E_INVALIDARG
One or more arguments is invalid.
IClientSecurity::SetBlanket()
,
CoQueryClientBlanket()
,
Security in COM
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;
[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.
[in] A single
DWORD
value from the list of
RPC_C_AUTHZ_
xxx
constants indicating
the
authorization
service to use.
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
.
[in] A single
DWORD
value from the list of
RPC_C_AUTHN_LEVEL_
xxx
constants indicating
the authentication level to use.
[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.
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;
[in] A
DWORD
defining flags to establish indicating
the
further capabilities of this proxy.
Currently, no capability flags are defined.
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.
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;
Reserved for future use. Must be 0.
Pointer to the name of the machine to be used.
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.
Reserved for future use. Must be 0.
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:
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 |
CLSCTX
,
CoGetClassObject()
,
CoGetInstanceFromFile()
,
CoGetInstanceFromIStorage()
,
CoCreateInstanceEx()
,
Locating a Remote Object
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.
CoInitializeSecurity()
,
CoQueryAuthenticationServices()
Used in the security functions and interfaces to specify the authentication level.
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.
IClientSecurity()
,
IServerSecurity()
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.
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).
Used in the security functions and interfaces to specify the authentication level.
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.
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.
CoInitializeSecurity()