windows-nt/Source/XPSP1/NT/ds/security/protocols/msv_sspi/ntlmutil.cxx

529 lines
12 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//+-----------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (c) Microsoft Corporation 1992 - 1996
//
// File: ntlmutil.cxx
//
// Contents: Utility functions for NtLm package:
// NtLmDuplicateUnicodeString
// NtLmDuplicateSid
// NtLmAllocate
// NtLmFree
//
//
// History: ChandanS 25-Jul-1996 Stolen from kerberos\client2\kerbutil.cxx
//
//------------------------------------------------------------------------
#include <global.h>
//+-------------------------------------------------------------------------
//
// Function: NtLmDuplicateUnicodeString
//
// Synopsis: Duplicates a UNICODE_STRING. If the source string buffer is
// NULL the destionation will be too.
//
// Effects: allocates memory with LsaFunctions.AllocateLsaHeap
//
// Arguments: DestinationString - Receives a copy of the source string
// SourceString - String to copy
//
// Requires:
//
// Returns: SEC_E_OK - the copy succeeded
// SEC_E_INSUFFICIENT_MEMORY - the call to allocate
// memory failed.
//
// Notes:
//
//
//--------------------------------------------------------------------------
NTSTATUS
NtLmDuplicateUnicodeString(
OUT PUNICODE_STRING DestinationString,
IN OPTIONAL PUNICODE_STRING SourceString
)
{
SspPrint((SSP_MISC, "Entering NtLmDuplicateUnicodeString\n"));
NTSTATUS Status = STATUS_SUCCESS;
DestinationString->Buffer = NULL;
DestinationString->Length =
DestinationString->MaximumLength =
0;
if ((ARGUMENT_PRESENT(SourceString)) &&
(SourceString->Buffer != NULL))
{
DestinationString->Buffer = (LPWSTR) NtLmAllocatePrivateHeap(
SourceString->Length + sizeof(WCHAR));
if (DestinationString->Buffer != NULL)
{
DestinationString->Length = SourceString->Length;
DestinationString->MaximumLength = SourceString->Length + sizeof(WCHAR);
RtlCopyMemory(
DestinationString->Buffer,
SourceString->Buffer,
SourceString->Length
);
DestinationString->Buffer[SourceString->Length/sizeof(WCHAR)] = L'\0';
}
else
{
Status = STATUS_NO_MEMORY;
SspPrint((SSP_CRITICAL, "NtLmDuplicateUnicodeString, NtLmAllocate returns NULL\n"));
goto CleanUp;
}
}
CleanUp:
SspPrint((SSP_MISC, "Leaving NtLmDuplicateUnicodeString\n"));
return(Status);
}
//+-------------------------------------------------------------------------
//
// Function: NtLmDuplicateString
//
// Synopsis: Duplicates a STRING. If the source string buffer is
// NULL the destionation will be too.
//
// Effects: allocates memory with LsaFunctions.AllocatePrivateHeap
//
// Arguments: DestinationString - Receives a copy of the source string
// SourceString - String to copy
//
// Requires:
//
// Returns: SEC_E_OK - the copy succeeded
// SEC_E_INSUFFICIENT_MEMORY - the call to allocate
// memory failed.
//
// Notes:
//
//
//--------------------------------------------------------------------------
NTSTATUS
NtLmDuplicateString(
OUT PSTRING DestinationString,
IN OPTIONAL PSTRING SourceString
)
{
SspPrint((SSP_MISC, "Entering NtLmDuplicateString\n"));
NTSTATUS Status = STATUS_SUCCESS;
DestinationString->Buffer = NULL;
DestinationString->Length =
DestinationString->MaximumLength =
0;
if ((ARGUMENT_PRESENT(SourceString)) &&
(SourceString->Buffer != NULL))
{
DestinationString->Buffer = (LPSTR) NtLmAllocatePrivateHeap(
SourceString->Length + sizeof(CHAR));
if (DestinationString->Buffer != NULL)
{
DestinationString->Length = SourceString->Length;
DestinationString->MaximumLength = SourceString->Length + sizeof(CHAR);
RtlCopyMemory(
DestinationString->Buffer,
SourceString->Buffer,
SourceString->Length
);
DestinationString->Buffer[SourceString->Length/sizeof(CHAR)] = '\0';
}
else
{
Status = STATUS_NO_MEMORY;
SspPrint((SSP_CRITICAL, "NtLmDuplicateString, NtLmAllocate returns NULL\n"));
goto CleanUp;
}
}
CleanUp:
SspPrint((SSP_MISC, "Leaving NtLmDuplicateString\n"));
return(Status);
}
//+-------------------------------------------------------------------------
//
// Function: NtLmDuplicatePassword
//
// Synopsis: Duplicates a UNICODE_STRING. If the source string buffer is
// NULL the destionation will be too. The MaximumLength contains
// room for encryption padding data.
//
// Effects: allocates memory with LsaFunctions.AllocatePrivateHeap
//
// Arguments: DestinationString - Receives a copy of the source string
// SourceString - String to copy
//
// Requires:
//
// Returns: SEC_E_OK - the copy succeeded
// SEC_E_INSUFFICIENT_MEMORY - the call to allocate
// memory failed.
//
// Notes:
//
//
//--------------------------------------------------------------------------
NTSTATUS
NtLmDuplicatePassword(
OUT PUNICODE_STRING DestinationString,
IN OPTIONAL PUNICODE_STRING SourceString
)
{
SspPrint((SSP_MISC, "Entering NtLmDuplicatePassword\n"));
NTSTATUS Status = STATUS_SUCCESS;
DestinationString->Buffer = NULL;
DestinationString->Length =
DestinationString->MaximumLength =
0;
if ((ARGUMENT_PRESENT(SourceString)) &&
(SourceString->Buffer != NULL))
{
USHORT PaddingLength;
PaddingLength = DESX_BLOCKLEN - (SourceString->Length % DESX_BLOCKLEN);
if( PaddingLength == DESX_BLOCKLEN )
{
PaddingLength = 0;
}
DestinationString->Buffer = (LPWSTR) NtLmAllocatePrivateHeap(
SourceString->Length +
PaddingLength
);
if (DestinationString->Buffer != NULL)
{
DestinationString->Length = SourceString->Length;
DestinationString->MaximumLength = SourceString->Length + PaddingLength;
if( DestinationString->MaximumLength == SourceString->MaximumLength )
{
//
// duplicating an already padded buffer -- pickup the original
// pad.
//
RtlCopyMemory(
DestinationString->Buffer,
SourceString->Buffer,
SourceString->MaximumLength
);
} else {
//
// duplicating an unpadded buffer -- pickup only the string
// and fill the rest with the boot time pad.
//
RtlCopyMemory(
DestinationString->Buffer,
SourceString->Buffer,
SourceString->Length
);
//
// CRYPTNOTE: consideration for ultra-paranoid:
// use a boot time random pad for fill.
//
}
}
else
{
Status = STATUS_NO_MEMORY;
SspPrint((SSP_CRITICAL, "NtLmDuplicatePassword, NtLmAllocate returns NULL\n"));
}
}
SspPrint((SSP_MISC, "Leaving NtLmDuplicatePassword\n"));
return(Status);
}
//+-------------------------------------------------------------------------
//
// Function: NtLmDuplicateSid
//
// Synopsis: Duplicates a SID
//
// Effects: allocates memory with LsaFunctions.AllocatePrivateHeap
//
// Arguments: DestinationSid - Receives a copy of the SourceSid
// SourceSid - SID to copy
//
// Requires:
//
// Returns: STATUS_SUCCESS - the copy succeeded
// STATUS_INSUFFICIENT_RESOURCES - the call to allocate memory
// failed
//
// Notes:
//
//
//--------------------------------------------------------------------------
NTSTATUS
NtLmDuplicateSid(
OUT PSID * DestinationSid,
IN PSID SourceSid
)
{
SspPrint((SSP_MISC, "Entering NtLmDuplicateSid\n"));
NTSTATUS Status = STATUS_SUCCESS;
ULONG SidSize;
ASSERT(RtlValidSid(SourceSid));
SidSize = RtlLengthSid(SourceSid);
*DestinationSid = (PSID) NtLmAllocatePrivateHeap( SidSize );
if (ARGUMENT_PRESENT(*DestinationSid))
{
RtlCopyMemory(
*DestinationSid,
SourceSid,
SidSize
);
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
SspPrint((SSP_CRITICAL, "NtLmDuplicateSid, NtLmAllocate returns NULL\n"));
goto CleanUp;
}
CleanUp:
SspPrint((SSP_MISC, "Leaving NtLmDuplicateSid\n"));
return(Status);
}
//+-------------------------------------------------------------------------
//
// Function: NtLmAllocate
//
// Synopsis: Allocate memory in either lsa mode or user mode
//
// Effects: Allocated chunk is zeroed out
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
PVOID
NtLmAllocate(
IN SIZE_T BufferSize
)
{
PVOID Buffer;
if (NtLmState == NtLmLsaMode)
{
ASSERT ((LsaFunctions->AllocatePrivateHeap));
Buffer = LsaFunctions->AllocatePrivateHeap(BufferSize);
// note: Lsa allocator zeroes the memory for us.
}
else
{
ASSERT(NtLmState == NtLmUserMode);
Buffer = LocalAlloc(LPTR, BufferSize);
// Buffer = CryptMemoryAlloc(BufferSize);
}
return Buffer;
}
//+-------------------------------------------------------------------------
//
// Function: NtLmFree
//
// Synopsis: Free memory in either lsa mode or user mode
//
// Effects:
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//
//--------------------------------------------------------------------------
VOID
NtLmFree(
IN PVOID Buffer
)
{
if (ARGUMENT_PRESENT(Buffer))
{
if (NtLmState == NtLmLsaMode)
{
ASSERT ((LsaFunctions->FreePrivateHeap));
LsaFunctions->FreePrivateHeap(Buffer);
}
else
{
ASSERT(NtLmState == NtLmUserMode);
LocalFree(Buffer);
// CryptMemoryFree(Buffer);
}
}
}
PVOID
NtLmAllocateLsaHeap(
IN ULONG BufferSize // should update to SIZE_T once lsa allocator def updated
)
{
PVOID Buffer;
if (NtLmState == NtLmLsaMode)
{
ASSERT ((LsaFunctions->AllocateLsaHeap));
Buffer = LsaFunctions->AllocateLsaHeap(BufferSize);
// note: Lsa allocator zeroes the memory for us.
}
else
{
ASSERT(NtLmState == NtLmUserMode);
Buffer = LocalAlloc(LPTR, BufferSize);
// Buffer = CryptMemoryAlloc(BufferSize);
}
return Buffer;
}
VOID
NtLmFreeLsaHeap(
IN PVOID Buffer
)
{
if (ARGUMENT_PRESENT(Buffer))
{
if (NtLmState == NtLmLsaMode)
{
ASSERT ((LsaFunctions->FreeLsaHeap));
LsaFunctions->FreeLsaHeap(Buffer);
}
else
{
ASSERT(NtLmState == NtLmUserMode);
LocalFree(Buffer);
// CryptMemoryFree(Buffer);
}
}
}
#if DBG
PVOID
NtLmAllocatePrivateHeap(
IN SIZE_T BufferSize
)
{
ASSERT (NtLmState == NtLmLsaMode);
ASSERT ((LsaFunctions->AllocatePrivateHeap));
// note: Lsa allocator zeroes the memory for us.
return LsaFunctions->AllocatePrivateHeap(BufferSize);
}
VOID
NtLmFreePrivateHeap(
IN PVOID Buffer
)
{
ASSERT (NtLmState == NtLmLsaMode);
ASSERT ((LsaFunctions->FreePrivateHeap));
if (ARGUMENT_PRESENT(Buffer))
{
LsaFunctions->FreePrivateHeap(Buffer);
}
}
PVOID
I_NtLmAllocate(
IN SIZE_T BufferSize
)
{
ASSERT (NtLmState == NtLmLsaMode);
ASSERT ((Lsa.AllocatePrivateHeap));
// note: Lsa allocator zeroes the memory for us.
return Lsa.AllocatePrivateHeap(BufferSize);
}
VOID
I_NtLmFree(
IN PVOID Buffer
)
{
ASSERT (NtLmState == NtLmLsaMode);
ASSERT ((Lsa.FreePrivateHeap));
if (ARGUMENT_PRESENT(Buffer))
{
Lsa.FreePrivateHeap(Buffer);
}
}
#endif