https://git.reactos.org/?p=reactos.git;a=commitdiff;h=33e6490532bd4d6428868…
commit 33e6490532bd4d6428868f08e0d89ebcca1a65ab
Author: George Bișoc <george.bisoc(a)reactos.org>
AuthorDate: Thu Aug 24 13:01:55 2023 +0200
Commit: George Bișoc <george.bisoc(a)reactos.org>
CommitDate: Fri Aug 25 14:09:14 2023 +0200
[ADVAPI32] Implement AccessCheckByType and AccessCheckByTypeResultList
---
dll/win32/advapi32/advapi32.spec | 2 +-
dll/win32/advapi32/wine/security.c | 237 ++++++++++++++++++++++++++++++++++---
sdk/include/psdk/winbase.h | 32 ++++-
3 files changed, 252 insertions(+), 19 deletions(-)
diff --git a/dll/win32/advapi32/advapi32.spec b/dll/win32/advapi32/advapi32.spec
index 7394948e011..3a02c1362ab 100644
--- a/dll/win32/advapi32/advapi32.spec
+++ b/dll/win32/advapi32/advapi32.spec
@@ -10,7 +10,7 @@
@ stdcall AccessCheckByType(ptr ptr long long ptr long ptr ptr ptr ptr ptr)
@ stdcall AccessCheckByTypeAndAuditAlarmA(str ptr str str ptr ptr long long long ptr long ptr long ptr ptr ptr)
@ stdcall AccessCheckByTypeAndAuditAlarmW(wstr ptr wstr wstr ptr ptr long long long ptr long ptr long ptr ptr ptr)
-@ stub AccessCheckByTypeResultList
+@ stdcall AccessCheckByTypeResultList(ptr ptr long long ptr long ptr ptr ptr ptr ptr)
@ stdcall AccessCheckByTypeResultListAndAuditAlarmA(str ptr str str ptr long long long long ptr long ptr long ptr ptr ptr)
@ stdcall AccessCheckByTypeResultListAndAuditAlarmByHandleA(str ptr ptr str str ptr long long long long ptr long ptr long ptr ptr ptr)
@ stdcall AccessCheckByTypeResultListAndAuditAlarmByHandleW(wstr ptr ptr wstr wstr ptr long long long long ptr long ptr long ptr ptr ptr)
diff --git a/dll/win32/advapi32/wine/security.c b/dll/win32/advapi32/wine/security.c
index 88f122d6d97..5a86b4d65c6 100644
--- a/dll/win32/advapi32/wine/security.c
+++ b/dll/win32/advapi32/wine/security.c
@@ -1696,27 +1696,230 @@ AccessCheck(IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
return TRUE;
}
-/*
- * @unimplemented
+/**
+ * @brief
+ * Determines whether security access can be granted to a client
+ * that requests such access on the object type list. The access
+ * is either granted or denied for the whole object hierarchy
+ * in the list.
+ *
+ * @param[in] pSecurityDescriptor
+ * A pointer to a security descriptor that identifies the security
+ * information of an object being accessed. This function walks
+ * through this descriptor for any ACLs and respective access
+ * rights if access can be granted.
+ *
+ * @param[in] PrincipalSelfSid
+ * A pointer to a principal self SID. This parameter can be NULL if
+ * the associated object being checked for access does not represent
+ * a principal.
+ *
+ * @param[in] ClientToken
+ * A handle to an access token, that identifies the client of which
+ * requests access to the target object.
+ *
+ * @param[in] DesiredAccess
+ * The access right bitmask where the client wants to acquire. This
+ * can be an OR'ed set of multiple access rights or MAXIMUM_ALLOWED
+ * to request all of possible access rights the target object allows.
+ * If only some rights were granted but not all the access is deemed
+ * as denied.
+ *
+ * @param[in] ObjectTypeList
+ * A pointer to a given object type list. If this parameter is not NULL
+ * the function will perform an access check against the main object
+ * and sub-objects of this list. If this parameter is NULL and
+ * ObjectTypeListLength is 0, the function will perform a normal
+ * access check instead.
+ *
+ * @param[in] ObjectTypeListLength
+ * The length of the object type list array, pointed by ObjectTypeList.
+ * This length in question represents the number of elements in such array.
+ * This parameter must be 0 if no array list is provided.
+ *
+ * @param[in] GenericMapping
+ * The generic mapping of access rights of an object type.
+ *
+ * @param[out] PrivilegeSet
+ * A pointer to a set of privileges that were used to perform the
+ * access check, returned to caller. This function will return no
+ * privileges (privilege count set to 0) if no privileges were used
+ * to accomplish the access check. This parameter must not be NULL!
+ *
+ * @param[in,out] PrivilegeSetLength
+ * The total length size of a set of privileges. This length represents
+ * the count of elements in the privilege set array.
+ *
+ * @param[out] GrantedAccess
+ * A pointer to granted access rights, returned to the caller.
+ *
+ * @param[out] AccessStatus
+ * A pointer to a boolean value that indicates whether access is granted
+ * or denied to the client that requests access to the entire hierarchy
+ * of an object type list. If ObjectTypeList is NULL, this value represents
+ * the access that is granted or denied to the target object, just like
+ * in AccessCheck.
+ *
+ * @return
+ * The function returns TRUE if the access check operation has completed
+ * successfully, otherwise it returns FALSE.
+ */
+BOOL
+WINAPI
+AccessCheckByType(
+ _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor,
+ _In_opt_ PSID PrincipalSelfSid,
+ _In_ HANDLE ClientToken,
+ _In_ DWORD DesiredAccess,
+ _In_reads_opt_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList,
+ _In_ DWORD ObjectTypeListLength,
+ _In_ PGENERIC_MAPPING GenericMapping,
+ _Out_writes_bytes_(*PrivilegeSetLength) PPRIVILEGE_SET PrivilegeSet,
+ _Inout_ LPDWORD PrivilegeSetLength,
+ _Out_ LPDWORD GrantedAccess,
+ _Out_ LPBOOL AccessStatus)
+{
+ NTSTATUS Status;
+ NTSTATUS NtAccessStatus;
+
+ Status = NtAccessCheckByType(pSecurityDescriptor,
+ PrincipalSelfSid,
+ ClientToken,
+ DesiredAccess,
+ ObjectTypeList,
+ ObjectTypeListLength,
+ GenericMapping,
+ PrivilegeSet,
+ PrivilegeSetLength,
+ (PACCESS_MASK)GrantedAccess,
+ &NtAccessStatus);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ if (!NT_SUCCESS(NtAccessStatus))
+ {
+ SetLastError(RtlNtStatusToDosError(NtAccessStatus));
+ *AccessStatus = FALSE;
+ }
+ else
+ {
+ *AccessStatus = TRUE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * @brief
+ * Determines whether security access can be granted to a client
+ * that requests such access on the object type list. Unlike the
+ * AccessCheckByType variant, this function will grant or deny
+ * access to each individual object and sub-object in the list.
+ *
+ * @param[in] pSecurityDescriptor
+ * A pointer to a security descriptor that identifies the security
+ * information of an object being accessed. This function walks
+ * through this descriptor for any ACLs and respective access
+ * rights if access can be granted.
+ *
+ * @param[in] PrincipalSelfSid
+ * A pointer to a principal self SID. This parameter can be NULL if
+ * the associated object being checked for access does not represent
+ * a principal.
+ *
+ * @param[in] ClientToken
+ * A handle to an access token, that identifies the client of which
+ * requests access to the target object.
+ *
+ * @param[in] DesiredAccess
+ * The access right bitmask where the client wants to acquire. This
+ * can be an OR'ed set of multiple access rights or MAXIMUM_ALLOWED
+ * to request all of possible access rights the target object allows.
+ * If only some rights were granted but not all the access is deemed
+ * as denied.
+ *
+ * @param[in] ObjectTypeList
+ * A pointer to a given object type list. This function will perform an
+ * access check against the main object and sub-objects of this list.
+ * This parameter must not be NULL!
+ *
+ * @param[in] ObjectTypeListLength
+ * The length of the object type list array, pointed by ObjectTypeList.
+ * This length in question represents the number of elements in such array.
+ * This parameter must be 0 if no array list is provided.
+ *
+ * @param[in] GenericMapping
+ * The generic mapping of access rights of an object type.
+ *
+ * @param[out] PrivilegeSet
+ * A pointer to a set of privileges that were used to perform the
+ * access check, returned to caller. This function will return no
+ * privileges (privilege count set to 0) if no privileges were used
+ * to accomplish the access check. This parameter must not be NULL!
+ *
+ * @param[in,out] PrivilegeSetLength
+ * The total length size of a set of privileges. This length represents
+ * the count of elements in the privilege set array.
+ *
+ * @param[out] GrantedAccess
+ * A pointer to granted access rights. This parameter is an array of granted
+ * rights for the object and each sub-object of an object type list.
+ *
+ * @param[out] AccessStatus
+ * A pointer to a boolean value that indicates whether access is granted
+ * or denied to the client that requests access to the object and sub-objects
+ * of an object type list. This parameter is an array of boolean values for the
+ * object and each individual sub-object of the list.
+ *
+ * @return
+ * The function returns TRUE if the access check operation has completed
+ * successfully, otherwise it returns FALSE.
*/
-BOOL WINAPI AccessCheckByType(
- PSECURITY_DESCRIPTOR pSecurityDescriptor,
- PSID PrincipalSelfSid,
- HANDLE ClientToken,
- DWORD DesiredAccess,
- POBJECT_TYPE_LIST ObjectTypeList,
- DWORD ObjectTypeListLength,
- PGENERIC_MAPPING GenericMapping,
- PPRIVILEGE_SET PrivilegeSet,
- LPDWORD PrivilegeSetLength,
- LPDWORD GrantedAccess,
- LPBOOL AccessStatus)
+BOOL
+WINAPI
+AccessCheckByTypeResultList(
+ _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor,
+ _In_opt_ PSID PrincipalSelfSid,
+ _In_ HANDLE ClientToken,
+ _In_ DWORD DesiredAccess,
+ _In_reads_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList,
+ _In_ DWORD ObjectTypeListLength,
+ _In_ PGENERIC_MAPPING GenericMapping,
+ _Out_writes_bytes_(*PrivilegeSetLength) PPRIVILEGE_SET PrivilegeSet,
+ _Inout_ LPDWORD PrivilegeSetLength,
+ _Out_writes_(ObjectTypeListLength) LPDWORD GrantedAccess,
+ _Out_writes_(ObjectTypeListLength) LPBOOL AccessStatus)
{
- FIXME("stub\n");
+ NTSTATUS Status;
+ DWORD ResultListIndex;
+ PNTSTATUS NtAccessStatus = NULL;
+
+ Status = NtAccessCheckByTypeResultList(pSecurityDescriptor,
+ PrincipalSelfSid,
+ ClientToken,
+ DesiredAccess,
+ ObjectTypeList,
+ ObjectTypeListLength,
+ GenericMapping,
+ PrivilegeSet,
+ PrivilegeSetLength,
+ (PACCESS_MASK)GrantedAccess,
+ NtAccessStatus);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
- *AccessStatus = TRUE;
+ for (ResultListIndex = 0; ResultListIndex < ObjectTypeListLength; ResultListIndex++)
+ {
+ AccessStatus[ResultListIndex] = RtlNtStatusToDosError(NtAccessStatus[ResultListIndex]);
+ }
- return !*AccessStatus;
+ return TRUE;
}
/*
diff --git a/sdk/include/psdk/winbase.h b/sdk/include/psdk/winbase.h
index de0cf891c67..4872e40d98b 100644
--- a/sdk/include/psdk/winbase.h
+++ b/sdk/include/psdk/winbase.h
@@ -1545,7 +1545,37 @@ void WINAPI AddRefActCtx(_Inout_ HANDLE);
_Ret_maybenull_ PVOID WINAPI AddVectoredExceptionHandler(_In_ ULONG, _In_ PVECTORED_EXCEPTION_HANDLER);
_Ret_maybenull_ PVOID WINAPI AddVectoredContinueHandler(_In_ ULONG, _In_ PVECTORED_EXCEPTION_HANDLER);
#endif
-BOOL WINAPI AccessCheckByType(PSECURITY_DESCRIPTOR,PSID,HANDLE,DWORD,POBJECT_TYPE_LIST,DWORD,PGENERIC_MAPPING,PPRIVILEGE_SET,LPDWORD,LPDWORD,LPBOOL);
+
+BOOL
+WINAPI
+AccessCheckByType(
+ _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor,
+ _In_opt_ PSID PrincipalSelfSid,
+ _In_ HANDLE ClientToken,
+ _In_ DWORD DesiredAccess,
+ _In_reads_opt_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList,
+ _In_ DWORD ObjectTypeListLength,
+ _In_ PGENERIC_MAPPING GenericMapping,
+ _Out_writes_bytes_(*PrivilegeSetLength)PPRIVILEGE_SET PrivilegeSet,
+ _Inout_ LPDWORD PrivilegeSetLength,
+ _Out_ LPDWORD GrantedAccess,
+ _Out_ LPBOOL AccessStatus);
+
+BOOL
+WINAPI
+AccessCheckByTypeResultList(
+ _In_ PSECURITY_DESCRIPTOR pSecurityDescriptor,
+ _In_opt_ PSID PrincipalSelfSid,
+ _In_ HANDLE ClientToken,
+ _In_ DWORD DesiredAccess,
+ _In_reads_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList,
+ _In_ DWORD ObjectTypeListLength,
+ _In_ PGENERIC_MAPPING GenericMapping,
+ _Out_writes_bytes_(*PrivilegeSetLength) PPRIVILEGE_SET PrivilegeSet,
+ _Inout_ LPDWORD PrivilegeSetLength,
+ _Out_writes_(ObjectTypeListLength) LPDWORD GrantedAccess,
+ _Out_writes_(ObjectTypeListLength) LPBOOL AccessStatus);
+
BOOL WINAPI AdjustTokenGroups(HANDLE,BOOL,PTOKEN_GROUPS,DWORD,PTOKEN_GROUPS,PDWORD);
BOOL WINAPI AdjustTokenPrivileges(HANDLE,BOOL,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD);
BOOL WINAPI AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY,BYTE,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,PSID*);
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=310563aece3399ad226d4…
commit 310563aece3399ad226d4fb8b8eba9c5fc634c99
Author: unknown <george.bisoc(a)reactos.org>
AuthorDate: Tue Aug 22 22:21:13 2023 +0200
Commit: unknown <george.bisoc(a)reactos.org>
CommitDate: Wed Aug 23 17:54:47 2023 +0200
[NTOS:SE] Let SepGetSidFromAce figure out the ACE type
As the commit title says. Instead of having the caller figuring out what
the ACE type should be of the ACE.
---
ntoskrnl/include/internal/se.h | 1 -
ntoskrnl/se/accesschk.c | 16 ++++++++--------
ntoskrnl/se/debug.c | 2 +-
ntoskrnl/se/sid.c | 12 ++----------
4 files changed, 11 insertions(+), 20 deletions(-)
diff --git a/ntoskrnl/include/internal/se.h b/ntoskrnl/include/internal/se.h
index db32e6bff73..1679d2fe86a 100644
--- a/ntoskrnl/include/internal/se.h
+++ b/ntoskrnl/include/internal/se.h
@@ -634,7 +634,6 @@ SepSidInTokenEx(
PSID
NTAPI
SepGetSidFromAce(
- _In_ UCHAR AceType,
_In_ PACE Ace);
NTSTATUS
diff --git a/ntoskrnl/se/accesschk.c b/ntoskrnl/se/accesschk.c
index d63e07429e8..eaf159f8ce1 100644
--- a/ntoskrnl/se/accesschk.c
+++ b/ntoskrnl/se/accesschk.c
@@ -517,7 +517,7 @@ SepAnalyzeAcesFromDacl(
if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
{
/* Get the SID from this ACE */
- Sid = SepGetSidFromAce(ACCESS_DENIED_ACE_TYPE, CurrentAce);
+ Sid = SepGetSidFromAce(CurrentAce);
ASSERT(Sid);
if (SepSidInTokenEx(AccessToken, PrincipalSelfSid, Sid, TRUE, IsTokenRestricted))
@@ -539,7 +539,7 @@ SepAnalyzeAcesFromDacl(
else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
{
/* Get the SID from this ACE */
- Sid = SepGetSidFromAce(ACCESS_ALLOWED_ACE_TYPE, CurrentAce);
+ Sid = SepGetSidFromAce(CurrentAce);
ASSERT(Sid);
if (SepSidInTokenEx(AccessToken, PrincipalSelfSid, Sid, FALSE, IsTokenRestricted))
@@ -561,7 +561,7 @@ SepAnalyzeAcesFromDacl(
else if (CurrentAce->Header.AceType == ACCESS_DENIED_OBJECT_ACE_TYPE)
{
/* Get the SID and object type from this ACE */
- Sid = SepGetSidFromAce(ACCESS_DENIED_OBJECT_ACE_TYPE, CurrentAce);
+ Sid = SepGetSidFromAce(CurrentAce);
ObjectTypeGuid = SepGetObjectTypeGuidFromAce(CurrentAce, TRUE);
ASSERT(Sid);
@@ -610,7 +610,7 @@ SepAnalyzeAcesFromDacl(
else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_OBJECT_ACE_TYPE)
{
/* Get the SID and object type from this ACE */
- Sid = SepGetSidFromAce(ACCESS_ALLOWED_OBJECT_ACE_TYPE, CurrentAce);
+ Sid = SepGetSidFromAce(CurrentAce);
ObjectTypeGuid = SepGetObjectTypeGuidFromAce(CurrentAce, FALSE);
ASSERT(Sid);
@@ -705,7 +705,7 @@ SepAnalyzeAcesFromDacl(
if (CurrentAce->Header.AceType == ACCESS_DENIED_ACE_TYPE)
{
/* Get the SID from this ACE */
- Sid = SepGetSidFromAce(ACCESS_DENIED_ACE_TYPE, CurrentAce);
+ Sid = SepGetSidFromAce(CurrentAce);
ASSERT(Sid);
if (SepSidInTokenEx(AccessToken, PrincipalSelfSid, Sid, TRUE, IsTokenRestricted))
@@ -735,7 +735,7 @@ SepAnalyzeAcesFromDacl(
else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
{
/* Get the SID from this ACE */
- Sid = SepGetSidFromAce(ACCESS_ALLOWED_ACE_TYPE, CurrentAce);
+ Sid = SepGetSidFromAce(CurrentAce);
ASSERT(Sid);
if (SepSidInTokenEx(AccessToken, PrincipalSelfSid, Sid, FALSE, IsTokenRestricted))
@@ -761,7 +761,7 @@ SepAnalyzeAcesFromDacl(
else if (CurrentAce->Header.AceType == ACCESS_DENIED_OBJECT_ACE_TYPE)
{
/* Get the SID and object type from this ACE */
- Sid = SepGetSidFromAce(ACCESS_DENIED_OBJECT_ACE_TYPE, CurrentAce);
+ Sid = SepGetSidFromAce(CurrentAce);
ObjectTypeGuid = SepGetObjectTypeGuidFromAce(CurrentAce, TRUE);
ASSERT(Sid);
@@ -811,7 +811,7 @@ SepAnalyzeAcesFromDacl(
else if (CurrentAce->Header.AceType == ACCESS_ALLOWED_OBJECT_ACE_TYPE)
{
/* Get the SID and object type from this ACE */
- Sid = SepGetSidFromAce(ACCESS_ALLOWED_OBJECT_ACE_TYPE, CurrentAce);
+ Sid = SepGetSidFromAce(CurrentAce);
ObjectTypeGuid = SepGetObjectTypeGuidFromAce(CurrentAce, FALSE);
ASSERT(Sid);
diff --git a/ntoskrnl/se/debug.c b/ntoskrnl/se/debug.c
index 1f038ac0702..bed647b18b8 100644
--- a/ntoskrnl/se/debug.c
+++ b/ntoskrnl/se/debug.c
@@ -118,7 +118,7 @@ SepDumpAces(
DbgPrint("Ace->Header.AceType -> %s\n", SepGetAceTypeString(Ace->Header.AceType));
DbgPrint("Ace->AccessMask -> 0x%08lx\n", Ace->AccessMask);
- Sid = SepGetSidFromAce(Ace->Header.AceType, Ace);
+ Sid = SepGetSidFromAce(Ace);
ASSERT(Sid);
RtlConvertSidToUnicodeString(&SidString, Sid, TRUE);
DbgPrint("Ace SID -> %wZ\n", &SidString);
diff --git a/ntoskrnl/se/sid.c b/ntoskrnl/se/sid.c
index 033d322d708..6de4b991f3b 100644
--- a/ntoskrnl/se/sid.c
+++ b/ntoskrnl/se/sid.c
@@ -558,13 +558,6 @@ SepSidInToken(
* given access control entry. This identifier
* is valid for the whole of its lifetime.
*
- * @param[in] AceType
- * The type of an access control entry. This
- * type that is given by the calling thread
- * must coincide with the actual ACE that is
- * given in the second parameter otherwise this
- * can potentially lead to UNDEFINED behavior!
- *
* @param[in] Ace
* A pointer to an access control entry, which
* can be obtained from a DACL.
@@ -577,7 +570,6 @@ SepSidInToken(
PSID
NTAPI
SepGetSidFromAce(
- _In_ UCHAR AceType,
_In_ PACE Ace)
{
PULONG Flags;
@@ -589,7 +581,7 @@ SepGetSidFromAce(
ASSERT(Ace);
/* Obtain the SID based upon ACE type */
- switch (AceType)
+ switch (Ace->Header.AceType)
{
case ACCESS_DENIED_ACE_TYPE:
case ACCESS_ALLOWED_ACE_TYPE:
@@ -620,7 +612,7 @@ SepGetSidFromAce(
default:
{
- DPRINT1("SepGetSidFromAce(): Unknown ACE type (Ace 0x%p, Type %u)\n", Ace, AceType);
+ DPRINT1("SepGetSidFromAce(): Unknown ACE type (Ace 0x%p, Type %u)\n", Ace, Ace->Header.AceType);
break;
}
}