- Implemented RtlAddAccessAllowedAce, RtlAddAccessDeniedAce,
RtlAddAce, RtlValidAcl.
- Added the corresponding functions in advapi32.
- Grouped the ACL functions in advapi32.
diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec
index 3116e98..8d8e152 100644
--- a/dlls/advapi32/advapi32.spec
+++ b/dlls/advapi32/advapi32.spec
@@ -6,8 +6,8 @@
@ stub AccessCheckByType #(ptr ptr long long ptr long ptr ptr ptr ptr ptr) AccessCheckByType
@ stdcall AddAccessAllowedAce (ptr long long ptr)
@ stub AddAccessAllowedAceEx #(ptr long long long ptr) AddAccessAllowedAceEx
-@ stub AddAccessDeniedAce
-@ stub AddAce
+@ stdcall AddAccessDeniedAce(ptr long long ptr)
+@ stdcall AddAce(ptr long long ptr long)
@ stub AddAuditAccessAce
@ stub AdjustTokenGroups
@ stdcall AdjustTokenPrivileges(long long ptr long ptr ptr)
@@ -87,7 +87,7 @@
@ stdcall EnumServicesStatusW (long long long ptr long ptr ptr ptr)
@ stdcall EqualPrefixSid(ptr ptr)
@ stdcall EqualSid(ptr ptr)
-@ stub FindFirstFreeAce
+@ stdcall FindFirstFreeAce(ptr ptr)
@ stdcall FreeSid(ptr)
@ stdcall GetAce(ptr long ptr)
@ stub GetAclInformation
@@ -135,7 +135,7 @@
@ stub IsProcessRestricted
@ stdcall IsTextUnicode(ptr long ptr) ntdll.RtlIsTextUnicode
@ stub IsTokenRestricted
-@ stub IsValidAcl
+@ stdcall IsValidAcl(ptr)
@ stdcall IsValidSecurityDescriptor(ptr)
@ stdcall IsValidSid(ptr)
@ stdcall LockServiceDatabase(ptr)
diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c
index be32689..398913f 100644
--- a/dlls/advapi32/security.c
+++ b/dlls/advapi32/security.c
@@ -651,6 +651,67 @@
CallWin32ToNt (RtlCreateAcl(acl, size, rev));
}
+/******************************************************************************
+ * AddAccessAllowedAce [ADVAPI32.@]
+ */
+BOOL WINAPI AddAccessAllowedAce(
+ IN OUT PACL pAcl,
+ IN DWORD dwAceRevision,
+ IN DWORD AccessMask,
+ IN PSID pSid)
+{
+ CallWin32ToNt(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
+}
+
+/******************************************************************************
+ * AddAccessDeniedAce [ADVAPI32.@]
+ */
+BOOL WINAPI AddAccessDeniedAce(
+ IN OUT PACL pAcl,
+ IN DWORD dwAceRevision,
+ IN DWORD AccessMask,
+ IN PSID pSid)
+{
+ CallWin32ToNt(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
+}
+
+/******************************************************************************
+ * AddAccessDeniedAce [ADVAPI32.@]
+ */
+BOOL WINAPI AddAce(
+ IN OUT PACL pAcl,
+ IN DWORD dwAceRevision,
+ IN DWORD dwStartingAceIndex,
+ LPVOID pAceList,
+ DWORD nAceListLength)
+{
+ CallWin32ToNt(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
+}
+
+/******************************************************************************
+ * FindFirstFreeAce [ADVAPI32.@]
+ */
+BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
+{
+ return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
+}
+
+/******************************************************************************
+ * GetAce [ADVAPI32.@]
+ */
+BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
+{
+ CallWin32ToNt(RtlGetAce(pAcl, dwAceIndex, pAce));
+}
+
+/******************************************************************************
+ * IsValidAcl [ADVAPI32.@]
+ */
+BOOL WINAPI IsValidAcl(IN PACL pAcl)
+{
+ return RtlValidAcl(pAcl);
+}
+
/* ##############################
###### MISC FUNCTIONS ######
##############################
@@ -1108,18 +1169,6 @@
}
/******************************************************************************
- * AddAccessAllowedAce [ADVAPI32.@]
- */
-BOOL WINAPI AddAccessAllowedAce(
- IN OUT PACL pAcl,
- IN DWORD dwAceRevision,
- IN DWORD AccessMask,
- IN PSID pSid)
-{
- return RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid);
-}
-
-/******************************************************************************
* LookupAccountNameA [ADVAPI32.@]
*/
BOOL WINAPI
@@ -1137,14 +1186,6 @@
}
/******************************************************************************
- * GetAce [ADVAPI32.@]
- */
-BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
-{
- CallWin32ToNt(RtlGetAce(pAcl, dwAceIndex, pAce));
-}
-
-/******************************************************************************
* PrivilegeCheck [ADVAPI32.@]
*/
BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index b77276e..0506d69 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -268,8 +268,8 @@
@ stdcall RtlAcquirePebLock()
@ stdcall RtlAcquireResourceExclusive(ptr long)
@ stdcall RtlAcquireResourceShared(ptr long)
-@ stdcall RtlAddAccessAllowedAce(long long long long)
-@ stub RtlAddAccessDeniedAce
+@ stdcall RtlAddAccessAllowedAce(ptr long long ptr)
+@ stdcall RtlAddAccessDeniedAce(ptr long long ptr)
@ stdcall RtlAddAce(ptr long long ptr long)
@ stub RtlAddActionToRXact
@ stub RtlAddAttributeActionToRXact
@@ -561,7 +561,7 @@
@ stdcall RtlUpperString(ptr ptr)
@ stub RtlUsageHeap
@ cdecl -i386 -norelay RtlUshortByteSwap() NTDLL_RtlUshortByteSwap
-@ stub RtlValidAcl
+@ stdcall RtlValidAcl(ptr)
@ stdcall RtlValidSecurityDescriptor(ptr)
@ stdcall RtlValidSid(ptr)
@ stdcall RtlValidateHeap(long long ptr)
diff --git a/dlls/ntdll/sec.c b/dlls/ntdll/sec.c
index 9b5a8bd..4b718c4 100644
--- a/dlls/ntdll/sec.c
+++ b/dlls/ntdll/sec.c
@@ -314,8 +314,7 @@
* TRUE if pSid is valid,
* FALSE otherwise.
*/
-BOOL WINAPI
-RtlValidSid( PSID pSid )
+BOOLEAN WINAPI RtlValidSid( PSID pSid )
{
BOOL ret;
__TRY
@@ -711,15 +710,122 @@
/******************************************************************************
* RtlAddAccessAllowedAce [NTDLL.@]
*/
-BOOL WINAPI RtlAddAccessAllowedAce(
+NTSTATUS WINAPI RtlAddAccessAllowedAce(
IN OUT PACL pAcl,
IN DWORD dwAceRevision,
IN DWORD AccessMask,
IN PSID pSid)
{
- FIXME("(%p,0x%08lx,0x%08lx,%p),stub!\n",
- pAcl, dwAceRevision, AccessMask, pSid);
- return TRUE;
+ DWORD dwLengthSid;
+ ACCESS_ALLOWED_ACE * pAaAce;
+ DWORD dwSpaceLeft;
+
+ TRACE("(%p,0x%08lx,0x%08lx,%p)\n",
+ pAcl, dwAceRevision, AccessMask, pSid);
+
+ if (!RtlValidSid(pSid))
+ return STATUS_INVALID_SID;
+ if (!RtlValidAcl(pAcl))
+ return STATUS_INVALID_ACL;
+
+ dwLengthSid = RtlLengthSid(pSid);
+ if (!RtlFirstFreeAce(pAcl, (PACE_HEADER *) &pAaAce))
+ return STATUS_INVALID_ACL;
+
+ if (!pAaAce)
+ return STATUS_ALLOTTED_SPACE_EXCEEDED;
+
+ dwSpaceLeft = (DWORD)pAcl + pAcl->AclSize - (DWORD)pAaAce;
+ if (dwSpaceLeft < sizeof(*pAaAce) - sizeof(pAaAce->SidStart) + dwLengthSid)
+ return STATUS_ALLOTTED_SPACE_EXCEEDED;
+
+ pAaAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
+ pAaAce->Header.AceFlags = 0;
+ pAaAce->Header.AceSize = sizeof(*pAaAce) - sizeof(pAaAce->SidStart) + dwLengthSid;
+ pAaAce->Mask = AccessMask;
+ pAcl->AceCount++;
+ RtlCopySid(dwLengthSid, (PSID)&pAaAce->SidStart, pSid);
+ return STATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * RtlAddAccessDeniedAce [NTDLL.@]
+ */
+NTSTATUS WINAPI RtlAddAccessDeniedAce(
+ IN OUT PACL pAcl,
+ IN DWORD dwAceRevision,
+ IN DWORD AccessMask,
+ IN PSID pSid)
+{
+ DWORD dwLengthSid;
+ DWORD dwSpaceLeft;
+ ACCESS_DENIED_ACE * pAdAce;
+
+ TRACE("(%p,0x%08lx,0x%08lx,%p)\n",
+ pAcl, dwAceRevision, AccessMask, pSid);
+
+ if (!RtlValidSid(pSid))
+ return STATUS_INVALID_SID;
+ if (!RtlValidAcl(pAcl))
+ return STATUS_INVALID_ACL;
+
+ dwLengthSid = RtlLengthSid(pSid);
+ if (!RtlFirstFreeAce(pAcl, (PACE_HEADER *) &pAdAce))
+ return STATUS_INVALID_ACL;
+
+ if (!pAdAce)
+ return STATUS_ALLOTTED_SPACE_EXCEEDED;
+
+ dwSpaceLeft = (DWORD)pAcl + pAcl->AclSize - (DWORD)pAdAce;
+ if (dwSpaceLeft < sizeof(*pAdAce) - sizeof(pAdAce->SidStart) + dwLengthSid)
+ return STATUS_ALLOTTED_SPACE_EXCEEDED;
+
+ pAdAce->Header.AceType = ACCESS_DENIED_ACE_TYPE;
+ pAdAce->Header.AceFlags = 0;
+ pAdAce->Header.AceSize = sizeof(*pAdAce) - sizeof(pAdAce->SidStart) + dwLengthSid;
+ pAdAce->Mask = AccessMask;
+ pAcl->AceCount++;
+ RtlCopySid(dwLengthSid, (PSID)&pAdAce->SidStart, pSid);
+ return STATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * RtlValidAcl [NTDLL.@]
+ */
+BOOLEAN WINAPI RtlValidAcl(PACL pAcl)
+{
+ BOOLEAN ret;
+ TRACE("(%p)\n", pAcl);
+
+ __TRY
+ {
+ PACE_HEADER ace;
+ int i;
+
+ if (pAcl->AclRevision != ACL_REVISION)
+ ret = FALSE;
+ else
+ {
+ ace = (PACE_HEADER)(pAcl+1);
+ ret = TRUE;
+ for (i=0;i<=pAcl->AceCount;i++)
+ {
+ if ((char *)ace > (char *)pAcl + pAcl->AclSize)
+ {
+ ret = FALSE;
+ break;
+ }
+ ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
+ }
+ }
+ }
+ __EXCEPT(page_fault)
+ {
+ WARN("(%p): invalid pointer!\n", pAcl);
+ return 0;
+ }
+ __ENDTRY
+ return ret;
}
/******************************************************************************
@@ -727,8 +833,20 @@
*/
DWORD WINAPI RtlGetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
{
- FIXME("(%p,%ld,%p),stub!\n",pAcl,dwAceIndex,pAce);
- return 0;
+ PACE_HEADER ace;
+
+ TRACE("(%p,%ld,%p)\n",pAcl,dwAceIndex,pAce);
+
+ if ((dwAceIndex < 0) || (dwAceIndex > pAcl->AceCount))
+ return STATUS_INVALID_PARAMETER;
+
+ ace = (PACE_HEADER)(pAcl + 1);
+ for (;dwAceIndex;dwAceIndex--)
+ ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
+
+ *pAce = (LPVOID) ace;
+
+ return STATUS_SUCCESS;
}
/*
diff --git a/include/winternl.h b/include/winternl.h
index 53efe3c..95b6a26 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -918,8 +918,9 @@
BYTE WINAPI RtlAcquireResourceExclusive(LPRTL_RWLOCK,BYTE);
BYTE WINAPI RtlAcquireResourceShared(LPRTL_RWLOCK,BYTE);
NTSTATUS WINAPI RtlAddAce(PACL,DWORD,DWORD,PACE_HEADER,DWORD);
-BOOL WINAPI RtlAddAccessAllowedAce(PACL,DWORD,DWORD,PSID);
+NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL,DWORD,DWORD,PSID);
BOOL WINAPI RtlAddAccessAllowedAceEx(PACL,DWORD,DWORD,DWORD,PSID);
+NTSTATUS WINAPI RtlAddAccessDeniedAce(PACL,DWORD,DWORD,PSID);
DWORD WINAPI RtlAdjustPrivilege(DWORD,DWORD,DWORD,DWORD);
BOOLEAN WINAPI RtlAllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY,BYTE,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,PSID *);
PVOID WINAPI RtlAllocateHeap(HANDLE,ULONG,ULONG);
@@ -1131,7 +1132,8 @@
void WINAPI RtlUpperString(STRING *,const STRING *);
NTSTATUS WINAPI RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR);
-BOOL WINAPI RtlValidSid(PSID);
+BOOLEAN WINAPI RtlValidAcl(PACL);
+BOOLEAN WINAPI RtlValidSid(PSID);
BOOLEAN WINAPI RtlValidateHeap(HANDLE,ULONG,LPCVOID);
NTSTATUS WINAPI RtlWalkHeap(HANDLE,PVOID);