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*);