📄 krnlapi.cxx
字号:
// STATUS_INVALID_HANDLE -- Credential/Context Handle is invalid
// STATUS_UNSUPPORTED_FUNCTION -- Function code is not supported
//
// Notes:
//
//--------------------------------------------------------------------------
NTSTATUS NTAPI
NtLmQueryContextAttributes(
IN ULONG_PTR KernelContextHandle,
IN ULONG Attribute,
IN OUT PVOID Buffer
)
{
NTSTATUS Status = STATUS_SUCCESS;
PSecPkgContext_NamesW ContextNames = NULL;
PSecPkgContext_DceInfo ContextDceInfo = NULL;
PSecPkgContext_SessionKey ContextSessionKeyInfo = NULL;
PSecPkgContext_Sizes ContextSizes = NULL;
PSecPkgContext_Flags ContextFlags = NULL;
PSecPkgContext_PasswordExpiry PasswordExpires;
PSecPkgContext_UserFlags UserFlags;
PSecPkgContext_PackageInfo PackageInfo = NULL;
PNTLM_KERNEL_CONTEXT pContext = NULL;
unsigned int Length = 0;
MAYBE_PAGED_CODE();
DebugLog(( DEB_TRACE, "Entering NtLmQueryContextAttributes\n" ));
Status = NtlmReferenceContext( KernelContextHandle, FALSE );
if ( NT_SUCCESS( Status ) )
{
pContext = (PNTLM_KERNEL_CONTEXT) KernelContextHandle ;
} else {
//
// for PACKAGE_INFO or NEGOTIATION_INFO, don't require a completed
// context.
//
if( (Attribute != SECPKG_ATTR_PACKAGE_INFO) &&
(Attribute != SECPKG_ATTR_NEGOTIATION_INFO)
)
{
DebugLog(( DEB_ERROR,
"Bad kernel context 0x%lx\n", KernelContextHandle));
goto CleanUp_NoDeref;
}
Status = STATUS_SUCCESS;
}
//
// Handle each of the various queried attributes
//
switch ( Attribute ) {
case SECPKG_ATTR_SIZES:
ContextSizes = (PSecPkgContext_Sizes) Buffer;
ContextSizes->cbMaxToken = NTLMSP_MAX_TOKEN_SIZE;
if (pContext->NegotiateFlags & (NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
NTLMSSP_NEGOTIATE_SIGN |
NTLMSSP_NEGOTIATE_SEAL) ) {
ContextSizes->cbMaxSignature = NTLMSSP_MESSAGE_SIGNATURE_SIZE;
} else {
ContextSizes->cbMaxSignature = 0;
}
if (pContext->NegotiateFlags & NTLMSSP_NEGOTIATE_SEAL) {
ContextSizes->cbBlockSize = 1;
ContextSizes->cbSecurityTrailer = NTLMSSP_MESSAGE_SIGNATURE_SIZE;
}
else
{
ContextSizes->cbBlockSize = 0;
ContextSizes->cbSecurityTrailer = 0;
}
break;
//
// No one uses the function so don't go to the overhead of maintaining
// the username in the context structure.
//
case SECPKG_ATTR_DCE_INFO:
ContextDceInfo = (PSecPkgContext_DceInfo) Buffer;
if (ContextDceInfo == NULL)
{
DebugLog(( DEB_ERROR, "Null buffer SECPKG_ATTR_DCE_INFO.\n" ));
Status = STATUS_INVALID_PARAMETER;
goto Cleanup;
}
if (pContext->ContextNames)
{
Length = wcslen(pContext->ContextNames);
}
ContextDceInfo->pPac = (LPWSTR) LsaKernelFunctions->AllocateHeap(
(Length + 1) * sizeof(WCHAR));
if (ContextDceInfo->pPac != NULL)
{
RtlCopyMemory(
ContextDceInfo->pPac,
pContext->ContextNames,
Length * sizeof(WCHAR));
LPWSTR Temp = (LPWSTR)ContextDceInfo->pPac;
Temp[Length] = L'\0';
}
else
{
DebugLog(( DEB_ERROR, "Bad Context->pPac in SECPKG_ATTR_DCE_INFO.\n" ));
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Cleanup;
}
ContextDceInfo->AuthzSvc = 0;
break;
case SECPKG_ATTR_NAMES:
ContextNames = (PSecPkgContext_Names) Buffer;
if (ContextNames == NULL)
{
DebugLog(( DEB_ERROR, "Null buffer SECPKG_ATTR_NAMES.\n" ));
Status = STATUS_INVALID_PARAMETER;
goto Cleanup;
}
if (pContext->ContextNames)
{
Length = wcslen(pContext->ContextNames);
DebugLog(( DEB_TRACE, "NtLmQueryContextAttributes: ContextNames length is 0x%lx\n", Length));
}
ContextNames->sUserName = (LPWSTR) LsaKernelFunctions->AllocateHeap(
(Length + 1) * sizeof(WCHAR));
if (ContextNames->sUserName != NULL)
{
RtlCopyMemory(
ContextNames->sUserName,
pContext->ContextNames,
Length * sizeof(WCHAR));
ContextNames->sUserName[Length] = L'\0';
}
else
{
DebugLog(( DEB_ERROR, "Bad Context->sUserName in SECPKG_ATTR_NAMES.\n" ));
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Cleanup;
}
break;
case SECPKG_ATTR_SESSION_KEY:
ContextSessionKeyInfo = (PSecPkgContext_SessionKey) Buffer;
ContextSessionKeyInfo->SessionKeyLength = MSV1_0_USER_SESSION_KEY_LENGTH;
ContextSessionKeyInfo->SessionKey =
(PUCHAR) LsaKernelFunctions->AllocateHeap(
ContextSessionKeyInfo->SessionKeyLength);
if (ContextSessionKeyInfo->SessionKey != NULL)
{
RtlCopyMemory(
ContextSessionKeyInfo->SessionKey,
pContext->SessionKey,
MSV1_0_USER_SESSION_KEY_LENGTH);
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
break;
case SECPKG_ATTR_PASSWORD_EXPIRY:
PasswordExpires = (PSecPkgContext_PasswordExpiry) Buffer;
if(pContext->PasswordExpiry.QuadPart != 0) {
PasswordExpires->tsPasswordExpires = pContext->PasswordExpiry;
} else {
Status = SEC_E_UNSUPPORTED_FUNCTION;
}
break;
case SECPKG_ATTR_USER_FLAGS:
UserFlags = (PSecPkgContext_UserFlags) Buffer;
UserFlags->UserFlags = pContext->UserFlags;
break;
case SECPKG_ATTR_FLAGS:
{
BOOLEAN Client = (pContext->ClientTokenHandle == 0);
ULONG Flags = 0;
//
// BUGBUG: this doesn't return the complete flags
//
ContextFlags = (PSecPkgContext_Flags) Buffer;
ContextFlags->Flags = 0;
if (pContext->NegotiateFlags & NTLMSSP_NEGOTIATE_SEAL) {
if( Client )
{
Flags |= ISC_RET_CONFIDENTIALITY;
} else {
Flags |= ASC_RET_CONFIDENTIALITY;
}
}
if (pContext->NegotiateFlags & NTLMSSP_NEGOTIATE_SIGN) {
if( Client )
{
Flags |= ISC_RET_SEQUENCE_DETECT | ISC_RET_REPLAY_DETECT | ISC_RET_INTEGRITY;
} else {
Flags |= ASC_RET_SEQUENCE_DETECT | ASC_RET_REPLAY_DETECT | ASC_RET_INTEGRITY;
}
}
if (pContext->NegotiateFlags & NTLMSSP_NEGOTIATE_NULL_SESSION) {
if( Client )
{
Flags |= ISC_RET_NULL_SESSION;
} else {
Flags |= ASC_RET_NULL_SESSION;
}
}
if (pContext->NegotiateFlags & NTLMSSP_NEGOTIATE_DATAGRAM) {
if( Client )
{
Flags |= ISC_RET_DATAGRAM;
} else {
Flags |= ASC_RET_DATAGRAM;
}
}
if (pContext->NegotiateFlags & NTLMSSP_NEGOTIATE_IDENTIFY) {
if( Client )
{
Flags |= ISC_RET_IDENTIFY;
} else {
Flags |= ASC_RET_IDENTIFY;
}
}
ContextFlags->Flags |= Flags;
break;
}
case SECPKG_ATTR_PACKAGE_INFO:
case SECPKG_ATTR_NEGOTIATION_INFO:
//
// Return the information about this package. This is useful for
// callers who used SPNEGO and don't know what package they got.
//
PackageInfo = (PSecPkgContext_PackageInfo) Buffer;
PackageInfo->PackageInfo = (PSecPkgInfoW) LsaKernelFunctions->AllocateHeap(
sizeof(SecPkgInfoW) +
sizeof(NTLMSP_NAME) +
sizeof(NTLMSP_COMMENT)
);
if (PackageInfo->PackageInfo == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Cleanup;
}
PackageInfo->PackageInfo->Name = (LPWSTR) (PackageInfo->PackageInfo + 1);
PackageInfo->PackageInfo->Comment = (LPWSTR) ((((PCHAR) PackageInfo->PackageInfo->Name)) + sizeof(NTLMSP_NAME));
wcscpy(
PackageInfo->PackageInfo->Name,
NTLMSP_NAME
);
wcscpy(
PackageInfo->PackageInfo->Comment,
NTLMSP_COMMENT
);
PackageInfo->PackageInfo->wVersion = SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION;
PackageInfo->PackageInfo->wRPCID = NTLMSP_RPCID;
PackageInfo->PackageInfo->fCapabilities = NTLMSP_CAPS;
PackageInfo->PackageInfo->cbMaxToken = NTLMSP_MAX_TOKEN_SIZE;
if ( Attribute == SECPKG_ATTR_NEGOTIATION_INFO )
{
PSecPkgContext_NegotiationInfo NegInfo ;
NegInfo = (PSecPkgContext_NegotiationInfo) PackageInfo ;
if( pContext ) {
NegInfo->NegotiationState = SECPKG_NEGOTIATION_COMPLETE ;
} else {
NegInfo->NegotiationState = 0;
}
}
break;
case SECPKG_ATTR_LIFESPAN:
default:
Status = STATUS_NOT_SUPPORTED;
break;
}
Cleanup:
if (!NT_SUCCESS(Status)) {
switch ( Attribute) {
case SECPKG_ATTR_NAMES:
if (ContextNames && ContextNames->sUserName)
{
LsaKernelFunctions->FreeHeap(ContextNames->sUserName);
ContextNames->sUserName = NULL;
}
break;
case SECPKG_ATTR_DCE_INFO:
if (ContextDceInfo && ContextDceInfo->pPac)
{
LsaKernelFunctions->FreeHeap(ContextDceInfo->pPac);
ContextDceInfo->pPac = NULL;
}
break;
case SECPKG_ATTR_SESSION_KEY:
if(ContextSessionKeyInfo && ContextSessionKeyInfo->SessionKey)
{
LsaKernelFunctions->FreeHeap(ContextSessionKeyInfo->SessionKey);
ContextSessionKeyInfo->SessionKey = NULL;
}
break;
case SECPKG_ATTR_NEGOTIATION_INFO:
if(PackageInfo && PackageInfo->PackageInfo)
{
LsaKernelFunctions->FreeHeap(PackageInfo->PackageInfo);
PackageInfo->PackageInfo = NULL;
}
break;
}
}
if( pContext ) {
NtlmDerefContext( pContext );
}
CleanUp_NoDeref:
DebugLog(( DEB_TRACE, "Leaving NtLmQueryContextAttributes 0x%lx\n", Status ));
return Status;
}
//+-------------------------------------------------------------------------
//
// Function: NtLmCompleteToken
//
// Synopsis: Completes a context
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
NTSTATUS NTAPI
NtLmCompleteToken(
IN ULONG_PTR ContextHandle,
IN PSecBufferDesc InputBuffer
)
{
UNREFERENCED_PARAMETER (ContextHandle);
UNREFERENCED_PARAMETER (InputBuffer);
PAGED_CODE();
DebugLog(( DEB_TRACE, "Entering NtLmCompleteToken\n" ));
DebugLog(( DEB_TRACE, "Leaving NtLmCompleteToken\n" ));
return(STATUS_NOT_SUPPORTED);
}
//+-------------------------------------------------------------------------
//
// Function: NtLmMakePackedContext
//
// Synopsis: Maps a context to the caller's address space
//
// Effects:
//
// Arguments: Context - The context to map
// MappedContext - Set to TRUE on success
// ContextData - Receives a buffer in the caller's address space
// with the mapped context.
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
NTSTATUS
NtLmMakePackedContext(
IN PNTLM_KERNEL_CONTEXT Context,
OUT PBOOLEAN MappedContext,
OUT PSecBuffer ContextData,
IN ULONG Flags
)
{
NTSTATUS Status = STATUS_SUCCESS;
PNTLM_KERNEL_CONTEXT PackedContext = NULL;
ULONG ContextSize, ContextNameSize = 0;
PAGED_CODE();
// ExAcquireResourceExclusiveLite(&NtLmKernelContextLock, TRUE);
if (Context->ContextNames)
{
ContextNameSize = wcslen(Context->ContextNames);
}
// ExReleaseResource(&NtLmKernelContextLock);
ContextSize = sizeof(NTLM_KERNEL_CONTEXT) +
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -