windows-nt/Source/XPSP1/NT/ds/security/authz/test/samplerm/main.c

537 lines
14 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
#include "pch.h"
#include "samplerm.h"
void _cdecl wmain( int argc, WCHAR * argv[] )
{
NTSTATUS Status = STATUS_SUCCESS;
BOOL b = TRUE;
DWORD DesiredAccess;
DWORD Callback;
DWORD Iteration;
AUTHZ_RESOURCE_MANAGER_HANDLE hRM = NULL;
HANDLE hToken = NULL;
LUID luid = {0xdead,0xbeef};
AUTHZ_CLIENT_CONTEXT_HANDLE hCC1 = NULL;
AUTHZ_CLIENT_CONTEXT_HANDLE hCC2 = NULL;
AUTHZ_CLIENT_CONTEXT_HANDLE hCC3 = NULL;
AUTHZ_ACCESS_REQUEST Request;
PAUTHZ_ACCESS_REPLY pReply = (PAUTHZ_ACCESS_REPLY) Buffer;
PSECURITY_DESCRIPTOR pSD = NULL;
DWORD dwErr;
ULONG i = 0, jj = 0;
PACE_HEADER Ace = NULL;
DWORD AceCount = 0;
DWORD Len = 0;
SID_AND_ATTRIBUTES SidAttr[1];
AUTHZ_AUDIT_INFO_HANDLE hAuditInfo = NULL;
AUTHZ_RM_AUDIT_INFO_HANDLE hRmAuditInfo;
PAUDIT_PARAMS pAuditParams;
AUTHZ_HANDLE AuthHandle = 0;
PACL pAcl = NULL;
AUDIT_EVENT_INFO AuditEventInfo;
PSID pUserSid = NULL;
AUTHZ_AUDIT_QUEUE_HANDLE hQueue;
PWCHAR StringSD = L"O:BAG:DUD:(A;;0x40;;;s-1-2-2)(A;;0x1;;;BA)(OA;;0x2;6da8a4ff-0e52-11d0-a286-00aa00304900;;BA)(OA;;0x4;6da8a4ff-0e52-11d0-a286-00aa00304901;;BA)(OA;;0x8;6da8a4ff-0e52-11d0-a286-00aa00304903;;AU)(OA;;0x10;6da8a4ff-0e52-11d0-a286-00aa00304904;;BU)(OA;;0x20;6da8a4ff-0e52-11d0-a286-00aa00304905;;AU)(A;;0x40;;;PS)S:(AU;IDSAFA;0xFFFFFF;;;WD)";
//PWCHAR StringSD = L"O:BAG:DUD:(A;;0x100;;;SY)(A;;0x100;;;PS)S:(AU;IDSA;SD;;;DU)";
if (argc != 4)
{
wprintf(L"usage: %s access iter [callback]\n", argv[0]);
exit(0);
}
DesiredAccess = wcstol(argv[1], NULL, 16);
Iteration = wcstol(argv[2], NULL, 16);
Callback = wcstol(argv[3], NULL, 16);
//
// Create the SD for the access checks
//
b = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSD, SDDL_REVISION_1, &pSD, NULL);
if (!b)
{
wprintf(L"SDDL failed with %d\n", GetLastError());
return;
}
//
// If Callback aces are specified, change the DACL to use them
//
if (Callback)
{
pAcl = RtlpDaclAddrSecurityDescriptor((PISECURITY_DESCRIPTOR) pSD);
AceCount = pAcl->AceCount;
for (i = 0, Ace = FirstAce(pAcl); i < AceCount; i++, Ace = NextAce(Ace))
{
switch(Ace->AceType)
{
case ACCESS_ALLOWED_ACE_TYPE:
Ace->AceType = ACCESS_ALLOWED_CALLBACK_ACE_TYPE;
break;
case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
Ace->AceType = ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE;
break;
}
}
}
AuditEventInfo.Version = AUDIT_TYPE_LEGACY;
AuditEventInfo.u.Legacy.CategoryId = SE_CATEGID_OBJECT_ACCESS;
AuditEventInfo.u.Legacy.AuditId = SE_AUDITID_OBJECT_OPERATION;
AuditEventInfo.u.Legacy.ParameterCount = 11;
b = AuthzInitializeAuditQueue(
&hQueue,
0,
1000,
100,
NULL
);
if (!b)
{
wprintf(L"authzinitauditqueueueueue %d\n", GetLastError());
return;
}
if (!b)
{
printf("AuthzAllocInitRmAuditInfoHandle FAILED.\n");
return;
}
b = AuthzInitializeResourceManager(
MyAccessCheck,
MyComputeDynamicGroups,
MyFreeDynamicGroups,
L"some rm",
0, // Flags
&hRM
);
if (!b)
{
wprintf(L"AuthzInitializeResourceManager failed with %d\n", GetLastError());
return;
}
// AuthzInitializeAuditParamsWithRM(
// &pAuditParams,
// hRM,
// APF_AuditSuccess,
// 1,
// APT_String, L"Jeff operation"
// );
//
//
b = AuthzInitializeAuditInfo(
&hAuditInfo,
0,
hRM,
&AuditEventInfo,
NULL,//pAuditParams,
hQueue,
INFINITE,
L"Cleaning",
L"Toothbrush",
L"Oral B",
L"Rinse after brushing."
);
if (!b)
{
printf("AuthzInitAuditInfo FAILED with %d.\n", GetLastError());
return;
}
OpenProcessToken(
GetCurrentProcess(),
TOKEN_QUERY,
&hToken
);
b = AuthzInitializeContextFromToken(
hToken,
hRM,
NULL,
luid,
0,
NULL,
&hCC1
);
if (!b)
{
wprintf(L"AuthzInitializeContextFromSid failed with 0x%x\n", GetLastError());
return;
}
Request.ObjectTypeList = (POBJECT_TYPE_LIST) TypeListBuffer;
Request.ObjectTypeList[0].Level = 0;
Request.ObjectTypeList[0].ObjectType = &Guid0;
Request.ObjectTypeList[0].Sbz = 0;
Request.ObjectTypeListLength = 1;
Request.OptionalArguments = NULL;
Request.PrincipalSelfSid = NULL;
Request.DesiredAccess = 0x100;
//
// The ResultListLength is set to the number of ObjectType GUIDs in the Request, indicating
// that the caller would like detailed information about granted access to each node in the
// tree.
//
RtlZeroMemory(Buffer, sizeof(Buffer));
pReply->ResultListLength = 1;
pReply->Error = (PDWORD) (((PCHAR) pReply) + sizeof(AUTHZ_ACCESS_REPLY));
pReply->GrantedAccessMask = (PACCESS_MASK) (pReply->Error + pReply->ResultListLength);
wprintf(L"* AccessCheck (PSS == NULL, ResultListLength == 1 with cache handle)\n");
b = AuthzAccessCheck(
hCC1,
&Request,
hAuditInfo,
pSD,
NULL,
0,
pReply,
&AuthHandle
);
if (!b)
{
wprintf(L"\tFailed. LastError = %d\n", GetLastError());
return;
}
else
{
wprintf(L"\tSucceeded. Granted Access Masks:\n");
for (i = 0; i < pReply->ResultListLength; i++)
{
wprintf(L"\t\tObjectType %d :: AccessMask = 0x%x, Error = %d\n",
i, pReply->GrantedAccessMask[i], pReply->Error[i]);
}
}
AuthzFreeAuditInfo(hAuditInfo);
AuthzFreeAuditQueue(hQueue);
return;
RtlZeroMemory(Buffer, sizeof(Buffer));
pReply->ResultListLength = 1;
pReply->Error = (PDWORD) (((PCHAR) pReply) + sizeof(AUTHZ_ACCESS_REPLY));
pReply->GrantedAccessMask = (PACCESS_MASK) (pReply->Error + pReply->ResultListLength);
wprintf(L"* AccessCheck (PSS == NULL, ResultListLength == 1 without cache handle)\n");
b = AuthzAccessCheck(
hCC1,
&Request,
hAuditInfo,
pSD,
NULL,
0,
pReply,
NULL
);
if (!b)
{
wprintf(L"\tFailed. LastError = %d\n", GetLastError());
return;
}
else
{
wprintf(L"\tSucceeded. Granted Access Masks:\n");
for (i = 0; i < pReply->ResultListLength; i++)
{
wprintf(L"\t\tObjectType %d :: AccessMask = 0x%x, Error = %d\n",
i, pReply->GrantedAccessMask[i], pReply->Error[i]);
}
}
AuthzFreeAuditParams(pAuditParams);
Request.ObjectTypeList = (POBJECT_TYPE_LIST) TypeListBuffer;
Request.ObjectTypeList[0].Level = 0;
Request.ObjectTypeList[0].ObjectType = &Guid0;
Request.ObjectTypeList[0].Sbz = 0;
Request.ObjectTypeList[1].Level = 1;
Request.ObjectTypeList[1].ObjectType = &Guid1;
Request.ObjectTypeList[1].Sbz = 0;
Request.ObjectTypeList[2].Level = 2;
Request.ObjectTypeList[2].ObjectType = &Guid2;
Request.ObjectTypeList[2].Sbz = 0;
Request.ObjectTypeList[3].Level = 2;
Request.ObjectTypeList[3].ObjectType = &Guid3;
Request.ObjectTypeList[3].Sbz = 0;
Request.ObjectTypeList[4].Level = 1;
Request.ObjectTypeList[4].ObjectType = &Guid4;
Request.ObjectTypeList[4].Sbz = 0;
Request.ObjectTypeList[5].Level = 2;
Request.ObjectTypeList[5].ObjectType = &Guid5;
Request.ObjectTypeList[5].Sbz = 0;
Request.ObjectTypeList[6].Level = 3;
Request.ObjectTypeList[6].ObjectType = &Guid6;
Request.ObjectTypeList[6].Sbz = 0;
Request.ObjectTypeList[7].Level = 2;
Request.ObjectTypeList[7].ObjectType = &Guid7;
Request.ObjectTypeList[7].Sbz = 0;
Request.ObjectTypeListLength = 8;
Request.OptionalArguments = NULL;
Request.PrincipalSelfSid = NULL;
Request.DesiredAccess = DesiredAccess;
//
// The ResultListLength is set to the number of ObjectType GUIDs in the Request, indicating
// that the caller would like detailed information about granted access to each node in the
// tree.
//
pReply->ResultListLength = 8;
pReply->Error = (PDWORD) (((PCHAR) pReply) + sizeof(AUTHZ_ACCESS_REPLY));
pReply->GrantedAccessMask = (PACCESS_MASK) (pReply->Error + pReply->ResultListLength);
wprintf(L"* AccessCheck (PrincipalSelfSid == NULL, ResultListLength == 8)\n");
b = AuthzAccessCheck(
hCC1,
&Request,
hAuditInfo,
pSD,
NULL,
0,
pReply,
&AuthHandle
);
if (!b)
{
wprintf(L"\tFailed. LastError = %d\n", GetLastError());
return;
}
else
{
wprintf(L"\tSucceeded. Granted Access Masks:\n");
for (i = 0; i < pReply->ResultListLength; i++)
{
wprintf(L"\t\tObjectType %d :: AccessMask = 0x%x, Error = %d\n",
i, pReply->GrantedAccessMask[i], pReply->Error[i]);
}
}
//
// In the original AuthzAccessCheck call, we passed in a handle to store caching information. Now we
// can use this handle to perform an AccessCheck on the same object.
//
if (AuthHandle)
{
wprintf(L"* Cached AccessCheck (PrincipalSelfSid == NULL, ResultListLength = 8)\n");
b = AuthzCachedAccessCheck(
AuthHandle,
&Request,
hAuditInfo,
pReply
);
if (!b)
{
wprintf(L"\tFailed. LastError = %d\n", GetLastError());
return;
}
else
{
wprintf(L"\tSucceeded. Granted Access Masks:\n");
for (i = 0; i < pReply->ResultListLength; i++)
{
wprintf(L"\t\tObjectType %d :: AccessMask = 0x%x, Error = %d\n",
i, pReply->GrantedAccessMask[i], pReply->Error[i]);
}
}
//
// Since we will no longer use this caching handle, free it.
//
AuthzFreeHandle(AuthHandle);
}
else
{
wprintf(L"No CachedAccessCheck done since NULL = AuthHandle\n");
}
//
// We set the PrincipalSelfSid in the Request, and leave all other parameters the same.
//
Request.PrincipalSelfSid = (PSID) KedarSid;
wprintf(L"* AccessCheck (PrincipalSelfSid == Kedard, ResultListLength == 8)\n");
b = AuthzAccessCheck(
hCC1,
&Request,
hAuditInfo,
pSD,
NULL,
0,
pReply,
&AuthHandle
);
if (!b)
{
wprintf(L"\tFailed. LastError = %d\n", GetLastError());
return;
}
else
{
wprintf(L"\tSucceeded. Granted Access Masks:\n");
for (i = 0; i < pReply->ResultListLength; i++)
{
wprintf(L"\t\tObjectType %d :: AccessMask = 0x%x, Error = %d\n",
i, pReply->GrantedAccessMask[i], pReply->Error[i]);
}
}
//
// Use our caching handle to perform the same AccessCheck with speed.
//
if (AuthHandle)
{
wprintf(L"* Cached AccessCheck (PrincipalSelfSid == Kedard, ResultListLength = 8)\n");
b = AuthzCachedAccessCheck(
AuthHandle,
&Request,
hAuditInfo,
pReply
);
if (!b)
{
wprintf(L"\tFailed. LastError = %d\n", GetLastError());
return;
}
else
{
wprintf(L"\tSucceeded. Granted Access Masks:\n");
for (i = 0; i < pReply->ResultListLength; i++)
{
wprintf(L"\t\tObjectType %d :: AccessMask = 0x%x, Error = %d\n",
i, pReply->GrantedAccessMask[i], pReply->Error[i]);
}
}
//
// Free the handle, since it will not be used again.
//
AuthzFreeHandle(AuthHandle);
}
else
{
wprintf(L"No CachedAccessCheck done since NULL = AuthHandle\n");
}
//
// Set the ResultListLength to 1, indicating that we do not care about the results
// of the AccessCheck at the individual nodes in the tree. Rather, we care about
// our permissions to the entire tree. The returned access indicates if we have
// access to the whole thing.
//
pReply->ResultListLength = 1;
wprintf(L"* AccessCheck (PrincipalSelfSid == Kedard, ResultListLength == 1)\n");
b = AuthzAccessCheck(
hCC1,
&Request,
hAuditInfo,
pSD,
NULL,
0,
pReply,
NULL
);
if (!b)
{
wprintf(L"\tFailed. LastError = %d\n", GetLastError());
return;
}
else
{
wprintf(L"\tSucceeded. Granted Access Masks:\n");
for (i = 0; i < pReply->ResultListLength; i++)
{
wprintf(L"\t\tObjectType %d :: AccessMask = 0x%x, Error = %d\n",
i, pReply->GrantedAccessMask[i], pReply->Error[i]);
}
}
// for (i = 0; i < 10; i ++)
// {
// AuthzOpenObjectAuditAlarm(
// hCC1,
// &Request,
// hAuditInfo,
// pSD,
// NULL,
// 0,
// pReply
// );
//
// if (!b)
// {
// wprintf(L"AuthzOpenObjectAuditAlarm failed with %d\n", GetLastError);
// }
// }
//
// Free the RM auditing data before exiting. This call is importants, as it also waits on
// threads used by the Authzs auditing component to complete.
//
//AuthzFreeRmAuditInfoHandle(hRmAuditInfo);
//
// Free the contexts that the RM created.
//
AuthzFreeContext(hCC1);
AuthzFreeAuditQueue(hQueue);
return;
}