bug 1467 : patch from w3seek, ACLs: Implement audit functions
authorMagnus Olsen <magnus@greatlord.com>
Wed, 10 May 2006 09:32:23 +0000 (09:32 +0000)
committerMagnus Olsen <magnus@greatlord.com>
Wed, 10 May 2006 09:32:23 +0000 (09:32 +0000)
svn path=/trunk/; revision=21875

reactos/dll/ntdll/def/ntdll.def
reactos/dll/win32/advapi32/advapi32.h
reactos/dll/win32/advapi32/sec/ac.c
reactos/dll/win32/advapi32/sec/sec.c
reactos/dll/win32/ntmarta/ntmarta.c
reactos/include/ndk/rtlfuncs.h
reactos/include/winnt.h
reactos/lib/rtl/acl.c

index ef3b141..feca2d3 100644 (file)
@@ -292,14 +292,17 @@ RtlAcquireResourceExclusive@8
 RtlAcquireResourceShared@8
 RtlAddAccessAllowedAce@16
 RtlAddAccessAllowedAceEx@20
+RtlAddAccessAllowedObjectAce@28
 RtlAddAccessDeniedAce@16
 RtlAddAccessDeniedAceEx@20
+RtlAddAccessDeniedObjectAce@28
 RtlAddAce@20
 ;RtlAddActionToRXact
 RtlAddAtomToAtomTable@12
 ;RtlAddAttributeActionToRXact
 RtlAddAuditAccessAce@24
 RtlAddAuditAccessAceEx@28
+RtlAddAuditAccessObjectAce@36
 ;RtlAddCompoundAce
 RtlAddRange@36
 RtlAddVectoredExceptionHandler@8
index a89d320..901e524 100644 (file)
@@ -17,6 +17,7 @@
 #define WIN32_NO_STATUS
 #include <windows.h>
 #include <accctrl.h>
+#include <aclapi.h>
 #include <sddl.h>
 #define NTOS_MODE_USER
 #include <ndk/ntndk.h>
