diff --git a/Build/Release/x64/repacls.exe b/Build/Release/x64/repacls.exe index 886d14b..f895482 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 5ddcf04..ff76e0d 100644 Binary files a/Build/Release/x86/repacls.exe and b/Build/Release/x86/repacls.exe differ diff --git a/Functions.h b/Functions.h index 19fccfe..e9f4a2d 100644 --- a/Functions.h +++ b/Functions.h @@ -5,7 +5,7 @@ #include // helper functions -VOID EnablePrivs(); +VOID EnablePrivs() noexcept; PSID GetSidFromName(const std::wstring & sAccountName); std::wstring GetNameFromSid(const PSID tSid, bool * bMarkAsOrphan = nullptr); std::wstring GetNameFromSidEx(const PSID tSid, bool * bMarkAsOrphan = nullptr); diff --git a/Helpers.cpp b/Helpers.cpp index a2c3d26..bcc7c35 100644 --- a/Helpers.cpp +++ b/Helpers.cpp @@ -243,7 +243,7 @@ std::wstring GenerateAccessMask(DWORD iCurrentMask) return sMaskList; } -VOID EnablePrivs() +VOID EnablePrivs() noexcept { // open the current token HANDLE hToken = NULL; @@ -265,7 +265,7 @@ VOID EnablePrivs() return; } - WCHAR * sPrivsToSet[] = { SE_RESTORE_NAME, SE_BACKUP_NAME, + const WCHAR * sPrivsToSet[] = { SE_RESTORE_NAME, SE_BACKUP_NAME, SE_TAKE_OWNERSHIP_NAME, SE_CHANGE_NOTIFY_NAME }; for (auto& i : sPrivsToSet) { @@ -307,7 +307,7 @@ VOID EnablePrivs() // convert the privilege name to a unicode string format LSA_UNICODE_STRING sPrivilege; - sPrivilege.Buffer = i; + sPrivilege.Buffer = (PWSTR) i; sPrivilege.Length = (USHORT)(wcslen(i) * sizeof(WCHAR)); sPrivilege.MaximumLength = (USHORT)((wcslen(i) + 1) * sizeof(WCHAR)); diff --git a/Operation.cpp b/Operation.cpp index 0d36900..ecfd477 100644 --- a/Operation.cpp +++ b/Operation.cpp @@ -4,7 +4,7 @@ #include -bool Operation::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) +bool Operation::ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) { // return immediately if acl is null if (tCurrentAcl == nullptr) return false; @@ -111,7 +111,7 @@ std::vector Operation::SplitArgs(std::wstring sInput, const std::w return { oFirst, oLast }; } -bool Operation::ProcessSidAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID & tCurrentSid, bool & bSidReplacement) +bool Operation::ProcessSidAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID & tCurrentSid, bool & bSidReplacement) { PSID tResultantSid; const SidActionResult tResult = DetermineSid(sSdPart, tObjectEntry, tCurrentSid, tResultantSid); diff --git a/Operation.h b/Operation.h index 970a483..75860a9 100644 --- a/Operation.h +++ b/Operation.h @@ -1,5 +1,8 @@ #pragma once +// mute compatibility concerns +#define _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS + #include #include #include @@ -60,8 +63,7 @@ typedef enum SidActionResult : char { Nothing = 0, Replace = 1 << 0, - Remove = 1 << 1, - Add = 1 << 2 + Remove = 1 << 1 } SidActionResult; @@ -90,9 +92,9 @@ class Operation 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); - virtual bool ProcessSidAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID & tCurrentSid, bool & bSidReplacement); - virtual SidActionResult DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) { return SidActionResult::Nothing; } + virtual bool ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement); + virtual bool ProcessSidAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID & tCurrentSid, bool & bSidReplacement); + virtual SidActionResult DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) { return SidActionResult::Nothing; } virtual void ProcessObjectAction(ObjectEntry & tObjectEntry) { return; } Operation(std::queue & oArgList); diff --git a/OperationAddAccountIfMissing.cpp b/OperationAddAccountIfMissing.cpp index 922546a..472561c 100644 --- a/OperationAddAccountIfMissing.cpp +++ b/OperationAddAccountIfMissing.cpp @@ -19,7 +19,7 @@ OperationAddAccountIfMissing::OperationAddAccountIfMissing(std::queueProcessAclAction(sSdPart, tObjectEntry, tCurrentAcl, bAclReplacement); } diff --git a/OperationAddAccountIfMissing.h b/OperationAddAccountIfMissing.h index f603ee9..d97d961 100644 --- a/OperationAddAccountIfMissing.h +++ b/OperationAddAccountIfMissing.h @@ -17,7 +17,7 @@ class OperationAddAccountIfMissing : public Operation public: // overrides - bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; + bool ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; // constructors OperationAddAccountIfMissing(std::queue & oArgList, const std::wstring & sCommand); diff --git a/OperationCanonicalizeAcls.cpp b/OperationCanonicalizeAcls.cpp index 2444900..4d7bd9f 100644 --- a/OperationCanonicalizeAcls.cpp +++ b/OperationCanonicalizeAcls.cpp @@ -11,7 +11,7 @@ OperationCanonicalizeAcls::OperationCanonicalizeAcls(std::queue & AppliesToDacl = true; } -bool OperationCanonicalizeAcls::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) +bool OperationCanonicalizeAcls::ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) { // sanity check (null acl is considered valid) if (tCurrentAcl == nullptr) return false; diff --git a/OperationCanonicalizeAcls.h b/OperationCanonicalizeAcls.h index 6e423f7..c96db34 100644 --- a/OperationCanonicalizeAcls.h +++ b/OperationCanonicalizeAcls.h @@ -13,7 +13,7 @@ class OperationCanonicalizeAcls : public Operation public: // overrides - bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; + bool ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; // constructors OperationCanonicalizeAcls(std::queue & oArgList, const std::wstring & sCommand); diff --git a/OperationCheckCanonical.cpp b/OperationCheckCanonical.cpp index afe5d40..57ffd1a 100644 --- a/OperationCheckCanonical.cpp +++ b/OperationCheckCanonical.cpp @@ -11,7 +11,7 @@ OperationCheckCanonical::OperationCheckCanonical(std::queue & oArg AppliesToDacl = true; } -bool OperationCheckCanonical::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) +bool OperationCheckCanonical::ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) { // sanity check (null acl is considered valid) if (tCurrentAcl == nullptr) return false; diff --git a/OperationCheckCanonical.h b/OperationCheckCanonical.h index 2479f0f..ae4731c 100644 --- a/OperationCheckCanonical.h +++ b/OperationCheckCanonical.h @@ -28,7 +28,7 @@ class OperationCheckCanonical : public Operation static bool IsAclCanonical(PACL & tCurrentAcl); // overrides - bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; + bool ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; // constructors OperationCheckCanonical(std::queue & oArgList, const std::wstring & sCommand); diff --git a/OperationCompact.cpp b/OperationCompact.cpp index fbe831a..65d5a15 100644 --- a/OperationCompact.cpp +++ b/OperationCompact.cpp @@ -14,7 +14,7 @@ OperationCompact::OperationCompact(std::queue & oArgList, const st AppliesToSacl = true; } -bool OperationCompact::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) +bool OperationCompact::ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) { // sanity check if (tCurrentAcl == nullptr) return false; diff --git a/OperationCompact.h b/OperationCompact.h index 28b6c13..bd2f185 100644 --- a/OperationCompact.h +++ b/OperationCompact.h @@ -13,7 +13,7 @@ class OperationCompact : public Operation public: // overrides - bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; + bool ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; // constructors OperationCompact(std::queue & oArgList, const std::wstring & sCommand); diff --git a/OperationCopyDomain.cpp b/OperationCopyDomain.cpp index 77c3750..6a99d70 100644 --- a/OperationCopyDomain.cpp +++ b/OperationCopyDomain.cpp @@ -42,7 +42,7 @@ OperationCopyDomain::OperationCopyDomain(std::queue & oArgList, co if (sSubArgs.size() > 2) ProcessGranularTargetting(sSubArgs.at(2)); } -bool OperationCopyDomain::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) +bool OperationCopyDomain::ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) { // check on canonicalization status so if can error if the acl needs to be updated const bool bAclIsCanonical = OperationCheckCanonical::IsAclCanonical(tCurrentAcl); diff --git a/OperationCopyDomain.h b/OperationCopyDomain.h index a511ce0..eca79f4 100644 --- a/OperationCopyDomain.h +++ b/OperationCopyDomain.h @@ -19,7 +19,7 @@ class OperationCopyDomain : public Operation public: // overrides - bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; + bool ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; // constructors OperationCopyDomain(std::queue & oArgList, const std::wstring & sCommand); diff --git a/OperationCopyMap.cpp b/OperationCopyMap.cpp new file mode 100644 index 0000000..a01629d --- /dev/null +++ b/OperationCopyMap.cpp @@ -0,0 +1,203 @@ +#include "OperationCopyMap.h" +#include "OperationCheckCanonical.h" +#include "InputOutput.h" +#include "Functions.h" + +#include +#include +#include +#include + +ClassFactory OperationCopyMap::RegisteredFactory(GetCommand()); + +OperationCopyMap::OperationCopyMap(std::queue & oArgList, const 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.at(0).c_str()); + + // adapt the stream to read windows unicode files + (void) fFile.imbue(std::locale(fFile.getloc(), new std::codecvt_utf8)); + + // read the file line-by-line + std::wstring sLine; + while (std::getline(fFile, sLine)) + { + // parse the search and replace account which are separated by a ':' character + // also, sometimes a carriage return appears in the input stream so adding + // it here ensures it is stripped from the very end + std::vector oLineItems = SplitArgs(sLine, L":|\r"); + + // verify the line contains at least two elements + if (oLineItems.size() != 2) + { + wprintf(L"ERROR: The replacement map line '%s' is invalid.", sLine.c_str()); + exit(-1); + } + + // verify search sid + const PSID tSearchSid = GetSidFromName(oLineItems.at(0)); + if (tSearchSid == nullptr) + { + wprintf(L"ERROR: The map search value '%s' is invalid.", oLineItems.at(0).c_str()); + exit(-1); + } + + // verify replace sid + const PSID tReplaceSid = GetSidFromName(oLineItems.at(1)); + if (tReplaceSid == nullptr) + { + wprintf(L"ERROR: The map replace value '%s' is invalid.", oLineItems.at(1).c_str()); + exit(-1); + } + + // get the reverse lookup for the search - since the ACE could contain a sid history sid + // we rely on doing a reverse lookup to normalize any accounts to update + std::wstring sSearchAccount = GetNameFromSidEx(tSearchSid); + + // update the map + oCopyMap[sSearchAccount] = tReplaceSid; + } + + // cleanup + fFile.close(); + + // flag this as being an ace-level action + AppliesToDacl = true; + AppliesToSacl = true; +} + +bool OperationCopyMap::ProcessAclAction(const WCHAR* const sSdPart, ObjectEntry& tObjectEntry, PACL& tCurrentAcl, bool& bAclReplacement) +{ + // check on canonicalization status so if can error if the acl needs to be updated + const bool bAclIsCanonical = OperationCheckCanonical::IsAclCanonical(tCurrentAcl); + + // check explicit effective rights from sid (no groups) + bool bAclIsDirty = false; + if (tCurrentAcl != nullptr) + { + ACCESS_ACE* tAceDacl = FirstAce(tCurrentAcl); + for (LONG iEntry = 0; iEntry < tCurrentAcl->AceCount; tAceDacl = + (iEntry == -1) ? FirstAce(tCurrentAcl) : NextAce(tAceDacl), iEntry++) + { + // do not bother with inherited aces + if (IsInherited(tAceDacl)) continue; + + // see if this ace matches a sid in the copy list + std::wstring sSourceAccountName = GetNameFromSidEx(&tAceDacl->Sid); + const auto oInteractor = oCopyMap.find(sSourceAccountName); + if (oInteractor == oCopyMap.end()) continue; + + // translate the old sid to an account name + std::wstring sTargetAccountName = GetNameFromSidEx(oInteractor->second, nullptr); + if (sTargetAccountName.empty()) continue; + + // record the status to report + std::wstring sInfoToReport = L"Copying '" + sSourceAccountName + L"' to '" + sTargetAccountName + L"'"; + + // determine access mode + ACCESS_MODE tMode = ACCESS_MODE::NOT_USED_ACCESS; + if (tAceDacl->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) + { + tMode = GRANT_ACCESS; + } + else if (tAceDacl->Header.AceType == ACCESS_DENIED_ACE_TYPE) + { + tMode = DENY_ACCESS; + } + else if (tAceDacl->Header.AceType == SYSTEM_AUDIT_ACE_TYPE) + { + if (CheckBitSet(tAceDacl->Header.AceFlags, SUCCESSFUL_ACCESS_ACE_FLAG)) + { + tMode = (ACCESS_MODE)(tMode | SET_AUDIT_SUCCESS); + } + if (CheckBitSet(tAceDacl->Header.AceFlags, FAILED_ACCESS_ACE_FLAG)) + { + tMode = (ACCESS_MODE)(tMode | SET_AUDIT_FAILURE); + } + } + else + { + // unknown type; skipping + continue; + } + + // since SetEntriesInAcl reacts poorly / unexpectedly in cases where the + // acl is not canonical, just error out and continue on + if (!bAclIsCanonical) + { + InputOutput::AddError(L"Could not copy account '" + sTargetAccountName + + L"' because access control list is not canonical.", sSdPart); + continue; + } + + // create a structure to add the missing permissions + EXPLICIT_ACCESS tEa; + tEa.grfAccessPermissions = tAceDacl->Mask; + tEa.grfAccessMode = tMode; + tEa.grfInheritance = VALID_INHERIT_FLAGS & tAceDacl->Header.AceFlags; + tEa.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; + tEa.Trustee.pMultipleTrustee = nullptr; + tEa.Trustee.ptstrName = (LPWSTR) oInteractor->second; + 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 = nullptr; + DWORD iError = 0; + if (CheckBitSet(tEa.grfAccessMode, SET_AUDIT_SUCCESS) && + CheckBitSet(tEa.grfAccessMode, SET_AUDIT_FAILURE)) + { + PACL tNewDaclTmp = nullptr; + tEa.grfAccessMode = SET_AUDIT_SUCCESS; + iError = SetEntriesInAcl(1, &tEa, tCurrentAcl, &tNewDaclTmp); + tEa.grfAccessMode = SET_AUDIT_FAILURE; + if (iError == ERROR_SUCCESS) { + SetEntriesInAcl(1, &tEa, tNewDaclTmp, &tNewDacl); + LocalFree(tNewDaclTmp); + } + } + else + { + // merge the new trustee into the dacl + iError = SetEntriesInAcl(1, &tEa, tCurrentAcl, &tNewDacl); + } + + // verify the new acl could be generated + if (iError != ERROR_SUCCESS || tNewDacl == nullptr) + { + //std::wstring sTargetAccountName = GetNameFromSid(tTargetAccountSid); + InputOutput::AddError(L"Could not copy '" + sTargetAccountName + + L"' to access control list (" + std::to_wstring(iError) + L").", sSdPart); + continue; + } + + // see if the old and new acl match + if (tCurrentAcl->AclSize == tNewDacl->AclSize && + memcmp(tCurrentAcl, tNewDacl, tCurrentAcl->AclSize) == 0) + { + // if acls match then no change was made and we do not need + // to mark this as dirty or restart the enumeration + LocalFree(tNewDacl); + } + else + { + // report status + InputOutput::AddInfo(sInfoToReport, sSdPart); + + // cleanup the old dacl (if necessary) and assign our new active dacl + if (bAclReplacement) LocalFree(tCurrentAcl); + tCurrentAcl = tNewDacl; + bAclReplacement = true; + bAclIsDirty = true; + iEntry = -1; + } + } + } + + return bAclIsDirty; +} \ No newline at end of file diff --git a/OperationCopyMap.h b/OperationCopyMap.h new file mode 100644 index 0000000..6954889 --- /dev/null +++ b/OperationCopyMap.h @@ -0,0 +1,23 @@ +#pragma once + +#include "Operation.h" + +class OperationCopyMap : public Operation +{ +private: + + // statics used by command registration utility + static std::wstring GetCommand() { return L"CopyMap"; } + static ClassFactory RegisteredFactory; + + // operation specific + std::map oCopyMap; + +public: + + // overrides + bool ProcessAclAction(const WCHAR* const sSdPart, ObjectEntry& tObjectEntry, PACL& tCurrentAcl, bool& bAclReplacement) override; + + // constructors + OperationCopyMap(std::queue & oArgList, const std::wstring & sCommand); +}; \ No newline at end of file diff --git a/OperationDomainPaths.cpp b/OperationDomainPaths.cpp index 645cec8..0616db5 100644 --- a/OperationDomainPaths.cpp +++ b/OperationDomainPaths.cpp @@ -74,9 +74,9 @@ OperationDomainPaths::OperationDomainPaths(std::queue & oArgList, "(!(userAccountControl:1.2.840.113556.1.4.803:=8192))(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(msDS-isRODC=true)))"; // execute the search. - LPWSTR sAttributes[] = { L"cn" }; + LPCWSTR sAttributes[] = { L"cn" }; ADS_SEARCH_HANDLE hSearch; - if (FAILED(oSearch->ExecuteSearch(sSearchFilter, sAttributes, _countof(sAttributes), &hSearch))) + if (FAILED(oSearch->ExecuteSearch(sSearchFilter, (LPWSTR*) sAttributes, _countof(sAttributes), &hSearch))) { wprintf(L"ERROR: Could not execute search for domain '%s'\n", sSubArgs.at(0).c_str()); exit(-1); @@ -88,7 +88,7 @@ OperationDomainPaths::OperationDomainPaths(std::queue & oArgList, { // get the data from the column ADS_SEARCH_COLUMN oColumn; - if (FAILED(oSearch->GetColumn(hSearch, sAttributes[0], &oColumn)) || + if (FAILED(oSearch->GetColumn(hSearch, (LPWSTR) sAttributes[0], &oColumn)) || oColumn.dwADsType != ADSTYPE_CASE_IGNORE_STRING) { continue; diff --git a/OperationFindAccount.cpp b/OperationFindAccount.cpp index 48bdc88..6f1233b 100644 --- a/OperationFindAccount.cpp +++ b/OperationFindAccount.cpp @@ -33,7 +33,7 @@ OperationFindAccount::OperationFindAccount(std::queue & oArgList, if (sSubArgs.size() > 1) ProcessGranularTargetting(sSubArgs.at(1)); } -SidActionResult OperationFindAccount::DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) +SidActionResult OperationFindAccount::DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) { // check if the sid matches the ace if (SidMatch(tCurrentSid, tFindSid)) diff --git a/OperationFindAccount.h b/OperationFindAccount.h index 63cd90a..3200951 100644 --- a/OperationFindAccount.h +++ b/OperationFindAccount.h @@ -17,7 +17,7 @@ class OperationFindAccount : public Operation public: // overrides - SidActionResult DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; + SidActionResult DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; // constructors OperationFindAccount(std::queue & oArgList, const std::wstring & sCommand); diff --git a/OperationFindDomain.cpp b/OperationFindDomain.cpp index e579b6d..db1bb49 100644 --- a/OperationFindDomain.cpp +++ b/OperationFindDomain.cpp @@ -34,7 +34,7 @@ OperationFindDomain::OperationFindDomain(std::queue & oArgList, co if (sSubArgs.size() > 1) ProcessGranularTargetting(sSubArgs.at(1)); } -SidActionResult OperationFindDomain::DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) +SidActionResult OperationFindDomain::DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) { // see if this sid in the source domain BOOL bDomainSidsEqual = FALSE; diff --git a/OperationFindDomain.h b/OperationFindDomain.h index cf254d7..31882f6 100644 --- a/OperationFindDomain.h +++ b/OperationFindDomain.h @@ -17,7 +17,7 @@ class OperationFindDomain : public Operation public: // overrides - SidActionResult DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; + SidActionResult DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; // constructors OperationFindDomain(std::queue & oArgList, const std::wstring & sCommand); diff --git a/OperationFindNullAcl.cpp b/OperationFindNullAcl.cpp index 43f0a6d..0c051e8 100644 --- a/OperationFindNullAcl.cpp +++ b/OperationFindNullAcl.cpp @@ -10,7 +10,7 @@ OperationFindNullAcl::OperationFindNullAcl(std::queue & oArgList, AppliesToDacl = true; } -bool OperationFindNullAcl::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) +bool OperationFindNullAcl::ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) { // sanity check (null acl is considered valid) if (tCurrentAcl == nullptr) diff --git a/OperationFindNullAcl.h b/OperationFindNullAcl.h index 3157729..36cef2c 100644 --- a/OperationFindNullAcl.h +++ b/OperationFindNullAcl.h @@ -13,7 +13,7 @@ class OperationFindNullAcl : public Operation public: // overrides - bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; + bool ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; // constructors OperationFindNullAcl(std::queue & oArgList, const std::wstring & sCommand); diff --git a/OperationGrantDenyPerms.cpp b/OperationGrantDenyPerms.cpp index 983fdfe..22d9a21 100644 --- a/OperationGrantDenyPerms.cpp +++ b/OperationGrantDenyPerms.cpp @@ -116,7 +116,7 @@ OperationGrantDenyPerms::OperationGrantDenyPerms(std::queue& oArgL AppliesToDacl = true; } -bool OperationGrantDenyPerms::ProcessAclAction(WCHAR* const sSdPart, ObjectEntry& tObjectEntry, PACL& tCurrentAcl, bool& bAclReplacement) +bool OperationGrantDenyPerms::ProcessAclAction(const WCHAR* const sSdPart, ObjectEntry& tObjectEntry, PACL& tCurrentAcl, bool& bAclReplacement) { // define what constitutes 'full control' based on the object const DWORD iObjectTypeMask = IsDirectory(tObjectEntry.Attributes) diff --git a/OperationGrantDenyPerms.h b/OperationGrantDenyPerms.h index 074f899..21b5963 100644 --- a/OperationGrantDenyPerms.h +++ b/OperationGrantDenyPerms.h @@ -22,7 +22,7 @@ class OperationGrantDenyPerms : public Operation public: // overrides - bool ProcessAclAction(WCHAR* const sSdPart, ObjectEntry& tObjectEntry, PACL& tCurrentAcl, bool& bAclReplacement) override; + bool ProcessAclAction(const WCHAR* const sSdPart, ObjectEntry& tObjectEntry, PACL& tCurrentAcl, bool& bAclReplacement) override; // constructors OperationGrantDenyPerms(std::queue& oArgList, const std::wstring & sCommand); diff --git a/OperationHelp.cpp b/OperationHelp.cpp index 1b8f50a..7cc8c1e 100644 --- a/OperationHelp.cpp +++ b/OperationHelp.cpp @@ -195,6 +195,13 @@ Commands That Can Alter Security (When /WhatIf Is Not Present) used multiple times, it is recommended to use /Compact to ensure there are not any redundant access control entries. +/CopyMap + This command will read in the specified file that contains a list of + account mappings in : format. This command only + affects the DACL and SACL. This common is similiar to the /ReplaceMap + command but it does not affect the owner and does not removed the original + account. + /MoveDomain : This command will look to see whether any account in has an identically-named account in . If so, any entries diff --git a/OperationInheritChildren.cpp b/OperationInheritChildren.cpp index 2a6e42f..b59f3a6 100644 --- a/OperationInheritChildren.cpp +++ b/OperationInheritChildren.cpp @@ -15,7 +15,7 @@ OperationInheritChildren::OperationInheritChildren(std::queue & oA SpecialCommitFlags = UNPROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION; } -bool OperationInheritChildren::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) +bool OperationInheritChildren::ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) { // nothing to do -- the special commit flags will take care of it return true; diff --git a/OperationInheritChildren.h b/OperationInheritChildren.h index d451a1d..eaafd4b 100644 --- a/OperationInheritChildren.h +++ b/OperationInheritChildren.h @@ -13,7 +13,7 @@ class OperationInheritChildren : public Operation public: // overrides - bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; + bool ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; // constructors OperationInheritChildren(std::queue & oArgList, const std::wstring & sCommand); diff --git a/OperationLocateText.cpp b/OperationLocateText.cpp new file mode 100644 index 0000000..2df5021 --- /dev/null +++ b/OperationLocateText.cpp @@ -0,0 +1,178 @@ +#include "OperationLocateText.h" +#include "InputOutput.h" +#include "Functions.h" + +#pragma comment(lib, "bcrypt.lib") +#pragma comment(lib, "crypt32.lib") + +#include +#include + +ClassFactory OperationLocateText::RegisteredFactory(GetCommand()); + +#define Q(x) L"\"" + (x) + L"\"" + +OperationLocateText::OperationLocateText(std::queue & oArgList, const 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); + + // fetch params + 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.at(0).c_str(), GetCommand().c_str()); + exit(-1); + } + + // register the file handle + hReportFile = RegisterFileHandle(hFile, GetCommand()); + + // if this is the first handle using this file, write out a header + if (hFile == hReportFile) + { + // write out the file type marker + const BYTE hHeader[] = { 0xEF,0xBB,0xBF }; + DWORD iBytes = 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); + } + + // write out the header + std::wstring sToWrite = std::wstring(L"") + Q(L"Path") + L"," + Q(L"Creation Time") + L"," + + Q(L"Modified Time") + L"," + Q(L"Size") + L"," + Q(L"Attributes") + L"\r\n"; + if (WriteToFile(sToWrite, hReportFile) == 0) + { + wprintf(L"ERROR: Could not write header to report file for parameter '%s'.\n", GetCommand().c_str()); + exit(-1); + } + } + + // only flag this to apply to the core object with the file name + AppliesToObject = true; + + // record specific s if specified + if (sMatchAndArgs.size() > 1) + { + // convert the sha1 string from hex to binary + /* + aHashToMatch = new BYTE[HASH_IN_BYTES]; + DWORD iBytesRead = HASH_IN_BYTES; + if (CryptStringToBinary(sMatchAndArgs.at(1).c_str(), (DWORD) sMatchAndArgs.at(1).size(), + CRYPT_STRING_HEX_ANY, aHashToMatch, &iBytesRead, NULL, NULL) == FALSE || iBytesRead != HASH_IN_BYTES) + { + wprintf(L"ERROR: Invalid hash '%s' specified for parameter '%s'.\n", sMatchAndArgs.at(1).c_str(), GetCommand().c_str()); + exit(-1); + } + */ + } +} + +void OperationLocateText::ProcessObjectAction(ObjectEntry & tObjectEntry) +{ + // skip directories + if (IsDirectory(tObjectEntry.Attributes)) return; + + /* + // skip any files that do not match the size (if specified) + if (iSizeToMatch != -1 && tObjectEntry.FileSize.QuadPart != iSizeToMatch) return; + + // skip any file names that do not match the regex + const WCHAR* sFileName = tObjectEntry.Name.c_str(); + if (wcsrchr(sFileName, '\\') != nullptr) sFileName = wcsrchr(sFileName, '\\') + 1; + if (!std::regex_match(sFileName, tRegex)) return; + + // initialize hash for this thread + static constexpr size_t iFileBuffer = 2 * 1024 * 1024; + __declspec(thread) static BCRYPT_HASH_HANDLE HashHandle = NULL; + __declspec(thread) static PBYTE Hash = nullptr; + __declspec(thread) static PBYTE FileBuffer = nullptr; + __declspec(thread) static DWORD HashLength = 0; + if (Hash == nullptr) + { + BCRYPT_ALG_HANDLE AlgHandle = NULL; + DWORD ResultLength = 0; + if (BCryptOpenAlgorithmProvider(&AlgHandle, BCRYPT_SHA256_ALGORITHM, NULL, BCRYPT_HASH_REUSABLE_FLAG) != 0 || + BCryptGetProperty(AlgHandle, BCRYPT_HASH_LENGTH, (PBYTE) &HashLength, sizeof(HashLength), &ResultLength, 0) != 0 || + BCryptCreateHash(AlgHandle, &HashHandle, NULL, 0, NULL, 0, BCRYPT_HASH_REUSABLE_FLAG) != 0 || + (Hash = (PBYTE) malloc(HashLength)) == NULL || + (FileBuffer = (PBYTE) malloc(iFileBuffer)) == NULL) + { + wprintf(L"ERROR: Could not setup hashing environment.\n"); + exit(-1); + } + } + + HANDLE hFile = CreateFile(tObjectEntry.Name.c_str(), GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + InputOutput::AddError(L"Unable to open file for reading."); + return; + } + + DWORD iReadResult = 0; + DWORD iHashResult = 0; + DWORD iReadBytes = 0; + while ((iReadResult = ReadFile(hFile, FileBuffer, iFileBuffer, &iReadBytes, NULL)) != 0 && iReadBytes > 0) + { + iHashResult = BCryptHashData(HashHandle, FileBuffer, iReadBytes, 0); + if (iHashResult != 0) break; + } + + // done reading data + CloseHandle(hFile); + + // complete hash data + if (BCryptFinishHash(HashHandle, Hash, HashLength, 0) != 0) + { + InputOutput::AddError(L"Could not finalize file data."); + exit(-1); + } + + // file read failed + if (iHashResult != 0 || iReadResult == 0) + { + InputOutput::AddError(L"Could not hash/read file data."); + return; + } + + // skip if a hash was specified and there is no match + if (aHashToMatch != nullptr && memcmp(aHashToMatch, Hash, HASH_IN_BYTES) != 0) + { + return; + } + + // convert to base64 + WCHAR sHash[HASH_IN_HEXCHARS + 1] = L""; + DWORD iHashStringLength = HASH_IN_HEXCHARS + 1; + CryptBinaryToStringW(Hash, HashLength, CRYPT_STRING_HEXRAW | CRYPT_STRING_NOCRLF, + sHash, &iHashStringLength); + + // get common file attributes + const std::wstring sSize = FileSizeToString(tObjectEntry.FileSize); + const std::wstring sAttributes = FileAttributesToString(tObjectEntry.Attributes); + const std::wstring sModifiedTime = FileTimeToString(tObjectEntry.ModifiedTime); + const std::wstring sCreationTime = FileTimeToString(tObjectEntry.CreationTime); + + // check if the target path matches out regex filter + if (true) + { + // write output to file + std::wstring sToWrite = std::wstring(L"") + Q(tObjectEntry.Name) + L"," + + Q(sCreationTime) + L"," + Q(sModifiedTime) + L"," + + Q(sSize) + L"," + Q(sAttributes) + L"," + Q(sHash) + L"," + L"\r\n"; + if (WriteToFile(sToWrite, hReportFile) == 0) + { + InputOutput::AddError(L"Unable to write information to report file."); + } + } + */ +} \ No newline at end of file diff --git a/OperationMoveDomain.cpp b/OperationMoveDomain.cpp index 106d950..82a69c1 100644 --- a/OperationMoveDomain.cpp +++ b/OperationMoveDomain.cpp @@ -43,7 +43,7 @@ OperationMoveDomain::OperationMoveDomain(std::queue & oArgList, co if (sSubArgs.size() > 2) ProcessGranularTargetting(sSubArgs.at(2)); } -SidActionResult OperationMoveDomain::DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) +SidActionResult OperationMoveDomain::DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) { // see if this sid in the source domain BOOL bDomainSidsEqual = FALSE; diff --git a/OperationMoveDomain.h b/OperationMoveDomain.h index eb0d360..ab88b7c 100644 --- a/OperationMoveDomain.h +++ b/OperationMoveDomain.h @@ -19,7 +19,7 @@ class OperationMoveDomain : public Operation public: // overrides - SidActionResult DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; + SidActionResult DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; // constructors OperationMoveDomain(std::queue & oArgList, const std::wstring & sCommand); diff --git a/OperationRemoveAccount.cpp b/OperationRemoveAccount.cpp index 454030b..ea7677c 100644 --- a/OperationRemoveAccount.cpp +++ b/OperationRemoveAccount.cpp @@ -33,7 +33,7 @@ OperationRemoveAccount::OperationRemoveAccount(std::queue & oArgLi if (sSubArgs.size() > 1) ProcessGranularTargetting(sSubArgs.at(1)); } -SidActionResult OperationRemoveAccount::DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) +SidActionResult OperationRemoveAccount::DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) { // only process if sid matches if (SidNotMatch(tCurrentSid, tRemoveSid)) diff --git a/OperationRemoveAccount.h b/OperationRemoveAccount.h index bf1ea3b..c90195e 100644 --- a/OperationRemoveAccount.h +++ b/OperationRemoveAccount.h @@ -17,7 +17,7 @@ class OperationRemoveAccount : public Operation public: // overrides - SidActionResult DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; + SidActionResult DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; // constructors OperationRemoveAccount(std::queue & oArgList, const std::wstring & sCommand); diff --git a/OperationRemoveOrphan.cpp b/OperationRemoveOrphan.cpp index c585445..4bf55d5 100644 --- a/OperationRemoveOrphan.cpp +++ b/OperationRemoveOrphan.cpp @@ -33,7 +33,7 @@ OperationRemoveOrphan::OperationRemoveOrphan(std::queue & oArgList if (sSubArgs.size() > 1) ProcessGranularTargetting(sSubArgs.at(1)); } -SidActionResult OperationRemoveOrphan::DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) +SidActionResult OperationRemoveOrphan::DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) { // only bother doing a domain check if a domain was specified if (tDomainSid != nullptr) diff --git a/OperationRemoveOrphan.h b/OperationRemoveOrphan.h index fcad326..8e1f9fe 100644 --- a/OperationRemoveOrphan.h +++ b/OperationRemoveOrphan.h @@ -17,7 +17,7 @@ class OperationRemoveOrphan : public Operation public: // overrides - SidActionResult DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; + SidActionResult DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; // constructors OperationRemoveOrphan(std::queue & oArgList, const std::wstring & sCommand); diff --git a/OperationRemoveRedundant.cpp b/OperationRemoveRedundant.cpp index c39e901..c332029 100644 --- a/OperationRemoveRedundant.cpp +++ b/OperationRemoveRedundant.cpp @@ -12,7 +12,7 @@ OperationRemoveRedundant::OperationRemoveRedundant(std::queue & oA AppliesToSacl = true; } -bool OperationRemoveRedundant::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) +bool OperationRemoveRedundant::ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) { // sanity check if (tCurrentAcl == nullptr) return false; diff --git a/OperationRemoveRedundant.h b/OperationRemoveRedundant.h index 10d6439..0f39255 100644 --- a/OperationRemoveRedundant.h +++ b/OperationRemoveRedundant.h @@ -13,7 +13,7 @@ class OperationRemoveRedundant : public Operation public: // overrides - bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; + bool ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; // constructors OperationRemoveRedundant(std::queue & oArgList, const std::wstring & sCommand); diff --git a/OperationReplaceAccount.cpp b/OperationReplaceAccount.cpp index a6303ea..a62f959 100644 --- a/OperationReplaceAccount.cpp +++ b/OperationReplaceAccount.cpp @@ -43,7 +43,7 @@ OperationReplaceAccount::OperationReplaceAccount(std::queue & oArg if (sSubArgs.size() > 2) ProcessGranularTargetting(sSubArgs.at(2)); } -SidActionResult OperationReplaceAccount::DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) +SidActionResult OperationReplaceAccount::DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) { // check if the sid matches the ace if (SidMatch(tCurrentSid, tSearchAccount)) diff --git a/OperationReplaceAccount.h b/OperationReplaceAccount.h index 6398537..402f6f7 100644 --- a/OperationReplaceAccount.h +++ b/OperationReplaceAccount.h @@ -19,7 +19,7 @@ class OperationReplaceAccount : public Operation public: // overrides - SidActionResult DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; + SidActionResult DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; // constructors OperationReplaceAccount(std::queue & oArgList, const std::wstring & sCommand); diff --git a/OperationReplaceMap.cpp b/OperationReplaceMap.cpp index 3cb3b01..6efb708 100644 --- a/OperationReplaceMap.cpp +++ b/OperationReplaceMap.cpp @@ -25,7 +25,7 @@ OperationReplaceMap::OperationReplaceMap(std::queue & oArgList, co std::wstring sLine; while (std::getline(fFile, sLine)) { - // parse the search and replace account which are separated by a '=' character + // parse the search and replace account which are separated by a ':' character // also, sometimes a carriage return appears in the input stream so adding // it here ensures it is stripped from the very end std::vector oLineItems = SplitArgs(sLine, L":|\r"); @@ -67,7 +67,7 @@ OperationReplaceMap::OperationReplaceMap(std::queue & oArgList, co AppliesToOwner = true; } -SidActionResult OperationReplaceMap::DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) +SidActionResult OperationReplaceMap::DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) { // check if the sid matches the ace const auto oInteractor = oReplaceMap.find(tCurrentSid); diff --git a/OperationReplaceMap.h b/OperationReplaceMap.h index 4f62a81..c6102f6 100644 --- a/OperationReplaceMap.h +++ b/OperationReplaceMap.h @@ -16,7 +16,7 @@ class OperationReplaceMap : public Operation public: // overrides - SidActionResult DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; + SidActionResult DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; // constructors OperationReplaceMap(std::queue & oArgList, const std::wstring & sCommand); diff --git a/OperationReport.cpp b/OperationReport.cpp index 8dbe654..192c48a 100644 --- a/OperationReport.cpp +++ b/OperationReport.cpp @@ -70,7 +70,7 @@ OperationReport::OperationReport(std::queue & oArgList, const std: if (sMatchAndArgs.size() > 1) ProcessGranularTargetting(sMatchAndArgs.at(1)); } -SidActionResult OperationReport::DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) +SidActionResult OperationReport::DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) { // do not report null sids if (tCurrentSid == nullptr) return SidActionResult::Nothing; @@ -91,7 +91,7 @@ SidActionResult OperationReport::DetermineSid(WCHAR * const sSdPart, ObjectEntry return SidActionResult::Nothing; } -bool OperationReport::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) +bool OperationReport::ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) { // do not report null acls if (tCurrentAcl == nullptr) return false; diff --git a/OperationReport.h b/OperationReport.h index e8d9e9d..57dc7ba 100644 --- a/OperationReport.h +++ b/OperationReport.h @@ -19,8 +19,8 @@ class OperationReport : public Operation public: // overrides - SidActionResult DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; - bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; + SidActionResult DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; + bool ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; // constructors OperationReport(std::queue & oArgList, const std::wstring & sCommand); diff --git a/OperationResetChildren.cpp b/OperationResetChildren.cpp index 33ee2cb..d657486 100644 --- a/OperationResetChildren.cpp +++ b/OperationResetChildren.cpp @@ -17,7 +17,7 @@ OperationResetChildren::OperationResetChildren(std::queue & oArgLi SpecialCommitFlags = UNPROTECTED_SACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION; } -bool OperationResetChildren::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) +bool OperationResetChildren::ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) { // cleanup existing if it had been reallocated if (bAclReplacement) LocalFree(tCurrentAcl); diff --git a/OperationResetChildren.h b/OperationResetChildren.h index 7e054e8..0b196c9 100644 --- a/OperationResetChildren.h +++ b/OperationResetChildren.h @@ -16,7 +16,7 @@ class OperationResetChildren : public Operation public: // overrides - bool ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; + bool ProcessAclAction(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PACL & tCurrentAcl, bool & bAclReplacement) override; // constructors OperationResetChildren(std::queue & oArgList, const std::wstring & sCommand); diff --git a/OperationSetOwner.cpp b/OperationSetOwner.cpp index 2840796..de89788 100644 --- a/OperationSetOwner.cpp +++ b/OperationSetOwner.cpp @@ -30,7 +30,7 @@ OperationSetOwner::OperationSetOwner(std::queue & oArgList, const if (sSubArgs.size() > 1) ProcessGranularTargetting(sSubArgs.at(1)); } -SidActionResult OperationSetOwner::DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) +SidActionResult OperationSetOwner::DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) { // only process if sid does not matches if (SidMatch(tCurrentSid, tOwnerSid)) diff --git a/OperationSetOwner.h b/OperationSetOwner.h index d118b6a..6172764 100644 --- a/OperationSetOwner.h +++ b/OperationSetOwner.h @@ -17,7 +17,7 @@ class OperationSetOwner : public Operation public: // overrides - SidActionResult DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; + SidActionResult DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; // constructors OperationSetOwner(std::queue & oArgList, const std::wstring & sCommand); diff --git a/OperationSidHistory.cpp b/OperationSidHistory.cpp index aef46b3..e784970 100644 --- a/OperationSidHistory.cpp +++ b/OperationSidHistory.cpp @@ -13,7 +13,7 @@ OperationSidHistory::OperationSidHistory(std::queue & oArgList, co AppliesToOwner = true; } -SidActionResult OperationSidHistory::DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) +SidActionResult OperationSidHistory::DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) { // lookup the textual name for this account and // return if it is not found diff --git a/OperationSidHistory.h b/OperationSidHistory.h index a1d0029..87e0f71 100644 --- a/OperationSidHistory.h +++ b/OperationSidHistory.h @@ -13,7 +13,7 @@ class OperationSidHistory : public Operation public: // overrides - SidActionResult DetermineSid(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; + SidActionResult DetermineSid(const WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID const tCurrentSid, PSID & tResultantSid) override; // constructors OperationSidHistory(std::queue & oArgList, const std::wstring & sCommand); diff --git a/Resource.rc b/Resource.rc index d322826..543c585 100644 Binary files a/Resource.rc and b/Resource.rc differ diff --git a/repacls.vcxproj b/repacls.vcxproj index cf5e512..8c1b316 100644 --- a/repacls.vcxproj +++ b/repacls.vcxproj @@ -102,6 +102,7 @@ Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) MultiThreadedDebug + stdcpplatest Console @@ -118,6 +119,7 @@ _DEBUG;_CONSOLE;%(PreprocessorDefinitions) MultiThreadedDebug 4100 + stdcpplatest Console @@ -145,6 +147,7 @@ true false + stdcpplatest Console @@ -176,6 +179,7 @@ true false true + stdcpplatest Console @@ -193,6 +197,7 @@ + @@ -233,6 +238,7 @@ + diff --git a/repacls.vcxproj.filters b/repacls.vcxproj.filters index 25d528b..c656c57 100644 --- a/repacls.vcxproj.filters +++ b/repacls.vcxproj.filters @@ -118,6 +118,9 @@ Source\Operations + + Source\Operations + @@ -252,6 +255,9 @@ Includes + + Includes\Operations +