921 lines
27 KiB
C++
921 lines
27 KiB
C++
|
|
|
|
#if _WIN64
|
|
|
|
#include <global.h>
|
|
#include "msp.h"
|
|
#include "nlp.h"
|
|
|
|
#include "msvwow.h"
|
|
|
|
|
|
#define RELOCATE_WOW_UNICODE_STRING(WOWString, NativeString, Offset) \
|
|
NativeString.Length = WOWString.Length; \
|
|
NativeString.MaximumLength = WOWString.MaximumLength; \
|
|
NativeString.Buffer = (LPWSTR) ((LPBYTE) UlongToPtr(WOWString.Buffer) + Offset);
|
|
|
|
#define RELOCATE_WOW_ANSI_STRING(WOWString, NativeString, Offset) \
|
|
NativeString.Length = WOWString.Length; \
|
|
NativeString.MaximumLength = WOWString.MaximumLength; \
|
|
NativeString.Buffer = (LPSTR) ((LPBYTE) UlongToPtr(WOWString.Buffer) + Offset);
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: MsvPutWOWString
|
|
//
|
|
// Synopsis: Copies a UNICODE_STRING into a buffer
|
|
//
|
|
// Effects:
|
|
//
|
|
// Arguments: InputString - String to 'put'
|
|
// OutputString - Receives 'put' string
|
|
// Offset - Difference in addresses of local and client buffers.
|
|
// Where - Location in local buffer to place string.
|
|
//
|
|
// Requires:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes: This code is (effectively) duplicated in
|
|
// KerbPutString. Make sure any changes
|
|
// made here are applied there as well.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
VOID
|
|
MsvPutWOWString(
|
|
IN PUNICODE_STRING InputString,
|
|
OUT PUNICODE_STRING_WOW64 OutputString,
|
|
IN LONG_PTR Offset,
|
|
IN OUT PBYTE * Where
|
|
)
|
|
{
|
|
OutputString->Length = OutputString->MaximumLength = InputString->Length;
|
|
OutputString->Buffer = PtrToUlong (*Where + Offset);
|
|
RtlCopyMemory(
|
|
*Where,
|
|
InputString->Buffer,
|
|
InputString->Length
|
|
);
|
|
*Where += InputString->Length;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: MsvPutWOWClientString
|
|
//
|
|
// Synopsis: Copies a string into a buffer that will be copied to the
|
|
// 32-bit client's address space
|
|
//
|
|
// Effects:
|
|
//
|
|
// Arguments: Where - Location in local buffer to place string.
|
|
// OutString - Receives 'put' string
|
|
// InString - String to 'put'
|
|
//
|
|
// Requires:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes: This code is (effectively) duplicated in
|
|
// KerbPutClientString. Make sure any changes
|
|
// made here are applied there as well.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
VOID
|
|
MsvPutWOWClientString(
|
|
IN OUT PCLIENT_BUFFER_DESC ClientBufferDesc,
|
|
IN PUNICODE_STRING_WOW64 OutString,
|
|
IN PUNICODE_STRING InString
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine copies the InString string to the memory pointed to by
|
|
ClientBufferDesc->StringOffset, and fixes the OutString string to point
|
|
to that new copy.
|
|
|
|
|
|
Parameters:
|
|
|
|
ClientBufferDesc - Descriptor of a buffer allocated in the client's
|
|
address space.
|
|
|
|
InString - A pointer to an NT string to be copied
|
|
|
|
OutString - A pointer to a destination NT string. This string structure
|
|
is in the "Mirror" allocated buffer.
|
|
|
|
Return Status:
|
|
|
|
STATUS_SUCCESS - Indicates the service completed successfully.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
//
|
|
// Ensure our caller passed good data.
|
|
//
|
|
|
|
ASSERT( OutString != NULL );
|
|
ASSERT( InString != NULL );
|
|
ASSERT( COUNT_IS_ALIGNED( ClientBufferDesc->StringOffset, sizeof(WCHAR)) );
|
|
ASSERT( (LPBYTE)OutString >= ClientBufferDesc->MsvBuffer );
|
|
ASSERT( (LPBYTE)OutString <
|
|
ClientBufferDesc->MsvBuffer + ClientBufferDesc->TotalSize - sizeof(UNICODE_STRING) );
|
|
|
|
ASSERT( ClientBufferDesc->StringOffset + InString->Length + sizeof(WCHAR) <=
|
|
ClientBufferDesc->TotalSize );
|
|
|
|
#ifdef notdef
|
|
KdPrint(("NlpPutClientString: %ld %Z\n", InString->Length, InString ));
|
|
KdPrint((" Orig: UserBuffer: %lx Offset: 0x%lx TotalSize: 0x%lx\n",
|
|
ClientBufferDesc->UserBuffer,
|
|
ClientBufferDesc->StringOffset,
|
|
ClientBufferDesc->TotalSize ));
|
|
#endif
|
|
|
|
//
|
|
// Build a string structure and copy the text to the Mirror buffer.
|
|
//
|
|
|
|
if ( InString->Length > 0 ) {
|
|
|
|
ULONG_PTR TmpPtr;
|
|
|
|
//
|
|
// Copy the string (Add a zero character)
|
|
//
|
|
|
|
RtlCopyMemory(
|
|
ClientBufferDesc->MsvBuffer + ClientBufferDesc->StringOffset,
|
|
InString->Buffer,
|
|
InString->Length );
|
|
|
|
// Do one byte at a time since some callers don't pass in an even
|
|
// InString->Length
|
|
*(ClientBufferDesc->MsvBuffer + ClientBufferDesc->StringOffset +
|
|
InString->Length) = '\0';
|
|
*(ClientBufferDesc->MsvBuffer + ClientBufferDesc->StringOffset +
|
|
InString->Length+1) = '\0';
|
|
|
|
//
|
|
// Build the string structure to point to the data in the client's
|
|
// address space.
|
|
//
|
|
|
|
TmpPtr = (ULONG_PTR)(ClientBufferDesc->UserBuffer +
|
|
ClientBufferDesc->StringOffset);
|
|
|
|
OutString->Buffer = (ULONG)TmpPtr;
|
|
OutString->Length = InString->Length;
|
|
OutString->MaximumLength = OutString->Length + sizeof(WCHAR);
|
|
|
|
//
|
|
// Adjust the offset to past the newly copied string.
|
|
//
|
|
|
|
ClientBufferDesc->StringOffset += OutString->MaximumLength;
|
|
|
|
} else {
|
|
ZeroMemory( OutString, sizeof(*OutString) );
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: MsvConvertWOWInteractiveLogonBuffer
|
|
//
|
|
// Synopsis: Converts logon buffers passed in from WOW clients to 64-bit
|
|
//
|
|
// Effects:
|
|
//
|
|
// Arguments: ProtocolSubmitBuffer -- original 32-bit logon buffer
|
|
// pSubmitBufferSize -- size of the 32-bit logon buffer
|
|
// MessageType -- format of the logon buffer
|
|
// ppTempSubmitBuffer -- filled in with the converted buffer
|
|
//
|
|
// Requires:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes: This routine allocates the converted buffer and returns it
|
|
// on success. It is the caller's responsibility to free it.
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
NTSTATUS
|
|
MsvConvertWOWInteractiveLogonBuffer(
|
|
IN PVOID ProtocolSubmitBuffer,
|
|
IN PVOID ClientBufferBase,
|
|
IN OUT PULONG pSubmitBufferSize,
|
|
OUT PVOID *ppTempSubmitBuffer
|
|
)
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
PVOID pTempBuffer = NULL;
|
|
ULONG dwBufferSize = *pSubmitBufferSize;
|
|
|
|
PMSV1_0_INTERACTIVE_LOGON Logon;
|
|
PMSV1_0_INTERACTIVE_LOGON_WOW64 LogonWOW;
|
|
DWORD dwOffset;
|
|
DWORD dwWOWOffset;
|
|
|
|
|
|
//
|
|
// Pacify the compiler
|
|
//
|
|
|
|
UNREFERENCED_PARAMETER(ClientBufferBase);
|
|
|
|
//
|
|
// Scale up the size and add on 3 PVOIDs for the worst-case
|
|
// scenario to align the three embedded UNICODE_STRINGs
|
|
//
|
|
|
|
dwBufferSize += sizeof(MSV1_0_INTERACTIVE_LOGON)
|
|
- sizeof(MSV1_0_INTERACTIVE_LOGON_WOW64);
|
|
|
|
if (dwBufferSize < sizeof(MSV1_0_INTERACTIVE_LOGON))
|
|
{
|
|
#if 0
|
|
DebugLog((DEB_ERROR,
|
|
"Submit buffer to logon too small: %d. %ws, line %d\n",
|
|
dwBufferSize,
|
|
THIS_FILE,
|
|
__LINE__));
|
|
#endif
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
goto Cleanup;
|
|
}
|
|
|
|
pTempBuffer = NtLmAllocatePrivateHeap(dwBufferSize);
|
|
|
|
if (pTempBuffer == NULL)
|
|
{
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
|
|
Logon = (PMSV1_0_INTERACTIVE_LOGON) pTempBuffer;
|
|
LogonWOW = (PMSV1_0_INTERACTIVE_LOGON_WOW64) ProtocolSubmitBuffer;
|
|
|
|
Logon->MessageType = LogonWOW->MessageType;
|
|
|
|
dwOffset = sizeof(MSV1_0_INTERACTIVE_LOGON);
|
|
dwWOWOffset = sizeof(MSV1_0_INTERACTIVE_LOGON_WOW64);
|
|
|
|
|
|
//
|
|
// Copy the variable-length data
|
|
//
|
|
|
|
RtlCopyMemory((LPBYTE) Logon + dwOffset,
|
|
(LPBYTE) LogonWOW + dwWOWOffset,
|
|
*pSubmitBufferSize - dwWOWOffset);
|
|
|
|
//
|
|
// Set up the pointers in the native struct
|
|
//
|
|
|
|
RELOCATE_WOW_UNICODE_STRING(LogonWOW->LogonDomainName,
|
|
Logon->LogonDomainName,
|
|
dwOffset - dwWOWOffset);
|
|
|
|
RELOCATE_WOW_UNICODE_STRING(LogonWOW->UserName,
|
|
Logon->UserName,
|
|
dwOffset - dwWOWOffset);
|
|
|
|
RELOCATE_WOW_UNICODE_STRING(LogonWOW->Password,
|
|
Logon->Password,
|
|
dwOffset - dwWOWOffset);
|
|
|
|
*pSubmitBufferSize = dwBufferSize;
|
|
*ppTempSubmitBuffer = pTempBuffer;
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
Cleanup:
|
|
|
|
ASSERT(!NT_SUCCESS(Status));
|
|
|
|
if (pTempBuffer)
|
|
{
|
|
NtLmFreePrivateHeap(pTempBuffer);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
MsvConvertWOWNetworkLogonBuffer(
|
|
IN PVOID ProtocolSubmitBuffer,
|
|
IN PVOID ClientBufferBase,
|
|
IN OUT PULONG pSubmitBufferSize,
|
|
OUT PVOID *ppTempSubmitBuffer
|
|
)
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
PVOID pTempBuffer = NULL;
|
|
ULONG dwBufferSize = *pSubmitBufferSize;
|
|
|
|
PMSV1_0_LM20_LOGON Logon;
|
|
PMSV1_0_LM20_LOGON_WOW64 LogonWOW;
|
|
DWORD dwOffset;
|
|
DWORD dwWOWOffset;
|
|
|
|
|
|
//
|
|
// Pacify the compiler
|
|
//
|
|
|
|
UNREFERENCED_PARAMETER(ClientBufferBase);
|
|
|
|
//
|
|
// Scale up the size and add on 5 PVOIDs for the worst-case
|
|
// scenario to align the three embedded UNICODE_STRINGs
|
|
//
|
|
|
|
dwBufferSize += sizeof(MSV1_0_LM20_LOGON)
|
|
- sizeof(MSV1_0_LM20_LOGON_WOW64);
|
|
|
|
if (dwBufferSize < sizeof(MSV1_0_LM20_LOGON))
|
|
{
|
|
#if 0
|
|
DebugLog((DEB_ERROR,
|
|
"Submit buffer to logon too small: %d. %ws, line %d\n",
|
|
dwBufferSize,
|
|
THIS_FILE,
|
|
__LINE__));
|
|
#endif
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
goto Cleanup;
|
|
}
|
|
|
|
pTempBuffer = NtLmAllocatePrivateHeap(dwBufferSize);
|
|
|
|
if (pTempBuffer == NULL)
|
|
{
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
|
|
Logon = (PMSV1_0_LM20_LOGON) pTempBuffer;
|
|
LogonWOW = (PMSV1_0_LM20_LOGON_WOW64) ProtocolSubmitBuffer;
|
|
|
|
//
|
|
// copy fixed fields.
|
|
//
|
|
|
|
Logon->MessageType = LogonWOW->MessageType;
|
|
Logon->ParameterControl = LogonWOW->ParameterControl;
|
|
|
|
RtlCopyMemory(Logon->ChallengeToClient, LogonWOW->ChallengeToClient, MSV1_0_CHALLENGE_LENGTH);
|
|
|
|
dwOffset = sizeof(MSV1_0_LM20_LOGON);
|
|
dwWOWOffset = sizeof(MSV1_0_LM20_LOGON_WOW64);
|
|
|
|
//
|
|
// Copy the variable-length data
|
|
//
|
|
|
|
RtlCopyMemory((LPBYTE) Logon + dwOffset,
|
|
(LPBYTE) LogonWOW + dwWOWOffset,
|
|
*pSubmitBufferSize - dwWOWOffset);
|
|
|
|
//
|
|
// Set up the pointers in the native struct
|
|
//
|
|
|
|
RELOCATE_WOW_UNICODE_STRING(LogonWOW->LogonDomainName,
|
|
Logon->LogonDomainName,
|
|
dwOffset - dwWOWOffset);
|
|
|
|
RELOCATE_WOW_UNICODE_STRING(LogonWOW->UserName,
|
|
Logon->UserName,
|
|
dwOffset - dwWOWOffset);
|
|
|
|
RELOCATE_WOW_UNICODE_STRING(LogonWOW->Workstation,
|
|
Logon->Workstation,
|
|
dwOffset - dwWOWOffset);
|
|
|
|
RELOCATE_WOW_ANSI_STRING(LogonWOW->CaseSensitiveChallengeResponse,
|
|
Logon->CaseSensitiveChallengeResponse,
|
|
dwOffset - dwWOWOffset);
|
|
|
|
RELOCATE_WOW_ANSI_STRING(LogonWOW->CaseInsensitiveChallengeResponse,
|
|
Logon->CaseInsensitiveChallengeResponse,
|
|
dwOffset - dwWOWOffset);
|
|
|
|
*pSubmitBufferSize = dwBufferSize;
|
|
*ppTempSubmitBuffer = pTempBuffer;
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
Cleanup:
|
|
|
|
ASSERT(!NT_SUCCESS(Status));
|
|
|
|
if (pTempBuffer)
|
|
{
|
|
NtLmFreePrivateHeap(pTempBuffer);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: MsvConvertWOWChangePasswordBuffer
|
|
//
|
|
// Synopsis: Converts change password buffers passed in from
|
|
// WOW clients to 64-bit
|
|
//
|
|
// Effects:
|
|
//
|
|
// Arguments: ProtocolSubmitBuffer -- original 32-bit buffer
|
|
// ClientBufferBase -- base address
|
|
// pSubmitBufferSize -- size of the 32-bit buffer
|
|
// ppTempSubmitBuffer -- filled in with the converted buffer
|
|
//
|
|
// Requires:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes: This routine allocates the converted buffer and returns it
|
|
// on success. It is the caller's responsibility to free it.
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
NTSTATUS
|
|
MsvConvertWOWChangePasswordBuffer(
|
|
IN PVOID ProtocolSubmitBuffer,
|
|
IN PVOID ClientBufferBase,
|
|
IN OUT PULONG pSubmitBufferSize,
|
|
OUT PVOID *ppTempSubmitBuffer
|
|
)
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
PVOID pTempBuffer = NULL;
|
|
ULONG dwBufferSize = *pSubmitBufferSize;
|
|
|
|
PMSV1_0_CHANGEPASSWORD_REQUEST PasswordRequest;
|
|
PMSV1_0_CHANGEPASSWORD_REQUEST_WOW64 PasswordRequestWOW;
|
|
DWORD dwOffset;
|
|
DWORD dwWOWOffset;
|
|
|
|
|
|
//
|
|
// Pacify the compiler
|
|
//
|
|
|
|
UNREFERENCED_PARAMETER(ClientBufferBase);
|
|
|
|
//
|
|
// Scale up the size
|
|
//
|
|
|
|
dwBufferSize += sizeof(MSV1_0_CHANGEPASSWORD_REQUEST)
|
|
- sizeof(MSV1_0_CHANGEPASSWORD_REQUEST_WOW64);
|
|
|
|
if (dwBufferSize < sizeof(MSV1_0_CHANGEPASSWORD_REQUEST))
|
|
{
|
|
#if 0
|
|
DebugLog((DEB_ERROR,
|
|
"Submit buffer to logon too small: %d. %ws, line %d\n",
|
|
dwBufferSize,
|
|
THIS_FILE,
|
|
__LINE__));
|
|
#endif
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
goto Cleanup;
|
|
}
|
|
|
|
pTempBuffer = NtLmAllocatePrivateHeap(dwBufferSize);
|
|
|
|
if (pTempBuffer == NULL)
|
|
{
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
|
|
PasswordRequest = (PMSV1_0_CHANGEPASSWORD_REQUEST) pTempBuffer;
|
|
PasswordRequestWOW = (PMSV1_0_CHANGEPASSWORD_REQUEST_WOW64) ProtocolSubmitBuffer;
|
|
|
|
//
|
|
// copy fixed fields.
|
|
//
|
|
|
|
PasswordRequest->MessageType = PasswordRequestWOW->MessageType;
|
|
PasswordRequest->Impersonating = PasswordRequestWOW->Impersonating;
|
|
|
|
dwOffset = sizeof(MSV1_0_CHANGEPASSWORD_REQUEST);
|
|
dwWOWOffset = sizeof(MSV1_0_CHANGEPASSWORD_REQUEST_WOW64);
|
|
|
|
//
|
|
// Copy the variable-length data
|
|
//
|
|
|
|
RtlCopyMemory((LPBYTE) PasswordRequest + dwOffset,
|
|
(LPBYTE) PasswordRequestWOW + dwWOWOffset,
|
|
*pSubmitBufferSize - dwWOWOffset);
|
|
|
|
//
|
|
// Set up the pointers in the native struct
|
|
//
|
|
|
|
RELOCATE_WOW_UNICODE_STRING(PasswordRequestWOW->DomainName,
|
|
PasswordRequest->DomainName,
|
|
dwOffset - dwWOWOffset);
|
|
|
|
RELOCATE_WOW_UNICODE_STRING(PasswordRequestWOW->AccountName,
|
|
PasswordRequest->AccountName,
|
|
dwOffset - dwWOWOffset);
|
|
|
|
RELOCATE_WOW_UNICODE_STRING(PasswordRequestWOW->OldPassword,
|
|
PasswordRequest->OldPassword,
|
|
dwOffset - dwWOWOffset);
|
|
|
|
RELOCATE_WOW_UNICODE_STRING(PasswordRequestWOW->NewPassword,
|
|
PasswordRequest->NewPassword,
|
|
dwOffset - dwWOWOffset);
|
|
|
|
*pSubmitBufferSize = dwBufferSize;
|
|
*ppTempSubmitBuffer = pTempBuffer;
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
Cleanup:
|
|
|
|
ASSERT(!NT_SUCCESS(Status));
|
|
|
|
if (pTempBuffer)
|
|
{
|
|
NtLmFreePrivateHeap(pTempBuffer);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
MsvAllocateInteractiveWOWProfile (
|
|
IN PLSA_CLIENT_REQUEST ClientRequest,
|
|
OUT PMSV1_0_INTERACTIVE_PROFILE *ProfileBuffer,
|
|
OUT PULONG ProfileBufferSize,
|
|
IN PNETLOGON_VALIDATION_SAM_INFO4 NlpUser
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This allocates and fills in the clients interactive profile.
|
|
|
|
Arguments:
|
|
|
|
ClientRequest - Is a pointer to an opaque data structure
|
|
representing the client's request.
|
|
|
|
ProfileBuffer - Is used to return the address of the profile
|
|
buffer in the client process. This routine is
|
|
responsible for allocating and returning the profile buffer
|
|
within the client process. However, if the caller subsequently
|
|
encounters an error which prevents a successful logon, then
|
|
then it will take care of deallocating the buffer. This
|
|
buffer is allocated with the AllocateClientBuffer() service.
|
|
|
|
ProfileBufferSize - Receives the Size (in bytes) of the
|
|
returned profile buffer.
|
|
|
|
NlpUser - Contains the validation information which is
|
|
to be copied in the ProfileBuffer.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS - Indicates the service completed successfully.
|
|
|
|
STATUS_QUOTA_EXCEEDED - This error indicates that the logon
|
|
could not be completed because the client does not have
|
|
sufficient quota to allocate the return buffer.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
CLIENT_BUFFER_DESC ClientBufferDesc;
|
|
PMSV1_0_INTERACTIVE_PROFILE_WOW64 LocalProfileBuffer;
|
|
|
|
|
|
//
|
|
// Alocate the profile buffer to return to the client
|
|
//
|
|
|
|
NlpInitClientBuffer( &ClientBufferDesc, ClientRequest );
|
|
|
|
*ProfileBuffer = NULL;
|
|
|
|
*ProfileBufferSize = sizeof(MSV1_0_INTERACTIVE_PROFILE_WOW64) +
|
|
NlpUser->LogonScript.Length + sizeof(WCHAR) +
|
|
NlpUser->HomeDirectory.Length + sizeof(WCHAR) +
|
|
NlpUser->HomeDirectoryDrive.Length + sizeof(WCHAR) +
|
|
NlpUser->FullName.Length + sizeof(WCHAR) +
|
|
NlpUser->ProfilePath.Length + sizeof(WCHAR) +
|
|
NlpUser->LogonServer.Length + sizeof(WCHAR);
|
|
|
|
Status = NlpAllocateClientBuffer( &ClientBufferDesc,
|
|
sizeof(MSV1_0_INTERACTIVE_PROFILE_WOW64),
|
|
*ProfileBufferSize );
|
|
|
|
|
|
if ( !NT_SUCCESS( Status ) ) {
|
|
goto Cleanup;
|
|
}
|
|
|
|
|
|
LocalProfileBuffer = (PMSV1_0_INTERACTIVE_PROFILE_WOW64) ClientBufferDesc.MsvBuffer;
|
|
|
|
|
|
//
|
|
// Copy the scalar fields into the profile buffer.
|
|
//
|
|
|
|
LocalProfileBuffer->MessageType = MsV1_0InteractiveProfile;
|
|
LocalProfileBuffer->LogonCount = NlpUser->LogonCount;
|
|
LocalProfileBuffer->BadPasswordCount= NlpUser->BadPasswordCount;
|
|
OLD_TO_NEW_LARGE_INTEGER( NlpUser->LogonTime,
|
|
LocalProfileBuffer->LogonTime );
|
|
OLD_TO_NEW_LARGE_INTEGER( NlpUser->LogoffTime,
|
|
LocalProfileBuffer->LogoffTime );
|
|
OLD_TO_NEW_LARGE_INTEGER( NlpUser->KickOffTime,
|
|
LocalProfileBuffer->KickOffTime );
|
|
OLD_TO_NEW_LARGE_INTEGER( NlpUser->PasswordLastSet,
|
|
LocalProfileBuffer->PasswordLastSet );
|
|
OLD_TO_NEW_LARGE_INTEGER( NlpUser->PasswordCanChange,
|
|
LocalProfileBuffer->PasswordCanChange );
|
|
OLD_TO_NEW_LARGE_INTEGER( NlpUser->PasswordMustChange,
|
|
LocalProfileBuffer->PasswordMustChange );
|
|
LocalProfileBuffer->UserFlags = NlpUser->UserFlags;
|
|
|
|
//
|
|
// Copy the Unicode strings into the profile buffer.
|
|
//
|
|
|
|
MsvPutWOWClientString( &ClientBufferDesc,
|
|
&LocalProfileBuffer->LogonScript,
|
|
&NlpUser->LogonScript );
|
|
|
|
MsvPutWOWClientString( &ClientBufferDesc,
|
|
&LocalProfileBuffer->HomeDirectory,
|
|
&NlpUser->HomeDirectory );
|
|
|
|
MsvPutWOWClientString( &ClientBufferDesc,
|
|
&LocalProfileBuffer->HomeDirectoryDrive,
|
|
&NlpUser->HomeDirectoryDrive );
|
|
|
|
MsvPutWOWClientString( &ClientBufferDesc,
|
|
&LocalProfileBuffer->FullName,
|
|
&NlpUser->FullName );
|
|
|
|
MsvPutWOWClientString( &ClientBufferDesc,
|
|
&LocalProfileBuffer->ProfilePath,
|
|
&NlpUser->ProfilePath );
|
|
|
|
MsvPutWOWClientString( &ClientBufferDesc,
|
|
&LocalProfileBuffer->LogonServer,
|
|
&NlpUser->LogonServer );
|
|
|
|
|
|
//
|
|
// Flush the buffer to the client's address space.
|
|
//
|
|
|
|
Status = NlpFlushClientBuffer( &ClientBufferDesc,
|
|
(PVOID *) ProfileBuffer );
|
|
|
|
Cleanup:
|
|
|
|
//
|
|
// If the copy wasn't successful,
|
|
// cleanup resources we would have returned to the caller.
|
|
//
|
|
|
|
if ( !NT_SUCCESS(Status) ) {
|
|
NlpFreeClientBuffer( &ClientBufferDesc );
|
|
}
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
NTSTATUS
|
|
MsvAllocateNetworkWOWProfile (
|
|
IN PLSA_CLIENT_REQUEST ClientRequest,
|
|
OUT PMSV1_0_LM20_LOGON_PROFILE *ProfileBuffer,
|
|
OUT PULONG ProfileBufferSize,
|
|
IN PNETLOGON_VALIDATION_SAM_INFO4 NlpUser,
|
|
IN ULONG ParameterControl
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This allocates and fills in the clients network profile.
|
|
|
|
Arguments:
|
|
|
|
ClientRequest - Is a pointer to an opaque data structure
|
|
representing the client's request.
|
|
|
|
ProfileBuffer - Is used to return the address of the profile
|
|
buffer in the client process. This routine is
|
|
responsible for allocating and returning the profile buffer
|
|
within the client process. However, if the caller subsequently
|
|
encounters an error which prevents a successful logon, then
|
|
then it will take care of deallocating the buffer. This
|
|
buffer is allocated with the AllocateClientBuffer() service.
|
|
|
|
ProfileBufferSize - Receives the Size (in bytes) of the
|
|
returned profile buffer.
|
|
|
|
NlpUser - Contains the validation information which is
|
|
to be copied in the ProfileBuffer. Will be NULL to indicate a
|
|
NULL session.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS - Indicates the service completed successfully.
|
|
|
|
STATUS_QUOTA_EXCEEDED - This error indicates that the logon
|
|
could not be completed because the client does not have
|
|
sufficient quota to allocate the return buffer.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
NTSTATUS SubAuthStatus = STATUS_SUCCESS;
|
|
|
|
CLIENT_BUFFER_DESC ClientBufferDesc;
|
|
PMSV1_0_LM20_LOGON_PROFILE_WOW64 LocalProfile;
|
|
|
|
//
|
|
// Alocate the profile buffer to return to the client
|
|
//
|
|
|
|
NlpInitClientBuffer( &ClientBufferDesc, ClientRequest );
|
|
|
|
*ProfileBuffer = NULL;
|
|
*ProfileBufferSize = sizeof(MSV1_0_LM20_LOGON_PROFILE_WOW64);
|
|
|
|
if ( NlpUser != NULL ) {
|
|
*ProfileBufferSize += NlpUser->LogonDomainName.Length + sizeof(WCHAR) +
|
|
NlpUser->LogonServer.Length + sizeof(WCHAR) +
|
|
NlpUser->HomeDirectoryDrive.Length + sizeof(WCHAR);
|
|
}
|
|
|
|
|
|
Status = NlpAllocateClientBuffer( &ClientBufferDesc,
|
|
sizeof(MSV1_0_LM20_LOGON_PROFILE_WOW64),
|
|
*ProfileBufferSize );
|
|
|
|
|
|
if ( !NT_SUCCESS( Status ) ) {
|
|
goto Cleanup;
|
|
}
|
|
|
|
LocalProfile = (PMSV1_0_LM20_LOGON_PROFILE_WOW64) ClientBufferDesc.MsvBuffer;
|
|
LocalProfile->MessageType = MsV1_0Lm20LogonProfile;
|
|
|
|
|
|
//
|
|
// For a NULL session, return a constant profile buffer
|
|
//
|
|
|
|
if ( NlpUser == NULL ) {
|
|
|
|
LocalProfile->KickOffTime.HighPart = 0x7FFFFFFF;
|
|
LocalProfile->KickOffTime.LowPart = 0xFFFFFFFF;
|
|
LocalProfile->LogoffTime.HighPart = 0x7FFFFFFF;
|
|
LocalProfile->LogoffTime.LowPart = 0xFFFFFFFF;
|
|
LocalProfile->UserFlags = 0;
|
|
RtlZeroMemory( LocalProfile->UserSessionKey,
|
|
sizeof(LocalProfile->UserSessionKey));
|
|
RtlZeroMemory( LocalProfile->LanmanSessionKey,
|
|
sizeof(LocalProfile->LanmanSessionKey));
|
|
RtlZeroMemory( &LocalProfile->LogonDomainName, sizeof(LocalProfile->LogonDomainName) );
|
|
RtlZeroMemory( &LocalProfile->LogonServer, sizeof(LocalProfile->LogonServer) );
|
|
RtlZeroMemory( &LocalProfile->UserParameters, sizeof(LocalProfile->UserParameters) );
|
|
|
|
|
|
//
|
|
// For non-null sessions,
|
|
// fill in the profile buffer.
|
|
//
|
|
|
|
} else {
|
|
|
|
//
|
|
// Copy the individual scalar fields into the profile buffer.
|
|
//
|
|
|
|
if ((ParameterControl & MSV1_0_RETURN_PASSWORD_EXPIRY) != 0) {
|
|
OLD_TO_NEW_LARGE_INTEGER( NlpUser->PasswordMustChange,
|
|
LocalProfile->LogoffTime);
|
|
} else {
|
|
OLD_TO_NEW_LARGE_INTEGER( NlpUser->LogoffTime,
|
|
LocalProfile->LogoffTime);
|
|
}
|
|
OLD_TO_NEW_LARGE_INTEGER( NlpUser->KickOffTime,
|
|
LocalProfile->KickOffTime);
|
|
LocalProfile->UserFlags = NlpUser->UserFlags;
|
|
|
|
RtlCopyMemory( LocalProfile->UserSessionKey,
|
|
&NlpUser->UserSessionKey,
|
|
sizeof(LocalProfile->UserSessionKey) );
|
|
|
|
ASSERT( SAMINFO_LM_SESSION_KEY_SIZE ==
|
|
sizeof(LocalProfile->LanmanSessionKey) );
|
|
RtlCopyMemory(
|
|
LocalProfile->LanmanSessionKey,
|
|
&NlpUser->ExpansionRoom[SAMINFO_LM_SESSION_KEY],
|
|
SAMINFO_LM_SESSION_KEY_SIZE );
|
|
|
|
|
|
// We need to extract the true status sent back for subauth users,
|
|
// but not by a sub auth package
|
|
|
|
SubAuthStatus = NlpUser->ExpansionRoom[SAMINFO_SUBAUTH_STATUS];
|
|
|
|
//
|
|
// Copy the Unicode strings into the profile buffer.
|
|
//
|
|
|
|
MsvPutWOWClientString( &ClientBufferDesc,
|
|
&LocalProfile->LogonDomainName,
|
|
&NlpUser->LogonDomainName );
|
|
|
|
MsvPutWOWClientString( &ClientBufferDesc,
|
|
&LocalProfile->LogonServer,
|
|
&NlpUser->LogonServer );
|
|
|
|
//
|
|
// Kludge: Pass back UserParameters in HomeDirectoryDrive since we
|
|
// can't change the NETLOGON_VALIDATION_SAM_INFO structure between
|
|
// releases NT 1.0 and NT 1.0A. HomeDirectoryDrive was NULL for release 1.0A
|
|
// so we'll use that field.
|
|
//
|
|
|
|
MsvPutWOWClientString( &ClientBufferDesc,
|
|
&LocalProfile->UserParameters,
|
|
&NlpUser->HomeDirectoryDrive );
|
|
|
|
}
|
|
|
|
//
|
|
// Flush the buffer to the client's address space.
|
|
//
|
|
|
|
Status = NlpFlushClientBuffer( &ClientBufferDesc,
|
|
(PVOID*)ProfileBuffer );
|
|
|
|
Cleanup:
|
|
|
|
//
|
|
// If the copy wasn't successful,
|
|
// cleanup resources we would have returned to the caller.
|
|
//
|
|
|
|
if ( !NT_SUCCESS(Status) ) {
|
|
NlpFreeClientBuffer( &ClientBufferDesc );
|
|
}
|
|
|
|
// Save the status for subauth logons
|
|
|
|
if (NT_SUCCESS(Status) && !NT_SUCCESS(SubAuthStatus))
|
|
{
|
|
Status = SubAuthStatus;
|
|
}
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
#endif // _WIN64
|