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 GetAccountDomainSid(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 GetNtAuthorityDomainSid(PRPC_SID
*Sid
)
76 SID_IDENTIFIER_AUTHORITY NtAuthority
= {SECURITY_NT_AUTHORITY
};
79 Length
= RtlLengthRequiredSid(0);
80 *Sid
= RtlAllocateHeap(RtlGetProcessHeap(), 0, Length
);
83 ERR("Failed to allocate SID\n");
84 return STATUS_INSUFFICIENT_RESOURCES
;
87 RtlInitializeSid(*Sid
,&NtAuthority
, 0);
89 return STATUS_SUCCESS
;
95 BuildInteractiveProfileBuffer(IN PLSA_CLIENT_REQUEST ClientRequest
,
96 IN PSAMPR_USER_INFO_BUFFER UserInfo
,
97 IN PWSTR ComputerName
,
98 OUT PMSV1_0_INTERACTIVE_PROFILE
*ProfileBuffer
,
99 OUT PULONG ProfileBufferLength
)
101 PMSV1_0_INTERACTIVE_PROFILE LocalBuffer
= NULL
;
102 PVOID ClientBaseAddress
= NULL
;
105 NTSTATUS Status
= STATUS_SUCCESS
;
107 *ProfileBuffer
= NULL
;
108 *ProfileBufferLength
= 0;
110 BufferLength
= sizeof(MSV1_0_INTERACTIVE_PROFILE
) +
111 UserInfo
->All
.FullName
.Length
+ sizeof(WCHAR
) +
112 UserInfo
->All
.HomeDirectory
.Length
+ sizeof(WCHAR
) +
113 UserInfo
->All
.HomeDirectoryDrive
.Length
+ sizeof(WCHAR
) +
114 UserInfo
->All
.ScriptPath
.Length
+ sizeof(WCHAR
) +
115 UserInfo
->All
.ProfilePath
.Length
+ sizeof(WCHAR
) +
116 ((wcslen(ComputerName
) + 3) * sizeof(WCHAR
));
118 LocalBuffer
= DispatchTable
.AllocateLsaHeap(BufferLength
);
119 if (LocalBuffer
== NULL
)
121 TRACE("Failed to allocate the local buffer!\n");
122 Status
= STATUS_INSUFFICIENT_RESOURCES
;
126 Status
= DispatchTable
.AllocateClientBuffer(ClientRequest
,
129 if (!NT_SUCCESS(Status
))
131 TRACE("DispatchTable.AllocateClientBuffer failed (Status 0x%08lx)\n", Status
);
135 TRACE("ClientBaseAddress: %p\n", ClientBaseAddress
);
137 Ptr
= (LPWSTR
)((ULONG_PTR
)LocalBuffer
+ sizeof(MSV1_0_INTERACTIVE_PROFILE
));
139 LocalBuffer
->MessageType
= MsV1_0InteractiveProfile
;
140 LocalBuffer
->LogonCount
= UserInfo
->All
.LogonCount
;
141 LocalBuffer
->BadPasswordCount
= UserInfo
->All
.BadPasswordCount
;
143 LocalBuffer
->LogonTime
.LowPart
= UserInfo
->All
.LastLogon
.LowPart
;
144 LocalBuffer
->LogonTime
.HighPart
= UserInfo
->All
.LastLogon
.HighPart
;
146 LocalBuffer
->LogoffTime
.LowPart
= UserInfo
->All
.AccountExpires
.LowPart
;
147 LocalBuffer
->LogoffTime
.HighPart
= UserInfo
->All
.AccountExpires
.HighPart
;
149 LocalBuffer
->KickOffTime
.LowPart
= UserInfo
->All
.AccountExpires
.LowPart
;
150 LocalBuffer
->KickOffTime
.HighPart
= UserInfo
->All
.AccountExpires
.HighPart
;
152 LocalBuffer
->PasswordLastSet
.LowPart
= UserInfo
->All
.PasswordLastSet
.LowPart
;
153 LocalBuffer
->PasswordLastSet
.HighPart
= UserInfo
->All
.PasswordLastSet
.HighPart
;
155 LocalBuffer
->PasswordCanChange
.LowPart
= UserInfo
->All
.PasswordCanChange
.LowPart
;
156 LocalBuffer
->PasswordCanChange
.HighPart
= UserInfo
->All
.PasswordCanChange
.HighPart
;
158 LocalBuffer
->PasswordMustChange
.LowPart
= UserInfo
->All
.PasswordMustChange
.LowPart
;
159 LocalBuffer
->PasswordMustChange
.HighPart
= UserInfo
->All
.PasswordMustChange
.HighPart
;
161 LocalBuffer
->LogonScript
.Length
= UserInfo
->All
.ScriptPath
.Length
;
162 LocalBuffer
->LogonScript
.MaximumLength
= UserInfo
->All
.ScriptPath
.Length
+ sizeof(WCHAR
);
163 LocalBuffer
->LogonScript
.Buffer
= (LPWSTR
)((ULONG_PTR
)ClientBaseAddress
+ (ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalBuffer
);
165 UserInfo
->All
.ScriptPath
.Buffer
,
166 UserInfo
->All
.ScriptPath
.Length
);
168 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ LocalBuffer
->LogonScript
.MaximumLength
);
170 LocalBuffer
->HomeDirectory
.Length
= UserInfo
->All
.HomeDirectory
.Length
;
171 LocalBuffer
->HomeDirectory
.MaximumLength
= UserInfo
->All
.HomeDirectory
.Length
+ sizeof(WCHAR
);
172 LocalBuffer
->HomeDirectory
.Buffer
= (LPWSTR
)((ULONG_PTR
)ClientBaseAddress
+ (ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalBuffer
);
174 UserInfo
->All
.HomeDirectory
.Buffer
,
175 UserInfo
->All
.HomeDirectory
.Length
);
177 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ LocalBuffer
->HomeDirectory
.MaximumLength
);
179 LocalBuffer
->FullName
.Length
= UserInfo
->All
.FullName
.Length
;
180 LocalBuffer
->FullName
.MaximumLength
= UserInfo
->All
.FullName
.Length
+ sizeof(WCHAR
);
181 LocalBuffer
->FullName
.Buffer
= (LPWSTR
)((ULONG_PTR
)ClientBaseAddress
+ (ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalBuffer
);
183 UserInfo
->All
.FullName
.Buffer
,
184 UserInfo
->All
.FullName
.Length
);
185 TRACE("FullName.Buffer: %p\n", LocalBuffer
->FullName
.Buffer
);
187 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ LocalBuffer
->FullName
.MaximumLength
);
189 LocalBuffer
->ProfilePath
.Length
= UserInfo
->All
.ProfilePath
.Length
;
190 LocalBuffer
->ProfilePath
.MaximumLength
= UserInfo
->All
.ProfilePath
.Length
+ sizeof(WCHAR
);
191 LocalBuffer
->ProfilePath
.Buffer
= (LPWSTR
)((ULONG_PTR
)ClientBaseAddress
+ (ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalBuffer
);
193 UserInfo
->All
.ProfilePath
.Buffer
,
194 UserInfo
->All
.ProfilePath
.Length
);
196 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ LocalBuffer
->ProfilePath
.MaximumLength
);
198 LocalBuffer
->HomeDirectoryDrive
.Length
= UserInfo
->All
.HomeDirectoryDrive
.Length
;
199 LocalBuffer
->HomeDirectoryDrive
.MaximumLength
= UserInfo
->All
.HomeDirectoryDrive
.Length
+ sizeof(WCHAR
);
200 LocalBuffer
->HomeDirectoryDrive
.Buffer
= (LPWSTR
)((ULONG_PTR
)ClientBaseAddress
+ (ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalBuffer
);
202 UserInfo
->All
.HomeDirectoryDrive
.Buffer
,
203 UserInfo
->All
.HomeDirectoryDrive
.Length
);
205 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ LocalBuffer
->HomeDirectoryDrive
.MaximumLength
);
207 LocalBuffer
->LogonServer
.Length
= (wcslen(ComputerName
) + 2) * sizeof(WCHAR
);
208 LocalBuffer
->LogonServer
.MaximumLength
= LocalBuffer
->LogonServer
.Length
+ sizeof(WCHAR
);
209 LocalBuffer
->LogonServer
.Buffer
= (LPWSTR
)((ULONG_PTR
)ClientBaseAddress
+ (ULONG_PTR
)Ptr
- (ULONG_PTR
)LocalBuffer
);
211 wcscat(Ptr
, ComputerName
);
213 LocalBuffer
->UserFlags
= 0;
215 Status
= DispatchTable
.CopyToClientBuffer(ClientRequest
,
219 if (!NT_SUCCESS(Status
))
221 TRACE("DispatchTable.CopyToClientBuffer failed (Status 0x%08lx)\n", Status
);
225 *ProfileBuffer
= (PMSV1_0_INTERACTIVE_PROFILE
)ClientBaseAddress
;
226 *ProfileBufferLength
= BufferLength
;
229 if (LocalBuffer
!= NULL
)
230 DispatchTable
.FreeLsaHeap(LocalBuffer
);
232 if (!NT_SUCCESS(Status
))
234 if (ClientBaseAddress
!= NULL
)
235 DispatchTable
.FreeClientBuffer(ClientRequest
,
245 AppendRidToSid(PSID SrcSid
,
251 RidCount
= *RtlSubAuthorityCountSid(SrcSid
);
255 DstSid
= DispatchTable
.AllocateLsaHeap(RtlLengthRequiredSid(RidCount
+ 1));
259 RtlCopyMemory(DstSid
,
261 RtlLengthRequiredSid(RidCount
));
263 *RtlSubAuthorityCountSid(DstSid
) = RidCount
+ 1;
264 *RtlSubAuthoritySid(DstSid
, RidCount
) = Rid
;
272 BuildTokenUser(OUT PTOKEN_USER User
,
273 IN PSID AccountDomainSid
,
276 User
->User
.Sid
= AppendRidToSid(AccountDomainSid
,
278 if (User
->User
.Sid
== NULL
)
280 ERR("Could not create the user SID\n");
281 return STATUS_INSUFFICIENT_RESOURCES
;
284 User
->User
.Attributes
= 0;
286 return STATUS_SUCCESS
;
292 BuildTokenPrimaryGroup(OUT PTOKEN_PRIMARY_GROUP PrimaryGroup
,
293 IN PSID AccountDomainSid
,
296 PrimaryGroup
->PrimaryGroup
= AppendRidToSid(AccountDomainSid
,
298 if (PrimaryGroup
->PrimaryGroup
== NULL
)
300 ERR("Could not create the primary group SID\n");
301 return STATUS_INSUFFICIENT_RESOURCES
;
304 return STATUS_SUCCESS
;
310 BuildTokenGroups(OUT PTOKEN_GROUPS
*Groups
,
311 IN PSID AccountDomainSid
,
313 IN BOOL SpecialAccount
)
315 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
316 PTOKEN_GROUPS TokenGroups
;
317 DWORD GroupCount
= 0;
320 NTSTATUS Status
= STATUS_SUCCESS
;
325 TokenGroups
= DispatchTable
.AllocateLsaHeap(sizeof(TOKEN_GROUPS
) +
326 MaxGroups
* sizeof(SID_AND_ATTRIBUTES
));
327 if (TokenGroups
== NULL
)
329 return STATUS_INSUFFICIENT_RESOURCES
;
335 Sid
= AppendRidToSid(AccountDomainSid
, RelativeId
);
341 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
342 TokenGroups
->Groups
[GroupCount
].Attributes
=
343 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
346 /* Member of 'Users' alias */
347 RtlAllocateAndInitializeSid(&SystemAuthority
,
349 SECURITY_BUILTIN_DOMAIN_RID
,
350 DOMAIN_ALIAS_RID_USERS
,
358 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
359 TokenGroups
->Groups
[GroupCount
].Attributes
=
360 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
365 /* Member of the domains users group */
366 Sid
= AppendRidToSid(AccountDomainSid
, DOMAIN_GROUP_RID_USERS
);
372 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
373 TokenGroups
->Groups
[GroupCount
].Attributes
=
374 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
378 /* Member of 'Authenticated users' */
379 RtlAllocateAndInitializeSid(&SystemAuthority
,
381 SECURITY_AUTHENTICATED_USER_RID
,
390 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
391 TokenGroups
->Groups
[GroupCount
].Attributes
=
392 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
395 TokenGroups
->GroupCount
= GroupCount
;
396 ASSERT(TokenGroups
->GroupCount
<= MaxGroups
);
398 *Groups
= TokenGroups
;
406 BuildTokenInformationBuffer(PLSA_TOKEN_INFORMATION_V1
*TokenInformation
,
407 PRPC_SID AccountDomainSid
,
408 PSAMPR_USER_INFO_BUFFER UserInfo
,
411 PLSA_TOKEN_INFORMATION_V1 Buffer
= NULL
;
413 NTSTATUS Status
= STATUS_SUCCESS
;
415 Buffer
= DispatchTable
.AllocateLsaHeap(sizeof(LSA_TOKEN_INFORMATION_V1
));
418 WARN("Failed to allocate the local buffer!\n");
419 Status
= STATUS_INSUFFICIENT_RESOURCES
;
423 Buffer
->ExpirationTime
.LowPart
= UserInfo
->All
.AccountExpires
.LowPart
;
424 Buffer
->ExpirationTime
.HighPart
= UserInfo
->All
.AccountExpires
.HighPart
;
426 Status
= BuildTokenUser(&Buffer
->User
,
427 (PSID
)AccountDomainSid
,
428 UserInfo
->All
.UserId
);
429 if (!NT_SUCCESS(Status
))
431 WARN("BuildTokenUser() failed (Status 0x%08lx)\n", Status
);
435 Status
= BuildTokenPrimaryGroup(&Buffer
->PrimaryGroup
,
436 (PSID
)AccountDomainSid
,
437 UserInfo
->All
.PrimaryGroupId
);
438 if (!NT_SUCCESS(Status
))
440 WARN("BuildTokenPrimaryGroup() failed (Status 0x%08lx)\n", Status
);
444 Status
= BuildTokenGroups(&Buffer
->Groups
,
445 (PSID
)AccountDomainSid
,
446 UserInfo
->All
.UserId
,
448 if (!NT_SUCCESS(Status
))
450 WARN("BuildTokenGroups() failed (Status 0x%08lx)\n", Status
);
454 *TokenInformation
= Buffer
;
457 if (!NT_SUCCESS(Status
))
461 if (Buffer
->User
.User
.Sid
!= NULL
)
462 DispatchTable
.FreeLsaHeap(Buffer
->User
.User
.Sid
);
464 if (Buffer
->Groups
!= NULL
)
466 for (i
= 0; i
< Buffer
->Groups
->GroupCount
; i
++)
468 if (Buffer
->Groups
->Groups
[i
].Sid
!= NULL
)
469 DispatchTable
.FreeLsaHeap(Buffer
->Groups
->Groups
[i
].Sid
);
472 DispatchTable
.FreeLsaHeap(Buffer
->Groups
);
475 if (Buffer
->PrimaryGroup
.PrimaryGroup
!= NULL
)
476 DispatchTable
.FreeLsaHeap(Buffer
->PrimaryGroup
.PrimaryGroup
);
478 if (Buffer
->DefaultDacl
.DefaultDacl
!= NULL
)
479 DispatchTable
.FreeLsaHeap(Buffer
->DefaultDacl
.DefaultDacl
);
481 DispatchTable
.FreeLsaHeap(Buffer
);
491 MsvpChangePassword(IN PLSA_CLIENT_REQUEST ClientRequest
,
492 IN PVOID ProtocolSubmitBuffer
,
493 IN PVOID ClientBufferBase
,
494 IN ULONG SubmitBufferLength
,
495 OUT PVOID
*ProtocolReturnBuffer
,
496 OUT PULONG ReturnBufferLength
,
497 OUT PNTSTATUS ProtocolStatus
)
499 PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer
;
502 SAMPR_HANDLE ServerHandle
= NULL
;
503 SAMPR_HANDLE DomainHandle
= NULL
;
504 SAMPR_HANDLE UserHandle
= NULL
;
505 PRPC_SID DomainSid
= NULL
;
506 RPC_UNICODE_STRING Names
[1];
507 SAMPR_ULONG_ARRAY RelativeIds
= {0, NULL
};
508 SAMPR_ULONG_ARRAY Use
= {0, NULL
};
511 ENCRYPTED_NT_OWF_PASSWORD OldNtPassword
;
512 ENCRYPTED_NT_OWF_PASSWORD NewNtPassword
;
513 ENCRYPTED_LM_OWF_PASSWORD OldLmPassword
;
514 ENCRYPTED_LM_OWF_PASSWORD NewLmPassword
;
515 OEM_STRING LmPwdString
;
516 CHAR LmPwdBuffer
[15];
517 BOOLEAN OldLmPasswordPresent
= FALSE
;
518 BOOLEAN NewLmPasswordPresent
= FALSE
;
520 ENCRYPTED_LM_OWF_PASSWORD OldLmEncryptedWithNewLm
;
521 ENCRYPTED_LM_OWF_PASSWORD NewLmEncryptedWithOldLm
;
522 ENCRYPTED_LM_OWF_PASSWORD OldNtEncryptedWithNewNt
;
523 ENCRYPTED_LM_OWF_PASSWORD NewNtEncryptedWithOldNt
;
524 PENCRYPTED_LM_OWF_PASSWORD pOldLmEncryptedWithNewLm
= NULL
;
525 PENCRYPTED_LM_OWF_PASSWORD pNewLmEncryptedWithOldLm
= NULL
;
529 RequestBuffer
= (PMSV1_0_CHANGEPASSWORD_REQUEST
)ProtocolSubmitBuffer
;
531 /* Fix-up pointers in the request buffer info */
532 PtrOffset
= (ULONG_PTR
)ProtocolSubmitBuffer
- (ULONG_PTR
)ClientBufferBase
;
534 RequestBuffer
->DomainName
.Buffer
= FIXUP_POINTER(RequestBuffer
->DomainName
.Buffer
, PtrOffset
);
535 RequestBuffer
->AccountName
.Buffer
= FIXUP_POINTER(RequestBuffer
->AccountName
.Buffer
, PtrOffset
);
536 RequestBuffer
->OldPassword
.Buffer
= FIXUP_POINTER(RequestBuffer
->OldPassword
.Buffer
, PtrOffset
);
537 RequestBuffer
->NewPassword
.Buffer
= FIXUP_POINTER(RequestBuffer
->NewPassword
.Buffer
, PtrOffset
);
539 TRACE("Domain: %S\n", RequestBuffer
->DomainName
.Buffer
);
540 TRACE("Account: %S\n", RequestBuffer
->AccountName
.Buffer
);
541 TRACE("Old Password: %S\n", RequestBuffer
->OldPassword
.Buffer
);
542 TRACE("New Password: %S\n", RequestBuffer
->NewPassword
.Buffer
);
544 /* Connect to the SAM server */
545 Status
= SamIConnect(NULL
,
547 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
549 if (!NT_SUCCESS(Status
))
551 TRACE("SamIConnect() failed (Status 0x%08lx)\n", Status
);
555 /* Get the domain SID */
556 Status
= SamrLookupDomainInSamServer(ServerHandle
,
557 (PRPC_UNICODE_STRING
)&RequestBuffer
->DomainName
,
559 if (!NT_SUCCESS(Status
))
561 TRACE("SamrLookupDomainInSamServer failed (Status %08lx)\n", Status
);
565 /* Open the domain */
566 Status
= SamrOpenDomain(ServerHandle
,
570 if (!NT_SUCCESS(Status
))
572 TRACE("SamrOpenDomain failed (Status %08lx)\n", Status
);
576 Names
[0].Length
= RequestBuffer
->AccountName
.Length
;
577 Names
[0].MaximumLength
= RequestBuffer
->AccountName
.MaximumLength
;
578 Names
[0].Buffer
= RequestBuffer
->AccountName
.Buffer
;
580 /* Try to get the RID for the user name */
581 Status
= SamrLookupNamesInDomain(DomainHandle
,
586 if (!NT_SUCCESS(Status
))
588 TRACE("SamrLookupNamesInDomain failed (Status %08lx)\n", Status
);
589 Status
= STATUS_NO_SUCH_USER
;
593 /* Fail, if it is not a user account */
594 if (Use
.Element
[0] != SidTypeUser
)
596 TRACE("Account is not a user account!\n");
597 Status
= STATUS_NO_SUCH_USER
;
601 /* Open the user object */
602 Status
= SamrOpenUser(DomainHandle
,
603 USER_CHANGE_PASSWORD
,
604 RelativeIds
.Element
[0],
606 if (!NT_SUCCESS(Status
))
608 TRACE("SamrOpenUser failed (Status %08lx)\n", Status
);
613 /* Calculate the NT hash for the old password */
614 Status
= SystemFunction007(&RequestBuffer
->OldPassword
,
615 (LPBYTE
)&OldNtPassword
);
616 if (!NT_SUCCESS(Status
))
618 TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status
);
622 /* Calculate the NT hash for the new password */
623 Status
= SystemFunction007(&RequestBuffer
->NewPassword
,
624 (LPBYTE
)&NewNtPassword
);
625 if (!NT_SUCCESS(Status
))
627 TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status
);
631 /* Calculate the LM password and hash for the old password */
632 LmPwdString
.Length
= 15;
633 LmPwdString
.MaximumLength
= 15;
634 LmPwdString
.Buffer
= LmPwdBuffer
;
635 ZeroMemory(LmPwdString
.Buffer
, LmPwdString
.MaximumLength
);
637 Status
= RtlUpcaseUnicodeStringToOemString(&LmPwdString
,
638 &RequestBuffer
->OldPassword
,
640 if (NT_SUCCESS(Status
))
642 /* Calculate the LM hash value of the password */
643 Status
= SystemFunction006(LmPwdString
.Buffer
,
644 (LPSTR
)&OldLmPassword
);
645 if (NT_SUCCESS(Status
))
647 OldLmPasswordPresent
= TRUE
;
651 /* Calculate the LM password and hash for the new password */
652 LmPwdString
.Length
= 15;
653 LmPwdString
.MaximumLength
= 15;
654 LmPwdString
.Buffer
= LmPwdBuffer
;
655 ZeroMemory(LmPwdString
.Buffer
, LmPwdString
.MaximumLength
);
657 Status
= RtlUpcaseUnicodeStringToOemString(&LmPwdString
,
658 &RequestBuffer
->NewPassword
,
660 if (NT_SUCCESS(Status
))
662 /* Calculate the LM hash value of the password */
663 Status
= SystemFunction006(LmPwdString
.Buffer
,
664 (LPSTR
)&NewLmPassword
);
665 if (NT_SUCCESS(Status
))
667 NewLmPasswordPresent
= TRUE
;
671 /* Encrypt the old and new LM passwords, if they exist */
672 if (OldLmPasswordPresent
&& NewLmPasswordPresent
)
674 /* Encrypt the old LM password */
675 Status
= SystemFunction012((const BYTE
*)&OldLmPassword
,
676 (const BYTE
*)&NewLmPassword
,
677 (LPBYTE
)&OldLmEncryptedWithNewLm
);
678 if (!NT_SUCCESS(Status
))
680 TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status
);
684 /* Encrypt the new LM password */
685 Status
= SystemFunction012((const BYTE
*)&NewLmPassword
,
686 (const BYTE
*)&OldLmPassword
,
687 (LPBYTE
)&NewLmEncryptedWithOldLm
);
688 if (!NT_SUCCESS(Status
))
690 TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status
);
694 pOldLmEncryptedWithNewLm
= &OldLmEncryptedWithNewLm
;
695 pNewLmEncryptedWithOldLm
= &NewLmEncryptedWithOldLm
;
698 /* Encrypt the old NT password */
699 Status
= SystemFunction012((const BYTE
*)&OldNtPassword
,
700 (const BYTE
*)&NewNtPassword
,
701 (LPBYTE
)&OldNtEncryptedWithNewNt
);
702 if (!NT_SUCCESS(Status
))
704 TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status
);
708 /* Encrypt the new NT password */
709 Status
= SystemFunction012((const BYTE
*)&NewNtPassword
,
710 (const BYTE
*)&OldNtPassword
,
711 (LPBYTE
)&NewNtEncryptedWithOldNt
);
712 if (!NT_SUCCESS(Status
))
714 TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status
);
718 /* Change the password */
719 Status
= SamrChangePasswordUser(UserHandle
,
720 OldLmPasswordPresent
&& NewLmPasswordPresent
,
721 pOldLmEncryptedWithNewLm
,
722 pNewLmEncryptedWithOldLm
,
724 &OldNtEncryptedWithNewNt
,
725 &NewNtEncryptedWithOldNt
,
730 if (!NT_SUCCESS(Status
))
732 TRACE("SamrChangePasswordUser failed (Status %08lx)\n", Status
);
737 if (UserHandle
!= NULL
)
738 SamrCloseHandle(&UserHandle
);
740 SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds
);
741 SamIFree_SAMPR_ULONG_ARRAY(&Use
);
743 if (DomainHandle
!= NULL
)
744 SamrCloseHandle(&DomainHandle
);
746 if (DomainSid
!= NULL
)
747 SamIFreeVoid(DomainSid
);
749 if (ServerHandle
!= NULL
)
750 SamrCloseHandle(&ServerHandle
);
758 MsvpCheckPassword(PUNICODE_STRING UserPassword
,
759 PSAMPR_USER_INFO_BUFFER UserInfo
)
761 ENCRYPTED_NT_OWF_PASSWORD UserNtPassword
;
762 ENCRYPTED_LM_OWF_PASSWORD UserLmPassword
;
763 BOOLEAN UserLmPasswordPresent
= FALSE
;
764 BOOLEAN UserNtPasswordPresent
= FALSE
;
765 OEM_STRING LmPwdString
;
766 CHAR LmPwdBuffer
[15];
769 TRACE("(%p %p)\n", UserPassword
, UserInfo
);
771 /* Calculate the LM password and hash for the users password */
772 LmPwdString
.Length
= 15;
773 LmPwdString
.MaximumLength
= 15;
774 LmPwdString
.Buffer
= LmPwdBuffer
;
775 ZeroMemory(LmPwdString
.Buffer
, LmPwdString
.MaximumLength
);
777 Status
= RtlUpcaseUnicodeStringToOemString(&LmPwdString
,
780 if (NT_SUCCESS(Status
))
782 /* Calculate the LM hash value of the users password */
783 Status
= SystemFunction006(LmPwdString
.Buffer
,
784 (LPSTR
)&UserLmPassword
);
785 if (NT_SUCCESS(Status
))
787 UserLmPasswordPresent
= TRUE
;
791 /* Calculate the NT hash of the users password */
792 Status
= SystemFunction007(UserPassword
,
793 (LPBYTE
)&UserNtPassword
);
794 if (NT_SUCCESS(Status
))
796 UserNtPasswordPresent
= TRUE
;
799 Status
= STATUS_WRONG_PASSWORD
;
801 /* Succeed, if no password has been set */
802 if (UserInfo
->All
.NtPasswordPresent
== FALSE
&&
803 UserInfo
->All
.LmPasswordPresent
== FALSE
)
805 TRACE("No password check!\n");
806 Status
= STATUS_SUCCESS
;
810 /* Succeed, if NT password matches */
811 if (UserNtPasswordPresent
&& UserInfo
->All
.NtPasswordPresent
)
813 TRACE("Check NT password hashes:\n");
814 if (RtlEqualMemory(&UserNtPassword
,
815 UserInfo
->All
.NtOwfPassword
.Buffer
,
816 sizeof(ENCRYPTED_NT_OWF_PASSWORD
)))
818 TRACE(" success!\n");
819 Status
= STATUS_SUCCESS
;
826 /* Succeed, if LM password matches */
827 if (UserLmPasswordPresent
&& UserInfo
->All
.LmPasswordPresent
)
829 TRACE("Check LM password hashes:\n");
830 if (RtlEqualMemory(&UserLmPassword
,
831 UserInfo
->All
.LmOwfPassword
.Buffer
,
832 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
834 TRACE(" success!\n");
835 Status
= STATUS_SUCCESS
;
849 _In_ PSAMPR_LOGON_HOURS LogonHours
,
850 _In_ PLARGE_INTEGER LogonTime
)
853 LARGE_INTEGER LocalLogonTime
;
854 TIME_FIELDS TimeFields
;
855 USHORT MinutesPerUnit
, Offset
;
858 FIXME("MsvpCheckLogonHours(%p %p)\n", LogonHours
, LogonTime
);
860 if (LogonHours
->UnitsPerWeek
== 0 || LogonHours
->LogonHours
== NULL
)
862 FIXME("No logon hours!\n");
866 RtlSystemTimeToLocalTime(LogonTime
, &LocalLogonTime
);
867 RtlTimeToTimeFields(&LocalLogonTime
, &TimeFields
);
869 FIXME("UnitsPerWeek: %u\n", LogonHours
->UnitsPerWeek
);
870 MinutesPerUnit
= 10080 / LogonHours
->UnitsPerWeek
;
872 Offset
= ((TimeFields
.Weekday
* 24 + TimeFields
.Hour
) * 60 + TimeFields
.Minute
) / MinutesPerUnit
;
873 FIXME("Offset: %us\n", Offset
);
875 bFound
= (BOOL
)(LogonHours
->LogonHours
[Offset
/ 8] & (1 << (Offset
% 8)));
876 FIXME("Logon permitted: %s\n", bFound
? "Yes" : "No");
886 MsvpCheckWorkstations(
887 _In_ PRPC_UNICODE_STRING WorkStations
,
888 _In_ PWSTR ComputerName
)
893 TRACE("MsvpCheckWorkstations(%p %S)\n", WorkStations
, ComputerName
);
895 if (WorkStations
->Length
== 0 || WorkStations
->Buffer
== NULL
)
897 TRACE("No workstations!\n");
901 TRACE("Workstations: %wZ\n", WorkStations
);
903 pStart
= WorkStations
->Buffer
;
906 pEnd
= wcschr(pStart
, L
',');
908 *pEnd
= UNICODE_NULL
;
910 TRACE("Comparing '%S' and '%S'\n", ComputerName
, pStart
);
911 if (_wcsicmp(ComputerName
, pStart
) == 0)
926 TRACE("Found allowed workstation: %s\n", (bFound
) ? "Yes" : "No");
937 LsaApCallPackage(IN PLSA_CLIENT_REQUEST ClientRequest
,
938 IN PVOID ProtocolSubmitBuffer
,
939 IN PVOID ClientBufferBase
,
940 IN ULONG SubmitBufferLength
,
941 OUT PVOID
*ProtocolReturnBuffer
,
942 OUT PULONG ReturnBufferLength
,
943 OUT PNTSTATUS ProtocolStatus
)
948 TRACE("LsaApCallPackage()\n");
950 if (SubmitBufferLength
< sizeof(MSV1_0_PROTOCOL_MESSAGE_TYPE
))
951 return STATUS_INVALID_PARAMETER
;
953 MessageType
= (ULONG
)*((PMSV1_0_PROTOCOL_MESSAGE_TYPE
)ProtocolSubmitBuffer
);
955 *ProtocolReturnBuffer
= NULL
;
956 *ReturnBufferLength
= 0;
960 case MsV1_0Lm20ChallengeRequest
:
961 case MsV1_0Lm20GetChallengeResponse
:
962 Status
= STATUS_NOT_IMPLEMENTED
;
965 case MsV1_0EnumerateUsers
:
966 case MsV1_0GetUserInfo
:
967 case MsV1_0ReLogonUsers
:
968 Status
= STATUS_INVALID_PARAMETER
;
971 case MsV1_0ChangePassword
:
972 Status
= MsvpChangePassword(ClientRequest
,
973 ProtocolSubmitBuffer
,
976 ProtocolReturnBuffer
,
981 case MsV1_0ChangeCachedPassword
:
982 case MsV1_0GenericPassthrough
:
983 case MsV1_0CacheLogon
:
985 case MsV1_0DeriveCredential
:
986 case MsV1_0CacheLookup
:
987 Status
= STATUS_NOT_IMPLEMENTED
;
991 return STATUS_INVALID_PARAMETER
;
1003 LsaApCallPackagePassthrough(IN PLSA_CLIENT_REQUEST ClientRequest
,
1004 IN PVOID ProtocolSubmitBuffer
,
1005 IN PVOID ClientBufferBase
,
1006 IN ULONG SubmitBufferLength
,
1007 OUT PVOID
*ProtocolReturnBuffer
,
1008 OUT PULONG ReturnBufferLength
,
1009 OUT PNTSTATUS ProtocolStatus
)
1011 TRACE("LsaApCallPackagePassthrough()\n");
1012 return STATUS_NOT_IMPLEMENTED
;
1021 LsaApCallPackageUntrusted(IN PLSA_CLIENT_REQUEST ClientRequest
,
1022 IN PVOID ProtocolSubmitBuffer
,
1023 IN PVOID ClientBufferBase
,
1024 IN ULONG SubmitBufferLength
,
1025 OUT PVOID
*ProtocolReturnBuffer
,
1026 OUT PULONG ReturnBufferLength
,
1027 OUT PNTSTATUS ProtocolStatus
)
1029 TRACE("LsaApCallPackageUntrusted()\n");
1030 return STATUS_NOT_IMPLEMENTED
;
1039 LsaApInitializePackage(IN ULONG AuthenticationPackageId
,
1040 IN PLSA_DISPATCH_TABLE LsaDispatchTable
,
1041 IN PLSA_STRING Database OPTIONAL
,
1042 IN PLSA_STRING Confidentiality OPTIONAL
,
1043 OUT PLSA_STRING
*AuthenticationPackageName
)
1045 PANSI_STRING NameString
;
1048 TRACE("LsaApInitializePackage(%lu %p %p %p %p)\n",
1049 AuthenticationPackageId
, LsaDispatchTable
, Database
,
1050 Confidentiality
, AuthenticationPackageName
);
1052 /* Get the dispatch table entries */
1053 DispatchTable
.CreateLogonSession
= LsaDispatchTable
->CreateLogonSession
;
1054 DispatchTable
.DeleteLogonSession
= LsaDispatchTable
->DeleteLogonSession
;
1055 DispatchTable
.AddCredential
= LsaDispatchTable
->AddCredential
;
1056 DispatchTable
.GetCredentials
= LsaDispatchTable
->GetCredentials
;
1057 DispatchTable
.DeleteCredential
= LsaDispatchTable
->DeleteCredential
;
1058 DispatchTable
.AllocateLsaHeap
= LsaDispatchTable
->AllocateLsaHeap
;
1059 DispatchTable
.FreeLsaHeap
= LsaDispatchTable
->FreeLsaHeap
;
1060 DispatchTable
.AllocateClientBuffer
= LsaDispatchTable
->AllocateClientBuffer
;
1061 DispatchTable
.FreeClientBuffer
= LsaDispatchTable
->FreeClientBuffer
;
1062 DispatchTable
.CopyToClientBuffer
= LsaDispatchTable
->CopyToClientBuffer
;
1063 DispatchTable
.CopyFromClientBuffer
= LsaDispatchTable
->CopyFromClientBuffer
;
1065 /* Return the package name */
1066 NameString
= DispatchTable
.AllocateLsaHeap(sizeof(LSA_STRING
));
1067 if (NameString
== NULL
)
1068 return STATUS_INSUFFICIENT_RESOURCES
;
1070 NameBuffer
= DispatchTable
.AllocateLsaHeap(sizeof(MSV1_0_PACKAGE_NAME
));
1071 if (NameBuffer
== NULL
)
1073 DispatchTable
.FreeLsaHeap(NameString
);
1074 return STATUS_INSUFFICIENT_RESOURCES
;
1077 strcpy(NameBuffer
, MSV1_0_PACKAGE_NAME
);
1079 RtlInitAnsiString(NameString
, NameBuffer
);
1081 *AuthenticationPackageName
= (PLSA_STRING
)NameString
;
1083 return STATUS_SUCCESS
;
1092 LsaApLogonTerminated(IN PLUID LogonId
)
1094 TRACE("LsaApLogonTerminated()\n");
1103 LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest
,
1104 IN SECURITY_LOGON_TYPE LogonType
,
1105 IN PVOID ProtocolSubmitBuffer
,
1106 IN PVOID ClientBufferBase
,
1107 IN ULONG SubmitBufferSize
,
1108 OUT PVOID
*ProfileBuffer
,
1109 OUT PULONG ProfileBufferSize
,
1111 OUT PNTSTATUS SubStatus
,
1112 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType
,
1113 OUT PVOID
*TokenInformation
,
1114 OUT PUNICODE_STRING
*AccountName
,
1115 OUT PUNICODE_STRING
*AuthenticatingAuthority
,
1116 OUT PUNICODE_STRING
*MachineName
,
1117 OUT PSECPKG_PRIMARY_CRED PrimaryCredentials
, /* Not supported yet */
1118 OUT PSECPKG_SUPPLEMENTAL_CRED_ARRAY
*SupplementalCredentials
) /* Not supported yet */
1120 PMSV1_0_INTERACTIVE_LOGON LogonInfo
;
1121 WCHAR ComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
1122 SAMPR_HANDLE ServerHandle
= NULL
;
1123 SAMPR_HANDLE DomainHandle
= NULL
;
1124 SAMPR_HANDLE UserHandle
= NULL
;
1125 PRPC_SID AccountDomainSid
= NULL
;
1126 RPC_UNICODE_STRING Names
[1];
1127 SAMPR_ULONG_ARRAY RelativeIds
= {0, NULL
};
1128 SAMPR_ULONG_ARRAY Use
= {0, NULL
};
1129 PSAMPR_USER_INFO_BUFFER UserInfo
= NULL
;
1130 BOOLEAN SessionCreated
= FALSE
;
1131 LARGE_INTEGER LogonTime
;
1132 LARGE_INTEGER AccountExpires
;
1133 LARGE_INTEGER PasswordMustChange
;
1134 LARGE_INTEGER PasswordLastSet
;
1135 DWORD ComputerNameSize
;
1136 BOOL SpecialAccount
= FALSE
;
1139 TRACE("LsaApLogonUser()\n");
1141 TRACE("LogonType: %lu\n", LogonType
);
1142 TRACE("ProtocolSubmitBuffer: %p\n", ProtocolSubmitBuffer
);
1143 TRACE("SubmitBufferSize: %lu\n", SubmitBufferSize
);
1145 *ProfileBuffer
= NULL
;
1146 *ProfileBufferSize
= 0;
1147 *SubStatus
= STATUS_SUCCESS
;
1148 *AccountName
= NULL
;
1149 *AuthenticatingAuthority
= NULL
;
1151 if (LogonType
== Interactive
||
1152 LogonType
== Batch
||
1153 LogonType
== Service
)
1155 ULONG_PTR PtrOffset
;
1157 LogonInfo
= (PMSV1_0_INTERACTIVE_LOGON
)ProtocolSubmitBuffer
;
1159 /* Fix-up pointers in the authentication info */
1160 PtrOffset
= (ULONG_PTR
)ProtocolSubmitBuffer
- (ULONG_PTR
)ClientBufferBase
;
1162 LogonInfo
->LogonDomainName
.Buffer
= FIXUP_POINTER(LogonInfo
->LogonDomainName
.Buffer
, PtrOffset
);
1163 LogonInfo
->UserName
.Buffer
= FIXUP_POINTER(LogonInfo
->UserName
.Buffer
, PtrOffset
);
1164 LogonInfo
->Password
.Buffer
= FIXUP_POINTER(LogonInfo
->Password
.Buffer
, PtrOffset
);
1166 TRACE("Domain: %S\n", LogonInfo
->LogonDomainName
.Buffer
);
1167 TRACE("User: %S\n", LogonInfo
->UserName
.Buffer
);
1168 TRACE("Password: %S\n", LogonInfo
->Password
.Buffer
);
1172 FIXME("LogonType %lu is not supported yet!\n", LogonType
);
1173 return STATUS_NOT_IMPLEMENTED
;
1176 /* Get the logon time */
1177 NtQuerySystemTime(&LogonTime
);
1179 /* Get the computer name */
1180 ComputerNameSize
= MAX_COMPUTERNAME_LENGTH
+ 1;
1181 GetComputerNameW(ComputerName
, &ComputerNameSize
);
1183 /* Check for special accounts */
1184 if (_wcsicmp(LogonInfo
->LogonDomainName
.Buffer
, L
"NT AUTHORITY") == 0)
1186 SpecialAccount
= TRUE
;
1188 /* Get the authority domain SID */
1189 Status
= GetNtAuthorityDomainSid(&AccountDomainSid
);
1190 if (!NT_SUCCESS(Status
))
1192 ERR("GetNtAuthorityDomainSid() failed (Status 0x%08lx)\n", Status
);
1196 if (_wcsicmp(LogonInfo
->UserName
.Buffer
, L
"LocalService") == 0)
1198 TRACE("SpecialAccount: LocalService\n");
1200 if (LogonType
!= Service
)
1201 return STATUS_LOGON_FAILURE
;
1203 UserInfo
= RtlAllocateHeap(RtlGetProcessHeap(),
1205 sizeof(SAMPR_USER_ALL_INFORMATION
));
1206 if (UserInfo
== NULL
)
1208 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1212 UserInfo
->All
.UserId
= SECURITY_LOCAL_SERVICE_RID
;
1213 UserInfo
->All
.PrimaryGroupId
= SECURITY_LOCAL_SERVICE_RID
;
1215 else if (_wcsicmp(LogonInfo
->UserName
.Buffer
, L
"NetworkService") == 0)
1217 TRACE("SpecialAccount: NetworkService\n");
1219 if (LogonType
!= Service
)
1220 return STATUS_LOGON_FAILURE
;
1222 UserInfo
= RtlAllocateHeap(RtlGetProcessHeap(),
1224 sizeof(SAMPR_USER_ALL_INFORMATION
));
1225 if (UserInfo
== NULL
)
1227 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1231 UserInfo
->All
.UserId
= SECURITY_NETWORK_SERVICE_RID
;
1232 UserInfo
->All
.PrimaryGroupId
= SECURITY_NETWORK_SERVICE_RID
;
1236 Status
= STATUS_NO_SUCH_USER
;
1242 TRACE("NormalAccount\n");
1244 /* Get the account domain SID */
1245 Status
= GetAccountDomainSid(&AccountDomainSid
);
1246 if (!NT_SUCCESS(Status
))
1248 ERR("GetAccountDomainSid() failed (Status 0x%08lx)\n", Status
);
1252 /* Connect to the SAM server */
1253 Status
= SamIConnect(NULL
,
1255 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
1257 if (!NT_SUCCESS(Status
))
1259 TRACE("SamIConnect() failed (Status 0x%08lx)\n", Status
);
1263 /* Open the account domain */
1264 Status
= SamrOpenDomain(ServerHandle
,
1268 if (!NT_SUCCESS(Status
))
1270 ERR("SamrOpenDomain failed (Status %08lx)\n", Status
);
1274 Names
[0].Length
= LogonInfo
->UserName
.Length
;
1275 Names
[0].MaximumLength
= LogonInfo
->UserName
.MaximumLength
;
1276 Names
[0].Buffer
= LogonInfo
->UserName
.Buffer
;
1278 /* Try to get the RID for the user name */
1279 Status
= SamrLookupNamesInDomain(DomainHandle
,
1284 if (!NT_SUCCESS(Status
))
1286 ERR("SamrLookupNamesInDomain failed (Status %08lx)\n", Status
);
1287 Status
= STATUS_NO_SUCH_USER
;
1291 /* Fail, if it is not a user account */
1292 if (Use
.Element
[0] != SidTypeUser
)
1294 ERR("Account is not a user account!\n");
1295 Status
= STATUS_NO_SUCH_USER
;
1299 /* Open the user object */
1300 Status
= SamrOpenUser(DomainHandle
,
1301 USER_READ_GENERAL
| USER_READ_LOGON
|
1302 USER_READ_ACCOUNT
| USER_READ_PREFERENCES
, /* FIXME */
1303 RelativeIds
.Element
[0],
1305 if (!NT_SUCCESS(Status
))
1307 ERR("SamrOpenUser failed (Status %08lx)\n", Status
);
1311 Status
= SamrQueryInformationUser(UserHandle
,
1314 if (!NT_SUCCESS(Status
))
1316 ERR("SamrQueryInformationUser failed (Status %08lx)\n", Status
);
1320 TRACE("UserName: %S\n", UserInfo
->All
.UserName
.Buffer
);
1322 /* Check the password */
1323 if ((UserInfo
->All
.UserAccountControl
& USER_PASSWORD_NOT_REQUIRED
) == 0)
1325 Status
= MsvpCheckPassword(&(LogonInfo
->Password
),
1327 if (!NT_SUCCESS(Status
))
1329 ERR("MsvpCheckPassword failed (Status %08lx)\n", Status
);
1334 /* Check account restrictions for non-administrator accounts */
1335 if (RelativeIds
.Element
[0] != DOMAIN_USER_RID_ADMIN
)
1337 /* Check if the account has been disabled */
1338 if (UserInfo
->All
.UserAccountControl
& USER_ACCOUNT_DISABLED
)
1340 ERR("Account disabled!\n");
1341 *SubStatus
= STATUS_ACCOUNT_DISABLED
;
1342 Status
= STATUS_ACCOUNT_RESTRICTION
;
1346 /* Check if the account has been locked */
1347 if (UserInfo
->All
.UserAccountControl
& USER_ACCOUNT_AUTO_LOCKED
)
1349 ERR("Account locked!\n");
1350 *SubStatus
= STATUS_ACCOUNT_LOCKED_OUT
;
1351 Status
= STATUS_ACCOUNT_RESTRICTION
;
1355 /* Check if the account expired */
1356 AccountExpires
.LowPart
= UserInfo
->All
.AccountExpires
.LowPart
;
1357 AccountExpires
.HighPart
= UserInfo
->All
.AccountExpires
.HighPart
;
1358 if (LogonTime
.QuadPart
>= AccountExpires
.QuadPart
)
1360 ERR("Account expired!\n");
1361 *SubStatus
= STATUS_ACCOUNT_EXPIRED
;
1362 Status
= STATUS_ACCOUNT_RESTRICTION
;
1366 /* Check if the password expired */
1367 PasswordMustChange
.LowPart
= UserInfo
->All
.PasswordMustChange
.LowPart
;
1368 PasswordMustChange
.HighPart
= UserInfo
->All
.PasswordMustChange
.HighPart
;
1369 PasswordLastSet
.LowPart
= UserInfo
->All
.PasswordLastSet
.LowPart
;
1370 PasswordLastSet
.HighPart
= UserInfo
->All
.PasswordLastSet
.HighPart
;
1372 if (LogonTime
.QuadPart
>= PasswordMustChange
.QuadPart
)
1374 ERR("Password expired!\n");
1375 if (PasswordLastSet
.QuadPart
== 0)
1376 *SubStatus
= STATUS_PASSWORD_MUST_CHANGE
;
1378 *SubStatus
= STATUS_PASSWORD_EXPIRED
;
1380 Status
= STATUS_ACCOUNT_RESTRICTION
;
1384 /* Check logon hours */
1385 if (!MsvpCheckLogonHours(&UserInfo
->All
.LogonHours
, &LogonTime
))
1387 ERR("Invalid logon hours!\n");
1388 *SubStatus
= STATUS_INVALID_LOGON_HOURS
;
1389 Status
= STATUS_ACCOUNT_RESTRICTION
;
1393 /* Check workstations */
1394 if (!MsvpCheckWorkstations(&UserInfo
->All
.WorkStations
, ComputerName
))
1396 ERR("Invalid workstation!\n");
1397 *SubStatus
= STATUS_INVALID_WORKSTATION
;
1398 Status
= STATUS_ACCOUNT_RESTRICTION
;
1404 /* Return logon information */
1406 /* Create and return a new logon id */
1407 Status
= NtAllocateLocallyUniqueId(LogonId
);
1408 if (!NT_SUCCESS(Status
))
1410 TRACE("NtAllocateLocallyUniqueId failed (Status %08lx)\n", Status
);
1414 /* Create the logon session */
1415 Status
= DispatchTable
.CreateLogonSession(LogonId
);
1416 if (!NT_SUCCESS(Status
))
1418 TRACE("CreateLogonSession failed (Status %08lx)\n", Status
);
1422 SessionCreated
= TRUE
;
1424 /* Build and fill the interactive profile buffer */
1425 Status
= BuildInteractiveProfileBuffer(ClientRequest
,
1428 (PMSV1_0_INTERACTIVE_PROFILE
*)ProfileBuffer
,
1430 if (!NT_SUCCESS(Status
))
1432 TRACE("BuildInteractiveProfileBuffer failed (Status %08lx)\n", Status
);
1436 /* Return the token information type */
1437 *TokenInformationType
= LsaTokenInformationV1
;
1439 /* Build and fill the token information buffer */
1440 Status
= BuildTokenInformationBuffer((PLSA_TOKEN_INFORMATION_V1
*)TokenInformation
,
1444 if (!NT_SUCCESS(Status
))
1446 TRACE("BuildTokenInformationBuffer failed (Status %08lx)\n", Status
);
1451 /* Update the logon time/count or the bad password time/count */
1452 if ((UserHandle
!= NULL
) &&
1453 (Status
== STATUS_SUCCESS
|| Status
== STATUS_WRONG_PASSWORD
))
1455 SAMPR_USER_INFO_BUFFER InternalInfo
;
1457 RtlZeroMemory(&InternalInfo
, sizeof(InternalInfo
));
1459 if (Status
== STATUS_SUCCESS
)
1460 InternalInfo
.Internal2
.Flags
= USER_LOGON_SUCCESS
;
1462 InternalInfo
.Internal2
.Flags
= USER_LOGON_BAD_PASSWORD
;
1464 SamrSetInformationUser(UserHandle
,
1465 UserInternal2Information
,
1469 /* Return the account name */
1470 *AccountName
= DispatchTable
.AllocateLsaHeap(sizeof(UNICODE_STRING
));
1471 if (*AccountName
!= NULL
)
1473 (*AccountName
)->Buffer
= DispatchTable
.AllocateLsaHeap(LogonInfo
->UserName
.Length
+
1474 sizeof(UNICODE_NULL
));
1475 if ((*AccountName
)->Buffer
!= NULL
)
1477 (*AccountName
)->MaximumLength
= LogonInfo
->UserName
.Length
+
1478 sizeof(UNICODE_NULL
);
1479 RtlCopyUnicodeString(*AccountName
, &LogonInfo
->UserName
);
1483 /* Return the authenticating authority */
1484 *AuthenticatingAuthority
= DispatchTable
.AllocateLsaHeap(sizeof(UNICODE_STRING
));
1485 if (*AuthenticatingAuthority
!= NULL
)
1487 (*AuthenticatingAuthority
)->Buffer
= DispatchTable
.AllocateLsaHeap(LogonInfo
->LogonDomainName
.Length
+
1488 sizeof(UNICODE_NULL
));
1489 if ((*AuthenticatingAuthority
)->Buffer
!= NULL
)
1491 (*AuthenticatingAuthority
)->MaximumLength
= LogonInfo
->LogonDomainName
.Length
+
1492 sizeof(UNICODE_NULL
);
1493 RtlCopyUnicodeString(*AuthenticatingAuthority
, &LogonInfo
->LogonDomainName
);
1497 /* Return the machine name */
1498 *MachineName
= DispatchTable
.AllocateLsaHeap(sizeof(UNICODE_STRING
));
1499 if (*MachineName
!= NULL
)
1501 (*MachineName
)->Buffer
= DispatchTable
.AllocateLsaHeap((ComputerNameSize
+ 1) * sizeof(WCHAR
));
1502 if ((*MachineName
)->Buffer
!= NULL
)
1504 (*MachineName
)->MaximumLength
= (ComputerNameSize
+ 1) * sizeof(WCHAR
);
1505 (*MachineName
)->Length
= ComputerNameSize
* sizeof(WCHAR
);
1506 RtlCopyMemory((*MachineName
)->Buffer
, ComputerName
, (*MachineName
)->MaximumLength
);
1510 if (!NT_SUCCESS(Status
))
1512 if (SessionCreated
!= FALSE
)
1513 DispatchTable
.DeleteLogonSession(LogonId
);
1515 if (*ProfileBuffer
!= NULL
)
1517 DispatchTable
.FreeClientBuffer(ClientRequest
,
1519 *ProfileBuffer
= NULL
;
1523 if (UserHandle
!= NULL
)
1524 SamrCloseHandle(&UserHandle
);
1526 SamIFree_SAMPR_USER_INFO_BUFFER(UserInfo
,
1527 UserAllInformation
);
1528 SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds
);
1529 SamIFree_SAMPR_ULONG_ARRAY(&Use
);
1531 if (DomainHandle
!= NULL
)
1532 SamrCloseHandle(&DomainHandle
);
1534 if (ServerHandle
!= NULL
)
1535 SamrCloseHandle(&ServerHandle
);
1537 if (AccountDomainSid
!= NULL
)
1538 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid
);
1540 if (Status
== STATUS_NO_SUCH_USER
||
1541 Status
== STATUS_WRONG_PASSWORD
)
1543 *SubStatus
= Status
;
1544 Status
= STATUS_LOGON_FAILURE
;
1547 TRACE("LsaApLogonUser done (Status 0x%08lx SubStatus 0x%08lx)\n", Status
, *SubStatus
);
1558 SpLsaModeInitialize(
1559 _In_ ULONG LsaVersion
,
1560 _Out_ PULONG PackageVersion
,
1561 _Out_ PSECPKG_FUNCTION_TABLE
*ppTables
,
1562 _Out_ PULONG pcTables
)
1564 SECPKG_FUNCTION_TABLE Tables
[1];
1566 TRACE("SpLsaModeInitialize(0x%lx %p %p %p)\n",
1567 LsaVersion
, PackageVersion
, ppTables
, pcTables
);
1569 if (LsaVersion
!= SECPKG_INTERFACE_VERSION
)
1570 return STATUS_INVALID_PARAMETER
;
1572 *PackageVersion
= SECPKG_INTERFACE_VERSION
;
1574 RtlZeroMemory(&Tables
, sizeof(Tables
));
1576 Tables
[0].InitializePackage
= LsaApInitializePackage
;
1577 // Tables[0].LogonUser = NULL;
1578 Tables
[0].CallPackage
= (PLSA_AP_CALL_PACKAGE
)LsaApCallPackage
;
1579 Tables
[0].LogonTerminated
= LsaApLogonTerminated
;
1580 Tables
[0].CallPackageUntrusted
= LsaApCallPackageUntrusted
;
1581 Tables
[0].CallPackagePassthrough
= (PLSA_AP_CALL_PACKAGE_PASSTHROUGH
)LsaApCallPackagePassthrough
;
1582 // Tables[0].LogonUserEx = NULL;
1583 Tables
[0].LogonUserEx2
= LsaApLogonUserEx2
;
1584 // Tables[0].Initialize = SpInitialize;
1585 // Tables[0].Shutdown = NULL;
1586 // Tables[0].GetInfo = NULL;
1587 // Tables[0].AcceptCredentials = NULL;
1588 // Tables[0].SpAcquireCredentialsHandle = NULL;
1589 // Tables[0].SpQueryCredentialsAttributes = NULL;
1590 // Tables[0].FreeCredentialsHandle = NULL;
1591 // Tables[0].SaveCredentials = NULL;
1592 // Tables[0].GetCredentials = NULL;
1593 // Tables[0].DeleteCredentials = NULL;
1594 // Tables[0].InitLsaModeContext = NULL;
1595 // Tables[0].AcceptLsaModeContext = NULL;
1596 // Tables[0].DeleteContext = NULL;
1597 // Tables[0].ApplyControlToken = NULL;
1598 // Tables[0].GetUserInfo = NULL;
1599 // Tables[0].GetExtendedInformation = NULL;
1600 // Tables[0].SpQueryContextAttributes = NULL;
1601 // Tables[0].SpAddCredentials = NULL;
1602 // Tables[0].SetExtendedInformation = NULL;
1607 return STATUS_SUCCESS
;
1616 SpUserModeInitialize(
1617 _In_ ULONG LsaVersion
,
1618 _Out_ PULONG PackageVersion
,
1619 _Out_ PSECPKG_USER_FUNCTION_TABLE
*ppTables
,
1620 _Out_ PULONG pcTables
)
1622 SECPKG_USER_FUNCTION_TABLE Tables
[1];
1624 TRACE("SpUserModeInitialize(0x%lx %p %p %p)\n",
1625 LsaVersion
, PackageVersion
, ppTables
, pcTables
);
1627 if (LsaVersion
!= SECPKG_INTERFACE_VERSION
)
1628 return STATUS_INVALID_PARAMETER
;
1630 *PackageVersion
= SECPKG_INTERFACE_VERSION
;
1632 RtlZeroMemory(&Tables
, sizeof(Tables
));
1634 // Tables[0].InstanceInit = SpInstanceInit;
1635 // Tables[0].InitUserModeContext = NULL;
1636 // Tables[0].MakeSignature = NULL;
1637 // Tables[0].VerifySignature = NULL;
1638 // Tables[0].SealMessage = NULL;
1639 // Tables[0].UnsealMessage = NULL;
1640 // Tables[0].GetContextToken = NULL;
1641 // Tables[0].SpQueryContextAttributes = NULL;
1642 // Tables[0].CompleteAuthToken = NULL;
1643 // Tables[0].DeleteUserModeContext = NULL;
1644 // Tables[0].FormatCredentials = NULL;
1645 // Tables[0].MarshallSupplementalCreds = NULL;
1646 // Tables[0].ExportContext = NULL;
1647 // Tables[0].ImportContext = NULL;
1652 return STATUS_SUCCESS
;