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