diff --git a/Operation.cpp b/Operation.cpp index 2c70b08..7e50436 100644 --- a/Operation.cpp +++ b/Operation.cpp @@ -98,6 +98,13 @@ bool Operation::ProcessAclAction(WCHAR * const sSdPart, ObjectEntry & tObjectEnt return bMadeChange; } +std::vector Operation::SplitArgs(std::wstring sInput, std::wstring sDelimiter) +{ + std::wregex oRegex(sDelimiter); + std::wsregex_token_iterator oFirst{ sInput.begin(), sInput.end(), oRegex, -1 }, oLast; + return { oFirst, oLast }; +} + bool Operation::ProcessSidAction(WCHAR * const sSdPart, ObjectEntry & tObjectEntry, PSID & tCurrentSid, bool & bSidReplacement) { PSID tResultantSid; @@ -142,9 +149,7 @@ std::vector Operation::ProcessAndCheckArgs(int iArgsRequired, std: // parse the parameters, splitting on : std::wstring sArg = oArgList.front(); oArgList.pop(); - std::wregex oRegex(sDelimiter); - std::wsregex_token_iterator oFirst{ sArg.begin(), sArg.end(), oRegex, -1 }, oLast; - std::vector oSubArgs = { oFirst, oLast }; + std::vector oSubArgs = SplitArgs(sArg, sDelimiter); // verify we have enough parameters if (oSubArgs.size() < (size_t) iArgsRequired) diff --git a/Operation.h b/Operation.h index 8ec7776..22d9216 100644 --- a/Operation.h +++ b/Operation.h @@ -63,6 +63,7 @@ class Operation { protected: + static std::vector Operation::SplitArgs(std::wstring sInput, std::wstring sDelimiter); static std::vector ProcessAndCheckArgs(int iArgsRequired, std::queue & oArgList, std::wstring sDelimiter = L":"); void ProcessGranularTargetting(std::wstring sScope); diff --git a/OperationDomainPaths.cpp b/OperationDomainPaths.cpp index 0bf7fa4..a24950d 100644 --- a/OperationDomainPaths.cpp +++ b/OperationDomainPaths.cpp @@ -66,7 +66,8 @@ OperationDomainPaths::OperationDomainPaths(std::queue & oArgList) } // create the search filter - WCHAR sSearchFilter[] = L"(&(objectCategory=computer)(|(operatingSystem=*server*)(operatingSystem=*ontap*)(operatingSystem=*netapp*))(!(userAccountControl:1.2.840.113556.1.4.803:=8192))(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"; + WCHAR sSearchFilter[] = L"(&(objectCategory=computer)(|(operatingSystem=*server*)(operatingSystem=*ontap*)(operatingSystem=*netapp*))" \ + "(!(userAccountControl:1.2.840.113556.1.4.803:=8192))(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"; // execute the search. LPWSTR sAttributes[] = { L"cn" }; diff --git a/OperationSharePaths.cpp b/OperationSharePaths.cpp index 18bbb29..ecf37d6 100644 --- a/OperationSharePaths.cpp +++ b/OperationSharePaths.cpp @@ -21,19 +21,47 @@ OperationSharePaths::OperationSharePaths(std::queue & oArgList) : bool bStopOnErrors = false; bool bAdminOnly = false; bool bHiddenIncluded = false; + std::wregex oMatchRegex = std::wregex(L".*"); + std::wregex oNoMatchRegex = std::wregex(L"\0"); if (sSubArgs.size() == 2) { // further split the second arg into a command delimited list - std::wstring sArg = oArgList.front(); oArgList.pop(); - std::wregex oRegex(L","); - std::wsregex_token_iterator oFirst{ sSubArgs[1].begin(), sSubArgs[1].end(), oRegex, -1 }, oLast; - std::vector oShareArgs = { oFirst, oLast }; + std::vector oShareArgs = SplitArgs(sSubArgs[1], L","); // enumerate list for (std::vector::iterator sShareArg = oShareArgs.begin(); sShareArg != oShareArgs.end(); sShareArg++) { - if (_wcsicmp((*sShareArg).c_str(), L"INCLUDEHIDDEN") == 0) + // check to see if a match parameter was passed + WCHAR sMatchArg[] = L"MATCH="; + WCHAR sNoMatchArg[] = L"NOMATCH="; + if (_wcsnicmp((*sShareArg).c_str(), sMatchArg, _countof(sMatchArg) - 1) == 0 || + _wcsnicmp((*sShareArg).c_str(), sNoMatchArg, _countof(sNoMatchArg) - 1) == 0) + { + // split the NOMATCH/MATCH= sub parameter to get the regular expression part + std::vector oMatchArgs = SplitArgs(*sShareArg, L"="); + + // 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()); + exit(-1); + } + + try + { + // parse the regular expression + (_wcsnicmp((*sShareArg).c_str(), sMatchArg, _countof(sMatchArg) - 1) == 0) ? oMatchRegex : oNoMatchRegex = + std::wregex(oMatchArgs[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()); + exit(-1); + } + } + else if (_wcsicmp((*sShareArg).c_str(), L"INCLUDEHIDDEN") == 0) { bHiddenIncluded = true; } @@ -41,13 +69,13 @@ OperationSharePaths::OperationSharePaths(std::queue & oArgList) : { bAdminOnly = true; } - if (_wcsicmp((*sShareArg).c_str(), L"STOPONERROR") == 0) + else if (_wcsicmp((*sShareArg).c_str(), L"STOPONERROR") == 0) { bStopOnErrors = true; } else { - wprintf(L"ERROR: Unrecognized parameter '%s' for command '%s'\n", sSubArgs[1].c_str(), sSubArgs[0].c_str()); + wprintf(L"ERROR: Unrecognized share lookup option '%s'\n", (*sShareArg).c_str()); exit(-1); } } @@ -94,6 +122,12 @@ OperationSharePaths::OperationSharePaths(std::queue & oArgList) : // convert to uppercase std::transform(sLocalPath.begin(), sLocalPath.end(), sLocalPath.begin(), ::toupper); + // see if the share name matches the regular expression + if (!std::regex_match(tInfo[iEntry].shi2_netname, oMatchRegex)) continue; + + // see if the share name does not match the regular expression + if (std::regex_match(tInfo[iEntry].shi2_netname, oNoMatchRegex)) continue; + // add path to the share list mPaths[tInfo[iEntry].shi2_netname] = sLocalPath; } diff --git a/Version.h b/Version.h index aebfc06..428989e 100644 --- a/Version.h +++ b/Version.h @@ -1,3 +1,3 @@ #pragma once -#define VERSION_STRING "1.6.0.0" +#define VERSION_STRING "1.6.2.0"