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 LARGE_INTEGER LogonTime; 970 // LARGE_INTEGER AccountExpires; 971 LARGE_INTEGER PasswordMustChange; 972 LARGE_INTEGER PasswordLastSet; 973 NTSTATUS Status; 974 975 TRACE("()\n"); 976 977 TRACE("LogonType: %lu\n", LogonType); 978 TRACE("AuthenticationInformation: %p\n", AuthenticationInformation); 979 TRACE("AuthenticationInformationLength: %lu\n", AuthenticationInformationLength); 980 981 *ProfileBuffer = NULL; 982 *ProfileBufferLength = 0; 983 *SubStatus = STATUS_SUCCESS; 984 985 if (LogonType == Interactive || 986 LogonType == Batch || 987 LogonType == Service) 988 { 989 ULONG_PTR PtrOffset; 990 991 LogonInfo = (PMSV1_0_INTERACTIVE_LOGON)AuthenticationInformation; 992 993 /* Fix-up pointers in the authentication info */ 994 PtrOffset = (ULONG_PTR)AuthenticationInformation - (ULONG_PTR)ClientAuthenticationBase; 995 996 LogonInfo->LogonDomainName.Buffer = FIXUP_POINTER(LogonInfo->LogonDomainName.Buffer, PtrOffset); 997 LogonInfo->UserName.Buffer = FIXUP_POINTER(LogonInfo->UserName.Buffer, PtrOffset); 998 LogonInfo->Password.Buffer = FIXUP_POINTER(LogonInfo->Password.Buffer, PtrOffset); 999 1000 TRACE("Domain: %S\n", LogonInfo->LogonDomainName.Buffer); 1001 TRACE("User: %S\n", LogonInfo->UserName.Buffer); 1002 TRACE("Password: %S\n", LogonInfo->Password.Buffer); 1003 1004 RtlInitUnicodeString(&LogonServer, L"Testserver"); 1005 } 1006 else 1007 { 1008 FIXME("LogonType %lu is not supported yet!\n", LogonType); 1009 return STATUS_NOT_IMPLEMENTED; 1010 } 1011 1012 /* Get the logon time */ 1013 NtQuerySystemTime(&LogonTime); 1014 1015 /* Get the domain SID */ 1016 Status = GetDomainSid(&AccountDomainSid); 1017 if (!NT_SUCCESS(Status)) 1018 { 1019 TRACE("GetDomainSid() failed (Status 0x%08lx)\n", Status); 1020 return Status; 1021 } 1022 1023 /* Connect to the SAM server */ 1024 Status = SamIConnect(NULL, 1025 &ServerHandle, 1026 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, 1027 TRUE); 1028 if (!NT_SUCCESS(Status)) 1029 { 1030 TRACE("SamIConnect() failed (Status 0x%08lx)\n", Status); 1031 goto done; 1032 } 1033 1034 /* Open the account domain */ 1035 Status = SamrOpenDomain(ServerHandle, 1036 DOMAIN_LOOKUP, 1037 AccountDomainSid, 1038 &DomainHandle); 1039 if (!NT_SUCCESS(Status)) 1040 { 1041 TRACE("SamrOpenDomain failed (Status %08lx)\n", Status); 1042 goto done; 1043 } 1044 1045 Names[0].Length = LogonInfo->UserName.Length; 1046 Names[0].MaximumLength = LogonInfo->UserName.MaximumLength; 1047 Names[0].Buffer = LogonInfo->UserName.Buffer; 1048 1049 /* Try to get the RID for the user name */ 1050 Status = SamrLookupNamesInDomain(DomainHandle, 1051 1, 1052 Names, 1053 &RelativeIds, 1054 &Use); 1055 if (!NT_SUCCESS(Status)) 1056 { 1057 TRACE("SamrLookupNamesInDomain failed (Status %08lx)\n", Status); 1058 Status = STATUS_NO_SUCH_USER; 1059 goto done; 1060 } 1061 1062 /* Fail, if it is not a user account */ 1063 if (Use.Element[0] != SidTypeUser) 1064 { 1065 TRACE("Account is not a user account!\n"); 1066 Status = STATUS_NO_SUCH_USER; 1067 goto done; 1068 } 1069 1070 /* Open the user object */ 1071 Status = SamrOpenUser(DomainHandle, 1072 USER_READ_GENERAL | USER_READ_LOGON | 1073 USER_READ_ACCOUNT | USER_READ_PREFERENCES, /* FIXME */ 1074 RelativeIds.Element[0], 1075 &UserHandle); 1076 if (!NT_SUCCESS(Status)) 1077 { 1078 TRACE("SamrOpenUser failed (Status %08lx)\n", Status); 1079 goto done; 1080 } 1081 1082 Status = SamrQueryInformationUser(UserHandle, 1083 UserAllInformation, 1084 &UserInfo); 1085 if (!NT_SUCCESS(Status)) 1086 { 1087 TRACE("SamrQueryInformationUser failed (Status %08lx)\n", Status); 1088 goto done; 1089 } 1090 1091 TRACE("UserName: %S\n", UserInfo->All.UserName.Buffer); 1092 1093 /* Check the password */ 1094 if ((UserInfo->All.UserAccountControl & USER_PASSWORD_NOT_REQUIRED) == 0) 1095 { 1096 Status = MsvpCheckPassword(&(LogonInfo->Password), 1097 UserInfo); 1098 if (!NT_SUCCESS(Status)) 1099 { 1100 TRACE("MsvpCheckPassword failed (Status %08lx)\n", Status); 1101 goto done; 1102 } 1103 } 1104 1105 /* Check account restrictions for non-administrator accounts */ 1106 if (RelativeIds.Element[0] != DOMAIN_USER_RID_ADMIN) 1107 { 1108 /* Check if the account has been disabled */ 1109 if (UserInfo->All.UserAccountControl & USER_ACCOUNT_DISABLED) 1110 { 1111 ERR("Account disabled!\n"); 1112 *SubStatus = STATUS_ACCOUNT_DISABLED; 1113 Status = STATUS_ACCOUNT_RESTRICTION; 1114 goto done; 1115 } 1116 1117 /* Check if the account has been locked */ 1118 if (UserInfo->All.UserAccountControl & USER_ACCOUNT_AUTO_LOCKED) 1119 { 1120 ERR("Account locked!\n"); 1121 *SubStatus = STATUS_ACCOUNT_LOCKED_OUT; 1122 Status = STATUS_ACCOUNT_RESTRICTION; 1123 goto done; 1124 } 1125 1126 #if 0 1127 /* Check if the account expired */ 1128 AccountExpires.LowPart = UserInfo->All.AccountExpires.LowPart; 1129 AccountExpires.HighPart = UserInfo->All.AccountExpires.HighPart; 1130 1131 if (AccountExpires.QuadPart != 0 && 1132 LogonTime.QuadPart >= AccountExpires.QuadPart) 1133 { 1134 ERR("Account expired!\n"); 1135 *SubStatus = STATUS_ACCOUNT_EXPIRED; 1136 Status = STATUS_ACCOUNT_RESTRICTION; 1137 goto done; 1138 } 1139 #endif 1140 1141 /* Check if the password expired */ 1142 PasswordMustChange.LowPart = UserInfo->All.PasswordMustChange.LowPart; 1143 PasswordMustChange.HighPart = UserInfo->All.PasswordMustChange.HighPart; 1144 PasswordLastSet.LowPart = UserInfo->All.PasswordLastSet.LowPart; 1145 PasswordLastSet.HighPart = UserInfo->All.PasswordLastSet.HighPart; 1146 1147 if (LogonTime.QuadPart >= PasswordMustChange.QuadPart) 1148 { 1149 ERR("Password expired!\n"); 1150 if (PasswordLastSet.QuadPart == 0) 1151 *SubStatus = STATUS_PASSWORD_MUST_CHANGE; 1152 else 1153 *SubStatus = STATUS_PASSWORD_EXPIRED; 1154 1155 Status = STATUS_ACCOUNT_RESTRICTION; 1156 goto done; 1157 } 1158 1159 /* FIXME: more checks */ 1160 // STATUS_INVALID_LOGON_HOURS; 1161 // STATUS_INVALID_WORKSTATION; 1162 } 1163 1164 /* Return logon information */ 1165 1166 /* Create and return a new logon id */ 1167 Status = NtAllocateLocallyUniqueId(LogonId); 1168 if (!NT_SUCCESS(Status)) 1169 { 1170 TRACE("NtAllocateLocallyUniqueId failed (Status %08lx)\n", Status); 1171 goto done; 1172 } 1173 1174 /* Create the logon session */ 1175 Status = DispatchTable.CreateLogonSession(LogonId); 1176 if (!NT_SUCCESS(Status)) 1177 { 1178 TRACE("CreateLogonSession failed (Status %08lx)\n", Status); 1179 goto done; 1180 } 1181 1182 SessionCreated = TRUE; 1183 1184 /* Build and fill the interactive profile buffer */ 1185 Status = BuildInteractiveProfileBuffer(ClientRequest, 1186 UserInfo, 1187 &LogonServer, 1188 (PMSV1_0_INTERACTIVE_PROFILE*)ProfileBuffer, 1189 ProfileBufferLength); 1190 if (!NT_SUCCESS(Status)) 1191 { 1192 TRACE("BuildInteractiveProfileBuffer failed (Status %08lx)\n", Status); 1193 goto done; 1194 } 1195 1196 /* Return the token information type */ 1197 *TokenInformationType = LsaTokenInformationV1; 1198 1199 /* Build and fill the token information buffer */ 1200 Status = BuildTokenInformationBuffer((PLSA_TOKEN_INFORMATION_V1*)TokenInformation, 1201 AccountDomainSid, 1202 UserInfo); 1203 if (!NT_SUCCESS(Status)) 1204 { 1205 TRACE("BuildTokenInformationBuffer failed (Status %08lx)\n", Status); 1206 goto done; 1207 } 1208 1209 done: 1210 /* Return the account name */ 1211 *AccountName = DispatchTable.AllocateLsaHeap(sizeof(UNICODE_STRING)); 1212 if (*AccountName != NULL) 1213 { 1214 (*AccountName)->Buffer = DispatchTable.AllocateLsaHeap(LogonInfo->UserName.Length + 1215 sizeof(UNICODE_NULL)); 1216 if ((*AccountName)->Buffer != NULL) 1217 { 1218 (*AccountName)->MaximumLength = LogonInfo->UserName.Length + 1219 sizeof(UNICODE_NULL); 1220 RtlCopyUnicodeString(*AccountName, &LogonInfo->UserName); 1221 } 1222 } 1223 1224 if (!NT_SUCCESS(Status)) 1225 { 1226 if (SessionCreated != FALSE) 1227 DispatchTable.DeleteLogonSession(LogonId); 1228 1229 if (*ProfileBuffer != NULL) 1230 { 1231 DispatchTable.FreeClientBuffer(ClientRequest, 1232 *ProfileBuffer); 1233 *ProfileBuffer = NULL; 1234 } 1235 } 1236 1237 if (UserHandle != NULL) 1238 SamrCloseHandle(&UserHandle); 1239 1240 SamIFree_SAMPR_USER_INFO_BUFFER(UserInfo, 1241 UserAllInformation); 1242 SamIFree_SAMPR_ULONG_ARRAY(&RelativeIds); 1243 SamIFree_SAMPR_ULONG_ARRAY(&Use); 1244 1245 if (DomainHandle != NULL) 1246 SamrCloseHandle(&DomainHandle); 1247 1248 if (ServerHandle != NULL) 1249 SamrCloseHandle(&ServerHandle); 1250 1251 if (AccountDomainSid != NULL) 1252 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid); 1253 1254 if (Status == STATUS_NO_SUCH_USER || 1255 Status == STATUS_WRONG_PASSWORD) 1256 { 1257 *SubStatus = Status; 1258 Status = STATUS_LOGON_FAILURE; 1259 } 1260 1261 TRACE("LsaApLogonUser done (Status 0x%08lx SubStatus 0x%08lx)\n", Status, *SubStatus); 1262 1263 return Status; 1264 } 1265 1266 1267 /* 1268 * @unimplemented 1269 */ 1270 #if 0 1271 NTSTATUS 1272 NTAPI 1273 LsaApLogonUserEx(IN PLSA_CLIENT_REQUEST ClientRequest, 1274 IN SECURITY_LOGON_TYPE LogonType, 1275 IN PVOID AuthenticationInformation, 1276 IN PVOID ClientAuthenticationBase, 1277 IN ULONG AuthenticationInformationLength, 1278 OUT PVOID *ProfileBuffer, 1279 OUT PULONG ProfileBufferLength, 1280 OUT PLUID LogonId, 1281 OUT PNTSTATUS SubStatus, 1282 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType, 1283 OUT PVOID *TokenInformation, 1284 OUT PUNICODE_STRING *AccountName, 1285 OUT PUNICODE_STRING *AuthenticatingAuthority, 1286 OUT PUNICODE_STRING *MachineName) 1287 { 1288 TRACE("()\n"); 1289 1290 TRACE("LogonType: %lu\n", LogonType); 1291 TRACE("AuthenticationInformation: %p\n", AuthenticationInformation); 1292 TRACE("AuthenticationInformationLength: %lu\n", AuthenticationInformationLength); 1293 1294 return STATUS_NOT_IMPLEMENTED; 1295 } 1296 1297 1298 /* 1299 * @unimplemented 1300 */ 1301 NTSTATUS 1302 NTAPI 1303 LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest, 1304 IN SECURITY_LOGON_TYPE LogonType, 1305 IN PVOID ProtocolSubmitBuffer, 1306 IN PVOID ClientBufferBase, 1307 IN ULONG SubmitBufferSize, 1308 OUT PVOID *ProfileBuffer, 1309 OUT PULONG ProfileBufferSize, 1310 OUT PLUID LogonId, 1311 OUT PNTSTATUS SubStatus, 1312 OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType, 1313 OUT PVOID *TokenInformation, 1314 OUT PUNICODE_STRING *AccountName, 1315 OUT PUNICODE_STRING *AuthenticatingAuthority, 1316 OUT PUNICODE_STRING *MachineName, 1317 OUT PSECPKG_PRIMARY_CRED PrimaryCredentials, 1318 OUT PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials) 1319 { 1320 TRACE("()\n"); 1321 1322 TRACE("LogonType: %lu\n", LogonType); 1323 TRACE("ProtocolSubmitBuffer: %p\n", ProtocolSubmitBuffer); 1324 TRACE("SubmitBufferSize: %lu\n", SubmitBufferSize); 1325 1326 1327 return STATUS_NOT_IMPLEMENTED; 1328 } 1329 #endif 1330 1331 /* EOF */ 1332