https://git.reactos.org/?p=reactos.git;a=commitdiff;h=33e6490532bd4d6428868f...
commit 33e6490532bd4d6428868f08e0d89ebcca1a65ab Author: George Bișoc george.bisoc@reactos.org AuthorDate: Thu Aug 24 13:01:55 2023 +0200 Commit: George Bișoc george.bisoc@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*);