ec63a04368d2f9db4639a701ccdd4cf2cea4fbfc
[reactos.git] / reactos / dll / win32 / msv1_0 / msv1_0.c
1 /*
2 * PROJECT: Authentication Package DLL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/msv1_0/msv1_0.c
5 * PURPOSE: Main file
6 * COPYRIGHT: Copyright 2013 Eric Kohl
7 */
8
9 /* INCLUDES ****************************************************************/
10
11 #include "msv1_0.h"
12
13 WINE_DEFAULT_DEBUG_CHANNEL(msv1_0);
14
15
16 /* GLOBALS *****************************************************************/
17
18 LSA_DISPATCH_TABLE DispatchTable;
19
20
21 /* FUNCTIONS ***************************************************************/
22
23 static
24 NTSTATUS
25 GetDomainSid(PRPC_SID *Sid)
26 {
27 LSAPR_HANDLE PolicyHandle = NULL;
28 PLSAPR_POLICY_INFORMATION PolicyInfo = NULL;
29 ULONG Length = 0;
30 NTSTATUS Status;
31
32 Status = LsaIOpenPolicyTrusted(&PolicyHandle);
33 if (!NT_SUCCESS(Status))
34 {
35 TRACE("LsaIOpenPolicyTrusted() failed (Status 0x%08lx)\n", Status);
36 return Status;
37 }
38
39 Status = LsarQueryInformationPolicy(PolicyHandle,
40 PolicyAccountDomainInformation,
41 &PolicyInfo);
42 if (!NT_SUCCESS(Status))
43 {
44 TRACE("LsarQueryInformationPolicy() failed (Status 0x%08lx)\n", Status);
45 goto done;
46 }
47
48 Length = RtlLengthSid(PolicyInfo->PolicyAccountDomainInfo.Sid);
49
50 *Sid = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
51 if (*Sid == NULL)
52 {
53 ERR("Failed to allocate SID\n");
54 Status = STATUS_INSUFFICIENT_RESOURCES;
55 goto done;
56 }
57
58 memcpy(*Sid, PolicyInfo->PolicyAccountDomainInfo.Sid, Length);
59
60 done:
61 if (PolicyInfo != NULL)
62 LsaIFree_LSAPR_POLICY_INFORMATION(PolicyAccountDomainInformation,
63 PolicyInfo);
64
65 if (PolicyHandle != NULL)
66 LsarClose(&PolicyHandle);
67
68 return Status;
69 }
70
71
72 static
73 NTSTATUS
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)
79 {
80 PMSV1_0_INTERACTIVE_PROFILE LocalBuffer = NULL;
81 PVOID ClientBaseAddress = NULL;
82 LPWSTR Ptr;
83 ULONG BufferLength;
84 NTSTATUS Status = STATUS_SUCCESS;
85
86 *ProfileBuffer = NULL;
87 *ProfileBufferLength = 0;
88
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);
96
97 LocalBuffer = DispatchTable.AllocateLsaHeap(BufferLength);
98 if (LocalBuffer == NULL)
99 {
100 TRACE("Failed to allocate the local buffer!\n");
101 Status = STATUS_INSUFFICIENT_RESOURCES;
102 goto done;
103 }
104
105 Status = DispatchTable.AllocateClientBuffer(ClientRequest,
106 BufferLength,
107 &ClientBaseAddress);
108 if (!NT_SUCCESS(Status))
109 {
110 TRACE("DispatchTable.AllocateClientBuffer failed (Status 0x%08lx)\n", Status);
111 goto done;
112 }
113
114 TRACE("ClientBaseAddress: %p\n", ClientBaseAddress);
115
116 Ptr = (LPWSTR)((ULONG_PTR)LocalBuffer + sizeof(MSV1_0_INTERACTIVE_PROFILE));
117
118 LocalBuffer->MessageType = MsV1_0InteractiveProfile;
119 LocalBuffer->LogonCount = UserInfo->All.LogonCount;
120 LocalBuffer->BadPasswordCount = UserInfo->All.BadPasswordCount;
121
122 LocalBuffer->LogonTime.LowPart = UserInfo->All.LastLogon.LowPart;
123 LocalBuffer->LogonTime.HighPart = UserInfo->All.LastLogon.HighPart;
124
125 // LocalBuffer->LogoffTime.LowPart =
126 // LocalBuffer->LogoffTime.HighPart =
127
128 // LocalBuffer->KickOffTime.LowPart =
129 // LocalBuffer->KickOffTime.HighPart =
130
131 LocalBuffer->PasswordLastSet.LowPart = UserInfo->All.PasswordLastSet.LowPart;
132 LocalBuffer->PasswordLastSet.HighPart = UserInfo->All.PasswordLastSet.HighPart;
133
134 LocalBuffer->PasswordCanChange.LowPart = UserInfo->All.PasswordCanChange.LowPart;
135 LocalBuffer->PasswordCanChange.HighPart = UserInfo->All.PasswordCanChange.HighPart;
136
137 LocalBuffer->PasswordMustChange.LowPart = UserInfo->All.PasswordMustChange.LowPart;
138 LocalBuffer->PasswordMustChange.HighPart = UserInfo->All.PasswordMustChange.HighPart;
139
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);
143 memcpy(Ptr,
144 UserInfo->All.ScriptPath.Buffer,
145 UserInfo->All.ScriptPath.Length);
146
147 Ptr = (LPWSTR)((ULONG_PTR)Ptr + LocalBuffer->LogonScript.MaximumLength);
148
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);
152 memcpy(Ptr,
153 UserInfo->All.HomeDirectory.Buffer,
154 UserInfo->All.HomeDirectory.Length);
155
156 Ptr = (LPWSTR)((ULONG_PTR)Ptr + LocalBuffer->HomeDirectory.MaximumLength);
157
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);
161 memcpy(Ptr,
162 UserInfo->All.FullName.Buffer,
163 UserInfo->All.FullName.Length);
164 TRACE("FullName.Buffer: %p\n", LocalBuffer->FullName.Buffer);
165
166 Ptr = (LPWSTR)((ULONG_PTR)Ptr + LocalBuffer->FullName.MaximumLength);
167
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);
171 memcpy(Ptr,
172 UserInfo->All.ProfilePath.Buffer,
173 UserInfo->All.ProfilePath.Length);
174
175 Ptr = (LPWSTR)((ULONG_PTR)Ptr + LocalBuffer->ProfilePath.MaximumLength);
176
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);
180 memcpy(Ptr,
181 UserInfo->All.HomeDirectoryDrive.Buffer,
182 UserInfo->All.HomeDirectoryDrive.Length);
183
184 Ptr = (LPWSTR)((ULONG_PTR)Ptr + LocalBuffer->HomeDirectoryDrive.MaximumLength);
185
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);;
189 memcpy(Ptr,
190 LogonServer->Buffer,
191 LogonServer->Length);
192
193 LocalBuffer->UserFlags = 0;
194
195 Status = DispatchTable.CopyToClientBuffer(ClientRequest,
196 BufferLength,
197 ClientBaseAddress,
198 LocalBuffer);
199 if (!NT_SUCCESS(Status))
200 {
201 TRACE("DispatchTable.CopyToClientBuffer failed (Status 0x%08lx)\n", Status);
202 goto done;
203 }
204
205 *ProfileBuffer = (PMSV1_0_INTERACTIVE_PROFILE)ClientBaseAddress;
206 *ProfileBufferLength = BufferLength;
207
208 done:
209 if (LocalBuffer != NULL)
210 DispatchTable.FreeLsaHeap(LocalBuffer);
211
212 if (!NT_SUCCESS(Status))
213 {
214 if (ClientBaseAddress != NULL)
215 DispatchTable.FreeClientBuffer(ClientRequest,
216 ClientBaseAddress);
217 }
218
219 return Status;
220 }
221
222
223 static
224 PSID
225 AppendRidToSid(PSID SrcSid,
226 ULONG Rid)
227 {
228 PSID DstSid = NULL;
229 UCHAR RidCount;
230
231 RidCount = *RtlSubAuthorityCountSid(SrcSid);
232 if (RidCount >= 8)
233 return NULL;
234
235 DstSid = DispatchTable.AllocateLsaHeap(RtlLengthRequiredSid(RidCount + 1));
236 if (DstSid == NULL)
237 return NULL;
238
239 RtlCopyMemory(DstSid,
240 SrcSid,
241 RtlLengthRequiredSid(RidCount));
242
243 *RtlSubAuthorityCountSid(DstSid) = RidCount + 1;
244 *RtlSubAuthoritySid(DstSid, RidCount) = Rid;
245
246 return DstSid;
247 }
248
249 static
250 NTSTATUS
251 BuildTokenUser(OUT PTOKEN_USER User,
252 IN PSID AccountDomainSid,
253 IN ULONG RelativeId)
254 {
255 User->User.Sid = AppendRidToSid(AccountDomainSid,
256 RelativeId);
257 if (User->User.Sid == NULL)
258 {
259 ERR("Could not create the user SID\n");
260 return STATUS_INSUFFICIENT_RESOURCES;
261 }
262
263 User->User.Attributes = 0;
264
265 return STATUS_SUCCESS;
266 }
267
268
269 static
270 NTSTATUS
271 BuildTokenPrimaryGroup(OUT PTOKEN_PRIMARY_GROUP PrimaryGroup,
272 IN PSID AccountDomainSid,
273 IN ULONG RelativeId)
274 {
275 PrimaryGroup->PrimaryGroup = AppendRidToSid(AccountDomainSid,
276 RelativeId);
277 if (PrimaryGroup->PrimaryGroup == NULL)
278 {
279 ERR("Could not create the primary group SID\n");
280 return STATUS_INSUFFICIENT_RESOURCES;
281 }
282
283 return STATUS_SUCCESS;
284 }
285
286
287 static
288 NTSTATUS
289 BuildTokenGroups(OUT PTOKEN_GROUPS *Groups,
290 IN PSID AccountDomainSid)
291 {
292 SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
293 PTOKEN_GROUPS TokenGroups;
294 #define MAX_GROUPS 2
295 DWORD GroupCount = 0;
296 PSID Sid;
297 NTSTATUS Status = STATUS_SUCCESS;
298
299 TokenGroups = DispatchTable.AllocateLsaHeap(sizeof(TOKEN_GROUPS) +
300 MAX_GROUPS * sizeof(SID_AND_ATTRIBUTES));
301 if (TokenGroups == NULL)
302 {
303 return STATUS_INSUFFICIENT_RESOURCES;
304 }
305
306 Sid = AppendRidToSid(AccountDomainSid, DOMAIN_GROUP_RID_USERS);
307 if (Sid == NULL)
308 {
309
310 }
311
312 /* Member of the domain */
313 TokenGroups->Groups[GroupCount].Sid = Sid;
314 TokenGroups->Groups[GroupCount].Attributes =
315 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
316 GroupCount++;
317
318
319 /* Member of 'Authenticated users' */
320 RtlAllocateAndInitializeSid(&SystemAuthority,
321 1,
322 SECURITY_AUTHENTICATED_USER_RID,
323 SECURITY_NULL_RID,
324 SECURITY_NULL_RID,
325 SECURITY_NULL_RID,
326 SECURITY_NULL_RID,
327 SECURITY_NULL_RID,
328 SECURITY_NULL_RID,
329 SECURITY_NULL_RID,
330 &Sid);
331 TokenGroups->Groups[GroupCount].Sid = Sid;
332 TokenGroups->Groups[GroupCount].Attributes =
333 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
334 GroupCount++;
335
336 TokenGroups->GroupCount = GroupCount;
337 ASSERT(TokenGroups->GroupCount <= MAX_GROUPS);
338
339 *Groups = TokenGroups;
340
341 return Status;
342 }
343
344
345 static
346 NTSTATUS
347 BuildTokenInformationBuffer(PLSA_TOKEN_INFORMATION_V1 *TokenInformation,
348 PRPC_SID AccountDomainSid,
349 PSAMPR_USER_INFO_BUFFER UserInfo)
350 {
351 PLSA_TOKEN_INFORMATION_V1 Buffer = NULL;
352 ULONG i;
353 NTSTATUS Status = STATUS_SUCCESS;
354
355 Buffer = DispatchTable.AllocateLsaHeap(sizeof(LSA_TOKEN_INFORMATION_V1));
356 if (Buffer == NULL)
357 {
358 TRACE("Failed to allocate the local buffer!\n");
359 Status = STATUS_INSUFFICIENT_RESOURCES;
360 goto done;
361 }
362
363 /* FIXME: */
364 Buffer->ExpirationTime.QuadPart = -1;
365
366 Status = BuildTokenUser(&Buffer->User,
367 (PSID)AccountDomainSid,
368 UserInfo->All.UserId);
369 if (!NT_SUCCESS(Status))
370 goto done;
371
372 Status = BuildTokenPrimaryGroup(&Buffer->PrimaryGroup,
373 (PSID)AccountDomainSid,
374 UserInfo->All.PrimaryGroupId);
375 if (!NT_SUCCESS(Status))
376 goto done;
377
378 Status = BuildTokenGroups(&Buffer->Groups,
379 (PSID)AccountDomainSid);
380 if (!NT_SUCCESS(Status))
381 goto done;
382
383 *TokenInformation = Buffer;
384
385 done:
386 if (!NT_SUCCESS(Status))
387 {
388 if (Buffer != NULL)
389 {
390 if (Buffer->User.User.Sid != NULL)
391 DispatchTable.FreeLsaHeap(Buffer->User.User.Sid);
392
393 if (Buffer->Groups != NULL)
394 {
395 for (i = 0; i < Buffer->Groups->GroupCount; i++)
396 {
397 if (Buffer->Groups->Groups[i].Sid != NULL)
398 DispatchTable.FreeLsaHeap(Buffer->Groups->Groups[i].Sid);
399 }
400
401 DispatchTable.FreeLsaHeap(Buffer->Groups);
402 }
403
404 if (Buffer->PrimaryGroup.PrimaryGroup != NULL)
405 DispatchTable.FreeLsaHeap(Buffer->PrimaryGroup.PrimaryGroup);
406
407 if (Buffer->DefaultDacl.DefaultDacl != NULL)
408 DispatchTable.FreeLsaHeap(Buffer->DefaultDacl.DefaultDacl);
409
410 DispatchTable.FreeLsaHeap(Buffer);
411 }
412 }
413
414 return Status;
415 }
416
417
418 static
419 NTSTATUS
420 MsvpChangePassword(IN PLSA_CLIENT_REQUEST ClientRequest,
421 IN PVOID ProtocolSubmitBuffer,
422 IN PVOID ClientBufferBase,
423 IN ULONG SubmitBufferLength,
424 OUT PVOID *ProtocolReturnBuffer,
425 OUT PULONG ReturnBufferLength,
426 OUT PNTSTATUS ProtocolStatus)
427 {
428 PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer;
429 ULONG_PTR PtrOffset;
430
431 SAMPR_HANDLE ServerHandle = NULL;
432 SAMPR_HANDLE DomainHandle = NULL;
433 SAMPR_HANDLE UserHandle = NULL;
434 PRPC_SID DomainSid = NULL;
435 RPC_UNICODE_STRING Names[1];
436 SAMPR_ULONG_ARRAY RelativeIds = {0, NULL};
437 SAMPR_ULONG_ARRAY Use = {0, NULL};
438 NTSTATUS Status;
439
440 ENCRYPTED_NT_OWF_PASSWORD OldNtPassword;
441 ENCRYPTED_NT_OWF_PASSWORD NewNtPassword;
442 ENCRYPTED_LM_OWF_PASSWORD OldLmPassword;
443 ENCRYPTED_LM_OWF_PASSWORD NewLmPassword;
444 OEM_STRING LmPwdString;
445 CHAR LmPwdBuffer[15];
446 BOOLEAN OldLmPasswordPresent = FALSE;
447 BOOLEAN NewLmPasswordPresent = FALSE;
448
449 ENCRYPTED_LM_OWF_PASSWORD OldLmEncryptedWithNewLm;
450 ENCRYPTED_LM_OWF_PASSWORD NewLmEncryptedWithOldLm;
451 ENCRYPTED_LM_OWF_PASSWORD OldNtEncryptedWithNewNt;
452 ENCRYPTED_LM_OWF_PASSWORD NewNtEncryptedWithOldNt;
453 PENCRYPTED_LM_OWF_PASSWORD pOldLmEncryptedWithNewLm = NULL;
454 PENCRYPTED_LM_OWF_PASSWORD pNewLmEncryptedWithOldLm = NULL;
455
456 TRACE("()\n");
457
458 RequestBuffer = (PMSV1_0_CHANGEPASSWORD_REQUEST)ProtocolSubmitBuffer;
459
460 /* Fix-up pointers in the request buffer info */
461 PtrOffset = (ULONG_PTR)ProtocolSubmitBuffer - (ULONG_PTR)ClientBufferBase;
462
463 RequestBuffer->DomainName.Buffer = FIXUP_POINTER(RequestBuffer->DomainName.Buffer, PtrOffset);
464 RequestBuffer->AccountName.Buffer = FIXUP_POINTER(RequestBuffer->AccountName.Buffer, PtrOffset);
465 RequestBuffer->OldPassword.Buffer = FIXUP_POINTER(RequestBuffer->OldPassword.Buffer, PtrOffset);
466 RequestBuffer->NewPassword.Buffer = FIXUP_POINTER(RequestBuffer->NewPassword.Buffer, PtrOffset);
467
468 TRACE("Domain: %S\n", RequestBuffer->DomainName.Buffer);
469 TRACE("Account: %S\n", RequestBuffer->AccountName.Buffer);
470 TRACE("Old Password: %S\n", RequestBuffer->OldPassword.Buffer);
471 TRACE("New Password: %S\n", RequestBuffer->NewPassword.Buffer);
472
473 /* Connect to the SAM server */
474 Status = SamIConnect(NULL,
475 &ServerHandle,
476 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
477 TRUE);
478 if (!NT_SUCCESS(Status))
479 {
480 TRACE("SamIConnect() failed (Status 0x%08lx)\n", Status);
481 goto done;
482 }
483
484 /* Get the domain SID */
485 Status = SamrLookupDomainInSamServer(ServerHandle,
486 (PRPC_UNICODE_STRING)&RequestBuffer->DomainName,
487 &DomainSid);
488 if (!NT_SUCCESS(Status))
489 {
490 TRACE("SamrLookupDomainInSamServer failed (Status %08lx)\n", Status);
491 goto done;
492 }
493
494 /* Open the domain */
495 Status = SamrOpenDomain(ServerHandle,
496 DOMAIN_LOOKUP,
497 DomainSid,
498 &DomainHandle);
499 if (!NT_SUCCESS(Status))
500 {
501 TRACE("SamrOpenDomain failed (Status %08lx)\n", Status);
502 goto done;
503 }
504
505 Names[0].Length = RequestBuffer->AccountName.Length;
506 Names[0].MaximumLength = RequestBuffer->AccountName.MaximumLength;
507 Names[0].Buffer = RequestBuffer->AccountName.Buffer;
508
509 /* Try to get the RID for the user name */
510 Status = SamrLookupNamesInDomain(DomainHandle,
511 1,
512 Names,
513 &RelativeIds,
514 &Use);
515 if (!NT_SUCCESS(Status))
516 {
517 TRACE("SamrLookupNamesInDomain failed (Status %08lx)\n", Status);
518 Status = STATUS_NO_SUCH_USER;
519 goto done;
520 }
521
522 /* Fail, if it is not a user account */
523 if (Use.Element[0] != SidTypeUser)
524 {
525 TRACE("Account is not a user account!\n");
526 Status = STATUS_NO_SUCH_USER;
527 goto done;
528 }
529
530 /* Open the user object */
531 Status = SamrOpenUser(DomainHandle,
532 USER_CHANGE_PASSWORD,
533 RelativeIds.Element[0],
534 &UserHandle);
535 if (!NT_SUCCESS(Status))
536 {
537 TRACE("SamrOpenUser failed (Status %08lx)\n", Status);
538 goto done;
539 }
540
541
542 /* Calculate the NT hash for the old password */
543 Status = SystemFunction007(&RequestBuffer->OldPassword,
544 (LPBYTE)&OldNtPassword);
545 if (!NT_SUCCESS(Status))
546 {
547 TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status);
548 goto done;
549 }
550
551 /* Calculate the NT hash for the new password */
552 Status = SystemFunction007(&RequestBuffer->NewPassword,
553 (LPBYTE)&NewNtPassword);
554 if (!NT_SUCCESS(Status))
555 {
556 TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status);
557 goto done;
558 }
559
560 /* Calculate the LM password and hash for the old password */
561 LmPwdString.Length = 15;
562 LmPwdString.MaximumLength = 15;
563 LmPwdString.Buffer = LmPwdBuffer;
564 ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength);
565
566 Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString,
567 &RequestBuffer->OldPassword,
568 FALSE);
569 if (NT_SUCCESS(Status))
570 {
571 /* Calculate the LM hash value of the password */
572 Status = SystemFunction006(LmPwdString.Buffer,
573 (LPSTR)&OldLmPassword);
574 if (NT_SUCCESS(Status))
575 {
576 OldLmPasswordPresent = TRUE;
577 }
578 }
579
580 /* Calculate the LM password and hash for the new password */
581 LmPwdString.Length = 15;
582 LmPwdString.MaximumLength = 15;
583 LmPwdString.Buffer = LmPwdBuffer;
584 ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength);
585
586 Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString,
587 &RequestBuffer->NewPassword,
588 FALSE);
589 if (NT_SUCCESS(Status))
590 {
591 /* Calculate the LM hash value of the password */
592 Status = SystemFunction006(LmPwdString.Buffer,
593 (LPSTR)&NewLmPassword);
594 if (NT_SUCCESS(Status))
595 {
596 NewLmPasswordPresent = TRUE;
597 }
598 }
599
600 /* Encrypt the old and new LM passwords, if they exist */
601 if (OldLmPasswordPresent && NewLmPasswordPresent)
602 {
603 /* Encrypt the old LM password */
604 Status = SystemFunction012((const BYTE *)&OldLmPassword,
605 (const BYTE *)&NewLmPassword,
606 (LPBYTE)&OldLmEncryptedWithNewLm);
607 if (!NT_SUCCESS(Status))
608 {
609 TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status);
610 goto done;
611 }
612
613 /* Encrypt the new LM password */
614 Status = SystemFunction012((const BYTE *)&NewLmPassword,
615 (const BYTE *)&OldLmPassword,
616 (LPBYTE)&NewLmEncryptedWithOldLm);
617 if (!NT_SUCCESS(Status))
618 {
619 TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status);
620 goto done;
621 }
622
623 pOldLmEncryptedWithNewLm = &OldLmEncryptedWithNewLm;
624 pNewLmEncryptedWithOldLm = &NewLmEncryptedWithOldLm;
625 }
626
627 /* Encrypt the old NT password */
628 Status = SystemFunction012((const BYTE *)&OldNtPassword,
629 (const BYTE *)&NewNtPassword,
630 (LPBYTE)&OldNtEncryptedWithNewNt);
631 if (!NT_SUCCESS(Status))
632 {
633 TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status);
634 goto done;
635 }
636
637 /* Encrypt the new NT password */
638 Status = SystemFunction012((const BYTE *)&NewNtPassword,
639 (const BYTE *)&OldNtPassword,
640 (LPBYTE)&NewNtEncryptedWithOldNt);
641 if (!NT_SUCCESS(Status))
642 {
643 TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status);
644 goto done;
645 }
646
647 /* Change the password */
648 Status = SamrChangePasswordUser(UserHandle,
649 OldLmPasswordPresent && NewLmPasswordPresent,
650 pOldLmEncryptedWithNewLm,
651 pNewLmEncryptedWithOldLm,
652 TRUE,
653 &OldNtEncryptedWithNewNt,
654 &NewNtEncryptedWithOldNt,
655 FALSE,
656 NULL,
657 FALSE,
658 NULL);
659 if (!NT_SUCCESS(Status))
660 {
661 TRACE("SamrChangePasswordUser failed (Status %08lx)\n", Status);
662 goto done;
663 }
664
665 done:
666 if (UserHandle != NULL)
667 SamrCloseHandle(&UserHandle);
668
669 SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds);
670 SamIFree_SAMPR_ULONG_ARRAY(&Use);
671
672 if (DomainHandle != NULL)
673 SamrCloseHandle(&DomainHandle);
674
675 if (DomainSid != NULL)
676 SamIFreeVoid(DomainSid);
677
678 if (ServerHandle != NULL)
679 SamrCloseHandle(&ServerHandle);
680
681 return Status;
682 }
683
684
685 static
686 NTSTATUS
687 MsvpCheckPassword(PUNICODE_STRING UserPassword,
688 PSAMPR_USER_INFO_BUFFER UserInfo)
689 {
690 ENCRYPTED_NT_OWF_PASSWORD UserNtPassword;
691 ENCRYPTED_LM_OWF_PASSWORD UserLmPassword;
692 BOOLEAN UserLmPasswordPresent = FALSE;
693 BOOLEAN UserNtPasswordPresent = FALSE;
694 OEM_STRING LmPwdString;
695 CHAR LmPwdBuffer[15];
696 NTSTATUS Status;
697
698 TRACE("(%p %p)\n", UserPassword, UserInfo);
699
700 /* Calculate the LM password and hash for the users password */
701 LmPwdString.Length = 15;
702 LmPwdString.MaximumLength = 15;
703 LmPwdString.Buffer = LmPwdBuffer;
704 ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength);
705
706 Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString,
707 UserPassword,
708 FALSE);
709 if (NT_SUCCESS(Status))
710 {
711 /* Calculate the LM hash value of the users password */
712 Status = SystemFunction006(LmPwdString.Buffer,
713 (LPSTR)&UserLmPassword);
714 if (NT_SUCCESS(Status))
715 {
716 UserLmPasswordPresent = TRUE;
717 }
718 }
719
720 /* Calculate the NT hash of the users password */
721 Status = SystemFunction007(UserPassword,
722 (LPBYTE)&UserNtPassword);
723 if (NT_SUCCESS(Status))
724 {
725 UserNtPasswordPresent = TRUE;
726 }
727
728 Status = STATUS_WRONG_PASSWORD;
729
730 /* Succeed, if no password has been set */
731 if (UserInfo->All.NtPasswordPresent == FALSE &&
732 UserInfo->All.LmPasswordPresent == FALSE)
733 {
734 TRACE("No password check!\n");
735 Status = STATUS_SUCCESS;
736 goto done;
737 }
738
739 /* Succeed, if NT password matches */
740 if (UserNtPasswordPresent && UserInfo->All.NtPasswordPresent)
741 {
742 TRACE("Check NT password hashes:\n");
743 if (RtlEqualMemory(&UserNtPassword,
744 UserInfo->All.NtOwfPassword.Buffer,
745 sizeof(ENCRYPTED_NT_OWF_PASSWORD)))
746 {
747 TRACE(" success!\n");
748 Status = STATUS_SUCCESS;
749 goto done;
750 }
751
752 TRACE(" failed!\n");
753 }
754
755 /* Succeed, if LM password matches */
756 if (UserLmPasswordPresent && UserInfo->All.LmPasswordPresent)
757 {
758 TRACE("Check LM password hashes:\n");
759 if (RtlEqualMemory(&UserLmPassword,
760 UserInfo->All.LmOwfPassword.Buffer,
761 sizeof(ENCRYPTED_LM_OWF_PASSWORD)))
762 {
763 TRACE(" success!\n");
764 Status = STATUS_SUCCESS;
765 goto done;
766 }
767 TRACE(" failed!\n");
768 }
769
770 done:
771 return Status;
772 }
773
774
775 /*
776 * @unimplemented
777 */
778 NTSTATUS
779 NTAPI
780 LsaApCallPackage(IN PLSA_CLIENT_REQUEST ClientRequest,
781 IN PVOID ProtocolSubmitBuffer,
782 IN PVOID ClientBufferBase,
783 IN ULONG SubmitBufferLength,
784 OUT PVOID *ProtocolReturnBuffer,
785 OUT PULONG ReturnBufferLength,
786 OUT PNTSTATUS ProtocolStatus)
787 {
788 ULONG MessageType;
789 NTSTATUS Status;
790
791 TRACE("()\n");
792
793 if (SubmitBufferLength < sizeof(MSV1_0_PROTOCOL_MESSAGE_TYPE))
794 return STATUS_INVALID_PARAMETER;
795
796 MessageType = (ULONG)*((PMSV1_0_PROTOCOL_MESSAGE_TYPE)ProtocolSubmitBuffer);
797
798 *ProtocolReturnBuffer = NULL;
799 *ReturnBufferLength = 0;
800
801 switch (MessageType)
802 {
803 case MsV1_0Lm20ChallengeRequest:
804 case MsV1_0Lm20GetChallengeResponse:
805 case MsV1_0EnumerateUsers:
806 case MsV1_0GetUserInfo:
807 case MsV1_0ReLogonUsers:
808 Status = STATUS_NOT_IMPLEMENTED;
809 break;
810
811 case MsV1_0ChangePassword:
812 Status = MsvpChangePassword(ClientRequest,
813 ProtocolSubmitBuffer,
814 ClientBufferBase,
815 SubmitBufferLength,
816 ProtocolReturnBuffer,
817 ReturnBufferLength,
818 ProtocolStatus);
819 break;
820
821 case MsV1_0ChangeCachedPassword:
822 case MsV1_0GenericPassthrough:
823 case MsV1_0CacheLogon:
824 case MsV1_0SubAuth:
825 case MsV1_0DeriveCredential:
826 case MsV1_0CacheLookup:
827 Status = STATUS_NOT_IMPLEMENTED;
828 break;
829
830 default:
831 return STATUS_INVALID_PARAMETER;
832 }
833
834 return Status;
835 }
836
837
838 /*
839 * @unimplemented
840 */
841 NTSTATUS
842 NTAPI
843 LsaApCallPackagePassthrough(IN PLSA_CLIENT_REQUEST ClientRequest,
844 IN PVOID ProtocolSubmitBuffer,
845 IN PVOID ClientBufferBase,
846 IN ULONG SubmitBufferLength,
847 OUT PVOID *ProtocolReturnBuffer,
848 OUT PULONG ReturnBufferLength,
849 OUT PNTSTATUS ProtocolStatus)
850 {
851 TRACE("()\n");
852 return STATUS_NOT_IMPLEMENTED;
853 }
854
855
856 /*
857 * @unimplemented
858 */
859 NTSTATUS
860 NTAPI
861 LsaApCallPackageUntrusted(IN PLSA_CLIENT_REQUEST ClientRequest,
862 IN PVOID ProtocolSubmitBuffer,
863 IN PVOID ClientBufferBase,
864 IN ULONG SubmitBufferLength,
865 OUT PVOID *ProtocolReturnBuffer,
866 OUT PULONG ReturnBufferLength,
867 OUT PNTSTATUS ProtocolStatus)
868 {
869 TRACE("()\n");
870 return STATUS_NOT_IMPLEMENTED;
871 }
872
873
874 /*
875 * @unimplemented
876 */
877 NTSTATUS
878 NTAPI
879 LsaApInitializePackage(IN ULONG AuthenticationPackageId,
880 IN PLSA_DISPATCH_TABLE LsaDispatchTable,
881 IN PLSA_STRING Database OPTIONAL,
882 IN PLSA_STRING Confidentiality OPTIONAL,
883 OUT PLSA_STRING *AuthenticationPackageName)
884 {
885 PANSI_STRING NameString;
886 PCHAR NameBuffer;
887
888 TRACE("(%lu %p %p %p %p)\n",
889 AuthenticationPackageId, LsaDispatchTable, Database,
890 Confidentiality, AuthenticationPackageName);
891
892 /* Get the dispatch table entries */
893 DispatchTable.CreateLogonSession = LsaDispatchTable->CreateLogonSession;
894 DispatchTable.DeleteLogonSession = LsaDispatchTable->DeleteLogonSession;
895 DispatchTable.AddCredential = LsaDispatchTable->AddCredential;
896 DispatchTable.GetCredentials = LsaDispatchTable->GetCredentials;
897 DispatchTable.DeleteCredential = LsaDispatchTable->DeleteCredential;
898 DispatchTable.AllocateLsaHeap = LsaDispatchTable->AllocateLsaHeap;
899 DispatchTable.FreeLsaHeap = LsaDispatchTable->FreeLsaHeap;
900 DispatchTable.AllocateClientBuffer = LsaDispatchTable->AllocateClientBuffer;
901 DispatchTable.FreeClientBuffer = LsaDispatchTable->FreeClientBuffer;
902 DispatchTable.CopyToClientBuffer = LsaDispatchTable->CopyToClientBuffer;
903 DispatchTable.CopyFromClientBuffer = LsaDispatchTable->CopyFromClientBuffer;
904
905 /* Return the package name */
906 NameString = DispatchTable.AllocateLsaHeap(sizeof(LSA_STRING));
907 if (NameString == NULL)
908 return STATUS_INSUFFICIENT_RESOURCES;
909
910 NameBuffer = DispatchTable.AllocateLsaHeap(sizeof(MSV1_0_PACKAGE_NAME));
911 if (NameBuffer == NULL)
912 {
913 DispatchTable.FreeLsaHeap(NameString);
914 return STATUS_INSUFFICIENT_RESOURCES;
915 }
916
917 strcpy(NameBuffer, MSV1_0_PACKAGE_NAME);
918
919 RtlInitAnsiString(NameString, NameBuffer);
920
921 *AuthenticationPackageName = (PLSA_STRING)NameString;
922
923 return STATUS_SUCCESS;
924 }
925
926
927 /*
928 * @unimplemented
929 */
930 VOID
931 NTAPI
932 LsaApLogonTerminated(IN PLUID LogonId)
933 {
934 TRACE("()\n");
935 }
936
937
938 /*
939 * @unimplemented
940 */
941 NTSTATUS
942 NTAPI
943 LsaApLogonUser(IN PLSA_CLIENT_REQUEST ClientRequest,
944 IN SECURITY_LOGON_TYPE LogonType,
945 IN PVOID AuthenticationInformation,
946 IN PVOID ClientAuthenticationBase,
947 IN ULONG AuthenticationInformationLength,
948 OUT PVOID *ProfileBuffer,
949 OUT PULONG ProfileBufferLength,
950 OUT PLUID LogonId,
951 OUT PNTSTATUS SubStatus,
952 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType,
953 OUT PVOID *TokenInformation,
954 OUT PLSA_UNICODE_STRING *AccountName,
955 OUT PLSA_UNICODE_STRING *AuthenticatingAuthority)
956 {
957 PMSV1_0_INTERACTIVE_LOGON LogonInfo;
958
959 SAMPR_HANDLE ServerHandle = NULL;
960 SAMPR_HANDLE DomainHandle = NULL;
961 SAMPR_HANDLE UserHandle = NULL;
962 PRPC_SID AccountDomainSid = NULL;
963 RPC_UNICODE_STRING Names[1];
964 SAMPR_ULONG_ARRAY RelativeIds = {0, NULL};
965 SAMPR_ULONG_ARRAY Use = {0, NULL};
966 PSAMPR_USER_INFO_BUFFER UserInfo = NULL;
967 UNICODE_STRING LogonServer;
968 BOOLEAN SessionCreated = FALSE;
969 NTSTATUS Status;
970
971 TRACE("()\n");
972
973 TRACE("LogonType: %lu\n", LogonType);
974 TRACE("AuthenticationInformation: %p\n", AuthenticationInformation);
975 TRACE("AuthenticationInformationLength: %lu\n", AuthenticationInformationLength);
976
977 *ProfileBuffer = NULL;
978 *ProfileBufferLength = 0;
979 *SubStatus = STATUS_SUCCESS;
980
981 if (LogonType == Interactive ||
982 LogonType == Batch ||
983 LogonType == Service)
984 {
985 ULONG_PTR PtrOffset;
986
987 LogonInfo = (PMSV1_0_INTERACTIVE_LOGON)AuthenticationInformation;
988
989 /* Fix-up pointers in the authentication info */
990 PtrOffset = (ULONG_PTR)AuthenticationInformation - (ULONG_PTR)ClientAuthenticationBase;
991
992 LogonInfo->LogonDomainName.Buffer = FIXUP_POINTER(LogonInfo->LogonDomainName.Buffer, PtrOffset);
993 LogonInfo->UserName.Buffer = FIXUP_POINTER(LogonInfo->UserName.Buffer, PtrOffset);
994 LogonInfo->Password.Buffer = FIXUP_POINTER(LogonInfo->Password.Buffer, PtrOffset);
995
996 TRACE("Domain: %S\n", LogonInfo->LogonDomainName.Buffer);
997 TRACE("User: %S\n", LogonInfo->UserName.Buffer);
998 TRACE("Password: %S\n", LogonInfo->Password.Buffer);
999
1000 RtlInitUnicodeString(&LogonServer, L"Testserver");
1001 }
1002 else
1003 {
1004 FIXME("LogonType %lu is not supported yet!\n", LogonType);
1005 return STATUS_NOT_IMPLEMENTED;
1006 }
1007
1008 Status = GetDomainSid(&AccountDomainSid);
1009 if (!NT_SUCCESS(Status))
1010 {
1011 TRACE("GetDomainSid() failed (Status 0x%08lx)\n", Status);
1012 return Status;
1013 }
1014
1015 /* Connect to the SAM server */
1016 Status = SamIConnect(NULL,
1017 &ServerHandle,
1018 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
1019 TRUE);
1020 if (!NT_SUCCESS(Status))
1021 {
1022 TRACE("SamIConnect() failed (Status 0x%08lx)\n", Status);
1023 goto done;
1024 }
1025
1026 /* Open the account domain */
1027 Status = SamrOpenDomain(ServerHandle,
1028 DOMAIN_LOOKUP,
1029 AccountDomainSid,
1030 &DomainHandle);
1031 if (!NT_SUCCESS(Status))
1032 {
1033 TRACE("SamrOpenDomain failed (Status %08lx)\n", Status);
1034 goto done;
1035 }
1036
1037 Names[0].Length = LogonInfo->UserName.Length;
1038 Names[0].MaximumLength = LogonInfo->UserName.MaximumLength;
1039 Names[0].Buffer = LogonInfo->UserName.Buffer;
1040
1041 /* Try to get the RID for the user name */
1042 Status = SamrLookupNamesInDomain(DomainHandle,
1043 1,
1044 Names,
1045 &RelativeIds,
1046 &Use);
1047 if (!NT_SUCCESS(Status))
1048 {
1049 TRACE("SamrLookupNamesInDomain failed (Status %08lx)\n", Status);
1050 Status = STATUS_NO_SUCH_USER;
1051 goto done;
1052 }
1053
1054 /* Fail, if it is not a user account */
1055 if (Use.Element[0] != SidTypeUser)
1056 {
1057 TRACE("Account is not a user account!\n");
1058 Status = STATUS_NO_SUCH_USER;
1059 goto done;
1060 }
1061
1062 /* Open the user object */
1063 Status = SamrOpenUser(DomainHandle,
1064 USER_READ_GENERAL | USER_READ_LOGON |
1065 USER_READ_ACCOUNT | USER_READ_PREFERENCES, /* FIXME */
1066 RelativeIds.Element[0],
1067 &UserHandle);
1068 if (!NT_SUCCESS(Status))
1069 {
1070 TRACE("SamrOpenUser failed (Status %08lx)\n", Status);
1071 goto done;
1072 }
1073
1074 Status = SamrQueryInformationUser(UserHandle,
1075 UserAllInformation,
1076 &UserInfo);
1077 if (!NT_SUCCESS(Status))
1078 {
1079 TRACE("SamrQueryInformationUser failed (Status %08lx)\n", Status);
1080 goto done;
1081 }
1082
1083
1084 TRACE("UserName: %S\n", UserInfo->All.UserName.Buffer);
1085
1086 /* Check account restrictions for non-administrator accounts */
1087 if (RelativeIds.Element[0] != DOMAIN_USER_RID_ADMIN)
1088 {
1089 /* Check if the account has been disabled */
1090 if (UserInfo->All.UserAccountControl & USER_ACCOUNT_DISABLED)
1091 {
1092 ERR("Account disabled!\n");
1093 *SubStatus = STATUS_ACCOUNT_DISABLED;
1094 Status = STATUS_ACCOUNT_RESTRICTION;
1095 goto done;
1096 }
1097
1098 /* Check if the account has been locked */
1099 if (UserInfo->All.UserAccountControl & USER_ACCOUNT_AUTO_LOCKED)
1100 {
1101 ERR("Account disabled!\n");
1102 *SubStatus = STATUS_ACCOUNT_LOCKED_OUT;
1103 Status = STATUS_ACCOUNT_RESTRICTION;
1104 goto done;
1105 }
1106
1107 /* FIXME: more checks */
1108 // *SubStatus = STATUS_PASSWORD_EXPIRED;
1109 // *SubStatus = STATUS_INVALID_LOGON_HOURS;
1110 // *SubStatus = STATUS_INVALID_WORKSTATION;
1111
1112 }
1113
1114 /* Check the password */
1115 if ((UserInfo->All.UserAccountControl & USER_PASSWORD_NOT_REQUIRED) == 0)
1116 {
1117 Status = MsvpCheckPassword(&(LogonInfo->Password),
1118 UserInfo);
1119 if (!NT_SUCCESS(Status))
1120 {
1121 TRACE("MsvpCheckPassword failed (Status %08lx)\n", Status);
1122 goto done;
1123 }
1124 }
1125
1126 /* Return logon information */
1127
1128 /* Create and return a new logon id */
1129 Status = NtAllocateLocallyUniqueId(LogonId);
1130 if (!NT_SUCCESS(Status))
1131 {
1132 TRACE("NtAllocateLocallyUniqueId failed (Status %08lx)\n", Status);
1133 goto done;
1134 }
1135
1136 /* Create the logon session */
1137 Status = DispatchTable.CreateLogonSession(LogonId);
1138 if (!NT_SUCCESS(Status))
1139 {
1140 TRACE("CreateLogonSession failed (Status %08lx)\n", Status);
1141 goto done;
1142 }
1143
1144 SessionCreated = TRUE;
1145
1146 /* Build and fill the interactve profile buffer */
1147 Status = BuildInteractiveProfileBuffer(ClientRequest,
1148 UserInfo,
1149 &LogonServer,
1150 (PMSV1_0_INTERACTIVE_PROFILE*)ProfileBuffer,
1151 ProfileBufferLength);
1152 if (!NT_SUCCESS(Status))
1153 {
1154 TRACE("BuildInteractiveProfileBuffer failed (Status %08lx)\n", Status);
1155 goto done;
1156 }
1157
1158 /* Return the token information type */
1159 *TokenInformationType = LsaTokenInformationV1;
1160
1161 /* Build and fill the token information buffer */
1162 Status = BuildTokenInformationBuffer((PLSA_TOKEN_INFORMATION_V1*)TokenInformation,
1163 AccountDomainSid,
1164 UserInfo);
1165 if (!NT_SUCCESS(Status))
1166 {
1167 TRACE("BuildTokenInformationBuffer failed (Status %08lx)\n", Status);
1168 goto done;
1169 }
1170
1171 done:
1172 /* Return the account name */
1173 *AccountName = DispatchTable.AllocateLsaHeap(sizeof(UNICODE_STRING));
1174 if (*AccountName != NULL)
1175 {
1176 (*AccountName)->Buffer = DispatchTable.AllocateLsaHeap(LogonInfo->UserName.Length +
1177 sizeof(UNICODE_NULL));
1178 if ((*AccountName)->Buffer != NULL)
1179 {
1180 (*AccountName)->MaximumLength = LogonInfo->UserName.Length +
1181 sizeof(UNICODE_NULL);
1182 RtlCopyUnicodeString(*AccountName, &LogonInfo->UserName);
1183 }
1184 }
1185
1186 if (!NT_SUCCESS(Status))
1187 {
1188 if (SessionCreated == TRUE)
1189 DispatchTable.DeleteLogonSession(LogonId);
1190
1191 if (*ProfileBuffer != NULL)
1192 {
1193 DispatchTable.FreeClientBuffer(ClientRequest,
1194 *ProfileBuffer);
1195 *ProfileBuffer = NULL;
1196 }
1197 }
1198
1199 if (UserHandle != NULL)
1200 SamrCloseHandle(&UserHandle);
1201
1202 SamIFree_SAMPR_USER_INFO_BUFFER(UserInfo,
1203 UserAllInformation);
1204 SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds);
1205 SamIFree_SAMPR_ULONG_ARRAY(&Use);
1206
1207 if (DomainHandle != NULL)
1208 SamrCloseHandle(&DomainHandle);
1209
1210 if (ServerHandle != NULL)
1211 SamrCloseHandle(&ServerHandle);
1212
1213 if (AccountDomainSid != NULL)
1214 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);
1215
1216 if (Status == STATUS_NO_SUCH_USER ||
1217 Status == STATUS_WRONG_PASSWORD)
1218 {
1219 *SubStatus = Status;
1220 Status = STATUS_LOGON_FAILURE;
1221 }
1222
1223 TRACE("LsaApLogonUser done (Status %08lx)\n", Status);
1224
1225 return Status;
1226 }
1227
1228
1229 /*
1230 * @unimplemented
1231 */
1232 #if 0
1233 NTSTATUS
1234 NTAPI
1235 LsaApLogonUserEx(IN PLSA_CLIENT_REQUEST ClientRequest,
1236 IN SECURITY_LOGON_TYPE LogonType,
1237 IN PVOID AuthenticationInformation,
1238 IN PVOID ClientAuthenticationBase,
1239 IN ULONG AuthenticationInformationLength,
1240 OUT PVOID *ProfileBuffer,
1241 OUT PULONG ProfileBufferLength,
1242 OUT PLUID LogonId,
1243 OUT PNTSTATUS SubStatus,
1244 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType,
1245 OUT PVOID *TokenInformation,
1246 OUT PUNICODE_STRING *AccountName,
1247 OUT PUNICODE_STRING *AuthenticatingAuthority,
1248 OUT PUNICODE_STRING *MachineName)
1249 {
1250 TRACE("()\n");
1251
1252 TRACE("LogonType: %lu\n", LogonType);
1253 TRACE("AuthenticationInformation: %p\n", AuthenticationInformation);
1254 TRACE("AuthenticationInformationLength: %lu\n", AuthenticationInformationLength);
1255
1256 return STATUS_NOT_IMPLEMENTED;
1257 }
1258
1259
1260 /*
1261 * @unimplemented
1262 */
1263 NTSTATUS
1264 NTAPI
1265 LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest,
1266 IN SECURITY_LOGON_TYPE LogonType,
1267 IN PVOID ProtocolSubmitBuffer,
1268 IN PVOID ClientBufferBase,
1269 IN ULONG SubmitBufferSize,
1270 OUT PVOID *ProfileBuffer,
1271 OUT PULONG ProfileBufferSize,
1272 OUT PLUID LogonId,
1273 OUT PNTSTATUS SubStatus,
1274 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType,
1275 OUT PVOID *TokenInformation,
1276 OUT PUNICODE_STRING *AccountName,
1277 OUT PUNICODE_STRING *AuthenticatingAuthority,
1278 OUT PUNICODE_STRING *MachineName,
1279 OUT PSECPKG_PRIMARY_CRED PrimaryCredentials,
1280 OUT PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials)
1281 {
1282 TRACE("()\n");
1283
1284 TRACE("LogonType: %lu\n", LogonType);
1285 TRACE("ProtocolSubmitBuffer: %p\n", ProtocolSubmitBuffer);
1286 TRACE("SubmitBufferSize: %lu\n", SubmitBufferSize);
1287
1288
1289 return STATUS_NOT_IMPLEMENTED;
1290 }
1291 #endif
1292
1293 /* EOF */