📄 nlp.c
字号:
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 PrimaryKeyValue;
RtlInitString( &PrimaryKeyValue, MSV1_0_PRIMARY_KEY );
Status = (*Lsa.DeleteCredential)( LogonId,
MspAuthenticationPackageId,
&PrimaryKeyValue );
return Status;
}
NTSTATUS
NlpChangePassword(
IN PUNICODE_STRING DomainName,
IN PUNICODE_STRING UserName,
IN PUNICODE_STRING Password
)
/*++
Routine Description:
Change the password for the specified user in all currently stored
credentials.
Arguments:
DomainName - The Netbios name of the domain in which the account exists.
UserName - The name of the account whose password is to be changed.
Password - The new password.
Return Value:
STATUS_SUCCESS - If the operation was successful.
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
PACTIVE_LOGON Logon;
ULONG LogonCount = 0;
PMSV1_0_PRIMARY_CREDENTIAL Credential = NULL;
ULONG CredentialSize;
MSV1_0_PRIMARY_CREDENTIAL TempCredential;
LUID LogonId;
BOOLEAN Found = FALSE;
BOOLEAN MatchedCaller = FALSE;
SECPKG_CLIENT_INFO ClientInfo;
//
// Get the logon ID of the caller.
//
Status = LsaFunctions->GetClientInfo(&ClientInfo);
if (!NT_SUCCESS(Status)) {
return(Status);
}
//
// Compute the OWFs of the password.
//
NlpPutOwfsInPrimaryCredential( Password, &TempCredential );
//
// Loop through the table looking for this particular UserName/DomainName.
//
NlpLockActiveLogons();
for( Logon = NlpActiveLogons; Logon != NULL; Logon = Logon->Next ) {
if(RtlEqualUnicodeString( UserName, &Logon->UserName, (BOOLEAN) TRUE) &&
RtlEqualDomainName( DomainName, &Logon->LogonDomainName )){
if (!MatchedCaller) {
LogonId = Logon->LogonId;
}
Found = TRUE;
//
// If this is the LUID of the caller, remember the caller's
// logon id.
//
if (RtlEqualLuid(
&LogonId,
&ClientInfo.LogonId
))
{
MatchedCaller = TRUE;
}
//
// Get the current credential for this logonid.
//
Status = NlpGetPrimaryCredential( &Logon->LogonId,
&Credential,
&CredentialSize );
if ( !NT_SUCCESS(Status) ) {
break;
}
//
// Delete it from the LSA.
//
Status = NlpDeletePrimaryCredential( &Logon->LogonId );
if ( !NT_SUCCESS(Status) ) {
(*Lsa.FreeLsaHeap)( Credential );
break;
}
//
// Change the passwords in it
//
Credential->LmOwfPassword = TempCredential.LmOwfPassword;
Credential->LmPasswordPresent = TempCredential.LmPasswordPresent;
Credential->NtOwfPassword = TempCredential.NtOwfPassword;
Credential->NtPasswordPresent = TempCredential.NtPasswordPresent;
//
// Add it back to the LSA.
//
Status = NlpAddPrimaryCredential( &Logon->LogonId,
Credential,
CredentialSize );
(*Lsa.FreeLsaHeap)( Credential );
if ( !NT_SUCCESS(Status) ) {
break;
}
}
}
NlpUnlockActiveLogons();
//
// Pass the change back to the LSA. Note - this only changes it for the
// last element in the list.
//
if (Found) {
SECPKG_PRIMARY_CRED PrimaryCredentials;
RtlZeroMemory(
&PrimaryCredentials,
sizeof(SECPKG_PRIMARY_CRED)
);
PrimaryCredentials.LogonId = LogonId;
PrimaryCredentials.Password = *Password;
PrimaryCredentials.Flags = PRIMARY_CRED_UPDATE | PRIMARY_CRED_CLEAR_PASSWORD;
(VOID) LsaFunctions->UpdateCredentials(
&PrimaryCredentials,
NULL // no supplemental credentials
);
}
//
// Pass the new password on to the logon cache
//
NlpChangeCachePassword(
DomainName,
UserName,
&TempCredential.LmOwfPassword,
&TempCredential.NtOwfPassword );
return Status;
}
NTSTATUS
NlpChangePasswordByLogonId(
IN PLUID LogonId,
IN PUNICODE_STRING Password
)
/*++
Routine Description:
Change the password for the specified user in all currently stored
credentials.
Arguments:
LogonId - Logon ID of user whose password changed.
Password - New password.
Return Value:
STATUS_SUCCESS - If the operation was successful.
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
PACTIVE_LOGON Logon;
ULONG LogonCount = 0;
PMSV1_0_PRIMARY_CREDENTIAL Credential = NULL;
ULONG CredentialSize;
ANSI_STRING LmPasswordString;
CHAR LmPassword[LM20_PWLEN+1];
LM_OWF_PASSWORD LmOwfPassword;
NT_OWF_PASSWORD NtOwfPassword;
LmPasswordString.Buffer = LmPassword;
LmPasswordString.Length = 0;
LmPasswordString.MaximumLength = sizeof( LmPassword );
Status = RtlUpcaseUnicodeStringToOemString( &LmPasswordString,
Password,
FALSE );
if ( NT_SUCCESS(Status) ) {
Status = RtlCalculateLmOwfPassword( LmPassword, &LmOwfPassword );
ASSERT( NT_SUCCESS(Status) );
}
Status = RtlCalculateNtOwfPassword( Password,
&NtOwfPassword );
ASSERT( NT_SUCCESS(Status) );
//
// Loop through the table looking for this particular UserName/DomainName.
//
NlpLockActiveLogons();
for( Logon = NlpActiveLogons; Logon != NULL; Logon = Logon->Next ) {
if(RtlEqualLuid( LogonId, &Logon->LogonId) ){
//
// Get the current credential for this logonid.
//
Status = NlpGetPrimaryCredential( &Logon->LogonId,
&Credential,
&CredentialSize );
if ( !NT_SUCCESS(Status) ) {
break;
}
//
// Delete it from the LSA.
//
Status = NlpDeletePrimaryCredential( &Logon->LogonId );
if ( !NT_SUCCESS(Status) ) {
(*Lsa.FreeLsaHeap)( Credential );
break;
}
//
// Change the passwords in it
//
Credential->LmOwfPassword = LmOwfPassword;
Credential->NtOwfPassword = NtOwfPassword;
//
// Add it back to the LSA.
//
Status = NlpAddPrimaryCredential( &Logon->LogonId,
Credential,
CredentialSize );
(*Lsa.FreeLsaHeap)( Credential );
if ( !NT_SUCCESS(Status) ) {
break;
}
//
// Pass the new password on to the logon cache
//
NlpChangeCachePassword(
&Logon->LogonDomainName,
&Logon->UserName,
&LmOwfPassword,
&NtOwfPassword );
}
}
NlpUnlockActiveLogons();
return Status;
}
VOID
NlpGetAccountNames(
IN PNETLOGON_LOGON_IDENTITY_INFO LogonInfo,
IN PNETLOGON_VALIDATION_SAM_INFO2 NlpUser,
OUT PUNICODE_STRING SamAccountName,
OUT PUNICODE_STRING NetbiosDomainName,
OUT PUNICODE_STRING DnsDomainName,
OUT PUNICODE_STRING Upn
)
/*++
Routine Description:
Get the sundry account names from the LogonInfo and NlpUser
Arguments:
LogonInfo - pointer to NETLOGON_INTERACTIVE_INFO structure which contains
the domain name, user name and password for this user. These
are what the user typed to WinLogon
NlpUser - pointer to NETLOGON_VALIDATION_SAM_INFO2 structure which
contains this user's specific interactive logon information
SamAccountName - Returns the SamAccountName of the logged on user.
The returned buffer is within the LogonInfo or NlpUser.
NetbiosDomainName - Returns the NetbiosDomainName of the logged on user.
The returned buffer is within the LogonInfo or NlpUser.
DnsDomainName - Returns the DnsDomainName of the logged on user.
The returned buffer is within the LogonInfo or NlpUser.
The returned length will be zero if DnsDomainName is not known.
UPN - Returns the UPN of the logged on user.
The returned buffer is within the LogonInfo or NlpUser.
The returned length will be zero if UPN is not known.
Return Value:
None.
--*/
{
//
// Return the SamAccountName and Netbios Domain Name
//
*SamAccountName = NlpUser->EffectiveName;
*NetbiosDomainName = NlpUser->LogonDomainName;
//
// Determine the DNS domain name of the user's domain.
//
// BUGBUG: This should be in NlpUser.
//
RtlInitUnicodeString( DnsDomainName, NULL );
//
// Determine the UPN of the account
//
// The caller passed in a UPN if all of the following are true:
// The is no domain name.
// The passed in user name isn't the one returned from the DC.
// The passed in user name has an @ in it.
//
//
RtlInitUnicodeString( Upn, NULL );
if ( LogonInfo->LogonDomainName.Length == 0 &&
!RtlEqualUnicodeString( &LogonInfo->UserName, &NlpUser->EffectiveName, (BOOLEAN) TRUE ) ) {
ULONG i;
for ( i=0; i<LogonInfo->UserName.Length/sizeof(WCHAR); i++) {
if ( LogonInfo->UserName.Buffer[i] == L'@') {
*Upn = LogonInfo->UserName;
break;
}
}
}
}
//+-------------------------------------------------------------------------
//
// Function: NlpCopyDomainRelativeSid
//
// Synopsis: Given a domain Id and a relative ID create the corresponding
// SID at the location indicated by TargetSid
//
// Effects:
//
// Arguments: TargetSid - target memory location
// DomainId - The template SID to use.
//
// RelativeId - The relative Id to append to the DomainId.
//
// Requires:
//
// Returns: Size - Size of the sid copied
//
// Notes:
//
//
//--------------------------------------------------------------------------
DWORD
NlpCopyDomainRelativeSid(
OUT PSID TargetSid,
IN PSID DomainId,
IN ULONG RelativeId
)
{
UCHAR DomainIdSubAuthorityCount;
ULONG Size;
//
// Allocate a Sid which has one more sub-authority than the domain ID.
//
DomainIdSubAuthorityCount = *(RtlSubAuthorityCountSid( DomainId ));
Size = RtlLengthRequiredSid(DomainIdSubAuthorityCount+1);
//
// Initialize the new SID to have the same inital value as the
// domain ID.
//
if ( !NT_SUCCESS( RtlCopySid( Size, TargetSid, DomainId ) ) ) {
return 0;
}
//
// Adjust the sub-authority count and
// add the relative Id unique to the newly allocated SID
//
(*(RtlSubAuthorityCountSid( TargetSid ))) ++;
*RtlSubAuthoritySid( TargetSid, DomainIdSubAuthorityCount ) = RelativeId;
return Size;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -