📄 nlp.c
字号:
&AnsiCleartextPassword,
CleartextPassword,
(BOOLEAN) FALSE );
if ( !NT_SUCCESS(Status) ) {
RtlZeroMemory( &LmPassword, sizeof(LmPassword) );
AnsiCleartextPassword.Length = 0;
LmPasswordPresent = FALSE;
} else {
LmPasswordPresent = TRUE;
}
//
// Save the OWF encrypted versions of the passwords.
//
Status = RtlCalculateLmOwfPassword( LmPassword,
&Credential->LmOwfPassword );
ASSERT( NT_SUCCESS(Status) );
Credential->LmPasswordPresent = LmPasswordPresent;
Status = RtlCalculateNtOwfPassword( CleartextPassword,
&Credential->NtOwfPassword );
ASSERT( NT_SUCCESS(Status) );
Credential->NtPasswordPresent = ( CleartextPassword->Length != 0 );
//
// Don't leave passwords around in the pagefile
//
RtlZeroMemory( &LmPassword, sizeof(LmPassword) );
return;
}
NTSTATUS
NlpMakePrimaryCredential(
IN PUNICODE_STRING LogonDomainName,
IN PUNICODE_STRING UserName,
IN PUNICODE_STRING CleartextPassword,
OUT PMSV1_0_PRIMARY_CREDENTIAL *CredentialBuffer,
OUT PULONG CredentialSize
)
/*++
Routine Description:
This routine makes a primary credential for the given user nam and
password.
Arguments:
LogonDomainName - Is a string representing the domain in which the user's
account is defined.
UserName - Is a string representing the user's account name. The
name may be up to 255 characters long. The name is treated case
insensitive.
CleartextPassword - Is a string containing the user's cleartext password.
The password may be up to 255 characters long and contain any
UNICODE value.
CredentialBuffer - Returns a pointer to the specified credential allocated
on the LsaHeap. It is the callers responsibility to deallocate
this credential.
CredentialSize - the size of the allocated credential buffer (in bytes).
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.
--*/
{
PMSV1_0_PRIMARY_CREDENTIAL Credential;
NTSTATUS Status;
PUCHAR Where;
//
// Build the credential
//
*CredentialSize = sizeof(MSV1_0_PRIMARY_CREDENTIAL) +
LogonDomainName->Length + sizeof(WCHAR) +
UserName->Length + sizeof(WCHAR);
Credential = (*Lsa.AllocateLsaHeap)( *CredentialSize );
if ( Credential == NULL ) {
KdPrint(("MSV1_0: NlpMakePrimaryCredential: No memory %ld\n",
*CredentialSize ));
return STATUS_QUOTA_EXCEEDED;
}
//
// Put the LogonDomainName into the Credential Buffer.
//
Where = (PUCHAR)(Credential + 1);
NlpPutString( &Credential->LogonDomainName, LogonDomainName, &Where );
//
// Put the UserName into the Credential Buffer.
//
NlpPutString( &Credential->UserName, UserName, &Where );
//
// Put the OWF passwords into the newly allocated credential.
//
NlpPutOwfsInPrimaryCredential( CleartextPassword, Credential );
//
// Return the credential to the caller.
//
*CredentialBuffer = Credential;
return STATUS_SUCCESS;
}
NTSTATUS
NlpMakePrimaryCredentialFromMsvCredential(
IN PUNICODE_STRING LogonDomainName,
IN PUNICODE_STRING UserName,
IN PMSV1_0_SUPPLEMENTAL_CREDENTIAL MsvCredential,
OUT PMSV1_0_PRIMARY_CREDENTIAL *CredentialBuffer,
OUT PULONG CredentialSize
)
/*++
Routine Description:
This routine makes a primary credential for the given user nam and
password.
Arguments:
LogonDomainName - Is a string representing the domain in which the user's
account is defined.
UserName - Is a string representing the user's account name. The
name may be up to 255 characters long. The name is treated case
insensitive.
SupplementalCred - The credentials retrieved from the user's account on
the domain controller.
CredentialBuffer - Returns a pointer to the specified credential allocated
on the LsaHeap. It is the callers responsibility to deallocate
this credential.
CredentialSize - the size of the allocated credential buffer (in bytes).
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.
--*/
{
PMSV1_0_PRIMARY_CREDENTIAL Credential;
NTSTATUS Status;
PUCHAR Where;
//
// Build the credential
//
*CredentialSize = sizeof(MSV1_0_PRIMARY_CREDENTIAL) +
LogonDomainName->Length + sizeof(WCHAR) +
UserName->Length + sizeof(WCHAR);
Credential = (*Lsa.AllocateLsaHeap)( *CredentialSize );
if ( Credential == NULL ) {
KdPrint(("MSV1_0: NlpMakePrimaryCredential: No memory %ld\n",
*CredentialSize ));
return STATUS_QUOTA_EXCEEDED;
}
RtlZeroMemory(
Credential,
*CredentialSize
);
//
// Put the LogonDomainName into the Credential Buffer.
//
Where = (PUCHAR)(Credential + 1);
NlpPutString( &Credential->LogonDomainName, LogonDomainName, &Where );
//
// Put the UserName into the Credential Buffer.
//
NlpPutString( &Credential->UserName, UserName, &Where );
//
// Save the OWF encrypted versions of the passwords.
//
if (MsvCredential->Flags & MSV1_0_CRED_NT_PRESENT) {
RtlCopyMemory(
&Credential->NtOwfPassword,
MsvCredential->NtPassword,
MSV1_0_OWF_PASSWORD_LENGTH
);
} else {
RtlCopyMemory(
&Credential->NtOwfPassword,
&NlpNullNtOwfPassword,
MSV1_0_OWF_PASSWORD_LENGTH
);
}
Credential->NtPasswordPresent = TRUE;
if (MsvCredential->Flags & MSV1_0_CRED_LM_PRESENT) {
RtlCopyMemory(
&Credential->LmOwfPassword,
MsvCredential->LmPassword,
MSV1_0_OWF_PASSWORD_LENGTH
);
} else {
RtlCopyMemory(
&Credential->LmOwfPassword,
&NlpNullLmOwfPassword,
MSV1_0_OWF_PASSWORD_LENGTH
);
}
Credential->LmPasswordPresent = TRUE;
//
// Return the credential to the caller.
//
*CredentialBuffer = Credential;
return STATUS_SUCCESS;
}
NTSTATUS
NlpAddPrimaryCredential(
IN PLUID LogonId,
IN PMSV1_0_PRIMARY_CREDENTIAL Credential,
IN ULONG CredentialSize
)
/*++
Routine Description:
This routine sets a primary credential for the given LogonId.
Arguments:
LogonId - The LogonId of the LogonSession to set the Credentials
for.
Credential - Specifies a pointer to the credential.
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;
STRING CredentialString;
STRING PrimaryKeyValue;
//
// Make all pointers in the credential relative.
//
NlpMakeRelativeString( (PUCHAR)Credential, &Credential->UserName );
NlpMakeRelativeString( (PUCHAR)Credential, &Credential->LogonDomainName );
//
// Add the credential to the logon session.
//
RtlInitString( &PrimaryKeyValue, MSV1_0_PRIMARY_KEY );
CredentialString.Buffer = (PCHAR) Credential;
CredentialString.Length = (USHORT) CredentialSize;
CredentialString.MaximumLength = CredentialString.Length;
Status = (*Lsa.AddCredential)(
LogonId,
MspAuthenticationPackageId,
&PrimaryKeyValue,
&CredentialString );
if ( !NT_SUCCESS( Status ) ) {
KdPrint(( "NlpAddPrimaryCredential: error from AddCredential %lX\n",
Status));
}
return Status;
}
NTSTATUS
NlpGetPrimaryCredentialByUserDomain(
IN PUNICODE_STRING LogonDomainName,
IN PUNICODE_STRING UserName,
OUT PMSV1_0_PRIMARY_CREDENTIAL *CredentialBuffer,
OUT PULONG CredentialSize OPTIONAL
)
{
PACTIVE_LOGON Logon;
LUID LogonId;
BOOLEAN Match = FALSE;
//
// 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 ))
{
Match = TRUE;
CopyMemory( &LogonId, &Logon->LogonId, sizeof(LogonId) );
break;
}
}
NlpUnlockActiveLogons();
if( !Match )
return STATUS_NO_SUCH_LOGON_SESSION;
return NlpGetPrimaryCredential( &LogonId, CredentialBuffer, CredentialSize );
}
NTSTATUS
NlpGetPrimaryCredential(
IN PLUID LogonId,
OUT PMSV1_0_PRIMARY_CREDENTIAL *CredentialBuffer,
OUT PULONG CredentialSize OPTIONAL
)
/*++
Routine Description:
This routine gets a primary credential for the given LogonId.
Arguments:
LogonId - The LogonId of the LogonSession to retrieve the Credentials
for.
CredentialBuffer - Returns a pointer to the specified credential allocated
on the LsaHeap. It is the callers responsibility to deallocate
this credential.
CredentialSize - Optionally returns the size of the credential buffer.
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;
ULONG QueryContext = 0;
ULONG PrimaryKeyLength;
STRING PrimaryKeyValue;
STRING CredentialString;
PMSV1_0_PRIMARY_CREDENTIAL Credential = NULL;
RtlInitString( &PrimaryKeyValue, MSV1_0_PRIMARY_KEY );
Status = (*Lsa.GetCredentials)( LogonId,
MspAuthenticationPackageId,
&QueryContext,
(BOOLEAN) FALSE, // Just retrieve primary
&PrimaryKeyValue,
&PrimaryKeyLength,
&CredentialString );
if ( !NT_SUCCESS( Status ) ) {
return Status;
}
//
// Make all pointers in the credential absolute.
//
Credential = (PMSV1_0_PRIMARY_CREDENTIAL) CredentialString.Buffer;
NlpRelativeToAbsolute( Credential,
(PULONG_PTR)&Credential->UserName.Buffer );
NlpRelativeToAbsolute( Credential,
(PULONG_PTR)&Credential->LogonDomainName.Buffer );
*CredentialBuffer = Credential;
if ( CredentialSize != NULL ) {
*CredentialSize = CredentialString.Length;
}
return STATUS_SUCCESS;
}
NTSTATUS
NlpDeletePrimaryCredential(
IN PLUID LogonId
)
/*++
Routine Description:
This routine deletes the credential for the given LogonId.
Arguments:
LogonId - The LogonId of the LogonSession to delete the Credentials for.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -