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 LocalAuthority
= {SECURITY_LOCAL_SID_AUTHORITY
};
278 SID_IDENTIFIER_AUTHORITY SystemAuthority
= {SECURITY_NT_AUTHORITY
};
279 PTOKEN_GROUPS TokenGroups
;
281 DWORD GroupCount
= 0;
283 NTSTATUS Status
= STATUS_SUCCESS
;
285 TokenGroups
= DispatchTable
.AllocateLsaHeap(sizeof(TOKEN_GROUPS
) +
286 MAX_GROUPS
* sizeof(SID_AND_ATTRIBUTES
));
287 if (TokenGroups
== NULL
)
289 return STATUS_INSUFFICIENT_RESOURCES
;
292 Sid
= AppendRidToSid(AccountDomainSid
, DOMAIN_GROUP_RID_USERS
);
298 /* Member of the domain */
299 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
300 TokenGroups
->Groups
[GroupCount
].Attributes
=
301 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
302 *PrimaryGroupSid
= Sid
;
305 /* Member of 'Everyone' */
306 RtlAllocateAndInitializeSid(&WorldAuthority
,
317 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
318 TokenGroups
->Groups
[GroupCount
].Attributes
=
319 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
323 /* Member of 'Administrators' */
324 RtlAllocateAndInitializeSid(&SystemAuthority
,
326 SECURITY_BUILTIN_DOMAIN_RID
,
327 DOMAIN_ALIAS_RID_ADMINS
,
335 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
336 TokenGroups
->Groups
[GroupCount
].Attributes
=
337 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
340 TRACE("Not adding user to Administrators group\n");
343 /* Member of 'Users' */
344 RtlAllocateAndInitializeSid(&SystemAuthority
,
346 SECURITY_BUILTIN_DOMAIN_RID
,
347 DOMAIN_ALIAS_RID_USERS
,
355 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
356 TokenGroups
->Groups
[GroupCount
].Attributes
=
357 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
361 RtlAllocateAndInitializeSid(&SystemAuthority
,
362 SECURITY_LOGON_IDS_RID_COUNT
,
363 SECURITY_LOGON_IDS_RID
,
372 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
373 TokenGroups
->Groups
[GroupCount
].Attributes
=
374 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
| SE_GROUP_LOGON_ID
;
377 /* Member of 'Local users */
378 RtlAllocateAndInitializeSid(&LocalAuthority
,
389 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
390 TokenGroups
->Groups
[GroupCount
].Attributes
=
391 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
394 /* Member of 'Interactive users' */
395 RtlAllocateAndInitializeSid(&SystemAuthority
,
397 SECURITY_INTERACTIVE_RID
,
406 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
407 TokenGroups
->Groups
[GroupCount
].Attributes
=
408 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
411 /* Member of 'Authenticated users' */
412 RtlAllocateAndInitializeSid(&SystemAuthority
,
414 SECURITY_AUTHENTICATED_USER_RID
,
423 TokenGroups
->Groups
[GroupCount
].Sid
= Sid
;
424 TokenGroups
->Groups
[GroupCount
].Attributes
=
425 SE_GROUP_ENABLED
| SE_GROUP_ENABLED_BY_DEFAULT
| SE_GROUP_MANDATORY
;
428 TokenGroups
->GroupCount
= GroupCount
;
429 ASSERT(TokenGroups
->GroupCount
<= MAX_GROUPS
);
431 *Groups
= TokenGroups
;
439 BuildTokenPrimaryGroup(PTOKEN_PRIMARY_GROUP PrimaryGroup
,
440 PSID PrimaryGroupSid
)
445 RidCount
= *RtlSubAuthorityCountSid(PrimaryGroupSid
);
446 Size
= RtlLengthRequiredSid(RidCount
);
448 PrimaryGroup
->PrimaryGroup
= DispatchTable
.AllocateLsaHeap(Size
);
449 if (PrimaryGroup
->PrimaryGroup
== NULL
)
451 return STATUS_INSUFFICIENT_RESOURCES
;
454 RtlCopyMemory(PrimaryGroup
->PrimaryGroup
,
458 return STATUS_SUCCESS
;
463 BuildTokenPrivileges(PTOKEN_PRIVILEGES
*TokenPrivileges
)
465 /* FIXME shouldn't use hard-coded list of privileges */
473 { L
"SeMachineAccountPrivilege", 0 },
474 { L
"SeSecurityPrivilege", 0 },
475 { L
"SeTakeOwnershipPrivilege", 0 },
476 { L
"SeLoadDriverPrivilege", 0 },
477 { L
"SeSystemProfilePrivilege", 0 },
478 { L
"SeSystemtimePrivilege", 0 },
479 { L
"SeProfileSingleProcessPrivilege", 0 },
480 { L
"SeIncreaseBasePriorityPrivilege", 0 },
481 { L
"SeCreatePagefilePrivilege", 0 },
482 { L
"SeBackupPrivilege", 0 },
483 { L
"SeRestorePrivilege", 0 },
484 { L
"SeShutdownPrivilege", 0 },
485 { L
"SeDebugPrivilege", 0 },
486 { L
"SeSystemEnvironmentPrivilege", 0 },
487 { L
"SeChangeNotifyPrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
},
488 { L
"SeRemoteShutdownPrivilege", 0 },
489 { L
"SeUndockPrivilege", 0 },
490 { L
"SeEnableDelegationPrivilege", 0 },
491 { L
"SeImpersonatePrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
},
492 { L
"SeCreateGlobalPrivilege", SE_PRIVILEGE_ENABLED
| SE_PRIVILEGE_ENABLED_BY_DEFAULT
}
494 PTOKEN_PRIVILEGES Privileges
= NULL
;
496 RPC_UNICODE_STRING PrivilegeName
;
497 LSAPR_HANDLE PolicyHandle
= NULL
;
498 NTSTATUS Status
= STATUS_SUCCESS
;
500 Status
= LsaIOpenPolicyTrusted(&PolicyHandle
);
501 if (!NT_SUCCESS(Status
))
506 /* Allocate and initialize token privileges */
507 Privileges
= DispatchTable
.AllocateLsaHeap(sizeof(TOKEN_PRIVILEGES
) +
508 sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0]) *
509 sizeof(LUID_AND_ATTRIBUTES
));
510 if (Privileges
== NULL
)
512 Status
= STATUS_INSUFFICIENT_RESOURCES
;
516 Privileges
->PrivilegeCount
= 0;
517 for (i
= 0; i
< sizeof(DefaultPrivs
) / sizeof(DefaultPrivs
[0]); i
++)
519 PrivilegeName
.Length
= wcslen(DefaultPrivs
[i
].PrivName
) * sizeof(WCHAR
);
520 PrivilegeName
.MaximumLength
= PrivilegeName
.Length
+ sizeof(WCHAR
);
521 PrivilegeName
.Buffer
= (LPWSTR
)DefaultPrivs
[i
].PrivName
;
523 Status
= LsarLookupPrivilegeValue(PolicyHandle
,
525 &Privileges
->Privileges
[Privileges
->PrivilegeCount
].Luid
);
526 if (!NT_SUCCESS(Status
))
528 WARN("Can't set privilege %S\n", DefaultPrivs
[i
].PrivName
);
532 Privileges
->Privileges
[Privileges
->PrivilegeCount
].Attributes
= DefaultPrivs
[i
].Attributes
;
533 Privileges
->PrivilegeCount
++;
537 *TokenPrivileges
= Privileges
;
540 if (PolicyHandle
!= NULL
)
541 LsarClose(&PolicyHandle
);
549 BuildTokenInformationBuffer(PLSA_TOKEN_INFORMATION_V1
*TokenInformation
,
550 PRPC_SID AccountDomainSid
,
554 PLSA_TOKEN_INFORMATION_V1 Buffer
= NULL
;
555 PSID PrimaryGroupSid
= NULL
;
557 NTSTATUS Status
= STATUS_SUCCESS
;
559 Buffer
= DispatchTable
.AllocateLsaHeap(sizeof(LSA_TOKEN_INFORMATION_V1
));
562 TRACE("Failed to allocate the local buffer!\n");
563 Status
= STATUS_INSUFFICIENT_RESOURCES
;
568 Buffer
->ExpirationTime
.QuadPart
= -1;
570 Status
= BuildTokenUser(&Buffer
->User
,
571 (PSID
)AccountDomainSid
,
573 if (!NT_SUCCESS(Status
))
576 Status
= BuildTokenGroups((PSID
)AccountDomainSid
,
580 if (!NT_SUCCESS(Status
))
583 Status
= BuildTokenPrimaryGroup(&Buffer
->PrimaryGroup
,
585 if (!NT_SUCCESS(Status
))
588 Status
= BuildTokenPrivileges(&Buffer
->Privileges
);
589 if (!NT_SUCCESS(Status
))
592 *TokenInformation
= Buffer
;
595 if (!NT_SUCCESS(Status
))
599 if (Buffer
->User
.User
.Sid
!= NULL
)
600 DispatchTable
.FreeLsaHeap(Buffer
->User
.User
.Sid
);
602 if (Buffer
->Groups
!= NULL
)
604 for (i
= 0; i
< Buffer
->Groups
->GroupCount
; i
++)
606 if (Buffer
->Groups
->Groups
[i
].Sid
!= NULL
)
607 DispatchTable
.FreeLsaHeap(Buffer
->Groups
->Groups
[i
].Sid
);
610 DispatchTable
.FreeLsaHeap(Buffer
->Groups
);
613 if (Buffer
->PrimaryGroup
.PrimaryGroup
!= NULL
)
614 DispatchTable
.FreeLsaHeap(Buffer
->PrimaryGroup
.PrimaryGroup
);
616 if (Buffer
->Privileges
!= NULL
)
617 DispatchTable
.FreeLsaHeap(Buffer
->Privileges
);
619 if (Buffer
->DefaultDacl
.DefaultDacl
!= NULL
)
620 DispatchTable
.FreeLsaHeap(Buffer
->DefaultDacl
.DefaultDacl
);
622 DispatchTable
.FreeLsaHeap(Buffer
);
632 MsvpChangePassword(IN PLSA_CLIENT_REQUEST ClientRequest
,
633 IN PVOID ProtocolSubmitBuffer
,
634 IN PVOID ClientBufferBase
,
635 IN ULONG SubmitBufferLength
,
636 OUT PVOID
*ProtocolReturnBuffer
,
637 OUT PULONG ReturnBufferLength
,
638 OUT PNTSTATUS ProtocolStatus
)
640 PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer
;
645 RequestBuffer
= (PMSV1_0_CHANGEPASSWORD_REQUEST
)ProtocolSubmitBuffer
;
647 /* Fix-up pointers in the request buffer info */
648 PtrOffset
= (ULONG_PTR
)ProtocolSubmitBuffer
- (ULONG_PTR
)ClientBufferBase
;
650 RequestBuffer
->DomainName
.Buffer
= FIXUP_POINTER(RequestBuffer
->DomainName
.Buffer
, PtrOffset
);
651 RequestBuffer
->AccountName
.Buffer
= FIXUP_POINTER(RequestBuffer
->AccountName
.Buffer
, PtrOffset
);
652 RequestBuffer
->OldPassword
.Buffer
= FIXUP_POINTER(RequestBuffer
->OldPassword
.Buffer
, PtrOffset
);
653 RequestBuffer
->NewPassword
.Buffer
= FIXUP_POINTER(RequestBuffer
->NewPassword
.Buffer
, PtrOffset
);
655 TRACE("Domain: %S\n", RequestBuffer
->DomainName
.Buffer
);
656 TRACE("Account: %S\n", RequestBuffer
->AccountName
.Buffer
);
657 TRACE("Old Password: %S\n", RequestBuffer
->OldPassword
.Buffer
);
658 TRACE("New Password: %S\n", RequestBuffer
->NewPassword
.Buffer
);
661 return STATUS_SUCCESS
;
667 MsvpCheckPassword(PUNICODE_STRING UserPassword
,
668 PSAMPR_USER_INFO_BUFFER UserInfo
)
670 ENCRYPTED_NT_OWF_PASSWORD UserNtPassword
;
671 ENCRYPTED_LM_OWF_PASSWORD UserLmPassword
;
672 BOOLEAN UserLmPasswordPresent
= FALSE
;
673 BOOLEAN UserNtPasswordPresent
= FALSE
;
674 OEM_STRING LmPwdString
;
675 CHAR LmPwdBuffer
[15];
678 TRACE("(%p %p)\n", UserPassword
, UserInfo
);
680 /* Calculate the LM password and hash for the users password */
681 LmPwdString
.Length
= 15;
682 LmPwdString
.MaximumLength
= 15;
683 LmPwdString
.Buffer
= LmPwdBuffer
;
684 ZeroMemory(LmPwdString
.Buffer
, LmPwdString
.MaximumLength
);
686 Status
= RtlUpcaseUnicodeStringToOemString(&LmPwdString
,
689 if (NT_SUCCESS(Status
))
691 /* Calculate the LM hash value of the users password */
692 Status
= SystemFunction006(LmPwdString
.Buffer
,
693 (LPSTR
)&UserLmPassword
);
694 if (NT_SUCCESS(Status
))
696 UserLmPasswordPresent
= TRUE
;
700 /* Calculate the NT hash of the users password */
701 Status
= SystemFunction007(UserPassword
,
702 (LPBYTE
)&UserNtPassword
);
703 if (NT_SUCCESS(Status
))
705 UserNtPasswordPresent
= TRUE
;
708 Status
= STATUS_WRONG_PASSWORD
;
710 /* Succeed, if no password has been set */
711 if (UserInfo
->All
.NtPasswordPresent
== FALSE
&&
712 UserInfo
->All
.LmPasswordPresent
== FALSE
)
714 TRACE("No password check!\n");
715 Status
= STATUS_SUCCESS
;
719 /* Succeed, if NT password matches */
720 if (UserNtPasswordPresent
&& UserInfo
->All
.NtPasswordPresent
)
722 TRACE("Check NT password hashes:\n");
723 if (RtlEqualMemory(&UserNtPassword
,
724 UserInfo
->All
.NtOwfPassword
.Buffer
,
725 sizeof(ENCRYPTED_NT_OWF_PASSWORD
)))
727 TRACE(" success!\n");
728 Status
= STATUS_SUCCESS
;
735 /* Succeed, if LM password matches */
736 if (UserLmPasswordPresent
&& UserInfo
->All
.LmPasswordPresent
)
738 TRACE("Check LM password hashes:\n");
739 if (RtlEqualMemory(&UserLmPassword
,
740 UserInfo
->All
.LmOwfPassword
.Buffer
,
741 sizeof(ENCRYPTED_LM_OWF_PASSWORD
)))
743 TRACE(" success!\n");
744 Status
= STATUS_SUCCESS
;
760 LsaApCallPackage(IN PLSA_CLIENT_REQUEST ClientRequest
,
761 IN PVOID ProtocolSubmitBuffer
,
762 IN PVOID ClientBufferBase
,
763 IN ULONG SubmitBufferLength
,
764 OUT PVOID
*ProtocolReturnBuffer
,
765 OUT PULONG ReturnBufferLength
,
766 OUT PNTSTATUS ProtocolStatus
)
773 if (SubmitBufferLength
< sizeof(MSV1_0_PROTOCOL_MESSAGE_TYPE
))
774 return STATUS_INVALID_PARAMETER
;
776 MessageType
= (ULONG
)*((PMSV1_0_PROTOCOL_MESSAGE_TYPE
)ProtocolSubmitBuffer
);
778 *ProtocolReturnBuffer
= NULL
;
779 *ReturnBufferLength
= 0;
783 case MsV1_0Lm20ChallengeRequest
:
784 case MsV1_0Lm20GetChallengeResponse
:
785 case MsV1_0EnumerateUsers
:
786 case MsV1_0GetUserInfo
:
787 case MsV1_0ReLogonUsers
:
788 Status
= STATUS_NOT_IMPLEMENTED
;
791 case MsV1_0ChangePassword
:
792 Status
= MsvpChangePassword(ClientRequest
,
793 ProtocolSubmitBuffer
,
796 ProtocolReturnBuffer
,
801 case MsV1_0ChangeCachedPassword
:
802 case MsV1_0GenericPassthrough
:
803 case MsV1_0CacheLogon
:
805 case MsV1_0DeriveCredential
:
806 case MsV1_0CacheLookup
:
807 Status
= STATUS_NOT_IMPLEMENTED
;
811 return STATUS_INVALID_PARAMETER
;
823 LsaApCallPackagePassthrough(IN PLSA_CLIENT_REQUEST ClientRequest
,
824 IN PVOID ProtocolSubmitBuffer
,
825 IN PVOID ClientBufferBase
,
826 IN ULONG SubmitBufferLength
,
827 OUT PVOID
*ProtocolReturnBuffer
,
828 OUT PULONG ReturnBufferLength
,
829 OUT PNTSTATUS ProtocolStatus
)
832 return STATUS_NOT_IMPLEMENTED
;
841 LsaApCallPackageUntrusted(IN PLSA_CLIENT_REQUEST ClientRequest
,
842 IN PVOID ProtocolSubmitBuffer
,
843 IN PVOID ClientBufferBase
,
844 IN ULONG SubmitBufferLength
,
845 OUT PVOID
*ProtocolReturnBuffer
,
846 OUT PULONG ReturnBufferLength
,
847 OUT PNTSTATUS ProtocolStatus
)
850 return STATUS_NOT_IMPLEMENTED
;
859 LsaApInitializePackage(IN ULONG AuthenticationPackageId
,
860 IN PLSA_DISPATCH_TABLE LsaDispatchTable
,
861 IN PLSA_STRING Database OPTIONAL
,
862 IN PLSA_STRING Confidentiality OPTIONAL
,
863 OUT PLSA_STRING
*AuthenticationPackageName
)
865 PANSI_STRING NameString
;
868 TRACE("(%lu %p %p %p %p)\n",
869 AuthenticationPackageId
, LsaDispatchTable
, Database
,
870 Confidentiality
, AuthenticationPackageName
);
872 /* Get the dispatch table entries */
873 DispatchTable
.CreateLogonSession
= LsaDispatchTable
->CreateLogonSession
;
874 DispatchTable
.DeleteLogonSession
= LsaDispatchTable
->DeleteLogonSession
;
875 DispatchTable
.AddCredential
= LsaDispatchTable
->AddCredential
;
876 DispatchTable
.GetCredentials
= LsaDispatchTable
->GetCredentials
;
877 DispatchTable
.DeleteCredential
= LsaDispatchTable
->DeleteCredential
;
878 DispatchTable
.AllocateLsaHeap
= LsaDispatchTable
->AllocateLsaHeap
;
879 DispatchTable
.FreeLsaHeap
= LsaDispatchTable
->FreeLsaHeap
;
880 DispatchTable
.AllocateClientBuffer
= LsaDispatchTable
->AllocateClientBuffer
;
881 DispatchTable
.FreeClientBuffer
= LsaDispatchTable
->FreeClientBuffer
;
882 DispatchTable
.CopyToClientBuffer
= LsaDispatchTable
->CopyToClientBuffer
;
883 DispatchTable
.CopyFromClientBuffer
= LsaDispatchTable
->CopyFromClientBuffer
;
885 /* Return the package name */
886 NameString
= DispatchTable
.AllocateLsaHeap(sizeof(LSA_STRING
));
887 if (NameString
== NULL
)
888 return STATUS_INSUFFICIENT_RESOURCES
;
890 NameBuffer
= DispatchTable
.AllocateLsaHeap(sizeof(MSV1_0_PACKAGE_NAME
));
891 if (NameBuffer
== NULL
)
893 DispatchTable
.FreeLsaHeap(NameString
);
894 return STATUS_INSUFFICIENT_RESOURCES
;
897 strcpy(NameBuffer
, MSV1_0_PACKAGE_NAME
);
899 RtlInitAnsiString(NameString
, NameBuffer
);
901 *AuthenticationPackageName
= (PLSA_STRING
)NameString
;
903 return STATUS_SUCCESS
;
912 LsaApLogonTerminated(IN PLUID LogonId
)
923 LsaApLogonUser(IN PLSA_CLIENT_REQUEST ClientRequest
,
924 IN SECURITY_LOGON_TYPE LogonType
,
925 IN PVOID AuthenticationInformation
,
926 IN PVOID ClientAuthenticationBase
,
927 IN ULONG AuthenticationInformationLength
,
928 OUT PVOID
*ProfileBuffer
,
929 OUT PULONG ProfileBufferLength
,
931 OUT PNTSTATUS SubStatus
,
932 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType
,
933 OUT PVOID
*TokenInformation
,
934 OUT PLSA_UNICODE_STRING
*AccountName
,
935 OUT PLSA_UNICODE_STRING
*AuthenticatingAuthority
)
937 PMSV1_0_INTERACTIVE_LOGON LogonInfo
;
939 SAMPR_HANDLE ServerHandle
= NULL
;
940 SAMPR_HANDLE DomainHandle
= NULL
;
941 SAMPR_HANDLE UserHandle
= NULL
;
942 PRPC_SID AccountDomainSid
= NULL
;
943 RPC_UNICODE_STRING Names
[1];
944 SAMPR_ULONG_ARRAY RelativeIds
= {0, NULL
};
945 SAMPR_ULONG_ARRAY Use
= {0, NULL
};
946 PSAMPR_USER_INFO_BUFFER UserInfo
= NULL
;
947 UNICODE_STRING LogonServer
;
948 BOOLEAN SessionCreated
= FALSE
;
953 TRACE("LogonType: %lu\n", LogonType
);
954 TRACE("AuthenticationInformation: %p\n", AuthenticationInformation
);
955 TRACE("AuthenticationInformationLength: %lu\n", AuthenticationInformationLength
);
957 *ProfileBuffer
= NULL
;
958 *ProfileBufferLength
= 0;
959 *SubStatus
= STATUS_SUCCESS
;
961 if (LogonType
== Interactive
||
962 LogonType
== Batch
||
963 LogonType
== Service
)
967 LogonInfo
= (PMSV1_0_INTERACTIVE_LOGON
)AuthenticationInformation
;
969 /* Fix-up pointers in the authentication info */
970 PtrOffset
= (ULONG_PTR
)AuthenticationInformation
- (ULONG_PTR
)ClientAuthenticationBase
;
972 LogonInfo
->LogonDomainName
.Buffer
= FIXUP_POINTER(LogonInfo
->LogonDomainName
.Buffer
, PtrOffset
);
973 LogonInfo
->UserName
.Buffer
= FIXUP_POINTER(LogonInfo
->UserName
.Buffer
, PtrOffset
);
974 LogonInfo
->Password
.Buffer
= FIXUP_POINTER(LogonInfo
->Password
.Buffer
, PtrOffset
);
976 TRACE("Domain: %S\n", LogonInfo
->LogonDomainName
.Buffer
);
977 TRACE("User: %S\n", LogonInfo
->UserName
.Buffer
);
978 TRACE("Password: %S\n", LogonInfo
->Password
.Buffer
);
980 RtlInitUnicodeString(&LogonServer
, L
"Testserver");
984 FIXME("LogonType %lu is not supported yet!\n", LogonType
);
985 return STATUS_NOT_IMPLEMENTED
;
988 Status
= GetDomainSid(&AccountDomainSid
);
989 if (!NT_SUCCESS(Status
))
991 TRACE("GetDomainSid() failed (Status 0x%08lx)\n", Status
);
995 /* Connect to the SAM server */
996 Status
= SamIConnect(NULL
,
998 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
1000 if (!NT_SUCCESS(Status
))
1002 TRACE("SamIConnect() failed (Status 0x%08lx)\n", Status
);
1006 /* Open the account domain */
1007 Status
= SamrOpenDomain(ServerHandle
,
1011 if (!NT_SUCCESS(Status
))
1013 TRACE("SamrOpenDomain failed (Status %08lx)\n", Status
);
1017 Names
[0].Length
= LogonInfo
->UserName
.Length
;
1018 Names
[0].MaximumLength
= LogonInfo
->UserName
.MaximumLength
;
1019 Names
[0].Buffer
= LogonInfo
->UserName
.Buffer
;
1021 /* Try to get the RID for the user name */
1022 Status
= SamrLookupNamesInDomain(DomainHandle
,
1027 if (!NT_SUCCESS(Status
))
1029 TRACE("SamrLookupNamesInDomain failed (Status %08lx)\n", Status
);
1030 Status
= STATUS_NO_SUCH_USER
;
1034 /* Fail, if it is not a user account */
1035 if (Use
.Element
[0] != SidTypeUser
)
1037 TRACE("Account is not a user account!\n");
1038 Status
= STATUS_NO_SUCH_USER
;
1042 /* Open the user object */
1043 Status
= SamrOpenUser(DomainHandle
,
1044 USER_READ_GENERAL
| USER_READ_LOGON
|
1045 USER_READ_ACCOUNT
| USER_READ_PREFERENCES
, /* FIXME */
1046 RelativeIds
.Element
[0],
1048 if (!NT_SUCCESS(Status
))
1050 TRACE("SamrOpenUser failed (Status %08lx)\n", Status
);
1054 Status
= SamrQueryInformationUser(UserHandle
,
1057 if (!NT_SUCCESS(Status
))
1059 TRACE("SamrQueryInformationUser failed (Status %08lx)\n", Status
);
1064 TRACE("UserName: %S\n", UserInfo
->All
.UserName
.Buffer
);
1066 /* FIXME: Check restrictions */
1068 /* Check the password */
1069 if ((UserInfo
->All
.UserAccountControl
& USER_PASSWORD_NOT_REQUIRED
) == 0)
1071 Status
= MsvpCheckPassword(&(LogonInfo
->Password
),
1073 if (!NT_SUCCESS(Status
))
1075 TRACE("MsvpCheckPassword failed (Status %08lx)\n", Status
);
1080 /* Return logon information */
1082 /* Create and return a new logon id */
1083 Status
= NtAllocateLocallyUniqueId(LogonId
);
1084 if (!NT_SUCCESS(Status
))
1086 TRACE("NtAllocateLocallyUniqueId failed (Status %08lx)\n", Status
);
1090 /* Create the logon session */
1091 Status
= DispatchTable
.CreateLogonSession(LogonId
);
1092 if (!NT_SUCCESS(Status
))
1094 TRACE("CreateLogonSession failed (Status %08lx)\n", Status
);
1098 SessionCreated
= TRUE
;
1100 /* Build and fill the interactve profile buffer */
1101 Status
= BuildInteractiveProfileBuffer(ClientRequest
,
1104 (PMSV1_0_INTERACTIVE_PROFILE
*)ProfileBuffer
,
1105 ProfileBufferLength
);
1106 if (!NT_SUCCESS(Status
))
1108 TRACE("BuildInteractiveProfileBuffer failed (Status %08lx)\n", Status
);
1112 /* Return the token information type */
1113 *TokenInformationType
= LsaTokenInformationV1
;
1115 /* Build and fill the token information buffer */
1116 Status
= BuildTokenInformationBuffer((PLSA_TOKEN_INFORMATION_V1
*)TokenInformation
,
1118 RelativeIds
.Element
[0],
1120 if (!NT_SUCCESS(Status
))
1122 TRACE("BuildTokenInformationBuffer failed (Status %08lx)\n", Status
);
1127 /* Return the account name */
1128 *AccountName
= DispatchTable
.AllocateLsaHeap(sizeof(UNICODE_STRING
));
1129 if (*AccountName
!= NULL
)
1131 (*AccountName
)->Buffer
= DispatchTable
.AllocateLsaHeap(LogonInfo
->UserName
.Length
+
1132 sizeof(UNICODE_NULL
));
1133 if ((*AccountName
)->Buffer
!= NULL
)
1135 (*AccountName
)->MaximumLength
= LogonInfo
->UserName
.Length
+
1136 sizeof(UNICODE_NULL
);
1137 RtlCopyUnicodeString(*AccountName
, &LogonInfo
->UserName
);
1141 if (!NT_SUCCESS(Status
))
1143 if (SessionCreated
== TRUE
)
1144 DispatchTable
.DeleteLogonSession(LogonId
);
1146 if (*ProfileBuffer
!= NULL
)
1148 DispatchTable
.FreeClientBuffer(ClientRequest
,
1150 *ProfileBuffer
= NULL
;
1154 if (UserHandle
!= NULL
)
1155 SamrCloseHandle(&UserHandle
);
1157 SamIFree_SAMPR_USER_INFO_BUFFER(UserInfo
,
1158 UserAllInformation
);
1159 SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds
);
1160 SamIFree_SAMPR_ULONG_ARRAY(&Use
);
1162 if (DomainHandle
!= NULL
)
1163 SamrCloseHandle(&DomainHandle
);
1165 if (ServerHandle
!= NULL
)
1166 SamrCloseHandle(&ServerHandle
);
1168 if (AccountDomainSid
!= NULL
)
1169 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid
);
1171 if (Status
== STATUS_NO_SUCH_USER
||
1172 Status
== STATUS_WRONG_PASSWORD
)
1174 *SubStatus
= Status
;
1175 Status
= STATUS_LOGON_FAILURE
;
1178 TRACE("LsaApLogonUser done (Status %08lx)\n", Status
);
1190 LsaApLogonUserEx(IN PLSA_CLIENT_REQUEST ClientRequest
,
1191 IN SECURITY_LOGON_TYPE LogonType
,
1192 IN PVOID AuthenticationInformation
,
1193 IN PVOID ClientAuthenticationBase
,
1194 IN ULONG AuthenticationInformationLength
,
1195 OUT PVOID
*ProfileBuffer
,
1196 OUT PULONG ProfileBufferLength
,
1198 OUT PNTSTATUS SubStatus
,
1199 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType
,
1200 OUT PVOID
*TokenInformation
,
1201 OUT PUNICODE_STRING
*AccountName
,
1202 OUT PUNICODE_STRING
*AuthenticatingAuthority
,
1203 OUT PUNICODE_STRING
*MachineName
)
1207 TRACE("LogonType: %lu\n", LogonType
);
1208 TRACE("AuthenticationInformation: %p\n", AuthenticationInformation
);
1209 TRACE("AuthenticationInformationLength: %lu\n", AuthenticationInformationLength
);
1211 return STATUS_NOT_IMPLEMENTED
;
1220 LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest
,
1221 IN SECURITY_LOGON_TYPE LogonType
,
1222 IN PVOID ProtocolSubmitBuffer
,
1223 IN PVOID ClientBufferBase
,
1224 IN ULONG SubmitBufferSize
,
1225 OUT PVOID
*ProfileBuffer
,
1226 OUT PULONG ProfileBufferSize
,
1228 OUT PNTSTATUS SubStatus
,
1229 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType
,
1230 OUT PVOID
*TokenInformation
,
1231 OUT PUNICODE_STRING
*AccountName
,
1232 OUT PUNICODE_STRING
*AuthenticatingAuthority
,
1233 OUT PUNICODE_STRING
*MachineName
,
1234 OUT PSECPKG_PRIMARY_CRED PrimaryCredentials
,
1235 OUT PSECPKG_SUPPLEMENTAL_CRED_ARRAY
*SupplementalCredentials
)
1239 TRACE("LogonType: %lu\n", LogonType
);
1240 TRACE("ProtocolSubmitBuffer: %p\n", ProtocolSubmitBuffer
);
1241 TRACE("SubmitBufferSize: %lu\n", SubmitBufferSize
);
1244 return STATUS_NOT_IMPLEMENTED
;