bug 1467 : patch from w3seek, ACLs: Implement audit functions

svn path=/trunk/; revision=21875
This commit is contained in:
Magnus Olsen 2006-05-10 09:32:23 +00:00
parent 27a4da82e1
commit c74cbfaf67
8 changed files with 907 additions and 128 deletions

View 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

View 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>

View 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,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 */

View 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)

View 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

View 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

View 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

View 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,