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 SIZE_T 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 SIZE_T 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_AND_ATTRIBUTES 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; 1151 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++) 1152 { 1153 if (EqualSid(TokenInfo1->Groups->Groups[i].Sid, LsapAdministratorsSid)) 1154 { 1155 OwnerSid = &TokenInfo1->Groups->Groups[i]; 1156 break; 1157 } 1158 } 1159 1160 Length = RtlLengthSid(OwnerSid->Sid); 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->Sid, 1167 Length); 1168 OwnerSid->Attributes |= SE_GROUP_OWNER; 1169 } 1170 1171 return STATUS_SUCCESS; 1172 } 1173 1174 1175 static 1176 NTSTATUS 1177 LsapAddTokenDefaultDacl( 1178 IN PVOID TokenInformation, 1179 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType) 1180 { 1181 PLSA_TOKEN_INFORMATION_V1 TokenInfo1; 1182 PACL Dacl = NULL; 1183 ULONG Length; 1184 1185 if (TokenInformationType == LsaTokenInformationV1) 1186 { 1187 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation; 1188 1189 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL) 1190 return STATUS_SUCCESS; 1191 1192 Length = sizeof(ACL) + 1193 (2 * sizeof(ACCESS_ALLOWED_ACE)) + 1194 RtlLengthSid(TokenInfo1->Owner.Owner) + 1195 RtlLengthSid(LsapLocalSystemSid); 1196 1197 Dacl = DispatchTable.AllocateLsaHeap(Length); 1198 if (Dacl == NULL) 1199 return STATUS_INSUFFICIENT_RESOURCES; 1200 1201 RtlCreateAcl(Dacl, Length, ACL_REVISION); 1202 1203 RtlAddAccessAllowedAce(Dacl, 1204 ACL_REVISION, 1205 GENERIC_ALL, 1206 TokenInfo1->Owner.Owner); 1207 1208 /* SID: S-1-5-18 */ 1209 RtlAddAccessAllowedAce(Dacl, 1210 ACL_REVISION, 1211 GENERIC_ALL, 1212 LsapLocalSystemSid); 1213 1214 TokenInfo1->DefaultDacl.DefaultDacl = Dacl; 1215 } 1216 1217 return STATUS_SUCCESS; 1218 } 1219 1220 1221 static 1222 NTSTATUS 1223 LsapAddPrivilegeToTokenPrivileges(PTOKEN_PRIVILEGES *TokenPrivileges, 1224 PLSAPR_LUID_AND_ATTRIBUTES Privilege) 1225 { 1226 PTOKEN_PRIVILEGES LocalPrivileges; 1227 ULONG Length, TokenPrivilegeCount, i; 1228 NTSTATUS Status = STATUS_SUCCESS; 1229 1230 if (*TokenPrivileges == NULL) 1231 { 1232 Length = sizeof(TOKEN_PRIVILEGES) + 1233 (1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES); 1234 LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(), 1235 0, 1236 Length); 1237 if (LocalPrivileges == NULL) 1238 return STATUS_INSUFFICIENT_RESOURCES; 1239 1240 LocalPrivileges->PrivilegeCount = 1; 1241 LocalPrivileges->Privileges[0].Luid = Privilege->Luid; 1242 LocalPrivileges->Privileges[0].Attributes = Privilege->Attributes; 1243 } 1244 else 1245 { 1246 TokenPrivilegeCount = (*TokenPrivileges)->PrivilegeCount; 1247 1248 for (i = 0; i < TokenPrivilegeCount; i++) 1249 { 1250 if (RtlEqualLuid(&(*TokenPrivileges)->Privileges[i].Luid, &Privilege->Luid)) 1251 return STATUS_SUCCESS; 1252 } 1253 1254 Length = sizeof(TOKEN_PRIVILEGES) + 1255 (TokenPrivilegeCount + 1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES); 1256 LocalPrivileges = RtlAllocateHeap(RtlGetProcessHeap(), 1257 0, 1258 Length); 1259 if (LocalPrivileges == NULL) 1260 return STATUS_INSUFFICIENT_RESOURCES; 1261 1262 LocalPrivileges->PrivilegeCount = TokenPrivilegeCount + 1; 1263 for (i = 0; i < TokenPrivilegeCount; i++) 1264 { 1265 LocalPrivileges->Privileges[i].Luid = (*TokenPrivileges)->Privileges[i].Luid; 1266 LocalPrivileges->Privileges[i].Attributes = (*TokenPrivileges)->Privileges[i].Attributes; 1267 } 1268 1269 LocalPrivileges->Privileges[TokenPrivilegeCount].Luid = Privilege->Luid; 1270 LocalPrivileges->Privileges[TokenPrivilegeCount].Attributes = Privilege->Attributes; 1271 1272 RtlFreeHeap(RtlGetProcessHeap(), 0, *TokenPrivileges); 1273 } 1274 1275 *TokenPrivileges = LocalPrivileges; 1276 1277 return Status; 1278 } 1279 1280 static 1281 NTSTATUS 1282 LsapSetPrivileges( 1283 IN PVOID TokenInformation, 1284 IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType) 1285 { 1286 PLSA_TOKEN_INFORMATION_V1 TokenInfo1; 1287 LSAPR_HANDLE PolicyHandle = NULL; 1288 LSAPR_HANDLE AccountHandle = NULL; 1289 PLSAPR_PRIVILEGE_SET Privileges = NULL; 1290 ULONG i, j; 1291 NTSTATUS Status; 1292 1293 if (TokenInformationType == LsaTokenInformationV1) 1294 { 1295 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation; 1296 1297 Status = LsarOpenPolicy(NULL, 1298 NULL, 1299 0, 1300 &PolicyHandle); 1301 if (!NT_SUCCESS(Status)) 1302 return Status; 1303 1304 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++) 1305 { 1306 Status = LsarOpenAccount(PolicyHandle, 1307 TokenInfo1->Groups->Groups[i].Sid, 1308 ACCOUNT_VIEW, 1309 &AccountHandle); 1310 if (!NT_SUCCESS(Status)) 1311 continue; 1312 1313 Status = LsarEnumeratePrivilegesAccount(AccountHandle, 1314 &Privileges); 1315 if (NT_SUCCESS(Status)) 1316 { 1317 for (j = 0; j < Privileges->PrivilegeCount; j++) 1318 { 1319 Status = LsapAddPrivilegeToTokenPrivileges(&TokenInfo1->Privileges, 1320 &(Privileges->Privilege[j])); 1321 if (!NT_SUCCESS(Status)) 1322 { 1323 /* We failed, clean everything and return */ 1324 LsaIFree_LSAPR_PRIVILEGE_SET(Privileges); 1325 LsarClose(&AccountHandle); 1326 LsarClose(&PolicyHandle); 1327 1328 return Status; 1329 } 1330 } 1331 1332 LsaIFree_LSAPR_PRIVILEGE_SET(Privileges); 1333 Privileges = NULL; 1334 } 1335 1336 LsarClose(&AccountHandle); 1337 } 1338 1339 LsarClose(&PolicyHandle); 1340 1341 if (TokenInfo1->Privileges != NULL) 1342 { 1343 for (i = 0; i < TokenInfo1->Privileges->PrivilegeCount; i++) 1344 { 1345 if (RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeChangeNotifyPrivilege) || 1346 RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeCreateGlobalPrivilege) || 1347 RtlEqualLuid(&TokenInfo1->Privileges->Privileges[i].Luid, &SeImpersonatePrivilege)) 1348 { 1349 TokenInfo1->Privileges->Privileges[i].Attributes |= SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT; 1350 } 1351 } 1352 } 1353 } 1354 1355 return STATUS_SUCCESS; 1356 } 1357 1358 1359 NTSTATUS 1360 LsapLogonUser(PLSA_API_MSG RequestMsg, 1361 PLSAP_LOGON_CONTEXT LogonContext) 1362 { 1363 PAUTH_PACKAGE Package; 1364 OBJECT_ATTRIBUTES ObjectAttributes; 1365 SECURITY_QUALITY_OF_SERVICE Qos; 1366 LSA_TOKEN_INFORMATION_TYPE TokenInformationType; 1367 PVOID TokenInformation = NULL; 1368 PLSA_TOKEN_INFORMATION_V1 TokenInfo1 = NULL; 1369 PUNICODE_STRING AccountName = NULL; 1370 PUNICODE_STRING AuthenticatingAuthority = NULL; 1371 PUNICODE_STRING MachineName = NULL; 1372 PVOID LocalAuthInfo = NULL; 1373 PTOKEN_GROUPS LocalGroups = NULL; 1374 HANDLE TokenHandle = NULL; 1375 ULONG i; 1376 ULONG PackageId; 1377 SECURITY_LOGON_TYPE LogonType; 1378 NTSTATUS Status; 1379 1380 PUNICODE_STRING UserName = NULL; 1381 PUNICODE_STRING LogonDomainName = NULL; 1382 // UNICODE_STRING LogonServer; 1383 1384 1385 TRACE("LsapLogonUser(%p %p)\n", RequestMsg, LogonContext); 1386 1387 PackageId = RequestMsg->LogonUser.Request.AuthenticationPackage; 1388 LogonType = RequestMsg->LogonUser.Request.LogonType; 1389 1390 /* Get the right authentication package */ 1391 Package = LsapGetAuthenticationPackage(PackageId); 1392 if (Package == NULL) 1393 { 1394 ERR("LsapGetAuthenticationPackage() failed to find a package\n"); 1395 return STATUS_NO_SUCH_PACKAGE; 1396 } 1397 1398 if (RequestMsg->LogonUser.Request.AuthenticationInformationLength > 0) 1399 { 1400 /* Allocate the local authentication info buffer */ 1401 LocalAuthInfo = RtlAllocateHeap(RtlGetProcessHeap(), 1402 HEAP_ZERO_MEMORY, 1403 RequestMsg->LogonUser.Request.AuthenticationInformationLength); 1404 if (LocalAuthInfo == NULL) 1405 { 1406 ERR("RtlAllocateHeap() failed\n"); 1407 return STATUS_INSUFFICIENT_RESOURCES; 1408 } 1409 1410 /* Read the authentication info from the callers address space */ 1411 Status = NtReadVirtualMemory(LogonContext->ClientProcessHandle, 1412 RequestMsg->LogonUser.Request.AuthenticationInformation, 1413 LocalAuthInfo, 1414 RequestMsg->LogonUser.Request.AuthenticationInformationLength, 1415 NULL); 1416 if (!NT_SUCCESS(Status)) 1417 { 1418 ERR("NtReadVirtualMemory() failed (Status 0x%08lx)\n", Status); 1419 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo); 1420 return Status; 1421 } 1422 } 1423 1424 if (RequestMsg->LogonUser.Request.LocalGroupsCount > 0) 1425 { 1426 Status = LsapCopyLocalGroups(LogonContext, 1427 RequestMsg->LogonUser.Request.LocalGroups, 1428 RequestMsg->LogonUser.Request.LocalGroupsCount, 1429 &LocalGroups); 1430 if (!NT_SUCCESS(Status)) 1431 { 1432 ERR("LsapCopyLocalGroups failed (Status 0x%08lx)\n", Status); 1433 goto done; 1434 } 1435 1436 TRACE("GroupCount: %lu\n", LocalGroups->GroupCount); 1437 } 1438 1439 if (Package->LsaApLogonUserEx2 != NULL) 1440 { 1441 Status = Package->LsaApLogonUserEx2((PLSA_CLIENT_REQUEST)LogonContext, 1442 RequestMsg->LogonUser.Request.LogonType, 1443 LocalAuthInfo, 1444 RequestMsg->LogonUser.Request.AuthenticationInformation, 1445 RequestMsg->LogonUser.Request.AuthenticationInformationLength, 1446 &RequestMsg->LogonUser.Reply.ProfileBuffer, 1447 &RequestMsg->LogonUser.Reply.ProfileBufferLength, 1448 &RequestMsg->LogonUser.Reply.LogonId, 1449 &RequestMsg->LogonUser.Reply.SubStatus, 1450 &TokenInformationType, 1451 &TokenInformation, 1452 &AccountName, 1453 &AuthenticatingAuthority, 1454 &MachineName, 1455 NULL, /* FIXME: PSECPKG_PRIMARY_CRED PrimaryCredentials */ 1456 NULL); /* FIXME: PSECPKG_SUPPLEMENTAL_CRED_ARRAY *SupplementalCredentials */ 1457 } 1458 else if (Package->LsaApLogonUserEx != NULL) 1459 { 1460 Status = Package->LsaApLogonUserEx((PLSA_CLIENT_REQUEST)LogonContext, 1461 RequestMsg->LogonUser.Request.LogonType, 1462 LocalAuthInfo, 1463 RequestMsg->LogonUser.Request.AuthenticationInformation, 1464 RequestMsg->LogonUser.Request.AuthenticationInformationLength, 1465 &RequestMsg->LogonUser.Reply.ProfileBuffer, 1466 &RequestMsg->LogonUser.Reply.ProfileBufferLength, 1467 &RequestMsg->LogonUser.Reply.LogonId, 1468 &RequestMsg->LogonUser.Reply.SubStatus, 1469 &TokenInformationType, 1470 &TokenInformation, 1471 &AccountName, 1472 &AuthenticatingAuthority, 1473 &MachineName); 1474 } 1475 else 1476 { 1477 Status = Package->LsaApLogonUser((PLSA_CLIENT_REQUEST)LogonContext, 1478 RequestMsg->LogonUser.Request.LogonType, 1479 LocalAuthInfo, 1480 RequestMsg->LogonUser.Request.AuthenticationInformation, 1481 RequestMsg->LogonUser.Request.AuthenticationInformationLength, 1482 &RequestMsg->LogonUser.Reply.ProfileBuffer, 1483 &RequestMsg->LogonUser.Reply.ProfileBufferLength, 1484 &RequestMsg->LogonUser.Reply.LogonId, 1485 &RequestMsg->LogonUser.Reply.SubStatus, 1486 &TokenInformationType, 1487 &TokenInformation, 1488 &AccountName, 1489 &AuthenticatingAuthority); 1490 } 1491 1492 if (!NT_SUCCESS(Status)) 1493 { 1494 ERR("LsaApLogonUser/Ex/2 failed (Status 0x%08lx)\n", Status); 1495 goto done; 1496 } 1497 1498 if (LocalGroups->GroupCount > 0) 1499 { 1500 /* Add local groups to the token information */ 1501 Status = LsapAddLocalGroups(TokenInformation, 1502 TokenInformationType, 1503 LocalGroups); 1504 if (!NT_SUCCESS(Status)) 1505 { 1506 ERR("LsapAddLocalGroupsToTokenInfo() failed (Status 0x%08lx)\n", Status); 1507 goto done; 1508 } 1509 } 1510 1511 Status = LsapAddDefaultGroups(TokenInformation, 1512 TokenInformationType, 1513 LogonType); 1514 if (!NT_SUCCESS(Status)) 1515 { 1516 ERR("LsapAddDefaultGroups() failed (Status 0x%08lx)\n", Status); 1517 goto done; 1518 } 1519 1520 Status = LsapAddSamGroups(TokenInformation, 1521 TokenInformationType); 1522 if (!NT_SUCCESS(Status)) 1523 { 1524 ERR("LsapAddSamGroups() failed (Status 0x%08lx)\n", Status); 1525 goto done; 1526 } 1527 1528 Status = LsapSetTokenOwner(TokenInformation, 1529 TokenInformationType); 1530 if (!NT_SUCCESS(Status)) 1531 { 1532 ERR("LsapSetTokenOwner() failed (Status 0x%08lx)\n", Status); 1533 goto done; 1534 } 1535 1536 Status = LsapAddTokenDefaultDacl(TokenInformation, 1537 TokenInformationType); 1538 if (!NT_SUCCESS(Status)) 1539 { 1540 ERR("LsapAddTokenDefaultDacl() failed (Status 0x%08lx)\n", Status); 1541 goto done; 1542 } 1543 1544 Status = LsapSetPrivileges(TokenInformation, 1545 TokenInformationType); 1546 if (!NT_SUCCESS(Status)) 1547 { 1548 ERR("LsapSetPrivileges() failed (Status 0x%08lx)\n", Status); 1549 goto done; 1550 } 1551 1552 if (TokenInformationType == LsaTokenInformationV1) 1553 { 1554 TOKEN_PRIVILEGES NoPrivilege = {0}; 1555 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation; 1556 1557 Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); 1558 Qos.ImpersonationLevel = SecurityImpersonation; 1559 Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; 1560 Qos.EffectiveOnly = FALSE; 1561 1562 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); 1563 ObjectAttributes.RootDirectory = NULL; 1564 ObjectAttributes.ObjectName = NULL; 1565 ObjectAttributes.Attributes = 0; 1566 ObjectAttributes.SecurityDescriptor = NULL; 1567 ObjectAttributes.SecurityQualityOfService = &Qos; 1568 1569 /* Create the logon token */ 1570 Status = NtCreateToken(&TokenHandle, 1571 TOKEN_ALL_ACCESS, 1572 &ObjectAttributes, 1573 (RequestMsg->LogonUser.Request.LogonType == Network) ? TokenImpersonation : TokenPrimary, 1574 &RequestMsg->LogonUser.Reply.LogonId, 1575 &TokenInfo1->ExpirationTime, 1576 &TokenInfo1->User, 1577 TokenInfo1->Groups, 1578 TokenInfo1->Privileges ? TokenInfo1->Privileges 1579 : &NoPrivilege, 1580 &TokenInfo1->Owner, 1581 &TokenInfo1->PrimaryGroup, 1582 &TokenInfo1->DefaultDacl, 1583 &RequestMsg->LogonUser.Request.SourceContext); 1584 if (!NT_SUCCESS(Status)) 1585 { 1586 ERR("NtCreateToken failed (Status 0x%08lx)\n", Status); 1587 goto done; 1588 } 1589 } 1590 else 1591 { 1592 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType); 1593 Status = STATUS_NOT_IMPLEMENTED; 1594 goto done; 1595 } 1596 1597 /* Duplicate the token handle into the client process */ 1598 Status = NtDuplicateObject(NtCurrentProcess(), 1599 TokenHandle, 1600 LogonContext->ClientProcessHandle, 1601 &RequestMsg->LogonUser.Reply.Token, 1602 0, 1603 0, 1604 DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_CLOSE_SOURCE); 1605 if (!NT_SUCCESS(Status)) 1606 { 1607 ERR("NtDuplicateObject failed (Status 0x%08lx)\n", Status); 1608 goto done; 1609 } 1610 1611 // TokenHandle = NULL; 1612 1613 if (LogonType == Interactive || 1614 LogonType == Batch || 1615 LogonType == Service) 1616 { 1617 UserName = &((PMSV1_0_INTERACTIVE_LOGON)LocalAuthInfo)->UserName; 1618 LogonDomainName = &((PMSV1_0_INTERACTIVE_LOGON)LocalAuthInfo)->LogonDomainName; 1619 } 1620 else 1621 { 1622 FIXME("LogonType %lu is not supported yet!\n", LogonType); 1623 } 1624 1625 Status = LsapSetLogonSessionData(&RequestMsg->LogonUser.Reply.LogonId, 1626 LogonType, 1627 UserName, 1628 LogonDomainName, 1629 TokenInfo1->User.User.Sid); 1630 if (!NT_SUCCESS(Status)) 1631 { 1632 ERR("LsapSetLogonSessionData failed (Status 0x%08lx)\n", Status); 1633 goto done; 1634 } 1635 1636 done: 1637 // if (!NT_SUCCESS(Status)) 1638 // { 1639 if (TokenHandle != NULL) 1640 NtClose(TokenHandle); 1641 // } 1642 1643 /* Free the local groups */ 1644 if (LocalGroups != NULL) 1645 { 1646 for (i = 0; i < LocalGroups->GroupCount; i++) 1647 { 1648 if (LocalGroups->Groups[i].Sid != NULL) 1649 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups->Groups[i].Sid); 1650 } 1651 1652 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalGroups); 1653 } 1654 1655 /* Free the local authentication info buffer */ 1656 if (LocalAuthInfo != NULL) 1657 RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo); 1658 1659 /* Free the token information */ 1660 if (TokenInformation != NULL) 1661 { 1662 if (TokenInformationType == LsaTokenInformationV1) 1663 { 1664 TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation; 1665 1666 if (TokenInfo1 != NULL) 1667 { 1668 if (TokenInfo1->User.User.Sid != NULL) 1669 LsapFreeHeap(TokenInfo1->User.User.Sid); 1670 1671 if (TokenInfo1->Groups != NULL) 1672 { 1673 for (i = 0; i < TokenInfo1->Groups->GroupCount; i++) 1674 { 1675 if (TokenInfo1->Groups->Groups[i].Sid != NULL) 1676 LsapFreeHeap(TokenInfo1->Groups->Groups[i].Sid); 1677 } 1678 1679 LsapFreeHeap(TokenInfo1->Groups); 1680 } 1681 1682 if (TokenInfo1->PrimaryGroup.PrimaryGroup != NULL) 1683 LsapFreeHeap(TokenInfo1->PrimaryGroup.PrimaryGroup); 1684 1685 if (TokenInfo1->Privileges != NULL) 1686 LsapFreeHeap(TokenInfo1->Privileges); 1687 1688 if (TokenInfo1->Owner.Owner != NULL) 1689 LsapFreeHeap(TokenInfo1->Owner.Owner); 1690 1691 if (TokenInfo1->DefaultDacl.DefaultDacl != NULL) 1692 LsapFreeHeap(TokenInfo1->DefaultDacl.DefaultDacl); 1693 1694 LsapFreeHeap(TokenInfo1); 1695 } 1696 } 1697 else 1698 { 1699 FIXME("TokenInformationType %d is not supported!\n", TokenInformationType); 1700 } 1701 } 1702 1703 /* Free the account name */ 1704 if (AccountName != NULL) 1705 { 1706 if (AccountName->Buffer != NULL) 1707 LsapFreeHeap(AccountName->Buffer); 1708 1709 LsapFreeHeap(AccountName); 1710 } 1711 1712 /* Free the authentication authority */ 1713 if (AuthenticatingAuthority != NULL) 1714 { 1715 if (AuthenticatingAuthority != NULL) 1716 LsapFreeHeap(AuthenticatingAuthority->Buffer); 1717 1718 LsapFreeHeap(AuthenticatingAuthority); 1719 } 1720 1721 /* Free the machine name */ 1722 if (MachineName != NULL) 1723 { 1724 if (MachineName->Buffer != NULL) 1725 LsapFreeHeap(MachineName->Buffer); 1726 1727 LsapFreeHeap(MachineName); 1728 } 1729 1730 TRACE("LsapLogonUser done (Status 0x%08lx)\n", Status); 1731 1732 return Status; 1733 } 1734 1735 /* EOF */ 1736