mirror of
https://github.com/reactos/reactos.git
synced 2025-06-13 11:38:36 +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
|
RtlAcquireResourceShared@8
|
||||||
RtlAddAccessAllowedAce@16
|
RtlAddAccessAllowedAce@16
|
||||||
RtlAddAccessAllowedAceEx@20
|
RtlAddAccessAllowedAceEx@20
|
||||||
|
RtlAddAccessAllowedObjectAce@28
|
||||||
RtlAddAccessDeniedAce@16
|
RtlAddAccessDeniedAce@16
|
||||||
RtlAddAccessDeniedAceEx@20
|
RtlAddAccessDeniedAceEx@20
|
||||||
|
RtlAddAccessDeniedObjectAce@28
|
||||||
RtlAddAce@20
|
RtlAddAce@20
|
||||||
;RtlAddActionToRXact
|
;RtlAddActionToRXact
|
||||||
RtlAddAtomToAtomTable@12
|
RtlAddAtomToAtomTable@12
|
||||||
;RtlAddAttributeActionToRXact
|
;RtlAddAttributeActionToRXact
|
||||||
RtlAddAuditAccessAce@24
|
RtlAddAuditAccessAce@24
|
||||||
RtlAddAuditAccessAceEx@28
|
RtlAddAuditAccessAceEx@28
|
||||||
|
RtlAddAuditAccessObjectAce@36
|
||||||
;RtlAddCompoundAce
|
;RtlAddCompoundAce
|
||||||
RtlAddRange@36
|
RtlAddRange@36
|
||||||
RtlAddVectoredExceptionHandler@8
|
RtlAddVectoredExceptionHandler@8
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#define WIN32_NO_STATUS
|
#define WIN32_NO_STATUS
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <accctrl.h>
|
#include <accctrl.h>
|
||||||
|
#include <aclapi.h>
|
||||||
#include <sddl.h>
|
#include <sddl.h>
|
||||||
#define NTOS_MODE_USER
|
#define NTOS_MODE_USER
|
||||||
#include <ndk/ntndk.h>
|
#include <ndk/ntndk.h>
|
||||||
|
|
|
@ -166,7 +166,7 @@ AddAccessAllowedAceEx(PACL pAcl,
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
|
@ -179,8 +179,22 @@ AddAccessAllowedObjectAce(
|
||||||
GUID* InheritedObjectTypeGuid,
|
GUID* InheritedObjectTypeGuid,
|
||||||
PSID pSid)
|
PSID pSid)
|
||||||
{
|
{
|
||||||
DPRINT1("%s() not implemented!\n", __FUNCTION__);
|
NTSTATUS Status;
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
|
||||||
|
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
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
|
@ -253,8 +267,22 @@ AddAccessDeniedObjectAce(
|
||||||
GUID* InheritedObjectTypeGuid,
|
GUID* InheritedObjectTypeGuid,
|
||||||
PSID pSid)
|
PSID pSid)
|
||||||
{
|
{
|
||||||
DPRINT1("%s() not implemented!\n", __FUNCTION__);
|
NTSTATUS Status;
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
|
||||||
|
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
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
|
@ -367,8 +395,24 @@ AddAuditAccessObjectAce(
|
||||||
BOOL bAuditSuccess,
|
BOOL bAuditSuccess,
|
||||||
BOOL bAuditFailure)
|
BOOL bAuditFailure)
|
||||||
{
|
{
|
||||||
DPRINT1("%s() not implemented!\n", __FUNCTION__);
|
NTSTATUS Status;
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
|
||||||
|
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
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
@ -565,100 +988,22 @@ SetEntriesInAclA(
|
||||||
PACL OldAcl,
|
PACL OldAcl,
|
||||||
PACL* NewAcl)
|
PACL* NewAcl)
|
||||||
{
|
{
|
||||||
PEXPLICIT_ACCESS_W ListOfExplicitEntriesW;
|
PEXPLICIT_ACCESS_W ListOfExplicitEntriesW = NULL;
|
||||||
ULONG i;
|
|
||||||
DWORD ErrorCode;
|
DWORD ErrorCode;
|
||||||
|
|
||||||
if (cCountOfExplicitEntries != 0)
|
ErrorCode = InternalExplicitAccessAToW(cCountOfExplicitEntries,
|
||||||
{
|
|
||||||
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,
|
pListOfExplicitEntries,
|
||||||
cCountOfExplicitEntries * sizeof(EXPLICIT_ACCESS_W));
|
&ListOfExplicitEntriesW);
|
||||||
|
|
||||||
/* convert the trustee names if required */
|
if (ErrorCode == ERROR_SUCCESS)
|
||||||
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,
|
ErrorCode = SetEntriesInAclW(cCountOfExplicitEntries,
|
||||||
ListOfExplicitEntriesW,
|
ListOfExplicitEntriesW,
|
||||||
OldAcl,
|
OldAcl,
|
||||||
NewAcl);
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* free the allocated array */
|
/* free the allocated array */
|
||||||
HeapFree(GetProcessHeap(),
|
RtlFreeHeap(RtlGetProcessHeap(),
|
||||||
0,
|
0,
|
||||||
ListOfExplicitEntriesW);
|
ListOfExplicitEntriesW);
|
||||||
}
|
}
|
||||||
|
@ -708,7 +1053,7 @@ GetEffectiveRightsFromAclW(IN PACL pacl,
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
DWORD
|
DWORD
|
||||||
STDCALL
|
STDCALL
|
||||||
|
@ -716,8 +1061,24 @@ GetEffectiveRightsFromAclA(IN PACL pacl,
|
||||||
IN PTRUSTEE_A pTrustee,
|
IN PTRUSTEE_A pTrustee,
|
||||||
OUT PACCESS_MASK pAccessRights)
|
OUT PACCESS_MASK pAccessRights)
|
||||||
{
|
{
|
||||||
DPRINT1("%s() not implemented!\n", __FUNCTION__);
|
PTRUSTEE_W pTrusteeW = NULL;
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
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
|
DWORD
|
||||||
STDCALL
|
STDCALL
|
||||||
|
@ -746,8 +1107,25 @@ GetAuditedPermissionsFromAclA(IN PACL pacl,
|
||||||
OUT PACCESS_MASK pSuccessfulAuditedRights,
|
OUT PACCESS_MASK pSuccessfulAuditedRights,
|
||||||
OUT PACCESS_MASK pFailedAuditRights)
|
OUT PACCESS_MASK pFailedAuditRights)
|
||||||
{
|
{
|
||||||
DPRINT1("%s() not implemented!\n", __FUNCTION__);
|
PTRUSTEE_W pTrusteeW = NULL;
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
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 */
|
/* EOF */
|
||||||
|
|
|
@ -490,9 +490,9 @@ STDCALL
|
||||||
BuildSecurityDescriptorW(IN PTRUSTEE_W pOwner OPTIONAL,
|
BuildSecurityDescriptorW(IN PTRUSTEE_W pOwner OPTIONAL,
|
||||||
IN PTRUSTEE_W pGroup OPTIONAL,
|
IN PTRUSTEE_W pGroup OPTIONAL,
|
||||||
IN ULONG cCountOfAccessEntries,
|
IN ULONG cCountOfAccessEntries,
|
||||||
IN PEXPLICIT_ACCESS pListOfAccessEntries OPTIONAL,
|
IN PEXPLICIT_ACCESS_W pListOfAccessEntries OPTIONAL,
|
||||||
IN ULONG cCountOfAuditEntries,
|
IN ULONG cCountOfAuditEntries,
|
||||||
IN PEXPLICIT_ACCESS pListOfAuditEntries OPTIONAL,
|
IN PEXPLICIT_ACCESS_W pListOfAuditEntries OPTIONAL,
|
||||||
IN PSECURITY_DESCRIPTOR pOldSD OPTIONAL,
|
IN PSECURITY_DESCRIPTOR pOldSD OPTIONAL,
|
||||||
OUT PULONG pSizeNewSD,
|
OUT PULONG pSizeNewSD,
|
||||||
OUT PSECURITY_DESCRIPTOR* pNewSD)
|
OUT PSECURITY_DESCRIPTOR* pNewSD)
|
||||||
|
@ -510,9 +510,9 @@ STDCALL
|
||||||
BuildSecurityDescriptorA(IN PTRUSTEE_A pOwner OPTIONAL,
|
BuildSecurityDescriptorA(IN PTRUSTEE_A pOwner OPTIONAL,
|
||||||
IN PTRUSTEE_A pGroup OPTIONAL,
|
IN PTRUSTEE_A pGroup OPTIONAL,
|
||||||
IN ULONG cCountOfAccessEntries,
|
IN ULONG cCountOfAccessEntries,
|
||||||
IN PEXPLICIT_ACCESS pListOfAccessEntries OPTIONAL,
|
IN PEXPLICIT_ACCESS_A pListOfAccessEntries OPTIONAL,
|
||||||
IN ULONG cCountOfAuditEntries,
|
IN ULONG cCountOfAuditEntries,
|
||||||
IN PEXPLICIT_ACCESS pListOfAuditEntries OPTIONAL,
|
IN PEXPLICIT_ACCESS_A pListOfAuditEntries OPTIONAL,
|
||||||
IN PSECURITY_DESCRIPTOR pOldSD OPTIONAL,
|
IN PSECURITY_DESCRIPTOR pOldSD OPTIONAL,
|
||||||
OUT PULONG pSizeNewSD,
|
OUT PULONG pSizeNewSD,
|
||||||
OUT PSECURITY_DESCRIPTOR* pNewSD)
|
OUT PSECURITY_DESCRIPTOR* pNewSD)
|
||||||
|
|
|
@ -157,6 +157,136 @@ AccpGetAceAccessMask(IN PACE_HEADER AceHeader)
|
||||||
return *((PACCESS_MASK)(AceHeader + 1));
|
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
|
* AccRewriteGetHandleRights EXPORTED
|
||||||
|
@ -925,6 +1055,8 @@ AccRewriteGetExplicitEntriesFromAcl(PACL pacl,
|
||||||
{
|
{
|
||||||
PACE_HEADER AceHeader;
|
PACE_HEADER AceHeader;
|
||||||
PSID Sid, SidTarget;
|
PSID Sid, SidTarget;
|
||||||
|
ULONG ObjectAceCount = 0;
|
||||||
|
POBJECTS_AND_SID ObjSid;
|
||||||
SIZE_T Size;
|
SIZE_T Size;
|
||||||
PEXPLICIT_ACCESS_W peaw;
|
PEXPLICIT_ACCESS_W peaw;
|
||||||
DWORD LastErr, SidLen;
|
DWORD LastErr, SidLen;
|
||||||
|
@ -947,10 +1079,15 @@ AccRewriteGetExplicitEntriesFromAcl(PACL pacl,
|
||||||
{
|
{
|
||||||
Sid = AccpGetAceSid(AceHeader);
|
Sid = AccpGetAceSid(AceHeader);
|
||||||
Size += GetLengthSid(Sid);
|
Size += GetLengthSid(Sid);
|
||||||
/* FIXME - take size of opaque data in account? */
|
|
||||||
|
if (AccpIsObjectAce(AceHeader))
|
||||||
|
ObjectAceCount++;
|
||||||
|
|
||||||
AceIndex++;
|
AceIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Size += ObjectAceCount * sizeof(OBJECTS_AND_SID);
|
||||||
|
|
||||||
ASSERT(pacl->AceCount == AceIndex);
|
ASSERT(pacl->AceCount == AceIndex);
|
||||||
|
|
||||||
/* allocate the array */
|
/* allocate the array */
|
||||||
|
@ -959,7 +1096,8 @@ AccRewriteGetExplicitEntriesFromAcl(PACL pacl,
|
||||||
if (peaw != NULL)
|
if (peaw != NULL)
|
||||||
{
|
{
|
||||||
AceIndex = 0;
|
AceIndex = 0;
|
||||||
SidTarget = (PSID)(peaw + pacl->AceCount);
|
ObjSid = (POBJECTS_AND_SID)(peaw + pacl->AceCount);
|
||||||
|
SidTarget = (PSID)(ObjSid + ObjectAceCount);
|
||||||
|
|
||||||
/* initialize the array */
|
/* initialize the array */
|
||||||
while (GetAce(pacl,
|
while (GetAce(pacl,
|
||||||
|
@ -976,9 +1114,21 @@ AccRewriteGetExplicitEntriesFromAcl(PACL pacl,
|
||||||
if (CopySid(SidLen,
|
if (CopySid(SidLen,
|
||||||
SidTarget,
|
SidTarget,
|
||||||
Sid))
|
Sid))
|
||||||
|
{
|
||||||
|
if (AccpIsObjectAce(AceHeader))
|
||||||
|
{
|
||||||
|
BuildTrusteeWithObjectsAndSid(&peaw[AceIndex].Trustee,
|
||||||
|
ObjSid++,
|
||||||
|
AccpGetObjectAceObjectType(AceHeader),
|
||||||
|
AccpGetObjectAceInheritedObjectType(AceHeader),
|
||||||
|
SidTarget);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
BuildTrusteeWithSid(&peaw[AceIndex].Trustee,
|
BuildTrusteeWithSid(&peaw[AceIndex].Trustee,
|
||||||
SidTarget);
|
SidTarget);
|
||||||
|
}
|
||||||
|
|
||||||
SidTarget = (PSID)((ULONG_PTR)SidTarget + SidLen);
|
SidTarget = (PSID)((ULONG_PTR)SidTarget + SidLen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -455,6 +455,19 @@ RtlAddAccessAllowedAceEx(
|
||||||
IN PSID pSid
|
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
|
NTSYSAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -479,14 +492,14 @@ RtlAddAccessDeniedAceEx(
|
||||||
NTSYSAPI
|
NTSYSAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlAddAuditAccessAceEx(
|
RtlAddAccessDeniedObjectAce(
|
||||||
IN OUT PACL Acl,
|
IN OUT PACL pAcl,
|
||||||
IN ULONG Revision,
|
IN ULONG dwAceRevision,
|
||||||
IN ULONG Flags,
|
IN ULONG AceFlags,
|
||||||
IN ACCESS_MASK AccessMask,
|
IN ULONG AccessMask,
|
||||||
IN PSID Sid,
|
IN GUID *ObjectTypeGuid OPTIONAL,
|
||||||
IN BOOLEAN Success,
|
IN GUID *InheritedObjectTypeGuid OPTIONAL,
|
||||||
IN BOOLEAN Failure
|
IN PSID pSid
|
||||||
);
|
);
|
||||||
|
|
||||||
NTSYSAPI
|
NTSYSAPI
|
||||||
|
@ -512,6 +525,34 @@ RtlAddAuditAccessAce(
|
||||||
BOOLEAN Failure
|
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
|
NTSYSAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
|
|
|
@ -225,7 +225,7 @@ typedef DWORD FLONG;
|
||||||
#define NO_PROPAGATE_INHERIT_ACE 4
|
#define NO_PROPAGATE_INHERIT_ACE 4
|
||||||
#define INHERIT_ONLY_ACE 8
|
#define INHERIT_ONLY_ACE 8
|
||||||
#define INHERITED_ACE 10
|
#define INHERITED_ACE 10
|
||||||
#define VALID_INHERIT_FLAGS 16
|
#define VALID_INHERIT_FLAGS 0x1F
|
||||||
#define SUCCESSFUL_ACCESS_ACE_FLAG 64
|
#define SUCCESSFUL_ACCESS_ACE_FLAG 64
|
||||||
#define FAILED_ACCESS_ACE_FLAG 128
|
#define FAILED_ACCESS_ACE_FLAG 128
|
||||||
#define DELETE 0x00010000L
|
#define DELETE 0x00010000L
|
||||||
|
|
|
@ -103,14 +103,40 @@ RtlpAddKnownAce (PACL Acl,
|
||||||
ULONG Revision,
|
ULONG Revision,
|
||||||
ULONG Flags,
|
ULONG Flags,
|
||||||
ACCESS_MASK AccessMask,
|
ACCESS_MASK AccessMask,
|
||||||
|
GUID *ObjectTypeGuid OPTIONAL,
|
||||||
|
GUID *InheritedObjectTypeGuid OPTIONAL,
|
||||||
PSID Sid,
|
PSID Sid,
|
||||||
ULONG Type)
|
ULONG Type)
|
||||||
{
|
{
|
||||||
PACE Ace;
|
PACE Ace;
|
||||||
ULONG InvalidFlags;
|
PSID SidStart;
|
||||||
|
ULONG AceSize, InvalidFlags;
|
||||||
|
ULONG AceObjectFlags = 0;
|
||||||
|
|
||||||
PAGED_CODE_RTL();
|
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))
|
if (!RtlValidSid(Sid))
|
||||||
{
|
{
|
||||||
return(STATUS_INVALID_SID);
|
return(STATUS_INVALID_SID);
|
||||||
|
@ -126,11 +152,17 @@ RtlpAddKnownAce (PACL Acl,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate the flags */
|
/* 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 |
|
InvalidFlags = Flags & ~(VALID_INHERIT_FLAGS |
|
||||||
SUCCESSFUL_ACCESS_ACE_FLAG | FAILED_ACCESS_ACE_FLAG);
|
SUCCESSFUL_ACCESS_ACE_FLAG | FAILED_ACCESS_ACE_FLAG);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
InvalidFlags = Flags & ~VALID_INHERIT_FLAGS;
|
InvalidFlags = Flags & ~VALID_INHERIT_FLAGS;
|
||||||
|
}
|
||||||
|
|
||||||
if (InvalidFlags != 0)
|
if (InvalidFlags != 0)
|
||||||
{
|
{
|
||||||
|
@ -145,16 +177,69 @@ RtlpAddKnownAce (PACL Acl,
|
||||||
{
|
{
|
||||||
return(STATUS_ALLOTTED_SPACE_EXCEEDED);
|
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)
|
(ULONG_PTR)Acl + Acl->AclSize)
|
||||||
{
|
{
|
||||||
return(STATUS_ALLOTTED_SPACE_EXCEEDED);
|
return(STATUS_ALLOTTED_SPACE_EXCEEDED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* initialize the header and common fields */
|
||||||
Ace->Header.AceFlags = Flags;
|
Ace->Header.AceFlags = Flags;
|
||||||
Ace->Header.AceType = Type;
|
Ace->Header.AceType = Type;
|
||||||
Ace->Header.AceSize = RtlLengthSid(Sid) + sizeof(ACE);
|
Ace->Header.AceSize = (WORD)AceSize;
|
||||||
Ace->AccessMask = AccessMask;
|
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->AceCount++;
|
||||||
Acl->AclRevision = Revision;
|
Acl->AclRevision = Revision;
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -176,6 +261,8 @@ RtlAddAccessAllowedAce (IN OUT PACL Acl,
|
||||||
Revision,
|
Revision,
|
||||||
0,
|
0,
|
||||||
AccessMask,
|
AccessMask,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
Sid,
|
Sid,
|
||||||
ACCESS_ALLOWED_ACE_TYPE);
|
ACCESS_ALLOWED_ACE_TYPE);
|
||||||
}
|
}
|
||||||
|
@ -197,11 +284,46 @@ RtlAddAccessAllowedAceEx (IN OUT PACL Acl,
|
||||||
Revision,
|
Revision,
|
||||||
Flags,
|
Flags,
|
||||||
AccessMask,
|
AccessMask,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
Sid,
|
Sid,
|
||||||
ACCESS_ALLOWED_ACE_TYPE);
|
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
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
@ -217,6 +339,8 @@ RtlAddAccessDeniedAce (PACL Acl,
|
||||||
Revision,
|
Revision,
|
||||||
0,
|
0,
|
||||||
AccessMask,
|
AccessMask,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
Sid,
|
Sid,
|
||||||
ACCESS_DENIED_ACE_TYPE);
|
ACCESS_DENIED_ACE_TYPE);
|
||||||
}
|
}
|
||||||
|
@ -238,11 +362,46 @@ RtlAddAccessDeniedAceEx (IN OUT PACL Acl,
|
||||||
Revision,
|
Revision,
|
||||||
Flags,
|
Flags,
|
||||||
AccessMask,
|
AccessMask,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
Sid,
|
Sid,
|
||||||
ACCESS_DENIED_ACE_TYPE);
|
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
|
static VOID
|
||||||
RtlpAddData(PVOID AceList,
|
RtlpAddData(PVOID AceList,
|
||||||
ULONG AceListLength,
|
ULONG AceListLength,
|
||||||
|
@ -363,6 +522,8 @@ RtlAddAuditAccessAce(PACL Acl,
|
||||||
Revision,
|
Revision,
|
||||||
Flags,
|
Flags,
|
||||||
AccessMask,
|
AccessMask,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
Sid,
|
Sid,
|
||||||
SYSTEM_AUDIT_ACE_TYPE);
|
SYSTEM_AUDIT_ACE_TYPE);
|
||||||
}
|
}
|
||||||
|
@ -394,11 +555,56 @@ RtlAddAuditAccessAceEx(PACL Acl,
|
||||||
Revision,
|
Revision,
|
||||||
Flags,
|
Flags,
|
||||||
AccessMask,
|
AccessMask,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
Sid,
|
Sid,
|
||||||
SYSTEM_AUDIT_ACE_TYPE);
|
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
|
static VOID
|
||||||
RtlpDeleteData(PVOID Ace,
|
RtlpDeleteData(PVOID Ace,
|
||||||
ULONG AceSize,
|
ULONG AceSize,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue