1 /* 2 * ReactOS MARTA provider 3 * Copyright (C) 2005 - 2006 ReactOS Team 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 /* 20 * PROJECT: ReactOS MARTA provider 21 * FILE: lib/ntmarta/ntmarta.c 22 * PURPOSE: ReactOS MARTA provider 23 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com> 24 * 25 * UPDATE HISTORY: 26 * 07/26/2005 Created 27 */ 28 29 #include "ntmarta.h" 30 31 #define NDEBUG 32 #include <debug.h> 33 34 HINSTANCE hDllInstance; 35 36 /* FIXME: Vista+ API */ 37 VOID 38 WINAPI 39 SetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, 40 OUT LPDWORD DesiredAccess) 41 { 42 *DesiredAccess = 0; 43 44 if (SecurityInformation & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION)) 45 *DesiredAccess |= WRITE_OWNER; 46 47 if (SecurityInformation & DACL_SECURITY_INFORMATION) 48 *DesiredAccess |= WRITE_DAC; 49 50 if (SecurityInformation & SACL_SECURITY_INFORMATION) 51 *DesiredAccess |= ACCESS_SYSTEM_SECURITY; 52 } 53 54 /* FIXME: Vista+ API */ 55 VOID 56 WINAPI 57 QuerySecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, 58 OUT LPDWORD DesiredAccess) 59 { 60 *DesiredAccess = 0; 61 62 if (SecurityInformation & (OWNER_SECURITY_INFORMATION | 63 GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION)) 64 { 65 *DesiredAccess |= READ_CONTROL; 66 } 67 68 if (SecurityInformation & SACL_SECURITY_INFORMATION) 69 *DesiredAccess |= ACCESS_SYSTEM_SECURITY; 70 } 71 72 static ACCESS_MODE 73 AccpGetAceAccessMode(IN PACE_HEADER AceHeader) 74 { 75 ACCESS_MODE Mode = NOT_USED_ACCESS; 76 77 switch (AceHeader->AceType) 78 { 79 case ACCESS_ALLOWED_ACE_TYPE: 80 case ACCESS_ALLOWED_CALLBACK_ACE_TYPE: 81 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE: 82 case ACCESS_ALLOWED_OBJECT_ACE_TYPE: 83 Mode = GRANT_ACCESS; 84 break; 85 86 case ACCESS_DENIED_ACE_TYPE: 87 case ACCESS_DENIED_CALLBACK_ACE_TYPE: 88 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE: 89 case ACCESS_DENIED_OBJECT_ACE_TYPE: 90 Mode = DENY_ACCESS; 91 break; 92 93 case SYSTEM_AUDIT_ACE_TYPE: 94 case SYSTEM_AUDIT_CALLBACK_ACE_TYPE: 95 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE: 96 case SYSTEM_AUDIT_OBJECT_ACE_TYPE: 97 if (AceHeader->AceFlags & FAILED_ACCESS_ACE_FLAG) 98 Mode = SET_AUDIT_FAILURE; 99 else if (AceHeader->AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG) 100 Mode = SET_AUDIT_SUCCESS; 101 break; 102 } 103 104 return Mode; 105 } 106 107 static UINT 108 AccpGetAceStructureSize(IN PACE_HEADER AceHeader) 109 { 110 UINT Size = 0; 111 112 switch (AceHeader->AceType) 113 { 114 case ACCESS_ALLOWED_ACE_TYPE: 115 case ACCESS_DENIED_ACE_TYPE: 116 Size = FIELD_OFFSET(ACCESS_ALLOWED_ACE, 117 SidStart); 118 break; 119 case ACCESS_ALLOWED_CALLBACK_ACE_TYPE: 120 case ACCESS_DENIED_CALLBACK_ACE_TYPE: 121 Size = FIELD_OFFSET(ACCESS_ALLOWED_CALLBACK_ACE, 122 SidStart); 123 break; 124 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE: 125 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE: 126 { 127 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace = (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE)AceHeader; 128 Size = FIELD_OFFSET(ACCESS_ALLOWED_CALLBACK_OBJECT_ACE, 129 ObjectType); 130 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 131 Size += sizeof(Ace->ObjectType); 132 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) 133 Size += sizeof(Ace->InheritedObjectType); 134 break; 135 } 136 case ACCESS_ALLOWED_OBJECT_ACE_TYPE: 137 case ACCESS_DENIED_OBJECT_ACE_TYPE: 138 { 139 PACCESS_ALLOWED_OBJECT_ACE Ace = (PACCESS_ALLOWED_OBJECT_ACE)AceHeader; 140 Size = FIELD_OFFSET(ACCESS_ALLOWED_OBJECT_ACE, 141 ObjectType); 142 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 143 Size += sizeof(Ace->ObjectType); 144 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) 145 Size += sizeof(Ace->InheritedObjectType); 146 break; 147 } 148 149 case SYSTEM_AUDIT_ACE_TYPE: 150 Size = FIELD_OFFSET(SYSTEM_AUDIT_ACE, 151 SidStart); 152 break; 153 case SYSTEM_AUDIT_CALLBACK_ACE_TYPE: 154 Size = FIELD_OFFSET(SYSTEM_AUDIT_CALLBACK_ACE, 155 SidStart); 156 break; 157 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE: 158 { 159 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace = (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE)AceHeader; 160 Size = FIELD_OFFSET(SYSTEM_AUDIT_CALLBACK_OBJECT_ACE, 161 ObjectType); 162 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 163 Size += sizeof(Ace->ObjectType); 164 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) 165 Size += sizeof(Ace->InheritedObjectType); 166 break; 167 } 168 case SYSTEM_AUDIT_OBJECT_ACE_TYPE: 169 { 170 PSYSTEM_AUDIT_OBJECT_ACE Ace = (PSYSTEM_AUDIT_OBJECT_ACE)AceHeader; 171 Size = FIELD_OFFSET(SYSTEM_AUDIT_OBJECT_ACE, 172 ObjectType); 173 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 174 Size += sizeof(Ace->ObjectType); 175 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) 176 Size += sizeof(Ace->InheritedObjectType); 177 break; 178 } 179 180 case SYSTEM_MANDATORY_LABEL_ACE_TYPE: 181 Size = FIELD_OFFSET(SYSTEM_MANDATORY_LABEL_ACE, 182 SidStart); 183 break; 184 } 185 186 return Size; 187 } 188 189 static PSID 190 AccpGetAceSid(IN PACE_HEADER AceHeader) 191 { 192 return (PSID)((ULONG_PTR)AceHeader + AccpGetAceStructureSize(AceHeader)); 193 } 194 195 static ACCESS_MASK 196 AccpGetAceAccessMask(IN PACE_HEADER AceHeader) 197 { 198 return *((PACCESS_MASK)(AceHeader + 1)); 199 } 200 201 static BOOL 202 AccpIsObjectAce(IN PACE_HEADER AceHeader) 203 { 204 BOOL Ret; 205 206 switch (AceHeader->AceType) 207 { 208 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE: 209 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE: 210 case ACCESS_ALLOWED_OBJECT_ACE_TYPE: 211 case ACCESS_DENIED_OBJECT_ACE_TYPE: 212 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE: 213 case SYSTEM_AUDIT_OBJECT_ACE_TYPE: 214 Ret = TRUE; 215 break; 216 217 default: 218 Ret = FALSE; 219 break; 220 } 221 222 return Ret; 223 } 224 225 static DWORD 226 AccpGetTrusteeObjects(IN PTRUSTEE_W Trustee, 227 OUT GUID *pObjectTypeGuid OPTIONAL, 228 OUT GUID *pInheritedObjectTypeGuid OPTIONAL) 229 { 230 DWORD Ret; 231 232 switch (Trustee->TrusteeForm) 233 { 234 case TRUSTEE_IS_OBJECTS_AND_NAME: 235 { 236 POBJECTS_AND_NAME_W pOan = (POBJECTS_AND_NAME_W)Trustee->ptstrName; 237 238 /* pOan->ObjectsPresent should always be 0 here because a previous 239 call to AccpGetTrusteeSid should have rejected these trustees 240 already. */ 241 ASSERT(pOan->ObjectsPresent == 0); 242 243 Ret = pOan->ObjectsPresent; 244 break; 245 } 246 247 case TRUSTEE_IS_OBJECTS_AND_SID: 248 { 249 POBJECTS_AND_SID pOas = (POBJECTS_AND_SID)Trustee->ptstrName; 250 251 if (pObjectTypeGuid != NULL && pOas->ObjectsPresent & ACE_OBJECT_TYPE_PRESENT) 252 *pObjectTypeGuid = pOas->ObjectTypeGuid; 253 254 if (pInheritedObjectTypeGuid != NULL && pOas->ObjectsPresent & ACE_INHERITED_OBJECT_TYPE_PRESENT) 255 *pInheritedObjectTypeGuid = pOas->InheritedObjectTypeGuid; 256 257 Ret = pOas->ObjectsPresent; 258 break; 259 } 260 261 default: 262 /* Any other trustee forms have no objects attached... */ 263 Ret = 0; 264 break; 265 } 266 267 return Ret; 268 } 269 270 static DWORD 271 AccpCalcNeededAceSize(IN PSID Sid, 272 IN DWORD ObjectsPresent) 273 { 274 DWORD Ret; 275 276 Ret = sizeof(ACE) + GetLengthSid(Sid); 277 278 /* This routine calculates the generic size of the ACE needed. 279 If no objects are present it is assumed that only a standard 280 ACE is to be created. */ 281 282 if (ObjectsPresent & ACE_OBJECT_TYPE_PRESENT) 283 Ret += sizeof(GUID); 284 if (ObjectsPresent & ACE_INHERITED_OBJECT_TYPE_PRESENT) 285 Ret += sizeof(GUID); 286 287 if (ObjectsPresent != 0) 288 Ret += sizeof(DWORD); /* Include the Flags member to make it an object ACE */ 289 290 return Ret; 291 } 292 293 static GUID* 294 AccpGetObjectAceObjectType(IN PACE_HEADER AceHeader) 295 { 296 GUID *ObjectType = NULL; 297 298 switch (AceHeader->AceType) 299 { 300 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE: 301 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE: 302 { 303 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace = (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE)AceHeader; 304 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 305 ObjectType = &Ace->ObjectType; 306 break; 307 } 308 case ACCESS_ALLOWED_OBJECT_ACE_TYPE: 309 case ACCESS_DENIED_OBJECT_ACE_TYPE: 310 { 311 PACCESS_ALLOWED_OBJECT_ACE Ace = (PACCESS_ALLOWED_OBJECT_ACE)AceHeader; 312 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 313 ObjectType = &Ace->ObjectType; 314 break; 315 } 316 317 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE: 318 { 319 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace = (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE)AceHeader; 320 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 321 ObjectType = &Ace->ObjectType; 322 break; 323 } 324 case SYSTEM_AUDIT_OBJECT_ACE_TYPE: 325 { 326 PSYSTEM_AUDIT_OBJECT_ACE Ace = (PSYSTEM_AUDIT_OBJECT_ACE)AceHeader; 327 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 328 ObjectType = &Ace->ObjectType; 329 break; 330 } 331 } 332 333 return ObjectType; 334 } 335 336 static GUID* 337 AccpGetObjectAceInheritedObjectType(IN PACE_HEADER AceHeader) 338 { 339 GUID *ObjectType = NULL; 340 341 switch (AceHeader->AceType) 342 { 343 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE: 344 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE: 345 { 346 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace = (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE)AceHeader; 347 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) 348 { 349 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 350 ObjectType = &Ace->InheritedObjectType; 351 else 352 ObjectType = &Ace->ObjectType; 353 } 354 break; 355 } 356 case ACCESS_ALLOWED_OBJECT_ACE_TYPE: 357 case ACCESS_DENIED_OBJECT_ACE_TYPE: 358 { 359 PACCESS_ALLOWED_OBJECT_ACE Ace = (PACCESS_ALLOWED_OBJECT_ACE)AceHeader; 360 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) 361 { 362 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 363 ObjectType = &Ace->InheritedObjectType; 364 else 365 ObjectType = &Ace->ObjectType; 366 } 367 break; 368 } 369 370 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE: 371 { 372 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace = (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE)AceHeader; 373 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) 374 { 375 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 376 ObjectType = &Ace->InheritedObjectType; 377 else 378 ObjectType = &Ace->ObjectType; 379 } 380 break; 381 } 382 case SYSTEM_AUDIT_OBJECT_ACE_TYPE: 383 { 384 PSYSTEM_AUDIT_OBJECT_ACE Ace = (PSYSTEM_AUDIT_OBJECT_ACE)AceHeader; 385 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) 386 { 387 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 388 ObjectType = &Ace->InheritedObjectType; 389 else 390 ObjectType = &Ace->ObjectType; 391 } 392 break; 393 } 394 } 395 396 return ObjectType; 397 } 398 399 static DWORD 400 AccpOpenLSAPolicyHandle(IN LPWSTR SystemName, 401 IN ACCESS_MASK DesiredAccess, 402 OUT PLSA_HANDLE pPolicyHandle) 403 { 404 LSA_OBJECT_ATTRIBUTES LsaObjectAttributes = {0}; 405 LSA_UNICODE_STRING LsaSystemName, *psn; 406 SIZE_T SystemNameLength; 407 NTSTATUS Status; 408 409 if (SystemName != NULL && SystemName[0] != L'\0') 410 { 411 SystemNameLength = wcslen(SystemName); 412 if (SystemNameLength > UNICODE_STRING_MAX_CHARS) 413 { 414 return ERROR_INVALID_PARAMETER; 415 } 416 417 LsaSystemName.Buffer = SystemName; 418 LsaSystemName.Length = (USHORT)SystemNameLength * sizeof(WCHAR); 419 LsaSystemName.MaximumLength = LsaSystemName.Length + sizeof(WCHAR); 420 psn = &LsaSystemName; 421 } 422 else 423 { 424 psn = NULL; 425 } 426 427 Status = LsaOpenPolicy(psn, 428 &LsaObjectAttributes, 429 DesiredAccess, 430 pPolicyHandle); 431 if (!NT_SUCCESS(Status)) 432 return LsaNtStatusToWinError(Status); 433 434 return ERROR_SUCCESS; 435 } 436 437 static LPWSTR 438 AccpGetTrusteeName(IN PTRUSTEE_W Trustee) 439 { 440 switch (Trustee->TrusteeForm) 441 { 442 case TRUSTEE_IS_NAME: 443 return Trustee->ptstrName; 444 445 case TRUSTEE_IS_OBJECTS_AND_NAME: 446 return ((POBJECTS_AND_NAME_W)Trustee->ptstrName)->ptstrName; 447 448 default: 449 return NULL; 450 } 451 } 452 453 static DWORD 454 AccpLookupCurrentUser(OUT PSID *ppSid) 455 { 456 DWORD Ret; 457 CHAR Buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES]; 458 DWORD Length; 459 HANDLE Token; 460 PSID pSid; 461 462 *ppSid = NULL; 463 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &Token)) 464 { 465 Ret = GetLastError(); 466 if (Ret != ERROR_NO_TOKEN) 467 { 468 return Ret; 469 } 470 471 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &Token)) 472 { 473 return GetLastError(); 474 } 475 } 476 477 Length = sizeof(Buffer); 478 if (!GetTokenInformation(Token, TokenUser, Buffer, Length, &Length)) 479 { 480 Ret = GetLastError(); 481 CloseHandle(Token); 482 return Ret; 483 } 484 CloseHandle(Token); 485 486 pSid = ((PTOKEN_USER)Buffer)->User.Sid; 487 Length = GetLengthSid(pSid); 488 *ppSid = LocalAlloc(LMEM_FIXED, Length); 489 if (!*ppSid) 490 { 491 return ERROR_NOT_ENOUGH_MEMORY; 492 } 493 CopyMemory(*ppSid, pSid, Length); 494 495 return ERROR_SUCCESS; 496 } 497 498 static DWORD 499 AccpLookupSidByName(IN LSA_HANDLE PolicyHandle, 500 IN LPWSTR Name, 501 OUT PSID *pSid) 502 { 503 NTSTATUS Status; 504 LSA_UNICODE_STRING LsaNames[1]; 505 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomains = NULL; 506 PLSA_TRANSLATED_SID2 TranslatedSid = NULL; 507 DWORD SidLen; 508 SIZE_T NameLength; 509 DWORD Ret = ERROR_SUCCESS; 510 511 NameLength = wcslen(Name); 512 if (NameLength > UNICODE_STRING_MAX_CHARS) 513 { 514 return ERROR_INVALID_PARAMETER; 515 } 516 517 LsaNames[0].Buffer = Name; 518 LsaNames[0].Length = (USHORT)NameLength * sizeof(WCHAR); 519 LsaNames[0].MaximumLength = LsaNames[0].Length + sizeof(WCHAR); 520 521 Status = LsaLookupNames2(PolicyHandle, 522 0, 523 sizeof(LsaNames) / sizeof(LsaNames[0]), 524 LsaNames, 525 &ReferencedDomains, 526 &TranslatedSid); 527 528 if (!NT_SUCCESS(Status)) 529 return LsaNtStatusToWinError(Status); 530 531 if (TranslatedSid->Use == SidTypeUnknown || TranslatedSid->Use == SidTypeInvalid) 532 { 533 Ret = LsaNtStatusToWinError(STATUS_NONE_MAPPED); /* FIXME- what error code? */ 534 goto Cleanup; 535 } 536 537 SidLen = GetLengthSid(TranslatedSid->Sid); 538 ASSERT(SidLen != 0); 539 540 *pSid = LocalAlloc(LMEM_FIXED, (SIZE_T)SidLen); 541 if (*pSid != NULL) 542 { 543 if (!CopySid(SidLen, 544 *pSid, 545 TranslatedSid->Sid)) 546 { 547 Ret = GetLastError(); 548 549 LocalFree((HLOCAL)*pSid); 550 *pSid = NULL; 551 } 552 } 553 else 554 Ret = ERROR_NOT_ENOUGH_MEMORY; 555 556 Cleanup: 557 LsaFreeMemory(ReferencedDomains); 558 LsaFreeMemory(TranslatedSid); 559 560 return Ret; 561 } 562 563 564 static DWORD 565 AccpGetTrusteeSid(IN PTRUSTEE_W Trustee, 566 IN OUT PLSA_HANDLE pPolicyHandle, 567 OUT PSID *ppSid, 568 OUT BOOL *Allocated) 569 { 570 DWORD Ret = ERROR_SUCCESS; 571 LPWSTR TrusteeName; 572 573 *ppSid = NULL; 574 *Allocated = FALSE; 575 576 /* Windows ignores this */ 577 #if 0 578 if (Trustee->pMultipleTrustee || Trustee->MultipleTrusteeOperation != NO_MULTIPLE_TRUSTEE) 579 { 580 /* This is currently not supported */ 581 return ERROR_INVALID_PARAMETER; 582 } 583 #endif 584 585 switch (Trustee->TrusteeForm) 586 { 587 case TRUSTEE_IS_OBJECTS_AND_NAME: 588 if (((POBJECTS_AND_NAME_W)Trustee->ptstrName)->ObjectsPresent != 0) 589 { 590 /* This is not supported as there is no way to interpret the 591 strings provided, and we need GUIDs for the ACEs... */ 592 Ret = ERROR_INVALID_PARAMETER; 593 break; 594 } 595 /* fall through */ 596 597 case TRUSTEE_IS_NAME: 598 TrusteeName = AccpGetTrusteeName(Trustee); 599 if (!wcscmp(TrusteeName, L"CURRENT_USER")) 600 { 601 Ret = AccpLookupCurrentUser(ppSid); 602 if (Ret == ERROR_SUCCESS) 603 { 604 ASSERT(*ppSid != NULL); 605 *Allocated = TRUE; 606 } 607 break; 608 } 609 610 if (*pPolicyHandle == NULL) 611 { 612 Ret = AccpOpenLSAPolicyHandle(NULL, /* FIXME - always local? */ 613 POLICY_LOOKUP_NAMES, 614 pPolicyHandle); 615 if (Ret != ERROR_SUCCESS) 616 return Ret; 617 618 ASSERT(*pPolicyHandle != NULL); 619 } 620 621 Ret = AccpLookupSidByName(*pPolicyHandle, 622 TrusteeName, 623 ppSid); 624 if (Ret == ERROR_SUCCESS) 625 { 626 ASSERT(*ppSid != NULL); 627 *Allocated = TRUE; 628 } 629 break; 630 631 case TRUSTEE_IS_OBJECTS_AND_SID: 632 *ppSid = ((POBJECTS_AND_SID)Trustee->ptstrName)->pSid; 633 break; 634 635 case TRUSTEE_IS_SID: 636 *ppSid = (PSID)Trustee->ptstrName; 637 break; 638 639 default: 640 Ret = ERROR_INVALID_PARAMETER; 641 break; 642 } 643 644 return Ret; 645 } 646 647 648 /********************************************************************** 649 * AccRewriteGetHandleRights EXPORTED 650 * 651 * @unimplemented 652 */ 653 DWORD WINAPI 654 AccRewriteGetHandleRights(HANDLE handle, 655 SE_OBJECT_TYPE ObjectType, 656 SECURITY_INFORMATION SecurityInfo, 657 PSID* ppsidOwner, 658 PSID* ppsidGroup, 659 PACL* ppDacl, 660 PACL* ppSacl, 661 PSECURITY_DESCRIPTOR* ppSecurityDescriptor) 662 { 663 PSECURITY_DESCRIPTOR pSD = NULL; 664 ULONG SDSize = 0; 665 NTSTATUS Status; 666 DWORD LastErr; 667 DWORD Ret; 668 669 /* save the last error code */ 670 LastErr = GetLastError(); 671 672 do 673 { 674 Ret = ERROR_SUCCESS; 675 676 /* allocate a buffer large enough to hold the 677 security descriptor we need to return */ 678 SDSize += 0x100; 679 if (pSD == NULL) 680 { 681 pSD = LocalAlloc(LMEM_FIXED, 682 (SIZE_T)SDSize); 683 } 684 else 685 { 686 PSECURITY_DESCRIPTOR newSD; 687 688 newSD = LocalReAlloc((HLOCAL)pSD, 689 (SIZE_T)SDSize, 690 LMEM_MOVEABLE); 691 if (newSD != NULL) 692 pSD = newSD; 693 } 694 695 if (pSD == NULL) 696 { 697 Ret = GetLastError(); 698 break; 699 } 700 701 /* perform the actual query depending on the object type */ 702 switch (ObjectType) 703 { 704 case SE_REGISTRY_KEY: 705 { 706 Ret = (DWORD)RegGetKeySecurity((HKEY)handle, 707 SecurityInfo, 708 pSD, 709 &SDSize); 710 break; 711 } 712 713 case SE_FILE_OBJECT: 714 /* FIXME - handle console handles? */ 715 case SE_KERNEL_OBJECT: 716 { 717 Status = NtQuerySecurityObject(handle, 718 SecurityInfo, 719 pSD, 720 SDSize, 721 &SDSize); 722 if (!NT_SUCCESS(Status)) 723 { 724 Ret = RtlNtStatusToDosError(Status); 725 } 726 break; 727 } 728 729 case SE_SERVICE: 730 { 731 if (!QueryServiceObjectSecurity((SC_HANDLE)handle, 732 SecurityInfo, 733 pSD, 734 SDSize, 735 &SDSize)) 736 { 737 Ret = GetLastError(); 738 } 739 break; 740 } 741 742 case SE_WINDOW_OBJECT: 743 { 744 if (!GetUserObjectSecurity(handle, 745 &SecurityInfo, 746 pSD, 747 SDSize, 748 &SDSize)) 749 { 750 Ret = GetLastError(); 751 } 752 break; 753 } 754 755 default: 756 { 757 UNIMPLEMENTED; 758 Ret = ERROR_CALL_NOT_IMPLEMENTED; 759 break; 760 } 761 } 762 763 } while (Ret == ERROR_INSUFFICIENT_BUFFER); 764 765 if (Ret == ERROR_SUCCESS) 766 { 767 BOOL Present, Defaulted; 768 769 if (SecurityInfo & OWNER_SECURITY_INFORMATION && ppsidOwner != NULL) 770 { 771 *ppsidOwner = NULL; 772 if (!GetSecurityDescriptorOwner(pSD, 773 ppsidOwner, 774 &Defaulted)) 775 { 776 Ret = GetLastError(); 777 goto Cleanup; 778 } 779 } 780 781 if (SecurityInfo & GROUP_SECURITY_INFORMATION && ppsidGroup != NULL) 782 { 783 *ppsidGroup = NULL; 784 if (!GetSecurityDescriptorGroup(pSD, 785 ppsidGroup, 786 &Defaulted)) 787 { 788 Ret = GetLastError(); 789 goto Cleanup; 790 } 791 } 792 793 if (SecurityInfo & DACL_SECURITY_INFORMATION && ppDacl != NULL) 794 { 795 *ppDacl = NULL; 796 if (!GetSecurityDescriptorDacl(pSD, 797 &Present, 798 ppDacl, 799 &Defaulted)) 800 { 801 Ret = GetLastError(); 802 goto Cleanup; 803 } 804 } 805 806 if (SecurityInfo & SACL_SECURITY_INFORMATION && ppSacl != NULL) 807 { 808 *ppSacl = NULL; 809 if (!GetSecurityDescriptorSacl(pSD, 810 &Present, 811 ppSacl, 812 &Defaulted)) 813 { 814 Ret = GetLastError(); 815 goto Cleanup; 816 } 817 } 818 819 *ppSecurityDescriptor = pSD; 820 } 821 else 822 { 823 Cleanup: 824 if (pSD != NULL) 825 { 826 LocalFree((HLOCAL)pSD); 827 } 828 } 829 830 /* restore the last error code */ 831 SetLastError(LastErr); 832 833 return Ret; 834 } 835 836 837 /********************************************************************** 838 * AccRewriteSetHandleRights EXPORTED 839 * 840 * @unimplemented 841 */ 842 DWORD WINAPI 843 AccRewriteSetHandleRights(HANDLE handle, 844 SE_OBJECT_TYPE ObjectType, 845 SECURITY_INFORMATION SecurityInfo, 846 PSECURITY_DESCRIPTOR pSecurityDescriptor) 847 { 848 NTSTATUS Status; 849 DWORD LastErr; 850 DWORD Ret = ERROR_SUCCESS; 851 852 /* save the last error code */ 853 LastErr = GetLastError(); 854 855 /* set the security according to the object type */ 856 switch (ObjectType) 857 { 858 case SE_REGISTRY_KEY: 859 { 860 Ret = (DWORD)RegSetKeySecurity((HKEY)handle, 861 SecurityInfo, 862 pSecurityDescriptor); 863 break; 864 } 865 866 case SE_FILE_OBJECT: 867 /* FIXME - handle console handles? */ 868 case SE_KERNEL_OBJECT: 869 { 870 Status = NtSetSecurityObject(handle, 871 SecurityInfo, 872 pSecurityDescriptor); 873 if (!NT_SUCCESS(Status)) 874 { 875 Ret = RtlNtStatusToDosError(Status); 876 } 877 break; 878 } 879 880 case SE_SERVICE: 881 { 882 if (!SetServiceObjectSecurity((SC_HANDLE)handle, 883 SecurityInfo, 884 pSecurityDescriptor)) 885 { 886 Ret = GetLastError(); 887 } 888 break; 889 } 890 891 case SE_WINDOW_OBJECT: 892 { 893 if (!SetUserObjectSecurity(handle, 894 &SecurityInfo, 895 pSecurityDescriptor)) 896 { 897 Ret = GetLastError(); 898 } 899 break; 900 } 901 902 default: 903 { 904 UNIMPLEMENTED; 905 Ret = ERROR_CALL_NOT_IMPLEMENTED; 906 break; 907 } 908 } 909 910 911 /* restore the last error code */ 912 SetLastError(LastErr); 913 914 return Ret; 915 } 916 917 918 static DWORD 919 AccpOpenNamedObject(LPWSTR pObjectName, 920 SE_OBJECT_TYPE ObjectType, 921 SECURITY_INFORMATION SecurityInfo, 922 PHANDLE Handle, 923 PHANDLE Handle2, 924 BOOL Write) 925 { 926 LPWSTR lpPath; 927 NTSTATUS Status; 928 ACCESS_MASK DesiredAccess = (ACCESS_MASK)0; 929 DWORD Ret = ERROR_SUCCESS; 930 931 /* determine the required access rights */ 932 switch (ObjectType) 933 { 934 case SE_REGISTRY_KEY: 935 case SE_FILE_OBJECT: 936 case SE_KERNEL_OBJECT: 937 case SE_SERVICE: 938 case SE_WINDOW_OBJECT: 939 if (Write) 940 { 941 SetSecurityAccessMask(SecurityInfo, 942 (PDWORD)&DesiredAccess); 943 } 944 else 945 { 946 QuerySecurityAccessMask(SecurityInfo, 947 (PDWORD)&DesiredAccess); 948 } 949 break; 950 951 default: 952 break; 953 } 954 955 /* make a copy of the path if we're modifying the string */ 956 switch (ObjectType) 957 { 958 case SE_REGISTRY_KEY: 959 case SE_SERVICE: 960 lpPath = (LPWSTR)LocalAlloc(LMEM_FIXED, 961 (wcslen(pObjectName) + 1) * sizeof(WCHAR)); 962 if (lpPath == NULL) 963 { 964 Ret = GetLastError(); 965 goto Cleanup; 966 } 967 968 wcscpy(lpPath, 969 pObjectName); 970 break; 971 972 default: 973 lpPath = pObjectName; 974 break; 975 } 976 977 /* open a handle to the path depending on the object type */ 978 switch (ObjectType) 979 { 980 case SE_FILE_OBJECT: 981 { 982 IO_STATUS_BLOCK IoStatusBlock; 983 OBJECT_ATTRIBUTES ObjectAttributes; 984 UNICODE_STRING FileName; 985 986 if (!RtlDosPathNameToNtPathName_U(pObjectName, 987 &FileName, 988 NULL, 989 NULL)) 990 { 991 Ret = ERROR_INVALID_NAME; 992 goto Cleanup; 993 } 994 995 InitializeObjectAttributes(&ObjectAttributes, 996 &FileName, 997 OBJ_CASE_INSENSITIVE, 998 NULL, 999 NULL); 1000 1001 Status = NtOpenFile(Handle, 1002 DesiredAccess | SYNCHRONIZE, 1003 &ObjectAttributes, 1004 &IoStatusBlock, 1005 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 1006 FILE_SYNCHRONOUS_IO_NONALERT); 1007 1008 RtlFreeHeap(RtlGetProcessHeap(), 1009 0, 1010 FileName.Buffer); 1011 1012 if (!NT_SUCCESS(Status)) 1013 { 1014 Ret = RtlNtStatusToDosError(Status); 1015 } 1016 break; 1017 } 1018 1019 case SE_REGISTRY_KEY: 1020 { 1021 static const struct 1022 { 1023 HKEY hRootKey; 1024 LPCWSTR szRootKey; 1025 } AccRegRootKeys[] = 1026 { 1027 {HKEY_CLASSES_ROOT, L"CLASSES_ROOT"}, 1028 {HKEY_CURRENT_USER, L"CURRENT_USER"}, 1029 {HKEY_LOCAL_MACHINE, L"MACHINE"}, 1030 {HKEY_USERS, L"USERS"}, 1031 {HKEY_CURRENT_CONFIG, L"CONFIG"}, 1032 }; 1033 LPWSTR lpMachineName, lpRootKeyName, lpKeyName; 1034 HKEY hRootKey = NULL; 1035 UINT i; 1036 1037 /* parse the registry path */ 1038 if (lpPath[0] == L'\\' && lpPath[1] == L'\\') 1039 { 1040 lpMachineName = lpPath; 1041 1042 lpRootKeyName = wcschr(lpPath + 2, 1043 L'\\'); 1044 if (lpRootKeyName == NULL) 1045 goto ParseRegErr; 1046 else 1047 *(lpRootKeyName++) = L'\0'; 1048 } 1049 else 1050 { 1051 lpMachineName = NULL; 1052 lpRootKeyName = lpPath; 1053 } 1054 1055 lpKeyName = wcschr(lpRootKeyName, 1056 L'\\'); 1057 if (lpKeyName != NULL) 1058 { 1059 *(lpKeyName++) = L'\0'; 1060 } 1061 1062 for (i = 0; 1063 i != sizeof(AccRegRootKeys) / sizeof(AccRegRootKeys[0]); 1064 i++) 1065 { 1066 if (!wcsicmp(lpRootKeyName, 1067 AccRegRootKeys[i].szRootKey)) 1068 { 1069 hRootKey = AccRegRootKeys[i].hRootKey; 1070 break; 1071 } 1072 } 1073 1074 if (hRootKey == NULL) 1075 { 1076 ParseRegErr: 1077 /* FIXME - right error code? */ 1078 Ret = ERROR_INVALID_PARAMETER; 1079 goto Cleanup; 1080 } 1081 1082 /* open the registry key */ 1083 if (lpMachineName != NULL) 1084 { 1085 Ret = RegConnectRegistry(lpMachineName, 1086 hRootKey, 1087 (PHKEY)Handle2); 1088 1089 if (Ret != ERROR_SUCCESS) 1090 goto Cleanup; 1091 1092 hRootKey = (HKEY)(*Handle2); 1093 } 1094 1095 Ret = RegOpenKeyEx(hRootKey, 1096 lpKeyName, 1097 0, 1098 (REGSAM)DesiredAccess, 1099 (PHKEY)Handle); 1100 if (Ret != ERROR_SUCCESS) 1101 { 1102 if (*Handle2 != NULL) 1103 { 1104 RegCloseKey((HKEY)(*Handle2)); 1105 } 1106 1107 goto Cleanup; 1108 } 1109 break; 1110 } 1111 1112 case SE_SERVICE: 1113 { 1114 LPWSTR lpServiceName, lpMachineName; 1115 1116 /* parse the service path */ 1117 if (lpPath[0] == L'\\' && lpPath[1] == L'\\') 1118 { 1119 DesiredAccess |= SC_MANAGER_CONNECT; 1120 1121 lpMachineName = lpPath; 1122 1123 lpServiceName = wcschr(lpPath + 2, 1124 L'\\'); 1125 if (lpServiceName == NULL) 1126 { 1127 /* FIXME - right error code? */ 1128 Ret = ERROR_INVALID_PARAMETER; 1129 goto Cleanup; 1130 } 1131 else 1132 *(lpServiceName++) = L'\0'; 1133 } 1134 else 1135 { 1136 lpMachineName = NULL; 1137 lpServiceName = lpPath; 1138 } 1139 1140 /* open the service */ 1141 *Handle2 = (HANDLE)OpenSCManager(lpMachineName, 1142 NULL, 1143 (DWORD)DesiredAccess); 1144 if (*Handle2 == NULL) 1145 { 1146 Ret = GetLastError(); 1147 ASSERT(Ret != ERROR_SUCCESS); 1148 goto Cleanup; 1149 } 1150 1151 DesiredAccess &= ~SC_MANAGER_CONNECT; 1152 *Handle = (HANDLE)OpenService((SC_HANDLE)(*Handle2), 1153 lpServiceName, 1154 (DWORD)DesiredAccess); 1155 if (*Handle == NULL) 1156 { 1157 Ret = GetLastError(); 1158 ASSERT(Ret != ERROR_SUCCESS); 1159 ASSERT(*Handle2 != NULL); 1160 CloseServiceHandle((SC_HANDLE)(*Handle2)); 1161 1162 goto Cleanup; 1163 } 1164 break; 1165 } 1166 1167 default: 1168 { 1169 UNIMPLEMENTED; 1170 Ret = ERROR_CALL_NOT_IMPLEMENTED; 1171 break; 1172 } 1173 } 1174 1175 Cleanup: 1176 if (lpPath != NULL && lpPath != pObjectName) 1177 { 1178 LocalFree((HLOCAL)lpPath); 1179 } 1180 1181 return Ret; 1182 } 1183 1184 1185 static VOID 1186 AccpCloseObjectHandle(SE_OBJECT_TYPE ObjectType, 1187 HANDLE Handle, 1188 HANDLE Handle2) 1189 { 1190 ASSERT(Handle != NULL); 1191 1192 /* close allocated handles depending on the object type */ 1193 switch (ObjectType) 1194 { 1195 case SE_REGISTRY_KEY: 1196 RegCloseKey((HKEY)Handle); 1197 if (Handle2 != NULL) 1198 RegCloseKey((HKEY)Handle2); 1199 break; 1200 1201 case SE_FILE_OBJECT: 1202 NtClose(Handle); 1203 break; 1204 1205 case SE_KERNEL_OBJECT: 1206 case SE_WINDOW_OBJECT: 1207 CloseHandle(Handle); 1208 break; 1209 1210 case SE_SERVICE: 1211 CloseServiceHandle((SC_HANDLE)Handle); 1212 ASSERT(Handle2 != NULL); 1213 CloseServiceHandle((SC_HANDLE)Handle2); 1214 break; 1215 1216 default: 1217 break; 1218 } 1219 } 1220 1221 1222 /********************************************************************** 1223 * AccRewriteGetNamedRights EXPORTED 1224 * 1225 * @unimplemented 1226 */ 1227 DWORD WINAPI 1228 AccRewriteGetNamedRights(LPWSTR pObjectName, 1229 SE_OBJECT_TYPE ObjectType, 1230 SECURITY_INFORMATION SecurityInfo, 1231 PSID* ppsidOwner, 1232 PSID* ppsidGroup, 1233 PACL* ppDacl, 1234 PACL* ppSacl, 1235 PSECURITY_DESCRIPTOR* ppSecurityDescriptor) 1236 { 1237 HANDLE Handle = NULL; 1238 HANDLE Handle2 = NULL; 1239 DWORD LastErr; 1240 DWORD Ret; 1241 1242 /* save the last error code */ 1243 LastErr = GetLastError(); 1244 1245 /* create the handle */ 1246 Ret = AccpOpenNamedObject(pObjectName, 1247 ObjectType, 1248 SecurityInfo, 1249 &Handle, 1250 &Handle2, 1251 FALSE); 1252 1253 if (Ret == ERROR_SUCCESS) 1254 { 1255 ASSERT(Handle != NULL); 1256 1257 /* perform the operation */ 1258 Ret = AccRewriteGetHandleRights(Handle, 1259 ObjectType, 1260 SecurityInfo, 1261 ppsidOwner, 1262 ppsidGroup, 1263 ppDacl, 1264 ppSacl, 1265 ppSecurityDescriptor); 1266 1267 /* close opened handles */ 1268 AccpCloseObjectHandle(ObjectType, 1269 Handle, 1270 Handle2); 1271 } 1272 1273 /* restore the last error code */ 1274 SetLastError(LastErr); 1275 1276 return Ret; 1277 } 1278 1279 1280 /********************************************************************** 1281 * AccRewriteSetNamedRights EXPORTED 1282 * 1283 * @unimplemented 1284 */ 1285 DWORD WINAPI 1286 AccRewriteSetNamedRights(LPWSTR pObjectName, 1287 SE_OBJECT_TYPE ObjectType, 1288 SECURITY_INFORMATION SecurityInfo, 1289 PSECURITY_DESCRIPTOR pSecurityDescriptor) 1290 { 1291 HANDLE Handle = NULL; 1292 HANDLE Handle2 = NULL; 1293 DWORD LastErr; 1294 DWORD Ret; 1295 1296 /* save the last error code */ 1297 LastErr = GetLastError(); 1298 1299 /* create the handle */ 1300 Ret = AccpOpenNamedObject(pObjectName, 1301 ObjectType, 1302 SecurityInfo, 1303 &Handle, 1304 &Handle2, 1305 TRUE); 1306 1307 if (Ret == ERROR_SUCCESS) 1308 { 1309 ASSERT(Handle != NULL); 1310 1311 /* perform the operation */ 1312 Ret = AccRewriteSetHandleRights(Handle, 1313 ObjectType, 1314 SecurityInfo, 1315 pSecurityDescriptor); 1316 1317 /* close opened handles */ 1318 AccpCloseObjectHandle(ObjectType, 1319 Handle, 1320 Handle2); 1321 } 1322 1323 /* restore the last error code */ 1324 SetLastError(LastErr); 1325 1326 return Ret; 1327 } 1328 1329 1330 /********************************************************************** 1331 * AccRewriteSetEntriesInAcl EXPORTED 1332 * 1333 * @implemented 1334 */ 1335 DWORD WINAPI 1336 AccRewriteSetEntriesInAcl(ULONG cCountOfExplicitEntries, 1337 PEXPLICIT_ACCESS_W pListOfExplicitEntries, 1338 PACL OldAcl, 1339 PACL* NewAcl) 1340 { 1341 PACL pNew = NULL; 1342 ACL_SIZE_INFORMATION SizeInformation; 1343 PACE_HEADER pAce; 1344 BOOLEAN KeepAceBuf[8]; 1345 BOOLEAN *pKeepAce = NULL; 1346 GUID ObjectTypeGuid, InheritedObjectTypeGuid; 1347 DWORD ObjectsPresent; 1348 BOOL needToClean; 1349 PSID pSid1, pSid2; 1350 ULONG i, j; 1351 LSA_HANDLE PolicyHandle = NULL; 1352 BOOL bRet; 1353 DWORD LastErr; 1354 DWORD Ret = ERROR_SUCCESS; 1355 1356 /* save the last error code */ 1357 LastErr = GetLastError(); 1358 1359 *NewAcl = NULL; 1360 1361 /* Get information about previous ACL */ 1362 if (OldAcl) 1363 { 1364 if (!GetAclInformation(OldAcl, &SizeInformation, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation)) 1365 { 1366 Ret = GetLastError(); 1367 goto Cleanup; 1368 } 1369 1370 if (SizeInformation.AceCount > sizeof(KeepAceBuf) / sizeof(KeepAceBuf[0])) 1371 { 1372 pKeepAce = (BOOLEAN *)LocalAlloc(LMEM_FIXED, SizeInformation.AceCount * sizeof(*pKeepAce)); 1373 if (!pKeepAce) 1374 { 1375 Ret = ERROR_NOT_ENOUGH_MEMORY; 1376 goto Cleanup; 1377 } 1378 } 1379 else 1380 pKeepAce = KeepAceBuf; 1381 1382 memset(pKeepAce, TRUE, SizeInformation.AceCount * sizeof(*pKeepAce)); 1383 } 1384 else 1385 { 1386 ZeroMemory(&SizeInformation, sizeof(ACL_SIZE_INFORMATION)); 1387 SizeInformation.AclBytesInUse = sizeof(ACL); 1388 } 1389 1390 /* Get size required for new entries */ 1391 for (i = 0; i < cCountOfExplicitEntries; i++) 1392 { 1393 Ret = AccpGetTrusteeSid(&pListOfExplicitEntries[i].Trustee, 1394 &PolicyHandle, 1395 &pSid1, 1396 &needToClean); 1397 if (Ret != ERROR_SUCCESS) 1398 goto Cleanup; 1399 1400 ObjectsPresent = AccpGetTrusteeObjects(&pListOfExplicitEntries[i].Trustee, 1401 NULL, 1402 NULL); 1403 1404 switch (pListOfExplicitEntries[i].grfAccessMode) 1405 { 1406 case REVOKE_ACCESS: 1407 case SET_ACCESS: 1408 /* Discard all accesses for the trustee... */ 1409 for (j = 0; j < SizeInformation.AceCount; j++) 1410 { 1411 if (!pKeepAce[j]) 1412 continue; 1413 if (!GetAce(OldAcl, j, (PVOID*)&pAce)) 1414 { 1415 Ret = GetLastError(); 1416 goto Cleanup; 1417 } 1418 1419 pSid2 = AccpGetAceSid(pAce); 1420 if (RtlEqualSid(pSid1, pSid2)) 1421 { 1422 pKeepAce[j] = FALSE; 1423 SizeInformation.AclBytesInUse -= pAce->AceSize; 1424 } 1425 } 1426 if (pListOfExplicitEntries[i].grfAccessMode == REVOKE_ACCESS) 1427 break; 1428 /* ...and replace by the current access */ 1429 case GRANT_ACCESS: 1430 case DENY_ACCESS: 1431 /* Add to ACL */ 1432 SizeInformation.AclBytesInUse += AccpCalcNeededAceSize(pSid1, ObjectsPresent); 1433 break; 1434 case SET_AUDIT_SUCCESS: 1435 case SET_AUDIT_FAILURE: 1436 /* FIXME */ 1437 DPRINT1("Case not implemented!\n"); 1438 break; 1439 default: 1440 DPRINT1("Unknown access mode 0x%x. Ignoring it\n", pListOfExplicitEntries[i].grfAccessMode); 1441 break; 1442 } 1443 1444 if (needToClean) 1445 LocalFree((HLOCAL)pSid1); 1446 } 1447 1448 /* Succeed, if no ACL needs to be allocated */ 1449 if (SizeInformation.AclBytesInUse == 0) 1450 goto Cleanup; 1451 1452 /* OK, now create the new ACL */ 1453 DPRINT("Allocating %u bytes for the new ACL\n", SizeInformation.AclBytesInUse); 1454 pNew = (PACL)LocalAlloc(LMEM_FIXED, SizeInformation.AclBytesInUse); 1455 if (!pNew) 1456 { 1457 Ret = ERROR_NOT_ENOUGH_MEMORY; 1458 goto Cleanup; 1459 } 1460 if (!InitializeAcl(pNew, SizeInformation.AclBytesInUse, ACL_REVISION)) 1461 { 1462 Ret = GetLastError(); 1463 goto Cleanup; 1464 } 1465 1466 /* Fill it */ 1467 /* 1a) New audit entries (SET_AUDIT_SUCCESS, SET_AUDIT_FAILURE) */ 1468 /* FIXME */ 1469 1470 /* 1b) Existing audit entries */ 1471 /* FIXME */ 1472 1473 /* 2a) New denied entries (DENY_ACCESS) */ 1474 for (i = 0; i < cCountOfExplicitEntries; i++) 1475 { 1476 if (pListOfExplicitEntries[i].grfAccessMode == DENY_ACCESS) 1477 { 1478 /* FIXME: take care of pListOfExplicitEntries[i].grfInheritance */ 1479 Ret = AccpGetTrusteeSid(&pListOfExplicitEntries[i].Trustee, 1480 &PolicyHandle, 1481 &pSid1, 1482 &needToClean); 1483 if (Ret != ERROR_SUCCESS) 1484 goto Cleanup; 1485 1486 ObjectsPresent = AccpGetTrusteeObjects(&pListOfExplicitEntries[i].Trustee, 1487 &ObjectTypeGuid, 1488 &InheritedObjectTypeGuid); 1489 1490 if (ObjectsPresent == 0) 1491 { 1492 /* FIXME: Call AddAccessDeniedAceEx instead! */ 1493 bRet = AddAccessDeniedAce(pNew, ACL_REVISION, pListOfExplicitEntries[i].grfAccessPermissions, pSid1); 1494 } 1495 else 1496 { 1497 /* FIXME: Call AddAccessDeniedObjectAce */ 1498 DPRINT1("Object ACEs not yet supported!\n"); 1499 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 1500 bRet = FALSE; 1501 } 1502 1503 if (needToClean) LocalFree((HLOCAL)pSid1); 1504 if (!bRet) 1505 { 1506 Ret = GetLastError(); 1507 goto Cleanup; 1508 } 1509 } 1510 } 1511 1512 /* 2b) Existing denied entries */ 1513 /* FIXME */ 1514 1515 /* 3a) New allow entries (GRANT_ACCESS, SET_ACCESS) */ 1516 for (i = 0; i < cCountOfExplicitEntries; i++) 1517 { 1518 if (pListOfExplicitEntries[i].grfAccessMode == SET_ACCESS || 1519 pListOfExplicitEntries[i].grfAccessMode == GRANT_ACCESS) 1520 { 1521 /* FIXME: take care of pListOfExplicitEntries[i].grfInheritance */ 1522 Ret = AccpGetTrusteeSid(&pListOfExplicitEntries[i].Trustee, 1523 &PolicyHandle, 1524 &pSid1, 1525 &needToClean); 1526 if (Ret != ERROR_SUCCESS) 1527 goto Cleanup; 1528 1529 ObjectsPresent = AccpGetTrusteeObjects(&pListOfExplicitEntries[i].Trustee, 1530 &ObjectTypeGuid, 1531 &InheritedObjectTypeGuid); 1532 1533 if (ObjectsPresent == 0) 1534 { 1535 /* FIXME: Call AddAccessAllowedAceEx instead! */ 1536 bRet = AddAccessAllowedAce(pNew, ACL_REVISION, pListOfExplicitEntries[i].grfAccessPermissions, pSid1); 1537 } 1538 else 1539 { 1540 /* FIXME: Call AddAccessAllowedObjectAce */ 1541 DPRINT1("Object ACEs not yet supported!\n"); 1542 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 1543 bRet = FALSE; 1544 } 1545 1546 if (needToClean) LocalFree((HLOCAL)pSid1); 1547 if (!bRet) 1548 { 1549 Ret = GetLastError(); 1550 goto Cleanup; 1551 } 1552 } 1553 } 1554 1555 /* 3b) Existing allow entries */ 1556 /* FIXME */ 1557 1558 *NewAcl = pNew; 1559 1560 Cleanup: 1561 if (pKeepAce && pKeepAce != KeepAceBuf) 1562 LocalFree((HLOCAL)pKeepAce); 1563 1564 if (pNew && Ret != ERROR_SUCCESS) 1565 LocalFree((HLOCAL)pNew); 1566 1567 if (PolicyHandle) 1568 LsaClose(PolicyHandle); 1569 1570 /* restore the last error code */ 1571 SetLastError(LastErr); 1572 1573 return Ret; 1574 } 1575 1576 1577 /********************************************************************** 1578 * AccGetInheritanceSource EXPORTED 1579 * 1580 * @unimplemented 1581 */ 1582 DWORD WINAPI 1583 AccGetInheritanceSource(LPWSTR pObjectName, 1584 SE_OBJECT_TYPE ObjectType, 1585 SECURITY_INFORMATION SecurityInfo, 1586 BOOL Container, 1587 GUID** pObjectClassGuids, 1588 DWORD GuidCount, 1589 PACL pAcl, 1590 PFN_OBJECT_MGR_FUNCTS pfnArray, 1591 PGENERIC_MAPPING pGenericMapping, 1592 PINHERITED_FROMW pInheritArray) 1593 { 1594 UNIMPLEMENTED; 1595 return ERROR_CALL_NOT_IMPLEMENTED; 1596 } 1597 1598 1599 /********************************************************************** 1600 * AccFreeIndexArray EXPORTED 1601 * 1602 * @implemented 1603 */ 1604 DWORD WINAPI 1605 AccFreeIndexArray(PINHERITED_FROMW pInheritArray, 1606 USHORT AceCnt, 1607 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL) 1608 { 1609 PINHERITED_FROMW pLast; 1610 1611 UNREFERENCED_PARAMETER(pfnArray); 1612 1613 pLast = pInheritArray + AceCnt; 1614 while (pInheritArray != pLast) 1615 { 1616 if (pInheritArray->AncestorName != NULL) 1617 { 1618 LocalFree((HLOCAL)pInheritArray->AncestorName); 1619 pInheritArray->AncestorName = NULL; 1620 } 1621 1622 pInheritArray++; 1623 } 1624 1625 return ERROR_SUCCESS; 1626 } 1627 1628 1629 /********************************************************************** 1630 * AccRewriteGetExplicitEntriesFromAcl EXPORTED 1631 * 1632 * @implemented 1633 */ 1634 DWORD WINAPI 1635 AccRewriteGetExplicitEntriesFromAcl(PACL pacl, 1636 PULONG pcCountOfExplicitEntries, 1637 PEXPLICIT_ACCESS_W* pListOfExplicitEntries) 1638 { 1639 PACE_HEADER AceHeader; 1640 PSID Sid, SidTarget; 1641 ULONG ObjectAceCount = 0; 1642 POBJECTS_AND_SID ObjSid; 1643 SIZE_T Size; 1644 PEXPLICIT_ACCESS_W peaw; 1645 DWORD LastErr, SidLen; 1646 DWORD AceIndex = 0; 1647 DWORD ErrorCode = ERROR_SUCCESS; 1648 1649 /* save the last error code */ 1650 LastErr = GetLastError(); 1651 1652 if (pacl != NULL) 1653 { 1654 if (pacl->AceCount != 0) 1655 { 1656 Size = (SIZE_T)pacl->AceCount * sizeof(EXPLICIT_ACCESS_W); 1657 1658 /* calculate the space needed */ 1659 while (GetAce(pacl, 1660 AceIndex, 1661 (LPVOID*)&AceHeader)) 1662 { 1663 Sid = AccpGetAceSid(AceHeader); 1664 Size += GetLengthSid(Sid); 1665 1666 if (AccpIsObjectAce(AceHeader)) 1667 ObjectAceCount++; 1668 1669 AceIndex++; 1670 } 1671 1672 Size += ObjectAceCount * sizeof(OBJECTS_AND_SID); 1673 1674 ASSERT(pacl->AceCount == AceIndex); 1675 1676 /* allocate the array */ 1677 peaw = (PEXPLICIT_ACCESS_W)LocalAlloc(LMEM_FIXED, 1678 Size); 1679 if (peaw != NULL) 1680 { 1681 AceIndex = 0; 1682 ObjSid = (POBJECTS_AND_SID)(peaw + pacl->AceCount); 1683 SidTarget = (PSID)(ObjSid + ObjectAceCount); 1684 1685 /* initialize the array */ 1686 while (GetAce(pacl, 1687 AceIndex, 1688 (LPVOID*)&AceHeader)) 1689 { 1690 Sid = AccpGetAceSid(AceHeader); 1691 SidLen = GetLengthSid(Sid); 1692 1693 peaw[AceIndex].grfAccessPermissions = AccpGetAceAccessMask(AceHeader); 1694 peaw[AceIndex].grfAccessMode = AccpGetAceAccessMode(AceHeader); 1695 peaw[AceIndex].grfInheritance = AceHeader->AceFlags & VALID_INHERIT_FLAGS; 1696 1697 if (CopySid(SidLen, 1698 SidTarget, 1699 Sid)) 1700 { 1701 if (AccpIsObjectAce(AceHeader)) 1702 { 1703 BuildTrusteeWithObjectsAndSid(&peaw[AceIndex].Trustee, 1704 ObjSid++, 1705 AccpGetObjectAceObjectType(AceHeader), 1706 AccpGetObjectAceInheritedObjectType(AceHeader), 1707 SidTarget); 1708 } 1709 else 1710 { 1711 BuildTrusteeWithSid(&peaw[AceIndex].Trustee, 1712 SidTarget); 1713 } 1714 1715 SidTarget = (PSID)((ULONG_PTR)SidTarget + SidLen); 1716 } 1717 else 1718 { 1719 /* copying the SID failed, treat it as an fatal error... */ 1720 ErrorCode = GetLastError(); 1721 1722 /* free allocated resources */ 1723 LocalFree(peaw); 1724 peaw = NULL; 1725 AceIndex = 0; 1726 break; 1727 } 1728 1729 AceIndex++; 1730 } 1731 1732 *pcCountOfExplicitEntries = AceIndex; 1733 *pListOfExplicitEntries = peaw; 1734 } 1735 else 1736 ErrorCode = ERROR_NOT_ENOUGH_MEMORY; 1737 } 1738 else 1739 { 1740 goto EmptyACL; 1741 } 1742 } 1743 else 1744 { 1745 EmptyACL: 1746 *pcCountOfExplicitEntries = 0; 1747 *pListOfExplicitEntries = NULL; 1748 } 1749 1750 /* restore the last error code */ 1751 SetLastError(LastErr); 1752 1753 return ErrorCode; 1754 } 1755 1756 1757 /********************************************************************** 1758 * AccTreeResetNamedSecurityInfo EXPORTED 1759 * 1760 * @unimplemented 1761 */ 1762 DWORD WINAPI 1763 AccTreeResetNamedSecurityInfo(LPWSTR pObjectName, 1764 SE_OBJECT_TYPE ObjectType, 1765 SECURITY_INFORMATION SecurityInfo, 1766 PSID pOwner, 1767 PSID pGroup, 1768 PACL pDacl, 1769 PACL pSacl, 1770 BOOL KeepExplicit, 1771 FN_PROGRESSW fnProgress, 1772 PROG_INVOKE_SETTING ProgressInvokeSetting, 1773 PVOID Args) 1774 { 1775 UNIMPLEMENTED; 1776 return ERROR_CALL_NOT_IMPLEMENTED; 1777 } 1778 1779 1780 BOOL WINAPI 1781 DllMain(IN HINSTANCE hinstDLL, 1782 IN DWORD dwReason, 1783 IN LPVOID lpvReserved) 1784 { 1785 switch (dwReason) 1786 { 1787 case DLL_PROCESS_ATTACH: 1788 hDllInstance = hinstDLL; 1789 DisableThreadLibraryCalls(hinstDLL); 1790 break; 1791 1792 case DLL_PROCESS_DETACH: 1793 break; 1794 } 1795 return TRUE; 1796 } 1797 1798