Hi,
Welcome to Microsoft Q&A!
When I have ACCESS_DENIED_CALLBACK_OBJECT_ACE in my ACL I do have a call to AuthzAccessCheckCallback function. But when I have ACCESS_ALLOWED_CALLBACK_OBJECT_ACE no calls to AuthzAccessCheckCallback. Is it as intended to be? But in this link it is clearly stated that such call should exists
This is not true. I was able to modify the sample. You could refer to the following code:
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (C) 2022 Microsoft Corporation. All rights reserved.
--*/
#define SECURITY_WIN32
#include<windows.h>
#include<security.h>
#include<lmcons.h>
#include<authz.h>
#include<stdio.h>
#define READ_BUFFER_SIZE 512
#define FirstAce(Acl) ((PVOID)((PUCHAR)(Acl) + sizeof(ACL)))
//
// The callback routines used with AuthZ
//
BOOL
WINAPI
AuthzAccessCheckCallback(
IN AUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext,
IN PACE_HEADER pAce,
IN PVOID pArgs OPTIONAL,
IN OUT PBOOL pbAceApplicable
)
{
wprintf(L"AuthzAccessCheckCallback called\n");
return TRUE;
}
//
// Personal expenditures
//
#define ACCESS_FUND_PERSONAL 0x00000001
//
// Company spending
//
#define ACCESS_FUND_CORPORATE 0x00000002
//
// Transfer to other funds
//
#define ACCESS_FUND_TRANSFER 0x00000004
int main(void)
{
AUTHZ_RESOURCE_MANAGER_HANDLE hAuthzResourceManager;
PACL pDaclFund = NULL;
if (!AuthzInitializeResourceManager(
AUTHZ_RM_FLAG_NO_AUDIT, // no flags
AuthzAccessCheckCallback,
NULL,
NULL,
L"SampRM", // no auditing
&hAuthzResourceManager))
{
wprintf(L"AuthzInitializeResourceManager failed with %u\n", GetLastError());
return 0;
}
else
wprintf(L"AuthzInitializeResourceManager SUCCESS\n");
SECURITY_DESCRIPTOR sd = { 0 };
PSID psidEveryone = NULL;
SID_IDENTIFIER_AUTHORITY siaWorld = SECURITY_WORLD_SID_AUTHORITY;
if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
{
wprintf(L"InitializeSecurityDescriptor failed with %u\n", GetLastError());
return 0;
}
if (!SetSecurityDescriptorGroup(&sd, NULL, FALSE))
{
wprintf(L"SetSecurityDescriptorGroup failed with %u\n", GetLastError());
return 0;
}
if (!SetSecurityDescriptorSacl(&sd, FALSE, NULL, FALSE))
{
wprintf(L"SetSecurityDescriptorSacl failed with %u\n", GetLastError());
return 0;
}
DWORD VPSidBuf[] = { 0x00000501, 0x05000000, 0x00000015, 0x17b85159, 0x255d7266, 0x0b3b6364, 0x00010001 };
DWORD ManagerSidBuf[] = { 0x00000501, 0x05000000, 0x00000015, 0x17b85159, 0x255d7266, 0x0b3b6364, 0x00010002 };
DWORD EmployeeSidBuf[] = { 0x00000501, 0x05000000, 0x00000015, 0x17b85159, 0x255d7266, 0x0b3b6364, 0x00010003 };
PSID VPSid = (PSID)VPSidBuf;
PSID ManagerSid = (PSID)ManagerSidBuf;
PSID EmployeeSid = (PSID)EmployeeSidBuf;
// an owner must be specified. Since VPs are the highest privileged group
// this sample we'll make them the owner.
if (!SetSecurityDescriptorOwner(&sd, VPSid, FALSE))
{
wprintf(L"SetSecurityDescriptorOwnerfailed with %u\n", GetLastError());
return 0;
}
//
// Initialize the DACL for the fund
//
pDaclFund = (PACL)malloc(1024);
InitializeAcl(pDaclFund, 1024, ACL_REVISION_DS);
//
// Add an access-allowed ACE for Everyone
// Only company spending and transfers are allowed for this fund
//
// build EVERYONE SID
if (!AllocateAndInitializeSid(
&siaWorld, 1, SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0,
&psidEveryone
))
{
wprintf(L"AllocateAndInitializeSid with %u\n", GetLastError());
return 0;
}
if (!AddAccessAllowedAce(pDaclFund,
ACL_REVISION_DS,
ACCESS_FUND_CORPORATE | ACCESS_FUND_TRANSFER,
psidEveryone))
{
wprintf(L"AddAccessAllowedAce with %u\n", GetLastError());
return 0;
}
//
// Now set that ACE to a callback ACE
//
((PACE_HEADER)FirstAce(pDaclFund))->AceType =
ACCESS_ALLOWED_CALLBACK_ACE_TYPE;
//
// Add that ACL as the security descriptor's DACL
//
if (!SetSecurityDescriptorDacl(&sd, TRUE, pDaclFund, FALSE))
{
wprintf(L"SetSecurityDescriptorDacl with %u\n", GetLastError());
return 0;
}
AUTHZ_CLIENT_CONTEXT_HANDLE AuthzClient;
LUID luid = { 0x0,0x0 };
HANDLE hToken = NULL;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
wprintf(L"OpenProcessToken failed with %u\n", GetLastError());
return 0;
}
else
wprintf(L"OpenProcessToken SUCCESS\n");
// access check
if (!AuthzInitializeContextFromToken(
0,
hToken,
hAuthzResourceManager,
NULL,
luid,
NULL,
&AuthzClient))
{
wprintf(L"AuthzInitializeContextFromToken failed with %u\n", GetLastError());
return 0;
}
AUTHZ_ACCESS_REQUEST AccessRequest = { 0 };
AUTHZ_ACCESS_REPLY AccessReply = { 0 };
BYTE Buffer[1024];
AccessRequest.DesiredAccess = ACCESS_FUND_PERSONAL | ACCESS_FUND_CORPORATE | ACCESS_FUND_TRANSFER;
AccessRequest.PrincipalSelfSid = NULL;
AccessRequest.ObjectTypeList = NULL;
AccessRequest.ObjectTypeListLength = 0;
AccessRequest.OptionalArguments = NULL;
RtlZeroMemory(Buffer, sizeof(Buffer));
AccessReply.ResultListLength = 1;
AccessReply.GrantedAccessMask = (PACCESS_MASK)(Buffer);
AccessReply.Error = (PDWORD)(Buffer + sizeof(ACCESS_MASK));
if (!AuthzAccessCheck(0,
AuthzClient,
&AccessRequest,
NULL,
&sd,
NULL,
0,
&AccessReply,
NULL))
{
wprintf(L"AuthzAccessCheck failed with %u\n", GetLastError());
return 0;
}
wprintf(L"GRANTED ACCESS MASK: 0x%X\n", *AccessReply.GrantedAccessMask);
AuthzFreeContext(AuthzClient);
if (!AuthzFreeResourceManager(hAuthzResourceManager))
{
wprintf(L"AuthzFreeResourceManager failed with %u\n", GetLastError());
return 0;
}
else
wprintf(L"AuthzFreeResourceManager SUCCESS\n");
FreeSid(psidEveryone);
}
to demonstrate that no ACCESS_DENIED_CALLBACK_OBJECT_ACE
is required in order for ACCESS_ALLOWED_CALLBACK_OBJECT_ACE
to trigger AuthzAccessCheckCallback()
.
It is possible to run AuthzAccessCheck without AuthzAccessCheckCallback in resource?
Yes, you do not need a callback to call AuthzAccessCheck()
.
I suggest you could review the code and if you have further questions, I would suggest you could create an incident with Microsoft for further research.
Best Regards,
Jeanine
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.