You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
528 lines
13 KiB
528 lines
13 KiB
//+-----------------------------------------------------------------------
|
|
//
|
|
// 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
|
|
|