ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ntmarta.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.