// // #include #include #include #include #ifdef KERNEL_MODE #include #endif #include #include #include #include #include #ifdef WIN32_CHICAGO NTSTATUS MyRtlUpcaseUnicodeStringToOemString( OUT POEM_STRING DestinationString, IN PUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString ); #define RtlUpcaseUnicodeStringToOemString(x, y, z) MyRtlUpcaseUnicodeStringToOemString(x, y, z) #endif // WIN32_CHICAGO typedef struct _LM_STATE_BUFFER { LM_OWF_PASSWORD Password; } LM_STATE_BUFFER, *PLM_STATE_BUFFER; NTSTATUS LmWrapInitialize(ULONG dwSeed, PCHECKSUM_BUFFER * ppcsBuffer); NTSTATUS LmWrapSum( PCHECKSUM_BUFFER pcsBuffer, ULONG cbData, PUCHAR pbData ); NTSTATUS LmWrapFinalize( PCHECKSUM_BUFFER pcsBuffer, PUCHAR pbSum); NTSTATUS LmWrapFinish(PCHECKSUM_BUFFER * ppcsBuffer); CHECKSUM_FUNCTION csfLM = { KERB_CHECKSUM_LM, LM_OWF_PASSWORD_LENGTH, CKSUM_COLLISION, LmWrapInitialize, LmWrapSum, LmWrapFinalize, LmWrapFinish // Note : missing last function }; #ifdef KERNEL_MODE #pragma alloc_text( PAGEMSG, LmWrapInitialize ) #pragma alloc_text( PAGEMSG, LmWrapSum ) #pragma alloc_text( PAGEMSG, LmWrapFinalize ) #pragma alloc_text( PAGEMSG, LmWrapFinish ); #endif NTSTATUS LmWrapInitialize( ULONG dwSeed, PCHECKSUM_BUFFER * ppcsBuffer) { PLM_STATE_BUFFER pContext; #ifdef KERNEL_MODE pContext = ExAllocatePool( NonPagedPool, sizeof( LM_STATE_BUFFER ) ); #else pContext = LocalAlloc( LMEM_ZEROINIT, sizeof( LM_STATE_BUFFER ) ); #endif if ( pContext != NULL ) { *ppcsBuffer = pContext; return( SEC_E_OK ); } return( STATUS_INSUFFICIENT_RESOURCES ); } NTSTATUS LmCalculateLmPassword( IN PUNICODE_STRING NtPassword, OUT PCHAR *LmPasswordBuffer ) /*++ Routine Description: This service converts an NT password into a LM password. Parameters: NtPassword - The Nt password to be converted. LmPasswordBuffer - On successful return, points at the LM password The buffer should be freed using MIDL_user_free Return Values: STATUS_SUCCESS - LMPassword contains the LM version of the password. STATUS_NULL_LM_PASSWORD - The password is too complex to be represented by a LM password. The LM password returned is a NULL string. --*/ { #define LM_BUFFER_LENGTH (LM20_PWLEN + 1) NTSTATUS NtStatus; ANSI_STRING LmPassword; // // Prepare for failure // *LmPasswordBuffer = NULL; // // Compute the Ansi version to the Unicode password. // // The Ansi version of the Cleartext password is at most 14 bytes long, // exists in a trailing zero filled 15 byte buffer, // is uppercased. // #ifdef KERNEL_MODE LmPassword.Buffer = ExAllocatePool(NonPagedPool,LM_BUFFER_LENGTH); #else LmPassword.Buffer = LocalAlloc(0,LM_BUFFER_LENGTH); #endif if (LmPassword.Buffer == NULL) { return(STATUS_INSUFFICIENT_RESOURCES); } LmPassword.MaximumLength = LmPassword.Length = LM_BUFFER_LENGTH; RtlZeroMemory( LmPassword.Buffer, LM_BUFFER_LENGTH ); NtStatus = RtlUpcaseUnicodeStringToOemString( &LmPassword, NtPassword, FALSE ); if ( !NT_SUCCESS(NtStatus) ) { // // The password is longer than the max LM password length // NtStatus = STATUS_NULL_LM_PASSWORD; // Informational return code RtlZeroMemory( LmPassword.Buffer, LM_BUFFER_LENGTH ); } // // Return a pointer to the allocated LM password // if (NT_SUCCESS(NtStatus)) { *LmPasswordBuffer = LmPassword.Buffer; } else { #ifdef KERNEL_MODE ExFreePool(LmPassword.Buffer); #else LocalFree(LmPassword.Buffer); #endif } return(NtStatus); } NTSTATUS LmWrapSum( PCHECKSUM_BUFFER pcsBuffer, ULONG cbData, PUCHAR pbData ) { PLM_STATE_BUFFER pContext = (PLM_STATE_BUFFER) pcsBuffer; UNICODE_STRING TempString; PUCHAR LmPassword; NTSTATUS Status; TempString.Length = TempString.MaximumLength = (USHORT) cbData; TempString.Buffer = (LPWSTR) pbData; Status = LmCalculateLmPassword( &TempString, &LmPassword ); if (!NT_SUCCESS(Status)) { return(Status); } Status = RtlCalculateLmOwfPassword( LmPassword, &pContext->Password ); #ifdef KERNEL_MODE ExFreePool(LmPassword); #else LocalFree(LmPassword); #endif return( Status ); } NTSTATUS LmWrapFinalize( PCHECKSUM_BUFFER pcsBuffer, PUCHAR pbSum) { PLM_STATE_BUFFER pContext = (PLM_STATE_BUFFER) pcsBuffer; RtlCopyMemory( pbSum, &pContext->Password, LM_OWF_PASSWORD_LENGTH ); return( STATUS_SUCCESS ); } NTSTATUS LmWrapFinish( PCHECKSUM_BUFFER * ppcsBuffer) { RtlZeroMemory( *ppcsBuffer, sizeof( PLM_STATE_BUFFER ) ); #ifdef KERNEL_MODE ExFreePool( *ppcsBuffer ); #else LocalFree( *ppcsBuffer ); #endif *ppcsBuffer = NULL ; return( STATUS_SUCCESS ); }