index f49a029..0bee9e5 100644 (file)
@@ -166,7 +166,7 @@ AddAccessAllowedAceEx(PACL pAcl,
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL
 STDCALL
@@ -179,8 +179,22 @@ AddAccessAllowedObjectAce(
        GUID*   InheritedObjectTypeGuid,
        PSID    pSid)
 {
-       DPRINT1("%s() not implemented!\n", __FUNCTION__);
-       return ERROR_CALL_NOT_IMPLEMENTED;
+  NTSTATUS Status;
+
+  Status = RtlAddAccessAllowedObjectAce(pAcl,
+                                        dwAceRevision,
+                                        AceFlags,
+                                        AccessMask,
+                                        ObjectTypeGuid,
+                                        InheritedObjectTypeGuid,
+                                        pSid);
+  if (!NT_SUCCESS(Status))
+  {
+    SetLastError(RtlNtStatusToDosError(Status));
+    return FALSE;
+  }
+
+  return TRUE;
 }
 
 
@@ -240,7 +254,7 @@ AddAccessDeniedAceEx(PACL pAcl,
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL
 STDCALL
@@ -253,8 +267,22 @@ AddAccessDeniedObjectAce(
        GUID*   InheritedObjectTypeGuid,
        PSID    pSid)
 {
-       DPRINT1("%s() not implemented!\n", __FUNCTION__);
-       return ERROR_CALL_NOT_IMPLEMENTED;
+  NTSTATUS Status;
+
+  Status = RtlAddAccessDeniedObjectAce(pAcl,
+                                       dwAceRevision,
+                                       AceFlags,
+                                       AccessMask,
+                                       ObjectTypeGuid,
+                                       InheritedObjectTypeGuid,
+                                       pSid);
+  if (!NT_SUCCESS(Status))
+  {
+    SetLastError(RtlNtStatusToDosError(Status));
+    return FALSE;
+  }
+
+  return TRUE;
 }
 
 
@@ -352,7 +380,7 @@ AddAuditAccessAceEx(PACL pAcl,
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL
 STDCALL
@@ -367,8 +395,24 @@ AddAuditAccessObjectAce(
        BOOL    bAuditSuccess,
        BOOL    bAuditFailure)
 {
-       DPRINT1("%s() not implemented!\n", __FUNCTION__);
-       return ERROR_CALL_NOT_IMPLEMENTED;
+  NTSTATUS Status;
+
+  Status = RtlAddAuditAccessObjectAce(pAcl,
+                                      dwAceRevision,
+                                      AceFlags,
+                                      AccessMask,
+                                      ObjectTypeGuid,
+                                      InheritedObjectTypeGuid,
+                                      pSid,
+                                      bAuditSuccess,
+                                      bAuditFailure);
+  if (!NT_SUCCESS(Status))
+  {
+    SetLastError(RtlNtStatusToDosError(Status));
+    return FALSE;
+  }
+
+  return TRUE;
 }
 
 
@@ -554,113 +598,414 @@ SetEntriesInAclW(
 }
 
 
-/*
- * @implemented
- */
-DWORD
-STDCALL
-SetEntriesInAclA(
-       ULONG                   cCountOfExplicitEntries,
-       PEXPLICIT_ACCESS_A      pListOfExplicitEntries,
-       PACL                    OldAcl,
-       PACL*                   NewAcl)
+static DWORD
+InternalTrusteeAToW(IN PTRUSTEE_A pTrusteeA,
+                    OUT PTRUSTEE_W *pTrusteeW)
 {
-    PEXPLICIT_ACCESS_W ListOfExplicitEntriesW;
-    ULONG i;
-    DWORD ErrorCode;
+    TRUSTEE_FORM TrusteeForm;
+    INT BufferSize = 0;
+    PSTR lpStr;
+    DWORD ErrorCode = ERROR_SUCCESS;
 
-    if (cCountOfExplicitEntries != 0)
+    ASSERT(sizeof(TRUSTEE_W) == sizeof(TRUSTEE_A));
+
+    TrusteeForm = GetTrusteeForm(pTrusteeA);
+    switch (TrusteeForm)
     {
-        ListOfExplicitEntriesW = HeapAlloc(GetProcessHeap(),
-                                           0,
-                                           cCountOfExplicitEntries * sizeof(EXPLICIT_ACCESS_W));
-        if (ListOfExplicitEntriesW != NULL)
+        case TRUSTEE_IS_NAME:
         {
-            /* directly copy the array, this works as the size of the EXPLICIT_ACCESS_A
-               structure matches the size of the EXPLICIT_ACCESS_W version */
-            ASSERT(sizeof(EXPLICIT_ACCESS_A) == sizeof(EXPLICIT_ACCESS_W));
-
-            RtlCopyMemory(ListOfExplicitEntriesW,
-                          pListOfExplicitEntries,
-                          cCountOfExplicitEntries * sizeof(EXPLICIT_ACCESS_W));
+            lpStr = GetTrusteeName(pTrusteeA);
+            if (lpStr != NULL)
+                BufferSize = strlen(lpStr) + 1;
 
-            /* convert the trustee names if required */
-            for (i = 0; i != cCountOfExplicitEntries; i++)
+            *pTrusteeW = RtlAllocateHeap(RtlGetProcessHeap(),
+                                         0,
+                                         sizeof(TRUSTEE_W) + (BufferSize * sizeof(WCHAR)));
+            if (*pTrusteeW != NULL)
             {
-                if (pListOfExplicitEntries[i].Trustee.TrusteeForm == TRUSTEE_IS_NAME)
+                RtlCopyMemory(*pTrusteeW,
+                              pTrusteeA,
+                              FIELD_OFFSET(TRUSTEE_A,
+                                           ptstrName));
+
+                if (lpStr != NULL)
                 {
-                    UINT BufCount = strlen(pListOfExplicitEntries[i].Trustee.ptstrName) + 1;
-                    ListOfExplicitEntriesW[i].Trustee.ptstrName =
-                        (LPWSTR)HeapAlloc(GetProcessHeap(),
-                                          0,
-                                          BufCount * sizeof(WCHAR));
-
-                    if (ListOfExplicitEntriesW[i].Trustee.ptstrName == NULL ||
-                        MultiByteToWideChar(CP_ACP,
+                    (*pTrusteeW)->ptstrName = (PWSTR)((*pTrusteeW) + 1);
+
+                    /* convert the trustee's name */
+                    if (MultiByteToWideChar(CP_ACP,
                                             0,
-                                            pListOfExplicitEntries[i].Trustee.ptstrName,
+                                            lpStr,
                                             -1,
-                                            ListOfExplicitEntriesW[i].Trustee.ptstrName,
-                                            BufCount) == 0)
+                                            (*pTrusteeW)->ptstrName,
+                                            BufferSize) == 0)
                     {
-                        /* failed to allocate enough momory for the strings or failed to
-                           convert the ansi string to unicode, then fail and free all
-                           allocated memory */
+                        goto ConvertErr;
+                    }
+                }
+                else
+                {
+                    RtlFreeHeap(RtlGetProcessHeap(),
+                                0,
+                                *pTrusteeW);
+                    goto NothingToConvert;
+                }
+            }
+            else
+                ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+            break;
+        }
 
-                        ErrorCode = GetLastError();
+        case TRUSTEE_IS_OBJECTS_AND_NAME:
+        {
+            POBJECTS_AND_NAME_A oanA = (POBJECTS_AND_NAME_A)GetTrusteeNameA(pTrusteeA);
+            POBJECTS_AND_NAME_W oan;
+            PWSTR StrBuf;
 
-                        do
-                        {
-                            if (ListOfExplicitEntriesW[i].Trustee.TrusteeForm == TRUSTEE_IS_NAME &&
-                                ListOfExplicitEntriesW[i].Trustee.ptstrName != NULL)
-                            {
-                                HeapFree(GetProcessHeap(),
+            /* calculate the size needed */
+            if ((oanA->ObjectsPresent & ACE_INHERITED_OBJECT_TYPE_PRESENT) &&
+                oanA->InheritedObjectTypeName != NULL)
+            {
+                BufferSize = strlen(oanA->InheritedObjectTypeName) + 1;
+            }
+            if (oanA->ptstrName != NULL)
+            {
+                BufferSize += strlen(oanA->ptstrName) + 1;
+            }
+
+            *pTrusteeW = RtlAllocateHeap(RtlGetProcessHeap(),
                                          0,
-                                         ListOfExplicitEntriesW[i].Trustee.ptstrName);
-                            }
-                        } while (i-- != 0);
+                                         sizeof(TRUSTEE_W) + sizeof(OBJECTS_AND_NAME_W) +
+                                             (BufferSize * sizeof(WCHAR)));
 
-                        /* free the allocated array */
-                        HeapFree(GetProcessHeap(),
-                                 0,
-                                 ListOfExplicitEntriesW);
+            if (*pTrusteeW != NULL)
+            {
+                oan = (POBJECTS_AND_NAME_W)((*pTrusteeW) + 1);
+                StrBuf = (PWSTR)(oan + 1);
+
+                /* copy over the parts of the TRUSTEE structure that don't need
+                   to be touched */
+                RtlCopyMemory(*pTrusteeW,
+                              pTrusteeA,
+                              FIELD_OFFSET(TRUSTEE_A,
+                                           ptstrName));
+
+                (*pTrusteeW)->ptstrName = (LPWSTR)oan;
+
+                /* convert the OBJECTS_AND_NAME_A structure */
+                oan->ObjectsPresent = oanA->ObjectsPresent;
+                oan->ObjectType = oanA->ObjectType;
+
+                if ((oanA->ObjectsPresent & ACE_INHERITED_OBJECT_TYPE_PRESENT) &&
+                    oanA->InheritedObjectTypeName != NULL)
+                {
+                    /* convert inherited object type name */
+                    BufferSize = strlen(oanA->InheritedObjectTypeName) + 1;
+
+                    if (MultiByteToWideChar(CP_ACP,
+                                            0,
+                                            oanA->InheritedObjectTypeName,
+                                            -1,
+                                            StrBuf,
+                                            BufferSize) == 0)
+                    {
+                        goto ConvertErr;
+                    }
+                    oan->InheritedObjectTypeName = StrBuf;
+
+                    StrBuf += BufferSize;
+                }
+                else
+                    oan->InheritedObjectTypeName = NULL;
+
+                if (oanA->ptstrName != NULL)
+                {
+                    /* convert the trustee name */
+                    BufferSize = strlen(oanA->ptstrName) + 1;
+
+                    if (MultiByteToWideChar(CP_ACP,
+                                            0,
+                                            oanA->ptstrName,
+                                            -1,
+                                            StrBuf,
+                                            BufferSize) == 0)
+                    {
+ConvertErr:
+                        ErrorCode = GetLastError();
+
+                        /* cleanup */
+                        RtlFreeHeap(RtlGetProcessHeap(),
+                                    0,
+                                    *pTrusteeW);
 
                         return ErrorCode;
                     }
+                    oan->ptstrName = StrBuf;
                 }
+                else
+                    oan->ptstrName = NULL;
             }
+            else
+                ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+            break;
         }
-        else
+
+        default:
         {
-            return GetLastError();
+NothingToConvert:
+            /* no need to convert anything to unicode */
+            *pTrusteeW = (PTRUSTEE_W)pTrusteeA;
+            break;
         }
     }
-    else
-        ListOfExplicitEntriesW = NULL;
 
-    ErrorCode = SetEntriesInAclW(cCountOfExplicitEntries,
-                                 ListOfExplicitEntriesW,
-                                 OldAcl,
-                                 NewAcl);
+    return ErrorCode;
+}
+
+
+static __inline VOID
+InternalFreeConvertedTrustee(IN PTRUSTEE_W pTrusteeW,
+                             IN PTRUSTEE_A pTrusteeA)
+{
+    if ((PVOID)pTrusteeW != (PVOID)pTrusteeA)
+    {
+        RtlFreeHeap(RtlGetProcessHeap(),
+                    0,
+                    pTrusteeW);
+    }
+}
+
 
-    /* free the strings */
-    if (ListOfExplicitEntriesW != NULL)
+static DWORD
+InternalExplicitAccessAToW(IN ULONG cCountOfExplicitEntries,
+                           IN PEXPLICIT_ACCESS_A pListOfExplicitEntriesA,
+                           OUT PEXPLICIT_ACCESS_W *pListOfExplicitEntriesW)
+{
+    TRUSTEE_FORM TrusteeForm;
+    SIZE_T Size;
+    ULONG i;
+    ULONG ObjectsAndNameCount = 0;
+    PEXPLICIT_ACCESS_W peaw = NULL;
+    DWORD ErrorCode = ERROR_SUCCESS;
+    LPSTR lpStr;
+
+    /* NOTE: This code assumes that the size of the TRUSTEE_A and TRUSTEE_W structure matches! */
+    ASSERT(sizeof(TRUSTEE_A) == sizeof(TRUSTEE_W));
+
+    if (cCountOfExplicitEntries != 0)
     {
-        /* free the converted strings */
+        /* calculate the size needed */
+        Size = cCountOfExplicitEntries * sizeof(EXPLICIT_ACCESS_W);
         for (i = 0; i != cCountOfExplicitEntries; i++)
         {
-            if (ListOfExplicitEntriesW[i].Trustee.TrusteeForm == TRUSTEE_IS_NAME)
+            TrusteeForm = GetTrusteeForm(&pListOfExplicitEntriesA[i].Trustee);
+
+            switch (TrusteeForm)
             {
-                HeapFree(GetProcessHeap(),
-                         0,
-                         ListOfExplicitEntriesW[i].Trustee.ptstrName);
+                case TRUSTEE_IS_NAME:
+                {
+                    lpStr = GetTrusteeNameA(&pListOfExplicitEntriesA[i].Trustee);
+                    if (lpStr != NULL)
+                        Size += (strlen(lpStr) + 1) * sizeof(WCHAR);
+                    break;
+                }
+
+                case TRUSTEE_IS_OBJECTS_AND_NAME:
+                {
+                    POBJECTS_AND_NAME_A oan = (POBJECTS_AND_NAME_A)GetTrusteeNameA(&pListOfExplicitEntriesA[i].Trustee);
+
+                    if ((oan->ObjectsPresent & ACE_INHERITED_OBJECT_TYPE_PRESENT) &&
+                        oan->InheritedObjectTypeName != NULL)
+                    {
+                        Size += (strlen(oan->InheritedObjectTypeName) + 1) * sizeof(WCHAR);
+                    }
+
+                    if (oan->ptstrName != NULL)
+                        Size += (strlen(oan->ptstrName) + 1) * sizeof(WCHAR);
+
+                    ObjectsAndNameCount++;
+                    break;
+                }
+
+                default:
+                    break;
             }
         }
 
+        /* allocate the array */
+        peaw = RtlAllocateHeap(RtlGetProcessHeap(),
+                               0,
+                               Size);
+        if (peaw != NULL)
+        {
+            INT BufferSize;
+            POBJECTS_AND_NAME_W oan = (POBJECTS_AND_NAME_W)(peaw + cCountOfExplicitEntries);
+            LPWSTR StrBuf = (LPWSTR)(oan + ObjectsAndNameCount);
+
+            /* convert the array to unicode */
+            for (i = 0; i != cCountOfExplicitEntries; i++)
+            {
+                peaw[i].grfAccessPermissions = pListOfExplicitEntriesA[i].grfAccessPermissions;
+                peaw[i].grfAccessMode = pListOfExplicitEntriesA[i].grfAccessMode;
+                peaw[i].grfInheritance = pListOfExplicitEntriesA[i].grfInheritance;
+
+                /* convert or copy the TRUSTEE structure */
+                TrusteeForm = GetTrusteeForm(&pListOfExplicitEntriesA[i].Trustee);
+                switch (TrusteeForm)
+                {
+                    case TRUSTEE_IS_NAME:
+                    {
+                        lpStr = GetTrusteeNameA(&pListOfExplicitEntriesA[i].Trustee);
+                        if (lpStr != NULL)
+                        {
+                            /* convert the trustee name */
+                            BufferSize = strlen(lpStr) + 1;
+
+                            if (MultiByteToWideChar(CP_ACP,
+                                                    0,
+                                                    lpStr,
+                                                    -1,
+                                                    StrBuf,
+                                                    BufferSize) == 0)
+                            {
+                                goto ConvertErr;
+                            }
+                            peaw[i].Trustee.ptstrName = StrBuf;
+
+                            StrBuf += BufferSize;
+                        }
+                        else
+                            goto RawTrusteeCopy;
+
+                        break;
+                    }
+
+                    case TRUSTEE_IS_OBJECTS_AND_NAME:
+                    {
+                        POBJECTS_AND_NAME_A oanA = (POBJECTS_AND_NAME_A)GetTrusteeNameA(&pListOfExplicitEntriesA[i].Trustee);
+
+                        /* copy over the parts of the TRUSTEE structure that don't need
+                           to be touched */
+                        RtlCopyMemory(&peaw[i].Trustee,
+                                      &pListOfExplicitEntriesA[i].Trustee,
+                                      FIELD_OFFSET(TRUSTEE_A,
+                                                   ptstrName));
+
+                        peaw[i].Trustee.ptstrName = (LPWSTR)oan;
+
+                        /* convert the OBJECTS_AND_NAME_A structure */
+                        oan->ObjectsPresent = oanA->ObjectsPresent;
+                        oan->ObjectType = oanA->ObjectType;
+
+                        if ((oanA->ObjectsPresent & ACE_INHERITED_OBJECT_TYPE_PRESENT) &&
+                            oanA->InheritedObjectTypeName != NULL)
+                        {
+                            /* convert inherited object type name */
+                            BufferSize = strlen(oanA->InheritedObjectTypeName) + 1;
+
+                            if (MultiByteToWideChar(CP_ACP,
+                                                    0,
+                                                    oanA->InheritedObjectTypeName,
+                                                    -1,
+                                                    StrBuf,
+                                                    BufferSize) == 0)
+                            {
+                                goto ConvertErr;
+                            }
+                            oan->InheritedObjectTypeName = StrBuf;
+
+                            StrBuf += BufferSize;
+                        }
+                        else
+                            oan->InheritedObjectTypeName = NULL;
+
+                        if (oanA->ptstrName != NULL)
+                        {
+                            /* convert the trustee name */
+                            BufferSize = strlen(oanA->ptstrName) + 1;
+
+                            if (MultiByteToWideChar(CP_ACP,
+                                                    0,
+                                                    oanA->ptstrName,
+                                                    -1,
+                                                    StrBuf,
+                                                    BufferSize) == 0)
+                            {
+ConvertErr:
+                                ErrorCode = GetLastError();
+
+                                /* cleanup */
+                                RtlFreeHeap(RtlGetProcessHeap(),
+                                            0,
+                                            peaw);
+
+                                return ErrorCode;
+                            }
+                            oan->ptstrName = StrBuf;
+
+                            StrBuf += BufferSize;
+                        }
+                        else
+                            oan->ptstrName = NULL;
+
+                        /* move on to the next OBJECTS_AND_NAME_A structure */
+                        oan++;
+                        break;
+                    }
+
+                    default:
+                    {
+RawTrusteeCopy:
+                        /* just copy over the TRUSTEE structure, they don't contain any
+                           ansi/unicode specific data */
+                        RtlCopyMemory(&peaw[i].Trustee,
+                                      &pListOfExplicitEntriesA[i].Trustee,
+                                      sizeof(TRUSTEE_A));
+                        break;
+                    }
+                }
+            }
+
+            ASSERT(ErrorCode == ERROR_SUCCESS);
+            *pListOfExplicitEntriesW = peaw;
+        }
+        else
+            ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+    }
+
+    return ErrorCode;
+}
+
+
+/*
+ * @implemented
+ */
+DWORD
+STDCALL
+SetEntriesInAclA(
+       ULONG                   cCountOfExplicitEntries,
+       PEXPLICIT_ACCESS_A      pListOfExplicitEntries,
+       PACL                    OldAcl,
+       PACL*                   NewAcl)
+{
+    PEXPLICIT_ACCESS_W ListOfExplicitEntriesW = NULL;
+    DWORD ErrorCode;
+
+    ErrorCode = InternalExplicitAccessAToW(cCountOfExplicitEntries,
+                                           pListOfExplicitEntries,
+                                           &ListOfExplicitEntriesW);
+
+    if (ErrorCode == ERROR_SUCCESS)
+    {
+        ErrorCode = SetEntriesInAclW(cCountOfExplicitEntries,
+                                     ListOfExplicitEntriesW,
+                                     OldAcl,
+                                     NewAcl);
+
         /* free the allocated array */
-        HeapFree(GetProcessHeap(),
-                 0,
-                 ListOfExplicitEntriesW);
+        RtlFreeHeap(RtlGetProcessHeap(),
+                    0,
+                    ListOfExplicitEntriesW);
     }
 
     return ErrorCode;
@@ -708,7 +1053,7 @@ GetEffectiveRightsFromAclW(IN PACL pacl,
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 DWORD
 STDCALL
@@ -716,8 +1061,24 @@ GetEffectiveRightsFromAclA(IN PACL pacl,
                            IN PTRUSTEE_A pTrustee,
                            OUT PACCESS_MASK pAccessRights)
 {
-       DPRINT1("%s() not implemented!\n", __FUNCTION__);
-       return ERROR_CALL_NOT_IMPLEMENTED;
+    PTRUSTEE_W pTrusteeW = NULL;
+    DWORD ErrorCode;
+
+    ErrorCode = InternalTrusteeAToW(pTrustee,
+                                    &pTrusteeW);
+    if (ErrorCode == ERROR_SUCCESS)
+    {
+        ErrorCode = GetEffectiveRightsFromAclW(pacl,
+                                               pTrusteeW,
+                                               pAccessRights);
+
+        InternalFreeConvertedTrustee(pTrusteeW,
+                                     pTrustee);
+    }
+    else
+        ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+
+    return ErrorCode;
 }
 
 
@@ -737,7 +1098,7 @@ GetAuditedPermissionsFromAclW(IN PACL pacl,
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 DWORD
 STDCALL
@@ -746,8 +1107,25 @@ GetAuditedPermissionsFromAclA(IN PACL pacl,
                               OUT PACCESS_MASK pSuccessfulAuditedRights,
                               OUT PACCESS_MASK pFailedAuditRights)
 {
-       DPRINT1("%s() not implemented!\n", __FUNCTION__);
-       return ERROR_CALL_NOT_IMPLEMENTED;
+    PTRUSTEE_W pTrusteeW = NULL;
+    DWORD ErrorCode;
+
+    ErrorCode = InternalTrusteeAToW(pTrustee,
+                                    &pTrusteeW);
+    if (ErrorCode == ERROR_SUCCESS)
+    {
+        ErrorCode = GetAuditedPermissionsFromAclW(pacl,
+                                                  pTrusteeW,
+                                                  pSuccessfulAuditedRights,
+                                                  pFailedAuditRights);
+
+        InternalFreeConvertedTrustee(pTrusteeW,
+                                     pTrustee);
+    }
+    else
+        ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+
+    return ErrorCode;
 }
 
 /* EOF */
index 20d664e..df8b067 100644 (file)
@@ -490,9 +490,9 @@ STDCALL
 BuildSecurityDescriptorW(IN PTRUSTEE_W pOwner  OPTIONAL,
                          IN PTRUSTEE_W pGroup  OPTIONAL,
                          IN ULONG cCountOfAccessEntries,
-                         IN PEXPLICIT_ACCESS pListOfAccessEntries  OPTIONAL,
+                         IN PEXPLICIT_ACCESS_W pListOfAccessEntries  OPTIONAL,
                          IN ULONG cCountOfAuditEntries,
-                         IN PEXPLICIT_ACCESS pListOfAuditEntries  OPTIONAL,
+                         IN PEXPLICIT_ACCESS_W pListOfAuditEntries  OPTIONAL,
                          IN PSECURITY_DESCRIPTOR pOldSD  OPTIONAL,
                          OUT PULONG pSizeNewSD,
                          OUT PSECURITY_DESCRIPTOR* pNewSD)
@@ -510,9 +510,9 @@ STDCALL
 BuildSecurityDescriptorA(IN PTRUSTEE_A pOwner  OPTIONAL,
                          IN PTRUSTEE_A pGroup  OPTIONAL,
                          IN ULONG cCountOfAccessEntries,
-                         IN PEXPLICIT_ACCESS pListOfAccessEntries  OPTIONAL,
+                         IN PEXPLICIT_ACCESS_A pListOfAccessEntries  OPTIONAL,
                          IN ULONG cCountOfAuditEntries,
-                         IN PEXPLICIT_ACCESS pListOfAuditEntries  OPTIONAL,
+                         IN PEXPLICIT_ACCESS_A pListOfAuditEntries  OPTIONAL,
                          IN PSECURITY_DESCRIPTOR pOldSD  OPTIONAL,
                          OUT PULONG pSizeNewSD,
                          OUT PSECURITY_DESCRIPTOR* pNewSD)
index 5108281..8295da3 100644 (file)
@@ -157,6 +157,136 @@ AccpGetAceAccessMask(IN PACE_HEADER AceHeader)
     return *((PACCESS_MASK)(AceHeader + 1));
 }
 
+static BOOL
+AccpIsObjectAce(IN PACE_HEADER AceHeader)
+{
+    BOOL Ret;
+
+    switch (AceHeader->AceType)
+    {
+        case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
+        case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
+        case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
+        case ACCESS_DENIED_OBJECT_ACE_TYPE:
+        case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE:
+        case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
+            Ret = TRUE;
+            break;
+
+        default:
+            Ret = FALSE;
+            break;
+    }
+
+    return Ret;
+}
+
+static GUID*
+AccpGetObjectAceObjectType(IN PACE_HEADER AceHeader)
+{
+    GUID *ObjectType = NULL;
+
+    switch (AceHeader->AceType)
+    {
+        case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
+        case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
+        {
+            PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace = (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE)AceHeader;
+            if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
+                ObjectType = &Ace->ObjectType;
+            break;
+        }
+        case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
+        case ACCESS_DENIED_OBJECT_ACE_TYPE:
+        {
+            PACCESS_ALLOWED_OBJECT_ACE Ace = (PACCESS_ALLOWED_OBJECT_ACE)AceHeader;
+            if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
+                ObjectType = &Ace->ObjectType;
+            break;
+        }
+
+        case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE:
+        {
+            PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace = (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE)AceHeader;
+            if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
+                ObjectType = &Ace->ObjectType;
+            break;
+        }
+        case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
+        {
+            PSYSTEM_AUDIT_OBJECT_ACE Ace = (PSYSTEM_AUDIT_OBJECT_ACE)AceHeader;
+            if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
+                ObjectType = &Ace->ObjectType;
+            break;
+        }
+    }
+
+    return ObjectType;
+}
+
+static GUID*
+AccpGetObjectAceInheritedObjectType(IN PACE_HEADER AceHeader)
+{
+    GUID *ObjectType = NULL;
+
+    switch (AceHeader->AceType)
+    {
+        case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
+        case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
+        {
+            PACCESS_ALLOWED_CALLBACK_OBJECT_ACE Ace = (PACCESS_ALLOWED_CALLBACK_OBJECT_ACE)AceHeader;
+            if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
+            {
+                if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
+                    ObjectType = &Ace->InheritedObjectType;
+                else
+                    ObjectType = &Ace->ObjectType;
+            }
+            break;
+        }
+        case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
+        case ACCESS_DENIED_OBJECT_ACE_TYPE:
+        {
+            PACCESS_ALLOWED_OBJECT_ACE Ace = (PACCESS_ALLOWED_OBJECT_ACE)AceHeader;
+            if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
+            {
+                if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
+                    ObjectType = &Ace->InheritedObjectType;
+                else
+                    ObjectType = &Ace->ObjectType;
+            }
+            break;
+        }
+
+        case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE:
+        {
+            PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE Ace = (PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE)AceHeader;
+            if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
+            {
+                if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
+                    ObjectType = &Ace->InheritedObjectType;
+                else
+                    ObjectType = &Ace->ObjectType;
+            }
+            break;
+        }
+        case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
+        {
+            PSYSTEM_AUDIT_OBJECT_ACE Ace = (PSYSTEM_AUDIT_OBJECT_ACE)AceHeader;
+            if (Ace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
+            {
+                if (Ace->Flags & ACE_OBJECT_TYPE_PRESENT)
+                    ObjectType = &Ace->InheritedObjectType;
+                else
+                    ObjectType = &Ace->ObjectType;
+            }
+            break;
+        }
+    }
+
+    return ObjectType;
+}
+
 
 /**********************************************************************
  * AccRewriteGetHandleRights                           EXPORTED
@@ -925,6 +1055,8 @@ AccRewriteGetExplicitEntriesFromAcl(PACL pacl,
 {
     PACE_HEADER AceHeader;
     PSID Sid, SidTarget;
+    ULONG ObjectAceCount = 0;
+    POBJECTS_AND_SID ObjSid;
     SIZE_T Size;
     PEXPLICIT_ACCESS_W peaw;
     DWORD LastErr, SidLen;
@@ -947,10 +1079,15 @@ AccRewriteGetExplicitEntriesFromAcl(PACL pacl,
             {
                 Sid = AccpGetAceSid(AceHeader);
                 Size += GetLengthSid(Sid);
-                /* FIXME - take size of opaque data in account? */
+
+                if (AccpIsObjectAce(AceHeader))
+                    ObjectAceCount++;
+
                 AceIndex++;
             }
 
+            Size += ObjectAceCount * sizeof(OBJECTS_AND_SID);
+
             ASSERT(pacl->AceCount == AceIndex);
 
             /* allocate the array */
@@ -959,7 +1096,8 @@ AccRewriteGetExplicitEntriesFromAcl(PACL pacl,
             if (peaw != NULL)
             {
                 AceIndex = 0;
-                SidTarget = (PSID)(peaw + pacl->AceCount);
+                ObjSid = (POBJECTS_AND_SID)(peaw + pacl->AceCount);
+                SidTarget = (PSID)(ObjSid + ObjectAceCount);
 
                 /* initialize the array */
                 while (GetAce(pacl,
@@ -977,8 +1115,20 @@ AccRewriteGetExplicitEntriesFromAcl(PACL pacl,
                                 SidTarget,
                                 Sid))
                     {
-                        BuildTrusteeWithSid(&peaw[AceIndex].Trustee,
-                                            SidTarget);
+                        if (AccpIsObjectAce(AceHeader))
+                        {
+                            BuildTrusteeWithObjectsAndSid(&peaw[AceIndex].Trustee,
+                                                          ObjSid++,
+                                                          AccpGetObjectAceObjectType(AceHeader),
+                                                          AccpGetObjectAceInheritedObjectType(AceHeader),
+                                                          SidTarget);
+                        }
+                        else
+                        {
+                            BuildTrusteeWithSid(&peaw[AceIndex].Trustee,
+                                                SidTarget);
+                        }
+
                         SidTarget = (PSID)((ULONG_PTR)SidTarget + SidLen);
                     }
                     else
index 97729ff..98cf6ae 100644 (file)
@@ -455,6 +455,19 @@ RtlAddAccessAllowedAceEx(
     IN PSID pSid
 );
 
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlAddAccessAllowedObjectAce(
+    IN OUT PACL pAcl,
+    IN ULONG dwAceRevision,
+    IN ULONG AceFlags,
+    IN ULONG AccessMask,
+    IN GUID *ObjectTypeGuid  OPTIONAL,
+    IN GUID *InheritedObjectTypeGuid  OPTIONAL,
+    IN PSID pSid
+);
+
 NTSYSAPI
 NTSTATUS
 NTAPI
@@ -479,14 +492,14 @@ RtlAddAccessDeniedAceEx(
 NTSYSAPI
 NTSTATUS
 NTAPI
-RtlAddAuditAccessAceEx(
-    IN OUT PACL Acl,
-    IN ULONG Revision,
-    IN ULONG Flags,
-    IN ACCESS_MASK AccessMask,
-    IN PSID Sid,
-    IN BOOLEAN Success,
-    IN BOOLEAN Failure
+RtlAddAccessDeniedObjectAce(
+    IN OUT PACL pAcl,
+    IN ULONG dwAceRevision,
+    IN ULONG AceFlags,
+    IN ULONG AccessMask,
+    IN GUID *ObjectTypeGuid  OPTIONAL,
+    IN GUID *InheritedObjectTypeGuid  OPTIONAL,
+    IN PSID pSid
 );
 
 NTSYSAPI
@@ -512,6 +525,34 @@ RtlAddAuditAccessAce(
     BOOLEAN Failure
 );
 
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlAddAuditAccessAceEx(
+    IN OUT PACL Acl,
+    IN ULONG Revision,
+    IN ULONG Flags,
+    IN ACCESS_MASK AccessMask,
+    IN PSID Sid,
+    IN BOOLEAN Success,
+    IN BOOLEAN Failure
+);
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlAddAuditAccessObjectAce(
+    IN OUT PACL Acl,
+    IN ULONG Revision,
+    IN ULONG Flags,
+    IN ACCESS_MASK AccessMask,
+    IN GUID *ObjectTypeGuid  OPTIONAL,
+    IN GUID *InheritedObjectTypeGuid  OPTIONAL,
+    IN PSID Sid,
+    IN BOOLEAN Success,
+    IN BOOLEAN Failure
+);
+
 NTSYSAPI
 NTSTATUS
 NTAPI
index 236fe1f..cd8f01b 100644 (file)
@@ -225,7 +225,7 @@ typedef DWORD FLONG;
 #define NO_PROPAGATE_INHERIT_ACE       4
 #define INHERIT_ONLY_ACE       8
 #define INHERITED_ACE  10
-#define VALID_INHERIT_FLAGS    16
+#define VALID_INHERIT_FLAGS    0x1F
 #define SUCCESSFUL_ACCESS_ACE_FLAG     64
 #define FAILED_ACCESS_ACE_FLAG 128
 #define DELETE 0x00010000L
index c975e9a..e3d68fd 100644 (file)
@@ -103,14 +103,40 @@ RtlpAddKnownAce (PACL Acl,
                  ULONG Revision,
                  ULONG Flags,
                  ACCESS_MASK AccessMask,
+                 GUID *ObjectTypeGuid  OPTIONAL,
+                 GUID *InheritedObjectTypeGuid  OPTIONAL,
                  PSID Sid,
                  ULONG Type)
 {
    PACE Ace;
-   ULONG InvalidFlags;
+   PSID SidStart;
+   ULONG AceSize, InvalidFlags;
+   ULONG AceObjectFlags = 0;
 
    PAGED_CODE_RTL();
 
+#if DBG
+   /* check if RtlpAddKnownAce was called incorrectly */
+   if (ObjectTypeGuid != NULL || InheritedObjectTypeGuid != NULL)
+   {
+      ASSERT(Type == ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE ||
+             Type == ACCESS_ALLOWED_OBJECT_ACE_TYPE ||
+             Type == ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE ||
+             Type == ACCESS_DENIED_OBJECT_ACE_TYPE ||
+             Type == SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE ||
+             Type == SYSTEM_AUDIT_OBJECT_ACE_TYPE);
+   }
+   else
+   {
+      ASSERT(Type != ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE &&
+             Type != ACCESS_ALLOWED_OBJECT_ACE_TYPE &&
+             Type != ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE &&
+             Type != ACCESS_DENIED_OBJECT_ACE_TYPE &&
+             Type != SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE &&
+             Type != SYSTEM_AUDIT_OBJECT_ACE_TYPE);
+   }
+#endif
+
    if (!RtlValidSid(Sid))
    {
       return(STATUS_INVALID_SID);
@@ -126,11 +152,17 @@ RtlpAddKnownAce (PACL Acl,
    }
 
    /* Validate the flags */
-   if (Type == SYSTEM_AUDIT_ACE_TYPE)
+   if (Type == SYSTEM_AUDIT_ACE_TYPE ||
+       Type == SYSTEM_AUDIT_OBJECT_ACE_TYPE ||
+       Type == SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE)
+   {
       InvalidFlags = Flags & ~(VALID_INHERIT_FLAGS |
                                SUCCESSFUL_ACCESS_ACE_FLAG | FAILED_ACCESS_ACE_FLAG);
+   }
    else
+   {
       InvalidFlags = Flags & ~VALID_INHERIT_FLAGS;
+   }
 
    if (InvalidFlags != 0)
    {
@@ -145,16 +177,69 @@ RtlpAddKnownAce (PACL Acl,
    {
       return(STATUS_ALLOTTED_SPACE_EXCEEDED);
    }
-   if ((ULONG_PTR)Ace + RtlLengthSid(Sid) + sizeof(ACE) >
+
+   /* Calculate the size of the ACE */
+   AceSize = RtlLengthSid(Sid) + sizeof(ACE);
+   if (ObjectTypeGuid != NULL)
+   {
+      AceObjectFlags |= ACE_OBJECT_TYPE_PRESENT;
+      AceSize += sizeof(GUID);
+   }
+   if (InheritedObjectTypeGuid != NULL)
+   {
+      AceObjectFlags |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
+      AceSize += sizeof(GUID);
+   }
+
+   if (AceObjectFlags != 0)
+   {
+      /* Don't forget the ACE object flags
+         (corresponds to the Flags field in the *_OBJECT_ACE structures) */
+      AceSize += sizeof(ULONG);
+   }
+
+   if ((ULONG_PTR)Ace + AceSize >
        (ULONG_PTR)Acl + Acl->AclSize)
    {
       return(STATUS_ALLOTTED_SPACE_EXCEEDED);
    }
+
+   /* initialize the header and common fields */
    Ace->Header.AceFlags = Flags;
    Ace->Header.AceType = Type;
-   Ace->Header.AceSize = RtlLengthSid(Sid) + sizeof(ACE);
+   Ace->Header.AceSize = (WORD)AceSize;
    Ace->AccessMask = AccessMask;
-   RtlCopySid(RtlLengthSid(Sid), (PSID)(Ace + 1), Sid);
+
+   if (AceObjectFlags != 0)
+   {
+      /* Write the ACE flags to the ACE
+         (corresponds to the Flags field in the *_OBJECT_ACE structures) */
+      *(PULONG)(Ace + 1) = AceObjectFlags;
+      SidStart = (PSID)((ULONG_PTR)(Ace + 1) + sizeof(ULONG));
+   }
+   else
+      SidStart = (PSID)(Ace + 1);
+
+   /* copy the GUIDs */
+   if (ObjectTypeGuid != NULL)
+   {
+       RtlCopyMemory(SidStart,
+                     ObjectTypeGuid,
+                     sizeof(GUID));
+       SidStart = (PSID)((ULONG_PTR)SidStart + sizeof(GUID));
+   }
+   if (InheritedObjectTypeGuid != NULL)
+   {
+       RtlCopyMemory(SidStart,
+                     InheritedObjectTypeGuid,
+                     sizeof(GUID));
+       SidStart = (PSID)((ULONG_PTR)SidStart + sizeof(GUID));
+   }
+
+   /* copy the SID */
+   RtlCopySid(RtlLengthSid(Sid),
+              SidStart,
+              Sid);
    Acl->AceCount++;
    Acl->AclRevision = Revision;
    return(STATUS_SUCCESS);
@@ -176,6 +261,8 @@ RtlAddAccessAllowedAce (IN OUT PACL Acl,
                            Revision,
                            0,
                            AccessMask,
+                           NULL,
+                           NULL,
                            Sid,
                            ACCESS_ALLOWED_ACE_TYPE);
 }
@@ -197,11 +284,46 @@ RtlAddAccessAllowedAceEx (IN OUT PACL Acl,
                            Revision,
                            Flags,
                            AccessMask,
+                           NULL,
+                           NULL,
                            Sid,
                            ACCESS_ALLOWED_ACE_TYPE);
 }
 
 
+/*
+ * @implemented
+ */
+NTSTATUS NTAPI
+RtlAddAccessAllowedObjectAce (IN OUT PACL Acl,
+                              IN ULONG Revision,
+                              IN ULONG Flags,
+                              IN ACCESS_MASK AccessMask,
+                              IN GUID *ObjectTypeGuid  OPTIONAL,
+                              IN GUID *InheritedObjectTypeGuid  OPTIONAL,
+                              IN PSID Sid)
+{
+   ULONG Type;
+
+   PAGED_CODE_RTL();
+
+   /* make sure we call RtlpAddKnownAce correctly */
+   if (ObjectTypeGuid != NULL || InheritedObjectTypeGuid != NULL)
+      Type = ACCESS_ALLOWED_OBJECT_ACE_TYPE;
+   else
+      Type = ACCESS_ALLOWED_ACE_TYPE;
+
+   return RtlpAddKnownAce (Acl,
+                           Revision,
+                           Flags,
+                           AccessMask,
+                           ObjectTypeGuid,
+                           InheritedObjectTypeGuid,
+                           Sid,
+                           Type);
+}
+
+
 /*
  * @implemented
  */
@@ -217,6 +339,8 @@ RtlAddAccessDeniedAce (PACL Acl,
                            Revision,
                            0,
                            AccessMask,
+                           NULL,
+                           NULL,
                            Sid,
                            ACCESS_DENIED_ACE_TYPE);
 }
@@ -238,11 +362,46 @@ RtlAddAccessDeniedAceEx (IN OUT PACL Acl,
                            Revision,
                            Flags,
                            AccessMask,
+                           NULL,
+                           NULL,
                            Sid,
                            ACCESS_DENIED_ACE_TYPE);
 }
 
 
+/*
+ * @implemented
+ */
+NTSTATUS NTAPI
+RtlAddAccessDeniedObjectAce (IN OUT PACL Acl,
+                             IN ULONG Revision,
+                             IN ULONG Flags,
+                             IN ACCESS_MASK AccessMask,
+                             IN GUID *ObjectTypeGuid  OPTIONAL,
+                             IN GUID *InheritedObjectTypeGuid  OPTIONAL,
+                             IN PSID Sid)
+{
+   ULONG Type;
+
+   PAGED_CODE_RTL();
+
+   /* make sure we call RtlpAddKnownAce correctly */
+   if (ObjectTypeGuid != NULL || InheritedObjectTypeGuid != NULL)
+      Type = ACCESS_DENIED_OBJECT_ACE_TYPE;
+   else
+      Type = ACCESS_DENIED_ACE_TYPE;
+
+   return RtlpAddKnownAce (Acl,
+                           Revision,
+                           Flags,
+                           AccessMask,
+                           ObjectTypeGuid,
+                           InheritedObjectTypeGuid,
+                           Sid,
+                           Type);
+}
+
+
 static VOID
 RtlpAddData(PVOID AceList,
             ULONG AceListLength,
@@ -363,6 +522,8 @@ RtlAddAuditAccessAce(PACL Acl,
                            Revision,
                            Flags,
                            AccessMask,
+                           NULL,
+                           NULL,
                            Sid,
                            SYSTEM_AUDIT_ACE_TYPE);
 }
@@ -394,11 +555,56 @@ RtlAddAuditAccessAceEx(PACL Acl,
                            Revision,
                            Flags,
                            AccessMask,
+                           NULL,
+                           NULL,
                            Sid,
                            SYSTEM_AUDIT_ACE_TYPE);
 }
 
 
+/*
+ * @implemented
+ */
+NTSTATUS NTAPI
+RtlAddAuditAccessObjectAce(PACL Acl,
+                           ULONG Revision,
+                           ULONG Flags,
+                           ACCESS_MASK AccessMask,
+                           IN GUID *ObjectTypeGuid  OPTIONAL,
+                           IN GUID *InheritedObjectTypeGuid  OPTIONAL,
+                           PSID Sid,
+                           BOOLEAN Success,
+                           BOOLEAN Failure)
+{
+   ULONG Type;
+
+   if (Success)
+   {
+      Flags |= SUCCESSFUL_ACCESS_ACE_FLAG;
+   }
+
+   if (Failure)
+   {
+      Flags |= FAILED_ACCESS_ACE_FLAG;
+   }
+
+   /* make sure we call RtlpAddKnownAce correctly */
+   if (ObjectTypeGuid != NULL || InheritedObjectTypeGuid != NULL)
+      Type = SYSTEM_AUDIT_OBJECT_ACE_TYPE;
+   else
+      Type = SYSTEM_AUDIT_ACE_TYPE;
+
+   return RtlpAddKnownAce (Acl,
+                           Revision,
+                           Flags,
+                           AccessMask,
+                           ObjectTypeGuid,
+                           InheritedObjectTypeGuid,
+                           Sid,
+                           Type);
+}
+
+
 static VOID
 RtlpDeleteData(PVOID Ace,
                ULONG AceSize,