Changing file ACL in Windows programmatically

By | August 18, 2020

File (or directory) access control list (ACL) is a bit similar to the file attribute. In the same way ACL specifies file properties related to access to the file. ACL contains records of ACEs (access control entities). Each ACE in an ACL identifies specific access rights for users or groups that allow or deny some operation with file or directory. Let us create in command prompt small text file and check its ACL using icacls command:
View ACL in command prompt


The same it is possible to view file ACL using Windows graphic user interface.
File security
Acually icalcs is very powerful command to change, add or delete ACE from ACL, but some operation should be executed with administrator privileges. Do not worry if something is going wrong, icalcs gives possibility to reset ALC for default settings very easily. For example resetting ACL in c:\Alex directory and files within it recursively:

using System;
> icalcs c:/alex /reset /t

.Net has API to modify ACL programmatically. The example below shows how to get ACL of some specific file and add/remove Everyone or “Authenticated Users” access control entities.

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Security.Principal;
using System.Security.AccessControl;
namespace acl
{
   class Program
   {
      static void Main(string[] args)
      {
         WindowsIdentity wi = WindowsIdentity.GetCurrent();
         WindowsPrincipal wp = new WindowsPrincipal(wi);
         if (!wp.IsInRole(WindowsBuiltInRole.Administrator))
         {
            Console.WriteLine(“Start application as administator”);
            return;
         }
         if (args.Length < 1)
         {
            Console.WriteLine(“Specify arguments (order is important):”);
            Console.WriteLine(” 1. File name with path”);
            Console.WriteLine(” 2. Optional. ae/re – add/remove Everyone or aau/aru – add/remove \”NT AUTHORITY\\Authenticated Users\””);
            Console.WriteLine(“\nExample to remove \”Authenticated Users\” from fake.txt file:”);
            Console.WriteLine(”   acl fake.txt rau”);
            return;
         }
         if(!File.Exists(args[0]))
         {
            Console.WriteLine(“The first argument error. File ” + args[0] + ” does not exists”);
            return;
         }
         FileSecurity fs = File.GetAccessControl(args[0]);
         AuthorizationRuleCollection arc = fs.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
         if (args.Length == 1)
         {
          accessControlList(arc);
          return;
         }
         string identityRefName = “”;
         bool addACE = true;
         FileSystemRights fileSystemRights = FileSystemRights.AppendData;
         AccessControlType type = AccessControlType.Allow;
         bool IsInherited = false;
         if (args.Length == 2)
         {
            switch (args[1])
            {
               case “ae”:
                  identityRefName = “Everyone”;
                  fileSystemRights = FileSystemRights.FullControl;
                  break;
               case “re”:
                  identityRefName = “Everyone”;
                  fileSystemRights = FileSystemRights.FullControl;
                  addACE = false;
                  break;
               case “aau”:
                  identityRefName = “NT AUTHORITY\\Authenticated Users”;
                  fileSystemRights = FileSystemRights.Modify | FileSystemRights.Synchronize;
                  break;
               case “rau”:
                  identityRefName = “NT AUTHORITY\\Authenticated Users”;
                  fileSystemRights = FileSystemRights.ReadAndExecute | FileSystemRights.Synchronize;
                  addACE = false;
                  break;
            }
            if(String.IsNullOrEmpty(identityRefName))
            {
               Console.WriteLine(“The second argument is not valid.”);
               Console.WriteLine(“Should be ae, re, au, ruu”);
               return;
            }
         }
         if (findIdentityRef(arc, identityRefName, ref fileSystemRights, ref type, ref IsInherited) == null)
         {
            if (!addACE)
            {
               Console.WriteLine(“ACE ” + identityRefName + ” was already removed”);
               return;
            }
            Console.WriteLine(“Add ” + identityRefName);
            fs.AddAccessRule(new FileSystemAccessRule(identityRefName, fileSystemRights, type));
            File.SetAccessControl(args[0], fs);
         }
         else
         {
            if (addACE)
            {
               Console.WriteLine(“ACE ” + identityRefName + ” was presented”);
               return;
            }
            if (!IsInherited)
            {
               Console.WriteLine(“Remove ” + identityRefName);
               //            fs.SetAccessRuleProtection(true, false);
               if (!fs.RemoveAccessRule(new FileSystemAccessRule(identityRefName, fileSystemRights, type)))
                  Console.WriteLine(“Rule ” + identityRefName + ” cannot be removed”);
               File.SetAccessControl(args[0], fs);
            }
            else
            {
               Console.WriteLine(“Disable inheritance of \”” + identityRefName + “\” before removing”);
            }
         }
      }
      static void accessControlList(AuthorizationRuleCollection arc)
      {
         foreach (FileSystemAccessRule fsar in arc)
         {
            string userName = fsar.IdentityReference.Value;
            Console.WriteLine(“User Name: ” + userName);
            string rights = fsar.FileSystemRights.ToString();
            Console.WriteLine(” Rights: ” + rights);
            string accessType = fsar.AccessControlType.ToString();
            Console.WriteLine(” Access Type: ” + accessType);
            string ruleSource = fsar.IsInherited ? “Inherited” : “Explicit”;
            Console.WriteLine(” Is Inherited: ” + ruleSource);
            string rulePropagation = fsar.PropagationFlags.ToString();
            Console.WriteLine(” Rule Propagation: ” + rulePropagation);
            string ruleInheritance = fsar.InheritanceFlags.ToString();
            Console.WriteLine(” Rule Inheritance: ” + ruleInheritance);
         }
      }
      static IdentityReference findIdentityRef(AuthorizationRuleCollection arc, string identityRefName,
         ref FileSystemRights fileSystemRights, ref AccessControlType type, ref bool IsInherited)
      {
         IdentityReference ir = null;
         foreach (FileSystemAccessRule fsar in arc)
         {
            string userName = fsar.IdentityReference.Value;
//            Console.WriteLine(identityRefName + “:” + userName);
            if (userName == identityRefName)
            {
               ir = fsar.IdentityReference;
               fileSystemRights = fsar.FileSystemRights;
               type = fsar.AccessControlType;
               IsInherited = fsar.IsInherited;
            }
         }
         return ir;
      }
   }
}

Leave a Reply

Your email address will not be published. Required fields are marked *