1201 lines
35 KiB
C++
1201 lines
35 KiB
C++
|
/*++
|
|||
|
|
|||
|
Copyright (C) Microsoft Corporation, 1991 - 1999
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
dcebind.cxx
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module contains the code implementing the Binding Object DCE RPC
|
|||
|
runtime APIs. APIs which are used only by server applications do not
|
|||
|
live here.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Michael Montague (mikemon) 25-Sep-1991
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include <precomp.hxx>
|
|||
|
#include <rpccfg.h>
|
|||
|
#include <CharConv.hxx>
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
RpcBindingCopy (
|
|||
|
IN RPC_BINDING_HANDLE SourceBinding,
|
|||
|
OUT RPC_BINDING_HANDLE PAPI * DestinationBinding
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine copies binding information and creates a new binding
|
|||
|
handle.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
SourceBinding - Supplies the binding to be duplicated.
|
|||
|
|
|||
|
DestinationBinding - Returns a new binding which is a duplicate of
|
|||
|
SourceBinding.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The status for the operation is returned.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
MESSAGE_OBJECT * Binding;
|
|||
|
THREAD *Thread;
|
|||
|
|
|||
|
InitializeIfNecessary();
|
|||
|
|
|||
|
Thread = ThreadSelf();
|
|||
|
if (Thread == NULL)
|
|||
|
return RPC_S_OUT_OF_MEMORY;
|
|||
|
RpcpPurgeEEInfoFromThreadIfNecessary(Thread);
|
|||
|
|
|||
|
Binding = (MESSAGE_OBJECT *) SourceBinding;
|
|||
|
if (Binding->InvalidHandle(BINDING_HANDLE_TYPE))
|
|||
|
{
|
|||
|
return NDRCCopyContextHandle(SourceBinding, DestinationBinding);
|
|||
|
}
|
|||
|
|
|||
|
return(Binding->BindingCopy((BINDING_HANDLE *PAPI *) DestinationBinding, 0));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
I_RpcBindingCopy (
|
|||
|
IN RPC_BINDING_HANDLE SourceBinding,
|
|||
|
OUT RPC_BINDING_HANDLE PAPI * DestinationBinding
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine copies binding information and creates a new binding
|
|||
|
handle. In addition, context is being maintained by the server over
|
|||
|
this binding handle.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
SourceBinding - Supplies the binding to be duplicated.
|
|||
|
|
|||
|
DestinationBinding - Returns a new binding which is a duplicate of
|
|||
|
SourceBinding.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The status for the operation is returned.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
MESSAGE_OBJECT * Binding;
|
|||
|
|
|||
|
InitializeIfNecessary();
|
|||
|
|
|||
|
Binding = (MESSAGE_OBJECT *) SourceBinding;
|
|||
|
if (Binding->InvalidHandle(BINDING_HANDLE_TYPE))
|
|||
|
return(RPC_S_INVALID_BINDING);
|
|||
|
|
|||
|
return(Binding->BindingCopy((BINDING_HANDLE * PAPI *) DestinationBinding, 1));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
RpcBindingFree (
|
|||
|
IN OUT RPC_BINDING_HANDLE PAPI * Binding
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description :
|
|||
|
|
|||
|
RpcBindingFree releases binding handle resources.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Binding - Supplies the binding handle to be freed, and returns zero.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The status of the operation is returned.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
BINDING_HANDLE * BindingHandle;
|
|||
|
RPC_STATUS Status;
|
|||
|
|
|||
|
// if we're shutting down, don't bother
|
|||
|
// Since our other threads have been nuked, data structures may
|
|||
|
// be in half modified state. Therefore it is unsafe to proceed
|
|||
|
// with freeing the binding handle during shutdown
|
|||
|
if (RtlDllShutdownInProgress())
|
|||
|
{
|
|||
|
*Binding = 0;
|
|||
|
return RPC_S_OK;
|
|||
|
}
|
|||
|
|
|||
|
InitializeIfNecessary();
|
|||
|
|
|||
|
// here it will be more efficient if we succeed, but other code will manage fine
|
|||
|
// even if we don't, so we don't really care about return value
|
|||
|
ThreadSelf();
|
|||
|
|
|||
|
ASSERT(!RpcpCheckHeap());
|
|||
|
|
|||
|
BindingHandle = (BINDING_HANDLE *) *Binding;
|
|||
|
if (BindingHandle->InvalidHandle(BINDING_HANDLE_TYPE))
|
|||
|
return(RPC_S_INVALID_BINDING);
|
|||
|
|
|||
|
Status = BindingHandle->BindingFree();
|
|||
|
*Binding = 0;
|
|||
|
|
|||
|
return(Status);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
RpcBindingReset (
|
|||
|
IN RPC_BINDING_HANDLE Binding
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine sets the endpoint in the supplied binding handle to
|
|||
|
zero. This makes the binding handle a partiallly bound binding
|
|||
|
handle. NOTE: this routine will fail if the binding handle has
|
|||
|
already been used to make remote procedure calls. Based on how
|
|||
|
this routine will be used (to iterate through the entries in the
|
|||
|
endpoint mapper database), this should not be a problem.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Binding - Supplies the binding handle for which the endpoint will
|
|||
|
be set to zero, hence making it a partially bound binding handle.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RPC_S_OK - The operation completed successfully.
|
|||
|
|
|||
|
RPC_S_INVALID_BINDING - The supplied argument is not a valid binding.
|
|||
|
|
|||
|
RPC_S_WRONG_KIND_OF_BINDING - Either the supplied binding is not a
|
|||
|
client binding handle or it is a client binding handle which has
|
|||
|
already been used to make remote procedure calls.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
BINDING_HANDLE * BindingHandle;
|
|||
|
THREAD *Thread;
|
|||
|
|
|||
|
Thread = ThreadSelf();
|
|||
|
if (Thread == NULL)
|
|||
|
return RPC_S_OUT_OF_MEMORY;
|
|||
|
|
|||
|
BindingHandle = (BINDING_HANDLE *) Binding;
|
|||
|
if (BindingHandle->InvalidHandle(BINDING_HANDLE_TYPE))
|
|||
|
return(RPC_S_INVALID_BINDING);
|
|||
|
|
|||
|
return(BindingHandle->BindingReset());
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
RpcBindingFromStringBinding (
|
|||
|
IN unsigned short PAPI * StringBinding,
|
|||
|
OUT RPC_BINDING_HANDLE PAPI * Binding
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine returns a binding handle from a string representation
|
|||
|
of a binding handle.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
StringBinding - Supplies the string representation of a binding handle.
|
|||
|
|
|||
|
Binding - Returns a binding handle constructed from the string
|
|||
|
representation.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The status of the operation is returned.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DCE_BINDING * DceBinding;
|
|||
|
RPC_STATUS Status;
|
|||
|
BINDING_HANDLE * BindingHandle;
|
|||
|
RPC_CHAR __RPC_FAR * CopiedStringBinding;
|
|||
|
THREAD *Thread;
|
|||
|
|
|||
|
InitializeIfNecessary();
|
|||
|
|
|||
|
ASSERT(!RpcpCheckHeap());
|
|||
|
|
|||
|
Thread = ThreadSelf();
|
|||
|
if (!Thread)
|
|||
|
return RPC_S_OUT_OF_MEMORY;
|
|||
|
RpcpPurgeEEInfoFromThreadIfNecessary(Thread);
|
|||
|
|
|||
|
*Binding = 0;
|
|||
|
|
|||
|
CopiedStringBinding = (RPC_CHAR *)
|
|||
|
_alloca( (RpcpStringLength(StringBinding)+1)*(sizeof(RPC_CHAR)) );
|
|||
|
if (CopiedStringBinding == 0)
|
|||
|
{
|
|||
|
return (RPC_S_OUT_OF_MEMORY);
|
|||
|
}
|
|||
|
RpcpStringCopy(CopiedStringBinding, StringBinding);
|
|||
|
|
|||
|
DceBinding = new DCE_BINDING(CopiedStringBinding, &Status);
|
|||
|
if (DceBinding == 0)
|
|||
|
Status = RPC_S_OUT_OF_MEMORY;
|
|||
|
|
|||
|
if (Status == RPC_S_OK)
|
|||
|
{
|
|||
|
BindingHandle = DceBinding->CreateBindingHandle(&Status);
|
|||
|
if (Status == RPC_S_OK)
|
|||
|
*Binding = BindingHandle;
|
|||
|
//
|
|||
|
// DceBinding gets deleted by the callee, if the above call fails
|
|||
|
//
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
delete DceBinding;
|
|||
|
}
|
|||
|
|
|||
|
return(Status);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
RpcBindingSetObject (
|
|||
|
IN RPC_BINDING_HANDLE Binding,
|
|||
|
IN UUID PAPI * ObjectUuid
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine sets the object UUID value in a binding handle.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Binding - Supplies the binding handle for which the object UUID is
|
|||
|
to be set.
|
|||
|
|
|||
|
ObjectUuid - Supplies the UUID value to put into the binding handle.
|
|||
|
|
|||
|
Return Values:
|
|||
|
|
|||
|
RPC_S_OK - The operation completed successfully.
|
|||
|
|
|||
|
RPC_S_INVALID_BINDING - The binding argument does not specify a binding
|
|||
|
handle.
|
|||
|
|
|||
|
RPC_S_WRONG_KIND_OF_BINDING - The binding argument does specify a
|
|||
|
binding handle, but it is not a client binding handle (ie. one
|
|||
|
owned by the client side rpc runtime).
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
BINDING_HANDLE * BindingHandle;
|
|||
|
|
|||
|
InitializeIfNecessary();
|
|||
|
|
|||
|
BindingHandle = (BINDING_HANDLE *) Binding;
|
|||
|
if (BindingHandle->InvalidHandle(BINDING_HANDLE_TYPE))
|
|||
|
return(RPC_S_INVALID_BINDING);
|
|||
|
|
|||
|
BindingHandle->SetObjectUuid((RPC_UUID PAPI *) ObjectUuid);
|
|||
|
|
|||
|
return(RPC_S_OK);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
RpcBindingVectorFree (
|
|||
|
IN OUT RPC_BINDING_VECTOR PAPI * PAPI * BindingVector
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine frees the binding handles contained in the vector, and
|
|||
|
the vector itself.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
BindingVector - Supplies a vector of binding handles which will be
|
|||
|
freed. On return, the pointer to the binding vector will be
|
|||
|
set to zero.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The status of the operation will be returned.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
unsigned int Index, Count;
|
|||
|
RPC_BINDING_VECTOR PAPI * Vector;
|
|||
|
RPC_STATUS Status;
|
|||
|
|
|||
|
InitializeIfNecessary();
|
|||
|
|
|||
|
for (Index = 0, Vector = *BindingVector,
|
|||
|
Count = (unsigned int) Vector->Count;
|
|||
|
Index < Count; Index++)
|
|||
|
if (Vector->BindingH[Index] != 0)
|
|||
|
{
|
|||
|
Status = RpcBindingFree(&(Vector->BindingH[Index]));
|
|||
|
if (Status != RPC_S_OK)
|
|||
|
return(Status);
|
|||
|
}
|
|||
|
RpcpFarFree(*BindingVector);
|
|||
|
*BindingVector = 0;
|
|||
|
|
|||
|
return(RPC_S_OK);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
RpcEpResolveBinding (
|
|||
|
IN RPC_BINDING_HANDLE Binding,
|
|||
|
IN RPC_IF_HANDLE IfSpec
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is used to resolve a partially-bound binding handle
|
|||
|
into a fully-bound binding handle. A partially-bound binding
|
|||
|
handle is one in which the endpoint is not specified. To make
|
|||
|
the binding handle fully-bound, we need to determine the endpoint.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Binding - Supplies a partially-bound binding handle to resolve into
|
|||
|
a fully bound one. Specifying a fully-bound binding handle to
|
|||
|
this routine is not an error; it has no effect on the binding
|
|||
|
handle.
|
|||
|
|
|||
|
IfSpec - Supplies a handle to the description of the interface for
|
|||
|
which we wish to resolve the endpoint. This information will
|
|||
|
be used to find the correct server on the machine specified by
|
|||
|
the network address in the binding handle.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RPC_S_OK - The binding handle is now fully-bound.
|
|||
|
|
|||
|
RPC_S_NO_ENDPOINT_FOUND - We were unable to resolve the endpoint
|
|||
|
for this particular combination of binding handle (network address)
|
|||
|
and interface.
|
|||
|
|
|||
|
RPC_S_OUT_OF_MEMORY - Insufficient memory is available to resolve
|
|||
|
the endpoint.
|
|||
|
|
|||
|
RPC_S_INVALID_BINDING - The binding argument does not specify a binding
|
|||
|
handle.
|
|||
|
|
|||
|
RPC_S_WRONG_KIND_OF_BINDING - The binding argument does specify a
|
|||
|
binding handle, but it is not a client binding handle (ie. one
|
|||
|
owned by the client side rpc runtime).
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
BINDING_HANDLE * BindingHandle;
|
|||
|
|
|||
|
InitializeIfNecessary();
|
|||
|
|
|||
|
BindingHandle = (BINDING_HANDLE *) Binding;
|
|||
|
if (BindingHandle->InvalidHandle(BINDING_HANDLE_TYPE))
|
|||
|
return(RPC_S_INVALID_BINDING);
|
|||
|
|
|||
|
return(BindingHandle->ResolveBinding((PRPC_CLIENT_INTERFACE) IfSpec));
|
|||
|
}
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
RpcNsBindingInqEntryName (
|
|||
|
IN RPC_BINDING_HANDLE Binding,
|
|||
|
IN unsigned long EntryNameSyntax,
|
|||
|
OUT unsigned short PAPI * PAPI * EntryName
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RPC_S_OK - The entry name for the binding handle has been successfully
|
|||
|
inquired and returned.
|
|||
|
|
|||
|
RPC_S_INVALID_BINDING - The binding argument does not specify a binding
|
|||
|
handle.
|
|||
|
|
|||
|
RPC_S_WRONG_KIND_OF_BINDING - The binding argument does specify a
|
|||
|
binding handle, but it is not a client binding handle (ie. one
|
|||
|
owned by the client side rpc runtime).
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
#if !defined(NO_LOCATOR_CODE)
|
|||
|
BINDING_HANDLE * BindingHandle;
|
|||
|
|
|||
|
InitializeIfNecessary();
|
|||
|
|
|||
|
BindingHandle = (BINDING_HANDLE *) Binding;
|
|||
|
if (BindingHandle->InvalidHandle(BINDING_HANDLE_TYPE))
|
|||
|
return(RPC_S_INVALID_BINDING);
|
|||
|
|
|||
|
return(BindingHandle->InquireEntryName(EntryNameSyntax, EntryName));
|
|||
|
#else
|
|||
|
return RPC_S_CANNOT_SUPPORT;
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
THUNK_FN(I_RpcNsBindingSetEntryName) (
|
|||
|
IN RPC_BINDING_HANDLE,
|
|||
|
IN unsigned long,
|
|||
|
IN unsigned char *
|
|||
|
)
|
|||
|
{
|
|||
|
return RPC_S_CANNOT_SUPPORT;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
I_RpcNsBindingSetEntryName (
|
|||
|
IN RPC_BINDING_HANDLE Binding,
|
|||
|
IN unsigned long EntryNameSyntax,
|
|||
|
IN unsigned short PAPI * EntryName
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is a private entry point for use by name service support
|
|||
|
dlls; it allows them to set the entry name in a binding handle
|
|||
|
before returning it from import or lookup. If an entry name already
|
|||
|
exists in the binding handle, we just go ahead and overwrite the
|
|||
|
old one with new one.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Binding - Supplies the binding handle for which we want to set the
|
|||
|
entry name.
|
|||
|
|
|||
|
EntryNameSyntax - Supplies the syntax used by the entry name. We need
|
|||
|
to save this information for when the entry name is inquired.
|
|||
|
|
|||
|
EntryName - Supplies the entry name for this binding handle.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RPC_S_OK - The entry name has been successfully set for the binding
|
|||
|
handle.
|
|||
|
|
|||
|
RPC_S_OUT_OF_MEMORY - Insufficient memory is available to complete
|
|||
|
the operation.
|
|||
|
|
|||
|
RPC_S_INVALID_BINDING - The binding argument does not specify a binding
|
|||
|
handle.
|
|||
|
|
|||
|
RPC_S_WRONG_KIND_OF_BINDING - The binding argument does specify a
|
|||
|
binding handle, but it is not a client binding handle (ie. one
|
|||
|
owned by the client side rpc runtime).
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
#if !defined(NO_LOCATOR_CODE)
|
|||
|
BINDING_HANDLE * BindingHandle;
|
|||
|
|
|||
|
InitializeIfNecessary();
|
|||
|
|
|||
|
BindingHandle = (BINDING_HANDLE *) Binding;
|
|||
|
if (BindingHandle->InvalidHandle(BINDING_HANDLE_TYPE))
|
|||
|
return(RPC_S_INVALID_BINDING);
|
|||
|
|
|||
|
return(BindingHandle->SetEntryName(EntryNameSyntax, EntryName));
|
|||
|
#else
|
|||
|
return RPC_S_CANNOT_SUPPORT;
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
RpcBindingInqAuthInfo (
|
|||
|
IN RPC_BINDING_HANDLE Binding,
|
|||
|
OUT unsigned short PAPI * PAPI * ServerPrincName, OPTIONAL
|
|||
|
OUT unsigned long PAPI * AuthnLevel, OPTIONAL
|
|||
|
OUT unsigned long PAPI * AuthnSvc, OPTIONAL
|
|||
|
OUT RPC_AUTH_IDENTITY_HANDLE PAPI * AuthIdentity, OPTIONAL
|
|||
|
OUT unsigned long PAPI * AuthzSvc OPTIONAL
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is used to return the authentication and authorization for
|
|||
|
a binding handle. You should also see RpcBindingSetAuthInfoW.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Binding - Supplies the binding handle for which we wish to query the
|
|||
|
authentication and authorization information.
|
|||
|
|
|||
|
ServerPrincName - Optionally returns the server principal name set for
|
|||
|
the binding handle.
|
|||
|
|
|||
|
AuthnLevel - Optionally returns the authentication level set for the
|
|||
|
binding handle.
|
|||
|
|
|||
|
AuthnSvc - Optionally returns the authentication service set for the
|
|||
|
binding handle.
|
|||
|
|
|||
|
AuthIdentity - Optionally returns a handle to the security context
|
|||
|
being used for authentication and authorization.
|
|||
|
|
|||
|
AuthzSvc - Optionally returns the authorization service set for the
|
|||
|
binding handle.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RPC_S_OK - We successfully returned the information requested.
|
|||
|
|
|||
|
RPC_S_OUT_OF_MEMORY - Insufficient memory is available to complete
|
|||
|
the operation.
|
|||
|
|
|||
|
RPC_S_INVALID_BINDING - The value supplied as the binding argument is
|
|||
|
not a valid binding handle.
|
|||
|
|
|||
|
RPC_S_WRONG_KIND_OF_BINDING - A binding handle on the client side must
|
|||
|
be specified as the binding argument.
|
|||
|
|
|||
|
RPC_S_BINDING_HAS_NO_AUTH - RpcBindingInqAuthInfo has not yet been
|
|||
|
called on the binding handle, so there is not authentication or
|
|||
|
authorization to be returned.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
BINDING_HANDLE * BindingObject;
|
|||
|
CLIENT_AUTH_INFO * ClientAuthInfo;
|
|||
|
|
|||
|
InitializeIfNecessary();
|
|||
|
|
|||
|
return( RpcBindingInqAuthInfoEx(
|
|||
|
Binding,
|
|||
|
ServerPrincName,
|
|||
|
AuthnLevel,
|
|||
|
AuthnSvc,
|
|||
|
AuthIdentity,
|
|||
|
AuthzSvc,
|
|||
|
0,
|
|||
|
0
|
|||
|
) );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
RpcBindingInqAuthInfoEx (
|
|||
|
IN RPC_BINDING_HANDLE Binding,
|
|||
|
OUT unsigned short PAPI * PAPI * ServerPrincName, OPTIONAL
|
|||
|
OUT unsigned long PAPI * AuthnLevel, OPTIONAL
|
|||
|
OUT unsigned long PAPI * AuthnSvc, OPTIONAL
|
|||
|
OUT RPC_AUTH_IDENTITY_HANDLE PAPI * AuthIdentity, OPTIONAL
|
|||
|
OUT unsigned long PAPI * AuthzSvc, OPTIONAL
|
|||
|
IN unsigned long RpcSecurityQosVersion,
|
|||
|
OUT RPC_SECURITY_QOS * SecurityQos
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is used to return the authentication and authorization for
|
|||
|
a binding handle. You should also see RpcBindingSetAuthInfoW.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Binding - Supplies the binding handle for which we wish to query the
|
|||
|
authentication and authorization information.
|
|||
|
|
|||
|
ServerPrincName - Optionally returns the server principal name set for
|
|||
|
the binding handle.
|
|||
|
|
|||
|
AuthnLevel - Optionally returns the authentication level set for the
|
|||
|
binding handle.
|
|||
|
|
|||
|
AuthnSvc - Optionally returns the authentication service set for the
|
|||
|
binding handle.
|
|||
|
|
|||
|
AuthIdentity - Optionally returns a handle to the security context
|
|||
|
being used for authentication and authorization.
|
|||
|
|
|||
|
AuthzSvc - Optionally returns the authorization service set for the
|
|||
|
binding handle.
|
|||
|
|
|||
|
RpcSecurityQosVersion - Indicates a version for RPC_SECURITY_QOS structure,
|
|||
|
that optionally can be inquired. If SecurityQOS passes in is 0, this
|
|||
|
is ignored.
|
|||
|
|
|||
|
SecurityQOS - is the version of the Security Quality Of Service
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RPC_S_OK - We successfully returned the information requested.
|
|||
|
|
|||
|
RPC_S_OUT_OF_MEMORY - Insufficient memory is available to complete
|
|||
|
the operation.
|
|||
|
|
|||
|
RPC_S_INVALID_BINDING - The value supplied as the binding argument is
|
|||
|
not a valid binding handle.
|
|||
|
|
|||
|
RPC_S_WRONG_KIND_OF_BINDING - A binding handle on the client side must
|
|||
|
be specified as the binding argument.
|
|||
|
|
|||
|
RPC_S_BINDING_HAS_NO_AUTH - RpcBindingInqAuthInfo has not yet been
|
|||
|
called on the binding handle, so there is not authentication or
|
|||
|
authorization to be returned.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
BINDING_HANDLE * BindingObject;
|
|||
|
CLIENT_AUTH_INFO * ClientAuthInfo;
|
|||
|
|
|||
|
InitializeIfNecessary();
|
|||
|
|
|||
|
BindingObject = (BINDING_HANDLE *) Binding;
|
|||
|
if ( BindingObject->InvalidHandle(BINDING_HANDLE_TYPE) )
|
|||
|
{
|
|||
|
return(RPC_S_INVALID_BINDING);
|
|||
|
}
|
|||
|
|
|||
|
ClientAuthInfo = BindingObject->InquireAuthInformation();
|
|||
|
if ( ClientAuthInfo == 0
|
|||
|
|| ClientAuthInfo->AuthenticationLevel == RPC_C_AUTHN_LEVEL_NONE)
|
|||
|
{
|
|||
|
return(RPC_S_BINDING_HAS_NO_AUTH);
|
|||
|
}
|
|||
|
|
|||
|
if (ARGUMENT_PRESENT(AuthnLevel))
|
|||
|
{
|
|||
|
*AuthnLevel = ClientAuthInfo->AuthenticationLevel;
|
|||
|
}
|
|||
|
if (ARGUMENT_PRESENT(AuthnSvc))
|
|||
|
{
|
|||
|
*AuthnSvc = ClientAuthInfo->AuthenticationService;
|
|||
|
}
|
|||
|
if (ARGUMENT_PRESENT(AuthIdentity))
|
|||
|
{
|
|||
|
*AuthIdentity = ClientAuthInfo->AuthIdentity;
|
|||
|
}
|
|||
|
if (ARGUMENT_PRESENT(AuthzSvc))
|
|||
|
{
|
|||
|
*AuthzSvc = ClientAuthInfo->AuthorizationService;
|
|||
|
}
|
|||
|
if (ARGUMENT_PRESENT(ServerPrincName))
|
|||
|
{
|
|||
|
if ( ClientAuthInfo->ServerPrincipalName == 0 )
|
|||
|
{
|
|||
|
*ServerPrincName = 0;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
*ServerPrincName = DuplicateStringPAPI(
|
|||
|
ClientAuthInfo->ServerPrincipalName);
|
|||
|
if ( *ServerPrincName == 0 )
|
|||
|
{
|
|||
|
return(RPC_S_OUT_OF_MEMORY);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (ARGUMENT_PRESENT(SecurityQos))
|
|||
|
{
|
|||
|
if (RpcSecurityQosVersion != RPC_C_SECURITY_QOS_VERSION)
|
|||
|
{
|
|||
|
if (ARGUMENT_PRESENT(ServerPrincName))
|
|||
|
delete *ServerPrincName;
|
|||
|
return (RPC_S_INVALID_ARG);
|
|||
|
}
|
|||
|
SecurityQos->Version = RPC_C_SECURITY_QOS_VERSION;
|
|||
|
SecurityQos->Capabilities = ClientAuthInfo->Capabilities;
|
|||
|
SecurityQos->ImpersonationType = ClientAuthInfo->ImpersonationType;
|
|||
|
SecurityQos->IdentityTracking = ClientAuthInfo->IdentityTracking;
|
|||
|
}
|
|||
|
return(RPC_S_OK);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
RpcBindingSetAuthInfo (
|
|||
|
IN RPC_BINDING_HANDLE Binding,
|
|||
|
IN unsigned short PAPI * ServerPrincName,
|
|||
|
IN unsigned long AuthnLevel,
|
|||
|
IN unsigned long AuthnSvc,
|
|||
|
IN RPC_AUTH_IDENTITY_HANDLE AuthIdentity, OPTIONAL
|
|||
|
IN unsigned long AuthzSvc
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
A client application will use this routine to specify the authentication
|
|||
|
and authorization information in a binding handle, so that the binding
|
|||
|
handle can be used to make authenticated remote procedure calls. If
|
|||
|
the this routine is not used, then all remote procedure calls on the
|
|||
|
binding handle will be unauthenticated.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Binding - Supplies binding handle for which we want to set authentication
|
|||
|
and authorization information.
|
|||
|
|
|||
|
ServerPrincName - Supplies the expected principal name of the server
|
|||
|
referenced by the binding handle (that is supplied as the binding
|
|||
|
argument). This information is necessary for some security services
|
|||
|
to be able to authenticate with the server.
|
|||
|
|
|||
|
AuthnLevel - Supplies a value indicating the amount (or level) of
|
|||
|
authentication to be performed on remote procedure calls using
|
|||
|
the binding handle. If we do not support the requested level,
|
|||
|
we will upgrade to the next highest supported level.
|
|||
|
|
|||
|
RPC_C_AUTHN_LEVEL_DEFAULT - Indicates that the default level for
|
|||
|
authentication service being used should be used.
|
|||
|
|
|||
|
RPC_C_AUTHN_LEVEL_NONE - Do not perform any authentication.
|
|||
|
|
|||
|
RPC_C_AUTHN_LEVEL_CONNECT - Authentication will be performed only
|
|||
|
when the client first talks to the server.
|
|||
|
|
|||
|
RPC_C_AUTHN_LEVEL_CALL - For connection based protocols, we will
|
|||
|
use RPC_C_AUTHN_LEVEL_PKT instead; for datagram based protocols,
|
|||
|
authentication will be performed at the beginning of each
|
|||
|
remote procedure call.
|
|||
|
|
|||
|
RPC_C_AUTHN_LEVEL_PKT - All data will be authenticated to insure that
|
|||
|
the data it is received from the expected client.
|
|||
|
|
|||
|
RPC_C_AUTHN_LEVEL_PKT_INTEGRITY - In addition, to authenticating that
|
|||
|
the data is from the expected client, we will verify that none
|
|||
|
of it has been modified.
|
|||
|
|
|||
|
RPC_C_AUTHN_LEVEL_PKT_PRIVACY - Finally, this includes all of the
|
|||
|
support in packet integrity, as well as encrypting all remote
|
|||
|
procedure call data.
|
|||
|
|
|||
|
AuthnSvc - Supplies the authentication service to use.
|
|||
|
|
|||
|
AuthIdentify - Optionally supplies authentication and authorization
|
|||
|
credentials to use; if this argument is not specified, the security
|
|||
|
context for the current address space will be used.
|
|||
|
|
|||
|
AuthzSvc - Supplies the authorization service being used by the
|
|||
|
server. The client must know this so that the correct authorization
|
|||
|
information can be sent to the server.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RPC_S_OK - The supplied authentication and authorization information has
|
|||
|
been set in the binding handle.
|
|||
|
|
|||
|
RPC_S_OUT_OF_MEMORY - Insufficient memory is available to complete the
|
|||
|
operation.
|
|||
|
|
|||
|
RPC_S_INVALID_BINDING - The value supplied as the binding argument is
|
|||
|
not a valid binding handle.
|
|||
|
|
|||
|
RPC_S_WRONG_KIND_OF_BINDING - A binding handle on the client side must
|
|||
|
be specified as the binding argument.
|
|||
|
|
|||
|
RPC_S_UNKNOWN_AUTHN_SERVICE - The specified authentication service is
|
|||
|
not supported.
|
|||
|
|
|||
|
RPC_S_UNKNOWN_AUTHN_LEVEL - The specified authentication level is
|
|||
|
not supported.
|
|||
|
|
|||
|
RPC_S_INVALID_AUTH_IDENTITY - The specified security context (supplied
|
|||
|
by the auth identity argument) is invalid.
|
|||
|
|
|||
|
RPC_S_UNKNOWN_AUTHZ_SERVICE - The specified authorization service is
|
|||
|
not supported.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return ( RpcBindingSetAuthInfoEx(
|
|||
|
Binding,
|
|||
|
ServerPrincName,
|
|||
|
AuthnLevel,
|
|||
|
AuthnSvc,
|
|||
|
AuthIdentity,
|
|||
|
AuthzSvc,
|
|||
|
0 ) );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
RpcBindingSetAuthInfoEx (
|
|||
|
IN RPC_BINDING_HANDLE Binding,
|
|||
|
IN unsigned short PAPI * ServerPrincName,
|
|||
|
IN unsigned long AuthnLevel,
|
|||
|
IN unsigned long AuthnSvc,
|
|||
|
IN RPC_AUTH_IDENTITY_HANDLE AuthIdentity, OPTIONAL
|
|||
|
IN unsigned long AuthzSvc,
|
|||
|
IN RPC_SECURITY_QOS *SecurityQOS
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
A client application will use this routine to specify the authentication
|
|||
|
and authorization information in a binding handle, so that the binding
|
|||
|
handle can be used to make authenticated remote procedure calls. If
|
|||
|
the this routine is not used, then all remote procedure calls on the
|
|||
|
binding handle will be unauthenticated.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Binding - Supplies binding handle for which we want to set authentication
|
|||
|
and authorization information.
|
|||
|
|
|||
|
ServerPrincName - Supplies the expected principal name of the server
|
|||
|
referenced by the binding handle (that is supplied as the binding
|
|||
|
argument). This information is necessary for some security services
|
|||
|
to be able to authenticate with the server.
|
|||
|
|
|||
|
AuthnLevel - Supplies a value indicating the amount (or level) of
|
|||
|
authentication to be performed on remote procedure calls using
|
|||
|
the binding handle. If we do not support the requested level,
|
|||
|
we will upgrade to the next highest supported level.
|
|||
|
|
|||
|
RPC_C_AUTHN_LEVEL_DEFAULT - Indicates that the default level for
|
|||
|
authentication service being used should be used.
|
|||
|
|
|||
|
RPC_C_AUTHN_LEVEL_NONE - Do not perform any authentication.
|
|||
|
|
|||
|
RPC_C_AUTHN_LEVEL_CONNECT - Authentication will be performed only
|
|||
|
when the client first talks to the server.
|
|||
|
|
|||
|
RPC_C_AUTHN_LEVEL_CALL - For connection based protocols, we will
|
|||
|
use RPC_C_AUTHN_LEVEL_PKT instead; for datagram based protocols,
|
|||
|
authentication will be performed at the beginning of each
|
|||
|
remote procedure call.
|
|||
|
|
|||
|
RPC_C_AUTHN_LEVEL_PKT - All data will be authenticated to insure that
|
|||
|
the data it is received from the expected client.
|
|||
|
|
|||
|
RPC_C_AUTHN_LEVEL_PKT_INTEGRITY - In addition, to authenticating that
|
|||
|
the data is from the expected client, we will verify that none
|
|||
|
of it has been modified.
|
|||
|
|
|||
|
RPC_C_AUTHN_LEVEL_PKT_PRIVACY - Finally, this includes all of the
|
|||
|
support in packet integrity, as well as encrypting all remote
|
|||
|
procedure call data.
|
|||
|
|
|||
|
AuthnSvc - Supplies the authentication service to use.
|
|||
|
|
|||
|
AuthIdentify - Optionally supplies authentication and authorization
|
|||
|
credentials to use; if this argument is not specified, the security
|
|||
|
context for the current address space will be used.
|
|||
|
|
|||
|
AuthzSvc - Supplies the authorization service being used by the
|
|||
|
server. The client must know this so that the correct authorization
|
|||
|
information can be sent to the server.
|
|||
|
|
|||
|
SecurityQOS - a security QOS stucture. Currently accepting RPC_C_SECURITY_QOS_VERSION_2
|
|||
|
and RPC_C_SECURITY_QOS_VERSION_1
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RPC_S_OK - The supplied authentication and authorization information has
|
|||
|
been set in the binding handle.
|
|||
|
|
|||
|
RPC_S_OUT_OF_MEMORY - Insufficient memory is available to complete the
|
|||
|
operation.
|
|||
|
|
|||
|
RPC_S_INVALID_BINDING - The value supplied as the binding argument is
|
|||
|
not a valid binding handle.
|
|||
|
|
|||
|
RPC_S_WRONG_KIND_OF_BINDING - A binding handle on the client side must
|
|||
|
be specified as the binding argument.
|
|||
|
|
|||
|
RPC_S_UNKNOWN_AUTHN_SERVICE - The specified authentication service is
|
|||
|
not supported.
|
|||
|
|
|||
|
RPC_S_UNKNOWN_AUTHN_LEVEL - The specified authentication level is
|
|||
|
not supported.
|
|||
|
|
|||
|
RPC_S_INVALID_AUTH_IDENTITY - The specified security context (supplied
|
|||
|
by the auth identity argument) is invalid.
|
|||
|
|
|||
|
RPC_S_UNKNOWN_AUTHZ_SERVICE - The specified authorization service is
|
|||
|
not supported.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
BINDING_HANDLE * BindingObject;
|
|||
|
RPC_STATUS Status;
|
|||
|
RPC_CHAR __RPC_FAR * ServerName;
|
|||
|
unsigned long ImpersonationType;
|
|||
|
unsigned long IdentityTracking;
|
|||
|
unsigned long Capabilities;
|
|||
|
void *AdditionalCredentials;
|
|||
|
ULONG AdditionalTransportCredentialsType;
|
|||
|
THREAD *Thread;
|
|||
|
RPC_HTTP_TRANSPORT_CREDENTIALS_W *HttpCredentials;
|
|||
|
unsigned int i;
|
|||
|
|
|||
|
InitializeIfNecessary();
|
|||
|
|
|||
|
Thread = ThreadSelf();
|
|||
|
if (Thread)
|
|||
|
{
|
|||
|
RpcpPurgeEEInfoFromThreadIfNecessary(Thread);
|
|||
|
}
|
|||
|
|
|||
|
BindingObject = (BINDING_HANDLE *) Binding;
|
|||
|
|
|||
|
if ((SecurityQOS != 0) &&
|
|||
|
(SecurityQOS->Version != RPC_C_SECURITY_QOS_VERSION_1) &&
|
|||
|
(SecurityQOS->Version != RPC_C_SECURITY_QOS_VERSION_2) )
|
|||
|
{
|
|||
|
return(RPC_S_INVALID_ARG);
|
|||
|
}
|
|||
|
|
|||
|
if ( BindingObject->InvalidHandle(BINDING_HANDLE_TYPE) )
|
|||
|
{
|
|||
|
return(RPC_S_INVALID_BINDING);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// For no authentication, bail out now.
|
|||
|
//
|
|||
|
|
|||
|
if (AuthnSvc == RPC_C_AUTHN_NONE)
|
|||
|
{
|
|||
|
if ((AuthnLevel != RPC_C_AUTHN_LEVEL_NONE) &&
|
|||
|
(AuthnLevel != RPC_C_AUTHN_LEVEL_DEFAULT))
|
|||
|
{
|
|||
|
return(RPC_S_UNKNOWN_AUTHN_LEVEL);
|
|||
|
}
|
|||
|
//
|
|||
|
// Clear the authentication info..
|
|||
|
//
|
|||
|
|
|||
|
Status = BindingObject->SetAuthInformation(
|
|||
|
0,
|
|||
|
RPC_C_AUTHN_LEVEL_NONE,
|
|||
|
AuthnSvc,
|
|||
|
0,
|
|||
|
0
|
|||
|
);
|
|||
|
return(Status);
|
|||
|
}
|
|||
|
|
|||
|
if (AuthnSvc == RPC_C_AUTHN_DEFAULT)
|
|||
|
{
|
|||
|
RpcpGetDefaultSecurityProviderInfo();
|
|||
|
AuthnSvc = DefaultProviderId;
|
|||
|
}
|
|||
|
|
|||
|
if (AuthnSvc == RPC_C_AUTHN_GSS_SCHANNEL)
|
|||
|
{
|
|||
|
if (AuthnLevel < RPC_C_AUTHN_LEVEL_PKT_PRIVACY)
|
|||
|
{
|
|||
|
AuthnLevel = RPC_C_AUTHN_LEVEL_PKT_PRIVACY;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (SecurityQOS != 0)
|
|||
|
{
|
|||
|
IdentityTracking = SecurityQOS->IdentityTracking;
|
|||
|
ImpersonationType= SecurityQOS->ImpersonationType;
|
|||
|
Capabilities = SecurityQOS->Capabilities;
|
|||
|
|
|||
|
if (SecurityQOS->Version == RPC_C_SECURITY_QOS_VERSION_1)
|
|||
|
{
|
|||
|
AdditionalTransportCredentialsType = 0;
|
|||
|
AdditionalCredentials = NULL;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
AdditionalTransportCredentialsType = ((RPC_SECURITY_QOS_V2 *)SecurityQOS)->AdditionalSecurityInfoType;
|
|||
|
AdditionalCredentials = ((RPC_SECURITY_QOS_V2 *)SecurityQOS)->u.HttpCredentials;
|
|||
|
|
|||
|
if (AdditionalTransportCredentialsType != RPC_C_AUTHN_INFO_TYPE_HTTP)
|
|||
|
{
|
|||
|
if (AdditionalTransportCredentialsType != 0)
|
|||
|
return(RPC_S_INVALID_ARG);
|
|||
|
|
|||
|
if (AdditionalCredentials != NULL)
|
|||
|
return(RPC_S_INVALID_ARG);
|
|||
|
}
|
|||
|
else if (AdditionalCredentials == NULL)
|
|||
|
return(RPC_S_INVALID_ARG);
|
|||
|
else
|
|||
|
{
|
|||
|
HttpCredentials = (RPC_HTTP_TRANSPORT_CREDENTIALS_W *)AdditionalCredentials;
|
|||
|
|
|||
|
if (HttpCredentials->TransportCredentials)
|
|||
|
{
|
|||
|
if (HttpCredentials->TransportCredentials->User)
|
|||
|
{
|
|||
|
if (RpcpStringLength(HttpCredentials->TransportCredentials->User)
|
|||
|
!= HttpCredentials->TransportCredentials->UserLength)
|
|||
|
{
|
|||
|
return(RPC_S_INVALID_ARG);
|
|||
|
}
|
|||
|
}
|
|||
|
else if (HttpCredentials->TransportCredentials->UserLength)
|
|||
|
return(RPC_S_INVALID_ARG);
|
|||
|
|
|||
|
if (HttpCredentials->TransportCredentials->Domain)
|
|||
|
{
|
|||
|
if (RpcpStringLength(HttpCredentials->TransportCredentials->Domain)
|
|||
|
!= HttpCredentials->TransportCredentials->DomainLength)
|
|||
|
{
|
|||
|
return(RPC_S_INVALID_ARG);
|
|||
|
}
|
|||
|
}
|
|||
|
else if (HttpCredentials->TransportCredentials->DomainLength)
|
|||
|
return(RPC_S_INVALID_ARG);
|
|||
|
|
|||
|
if (HttpCredentials->TransportCredentials->Password)
|
|||
|
{
|
|||
|
if (RpcpStringLength(HttpCredentials->TransportCredentials->Password)
|
|||
|
!= HttpCredentials->TransportCredentials->PasswordLength)
|
|||
|
{
|
|||
|
return(RPC_S_INVALID_ARG);
|
|||
|
}
|
|||
|
}
|
|||
|
else if (HttpCredentials->TransportCredentials->PasswordLength)
|
|||
|
return(RPC_S_INVALID_ARG);
|
|||
|
|
|||
|
if (HttpCredentials->TransportCredentials->Flags != SEC_WINNT_AUTH_IDENTITY_UNICODE)
|
|||
|
return(RPC_S_INVALID_ARG);
|
|||
|
}
|
|||
|
|
|||
|
// if you don't want to authenticate against anyone, you can't authenticate
|
|||
|
if (HttpCredentials->AuthenticationTarget == 0)
|
|||
|
return(RPC_S_INVALID_ARG);
|
|||
|
|
|||
|
// if you don't support any method of authentication, you can't authenticate
|
|||
|
if (HttpCredentials->NumberOfAuthnSchemes == 0)
|
|||
|
return(RPC_S_INVALID_ARG);
|
|||
|
|
|||
|
// if you don't support any method of authentication, you can't authenticate
|
|||
|
if (HttpCredentials->AuthnSchemes == NULL)
|
|||
|
return(RPC_S_INVALID_ARG);
|
|||
|
|
|||
|
// check whether Negotiate, Passport or Digest are in the list of auth scehemes. If yes,
|
|||
|
// reject the call since we don't support them yet.
|
|||
|
for (i = 0; i < HttpCredentials->NumberOfAuthnSchemes; i ++)
|
|||
|
{
|
|||
|
if (HttpCredentials->AuthnSchemes[i] == RPC_C_HTTP_AUTHN_SCHEME_PASSPORT)
|
|||
|
return RPC_S_CANNOT_SUPPORT;
|
|||
|
if (HttpCredentials->AuthnSchemes[i] == RPC_C_HTTP_AUTHN_SCHEME_NEGOTIATE)
|
|||
|
return RPC_S_CANNOT_SUPPORT;
|
|||
|
if (HttpCredentials->AuthnSchemes[i] == RPC_C_HTTP_AUTHN_SCHEME_DIGEST)
|
|||
|
return RPC_S_CANNOT_SUPPORT;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
IdentityTracking = RPC_C_QOS_IDENTITY_STATIC;
|
|||
|
ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE;
|
|||
|
Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;
|
|||
|
AdditionalTransportCredentialsType = 0;
|
|||
|
AdditionalCredentials = NULL;
|
|||
|
}
|
|||
|
|
|||
|
Status = BindingObject->SetAuthInformation(
|
|||
|
ServerPrincName,
|
|||
|
AuthnLevel,
|
|||
|
AuthnSvc,
|
|||
|
AuthIdentity,
|
|||
|
AuthzSvc,
|
|||
|
0,
|
|||
|
ImpersonationType,
|
|||
|
IdentityTracking,
|
|||
|
Capabilities,
|
|||
|
TRUE, // Acquire new credentials
|
|||
|
AdditionalTransportCredentialsType,
|
|||
|
AdditionalCredentials
|
|||
|
);
|
|||
|
|
|||
|
return (Status);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
I_RpcBindingInqSecurityContext (
|
|||
|
IN RPC_BINDING_HANDLE Binding,
|
|||
|
OUT void **SecurityContextHandle
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The status for the operation is returned.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
CALL * Call;
|
|||
|
|
|||
|
InitializeIfNecessary();
|
|||
|
|
|||
|
Call = (CALL *) Binding;
|
|||
|
|
|||
|
if (Call->InvalidHandle(CALL_TYPE))
|
|||
|
return(RPC_S_INVALID_BINDING);
|
|||
|
|
|||
|
return(Call->InqSecurityContext(SecurityContextHandle));
|
|||
|
}
|
|||
|
|
|||
|
RPC_STATUS RPC_ENTRY
|
|||
|
I_RpcTurnOnEEInfoPropagation (
|
|||
|
void
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
Turns on extended error info propagation for this process.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RPC_S_OK.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
g_fSendEEInfo = TRUE;
|
|||
|
|
|||
|
return RPC_S_OK;
|
|||
|
}
|
|||
|
|