1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS system libraries 4 * FILE: lib/advapi32/misc/logon.c 5 * PURPOSE: Logon functions 6 * PROGRAMMER: Eric Kohl 7 */ 8 9 #include <advapi32.h> 10 WINE_DEFAULT_DEBUG_CHANNEL(advapi); 11 12 /* GLOBALS *****************************************************************/ 13 14 HANDLE LsaHandle = NULL; 15 ULONG AuthenticationPackage = 0; 16 17 /* FUNCTIONS ***************************************************************/ 18 19 static 20 NTSTATUS 21 OpenLogonLsaHandle(VOID) 22 { 23 LSA_STRING LogonProcessName; 24 LSA_STRING PackageName; 25 LSA_OPERATIONAL_MODE SecurityMode = 0; 26 NTSTATUS Status; 27 28 RtlInitAnsiString((PANSI_STRING)&LogonProcessName, 29 "User32LogonProcess"); 30 31 Status = LsaRegisterLogonProcess(&LogonProcessName, 32 &LsaHandle, 33 &SecurityMode); 34 if (!NT_SUCCESS(Status)) 35 { 36 TRACE("LsaRegisterLogonProcess failed (Status 0x%08lx)\n", Status); 37 goto done; 38 } 39 40 RtlInitAnsiString((PANSI_STRING)&PackageName, 41 MSV1_0_PACKAGE_NAME); 42 43 Status = LsaLookupAuthenticationPackage(LsaHandle, 44 &PackageName, 45 &AuthenticationPackage); 46 if (!NT_SUCCESS(Status)) 47 { 48 TRACE("LsaLookupAuthenticationPackage failed (Status 0x%08lx)\n", Status); 49 goto done; 50 } 51 52 TRACE("AuthenticationPackage: 0x%08lx\n", AuthenticationPackage); 53 54 done: 55 if (!NT_SUCCESS(Status)) 56 { 57 if (LsaHandle != NULL) 58 { 59 Status = LsaDeregisterLogonProcess(LsaHandle); 60 if (!NT_SUCCESS(Status)) 61 { 62 TRACE("LsaDeregisterLogonProcess failed (Status 0x%08lx)\n", Status); 63 } 64 } 65 } 66 67 return Status; 68 } 69 70 71 NTSTATUS 72 CloseLogonLsaHandle(VOID) 73 { 74 NTSTATUS Status = STATUS_SUCCESS; 75 76 if (LsaHandle != NULL) 77 { 78 Status = LsaDeregisterLogonProcess(LsaHandle); 79 if (!NT_SUCCESS(Status)) 80 { 81 TRACE("LsaDeregisterLogonProcess failed (Status 0x%08lx)\n", Status); 82 } 83 } 84 85 return Status; 86 } 87 88 89 static 90 BOOL 91 CreateProcessAsUserCommon( 92 _In_ BOOL bUnicode, 93 _In_opt_ HANDLE hToken, 94 _In_opt_ LPCVOID lpApplicationName, 95 _Inout_opt_ LPVOID lpCommandLine, 96 _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 97 _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 98 _In_ BOOL bInheritHandles, 99 _In_ DWORD dwCreationFlags, 100 _In_opt_ LPVOID lpEnvironment, 101 _In_opt_ LPCVOID lpCurrentDirectory, 102 _In_ LPVOID lpStartupInfo, 103 _Out_ LPPROCESS_INFORMATION lpProcessInformation) 104 { 105 NTSTATUS Status; 106 PROCESS_ACCESS_TOKEN AccessToken; 107 108 /* Create the process with a suspended main thread */ 109 if (bUnicode) 110 { 111 /* Call the UNICODE version */ 112 if (!CreateProcessW((LPCWSTR)lpApplicationName, 113 (LPWSTR)lpCommandLine, 114 lpProcessAttributes, 115 lpThreadAttributes, 116 bInheritHandles, 117 dwCreationFlags | CREATE_SUSPENDED, 118 lpEnvironment, 119 (LPCWSTR)lpCurrentDirectory, 120 (LPSTARTUPINFOW)lpStartupInfo, 121 lpProcessInformation)) 122 { 123 ERR("CreateProcessW failed, last error: %d\n", GetLastError()); 124 return FALSE; 125 } 126 } 127 else 128 { 129 /* Call the ANSI version */ 130 if (!CreateProcessA((LPCSTR)lpApplicationName, 131 (LPSTR)lpCommandLine, 132 lpProcessAttributes, 133 lpThreadAttributes, 134 bInheritHandles, 135 dwCreationFlags | CREATE_SUSPENDED, 136 lpEnvironment, 137 (LPCSTR)lpCurrentDirectory, 138 (LPSTARTUPINFOA)lpStartupInfo, 139 lpProcessInformation)) 140 { 141 ERR("CreateProcessA failed, last error: %d\n", GetLastError()); 142 return FALSE; 143 } 144 } 145 146 if (hToken != NULL) 147 { 148 TOKEN_TYPE Type; 149 ULONG ReturnLength; 150 OBJECT_ATTRIBUTES ObjectAttributes; 151 HANDLE hTokenDup; 152 BOOLEAN PrivilegeSet = FALSE, HavePrivilege; 153 154 /* Check whether the user-provided token is a primary token */ 155 // GetTokenInformation(); 156 Status = NtQueryInformationToken(hToken, 157 TokenType, 158 &Type, 159 sizeof(Type), 160 &ReturnLength); 161 if (!NT_SUCCESS(Status)) 162 { 163 ERR("NtQueryInformationToken() failed, Status 0x%08x\n", Status); 164 goto Quit; 165 } 166 if (Type != TokenPrimary) 167 { 168 ERR("Wrong token type for token 0x%p, expected TokenPrimary, got %ld\n", hToken, Type); 169 Status = STATUS_BAD_TOKEN_TYPE; 170 goto Quit; 171 } 172 173 /* Duplicate the token for this new process */ 174 InitializeObjectAttributes(&ObjectAttributes, 175 NULL, 176 0, 177 NULL, 178 NULL); // FIXME: Use a valid SecurityDescriptor! 179 Status = NtDuplicateToken(hToken, 180 0, 181 &ObjectAttributes, 182 FALSE, 183 TokenPrimary, 184 &hTokenDup); 185 if (!NT_SUCCESS(Status)) 186 { 187 ERR("NtDuplicateToken() failed, Status 0x%08x\n", Status); 188 goto Quit; 189 } 190 191 // FIXME: Do we always need SecurityImpersonation? 192 Status = RtlImpersonateSelf(SecurityImpersonation); 193 if (!NT_SUCCESS(Status)) 194 { 195 ERR("RtlImpersonateSelf(SecurityImpersonation) failed, Status 0x%08x\n", Status); 196 NtClose(hTokenDup); 197 goto Quit; 198 } 199 200 /* 201 * Attempt to acquire the process primary token assignment privilege 202 * in case we actually need it. 203 * The call will either succeed or fail when the caller has (or has not) 204 * enough rights. 205 * The last situation may not be dramatic for us. Indeed it may happen 206 * that the user-provided token is a restricted version of the caller's 207 * primary token (aka. a "child" token), or both tokens inherit (i.e. are 208 * children, and are together "siblings") from a common parent token. 209 * In this case the NT kernel allows us to assign the token to the child 210 * process without the need for the assignment privilege, which is fine. 211 * On the contrary, if the user-provided token is completely arbitrary, 212 * then the NT kernel will enforce the presence of the assignment privilege: 213 * because we failed (by assumption) to assign the privilege, the process 214 * token assignment will fail as required. It is then the job of the 215 * caller to manually acquire the necessary privileges. 216 */ 217 Status = RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, 218 TRUE, TRUE, &PrivilegeSet); 219 HavePrivilege = NT_SUCCESS(Status); 220 if (!HavePrivilege) 221 { 222 ERR("RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE) failed, Status 0x%08lx, " 223 "attempting to continue without it...\n", Status); 224 } 225 226 AccessToken.Token = hTokenDup; 227 AccessToken.Thread = lpProcessInformation->hThread; 228 229 /* Set the new process token */ 230 Status = NtSetInformationProcess(lpProcessInformation->hProcess, 231 ProcessAccessToken, 232 (PVOID)&AccessToken, 233 sizeof(AccessToken)); 234 235 /* Restore the privilege */ 236 if (HavePrivilege) 237 { 238 RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, 239 PrivilegeSet, TRUE, &PrivilegeSet); 240 } 241 242 RevertToSelf(); 243 244 /* Close the duplicated token */ 245 NtClose(hTokenDup); 246 247 /* Check whether NtSetInformationProcess() failed */ 248 if (!NT_SUCCESS(Status)) 249 { 250 ERR("NtSetInformationProcess() failed, Status 0x%08x\n", Status); 251 goto Quit; 252 } 253 254 if (!NT_SUCCESS(Status)) 255 { 256 Quit: 257 TerminateProcess(lpProcessInformation->hProcess, Status); 258 SetLastError(RtlNtStatusToDosError(Status)); 259 return FALSE; 260 } 261 } 262 263 /* Resume the main thread */ 264 if (!(dwCreationFlags & CREATE_SUSPENDED)) 265 { 266 ResumeThread(lpProcessInformation->hThread); 267 } 268 269 return TRUE; 270 } 271 272 273 /* 274 * @implemented 275 */ 276 BOOL 277 WINAPI 278 DECLSPEC_HOTPATCH 279 CreateProcessAsUserA( 280 _In_opt_ HANDLE hToken, 281 _In_opt_ LPCSTR lpApplicationName, 282 _Inout_opt_ LPSTR lpCommandLine, 283 _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 284 _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 285 _In_ BOOL bInheritHandles, 286 _In_ DWORD dwCreationFlags, 287 _In_opt_ LPVOID lpEnvironment, 288 _In_opt_ LPCSTR lpCurrentDirectory, 289 _In_ LPSTARTUPINFOA lpStartupInfo, 290 _Out_ LPPROCESS_INFORMATION lpProcessInformation) 291 { 292 TRACE("%p %s %s %p %p %d 0x%08x %p %s %p %p\n", hToken, debugstr_a(lpApplicationName), 293 debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles, 294 dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation); 295 296 /* Call the helper function */ 297 return CreateProcessAsUserCommon(FALSE, 298 hToken, 299 lpApplicationName, 300 lpCommandLine, 301 lpProcessAttributes, 302 lpThreadAttributes, 303 bInheritHandles, 304 dwCreationFlags, 305 lpEnvironment, 306 lpCurrentDirectory, 307 lpStartupInfo, 308 lpProcessInformation); 309 } 310 311 312 /* 313 * @implemented 314 */ 315 BOOL 316 WINAPI 317 DECLSPEC_HOTPATCH 318 CreateProcessAsUserW( 319 _In_opt_ HANDLE hToken, 320 _In_opt_ LPCWSTR lpApplicationName, 321 _Inout_opt_ LPWSTR lpCommandLine, 322 _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 323 _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 324 _In_ BOOL bInheritHandles, 325 _In_ DWORD dwCreationFlags, 326 _In_opt_ LPVOID lpEnvironment, 327 _In_opt_ LPCWSTR lpCurrentDirectory, 328 _In_ LPSTARTUPINFOW lpStartupInfo, 329 _Out_ LPPROCESS_INFORMATION lpProcessInformation) 330 { 331 TRACE("%p %s %s %p %p %d 0x%08x %p %s %p %p\n", hToken, debugstr_w(lpApplicationName), 332 debugstr_w(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles, 333 dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation); 334 335 /* Call the helper function */ 336 return CreateProcessAsUserCommon(TRUE, 337 hToken, 338 lpApplicationName, 339 lpCommandLine, 340 lpProcessAttributes, 341 lpThreadAttributes, 342 bInheritHandles, 343 dwCreationFlags, 344 lpEnvironment, 345 lpCurrentDirectory, 346 lpStartupInfo, 347 lpProcessInformation); 348 } 349 350 351 /* 352 * @implemented 353 */ 354 BOOL 355 WINAPI 356 LogonUserA( 357 _In_ LPSTR lpszUsername, 358 _In_opt_ LPSTR lpszDomain, 359 _In_opt_ LPSTR lpszPassword, 360 _In_ DWORD dwLogonType, 361 _In_ DWORD dwLogonProvider, 362 _Out_opt_ PHANDLE phToken) 363 { 364 return LogonUserExA(lpszUsername, 365 lpszDomain, 366 lpszPassword, 367 dwLogonType, 368 dwLogonProvider, 369 phToken, 370 NULL, 371 NULL, 372 NULL, 373 NULL); 374 } 375 376 377 /* 378 * @implemented 379 */ 380 BOOL 381 WINAPI 382 LogonUserExA( 383 _In_ LPSTR lpszUsername, 384 _In_opt_ LPSTR lpszDomain, 385 _In_opt_ LPSTR lpszPassword, 386 _In_ DWORD dwLogonType, 387 _In_ DWORD dwLogonProvider, 388 _Out_opt_ PHANDLE phToken, 389 _Out_opt_ PSID *ppLogonSid, 390 _Out_opt_ PVOID *ppProfileBuffer, 391 _Out_opt_ LPDWORD pdwProfileLength, 392 _Out_opt_ PQUOTA_LIMITS pQuotaLimits) 393 { 394 UNICODE_STRING UserName; 395 UNICODE_STRING Domain; 396 UNICODE_STRING Password; 397 BOOL ret = FALSE; 398 399 UserName.Buffer = NULL; 400 Domain.Buffer = NULL; 401 Password.Buffer = NULL; 402 403 if (!RtlCreateUnicodeStringFromAsciiz(&UserName, lpszUsername)) 404 { 405 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 406 goto UsernameDone; 407 } 408 409 if (!RtlCreateUnicodeStringFromAsciiz(&Domain, lpszDomain)) 410 { 411 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 412 goto DomainDone; 413 } 414 415 if (!RtlCreateUnicodeStringFromAsciiz(&Password, lpszPassword)) 416 { 417 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 418 goto PasswordDone; 419 } 420 421 ret = LogonUserExW(UserName.Buffer, 422 Domain.Buffer, 423 Password.Buffer, 424 dwLogonType, 425 dwLogonProvider, 426 phToken, 427 ppLogonSid, 428 ppProfileBuffer, 429 pdwProfileLength, 430 pQuotaLimits); 431 432 if (Password.Buffer != NULL) 433 RtlFreeUnicodeString(&Password); 434 435 PasswordDone: 436 if (Domain.Buffer != NULL) 437 RtlFreeUnicodeString(&Domain); 438 439 DomainDone: 440 if (UserName.Buffer != NULL) 441 RtlFreeUnicodeString(&UserName); 442 443 UsernameDone: 444 return ret; 445 } 446 447 448 /* 449 * @implemented 450 */ 451 BOOL 452 WINAPI 453 LogonUserW( 454 _In_ LPWSTR lpszUsername, 455 _In_opt_ LPWSTR lpszDomain, 456 _In_opt_ LPWSTR lpszPassword, 457 _In_ DWORD dwLogonType, 458 _In_ DWORD dwLogonProvider, 459 _Out_opt_ PHANDLE phToken) 460 { 461 return LogonUserExW(lpszUsername, 462 lpszDomain, 463 lpszPassword, 464 dwLogonType, 465 dwLogonProvider, 466 phToken, 467 NULL, 468 NULL, 469 NULL, 470 NULL); 471 } 472 473 474 /* 475 * @implemented 476 */ 477 BOOL 478 WINAPI 479 LogonUserExW( 480 _In_ LPWSTR lpszUsername, 481 _In_opt_ LPWSTR lpszDomain, 482 _In_opt_ LPWSTR lpszPassword, 483 _In_ DWORD dwLogonType, 484 _In_ DWORD dwLogonProvider, 485 _Out_opt_ PHANDLE phToken, 486 _Out_opt_ PSID *ppLogonSid, 487 _Out_opt_ PVOID *ppProfileBuffer, 488 _Out_opt_ LPDWORD pdwProfileLength, 489 _Out_opt_ PQUOTA_LIMITS pQuotaLimits) 490 { 491 SID_IDENTIFIER_AUTHORITY LocalAuthority = {SECURITY_LOCAL_SID_AUTHORITY}; 492 SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY}; 493 PSID LogonSid = NULL; 494 PSID LocalSid = NULL; 495 LSA_STRING OriginName; 496 UNICODE_STRING DomainName; 497 UNICODE_STRING UserName; 498 UNICODE_STRING Password; 499 PMSV1_0_INTERACTIVE_LOGON AuthInfo = NULL; 500 ULONG AuthInfoLength; 501 ULONG_PTR Ptr; 502 TOKEN_SOURCE TokenSource; 503 PTOKEN_GROUPS TokenGroups = NULL; 504 PMSV1_0_INTERACTIVE_PROFILE ProfileBuffer = NULL; 505 ULONG ProfileBufferLength = 0; 506 LUID Luid = {0, 0}; 507 LUID LogonId = {0, 0}; 508 HANDLE TokenHandle = NULL; 509 QUOTA_LIMITS QuotaLimits; 510 SECURITY_LOGON_TYPE LogonType; 511 NTSTATUS SubStatus = STATUS_SUCCESS; 512 NTSTATUS Status; 513 514 if ((ppProfileBuffer != NULL && pdwProfileLength == NULL) || 515 (ppProfileBuffer == NULL && pdwProfileLength != NULL)) 516 { 517 SetLastError(ERROR_INVALID_PARAMETER); 518 return FALSE; 519 } 520 521 if (ppProfileBuffer != NULL && pdwProfileLength != NULL) 522 { 523 *ppProfileBuffer = NULL; 524 *pdwProfileLength = 0; 525 } 526 527 if (phToken != NULL) 528 *phToken = NULL; 529 530 switch (dwLogonType) 531 { 532 case LOGON32_LOGON_INTERACTIVE: 533 LogonType = Interactive; 534 break; 535 536 case LOGON32_LOGON_NETWORK: 537 LogonType = Network; 538 break; 539 540 case LOGON32_LOGON_BATCH: 541 LogonType = Batch; 542 break; 543 544 case LOGON32_LOGON_SERVICE: 545 LogonType = Service; 546 break; 547 548 default: 549 ERR("Invalid logon type: %ul\n", dwLogonType); 550 Status = STATUS_INVALID_PARAMETER; 551 goto done; 552 } 553 554 if (LsaHandle == NULL) 555 { 556 Status = OpenLogonLsaHandle(); 557 if (!NT_SUCCESS(Status)) 558 goto done; 559 } 560 561 RtlInitAnsiString((PANSI_STRING)&OriginName, 562 "Advapi32 Logon"); 563 564 RtlInitUnicodeString(&DomainName, 565 lpszDomain); 566 567 RtlInitUnicodeString(&UserName, 568 lpszUsername); 569 570 RtlInitUnicodeString(&Password, 571 lpszPassword); 572 573 AuthInfoLength = sizeof(MSV1_0_INTERACTIVE_LOGON)+ 574 DomainName.MaximumLength + 575 UserName.MaximumLength + 576 Password.MaximumLength; 577 578 AuthInfo = RtlAllocateHeap(RtlGetProcessHeap(), 579 HEAP_ZERO_MEMORY, 580 AuthInfoLength); 581 if (AuthInfo == NULL) 582 { 583 Status = STATUS_INSUFFICIENT_RESOURCES; 584 goto done; 585 } 586 587 AuthInfo->MessageType = MsV1_0InteractiveLogon; 588 589 Ptr = (ULONG_PTR)AuthInfo + sizeof(MSV1_0_INTERACTIVE_LOGON); 590 591 AuthInfo->LogonDomainName.Length = DomainName.Length; 592 AuthInfo->LogonDomainName.MaximumLength = DomainName.MaximumLength; 593 AuthInfo->LogonDomainName.Buffer = (DomainName.Buffer == NULL) ? NULL : (PWCHAR)Ptr; 594 if (DomainName.MaximumLength > 0) 595 { 596 RtlCopyMemory(AuthInfo->LogonDomainName.Buffer, 597 DomainName.Buffer, 598 DomainName.MaximumLength); 599 600 Ptr += DomainName.MaximumLength; 601 } 602 603 AuthInfo->UserName.Length = UserName.Length; 604 AuthInfo->UserName.MaximumLength = UserName.MaximumLength; 605 AuthInfo->UserName.Buffer = (PWCHAR)Ptr; 606 if (UserName.MaximumLength > 0) 607 RtlCopyMemory(AuthInfo->UserName.Buffer, 608 UserName.Buffer, 609 UserName.MaximumLength); 610 611 Ptr += UserName.MaximumLength; 612 613 AuthInfo->Password.Length = Password.Length; 614 AuthInfo->Password.MaximumLength = Password.MaximumLength; 615 AuthInfo->Password.Buffer = (PWCHAR)Ptr; 616 if (Password.MaximumLength > 0) 617 RtlCopyMemory(AuthInfo->Password.Buffer, 618 Password.Buffer, 619 Password.MaximumLength); 620 621 /* Create the Logon SID */ 622 AllocateLocallyUniqueId(&LogonId); 623 Status = RtlAllocateAndInitializeSid(&SystemAuthority, 624 SECURITY_LOGON_IDS_RID_COUNT, 625 SECURITY_LOGON_IDS_RID, 626 LogonId.HighPart, 627 LogonId.LowPart, 628 SECURITY_NULL_RID, 629 SECURITY_NULL_RID, 630 SECURITY_NULL_RID, 631 SECURITY_NULL_RID, 632 SECURITY_NULL_RID, 633 &LogonSid); 634 if (!NT_SUCCESS(Status)) 635 goto done; 636 637 /* Create the Local SID */ 638 Status = RtlAllocateAndInitializeSid(&LocalAuthority, 639 1, 640 SECURITY_LOCAL_RID, 641 SECURITY_NULL_RID, 642 SECURITY_NULL_RID, 643 SECURITY_NULL_RID, 644 SECURITY_NULL_RID, 645 SECURITY_NULL_RID, 646 SECURITY_NULL_RID, 647 SECURITY_NULL_RID, 648 &LocalSid); 649 if (!NT_SUCCESS(Status)) 650 goto done; 651 652 /* Allocate and set the token groups */ 653 TokenGroups = RtlAllocateHeap(RtlGetProcessHeap(), 654 HEAP_ZERO_MEMORY, 655 sizeof(TOKEN_GROUPS) + ((2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES))); 656 if (TokenGroups == NULL) 657 { 658 Status = STATUS_INSUFFICIENT_RESOURCES; 659 goto done; 660 } 661 662 TokenGroups->GroupCount = 2; 663 TokenGroups->Groups[0].Sid = LogonSid; 664 TokenGroups->Groups[0].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED | 665 SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_LOGON_ID; 666 TokenGroups->Groups[1].Sid = LocalSid; 667 TokenGroups->Groups[1].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED | 668 SE_GROUP_ENABLED_BY_DEFAULT; 669 670 /* Set the token source */ 671 strncpy(TokenSource.SourceName, "Advapi ", sizeof(TokenSource.SourceName)); 672 AllocateLocallyUniqueId(&TokenSource.SourceIdentifier); 673 674 Status = LsaLogonUser(LsaHandle, 675 &OriginName, 676 LogonType, 677 AuthenticationPackage, 678 (PVOID)AuthInfo, 679 AuthInfoLength, 680 TokenGroups, 681 &TokenSource, 682 (PVOID*)&ProfileBuffer, 683 &ProfileBufferLength, 684 &Luid, 685 &TokenHandle, 686 &QuotaLimits, 687 &SubStatus); 688 if (!NT_SUCCESS(Status)) 689 { 690 ERR("LsaLogonUser failed (Status 0x%08lx)\n", Status); 691 goto done; 692 } 693 694 if (ProfileBuffer != NULL) 695 { 696 TRACE("ProfileBuffer: %p\n", ProfileBuffer); 697 TRACE("MessageType: %u\n", ProfileBuffer->MessageType); 698 699 TRACE("FullName: %p\n", ProfileBuffer->FullName.Buffer); 700 TRACE("FullName: %S\n", ProfileBuffer->FullName.Buffer); 701 702 TRACE("LogonServer: %p\n", ProfileBuffer->LogonServer.Buffer); 703 TRACE("LogonServer: %S\n", ProfileBuffer->LogonServer.Buffer); 704 } 705 706 TRACE("Luid: 0x%08lx%08lx\n", Luid.HighPart, Luid.LowPart); 707 708 if (TokenHandle != NULL) 709 { 710 TRACE("TokenHandle: %p\n", TokenHandle); 711 } 712 713 if (phToken != NULL) 714 *phToken = TokenHandle; 715 716 /* FIXME: return ppLogonSid and pQuotaLimits */ 717 718 done: 719 if (ProfileBuffer != NULL) 720 LsaFreeReturnBuffer(ProfileBuffer); 721 722 if (!NT_SUCCESS(Status)) 723 { 724 if (TokenHandle != NULL) 725 CloseHandle(TokenHandle); 726 } 727 728 if (TokenGroups != NULL) 729 RtlFreeHeap(RtlGetProcessHeap(), 0, TokenGroups); 730 731 if (LocalSid != NULL) 732 RtlFreeSid(LocalSid); 733 734 if (LogonSid != NULL) 735 RtlFreeSid(LogonSid); 736 737 if (AuthInfo != NULL) 738 RtlFreeHeap(RtlGetProcessHeap(), 0, AuthInfo); 739 740 if (!NT_SUCCESS(Status)) 741 { 742 SetLastError(RtlNtStatusToDosError(Status)); 743 return FALSE; 744 } 745 746 return TRUE; 747 } 748 749 /* EOF */ 750