2 * PROJECT: Authentication Package DLL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/msv1_0/msv1_0.c
6 * COPYRIGHT: Copyright 2013 Eric Kohl
9 /* INCLUDES ****************************************************************/
13 WINE_DEFAULT_DEBUG_CHANNEL(msv1_0
);
16 /* GLOBALS *****************************************************************/
18 LSA_DISPATCH_TABLE DispatchTable
;
21 /* FUNCTIONS ***************************************************************/
25 GetDomainSid(PRPC_SID
*Sid
)
27 LSAPR_HANDLE PolicyHandle
= NULL
;
28 PLSAPR_POLICY_INFORMATION PolicyInfo
= NULL
;
32 Status
= LsaIOpenPolicyTrusted(&PolicyHandle
);
33 if (!NT_SUCCESS(Status
))
35 TRACE("LsaIOpenPolicyTrusted() failed (Status 0x%08lx)\n", Status
);
39 Status
= LsarQueryInformationPolicy(PolicyHandle
,
40 PolicyAccountDomainInformation
,
42 if (!NT_SUCCESS(Status
))
44 TRACE("LsarQueryInformationPolicy() failed (Status 0x%08lx)\n", Status
);
48 Length
= RtlLengthSid(PolicyInfo
->PolicyAccountDomainInfo
.Sid
);
50 *Sid
= RtlAllocateHeap(RtlGetProcessHeap(), 0, Length
);
53 ERR("Failed to allocate SID\n");
54 Status
= STATUS_INSUFFICIENT_RESOURCES
;
58 memcpy(*Sid
, PolicyInfo
->PolicyAccountDomainInfo
.Sid
, Length
);
61 if (PolicyInfo
!= NULL
)
62 LsaIFree_LSAPR_POLICY_INFORMATION(PolicyAccountDomainInformation
,
65 if (PolicyHandle
!= NULL
)
66 LsarClose(&PolicyHandle
);
74 BuildInteractiveProfileBuffer(IN PLSA_CLIENT_REQUEST ClientRequest
,
75 IN PSAMPR_USER_INFO_BUFFER UserInfo
,
76 IN PUNICODE_STRING LogonServer
,
77 OUT PMSV1_0_INTERACTIVE_PROFILE
*ProfileBuffer
,
78 OUT PULONG ProfileBufferLength
)
80 PMSV1_0_INTERACTIVE_PROFILE LocalBuffer
= NULL
;
81 PVOID ClientBaseAddress
= NULL
;
84 NTSTATUS Status
= STATUS_SUCCESS
;
86 *ProfileBuffer
= NULL
;
87 *ProfileBufferLength
= 0;
89 BufferLength
= sizeof(MSV1_0_INTERACTIVE_PROFILE
) +
90 UserInfo
->All
.FullName
.Length
+ sizeof(WCHAR
) +
91 UserInfo
->All
.HomeDirectory
.Length
+ sizeof(WCHAR
) +
92 UserInfo
->All
.HomeDirectoryDrive
.Length
+ sizeof(WCHAR
) +
93 UserInfo
->All
.ScriptPath
.Length
+ sizeof(WCHAR
) +
94 UserInfo
->All
.ProfilePath
.Length
+ sizeof(WCHAR
) +
95 LogonServer
->Length
+ sizeof(WCHAR
);
97 LocalBuffer
= DispatchTable
.AllocateLsaHeap(BufferLength
);
98 if (LocalBuffer
== NULL
)
100 TRACE("Failed to allocate the local buffer!\n");
101 Status
= STATUS_INSUFFICIENT_RESOURCES
;
105 Status
= DispatchTable
.AllocateClientBuffer(ClientRequest
,
108 if (!NT_SUCCESS(Status
))
110 TRACE("DispatchTable.AllocateClientBuffer failed (Status 0x%08lx)\n", Status
);
114 TRACE("ClientBaseAddress: %p\n", ClientBaseAddress
);
116 Ptr
= (LPWSTR
)((ULONG_PTR
)LocalBuffer
+ sizeof(MSV1_0_INTERACTIVE_PROFILE
));
118 LocalBuffer
->MessageType
= MsV1_0InteractiveProfile
;
119 LocalBuffer
->LogonCount
= UserInfo
->All
.LogonCount
;
120 LocalBuffer
->BadPasswordCount
= UserInfo
->All
.BadPasswordCount
;
122 LocalBuffer
->LogonTime
.LowPart
= UserInfo
->All
.LastLogon
.LowPart
;
123 LocalBuffer
->LogonTime
.HighPart
= UserInfo
->All
.LastLogon
.HighPart
;
125 // LocalBuffer->LogoffTime.LowPart =
126 // LocalBuffer->LogoffTime.HighPart =
128 // LocalBuffer->KickOffTime.LowPart =
129 // LocalBuffer->KickOffTime.HighPart =
131 LocalBuffer
->PasswordLastSet
.LowPart
= UserInfo
->All
.PasswordLastSet
.LowPart
;
132 LocalBuffer
->PasswordLastSet
.HighPart
= UserInfo
->All
.PasswordLastSet
.HighPart
;
134 LocalBuffer
->PasswordCanChange
.LowPart
= UserInfo
->All
.PasswordCanChange
.LowPart
;
135 LocalBuffer
->PasswordCanChange
.HighPart
= UserInfo
->All
.PasswordCanChange
.HighPart
;
137 LocalBuffer
->PasswordMustChange
.LowPart
= UserInfo
->All
.PasswordMustChange
.LowPart
;
138 LocalBuffer
->PasswordMustChange
.HighPart
= UserInfo
->All
.PasswordMustChange
.HighPart
;
140 LocalBuffer
->LogonScript
.Length
= UserInfo
->All
.ScriptPath
.Length
;
141 LocalBuffer
->LogonScript
.MaximumLength
= UserInfo
->All
.ScriptPath
.Length
+ sizeof(WCHAR
);
142 LocalBuffer
->LogonScript
.Buffer
= (LPWSTR
)((ULONG_PTR
)ClientBaseAddress
+ (ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalBuffer
);
144 UserInfo
->All
.ScriptPath
.Buffer
,
145 UserInfo
->All
.ScriptPath
.Length
);
147 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ LocalBuffer
->LogonScript
.MaximumLength
);
149 LocalBuffer
->HomeDirectory
.Length
= UserInfo
->All
.HomeDirectory
.Length
;
150 LocalBuffer
->HomeDirectory
.MaximumLength
= UserInfo
->All
.HomeDirectory
.Length
+ sizeof(WCHAR
);
151 LocalBuffer
->HomeDirectory
.Buffer
= (LPWSTR
)((ULONG_PTR
)ClientBaseAddress
+ (ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalBuffer
);
153 UserInfo
->All
.HomeDirectory
.Buffer
,
154 UserInfo
->All
.HomeDirectory
.Length
);
156 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ LocalBuffer
->HomeDirectory
.MaximumLength
);
158 LocalBuffer
->FullName
.Length
= UserInfo
->All
.FullName
.Length
;
159 LocalBuffer
->FullName
.MaximumLength
= UserInfo
->All
.FullName
.Length
+ sizeof(WCHAR
);
160 LocalBuffer
->FullName
.Buffer
= (LPWSTR
)((ULONG_PTR
)ClientBaseAddress
+ (ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalBuffer
);
162 UserInfo
->All
.FullName
.Buffer
,
163 UserInfo
->All
.FullName
.Length
);
164 TRACE("FullName.Buffer: %p\n", LocalBuffer
->FullName
.Buffer
);
166 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ LocalBuffer
->FullName
.MaximumLength
);
168 LocalBuffer
->ProfilePath
.Length
= UserInfo
->All
.ProfilePath
.Length
;
169 LocalBuffer
->ProfilePath
.MaximumLength
= UserInfo
->All
.ProfilePath
.Length
+ sizeof(WCHAR
);
170 LocalBuffer
->ProfilePath
.Buffer
= (LPWSTR
)((ULONG_PTR
)ClientBaseAddress
+ (ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalBuffer
);
172 UserInfo
->All
.ProfilePath
.Buffer
,
173 UserInfo
->All
.ProfilePath
.Length
);
175 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ LocalBuffer
->ProfilePath
.MaximumLength
);
177 LocalBuffer
->HomeDirectoryDrive
.Length
= UserInfo
->All
.HomeDirectoryDrive
.Length
;
178 LocalBuffer
->HomeDirectoryDrive
.MaximumLength
= UserInfo
->All
.HomeDirectoryDrive
.Length
+ sizeof(WCHAR
);
179 LocalBuffer
->HomeDirectoryDrive
.Buffer
= (LPWSTR
)((ULONG_PTR
)ClientBaseAddress
+ (ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalBuffer
);
181 UserInfo
->All
.HomeDirectoryDrive
.Buffer
,
182 UserInfo
->All
.HomeDirectoryDrive
.Length
);
184 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ LocalBuffer
->HomeDirectoryDrive
.MaximumLength
);
186 LocalBuffer
->LogonServer
.Length
= LogonServer
->Length
;
187 LocalBuffer
->LogonServer
.MaximumLength
= LogonServer
->Length
+ sizeof(WCHAR
);
188 LocalBuffer
->LogonServer
.Buffer
= (LPWSTR
)((ULONG_PTR
)ClientBaseAddress
+ (ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalBuffer
);;
191 LogonServer
->Length
);
193 LocalBuffer
->UserFlags
= 0;
195 Status
= DispatchTable
.CopyToClientBuffer(ClientRequest
,
199 if (!NT_SUCCESS(Status
))
201 TRACE("DispatchTable.CopyToClientBuffer failed (Status 0x%08lx)\n", Status
);
205 *ProfileBuffer
= (PMSV1_0_INTERACTIVE_PROFILE
)ClientBaseAddress
;
206 *ProfileBufferLength
= BufferLength
;
209 if (LocalBuffer
!= NULL
)
210 DispatchTable
.FreeLsaHeap(LocalBuffer
);
212 if (!NT_SUCCESS(Status
))
214 if (ClientBaseAddress
!= NULL
)
215 DispatchTable
.FreeClientBuffer(ClientRequest
,
225 AppendRidToSid(PSID SrcSid
,
231 RidCount
= *RtlSubAuthorityCountSid(SrcSid
);
235 DstSid
= DispatchTable
.AllocateLsaHeap(RtlLengthRequiredSid(RidCount
+ 1));
239 RtlCopyMemory(DstSid
,
241 RtlLengthRequiredSid(RidCount
));
243 *RtlSubAuthorityCountSid(DstSid
) = RidCount
+ 1;
244 *RtlSubAuthoritySid(DstSid
, RidCount
) = Rid
;
251 BuildTokenUser(OUT PTOKEN_USER User
,
252 IN PSID AccountDomainSid
,
255 User
->User
.Sid
= AppendRidToSid(AccountDomainSid
,
257 if (User
->User
.Sid
== NULL
)
259 ERR("Could not create the user SID\n");
260 return STATUS_INSUFFICIENT_RESOURCES
;
263 User
->User
.Attributes
= 0;
265 return STATUS_SUCCESS
;
271 BuildTokenPrimaryGroup(OUT PTOKEN_PRIMARY_GROUP PrimaryGroup
,
272 IN PSID AccountDomainSid
,
275 PrimaryGroup
->PrimaryGroup
= AppendRidToSid(AccountDomainSid
,
277 if (PrimaryGroup
->PrimaryGroup
== NULL
)
279 ERR("Could not create the primary group SID\n");
280 return STATUS_INSUFFICIENT_RESOURCES
;
283 return STATUS_SUCCESS
;
289 BuildTokenGroups(OUT PTOKEN_GROUPS
*Groups
,
290 IN PSID AccountDomainSid
)
292 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
293 PTOKEN_GROUPS TokenGroups
;
295 DWORD GroupCount
= 0;
297 NTSTATUS Status
= STATUS_SUCCESS
;
299 TokenGroups
= DispatchTable
.AllocateLsaHeap(sizeof(TOKEN_GROUPS
) +
300 MAX_GROUPS
* sizeof(SID_AND_ATTRIBUTES
));
301 if (TokenGroups
== NULL
)
303 return STATUS_INSUFFICIENT_RESOURCES
;
306 Sid
= AppendRidToSid(AccountDomainSid
, DOMAIN_GROUP_RID_USERS
);
312 /* Member of the domain */
313 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
314 TokenGroups
->Groups
[GroupCount
].Attributes
=
315 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
319 /* Member of 'Authenticated users' */
320 RtlAllocateAndInitializeSid(&SystemAuthority
,
322 SECURITY_AUTHENTICATED_USER_RID
,
331 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
332 TokenGroups
->Groups
[GroupCount
].Attributes
=
333 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
336 TokenGroups
->GroupCount
= GroupCount
;
337 ASSERT(TokenGroups
->GroupCount
<= MAX_GROUPS
);
339 *Groups
= TokenGroups
;
347 BuildTokenInformationBuffer(PLSA_TOKEN_INFORMATION_V1
*TokenInformation
,
348 PRPC_SID AccountDomainSid
,
349 PSAMPR_USER_INFO_BUFFER UserInfo
)
351 PLSA_TOKEN_INFORMATION_V1 Buffer
= NULL
;
353 NTSTATUS Status
= STATUS_SUCCESS
;
355 Buffer
= DispatchTable
.AllocateLsaHeap(sizeof(LSA_TOKEN_INFORMATION_V1
));
358 TRACE("Failed to allocate the local buffer!\n");
359 Status
= STATUS_INSUFFICIENT_RESOURCES
;
364 Buffer
->ExpirationTime
.QuadPart
= -1;
366 Status
= BuildTokenUser(&Buffer
->User
,
367 (PSID
)AccountDomainSid
,
368 UserInfo
->All
.UserId
);
369 if (!NT_SUCCESS(Status
))
372 Status
= BuildTokenPrimaryGroup(&Buffer
->PrimaryGroup
,
373 (PSID
)AccountDomainSid
,
374 UserInfo
->All
.PrimaryGroupId
);
375 if (!NT_SUCCESS(Status
))
378 Status
= BuildTokenGroups(&Buffer
->Groups
,
379 (PSID
)AccountDomainSid
);
380 if (!NT_SUCCESS(Status
))
383 *TokenInformation
= Buffer
;
386 if (!NT_SUCCESS(Status
))
390 if (Buffer
->User
.User
.Sid
!= NULL
)
391 DispatchTable
.FreeLsaHeap(Buffer
->User
.User
.Sid
);
393 if (Buffer
->Groups
!= NULL
)
395 for (i
= 0; i
< Buffer
->Groups
->GroupCount
; i
++)
397 if (Buffer
->Groups
->Groups
[i
].Sid
!= NULL
)
398 DispatchTable
.FreeLsaHeap(Buffer
->Groups
->Groups
[i
].Sid
);
401 DispatchTable
.FreeLsaHeap(Buffer
->Groups
);
404 if (Buffer
->PrimaryGroup
.PrimaryGroup
!= NULL
)
405 DispatchTable
.FreeLsaHeap(Buffer
->PrimaryGroup
.PrimaryGroup
);
407 if (Buffer
->DefaultDacl
.DefaultDacl
!= NULL
)
408 DispatchTable
.FreeLsaHeap(Buffer
->DefaultDacl
.DefaultDacl
);
410 DispatchTable
.FreeLsaHeap(Buffer
);
420 MsvpChangePassword(IN PLSA_CLIENT_REQUEST ClientRequest
,
421 IN PVOID ProtocolSubmitBuffer
,
422 IN PVOID ClientBufferBase
,
423 IN ULONG SubmitBufferLength
,
424 OUT PVOID
*ProtocolReturnBuffer
,
425 OUT PULONG ReturnBufferLength
,
426 OUT PNTSTATUS ProtocolStatus
)
428 PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer
;
431 SAMPR_HANDLE ServerHandle
= NULL
;
432 SAMPR_HANDLE DomainHandle
= NULL
;
433 SAMPR_HANDLE UserHandle
= NULL
;
434 PRPC_SID DomainSid
= NULL
;
435 RPC_UNICODE_STRING Names
[1];
436 SAMPR_ULONG_ARRAY RelativeIds
= {0, NULL
};
437 SAMPR_ULONG_ARRAY Use
= {0, NULL
};
440 ENCRYPTED_NT_OWF_PASSWORD OldNtPassword
;
441 ENCRYPTED_NT_OWF_PASSWORD NewNtPassword
;
442 ENCRYPTED_LM_OWF_PASSWORD OldLmPassword
;
443 ENCRYPTED_LM_OWF_PASSWORD NewLmPassword
;
444 OEM_STRING LmPwdString
;
445 CHAR LmPwdBuffer
[15];
446 BOOLEAN OldLmPasswordPresent
= FALSE
;
447 BOOLEAN NewLmPasswordPresent
= FALSE
;
449 ENCRYPTED_LM_OWF_PASSWORD OldLmEncryptedWithNewLm
;
450 ENCRYPTED_LM_OWF_PASSWORD NewLmEncryptedWithOldLm
;
451 ENCRYPTED_LM_OWF_PASSWORD OldNtEncryptedWithNewNt
;
452 ENCRYPTED_LM_OWF_PASSWORD NewNtEncryptedWithOldNt
;
453 PENCRYPTED_LM_OWF_PASSWORD pOldLmEncryptedWithNewLm
= NULL
;
454 PENCRYPTED_LM_OWF_PASSWORD pNewLmEncryptedWithOldLm
= NULL
;
458 RequestBuffer
= (PMSV1_0_CHANGEPASSWORD_REQUEST
)ProtocolSubmitBuffer
;
460 /* Fix-up pointers in the request buffer info */
461 PtrOffset
= (ULONG_PTR
)ProtocolSubmitBuffer
- (ULONG_PTR
)ClientBufferBase
;
463 RequestBuffer
->DomainName
.Buffer
= FIXUP_POINTER(RequestBuffer
->DomainName
.Buffer
, PtrOffset
);
464 RequestBuffer
->AccountName
.Buffer
= FIXUP_POINTER(RequestBuffer
->AccountName
.Buffer
, PtrOffset
);
465 RequestBuffer
->OldPassword
.Buffer
= FIXUP_POINTER(RequestBuffer
->OldPassword
.Buffer
, PtrOffset
);
466 RequestBuffer
->NewPassword
.Buffer
= FIXUP_POINTER(RequestBuffer
->NewPassword
.Buffer
, PtrOffset
);
468 TRACE("Domain: %S\n", RequestBuffer
->DomainName
.Buffer
);
469 TRACE("Account: %S\n", RequestBuffer
->AccountName
.Buffer
);
470 TRACE("Old Password: %S\n", RequestBuffer
->OldPassword
.Buffer
);
471 TRACE("New Password: %S\n", RequestBuffer
->NewPassword
.Buffer
);
473 /* Connect to the SAM server */
474 Status
= SamIConnect(NULL
,
476 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
478 if (!NT_SUCCESS(Status
))
480 TRACE("SamIConnect() failed (Status 0x%08lx)\n", Status
);
484 /* Get the domain SID */
485 Status
= SamrLookupDomainInSamServer(ServerHandle
,
486 (PRPC_UNICODE_STRING
)&RequestBuffer
->DomainName
,
488 if (!NT_SUCCESS(Status
))
490 TRACE("SamrLookupDomainInSamServer failed (Status %08lx)\n", Status
);
494 /* Open the domain */
495 Status
= SamrOpenDomain(ServerHandle
,
499 if (!NT_SUCCESS(Status
))
501 TRACE("SamrOpenDomain failed (Status %08lx)\n", Status
);
505 Names
[0].Length
= RequestBuffer
->AccountName
.Length
;
506 Names
[0].MaximumLength
= RequestBuffer
->AccountName
.MaximumLength
;
507 Names
[0].Buffer
= RequestBuffer
->AccountName
.Buffer
;
509 /* Try to get the RID for the user name */
510 Status
= SamrLookupNamesInDomain(DomainHandle
,
515 if (!NT_SUCCESS(Status
))
517 TRACE("SamrLookupNamesInDomain failed (Status %08lx)\n", Status
);
518 Status
= STATUS_NO_SUCH_USER
;
522 /* Fail, if it is not a user account */
523 if (Use
.Element
[0] != SidTypeUser
)
525 TRACE("Account is not a user account!\n");
526 Status
= STATUS_NO_SUCH_USER
;
530 /* Open the user object */
531 Status
= SamrOpenUser(DomainHandle
,
532 USER_CHANGE_PASSWORD
,
533 RelativeIds
.Element
[0],
535 if (!NT_SUCCESS(Status
))
537 TRACE("SamrOpenUser failed (Status %08lx)\n", Status
);
542 /* Calculate the NT hash for the old password */
543 Status
= SystemFunction007(&RequestBuffer
->OldPassword
,
544 (LPBYTE
)&OldNtPassword
);
545 if (!NT_SUCCESS(Status
))
547 TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status
);
551 /* Calculate the NT hash for the new password */
552 Status
= SystemFunction007(&RequestBuffer
->NewPassword
,
553 (LPBYTE
)&NewNtPassword
);
554 if (!NT_SUCCESS(Status
))
556 TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status
);
560 /* Calculate the LM password and hash for the old password */
561 LmPwdString
.Length
= 15;
562 LmPwdString
.MaximumLength
= 15;
563 LmPwdString
.Buffer
= LmPwdBuffer
;
564 ZeroMemory(LmPwdString
.Buffer
, LmPwdString
.MaximumLength
);
566 Status
= RtlUpcaseUnicodeStringToOemString(&LmPwdString
,
567 &RequestBuffer
->OldPassword
,
569 if (NT_SUCCESS(Status
))
571 /* Calculate the LM hash value of the password */
572 Status
= SystemFunction006(LmPwdString
.Buffer
,
573 (LPSTR
)&OldLmPassword
);
574 if (NT_SUCCESS(Status
))
576 OldLmPasswordPresent
= TRUE
;
580 /* Calculate the LM password and hash for the new password */
581 LmPwdString
.Length
= 15;
582 LmPwdString
.MaximumLength
= 15;
583 LmPwdString
.Buffer
= LmPwdBuffer
;
584 ZeroMemory(LmPwdString
.Buffer
, LmPwdString
.MaximumLength
);
586 Status
= RtlUpcaseUnicodeStringToOemString(&LmPwdString
,
587 &RequestBuffer
->NewPassword
,
589 if (NT_SUCCESS(Status
))
591 /* Calculate the LM hash value of the password */
592 Status
= SystemFunction006(LmPwdString
.Buffer
,
593 (LPSTR
)&NewLmPassword
);
594 if (NT_SUCCESS(Status
))
596 NewLmPasswordPresent
= TRUE
;
600 /* Encrypt the old and new LM passwords, if they exist */
601 if (OldLmPasswordPresent
&& NewLmPasswordPresent
)
603 /* Encrypt the old LM password */
604 Status
= SystemFunction012((const BYTE
*)&OldLmPassword
,
605 (const BYTE
*)&NewLmPassword
,
606 (LPBYTE
)&OldLmEncryptedWithNewLm
);
607 if (!NT_SUCCESS(Status
))
609 TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status
);
613 /* Encrypt the new LM password */
614 Status
= SystemFunction012((const BYTE
*)&NewLmPassword
,
615 (const BYTE
*)&OldLmPassword
,
616 (LPBYTE
)&NewLmEncryptedWithOldLm
);
617 if (!NT_SUCCESS(Status
))
619 TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status
);
623 pOldLmEncryptedWithNewLm
= &OldLmEncryptedWithNewLm
;
624 pNewLmEncryptedWithOldLm
= &NewLmEncryptedWithOldLm
;
627 /* Encrypt the old NT password */
628 Status
= SystemFunction012((const BYTE
*)&OldNtPassword
,
629 (const BYTE
*)&NewNtPassword
,
630 (LPBYTE
)&OldNtEncryptedWithNewNt
);
631 if (!NT_SUCCESS(Status
))
633 TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status
);
637 /* Encrypt the new NT password */
638 Status
= SystemFunction012((const BYTE
*)&NewNtPassword
,
639 (const BYTE
*)&OldNtPassword
,
640 (LPBYTE
)&NewNtEncryptedWithOldNt
);
641 if (!NT_SUCCESS(Status
))
643 TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status
);
647 /* Change the password */
648 Status
= SamrChangePasswordUser(UserHandle
,
649 OldLmPasswordPresent
&& NewLmPasswordPresent
,
650 pOldLmEncryptedWithNewLm
,
651 pNewLmEncryptedWithOldLm
,
653 &OldNtEncryptedWithNewNt
,
654 &NewNtEncryptedWithOldNt
,
659 if (!NT_SUCCESS(Status
))
661 TRACE("SamrChangePasswordUser failed (Status %08lx)\n", Status
);
666 if (UserHandle
!= NULL
)
667 SamrCloseHandle(&UserHandle
);
669 SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds
);
670 SamIFree_SAMPR_ULONG_ARRAY(&Use
);
672 if (DomainHandle
!= NULL
)
673 SamrCloseHandle(&DomainHandle
);
675 if (DomainSid
!= NULL
)
676 SamIFreeVoid(DomainSid
);
678 if (ServerHandle
!= NULL
)
679 SamrCloseHandle(&ServerHandle
);
687 MsvpCheckPassword(PUNICODE_STRING UserPassword
,
688 PSAMPR_USER_INFO_BUFFER UserInfo
)
690 ENCRYPTED_NT_OWF_PASSWORD UserNtPassword
;
691 ENCRYPTED_LM_OWF_PASSWORD UserLmPassword
;
692 BOOLEAN UserLmPasswordPresent
= FALSE
;
693 BOOLEAN UserNtPasswordPresent
= FALSE
;
694 OEM_STRING LmPwdString
;
695 CHAR LmPwdBuffer
[15];
698 TRACE("(%p %p)\n", UserPassword
, UserInfo
);
700 /* Calculate the LM password and hash for the users password */
701 LmPwdString
.Length
= 15;
702 LmPwdString
.MaximumLength
= 15;
703 LmPwdString
.Buffer
= LmPwdBuffer
;
704 ZeroMemory(LmPwdString
.Buffer
, LmPwdString
.MaximumLength
);
706 Status
= RtlUpcaseUnicodeStringToOemString(&LmPwdString
,
709 if (NT_SUCCESS(Status
))
711 /* Calculate the LM hash value of the users password */
712 Status
= SystemFunction006(LmPwdString
.Buffer
,
713 (LPSTR
)&UserLmPassword
);
714 if (NT_SUCCESS(Status
))
716 UserLmPasswordPresent
= TRUE
;
720 /* Calculate the NT hash of the users password */
721 Status
= SystemFunction007(UserPassword
,
722 (LPBYTE
)&UserNtPassword
);
723 if (NT_SUCCESS(Status
))
725 UserNtPasswordPresent
= TRUE
;
728 Status
= STATUS_WRONG_PASSWORD
;
730 /* Succeed, if no password has been set */
731 if (UserInfo
->All
.NtPasswordPresent
== FALSE
&&
732 UserInfo
->All
.LmPasswordPresent
== FALSE
)
734 TRACE("No password check!\n");
735 Status
= STATUS_SUCCESS
;
739 /* Succeed, if NT password matches */
740 if (UserNtPasswordPresent
&& UserInfo
->All
.NtPasswordPresent
)
742 TRACE("Check NT password hashes:\n");
743 if (RtlEqualMemory(&UserNtPassword
,
744 UserInfo
->All
.NtOwfPassword
.Buffer
,
745 sizeof(ENCRYPTED_NT_OWF_PASSWORD
)))
747 TRACE(" success!\n");
748 Status
= STATUS_SUCCESS
;
755 /* Succeed, if LM password matches */
756 if (UserLmPasswordPresent
&& UserInfo
->All
.LmPasswordPresent
)
758 TRACE("Check LM password hashes:\n");
759 if (RtlEqualMemory(&UserLmPassword
,
760 UserInfo
->All
.LmOwfPassword
.Buffer
,
761 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
763 TRACE(" success!\n");
764 Status
= STATUS_SUCCESS
;
780 LsaApCallPackage(IN PLSA_CLIENT_REQUEST ClientRequest
,
781 IN PVOID ProtocolSubmitBuffer
,
782 IN PVOID ClientBufferBase
,
783 IN ULONG SubmitBufferLength
,
784 OUT PVOID
*ProtocolReturnBuffer
,
785 OUT PULONG ReturnBufferLength
,
786 OUT PNTSTATUS ProtocolStatus
)
793 if (SubmitBufferLength
< sizeof(MSV1_0_PROTOCOL_MESSAGE_TYPE
))
794 return STATUS_INVALID_PARAMETER
;
796 MessageType
= (ULONG
)*((PMSV1_0_PROTOCOL_MESSAGE_TYPE
)ProtocolSubmitBuffer
);
798 *ProtocolReturnBuffer
= NULL
;
799 *ReturnBufferLength
= 0;
803 case MsV1_0Lm20ChallengeRequest
:
804 case MsV1_0Lm20GetChallengeResponse
:
805 case MsV1_0EnumerateUsers
:
806 case MsV1_0GetUserInfo
:
807 case MsV1_0ReLogonUsers
:
808 Status
= STATUS_NOT_IMPLEMENTED
;
811 case MsV1_0ChangePassword
:
812 Status
= MsvpChangePassword(ClientRequest
,
813 ProtocolSubmitBuffer
,
816 ProtocolReturnBuffer
,
821 case MsV1_0ChangeCachedPassword
:
822 case MsV1_0GenericPassthrough
:
823 case MsV1_0CacheLogon
:
825 case MsV1_0DeriveCredential
:
826 case MsV1_0CacheLookup
:
827 Status
= STATUS_NOT_IMPLEMENTED
;
831 return STATUS_INVALID_PARAMETER
;
843 LsaApCallPackagePassthrough(IN PLSA_CLIENT_REQUEST ClientRequest
,
844 IN PVOID ProtocolSubmitBuffer
,
845 IN PVOID ClientBufferBase
,
846 IN ULONG SubmitBufferLength
,
847 OUT PVOID
*ProtocolReturnBuffer
,
848 OUT PULONG ReturnBufferLength
,
849 OUT PNTSTATUS ProtocolStatus
)
852 return STATUS_NOT_IMPLEMENTED
;
861 LsaApCallPackageUntrusted(IN PLSA_CLIENT_REQUEST ClientRequest
,
862 IN PVOID ProtocolSubmitBuffer
,
863 IN PVOID ClientBufferBase
,
864 IN ULONG SubmitBufferLength
,
865 OUT PVOID
*ProtocolReturnBuffer
,
866 OUT PULONG ReturnBufferLength
,
867 OUT PNTSTATUS ProtocolStatus
)
870 return STATUS_NOT_IMPLEMENTED
;
879 LsaApInitializePackage(IN ULONG AuthenticationPackageId
,
880 IN PLSA_DISPATCH_TABLE LsaDispatchTable
,
881 IN PLSA_STRING Database OPTIONAL
,
882 IN PLSA_STRING Confidentiality OPTIONAL
,
883 OUT PLSA_STRING
*AuthenticationPackageName
)
885 PANSI_STRING NameString
;
888 TRACE("(%lu %p %p %p %p)\n",
889 AuthenticationPackageId
, LsaDispatchTable
, Database
,
890 Confidentiality
, AuthenticationPackageName
);
892 /* Get the dispatch table entries */
893 DispatchTable
.CreateLogonSession
= LsaDispatchTable
->CreateLogonSession
;
894 DispatchTable
.DeleteLogonSession
= LsaDispatchTable
->DeleteLogonSession
;
895 DispatchTable
.AddCredential
= LsaDispatchTable
->AddCredential
;
896 DispatchTable
.GetCredentials
= LsaDispatchTable
->GetCredentials
;
897 DispatchTable
.DeleteCredential
= LsaDispatchTable
->DeleteCredential
;
898 DispatchTable
.AllocateLsaHeap
= LsaDispatchTable
->AllocateLsaHeap
;
899 DispatchTable
.FreeLsaHeap
= LsaDispatchTable
->FreeLsaHeap
;
900 DispatchTable
.AllocateClientBuffer
= LsaDispatchTable
->AllocateClientBuffer
;
901 DispatchTable
.FreeClientBuffer
= LsaDispatchTable
->FreeClientBuffer
;
902 DispatchTable
.CopyToClientBuffer
= LsaDispatchTable
->CopyToClientBuffer
;
903 DispatchTable
.CopyFromClientBuffer
= LsaDispatchTable
->CopyFromClientBuffer
;
905 /* Return the package name */
906 NameString
= DispatchTable
.AllocateLsaHeap(sizeof(LSA_STRING
));
907 if (NameString
== NULL
)
908 return STATUS_INSUFFICIENT_RESOURCES
;
910 NameBuffer
= DispatchTable
.AllocateLsaHeap(sizeof(MSV1_0_PACKAGE_NAME
));
911 if (NameBuffer
== NULL
)
913 DispatchTable
.FreeLsaHeap(NameString
);
914 return STATUS_INSUFFICIENT_RESOURCES
;
917 strcpy(NameBuffer
, MSV1_0_PACKAGE_NAME
);
919 RtlInitAnsiString(NameString
, NameBuffer
);
921 *AuthenticationPackageName
= (PLSA_STRING
)NameString
;
923 return STATUS_SUCCESS
;
932 LsaApLogonTerminated(IN PLUID LogonId
)
943 LsaApLogonUser(IN PLSA_CLIENT_REQUEST ClientRequest
,
944 IN SECURITY_LOGON_TYPE LogonType
,
945 IN PVOID AuthenticationInformation
,
946 IN PVOID ClientAuthenticationBase
,
947 IN ULONG AuthenticationInformationLength
,
948 OUT PVOID
*ProfileBuffer
,
949 OUT PULONG ProfileBufferLength
,
951 OUT PNTSTATUS SubStatus
,
952 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType
,
953 OUT PVOID
*TokenInformation
,
954 OUT PLSA_UNICODE_STRING
*AccountName
,
955 OUT PLSA_UNICODE_STRING
*AuthenticatingAuthority
)
957 PMSV1_0_INTERACTIVE_LOGON LogonInfo
;
959 SAMPR_HANDLE ServerHandle
= NULL
;
960 SAMPR_HANDLE DomainHandle
= NULL
;
961 SAMPR_HANDLE UserHandle
= NULL
;
962 PRPC_SID AccountDomainSid
= NULL
;
963 RPC_UNICODE_STRING Names
[1];
964 SAMPR_ULONG_ARRAY RelativeIds
= {0, NULL
};
965 SAMPR_ULONG_ARRAY Use
= {0, NULL
};
966 PSAMPR_USER_INFO_BUFFER UserInfo
= NULL
;
967 UNICODE_STRING LogonServer
;
968 BOOLEAN SessionCreated
= FALSE
;
973 TRACE("LogonType: %lu\n", LogonType
);
974 TRACE("AuthenticationInformation: %p\n", AuthenticationInformation
);
975 TRACE("AuthenticationInformationLength: %lu\n", AuthenticationInformationLength
);
977 *ProfileBuffer
= NULL
;
978 *ProfileBufferLength
= 0;
979 *SubStatus
= STATUS_SUCCESS
;
981 if (LogonType
== Interactive
||
982 LogonType
== Batch
||
983 LogonType
== Service
)
987 LogonInfo
= (PMSV1_0_INTERACTIVE_LOGON
)AuthenticationInformation
;
989 /* Fix-up pointers in the authentication info */
990 PtrOffset
= (ULONG_PTR
)AuthenticationInformation
- (ULONG_PTR
)ClientAuthenticationBase
;
992 LogonInfo
->LogonDomainName
.Buffer
= FIXUP_POINTER(LogonInfo
->LogonDomainName
.Buffer
, PtrOffset
);
993 LogonInfo
->UserName
.Buffer
= FIXUP_POINTER(LogonInfo
->UserName
.Buffer
, PtrOffset
);
994 LogonInfo
->Password
.Buffer
= FIXUP_POINTER(LogonInfo
->Password
.Buffer
, PtrOffset
);
996 TRACE("Domain: %S\n", LogonInfo
->LogonDomainName
.Buffer
);
997 TRACE("User: %S\n", LogonInfo
->UserName
.Buffer
);
998 TRACE("Password: %S\n", LogonInfo
->Password
.Buffer
);
1000 RtlInitUnicodeString(&LogonServer
, L
"Testserver");
1004 FIXME("LogonType %lu is not supported yet!\n", LogonType
);
1005 return STATUS_NOT_IMPLEMENTED
;
1008 Status
= GetDomainSid(&AccountDomainSid
);
1009 if (!NT_SUCCESS(Status
))
1011 TRACE("GetDomainSid() failed (Status 0x%08lx)\n", Status
);
1015 /* Connect to the SAM server */
1016 Status
= SamIConnect(NULL
,
1018 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
1020 if (!NT_SUCCESS(Status
))
1022 TRACE("SamIConnect() failed (Status 0x%08lx)\n", Status
);
1026 /* Open the account domain */
1027 Status
= SamrOpenDomain(ServerHandle
,
1031 if (!NT_SUCCESS(Status
))
1033 TRACE("SamrOpenDomain failed (Status %08lx)\n", Status
);
1037 Names
[0].Length
= LogonInfo
->UserName
.Length
;
1038 Names
[0].MaximumLength
= LogonInfo
->UserName
.MaximumLength
;
1039 Names
[0].Buffer
= LogonInfo
->UserName
.Buffer
;
1041 /* Try to get the RID for the user name */
1042 Status
= SamrLookupNamesInDomain(DomainHandle
,
1047 if (!NT_SUCCESS(Status
))
1049 TRACE("SamrLookupNamesInDomain failed (Status %08lx)\n", Status
);
1050 Status
= STATUS_NO_SUCH_USER
;
1054 /* Fail, if it is not a user account */
1055 if (Use
.Element
[0] != SidTypeUser
)
1057 TRACE("Account is not a user account!\n");
1058 Status
= STATUS_NO_SUCH_USER
;
1062 /* Open the user object */
1063 Status
= SamrOpenUser(DomainHandle
,
1064 USER_READ_GENERAL
| USER_READ_LOGON
|
1065 USER_READ_ACCOUNT
| USER_READ_PREFERENCES
, /* FIXME */
1066 RelativeIds
.Element
[0],
1068 if (!NT_SUCCESS(Status
))
1070 TRACE("SamrOpenUser failed (Status %08lx)\n", Status
);
1074 Status
= SamrQueryInformationUser(UserHandle
,
1077 if (!NT_SUCCESS(Status
))
1079 TRACE("SamrQueryInformationUser failed (Status %08lx)\n", Status
);
1084 TRACE("UserName: %S\n", UserInfo
->All
.UserName
.Buffer
);
1086 /* Check account restrictions for non-administrator accounts */
1087 if (RelativeIds
.Element
[0] != DOMAIN_USER_RID_ADMIN
)
1089 /* Check if the account has been disabled */
1090 if (UserInfo
->All
.UserAccountControl
& USER_ACCOUNT_DISABLED
)
1092 ERR("Account disabled!\n");
1093 *SubStatus
= STATUS_ACCOUNT_DISABLED
;
1094 Status
= STATUS_ACCOUNT_RESTRICTION
;
1098 /* Check if the account has been locked */
1099 if (UserInfo
->All
.UserAccountControl
& USER_ACCOUNT_AUTO_LOCKED
)
1101 ERR("Account disabled!\n");
1102 *SubStatus
= STATUS_ACCOUNT_LOCKED_OUT
;
1103 Status
= STATUS_ACCOUNT_RESTRICTION
;
1107 /* FIXME: more checks */
1108 // *SubStatus = STATUS_PASSWORD_EXPIRED;
1109 // *SubStatus = STATUS_INVALID_LOGON_HOURS;
1110 // *SubStatus = STATUS_INVALID_WORKSTATION;
1114 /* Check the password */
1115 if ((UserInfo
->All
.UserAccountControl
& USER_PASSWORD_NOT_REQUIRED
) == 0)
1117 Status
= MsvpCheckPassword(&(LogonInfo
->Password
),
1119 if (!NT_SUCCESS(Status
))
1121 TRACE("MsvpCheckPassword failed (Status %08lx)\n", Status
);
1126 /* Return logon information */
1128 /* Create and return a new logon id */
1129 Status
= NtAllocateLocallyUniqueId(LogonId
);
1130 if (!NT_SUCCESS(Status
))
1132 TRACE("NtAllocateLocallyUniqueId failed (Status %08lx)\n", Status
);
1136 /* Create the logon session */
1137 Status
= DispatchTable
.CreateLogonSession(LogonId
);
1138 if (!NT_SUCCESS(Status
))
1140 TRACE("CreateLogonSession failed (Status %08lx)\n", Status
);
1144 SessionCreated
= TRUE
;
1146 /* Build and fill the interactve profile buffer */
1147 Status
= BuildInteractiveProfileBuffer(ClientRequest
,
1150 (PMSV1_0_INTERACTIVE_PROFILE
*)ProfileBuffer
,
1151 ProfileBufferLength
);
1152 if (!NT_SUCCESS(Status
))
1154 TRACE("BuildInteractiveProfileBuffer failed (Status %08lx)\n", Status
);
1158 /* Return the token information type */
1159 *TokenInformationType
= LsaTokenInformationV1
;
1161 /* Build and fill the token information buffer */
1162 Status
= BuildTokenInformationBuffer((PLSA_TOKEN_INFORMATION_V1
*)TokenInformation
,
1165 if (!NT_SUCCESS(Status
))
1167 TRACE("BuildTokenInformationBuffer failed (Status %08lx)\n", Status
);
1172 /* Return the account name */
1173 *AccountName
= DispatchTable
.AllocateLsaHeap(sizeof(UNICODE_STRING
));
1174 if (*AccountName
!= NULL
)
1176 (*AccountName
)->Buffer
= DispatchTable
.AllocateLsaHeap(LogonInfo
->UserName
.Length
+
1177 sizeof(UNICODE_NULL
));
1178 if ((*AccountName
)->Buffer
!= NULL
)
1180 (*AccountName
)->MaximumLength
= LogonInfo
->UserName
.Length
+
1181 sizeof(UNICODE_NULL
);
1182 RtlCopyUnicodeString(*AccountName
, &LogonInfo
->UserName
);
1186 if (!NT_SUCCESS(Status
))
1188 if (SessionCreated
== TRUE
)
1189 DispatchTable
.DeleteLogonSession(LogonId
);
1191 if (*ProfileBuffer
!= NULL
)
1193 DispatchTable
.FreeClientBuffer(ClientRequest
,
1195 *ProfileBuffer
= NULL
;
1199 if (UserHandle
!= NULL
)
1200 SamrCloseHandle(&UserHandle
);
1202 SamIFree_SAMPR_USER_INFO_BUFFER(UserInfo
,
1203 UserAllInformation
);
1204 SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds
);
1205 SamIFree_SAMPR_ULONG_ARRAY(&Use
);
1207 if (DomainHandle
!= NULL
)
1208 SamrCloseHandle(&DomainHandle
);
1210 if (ServerHandle
!= NULL
)
1211 SamrCloseHandle(&ServerHandle
);
1213 if (AccountDomainSid
!= NULL
)
1214 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid
);
1216 if (Status
== STATUS_NO_SUCH_USER
||
1217 Status
== STATUS_WRONG_PASSWORD
)
1219 *SubStatus
= Status
;
1220 Status
= STATUS_LOGON_FAILURE
;
1223 TRACE("LsaApLogonUser done (Status %08lx)\n", Status
);
1235 LsaApLogonUserEx(IN PLSA_CLIENT_REQUEST ClientRequest
,
1236 IN SECURITY_LOGON_TYPE LogonType
,
1237 IN PVOID AuthenticationInformation
,
1238 IN PVOID ClientAuthenticationBase
,
1239 IN ULONG AuthenticationInformationLength
,
1240 OUT PVOID
*ProfileBuffer
,
1241 OUT PULONG ProfileBufferLength
,
1243 OUT PNTSTATUS SubStatus
,
1244 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType
,
1245 OUT PVOID
*TokenInformation
,
1246 OUT PUNICODE_STRING
*AccountName
,
1247 OUT PUNICODE_STRING
*AuthenticatingAuthority
,
1248 OUT PUNICODE_STRING
*MachineName
)
1252 TRACE("LogonType: %lu\n", LogonType
);
1253 TRACE("AuthenticationInformation: %p\n", AuthenticationInformation
);
1254 TRACE("AuthenticationInformationLength: %lu\n", AuthenticationInformationLength
);
1256 return STATUS_NOT_IMPLEMENTED
;
1265 LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest
,
1266 IN SECURITY_LOGON_TYPE LogonType
,
1267 IN PVOID ProtocolSubmitBuffer
,
1268 IN PVOID ClientBufferBase
,
1269 IN ULONG SubmitBufferSize
,
1270 OUT PVOID
*ProfileBuffer
,
1271 OUT PULONG ProfileBufferSize
,
1273 OUT PNTSTATUS SubStatus
,
1274 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType
,
1275 OUT PVOID
*TokenInformation
,
1276 OUT PUNICODE_STRING
*AccountName
,
1277 OUT PUNICODE_STRING
*AuthenticatingAuthority
,
1278 OUT PUNICODE_STRING
*MachineName
,
1279 OUT PSECPKG_PRIMARY_CRED PrimaryCredentials
,
1280 OUT PSECPKG_SUPPLEMENTAL_CRED_ARRAY
*SupplementalCredentials
)
1284 TRACE("LogonType: %lu\n", LogonType
);
1285 TRACE("ProtocolSubmitBuffer: %p\n", ProtocolSubmitBuffer
);
1286 TRACE("SubmitBufferSize: %lu\n", SubmitBufferSize
);
1289 return STATUS_NOT_IMPLEMENTED
;