1 /* 2 * PROJECT: Local Security Authority Server DLL 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: dll/win32/lsasrv/authpackage.c 5 * PURPOSE: Authentication package management routines 6 * COPYRIGHT: Copyright 2013 Eric Kohl 7 */ 8 9 #include "lsasrv.h" 10 11 #include <ndk/sefuncs.h> 12 #include <ndk/umfuncs.h> 13 14 typedef enum _LSA_TOKEN_INFORMATION_TYPE 15 { 16 LsaTokenInformationNull, 17 LsaTokenInformationV1 18 } LSA_TOKEN_INFORMATION_TYPE, *PLSA_TOKEN_INFORMATION_TYPE; 19 20 typedef struct _LSA_TOKEN_INFORMATION_V1 21 { 22 LARGE_INTEGER ExpirationTime; 23 TOKEN_USER User; 24 PTOKEN_GROUPS Groups; 25 TOKEN_PRIMARY_GROUP PrimaryGroup; 26 PTOKEN_PRIVILEGES Privileges; 27 TOKEN_OWNER Owner; 28 TOKEN_DEFAULT_DACL DefaultDacl; 29 } LSA_TOKEN_INFORMATION_V1, *PLSA_TOKEN_INFORMATION_V1; 30 31 typedef PVOID PLSA_CLIENT_REQUEST; 32 33 typedef NTSTATUS (NTAPI *PLSA_CREATE_LOGON_SESSION)(PLUID); 34 typedef NTSTATUS (NTAPI *PLSA_DELETE_LOGON_SESSION)(PLUID); 35 typedef NTSTATUS (NTAPI *PLSA_ADD_CREDENTIAL)(PLUID, ULONG, PLSA_STRING, PLSA_STRING); 36 typedef NTSTATUS (NTAPI *PLSA_GET_CREDENTIALS)(PLUID, ULONG, PULONG, BOOLEAN, PLSA_STRING, PULONG, PLSA_STRING); 37 typedef NTSTATUS (NTAPI *PLSA_DELETE_CREDENTIAL)(PLUID, ULONG, PLSA_STRING); 38 typedef PVOID (NTAPI *PLSA_ALLOCATE_LSA_HEAP)(ULONG); 39 typedef VOID (NTAPI *PLSA_FREE_LSA_HEAP)(PVOID); 40 typedef NTSTATUS (NTAPI *PLSA_ALLOCATE_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, ULONG, PVOID*); 41 typedef NTSTATUS (NTAPI *PLSA_FREE_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, PVOID); 42 typedef NTSTATUS (NTAPI *PLSA_COPY_TO_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, ULONG, 43 PVOID, PVOID); 44 typedef NTSTATUS (NTAPI *PLSA_COPY_FROM_CLIENT_BUFFER)(PLSA_CLIENT_REQUEST, 45 ULONG, PVOID, PVOID); 46 47 typedef struct LSA_DISPATCH_TABLE 48 { 49 PLSA_CREATE_LOGON_SESSION CreateLogonSession; 50 PLSA_DELETE_LOGON_SESSION DeleteLogonSession; 51 PLSA_ADD_CREDENTIAL AddCredential; 52 PLSA_GET_CREDENTIALS GetCredentials; 53 PLSA_DELETE_CREDENTIAL DeleteCredential; 54 PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap; 55 PLSA_FREE_LSA_HEAP FreeLsaHeap; 56 PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer; 57 PLSA_FREE_CLIENT_BUFFER FreeClientBuffer; 58 PLSA_COPY_TO_CLIENT_BUFFER CopyToClientBuffer; 59 PLSA_COPY_FROM_CLIENT_BUFFER CopyFromClientBuffer; 60 } LSA_DISPATCH_TABLE, *PLSA_DISPATCH_TABLE; 61 62 63 typedef NTSTATUS (NTAPI *PLSA_AP_INITIALIZE_PACKAGE)(ULONG, PLSA_DISPATCH_TABLE, 64 PLSA_STRING, PLSA_STRING, PLSA_STRING *); 65 typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_INTERNAL)(PLSA_CLIENT_REQUEST, PVOID, PVOID, 66 ULONG, PVOID *, PULONG, PNTSTATUS); 67 typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_PASSTHROUGH)(PLSA_CLIENT_REQUEST, 68 PVOID, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS); 69 typedef NTSTATUS (NTAPI *PLSA_AP_CALL_PACKAGE_UNTRUSTED)(PLSA_CLIENT_REQUEST, 70 PVOID, PVOID, ULONG, PVOID *, PULONG, PNTSTATUS); 71 typedef VOID (NTAPI *PLSA_AP_LOGON_TERMINATED)(PLUID); 72 typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_EX2)(PLSA_CLIENT_REQUEST, 73 SECURITY_LOGON_TYPE, PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS, 74 PLSA_TOKEN_INFORMATION_TYPE, PVOID *, PUNICODE_STRING *, PUNICODE_STRING *, 75 PUNICODE_STRING *, PVOID /*PSECPKG_PRIMARY_CRED*/, PVOID /*PSECPKG_SUPPLEMENTAL_CRED_ARRAY **/); 76 typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_EX)(PLSA_CLIENT_REQUEST, 77 SECURITY_LOGON_TYPE, PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS, 78 PLSA_TOKEN_INFORMATION_TYPE, PVOID *, PUNICODE_STRING *, PUNICODE_STRING *, 79 PUNICODE_STRING *); 80 81 typedef NTSTATUS (NTAPI *PLSA_AP_LOGON_USER_INTERNAL)(PLSA_CLIENT_REQUEST, SECURITY_LOGON_TYPE, 82 PVOID, PVOID, ULONG, PVOID *, PULONG, PLUID, PNTSTATUS, PLSA_TOKEN_INFORMATION_TYPE, 83 PVOID *, PUNICODE_STRING *, PUNICODE_STRING *); 84 85 typedef struct _AUTH_PACKAGE 86 { 87 LIST_ENTRY Entry; 88 PSTRING Name; 89 ULONG Id; 90 PVOID ModuleHandle; 91 92 PLSA_AP_INITIALIZE_PACKAGE LsaApInitializePackage; 93 PLSA_AP_CALL_PACKAGE_INTERNAL LsaApCallPackage; 94 PLSA_AP_CALL_PACKAGE_PASSTHROUGH LsaApCallPackagePassthrough; 95 PLSA_AP_CALL_PACKAGE_UNTRUSTED LsaApCallPackageUntrusted; 96 PLSA_AP_LOGON_TERMINATED LsaApLogonTerminated; 97 PLSA_AP_LOGON_USER_EX2 LsaApLogonUserEx2; 98 PLSA_AP_LOGON_USER_EX LsaApLogonUserEx; 99 PLSA_AP_LOGON_USER_INTERNAL LsaApLogonUser; 100 } AUTH_PACKAGE, *PAUTH_PACKAGE; 101 102 VOID 103 NTAPI 104 LsaIFree_LSAPR_PRIVILEGE_SET(IN PLSAPR_PRIVILEGE_SET Ptr); 105 106 typedef wchar_t *PSAMPR_SERVER_NAME; 107 typedef void *SAMPR_HANDLE; 108 109 typedef struct _SAMPR_SID_INFORMATION 110 { 111 PRPC_SID SidPointer; 112 } SAMPR_SID_INFORMATION, *PSAMPR_SID_INFORMATION; 113 114 typedef struct _SAMPR_PSID_ARRAY 115 { 116 unsigned long Count; 117 PSAMPR_SID_INFORMATION Sids; 118 } SAMPR_PSID_ARRAY, *PSAMPR_PSID_ARRAY; 119 120 NTSTATUS 121 NTAPI 122 SamIConnect( 123 PSAMPR_SERVER_NAME ServerName, 124 SAMPR_HANDLE *ServerHandle, 125 ACCESS_MASK DesiredAccess, 126 BOOLEAN Trusted); 127 128 VOID 129 NTAPI 130 SamIFree_SAMPR_ULONG_ARRAY( 131 PSAMPR_ULONG_ARRAY Ptr); 132 133 NTSTATUS 134 __stdcall 135 SamrCloseHandle( 136 SAMPR_HANDLE *SamHandle); 137 138 NTSTATUS 139 __stdcall 140 SamrOpenDomain( 141 SAMPR_HANDLE ServerHandle, 142 ACCESS_MASK DesiredAccess, 143 PRPC_SID DomainId, 144 SAMPR_HANDLE *DomainHandle); 145 146 NTSTATUS 147 __stdcall 148 SamrGetAliasMembership( 149 SAMPR_HANDLE DomainHandle, 150 PSAMPR_PSID_ARRAY SidArray, 151 PSAMPR_ULONG_ARRAY Membership); 152 153 154 /* GLOBALS *****************************************************************/ 155 156 static LIST_ENTRY PackageListHead; 157 static ULONG PackageId; 158 static LSA_DISPATCH_TABLE DispatchTable; 159 160 #define CONST_LUID(x1, x2) {x1, x2} 161 static const LUID SeChangeNotifyPrivilege = CONST_LUID(SE_CHANGE_NOTIFY_PRIVILEGE, 0); 162 static const LUID SeCreateGlobalPrivilege = CONST_LUID(SE_CREATE_GLOBAL_PRIVILEGE, 0); 163 static const LUID SeImpersonatePrivilege = CONST_LUID(SE_IMPERSONATE_PRIVILEGE, 0); 164 165 166 /* FUNCTIONS ***************************************************************/ 167 168 static 169 NTSTATUS 170 NTAPI 171 LsapAddAuthPackage(IN PWSTR ValueName, 172 IN ULONG ValueType, 173 IN PVOID ValueData, 174 IN ULONG ValueLength, 175 IN PVOID Context, 176 IN PVOID EntryContext) 177 { 178 PAUTH_PACKAGE Package = NULL; 179 UNICODE_STRING PackageName; 180 STRING ProcName; 181 PULONG Id; 182 NTSTATUS Status = STATUS_SUCCESS; 183 184 TRACE("LsapAddAuthPackage()\n"); 185 186 PackageName.Length = (USHORT)ValueLength - sizeof(WCHAR); 187 PackageName.MaximumLength = (USHORT)ValueLength; 188 PackageName.Buffer = ValueData; 189 190 Id = (PULONG)Context; 191 192 Package = RtlAllocateHeap(RtlGetProcessHeap(), 193 HEAP_ZERO_MEMORY, 194 sizeof(AUTH_PACKAGE)); 195 if (Package == NULL) 196 return STATUS_INSUFFICIENT_RESOURCES; 197 198 Status = LdrLoadDll(NULL, 199 NULL, 200 &PackageName, 201 &Package->ModuleHandle); 202 if (!NT_SUCCESS(Status)) 203 { 204 TRACE("LdrLoadDll failed (Status 0x%08lx)\n", Status); 205 goto done; 206 } 207 208 RtlInitAnsiString(&ProcName, "LsaApInitializePackage"); 209 Status = LdrGetProcedureAddress(Package->ModuleHandle, 210 &ProcName, 211 0, 212 (PVOID *)&Package->LsaApInitializePackage); 213 if (!NT_SUCCESS(Status)) 214 { 215 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status); 216 goto done; 217 } 218 219 RtlInitAnsiString(&ProcName, "LsaApCallPackage"); 220 Status = LdrGetProcedureAddress(Package->ModuleHandle, 221 &ProcName, 222 0, 223 (PVOID *)&Package->LsaApCallPackage); 224 if (!NT_SUCCESS(Status)) 225 { 226 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status); 227 goto done; 228 } 229 230 RtlInitAnsiString(&ProcName, "LsaApCallPackagePassthrough"); 231 Status = LdrGetProcedureAddress(Package->ModuleHandle, 232 &ProcName, 233 0, 234 (PVOID *)&Package->LsaApCallPackagePassthrough); 235 if (!NT_SUCCESS(Status)) 236 { 237 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status); 238 goto done; 239 } 240 241 RtlInitAnsiString(&ProcName, "LsaApCallPackageUntrusted"); 242 Status = LdrGetProcedureAddress(Package->ModuleHandle, 243 &ProcName, 244 0, 245 (PVOID *)&Package->LsaApCallPackageUntrusted); 246 if (!NT_SUCCESS(Status)) 247 { 248 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status); 249 goto done; 250 } 251 252 RtlInitAnsiString(&ProcName, "LsaApLogonTerminated"); 253 Status = LdrGetProcedureAddress(Package->ModuleHandle, 254 &ProcName, 255 0, 256 (PVOID *)&Package->LsaApLogonTerminated); 257 if (!NT_SUCCESS(Status)) 258 { 259 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status); 260 goto done; 261 } 262 263 RtlInitAnsiString(&ProcName, "LsaApLogonUserEx2"); 264 Status = LdrGetProcedureAddress(Package->ModuleHandle, 265 &ProcName, 266 0, 267 (PVOID *)&Package->LsaApLogonUserEx2); 268 if (!NT_SUCCESS(Status)) 269 { 270 RtlInitAnsiString(&ProcName, "LsaApLogonUserEx"); 271 Status = LdrGetProcedureAddress(Package->ModuleHandle, 272 &ProcName, 273 0, 274 (PVOID *)&Package->LsaApLogonUserEx); 275 if (!NT_SUCCESS(Status)) 276 { 277 RtlInitAnsiString(&ProcName, "LsaApLogonUser"); 278 Status = LdrGetProcedureAddress(Package->ModuleHandle, 279 &ProcName, 280 0, 281 (PVOID *)&Package->LsaApLogonUser); 282 if (!NT_SUCCESS(Status)) 283 { 284 TRACE("LdrGetProcedureAddress() failed (Status 0x%08lx)\n", Status); 285 goto done; 286 } 287 } 288 } 289 290 /* Initialize the current package */ 291 Status = Package->LsaApInitializePackage(*Id, 292 &DispatchTable, 293 NULL, 294 NULL, 295 &Package->Name); 296 if (!NT_SUCCESS(Status)) 297 { 298 TRACE("Package->LsaApInitializePackage() failed (Status 0x%08lx)\n", Status); 299 goto done; 300 } 301 302 TRACE("Package Name: %s\n", Package->Name->Buffer); 303 304 Package->Id = *Id; 305 (*Id)++; 306 307 InsertTailList(&PackageListHead, &Package->Entry); 308 309 done: 310 if (!NT_SUCCESS(Status)) 311 { 312 if (Package != NULL) 313 { 314 if (Package->ModuleHandle != NULL) 315 LdrUnloadDll(Package->ModuleHandle); 316 317 if (Package->Name != NULL) 318 { 319 if (Package->Name->Buffer != NULL) 320 RtlFreeHeap(RtlGetProcessHeap(), 0, Package->Name->Buffer); 321 322 RtlFreeHeap(RtlGetProcessHeap(), 0, Package->Name); 323 } 324 325 RtlFreeHeap(RtlGetProcessHeap(), 0, Package); 326 } 327 } 328 329 return Status; 330 } 331 332 333 static 334 PAUTH_PACKAGE 335 LsapGetAuthenticationPackage(IN ULONG PackageId) 336 { 337 PLIST_ENTRY ListEntry; 338 PAUTH_PACKAGE Package; 339 340 ListEntry = PackageListHead.Flink; 341 while (ListEntry != &PackageListHead) 342 { 343 Package = CONTAINING_RECORD(ListEntry, AUTH_PACKAGE, Entry); 344 345 if (Package->Id == PackageId) 346 { 347 return Package; 348 } 349 350 ListEntry = ListEntry->Flink; 351 } 352 353 return NULL; 354 } 355 356 357 PVOID 358 NTAPI 359 LsapAllocateHeap(IN ULONG Length) 360 { 361 return RtlAllocateHeap(RtlGetProcessHeap(), 0, Length); 362 } 363 364 365 PVOID 366 NTAPI 367 LsapAllocateHeapZero(IN ULONG Length) 368 { 369 return RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length); 370 } 371 372 373 VOID 374 NTAPI 375 LsapFreeHeap(IN PVOID Base) 376 { 377 RtlFreeHeap(RtlGetProcessHeap(), 0, Base); 378 } 379 380 381 static 382 NTSTATUS 383 NTAPI 384 LsapAllocateClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest, 385 IN ULONG LengthRequired, 386 OUT PVOID *ClientBaseAddress) 387 { 388 PLSAP_LOGON_CONTEXT LogonContext; 389 ULONG Length; 390 391 *ClientBaseAddress = NULL; 392 393 LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest; 394 395 Length = LengthRequired; 396 return NtAllocateVirtualMemory(LogonContext->ClientProcessHandle, 397 ClientBaseAddress, 398 0, 399 &Length, 400 MEM_COMMIT, 401 PAGE_READWRITE); 402 } 403 404 405 static 406 NTSTATUS 407 NTAPI 408 LsapFreeClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest, 409 IN PVOID ClientBaseAddress) 410 { 411 PLSAP_LOGON_CONTEXT LogonContext; 412 ULONG Length; 413 414 if (ClientBaseAddress == NULL) 415 return STATUS_SUCCESS; 416 417 LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest; 418 419 Length = 0; 420 return NtFreeVirtualMemory(LogonContext->ClientProcessHandle, 421 &ClientBaseAddress, 422 &Length, 423 MEM_RELEASE); 424 } 425 426 427 static 428 NTSTATUS 429 NTAPI 430 LsapCopyToClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest, 431 IN ULONG Length, 432 IN PVOID ClientBaseAddress, 433 IN PVOID BufferToCopy) 434 { 435 PLSAP_LOGON_CONTEXT LogonContext; 436 437 LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest; 438 439 return NtWriteVirtualMemory(LogonContext->ClientProcessHandle, 440 ClientBaseAddress, 441 BufferToCopy, 442 Length, 443 NULL); 444 } 445 446 447 static 448 NTSTATUS 449 NTAPI 450 LsapCopyFromClientBuffer(IN PLSA_CLIENT_REQUEST ClientRequest, 451 IN ULONG Length, 452 IN PVOID BufferToCopy, 453 IN PVOID ClientBaseAddress) 454 { 455 PLSAP_LOGON_CONTEXT LogonContext; 456 457 LogonContext = (PLSAP_LOGON_CONTEXT)ClientRequest; 458 459 return NtReadVirtualMemory(LogonContext->ClientProcessHandle, 460 ClientBaseAddress, 461 BufferToCopy, 462 Length, 463 NULL); 464 } 465 466 467 NTSTATUS 468 LsapInitAuthPackages(VOID) 469 { 470 RTL_QUERY_REGISTRY_TABLE AuthPackageTable[] = { 471 {LsapAddAuthPackage, 0, L"Authentication Packages", NULL, REG_NONE, NULL, 0}, 472 {NULL, 0, NULL, NULL, REG_NONE, NULL, 0}}; 473 474 NTSTATUS Status; 475 476 InitializeListHead(&PackageListHead); 477 PackageId = 0; 478 479 /* Initialize the dispatch table */ 480 DispatchTable.CreateLogonSession = &LsapCreateLogonSession; 481 DispatchTable.DeleteLogonSession = &LsapDeleteLogonSession; 482 DispatchTable.AddCredential = &LsapAddCredential; 483 DispatchTable.GetCredentials = &LsapGetCredentials; 484 DispatchTable.DeleteCredential = &LsapDeleteCredential; 485 DispatchTable.AllocateLsaHeap = &LsapAllocateHeapZero; 486 DispatchTable.FreeLsaHeap = &LsapFreeHeap; 487 DispatchTable.AllocateClientBuffer = &LsapAllocateClientBuffer; 488 DispatchTable.FreeClientBuffer = &LsapFreeClientBuffer; 489 DispatchTable.CopyToClientBuffer = &LsapCopyToClientBuffer; 490 DispatchTable.CopyFromClientBuffer = &LsapCopyFromClientBuffer; 491 492 /* Add registered authentication packages */ 493 Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL, 494 L"Lsa", 495 AuthPackageTable, 496 &PackageId, 497 NULL); 498 499 return Status; 500 } 501 502 503 NTSTATUS 504 LsapLookupAuthenticationPackage(PLSA_API_MSG RequestMsg, 505 PLSAP_LOGON_CONTEXT LogonContext) 506 { 507 PLIST_ENTRY ListEntry; 508 PAUTH_PACKAGE Package; 509 ULONG PackageNameLength; 510 PCHAR PackageName; 511 512 TRACE("(%p %p)\n", RequestMsg, LogonContext); 513 514 PackageNameLength = RequestMsg->LookupAuthenticationPackage.Request.PackageNameLength; 515 PackageName = RequestMsg->LookupAuthenticationPackage.Request.PackageName; 516 517 TRACE("PackageName: %s\n", PackageName); 518 519 ListEntry = PackageListHead.Flink; 520 while (ListEntry != &PackageListHead) 521 { 522 Package = CONTAINING_RECORD(ListEntry, AUTH_PACKAGE, Entry); 523 524 if ((PackageNameLength == Package->Name->Length) && 525 (_strnicmp(PackageName, Package->Name->Buffer, Package->Name->Length) == 0)) 526 { 527 RequestMsg->LookupAuthenticationPackage.Reply.Package = Package->Id; 528 return STATUS_SUCCESS; 529 } 530 531 ListEntry = ListEntry->Flink; 532 } 533 534 return STATUS_NO_SUCH_PACKAGE; 535 } 536 537 538 NTSTATUS 539 LsapCallAuthenticationPackage(PLSA_API_MSG RequestMsg, 540 PLSAP_LOGON_CONTEXT LogonContext) 541 { 542 PAUTH_PACKAGE Package; 543 PVOID LocalBuffer = NULL; 544 ULONG PackageId; 545 NTSTATUS Status; 546 547 TRACE("(%p %p)\n", RequestMsg, LogonContext); 548 549 PackageId = RequestMsg->CallAuthenticationPackage.Request.AuthenticationPackage; 550 551 /* Get the right authentication package */ 552 Package = LsapGetAuthenticationPackage(PackageId); 553 if (Package == NULL) 554 { 555 TRACE("LsapGetAuthenticationPackage() failed to find a package\n"); 556 return STATUS_NO_SUCH_PACKAGE; 557 } 558 559 if (RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength > 0) 560 { 561 LocalBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 562 HEAP_ZERO_MEMORY, 563 RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength); 564 if (LocalBuffer == NULL) 565 { 566 return STATUS_INSUFFICIENT_RESOURCES; 567 } 568 569 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle, 570 RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer, 571 LocalBuffer, 572 RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength, 573 NULL); 574 if (!NT_SUCCESS(Status)) 575 { 576 TRACE("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status); 577 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer); 578 return Status; 579 } 580 } 581 582 Status = Package->LsaApCallPackage((PLSA_CLIENT_REQUEST)LogonContext, 583 LocalBuffer, 584 RequestMsg->CallAuthenticationPackage.Request.ProtocolSubmitBuffer, 585 RequestMsg->CallAuthenticationPackage.Request.SubmitBufferLength, 586 &RequestMsg->CallAuthenticationPackage.Reply.ProtocolReturnBuffer, 587 &RequestMsg->CallAuthenticationPackage.Reply.ReturnBufferLength, 588 &RequestMsg->CallAuthenticationPackage.Reply.ProtocolStatus); 589 if (!NT_SUCCESS(Status)) 590 { 591 TRACE("Package->LsaApCallPackage() failed (Status 0x%08lx)\n", Status); 592 } 593 594 if (LocalBuffer != NULL) 595 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer); 596 597 return Status; 598 } 599 600 601 static 602 NTSTATUS 603 LsapCopyLocalGroups( 604 IN PLSAP_LOGON_CONTEXT LogonContext, 605 IN PTOKEN_GROUPS ClientGroups, 606 IN ULONG ClientGroupsCount, 607 OUT PTOKEN_GROUPS *TokenGroups) 608 { 609 ULONG LocalGroupsLength = 0; 610 PTOKEN_GROUPS LocalGroups = NULL; 611 ULONG SidHeaderLength = 0; 612 PSID SidHeader = NULL; 613 PSID SrcSid, DstSid; 614 ULONG SidLength; 615 ULONG AllocatedSids = 0; 616 ULONG i; 617 NTSTATUS Status; 618 619 LocalGroupsLength = sizeof(TOKEN_GROUPS) + 620 (ClientGroupsCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES); 621 LocalGroups = RtlAllocateHeap(RtlGetProcessHeap(), 622 HEAP_ZERO_MEMORY, 623 LocalGroupsLength); 624 if (LocalGroups == NULL) 625 { 626 TRACE("RtlAllocateHeap() failed\n"); 627 return STATUS_INSUFFICIENT_RESOURCES; 628 } 629 630 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle, 631 ClientGroups, 632 LocalGroups, 633 LocalGroupsLength, 634 NULL); 635 if (!NT_SUCCESS(Status)) 636 goto done; 637 638 639 SidHeaderLength = RtlLengthRequiredSid(0); 640 SidHeader = RtlAllocateHeap(RtlGetProcessHeap(), 641 HEAP_ZERO_MEMORY, 642 SidHeaderLength); 643 if (SidHeader == NULL) 644 { 645 Status = STATUS_INSUFFICIENT_RESOURCES; 646 goto done; 647 } 648 649 for (i = 0; i < ClientGroupsCount; i++) 650 { 651 SrcSid = LocalGroups->Groups[i].Sid; 652 653 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle, 654 SrcSid, 655 SidHeader, 656 SidHeaderLength, 657 NULL); 658 if (!NT_SUCCESS(Status)) 659 goto done; 660 661 SidLength = RtlLengthSid(SidHeader); 662 TRACE("Sid %lu: Length %lu\n", i, SidLength); 663 664 DstSid = RtlAllocateHeap(RtlGetProcessHeap(), 665 HEAP_ZERO_MEMORY, 666 SidLength); 667 if (DstSid == NULL) 668 { 669 Status = STATUS_INSUFFICIENT_RESOURCES; 670 goto done; 671 } 672 673 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle, 674 SrcSid, 675 DstSid, 676 SidLength, 677 NULL); 678 if (!NT_SUCCESS(Status)) 679 { 680 RtlFreeHeap(RtlGetProcessHeap(), 0, DstSid); 681 goto done; 682 } 683 684 LocalGroups->Groups[i].Sid = DstSid; 685 AllocatedSids++; 686 } 687 688 *TokenGroups = LocalGroups; 689 690 done: 691 if (SidHeader != NULL) 692 RtlFreeHeap(RtlGetProcessHeap(), 0, SidHeader); 693 694 if (!NT_SUCCESS(Status)) 695 { 696 if (LocalGroups != NULL) 697 { 698 for (i = 0; i < AllocatedSids; i++) 699 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid); 700 701 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups); 702 } 703 } 704 705 return Status; 706 } 707 708 709 static 710 NTSTATUS 711 LsapAddLocalGroups( 712 IN PVOID TokenInformation, 713 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType, 714 IN PTOKEN_GROUPS LocalGroups) 715 { 716 PLSA_TOKEN_INFORMATION_V1 TokenInfo1; 717 PTOKEN_GROUPS Groups; 718 ULONG Length; 719 ULONG i; 720 ULONG j; 721 722 if (LocalGroups == NULL || LocalGroups->GroupCount == 0) 723 return STATUS_SUCCESS; 724 725 if (TokenInformationType == LsaTokenInformationV1) 726 { 727 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation; 728 729 if (TokenInfo1->Groups != NULL) 730 { 731 Length = sizeof(TOKEN_GROUPS) + 732 (LocalGroups->GroupCount + TokenInfo1->Groups->GroupCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES); 733 734 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length); 735 if (Groups == NULL) 736 { 737 ERR("Group buffer allocation failed!\n"); 738 return STATUS_INSUFFICIENT_RESOURCES; 739 } 740 741 Groups->GroupCount = LocalGroups->GroupCount + TokenInfo1->Groups->GroupCount; 742 743 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++) 744 { 745 Groups->Groups[i].Sid = TokenInfo1->Groups->Groups[i].Sid; 746 Groups->Groups[i].Attributes = TokenInfo1->Groups->Groups[i].Attributes; 747 } 748 749 for (j = 0; j < LocalGroups->GroupCount; i++, j++) 750 { 751 Groups->Groups[i].Sid = LocalGroups->Groups[j].Sid; 752 Groups->Groups[i].Attributes = LocalGroups->Groups[j].Attributes; 753 LocalGroups->Groups[j].Sid = NULL; 754 } 755 756 RtlFreeHeap(RtlGetProcessHeap(), 0, TokenInfo1->Groups); 757 758 TokenInfo1->Groups = Groups; 759 } 760 else 761 { 762 Length = sizeof(TOKEN_GROUPS) + 763 (LocalGroups->GroupCount - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES); 764 765 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length); 766 if (Groups == NULL) 767 { 768 ERR("Group buffer allocation failed!\n"); 769 return STATUS_INSUFFICIENT_RESOURCES; 770 } 771 772 Groups->GroupCount = LocalGroups->GroupCount; 773 774 for (i = 0; i < LocalGroups->GroupCount; i++) 775 { 776 Groups->Groups[i].Sid = LocalGroups->Groups[i].Sid; 777 Groups->Groups[i].Attributes = LocalGroups->Groups[i].Attributes; 778 } 779 780 TokenInfo1->Groups = Groups; 781 } 782 } 783 else 784 { 785 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType); 786 return STATUS_NOT_IMPLEMENTED; 787 } 788 789 return STATUS_SUCCESS; 790 } 791 792 static 793 NTSTATUS 794 LsapAddDefaultGroups( 795 IN PVOID TokenInformation, 796 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType, 797 IN SECURITY_LOGON_TYPE LogonType) 798 { 799 PLSA_TOKEN_INFORMATION_V1 TokenInfo1; 800 PTOKEN_GROUPS Groups; 801 ULONG i, Length; 802 PSID SrcSid; 803 804 if (TokenInformationType == LsaTokenInformationV1) 805 { 806 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation; 807 808 if (TokenInfo1->Groups != NULL) 809 { 810 Length = sizeof(TOKEN_GROUPS) + 811 (TokenInfo1->Groups->GroupCount + 2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES); 812 813 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length); 814 if (Groups == NULL) 815 { 816 ERR("Group buffer allocation failed!\n"); 817 return STATUS_INSUFFICIENT_RESOURCES; 818 } 819 820 Groups->GroupCount = TokenInfo1->Groups->GroupCount; 821 822 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++) 823 { 824 Groups->Groups[i].Sid = TokenInfo1->Groups->Groups[i].Sid; 825 Groups->Groups[i].Attributes = TokenInfo1->Groups->Groups[i].Attributes; 826 } 827 828 RtlFreeHeap(RtlGetProcessHeap(), 0, TokenInfo1->Groups); 829 830 TokenInfo1->Groups = Groups; 831 832 } 833 else 834 { 835 Length = sizeof(TOKEN_GROUPS) + 836 (2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES); 837 838 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length); 839 if (Groups == NULL) 840 { 841 ERR("Group buffer allocation failed!\n"); 842 return STATUS_INSUFFICIENT_RESOURCES; 843 } 844 845 TokenInfo1->Groups = Groups; 846 } 847 848 /* Append the World SID (aka Everyone) */ 849 Length = RtlLengthSid(LsapWorldSid); 850 Groups->Groups[Groups->GroupCount].Sid = RtlAllocateHeap(RtlGetProcessHeap(), 851 HEAP_ZERO_MEMORY, 852 Length); 853 if (Groups->Groups[Groups->GroupCount].Sid == NULL) 854 return STATUS_INSUFFICIENT_RESOURCES; 855 856 RtlCopyMemory(Groups->Groups[Groups->GroupCount].Sid, 857 LsapWorldSid, 858 Length); 859 860 Groups->Groups[Groups->GroupCount].Attributes = 861 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; 862 863 Groups->GroupCount++; 864 865 /* Append the logon type SID */ 866 switch (LogonType) 867 { 868 case Interactive: 869 SrcSid = LsapInteractiveSid; 870 break; 871 872 case Network: 873 SrcSid = LsapNetworkSid; 874 break; 875 876 case Batch: 877 SrcSid = LsapBatchSid; 878 break; 879 880 case Service: 881 SrcSid = LsapServiceSid; 882 break; 883 884 default: 885 FIXME("LogonType %d is not supported!\n", LogonType); 886 return STATUS_NOT_IMPLEMENTED; 887 } 888 889 Length = RtlLengthSid(SrcSid); 890 Groups->Groups[Groups->GroupCount].Sid = RtlAllocateHeap(RtlGetProcessHeap(), 891 HEAP_ZERO_MEMORY, 892 Length); 893 if (Groups->Groups[Groups->GroupCount].Sid == NULL) 894 return STATUS_INSUFFICIENT_RESOURCES; 895 896 RtlCopyMemory(Groups->Groups[Groups->GroupCount].Sid, 897 SrcSid, 898 Length); 899 900 Groups->Groups[Groups->GroupCount].Attributes = 901 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; 902 903 Groups->GroupCount++; 904 } 905 else 906 { 907 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType); 908 return STATUS_NOT_IMPLEMENTED; 909 } 910 911 return STATUS_SUCCESS; 912 } 913 914 915 static 916 NTSTATUS 917 LsapAppendSidToGroups( 918 IN PTOKEN_GROUPS *TokenGroups, 919 IN PSID DomainSid, 920 IN ULONG RelativeId) 921 { 922 PTOKEN_GROUPS Groups; 923 PSID Sid; 924 ULONG Length; 925 ULONG i; 926 927 Sid = LsapAppendRidToSid(DomainSid, RelativeId); 928 if (Sid == NULL) 929 { 930 ERR("Group SID creation failed!\n"); 931 return STATUS_INSUFFICIENT_RESOURCES; 932 } 933 934 if (*TokenGroups == NULL) 935 { 936 Length = sizeof(TOKEN_GROUPS) + 937 (1 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES); 938 939 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length); 940 if (Groups == NULL) 941 { 942 ERR("Group buffer allocation failed!\n"); 943 return STATUS_INSUFFICIENT_RESOURCES; 944 } 945 946 Groups->GroupCount = 1; 947 948 Groups->Groups[0].Sid = Sid; 949 Groups->Groups[0].Attributes = 950 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; 951 952 *TokenGroups = Groups; 953 } 954 else 955 { 956 for (i = 0; i < (*TokenGroups)->GroupCount; i++) 957 { 958 if (RtlEqualSid((*TokenGroups)->Groups[i].Sid, Sid)) 959 { 960 RtlFreeHeap(RtlGetProcessHeap(), 0, Sid); 961 return STATUS_SUCCESS; 962 } 963 } 964 965 Length = sizeof(TOKEN_GROUPS) + 966 ((*TokenGroups)->GroupCount + 1 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES); 967 968 Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length); 969 if (Groups == NULL) 970 { 971 ERR("Group buffer allocation failed!\n"); 972 return STATUS_INSUFFICIENT_RESOURCES; 973 } 974 975 Groups->GroupCount = (*TokenGroups)->GroupCount; 976 977 for (i = 0; i < (*TokenGroups)->GroupCount; i++) 978 { 979 Groups->Groups[i].Sid = (*TokenGroups)->Groups[i].Sid; 980 Groups->Groups[i].Attributes = (*TokenGroups)->Groups[i].Attributes; 981 } 982 983 Groups->Groups[Groups->GroupCount].Sid = Sid; 984 Groups->Groups[Groups->GroupCount].Attributes = 985 SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; 986 987 Groups->GroupCount++; 988 989 RtlFreeHeap(RtlGetProcessHeap(), 0, *TokenGroups); 990 991 *TokenGroups = Groups; 992 } 993 994 return STATUS_SUCCESS; 995 } 996 997 998 static 999 NTSTATUS 1000 LsapAddSamGroups( 1001 IN PVOID TokenInformation, 1002 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType) 1003 { 1004 PLSA_TOKEN_INFORMATION_V1 TokenInfo1; 1005 SAMPR_HANDLE ServerHandle = NULL; 1006 SAMPR_HANDLE BuiltinDomainHandle = NULL; 1007 SAMPR_HANDLE AccountDomainHandle = NULL; 1008 SAMPR_PSID_ARRAY SidArray; 1009 SAMPR_ULONG_ARRAY BuiltinMembership; 1010 SAMPR_ULONG_ARRAY AccountMembership; 1011 ULONG i; 1012 NTSTATUS Status = STATUS_SUCCESS; 1013 1014 if (TokenInformationType != LsaTokenInformationV1) 1015 return STATUS_SUCCESS; 1016 1017 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation; 1018 1019 SidArray.Count = TokenInfo1->Groups->GroupCount + 1; 1020 SidArray.Sids = RtlAllocateHeap(RtlGetProcessHeap(), 1021 HEAP_ZERO_MEMORY, 1022 (TokenInfo1->Groups->GroupCount + 1) * sizeof(PRPC_SID)); 1023 if (SidArray.Sids == NULL) 1024 return STATUS_INSUFFICIENT_RESOURCES; 1025 1026 SidArray.Sids[0].SidPointer = TokenInfo1->User.User.Sid; 1027 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++) 1028 SidArray.Sids[i + 1].SidPointer = TokenInfo1->Groups->Groups[i].Sid; 1029 1030 BuiltinMembership.Element = NULL; 1031 AccountMembership.Element = NULL; 1032 1033 Status = SamIConnect(NULL, 1034 &ServerHandle, 1035 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, 1036 FALSE); 1037 if (!NT_SUCCESS(Status)) 1038 { 1039 TRACE("SamIConnect failed (Status %08lx)\n", Status); 1040 goto done; 1041 } 1042 1043 Status = SamrOpenDomain(ServerHandle, 1044 DOMAIN_GET_ALIAS_MEMBERSHIP, 1045 BuiltinDomainSid, 1046 &BuiltinDomainHandle); 1047 if (!NT_SUCCESS(Status)) 1048 { 1049 TRACE("SamrOpenDomain failed (Status %08lx)\n", Status); 1050 goto done; 1051 } 1052 1053 Status = SamrOpenDomain(ServerHandle, 1054 DOMAIN_GET_ALIAS_MEMBERSHIP, 1055 AccountDomainSid, 1056 &AccountDomainHandle); 1057 if (!NT_SUCCESS(Status)) 1058 { 1059 TRACE("SamrOpenDomain failed (Status %08lx)\n", Status); 1060 goto done; 1061 } 1062 1063 Status = SamrGetAliasMembership(BuiltinDomainHandle, 1064 &SidArray, 1065 &BuiltinMembership); 1066 if (!NT_SUCCESS(Status)) 1067 { 1068 TRACE("SamrGetAliasMembership failed (Status %08lx)\n", Status); 1069 goto done; 1070 } 1071 1072 Status = SamrGetAliasMembership(AccountDomainHandle, 1073 &SidArray, 1074 &AccountMembership); 1075 if (!NT_SUCCESS(Status)) 1076 { 1077 TRACE("SamrGetAliasMembership failed (Status %08lx)\n", Status); 1078 goto done; 1079 } 1080 1081 TRACE("Builtin Memberships: %lu\n", BuiltinMembership.Count); 1082 for (i = 0; i < BuiltinMembership.Count; i++) 1083 { 1084 TRACE("RID %lu: %lu (0x%lx)\n", i, BuiltinMembership.Element[i], BuiltinMembership.Element[i]); 1085 Status = LsapAppendSidToGroups(&TokenInfo1->Groups, 1086 BuiltinDomainSid, 1087 BuiltinMembership.Element[i]); 1088 if (!NT_SUCCESS(Status)) 1089 { 1090 TRACE("LsapAppendSidToGroups failed (Status %08lx)\n", Status); 1091 goto done; 1092 } 1093 } 1094 1095 TRACE("Account Memberships: %lu\n", AccountMembership.Count); 1096 for (i = 0; i < AccountMembership.Count; i++) 1097 { 1098 TRACE("RID %lu: %lu (0x%lx)\n", i, AccountMembership.Element[i], AccountMembership.Element[i]); 1099 Status = LsapAppendSidToGroups(&TokenInfo1->Groups, 1100 AccountDomainSid, 1101 AccountMembership.Element[i]); 1102 if (!NT_SUCCESS(Status)) 1103 { 1104 TRACE("LsapAppendSidToGroups failed (Status %08lx)\n", Status); 1105 goto done; 1106 } 1107 } 1108 1109 done: 1110 RtlFreeHeap(RtlGetProcessHeap(), 0, SidArray.Sids); 1111 1112 if (AccountMembership.Element != NULL) 1113 SamIFree_SAMPR_ULONG_ARRAY(&AccountMembership); 1114 1115 if (BuiltinMembership.Element != NULL) 1116 SamIFree_SAMPR_ULONG_ARRAY(&BuiltinMembership); 1117 1118 if (AccountDomainHandle != NULL) 1119 SamrCloseHandle(&AccountDomainHandle); 1120 1121 if (BuiltinDomainHandle != NULL) 1122 SamrCloseHandle(&BuiltinDomainHandle); 1123 1124 if (ServerHandle != NULL) 1125 SamrCloseHandle(&ServerHandle); 1126 1127 // return Status; 1128 1129 return STATUS_SUCCESS; 1130 } 1131 1132 1133 static 1134 NTSTATUS 1135 LsapSetTokenOwner( 1136 IN PVOID TokenInformation, 1137 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType) 1138 { 1139 PLSA_TOKEN_INFORMATION_V1 TokenInfo1; 1140 PSID OwnerSid = NULL; 1141 ULONG i, Length; 1142 1143 if (TokenInformationType == LsaTokenInformationV1) 1144 { 1145 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation; 1146 1147 if (TokenInfo1->Owner.Owner != NULL) 1148 return STATUS_SUCCESS; 1149 1150 OwnerSid = TokenInfo1->User.User.Sid; 1151 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++) 1152 { 1153 if (EqualSid(TokenInfo1->Groups->Groups[i].Sid, LsapAdministratorsSid)) 1154 { 1155 OwnerSid = LsapAdministratorsSid; 1156 break; 1157 } 1158 } 1159 1160 Length = RtlLengthSid(OwnerSid); 1161 TokenInfo1->Owner.Owner = DispatchTable.AllocateLsaHeap(Length); 1162 if (TokenInfo1->Owner.Owner == NULL) 1163 return STATUS_INSUFFICIENT_RESOURCES; 1164 1165 RtlCopyMemory(TokenInfo1->Owner.Owner, 1166 OwnerSid, 1167 Length); 1168 } 1169 1170 return STATUS_SUCCESS; 1171 } 1172 1173 1174 static 1175 NTSTATUS 1176 LsapAddTokenDefaultDacl( 1177 IN PVOID TokenInformation, 1178 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType) 1179 { 1180 PLSA_TOKEN_INFORMATION_V1 TokenInfo1; 1181 PACL Dacl = NULL; 1182 ULONG Length; 1183 1184 if (TokenInformationType == LsaTokenInformationV1) 1185 { 1186 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation; 1187 1188 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL) 1189 return STATUS_SUCCESS; 1190 1191 Length = sizeof(ACL) + 1192 (2 * sizeof(ACCESS_ALLOWED_ACE)) + 1193 RtlLengthSid(TokenInfo1->Owner.Owner) + 1194 RtlLengthSid(LsapLocalSystemSid); 1195 1196 Dacl = DispatchTable.AllocateLsaHeap(Length); 1197 if (Dacl == NULL) 1198 return STATUS_INSUFFICIENT_RESOURCES; 1199 1200 RtlCreateAcl(Dacl, Length, ACL_REVISION); 1201 1202 RtlAddAccessAllowedAce(Dacl, 1203 ACL_REVISION, 1204 GENERIC_ALL, 1205 TokenInfo1->Owner.Owner); 1206 1207 /* SID: S-1-5-18 */ 1208 RtlAddAccessAllowedAce(Dacl, 1209 ACL_REVISION, 1210 GENERIC_ALL, 1211 LsapLocalSystemSid); 1212 1213 TokenInfo1->DefaultDacl.DefaultDacl = Dacl; 1214 } 1215 1216 return STATUS_SUCCESS; 1217 } 1218 1219 1220 static 1221 NTSTATUS 1222 LsapAddPrivilegeToTokenPrivileges(PTOKEN_PRIVILEGES *TokenPrivileges, 1223 PLSAPR_LUID_AND_ATTRIBUTES Privilege) 1224 { 1225 PTOKEN_PRIVILEGES LocalPrivileges; 1226 ULONG Length, TokenPrivilegeCount, i; 1227 NTSTATUS Status = STATUS_SUCCESS; 1228 1229 if (*TokenPrivileges == NULL) 1230 { 1231 Length = sizeof(TOKEN_PRIVILEGES) + 1232 (1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES); 1233 LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(), 1234 0, 1235 Length); 1236 if (LocalPrivileges == NULL) 1237 return STATUS_INSUFFICIENT_RESOURCES; 1238 1239 LocalPrivileges->PrivilegeCount = 1; 1240 LocalPrivileges->Privileges[0].Luid = Privilege->Luid; 1241 LocalPrivileges->Privileges[0].Attributes = Privilege->Attributes; 1242 } 1243 else 1244 { 1245 TokenPrivilegeCount = (*TokenPrivileges)->PrivilegeCount; 1246 1247 for (i = 0; i < TokenPrivilegeCount; i++) 1248 { 1249 if (RtlEqualLuid(&(*TokenPrivileges)->Privileges[i].Luid, &Privilege->Luid)) 1250 return STATUS_SUCCESS; 1251 } 1252 1253 Length = sizeof(TOKEN_PRIVILEGES) + 1254 (TokenPrivilegeCount + 1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES); 1255 LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(), 1256 0, 1257 Length); 1258 if (LocalPrivileges == NULL) 1259 return STATUS_INSUFFICIENT_RESOURCES; 1260 1261 LocalPrivileges->PrivilegeCount = TokenPrivilegeCount + 1; 1262 for (i = 0; i < TokenPrivilegeCount; i++) 1263 { 1264 LocalPrivileges->Privileges[i].Luid = (*TokenPrivileges)->Privileges[i].Luid; 1265 LocalPrivileges->Privileges[i].Attributes = (*TokenPrivileges)->Privileges[i].Attributes; 1266 } 1267 1268 LocalPrivileges->Privileges[TokenPrivilegeCount].Luid = Privilege->Luid; 1269 LocalPrivileges->Privileges[TokenPrivilegeCount].Attributes = Privilege->Attributes; 1270 1271 RtlFreeHeap(RtlGetProcessHeap(), 0, *TokenPrivileges); 1272 } 1273 1274 *TokenPrivileges = LocalPrivileges; 1275 1276 return Status; 1277 } 1278 1279 static 1280 NTSTATUS 1281 LsapSetPrivileges( 1282 IN PVOID TokenInformation, 1283 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType) 1284 { 1285 PLSA_TOKEN_INFORMATION_V1 TokenInfo1; 1286 LSAPR_HANDLE PolicyHandle = NULL; 1287 LSAPR_HANDLE AccountHandle = NULL; 1288 PLSAPR_PRIVILEGE_SET Privileges = NULL; 1289 ULONG i, j; 1290 NTSTATUS Status; 1291 1292 if (TokenInformationType == LsaTokenInformationV1) 1293 { 1294 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation; 1295 1296 Status = LsarOpenPolicy(NULL, 1297 NULL, 1298 0, 1299 &PolicyHandle); 1300 if (!NT_SUCCESS(Status)) 1301 return Status; 1302 1303 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++) 1304 { 1305 Status = LsarOpenAccount(PolicyHandle, 1306 TokenInfo1->Groups->Groups[i].Sid, 1307 ACCOUNT_VIEW, 1308 &AccountHandle); 1309 if (!NT_SUCCESS(Status)) 1310 continue; 1311 1312 Status = LsarEnumeratePrivilegesAccount(AccountHandle, 1313 &Privileges); 1314 if (NT_SUCCESS(Status)) 1315 { 1316 for (j = 0; j < Privileges->PrivilegeCount; j++) 1317 { 1318 Status = LsapAddPrivilegeToTokenPrivileges(&TokenInfo1->Privileges, 1319 &(Privileges->Privilege[j])); 1320 if (!NT_SUCCESS(Status)) 1321 { 1322 /* We failed, clean everything and return */ 1323 LsaIFree_LSAPR_PRIVILEGE_SET(Privileges); 1324 LsarClose(&AccountHandle); 1325 LsarClose(&PolicyHandle); 1326 1327 return Status; 1328 } 1329 } 1330 1331 LsaIFree_LSAPR_PRIVILEGE_SET(Privileges); 1332 Privileges = NULL; 1333 } 1334 1335 LsarClose(&AccountHandle); 1336 } 1337 1338 LsarClose(&PolicyHandle); 1339 1340 if (TokenInfo1->Privileges != NULL) 1341 { 1342 for (i = 0; i < TokenInfo1->Privileges->PrivilegeCount; i++) 1343 { 1344 if (RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeChangeNotifyPrivilege) || 1345 RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeCreateGlobalPrivilege) || 1346 RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeImpersonatePrivilege)) 1347 { 1348 TokenInfo1->Privileges->Privileges[i].Attributes |= SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT; 1349 } 1350 } 1351 } 1352 } 1353 1354 return STATUS_SUCCESS; 1355 } 1356 1357 1358 NTSTATUS 1359 LsapLogonUser(PLSA_API_MSG RequestMsg, 1360 PLSAP_LOGON_CONTEXT LogonContext) 1361 { 1362 PAUTH_PACKAGE Package; 1363 OBJECT_ATTRIBUTES ObjectAttributes; 1364 SECURITY_QUALITY_OF_SERVICE Qos; 1365 LSA_TOKEN_INFORMATION_TYPE TokenInformationType; 1366 PVOID TokenInformation = NULL; 1367 PLSA_TOKEN_INFORMATION_V1 TokenInfo1 = NULL; 1368 PUNICODE_STRING AccountName = NULL; 1369 PUNICODE_STRING AuthenticatingAuthority = NULL; 1370 PUNICODE_STRING MachineName = NULL; 1371 PVOID LocalAuthInfo = NULL; 1372 PTOKEN_GROUPS LocalGroups = NULL; 1373 HANDLE TokenHandle = NULL; 1374 ULONG i; 1375 ULONG PackageId; 1376 SECURITY_LOGON_TYPE LogonType; 1377 NTSTATUS Status; 1378 1379 PUNICODE_STRING UserName = NULL; 1380 PUNICODE_STRING LogonDomainName = NULL; 1381 // UNICODE_STRING LogonServer; 1382 1383 1384 TRACE("LsapLogonUser(%p %p)\n", RequestMsg, LogonContext); 1385 1386 PackageId = RequestMsg->LogonUser.Request.AuthenticationPackage; 1387 LogonType = RequestMsg->LogonUser.Request.LogonType; 1388 1389 /* Get the right authentication package */ 1390 Package = LsapGetAuthenticationPackage(PackageId); 1391 if (Package == NULL) 1392 { 1393 ERR("LsapGetAuthenticationPackage() failed to find a package\n"); 1394 return STATUS_NO_SUCH_PACKAGE; 1395 } 1396 1397 if (RequestMsg->LogonUser.Request.AuthenticationInformationLength > 0) 1398 { 1399 /* Allocate the local authentication info buffer */ 1400 LocalAuthInfo = RtlAllocateHeap(RtlGetProcessHeap(), 1401 HEAP_ZERO_MEMORY, 1402 RequestMsg->LogonUser.Request.AuthenticationInformationLength); 1403 if (LocalAuthInfo == NULL) 1404 { 1405 ERR("RtlAllocateHeap() failed\n"); 1406 return STATUS_INSUFFICIENT_RESOURCES; 1407 } 1408 1409 /* Read the authentication info from the callers address space */ 1410 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle, 1411 RequestMsg->LogonUser.Request.AuthenticationInformation, 1412 LocalAuthInfo, 1413 RequestMsg->LogonUser.Request.AuthenticationInformationLength, 1414 NULL); 1415 if (!NT_SUCCESS(Status)) 1416 { 1417 ERR("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status); 1418 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo); 1419 return Status; 1420 } 1421 } 1422 1423 if (RequestMsg->LogonUser.Request.LocalGroupsCount > 0) 1424 { 1425 Status = LsapCopyLocalGroups(LogonContext, 1426 RequestMsg->LogonUser.Request.LocalGroups, 1427 RequestMsg->LogonUser.Request.LocalGroupsCount, 1428 &LocalGroups); 1429 if (!NT_SUCCESS(Status)) 1430 { 1431 ERR("LsapCopyLocalGroups failed (Status 0x%08lx)\n", Status); 1432 goto done; 1433 } 1434 1435 TRACE("GroupCount: %lu\n", LocalGroups->GroupCount); 1436 } 1437 1438 if (Package->LsaApLogonUserEx2 != NULL) 1439 { 1440 Status = Package->LsaApLogonUserEx2((PLSA_CLIENT_REQUEST)LogonContext, 1441 RequestMsg->LogonUser.Request.LogonType, 1442 LocalAuthInfo, 1443 RequestMsg->LogonUser.Request.AuthenticationInformation, 1444 RequestMsg->LogonUser.Request.AuthenticationInformationLength, 1445 &RequestMsg->LogonUser.Reply.ProfileBuffer, 1446 &RequestMsg->LogonUser.Reply.ProfileBufferLength, 1447 &RequestMsg->LogonUser.Reply.LogonId, 1448 &RequestMsg->LogonUser.Reply.SubStatus, 1449 &TokenInformationType, 1450 &TokenInformation, 1451 &AccountName, 1452 &AuthenticatingAuthority, 1453 &MachineName, 1454 NULL, /* FIXME: PSECPKG_PRIMARY_CRED PrimaryCredentials */ 1455 NULL); /* FIXME: PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials */ 1456 } 1457 else if (Package->LsaApLogonUserEx != NULL) 1458 { 1459 Status = Package->LsaApLogonUserEx((PLSA_CLIENT_REQUEST)LogonContext, 1460 RequestMsg->LogonUser.Request.LogonType, 1461 LocalAuthInfo, 1462 RequestMsg->LogonUser.Request.AuthenticationInformation, 1463 RequestMsg->LogonUser.Request.AuthenticationInformationLength, 1464 &RequestMsg->LogonUser.Reply.ProfileBuffer, 1465 &RequestMsg->LogonUser.Reply.ProfileBufferLength, 1466 &RequestMsg->LogonUser.Reply.LogonId, 1467 &RequestMsg->LogonUser.Reply.SubStatus, 1468 &TokenInformationType, 1469 &TokenInformation, 1470 &AccountName, 1471 &AuthenticatingAuthority, 1472 &MachineName); 1473 } 1474 else 1475 { 1476 Status = Package->LsaApLogonUser((PLSA_CLIENT_REQUEST)LogonContext, 1477 RequestMsg->LogonUser.Request.LogonType, 1478 LocalAuthInfo, 1479 RequestMsg->LogonUser.Request.AuthenticationInformation, 1480 RequestMsg->LogonUser.Request.AuthenticationInformationLength, 1481 &RequestMsg->LogonUser.Reply.ProfileBuffer, 1482 &RequestMsg->LogonUser.Reply.ProfileBufferLength, 1483 &RequestMsg->LogonUser.Reply.LogonId, 1484 &RequestMsg->LogonUser.Reply.SubStatus, 1485 &TokenInformationType, 1486 &TokenInformation, 1487 &AccountName, 1488 &AuthenticatingAuthority); 1489 } 1490 1491 if (!NT_SUCCESS(Status)) 1492 { 1493 ERR("LsaApLogonUser/Ex/2 failed (Status 0x%08lx)\n", Status); 1494 goto done; 1495 } 1496 1497 if (LocalGroups->GroupCount > 0) 1498 { 1499 /* Add local groups to the token information */ 1500 Status = LsapAddLocalGroups(TokenInformation, 1501 TokenInformationType, 1502 LocalGroups); 1503 if (!NT_SUCCESS(Status)) 1504 { 1505 ERR("LsapAddLocalGroupsToTokenInfo() failed (Status 0x%08lx)\n", Status); 1506 goto done; 1507 } 1508 } 1509 1510 Status = LsapAddDefaultGroups(TokenInformation, 1511 TokenInformationType, 1512 LogonType); 1513 if (!NT_SUCCESS(Status)) 1514 { 1515 ERR("LsapAddDefaultGroups() failed (Status 0x%08lx)\n", Status); 1516 goto done; 1517 } 1518 1519 Status = LsapAddSamGroups(TokenInformation, 1520 TokenInformationType); 1521 if (!NT_SUCCESS(Status)) 1522 { 1523 ERR("LsapAddSamGroups() failed (Status 0x%08lx)\n", Status); 1524 goto done; 1525 } 1526 1527 Status = LsapSetTokenOwner(TokenInformation, 1528 TokenInformationType); 1529 if (!NT_SUCCESS(Status)) 1530 { 1531 ERR("LsapSetTokenOwner() failed (Status 0x%08lx)\n", Status); 1532 goto done; 1533 } 1534 1535 Status = LsapAddTokenDefaultDacl(TokenInformation, 1536 TokenInformationType); 1537 if (!NT_SUCCESS(Status)) 1538 { 1539 ERR("LsapAddTokenDefaultDacl() failed (Status 0x%08lx)\n", Status); 1540 goto done; 1541 } 1542 1543 Status = LsapSetPrivileges(TokenInformation, 1544 TokenInformationType); 1545 if (!NT_SUCCESS(Status)) 1546 { 1547 ERR("LsapSetPrivileges() failed (Status 0x%08lx)\n", Status); 1548 goto done; 1549 } 1550 1551 if (TokenInformationType == LsaTokenInformationV1) 1552 { 1553 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation; 1554 1555 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); 1556 Qos.ImpersonationLevel = SecurityImpersonation; 1557 Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; 1558 Qos.EffectiveOnly = FALSE; 1559 1560 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); 1561 ObjectAttributes.RootDirectory = NULL; 1562 ObjectAttributes.ObjectName = NULL; 1563 ObjectAttributes.Attributes = 0; 1564 ObjectAttributes.SecurityDescriptor = NULL; 1565 ObjectAttributes.SecurityQualityOfService = &Qos; 1566 1567 /* Create the logon token */ 1568 Status = NtCreateToken(&TokenHandle, 1569 TOKEN_ALL_ACCESS, 1570 &ObjectAttributes, 1571 TokenPrimary, 1572 &RequestMsg->LogonUser.Reply.LogonId, 1573 &TokenInfo1->ExpirationTime, 1574 &TokenInfo1->User, 1575 TokenInfo1->Groups, 1576 TokenInfo1->Privileges, 1577 &TokenInfo1->Owner, 1578 &TokenInfo1->PrimaryGroup, 1579 &TokenInfo1->DefaultDacl, 1580 &RequestMsg->LogonUser.Request.SourceContext); 1581 if (!NT_SUCCESS(Status)) 1582 { 1583 ERR("NtCreateToken failed (Status 0x%08lx)\n", Status); 1584 goto done; 1585 } 1586 } 1587 else 1588 { 1589 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType); 1590 Status = STATUS_NOT_IMPLEMENTED; 1591 goto done; 1592 } 1593 1594 /* Duplicate the token handle into the client process */ 1595 Status = NtDuplicateObject(NtCurrentProcess(), 1596 TokenHandle, 1597 LogonContext->ClientProcessHandle, 1598 &RequestMsg->LogonUser.Reply.Token, 1599 0, 1600 0, 1601 DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_CLOSE_SOURCE); 1602 if (!NT_SUCCESS(Status)) 1603 { 1604 ERR("NtDuplicateObject failed (Status 0x%08lx)\n", Status); 1605 goto done; 1606 } 1607 1608 // TokenHandle = NULL; 1609 1610 if (LogonType == Interactive || 1611 LogonType == Batch || 1612 LogonType == Service) 1613 { 1614 UserName = &((PMSV1_0_INTERACTIVE_LOGON)LocalAuthInfo)->UserName; 1615 LogonDomainName = &((PMSV1_0_INTERACTIVE_LOGON)LocalAuthInfo)->LogonDomainName; 1616 } 1617 else 1618 { 1619 FIXME("LogonType %lu is not supported yet!\n", LogonType); 1620 } 1621 1622 Status = LsapSetLogonSessionData(&RequestMsg->LogonUser.Reply.LogonId, 1623 LogonType, 1624 UserName, 1625 LogonDomainName, 1626 TokenInfo1->User.User.Sid); 1627 if (!NT_SUCCESS(Status)) 1628 { 1629 ERR("LsapSetLogonSessionData failed (Status 0x%08lx)\n", Status); 1630 goto done; 1631 } 1632 1633 done: 1634 // if (!NT_SUCCESS(Status)) 1635 // { 1636 if (TokenHandle != NULL) 1637 NtClose(TokenHandle); 1638 // } 1639 1640 /* Free the local groups */ 1641 if (LocalGroups != NULL) 1642 { 1643 for (i = 0; i < LocalGroups->GroupCount; i++) 1644 { 1645 if (LocalGroups->Groups[i].Sid != NULL) 1646 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid); 1647 } 1648 1649 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups); 1650 } 1651 1652 /* Free the local authentication info buffer */ 1653 if (LocalAuthInfo != NULL) 1654 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo); 1655 1656 /* Free the token information */ 1657 if (TokenInformation != NULL) 1658 { 1659 if (TokenInformationType == LsaTokenInformationV1) 1660 { 1661 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation; 1662 1663 if (TokenInfo1 != NULL) 1664 { 1665 if (TokenInfo1->User.User.Sid != NULL) 1666 LsapFreeHeap(TokenInfo1->User.User.Sid); 1667 1668 if (TokenInfo1->Groups != NULL) 1669 { 1670 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++) 1671 { 1672 if (TokenInfo1->Groups->Groups[i].Sid != NULL) 1673 LsapFreeHeap(TokenInfo1->Groups->Groups[i].Sid); 1674 } 1675 1676 LsapFreeHeap(TokenInfo1->Groups); 1677 } 1678 1679 if (TokenInfo1->PrimaryGroup.PrimaryGroup != NULL) 1680 LsapFreeHeap(TokenInfo1->PrimaryGroup.PrimaryGroup); 1681 1682 if (TokenInfo1->Privileges != NULL) 1683 LsapFreeHeap(TokenInfo1->Privileges); 1684 1685 if (TokenInfo1->Owner.Owner != NULL) 1686 LsapFreeHeap(TokenInfo1->Owner.Owner); 1687 1688 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL) 1689 LsapFreeHeap(TokenInfo1->DefaultDacl.DefaultDacl); 1690 1691 LsapFreeHeap(TokenInfo1); 1692 } 1693 } 1694 else 1695 { 1696 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType); 1697 } 1698 } 1699 1700 /* Free the account name */ 1701 if (AccountName != NULL) 1702 { 1703 if (AccountName->Buffer != NULL) 1704 LsapFreeHeap(AccountName->Buffer); 1705 1706 LsapFreeHeap(AccountName); 1707 } 1708 1709 /* Free the authentication authority */ 1710 if (AuthenticatingAuthority != NULL) 1711 { 1712 if (AuthenticatingAuthority != NULL) 1713 LsapFreeHeap(AuthenticatingAuthority->Buffer); 1714 1715 LsapFreeHeap(AuthenticatingAuthority); 1716 } 1717 1718 /* Free the machine name */ 1719 if (MachineName != NULL) 1720 { 1721 if (MachineName->Buffer != NULL) 1722 LsapFreeHeap(MachineName->Buffer); 1723 1724 LsapFreeHeap(MachineName); 1725 } 1726 1727 TRACE("LsapLogonUser done (Status 0x%08lx)\n", Status); 1728 1729 return Status; 1730 } 1731 1732 /* EOF */ 1733