|
|
#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; }
|