//+----------------------------------------------------------------------- // // 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 //+------------------------------------------------------------------------- // // 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