diff --git a/Build/Release/x64/repacls.exe b/Build/Release/x64/repacls.exe index ddded85..db63e69 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 bfe6909..9a33eb9 100644 Binary files a/Build/Release/x86/repacls.exe and b/Build/Release/x86/repacls.exe differ diff --git a/Build/Repacls.Binaries.1.9.1.0.zip b/Build/Repacls.Binaries.1.9.1.0.zip deleted file mode 100644 index dee9833..0000000 Binary files a/Build/Repacls.Binaries.1.9.1.0.zip and /dev/null differ diff --git a/Build/Repacls.zip b/Build/Repacls.zip new file mode 100644 index 0000000..42c35dd Binary files /dev/null and b/Build/Repacls.zip differ diff --git a/Build/build.cmd b/Build/build.cmd index 5806862..a3be320 100644 --- a/Build/build.cmd +++ b/Build/build.cmd @@ -1,20 +1,29 @@ @ECHO OFF +TITLE Building Repacls... +CLS +SET PATH=%WINDIR%\system32;%WINDIR%\system32\WindowsPowerShell\v1.0 :: cert info to use for signing -SET CERT=9CC90E20ABF21CDEF09EE4C467A79FD454140C5A +SET CERT=2FA35B20356EFEB88F9E9B5F20221693C57100E5 set TSAURL=http://time.certum.pl/ set LIBNAME=Repacls set LIBURL=https://github.com/NoMoreFood/Repacls :: do cleanup -FOR %%X IN (Debug Temp .vs) DO ( - FORFILES /S /P "%~dp0.." /M "%%X" /C "CMD /C IF @isdir==TRUE RD /S /Q @path" -) -FOR %%X IN (Win32 x64 Debug Release) DO ( - FORFILES /S /P "%~dp0.." /M "*.*pdb" /C "CMD /C DEL /Q @path" - FORFILES /S /P "%~dp0.." /M "*.*obj" /C "CMD /C DEL /Q @path" - FORFILES /S /P "%~dp0.." /M "*.log" /C "CMD /C DEL /Q @path" -) +RD /S /Q "%~dp0..\.vs" >NUL 2>&1 +RD /S /Q "%~dp0..\Temp" >NUL 2>&1 +RD /S /Q "%~dp0Debug" >NUL 2>&1 +RD /S /Q "%~dp0Release\x86\Temp" >NUL 2>&1 +RD /S /Q "%~dp0Release\x64\Temp" >NUL 2>&1 +FORFILES /S /P "%~dp0." /M "*.*pdb" /C "CMD /C DEL /Q @path" >NUL 2>&1 +FORFILES /S /P "%~dp0." /M "*.*obj" /C "CMD /C DEL /Q @path" >NUL 2>&1 +FORFILES /S /P "%~dp0." /M "*.zip" /C "CMD /C DEL /Q @path" >NUL 2>&1 +FORFILES /S /P "%~dp0." /M "*.log" /C "CMD /C DEL /Q @path" >NUL 2>&1 +FORFILES /S /P "%~dp0." /M "*.lib" /C "CMD /C DEL /Q @path" >NUL 2>&1 +FORFILES /S /P "%~dp0." /M "*.dll" /C "CMD /C DEL /Q @path" >NUL 2>&1 +FORFILES /S /P "%~dp0." /M "*.bsc" /C "CMD /C DEL /Q @path" >NUL 2>&1 +FORFILES /S /P "%~dp0." /M "*.exp" /C "CMD /C DEL /Q @path" >NUL 2>&1 +FORFILES /S /P "%~dp0." /M "*.last*" /C "CMD /C DEL /Q @path" >NUL 2>&1 :: setup environment variables based on location of this script SET BINDIR=%~dp0Release @@ -23,13 +32,17 @@ SET BINDIR=%~dp0Release IF DEFINED ProgramFiles SET PX86=%ProgramFiles% IF DEFINED ProgramFiles(x86) SET PX86=%ProgramFiles(x86)% -:: setup paths -SET PATH=%WINDIR%\system32;%WINDIR%\system32\WindowsPowerShell\v1.0 -SET PATH=%PATH%;%PX86%\Windows Kits\10\bin\x64 -SET PATH=%PATH%;%PX86%\Windows Kits\8.1\bin\x64 +:: setup commands and paths +SET POWERSHELL=POWERSHELL.EXE -NoProfile -NonInteractive -NoLogo +FOR /F "USEBACKQ DELIMS=" %%X IN (`DIR /OD /B /S "%PX86%\Windows Kits\10\SIGNTOOL.exe" ^| FINDSTR x64`) DO SET SIGNTOOL="%%~X" :: sign the main executables -signtool sign /sha1 %CERT% /fd sha1 /tr %TSAURL% /td sha1 /d %LIBNAME% /du %LIBURL% "%BINDIR%\x86\*.exe" "%BINDIR%\x64\*.exe" -signtool sign /sha1 %CERT% /as /fd sha256 /tr %TSAURL% /td sha256 /d %LIBNAME% /du %LIBURL% "%BINDIR%\x86\*.exe" "%BINDIR%\x64\*.exe" +%SIGNTOOL% sign /sha1 %CERT% /fd sha1 /tr %TSAURL% /td sha1 /d %LIBNAME% /du %LIBURL% "%BINDIR%\x86\*.exe" "%BINDIR%\x64\*.exe" +%SIGNTOOL% sign /sha1 %CERT% /as /fd sha256 /tr %TSAURL% /td sha256 /d %LIBNAME% /du %LIBURL% "%BINDIR%\x86\*.exe" "%BINDIR%\x64\*.exe" + +:: zip up executatables +PUSHD "%BINDIR%" +%POWERSHELL% -Command "Compress-Archive -LiteralPath @('x86','x64') -DestinationPath '%~dp0Repacls.zip'" +POPD PAUSE \ No newline at end of file diff --git a/OperationAddAccountIfMissing.cpp b/OperationAddAccountIfMissing.cpp index 1127670..267daad 100644 --- a/OperationAddAccountIfMissing.cpp +++ b/OperationAddAccountIfMissing.cpp @@ -7,7 +7,7 @@ new ClassFactory(GetCommand()); OperationAddAccountIfMissing::OperationAddAccountIfMissing(std::queue & oArgList) : Operation(oArgList) { - // exit if there are not enough arguments to part + // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList); // fetch params diff --git a/OperationBackupSecurity.cpp b/OperationBackupSecurity.cpp index 08e7d55..9531828 100644 --- a/OperationBackupSecurity.cpp +++ b/OperationBackupSecurity.cpp @@ -7,7 +7,7 @@ new ClassFactory(GetCommand()); OperationBackupSecurity::OperationBackupSecurity(std::queue & oArgList) : Operation(oArgList) { - // exit if there are not enough arguments to part + // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList, L"\\0"); // fetch params diff --git a/OperationCopyDomain.cpp b/OperationCopyDomain.cpp index e87d5c6..81cf202 100644 --- a/OperationCopyDomain.cpp +++ b/OperationCopyDomain.cpp @@ -7,7 +7,7 @@ new ClassFactory(GetCommand()); OperationCopyDomain::OperationCopyDomain(std::queue & oArgList) : Operation(oArgList) { - // exit if there are not enough arguments to part + // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(2, oArgList); // fetch params diff --git a/OperationDomainPaths.cpp b/OperationDomainPaths.cpp index d9834fd..06d15bb 100644 --- a/OperationDomainPaths.cpp +++ b/OperationDomainPaths.cpp @@ -19,7 +19,7 @@ new ClassFactory(GetCommand()); OperationDomainPaths::OperationDomainPaths(std::queue & oArgList) : Operation(oArgList) { - // exit if there are not enough arguments to part + // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList); // initialize com only diff --git a/OperationFindAccount.cpp b/OperationFindAccount.cpp index 747dbbe..9ac280c 100644 --- a/OperationFindAccount.cpp +++ b/OperationFindAccount.cpp @@ -7,7 +7,7 @@ ClassFactory * OperationFindAccount::RegisteredFactory = OperationFindAccount::OperationFindAccount(std::queue & oArgList) : Operation(oArgList) { - // exit if there are not enough arguments to part + // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList); // decode the passed parameter to an account name diff --git a/OperationFindDomain.cpp b/OperationFindDomain.cpp index ce3977b..739af90 100644 --- a/OperationFindDomain.cpp +++ b/OperationFindDomain.cpp @@ -7,7 +7,7 @@ new ClassFactory(GetCommand()); OperationFindDomain::OperationFindDomain(std::queue & oArgList) : Operation(oArgList) { - // exit if there are not enough arguments to part + // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList); // decode the passed parameter to an account name diff --git a/OperationHelp.cpp b/OperationHelp.cpp index 10136dc..07054c6 100644 --- a/OperationHelp.cpp +++ b/OperationHelp.cpp @@ -44,6 +44,12 @@ or end of your command as to not confuse them with ordered parameters. and all files and folders under the directory (unless otherwise specified). This parameter is mandatory. This command can be specified multiple times. +/PathList + 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). + /SharePaths [:AdminOnly|IncludeHidden|Match=|NoMatch=] Specifies a server that has one or more shares to process. This command is equivalent to specifying /Path for every share on a particular file server. @@ -103,10 +109,10 @@ Commands That Do Not Alter Security /CheckCanonical This command inspects the DACL and SACL for canonical order compliance - (i.e., the rules in the ACL are ordered as explicitly deny, explicitly allow, - inherited deny, inherited allow). If non-canonical entries are detected, - it is recommended to inspect the ACL with icacls.exe or Windows Explorer - to ensure the ACL is not corrupted in a more significant way. + (i.e., the rules in the ACL are ordered as explicitly deny, explicitly + allow, inherited deny, inherited allow). If non-canonical entries are + detected, it is recommended to inspect the ACL with icacls.exe or Windows + Explorer to ensure the ACL is not corrupted in a more significant way. /BackupSecurity Export the security descriptor to the file specified. The file is @@ -164,17 +170,17 @@ Commands That Can Alter Security (When /WhatIf Is Not Present) inefficiencies. While there's nothing inherently wrong with these entries, it possible for them to result file system is performance degradation. +)"; + std::wcout << + LR"( /CopyDomain : This command is identical to /MoveDomain except that the original entry referring the SourceDomainName is retained instead of replaced. This command only applies to the SACL and the DACL. If this command is used multiple times, it is recommended to use /Compact to ensure there are not any redundant access control entries. -)"; - std::wcout << - LR"( /MoveDomain : This command will look to see whether any account in has an identically-named account in . If so, any entires diff --git a/OperationLocate.cpp b/OperationLocate.cpp index 592c735..59fa8fc 100644 --- a/OperationLocate.cpp +++ b/OperationLocate.cpp @@ -9,7 +9,7 @@ new ClassFactory(GetCommand()); OperationLocate::OperationLocate(std::queue & oArgList) : Operation(oArgList) { - // exit if there are not enough arguments to part + // 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"); diff --git a/OperationMoveDomain.cpp b/OperationMoveDomain.cpp index 37ab762..b414978 100644 --- a/OperationMoveDomain.cpp +++ b/OperationMoveDomain.cpp @@ -7,7 +7,7 @@ new ClassFactory(GetCommand()); OperationMoveDomain::OperationMoveDomain(std::queue & oArgList) : Operation(oArgList) { - // exit if there are not enough arguments to part + // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(2, oArgList); // fetch params diff --git a/OperationPath.cpp b/OperationPath.cpp index 6144bb8..30e1158 100644 --- a/OperationPath.cpp +++ b/OperationPath.cpp @@ -7,7 +7,7 @@ ClassFactory * OperationPath::RegisteredFactory = OperationPath::OperationPath(std::queue & oArgList) : Operation(oArgList) { - // exit if there are not enough arguments to part + // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList, L"\\0"); // store off the argument diff --git a/OperationPathList.cpp b/OperationPathList.cpp new file mode 100644 index 0000000..3fe3c9a --- /dev/null +++ b/OperationPathList.cpp @@ -0,0 +1,44 @@ +#include "OperationPathList.h" +#include "InputOutput.h" +#include "Functions.h" + +#include +#include +#include +#include + +ClassFactory * OperationPathList::RegisteredFactory = +new ClassFactory(GetCommand()); + +OperationPathList::OperationPathList(std::queue & oArgList) : 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()); + + // adapt the stream to read windows unicode files + fFile.imbue(std::locale(fFile.getloc(), new std::codecvt_utf8)); + + // read the file line-by-line + std::wstring sLine; + while (std::getline(fFile, sLine)) + { + // 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"); + if (oLineItems.size() != 1) + { + wprintf(L"ERROR: Unable to parse string path list file."); + exit(-1); + } + + // store off the argument + InputOutput::ScanPaths().push_back(oLineItems[0]); + } + + // cleanup + fFile.close(); +}; \ No newline at end of file diff --git a/OperationPathList.h b/OperationPathList.h new file mode 100644 index 0000000..2498b09 --- /dev/null +++ b/OperationPathList.h @@ -0,0 +1,17 @@ +#pragma once + +#include "Operation.h" + +class OperationPathList : public Operation +{ +private: + + // statics used by command registration utility + static std::wstring GetCommand() { return L"PathList"; } + static ClassFactory * RegisteredFactory; + +public: + + // constructors + OperationPathList(std::queue & oArgList); +}; \ No newline at end of file diff --git a/OperationRemoveAccount.cpp b/OperationRemoveAccount.cpp index e5be0ae..cba4e8e 100644 --- a/OperationRemoveAccount.cpp +++ b/OperationRemoveAccount.cpp @@ -7,7 +7,7 @@ new ClassFactory(GetCommand()); OperationRemoveAccount::OperationRemoveAccount(std::queue & oArgList) : Operation(oArgList) { - // exit if there are not enough arguments to part + // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList); // fetch params diff --git a/OperationRemoveOrphan.cpp b/OperationRemoveOrphan.cpp index 922d3c8..def5da5 100644 --- a/OperationRemoveOrphan.cpp +++ b/OperationRemoveOrphan.cpp @@ -7,7 +7,7 @@ new ClassFactory(GetCommand()); OperationRemoveOrphan::OperationRemoveOrphan(std::queue & oArgList) : Operation(oArgList) { - // exit if there are not enough arguments to part + // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList); // decode the passed parameter to an account name diff --git a/OperationReplaceAccount.cpp b/OperationReplaceAccount.cpp index be36f9f..4adc66b 100644 --- a/OperationReplaceAccount.cpp +++ b/OperationReplaceAccount.cpp @@ -7,7 +7,7 @@ ClassFactory * OperationReplaceAccount::RegisteredFacto OperationReplaceAccount::OperationReplaceAccount(std::queue & oArgList) : Operation(oArgList) { - // exit if there are not enough arguments to part + // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(2, oArgList); // fetch params diff --git a/OperationReplaceMap.cpp b/OperationReplaceMap.cpp index 2e93613..d4a39ed 100644 --- a/OperationReplaceMap.cpp +++ b/OperationReplaceMap.cpp @@ -12,7 +12,7 @@ new ClassFactory(GetCommand()); OperationReplaceMap::OperationReplaceMap(std::queue & oArgList) : Operation(oArgList) { - // exit if there are not enough arguments to part + // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList, L"\\0"); // open the file diff --git a/OperationReport.cpp b/OperationReport.cpp index d7c9dea..e5d898f 100644 --- a/OperationReport.cpp +++ b/OperationReport.cpp @@ -9,7 +9,7 @@ new ClassFactory(GetCommand()); OperationReport::OperationReport(std::queue & oArgList) : Operation(oArgList) { - // exit if there are not enough arguments to part + // exit if there are not enough arguments to parse std::vector sReportFile = ProcessAndCheckArgs(1, oArgList, L"\\0"); std::vector sMatchAndArgs = ProcessAndCheckArgs(1, oArgList, L":"); diff --git a/OperationRestoreSecurity.cpp b/OperationRestoreSecurity.cpp index 4a2acd4..ba5efbe 100644 --- a/OperationRestoreSecurity.cpp +++ b/OperationRestoreSecurity.cpp @@ -12,7 +12,7 @@ new ClassFactory(GetCommand()); OperationRestoreSecurity::OperationRestoreSecurity(std::queue & oArgList) : Operation(oArgList) { - // exit if there are not enough arguments to part + // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList, L"\\0"); // open the file diff --git a/OperationSetOwner.cpp b/OperationSetOwner.cpp index badbd5f..9629642 100644 --- a/OperationSetOwner.cpp +++ b/OperationSetOwner.cpp @@ -7,7 +7,7 @@ new ClassFactory(GetCommand()); OperationSetOwner::OperationSetOwner(std::queue & oArgList) : Operation(oArgList) { - // exit if there are not enough arguments to part + // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList); // fetch params diff --git a/OperationSharePaths.cpp b/OperationSharePaths.cpp index 52c9efd..b0caa2a 100644 --- a/OperationSharePaths.cpp +++ b/OperationSharePaths.cpp @@ -14,7 +14,7 @@ ClassFactory * OperationSharePaths::RegisteredFactory = OperationSharePaths::OperationSharePaths(std::queue & oArgList) : Operation(oArgList) { - // exit if there are not enough arguments to part + // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList); // if extra arguments are specified, parse them diff --git a/OperationThreads.cpp b/OperationThreads.cpp index ef3b8eb..afbb047 100644 --- a/OperationThreads.cpp +++ b/OperationThreads.cpp @@ -7,7 +7,7 @@ new ClassFactory(GetCommand()); OperationThreads::OperationThreads(std::queue & oArgList) : Operation(oArgList) { - // exit if there are not enough arguments to part + // exit if there are not enough arguments to parse std::vector sSubArgs = ProcessAndCheckArgs(1, oArgList); // store off the argument diff --git a/Resource.rc b/Resource.rc index b70c99a..69dbc99 100644 Binary files a/Resource.rc and b/Resource.rc differ diff --git a/Version.h b/Version.h index f9398e7..1ed8185 100644 --- a/Version.h +++ b/Version.h @@ -1,3 +1,4 @@ #pragma once -#define VERSION_STRING "1.9.1.0" +#define VERSION_STRING "1.9.3.0" +#define VERSION_COMMA 1,9,3,0 diff --git a/repacls.vcxproj b/repacls.vcxproj index 3878713..f29df9c 100644 --- a/repacls.vcxproj +++ b/repacls.vcxproj @@ -22,7 +22,7 @@ {0E11E31A-BE5D-4B31-AA8E-DA9AEEC84F37} Win32Proj PermChange - 10.0.15063.0 + 10.0.17134.0 repacls @@ -203,6 +203,7 @@ + @@ -231,6 +232,7 @@ + diff --git a/repacls.vcxproj.filters b/repacls.vcxproj.filters index b4485b9..d592a39 100644 --- a/repacls.vcxproj.filters +++ b/repacls.vcxproj.filters @@ -100,6 +100,9 @@ Source\Operations + + Source\Operations + @@ -216,6 +219,9 @@ Includes\Operations + + Includes\Operations +