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_UNSUCCESSFUL
;
263 User
->User
.Attributes
= 0;
265 return STATUS_SUCCESS
;
271 BuildTokenGroups(IN PSID AccountDomainSid
,
273 OUT PTOKEN_GROUPS
*Groups
,
274 OUT PSID
*PrimaryGroupSid
)
276 SID_IDENTIFIER_AUTHORITY WorldAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
277 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
278 PTOKEN_GROUPS TokenGroups
;
280 DWORD GroupCount
= 0;
282 NTSTATUS Status
= STATUS_SUCCESS
;
284 TokenGroups
= DispatchTable
.AllocateLsaHeap(sizeof(TOKEN_GROUPS
) +
285 MAX_GROUPS
* sizeof(SID_AND_ATTRIBUTES
));
286 if (TokenGroups
== NULL
)
288 return STATUS_INSUFFICIENT_RESOURCES
;
291 Sid
= AppendRidToSid(AccountDomainSid
, DOMAIN_GROUP_RID_USERS
);
297 /* Member of the domain */
298 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
299 TokenGroups
->Groups
[GroupCount
].Attributes
=
300 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
301 *PrimaryGroupSid
= Sid
;
304 /* Member of 'Everyone' */
305 RtlAllocateAndInitializeSid(&WorldAuthority
,
316 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
317 TokenGroups
->Groups
[GroupCount
].Attributes
=
318 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
322 /* Member of 'Administrators' */
323 RtlAllocateAndInitializeSid(&SystemAuthority
,
325 SECURITY_BUILTIN_DOMAIN_RID
,
326 DOMAIN_ALIAS_RID_ADMINS
,
334 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
335 TokenGroups
->Groups
[GroupCount
].Attributes
=
336 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
339 TRACE("Not adding user to Administrators group\n");
342 /* Member of 'Users' */
343 RtlAllocateAndInitializeSid(&SystemAuthority
,
345 SECURITY_BUILTIN_DOMAIN_RID
,
346 DOMAIN_ALIAS_RID_USERS
,
354 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
355 TokenGroups
->Groups
[GroupCount
].Attributes
=
356 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
359 /* Member of 'Interactive users' */
360 RtlAllocateAndInitializeSid(&SystemAuthority
,
362 SECURITY_INTERACTIVE_RID
,
371 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
372 TokenGroups
->Groups
[GroupCount
].Attributes
=
373 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
376 /* Member of 'Authenticated users' */
377 RtlAllocateAndInitializeSid(&SystemAuthority
,
379 SECURITY_AUTHENTICATED_USER_RID
,
388 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
389 TokenGroups
->Groups
[GroupCount
].Attributes
=
390 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
393 TokenGroups
->GroupCount
= GroupCount
;
394 ASSERT(TokenGroups
->GroupCount
<= MAX_GROUPS
);
396 *Groups
= TokenGroups
;
404 BuildTokenPrimaryGroup(PTOKEN_PRIMARY_GROUP PrimaryGroup
,
405 PSID PrimaryGroupSid
)
410 RidCount
= *RtlSubAuthorityCountSid(PrimaryGroupSid
);
411 Size
= RtlLengthRequiredSid(RidCount
);
413 PrimaryGroup
->PrimaryGroup
= DispatchTable
.AllocateLsaHeap(Size
);
414 if (PrimaryGroup
->PrimaryGroup
== NULL
)
416 return STATUS_INSUFFICIENT_RESOURCES
;
419 RtlCopyMemory(PrimaryGroup
->PrimaryGroup
,
423 return STATUS_SUCCESS
;
428 BuildTokenPrivileges(PTOKEN_PRIVILEGES
*TokenPrivileges
)
430 /* FIXME shouldn't use hard-coded list of privileges */
438 { L
"SeMachineAccountPrivilege", 0 },
439 { L
"SeSecurityPrivilege", 0 },
440 { L
"SeTakeOwnershipPrivilege", 0 },
441 { L
"SeLoadDriverPrivilege", 0 },
442 { L
"SeSystemProfilePrivilege", 0 },
443 { L
"SeSystemtimePrivilege", 0 },
444 { L
"SeProfileSingleProcessPrivilege", 0 },
445 { L
"SeIncreaseBasePriorityPrivilege", 0 },
446 { L
"SeCreatePagefilePrivilege", 0 },
447 { L
"SeBackupPrivilege", 0 },
448 { L
"SeRestorePrivilege", 0 },
449 { L
"SeShutdownPrivilege", 0 },
450 { L
"SeDebugPrivilege", 0 },
451 { L
"SeSystemEnvironmentPrivilege", 0 },
452 { L
"SeChangeNotifyPrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
},
453 { L
"SeRemoteShutdownPrivilege", 0 },
454 { L
"SeUndockPrivilege", 0 },
455 { L
"SeEnableDelegationPrivilege", 0 },
456 { L
"SeImpersonatePrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
},
457 { L
"SeCreateGlobalPrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
}
459 PTOKEN_PRIVILEGES Privileges
= NULL
;
461 RPC_UNICODE_STRING PrivilegeName
;
462 LSAPR_HANDLE PolicyHandle
= NULL
;
463 NTSTATUS Status
= STATUS_SUCCESS
;
465 Status
= LsaIOpenPolicyTrusted(&PolicyHandle
);
466 if (!NT_SUCCESS(Status
))
471 /* Allocate and initialize token privileges */
472 Privileges
= DispatchTable
.AllocateLsaHeap(sizeof(TOKEN_PRIVILEGES
) +
473 sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0]) *
474 sizeof(LUID_AND_ATTRIBUTES
));
475 if (Privileges
== NULL
)
477 Status
= STATUS_INSUFFICIENT_RESOURCES
;
481 Privileges
->PrivilegeCount
= 0;
482 for (i
= 0; i
< sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0]); i
++)
484 PrivilegeName
.Length
= wcslen(DefaultPrivs
[i
].PrivName
) * sizeof(WCHAR
);
485 PrivilegeName
.MaximumLength
= PrivilegeName
.Length
+ sizeof(WCHAR
);
486 PrivilegeName
.Buffer
= (LPWSTR
)DefaultPrivs
[i
].PrivName
;
488 Status
= LsarLookupPrivilegeValue(PolicyHandle
,
490 &Privileges
->Privileges
[Privileges
->PrivilegeCount
].Luid
);
491 if (!NT_SUCCESS(Status
))
493 WARN("Can't set privilege %S\n", DefaultPrivs
[i
].PrivName
);
497 Privileges
->Privileges
[Privileges
->PrivilegeCount
].Attributes
= DefaultPrivs
[i
].Attributes
;
498 Privileges
->PrivilegeCount
++;
502 *TokenPrivileges
= Privileges
;
505 if (PolicyHandle
!= NULL
)
506 LsarClose(&PolicyHandle
);
514 BuildTokenInformationBuffer(PLSA_TOKEN_INFORMATION_V1
*TokenInformation
,
515 PRPC_SID AccountDomainSid
,
519 PLSA_TOKEN_INFORMATION_V1 Buffer
= NULL
;
520 PSID PrimaryGroupSid
= NULL
;
522 NTSTATUS Status
= STATUS_SUCCESS
;
524 Buffer
= DispatchTable
.AllocateLsaHeap(sizeof(LSA_TOKEN_INFORMATION_V1
));
527 TRACE("Failed to allocate the local buffer!\n");
528 Status
= STATUS_INSUFFICIENT_RESOURCES
;
533 Buffer
->ExpirationTime
.QuadPart
= -1;
535 Status
= BuildTokenUser(&Buffer
->User
,
536 (PSID
)AccountDomainSid
,
538 if (!NT_SUCCESS(Status
))
541 Status
= BuildTokenGroups((PSID
)AccountDomainSid
,
545 if (!NT_SUCCESS(Status
))
548 Status
= BuildTokenPrimaryGroup(&Buffer
->PrimaryGroup
,
550 if (!NT_SUCCESS(Status
))
553 Status
= BuildTokenPrivileges(&Buffer
->Privileges
);
554 if (!NT_SUCCESS(Status
))
557 *TokenInformation
= Buffer
;
560 if (!NT_SUCCESS(Status
))
564 if (Buffer
->User
.User
.Sid
!= NULL
)
565 DispatchTable
.FreeLsaHeap(Buffer
->User
.User
.Sid
);
567 if (Buffer
->Groups
!= NULL
)
569 for (i
= 0; i
< Buffer
->Groups
->GroupCount
; i
++)
571 if (Buffer
->Groups
->Groups
[i
].Sid
!= NULL
)
572 DispatchTable
.FreeLsaHeap(Buffer
->Groups
->Groups
[i
].Sid
);
575 DispatchTable
.FreeLsaHeap(Buffer
->Groups
);
578 if (Buffer
->PrimaryGroup
.PrimaryGroup
!= NULL
)
579 DispatchTable
.FreeLsaHeap(Buffer
->PrimaryGroup
.PrimaryGroup
);
581 if (Buffer
->Privileges
!= NULL
)
582 DispatchTable
.FreeLsaHeap(Buffer
->Privileges
);
584 if (Buffer
->DefaultDacl
.DefaultDacl
!= NULL
)
585 DispatchTable
.FreeLsaHeap(Buffer
->DefaultDacl
.DefaultDacl
);
587 DispatchTable
.FreeLsaHeap(Buffer
);
597 MsvpChangePassword(IN PLSA_CLIENT_REQUEST ClientRequest
,
598 IN PVOID ProtocolSubmitBuffer
,
599 IN PVOID ClientBufferBase
,
600 IN ULONG SubmitBufferLength
,
601 OUT PVOID
*ProtocolReturnBuffer
,
602 OUT PULONG ReturnBufferLength
,
603 OUT PNTSTATUS ProtocolStatus
)
605 PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer
;
610 RequestBuffer
= (PMSV1_0_CHANGEPASSWORD_REQUEST
)ProtocolSubmitBuffer
;
612 /* Fix-up pointers in the request buffer info */
613 PtrOffset
= (ULONG_PTR
)ProtocolSubmitBuffer
- (ULONG_PTR
)ClientBufferBase
;
615 RequestBuffer
->DomainName
.Buffer
= FIXUP_POINTER(RequestBuffer
->DomainName
.Buffer
, PtrOffset
);
616 RequestBuffer
->AccountName
.Buffer
= FIXUP_POINTER(RequestBuffer
->AccountName
.Buffer
, PtrOffset
);
617 RequestBuffer
->OldPassword
.Buffer
= FIXUP_POINTER(RequestBuffer
->OldPassword
.Buffer
, PtrOffset
);
618 RequestBuffer
->NewPassword
.Buffer
= FIXUP_POINTER(RequestBuffer
->NewPassword
.Buffer
, PtrOffset
);
620 TRACE("Domain: %S\n", RequestBuffer
->DomainName
.Buffer
);
621 TRACE("Account: %S\n", RequestBuffer
->AccountName
.Buffer
);
622 TRACE("Old Password: %S\n", RequestBuffer
->OldPassword
.Buffer
);
623 TRACE("New Password: %S\n", RequestBuffer
->NewPassword
.Buffer
);
626 return STATUS_SUCCESS
;
632 MsvpCheckPassword(PUNICODE_STRING UserPassword
,
633 PSAMPR_USER_INFO_BUFFER UserInfo
)
635 ENCRYPTED_NT_OWF_PASSWORD UserNtPassword
;
636 ENCRYPTED_LM_OWF_PASSWORD UserLmPassword
;
637 BOOLEAN UserLmPasswordPresent
= FALSE
;
638 BOOLEAN UserNtPasswordPresent
= FALSE
;
639 OEM_STRING LmPwdString
;
640 CHAR LmPwdBuffer
[15];
643 TRACE("(%p %p)\n", UserPassword
, UserInfo
);
645 /* Calculate the LM password and hash for the users password */
646 LmPwdString
.Length
= 15;
647 LmPwdString
.MaximumLength
= 15;
648 LmPwdString
.Buffer
= LmPwdBuffer
;
649 ZeroMemory(LmPwdString
.Buffer
, LmPwdString
.MaximumLength
);
651 Status
= RtlUpcaseUnicodeStringToOemString(&LmPwdString
,
654 if (NT_SUCCESS(Status
))
656 /* Calculate the LM hash value of the users password */
657 Status
= SystemFunction006(LmPwdString
.Buffer
,
658 (LPSTR
)&UserLmPassword
);
659 if (NT_SUCCESS(Status
))
661 UserLmPasswordPresent
= TRUE
;
665 /* Calculate the NT hash of the users password */
666 Status
= SystemFunction007(UserPassword
,
667 (LPBYTE
)&UserNtPassword
);
668 if (NT_SUCCESS(Status
))
670 UserNtPasswordPresent
= TRUE
;
673 Status
= STATUS_WRONG_PASSWORD
;
675 /* Succeed, if no password has been set */
676 if (UserInfo
->All
.NtPasswordPresent
== FALSE
&&
677 UserInfo
->All
.LmPasswordPresent
== FALSE
)
679 TRACE("No password check!\n");
680 Status
= STATUS_SUCCESS
;
684 /* Succeed, if NT password matches */
685 if (UserNtPasswordPresent
&& UserInfo
->All
.NtPasswordPresent
)
687 TRACE("Check NT password hashes:\n");
688 if (RtlEqualMemory(&UserNtPassword
,
689 UserInfo
->All
.NtOwfPassword
.Buffer
,
690 sizeof(ENCRYPTED_NT_OWF_PASSWORD
)))
692 TRACE(" success!\n");
693 Status
= STATUS_SUCCESS
;
700 /* Succeed, if LM password matches */
701 if (UserLmPasswordPresent
&& UserInfo
->All
.LmPasswordPresent
)
703 TRACE("Check LM password hashes:\n");
704 if (RtlEqualMemory(&UserLmPassword
,
705 UserInfo
->All
.LmOwfPassword
.Buffer
,
706 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
708 TRACE(" success!\n");
709 Status
= STATUS_SUCCESS
;
725 LsaApCallPackage(IN PLSA_CLIENT_REQUEST ClientRequest
,
726 IN PVOID ProtocolSubmitBuffer
,
727 IN PVOID ClientBufferBase
,
728 IN ULONG SubmitBufferLength
,
729 OUT PVOID
*ProtocolReturnBuffer
,
730 OUT PULONG ReturnBufferLength
,
731 OUT PNTSTATUS ProtocolStatus
)
738 if (SubmitBufferLength
< sizeof(MSV1_0_PROTOCOL_MESSAGE_TYPE
))
739 return STATUS_INVALID_PARAMETER
;
741 MessageType
= (ULONG
)*((PMSV1_0_PROTOCOL_MESSAGE_TYPE
)ProtocolSubmitBuffer
);
743 *ProtocolReturnBuffer
= NULL
;
744 *ReturnBufferLength
= 0;
748 case MsV1_0Lm20ChallengeRequest
:
749 case MsV1_0Lm20GetChallengeResponse
:
750 case MsV1_0EnumerateUsers
:
751 case MsV1_0GetUserInfo
:
752 case MsV1_0ReLogonUsers
:
753 Status
= STATUS_NOT_IMPLEMENTED
;
756 case MsV1_0ChangePassword
:
757 Status
= MsvpChangePassword(ClientRequest
,
758 ProtocolSubmitBuffer
,
761 ProtocolReturnBuffer
,
766 case MsV1_0ChangeCachedPassword
:
767 case MsV1_0GenericPassthrough
:
768 case MsV1_0CacheLogon
:
770 case MsV1_0DeriveCredential
:
771 case MsV1_0CacheLookup
:
772 Status
= STATUS_NOT_IMPLEMENTED
;
776 return STATUS_INVALID_PARAMETER
;
788 LsaApCallPackagePassthrough(IN PLSA_CLIENT_REQUEST ClientRequest
,
789 IN PVOID ProtocolSubmitBuffer
,
790 IN PVOID ClientBufferBase
,
791 IN ULONG SubmitBufferLength
,
792 OUT PVOID
*ProtocolReturnBuffer
,
793 OUT PULONG ReturnBufferLength
,
794 OUT PNTSTATUS ProtocolStatus
)
797 return STATUS_NOT_IMPLEMENTED
;
806 LsaApCallPackageUntrusted(IN PLSA_CLIENT_REQUEST ClientRequest
,
807 IN PVOID ProtocolSubmitBuffer
,
808 IN PVOID ClientBufferBase
,
809 IN ULONG SubmitBufferLength
,
810 OUT PVOID
*ProtocolReturnBuffer
,
811 OUT PULONG ReturnBufferLength
,
812 OUT PNTSTATUS ProtocolStatus
)
815 return STATUS_NOT_IMPLEMENTED
;
824 LsaApInitializePackage(IN ULONG AuthenticationPackageId
,
825 IN PLSA_DISPATCH_TABLE LsaDispatchTable
,
826 IN PLSA_STRING Database OPTIONAL
,
827 IN PLSA_STRING Confidentiality OPTIONAL
,
828 OUT PLSA_STRING
*AuthenticationPackageName
)
830 PANSI_STRING NameString
;
833 TRACE("(%lu %p %p %p %p)\n",
834 AuthenticationPackageId
, LsaDispatchTable
, Database
,
835 Confidentiality
, AuthenticationPackageName
);
837 /* Get the dispatch table entries */
838 DispatchTable
.CreateLogonSession
= LsaDispatchTable
->CreateLogonSession
;
839 DispatchTable
.DeleteLogonSession
= LsaDispatchTable
->DeleteLogonSession
;
840 DispatchTable
.AddCredential
= LsaDispatchTable
->AddCredential
;
841 DispatchTable
.GetCredentials
= LsaDispatchTable
->GetCredentials
;
842 DispatchTable
.DeleteCredential
= LsaDispatchTable
->DeleteCredential
;
843 DispatchTable
.AllocateLsaHeap
= LsaDispatchTable
->AllocateLsaHeap
;
844 DispatchTable
.FreeLsaHeap
= LsaDispatchTable
->FreeLsaHeap
;
845 DispatchTable
.AllocateClientBuffer
= LsaDispatchTable
->AllocateClientBuffer
;
846 DispatchTable
.FreeClientBuffer
= LsaDispatchTable
->FreeClientBuffer
;
847 DispatchTable
.CopyToClientBuffer
= LsaDispatchTable
->CopyToClientBuffer
;
848 DispatchTable
.CopyFromClientBuffer
= LsaDispatchTable
->CopyFromClientBuffer
;
850 /* Return the package name */
851 NameString
= DispatchTable
.AllocateLsaHeap(sizeof(LSA_STRING
));
852 if (NameString
== NULL
)
853 return STATUS_INSUFFICIENT_RESOURCES
;
855 NameBuffer
= DispatchTable
.AllocateLsaHeap(sizeof(MSV1_0_PACKAGE_NAME
));
856 if (NameBuffer
== NULL
)
858 DispatchTable
.FreeLsaHeap(NameString
);
859 return STATUS_INSUFFICIENT_RESOURCES
;
862 strcpy(NameBuffer
, MSV1_0_PACKAGE_NAME
);
864 RtlInitAnsiString(NameString
, NameBuffer
);
866 *AuthenticationPackageName
= (PLSA_STRING
)NameString
;
868 return STATUS_SUCCESS
;
877 LsaApLogonTerminated(IN PLUID LogonId
)
888 LsaApLogonUser(IN PLSA_CLIENT_REQUEST ClientRequest
,
889 IN SECURITY_LOGON_TYPE LogonType
,
890 IN PVOID AuthenticationInformation
,
891 IN PVOID ClientAuthenticationBase
,
892 IN ULONG AuthenticationInformationLength
,
893 OUT PVOID
*ProfileBuffer
,
894 OUT PULONG ProfileBufferLength
,
896 OUT PNTSTATUS SubStatus
,
897 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType
,
898 OUT PVOID
*TokenInformation
,
899 OUT PLSA_UNICODE_STRING
*AccountName
,
900 OUT PLSA_UNICODE_STRING
*AuthenticatingAuthority
)
902 PMSV1_0_INTERACTIVE_LOGON LogonInfo
;
904 SAMPR_HANDLE ServerHandle
= NULL
;
905 SAMPR_HANDLE DomainHandle
= NULL
;
906 SAMPR_HANDLE UserHandle
= NULL
;
907 PRPC_SID AccountDomainSid
= NULL
;
908 RPC_UNICODE_STRING Names
[1];
909 SAMPR_ULONG_ARRAY RelativeIds
= {0, NULL
};
910 SAMPR_ULONG_ARRAY Use
= {0, NULL
};
911 PSAMPR_USER_INFO_BUFFER UserInfo
= NULL
;
912 UNICODE_STRING LogonServer
;
913 BOOLEAN SessionCreated
= FALSE
;
918 TRACE("LogonType: %lu\n", LogonType
);
919 TRACE("AuthenticationInformation: %p\n", AuthenticationInformation
);
920 TRACE("AuthenticationInformationLength: %lu\n", AuthenticationInformationLength
);
922 *ProfileBuffer
= NULL
;
923 *ProfileBufferLength
= 0;
924 *SubStatus
= STATUS_SUCCESS
;
926 if (LogonType
== Interactive
||
927 LogonType
== Batch
||
928 LogonType
== Service
)
932 LogonInfo
= (PMSV1_0_INTERACTIVE_LOGON
)AuthenticationInformation
;
934 /* Fix-up pointers in the authentication info */
935 PtrOffset
= (ULONG_PTR
)AuthenticationInformation
- (ULONG_PTR
)ClientAuthenticationBase
;
937 LogonInfo
->LogonDomainName
.Buffer
= FIXUP_POINTER(LogonInfo
->LogonDomainName
.Buffer
, PtrOffset
);
938 LogonInfo
->UserName
.Buffer
= FIXUP_POINTER(LogonInfo
->UserName
.Buffer
, PtrOffset
);
939 LogonInfo
->Password
.Buffer
= FIXUP_POINTER(LogonInfo
->Password
.Buffer
, PtrOffset
);
941 TRACE("Domain: %S\n", LogonInfo
->LogonDomainName
.Buffer
);
942 TRACE("User: %S\n", LogonInfo
->UserName
.Buffer
);
943 TRACE("Password: %S\n", LogonInfo
->Password
.Buffer
);
945 RtlInitUnicodeString(&LogonServer
, L
"Testserver");
949 FIXME("LogonType %lu is not supported yet!\n", LogonType
);
950 return STATUS_NOT_IMPLEMENTED
;
953 Status
= GetDomainSid(&AccountDomainSid
);
954 if (!NT_SUCCESS(Status
))
956 TRACE("GetDomainSid() failed (Status 0x%08lx)\n", Status
);
960 /* Connect to the SAM server */
961 Status
= SamIConnect(NULL
,
963 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
965 if (!NT_SUCCESS(Status
))
967 TRACE("SamIConnect() failed (Status 0x%08lx)\n", Status
);
971 /* Open the account domain */
972 Status
= SamrOpenDomain(ServerHandle
,
976 if (!NT_SUCCESS(Status
))
978 TRACE("SamrOpenDomain failed (Status %08lx)\n", Status
);
982 Names
[0].Length
= LogonInfo
->UserName
.Length
;
983 Names
[0].MaximumLength
= LogonInfo
->UserName
.MaximumLength
;
984 Names
[0].Buffer
= LogonInfo
->UserName
.Buffer
;
986 /* Try to get the RID for the user name */
987 Status
= SamrLookupNamesInDomain(DomainHandle
,
992 if (!NT_SUCCESS(Status
))
994 TRACE("SamrLookupNamesInDomain failed (Status %08lx)\n", Status
);
995 Status
= STATUS_NO_SUCH_USER
;
999 /* Fail, if it is not a user account */
1000 if (Use
.Element
[0] != SidTypeUser
)
1002 TRACE("Account is not a user account!\n");
1003 Status
= STATUS_NO_SUCH_USER
;
1007 /* Open the user object */
1008 Status
= SamrOpenUser(DomainHandle
,
1009 USER_READ_GENERAL
| USER_READ_LOGON
|
1010 USER_READ_ACCOUNT
| USER_READ_PREFERENCES
, /* FIXME */
1011 RelativeIds
.Element
[0],
1013 if (!NT_SUCCESS(Status
))
1015 TRACE("SamrOpenUser failed (Status %08lx)\n", Status
);
1019 Status
= SamrQueryInformationUser(UserHandle
,
1022 if (!NT_SUCCESS(Status
))
1024 TRACE("SamrQueryInformationUser failed (Status %08lx)\n", Status
);
1029 TRACE("UserName: %S\n", UserInfo
->All
.UserName
.Buffer
);
1031 /* FIXME: Check restrictions */
1033 /* Check the password */
1034 if ((UserInfo
->All
.UserAccountControl
& USER_PASSWORD_NOT_REQUIRED
) == 0)
1036 Status
= MsvpCheckPassword(&(LogonInfo
->Password
),
1038 if (!NT_SUCCESS(Status
))
1040 TRACE("MsvpCheckPassword failed (Status %08lx)\n", Status
);
1045 /* Return logon information */
1047 /* Create and return a new logon id */
1048 Status
= NtAllocateLocallyUniqueId(LogonId
);
1049 if (!NT_SUCCESS(Status
))
1051 TRACE("NtAllocateLocallyUniqueId failed (Status %08lx)\n", Status
);
1055 /* Create the logon session */
1056 Status
= DispatchTable
.CreateLogonSession(LogonId
);
1057 if (!NT_SUCCESS(Status
))
1059 TRACE("CreateLogonSession failed (Status %08lx)\n", Status
);
1063 SessionCreated
= TRUE
;
1065 /* Build and fill the interactve profile buffer */
1066 Status
= BuildInteractiveProfileBuffer(ClientRequest
,
1069 (PMSV1_0_INTERACTIVE_PROFILE
*)ProfileBuffer
,
1070 ProfileBufferLength
);
1071 if (!NT_SUCCESS(Status
))
1073 TRACE("BuildInteractiveProfileBuffer failed (Status %08lx)\n", Status
);
1077 /* Return the token information type */
1078 *TokenInformationType
= LsaTokenInformationV1
;
1080 /* Build and fill the token information buffer */
1081 Status
= BuildTokenInformationBuffer((PLSA_TOKEN_INFORMATION_V1
*)TokenInformation
,
1083 RelativeIds
.Element
[0],
1085 if (!NT_SUCCESS(Status
))
1087 TRACE("BuildTokenInformationBuffer failed (Status %08lx)\n", Status
);
1092 /* Return the account name */
1093 *AccountName
= DispatchTable
.AllocateLsaHeap(sizeof(UNICODE_STRING
));
1094 if (*AccountName
!= NULL
)
1096 (*AccountName
)->Buffer
= DispatchTable
.AllocateLsaHeap(LogonInfo
->UserName
.Length
+
1097 sizeof(UNICODE_NULL
));
1098 if ((*AccountName
)->Buffer
!= NULL
)
1100 (*AccountName
)->MaximumLength
= LogonInfo
->UserName
.Length
+
1101 sizeof(UNICODE_NULL
);
1102 RtlCopyUnicodeString(*AccountName
, &LogonInfo
->UserName
);
1106 if (!NT_SUCCESS(Status
))
1108 if (SessionCreated
== TRUE
)
1109 DispatchTable
.DeleteLogonSession(LogonId
);
1111 if (*ProfileBuffer
!= NULL
)
1113 DispatchTable
.FreeClientBuffer(ClientRequest
,
1115 *ProfileBuffer
= NULL
;
1119 if (UserHandle
!= NULL
)
1120 SamrCloseHandle(&UserHandle
);
1122 SamIFree_SAMPR_USER_INFO_BUFFER(UserInfo
,
1123 UserAllInformation
);
1124 SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds
);
1125 SamIFree_SAMPR_ULONG_ARRAY(&Use
);
1127 if (DomainHandle
!= NULL
)
1128 SamrCloseHandle(&DomainHandle
);
1130 if (ServerHandle
!= NULL
)
1131 SamrCloseHandle(&ServerHandle
);
1133 if (AccountDomainSid
!= NULL
)
1134 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid
);
1136 if (Status
== STATUS_NO_SUCH_USER
||
1137 Status
== STATUS_WRONG_PASSWORD
)
1139 *SubStatus
= Status
;
1140 Status
= STATUS_LOGON_FAILURE
;
1143 TRACE("LsaApLogonUser done (Status %08lx)\n", Status
);
1155 LsaApLogonUserEx(IN PLSA_CLIENT_REQUEST ClientRequest
,
1156 IN SECURITY_LOGON_TYPE LogonType
,
1157 IN PVOID AuthenticationInformation
,
1158 IN PVOID ClientAuthenticationBase
,
1159 IN ULONG AuthenticationInformationLength
,
1160 OUT PVOID
*ProfileBuffer
,
1161 OUT PULONG ProfileBufferLength
,
1163 OUT PNTSTATUS SubStatus
,
1164 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType
,
1165 OUT PVOID
*TokenInformation
,
1166 OUT PUNICODE_STRING
*AccountName
,
1167 OUT PUNICODE_STRING
*AuthenticatingAuthority
,
1168 OUT PUNICODE_STRING
*MachineName
)
1172 TRACE("LogonType: %lu\n", LogonType
);
1173 TRACE("AuthenticationInformation: %p\n", AuthenticationInformation
);
1174 TRACE("AuthenticationInformationLength: %lu\n", AuthenticationInformationLength
);
1176 return STATUS_NOT_IMPLEMENTED
;
1185 LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest
,
1186 IN SECURITY_LOGON_TYPE LogonType
,
1187 IN PVOID ProtocolSubmitBuffer
,
1188 IN PVOID ClientBufferBase
,
1189 IN ULONG SubmitBufferSize
,
1190 OUT PVOID
*ProfileBuffer
,
1191 OUT PULONG ProfileBufferSize
,
1193 OUT PNTSTATUS SubStatus
,
1194 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType
,
1195 OUT PVOID
*TokenInformation
,
1196 OUT PUNICODE_STRING
*AccountName
,
1197 OUT PUNICODE_STRING
*AuthenticatingAuthority
,
1198 OUT PUNICODE_STRING
*MachineName
,
1199 OUT PSECPKG_PRIMARY_CRED PrimaryCredentials
,
1200 OUT PSECPKG_SUPPLEMENTAL_CRED_ARRAY
*SupplementalCredentials
)
1204 TRACE("LogonType: %lu\n", LogonType
);
1205 TRACE("ProtocolSubmitBuffer: %p\n", ProtocolSubmitBuffer
);
1206 TRACE("SubmitBufferSize: %lu\n", SubmitBufferSize
);
1209 return STATUS_NOT_IMPLEMENTED
;