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
,
277 SID_IDENTIFIER_AUTHORITY WorldAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
278 SID_IDENTIFIER_AUTHORITY LocalAuthority
= {SECURITY_LOCAL_SID_AUTHORITY
};
279 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
280 PTOKEN_GROUPS TokenGroups
;
282 DWORD GroupCount
= 0;
284 NTSTATUS Status
= STATUS_SUCCESS
;
286 TokenGroups
= DispatchTable
.AllocateLsaHeap(sizeof(TOKEN_GROUPS
) +
287 MAX_GROUPS
* sizeof(SID_AND_ATTRIBUTES
));
288 if (TokenGroups
== NULL
)
290 return STATUS_INSUFFICIENT_RESOURCES
;
293 Sid
= AppendRidToSid(AccountDomainSid
, DOMAIN_GROUP_RID_USERS
);
299 /* Member of the domain */
300 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
301 TokenGroups
->Groups
[GroupCount
].Attributes
=
302 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
303 *PrimaryGroupSid
= Sid
;
306 /* Member of 'Everyone' */
307 RtlAllocateAndInitializeSid(&WorldAuthority
,
318 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
319 TokenGroups
->Groups
[GroupCount
].Attributes
=
320 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
324 /* Member of 'Administrators' */
325 RtlAllocateAndInitializeSid(&SystemAuthority
,
327 SECURITY_BUILTIN_DOMAIN_RID
,
328 DOMAIN_ALIAS_RID_ADMINS
,
336 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
337 TokenGroups
->Groups
[GroupCount
].Attributes
=
338 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
341 TRACE("Not adding user to Administrators group\n");
344 /* Member of 'Users' */
345 RtlAllocateAndInitializeSid(&SystemAuthority
,
347 SECURITY_BUILTIN_DOMAIN_RID
,
348 DOMAIN_ALIAS_RID_USERS
,
356 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
357 TokenGroups
->Groups
[GroupCount
].Attributes
=
358 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
362 RtlAllocateAndInitializeSid(&SystemAuthority
,
363 SECURITY_LOGON_IDS_RID_COUNT
,
364 SECURITY_LOGON_IDS_RID
,
373 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
374 TokenGroups
->Groups
[GroupCount
].Attributes
=
375 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
| SE_GROUP_LOGON_ID
;
379 /* Member of 'Local users */
380 RtlAllocateAndInitializeSid(&LocalAuthority
,
391 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
392 TokenGroups
->Groups
[GroupCount
].Attributes
=
393 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
396 /* Member of 'Interactive users' */
397 RtlAllocateAndInitializeSid(&SystemAuthority
,
399 SECURITY_INTERACTIVE_RID
,
408 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
409 TokenGroups
->Groups
[GroupCount
].Attributes
=
410 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
413 /* Member of 'Authenticated users' */
414 RtlAllocateAndInitializeSid(&SystemAuthority
,
416 SECURITY_AUTHENTICATED_USER_RID
,
425 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
426 TokenGroups
->Groups
[GroupCount
].Attributes
=
427 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
430 TokenGroups
->GroupCount
= GroupCount
;
431 ASSERT(TokenGroups
->GroupCount
<= MAX_GROUPS
);
433 *Groups
= TokenGroups
;
441 BuildTokenPrimaryGroup(PTOKEN_PRIMARY_GROUP PrimaryGroup
,
442 PSID PrimaryGroupSid
)
447 RidCount
= *RtlSubAuthorityCountSid(PrimaryGroupSid
);
448 Size
= RtlLengthRequiredSid(RidCount
);
450 PrimaryGroup
->PrimaryGroup
= DispatchTable
.AllocateLsaHeap(Size
);
451 if (PrimaryGroup
->PrimaryGroup
== NULL
)
453 return STATUS_INSUFFICIENT_RESOURCES
;
456 RtlCopyMemory(PrimaryGroup
->PrimaryGroup
,
460 return STATUS_SUCCESS
;
465 BuildTokenPrivileges(PTOKEN_PRIVILEGES
*TokenPrivileges
)
467 /* FIXME shouldn't use hard-coded list of privileges */
475 { L
"SeMachineAccountPrivilege", 0 },
476 { L
"SeSecurityPrivilege", 0 },
477 { L
"SeTakeOwnershipPrivilege", 0 },
478 { L
"SeLoadDriverPrivilege", 0 },
479 { L
"SeSystemProfilePrivilege", 0 },
480 { L
"SeSystemtimePrivilege", 0 },
481 { L
"SeProfileSingleProcessPrivilege", 0 },
482 { L
"SeIncreaseBasePriorityPrivilege", 0 },
483 { L
"SeCreatePagefilePrivilege", 0 },
484 { L
"SeBackupPrivilege", 0 },
485 { L
"SeRestorePrivilege", 0 },
486 { L
"SeShutdownPrivilege", 0 },
487 { L
"SeDebugPrivilege", 0 },
488 { L
"SeSystemEnvironmentPrivilege", 0 },
489 { L
"SeChangeNotifyPrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
},
490 { L
"SeRemoteShutdownPrivilege", 0 },
491 { L
"SeUndockPrivilege", 0 },
492 { L
"SeEnableDelegationPrivilege", 0 },
493 { L
"SeImpersonatePrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
},
494 { L
"SeCreateGlobalPrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
}
496 PTOKEN_PRIVILEGES Privileges
= NULL
;
498 RPC_UNICODE_STRING PrivilegeName
;
499 LSAPR_HANDLE PolicyHandle
= NULL
;
500 NTSTATUS Status
= STATUS_SUCCESS
;
502 Status
= LsaIOpenPolicyTrusted(&PolicyHandle
);
503 if (!NT_SUCCESS(Status
))
508 /* Allocate and initialize token privileges */
509 Privileges
= DispatchTable
.AllocateLsaHeap(sizeof(TOKEN_PRIVILEGES
) +
510 sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0]) *
511 sizeof(LUID_AND_ATTRIBUTES
));
512 if (Privileges
== NULL
)
514 Status
= STATUS_INSUFFICIENT_RESOURCES
;
518 Privileges
->PrivilegeCount
= 0;
519 for (i
= 0; i
< sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0]); i
++)
521 PrivilegeName
.Length
= wcslen(DefaultPrivs
[i
].PrivName
) * sizeof(WCHAR
);
522 PrivilegeName
.MaximumLength
= PrivilegeName
.Length
+ sizeof(WCHAR
);
523 PrivilegeName
.Buffer
= (LPWSTR
)DefaultPrivs
[i
].PrivName
;
525 Status
= LsarLookupPrivilegeValue(PolicyHandle
,
527 &Privileges
->Privileges
[Privileges
->PrivilegeCount
].Luid
);
528 if (!NT_SUCCESS(Status
))
530 WARN("Can't set privilege %S\n", DefaultPrivs
[i
].PrivName
);
534 Privileges
->Privileges
[Privileges
->PrivilegeCount
].Attributes
= DefaultPrivs
[i
].Attributes
;
535 Privileges
->PrivilegeCount
++;
539 *TokenPrivileges
= Privileges
;
542 if (PolicyHandle
!= NULL
)
543 LsarClose(&PolicyHandle
);
551 BuildTokenOwner(PTOKEN_OWNER Owner
,
557 RidCount
= *RtlSubAuthorityCountSid(OwnerSid
);
558 Size
= RtlLengthRequiredSid(RidCount
);
560 Owner
->Owner
= DispatchTable
.AllocateLsaHeap(Size
);
561 if (Owner
->Owner
== NULL
)
563 return STATUS_INSUFFICIENT_RESOURCES
;
566 RtlCopyMemory(Owner
->Owner
,
570 return STATUS_SUCCESS
;
576 BuildTokenInformationBuffer(PLSA_TOKEN_INFORMATION_V1
*TokenInformation
,
577 PRPC_SID AccountDomainSid
,
581 PLSA_TOKEN_INFORMATION_V1 Buffer
= NULL
;
582 PSID OwnerSid
= NULL
;
583 PSID PrimaryGroupSid
= NULL
;
585 NTSTATUS Status
= STATUS_SUCCESS
;
587 Buffer
= DispatchTable
.AllocateLsaHeap(sizeof(LSA_TOKEN_INFORMATION_V1
));
590 TRACE("Failed to allocate the local buffer!\n");
591 Status
= STATUS_INSUFFICIENT_RESOURCES
;
596 Buffer
->ExpirationTime
.QuadPart
= -1;
598 Status
= BuildTokenUser(&Buffer
->User
,
599 (PSID
)AccountDomainSid
,
601 if (!NT_SUCCESS(Status
))
604 Status
= BuildTokenGroups((PSID
)AccountDomainSid
,
609 if (!NT_SUCCESS(Status
))
612 Status
= BuildTokenPrimaryGroup(&Buffer
->PrimaryGroup
,
614 if (!NT_SUCCESS(Status
))
617 Status
= BuildTokenPrivileges(&Buffer
->Privileges
);
618 if (!NT_SUCCESS(Status
))
621 Status
= BuildTokenOwner(&Buffer
->Owner
,
623 if (!NT_SUCCESS(Status
))
626 *TokenInformation
= Buffer
;
629 if (!NT_SUCCESS(Status
))
633 if (Buffer
->User
.User
.Sid
!= NULL
)
634 DispatchTable
.FreeLsaHeap(Buffer
->User
.User
.Sid
);
636 if (Buffer
->Groups
!= NULL
)
638 for (i
= 0; i
< Buffer
->Groups
->GroupCount
; i
++)
640 if (Buffer
->Groups
->Groups
[i
].Sid
!= NULL
)
641 DispatchTable
.FreeLsaHeap(Buffer
->Groups
->Groups
[i
].Sid
);
644 DispatchTable
.FreeLsaHeap(Buffer
->Groups
);
647 if (Buffer
->PrimaryGroup
.PrimaryGroup
!= NULL
)
648 DispatchTable
.FreeLsaHeap(Buffer
->PrimaryGroup
.PrimaryGroup
);
650 if (Buffer
->Privileges
!= NULL
)
651 DispatchTable
.FreeLsaHeap(Buffer
->Privileges
);
653 if (Buffer
->Owner
.Owner
!= NULL
)
654 DispatchTable
.FreeLsaHeap(Buffer
->Owner
.Owner
);
656 if (Buffer
->DefaultDacl
.DefaultDacl
!= NULL
)
657 DispatchTable
.FreeLsaHeap(Buffer
->DefaultDacl
.DefaultDacl
);
659 DispatchTable
.FreeLsaHeap(Buffer
);
669 MsvpChangePassword(IN PLSA_CLIENT_REQUEST ClientRequest
,
670 IN PVOID ProtocolSubmitBuffer
,
671 IN PVOID ClientBufferBase
,
672 IN ULONG SubmitBufferLength
,
673 OUT PVOID
*ProtocolReturnBuffer
,
674 OUT PULONG ReturnBufferLength
,
675 OUT PNTSTATUS ProtocolStatus
)
677 PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer
;
682 RequestBuffer
= (PMSV1_0_CHANGEPASSWORD_REQUEST
)ProtocolSubmitBuffer
;
684 /* Fix-up pointers in the request buffer info */
685 PtrOffset
= (ULONG_PTR
)ProtocolSubmitBuffer
- (ULONG_PTR
)ClientBufferBase
;
687 RequestBuffer
->DomainName
.Buffer
= FIXUP_POINTER(RequestBuffer
->DomainName
.Buffer
, PtrOffset
);
688 RequestBuffer
->AccountName
.Buffer
= FIXUP_POINTER(RequestBuffer
->AccountName
.Buffer
, PtrOffset
);
689 RequestBuffer
->OldPassword
.Buffer
= FIXUP_POINTER(RequestBuffer
->OldPassword
.Buffer
, PtrOffset
);
690 RequestBuffer
->NewPassword
.Buffer
= FIXUP_POINTER(RequestBuffer
->NewPassword
.Buffer
, PtrOffset
);
692 TRACE("Domain: %S\n", RequestBuffer
->DomainName
.Buffer
);
693 TRACE("Account: %S\n", RequestBuffer
->AccountName
.Buffer
);
694 TRACE("Old Password: %S\n", RequestBuffer
->OldPassword
.Buffer
);
695 TRACE("New Password: %S\n", RequestBuffer
->NewPassword
.Buffer
);
698 return STATUS_SUCCESS
;
704 MsvpCheckPassword(PUNICODE_STRING UserPassword
,
705 PSAMPR_USER_INFO_BUFFER UserInfo
)
707 ENCRYPTED_NT_OWF_PASSWORD UserNtPassword
;
708 ENCRYPTED_LM_OWF_PASSWORD UserLmPassword
;
709 BOOLEAN UserLmPasswordPresent
= FALSE
;
710 BOOLEAN UserNtPasswordPresent
= FALSE
;
711 OEM_STRING LmPwdString
;
712 CHAR LmPwdBuffer
[15];
715 TRACE("(%p %p)\n", UserPassword
, UserInfo
);
717 /* Calculate the LM password and hash for the users password */
718 LmPwdString
.Length
= 15;
719 LmPwdString
.MaximumLength
= 15;
720 LmPwdString
.Buffer
= LmPwdBuffer
;
721 ZeroMemory(LmPwdString
.Buffer
, LmPwdString
.MaximumLength
);
723 Status
= RtlUpcaseUnicodeStringToOemString(&LmPwdString
,
726 if (NT_SUCCESS(Status
))
728 /* Calculate the LM hash value of the users password */
729 Status
= SystemFunction006(LmPwdString
.Buffer
,
730 (LPSTR
)&UserLmPassword
);
731 if (NT_SUCCESS(Status
))
733 UserLmPasswordPresent
= TRUE
;
737 /* Calculate the NT hash of the users password */
738 Status
= SystemFunction007(UserPassword
,
739 (LPBYTE
)&UserNtPassword
);
740 if (NT_SUCCESS(Status
))
742 UserNtPasswordPresent
= TRUE
;
745 Status
= STATUS_WRONG_PASSWORD
;
747 /* Succeed, if no password has been set */
748 if (UserInfo
->All
.NtPasswordPresent
== FALSE
&&
749 UserInfo
->All
.LmPasswordPresent
== FALSE
)
751 TRACE("No password check!\n");
752 Status
= STATUS_SUCCESS
;
756 /* Succeed, if NT password matches */
757 if (UserNtPasswordPresent
&& UserInfo
->All
.NtPasswordPresent
)
759 TRACE("Check NT password hashes:\n");
760 if (RtlEqualMemory(&UserNtPassword
,
761 UserInfo
->All
.NtOwfPassword
.Buffer
,
762 sizeof(ENCRYPTED_NT_OWF_PASSWORD
)))
764 TRACE(" success!\n");
765 Status
= STATUS_SUCCESS
;
772 /* Succeed, if LM password matches */
773 if (UserLmPasswordPresent
&& UserInfo
->All
.LmPasswordPresent
)
775 TRACE("Check LM password hashes:\n");
776 if (RtlEqualMemory(&UserLmPassword
,
777 UserInfo
->All
.LmOwfPassword
.Buffer
,
778 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
780 TRACE(" success!\n");
781 Status
= STATUS_SUCCESS
;
797 LsaApCallPackage(IN PLSA_CLIENT_REQUEST ClientRequest
,
798 IN PVOID ProtocolSubmitBuffer
,
799 IN PVOID ClientBufferBase
,
800 IN ULONG SubmitBufferLength
,
801 OUT PVOID
*ProtocolReturnBuffer
,
802 OUT PULONG ReturnBufferLength
,
803 OUT PNTSTATUS ProtocolStatus
)
810 if (SubmitBufferLength
< sizeof(MSV1_0_PROTOCOL_MESSAGE_TYPE
))
811 return STATUS_INVALID_PARAMETER
;
813 MessageType
= (ULONG
)*((PMSV1_0_PROTOCOL_MESSAGE_TYPE
)ProtocolSubmitBuffer
);
815 *ProtocolReturnBuffer
= NULL
;
816 *ReturnBufferLength
= 0;
820 case MsV1_0Lm20ChallengeRequest
:
821 case MsV1_0Lm20GetChallengeResponse
:
822 case MsV1_0EnumerateUsers
:
823 case MsV1_0GetUserInfo
:
824 case MsV1_0ReLogonUsers
:
825 Status
= STATUS_NOT_IMPLEMENTED
;
828 case MsV1_0ChangePassword
:
829 Status
= MsvpChangePassword(ClientRequest
,
830 ProtocolSubmitBuffer
,
833 ProtocolReturnBuffer
,
838 case MsV1_0ChangeCachedPassword
:
839 case MsV1_0GenericPassthrough
:
840 case MsV1_0CacheLogon
:
842 case MsV1_0DeriveCredential
:
843 case MsV1_0CacheLookup
:
844 Status
= STATUS_NOT_IMPLEMENTED
;
848 return STATUS_INVALID_PARAMETER
;
860 LsaApCallPackagePassthrough(IN PLSA_CLIENT_REQUEST ClientRequest
,
861 IN PVOID ProtocolSubmitBuffer
,
862 IN PVOID ClientBufferBase
,
863 IN ULONG SubmitBufferLength
,
864 OUT PVOID
*ProtocolReturnBuffer
,
865 OUT PULONG ReturnBufferLength
,
866 OUT PNTSTATUS ProtocolStatus
)
869 return STATUS_NOT_IMPLEMENTED
;
878 LsaApCallPackageUntrusted(IN PLSA_CLIENT_REQUEST ClientRequest
,
879 IN PVOID ProtocolSubmitBuffer
,
880 IN PVOID ClientBufferBase
,
881 IN ULONG SubmitBufferLength
,
882 OUT PVOID
*ProtocolReturnBuffer
,
883 OUT PULONG ReturnBufferLength
,
884 OUT PNTSTATUS ProtocolStatus
)
887 return STATUS_NOT_IMPLEMENTED
;
896 LsaApInitializePackage(IN ULONG AuthenticationPackageId
,
897 IN PLSA_DISPATCH_TABLE LsaDispatchTable
,
898 IN PLSA_STRING Database OPTIONAL
,
899 IN PLSA_STRING Confidentiality OPTIONAL
,
900 OUT PLSA_STRING
*AuthenticationPackageName
)
902 PANSI_STRING NameString
;
905 TRACE("(%lu %p %p %p %p)\n",
906 AuthenticationPackageId
, LsaDispatchTable
, Database
,
907 Confidentiality
, AuthenticationPackageName
);
909 /* Get the dispatch table entries */
910 DispatchTable
.CreateLogonSession
= LsaDispatchTable
->CreateLogonSession
;
911 DispatchTable
.DeleteLogonSession
= LsaDispatchTable
->DeleteLogonSession
;
912 DispatchTable
.AddCredential
= LsaDispatchTable
->AddCredential
;
913 DispatchTable
.GetCredentials
= LsaDispatchTable
->GetCredentials
;
914 DispatchTable
.DeleteCredential
= LsaDispatchTable
->DeleteCredential
;
915 DispatchTable
.AllocateLsaHeap
= LsaDispatchTable
->AllocateLsaHeap
;
916 DispatchTable
.FreeLsaHeap
= LsaDispatchTable
->FreeLsaHeap
;
917 DispatchTable
.AllocateClientBuffer
= LsaDispatchTable
->AllocateClientBuffer
;
918 DispatchTable
.FreeClientBuffer
= LsaDispatchTable
->FreeClientBuffer
;
919 DispatchTable
.CopyToClientBuffer
= LsaDispatchTable
->CopyToClientBuffer
;
920 DispatchTable
.CopyFromClientBuffer
= LsaDispatchTable
->CopyFromClientBuffer
;
922 /* Return the package name */
923 NameString
= DispatchTable
.AllocateLsaHeap(sizeof(LSA_STRING
));
924 if (NameString
== NULL
)
925 return STATUS_INSUFFICIENT_RESOURCES
;
927 NameBuffer
= DispatchTable
.AllocateLsaHeap(sizeof(MSV1_0_PACKAGE_NAME
));
928 if (NameBuffer
== NULL
)
930 DispatchTable
.FreeLsaHeap(NameString
);
931 return STATUS_INSUFFICIENT_RESOURCES
;
934 strcpy(NameBuffer
, MSV1_0_PACKAGE_NAME
);
936 RtlInitAnsiString(NameString
, NameBuffer
);
938 *AuthenticationPackageName
= (PLSA_STRING
)NameString
;
940 return STATUS_SUCCESS
;
949 LsaApLogonTerminated(IN PLUID LogonId
)
960 LsaApLogonUser(IN PLSA_CLIENT_REQUEST ClientRequest
,
961 IN SECURITY_LOGON_TYPE LogonType
,
962 IN PVOID AuthenticationInformation
,
963 IN PVOID ClientAuthenticationBase
,
964 IN ULONG AuthenticationInformationLength
,
965 OUT PVOID
*ProfileBuffer
,
966 OUT PULONG ProfileBufferLength
,
968 OUT PNTSTATUS SubStatus
,
969 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType
,
970 OUT PVOID
*TokenInformation
,
971 OUT PLSA_UNICODE_STRING
*AccountName
,
972 OUT PLSA_UNICODE_STRING
*AuthenticatingAuthority
)
974 PMSV1_0_INTERACTIVE_LOGON LogonInfo
;
976 SAMPR_HANDLE ServerHandle
= NULL
;
977 SAMPR_HANDLE DomainHandle
= NULL
;
978 SAMPR_HANDLE UserHandle
= NULL
;
979 PRPC_SID AccountDomainSid
= NULL
;
980 RPC_UNICODE_STRING Names
[1];
981 SAMPR_ULONG_ARRAY RelativeIds
= {0, NULL
};
982 SAMPR_ULONG_ARRAY Use
= {0, NULL
};
983 PSAMPR_USER_INFO_BUFFER UserInfo
= NULL
;
984 UNICODE_STRING LogonServer
;
985 BOOLEAN SessionCreated
= FALSE
;
990 TRACE("LogonType: %lu\n", LogonType
);
991 TRACE("AuthenticationInformation: %p\n", AuthenticationInformation
);
992 TRACE("AuthenticationInformationLength: %lu\n", AuthenticationInformationLength
);
994 *ProfileBuffer
= NULL
;
995 *ProfileBufferLength
= 0;
996 *SubStatus
= STATUS_SUCCESS
;
998 if (LogonType
== Interactive
||
999 LogonType
== Batch
||
1000 LogonType
== Service
)
1002 ULONG_PTR PtrOffset
;
1004 LogonInfo
= (PMSV1_0_INTERACTIVE_LOGON
)AuthenticationInformation
;
1006 /* Fix-up pointers in the authentication info */
1007 PtrOffset
= (ULONG_PTR
)AuthenticationInformation
- (ULONG_PTR
)ClientAuthenticationBase
;
1009 LogonInfo
->LogonDomainName
.Buffer
= FIXUP_POINTER(LogonInfo
->LogonDomainName
.Buffer
, PtrOffset
);
1010 LogonInfo
->UserName
.Buffer
= FIXUP_POINTER(LogonInfo
->UserName
.Buffer
, PtrOffset
);
1011 LogonInfo
->Password
.Buffer
= FIXUP_POINTER(LogonInfo
->Password
.Buffer
, PtrOffset
);
1013 TRACE("Domain: %S\n", LogonInfo
->LogonDomainName
.Buffer
);
1014 TRACE("User: %S\n", LogonInfo
->UserName
.Buffer
);
1015 TRACE("Password: %S\n", LogonInfo
->Password
.Buffer
);
1017 RtlInitUnicodeString(&LogonServer
, L
"Testserver");
1021 FIXME("LogonType %lu is not supported yet!\n", LogonType
);
1022 return STATUS_NOT_IMPLEMENTED
;
1025 Status
= GetDomainSid(&AccountDomainSid
);
1026 if (!NT_SUCCESS(Status
))
1028 TRACE("GetDomainSid() failed (Status 0x%08lx)\n", Status
);
1032 /* Connect to the SAM server */
1033 Status
= SamIConnect(NULL
,
1035 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
1037 if (!NT_SUCCESS(Status
))
1039 TRACE("SamIConnect() failed (Status 0x%08lx)\n", Status
);
1043 /* Open the account domain */
1044 Status
= SamrOpenDomain(ServerHandle
,
1048 if (!NT_SUCCESS(Status
))
1050 TRACE("SamrOpenDomain failed (Status %08lx)\n", Status
);
1054 Names
[0].Length
= LogonInfo
->UserName
.Length
;
1055 Names
[0].MaximumLength
= LogonInfo
->UserName
.MaximumLength
;
1056 Names
[0].Buffer
= LogonInfo
->UserName
.Buffer
;
1058 /* Try to get the RID for the user name */
1059 Status
= SamrLookupNamesInDomain(DomainHandle
,
1064 if (!NT_SUCCESS(Status
))
1066 TRACE("SamrLookupNamesInDomain failed (Status %08lx)\n", Status
);
1067 Status
= STATUS_NO_SUCH_USER
;
1071 /* Fail, if it is not a user account */
1072 if (Use
.Element
[0] != SidTypeUser
)
1074 TRACE("Account is not a user account!\n");
1075 Status
= STATUS_NO_SUCH_USER
;
1079 /* Open the user object */
1080 Status
= SamrOpenUser(DomainHandle
,
1081 USER_READ_GENERAL
| USER_READ_LOGON
|
1082 USER_READ_ACCOUNT
| USER_READ_PREFERENCES
, /* FIXME */
1083 RelativeIds
.Element
[0],
1085 if (!NT_SUCCESS(Status
))
1087 TRACE("SamrOpenUser failed (Status %08lx)\n", Status
);
1091 Status
= SamrQueryInformationUser(UserHandle
,
1094 if (!NT_SUCCESS(Status
))
1096 TRACE("SamrQueryInformationUser failed (Status %08lx)\n", Status
);
1101 TRACE("UserName: %S\n", UserInfo
->All
.UserName
.Buffer
);
1103 /* FIXME: Check restrictions */
1105 /* Check the password */
1106 if ((UserInfo
->All
.UserAccountControl
& USER_PASSWORD_NOT_REQUIRED
) == 0)
1108 Status
= MsvpCheckPassword(&(LogonInfo
->Password
),
1110 if (!NT_SUCCESS(Status
))
1112 TRACE("MsvpCheckPassword failed (Status %08lx)\n", Status
);
1117 /* Return logon information */
1119 /* Create and return a new logon id */
1120 Status
= NtAllocateLocallyUniqueId(LogonId
);
1121 if (!NT_SUCCESS(Status
))
1123 TRACE("NtAllocateLocallyUniqueId failed (Status %08lx)\n", Status
);
1127 /* Create the logon session */
1128 Status
= DispatchTable
.CreateLogonSession(LogonId
);
1129 if (!NT_SUCCESS(Status
))
1131 TRACE("CreateLogonSession failed (Status %08lx)\n", Status
);
1135 SessionCreated
= TRUE
;
1137 /* Build and fill the interactve profile buffer */
1138 Status
= BuildInteractiveProfileBuffer(ClientRequest
,
1141 (PMSV1_0_INTERACTIVE_PROFILE
*)ProfileBuffer
,
1142 ProfileBufferLength
);
1143 if (!NT_SUCCESS(Status
))
1145 TRACE("BuildInteractiveProfileBuffer failed (Status %08lx)\n", Status
);
1149 /* Return the token information type */
1150 *TokenInformationType
= LsaTokenInformationV1
;
1152 /* Build and fill the token information buffer */
1153 Status
= BuildTokenInformationBuffer((PLSA_TOKEN_INFORMATION_V1
*)TokenInformation
,
1155 RelativeIds
.Element
[0],
1157 if (!NT_SUCCESS(Status
))
1159 TRACE("BuildTokenInformationBuffer failed (Status %08lx)\n", Status
);
1164 /* Return the account name */
1165 *AccountName
= DispatchTable
.AllocateLsaHeap(sizeof(UNICODE_STRING
));
1166 if (*AccountName
!= NULL
)
1168 (*AccountName
)->Buffer
= DispatchTable
.AllocateLsaHeap(LogonInfo
->UserName
.Length
+
1169 sizeof(UNICODE_NULL
));
1170 if ((*AccountName
)->Buffer
!= NULL
)
1172 (*AccountName
)->MaximumLength
= LogonInfo
->UserName
.Length
+
1173 sizeof(UNICODE_NULL
);
1174 RtlCopyUnicodeString(*AccountName
, &LogonInfo
->UserName
);
1178 if (!NT_SUCCESS(Status
))
1180 if (SessionCreated
== TRUE
)
1181 DispatchTable
.DeleteLogonSession(LogonId
);
1183 if (*ProfileBuffer
!= NULL
)
1185 DispatchTable
.FreeClientBuffer(ClientRequest
,
1187 *ProfileBuffer
= NULL
;
1191 if (UserHandle
!= NULL
)
1192 SamrCloseHandle(&UserHandle
);
1194 SamIFree_SAMPR_USER_INFO_BUFFER(UserInfo
,
1195 UserAllInformation
);
1196 SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds
);
1197 SamIFree_SAMPR_ULONG_ARRAY(&Use
);
1199 if (DomainHandle
!= NULL
)
1200 SamrCloseHandle(&DomainHandle
);
1202 if (ServerHandle
!= NULL
)
1203 SamrCloseHandle(&ServerHandle
);
1205 if (AccountDomainSid
!= NULL
)
1206 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid
);
1208 if (Status
== STATUS_NO_SUCH_USER
||
1209 Status
== STATUS_WRONG_PASSWORD
)
1211 *SubStatus
= Status
;
1212 Status
= STATUS_LOGON_FAILURE
;
1215 TRACE("LsaApLogonUser done (Status %08lx)\n", Status
);
1227 LsaApLogonUserEx(IN PLSA_CLIENT_REQUEST ClientRequest
,
1228 IN SECURITY_LOGON_TYPE LogonType
,
1229 IN PVOID AuthenticationInformation
,
1230 IN PVOID ClientAuthenticationBase
,
1231 IN ULONG AuthenticationInformationLength
,
1232 OUT PVOID
*ProfileBuffer
,
1233 OUT PULONG ProfileBufferLength
,
1235 OUT PNTSTATUS SubStatus
,
1236 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType
,
1237 OUT PVOID
*TokenInformation
,
1238 OUT PUNICODE_STRING
*AccountName
,
1239 OUT PUNICODE_STRING
*AuthenticatingAuthority
,
1240 OUT PUNICODE_STRING
*MachineName
)
1244 TRACE("LogonType: %lu\n", LogonType
);
1245 TRACE("AuthenticationInformation: %p\n", AuthenticationInformation
);
1246 TRACE("AuthenticationInformationLength: %lu\n", AuthenticationInformationLength
);
1248 return STATUS_NOT_IMPLEMENTED
;
1257 LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest
,
1258 IN SECURITY_LOGON_TYPE LogonType
,
1259 IN PVOID ProtocolSubmitBuffer
,
1260 IN PVOID ClientBufferBase
,
1261 IN ULONG SubmitBufferSize
,
1262 OUT PVOID
*ProfileBuffer
,
1263 OUT PULONG ProfileBufferSize
,
1265 OUT PNTSTATUS SubStatus
,
1266 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType
,
1267 OUT PVOID
*TokenInformation
,
1268 OUT PUNICODE_STRING
*AccountName
,
1269 OUT PUNICODE_STRING
*AuthenticatingAuthority
,
1270 OUT PUNICODE_STRING
*MachineName
,
1271 OUT PSECPKG_PRIMARY_CRED PrimaryCredentials
,
1272 OUT PSECPKG_SUPPLEMENTAL_CRED_ARRAY
*SupplementalCredentials
)
1276 TRACE("LogonType: %lu\n", LogonType
);
1277 TRACE("ProtocolSubmitBuffer: %p\n", ProtocolSubmitBuffer
);
1278 TRACE("SubmitBufferSize: %lu\n", SubmitBufferSize
);
1281 return STATUS_NOT_IMPLEMENTED
;