Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenntmarta.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS MARTA provider 00003 * Copyright (C) 2005 - 2006 ReactOS Team 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00018 */ 00019 /* $Id: ntmarta.c 31176 2007-12-12 07:04:12Z weiden $ 00020 * 00021 * PROJECT: ReactOS MARTA provider 00022 * FILE: lib/ntmarta/ntmarta.c 00023 * PURPOSE: ReactOS MARTA provider 00024 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com> 00025 * 00026 * UPDATE HISTORY: 00027 * 07/26/2005 Created 00028 */ 00029 #include <ntmarta.h> 00030 00031 #define NDEBUG 00032 #include <debug.h> 00033 00034 HINSTANCE hDllInstance; 00035 00036 static ACCESS_MODE 00037 AccpGetAceAccessMode(IN PACE_HEADER AceHeader) 00038 { 00039 ACCESS_MODE Mode = NOT_USED_ACCESS; 00040 00041 switch (AceHeader->AceType) 00042 { 00043 case ACCESS_ALLOWED_ACE_TYPE: 00044 case ACCESS_ALLOWED_CALLBACK_ACE_TYPE: 00045 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE: 00046 case ACCESS_ALLOWED_OBJECT_ACE_TYPE: 00047 Mode = GRANT_ACCESS; 00048 break; 00049 00050 case ACCESS_DENIED_ACE_TYPE: 00051 case ACCESS_DENIED_CALLBACK_ACE_TYPE: 00052 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE: 00053 case ACCESS_DENIED_OBJECT_ACE_TYPE: 00054 Mode = DENY_ACCESS; 00055 break; 00056 00057 case SYSTEM_AUDIT_ACE_TYPE: 00058 case SYSTEM_AUDIT_CALLBACK_ACE_TYPE: 00059 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE: 00060 case SYSTEM_AUDIT_OBJECT_ACE_TYPE: 00061 if (AceHeader->AceFlags & FAILED_ACCESS_ACE_FLAG) 00062 Mode = SET_AUDIT_FAILURE; 00063 else if (AceHeader->AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG) 00064 Mode = SET_AUDIT_SUCCESS; 00065 break; 00066 } 00067 00068 return Mode; 00069 } 00070 00071 static UINT 00072 AccpGetAceStructureSize(IN PACE_HEADER AceHeader) 00073 { 00074 UINT Size = 0; 00075 00076 switch (AceHeader->AceType) 00077 { 00078 case ACCESS_ALLOWED_ACE_TYPE: 00079 case ACCESS_DENIED_ACE_TYPE: 00080 Size = FIELD_OFFSET(ACCESS_ALLOWED_ACE, 00081 SidStart); 00082 break; 00083 case ACCESS_ALLOWED_CALLBACK_ACE_TYPE: 00084 case ACCESS_DENIED_CALLBACK_ACE_TYPE: 00085 Size = FIELD_OFFSET(ACCESS_ALLOWED_CALLBACK_ACE, 00086 SidStart); 00087 break; 00088 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE: 00089 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE: 00090 { 00091 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace = (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE)AceHeader; 00092 Size = FIELD_OFFSET(ACCESS_ALLOWED_CALLBACK_OBJECT_ACE, 00093 ObjectType); 00094 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 00095 Size += sizeof(Ace->ObjectType); 00096 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) 00097 Size += sizeof(Ace->InheritedObjectType); 00098 break; 00099 } 00100 case ACCESS_ALLOWED_OBJECT_ACE_TYPE: 00101 case ACCESS_DENIED_OBJECT_ACE_TYPE: 00102 { 00103 PACCESS_ALLOWED_OBJECT_ACE Ace = (PACCESS_ALLOWED_OBJECT_ACE)AceHeader; 00104 Size = FIELD_OFFSET(ACCESS_ALLOWED_OBJECT_ACE, 00105 ObjectType); 00106 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 00107 Size += sizeof(Ace->ObjectType); 00108 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) 00109 Size += sizeof(Ace->InheritedObjectType); 00110 break; 00111 } 00112 00113 case SYSTEM_AUDIT_ACE_TYPE: 00114 Size = FIELD_OFFSET(SYSTEM_AUDIT_ACE, 00115 SidStart); 00116 break; 00117 case SYSTEM_AUDIT_CALLBACK_ACE_TYPE: 00118 Size = FIELD_OFFSET(SYSTEM_AUDIT_CALLBACK_ACE, 00119 SidStart); 00120 break; 00121 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE: 00122 { 00123 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace = (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE)AceHeader; 00124 Size = FIELD_OFFSET(SYSTEM_AUDIT_CALLBACK_OBJECT_ACE, 00125 ObjectType); 00126 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 00127 Size += sizeof(Ace->ObjectType); 00128 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) 00129 Size += sizeof(Ace->InheritedObjectType); 00130 break; 00131 } 00132 case SYSTEM_AUDIT_OBJECT_ACE_TYPE: 00133 { 00134 PSYSTEM_AUDIT_OBJECT_ACE Ace = (PSYSTEM_AUDIT_OBJECT_ACE)AceHeader; 00135 Size = FIELD_OFFSET(SYSTEM_AUDIT_OBJECT_ACE, 00136 ObjectType); 00137 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 00138 Size += sizeof(Ace->ObjectType); 00139 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) 00140 Size += sizeof(Ace->InheritedObjectType); 00141 break; 00142 } 00143 00144 case SYSTEM_MANDATORY_LABEL_ACE_TYPE: 00145 Size = FIELD_OFFSET(SYSTEM_MANDATORY_LABEL_ACE, 00146 SidStart); 00147 break; 00148 } 00149 00150 return Size; 00151 } 00152 00153 static PSID 00154 AccpGetAceSid(IN PACE_HEADER AceHeader) 00155 { 00156 return (PSID)((ULONG_PTR)AceHeader + AccpGetAceStructureSize(AceHeader)); 00157 } 00158 00159 static ACCESS_MASK 00160 AccpGetAceAccessMask(IN PACE_HEADER AceHeader) 00161 { 00162 return *((PACCESS_MASK)(AceHeader + 1)); 00163 } 00164 00165 static BOOL 00166 AccpIsObjectAce(IN PACE_HEADER AceHeader) 00167 { 00168 BOOL Ret; 00169 00170 switch (AceHeader->AceType) 00171 { 00172 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE: 00173 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE: 00174 case ACCESS_ALLOWED_OBJECT_ACE_TYPE: 00175 case ACCESS_DENIED_OBJECT_ACE_TYPE: 00176 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE: 00177 case SYSTEM_AUDIT_OBJECT_ACE_TYPE: 00178 Ret = TRUE; 00179 break; 00180 00181 default: 00182 Ret = FALSE; 00183 break; 00184 } 00185 00186 return Ret; 00187 } 00188 00189 static DWORD 00190 AccpGetTrusteeObjects(IN PTRUSTEE_W Trustee, 00191 OUT GUID *pObjectTypeGuid OPTIONAL, 00192 OUT GUID *pInheritedObjectTypeGuid OPTIONAL) 00193 { 00194 DWORD Ret; 00195 00196 switch (Trustee->TrusteeForm) 00197 { 00198 case TRUSTEE_IS_OBJECTS_AND_NAME: 00199 { 00200 POBJECTS_AND_NAME_W pOan = (POBJECTS_AND_NAME_W)Trustee->ptstrName; 00201 00202 /* pOan->ObjectsPresent should always be 0 here because a previous 00203 call to AccpGetTrusteeSid should have rejected these trustees 00204 already. */ 00205 ASSERT(pOan->ObjectsPresent == 0); 00206 00207 Ret = pOan->ObjectsPresent; 00208 break; 00209 } 00210 00211 case TRUSTEE_IS_OBJECTS_AND_SID: 00212 { 00213 POBJECTS_AND_SID pOas = (POBJECTS_AND_SID)Trustee->ptstrName; 00214 00215 if (pObjectTypeGuid != NULL && pOas->ObjectsPresent & ACE_OBJECT_TYPE_PRESENT) 00216 *pObjectTypeGuid = pOas->ObjectTypeGuid; 00217 00218 if (pInheritedObjectTypeGuid != NULL && pOas->ObjectsPresent & ACE_INHERITED_OBJECT_TYPE_PRESENT) 00219 *pObjectTypeGuid = pOas->InheritedObjectTypeGuid; 00220 00221 Ret = pOas->ObjectsPresent; 00222 break; 00223 } 00224 00225 default: 00226 /* Any other trustee forms have no objects attached... */ 00227 Ret = 0; 00228 break; 00229 } 00230 00231 return Ret; 00232 } 00233 00234 static DWORD 00235 AccpCalcNeededAceSize(IN PSID Sid, 00236 IN DWORD ObjectsPresent) 00237 { 00238 DWORD Ret; 00239 00240 Ret = sizeof(ACE) + GetLengthSid(Sid); 00241 00242 /* This routine calculates the generic size of the ACE needed. 00243 If no objects are present it is assumed that only a standard 00244 ACE is to be created. */ 00245 00246 if (ObjectsPresent & ACE_OBJECT_TYPE_PRESENT) 00247 Ret += sizeof(GUID); 00248 if (ObjectsPresent & ACE_INHERITED_OBJECT_TYPE_PRESENT) 00249 Ret += sizeof(GUID); 00250 00251 if (ObjectsPresent != 0) 00252 Ret += sizeof(DWORD); /* Include the Flags member to make it an object ACE */ 00253 00254 return Ret; 00255 } 00256 00257 static GUID* 00258 AccpGetObjectAceObjectType(IN PACE_HEADER AceHeader) 00259 { 00260 GUID *ObjectType = NULL; 00261 00262 switch (AceHeader->AceType) 00263 { 00264 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE: 00265 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE: 00266 { 00267 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace = (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE)AceHeader; 00268 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 00269 ObjectType = &Ace->ObjectType; 00270 break; 00271 } 00272 case ACCESS_ALLOWED_OBJECT_ACE_TYPE: 00273 case ACCESS_DENIED_OBJECT_ACE_TYPE: 00274 { 00275 PACCESS_ALLOWED_OBJECT_ACE Ace = (PACCESS_ALLOWED_OBJECT_ACE)AceHeader; 00276 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 00277 ObjectType = &Ace->ObjectType; 00278 break; 00279 } 00280 00281 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE: 00282 { 00283 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace = (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE)AceHeader; 00284 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 00285 ObjectType = &Ace->ObjectType; 00286 break; 00287 } 00288 case SYSTEM_AUDIT_OBJECT_ACE_TYPE: 00289 { 00290 PSYSTEM_AUDIT_OBJECT_ACE Ace = (PSYSTEM_AUDIT_OBJECT_ACE)AceHeader; 00291 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 00292 ObjectType = &Ace->ObjectType; 00293 break; 00294 } 00295 } 00296 00297 return ObjectType; 00298 } 00299 00300 static GUID* 00301 AccpGetObjectAceInheritedObjectType(IN PACE_HEADER AceHeader) 00302 { 00303 GUID *ObjectType = NULL; 00304 00305 switch (AceHeader->AceType) 00306 { 00307 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE: 00308 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE: 00309 { 00310 PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace = (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE)AceHeader; 00311 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) 00312 { 00313 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 00314 ObjectType = &Ace->InheritedObjectType; 00315 else 00316 ObjectType = &Ace->ObjectType; 00317 } 00318 break; 00319 } 00320 case ACCESS_ALLOWED_OBJECT_ACE_TYPE: 00321 case ACCESS_DENIED_OBJECT_ACE_TYPE: 00322 { 00323 PACCESS_ALLOWED_OBJECT_ACE Ace = (PACCESS_ALLOWED_OBJECT_ACE)AceHeader; 00324 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) 00325 { 00326 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 00327 ObjectType = &Ace->InheritedObjectType; 00328 else 00329 ObjectType = &Ace->ObjectType; 00330 } 00331 break; 00332 } 00333 00334 case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE: 00335 { 00336 PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace = (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE)AceHeader; 00337 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) 00338 { 00339 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 00340 ObjectType = &Ace->InheritedObjectType; 00341 else 00342 ObjectType = &Ace->ObjectType; 00343 } 00344 break; 00345 } 00346 case SYSTEM_AUDIT_OBJECT_ACE_TYPE: 00347 { 00348 PSYSTEM_AUDIT_OBJECT_ACE Ace = (PSYSTEM_AUDIT_OBJECT_ACE)AceHeader; 00349 if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) 00350 { 00351 if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT) 00352 ObjectType = &Ace->InheritedObjectType; 00353 else 00354 ObjectType = &Ace->ObjectType; 00355 } 00356 break; 00357 } 00358 } 00359 00360 return ObjectType; 00361 } 00362 00363 static DWORD 00364 AccpOpenLSAPolicyHandle(IN LPWSTR SystemName, 00365 IN ACCESS_MASK DesiredAccess, 00366 OUT PLSA_HANDLE pPolicyHandle) 00367 { 00368 LSA_OBJECT_ATTRIBUTES LsaObjectAttributes = {0}; 00369 LSA_UNICODE_STRING LsaSystemName, *psn; 00370 NTSTATUS Status; 00371 00372 if (SystemName != NULL && SystemName[0] != L'\0') 00373 { 00374 LsaSystemName.Buffer = SystemName; 00375 LsaSystemName.Length = wcslen(SystemName) * sizeof(WCHAR); 00376 LsaSystemName.MaximumLength = LsaSystemName.Length + sizeof(WCHAR); 00377 psn = &LsaSystemName; 00378 } 00379 else 00380 { 00381 psn = NULL; 00382 } 00383 00384 Status = LsaOpenPolicy(psn, 00385 &LsaObjectAttributes, 00386 DesiredAccess, 00387 pPolicyHandle); 00388 if (!NT_SUCCESS(Status)) 00389 return LsaNtStatusToWinError(Status); 00390 00391 return ERROR_SUCCESS; 00392 } 00393 00394 static LPWSTR 00395 AccpGetTrusteeName(IN PTRUSTEE_W Trustee) 00396 { 00397 switch (Trustee->TrusteeForm) 00398 { 00399 case TRUSTEE_IS_NAME: 00400 return Trustee->ptstrName; 00401 00402 case TRUSTEE_IS_OBJECTS_AND_NAME: 00403 return ((POBJECTS_AND_NAME_W)Trustee->ptstrName)->ptstrName; 00404 00405 default: 00406 return NULL; 00407 } 00408 } 00409 00410 static DWORD 00411 AccpLookupSidByName(IN LSA_HANDLE PolicyHandle, 00412 IN LPWSTR Name, 00413 OUT PSID *pSid) 00414 { 00415 NTSTATUS Status; 00416 LSA_UNICODE_STRING LsaNames[1]; 00417 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomains = NULL; 00418 PLSA_TRANSLATED_SID2 TranslatedSid = NULL; 00419 DWORD SidLen; 00420 DWORD Ret = ERROR_SUCCESS; 00421 00422 LsaNames[0].Buffer = Name; 00423 LsaNames[0].Length = wcslen(Name) * sizeof(WCHAR); 00424 LsaNames[0].MaximumLength = LsaNames[0].Length + sizeof(WCHAR); 00425 00426 Status = LsaLookupNames2(PolicyHandle, 00427 0, 00428 sizeof(LsaNames) / sizeof(LsaNames[0]), 00429 LsaNames, 00430 &ReferencedDomains, 00431 &TranslatedSid); 00432 00433 if (!NT_SUCCESS(Status)) 00434 return LsaNtStatusToWinError(Status); 00435 00436 if (TranslatedSid->Use == SidTypeUnknown || TranslatedSid->Use == SidTypeInvalid) 00437 { 00438 Ret = LsaNtStatusToWinError(STATUS_NONE_MAPPED); /* FIXME- what error code? */ 00439 goto Cleanup; 00440 } 00441 00442 SidLen = GetLengthSid(TranslatedSid->Sid); 00443 ASSERT(SidLen != 0); 00444 00445 *pSid = LocalAlloc(LMEM_FIXED, (SIZE_T)SidLen); 00446 if (*pSid != NULL) 00447 { 00448 if (!CopySid(SidLen, 00449 *pSid, 00450 TranslatedSid->Sid)) 00451 { 00452 Ret = GetLastError(); 00453 00454 LocalFree((HLOCAL)*pSid); 00455 *pSid = NULL; 00456 } 00457 } 00458 else 00459 Ret = ERROR_NOT_ENOUGH_MEMORY; 00460 00461 Cleanup: 00462 LsaFreeMemory(ReferencedDomains); 00463 LsaFreeMemory(TranslatedSid); 00464 00465 return Ret; 00466 } 00467 00468 00469 static DWORD 00470 AccpGetTrusteeSid(IN PTRUSTEE_W Trustee, 00471 IN OUT PLSA_HANDLE pPolicyHandle, 00472 OUT PSID *ppSid, 00473 OUT BOOL *Allocated) 00474 { 00475 DWORD Ret = ERROR_SUCCESS; 00476 00477 *ppSid = NULL; 00478 *Allocated = FALSE; 00479 00480 if (Trustee->pMultipleTrustee || Trustee->MultipleTrusteeOperation != NO_MULTIPLE_TRUSTEE) 00481 { 00482 /* This is currently not supported */ 00483 return ERROR_INVALID_PARAMETER; 00484 } 00485 00486 switch (Trustee->TrusteeForm) 00487 { 00488 case TRUSTEE_IS_OBJECTS_AND_NAME: 00489 if (((POBJECTS_AND_NAME_W)Trustee->ptstrName)->ObjectsPresent != 0) 00490 { 00491 /* This is not supported as there is no way to interpret the 00492 strings provided, and we need GUIDs for the ACEs... */ 00493 Ret = ERROR_INVALID_PARAMETER; 00494 break; 00495 } 00496 /* fall through */ 00497 00498 case TRUSTEE_IS_NAME: 00499 if (*pPolicyHandle == NULL) 00500 { 00501 Ret = AccpOpenLSAPolicyHandle(NULL, /* FIXME - always local? */ 00502 POLICY_LOOKUP_NAMES, 00503 pPolicyHandle); 00504 if (Ret != ERROR_SUCCESS) 00505 return Ret; 00506 00507 ASSERT(*pPolicyHandle != NULL); 00508 } 00509 00510 Ret = AccpLookupSidByName(*pPolicyHandle, 00511 AccpGetTrusteeName(Trustee), 00512 ppSid); 00513 if (Ret == ERROR_SUCCESS) 00514 { 00515 ASSERT(*ppSid != NULL); 00516 *Allocated = TRUE; 00517 } 00518 break; 00519 00520 case TRUSTEE_IS_OBJECTS_AND_SID: 00521 *ppSid = ((POBJECTS_AND_SID)Trustee->ptstrName)->pSid; 00522 break; 00523 00524 case TRUSTEE_IS_SID: 00525 *ppSid = (PSID)Trustee->ptstrName; 00526 break; 00527 00528 default: 00529 Ret = ERROR_INVALID_PARAMETER; 00530 break; 00531 } 00532 00533 return Ret; 00534 } 00535 00536 00537 /********************************************************************** 00538 * AccRewriteGetHandleRights EXPORTED 00539 * 00540 * @unimplemented 00541 */ 00542 DWORD WINAPI 00543 AccRewriteGetHandleRights(HANDLE handle, 00544 SE_OBJECT_TYPE ObjectType, 00545 SECURITY_INFORMATION SecurityInfo, 00546 PSID* ppsidOwner, 00547 PSID* ppsidGroup, 00548 PACL* ppDacl, 00549 PACL* ppSacl, 00550 PSECURITY_DESCRIPTOR* ppSecurityDescriptor) 00551 { 00552 PSECURITY_DESCRIPTOR pSD = NULL; 00553 ULONG SDSize = 0; 00554 NTSTATUS Status; 00555 DWORD LastErr; 00556 DWORD Ret; 00557 00558 /* save the last error code */ 00559 LastErr = GetLastError(); 00560 00561 do 00562 { 00563 Ret = ERROR_SUCCESS; 00564 00565 /* allocate a buffer large enough to hold the 00566 security descriptor we need to return */ 00567 SDSize += 0x100; 00568 if (pSD == NULL) 00569 { 00570 pSD = LocalAlloc(LMEM_FIXED, 00571 (SIZE_T)SDSize); 00572 } 00573 else 00574 { 00575 PSECURITY_DESCRIPTOR newSD; 00576 00577 newSD = LocalReAlloc((HLOCAL)pSD, 00578 (SIZE_T)SDSize, 00579 LMEM_MOVEABLE); 00580 if (newSD != NULL) 00581 pSD = newSD; 00582 } 00583 00584 if (pSD == NULL) 00585 { 00586 Ret = GetLastError(); 00587 break; 00588 } 00589 00590 /* perform the actual query depending on the object type */ 00591 switch (ObjectType) 00592 { 00593 case SE_REGISTRY_KEY: 00594 { 00595 Ret = (DWORD)RegGetKeySecurity((HKEY)handle, 00596 SecurityInfo, 00597 pSD, 00598 &SDSize); 00599 break; 00600 } 00601 00602 case SE_FILE_OBJECT: 00603 /* FIXME - handle console handles? */ 00604 case SE_KERNEL_OBJECT: 00605 { 00606 Status = NtQuerySecurityObject(handle, 00607 SecurityInfo, 00608 pSD, 00609 SDSize, 00610 &SDSize); 00611 if (!NT_SUCCESS(Status)) 00612 { 00613 Ret = RtlNtStatusToDosError(Status); 00614 } 00615 break; 00616 } 00617 00618 case SE_SERVICE: 00619 { 00620 if (!QueryServiceObjectSecurity((SC_HANDLE)handle, 00621 SecurityInfo, 00622 pSD, 00623 SDSize, 00624 &SDSize)) 00625 { 00626 Ret = GetLastError(); 00627 } 00628 break; 00629 } 00630 00631 case SE_WINDOW_OBJECT: 00632 { 00633 if (!GetUserObjectSecurity(handle, 00634 &SecurityInfo, 00635 pSD, 00636 SDSize, 00637 &SDSize)) 00638 { 00639 Ret = GetLastError(); 00640 } 00641 break; 00642 } 00643 00644 default: 00645 { 00646 UNIMPLEMENTED; 00647 Ret = ERROR_CALL_NOT_IMPLEMENTED; 00648 break; 00649 } 00650 } 00651 00652 } while (Ret == ERROR_INSUFFICIENT_BUFFER); 00653 00654 if (Ret == ERROR_SUCCESS) 00655 { 00656 BOOL Present, Defaulted; 00657 00658 if (SecurityInfo & OWNER_SECURITY_INFORMATION && ppsidOwner != NULL) 00659 { 00660 *ppsidOwner = NULL; 00661 if (!GetSecurityDescriptorOwner(pSD, 00662 ppsidOwner, 00663 &Defaulted)) 00664 { 00665 Ret = GetLastError(); 00666 goto Cleanup; 00667 } 00668 } 00669 00670 if (SecurityInfo & GROUP_SECURITY_INFORMATION && ppsidGroup != NULL) 00671 { 00672 *ppsidOwner = NULL; 00673 if (!GetSecurityDescriptorGroup(pSD, 00674 ppsidGroup, 00675 &Defaulted)) 00676 { 00677 Ret = GetLastError(); 00678 goto Cleanup; 00679 } 00680 } 00681 00682 if (SecurityInfo & DACL_SECURITY_INFORMATION && ppDacl != NULL) 00683 { 00684 *ppDacl = NULL; 00685 if (!GetSecurityDescriptorDacl(pSD, 00686 &Present, 00687 ppDacl, 00688 &Defaulted)) 00689 { 00690 Ret = GetLastError(); 00691 goto Cleanup; 00692 } 00693 } 00694 00695 if (SecurityInfo & SACL_SECURITY_INFORMATION && ppSacl != NULL) 00696 { 00697 *ppSacl = NULL; 00698 if (!GetSecurityDescriptorSacl(pSD, 00699 &Present, 00700 ppSacl, 00701 &Defaulted)) 00702 { 00703 Ret = GetLastError(); 00704 goto Cleanup; 00705 } 00706 } 00707 00708 *ppSecurityDescriptor = pSD; 00709 } 00710 else 00711 { 00712 Cleanup: 00713 if (pSD != NULL) 00714 { 00715 LocalFree((HLOCAL)pSD); 00716 } 00717 } 00718 00719 /* restore the last error code */ 00720 SetLastError(LastErr); 00721 00722 return Ret; 00723 } 00724 00725 00726 /********************************************************************** 00727 * AccRewriteSetHandleRights EXPORTED 00728 * 00729 * @unimplemented 00730 */ 00731 DWORD WINAPI 00732 AccRewriteSetHandleRights(HANDLE handle, 00733 SE_OBJECT_TYPE ObjectType, 00734 SECURITY_INFORMATION SecurityInfo, 00735 PSECURITY_DESCRIPTOR pSecurityDescriptor) 00736 { 00737 NTSTATUS Status; 00738 DWORD LastErr; 00739 DWORD Ret = ERROR_SUCCESS; 00740 00741 /* save the last error code */ 00742 LastErr = GetLastError(); 00743 00744 /* set the security according to the object type */ 00745 switch (ObjectType) 00746 { 00747 case SE_REGISTRY_KEY: 00748 { 00749 Ret = (DWORD)RegSetKeySecurity((HKEY)handle, 00750 SecurityInfo, 00751 pSecurityDescriptor); 00752 break; 00753 } 00754 00755 case SE_FILE_OBJECT: 00756 /* FIXME - handle console handles? */ 00757 case SE_KERNEL_OBJECT: 00758 { 00759 Status = NtSetSecurityObject(handle, 00760 SecurityInfo, 00761 pSecurityDescriptor); 00762 if (!NT_SUCCESS(Status)) 00763 { 00764 Ret = RtlNtStatusToDosError(Status); 00765 } 00766 break; 00767 } 00768 00769 case SE_SERVICE: 00770 { 00771 if (!SetServiceObjectSecurity((SC_HANDLE)handle, 00772 SecurityInfo, 00773 pSecurityDescriptor)) 00774 { 00775 Ret = GetLastError(); 00776 } 00777 break; 00778 } 00779 00780 case SE_WINDOW_OBJECT: 00781 { 00782 if (!SetUserObjectSecurity(handle, 00783 &SecurityInfo, 00784 pSecurityDescriptor)) 00785 { 00786 Ret = GetLastError(); 00787 } 00788 break; 00789 } 00790 00791 default: 00792 { 00793 UNIMPLEMENTED; 00794 Ret = ERROR_CALL_NOT_IMPLEMENTED; 00795 break; 00796 } 00797 } 00798 00799 00800 /* restore the last error code */ 00801 SetLastError(LastErr); 00802 00803 return Ret; 00804 } 00805 00806 00807 static DWORD 00808 AccpOpenNamedObject(LPWSTR pObjectName, 00809 SE_OBJECT_TYPE ObjectType, 00810 SECURITY_INFORMATION SecurityInfo, 00811 PHANDLE Handle, 00812 PHANDLE Handle2, 00813 BOOL Write) 00814 { 00815 LPWSTR lpPath; 00816 NTSTATUS Status; 00817 ACCESS_MASK DesiredAccess = (ACCESS_MASK)0; 00818 DWORD Ret = ERROR_SUCCESS; 00819 00820 /* determine the required access rights */ 00821 switch (ObjectType) 00822 { 00823 case SE_REGISTRY_KEY: 00824 case SE_FILE_OBJECT: 00825 case SE_KERNEL_OBJECT: 00826 case SE_SERVICE: 00827 case SE_WINDOW_OBJECT: 00828 if (Write) 00829 { 00830 SetSecurityAccessMask(SecurityInfo, 00831 (PDWORD)&DesiredAccess); 00832 } 00833 else 00834 { 00835 QuerySecurityAccessMask(SecurityInfo, 00836 (PDWORD)&DesiredAccess); 00837 } 00838 break; 00839 00840 default: 00841 break; 00842 } 00843 00844 /* make a copy of the path if we're modifying the string */ 00845 switch (ObjectType) 00846 { 00847 case SE_REGISTRY_KEY: 00848 case SE_SERVICE: 00849 lpPath = (LPWSTR)LocalAlloc(LMEM_FIXED, 00850 (wcslen(pObjectName) + 1) * sizeof(WCHAR)); 00851 if (lpPath == NULL) 00852 { 00853 Ret = GetLastError(); 00854 goto Cleanup; 00855 } 00856 00857 wcscpy(lpPath, 00858 pObjectName); 00859 break; 00860 00861 default: 00862 lpPath = pObjectName; 00863 break; 00864 } 00865 00866 /* open a handle to the path depending on the object type */ 00867 switch (ObjectType) 00868 { 00869 case SE_FILE_OBJECT: 00870 { 00871 IO_STATUS_BLOCK IoStatusBlock; 00872 OBJECT_ATTRIBUTES ObjectAttributes; 00873 UNICODE_STRING FileName; 00874 00875 if (!RtlDosPathNameToNtPathName_U(pObjectName, 00876 &FileName, 00877 NULL, 00878 NULL)) 00879 { 00880 Ret = ERROR_INVALID_NAME; 00881 goto Cleanup; 00882 } 00883 00884 InitializeObjectAttributes(&ObjectAttributes, 00885 &FileName, 00886 OBJ_CASE_INSENSITIVE, 00887 NULL, 00888 NULL); 00889 00890 Status = NtOpenFile(Handle, 00891 DesiredAccess, 00892 &ObjectAttributes, 00893 &IoStatusBlock, 00894 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 00895 FILE_SYNCHRONOUS_IO_NONALERT); 00896 00897 RtlFreeHeap(RtlGetProcessHeap(), 00898 0, 00899 FileName.Buffer); 00900 00901 if (!NT_SUCCESS(Status)) 00902 { 00903 Ret = RtlNtStatusToDosError(Status); 00904 } 00905 break; 00906 } 00907 00908 case SE_REGISTRY_KEY: 00909 { 00910 static const struct 00911 { 00912 HKEY hRootKey; 00913 LPCWSTR szRootKey; 00914 } AccRegRootKeys[] = 00915 { 00916 {HKEY_CLASSES_ROOT, L"CLASSES_ROOT"}, 00917 {HKEY_CURRENT_USER, L"CURRENT_USER"}, 00918 {HKEY_LOCAL_MACHINE, L"MACHINE"}, 00919 {HKEY_USERS, L"USERS"}, 00920 {HKEY_CURRENT_CONFIG, L"CONFIG"}, 00921 }; 00922 LPWSTR lpMachineName, lpRootKeyName, lpKeyName; 00923 HKEY hRootKey = NULL; 00924 UINT i; 00925 00926 /* parse the registry path */ 00927 if (lpPath[0] == L'\\' && lpPath[1] == L'\\') 00928 { 00929 lpMachineName = lpPath; 00930 00931 lpRootKeyName = wcschr(lpPath + 2, 00932 L'\\'); 00933 if (lpRootKeyName == NULL) 00934 goto ParseRegErr; 00935 else 00936 *(lpRootKeyName++) = L'\0'; 00937 } 00938 else 00939 { 00940 lpMachineName = NULL; 00941 lpRootKeyName = lpPath; 00942 } 00943 00944 lpKeyName = wcschr(lpRootKeyName, 00945 L'\\'); 00946 if (lpKeyName != NULL) 00947 { 00948 *(lpKeyName++) = L'\0'; 00949 } 00950 00951 for (i = 0; 00952 i != sizeof(AccRegRootKeys) / sizeof(AccRegRootKeys[0]); 00953 i++) 00954 { 00955 if (!wcsicmp(lpRootKeyName, 00956 AccRegRootKeys[i].szRootKey)) 00957 { 00958 hRootKey = AccRegRootKeys[i].hRootKey; 00959 break; 00960 } 00961 } 00962 00963 if (hRootKey == NULL) 00964 { 00965 ParseRegErr: 00966 /* FIXME - right error code? */ 00967 Ret = ERROR_INVALID_PARAMETER; 00968 goto Cleanup; 00969 } 00970 00971 /* open the registry key */ 00972 if (lpMachineName != NULL) 00973 { 00974 Ret = RegConnectRegistry(lpMachineName, 00975 hRootKey, 00976 (PHKEY)Handle2); 00977 00978 if (Ret != ERROR_SUCCESS) 00979 goto Cleanup; 00980 00981 hRootKey = (HKEY)(*Handle2); 00982 } 00983 00984 Ret = RegOpenKeyEx(hRootKey, 00985 lpKeyName, 00986 0, 00987 (REGSAM)DesiredAccess, 00988 (PHKEY)Handle); 00989 if (Ret != ERROR_SUCCESS) 00990 { 00991 if (*Handle2 != NULL) 00992 { 00993 RegCloseKey((HKEY)(*Handle2)); 00994 } 00995 00996 goto Cleanup; 00997 } 00998 break; 00999 } 01000 01001 case SE_SERVICE: 01002 { 01003 LPWSTR lpServiceName, lpMachineName; 01004 01005 /* parse the service path */ 01006 if (lpPath[0] == L'\\' && lpPath[1] == L'\\') 01007 { 01008 DesiredAccess |= SC_MANAGER_CONNECT; 01009 01010 lpMachineName = lpPath; 01011 01012 lpServiceName = wcschr(lpPath + 2, 01013 L'\\'); 01014 if (lpServiceName == NULL) 01015 { 01016 /* FIXME - right error code? */ 01017 Ret = ERROR_INVALID_PARAMETER; 01018 goto Cleanup; 01019 } 01020 else 01021 *(lpServiceName++) = L'\0'; 01022 } 01023 else 01024 { 01025 lpMachineName = NULL; 01026 lpServiceName = lpPath; 01027 } 01028 01029 /* open the service */ 01030 *Handle2 = (HANDLE)OpenSCManager(lpMachineName, 01031 NULL, 01032 (DWORD)DesiredAccess); 01033 if (*Handle2 == NULL) 01034 { 01035 goto FailOpenService; 01036 } 01037 01038 DesiredAccess &= ~SC_MANAGER_CONNECT; 01039 *Handle = (HANDLE)OpenService((SC_HANDLE)(*Handle2), 01040 lpServiceName, 01041 (DWORD)DesiredAccess); 01042 if (*Handle == NULL) 01043 { 01044 if (*Handle2 != NULL) 01045 { 01046 CloseServiceHandle((SC_HANDLE)(*Handle2)); 01047 } 01048 01049 FailOpenService: 01050 Ret = GetLastError(); 01051 goto Cleanup; 01052 } 01053 break; 01054 } 01055 01056 default: 01057 { 01058 UNIMPLEMENTED; 01059 Ret = ERROR_CALL_NOT_IMPLEMENTED; 01060 break; 01061 } 01062 } 01063 01064 Cleanup: 01065 if (lpPath != NULL && lpPath != pObjectName) 01066 { 01067 LocalFree((HLOCAL)lpPath); 01068 } 01069 01070 return Ret; 01071 } 01072 01073 01074 static VOID 01075 AccpCloseObjectHandle(SE_OBJECT_TYPE ObjectType, 01076 HANDLE Handle, 01077 HANDLE Handle2) 01078 { 01079 ASSERT(Handle != NULL); 01080 01081 /* close allocated handlees depending on the object type */ 01082 switch (ObjectType) 01083 { 01084 case SE_REGISTRY_KEY: 01085 RegCloseKey((HKEY)Handle); 01086 if (Handle2 != NULL) 01087 RegCloseKey((HKEY)Handle2); 01088 break; 01089 01090 case SE_FILE_OBJECT: 01091 NtClose(Handle); 01092 break; 01093 01094 case SE_KERNEL_OBJECT: 01095 case SE_WINDOW_OBJECT: 01096 CloseHandle(Handle); 01097 break; 01098 01099 case SE_SERVICE: 01100 CloseServiceHandle((SC_HANDLE)Handle); 01101 ASSERT(Handle2 != NULL); 01102 CloseServiceHandle((SC_HANDLE)Handle2); 01103 break; 01104 01105 default: 01106 break; 01107 } 01108 } 01109 01110 01111 /********************************************************************** 01112 * AccRewriteGetNamedRights EXPORTED 01113 * 01114 * @unimplemented 01115 */ 01116 DWORD WINAPI 01117 AccRewriteGetNamedRights(LPWSTR pObjectName, 01118 SE_OBJECT_TYPE ObjectType, 01119 SECURITY_INFORMATION SecurityInfo, 01120 PSID* ppsidOwner, 01121 PSID* ppsidGroup, 01122 PACL* ppDacl, 01123 PACL* ppSacl, 01124 PSECURITY_DESCRIPTOR* ppSecurityDescriptor) 01125 { 01126 HANDLE Handle = NULL; 01127 HANDLE Handle2 = NULL; 01128 DWORD LastErr; 01129 DWORD Ret; 01130 01131 /* save the last error code */ 01132 LastErr = GetLastError(); 01133 01134 /* create the handle */ 01135 Ret = AccpOpenNamedObject(pObjectName, 01136 ObjectType, 01137 SecurityInfo, 01138 &Handle, 01139 &Handle2, 01140 FALSE); 01141 01142 if (Ret == ERROR_SUCCESS) 01143 { 01144 ASSERT(Handle != NULL); 01145 01146 /* perform the operation */ 01147 Ret = AccRewriteGetHandleRights(Handle, 01148 ObjectType, 01149 SecurityInfo, 01150 ppsidOwner, 01151 ppsidGroup, 01152 ppDacl, 01153 ppSacl, 01154 ppSecurityDescriptor); 01155 01156 /* close opened handles */ 01157 AccpCloseObjectHandle(ObjectType, 01158 Handle, 01159 Handle2); 01160 } 01161 01162 /* restore the last error code */ 01163 SetLastError(LastErr); 01164 01165 return Ret; 01166 } 01167 01168 01169 /********************************************************************** 01170 * AccRewriteSetNamedRights EXPORTED 01171 * 01172 * @unimplemented 01173 */ 01174 DWORD WINAPI 01175 AccRewriteSetNamedRights(LPWSTR pObjectName, 01176 SE_OBJECT_TYPE ObjectType, 01177 SECURITY_INFORMATION SecurityInfo, 01178 PSECURITY_DESCRIPTOR pSecurityDescriptor) 01179 { 01180 HANDLE Handle = NULL; 01181 HANDLE Handle2 = NULL; 01182 DWORD LastErr; 01183 DWORD Ret; 01184 01185 /* save the last error code */ 01186 LastErr = GetLastError(); 01187 01188 /* create the handle */ 01189 Ret = AccpOpenNamedObject(pObjectName, 01190 ObjectType, 01191 SecurityInfo, 01192 &Handle, 01193 &Handle2, 01194 TRUE); 01195 01196 if (Ret == ERROR_SUCCESS) 01197 { 01198 ASSERT(Handle != NULL); 01199 01200 /* perform the operation */ 01201 Ret = AccRewriteSetHandleRights(Handle, 01202 ObjectType, 01203 SecurityInfo, 01204 pSecurityDescriptor); 01205 01206 /* close opened handles */ 01207 AccpCloseObjectHandle(ObjectType, 01208 Handle, 01209 Handle2); 01210 } 01211 01212 /* restore the last error code */ 01213 SetLastError(LastErr); 01214 01215 return Ret; 01216 } 01217 01218 01219 /********************************************************************** 01220 * AccRewriteSetEntriesInAcl EXPORTED 01221 * 01222 * @implemented 01223 */ 01224 DWORD WINAPI 01225 AccRewriteSetEntriesInAcl(ULONG cCountOfExplicitEntries, 01226 PEXPLICIT_ACCESS_W pListOfExplicitEntries, 01227 PACL OldAcl, 01228 PACL* NewAcl) 01229 { 01230 PACL pNew = NULL; 01231 ACL_SIZE_INFORMATION SizeInformation; 01232 PACE_HEADER pAce; 01233 BOOLEAN KeepAceBuf[8]; 01234 BOOLEAN *pKeepAce = NULL; 01235 GUID ObjectTypeGuid, InheritedObjectTypeGuid; 01236 DWORD ObjectsPresent; 01237 BOOL needToClean; 01238 PSID pSid1, pSid2; 01239 ULONG i, j; 01240 LSA_HANDLE PolicyHandle = NULL; 01241 BOOL bRet; 01242 DWORD LastErr; 01243 DWORD Ret = ERROR_SUCCESS; 01244 01245 /* save the last error code */ 01246 LastErr = GetLastError(); 01247 01248 *NewAcl = NULL; 01249 01250 /* Get information about previous ACL */ 01251 if (OldAcl) 01252 { 01253 if (!GetAclInformation(OldAcl, &SizeInformation, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation)) 01254 { 01255 Ret = GetLastError(); 01256 goto Cleanup; 01257 } 01258 01259 if (SizeInformation.AceCount > sizeof(KeepAceBuf) / sizeof(KeepAceBuf[0])) 01260 { 01261 pKeepAce = (BOOLEAN *)LocalAlloc(LMEM_FIXED, SizeInformation.AceCount * sizeof(*pKeepAce)); 01262 if (!pKeepAce) 01263 { 01264 Ret = ERROR_NOT_ENOUGH_MEMORY; 01265 goto Cleanup; 01266 } 01267 } 01268 else 01269 pKeepAce = KeepAceBuf; 01270 01271 memset(pKeepAce, TRUE, SizeInformation.AceCount * sizeof(*pKeepAce)); 01272 } 01273 else 01274 { 01275 ZeroMemory(&SizeInformation, sizeof(ACL_SIZE_INFORMATION)); 01276 SizeInformation.AclBytesInUse = sizeof(ACL); 01277 } 01278 01279 /* Get size required for new entries */ 01280 for (i = 0; i < cCountOfExplicitEntries; i++) 01281 { 01282 Ret = AccpGetTrusteeSid(&pListOfExplicitEntries[i].Trustee, 01283 &PolicyHandle, 01284 &pSid1, 01285 &needToClean); 01286 if (Ret != ERROR_SUCCESS) 01287 goto Cleanup; 01288 01289 ObjectsPresent = AccpGetTrusteeObjects(&pListOfExplicitEntries[i].Trustee, 01290 NULL, 01291 NULL); 01292 01293 switch (pListOfExplicitEntries[i].grfAccessMode) 01294 { 01295 case REVOKE_ACCESS: 01296 case SET_ACCESS: 01297 /* Discard all accesses for the trustee... */ 01298 for (j = 0; j < SizeInformation.AceCount; j++) 01299 { 01300 if (!pKeepAce[j]) 01301 continue; 01302 if (!GetAce(OldAcl, j, (PVOID*)&pAce)) 01303 { 01304 Ret = GetLastError(); 01305 goto Cleanup; 01306 } 01307 01308 pSid2 = AccpGetAceSid(pAce); 01309 if (RtlEqualSid(pSid1, pSid2)) 01310 { 01311 pKeepAce[j] = FALSE; 01312 SizeInformation.AclBytesInUse -= pAce->AceSize; 01313 } 01314 } 01315 if (pListOfExplicitEntries[i].grfAccessMode == REVOKE_ACCESS) 01316 break; 01317 /* ...and replace by the current access */ 01318 case GRANT_ACCESS: 01319 case DENY_ACCESS: 01320 /* Add to ACL */ 01321 SizeInformation.AclBytesInUse += AccpCalcNeededAceSize(pSid1, ObjectsPresent); 01322 break; 01323 case SET_AUDIT_SUCCESS: 01324 case SET_AUDIT_FAILURE: 01325 /* FIXME */ 01326 DPRINT1("Case not implemented!\n"); 01327 break; 01328 default: 01329 DPRINT1("Unknown access mode 0x%x. Ignoring it\n", pListOfExplicitEntries[i].grfAccessMode); 01330 break; 01331 } 01332 01333 if (needToClean) 01334 LocalFree((HLOCAL)pSid1); 01335 } 01336 01337 /* OK, now create the new ACL */ 01338 DPRINT("Allocating %u bytes for the new ACL\n", SizeInformation.AclBytesInUse); 01339 pNew = (PACL)LocalAlloc(LMEM_FIXED, SizeInformation.AclBytesInUse); 01340 if (!pNew) 01341 { 01342 Ret = ERROR_NOT_ENOUGH_MEMORY; 01343 goto Cleanup; 01344 } 01345 if (!InitializeAcl(pNew, SizeInformation.AclBytesInUse, ACL_REVISION)) 01346 { 01347 Ret = GetLastError(); 01348 goto Cleanup; 01349 } 01350 01351 /* Fill it */ 01352 /* 1a) New audit entries (SET_AUDIT_SUCCESS, SET_AUDIT_FAILURE) */ 01353 /* FIXME */ 01354 01355 /* 1b) Existing audit entries */ 01356 /* FIXME */ 01357 01358 /* 2a) New denied entries (DENY_ACCESS) */ 01359 for (i = 0; i < cCountOfExplicitEntries; i++) 01360 { 01361 if (pListOfExplicitEntries[i].grfAccessMode == DENY_ACCESS) 01362 { 01363 /* FIXME: take care of pListOfExplicitEntries[i].grfInheritance */ 01364 Ret = AccpGetTrusteeSid(&pListOfExplicitEntries[i].Trustee, 01365 &PolicyHandle, 01366 &pSid1, 01367 &needToClean); 01368 if (Ret != ERROR_SUCCESS) 01369 goto Cleanup; 01370 01371 ObjectsPresent = AccpGetTrusteeObjects(&pListOfExplicitEntries[i].Trustee, 01372 &ObjectTypeGuid, 01373 &InheritedObjectTypeGuid); 01374 01375 if (ObjectsPresent == 0) 01376 { 01377 /* FIXME: Call AddAccessDeniedAceEx instead! */ 01378 bRet = AddAccessDeniedAce(pNew, ACL_REVISION, pListOfExplicitEntries[i].grfAccessPermissions, pSid1); 01379 } 01380 else 01381 { 01382 /* FIXME: Call AddAccessDeniedObjectAce */ 01383 DPRINT1("Object ACEs not yet supported!\n"); 01384 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 01385 bRet = FALSE; 01386 } 01387 01388 if (needToClean) LocalFree((HLOCAL)pSid1); 01389 if (!bRet) 01390 { 01391 Ret = GetLastError(); 01392 goto Cleanup; 01393 } 01394 } 01395 } 01396 01397 /* 2b) Existing denied entries */ 01398 /* FIXME */ 01399 01400 /* 3a) New allow entries (GRANT_ACCESS, SET_ACCESS) */ 01401 for (i = 0; i < cCountOfExplicitEntries; i++) 01402 { 01403 if (pListOfExplicitEntries[i].grfAccessMode == SET_ACCESS || 01404 pListOfExplicitEntries[i].grfAccessMode == GRANT_ACCESS) 01405 { 01406 /* FIXME: take care of pListOfExplicitEntries[i].grfInheritance */ 01407 Ret = AccpGetTrusteeSid(&pListOfExplicitEntries[i].Trustee, 01408 &PolicyHandle, 01409 &pSid1, 01410 &needToClean); 01411 if (Ret != ERROR_SUCCESS) 01412 goto Cleanup; 01413 01414 ObjectsPresent = AccpGetTrusteeObjects(&pListOfExplicitEntries[i].Trustee, 01415 &ObjectTypeGuid, 01416 &InheritedObjectTypeGuid); 01417 01418 if (ObjectsPresent == 0) 01419 { 01420 /* FIXME: Call AddAccessAllowedAceEx instead! */ 01421 bRet = AddAccessAllowedAce(pNew, ACL_REVISION, pListOfExplicitEntries[i].grfAccessPermissions, pSid1); 01422 } 01423 else 01424 { 01425 /* FIXME: Call AddAccessAllowedObjectAce */ 01426 DPRINT1("Object ACEs not yet supported!\n"); 01427 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 01428 bRet = FALSE; 01429 } 01430 01431 if (needToClean) LocalFree((HLOCAL)pSid1); 01432 if (!bRet) 01433 { 01434 Ret = GetLastError(); 01435 goto Cleanup; 01436 } 01437 } 01438 } 01439 01440 /* 3b) Existing allow entries */ 01441 /* FIXME */ 01442 01443 *NewAcl = pNew; 01444 01445 Cleanup: 01446 if (pKeepAce && pKeepAce != KeepAceBuf) 01447 LocalFree((HLOCAL)pKeepAce); 01448 01449 if (pNew && Ret != ERROR_SUCCESS) 01450 LocalFree((HLOCAL)pNew); 01451 01452 if (PolicyHandle) 01453 LsaClose(PolicyHandle); 01454 01455 /* restore the last error code */ 01456 SetLastError(LastErr); 01457 01458 return Ret; 01459 } 01460 01461 01462 /********************************************************************** 01463 * AccGetInheritanceSource EXPORTED 01464 * 01465 * @unimplemented 01466 */ 01467 DWORD WINAPI 01468 AccGetInheritanceSource(LPWSTR pObjectName, 01469 SE_OBJECT_TYPE ObjectType, 01470 SECURITY_INFORMATION SecurityInfo, 01471 BOOL Container, 01472 GUID** pObjectClassGuids, 01473 DWORD GuidCount, 01474 PACL pAcl, 01475 PFN_OBJECT_MGR_FUNCTS pfnArray, 01476 PGENERIC_MAPPING pGenericMapping, 01477 PINHERITED_FROMW pInheritArray) 01478 { 01479 UNIMPLEMENTED; 01480 return ERROR_CALL_NOT_IMPLEMENTED; 01481 } 01482 01483 01484 /********************************************************************** 01485 * AccFreeIndexArray EXPORTED 01486 * 01487 * @implemented 01488 */ 01489 DWORD WINAPI 01490 AccFreeIndexArray(PINHERITED_FROMW pInheritArray, 01491 USHORT AceCnt, 01492 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL) 01493 { 01494 PINHERITED_FROMW pLast; 01495 01496 UNREFERENCED_PARAMETER(pfnArray); 01497 01498 pLast = pInheritArray + AceCnt; 01499 while (pInheritArray != pLast) 01500 { 01501 if (pInheritArray->AncestorName != NULL) 01502 { 01503 LocalFree((HLOCAL)pInheritArray->AncestorName); 01504 pInheritArray->AncestorName = NULL; 01505 } 01506 01507 pInheritArray++; 01508 } 01509 01510 return ERROR_SUCCESS; 01511 } 01512 01513 01514 /********************************************************************** 01515 * AccRewriteGetExplicitEntriesFromAcl EXPORTED 01516 * 01517 * @implemented 01518 */ 01519 DWORD WINAPI 01520 AccRewriteGetExplicitEntriesFromAcl(PACL pacl, 01521 PULONG pcCountOfExplicitEntries, 01522 PEXPLICIT_ACCESS_W* pListOfExplicitEntries) 01523 { 01524 PACE_HEADER AceHeader; 01525 PSID Sid, SidTarget; 01526 ULONG ObjectAceCount = 0; 01527 POBJECTS_AND_SID ObjSid; 01528 SIZE_T Size; 01529 PEXPLICIT_ACCESS_W peaw; 01530 DWORD LastErr, SidLen; 01531 DWORD AceIndex = 0; 01532 DWORD ErrorCode = ERROR_SUCCESS; 01533 01534 /* save the last error code */ 01535 LastErr = GetLastError(); 01536 01537 if (pacl != NULL) 01538 { 01539 if (pacl->AceCount != 0) 01540 { 01541 Size = (SIZE_T)pacl->AceCount * sizeof(EXPLICIT_ACCESS_W); 01542 01543 /* calculate the space needed */ 01544 while (GetAce(pacl, 01545 AceIndex, 01546 (LPVOID*)&AceHeader)) 01547 { 01548 Sid = AccpGetAceSid(AceHeader); 01549 Size += GetLengthSid(Sid); 01550 01551 if (AccpIsObjectAce(AceHeader)) 01552 ObjectAceCount++; 01553 01554 AceIndex++; 01555 } 01556 01557 Size += ObjectAceCount * sizeof(OBJECTS_AND_SID); 01558 01559 ASSERT(pacl->AceCount == AceIndex); 01560 01561 /* allocate the array */ 01562 peaw = (PEXPLICIT_ACCESS_W)LocalAlloc(LMEM_FIXED, 01563 Size); 01564 if (peaw != NULL) 01565 { 01566 AceIndex = 0; 01567 ObjSid = (POBJECTS_AND_SID)(peaw + pacl->AceCount); 01568 SidTarget = (PSID)(ObjSid + ObjectAceCount); 01569 01570 /* initialize the array */ 01571 while (GetAce(pacl, 01572 AceIndex, 01573 (LPVOID*)&AceHeader)) 01574 { 01575 Sid = AccpGetAceSid(AceHeader); 01576 SidLen = GetLengthSid(Sid); 01577 01578 peaw[AceIndex].grfAccessPermissions = AccpGetAceAccessMask(AceHeader); 01579 peaw[AceIndex].grfAccessMode = AccpGetAceAccessMode(AceHeader); 01580 peaw[AceIndex].grfInheritance = AceHeader->AceFlags & VALID_INHERIT_FLAGS; 01581 01582 if (CopySid(SidLen, 01583 SidTarget, 01584 Sid)) 01585 { 01586 if (AccpIsObjectAce(AceHeader)) 01587 { 01588 BuildTrusteeWithObjectsAndSid(&peaw[AceIndex].Trustee, 01589 ObjSid++, 01590 AccpGetObjectAceObjectType(AceHeader), 01591 AccpGetObjectAceInheritedObjectType(AceHeader), 01592 SidTarget); 01593 } 01594 else 01595 { 01596 BuildTrusteeWithSid(&peaw[AceIndex].Trustee, 01597 SidTarget); 01598 } 01599 01600 SidTarget = (PSID)((ULONG_PTR)SidTarget + SidLen); 01601 } 01602 else 01603 { 01604 /* copying the SID failed, treat it as an fatal error... */ 01605 ErrorCode = GetLastError(); 01606 01607 /* free allocated resources */ 01608 LocalFree(peaw); 01609 peaw = NULL; 01610 AceIndex = 0; 01611 break; 01612 } 01613 01614 AceIndex++; 01615 } 01616 01617 *pcCountOfExplicitEntries = AceIndex; 01618 *pListOfExplicitEntries = peaw; 01619 } 01620 else 01621 ErrorCode = ERROR_NOT_ENOUGH_MEMORY; 01622 } 01623 else 01624 { 01625 goto EmptyACL; 01626 } 01627 } 01628 else 01629 { 01630 EmptyACL: 01631 *pcCountOfExplicitEntries = 0; 01632 *pListOfExplicitEntries = NULL; 01633 } 01634 01635 /* restore the last error code */ 01636 SetLastError(LastErr); 01637 01638 return ErrorCode; 01639 } 01640 01641 01642 /********************************************************************** 01643 * AccTreeResetNamedSecurityInfo EXPORTED 01644 * 01645 * @unimplemented 01646 */ 01647 DWORD WINAPI 01648 AccTreeResetNamedSecurityInfo(LPWSTR pObjectName, 01649 SE_OBJECT_TYPE ObjectType, 01650 SECURITY_INFORMATION SecurityInfo, 01651 PSID pOwner, 01652 PSID pGroup, 01653 PACL pDacl, 01654 PACL pSacl, 01655 BOOL KeepExplicit, 01656 FN_PROGRESSW fnProgress, 01657 PROG_INVOKE_SETTING ProgressInvokeSetting, 01658 PVOID Args) 01659 { 01660 UNIMPLEMENTED; 01661 return ERROR_CALL_NOT_IMPLEMENTED; 01662 } 01663 01664 01665 BOOL WINAPI 01666 DllMain(IN HINSTANCE hinstDLL, 01667 IN DWORD dwReason, 01668 IN LPVOID lpvReserved) 01669 { 01670 switch (dwReason) 01671 { 01672 case DLL_PROCESS_ATTACH: 01673 hDllInstance = hinstDLL; 01674 DisableThreadLibraryCalls(hinstDLL); 01675 break; 01676 01677 case DLL_PROCESS_DETACH: 01678 break; 01679 } 01680 return TRUE; 01681 } 01682 Generated on Sat May 26 2012 04:24:03 for ReactOS by
1.7.6.1
|