mirror of
https://github.com/reactos/reactos.git
synced 2025-06-05 17:30:32 +00:00
bug 1467 : patch from w3seek, ACLs: Implement audit functions
svn path=/trunk/; revision=21875
This commit is contained in:
parent
27a4da82e1
commit
c74cbfaf67
8 changed files with 907 additions and 128 deletions
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,6 +598,385 @@ SetEntriesInAclW(
|
|||
}
|
||||
|
||||
|
||||
static DWORD
|
||||
InternalTrusteeAToW(IN PTRUSTEE_A pTrusteeA,
|
||||
OUT PTRUSTEE_W *pTrusteeW)
|
||||
{
|
||||
TRUSTEE_FORM TrusteeForm;
|
||||
INT BufferSize = 0;
|
||||
PSTR lpStr;
|
||||
DWORD ErrorCode = ERROR_SUCCESS;
|
||||
|
||||
ASSERT(sizeof(TRUSTEE_W) == sizeof(TRUSTEE_A));
|
||||
|
||||
TrusteeForm = GetTrusteeForm(pTrusteeA);
|
||||
switch (TrusteeForm)
|
||||
{
|
||||
case TRUSTEE_IS_NAME:
|
||||
{
|
||||
lpStr = GetTrusteeName(pTrusteeA);
|
||||
if (lpStr != NULL)
|
||||
BufferSize = strlen(lpStr) + 1;
|
||||
|
||||
*pTrusteeW = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
sizeof(TRUSTEE_W) + (BufferSize * sizeof(WCHAR)));
|
||||
if (*pTrusteeW != NULL)
|
||||
{
|
||||
RtlCopyMemory(*pTrusteeW,
|
||||
pTrusteeA,
|
||||
FIELD_OFFSET(TRUSTEE_A,
|
||||
ptstrName));
|
||||
|
||||
if (lpStr != NULL)
|
||||
{
|
||||
(*pTrusteeW)->ptstrName = (PWSTR)((*pTrusteeW) + 1);
|
||||
|
||||
/* convert the trustee's name */
|
||||
if (MultiByteToWideChar(CP_ACP,
|
||||
0,
|
||||
lpStr,
|
||||
-1,
|
||||
(*pTrusteeW)->ptstrName,
|
||||
BufferSize) == 0)
|
||||
{
|
||||
goto ConvertErr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlFreeHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
*pTrusteeW);
|
||||
goto NothingToConvert;
|
||||
}
|
||||
}
|
||||
else
|
||||
ErrorCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
case TRUSTEE_IS_OBJECTS_AND_NAME:
|
||||
{
|
||||
POBJECTS_AND_NAME_A oanA = (POBJECTS_AND_NAME_A)GetTrusteeNameA(pTrusteeA);
|
||||
POBJECTS_AND_NAME_W oan;
|
||||
PWSTR StrBuf;
|
||||
|
||||
/* 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,
|
||||
sizeof(TRUSTEE_W) + sizeof(OBJECTS_AND_NAME_W) +
|
||||
(BufferSize * sizeof(WCHAR)));
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
NothingToConvert:
|
||||
/* no need to convert anything to unicode */
|
||||
*pTrusteeW = (PTRUSTEE_W)pTrusteeA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
|
||||
static __inline VOID
|
||||
InternalFreeConvertedTrustee(IN PTRUSTEE_W pTrusteeW,
|
||||
IN PTRUSTEE_A pTrusteeA)
|
||||
{
|
||||
if ((PVOID)pTrusteeW != (PVOID)pTrusteeA)
|
||||
{
|
||||
RtlFreeHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
pTrusteeW);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
/* calculate the size needed */
|
||||
Size = cCountOfExplicitEntries * sizeof(EXPLICIT_ACCESS_W);
|
||||
for (i = 0; i != cCountOfExplicitEntries; i++)
|
||||
{
|
||||
TrusteeForm = GetTrusteeForm(&pListOfExplicitEntriesA[i].Trustee);
|
||||
|
||||
switch (TrusteeForm)
|
||||
{
|
||||
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
|
||||
*/
|
||||
|
@ -565,102 +988,24 @@ SetEntriesInAclA(
|
|||
PACL OldAcl,
|
||||
PACL* NewAcl)
|
||||
{
|
||||
PEXPLICIT_ACCESS_W ListOfExplicitEntriesW;
|
||||
ULONG i;
|
||||
PEXPLICIT_ACCESS_W ListOfExplicitEntriesW = NULL;
|
||||
DWORD ErrorCode;
|
||||
|
||||
if (cCountOfExplicitEntries != 0)
|
||||
ErrorCode = InternalExplicitAccessAToW(cCountOfExplicitEntries,
|
||||
pListOfExplicitEntries,
|
||||
&ListOfExplicitEntriesW);
|
||||
|
||||
if (ErrorCode == ERROR_SUCCESS)
|
||||
{
|
||||
ListOfExplicitEntriesW = HeapAlloc(GetProcessHeap(),
|
||||
0,
|
||||
cCountOfExplicitEntries * sizeof(EXPLICIT_ACCESS_W));
|
||||
if (ListOfExplicitEntriesW != NULL)
|
||||
{
|
||||
/* 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));
|
||||
|
||||
/* convert the trustee names if required */
|
||||
for (i = 0; i != cCountOfExplicitEntries; i++)
|
||||
{
|
||||
if (pListOfExplicitEntries[i].Trustee.TrusteeForm == TRUSTEE_IS_NAME)
|
||||
{
|
||||
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,
|
||||
0,
|
||||
pListOfExplicitEntries[i].Trustee.ptstrName,
|
||||
-1,
|
||||
ListOfExplicitEntriesW[i].Trustee.ptstrName,
|
||||
BufCount) == 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 */
|
||||
|
||||
ErrorCode = GetLastError();
|
||||
|
||||
do
|
||||
{
|
||||
if (ListOfExplicitEntriesW[i].Trustee.TrusteeForm == TRUSTEE_IS_NAME &&
|
||||
ListOfExplicitEntriesW[i].Trustee.ptstrName != NULL)
|
||||
{
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
ListOfExplicitEntriesW[i].Trustee.ptstrName);
|
||||
}
|
||||
} while (i-- != 0);
|
||||
|
||||
/* free the allocated array */
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
ListOfExplicitEntriesW);
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetLastError();
|
||||
}
|
||||
}
|
||||
else
|
||||
ListOfExplicitEntriesW = NULL;
|
||||
|
||||
ErrorCode = SetEntriesInAclW(cCountOfExplicitEntries,
|
||||
ListOfExplicitEntriesW,
|
||||
OldAcl,
|
||||
NewAcl);
|
||||
|
||||
/* free the strings */
|
||||
if (ListOfExplicitEntriesW != NULL)
|
||||
{
|
||||
/* free the converted strings */
|
||||
for (i = 0; i != cCountOfExplicitEntries; i++)
|
||||
{
|
||||
if (ListOfExplicitEntriesW[i].Trustee.TrusteeForm == TRUSTEE_IS_NAME)
|
||||
{
|
||||
HeapFree(GetProcessHeap(),
|
||||
0,
|
||||
ListOfExplicitEntriesW[i].Trustee.ptstrName);
|
||||
}
|
||||
}
|
||||
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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue