diff --git a/Build/Release/x64/repacls.exe b/Build/Release/x64/repacls.exe index 14474be..8bcd820 100644 Binary files a/Build/Release/x64/repacls.exe and b/Build/Release/x64/repacls.exe differ diff --git a/Build/Release/x86/repacls.exe b/Build/Release/x86/repacls.exe index fbf485b..4d90933 100644 Binary files a/Build/Release/x86/repacls.exe and b/Build/Release/x86/repacls.exe differ diff --git a/Build/Repacls.zip b/Build/Repacls.zip index 94a1387..a9bb011 100644 Binary files a/Build/Repacls.zip and b/Build/Repacls.zip differ diff --git a/Build/build.cmd b/Build/build.cmd index 67a652e..8c61b42 100644 --- a/Build/build.cmd +++ b/Build/build.cmd @@ -4,7 +4,7 @@ CLS SET PATH=%WINDIR%\system32;%WINDIR%\system32\WindowsPowerShell\v1.0 :: cert info to use for signing -SET CERT=2FA35B20356EFEB88F9E9B5F20221693C57100E5 +SET CERT=D4C06C609230B7BC433A428BFFD6EDC4F77FD166 set TSAURL=http://time.certum.pl/ set LIBNAME=Repacls set LIBURL=https://github.com/NoMoreFood/Repacls diff --git a/Functions.h b/Functions.h index d46fd9c..482de6f 100644 --- a/Functions.h +++ b/Functions.h @@ -14,13 +14,13 @@ std::wstring GenerateAccessMask(DWORD iCurrentMask); std::wstring GenerateInheritanceFlags(DWORD iCurrentFlags); HANDLE RegisterFileHandle(HANDLE hFile, std::wstring sOperation); std::wstring GetAntivirusStateDescription(); -std::wstring FileTimeToString(LPFILETIME tFileTime); -BOOL WriteToFile(std::wstring & sStringToWrite, HANDLE hFile); +std::wstring FileTimeToString(LPFILETIME const tFileTime); +BOOL WriteToFile(const std::wstring & sStringToWrite, HANDLE hFile); // helper typedefs typedef struct SidCompare { - inline bool operator()(PSID p1, PSID p2) const + inline bool operator()(PSID p1, PSID p2) const noexcept { const DWORD iLength1 = GetLengthSid(p1); const DWORD iLength2 = GetLengthSid(p2); diff --git a/Helpers.cpp b/Helpers.cpp index bc58cfe..be43d44 100644 --- a/Helpers.cpp +++ b/Helpers.cpp @@ -106,7 +106,7 @@ std::wstring GetNameFromSid(const PSID tSid, bool * bMarkAsOrphan) if (LookupAccountSid(NULL, tSid, sAccountName, &iAccountNameSize, sDomainName, &iDomainName, &tNameUse) == 0) { - DWORD iError = GetLastError(); + const DWORD iError = GetLastError(); if (iError == ERROR_NONE_MAPPED) { if (bMarkAsOrphan != NULL) *bMarkAsOrphan = true; @@ -347,7 +347,7 @@ HANDLE RegisterFileHandle(HANDLE hFile, std::wstring sOperation) static std::map> oFileLookup; // do a reverse lookup on the file name - auto iSize = (size_t) GetFinalPathNameByHandle(hFile, NULL, 0, VOLUME_NAME_NT); + const auto iSize = (size_t) GetFinalPathNameByHandle(hFile, NULL, 0, VOLUME_NAME_NT); // create a string that can accommodate that size (plus null terminating character) std::wstring sPath; @@ -449,7 +449,7 @@ std::wstring GetAntivirusStateDescription() return (bIsEnabled) ? L"On" : L"Off"; } -std::wstring FileTimeToString(LPFILETIME tFileTime) +std::wstring FileTimeToString(LPFILETIME const tFileTime) { // the date format function require system time structure SYSTEMTIME tTime; @@ -465,11 +465,11 @@ std::wstring FileTimeToString(LPFILETIME tFileTime) return std::wstring(sTime); } -BOOL WriteToFile(std::wstring & sStringToWrite, HANDLE hFile) +BOOL WriteToFile(const std::wstring& sStringToWrite, HANDLE hFile) { // see how many characters we need to store as utf-8 int iChars = WideCharToMultiByte(CP_UTF8, 0, - sStringToWrite.c_str(), (int) sStringToWrite.length(), + sStringToWrite.c_str(), (int)sStringToWrite.length(), NULL, 0, NULL, NULL); if (iChars == 0) { @@ -477,10 +477,10 @@ BOOL WriteToFile(std::wstring & sStringToWrite, HANDLE hFile) } // allocate and do the conversion - auto* sString = (BYTE *) malloc(iChars); - iChars = WideCharToMultiByte(CP_UTF8, 0, - sStringToWrite.c_str(), (int) sStringToWrite.length(), - (LPSTR) sString, iChars, NULL, NULL); + auto* sString = (BYTE*)malloc(iChars); + iChars = WideCharToMultiByte(CP_UTF8, 0, + sStringToWrite.c_str(), (int)sStringToWrite.length(), + (LPSTR)sString, iChars, NULL, NULL); if (iChars == 0) { free(sString); @@ -489,7 +489,7 @@ BOOL WriteToFile(std::wstring & sStringToWrite, HANDLE hFile) // write to file, free memory, and return result DWORD iBytes = 0; - BOOL bResult = WriteFile(hFile, sString, iChars, &iBytes, NULL); + const BOOL bResult = WriteFile(hFile, sString, iChars, &iBytes, NULL); free(sString); return bResult; -} \ No newline at end of file +} diff --git a/InputOutput.h b/InputOutput.h index deda596..41a1261 100644 --- a/InputOutput.h +++ b/InputOutput.h @@ -23,37 +23,37 @@ class InputOutput public: - static bool & InQuietMode() + static bool & InQuietMode() noexcept { static bool bQuietMode = false; return bQuietMode; } - static bool & InWhatIfMode() + static bool & InWhatIfMode() noexcept { static bool bWhatIfMode = false; return bWhatIfMode; } - static bool & ExcludeHiddenSystem() + static bool & ExcludeHiddenSystem() noexcept { static bool bExcludeHiddenSystem = false; return bExcludeHiddenSystem; } - static short & MaxThreads() + static short & MaxThreads() noexcept { static short iMaxThreads = 5; return iMaxThreads; } - static bool & Log() + static bool & Log() noexcept { static bool bLog = false; return bLog; } - static std::vector & ScanPaths() + static std::vector & ScanPaths() noexcept { static std::vector vScanPaths; return vScanPaths; diff --git a/Main.cpp b/Main.cpp index 691c4aa..eaca57f 100644 --- a/Main.cpp +++ b/Main.cpp @@ -66,22 +66,22 @@ void AnalyzeSecurity(ObjectEntry & oEntry) bool bGroupIsDirty = false; // read security information from the file handle - PACL tAclDacl = NULL; - PACL tAclSacl = NULL; - PSID tOwnerSid = NULL; - PSID tGroupSid = NULL; - PSECURITY_DESCRIPTOR tDesc = NULL; + PACL tAclDacl = nullptr; + PACL tAclSacl = nullptr; + PSID tOwnerSid = nullptr; + PSID tGroupSid = nullptr; + PSECURITY_DESCRIPTOR tDesc = nullptr; DWORD iError = 0; if (iInformationToLookup != 0 && (iError = GetNamedSecurityInfo(oEntry.Name.c_str(), SE_FILE_OBJECT, - iInformationToLookup, (bFetchOwner) ? &tOwnerSid : NULL, (bFetchGroup) ? &tGroupSid : NULL, - (bFetchDacl) ? &tAclDacl : NULL, (bFetchSacl) ? &tAclSacl : NULL, &tDesc)) != ERROR_SUCCESS) + iInformationToLookup, (bFetchOwner) ? &tOwnerSid : nullptr, (bFetchGroup) ? &tGroupSid : nullptr, + (bFetchDacl) ? &tAclDacl : nullptr, (bFetchSacl) ? &tAclSacl : nullptr, &tDesc)) != ERROR_SUCCESS) { // attempt to look up error message - LPWSTR sError = NULL; - size_t iSize = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + LPWSTR sError = nullptr; + const size_t iSize = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, - NULL, iError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&sError, 0, NULL); + nullptr, iError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&sError, 0, nullptr); InputOutput::AddError(L"Unable to read file security", (iSize == 0) ? L"" : sError); if (iSize > 0) LocalFree(sError); @@ -96,7 +96,7 @@ void AnalyzeSecurity(ObjectEntry & oEntry) bool bSaclCleanupRequired = false; bool bOwnerCleanupRequired = false; bool bGroupCleanupRequired = false; - bool bDescCleanupRequired = (tDesc != NULL); + bool bDescCleanupRequired = (tDesc != nullptr); // used for one-shot operations like reset children or inheritance DWORD iSpecialCommitMergeFlags = 0; @@ -188,14 +188,14 @@ void AnalyzeSecurity(ObjectEntry & oEntry) if (!InputOutput::InWhatIfMode()) { if ((iError = SetNamedSecurityInfo((LPWSTR) oEntry.Name.c_str(), SE_FILE_OBJECT, iInformationToCommit, - (bOwnerIsDirty) ? tOwnerSid : NULL, (bGroupIsDirty) ? tGroupSid : NULL, - (bDaclIsDirty) ? tAclDacl : NULL, (bSaclIsDirty) ? tAclSacl : NULL)) != ERROR_SUCCESS) + (bOwnerIsDirty) ? tOwnerSid : nullptr, (bGroupIsDirty) ? tGroupSid : nullptr, + (bDaclIsDirty) ? tAclDacl : nullptr, (bSaclIsDirty) ? tAclSacl : nullptr)) != ERROR_SUCCESS) { // attempt to look up error message - LPWSTR sError = NULL; - size_t iSize = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + LPWSTR sError = nullptr; + const size_t iSize = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, - NULL, iError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR) &sError, 0, NULL); + nullptr, iError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR) &sError, 0, NULL); InputOutput::AddError(L"Unable to update file security", (iSize == 0) ? L"" : sError); if (iSize > 0) LocalFree(sError); @@ -273,7 +273,7 @@ void AnalyzingQueue() // update object attributes object OBJECT_ATTRIBUTES oAttributes; - InitializeObjectAttributes(&oAttributes, NULL, OBJ_CASE_INSENSITIVE, NULL, NULL); + InitializeObjectAttributes(&oAttributes, nullptr, OBJ_CASE_INSENSITIVE, nullptr, nullptr); oAttributes.ObjectName = &tPathU; // get an open file handle @@ -310,9 +310,9 @@ void AnalyzingQueue() // enumerate files in the directory for (bool bFirstRun = true; true; bFirstRun = false) { - Status = NtQueryDirectoryFile(hFindFile, NULL, NULL, NULL, &IoStatusBlock, + Status = NtQueryDirectoryFile(hFindFile, nullptr, nullptr, nullptr, &IoStatusBlock, DirectoryInfo, MAX_DIRECTORY_BUFFER, (FILE_INFORMATION_CLASS)FileDirectoryInformation, - FALSE, NULL, (bFirstRun) ? TRUE : FALSE); + FALSE, nullptr, (bFirstRun) ? TRUE : FALSE); // done processing if (Status == STATUS_NO_MORE_FILES) break; @@ -324,7 +324,7 @@ void AnalyzingQueue() } for (auto* oInfo = (FILE_DIRECTORY_INFORMATION *)DirectoryInfo; - oInfo != NULL; oInfo = (FILE_DIRECTORY_INFORMATION *)((BYTE *)oInfo + oInfo->NextEntryOffset)) + oInfo != nullptr; oInfo = (FILE_DIRECTORY_INFORMATION *)((BYTE *)oInfo + oInfo->NextEntryOffset)) { // continue immediately if we get the '.' or '..' entries if (IsDirectory(oInfo->FileAttributes)) @@ -384,7 +384,7 @@ VOID BeginFileScan() // make a local copy of the path since we may have to alter it // handle special case where a drive root is specified // we must ensure it takes the form x:\. to resolve correctly - size_t iSemiColon = sPath.rfind(L':'); + const size_t iSemiColon = sPath.rfind(L':'); if (iSemiColon != std::wstring::npos) { std::wstring sEnd = sPath.substr(iSemiColon); @@ -396,7 +396,7 @@ VOID BeginFileScan() // convert the path to a long path that is compatible with the other call UNICODE_STRING tPathU; - RtlDosPathNameToNtPathName_U(sPath.c_str(), &tPathU, NULL, NULL); + RtlDosPathNameToNtPathName_U(sPath.c_str(), &tPathU, nullptr, nullptr); // copy it to a null terminated string oEntryFirst.Name = std::wstring(tPathU.Buffer, tPathU.Length / sizeof(WCHAR)); @@ -517,9 +517,9 @@ int wmain(int iArgs, WCHAR * aArgs[]) wprintf(L"===============================================================================\n"); // do the scan - ULONGLONG iTimeStart = GetTickCount64(); + const ULONGLONG iTimeStart = GetTickCount64(); BeginFileScan(); - ULONGLONG iTimeStop = GetTickCount64(); + const ULONGLONG iTimeStop = GetTickCount64(); // print out statistics wprintf(L"===============================================================================\n"); diff --git a/Notes.txt b/Notes.txt index 9a8cc10..c6652e2 100644 --- a/Notes.txt +++ b/Notes.txt @@ -1,15 +1,15 @@ This file contains various information that may be useful in understanding -various elements of ACL, ACE, or SID contructs. +various elements of ACL, ACE, or SID constructs. IO CI OI DIR DOB SUB SOB - 0 0 0 1 0 0 0 icacls Exact /grant Everyone:F - 0 0 1 1 1 0 1 icacls Exact /grant Everyone:(OI)F - 0 1 0 1 0 1 0 icacls Exact /grant Everyone:(CI)F - 0 1 1 1 1 1 1 icacls Exact /grant Everyone:(CI)(OI)F - 1 0 0 0 0 0 0 icacls Exact /grant Everyone:(IO)F - 1 0 1 0 1 0 1 icacls Exact /grant Everyone:(OI)(IO)F - 1 1 0 0 0 1 0 icacls Exact /grant Everyone:(CI)(IO)F - 1 1 1 0 1 1 1 icacls Exact /grant Everyone:(CI)(OI)(IO)F + 0 0 0 1 0 0 0 icacls Exact /grant Everyone:(F) + 0 0 1 1 1 0 1 icacls Exact /grant Everyone:(OI)(F) + 0 1 0 1 0 1 0 icacls Exact /grant Everyone:(CI)(F) + 0 1 1 1 1 1 1 icacls Exact /grant Everyone:(CI)(OI)(F) + 1 0 0 0 0 0 0 icacls Exact /grant Everyone:(IO)(F) + 1 0 1 0 1 0 1 icacls Exact /grant Everyone:(OI)(IO)(F) + 1 1 0 0 0 1 0 icacls Exact /grant Everyone:(CI)(IO)(F) + 1 1 1 0 1 1 1 icacls Exact /grant Everyone:(CI)(OI)(IO)(F) Bit Mapping DIR = ~IO diff --git a/Operation.cpp b/Operation.cpp index 11594d6..0d36900 100644 --- a/Operation.cpp +++ b/Operation.cpp @@ -7,7 +7,7 @@ bool Operation::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) { // return immediately if acl is null - if (tCurrentAcl == NULL) return false; + if (tCurrentAcl == nullptr) return false; // flag to note whether a change was actually made bool bMadeChange = false; @@ -75,7 +75,7 @@ bool Operation::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEnt else { PBYTE const tNewAcl = (PBYTE)LocalAlloc(LMEM_FIXED, tAcl->AclSize + (iNewLen - iOldLen)); - if (tNewAcl == NULL) + if (tNewAcl == nullptr) { wprintf(L"ERROR: Unable to allocate memory for new SID.\n"); exit(-1); diff --git a/Operation.h b/Operation.h index 4f115e7..f5eea19 100644 --- a/Operation.h +++ b/Operation.h @@ -41,6 +41,10 @@ typedef ACCESS_ACE *PACCESS_ACE; #define HasNoPropogate(x) CheckBitSet((x)->Header.AceFlags,NO_PROPAGATE_INHERIT_ACE) #define GetNonOiCiIoBits(x) ((~(CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE | INHERIT_ONLY_ACE)) & (x)->Header.AceFlags) +// string helper operations +#define ConvertToUpper(_x) std::transform(_x.begin(), _x.end(), _x.begin(), \ + [](const WCHAR c) noexcept { return static_cast(::toupper(c)); }); + typedef struct ObjectEntry { std::wstring Name; @@ -80,7 +84,7 @@ class Operation bool ExclusiveOperation = false; DWORD SpecialCommitFlags = false; - PSID DefaultSidWhenEmpty = NULL; + PSID DefaultSidWhenEmpty = nullptr; virtual bool ProcessSdAction(std::wstring & sFileName, ObjectEntry & tObjectEntry, PSECURITY_DESCRIPTOR & tDescriptor, bool & bDescReplacement) { return false; } virtual bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement); @@ -89,7 +93,7 @@ class Operation virtual void ProcessObjectAction(ObjectEntry & tObjectEntry) { return; } Operation(std::queue & oArgList); - virtual ~Operation() = default;; + virtual ~Operation() = default; }; #include "OperationFactory.h" \ No newline at end of file diff --git a/OperationAddAccountIfMissing.cpp b/OperationAddAccountIfMissing.cpp index 9672284..e410243 100644 --- a/OperationAddAccountIfMissing.cpp +++ b/OperationAddAccountIfMissing.cpp @@ -3,27 +3,17 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationAddAccountIfMissing::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationAddAccountIfMissing::RegisteredFactory(GetCommand()); -OperationAddAccountIfMissing::OperationAddAccountIfMissing(std::queue & oArgList) : Operation(oArgList) +OperationAddAccountIfMissing::OperationAddAccountIfMissing(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList); - - // fetch params - tAddSid = GetSidFromName(sSubArgs[0]); - - // see if names could be resolved - if (tAddSid == NULL) - { - // complain - wprintf(L"ERROR: Invalid account '%s' specified for parameter '%s'.\n", sSubArgs[0].c_str(), GetCommand().c_str()); - exit(-1); - } - - // do a reverse lookup on the name for info messages - sAddSid = GetNameFromSidEx(tAddSid); + + // defer construction to delegate + std::queue oArgListAlt; + oArgListAlt.push(sSubArgs.at(0) + L":(OI)(CI)(F)"); + oDelegate = new OperationGrantDenyPerms(oArgListAlt, L"AddPerms"); // flag this as being an ace-level action AppliesToDacl = true; @@ -31,66 +21,5 @@ OperationAddAccountIfMissing::OperationAddAccountIfMissing(std::queueAceCount; tAceDacl = NextAce(tAceDacl), iEntry++) - { - // skip other ace types that are not allowing accessing - if (tAceDacl->Header.AceType != ACCESS_ALLOWED_ACE_TYPE) continue; - - // do not look at sids that are not the specified account - if (SidNotMatch(&tAceDacl->Sid, tAddSid)) continue; - - // merge if the effective permissions - // ignore the inherited ace flag since its not relevant - iPermissionMask |= tAceDacl->Mask; - iInheritMask |= (tAceDacl->Header.AceFlags & ~INHERITED_ACE); - } - } - - // define what constitutes 'full control' based on the object - const DWORD iDesiredInheritMask = IsDirectory(tObjectEntry.Attributes) - ? (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE) : 0; - - // only attempt to add permissions if our flags do not match - if (iPermissionMask != FILE_ALL_ACCESS || iInheritMask != iDesiredInheritMask) - { - // since SetEntriesInAcl reacts poorly / unexpectedly in cases where the - // acl is not canonical, just error out and continue on - if (!OperationCheckCanonical::IsAclCanonical(tCurrentAcl)) - { - InputOutput::AddError(L"Could not add '" + sAddSid + - L"' to access control list since ACL was not canonical.", sSdPart); - return false; - } - - EXPLICIT_ACCESS tEa; - tEa.grfAccessPermissions = FILE_ALL_ACCESS; - tEa.grfAccessMode = GRANT_ACCESS; - tEa.grfInheritance = iDesiredInheritMask; - tEa.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; - tEa.Trustee.pMultipleTrustee = NULL; - tEa.Trustee.ptstrName = (LPWSTR) tAddSid; - tEa.Trustee.TrusteeForm = TRUSTEE_IS_SID; - tEa.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN; - - // merge the new trustee into the dacl - PACL tNewDacl; - SetEntriesInAcl(1, &tEa, tCurrentAcl, &tNewDacl); - - // cleanup the old dacl (if necessary) and assign our new active dacl - if (bAclReplacement) LocalFree(tCurrentAcl); - tCurrentAcl = tNewDacl; - - // flag to commit tag and cleanup dacl - InputOutput::AddInfo(L"Adding full control for '" + sAddSid + L"'", sSdPart); - bAclReplacement = true; - return true; - } - - return false; + return oDelegate->ProcessAclAction(sSdPart, tObjectEntry, tCurrentAcl, bAclReplacement); } diff --git a/OperationAddAccountIfMissing.h b/OperationAddAccountIfMissing.h index 260c0da..a60a038 100644 --- a/OperationAddAccountIfMissing.h +++ b/OperationAddAccountIfMissing.h @@ -1,6 +1,7 @@ #pragma once #include "Operation.h" +#include "OperationGrantDenyPerms.h" class OperationAddAccountIfMissing : public Operation { @@ -8,11 +9,10 @@ class OperationAddAccountIfMissing : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"AddAccountIfMissing"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; // operation specific - PSID tAddSid = nullptr; - std::wstring sAddSid = L""; + OperationGrantDenyPerms * oDelegate; public: @@ -20,5 +20,5 @@ class OperationAddAccountIfMissing : public Operation bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; // constructors - OperationAddAccountIfMissing(std::queue & oArgList); + OperationAddAccountIfMissing(std::queue & oArgList, std::wstring sCommand); }; \ No newline at end of file diff --git a/OperationBackupSecurity.cpp b/OperationBackupSecurity.cpp index 9531828..8f2c1e9 100644 --- a/OperationBackupSecurity.cpp +++ b/OperationBackupSecurity.cpp @@ -2,30 +2,29 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationBackupSecurity::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationBackupSecurity::RegisteredFactory(GetCommand()); -OperationBackupSecurity::OperationBackupSecurity(std::queue & oArgList) : Operation(oArgList) +OperationBackupSecurity::OperationBackupSecurity(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList, L"\\0"); // fetch params - hFile = CreateFile(sSubArgs[0].c_str(), GENERIC_WRITE, - FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + hFile = CreateFile(sSubArgs.at(0).c_str(), GENERIC_WRITE, + FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); // see if names could be resolved if (hFile == INVALID_HANDLE_VALUE) { // complain - wprintf(L"ERROR: Could not create file '%s' specified for parameter '%s'.\n", sSubArgs[0].c_str(), GetCommand().c_str()); + wprintf(L"ERROR: Could not create file '%s' specified for parameter '%s'.\n", sSubArgs.at(0).c_str(), GetCommand().c_str()); exit(-1); } // write out the file type marker - BYTE hHeader[] = { 0xEF,0xBB,0xBF }; + const BYTE hHeader[] = { 0xEF,0xBB,0xBF }; DWORD iBytes = 0; - if (WriteFile(hFile, &hHeader, _countof(hHeader), &iBytes, NULL) == 0) + if (WriteFile(hFile, &hHeader, _countof(hHeader), &iBytes, nullptr) == 0) { wprintf(L"ERROR: Could not write out file type marker '%s'.\n", GetCommand().c_str()); exit(-1); diff --git a/OperationBackupSecurity.h b/OperationBackupSecurity.h index 8653dfb..fcbe80b 100644 --- a/OperationBackupSecurity.h +++ b/OperationBackupSecurity.h @@ -8,7 +8,7 @@ class OperationBackupSecurity : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"BackupSecurity"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; HANDLE hFile = INVALID_HANDLE_VALUE; std::wstring sFile = L""; @@ -19,6 +19,6 @@ class OperationBackupSecurity : public Operation bool ProcessSdAction(std::wstring & sFileName, ObjectEntry & tObjectEntry, PSECURITY_DESCRIPTOR & tDescriptor, bool & bDescReplacement) override; // constructors - OperationBackupSecurity(std::queue & oArgList); + OperationBackupSecurity(std::queue & oArgList, std::wstring sCommand); }; diff --git a/OperationCanonicalizeAcls.cpp b/OperationCanonicalizeAcls.cpp index 1c53bf6..ee5a421 100644 --- a/OperationCanonicalizeAcls.cpp +++ b/OperationCanonicalizeAcls.cpp @@ -4,10 +4,9 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationCanonicalizeAcls::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationCanonicalizeAcls::RegisteredFactory(GetCommand()); -OperationCanonicalizeAcls::OperationCanonicalizeAcls(std::queue & oArgList) : Operation(oArgList) +OperationCanonicalizeAcls::OperationCanonicalizeAcls(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // flag this as being an ace-level action AppliesToDacl = true; @@ -16,7 +15,7 @@ OperationCanonicalizeAcls::OperationCanonicalizeAcls(std::queue & bool OperationCanonicalizeAcls::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) { // sanity check (null acl is considered valid) - if (tCurrentAcl == NULL) return false; + if (tCurrentAcl == nullptr) return false; // if no problem, then no need to perform a reorder if (OperationCheckCanonical::IsAclCanonical(tCurrentAcl)) @@ -31,11 +30,8 @@ bool OperationCanonicalizeAcls::ProcessAclAction(WCHAR * const sSdPart, ObjectEn ACCESS_ACE * tAce = FirstAce(tCurrentAcl); for (ULONG iEntry = 0; iEntry < tCurrentAcl->AceCount; tAce = NextAce(tAce), iEntry++) { - // determine the overall over type of this ace - OperationCheckCanonical::AceOrder oThisAceOrder = OperationCheckCanonical::DetermineAceOrder(tAce); - // copy the ace if it matches the sequential order (explicit deny, explicit allow, ...) - if (iAceOrder == oThisAceOrder) + if (iAceOrder == OperationCheckCanonical::DetermineAceOrder(tAce)) { memcpy(tNewAce, tAce, tAce->Header.AceSize); tNewAce = NextAce(tNewAce); diff --git a/OperationCanonicalizeAcls.h b/OperationCanonicalizeAcls.h index c5520e8..16cbc4a 100644 --- a/OperationCanonicalizeAcls.h +++ b/OperationCanonicalizeAcls.h @@ -8,7 +8,7 @@ class OperationCanonicalizeAcls : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"CanonicalizeAcls"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; public: @@ -16,6 +16,6 @@ class OperationCanonicalizeAcls : public Operation bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; // constructors - OperationCanonicalizeAcls(std::queue & oArgList); + OperationCanonicalizeAcls(std::queue & oArgList, std::wstring sCommand); }; diff --git a/OperationCheckCanonical.cpp b/OperationCheckCanonical.cpp index f03d6b7..1cac35a 100644 --- a/OperationCheckCanonical.cpp +++ b/OperationCheckCanonical.cpp @@ -3,10 +3,9 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationCheckCanonical::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationCheckCanonical::RegisteredFactory(GetCommand()); -OperationCheckCanonical::OperationCheckCanonical(std::queue & oArgList) : Operation(oArgList) +OperationCheckCanonical::OperationCheckCanonical(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // flag this as being an ace-level action AppliesToDacl = true; @@ -15,7 +14,7 @@ OperationCheckCanonical::OperationCheckCanonical(std::queue & oArg bool OperationCheckCanonical::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) { // sanity check (null acl is considered valid) - if (tCurrentAcl == NULL) return false; + if (tCurrentAcl == nullptr) return false; // do the check and report if (!IsAclCanonical(tCurrentAcl)) @@ -30,14 +29,14 @@ bool OperationCheckCanonical::ProcessAclAction(WCHAR * const sSdPart, ObjectEntr bool OperationCheckCanonical::IsAclCanonical(PACL & tAcl) { // sanity check (null acl is considered valid) - if (tAcl == NULL) return true; + if (tAcl == nullptr) return true; AceOrder oOrderOverall = Unspecified; ACCESS_ACE * tAce = FirstAce(tAcl); for (ULONG iEntry = 0; iEntry < tAcl->AceCount; tAce = NextAce(tAce), iEntry++) { // check inheritance bits - AceOrder oThisAceOrder = DetermineAceOrder(tAce); + const AceOrder oThisAceOrder = DetermineAceOrder(tAce); // make sure this order is not less then the current order if (oThisAceOrder < oOrderOverall) diff --git a/OperationCheckCanonical.h b/OperationCheckCanonical.h index 218a166..9f220ad 100644 --- a/OperationCheckCanonical.h +++ b/OperationCheckCanonical.h @@ -8,7 +8,7 @@ class OperationCheckCanonical : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"CheckCanonical"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; public: @@ -31,6 +31,6 @@ class OperationCheckCanonical : public Operation bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; // constructors - OperationCheckCanonical(std::queue & oArgList); + OperationCheckCanonical(std::queue & oArgList, std::wstring sCommand); }; diff --git a/OperationCompact.cpp b/OperationCompact.cpp index 237654e..749d7ef 100644 --- a/OperationCompact.cpp +++ b/OperationCompact.cpp @@ -5,11 +5,9 @@ #include -ClassFactory * OperationCompact::RegisteredFactory = -new ClassFactory(GetCommand()); -std::atomic iTestCount; +ClassFactory OperationCompact::RegisteredFactory(GetCommand()); -OperationCompact::OperationCompact(std::queue & oArgList) : Operation(oArgList) +OperationCompact::OperationCompact(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // flag this as being an ace-level action AppliesToDacl = true; @@ -19,7 +17,7 @@ OperationCompact::OperationCompact(std::queue & oArgList) : Operat bool OperationCompact::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) { // sanity check - if (tCurrentAcl == NULL) return false; + if (tCurrentAcl == nullptr) return false; // track whether the acl was actually change so the caller may decide // that the change needs to be persisted diff --git a/OperationCompact.h b/OperationCompact.h index bd6a931..cade124 100644 --- a/OperationCompact.h +++ b/OperationCompact.h @@ -8,7 +8,7 @@ class OperationCompact : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"Compact"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; public: @@ -16,6 +16,6 @@ class OperationCompact : public Operation bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; // constructors - OperationCompact(std::queue & oArgList); + OperationCompact(std::queue & oArgList, std::wstring sCommand); }; diff --git a/OperationCopyDomain.cpp b/OperationCopyDomain.cpp index 61b47e1..56cc941 100644 --- a/OperationCopyDomain.cpp +++ b/OperationCopyDomain.cpp @@ -3,23 +3,22 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationCopyDomain::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationCopyDomain::RegisteredFactory(GetCommand()); -OperationCopyDomain::OperationCopyDomain(std::queue & oArgList) : Operation(oArgList) +OperationCopyDomain::OperationCopyDomain(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(2, oArgList); // fetch params - tSourceDomain = GetSidFromName(sSubArgs[0]); - tTargetDomain = GetSidFromName(sSubArgs[1]); + tSourceDomain = GetSidFromName(sSubArgs.at(0)); + tTargetDomain = GetSidFromName(sSubArgs.at(1)); // see if names could be resolved if (tSourceDomain == nullptr) { // complain - wprintf(L"ERROR: Invalid source domain '%s' specified for parameter '%s'.\n", sSubArgs[0].c_str(), GetCommand().c_str()); + wprintf(L"ERROR: Invalid source domain '%s' specified for parameter '%s'.\n", sSubArgs.at(0).c_str(), GetCommand().c_str()); exit(0); } @@ -27,7 +26,7 @@ OperationCopyDomain::OperationCopyDomain(std::queue & oArgList) : if (tTargetDomain == nullptr) { // complain - wprintf(L"ERROR: Invalid target domain '%s' specified for parameter '%s'.\n", sSubArgs[1].c_str(), GetCommand().c_str()); + wprintf(L"ERROR: Invalid target domain '%s' specified for parameter '%s'.\n", sSubArgs.at(1).c_str(), GetCommand().c_str()); exit(0); } @@ -40,7 +39,7 @@ OperationCopyDomain::OperationCopyDomain(std::queue & oArgList) : AppliesToSacl = true; // target certain parts of the security descriptor - if (sSubArgs.size() > 2) ProcessGranularTargetting(sSubArgs[2]); + if (sSubArgs.size() > 2) ProcessGranularTargetting(sSubArgs.at(2)); } bool OperationCopyDomain::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) @@ -50,7 +49,7 @@ bool OperationCopyDomain::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & // check explicit effective rights from sid (no groups) bool bAclIsDirty = false; - if (tCurrentAcl != NULL) + if (tCurrentAcl != nullptr) { ACCESS_ACE * tAceDacl = FirstAce(tCurrentAcl); for (LONG iEntry = 0; iEntry < tCurrentAcl->AceCount; tAceDacl = @@ -70,14 +69,14 @@ bool OperationCopyDomain::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & const PISID tSidStruct = (PISID) &tAceDacl->Sid; const PISID tSidTargetDomain = (PISID)tTargetDomain; - PSID tTargetAccountSid = NULL; + PSID tTargetAccountSid = nullptr; std::wstring sInfoToReport = L""; if (tSidStruct->SubAuthorityCount == 5 && tSidStruct->SubAuthority[0] == 21 && tSidStruct->SubAuthority[4] < 1000) { // create a new sid that has the domain identifier of the target domain - PSID tSidTmp = NULL; + PSID tSidTmp = nullptr; AllocateAndInitializeSid(&tSidStruct->IdentifierAuthority, tSidStruct->SubAuthorityCount, tSidStruct->SubAuthority[0], tSidTargetDomain->SubAuthority[1], tSidTargetDomain->SubAuthority[2], tSidTargetDomain->SubAuthority[3], tSidStruct->SubAuthority[4], 0, 0, 0, &tSidTmp); @@ -100,7 +99,7 @@ bool OperationCopyDomain::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & else { // translate the old sid to an account name - std::wstring sSourceAccountName = GetNameFromSid(&tAceDacl->Sid, NULL); + std::wstring sSourceAccountName = GetNameFromSid(&tAceDacl->Sid, nullptr); if (sSourceAccountName.empty()) continue; // check to see if an equivalent account exists in the target domain @@ -126,7 +125,7 @@ bool OperationCopyDomain::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & } // determine access mode - ACCESS_MODE tMode = NOT_USED_ACCESS; + ACCESS_MODE tMode = ACCESS_MODE::NOT_USED_ACCESS; if (tAceDacl->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) { tMode = GRANT_ACCESS; @@ -158,7 +157,7 @@ bool OperationCopyDomain::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & { std::wstring sTargetAccountName = GetNameFromSid(tTargetAccountSid); InputOutput::AddError(L"Could not add '" + sTargetAccountName + L"' for domain '" - + sTargetDomain + L"' to access control list since ACL was not canonical.", sSdPart); + + sTargetDomain + L"' because access control list is not canonical.", sSdPart); continue; } @@ -168,19 +167,19 @@ bool OperationCopyDomain::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tEa.grfAccessMode = tMode; tEa.grfInheritance = VALID_INHERIT_FLAGS & tAceDacl->Header.AceFlags; tEa.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; - tEa.Trustee.pMultipleTrustee = NULL; + tEa.Trustee.pMultipleTrustee = nullptr; tEa.Trustee.ptstrName = (LPWSTR) tTargetAccountSid; tEa.Trustee.TrusteeForm = TRUSTEE_IS_SID; tEa.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN; // special case since SetEntriesInAcl does not handle setting both success // and failure types together - PACL tNewDacl = NULL; + PACL tNewDacl = nullptr; DWORD iError = 0; if (CheckBitSet(tEa.grfAccessMode, SET_AUDIT_SUCCESS) && CheckBitSet(tEa.grfAccessMode, SET_AUDIT_FAILURE)) { - PACL tNewDaclTmp = NULL; + PACL tNewDaclTmp = nullptr; tEa.grfAccessMode = SET_AUDIT_SUCCESS; iError = SetEntriesInAcl(1, &tEa, tCurrentAcl, &tNewDaclTmp); tEa.grfAccessMode = SET_AUDIT_FAILURE; @@ -196,7 +195,7 @@ bool OperationCopyDomain::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & } // verify the new acl could be generated - if (iError != ERROR_SUCCESS || tNewDacl == NULL) + if (iError != ERROR_SUCCESS || tNewDacl == nullptr) { std::wstring sTargetAccountName = GetNameFromSid(tTargetAccountSid); InputOutput::AddError(L"Could not add '" + sTargetAccountName + L"' for domain '" diff --git a/OperationCopyDomain.h b/OperationCopyDomain.h index d105e98..ddeb457 100644 --- a/OperationCopyDomain.h +++ b/OperationCopyDomain.h @@ -8,7 +8,7 @@ class OperationCopyDomain : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"CopyDomain"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; // operation specific PSID tSourceDomain = nullptr; @@ -22,5 +22,5 @@ class OperationCopyDomain : public Operation bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; // constructors - OperationCopyDomain(std::queue & oArgList); + OperationCopyDomain(std::queue & oArgList, std::wstring sCommand); }; \ No newline at end of file diff --git a/OperationDomainPaths.cpp b/OperationDomainPaths.cpp index 5e9d311..b54eb68 100644 --- a/OperationDomainPaths.cpp +++ b/OperationDomainPaths.cpp @@ -14,16 +14,15 @@ #include "OperationSharePaths.h" #include "InputOutput.h" -ClassFactory * OperationDomainPaths::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationDomainPaths::RegisteredFactory(GetCommand()); -OperationDomainPaths::OperationDomainPaths(std::queue & oArgList) : Operation(oArgList) +OperationDomainPaths::OperationDomainPaths(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList); // initialize com only - static HRESULT hComInit = CoInitializeEx(NULL, COINIT_MULTITHREADED); + static HRESULT hComInit = CoInitializeEx(nullptr, COINIT_MULTITHREADED); if (hComInit != S_OK && hComInit != S_FALSE) { wprintf(L"ERROR: Could not initialize COM.\n"); @@ -32,11 +31,11 @@ OperationDomainPaths::OperationDomainPaths(std::queue & oArgList) // find a domain controller for the specified domain PDOMAIN_CONTROLLER_INFO tDomainControllerInfo; - if (DsGetDcName(NULL, sSubArgs[0].c_str(), NULL, NULL, + if (DsGetDcName(nullptr, sSubArgs.at(0).c_str(), nullptr, nullptr, DS_IS_FLAT_NAME | DS_RETURN_DNS_NAME | DS_TRY_NEXTCLOSEST_SITE | DS_FORCE_REDISCOVERY, &tDomainControllerInfo) != ERROR_SUCCESS) { - wprintf(L"ERROR: Could not locate domain controller for domain '%s'\n", sSubArgs[0].c_str()); + wprintf(L"ERROR: Could not locate domain controller for domain '%s'\n", sSubArgs.at(0).c_str()); exit(-1); } @@ -49,10 +48,10 @@ OperationDomainPaths::OperationDomainPaths(std::queue & oArgList) // bind to global catalog CComPtr oSearch; - if (FAILED(ADsOpenObject(sPath.c_str(), NULL, NULL, ADS_SECURE_AUTHENTICATION, + if (FAILED(ADsOpenObject(sPath.c_str(), nullptr, NULL, ADS_SECURE_AUTHENTICATION, IID_IDirectorySearch, (void**)&oSearch))) { - wprintf(L"ERROR: Could not establish search for domain '%s'\n", sSubArgs[0].c_str()); + wprintf(L"ERROR: Could not establish search for domain '%s'\n", sSubArgs.at(0).c_str()); exit(-1); } @@ -65,7 +64,7 @@ OperationDomainPaths::OperationDomainPaths(std::queue & oArgList) // set the search preference. if (FAILED(oSearch->SetSearchPreference(&SearchPref, 1))) { - wprintf(L"ERROR: Could not set search preference for domain '%s'\n", sSubArgs[0].c_str()); + wprintf(L"ERROR: Could not set search preference for domain '%s'\n", sSubArgs.at(0).c_str()); exit(-1); } @@ -79,7 +78,7 @@ OperationDomainPaths::OperationDomainPaths(std::queue & oArgList) ADS_SEARCH_HANDLE hSearch; if (FAILED(oSearch->ExecuteSearch(sSearchFilter, sAttributes, _countof(sAttributes), &hSearch))) { - wprintf(L"ERROR: Could not execute search for domain '%s'\n", sSubArgs[0].c_str()); + wprintf(L"ERROR: Could not execute search for domain '%s'\n", sSubArgs.at(0).c_str()); exit(-1); } @@ -98,7 +97,7 @@ OperationDomainPaths::OperationDomainPaths(std::queue & oArgList) // add the server to our list oArgList.push(L"/SharePaths"); oArgList.push(std::wstring(oColumn.pADsValues->CaseIgnoreString) + L"." + sSuffix + - ((sSubArgs.size() == 2) ? (L":" + sSubArgs[1]) : L"")); + ((sSubArgs.size() == 2) ? (L":" + sSubArgs.at(1)) : L"")); // free the column. oSearch->FreeColumn(&oColumn); @@ -107,7 +106,7 @@ OperationDomainPaths::OperationDomainPaths(std::queue & oArgList) // close search handle if (oSearch->CloseSearchHandle(hSearch) != NULL) { - wprintf(L"ERROR: Could not close search for domain '%s'\n", sSubArgs[0].c_str()); + wprintf(L"ERROR: Could not close search for domain '%s'\n", sSubArgs.at(0).c_str()); exit(-1); } }; diff --git a/OperationDomainPaths.h b/OperationDomainPaths.h index 76170f0..09420d0 100644 --- a/OperationDomainPaths.h +++ b/OperationDomainPaths.h @@ -8,10 +8,10 @@ class OperationDomainPaths : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"DomainPaths"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; public: // constructors - OperationDomainPaths(std::queue & oArgList); + OperationDomainPaths(std::queue & oArgList, std::wstring sCommand); }; \ No newline at end of file diff --git a/OperationFactory.h b/OperationFactory.h index b0d3417..873d710 100644 --- a/OperationFactory.h +++ b/OperationFactory.h @@ -6,7 +6,7 @@ class FactoryPlant { protected: - virtual Operation * CreateInstanceSub(std::queue & oArgList) = 0; + virtual Operation * CreateInstanceSub(std::queue & oArgList, std::wstring sCommand) = 0; static std::map & GetCommands() { @@ -32,8 +32,7 @@ class FactoryPlant } // convert to uppercase for map matching - std::transform(sCommand.begin(), sCommand.end(), sCommand.begin(), - [](const WCHAR c) { return static_cast(::toupper(c)); }); + ConvertToUpper(sCommand); // remove the first character sCommand.erase(0, 1); @@ -49,7 +48,7 @@ class FactoryPlant } // create the the new class - return GetCommands()[sCommand]->CreateInstanceSub(oArgList); + return GetCommands()[sCommand]->CreateInstanceSub(oArgList, sCommand); } }; @@ -57,17 +56,16 @@ template class ClassFactory : public FactoryPlant { private: - Operation * CreateInstanceSub(std::queue & oArgList) override + Operation * CreateInstanceSub(std::queue & oArgList, std::wstring sCommand) override { - return new SubType(oArgList); + return new SubType(oArgList, sCommand); } public: ClassFactory(std::wstring sCommand) { - std::transform(sCommand.begin(), sCommand.end(), sCommand.begin(), - [](const WCHAR c) { return static_cast(::toupper(c)); }); + ConvertToUpper(sCommand); GetCommands()[sCommand] = this; }; }; diff --git a/OperationFindAccount.cpp b/OperationFindAccount.cpp index 9ac280c..213d367 100644 --- a/OperationFindAccount.cpp +++ b/OperationFindAccount.cpp @@ -2,22 +2,21 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationFindAccount::RegisteredFactory = - new ClassFactory(GetCommand()); +ClassFactory OperationFindAccount::RegisteredFactory(GetCommand()); -OperationFindAccount::OperationFindAccount(std::queue & oArgList) : Operation(oArgList) +OperationFindAccount::OperationFindAccount(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList); // decode the passed parameter to an account name - tFindSid = GetSidFromName(sSubArgs[0]); + tFindSid = GetSidFromName(sSubArgs.at(0)); // see if names could be resolved if (tFindSid == nullptr) { // complain - wprintf(L"ERROR: Invalid account '%s' specified for parameter '%s'.\n", sSubArgs[0].c_str(), GetCommand().c_str()); + wprintf(L"ERROR: Invalid account '%s' specified for parameter '%s'.\n", sSubArgs.at(0).c_str(), GetCommand().c_str()); exit(0); } @@ -31,7 +30,7 @@ OperationFindAccount::OperationFindAccount(std::queue & oArgList) AppliesToOwner = true; // target certain parts of the security descriptor - if (sSubArgs.size() > 1) ProcessGranularTargetting(sSubArgs[1]); + if (sSubArgs.size() > 1) ProcessGranularTargetting(sSubArgs.at(1)); } SidActionResult OperationFindAccount::DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) diff --git a/OperationFindAccount.h b/OperationFindAccount.h index 3ccd9bc..4f7f748 100644 --- a/OperationFindAccount.h +++ b/OperationFindAccount.h @@ -8,7 +8,7 @@ class OperationFindAccount : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"FindAccount"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; // operation specific PSID tFindSid = nullptr; @@ -20,5 +20,5 @@ class OperationFindAccount : public Operation SidActionResult DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; // constructors - OperationFindAccount(std::queue & oArgList); + OperationFindAccount(std::queue & oArgList, std::wstring sCommand); }; \ No newline at end of file diff --git a/OperationFindDomain.cpp b/OperationFindDomain.cpp index 06ffb4a..a54c5a5 100644 --- a/OperationFindDomain.cpp +++ b/OperationFindDomain.cpp @@ -2,22 +2,21 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationFindDomain::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationFindDomain::RegisteredFactory(GetCommand()); -OperationFindDomain::OperationFindDomain(std::queue & oArgList) : Operation(oArgList) +OperationFindDomain::OperationFindDomain(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList); // decode the passed parameter to an account name - tDomainSid = GetSidFromName(sSubArgs[0]); + tDomainSid = GetSidFromName(sSubArgs.at(0)); // see if names could be resolved if (tDomainSid == nullptr) { // complain - wprintf(L"ERROR: Invalid domain '%s' specified for parameter '%s'.\n", sSubArgs[0].c_str(), GetCommand().c_str()); + wprintf(L"ERROR: Invalid domain '%s' specified for parameter '%s'.\n", sSubArgs.at(0).c_str(), GetCommand().c_str()); exit(0); } @@ -32,7 +31,7 @@ OperationFindDomain::OperationFindDomain(std::queue & oArgList) : AppliesToOwner = true; // target certain parts of the security descriptor - if (sSubArgs.size() > 1) ProcessGranularTargetting(sSubArgs[1]); + if (sSubArgs.size() > 1) ProcessGranularTargetting(sSubArgs.at(1)); } SidActionResult OperationFindDomain::DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) diff --git a/OperationFindDomain.h b/OperationFindDomain.h index 0844b2a..f79bcfa 100644 --- a/OperationFindDomain.h +++ b/OperationFindDomain.h @@ -8,7 +8,7 @@ class OperationFindDomain : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"FindDomain"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; // operation specific PSID tDomainSid = nullptr; @@ -20,5 +20,5 @@ class OperationFindDomain : public Operation SidActionResult DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; // constructors - OperationFindDomain(std::queue & oArgList); + OperationFindDomain(std::queue & oArgList, std::wstring sCommand); }; diff --git a/OperationFindNullAcl.cpp b/OperationFindNullAcl.cpp index 155c7de..f712c2e 100644 --- a/OperationFindNullAcl.cpp +++ b/OperationFindNullAcl.cpp @@ -2,10 +2,9 @@ #include "DriverKitPartial.h" #include "InputOutput.h" -ClassFactory * OperationFindNullAcl::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationFindNullAcl::RegisteredFactory(GetCommand()); -OperationFindNullAcl::OperationFindNullAcl(std::queue & oArgList) : Operation(oArgList) +OperationFindNullAcl::OperationFindNullAcl(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // flag this as being an ace-level action AppliesToDacl = true; @@ -14,7 +13,7 @@ OperationFindNullAcl::OperationFindNullAcl(std::queue & oArgList) bool OperationFindNullAcl::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) { // sanity check (null acl is considered valid) - if (tCurrentAcl == NULL) + if (tCurrentAcl == nullptr) { InputOutput::AddInfo(L"Access control list is null", sSdPart); } diff --git a/OperationFindNullAcl.h b/OperationFindNullAcl.h index 5ad7d68..5435800 100644 --- a/OperationFindNullAcl.h +++ b/OperationFindNullAcl.h @@ -8,7 +8,7 @@ class OperationFindNullAcl : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"FindNullAcl"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; public: @@ -16,6 +16,6 @@ class OperationFindNullAcl : public Operation bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; // constructors - OperationFindNullAcl(std::queue & oArgList); + OperationFindNullAcl(std::queue & oArgList, std::wstring sCommand); }; diff --git a/OperationGrantDenyPerms.cpp b/OperationGrantDenyPerms.cpp new file mode 100644 index 0000000..ca70cad --- /dev/null +++ b/OperationGrantDenyPerms.cpp @@ -0,0 +1,186 @@ +#include "OperationGrantDenyPerms.h" +#include "OperationCheckCanonical.h" +#include "InputOutput.h" +#include "Functions.h" + +#include +#include + +ClassFactory OperationGrantDenyPerms::RegisteredFactoryGrant(GetCommandAdd()); +ClassFactory OperationGrantDenyPerms::RegisteredFactoryDeny(GetCommandDeny()); + +OperationGrantDenyPerms::OperationGrantDenyPerms(std::queue& oArgList, std::wstring sCommand) : Operation(oArgList) +{ + // exit if there are not enough arguments to parse + std::vector sSubArgs = ProcessAndCheckArgs(2, oArgList); + + // store off variables for reporting later + sIdentity = sSubArgs.at(0); + sPerms = sSubArgs.at(1); + + // constructor extract the list of perm strings + ConvertToUpper(sPerms); + std::vector aPermList; + const std::wregex oPermsRegex(LR"(\(([A-Z]+)\))"); + for (std::wsregex_iterator oPermsIterator(sPerms.begin(), sPerms.end(), oPermsRegex, + std::regex_constants::match_continuous); oPermsIterator != std::wsregex_iterator(); oPermsIterator++) { + aPermList.push_back((*oPermsIterator).str(1)); + } + + // error if no options set + if (aPermList.size() == 0) + { + wprintf(L"ERROR: Invalid or no permissions string specified for parameter '%s'.\n", GetCommandAdd().c_str()); + exit(-1); + } + + // populate default values + ConvertToUpper(sCommand); + tEa.grfAccessMode = (sCommand == GetCommandAdd()) ? GRANT_ACCESS : DENY_ACCESS; + tEa.grfInheritance = NO_INHERITANCE; + tEa.grfAccessPermissions = 0; + tEa.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; + tEa.Trustee.pMultipleTrustee = nullptr; + tEa.Trustee.TrusteeForm = TRUSTEE_IS_SID; + tEa.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN; + + // see if names could be resolved + tEa.Trustee.ptstrName = (LPWCH) GetSidFromName(sIdentity); + if (tEa.Trustee.ptstrName == nullptr) + { + wprintf(L"ERROR: Invalid account '%s' specified for parameter '%s'.\n", + sIdentity.c_str(), GetCommandAdd().c_str()); + exit(-1); + } + + // list for easily parsing icacls permissions access syntax + const std::map aPermsMap = + { + /* combo perms */ + { L"N", 0 }, + { L"F", FILE_ALL_ACCESS }, + { L"M", FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE }, + { L"RX", FILE_GENERIC_READ | FILE_GENERIC_EXECUTE }, + { L"R", FILE_GENERIC_READ }, + { L"W", FILE_GENERIC_WRITE }, + { L"D", SYNCHRONIZE | DELETE }, + + /* itemized perms */ + { L"DE", DELETE }, + { L"RC", READ_CONTROL }, + { L"WDAC", WRITE_DAC }, + { L"WO", WRITE_OWNER }, + { L"S", SYNCHRONIZE }, + { L"AS", ACCESS_SYSTEM_SECURITY }, + { L"MA", MAXIMUM_ALLOWED }, + { L"GR", GENERIC_READ }, + { L"GW", GENERIC_WRITE }, + { L"GE", GENERIC_EXECUTE }, + { L"GA", GENERIC_ALL }, + { L"RD", FILE_READ_DATA | FILE_LIST_DIRECTORY }, + { L"WD", FILE_WRITE_DATA | FILE_ADD_FILE }, + { L"AD", FILE_APPEND_DATA | FILE_ADD_SUBDIRECTORY }, + { L"REA", FILE_READ_EA }, + { L"WEA", FILE_WRITE_EA }, + { L"X", FILE_EXECUTE | FILE_EXECUTE }, + { L"DC", FILE_DELETE_CHILD }, + { L"RA", FILE_READ_ATTRIBUTES }, + { L"WA", FILE_WRITE_ATTRIBUTES } + }; + + // list for easily parsing icacls inheritance syntax + const std::map aInheritMap = + { + { L"OI", OBJECT_INHERIT_ACE }, + { L"CI", CONTAINER_INHERIT_ACE }, + { L"IO", NO_PROPAGATE_INHERIT_ACE }, + { L"NP", INHERIT_ONLY_ACE } + }; + + // decode the permissions string to their binary values + for (const std::wstring sKey : aPermList) + { + if (aInheritMap.find(sKey) != aInheritMap.end()) tEa.grfInheritance |= aInheritMap.at(sKey); + else if (aPermsMap.find(sKey) != aPermsMap.end()) tEa.grfAccessPermissions |= aPermsMap.at(sKey); + else + { + // complain + wprintf(L"ERROR: Invalid permission string '%s' specified for parameter '%s'.\n", sPerms.c_str(), GetCommandAdd().c_str()); + exit(-1); + } + } + + // do a reverse lookup on the name for info messages + sIdentity = GetNameFromSidEx((PSID)tEa.Trustee.ptstrName); + + // flag this as being an ace-level action + AppliesToDacl = true; +} + +bool OperationGrantDenyPerms::ProcessAclAction(WCHAR* const sSdPart, ObjectEntry& tObjectEntry, PACL& tCurrentAcl, bool& bAclReplacement) +{ + // define what constitutes 'full control' based on the object + const DWORD iObjectTypeMask = IsDirectory(tObjectEntry.Attributes) + ? ~0 : ~(CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE); + + // verify this is not alraedy part of the ace as an inherited or explicit entry + if (tCurrentAcl != nullptr) + { + ACCESS_ACE* tAceDacl = FirstAce(tCurrentAcl); + for (ULONG iEntry = 0; iEntry < tCurrentAcl->AceCount; tAceDacl = NextAce(tAceDacl), iEntry++) + { + // skip other ace types that are not allowing accessing + if ((tAceDacl->Header.AceType == ACCESS_ALLOWED_ACE_TYPE && + tEa.grfAccessMode != GRANT_ACCESS) || + (tAceDacl->Header.AceType == ACCESS_DENIED_ACE_TYPE && + tEa.grfAccessMode != DENY_ACCESS)) continue; + + // do not look at sids that are not the specified account + if (SidNotMatch(&tAceDacl->Sid, ((PSID) tEa.Trustee.ptstrName))) continue; + + // skip if access mask is not exactly the same + if (tAceDacl->Mask != tEa.grfAccessPermissions) continue; + + // skip this ace inheritance mask is not the same except if it is inherited + if ((tAceDacl->Header.AceFlags & ((DWORD) ~INHERITED_ACE)) != + (tEa.grfInheritance & iObjectTypeMask)) continue; + + // if we got this far, it means we have a duplicate ace so just skip it + return false; + } + } + + // since SetEntriesInAcl reacts poorly / unexpectedly in cases where the + // acl is not canonical, just error out and continue on + if (!OperationCheckCanonical::IsAclCanonical(tCurrentAcl)) + { + InputOutput::AddError(L"Could not modify permissions for because access control list is not canonical.", sSdPart); + return false; + } + + // merge the new trustee into the dacl + PACL tNewDacl; + if (SetEntriesInAcl(1, &tEa, tCurrentAcl, &tNewDacl) != ERROR_SUCCESS) + { + InputOutput::AddError(L"Could not modify permissions due to a system error.", sSdPart); + return false; + } + + // do not commit change is no actual change was made + if (tCurrentAcl->AclSize == tNewDacl->AclSize && + memcmp(tCurrentAcl, tNewDacl, tCurrentAcl->AclSize) == 0) + { + LocalFree(tNewDacl); + return false; + } + + // cleanup the old dacl (if necessary) and assign our new active dacl + if (bAclReplacement) LocalFree(tCurrentAcl); + tCurrentAcl = tNewDacl; + bAclReplacement = true; + + // flag to commit tag and cleanup dacl + InputOutput::AddInfo(((tEa.grfAccessMode == GRANT_ACCESS) ? L"Granting '" : L"Denying '") + + sIdentity + L"' with perms '" + sPerms + L"'", sSdPart); + return true; +} diff --git a/OperationGrantDenyPerms.h b/OperationGrantDenyPerms.h new file mode 100644 index 0000000..f9ad25b --- /dev/null +++ b/OperationGrantDenyPerms.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +#include "Operation.h" + +class OperationGrantDenyPerms : public Operation +{ +private: + + // statics used by command registration utility + static std::wstring GetCommandAdd() { return L"GrantPerms"; } + static std::wstring GetCommandDeny() { return L"DenyPerms"; } + static ClassFactory RegisteredFactoryGrant; + static ClassFactory RegisteredFactoryDeny; + + // operation specific + EXPLICIT_ACCESS tEa; + std::wstring sIdentity; + std::wstring sPerms; + +public: + + // overrides + bool ProcessAclAction(WCHAR* const sSdPart, ObjectEntry& tObjectEntry, PACL& tCurrentAcl, bool& bAclReplacement) override; + + // constructors + OperationGrantDenyPerms(std::queue& oArgList, std::wstring sCommand); +}; \ No newline at end of file diff --git a/OperationHelp.cpp b/OperationHelp.cpp index 72ebad9..fcc6e8c 100644 --- a/OperationHelp.cpp +++ b/OperationHelp.cpp @@ -2,14 +2,11 @@ #include -ClassFactory * OperationHelp::RegisteredFactory = - new ClassFactory(GetCommand()); -ClassFactory * OperationHelp::RegisteredFactoryAltOne = - new ClassFactory(GetCommandAltOne()); -ClassFactory * OperationHelp::RegisteredFactoryAltTwo = - new ClassFactory(GetCommandAltTwo()); - -OperationHelp::OperationHelp(std::queue & oArgList) : Operation(oArgList) +ClassFactory OperationHelp::RegisteredFactory(GetCommand()); +ClassFactory OperationHelp::RegisteredFactoryAltOne(GetCommandAltOne()); +ClassFactory OperationHelp::RegisteredFactoryAltTwo(GetCommandAltTwo()); + +OperationHelp::OperationHelp(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { std::wcout << LR"( @@ -48,7 +45,7 @@ or end of your command as to not confuse them with ordered parameters. Specifies a file that contains a list of files or directories to process. Each path should be listed on a separate line and the file should be UTF-8 formatted. Each path read from the file is processed the same as if it - where passed using /Path (see above). + were passed using /Path (see above). /SharePaths [:AdminOnly|IncludeHidden|Match=|NoMatch=] Specifies a server that has one or more shares to process. This command is @@ -154,15 +151,16 @@ Commands That Do Not Alter Security Commands That Can Alter Security (When /WhatIf Is Not Present) -------------------------------- -/AddAccountIfMissing - This command will ensure the account specified has full control access to - path and all directories/files under the path either via explicit or - inherited permissions. This command does not take into account any - permissions that would be granted to the specified user via group - membership. If the account does not have access, access is - granted. This command is useful to correct issues where a user or - administrator has mistakenly removed an administrative group from some - directories. +/GrantPerms : +/DenyPerms : + This command will ensure the account specified has the specified access to + the path and all subdirectories/files within the path either via explicit or + inherited permissions. The syntax of : is the same of that + from ICACLS. For example, /GrantPerms SYSTEM:(F)(CI)(OI) will check if + SYSTEM has Full Control to all subdirectories and, if it does not, will add + full control with inheritance enabled. This command is often useful to + correct issues where a user or administrator has mistakenly removed an group + from subdirectories with broken inheritance. )"; std::wcout << @@ -176,11 +174,11 @@ Commands That Can Alter Security (When /WhatIf Is Not Present) This command will look for mergeable entries in the security descriptor and merge them. For example, running icacls.exe /grant Everyone:R followed by icacls.exe /grant Everyone:(CI)(OI)(R) will produce - two entries even those the second command supersedes the first one. - Windows Explorer automatically merges these entries when display security + two entries even though the second command supersedes the first one. + Windows Explorer automatically merges these entries when displaying security information so you have to use other utilities to detect these inefficiencies. While there's nothing inherently wrong with these - entries, it possible for them to result file system is performance + entries, it is possible for them to result in file system performance degradation. /CopyDomain : @@ -192,7 +190,7 @@ Commands That Can Alter Security (When /WhatIf Is Not Present) /MoveDomain : This command will look to see whether any account in - has an identically-named account in . If so, any entires + has an identically-named account in . If so, any entries are converted to use the new domain. For example, 'OldDomain\Domain Admins' would become 'NewDomain\Domain Admins'. Since this operation relies on the names being resolvable, specifying a SID @@ -203,7 +201,7 @@ Commands That Can Alter Security (When /WhatIf Is Not Present) is found as the file owner, the owner is replaced by the built-in Administrators group. If the specified name is found as the group owner (a defunct attribute that has no function in terms of security), it is - also replace with the built-in Administrators group. + also replaced with the built-in Administrators group. /RemoveOrphans Remove any account whose SID is derived from the specified @@ -211,8 +209,8 @@ Commands That Can Alter Security (When /WhatIf Is Not Present) /RemoveRedundant This command will remove any explicit permission that is redundant of - of the permissions its already given through inheritance. This option - helps recovered from the many individual explicit permissions that may + the permissions it is already given through inheritance. This option + helps recover from the many individual explicit permissions that may have been littered from the old cacls.exe command that didn't understand how to set up inheritance. @@ -233,10 +231,10 @@ Commands That Can Alter Security (When /WhatIf Is Not Present) Will set the owner of the file to the name specified. /UpdateHistoricalSids - Will update any SIDs that present in the security descriptor and are part - of a SID history with the primary SID that is associated an account. This - is especially useful after a domain migration and prior to removing - excess SID history on accounts. + Will update any SIDs that are present in the security descriptor and are + part of a SID history with the primary SID that is associated with an + account. This is especially useful after a domain migration and prior to + removing excess SID history on accounts. Exclusive Options ================= @@ -248,19 +246,19 @@ Exclusive options cannot be combined with any other security operations. /ResetChildren This will reset all children of path to the to inherit from the parent. It will not affect the security of the parent. This command does not affect - the security the root directory as specified by the /Path argument. + the security of the root directory as specified by the /Path argument. /InheritChildren This will cause any parent that is currently set to block inheritance to start allowing inheritance. Any explicit entries on the children are - preserved. This command does not will not affect the security the root - directory as specified by the /Path argument. + preserved. This command will not affect the security of the root directory + as specified by the /Path argument. Other Notes & Limitations ========================= - To only affect a particular part of a security descriptor, you can add on an optional ':X' parameter after the end of the account name where X is a comma - separated list of DACL,SACL, OWNER, or GROUP. For example, + separated list of DACL, SACL, OWNER, or GROUP. For example, '/RemoveAccount "DOM\joe:DACL,OWNER"' will only cause the designated account to be removed from the DACL and OWNER parts of the security descriptor. diff --git a/OperationHelp.h b/OperationHelp.h index 417cce8..5705dd5 100644 --- a/OperationHelp.h +++ b/OperationHelp.h @@ -10,12 +10,12 @@ class OperationHelp : public Operation static std::wstring GetCommand() { return L"Help"; } static std::wstring GetCommandAltOne() { return L"?"; } static std::wstring GetCommandAltTwo() { return L"H"; } - static ClassFactory * RegisteredFactory; - static ClassFactory * RegisteredFactoryAltOne; - static ClassFactory * RegisteredFactoryAltTwo; + static ClassFactory RegisteredFactory; + static ClassFactory RegisteredFactoryAltOne; + static ClassFactory RegisteredFactoryAltTwo; public: // constructors - OperationHelp(std::queue & oArgList); + OperationHelp(std::queue & oArgList, std::wstring sCommand); }; \ No newline at end of file diff --git a/OperationInheritChildren.cpp b/OperationInheritChildren.cpp index 8f21055..91962a1 100644 --- a/OperationInheritChildren.cpp +++ b/OperationInheritChildren.cpp @@ -3,10 +3,9 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationInheritChildren::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationInheritChildren::RegisteredFactory(GetCommand()); -OperationInheritChildren::OperationInheritChildren(std::queue & oArgList) : Operation(oArgList) +OperationInheritChildren::OperationInheritChildren(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // flag this as being an ace-level action AppliesToDacl = true; diff --git a/OperationInheritChildren.h b/OperationInheritChildren.h index 3a04512..32a254f 100644 --- a/OperationInheritChildren.h +++ b/OperationInheritChildren.h @@ -8,7 +8,7 @@ class OperationInheritChildren : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"InheritChildren"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; public: @@ -16,6 +16,6 @@ class OperationInheritChildren : public Operation bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; // constructors - OperationInheritChildren(std::queue & oArgList); + OperationInheritChildren(std::queue & oArgList, std::wstring sCommand); }; diff --git a/OperationLocate.cpp b/OperationLocate.cpp index 3776b65..8d9c330 100644 --- a/OperationLocate.cpp +++ b/OperationLocate.cpp @@ -2,12 +2,11 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationLocate::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationLocate::RegisteredFactory(GetCommand()); #define Q(x) L"\"" + (x) + L"\"" -OperationLocate::OperationLocate(std::queue & oArgList) : Operation(oArgList) +OperationLocate::OperationLocate(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sReportFile = ProcessAndCheckArgs(1, oArgList, L"\\0"); @@ -15,7 +14,7 @@ OperationLocate::OperationLocate(std::queue & oArgList) : Operatio // fetch params HANDLE hFile = CreateFile(sReportFile[0].c_str(), GENERIC_WRITE, - FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); // see if names could be resolved if (hFile == INVALID_HANDLE_VALUE) @@ -34,7 +33,7 @@ OperationLocate::OperationLocate(std::queue & oArgList) : Operatio // write out the file type marker const BYTE hHeader[] = { 0xEF,0xBB,0xBF }; DWORD iBytes = 0; - if (WriteFile(hFile, &hHeader, _countof(hHeader), &iBytes, NULL) == 0) + if (WriteFile(hFile, &hHeader, _countof(hHeader), &iBytes, nullptr) == 0) { wprintf(L"ERROR: Could not write out file type marker '%s'.\n", GetCommand().c_str()); exit(-1); @@ -56,11 +55,11 @@ OperationLocate::OperationLocate(std::queue & oArgList) : Operatio // compile the regular expression try { - tRegex = std::wregex(sMatchAndArgs[0], std::wregex::icase | std::wregex::optimize); + tRegex = std::wregex(sMatchAndArgs.at(0), std::wregex::icase | std::wregex::optimize); } catch (const std::regex_error &) { - wprintf(L"ERROR: Invalid regular expression '%s' specified for parameter '%s'.\n", sMatchAndArgs[0].c_str(), GetCommand().c_str()); + wprintf(L"ERROR: Invalid regular expression '%s' specified for parameter '%s'.\n", sMatchAndArgs.at(0).c_str(), GetCommand().c_str()); exit(-1); } } @@ -69,7 +68,7 @@ void OperationLocate::ProcessObjectAction(ObjectEntry & tObjectEntry) { // skip any file names that do not match the regex const WCHAR * sFileName = tObjectEntry.Name.c_str(); - if (wcsrchr(sFileName, '\\') != NULL) sFileName = wcsrchr(sFileName, '\\') + 1; + if (wcsrchr(sFileName, '\\') != nullptr) sFileName = wcsrchr(sFileName, '\\') + 1; if (!std::regex_match(sFileName, tRegex)) return; // fetch file attribute data diff --git a/OperationLocate.h b/OperationLocate.h index b635b0c..220128a 100644 --- a/OperationLocate.h +++ b/OperationLocate.h @@ -10,7 +10,7 @@ class OperationLocate : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"Locate"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; // operation specific HANDLE hReportFile = INVALID_HANDLE_VALUE; @@ -22,5 +22,5 @@ class OperationLocate : public Operation void ProcessObjectAction(ObjectEntry & tObjectEntry) override; // constructors - OperationLocate(std::queue & oArgList); + OperationLocate(std::queue & oArgList, std::wstring sCommand); }; \ No newline at end of file diff --git a/OperationLocateShortcut.cpp b/OperationLocateShortcut.cpp index 10bd265..1c4aa95 100644 --- a/OperationLocateShortcut.cpp +++ b/OperationLocateShortcut.cpp @@ -7,26 +7,25 @@ #include #include -ClassFactory * OperationLocateShortcut::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationLocateShortcut::RegisteredFactory(GetCommand()); #define Q(x) L"\"" + (x) + L"\"" -OperationLocateShortcut::OperationLocateShortcut(std::queue & oArgList) : Operation(oArgList) +OperationLocateShortcut::OperationLocateShortcut(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sReportFile = ProcessAndCheckArgs(1, oArgList, L"\\0"); std::vector sMatchAndArgs = ProcessAndCheckArgs(1, oArgList, L"\\0"); // fetch params - HANDLE hFile = CreateFile(sReportFile[0].c_str(), GENERIC_WRITE, - FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + HANDLE hFile = CreateFile(sReportFile.at(0).c_str(), GENERIC_WRITE, + FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); // see if names could be resolved if (hFile == INVALID_HANDLE_VALUE) { // complain - wprintf(L"ERROR: Could not create file '%s' specified for parameter '%s'.\n", sReportFile[0].c_str(), GetCommand().c_str()); + wprintf(L"ERROR: Could not create file '%s' specified for parameter '%s'.\n", sReportFile.at(0).c_str(), GetCommand().c_str()); exit(-1); } @@ -39,7 +38,7 @@ OperationLocateShortcut::OperationLocateShortcut(std::queue & oArg // write out the file type marker const BYTE hHeader[] = { 0xEF,0xBB,0xBF }; DWORD iBytes = 0; - if (WriteFile(hFile, &hHeader, _countof(hHeader), &iBytes, NULL) == 0) + if (WriteFile(hFile, &hHeader, _countof(hHeader), &iBytes, nullptr) == 0) { wprintf(L"ERROR: Could not write out file type marker '%s'.\n", GetCommand().c_str()); exit(-1); @@ -62,7 +61,7 @@ OperationLocateShortcut::OperationLocateShortcut(std::queue & oArg // compile the regular expression try { - tRegexTarget = std::wregex(sMatchAndArgs[0], std::wregex::icase | std::wregex::optimize); + tRegexTarget = std::wregex(sMatchAndArgs.at(0), std::wregex::icase | std::wregex::optimize); tRegexLink = std::wregex(L".*\\.lnk", std::wregex::icase | std::wregex::optimize); } catch (const std::regex_error &) @@ -76,7 +75,7 @@ void OperationLocateShortcut::ProcessObjectAction(ObjectEntry & tObjectEntry) { // skip any file names that do not match the regex const WCHAR * sFileName = tObjectEntry.Name.c_str(); - if (wcsrchr(sFileName, '\\') != NULL) sFileName = wcsrchr(sFileName, '\\') + 1; + if (wcsrchr(sFileName, '\\') != nullptr) sFileName = wcsrchr(sFileName, '\\') + 1; if (!std::regex_match(sFileName, tRegexLink)) return; // initialize com for this thread @@ -84,7 +83,7 @@ void OperationLocateShortcut::ProcessObjectAction(ObjectEntry & tObjectEntry) if (!bComInitialized) { bComInitialized = true; - const HRESULT hComInit = CoInitializeEx(0, COINIT_APARTMENTTHREADED); + const HRESULT hComInit = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); if (hComInit != S_OK && hComInit != S_FALSE) { wprintf(L"ERROR: Could not initialize COM.\n"); @@ -121,9 +120,9 @@ void OperationLocateShortcut::ProcessObjectAction(ObjectEntry & tObjectEntry) if (tData.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) sAttributes += L"E"; // create shortcut interfaces - IShellLinkW * oLink = NULL; - IPersistFile * oFile = NULL; - if (CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (VOID **)&oLink) != S_OK || + IShellLinkW * oLink = nullptr; + IPersistFile * oFile = nullptr; + if (CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (VOID **)&oLink) != S_OK || oLink->QueryInterface(IID_IPersistFile, (VOID **)&oFile) != S_OK) { wprintf(L"ERROR: Could not initialize ShellLink COM instance.\n"); @@ -137,7 +136,7 @@ void OperationLocateShortcut::ProcessObjectAction(ObjectEntry & tObjectEntry) { WCHAR sTargetPathRaw[MAX_PATH]; WCHAR sWorkingDirRaw[MAX_PATH]; - if (oLink->GetPath(sTargetPathRaw, MAX_PATH, NULL, SLGP_RAWPATH) == S_OK) sTargetPath = sTargetPathRaw; + if (oLink->GetPath(sTargetPathRaw, MAX_PATH, nullptr, SLGP_RAWPATH) == S_OK) sTargetPath = sTargetPathRaw; if (oLink->GetWorkingDirectory(sWorkingDirRaw, MAX_PATH) == S_OK) sWorkingDirectory = sWorkingDirRaw; } diff --git a/OperationLocateShortcut.h b/OperationLocateShortcut.h index e0fd3f1..5439e98 100644 --- a/OperationLocateShortcut.h +++ b/OperationLocateShortcut.h @@ -10,7 +10,7 @@ class OperationLocateShortcut : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"LocateShortcut"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; // operation specific HANDLE hReportFile = INVALID_HANDLE_VALUE; @@ -23,5 +23,5 @@ class OperationLocateShortcut : public Operation void ProcessObjectAction(ObjectEntry & tObjectEntry) override; // constructors - OperationLocateShortcut(std::queue & oArgList); + OperationLocateShortcut(std::queue & oArgList, std::wstring sCommand); }; \ No newline at end of file diff --git a/OperationLog.cpp b/OperationLog.cpp index 18501a9..4408689 100644 --- a/OperationLog.cpp +++ b/OperationLog.cpp @@ -7,14 +7,13 @@ #include #include -ClassFactory * OperationLog::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationLog::RegisteredFactory(GetCommand()); #define Q(x) L"\"" + (x) + L"\"" HANDLE OperationLog::hLogHandle = INVALID_HANDLE_VALUE; -OperationLog::OperationLog(std::queue & oArgList) : Operation(oArgList) +OperationLog::OperationLog(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sLogFile = ProcessAndCheckArgs(1, oArgList, L"\\0"); @@ -27,13 +26,13 @@ OperationLog::OperationLog(std::queue & oArgList) : Operation(oArg } // fetch params - hLogHandle = CreateFile(sLogFile[0].c_str(), GENERIC_WRITE, - FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + hLogHandle = CreateFile(sLogFile.at(0).c_str(), GENERIC_WRITE, + FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); // write out the file type marker const BYTE hHeader[] = { 0xEF,0xBB,0xBF }; DWORD iBytes = 0; - if (WriteFile(hLogHandle, &hHeader, _countof(hHeader), &iBytes, NULL) == 0) + if (WriteFile(hLogHandle, &hHeader, _countof(hHeader), &iBytes, nullptr) == 0) { wprintf(L"ERROR: Could not write out file type marker '%s'.\n", GetCommand().c_str()); exit(-1); @@ -58,7 +57,7 @@ void OperationLog::LogFileItem(const std::wstring & sInfoLevel, const std::wstri // get time string WCHAR sDate[20]; - const __time64_t tUtcTime = _time64(NULL); + const __time64_t tUtcTime = _time64(nullptr); struct tm tLocalTime; _localtime64_s(&tLocalTime, &tUtcTime); wcsftime(sDate, _countof(sDate), L"%Y-%m-%d %H:%M:%S", &tLocalTime); diff --git a/OperationLog.h b/OperationLog.h index a95dabe..79a1b41 100644 --- a/OperationLog.h +++ b/OperationLog.h @@ -8,14 +8,14 @@ class OperationLog : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"Log"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; static HANDLE hLogHandle; public: // constructors - OperationLog(std::queue & oArgList); + OperationLog(std::queue & oArgList, std::wstring sCommand); // functions static void LogFileItem(const std::wstring & sInfoLevel, const std::wstring & sPath, const std::wstring & sMessage); diff --git a/OperationMoveDomain.cpp b/OperationMoveDomain.cpp index 499afac..ec063c6 100644 --- a/OperationMoveDomain.cpp +++ b/OperationMoveDomain.cpp @@ -2,23 +2,22 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationMoveDomain::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationMoveDomain::RegisteredFactory(GetCommand()); -OperationMoveDomain::OperationMoveDomain(std::queue & oArgList) : Operation(oArgList) +OperationMoveDomain::OperationMoveDomain(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(2, oArgList); // fetch params - tSourceDomain = GetSidFromName(sSubArgs[0]); - tTargetDomain = GetSidFromName(sSubArgs[1]); + tSourceDomain = GetSidFromName(sSubArgs.at(0)); + tTargetDomain = GetSidFromName(sSubArgs.at(1)); // see if names could be resolved if (tSourceDomain == nullptr) { // complain - wprintf(L"ERROR: Invalid source domain '%s' specified for parameter '%s'.\n", sSubArgs[0].c_str(), GetCommand().c_str()); + wprintf(L"ERROR: Invalid source domain '%s' specified for parameter '%s'.\n", sSubArgs.at(0).c_str(), GetCommand().c_str()); exit(0); } @@ -26,7 +25,7 @@ OperationMoveDomain::OperationMoveDomain(std::queue & oArgList) : if (tTargetDomain == nullptr) { // complain - wprintf(L"ERROR: Invalid target domain '%s' specified for parameter '%s'.\n", sSubArgs[1].c_str(), GetCommand().c_str()); + wprintf(L"ERROR: Invalid target domain '%s' specified for parameter '%s'.\n", sSubArgs.at(1).c_str(), GetCommand().c_str()); exit(0); } @@ -41,7 +40,7 @@ OperationMoveDomain::OperationMoveDomain(std::queue & oArgList) : AppliesToOwner = true; // target certain parts of the security descriptor - if (sSubArgs.size() > 2) ProcessGranularTargetting(sSubArgs[2]); + if (sSubArgs.size() > 2) ProcessGranularTargetting(sSubArgs.at(2)); } SidActionResult OperationMoveDomain::DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) @@ -63,7 +62,7 @@ SidActionResult OperationMoveDomain::DetermineSid(WCHAR * const sSdPart, ObjectE tSidStruct->SubAuthority[4] < 1000) { // create a new sid that has the domain identifier of the target domain - PSID tSidTmp = NULL; + PSID tSidTmp = nullptr; AllocateAndInitializeSid(&tSidStruct->IdentifierAuthority, tSidStruct->SubAuthorityCount, tSidStruct->SubAuthority[0], tSidTargetDomain->SubAuthority[1], tSidTargetDomain->SubAuthority[2], tSidTargetDomain->SubAuthority[3], tSidStruct->SubAuthority[4], 0, 0, 0, &tSidTmp); @@ -86,7 +85,7 @@ SidActionResult OperationMoveDomain::DetermineSid(WCHAR * const sSdPart, ObjectE else { // translate the old sid to an account name - std::wstring sSourceAccountName = GetNameFromSid(tCurrentSid, NULL); + std::wstring sSourceAccountName = GetNameFromSid(tCurrentSid, nullptr); if (sSourceAccountName.empty()) return SidActionResult::Nothing; // check to see if an equivalent account exists in the target domain diff --git a/OperationMoveDomain.h b/OperationMoveDomain.h index fc49237..bbdf461 100644 --- a/OperationMoveDomain.h +++ b/OperationMoveDomain.h @@ -8,7 +8,7 @@ class OperationMoveDomain : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"MoveDomain"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; // operation specific PSID tSourceDomain = nullptr; @@ -22,5 +22,5 @@ class OperationMoveDomain : public Operation SidActionResult DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; // constructors - OperationMoveDomain(std::queue & oArgList); + OperationMoveDomain(std::queue & oArgList, std::wstring sCommand); }; \ No newline at end of file diff --git a/OperationNoHiddenSystem.cpp b/OperationNoHiddenSystem.cpp index fe896e6..e4c97b3 100644 --- a/OperationNoHiddenSystem.cpp +++ b/OperationNoHiddenSystem.cpp @@ -1,10 +1,9 @@ #include "OperationNoHiddenSystem.h" #include "InputOutput.h" -ClassFactory * OperationNoHiddenSystem::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationNoHiddenSystem::RegisteredFactory(GetCommand()); -OperationNoHiddenSystem::OperationNoHiddenSystem(std::queue & oArgList) : Operation(oArgList) +OperationNoHiddenSystem::OperationNoHiddenSystem(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { InputOutput::ExcludeHiddenSystem() = true; } \ No newline at end of file diff --git a/OperationNoHiddenSystem.h b/OperationNoHiddenSystem.h index 5b21b5e..416c887 100644 --- a/OperationNoHiddenSystem.h +++ b/OperationNoHiddenSystem.h @@ -8,10 +8,10 @@ class OperationNoHiddenSystem : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"NoHiddenSystem"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; public: // constructors - OperationNoHiddenSystem(std::queue & oArgList); + OperationNoHiddenSystem(std::queue & oArgList, std::wstring sCommand); }; \ No newline at end of file diff --git a/OperationPath.cpp b/OperationPath.cpp index 30e1158..770e4d3 100644 --- a/OperationPath.cpp +++ b/OperationPath.cpp @@ -2,14 +2,13 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationPath::RegisteredFactory = - new ClassFactory(GetCommand()); +ClassFactory OperationPath::RegisteredFactory(GetCommand()); -OperationPath::OperationPath(std::queue & oArgList) : Operation(oArgList) +OperationPath::OperationPath(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList, L"\\0"); // store off the argument - InputOutput::ScanPaths().push_back(sSubArgs[0]); + InputOutput::ScanPaths().push_back(sSubArgs.at(0)); }; \ No newline at end of file diff --git a/OperationPath.h b/OperationPath.h index b1ddf09..3352678 100644 --- a/OperationPath.h +++ b/OperationPath.h @@ -8,10 +8,10 @@ class OperationPath : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"Path"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; public: // constructors - OperationPath(std::queue & oArgList); + OperationPath(std::queue & oArgList, std::wstring sCommand); }; \ No newline at end of file diff --git a/OperationPathList.cpp b/OperationPathList.cpp index d123629..7d67f53 100644 --- a/OperationPathList.cpp +++ b/OperationPathList.cpp @@ -7,16 +7,15 @@ #include #include -ClassFactory * OperationPathList::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationPathList::RegisteredFactory(GetCommand()); -OperationPathList::OperationPathList(std::queue & oArgList) : Operation(oArgList) +OperationPathList::OperationPathList(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList, L"\\0"); // open the file - std::wifstream fFile(sSubArgs[0].c_str()); + std::wifstream fFile(sSubArgs.at(0).c_str()); // adapt the stream to read windows unicode files (void) fFile.imbue(std::locale(fFile.getloc(), new std::codecvt_utf8 * RegisteredFactory; + static ClassFactory RegisteredFactory; public: // constructors - OperationPathList(std::queue & oArgList); + OperationPathList(std::queue & oArgList, std::wstring sCommand); }; \ No newline at end of file diff --git a/OperationPrintDescriptor.cpp b/OperationPrintDescriptor.cpp index acd230f..d6e52f7 100644 --- a/OperationPrintDescriptor.cpp +++ b/OperationPrintDescriptor.cpp @@ -3,10 +3,9 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationPrintDescriptor::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationPrintDescriptor::RegisteredFactory(GetCommand()); -OperationPrintDescriptor::OperationPrintDescriptor(std::queue & oArgList) : Operation(oArgList) +OperationPrintDescriptor::OperationPrintDescriptor(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // flag this as being an ace-level action AppliesToSd = true; @@ -19,7 +18,7 @@ OperationPrintDescriptor::OperationPrintDescriptor(std::queue & oA bool OperationPrintDescriptor::ProcessSdAction(std::wstring & sFileName, ObjectEntry & tObjectEntry, PSECURITY_DESCRIPTOR & tDescriptor, bool & bDescReplacement) { // convert the current security descriptor to a string - WCHAR * sInfo = NULL; + WCHAR * sInfo = nullptr; if (ConvertSecurityDescriptorToStringSecurityDescriptor(tDescriptor, SDDL_REVISION_1, DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION, &sInfo, NULL) == 0) diff --git a/OperationPrintDescriptor.h b/OperationPrintDescriptor.h index 0eb2513..a089a06 100644 --- a/OperationPrintDescriptor.h +++ b/OperationPrintDescriptor.h @@ -8,7 +8,7 @@ class OperationPrintDescriptor : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"PrintDescriptor"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; public: @@ -16,6 +16,6 @@ class OperationPrintDescriptor : public Operation bool ProcessSdAction(std::wstring & sFileName, ObjectEntry & tObjectEntry, PSECURITY_DESCRIPTOR & tDescriptor, bool & bDescReplacement) override; // constructors - OperationPrintDescriptor(std::queue & oArgList); + OperationPrintDescriptor(std::queue & oArgList, std::wstring sCommand); }; diff --git a/OperationQuiet.cpp b/OperationQuiet.cpp index 11bc543..a3e79d9 100644 --- a/OperationQuiet.cpp +++ b/OperationQuiet.cpp @@ -1,10 +1,9 @@ #include "OperationQuiet.h" #include "InputOutput.h" -ClassFactory * OperationQuiet::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationQuiet::RegisteredFactory(GetCommand()); -OperationQuiet::OperationQuiet(std::queue & oArgList) : Operation(oArgList) +OperationQuiet::OperationQuiet(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { InputOutput::InQuietMode() = true; } \ No newline at end of file diff --git a/OperationQuiet.h b/OperationQuiet.h index cd135d5..4597e0b 100644 --- a/OperationQuiet.h +++ b/OperationQuiet.h @@ -8,10 +8,10 @@ class OperationQuiet : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"Quiet"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; public: // constructors - OperationQuiet(std::queue & oArgList); + OperationQuiet(std::queue & oArgList, std::wstring sCommand); }; \ No newline at end of file diff --git a/OperationRemoveAccount.cpp b/OperationRemoveAccount.cpp index cba4e8e..33b88e2 100644 --- a/OperationRemoveAccount.cpp +++ b/OperationRemoveAccount.cpp @@ -2,22 +2,21 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationRemoveAccount::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationRemoveAccount::RegisteredFactory(GetCommand()); -OperationRemoveAccount::OperationRemoveAccount(std::queue & oArgList) : Operation(oArgList) +OperationRemoveAccount::OperationRemoveAccount(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList); // fetch params - tRemoveSid = GetSidFromName(sSubArgs[0]); + tRemoveSid = GetSidFromName(sSubArgs.at(0)); // see if names could be resolved if (tRemoveSid == nullptr) { // complain - wprintf(L"ERROR: Invalid account '%s' specified for parameter '%s'.\n", sSubArgs[0].c_str(), GetCommand().c_str()); + wprintf(L"ERROR: Invalid account '%s' specified for parameter '%s'.\n", sSubArgs.at(0).c_str(), GetCommand().c_str()); exit(-1); } @@ -31,7 +30,7 @@ OperationRemoveAccount::OperationRemoveAccount(std::queue & oArgLi AppliesToOwner = true; // target certain parts of the security descriptor - if (sSubArgs.size() > 1) ProcessGranularTargetting(sSubArgs[1]); + if (sSubArgs.size() > 1) ProcessGranularTargetting(sSubArgs.at(1)); } SidActionResult OperationRemoveAccount::DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) @@ -44,6 +43,6 @@ SidActionResult OperationRemoveAccount::DetermineSid(WCHAR * const sSdPart, Obje // update the sid in the ace InputOutput::AddInfo(L"Removing account '" + sRemoveSid + L"'", sSdPart); - tResultantSid = NULL; + tResultantSid = nullptr; return SidActionResult::Remove; } diff --git a/OperationRemoveAccount.h b/OperationRemoveAccount.h index b06739b..ed29160 100644 --- a/OperationRemoveAccount.h +++ b/OperationRemoveAccount.h @@ -8,7 +8,7 @@ class OperationRemoveAccount : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"RemoveAccount"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; // operation specific PSID tRemoveSid = nullptr; @@ -20,5 +20,5 @@ class OperationRemoveAccount : public Operation SidActionResult DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; // constructors - OperationRemoveAccount(std::queue & oArgList); + OperationRemoveAccount(std::queue & oArgList, std::wstring sCommand); }; \ No newline at end of file diff --git a/OperationRemoveOrphan.cpp b/OperationRemoveOrphan.cpp index def5da5..dca5675 100644 --- a/OperationRemoveOrphan.cpp +++ b/OperationRemoveOrphan.cpp @@ -2,22 +2,21 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationRemoveOrphan::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationRemoveOrphan::RegisteredFactory(GetCommand()); -OperationRemoveOrphan::OperationRemoveOrphan(std::queue & oArgList) : Operation(oArgList) +OperationRemoveOrphan::OperationRemoveOrphan(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList); // decode the passed parameter to an account name - tDomainSid = GetSidFromName(sSubArgs[0]); + tDomainSid = GetSidFromName(sSubArgs.at(0)); // see if names could be resolved if (tDomainSid == nullptr) { // complain - wprintf(L"ERROR: Invalid domain '%s' specified for parameter '%s'.\n", sSubArgs[0].c_str(), GetCommand().c_str()); + wprintf(L"ERROR: Invalid domain '%s' specified for parameter '%s'.\n", sSubArgs.at(0).c_str(), GetCommand().c_str()); exit(0); } @@ -31,13 +30,13 @@ OperationRemoveOrphan::OperationRemoveOrphan(std::queue & oArgList AppliesToOwner = true; // target certain parts of the security descriptor - if (sSubArgs.size() > 1) ProcessGranularTargetting(sSubArgs[1]); + if (sSubArgs.size() > 1) ProcessGranularTargetting(sSubArgs.at(1)); } SidActionResult OperationRemoveOrphan::DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) { // only bother doing a domain check if a domain was specified - if (tDomainSid != NULL) + if (tDomainSid != nullptr) { // see if this sid in the source domain BOOL bDomainSidsEqual = FALSE; @@ -56,6 +55,6 @@ SidActionResult OperationRemoveOrphan::DetermineSid(WCHAR * const sSdPart, Objec // update the sid in the ace InputOutput::AddInfo(L"Removing orphan of security identifier '" + sSid + L"' from domain '" + sDomainName + L"'", sSdPart); - tResultantSid = NULL; + tResultantSid = nullptr; return SidActionResult::Remove; } diff --git a/OperationRemoveOrphan.h b/OperationRemoveOrphan.h index e3a7c44..8de727c 100644 --- a/OperationRemoveOrphan.h +++ b/OperationRemoveOrphan.h @@ -8,7 +8,7 @@ class OperationRemoveOrphan : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"RemoveOrphans"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; // operation specific PSID tDomainSid = nullptr; @@ -20,5 +20,5 @@ class OperationRemoveOrphan : public Operation SidActionResult DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; // constructors - OperationRemoveOrphan(std::queue & oArgList); + OperationRemoveOrphan(std::queue & oArgList, std::wstring sCommand); }; \ No newline at end of file diff --git a/OperationRemoveRedundant.cpp b/OperationRemoveRedundant.cpp index d311ca1..7cb0bb9 100644 --- a/OperationRemoveRedundant.cpp +++ b/OperationRemoveRedundant.cpp @@ -3,10 +3,9 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationRemoveRedundant::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationRemoveRedundant::RegisteredFactory(GetCommand()); -OperationRemoveRedundant::OperationRemoveRedundant(std::queue & oArgList) : Operation(oArgList) +OperationRemoveRedundant::OperationRemoveRedundant(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // flag this as being an ace-level action AppliesToDacl = true; @@ -16,7 +15,7 @@ OperationRemoveRedundant::OperationRemoveRedundant(std::queue & oA bool OperationRemoveRedundant::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) { // sanity check - if (tCurrentAcl == NULL) return false; + if (tCurrentAcl == nullptr) return false; // track whether the acl was actually change so the caller may decide // that the change needs to be persisted diff --git a/OperationRemoveRedundant.h b/OperationRemoveRedundant.h index 845ee0b..10adbd0 100644 --- a/OperationRemoveRedundant.h +++ b/OperationRemoveRedundant.h @@ -8,7 +8,7 @@ class OperationRemoveRedundant : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"RemoveRedundant"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; public: @@ -16,6 +16,6 @@ class OperationRemoveRedundant : public Operation bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; // constructors - OperationRemoveRedundant(std::queue & oArgList); + OperationRemoveRedundant(std::queue & oArgList, std::wstring sCommand); }; diff --git a/OperationReplaceAccount.cpp b/OperationReplaceAccount.cpp index 4adc66b..01e588d 100644 --- a/OperationReplaceAccount.cpp +++ b/OperationReplaceAccount.cpp @@ -2,23 +2,22 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationReplaceAccount::RegisteredFactory = - new ClassFactory(GetCommand()); +ClassFactory OperationReplaceAccount::RegisteredFactory(GetCommand()); -OperationReplaceAccount::OperationReplaceAccount(std::queue & oArgList) : Operation(oArgList) +OperationReplaceAccount::OperationReplaceAccount(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(2, oArgList); // fetch params - tSearchAccount = GetSidFromName(sSubArgs[0]); - tReplaceAccount = GetSidFromName(sSubArgs[1]); + tSearchAccount = GetSidFromName(sSubArgs.at(0)); + tReplaceAccount = GetSidFromName(sSubArgs.at(1)); // see if names could be resolved if (tSearchAccount == nullptr) { // complain - wprintf(L"ERROR: Invalid search account '%s' specified for parameter '%s'.\n", sSubArgs[0].c_str(), GetCommand().c_str()); + wprintf(L"ERROR: Invalid search account '%s' specified for parameter '%s'.\n", sSubArgs.at(0).c_str(), GetCommand().c_str()); exit(0); } @@ -26,7 +25,7 @@ OperationReplaceAccount::OperationReplaceAccount(std::queue & oArg if (tReplaceAccount == nullptr) { // complain - wprintf(L"ERROR: Invalid replace account '%s' specified for parameter '%s'.\n", sSubArgs[1].c_str(), GetCommand().c_str()); + wprintf(L"ERROR: Invalid replace account '%s' specified for parameter '%s'.\n", sSubArgs.at(1).c_str(), GetCommand().c_str()); exit(0); } @@ -41,7 +40,7 @@ OperationReplaceAccount::OperationReplaceAccount(std::queue & oArg AppliesToOwner = true; // target certain parts of the security descriptor - if (sSubArgs.size() > 2) ProcessGranularTargetting(sSubArgs[2]); + if (sSubArgs.size() > 2) ProcessGranularTargetting(sSubArgs.at(2)); } SidActionResult OperationReplaceAccount::DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) diff --git a/OperationReplaceAccount.h b/OperationReplaceAccount.h index dc2cd28..d3e8a53 100644 --- a/OperationReplaceAccount.h +++ b/OperationReplaceAccount.h @@ -8,7 +8,7 @@ class OperationReplaceAccount : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"ReplaceAccount"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; // operation specific PSID tSearchAccount = nullptr; @@ -22,5 +22,5 @@ class OperationReplaceAccount : public Operation SidActionResult DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; // constructors - OperationReplaceAccount(std::queue & oArgList); + OperationReplaceAccount(std::queue & oArgList, std::wstring sCommand); }; \ No newline at end of file diff --git a/OperationReplaceMap.cpp b/OperationReplaceMap.cpp index 3d45388..a12bff3 100644 --- a/OperationReplaceMap.cpp +++ b/OperationReplaceMap.cpp @@ -7,16 +7,15 @@ #include #include -ClassFactory * OperationReplaceMap::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationReplaceMap::RegisteredFactory(GetCommand()); -OperationReplaceMap::OperationReplaceMap(std::queue & oArgList) : Operation(oArgList) +OperationReplaceMap::OperationReplaceMap(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList, L"\\0"); // open the file - std::wifstream fFile(sSubArgs[0].c_str()); + std::wifstream fFile(sSubArgs.at(0).c_str()); // adapt the stream to read windows unicode files (void) fFile.imbue(std::locale(fFile.getloc(), new std::codecvt_utf8 * RegisteredFactory; + static ClassFactory RegisteredFactory; // operation specific std::map oReplaceMap; @@ -19,5 +19,5 @@ class OperationReplaceMap : public Operation SidActionResult DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; // constructors - OperationReplaceMap(std::queue & oArgList); + OperationReplaceMap(std::queue & oArgList, std::wstring sCommand); }; \ No newline at end of file diff --git a/OperationReport.cpp b/OperationReport.cpp index dd81e8d..f84701a 100644 --- a/OperationReport.cpp +++ b/OperationReport.cpp @@ -2,26 +2,25 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationReport::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationReport::RegisteredFactory(GetCommand()); #define Q(x) L"\"" + (x) + L"\"" -OperationReport::OperationReport(std::queue & oArgList) : Operation(oArgList) +OperationReport::OperationReport(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sReportFile = ProcessAndCheckArgs(1, oArgList, L"\\0"); std::vector sMatchAndArgs = ProcessAndCheckArgs(1, oArgList, L":"); // fetch params - HANDLE hFile = CreateFile(sReportFile[0].c_str(), GENERIC_WRITE, - FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + HANDLE hFile = CreateFile(sReportFile.at(0).c_str(), GENERIC_WRITE, + FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); // see if names could be resolved if (hFile == INVALID_HANDLE_VALUE) { // complain - wprintf(L"ERROR: Could not create file '%s' specified for parameter '%s'.\n", sReportFile[0].c_str(), GetCommand().c_str()); + wprintf(L"ERROR: Could not create file '%s' specified for parameter '%s'.\n", sReportFile.at(0).c_str(), GetCommand().c_str()); exit(-1); } @@ -32,9 +31,9 @@ OperationReport::OperationReport(std::queue & oArgList) : Operatio if (hFile == hReportFile) { // write out the file type marker - BYTE hHeader[] = { 0xEF,0xBB,0xBF }; + const BYTE hHeader[] = { 0xEF,0xBB,0xBF }; DWORD iBytes = 0; - if (WriteFile(hFile, &hHeader, _countof(hHeader), &iBytes, NULL) == 0) + if (WriteFile(hFile, &hHeader, _countof(hHeader), &iBytes, nullptr) == 0) { wprintf(L"ERROR: Could not write out file type marker '%s'.\n", GetCommand().c_str()); exit(-1); @@ -53,11 +52,11 @@ OperationReport::OperationReport(std::queue & oArgList) : Operatio // compile the regular expression try { - tRegex = std::wregex(sMatchAndArgs[0], std::wregex::icase | std::wregex::optimize); + tRegex = std::wregex(sMatchAndArgs.at(0), std::wregex::icase | std::wregex::optimize); } catch (const std::regex_error &) { - wprintf(L"ERROR: Invalid regular expression '%s' specified for parameter '%s'.\n", sMatchAndArgs[0].c_str(), GetCommand().c_str()); + wprintf(L"ERROR: Invalid regular expression '%s' specified for parameter '%s'.\n", sMatchAndArgs.at(0).c_str(), GetCommand().c_str()); exit(-1); } @@ -74,7 +73,7 @@ OperationReport::OperationReport(std::queue & oArgList) : Operatio SidActionResult OperationReport::DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) { // do not report null sids - if (tCurrentSid == NULL) return SidActionResult::Nothing; + if (tCurrentSid == nullptr) return SidActionResult::Nothing; // fetch the account from the sid std::wstring sAccount = GetNameFromSidEx(tCurrentSid); @@ -95,7 +94,7 @@ SidActionResult OperationReport::DetermineSid(WCHAR * const sSdPart, ObjectEntry bool OperationReport::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) { // do not report null acls - if (tCurrentAcl == NULL) return false; + if (tCurrentAcl == nullptr) return false; ACCESS_ACE * tAce = FirstAce(tCurrentAcl); for (ULONG iEntry = 0; iEntry < tCurrentAcl->AceCount; tAce = NextAce(tAce), iEntry++) diff --git a/OperationReport.h b/OperationReport.h index 45eef89..3c65897 100644 --- a/OperationReport.h +++ b/OperationReport.h @@ -10,7 +10,7 @@ class OperationReport : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"Report"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; // operation specific HANDLE hReportFile = INVALID_HANDLE_VALUE; @@ -23,5 +23,5 @@ class OperationReport : public Operation bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; // constructors - OperationReport(std::queue & oArgList); + OperationReport(std::queue & oArgList, std::wstring sCommand); }; \ No newline at end of file diff --git a/OperationResetChildren.cpp b/OperationResetChildren.cpp index 3e1c3d5..32579ff 100644 --- a/OperationResetChildren.cpp +++ b/OperationResetChildren.cpp @@ -2,10 +2,9 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationResetChildren::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationResetChildren::RegisteredFactory(GetCommand()); -OperationResetChildren::OperationResetChildren(std::queue & oArgList) : Operation(oArgList) +OperationResetChildren::OperationResetChildren(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // setup null ace for allowing inheritance InitializeAcl(&tAclNull, sizeof(tAclNull), ACL_REVISION); diff --git a/OperationResetChildren.h b/OperationResetChildren.h index 246791e..c3d22e5 100644 --- a/OperationResetChildren.h +++ b/OperationResetChildren.h @@ -8,7 +8,7 @@ class OperationResetChildren : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"ResetChildren"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; // used for clearing out explicit aces ACL tAclNull = { 0, 0, 0, 0, 0 }; @@ -19,6 +19,6 @@ class OperationResetChildren : public Operation bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; // constructors - OperationResetChildren(std::queue & oArgList); + OperationResetChildren(std::queue & oArgList, std::wstring sCommand); }; diff --git a/OperationRestoreSecurity.cpp b/OperationRestoreSecurity.cpp index 2367e76..4b51cba 100644 --- a/OperationRestoreSecurity.cpp +++ b/OperationRestoreSecurity.cpp @@ -7,16 +7,15 @@ #include #include -ClassFactory * OperationRestoreSecurity::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationRestoreSecurity::RegisteredFactory(GetCommand()); -OperationRestoreSecurity::OperationRestoreSecurity(std::queue & oArgList) : Operation(oArgList) +OperationRestoreSecurity::OperationRestoreSecurity(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList, L"\\0"); // open the file - std::wifstream fFile(sSubArgs[0].c_str()); + std::wifstream fFile(sSubArgs.at(0).c_str()); // adapt the stream to read windows unicode files (void) fFile.imbue(std::locale(fFile.getloc(), new std::codecvt_utf8 * RegisteredFactory; + static ClassFactory RegisteredFactory; std::map oImportMap; std::wstring sFile = L""; @@ -19,6 +19,6 @@ class OperationRestoreSecurity : public Operation bool ProcessSdAction(std::wstring & sFileName, ObjectEntry & tObjectEntry, PSECURITY_DESCRIPTOR & tDescriptor, bool & bDescReplacement) override; // constructors - OperationRestoreSecurity(std::queue & oArgList); + OperationRestoreSecurity(std::queue & oArgList, std::wstring sCommand); }; diff --git a/OperationSetOwner.cpp b/OperationSetOwner.cpp index 9629642..e01a550 100644 --- a/OperationSetOwner.cpp +++ b/OperationSetOwner.cpp @@ -2,22 +2,21 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationSetOwner::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationSetOwner::RegisteredFactory(GetCommand()); -OperationSetOwner::OperationSetOwner(std::queue & oArgList) : Operation(oArgList) +OperationSetOwner::OperationSetOwner(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList); // fetch params - tOwnerSid = GetSidFromName(sSubArgs[0]); + tOwnerSid = GetSidFromName(sSubArgs.at(0)); // see if names could be resolved if (tOwnerSid == nullptr) { // complain - wprintf(L"ERROR: Invalid account '%s' specified for parameter '%s'.\n", sSubArgs[0].c_str(), GetCommand().c_str()); + wprintf(L"ERROR: Invalid account '%s' specified for parameter '%s'.\n", sSubArgs.at(0).c_str(), GetCommand().c_str()); exit(-1); } @@ -28,7 +27,7 @@ OperationSetOwner::OperationSetOwner(std::queue & oArgList) : Oper AppliesToOwner = true; // target certain parts of the security descriptor - if (sSubArgs.size() > 1) ProcessGranularTargetting(sSubArgs[1]); + if (sSubArgs.size() > 1) ProcessGranularTargetting(sSubArgs.at(1)); } SidActionResult OperationSetOwner::DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) diff --git a/OperationSetOwner.h b/OperationSetOwner.h index bccdd49..9d4e31f 100644 --- a/OperationSetOwner.h +++ b/OperationSetOwner.h @@ -8,7 +8,7 @@ class OperationSetOwner : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"SetOwner"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; // operation specific PSID tOwnerSid = nullptr; @@ -20,5 +20,5 @@ class OperationSetOwner : public Operation SidActionResult DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; // constructors - OperationSetOwner(std::queue & oArgList); + OperationSetOwner(std::queue & oArgList, std::wstring sCommand); }; diff --git a/OperationSharePaths.cpp b/OperationSharePaths.cpp index 4898df4..56f6825 100644 --- a/OperationSharePaths.cpp +++ b/OperationSharePaths.cpp @@ -9,10 +9,9 @@ #include "OperationSharePaths.h" #include "InputOutput.h" -ClassFactory * OperationSharePaths::RegisteredFactory = - new ClassFactory(GetCommand()); +ClassFactory OperationSharePaths::RegisteredFactory(GetCommand()); -OperationSharePaths::OperationSharePaths(std::queue & oArgList) : Operation(oArgList) +OperationSharePaths::OperationSharePaths(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList); @@ -26,14 +25,14 @@ OperationSharePaths::OperationSharePaths(std::queue & oArgList) : if (sSubArgs.size() == 2) { // further split the second arg into a command delimited list - std::vector oShareArgs = SplitArgs(sSubArgs[1], L","); + std::vector oShareArgs = SplitArgs(sSubArgs.at(1), L","); // enumerate list for (auto& oShareArg : oShareArgs) { // check to see if a match parameter was passed - WCHAR sMatchArg[] = L"MATCH="; - WCHAR sNoMatchArg[] = L"NOMATCH="; + const WCHAR sMatchArg[] = L"MATCH="; + const WCHAR sNoMatchArg[] = L"NOMATCH="; if (_wcsnicmp(oShareArg.c_str(), sMatchArg, _countof(sMatchArg) - 1) == 0 || _wcsnicmp(oShareArg.c_str(), sNoMatchArg, _countof(sNoMatchArg) - 1) == 0) { @@ -43,7 +42,7 @@ OperationSharePaths::OperationSharePaths(std::queue & oArgList) : // verify a regular expression was actually specified if (oMatchArgs.size() != 2) { - wprintf(L"ERROR: No regular expression specified for parameter '%s'\n", sSubArgs[0].c_str()); + wprintf(L"ERROR: No regular expression specified for parameter '%s'\n", sSubArgs.at(0).c_str()); exit(-1); } @@ -51,12 +50,12 @@ OperationSharePaths::OperationSharePaths(std::queue & oArgList) : { // parse the regular expression ((_wcsnicmp(oShareArg.c_str(), sMatchArg, _countof(sMatchArg) - 1) == 0) ? oMatchRegex : oNoMatchRegex) = - std::wregex(oMatchArgs[1], std::regex_constants::icase); + std::wregex(oMatchArgs.at(1), std::regex_constants::icase); } catch (std::exception &) { // regular expression could no be parsed - wprintf(L"ERROR: Invalid regular expression '%s'\n", oMatchArgs[1].c_str()); + wprintf(L"ERROR: Invalid regular expression '%s'\n", oMatchArgs.at(1).c_str()); exit(-1); } } @@ -90,13 +89,13 @@ OperationSharePaths::OperationSharePaths(std::queue & oArgList) : DWORD iTotalEntries = 0; // enumerate file share - iReturn = NetShareEnum((LPWSTR)sSubArgs[0].c_str(), 2, (LPBYTE*)&tInfo, + iReturn = NetShareEnum((LPWSTR)sSubArgs.at(0).c_str(), 2, (LPBYTE*)&tInfo, MAX_PREFERRED_LENGTH, &iEntries, &iTotalEntries, &hResumeHandle); // check for unknown error if (iReturn != ERROR_SUCCESS && iReturn != ERROR_MORE_DATA) { - wprintf(L"ERROR: Could not enumerate shares on '%s'\n", sSubArgs[0].c_str()); + wprintf(L"ERROR: Could not enumerate shares on '%s'\n", sSubArgs.at(0).c_str()); if (bStopOnErrors) exit(-1); else return; } @@ -111,16 +110,13 @@ OperationSharePaths::OperationSharePaths(std::queue & oArgList) : !bAdminOnly && CheckBitSet(tInfo[iEntry].shi2_type, STYPE_SPECIAL)) continue; // skip hidden shares unless hidden command was specified - WCHAR * cEnd = (wcsrchr(tInfo[iEntry].shi2_netname, '$')); - if (!bAdminOnly && !bHiddenIncluded && (cEnd != NULL && *(cEnd + 1) == '\0')) continue; + const WCHAR * cEnd = (wcsrchr(tInfo[iEntry].shi2_netname, '$')); + if (!bAdminOnly && !bHiddenIncluded && (cEnd != nullptr && *(cEnd + 1) == '\0')) continue; // add a trailing path if the path does not have one std::wstring sLocalPath = tInfo[iEntry].shi2_path; if (sLocalPath.back() != L'\\') sLocalPath += L'\\'; - - // convert to uppercase - std::transform(sLocalPath.begin(), sLocalPath.end(), sLocalPath.begin(), - [](const WCHAR c) { return static_cast(::toupper(c)); }); + ConvertToUpper(sLocalPath); // see if the share name matches the regular expression if (!std::regex_search(tInfo[iEntry].shi2_netname, oMatchRegex)) continue; @@ -151,7 +147,7 @@ OperationSharePaths::OperationSharePaths(std::queue & oArgList) : oPathOuter->second.find(oPathInner->second) != std::wstring::npos) { wprintf(L"NOTE: Share '%s' is included in '%s' on '%s'; skipping\n", - oPathOuter->first.c_str(), oPathInner->first.c_str(), sSubArgs[0].c_str()); + oPathOuter->first.c_str(), oPathInner->first.c_str(), sSubArgs.at(0).c_str()); bAddToPathList = false; break; } @@ -161,7 +157,7 @@ OperationSharePaths::OperationSharePaths(std::queue & oArgList) : if (bAddToPathList) { InputOutput::ScanPaths().push_back( - L"\\\\" + sSubArgs[0] + L"\\" + oPathOuter->first); + L"\\\\" + sSubArgs.at(0) + L"\\" + oPathOuter->first); } } }; \ No newline at end of file diff --git a/OperationSharePaths.h b/OperationSharePaths.h index 757ede0..83f3cbb 100644 --- a/OperationSharePaths.h +++ b/OperationSharePaths.h @@ -8,10 +8,10 @@ class OperationSharePaths : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"SharePaths"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; public: // constructors - OperationSharePaths(std::queue & oArgList); + OperationSharePaths(std::queue & oArgList, std::wstring sCommand); }; \ No newline at end of file diff --git a/OperationSidHistory.cpp b/OperationSidHistory.cpp index d5a282c..07cd8ff 100644 --- a/OperationSidHistory.cpp +++ b/OperationSidHistory.cpp @@ -2,10 +2,9 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationSidHistory::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationSidHistory::RegisteredFactory(GetCommand()); -OperationSidHistory::OperationSidHistory(std::queue & oArgList) : Operation(oArgList) +OperationSidHistory::OperationSidHistory(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // flag this as being an ace-level action AppliesToDacl = true; @@ -18,7 +17,7 @@ SidActionResult OperationSidHistory::DetermineSid(WCHAR * const sSdPart, ObjectE { // lookup the textual name for this account and // return if it is not found - std::wstring sAccountName = GetNameFromSid(tCurrentSid, NULL); + std::wstring sAccountName = GetNameFromSid(tCurrentSid, nullptr); if (sAccountName.empty()) return SidActionResult::Nothing; // now do a forward lookup on that same account name to see what the diff --git a/OperationSidHistory.h b/OperationSidHistory.h index c327d8b..252dbcf 100644 --- a/OperationSidHistory.h +++ b/OperationSidHistory.h @@ -8,7 +8,7 @@ class OperationSidHistory : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"UpdateHistoricalSids"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; public: @@ -16,5 +16,5 @@ class OperationSidHistory : public Operation SidActionResult DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; // constructors - OperationSidHistory(std::queue & oArgList); + OperationSidHistory(std::queue & oArgList, std::wstring sCommand); }; diff --git a/OperationThreads.cpp b/OperationThreads.cpp index afbb047..67a80e7 100644 --- a/OperationThreads.cpp +++ b/OperationThreads.cpp @@ -2,16 +2,15 @@ #include "InputOutput.h" #include "Functions.h" -ClassFactory * OperationThreads::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationThreads::RegisteredFactory(GetCommand()); -OperationThreads::OperationThreads(std::queue & oArgList) : Operation(oArgList) +OperationThreads::OperationThreads(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList); // store off the argument - InputOutput::MaxThreads() = (short)_wtoi(sSubArgs[0].c_str()); + InputOutput::MaxThreads() = (short)_wtoi(sSubArgs.at(0).c_str()); if (InputOutput::MaxThreads() == 0 || InputOutput::MaxThreads() > 100) { // complain diff --git a/OperationThreads.h b/OperationThreads.h index eddd429..67715bd 100644 --- a/OperationThreads.h +++ b/OperationThreads.h @@ -8,10 +8,10 @@ class OperationThreads : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"Threads"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; public: // constructors - OperationThreads(std::queue & oArgList); + OperationThreads(std::queue & oArgList, std::wstring sCommand); }; \ No newline at end of file diff --git a/OperationWhatIf.cpp b/OperationWhatIf.cpp index db8da13..d4dc6b4 100644 --- a/OperationWhatIf.cpp +++ b/OperationWhatIf.cpp @@ -1,10 +1,9 @@ #include "OperationWhatIf.h" #include "InputOutput.h" -ClassFactory * OperationWhatIf::RegisteredFactory = -new ClassFactory(GetCommand()); +ClassFactory OperationWhatIf::RegisteredFactory(GetCommand()); -OperationWhatIf::OperationWhatIf(std::queue & oArgList) : Operation(oArgList) +OperationWhatIf::OperationWhatIf(std::queue & oArgList, std::wstring sCommand) : Operation(oArgList) { InputOutput::InWhatIfMode() = true; } \ No newline at end of file diff --git a/OperationWhatIf.h b/OperationWhatIf.h index 8c0fb27..181ea0b 100644 --- a/OperationWhatIf.h +++ b/OperationWhatIf.h @@ -8,10 +8,10 @@ class OperationWhatIf : public Operation // statics used by command registration utility static std::wstring GetCommand() { return L"WhatIf"; } - static ClassFactory * RegisteredFactory; + static ClassFactory RegisteredFactory; public: // constructors - OperationWhatIf(std::queue & oArgList); + OperationWhatIf(std::queue & oArgList, std::wstring sCommand); }; \ No newline at end of file diff --git a/Resource.rc b/Resource.rc index 541e116..14b7211 100644 Binary files a/Resource.rc and b/Resource.rc differ diff --git a/repacls.vcxproj b/repacls.vcxproj index e09ad7e..a38a005 100644 --- a/repacls.vcxproj +++ b/repacls.vcxproj @@ -22,34 +22,34 @@ {0E11E31A-BE5D-4B31-AA8E-DA9AEEC84F37} Win32Proj PermChange - 10.0.17134.0 + 10.0 repacls Application true - v141 + v142 Unicode Application false - v141 + v142 true Unicode Application true - v141 + v142 Unicode false Application false - v141 + v142 true Unicode @@ -98,7 +98,7 @@ - Level3 + Level4 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) MultiThreadedDebug @@ -106,14 +106,14 @@ Console true - true + false - Level3 + Level4 Disabled _DEBUG;_CONSOLE;%(PreprocessorDefinitions) MultiThreadedDebug @@ -123,7 +123,7 @@ Console true RequireAdministrator - true + false @@ -193,6 +193,7 @@ + @@ -231,6 +232,7 @@ + diff --git a/repacls.vcxproj.filters b/repacls.vcxproj.filters index e0d8dd2..1f8a1a8 100644 --- a/repacls.vcxproj.filters +++ b/repacls.vcxproj.filters @@ -112,6 +112,9 @@ Source\Operations + + Source\Operations + @@ -240,6 +243,9 @@ Includes\Operations + + Includes\Operations +