4c080fb5575318da60b1b20247dd53411b1a94fa
[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 TRACE("()\n");
432
433 RequestBuffer = (PMSV1_0_CHANGEPASSWORD_REQUEST)ProtocolSubmitBuffer;
434
435 /* Fix-up pointers in the request buffer info */
436 PtrOffset = (ULONG_PTR)ProtocolSubmitBuffer - (ULONG_PTR)ClientBufferBase;
437
438 RequestBuffer->DomainName.Buffer = FIXUP_POINTER(RequestBuffer->DomainName.Buffer, PtrOffset);
439 RequestBuffer->AccountName.Buffer = FIXUP_POINTER(RequestBuffer->AccountName.Buffer, PtrOffset);
440 RequestBuffer->OldPassword.Buffer = FIXUP_POINTER(RequestBuffer->OldPassword.Buffer, PtrOffset);
441 RequestBuffer->NewPassword.Buffer = FIXUP_POINTER(RequestBuffer->NewPassword.Buffer, PtrOffset);
442
443 TRACE("Domain: %S\n", RequestBuffer->DomainName.Buffer);
444 TRACE("Account: %S\n", RequestBuffer->AccountName.Buffer);
445 TRACE("Old Password: %S\n", RequestBuffer->OldPassword.Buffer);
446 TRACE("New Password: %S\n", RequestBuffer->NewPassword.Buffer);
447
448
449 return STATUS_SUCCESS;
450 }
451
452
453 static
454 NTSTATUS
455 MsvpCheckPassword(PUNICODE_STRING UserPassword,
456 PSAMPR_USER_INFO_BUFFER UserInfo)
457 {
458 ENCRYPTED_NT_OWF_PASSWORD UserNtPassword;
459 ENCRYPTED_LM_OWF_PASSWORD UserLmPassword;
460 BOOLEAN UserLmPasswordPresent = FALSE;
461 BOOLEAN UserNtPasswordPresent = FALSE;
462 OEM_STRING LmPwdString;
463 CHAR LmPwdBuffer[15];
464 NTSTATUS Status;
465
466 TRACE("(%p %p)\n", UserPassword, UserInfo);
467
468 /* Calculate the LM password and hash for the users password */
469 LmPwdString.Length = 15;
470 LmPwdString.MaximumLength = 15;
471 LmPwdString.Buffer = LmPwdBuffer;
472 ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength);
473
474 Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString,
475 UserPassword,
476 FALSE);
477 if (NT_SUCCESS(Status))
478 {
479 /* Calculate the LM hash value of the users password */
480 Status = SystemFunction006(LmPwdString.Buffer,
481 (LPSTR)&UserLmPassword);
482 if (NT_SUCCESS(Status))
483 {
484 UserLmPasswordPresent = TRUE;
485 }
486 }
487
488 /* Calculate the NT hash of the users password */
489 Status = SystemFunction007(UserPassword,
490 (LPBYTE)&UserNtPassword);
491 if (NT_SUCCESS(Status))
492 {
493 UserNtPasswordPresent = TRUE;
494 }
495
496 Status = STATUS_WRONG_PASSWORD;
497
498 /* Succeed, if no password has been set */
499 if (UserInfo->All.NtPasswordPresent == FALSE &&
500 UserInfo->All.LmPasswordPresent == FALSE)
501 {
502 TRACE("No password check!\n");
503 Status = STATUS_SUCCESS;
504 goto done;
505 }
506
507 /* Succeed, if NT password matches */
508 if (UserNtPasswordPresent && UserInfo->All.NtPasswordPresent)
509 {
510 TRACE("Check NT password hashes:\n");
511 if (RtlEqualMemory(&UserNtPassword,
512 UserInfo->All.NtOwfPassword.Buffer,
513 sizeof(ENCRYPTED_NT_OWF_PASSWORD)))
514 {
515 TRACE(" success!\n");
516 Status = STATUS_SUCCESS;
517 goto done;
518 }
519
520 TRACE(" failed!\n");
521 }
522
523 /* Succeed, if LM password matches */
524 if (UserLmPasswordPresent && UserInfo->All.LmPasswordPresent)
525 {
526 TRACE("Check LM password hashes:\n");
527 if (RtlEqualMemory(&UserLmPassword,
528 UserInfo->All.LmOwfPassword.Buffer,
529 sizeof(ENCRYPTED_LM_OWF_PASSWORD)))
530 {
531 TRACE(" success!\n");
532 Status = STATUS_SUCCESS;
533 goto done;
534 }
535 TRACE(" failed!\n");
536 }
537
538 done:
539 return Status;
540 }
541
542
543 /*
544 * @unimplemented
545 */
546 NTSTATUS
547 NTAPI
548 LsaApCallPackage(IN PLSA_CLIENT_REQUEST ClientRequest,
549 IN PVOID ProtocolSubmitBuffer,
550 IN PVOID ClientBufferBase,
551 IN ULONG SubmitBufferLength,
552 OUT PVOID *ProtocolReturnBuffer,
553 OUT PULONG ReturnBufferLength,
554 OUT PNTSTATUS ProtocolStatus)
555 {
556 ULONG MessageType;
557 NTSTATUS Status;
558
559 TRACE("()\n");
560
561 if (SubmitBufferLength < sizeof(MSV1_0_PROTOCOL_MESSAGE_TYPE))
562 return STATUS_INVALID_PARAMETER;
563
564 MessageType = (ULONG)*((PMSV1_0_PROTOCOL_MESSAGE_TYPE)ProtocolSubmitBuffer);
565
566 *ProtocolReturnBuffer = NULL;
567 *ReturnBufferLength = 0;
568
569 switch (MessageType)
570 {
571 case MsV1_0Lm20ChallengeRequest:
572 case MsV1_0Lm20GetChallengeResponse:
573 case MsV1_0EnumerateUsers:
574 case MsV1_0GetUserInfo:
575 case MsV1_0ReLogonUsers:
576 Status = STATUS_NOT_IMPLEMENTED;
577 break;
578
579 case MsV1_0ChangePassword:
580 Status = MsvpChangePassword(ClientRequest,
581 ProtocolSubmitBuffer,
582 ClientBufferBase,
583 SubmitBufferLength,
584 ProtocolReturnBuffer,
585 ReturnBufferLength,
586 ProtocolStatus);
587 break;
588
589 case MsV1_0ChangeCachedPassword:
590 case MsV1_0GenericPassthrough:
591 case MsV1_0CacheLogon:
592 case MsV1_0SubAuth:
593 case MsV1_0DeriveCredential:
594 case MsV1_0CacheLookup:
595 Status = STATUS_NOT_IMPLEMENTED;
596 break;
597
598 default:
599 return STATUS_INVALID_PARAMETER;
600 }
601
602 return Status;
603 }
604
605
606 /*
607 * @unimplemented
608 */
609 NTSTATUS
610 NTAPI
611 LsaApCallPackagePassthrough(IN PLSA_CLIENT_REQUEST ClientRequest,
612 IN PVOID ProtocolSubmitBuffer,
613 IN PVOID ClientBufferBase,
614 IN ULONG SubmitBufferLength,
615 OUT PVOID *ProtocolReturnBuffer,
616 OUT PULONG ReturnBufferLength,
617 OUT PNTSTATUS ProtocolStatus)
618 {
619 TRACE("()\n");
620 return STATUS_NOT_IMPLEMENTED;
621 }
622
623
624 /*
625 * @unimplemented
626 */
627 NTSTATUS
628 NTAPI
629 LsaApCallPackageUntrusted(IN PLSA_CLIENT_REQUEST ClientRequest,
630 IN PVOID ProtocolSubmitBuffer,
631 IN PVOID ClientBufferBase,
632 IN ULONG SubmitBufferLength,
633 OUT PVOID *ProtocolReturnBuffer,
634 OUT PULONG ReturnBufferLength,
635 OUT PNTSTATUS ProtocolStatus)
636 {
637 TRACE("()\n");
638 return STATUS_NOT_IMPLEMENTED;
639 }
640
641
642 /*
643 * @unimplemented
644 */
645 NTSTATUS
646 NTAPI
647 LsaApInitializePackage(IN ULONG AuthenticationPackageId,
648 IN PLSA_DISPATCH_TABLE LsaDispatchTable,
649 IN PLSA_STRING Database OPTIONAL,
650 IN PLSA_STRING Confidentiality OPTIONAL,
651 OUT PLSA_STRING *AuthenticationPackageName)
652 {
653 PANSI_STRING NameString;
654 PCHAR NameBuffer;
655
656 TRACE("(%lu %p %p %p %p)\n",
657 AuthenticationPackageId, LsaDispatchTable, Database,
658 Confidentiality, AuthenticationPackageName);
659
660 /* Get the dispatch table entries */
661 DispatchTable.CreateLogonSession = LsaDispatchTable->CreateLogonSession;
662 DispatchTable.DeleteLogonSession = LsaDispatchTable->DeleteLogonSession;
663 DispatchTable.AddCredential = LsaDispatchTable->AddCredential;
664 DispatchTable.GetCredentials = LsaDispatchTable->GetCredentials;
665 DispatchTable.DeleteCredential = LsaDispatchTable->DeleteCredential;
666 DispatchTable.AllocateLsaHeap = LsaDispatchTable->AllocateLsaHeap;
667 DispatchTable.FreeLsaHeap = LsaDispatchTable->FreeLsaHeap;
668 DispatchTable.AllocateClientBuffer = LsaDispatchTable->AllocateClientBuffer;
669 DispatchTable.FreeClientBuffer = LsaDispatchTable->FreeClientBuffer;
670 DispatchTable.CopyToClientBuffer = LsaDispatchTable->CopyToClientBuffer;
671 DispatchTable.CopyFromClientBuffer = LsaDispatchTable->CopyFromClientBuffer;
672
673 /* Return the package name */
674 NameString = DispatchTable.AllocateLsaHeap(sizeof(LSA_STRING));
675 if (NameString == NULL)
676 return STATUS_INSUFFICIENT_RESOURCES;
677
678 NameBuffer = DispatchTable.AllocateLsaHeap(sizeof(MSV1_0_PACKAGE_NAME));
679 if (NameBuffer == NULL)
680 {
681 DispatchTable.FreeLsaHeap(NameString);
682 return STATUS_INSUFFICIENT_RESOURCES;
683 }
684
685 strcpy(NameBuffer, MSV1_0_PACKAGE_NAME);
686
687 RtlInitAnsiString(NameString, NameBuffer);
688
689 *AuthenticationPackageName = (PLSA_STRING)NameString;
690
691 return STATUS_SUCCESS;
692 }
693
694
695 /*
696 * @unimplemented
697 */
698 VOID
699 NTAPI
700 LsaApLogonTerminated(IN PLUID LogonId)
701 {
702 TRACE("()\n");
703 }
704
705
706 /*
707 * @unimplemented
708 */
709 NTSTATUS
710 NTAPI
711 LsaApLogonUser(IN PLSA_CLIENT_REQUEST ClientRequest,
712 IN SECURITY_LOGON_TYPE LogonType,
713 IN PVOID AuthenticationInformation,
714 IN PVOID ClientAuthenticationBase,
715 IN ULONG AuthenticationInformationLength,
716 OUT PVOID *ProfileBuffer,
717 OUT PULONG ProfileBufferLength,
718 OUT PLUID LogonId,
719 OUT PNTSTATUS SubStatus,
720 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType,
721 OUT PVOID *TokenInformation,
722 OUT PLSA_UNICODE_STRING *AccountName,
723 OUT PLSA_UNICODE_STRING *AuthenticatingAuthority)
724 {
725 PMSV1_0_INTERACTIVE_LOGON LogonInfo;
726
727 SAMPR_HANDLE ServerHandle = NULL;
728 SAMPR_HANDLE DomainHandle = NULL;
729 SAMPR_HANDLE UserHandle = NULL;
730 PRPC_SID AccountDomainSid = NULL;
731 RPC_UNICODE_STRING Names[1];
732 SAMPR_ULONG_ARRAY RelativeIds = {0, NULL};
733 SAMPR_ULONG_ARRAY Use = {0, NULL};
734 PSAMPR_USER_INFO_BUFFER UserInfo = NULL;
735 UNICODE_STRING LogonServer;
736 BOOLEAN SessionCreated = FALSE;
737 NTSTATUS Status;
738
739 TRACE("()\n");
740
741 TRACE("LogonType: %lu\n", LogonType);
742 TRACE("AuthenticationInformation: %p\n", AuthenticationInformation);
743 TRACE("AuthenticationInformationLength: %lu\n", AuthenticationInformationLength);
744
745 *ProfileBuffer = NULL;
746 *ProfileBufferLength = 0;
747 *SubStatus = STATUS_SUCCESS;
748
749 if (LogonType == Interactive ||
750 LogonType == Batch ||
751 LogonType == Service)
752 {
753 ULONG_PTR PtrOffset;
754
755 LogonInfo = (PMSV1_0_INTERACTIVE_LOGON)AuthenticationInformation;
756
757 /* Fix-up pointers in the authentication info */
758 PtrOffset = (ULONG_PTR)AuthenticationInformation - (ULONG_PTR)ClientAuthenticationBase;
759
760 LogonInfo->LogonDomainName.Buffer = FIXUP_POINTER(LogonInfo->LogonDomainName.Buffer, PtrOffset);
761 LogonInfo->UserName.Buffer = FIXUP_POINTER(LogonInfo->UserName.Buffer, PtrOffset);
762 LogonInfo->Password.Buffer = FIXUP_POINTER(LogonInfo->Password.Buffer, PtrOffset);
763
764 TRACE("Domain: %S\n", LogonInfo->LogonDomainName.Buffer);
765 TRACE("User: %S\n", LogonInfo->UserName.Buffer);
766 TRACE("Password: %S\n", LogonInfo->Password.Buffer);
767
768 RtlInitUnicodeString(&LogonServer, L"Testserver");
769 }
770 else
771 {
772 FIXME("LogonType %lu is not supported yet!\n", LogonType);
773 return STATUS_NOT_IMPLEMENTED;
774 }
775
776 Status = GetDomainSid(&AccountDomainSid);
777 if (!NT_SUCCESS(Status))
778 {
779 TRACE("GetDomainSid() failed (Status 0x%08lx)\n", Status);
780 return Status;
781 }
782
783 /* Connect to the SAM server */
784 Status = SamIConnect(NULL,
785 &ServerHandle,
786 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
787 TRUE);
788 if (!NT_SUCCESS(Status))
789 {
790 TRACE("SamIConnect() failed (Status 0x%08lx)\n", Status);
791 goto done;
792 }
793
794 /* Open the account domain */
795 Status = SamrOpenDomain(ServerHandle,
796 DOMAIN_LOOKUP,
797 AccountDomainSid,
798 &DomainHandle);
799 if (!NT_SUCCESS(Status))
800 {
801 TRACE("SamrOpenDomain failed (Status %08lx)\n", Status);
802 goto done;
803 }
804
805 Names[0].Length = LogonInfo->UserName.Length;
806 Names[0].MaximumLength = LogonInfo->UserName.MaximumLength;
807 Names[0].Buffer = LogonInfo->UserName.Buffer;
808
809 /* Try to get the RID for the user name */
810 Status = SamrLookupNamesInDomain(DomainHandle,
811 1,
812 Names,
813 &RelativeIds,
814 &Use);
815 if (!NT_SUCCESS(Status))
816 {
817 TRACE("SamrLookupNamesInDomain failed (Status %08lx)\n", Status);
818 Status = STATUS_NO_SUCH_USER;
819 goto done;
820 }
821
822 /* Fail, if it is not a user account */
823 if (Use.Element[0] != SidTypeUser)
824 {
825 TRACE("Account is not a user account!\n");
826 Status = STATUS_NO_SUCH_USER;
827 goto done;
828 }
829
830 /* Open the user object */
831 Status = SamrOpenUser(DomainHandle,
832 USER_READ_GENERAL | USER_READ_LOGON |
833 USER_READ_ACCOUNT | USER_READ_PREFERENCES, /* FIXME */
834 RelativeIds.Element[0],
835 &UserHandle);
836 if (!NT_SUCCESS(Status))
837 {
838 TRACE("SamrOpenUser failed (Status %08lx)\n", Status);
839 goto done;
840 }
841
842 Status = SamrQueryInformationUser(UserHandle,
843 UserAllInformation,
844 &UserInfo);
845 if (!NT_SUCCESS(Status))
846 {
847 TRACE("SamrQueryInformationUser failed (Status %08lx)\n", Status);
848 goto done;
849 }
850
851
852 TRACE("UserName: %S\n", UserInfo->All.UserName.Buffer);
853
854 /* FIXME: Check restrictions */
855
856 /* Check the password */
857 if ((UserInfo->All.UserAccountControl & USER_PASSWORD_NOT_REQUIRED) == 0)
858 {
859 Status = MsvpCheckPassword(&(LogonInfo->Password),
860 UserInfo);
861 if (!NT_SUCCESS(Status))
862 {
863 TRACE("MsvpCheckPassword failed (Status %08lx)\n", Status);
864 goto done;
865 }
866 }
867
868 /* Return logon information */
869
870 /* Create and return a new logon id */
871 Status = NtAllocateLocallyUniqueId(LogonId);
872 if (!NT_SUCCESS(Status))
873 {
874 TRACE("NtAllocateLocallyUniqueId failed (Status %08lx)\n", Status);
875 goto done;
876 }
877
878 /* Create the logon session */
879 Status = DispatchTable.CreateLogonSession(LogonId);
880 if (!NT_SUCCESS(Status))
881 {
882 TRACE("CreateLogonSession failed (Status %08lx)\n", Status);
883 goto done;
884 }
885
886 SessionCreated = TRUE;
887
888 /* Build and fill the interactve profile buffer */
889 Status = BuildInteractiveProfileBuffer(ClientRequest,
890 UserInfo,
891 &LogonServer,
892 (PMSV1_0_INTERACTIVE_PROFILE*)ProfileBuffer,
893 ProfileBufferLength);
894 if (!NT_SUCCESS(Status))
895 {
896 TRACE("BuildInteractiveProfileBuffer failed (Status %08lx)\n", Status);
897 goto done;
898 }
899
900 /* Return the token information type */
901 *TokenInformationType = LsaTokenInformationV1;
902
903 /* Build and fill the token information buffer */
904 Status = BuildTokenInformationBuffer((PLSA_TOKEN_INFORMATION_V1*)TokenInformation,
905 AccountDomainSid,
906 UserInfo);
907 if (!NT_SUCCESS(Status))
908 {
909 TRACE("BuildTokenInformationBuffer failed (Status %08lx)\n", Status);
910 goto done;
911 }
912
913 done:
914 /* Return the account name */
915 *AccountName = DispatchTable.AllocateLsaHeap(sizeof(UNICODE_STRING));
916 if (*AccountName != NULL)
917 {
918 (*AccountName)->Buffer = DispatchTable.AllocateLsaHeap(LogonInfo->UserName.Length +
919 sizeof(UNICODE_NULL));
920 if ((*AccountName)->Buffer != NULL)
921 {
922 (*AccountName)->MaximumLength = LogonInfo->UserName.Length +
923 sizeof(UNICODE_NULL);
924 RtlCopyUnicodeString(*AccountName, &LogonInfo->UserName);
925 }
926 }
927
928 if (!NT_SUCCESS(Status))
929 {
930 if (SessionCreated == TRUE)
931 DispatchTable.DeleteLogonSession(LogonId);
932
933 if (*ProfileBuffer != NULL)
934 {
935 DispatchTable.FreeClientBuffer(ClientRequest,
936 *ProfileBuffer);
937 *ProfileBuffer = NULL;
938 }
939 }
940
941 if (UserHandle != NULL)
942 SamrCloseHandle(&UserHandle);
943
944 SamIFree_SAMPR_USER_INFO_BUFFER(UserInfo,
945 UserAllInformation);
946 SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds);
947 SamIFree_SAMPR_ULONG_ARRAY(&Use);
948
949 if (DomainHandle != NULL)
950 SamrCloseHandle(&DomainHandle);
951
952 if (ServerHandle != NULL)
953 SamrCloseHandle(&ServerHandle);
954
955 if (AccountDomainSid != NULL)
956 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);
957
958 if (Status == STATUS_NO_SUCH_USER ||
959 Status == STATUS_WRONG_PASSWORD)
960 {
961 *SubStatus = Status;
962 Status = STATUS_LOGON_FAILURE;
963 }
964
965 TRACE("LsaApLogonUser done (Status %08lx)\n", Status);
966
967 return Status;
968 }
969
970
971 /*
972 * @unimplemented
973 */
974 #if 0
975 NTSTATUS
976 NTAPI
977 LsaApLogonUserEx(IN PLSA_CLIENT_REQUEST ClientRequest,
978 IN SECURITY_LOGON_TYPE LogonType,
979 IN PVOID AuthenticationInformation,
980 IN PVOID ClientAuthenticationBase,
981 IN ULONG AuthenticationInformationLength,
982 OUT PVOID *ProfileBuffer,
983 OUT PULONG ProfileBufferLength,
984 OUT PLUID LogonId,
985 OUT PNTSTATUS SubStatus,
986 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType,
987 OUT PVOID *TokenInformation,
988 OUT PUNICODE_STRING *AccountName,
989 OUT PUNICODE_STRING *AuthenticatingAuthority,
990 OUT PUNICODE_STRING *MachineName)
991 {
992 TRACE("()\n");
993
994 TRACE("LogonType: %lu\n", LogonType);
995 TRACE("AuthenticationInformation: %p\n", AuthenticationInformation);
996 TRACE("AuthenticationInformationLength: %lu\n", AuthenticationInformationLength);
997
998 return STATUS_NOT_IMPLEMENTED;
999 }
1000
1001
1002 /*
1003 * @unimplemented
1004 */
1005 NTSTATUS
1006 NTAPI
1007 LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest,
1008 IN SECURITY_LOGON_TYPE LogonType,
1009 IN PVOID ProtocolSubmitBuffer,
1010 IN PVOID ClientBufferBase,
1011 IN ULONG SubmitBufferSize,
1012 OUT PVOID *ProfileBuffer,
1013 OUT PULONG ProfileBufferSize,
1014 OUT PLUID LogonId,
1015 OUT PNTSTATUS SubStatus,
1016 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType,
1017 OUT PVOID *TokenInformation,
1018 OUT PUNICODE_STRING *AccountName,
1019 OUT PUNICODE_STRING *AuthenticatingAuthority,
1020 OUT PUNICODE_STRING *MachineName,
1021 OUT PSECPKG_PRIMARY_CRED PrimaryCredentials,
1022 OUT PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials)
1023 {
1024 TRACE("()\n");
1025
1026 TRACE("LogonType: %lu\n", LogonType);
1027 TRACE("ProtocolSubmitBuffer: %p\n", ProtocolSubmitBuffer);
1028 TRACE("SubmitBufferSize: %lu\n", SubmitBufferSize);
1029
1030
1031 return STATUS_NOT_IMPLEMENTED;
1032 }
1033 #endif
1034
1035 /* EOF */