Skip to content

Commit

Permalink
fix(installer): ensure NetworkService has proper file permissions (#1260
Browse files Browse the repository at this point in the history
)

We've had sporadic issues where users cannot update the revocation list
due to a permissions error on the .jrl file (access denied deleting the
original file).

Likely cause:

- Gateway was installed and created this file(s) at or before version
2024.1.5
- In subsequent versions, we switched the service account to
`NetworkService` and updated the DACL applied to the top-level
%programdata%\Devolutions\Gateway directory
- However, files created previously did not retroactively inherit
`NetworkService`'s new ACL
- This doesn't matter for most files where `Users` has read and execute
permission
- Files that need `Modify` permission won't have it (for example, the
.jrl and existing log files)

This version:

- Updates the SDDL set on the top-level
%programdata%\Devolutions\Gateway directory to ensure that
`NetworkService` can delete subfolders and files
- Forcibly resets the ACL on files in the program data directory
  • Loading branch information
thenextman authored Mar 4, 2025
1 parent f94d56a commit 9567417
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 13 deletions.
22 changes: 22 additions & 0 deletions package/WindowsManaged/Actions/CustomActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
using DevolutionsGateway.Configuration;
using static DevolutionsGateway.Actions.WinAPI;
using System.Security.Principal;
using System.Security.AccessControl;

namespace DevolutionsGateway.Actions
{
Expand Down Expand Up @@ -985,6 +986,27 @@ public static ActionResult SetProgramDataDirectoryPermissions(Session session)
try
{
SetFileSecurity(session, ProgramDataDirectory, Includes.PROGRAM_DATA_SDDL);

// Files created before NetworkService was granted access to the program data directory
// don't retroactively inherit the new ACE
// We fix this by removing access rule protection on the files
// and then reapplying the ACL
DirectoryInfo dir = new DirectoryInfo(ProgramDataDirectory);

foreach (FileInfo file in dir.GetFiles("*", SearchOption.AllDirectories))
{
try
{
FileSecurity fileSecurity = file.GetAccessControl();
fileSecurity.SetAccessRuleProtection(false, false);
file.SetAccessControl(fileSecurity);
}
catch (Exception e)
{
session.Log($"failed to reset permissions on path {file.FullName}: {e}");
}
}

return ActionResult.Success;
}
catch (Exception e)
Expand Down
23 changes: 10 additions & 13 deletions package/WindowsManaged/Resources/Includes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,22 @@ internal static class Includes
/// Easiest way to generate an SDDL is to configure the required access, and then query the path with PowerShell: `Get-Acl | Format-List`
/// </summary>
/// <remarks>
/// Owner : NT AUTHORITY\SYSTEM
/// Group : NT AUTHORITY\SYSTEM
/// Access :
/// NT AUTHORITY\SYSTEM Allow FullControl
/// NT AUTHORITY\LOCAL SERVICE Allow Write, ReadAndExecute, Synchronize
/// NT AUTHORITY\NETWORK SERVICE Allow Modify, Synchronize
/// BUILTIN\Administrators Allow FullControl
/// BUILTIN\Users Allow ReadAndExecute, Synchronize
/// Local System (SY) Full Access (FA)
/// Local Service (LS) Read, Execute
/// Network Service (NS) Read, Execute, Write, Delete Subfolders and Files
/// Administrators (BA) Full Access (FA)
/// Users (BU) Read, Execute
/// </remarks>
internal static string PROGRAM_DATA_SDDL = "O:SYG:SYD:PAI(A;OICI;FA;;;SY)(A;OICI;0x1201bf;;;LS)(A;OICI;0x1301bf;;;NS)(A;OICI;FA;;;BA)(A;OICI;0x1200a9;;;BU)";
internal static string PROGRAM_DATA_SDDL = "O:SYG:SYD:PAI(A;OICI;FA;;;SY)(A;OICI;0x1201bf;;;LS)(A;OICI;0x1301ff;;;NS)(A;OICI;FA;;;BA)(A;OICI;0x1200a9;;;BU)";

/// <remarks>
/// Owner : NT AUTHORITY\SYSTEM
/// Group : NT AUTHORITY\SYSTEM
/// Access :
/// NT AUTHORITY\SYSTEM Allow FullControl
/// NT AUTHORITY\LOCAL SERVICE Allow Write, ReadAndExecute, Synchronize
/// NT AUTHORITY\NETWORK SERVICE Allow Write, ReadAndExecute, Synchronize
/// BUILTIN\Administrators Allow FullControl
/// Local System (SY) Full Access (FA)
/// Local Service (LS) Read, Execute, Modify (Write)
/// Network Service (NS) Read, Execute, Modify (Write)
/// Administrators (BA) Full Access (FA)
/// </remarks>
internal static string USERS_FILE_SDDL = "O:SYG:SYD:PAI(A;;FA;;;SY)(A;;0x1201bf;;;LS)(A;;0x1201bf;;;NS)(A;;FA;;;BA)";
}
Expand Down

0 comments on commit 9567417

Please sign in to comment.