📄 nlp.c
字号:
Routine Description:
This routine converts the buffer address in the specified string to
be a byte offset from BaseAddress.
Parameters:
BaseAddress - A pointer to make the destination address relative to.
String - A pointer to a NT string to make relative.
Return Values:
None.
--*/
{
ASSERT( BaseAddress != NULL );
ASSERT( String != NULL );
ASSERT( sizeof(ULONG_PTR) == sizeof(String->Buffer) );
if ( String->Buffer != NULL ) {
*((PULONG_PTR)(&String->Buffer)) =
(ULONG_PTR)((PUCHAR)String->Buffer - (PUCHAR)BaseAddress);
}
return;
}
VOID
NlpRelativeToAbsolute(
IN PVOID BaseAddress,
IN OUT PULONG_PTR RelativeValue
)
/*++
Routine Description:
This routine converts the byte offset from BaseAddress to be an
absolute address.
Parameters:
BaseAddress - A pointer the destination address is relative to.
RelativeValue - A pointer to a relative value to make absolute.
Return Values:
None.
--*/
{
ASSERT( BaseAddress != NULL );
ASSERT( RelativeValue != NULL );
if ( *((PUCHAR *)RelativeValue) != NULL ) {
*RelativeValue = (ULONG_PTR)((PUCHAR)BaseAddress + (*RelativeValue));
}
return;
}
BOOLEAN
NlpFindActiveLogon(
IN PLUID LogonId,
OUT PACTIVE_LOGON **ActiveLogon
)
/*++
Routine Description:
This routine finds the specified Logon Id in the ActiveLogon table.
It returns a boolean indicating whether the Logon Id exists in the
ActiveLogon Table. If so, this routine also returns a pointer to a
pointer to the appropriate entry in the table. If not, this routine
returns a pointer to where such an entry would be inserted in the table.
This routine must be called with the NlpActiveLogonLock locked.
Parameters:
LogonId - The LogonId of the logon to find in the table.
ActiveLogon - If the specified logon Id exists, returns a pointer to a
pointer to the appropriate entry in the table. Otherwise,
returns a pointer to where such an entry would be inserted in the
table.
Return Values:
TRUE - The specified LogonId already exists in the table.
FALSE - The specified LogonId does not exist in the table.
--*/
{
PACTIVE_LOGON *Logon;
//
// Loop through the table looking for this particular LogonId.
//
for( Logon = &NlpActiveLogons; *Logon != NULL; Logon = &((*Logon)->Next) ) {
if (RtlCompareMemory( &(*Logon)->LogonId, LogonId, sizeof(*LogonId))
== sizeof(*LogonId) ) {
*ActiveLogon = Logon;
return TRUE;
}
}
//
// By returning a pointer to the NULL at the end of the list, we
// are forcing new entries to be placed at the end. The list is
// thereby maintained in the order that the logon occurred.
// MsV1_0EnumerateUsers relies on this behavior.
//
*ActiveLogon = Logon;
return FALSE;
}
ULONG
NlpCountActiveLogon(
IN PUNICODE_STRING LogonDomainName,
IN PUNICODE_STRING UserName
)
/*++
Routine Description:
This routine counts the number of time a particular user is logged on
in the Active Logon Table.
Parameters:
LogonDomainName - Domain in which this user account is defined.
UserName - The user name to count the active logons for.
Return Values:
The count of active logons for the specified user.
--*/
{
PACTIVE_LOGON Logon;
ULONG LogonCount = 0;
//
// Loop through the table looking for this particular LogonId.
//
NlpLockActiveLogons();
for( Logon = NlpActiveLogons; Logon != NULL; Logon = Logon->Next ) {
if(RtlEqualUnicodeString( UserName, &Logon->UserName, (BOOLEAN) TRUE) &&
RtlEqualDomainName(LogonDomainName,&Logon->LogonDomainName )){
LogonCount ++;
}
}
NlpUnlockActiveLogons();
return LogonCount;
}
NTSTATUS
NlpAllocateInteractiveProfile (
IN PLSA_CLIENT_REQUEST ClientRequest,
OUT PMSV1_0_INTERACTIVE_PROFILE *ProfileBuffer,
OUT PULONG ProfileBufferSize,
IN PNETLOGON_VALIDATION_SAM_INFO2 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 LocalProfileBuffer;
//
// Alocate the profile buffer to return to the client
//
NlpInitClientBuffer( &ClientBufferDesc, ClientRequest );
*ProfileBuffer = NULL;
*ProfileBufferSize = sizeof(MSV1_0_INTERACTIVE_PROFILE) +
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),
*ProfileBufferSize );
if ( !NT_SUCCESS( Status ) ) {
goto Cleanup;
}
LocalProfileBuffer = (PMSV1_0_INTERACTIVE_PROFILE) 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.
//
NlpPutClientString( &ClientBufferDesc,
&LocalProfileBuffer->LogonScript,
&NlpUser->LogonScript );
NlpPutClientString( &ClientBufferDesc,
&LocalProfileBuffer->HomeDirectory,
&NlpUser->HomeDirectory );
NlpPutClientString( &ClientBufferDesc,
&LocalProfileBuffer->HomeDirectoryDrive,
&NlpUser->HomeDirectoryDrive );
NlpPutClientString( &ClientBufferDesc,
&LocalProfileBuffer->FullName,
&NlpUser->FullName );
NlpPutClientString( &ClientBufferDesc,
&LocalProfileBuffer->ProfilePath,
&NlpUser->ProfilePath );
NlpPutClientString( &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
NlpAllocateNetworkProfile (
IN PLSA_CLIENT_REQUEST ClientRequest,
OUT PMSV1_0_LM20_LOGON_PROFILE *ProfileBuffer,
OUT PULONG ProfileBufferSize,
IN PNETLOGON_VALIDATION_SAM_INFO2 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 LocalProfile;
//
// Alocate the profile buffer to return to the client
//
NlpInitClientBuffer( &ClientBufferDesc, ClientRequest );
*ProfileBuffer = NULL;
*ProfileBufferSize = sizeof(MSV1_0_LM20_LOGON_PROFILE);
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),
*ProfileBufferSize );
if ( !NT_SUCCESS( Status ) ) {
goto Cleanup;
}
LocalProfile = (PMSV1_0_LM20_LOGON_PROFILE) 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));
RtlInitUnicodeString( &LocalProfile->LogonDomainName, NULL );
RtlInitUnicodeString( &LocalProfile->LogonServer, NULL );
RtlInitUnicodeString( &LocalProfile->UserParameters, NULL );
//
// 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.
//
NlpPutClientString( &ClientBufferDesc,
&LocalProfile->LogonDomainName,
&NlpUser->LogonDomainName );
NlpPutClientString( &ClientBufferDesc,
&LocalProfile->LogonServer,
&NlpUser->LogonServer );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -