-
-
Notifications
You must be signed in to change notification settings - Fork 16
/
Operation.h
110 lines (90 loc) · 4.21 KB
/
Operation.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#pragma once
// mute compatibility concerns
#define _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
#include <Windows.h>
#include <AccCtrl.h>
#include <AclAPI.h>
#include <string>
#include <vector>
#include <queue>
#include <map>
typedef struct ObjectEntry
{
std::wstring Name;
SE_OBJECT_TYPE ObjectType;
DWORD Attributes;
FILETIME ModifiedTime;
FILETIME CreationTime;
LARGE_INTEGER FileSize;
unsigned int Depth;
std::wstring NameExtended;
HANDLE hObject;
}
ObjectEntry;
// generic header for allow, deny, and audit object aces
using ACE_ACCESS_HEADER = struct {
BYTE AceType;
BYTE AceFlags;
WORD AceSize;
ACCESS_MASK Mask;
} ;
using PACE_ACCESS_HEADER = ACE_ACCESS_HEADER*;;
// macros to iterate through access control entries
#define FirstAce(Acl) reinterpret_cast<PACE_ACCESS_HEADER>(((PUCHAR)(Acl) + sizeof(ACL)))
#define NextAce(Ace) reinterpret_cast<PACE_ACCESS_HEADER>((PUCHAR)(Ace) + ((PACE_ACCESS_HEADER)(Ace))->AceSize)
// define our own version of sid length since its faster
constexpr DWORD SidGetLength(PSID x) { return sizeof(SID) + (((SID*)(x))->SubAuthorityCount - 1) * sizeof(((SID*)(x))->SubAuthority); };
constexpr bool SidMatch(PSID x, PSID y) { return __builtin_memcmp(x, y, min(SidGetLength(x), SidGetLength(y))) == 0; };
constexpr bool SidNotMatch(PSID x, PSID y) { return !SidMatch(x, y); };
// macros for checking file attributes
constexpr bool CheckBitSet(DWORD x, DWORD y) { return (((x) & (y)) != 0); }
constexpr bool IsDirectory(DWORD x) { return CheckBitSet(x, FILE_ATTRIBUTE_DIRECTORY); };
constexpr bool IsHiddenSystem(DWORD x) { return CheckBitSet(x, FILE_ATTRIBUTE_HIDDEN) && CheckBitSet(x, FILE_ATTRIBUTE_SYSTEM); };
constexpr bool IsReparsePoint(DWORD x) { return CheckBitSet(x, FILE_ATTRIBUTE_REPARSE_POINT); };
// a few simple defines for convenience
constexpr bool IsInherited(PACE_ACCESS_HEADER x) { return CheckBitSet((x)->AceFlags, INHERITED_ACE); };
constexpr bool HasContainerInherit(PACE_ACCESS_HEADER x) { return CheckBitSet((x)->AceFlags, CONTAINER_INHERIT_ACE); };
constexpr bool HasObjectInherit(PACE_ACCESS_HEADER x) { return CheckBitSet((x)->AceFlags, OBJECT_INHERIT_ACE); };
constexpr bool HasInheritOnly(PACE_ACCESS_HEADER x) { return CheckBitSet((x)->AceFlags, INHERIT_ONLY_ACE); };
constexpr bool HasNoPropogate(PACE_ACCESS_HEADER x) { return CheckBitSet((x)->AceFlags, NO_PROPAGATE_INHERIT_ACE); };
constexpr DWORD GetNonOiCiIoBits(PACE_ACCESS_HEADER x) { return ((~(CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE | INHERIT_ONLY_ACE)) & (x)->AceFlags); };
// string helper operations
constexpr void ConvertToUpper(std::wstring & str)
{
std::ranges::transform(str, str.begin(), ::towupper);
}
typedef enum SidActionResult : char
{
Nothing = 0,
Replace = 1 << 0,
Remove = 1 << 1
}
SidActionResult;
class Operation
{
protected:
static std::vector<std::wstring> SplitArgs(std::wstring sInput, const std::wstring & sDelimiter);
static std::vector<std::wstring> ProcessAndCheckArgs(int iArgsRequired, std::queue<std::wstring> & oArgList, const std::wstring & sDelimiter = L":");
void ProcessGranularTargetting(std::wstring sScope);
public:
bool AppliesToDacl = false;
bool AppliesToSacl = false;
bool AppliesToOwner = false;
bool AppliesToGroup = false;
bool AppliesToSd = false;
bool AppliesToObject = false;
bool AppliesToRootOnly = false;
bool AppliesToChildrenOnly = false;
bool ExclusiveOperation = false;
DWORD SpecialCommitFlags = false;
PSID DefaultSidWhenEmpty = nullptr;
virtual bool ProcessSdAction(std::wstring & sFileName, ObjectEntry & tObjectEntry, PSECURITY_DESCRIPTOR & tDescriptor, bool & bDescReplacement) { return false; }
virtual bool ProcessAclAction(const WCHAR * sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement);
virtual bool ProcessSidAction(const WCHAR * sSdPart, ObjectEntry & tObjectEntry, PSID & tCurrentSid, bool & bSidReplacement);
virtual SidActionResult DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) { return SidActionResult::Nothing; }
virtual void ProcessObjectAction(ObjectEntry & tObjectEntry) { return; }
static PSID GetSidFromAce(PACE_ACCESS_HEADER tAce) noexcept;
Operation(std::queue<std::wstring> & oArgList);
virtual ~Operation() = default;
};
#include "OperationFactory.h"