Skip to content

Commit

Permalink
Added /PathList Operation
Browse files Browse the repository at this point in the history
- Added /PathList operator that allows the user to provide a newline-delimited text file that contains paths of files or directories to process.
- Updated build script to use new certificate, perform cleanup similiar to other projects, and automatically create a zip file.
- Updated and signed binaries for 1.9.3.0.
  • Loading branch information
NoMoreFood committed Nov 7, 2018
1 parent 112d6f6 commit e51588b
Show file tree
Hide file tree
Showing 30 changed files with 131 additions and 42 deletions.
Binary file modified Build/Release/x64/repacls.exe
Binary file not shown.
Binary file modified Build/Release/x86/repacls.exe
Binary file not shown.
Binary file removed Build/Repacls.Binaries.1.9.1.0.zip
Binary file not shown.
Binary file added Build/Repacls.zip
Binary file not shown.
43 changes: 28 additions & 15 deletions Build/build.cmd
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
2 changes: 1 addition & 1 deletion OperationAddAccountIfMissing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ new ClassFactory<OperationAddAccountIfMissing>(GetCommand());

OperationAddAccountIfMissing::OperationAddAccountIfMissing(std::queue<std::wstring> & oArgList) : Operation(oArgList)
{
// exit if there are not enough arguments to part
// exit if there are not enough arguments to parse
std::vector<std::wstring> sSubArgs = ProcessAndCheckArgs(1, oArgList);

// fetch params
Expand Down
2 changes: 1 addition & 1 deletion OperationBackupSecurity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ new ClassFactory<OperationBackupSecurity>(GetCommand());

OperationBackupSecurity::OperationBackupSecurity(std::queue<std::wstring> & oArgList) : Operation(oArgList)
{
// exit if there are not enough arguments to part
// exit if there are not enough arguments to parse
std::vector<std::wstring> sSubArgs = ProcessAndCheckArgs(1, oArgList, L"\\0");

// fetch params
Expand Down
2 changes: 1 addition & 1 deletion OperationCopyDomain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ new ClassFactory<OperationCopyDomain>(GetCommand());

OperationCopyDomain::OperationCopyDomain(std::queue<std::wstring> & oArgList) : Operation(oArgList)
{
// exit if there are not enough arguments to part
// exit if there are not enough arguments to parse
std::vector<std::wstring> sSubArgs = ProcessAndCheckArgs(2, oArgList);

// fetch params
Expand Down
2 changes: 1 addition & 1 deletion OperationDomainPaths.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ new ClassFactory<OperationDomainPaths>(GetCommand());

OperationDomainPaths::OperationDomainPaths(std::queue<std::wstring> & oArgList) : Operation(oArgList)
{
// exit if there are not enough arguments to part
// exit if there are not enough arguments to parse
std::vector<std::wstring> sSubArgs = ProcessAndCheckArgs(1, oArgList);

// initialize com only
Expand Down
2 changes: 1 addition & 1 deletion OperationFindAccount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ClassFactory<OperationFindAccount> * OperationFindAccount::RegisteredFactory =

OperationFindAccount::OperationFindAccount(std::queue<std::wstring> & oArgList) : Operation(oArgList)
{
// exit if there are not enough arguments to part
// exit if there are not enough arguments to parse
std::vector<std::wstring> sSubArgs = ProcessAndCheckArgs(1, oArgList);

// decode the passed parameter to an account name
Expand Down
2 changes: 1 addition & 1 deletion OperationFindDomain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ new ClassFactory<OperationFindDomain>(GetCommand());

OperationFindDomain::OperationFindDomain(std::queue<std::wstring> & oArgList) : Operation(oArgList)
{
// exit if there are not enough arguments to part
// exit if there are not enough arguments to parse
std::vector<std::wstring> sSubArgs = ProcessAndCheckArgs(1, oArgList);

// decode the passed parameter to an account name
Expand Down
20 changes: 13 additions & 7 deletions OperationHelp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <FileName>
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 <ComputerName>[:AdminOnly|IncludeHidden|Match=<Str>|NoMatch=<Str>]
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.
Expand Down Expand Up @@ -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 <FileName>
Export the security descriptor to the file specified. The file is
Expand Down Expand Up @@ -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 <SourceDomainName>:<TargetDomainName>
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 <SourceDomainName>:<TargetDomainName>
This command will look to see whether any account in <SourceDomain>
has an identically-named account in <TargetDomain>. If so, any entires
Expand Down
2 changes: 1 addition & 1 deletion OperationLocate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ new ClassFactory<OperationLocate>(GetCommand());

OperationLocate::OperationLocate(std::queue<std::wstring> & oArgList) : Operation(oArgList)
{
// exit if there are not enough arguments to part
// exit if there are not enough arguments to parse
std::vector<std::wstring> sReportFile = ProcessAndCheckArgs(1, oArgList, L"\\0");
std::vector<std::wstring> sMatchAndArgs = ProcessAndCheckArgs(1, oArgList, L"\\0");

Expand Down
2 changes: 1 addition & 1 deletion OperationMoveDomain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ new ClassFactory<OperationMoveDomain>(GetCommand());

OperationMoveDomain::OperationMoveDomain(std::queue<std::wstring> & oArgList) : Operation(oArgList)
{
// exit if there are not enough arguments to part
// exit if there are not enough arguments to parse
std::vector<std::wstring> sSubArgs = ProcessAndCheckArgs(2, oArgList);

// fetch params
Expand Down
2 changes: 1 addition & 1 deletion OperationPath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ClassFactory<OperationPath> * OperationPath::RegisteredFactory =

OperationPath::OperationPath(std::queue<std::wstring> & oArgList) : Operation(oArgList)
{
// exit if there are not enough arguments to part
// exit if there are not enough arguments to parse
std::vector<std::wstring> sSubArgs = ProcessAndCheckArgs(1, oArgList, L"\\0");

// store off the argument
Expand Down
44 changes: 44 additions & 0 deletions OperationPathList.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "OperationPathList.h"
#include "InputOutput.h"
#include "Functions.h"

#include <fstream>
#include <iostream>
#include <locale>
#include <codecvt>

ClassFactory<OperationPathList> * OperationPathList::RegisteredFactory =
new ClassFactory<OperationPathList>(GetCommand());

OperationPathList::OperationPathList(std::queue<std::wstring> & oArgList) : Operation(oArgList)
{
// exit if there are not enough arguments to parse
std::vector<std::wstring> 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<wchar_t,
0x10ffff, std::consume_header>));

// 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<std::wstring> 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();
};
17 changes: 17 additions & 0 deletions OperationPathList.h
Original file line number Diff line number Diff line change
@@ -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<OperationPathList> * RegisteredFactory;

public:

// constructors
OperationPathList(std::queue<std::wstring> & oArgList);
};
2 changes: 1 addition & 1 deletion OperationRemoveAccount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ new ClassFactory<OperationRemoveAccount>(GetCommand());

OperationRemoveAccount::OperationRemoveAccount(std::queue<std::wstring> & oArgList) : Operation(oArgList)
{
// exit if there are not enough arguments to part
// exit if there are not enough arguments to parse
std::vector<std::wstring> sSubArgs = ProcessAndCheckArgs(1, oArgList);

// fetch params
Expand Down
2 changes: 1 addition & 1 deletion OperationRemoveOrphan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ new ClassFactory<OperationRemoveOrphan>(GetCommand());

OperationRemoveOrphan::OperationRemoveOrphan(std::queue<std::wstring> & oArgList) : Operation(oArgList)
{
// exit if there are not enough arguments to part
// exit if there are not enough arguments to parse
std::vector<std::wstring> sSubArgs = ProcessAndCheckArgs(1, oArgList);

// decode the passed parameter to an account name
Expand Down
2 changes: 1 addition & 1 deletion OperationReplaceAccount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ClassFactory<OperationReplaceAccount> * OperationReplaceAccount::RegisteredFacto

OperationReplaceAccount::OperationReplaceAccount(std::queue<std::wstring> & oArgList) : Operation(oArgList)
{
// exit if there are not enough arguments to part
// exit if there are not enough arguments to parse
std::vector<std::wstring> sSubArgs = ProcessAndCheckArgs(2, oArgList);

// fetch params
Expand Down
2 changes: 1 addition & 1 deletion OperationReplaceMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ new ClassFactory<OperationReplaceMap>(GetCommand());

OperationReplaceMap::OperationReplaceMap(std::queue<std::wstring> & oArgList) : Operation(oArgList)
{
// exit if there are not enough arguments to part
// exit if there are not enough arguments to parse
std::vector<std::wstring> sSubArgs = ProcessAndCheckArgs(1, oArgList, L"\\0");

// open the file
Expand Down
2 changes: 1 addition & 1 deletion OperationReport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ new ClassFactory<OperationReport>(GetCommand());

OperationReport::OperationReport(std::queue<std::wstring> & oArgList) : Operation(oArgList)
{
// exit if there are not enough arguments to part
// exit if there are not enough arguments to parse
std::vector<std::wstring> sReportFile = ProcessAndCheckArgs(1, oArgList, L"\\0");
std::vector<std::wstring> sMatchAndArgs = ProcessAndCheckArgs(1, oArgList, L":");

Expand Down
2 changes: 1 addition & 1 deletion OperationRestoreSecurity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ new ClassFactory<OperationRestoreSecurity>(GetCommand());

OperationRestoreSecurity::OperationRestoreSecurity(std::queue<std::wstring> & oArgList) : Operation(oArgList)
{
// exit if there are not enough arguments to part
// exit if there are not enough arguments to parse
std::vector<std::wstring> sSubArgs = ProcessAndCheckArgs(1, oArgList, L"\\0");

// open the file
Expand Down
2 changes: 1 addition & 1 deletion OperationSetOwner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ new ClassFactory<OperationSetOwner>(GetCommand());

OperationSetOwner::OperationSetOwner(std::queue<std::wstring> & oArgList) : Operation(oArgList)
{
// exit if there are not enough arguments to part
// exit if there are not enough arguments to parse
std::vector<std::wstring> sSubArgs = ProcessAndCheckArgs(1, oArgList);

// fetch params
Expand Down
2 changes: 1 addition & 1 deletion OperationSharePaths.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ ClassFactory<OperationSharePaths> * OperationSharePaths::RegisteredFactory =

OperationSharePaths::OperationSharePaths(std::queue<std::wstring> & oArgList) : Operation(oArgList)
{
// exit if there are not enough arguments to part
// exit if there are not enough arguments to parse
std::vector<std::wstring> sSubArgs = ProcessAndCheckArgs(1, oArgList);

// if extra arguments are specified, parse them
Expand Down
2 changes: 1 addition & 1 deletion OperationThreads.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ new ClassFactory<OperationThreads>(GetCommand());

OperationThreads::OperationThreads(std::queue<std::wstring> & oArgList) : Operation(oArgList)
{
// exit if there are not enough arguments to part
// exit if there are not enough arguments to parse
std::vector<std::wstring> sSubArgs = ProcessAndCheckArgs(1, oArgList);

// store off the argument
Expand Down
Binary file modified Resource.rc
Binary file not shown.
3 changes: 2 additions & 1 deletion Version.h
Original file line number Diff line number Diff line change
@@ -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
4 changes: 3 additions & 1 deletion repacls.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<ProjectGuid>{0E11E31A-BE5D-4B31-AA8E-DA9AEEC84F37}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>PermChange</RootNamespace>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
<ProjectName>repacls</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
Expand Down Expand Up @@ -203,6 +203,7 @@
<ClCompile Include="OperationFindNullAcl.cpp" />
<ClCompile Include="OperationHelp.cpp" />
<ClCompile Include="OperationLocate.cpp" />
<ClCompile Include="OperationPathList.cpp" />
<ClCompile Include="OperationReplaceMap.cpp" />
<ClCompile Include="OperationRestoreSecurity.cpp" />
<ClCompile Include="OperationInheritChildren.cpp" />
Expand Down Expand Up @@ -231,6 +232,7 @@
<ClInclude Include="OperationCopyDomain.h" />
<ClInclude Include="OperationDomainPaths.h" />
<ClInclude Include="OperationLocate.h" />
<ClInclude Include="OperationPathList.h" />
<ClInclude Include="OperationReplaceMap.h" />
<ClInclude Include="OperationRestoreSecurity.h" />
<ClInclude Include="OperationSharePaths.h" />
Expand Down
6 changes: 6 additions & 0 deletions repacls.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@
<ClCompile Include="OperationReplaceMap.cpp">
<Filter>Source\Operations</Filter>
</ClCompile>
<ClCompile Include="OperationPathList.cpp">
<Filter>Source\Operations</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ConcurrentQueue.h">
Expand Down Expand Up @@ -216,6 +219,9 @@
<ClInclude Include="OperationReplaceMap.h">
<Filter>Includes\Operations</Filter>
</ClInclude>
<ClInclude Include="OperationPathList.h">
<Filter>Includes\Operations</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Includes">
Expand Down

0 comments on commit e51588b

Please sign in to comment.