📄 ctxtapi.cxx
字号:
//+-----------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (c) Microsoft Corporation 1992 - 1996
//
// File: ctxtapi.cxx
//
// Contents: Context APIs for the NtLm security package
// Main entry points into this dll:
// SpDeleteContext
// SpInitLsaModeContext
// SpApplyControlToken
// SpAcceptLsaModeContext
//
// History: ChandanS 26-Jul-1996 Stolen from kerberos\client2\ctxtapi.cxx
//
//------------------------------------------------------------------------
#define NTLM_CTXTAPI
#include <global.h>
//+-------------------------------------------------------------------------
//
// Function: SpDeleteContext
//
// Synopsis: Deletes an NtLm context
//
// Effects:
//
// Arguments: ContextHandle - The context to delete
//
// Requires:
//
// Returns: STATUS_SUCCESS or STATUS_INVALID_HANDLE
//
// Notes:
//
//
//--------------------------------------------------------------------------
NTSTATUS NTAPI
SpDeleteContext(
IN ULONG_PTR ContextHandle
)
/*++
Routine Description:
Deletes the local data structures associated with the specified
security context.
This API terminates a context on the local machine.
Arguments:
ContextHandle - Handle to the context to delete
Return Value:
STATUS_SUCCESS - Call completed successfully
SEC_E_NO_SPM -- Security Support Provider is not running
SEC_E_INVALID_HANDLE -- Credential/Context Handle is invalid
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
ULONG_PTR TempContextHandle = ContextHandle;
SspPrint((SSP_API, "Entering SpDeleteContext for 0x%x\n", ContextHandle));
// BUGBUG Check args specific to NTLM
Status = SsprDeleteSecurityContext(
TempContextHandle );
SspPrint((SSP_API, "Leaving SpDeleteContext for 0x%x\n", ContextHandle));
return (SspNtStatusToSecStatus(Status, SEC_E_INTERNAL_ERROR));
}
//+-------------------------------------------------------------------------
//
// Function: SpInitLsaModeContext
//
// Synopsis: NtLm implementation of InitializeSecurityContext
// while in Lsa mode. If we return TRUE in *MappedContext,
// secur32 will call SpInitUserModeContext with
// the returned context handle and ContextData
// as input. Fill in whatever info needed for
// the user mode apis
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes: This function can be called in various ways:
// 1. Generic users of ntlm make the first call to
// InitializeSecurityContext and we return a NEGOTIATE_MESSAGE
// 2. The rdr makes the first call to InitializeSecurityContext
// with no contextHandle but info is passed in through a
// CHALLENGE_MESSAGE (& possibly an NTLM_CHALLENGE_MESSAGE),
// we return an AUTHENTICATE_MESSAGE and an
// NTLM_INITIALIZE_RESPONSE
// 3. Generic users of NTLM make the second call to
// InitializeSecurityContext, passing in a CHALLENGE_MESSAGE
// and we return an AUTHENTICATE_MESSAGE
//
//--------------------------------------------------------------------------
NTSTATUS NTAPI
SpInitLsaModeContext(
IN OPTIONAL ULONG_PTR CredentialHandle,
IN OPTIONAL ULONG_PTR OldContextHandle,
IN OPTIONAL PUNICODE_STRING TargetName,
IN ULONG ContextReqFlags,
IN ULONG TargetDataRep,
IN PSecBufferDesc InputBuffers,
OUT PULONG_PTR NewContextHandle,
IN OUT PSecBufferDesc OutputBuffers,
OUT PULONG ContextAttributes,
OUT PTimeStamp ExpirationTime,
OUT PBOOLEAN MappedContext,
OUT PSecBuffer ContextData
)
{
NTSTATUS Status = STATUS_SUCCESS;
SecBuffer TempTokens[4];
PSecBuffer FirstInputToken;
PSecBuffer SecondInputToken;
PSecBuffer FirstOutputToken;
PSecBuffer SecondOutputToken;
ULONG_PTR OriginalContextHandle = NULL;
ULONG_PTR TempContextHandle = NULL;
ULONG NegotiateFlags = 0;
UCHAR SessionKey[MSV1_0_USER_SESSION_KEY_LENGTH];
SspPrint((SSP_API, "Entering SpInitLsaModeContext for Old:0x%x, New:0x%x\n", OldContextHandle, *NewContextHandle));
// BUGBUG Check args specific to NTLM
RtlZeroMemory(
TempTokens,
sizeof(TempTokens)
);
FirstInputToken = &TempTokens[0];
SecondInputToken = &TempTokens[1];
FirstOutputToken = &TempTokens[2];
SecondOutputToken = &TempTokens[3];
*MappedContext = FALSE;
ASSERT(ContextData);
ContextData->pvBuffer = NULL;
ContextData->cbBuffer = 0;
RtlZeroMemory(SessionKey,
MSV1_0_USER_SESSION_KEY_LENGTH);
#ifdef notdef // ? RPC passes 0x10 or 0 here depending on attitude
if ( TargetDataRep != SECURITY_NATIVE_DREP ) {
Status = STATUS_INVALID_PARAMETER;
SspPrint((SSP_CRITICAL, "SpInitLsaModeContext, TargetdataRep is 0x%lx\n", TargetDataRep));
goto Cleanup;
}
#else // notdef
UNREFERENCED_PARAMETER( TargetDataRep );
#endif // notdef
//
// Extract tokens from the SecBuffers
//
if ( !SspGetTokenBuffer( InputBuffers,
0, // get the first SECBUFFER_TOKEN
&FirstInputToken,
TRUE
) ) {
Status = SEC_E_INVALID_TOKEN;
SspPrint((SSP_CRITICAL, "SpInitLsaModeContext, SspGetTokenBuffer (FirstInputToken) returns %d\n", Status));
goto Cleanup;
}
//
// If we are using supplied credentials, gte the second SECBUFFER_TOKEN
//
if (ContextReqFlags & ISC_REQ_USE_SUPPLIED_CREDS)
{
if ( !SspGetTokenBuffer( InputBuffers,
1, // get the second SECBUFFER_TOKEN
&SecondInputToken,
TRUE
) ) {
Status = SEC_E_INVALID_TOKEN;
SspPrint((SSP_CRITICAL, "SpInitLsaModeContext, SspGetTokenBuffer (SecondInputToken) returns %d\n", Status));
goto Cleanup;
}
}
if ( !SspGetTokenBuffer( OutputBuffers,
0, // get the first SECBUFFER_TOKEN
&FirstOutputToken,
FALSE
) ) {
Status = SEC_E_INVALID_TOKEN;
SspPrint((SSP_CRITICAL, "SpInitLsaModeContext, SspGetTokenBuffer (FirstOutputToken) returns %d\n", Status));
goto Cleanup;
}
if ( !SspGetTokenBuffer( OutputBuffers,
1, // get the second SECBUFFER_TOKEN
&SecondOutputToken,
FALSE
) ) {
Status = SEC_E_INVALID_TOKEN;
SspPrint((SSP_CRITICAL, "SpInitLsaModeContext, SspGetTokenBuffer (SecondOutputToken) returns %d\n", Status));
goto Cleanup;
}
//
// Save the old context handle, in case someone changes it
//
TempContextHandle = OldContextHandle;
OriginalContextHandle = OldContextHandle;
//
// If no previous context was passed
// and if no legitimate input token existed, this is the first call
//
if ((OriginalContextHandle == 0 ) &&
(FirstInputToken->cbBuffer == 0))
{
if ( !ARGUMENT_PRESENT( CredentialHandle ) ) {
Status = STATUS_INVALID_HANDLE;
SspPrint((SSP_CRITICAL, "SpInitLsaModeContext, No CredentialHandle\n"));
goto Cleanup;
}
*NewContextHandle = 0;
Status = SsprHandleFirstCall(
CredentialHandle,
NewContextHandle,
ContextReqFlags,
FirstInputToken->cbBuffer,
FirstInputToken->pvBuffer,
&FirstOutputToken->cbBuffer,
&FirstOutputToken->pvBuffer,
ContextAttributes,
ExpirationTime,
SessionKey,
&NegotiateFlags );
TempContextHandle = *NewContextHandle;
//
// If context was passed in, continue where we left off.
// Or if the redir's passing in stuff in the InputBuffers,
// skip the first call and get on with the second
//
} else {
*NewContextHandle = OldContextHandle;
Status = SsprHandleChallengeMessage(
CredentialHandle,
&TempContextHandle,
NULL, // No client token
NULL, // No logon ID
ContextReqFlags,
FirstInputToken->cbBuffer,
FirstInputToken->pvBuffer,
SecondInputToken->cbBuffer,
SecondInputToken->pvBuffer,
&FirstOutputToken->cbBuffer,
&FirstOutputToken->pvBuffer,
&SecondOutputToken->cbBuffer,
&SecondOutputToken->pvBuffer,
ContextAttributes,
ExpirationTime,
SessionKey,
&NegotiateFlags
);
}
//
// If the original handle is zero, set it to be the TempContextHandle.
// This is for the datagram case, where we map the context after the
// first call to initialize.
//
if (OriginalContextHandle == 0) {
OriginalContextHandle = TempContextHandle;
*NewContextHandle = OriginalContextHandle;
}
//
// Only map the context if this is the real authentication, not a re-auth
// or if this was datagram.
//
if (((Status == SEC_I_CONTINUE_NEEDED) &&
((*ContextAttributes & ISC_RET_DATAGRAM) != 0)) ||
((Status == SEC_E_OK) &&
((*ContextAttributes & (SSP_RET_REAUTHENTICATION | ISC_RET_DATAGRAM)) == 0))) {
NTSTATUS TempStatus;
TempStatus = SspMapContext(
&OriginalContextHandle,
SessionKey,
NegotiateFlags,
NULL, // no token handle for clients
NULL, // no password expiry for clients
0, // no userflags
ContextData
);
if (!NT_SUCCESS(TempStatus)) {
Status = TempStatus;
SspPrint((SSP_CRITICAL, "SpInitLsaModeContext, SspMapContext returns %d\n", Status));
goto Cleanup;
}
SspPrint((SSP_SESSION_KEYS, "Init sessionkey %lx %lx %lx %lx\n",
((DWORD*)SessionKey)[0],
((DWORD*)SessionKey)[1],
((DWORD*)SessionKey)[2],
((DWORD*)SessionKey)[3]
));
//
// Yes, do load msv1_0.dll in the client's process
// and ContextData will contain info to be passed on
// to the InitializeSecurityContext counterpart that
// runs in the client's process
*MappedContext = TRUE;
}
//
// Make sure this bit isn't sent to the caller
//
*ContextAttributes &= ~SSP_RET_REAUTHENTICATION;
Cleanup:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -