}
+static
+NTSTATUS
+ChangePassword(IN PLSA_CLIENT_REQUEST ClientRequest,
+ IN PVOID ProtocolSubmitBuffer,
+ IN PVOID ClientBufferBase,
+ IN ULONG SubmitBufferLength,
+ OUT PVOID *ProtocolReturnBuffer,
+ OUT PULONG ReturnBufferLength,
+ OUT PNTSTATUS ProtocolStatus)
+{
+ PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer;
+ ULONG_PTR PtrOffset;
+
+ TRACE("()\n");
+
+ RequestBuffer = (PMSV1_0_CHANGEPASSWORD_REQUEST)ProtocolSubmitBuffer;
+
+ /* Fix-up pointers in the request buffer info */
+ PtrOffset = (ULONG_PTR)ProtocolSubmitBuffer - (ULONG_PTR)ClientBufferBase;
+
+ RequestBuffer->DomainName.Buffer = (PWSTR)((ULONG_PTR)RequestBuffer->DomainName.Buffer + PtrOffset);
+ RequestBuffer->AccountName.Buffer = (PWSTR)((ULONG_PTR)RequestBuffer->AccountName.Buffer + PtrOffset);
+ RequestBuffer->OldPassword.Buffer = (PWSTR)((ULONG_PTR)RequestBuffer->OldPassword.Buffer + PtrOffset);
+ RequestBuffer->NewPassword.Buffer = (PWSTR)((ULONG_PTR)RequestBuffer->NewPassword.Buffer + PtrOffset);
+
+ TRACE("Domain: %S\n", RequestBuffer->DomainName.Buffer);
+ TRACE("Account: %S\n", RequestBuffer->AccountName.Buffer);
+ TRACE("Old Password: %S\n", RequestBuffer->OldPassword.Buffer);
+ TRACE("New Password: %S\n", RequestBuffer->NewPassword.Buffer);
+
+
+ return STATUS_SUCCESS;
+}
+
+
+static
+NTSTATUS
+MsvpCheckPassword(PUNICODE_STRING UserPassword,
+ PSAMPR_USER_INFO_BUFFER UserInfo)
+{
+ ENCRYPTED_NT_OWF_PASSWORD UserNtPassword;
+ ENCRYPTED_LM_OWF_PASSWORD UserLmPassword;
+ BOOLEAN UserLmPasswordPresent = FALSE;
+ BOOLEAN UserNtPasswordPresent = FALSE;
+ OEM_STRING LmPwdString;
+ CHAR LmPwdBuffer[15];
+ NTSTATUS Status;
+
+ TRACE("(%p %p)\n", UserPassword, UserInfo);
+
+ /* Calculate the LM password and hash for the users password */
+ LmPwdString.Length = 15;
+ LmPwdString.MaximumLength = 15;
+ LmPwdString.Buffer = LmPwdBuffer;
+ ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength);
+
+ Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString,
+ UserPassword,
+ FALSE);
+ if (NT_SUCCESS(Status))
+ {
+ /* Calculate the LM hash value of the users password */
+ Status = SystemFunction006(LmPwdString.Buffer,
+ (LPSTR)&UserLmPassword);
+ if (NT_SUCCESS(Status))
+ {
+ UserLmPasswordPresent = TRUE;
+ }
+ }
+
+ /* Calculate the NT hash of the users password */
+ Status = SystemFunction007(UserPassword,
+ (LPBYTE)&UserNtPassword);
+ if (NT_SUCCESS(Status))
+ {
+ UserNtPasswordPresent = TRUE;
+ }
+
+ Status = STATUS_SUCCESS;
+
+ if (UserNtPasswordPresent && UserInfo->All.NtPasswordPresent)
+ {
+ TRACE("Check NT password hashes:\n");
+ if (!RtlEqualMemory(&UserNtPassword,
+ UserInfo->All.NtOwfPassword.Buffer,
+ sizeof(ENCRYPTED_NT_OWF_PASSWORD)))
+ {
+ TRACE(" failed!\n");
+ Status = STATUS_WRONG_PASSWORD;
+ }
+ }
+ else if (UserLmPasswordPresent && UserInfo->All.LmPasswordPresent)
+ {
+ TRACE("Check LM password hashes:\n");
+ if (!RtlEqualMemory(&UserLmPassword,
+ UserInfo->All.LmOwfPassword.Buffer,
+ sizeof(ENCRYPTED_LM_OWF_PASSWORD)))
+ {
+ TRACE(" failed!\n");
+ Status = STATUS_WRONG_PASSWORD;
+ }
+ }
+ else
+ {
+ TRACE("No matching hashes available!\n");
+ Status = STATUS_WRONG_PASSWORD;
+ }
+
+ return Status;
+}
+
+
/*
* @unimplemented
*/
OUT PULONG ReturnBufferLength,
OUT PNTSTATUS ProtocolStatus)
{
+ ULONG MessageType;
+ NTSTATUS Status;
+
TRACE("()\n");
- return STATUS_NOT_IMPLEMENTED;
+
+ if (SubmitBufferLength < sizeof(MSV1_0_PROTOCOL_MESSAGE_TYPE))
+ return STATUS_INVALID_PARAMETER;
+
+ MessageType = (ULONG)*((PMSV1_0_PROTOCOL_MESSAGE_TYPE)ProtocolSubmitBuffer);
+
+ *ProtocolReturnBuffer = NULL;
+ *ReturnBufferLength = 0;
+
+ switch (MessageType)
+ {
+ case MsV1_0Lm20ChallengeRequest:
+ case MsV1_0Lm20GetChallengeResponse:
+ case MsV1_0EnumerateUsers:
+ case MsV1_0GetUserInfo:
+ case MsV1_0ReLogonUsers:
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ case MsV1_0ChangePassword:
+ Status = ChangePassword(ClientRequest,
+ ProtocolSubmitBuffer,
+ ClientBufferBase,
+ SubmitBufferLength,
+ ProtocolReturnBuffer,
+ ReturnBufferLength,
+ ProtocolStatus);
+ break;
+
+ case MsV1_0ChangeCachedPassword:
+ case MsV1_0GenericPassthrough:
+ case MsV1_0CacheLogon:
+ case MsV1_0SubAuth:
+ case MsV1_0DeriveCredential:
+ case MsV1_0CacheLookup:
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ default:
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ return Status;
}
Confidentiality, AuthenticationPackageName);
/* Get the dispatch table entries */
+ DispatchTable.CreateLogonSession = LsaDispatchTable->CreateLogonSession;
+ DispatchTable.DeleteLogonSession = LsaDispatchTable->DeleteLogonSession;
+ DispatchTable.AddCredential = LsaDispatchTable->AddCredential;
+ DispatchTable.GetCredentials = LsaDispatchTable->GetCredentials;
+ DispatchTable.DeleteCredential = LsaDispatchTable->DeleteCredential;
DispatchTable.AllocateLsaHeap = LsaDispatchTable->AllocateLsaHeap;
DispatchTable.FreeLsaHeap = LsaDispatchTable->FreeLsaHeap;
DispatchTable.AllocateClientBuffer = LsaDispatchTable->AllocateClientBuffer;
DispatchTable.CopyToClientBuffer = LsaDispatchTable->CopyToClientBuffer;
DispatchTable.CopyFromClientBuffer = LsaDispatchTable->CopyFromClientBuffer;
-
/* Return the package name */
NameString = DispatchTable.AllocateLsaHeap(sizeof(LSA_STRING));
if (NameString == NULL)
SAMPR_ULONG_ARRAY Use = {0, NULL};
PSAMPR_USER_INFO_BUFFER UserInfo = NULL;
UNICODE_STRING LogonServer;
+ BOOLEAN SessionCreated = FALSE;
NTSTATUS Status;
TRACE("()\n");
TRACE("AuthenticationInformation: %p\n", AuthenticationInformation);
TRACE("AuthenticationInformationLength: %lu\n", AuthenticationInformationLength);
-
*ProfileBuffer = NULL;
*ProfileBufferLength = 0;
*SubStatus = STATUS_SUCCESS;
/* Fix-up pointers in the authentication info */
PtrOffset = (ULONG_PTR)AuthenticationInformation - (ULONG_PTR)ClientAuthenticationBase;
- LogonInfo->LogonDomainName.Buffer = (PWSTR)((ULONG_PTR)LogonInfo->LogonDomainName.Buffer + PtrOffset);
- LogonInfo->UserName.Buffer = (PWSTR)((ULONG_PTR)LogonInfo->UserName.Buffer + PtrOffset);
- LogonInfo->Password.Buffer = (PWSTR)((ULONG_PTR)LogonInfo->Password.Buffer + PtrOffset);
+ LogonInfo->LogonDomainName.Buffer = FIXUP_POINTER(LogonInfo->LogonDomainName.Buffer, PtrOffset);
+ LogonInfo->UserName.Buffer = FIXUP_POINTER(LogonInfo->UserName.Buffer, PtrOffset);
+ LogonInfo->Password.Buffer = FIXUP_POINTER(LogonInfo->Password.Buffer, PtrOffset);
TRACE("Domain: %S\n", LogonInfo->LogonDomainName.Buffer);
TRACE("User: %S\n", LogonInfo->UserName.Buffer);
/* FIXME: Check restrictions */
- /* FIXME: Check the password */
+ /* Check the password */
if ((UserInfo->All.UserAccountControl & USER_PASSWORD_NOT_REQUIRED) == 0)
{
- FIXME("Must check the password!\n");
-
+ Status = MsvpCheckPassword(&(LogonInfo->Password),
+ UserInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("MsvpCheckPassword failed (Status %08lx)\n", Status);
+ goto done;
+ }
}
/* Return logon information */
goto done;
}
+ /* Create the logon session */
+ Status = DispatchTable.CreateLogonSession(LogonId);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("CreateLogonSession failed (Status %08lx)\n", Status);
+ goto done;
+ }
+
+ SessionCreated = TRUE;
+
/* Build and fill the interactve profile buffer */
Status = BuildInteractiveProfileBuffer(ClientRequest,
UserInfo,
goto done;
}
- *SubStatus = STATUS_SUCCESS;
-
done:
/* Return the account name */
*AccountName = DispatchTable.AllocateLsaHeap(sizeof(UNICODE_STRING));
if (!NT_SUCCESS(Status))
{
+ if (SessionCreated == TRUE)
+ DispatchTable.DeleteLogonSession(LogonId);
+
if (*ProfileBuffer != NULL)
{
DispatchTable.FreeClientBuffer(ClientRequest,
if (AccountDomainSid != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);
+ if (Status == STATUS_NO_SUCH_USER ||
+ Status == STATUS_WRONG_PASSWORD)
+ {
+ *SubStatus = Status;
+ Status = STATUS_LOGON_FAILURE;
+ }
+
TRACE("LsaApLogonUser done (Status %08lx)\n", Status);
return Status;
/*
* @unimplemented
*/
+#if 0
NTSTATUS
NTAPI
LsaApLogonUserEx(IN PLSA_CLIENT_REQUEST ClientRequest,
return STATUS_NOT_IMPLEMENTED;
}
+#endif
/* EOF */