When you want to set permissions for a directory (and its files/subdirectories), you can use DirectoryInfo.GetAccessControl() to get the directory’s security, add/modify/remove access control rules, and then use DirectoryInfo.SetAccessControl() to apply the changes.
Access control rules are a complex combination of different settings. They control being able to do things like creating a file in the directory, read files, etc… . So before jumping into setting the permissions programmatically, I suggest taking a look at the directory’s current access control rules so you have an idea about what combination of settings to use. Here’s an example of reading and outputting the directory’s permissions:
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
var directoryInfo = new DirectoryInfo(@"C:\HelloWorld\");
var security = directoryInfo.GetAccessControl();
var accessRules = security.GetAccessRules(true, true, typeof(NTAccount));
foreach (FileSystemAccessRule rule in accessRules)
{
Console.WriteLine(new
{
rule.FileSystemRights,
rule.AccessControlType,
rule.InheritanceFlags,
rule.IdentityReference,
rule.PropagationFlags
});
}
Code language: C# (cs)
Here’s just one access control rule that this outputs:
{ FileSystemRights = FullControl, AccessControlType = Allow, InheritanceFlags = ContainerInherit, ObjectInherit, IdentityReference = BUILTIN\Administrators, PropagationFlags = None }
Code language: plaintext (plaintext)
Now I’ll show an example of setting the permissions programmatically.
Example: Add an access control rule for Everyone
Here’s an example of granting modify permissions (read/execute/write/list contents) to the Everyone group to a directory and applying the permissions to its files/subdirectories (they inherit the permissions):
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
//Get directory security
var directoryInfo = new DirectoryInfo(@"C:\HelloWorld\");
var security = directoryInfo.GetAccessControl();
//Which group/user?
var everyone = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
security.AddAccessRule(
new FileSystemAccessRule(everyone,
FileSystemRights.Modify,
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
PropagationFlags.None,
AccessControlType.Allow));
directoryInfo.SetAccessControl(security);
Code language: C# (cs)
Here’s what this looks like in the directory’s security properties:
The new access control rule looks like this when you output it programmatically:
{ FileSystemRights = Modify, Synchronize, AccessControlType = Allow, InheritanceFlags = ContainerInherit, ObjectInherit, IdentityReference = Everyone, PropagationFlags = None }
Code language: plaintext (plaintext)
Note: If you aren’t sure what combination of settings to use, you can add the permission manually in the directory properties in Windows and then take a look at the access rule settings in the code. See the code at the top of this article for an example of how to read and output the settings.
Specifying the permission type
In the example, it’s passing in FileSystemRights.Modify. This is actually a combination of several permissions: read & execute, list folder contents, and read/write. There are several options that are a combination of permissions for convenience.
When necessary, you can combine permissions together by bitwise ORing the exact settings you want. Here’s an example of bitwise ORing two permissions:
security.AddAccessRule(
new FileSystemAccessRule(everyone,
FileSystemRights.Read | FileSystemRights.Write,
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
PropagationFlags.None,
AccessControlType.Allow));
Code language: C# (cs)
Applying permissions to files/subdirectories
When you set permissions for a directory, you can apply the permissions to the directory’s files and subdirectories. You can control permission inheritance by using a combination of the InheritanceFlags and PropagationFlags parameters.
I suggest taking a look at the official documentation about ACL Propagation Rules to understand what combinations of the flags you need to get the results you want.
Note: InheritanceFlags is an enum flag, so you can bitwise OR settings together. For example, when the documentation refers to using ContainerInherit and ObjectInherit, you would use both of these by bitwise ORing them like this: InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit.
Specifying the user/group
You can specify which user/group the permission applies to by either 1) using a security identifer or 2) using a user/group name (string). It really depends where you expect this code to run. In the example shown above, it’s setting the permissions for the Everyone group by using a SecurityIdentifier object and setting it to WellKnownSideType.WorldSid:
var everyone = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
security.AddAccessRule(
new FileSystemAccessRule(everyone,
...
Code language: C# (cs)
If you’re going to be specifying a special group/user like Everyone, definitely use the WellKnownSidType enum. Otherwise you’ll run into problems when using this in different cultures.
You can also specify the group/name as a string (I suggest only doing this for users/groups you explicitly created in your system):
security.AddAccessRule(
new FileSystemAccessRule(@"SUPERCOMPUTER\Coder",
...
Code language: C# (cs)