Wednesday, March 30, 2022

Set specific directory access controls

I had to create a directory with was only accessible to a specific Windows account and no other accounts, not even Administrators or SYSTEM. This was needed to isolate the important directory and its files from accidental (or malicious) access by any process other than the single service that used them.

The .NET Framework has managed wrapper classes over most of the Windows security API, but to the developer who only tampers with security occasionally, the classes can be really confusing. The relationships between account names, SIDs, ACLs, ACEs, inheritance, propagation, etc can be hard to remember and untangle.

As a reminder to myself and others, here is skeleton code that isolates a directory by removing all existing account access, disabling inheritance from the parent folder, then adding access to a specific account.

In my example I use the built-in NETWORK SERVICE account as the one to have access, but that can be replaced with different account(s).

  var dir = new DirectoryInfo(@"D:\temp\TestDir");
  var sid = new SecurityIdentifier(WellKnownSidType.NetworkServiceSid, null);
  NTAccount acc = (NTAccount)sid.Translate(typeof(NTAccount));
  var rule1 = new FileSystemAccessRule(
    acc,
    FileSystemRights.Modify,
    InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
    PropagationFlags.None,
    AccessControlType.Allow);
  var dsec = new DirectorySecurity();
  dsec.SetAccessRuleProtection(true, false);
  dsec.AddAccessRule(rule1);
  dir.SetAccessControl(dsec);

A bit of a trick is the usage of the SetAccessRuleProtection call to disable inheritance from parent directories. If you dump a DirectorySecurity object you will see it corresponds to the DACL, and that's where inheritance is defined.

For a similar exercise related to the Registry, see the post titled Registry Secrets and Permissions.

No comments:

Post a Comment