Setting NTFS Permissions with C#

Posted Sunday, February 08, 2004 12:06 AM by CumpsD
Today I needed to set NTFS permissions in C# on some newly created directories.

No problem I thought, the CLR will have something for it somewhere in Security, so I checked Google in the hopes to find which class to use.

But Google didn't find anything... This amazed me. "Why can't I control NTFS permissions with .NET ?!?"

After looking for an hour or so, I found a GotDotNet User Sample, called 'ACLs in .NET'. Finally I thought, now it's going to be plug in and set rights.

Well this library is great. It makes settings NTFS rights so easy.

But it lacks a bit in documentation. Therefore I'm providing some of the code I used with it, it could help you. (or it could show my possibly bad coding style, as far as my knowledge goes for know, it should be fine)

Reference the dll, and use it.

using Microsoft.Win32.Security;


Here's a method to add a dir, and set NTFS permissions on it for a given user:

private Boolean CreateDir(String strSitePath, String strUserName) {

       Boolean bOk;

       try {

              Directory.CreateDirectory(strSitePath);

              SecurityDescriptor secDesc = SecurityDescriptor.GetFileSecurity(strSitePath, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION);

              Dacl dacl = secDesc.Dacl;

              Sid sidUser = new Sid (strUserName);

 

              // allow: folder, subfolder and files

              // modify

              dacl.AddAce (new AceAccessAllowed (sidUser, AccessType.GENERIC_WRITE | AccessType.GENERIC_READ | AccessType.DELETE | AccessType.GENERIC_EXECUTE , AceFlags.OBJECT_INHERIT_ACE | AceFlags.CONTAINER_INHERIT_ACE));

             

              // deny: this folder

              // write attribs

              // write extended attribs

              // delete

              // change permissions

              // take ownership

              DirectoryAccessType DAType = DirectoryAccessType.FILE_WRITE_ATTRIBUTES | DirectoryAccessType.FILE_WRITE_EA | DirectoryAccessType.DELETE | DirectoryAccessType.WRITE_OWNER | DirectoryAccessType.WRITE_DAC;

              AccessType AType = (AccessType)DAType;

              dacl.AddAce (new AceAccessDenied (sidUser, AType));

 

              secDesc.SetDacl(dacl);

              secDesc.SetFileSecurity(strSitePath, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION);

              bOk = true;

       } catch {

              bOk = false;

       }

       return bOk;

} /* CreateDir */


The AceFlags determine the level of inheritance on the object.

And the DirectoryAccessType is used to create a AccessType with some permissions not in the AccessType enum.

I hope this is useful.

Filed under:

Comments

# re: Setting NTFS Permissions with C#

Sunday, February 08, 2004 5:36 AM by Spike

thanks for the code ;-)

# re: Setting NTFS Permissions with C#

Monday, February 09, 2004 5:07 PM by Kit George

As a side note, we are looking at exposing ACLs directly in the base classes for the framewokr, in the future. Keep an eye out for Beta1, and feel free to ask the team any question directly, via the questions page at <a href="http://www.gotdotnet.com/team/clr/bcl/">The BCL WebPage</a>.

# re: Setting NTFS Permissions with C#

Thursday, February 26, 2004 12:09 AM by Aero

Thanks, this was just what I was looking for.
Doesn't look difficult after all.

# re: Setting NTFS Permissions with C#

Wednesday, March 17, 2004 11:19 AM by Tom Jones

There is no Microsoft.Win32.Security package

# re: Setting NTFS Permissions with C#

Wednesday, March 17, 2004 3:11 PM by David Cumps

If you would download the source you'd see what it is :)

The GotDotNet sample has that namespace for it's class.

# re: Setting NTFS Permissions with C#

Wednesday, March 17, 2004 3:35 PM by Tom Jones

... right, sorry/thanks.

# re: Setting NTFS Permissions with C#

Tuesday, March 23, 2004 7:49 AM by manish gupta

nice article,it quench my programming hurdel....

# re: Setting NTFS Permissions with C#

Wednesday, May 05, 2004 4:04 PM by srfonden

This was extremeley helpful, thanks!!!

# re: Setting NTFS Permissions with C#

Sunday, June 06, 2004 8:59 AM by Chris

This is the most straight forward code example I have yet seen on this topic, however I belive there is a rather BIG SECURITY FLAW! You simply take the existing DACL and use AddAce twice to implement the permissions you desire. This may not always work if a Deny ACE already exists further up the ACL. ACE order is very important and it must be assured that ACEs are in the following order
Explicit Deny
Explicit Allow
Inherited Deny from parent
Inherited Allow from parent
Inherited Deny from grandparent
Inherited Allow from grandparent
Inherited Deny from great grand-parent
Inherited Allow from great grandparent
and so on.
Since the ACL is traversed from top to bottom, if an Allow ACE precedes a Deny ACE and the Deny ACE is a subset of the Allow ACE then the subset of denied users will actually be allowed.

The code above should probably be fixed by calling Dacl.PrepareAcesForACL before calling SecurityDescriptor.SetDacl

Also, any existing ACE entries in the original ACL should be checked to ensure there aren't any duplicates. Of course one way of avoiding checking and being absolutely certain that only the access you have allowed is allowed is by throwing out the existing Dacl and creating a new one from scratch.

-Chris

# re: Setting NTFS Permissions with C#

Sunday, June 06, 2004 9:16 AM by David Cumps

Hey, first of all, tnx for the comment, I learned something from it.
Didn't knew something like PrepareAcesForACL existed.

Now, on to the comment:
I never thought about duplicates, as this code was more something made for one goal, where it would never happen, but now I know it can couse problems as well.

As for the PrepareAcesForACL, I checked out the source of the used dll and found the following pieces:

/// <summary>
/// This algorithm was copied from ATL source code: CAdcl::PrepareAcesForACL.
///
/// We can't use QuickSort (or any other n log (n)) generic sort algorithm
/// because we want partial ordering to be preserved. All we want to do is sort
/// the elements according to their "Order" (see OrderAceAccess.Compare method),
/// but we want the elements which compare to "Equal" to remain in their
/// original order in the array.
/// </summary>
protected override void PrepareAcesForACL()

And this method gets called by
private unsafe byte[] UnsafeGetNativeACL()

Which gets called by
internal byte[] GetNativeACL()

Which is used in
private static void UnsafeSetDacl(SecurityDescriptor secDesc, Dacl dacl, bool defaulted)

And finally used in
public void SetDacl(Dacl dacl)

So, I guess the security flaw is fixed by this? Each time you do a SetDacl it automatically PrepareAcesForACL.

Tell me if I'm wrong, don't want a security flaw in what I tell

# re: Setting NTFS Permissions with C#

Sunday, June 06, 2004 3:32 PM by Chris

I am terribly sorry, I had thought I reviewed the Win32Security dll code carefully, however I missed the call to PrepareAcesForACL() that ultimately gets indirectly called by the SetDacl function. I've been researching how to do this for some time including reading some security books on common mistakes. Most of my reading brought me right to the windows api level (advapi32) where the SetDacl function does not take care of ACE ordering for you. I guess I got a bit over zealous and jumped the gun, I believe you are correct, your orginal code should work well.

-Chris

# re: Setting NTFS Permissions with C#

Sunday, June 06, 2004 9:24 PM by Chris

Adding the following line should take care of any Ace issues.
dacl.RemoveAces(sidUser);

I have looked in the source for Win32Security and the funciton returns false if the Dacl is null, empty, or an Ace for the sid specified is not found.

# re: Setting NTFS Permissions with C#

Monday, June 07, 2004 4:11 PM by Silvia Brunet JOnes

Can you help me on a couple of lines I need to write. All I need is to remove access to everyone to a particular file and then set read and write accress to one particular user. Help help ehlps

# re: Setting NTFS Permissions with C#

Monday, June 07, 2004 4:16 PM by David Cumps

look at the above sample and first removeAces from them, and then AddAce your desired rights..

# re: Setting NTFS Permissions with C#

Tuesday, June 08, 2004 9:51 AM by Silvia Brunet Jones

How can I get a list of all the sid. is there are way to remove acces to all ?

# Some useful tools found during creating an installer for Kajima

Saturday, June 19, 2004 11:51 AM by TrackBack

# re: Setting NTFS Permissions with C# (urgent)

Saturday, June 19, 2004 5:36 PM by Sakda Chaiworawitkul

I've read your code. It was wonderful. I have added ASPNET user to a folder access allowed user. However, I follow your code to give it full-control right. I found it didn't do anything. Here is my code. What did I do wrong? Please let me know. Thank you.

Microsoft.Win32.Security.SecurityDescriptor secDesc =
Microsoft.Win32.Security.SecurityDescriptor.GetFileSecurity(strSitePath, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION);

Dacl dacl = secDesc.Dacl;

Sid sidUser = new Sid (username);

// allow: folder, subfolder and files

// modify

dacl.AddAce (new AceAccessAllowed (sidUser,
AccessType.GENERIC_WRITE | AccessType.GENERIC_READ | AccessType.DELETE | AccessType.GENERIC_EXECUTE , AceFlags.OBJECT_INHERIT_ACE | AceFlags.CONTAINER_INHERIT_ACE));



// allow: this folder

// write attribs

// write extended attribs

// delete

// change permissions

// take ownership

DirectoryAccessType DAType = DirectoryAccessType.FILE_WRITE_ATTRIBUTES | DirectoryAccessType.FILE_WRITE_EA | DirectoryAccessType.DELETE | DirectoryAccessType.WRITE_OWNER | DirectoryAccessType.WRITE_DAC | DirectoryAccessType.MAXIMUM_ALLOWED;

AccessType AType = (AccessType)DAType;

dacl.AddAce (new AceAccessAllowed (sidUser, AType));



secDesc.SetDacl(dacl);

secDesc.SetFileSecurity(strSitePath, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION);

# re: Setting NTFS Permissions with C#

Sunday, June 20, 2004 4:37 AM by David Cumps

My guess is that you need to use this:

Microsoft.Win32.Security.SecurityDescriptor secDesc =
Microsoft.Win32.Security.SecurityDescriptor.GetFileSecurity(strSitePath, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION);
Dacl dacl = secDesc.Dacl;
Sid sidUser = new Sid (username);

// allow: folder, subfolder and files
// full control
dacl.AddAce (new AceAccessAllowed (sidUser, AccessType.GENERIC_ALL | AccessType.STANDARD_RIGHTS_ALL , AceFlags.OBJECT_INHERIT_ACE | AceFlags.CONTAINER_INHERIT_ACE));

secDesc.SetDacl(dacl);
secDesc.SetFileSecurity(strSitePath, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION);

and don't forget to fill up username and strSitePath in your code :)

# re: Setting NTFS Permissions with C#

Wednesday, June 23, 2004 6:12 PM by Jeremy Nunn

I wrote a short app that creates folders for users in Active Directory, and assigns permissions to them using this library. I was curious if permissions could be set on a network share (since we programmatically create a share of these folders once they are created.)

By default, the share gives 'Everyone' full control, and I would like to modify this. Can this be done using this or some other library.

# re: Setting NTFS Permissions with C#

Thursday, June 24, 2004 5:25 AM by David Cumps

Hmm, I really don't have an idea how to do that, if anyone knows, please reply :p

# re: Setting NTFS Permissions with C#

Thursday, June 24, 2004 2:55 PM by Paul L

I used this library basically the same way you have, however, the containter inheritance does not seem to be working for me. I set the AceFlags to AceFlags.OBJECT_INHERIT_ACE | AceFlags.CONTAINER_INHERIT_ACE, as you do, but when I look at the properties of a subfolder, it does not show the user in the security tab. If I subsequently add another user to the same folder using Explorer, then the user I added with code magically appears.

Does this work for anyone else?

# re: Setting NTFS Permissions with C#

Wednesday, June 30, 2004 4:20 AM by marcus

Hi, thanks for the Code !!

But I got an issue setting the owner ship of an user. Anything that I am doin is add a line to your code:

secDesc.SetOwner(sidUser);

This does not work, I am new to ACLs and stuff like that, what am I doing wrong ?

:marcus

# re: Setting NTFS Permissions with C#

Thursday, July 22, 2004 4:27 PM by Salim

Hi, Thanks for the code.
i want to access effective permission of logged in User for file as well as AD Object.
This DAcl gives me splitted permission and i dont know how to calculate effective permission for logged in user. I think there must be something but i dont know what and where?
I would be great if you guys can help me.

Thanks a million in advance.

# re: Setting NTFS Permissions with C#

Friday, July 23, 2004 8:19 AM by David Cumps

You can loop over every sid in dacl and see if it applies to user, and then I think you can use the following method to extract the NTFS permissions out of the sid:

http://weblogs.asp.net/cumpsd/archive/2004/06/28/168112.aspx

# re: Setting NTFS Permissions with C#

Thursday, July 29, 2004 8:07 AM by Rin

I gone through your code. It was wonderful. I have added ASPNET user to my application folder access allowed user. I added your code to give it full-control. when i open the folder security settings its showing full control but my application is not working, once i open the application folder again i set ASPNET user permission to full control then its working fine. Pls suggest me What did I do wrong?

this is my Code

// strSitePath : Application Folder
// strUserName : ASPNET

SecurityDescriptor secDesc = SecurityDescriptor.GetFileSecurity(strSitePath, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION);

Dacl dacl = secDesc.Dacl;

Sid sidUser = new Sid (strUserName);
dacl.AddAce (new AceAccessAllowed (sidUser, AccessType.GENERIC_WRITE | AccessType.GENERIC_READ | AccessType.DELETE | AccessType.GENERIC_EXECUTE , AceFlags.OBJECT_INHERIT_ACE | AceFlags.CONTAINER_INHERIT_ACE));
secDesc.SetDacl(dacl);
secDesc.SetFileSecurity(strSitePath, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION);



Rin

# re: Setting NTFS Permissions with C#

Thursday, July 29, 2004 8:30 AM by David Cumps

The full control checkbox is checked? Hmm, i don't really know what could be the problem then, sorry.

# re: Setting NTFS Permissions with C#

Thursday, July 29, 2004 10:31 AM by Rin

Hi Cumps
nice to meet you

yes its checked but i am unable to get the files from sub folders




Rin

# re: Setting NTFS Permissions with C#

Thursday, July 29, 2004 12:43 PM by Rin

Hi Cumps

with your code only root directory getting the Full control permission.
How to get the permissions to sub folders of that root directory.





Rin

# re: Setting NTFS Permissions with C#

Thursday, July 29, 2004 1:55 PM by David Cumps

Normally that gets passed because of the "AceFlags.OBJECT_INHERIT_ACE | AceFlags.CONTAINER_INHERIT_ACE", but since you have them set I don't really know what's happening

# re: copying NTFS Permissions with C#

Friday, July 30, 2004 10:37 AM by MVB

I have a question
..
I am copying some files from one folder to another.
I want to copy the NTFS permissions of the files too
Any Idea on how to do that???

Thanks
MVB

# re: Setting NTFS Permissions with C#

Friday, July 30, 2004 11:09 AM by David Cumps

Simple way? xcopy /o (/O : Copies file ownership and ACL information.)

Hard way? Try fo find if File.Copy somehow supports keeping NTFS settings, if not, File.Copy the files over and then use this library to read the rights from the source and apply them to the destination

string sourceFile = @"C:\bla\blaat.doc";
strinc destinationFile = @"C:\somehwere\blaat.doc";

SecurityDescriptor secDescS = SecurityDescriptor.GetFileSecurity(sourceFile, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION);
Dacl dacl = secDescS.Dacl;

SecurityDescriptor secDescD = SecurityDescriptor.GetFileSecurity(destinationFile , SECURITY_INFORMATION.DACL_SECURITY_INFORMATION);
secDescD.SetDacl(dacl);
secDescD.SetFileSecurity(destinationFile , SECURITY_INFORMATION.DACL_SECURITY_INFORMATION);

---
I'm not sure if this way works, if it does, it's shorter:

SecurityDescriptor secDesc = SecurityDescriptor.GetFileSecurity(sourceFile, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION);
secDesc.SetFileSecurity(destinationFile , SECURITY_INFORMATION.DACL_SECURITY_INFORMATION);

# re: Setting NTFS Permissions with C#

Saturday, July 31, 2004 10:40 AM by Rin

Hi Cumps
This is Rin

using your code can you tested the permissions for the Root directory and sub directories of that root directory?

can you have any idea or code for that Pls do favour.


Thanks
~Rin.

# re: Setting NTFS Permissions with C#

Sunday, August 01, 2004 9:20 AM by David Cumps

Right, First, there is NO way this line gives full control:

dacl.AddAce (new AceAccessAllowed (sidUser, AccessType.GENERIC_WRITE | AccessType.GENERIC_READ | AccessType.DELETE | AccessType.GENERIC_EXECUTE , AceFlags.OBJECT_INHERIT_ACE | AceFlags.CONTAINER_INHERIT_ACE));

This Gives 'Modifiy' rights, nothing more, nothing less.

This on the other hand will give you Full:

dacl.AddAce (new AceAccessAllowed (sidUser, AccessType.GENERIC_ALL , AceFlags.OBJECT_INHERIT_ACE | AceFlags.CONTAINER_INHERIT_ACE));

So replace your line by mine and try again.

# Setting NFTS Permissions with C#

Monday, December 13, 2004 5:43 AM by TrackBack

# c#中如何设置文件夹权限和在安全中添加用户

Sunday, January 30, 2005 11:22 PM by TrackBack

Ping Back来自:blog.csdn.net

# re: Setting NTFS Permissions with C#

Thursday, January 04, 2007 5:57 AM by Mr ChriZ

Awesome Cheers David, worked like a charm.

It would be nice to see a codeproject article on this.

# re: Setting NTFS Permissions with C#

Thursday, January 04, 2007 7:02 AM by CumpsD

It's better to switch to .NET 2.0 which has built in classes now to set NTFS permissions :)

# re: Setting NTFS Permissions with C#

Wednesday, February 14, 2007 10:46 AM by Mato

A have a question how to set a permission on a local printer.

I have tried with:

  GetSecurityInfo(ptrPrinter, SE_OBJECT_TYPE.SE_PRINTER, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION)

and I get info about DACL and ACE-s, that added new ACE

and when I tried to save all the thing with

  SetSecurityInfo(ptrPrinter, SE_OBJECT_TYPE.SE_PRINTER, SECURITY_INFORMATION.UNPROTECTED_DACL_SECURITY_INFORMATION);

I got an error : Object reference not set to an instance of an object.

What have I done wrong.

Help me please,

Mato

# re: Setting NTFS Permissions with C#

Thursday, February 15, 2007 5:16 PM by CumpsD

Have you checked the NTFS possibilities of .NET 2.0 already? I don't have an answer for your question, sorry.

# re: Setting NTFS Permissions with C#

Wednesday, March 07, 2007 2:03 AM by zenkill

thanks for your codes.

but i hava one question.

how can i  show the user in the sharing tab's Pemission?not only in the security tab?

Thanks

# re: Setting NTFS Permissions with C#

Tuesday, May 08, 2007 12:22 PM by Peter Jacobs

Thanks for the code!

# re: Setting NTFS Permissions with C#

Thursday, May 10, 2007 1:31 PM by Alex

Hi,

I have used your code to set "mofify permissions" to a folder for a specific user.

Everything works great except permission of child folders and files. Even thought they have "allow inheritable permissions..." check they dont seem to inherit that user.

Any idea what may i am doing wrong?

Thanks

# re: Setting NTFS Permissions with C#

Wednesday, July 04, 2007 6:57 AM by Harry

.Net Framework 2.0 example

------------------------------------

using System.Security.AccessControl;

DirectoryInfo di = new DirectoryInfo(path);

               DirectorySecurity dSecurity = di.GetAccessControl();

               FileSystemAccessRule rule = new FileSystemAccessRule("users", FileSystemRights.Modify , InheritanceFlags.None | InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, ControlType);

               dSecurity.SetAccessRule(rule);

               di.SetAccessControl(dSecurity);

# re: Setting NTFS Permissions with C#

Thursday, July 05, 2007 5:13 AM by Harry

How can i remove inheritance for a directory ?

Harry

# re: Setting NTFS Permissions with C#

Monday, July 30, 2007 6:56 PM by Branden

I'm having the same problem as Alex. The permissions, although the flags seem to be set correctly are not being inherited by any child objects. I have set the original permissions for the container to allow everyone on my domain full control on that folder.

Also, can anyone suggest how to get the SID for a security group instead of just a user? I tried <domain>\<group> but that causes an error.

# re: Setting NTFS Permissions with C#

Sunday, August 26, 2007 5:40 PM by Josh

thanks! Works great!

# re: Setting NTFS Permissions with C#

Thursday, October 18, 2007 11:08 AM by Ralf

How can i remove inheritance for a file kill all rules and add a special user with rights ?

# re: Setting NTFS Permissions with C#

Wednesday, October 31, 2007 3:04 PM by Sanjay

Branden,

You can use Sid constructor to provide domain along with userid while creating AceAccessAllowed, as shown below:

acl.AddAce(new AceAccessAllowed(new Sid(userId, domain), AccessType.GENERIC_ALL, AceFlags.OBJECT_INHERIT_ACE | AceFlags.CONTAINER_INHERIT_ACE));

# re: Setting NTFS Permissions with C#

Wednesday, October 31, 2007 3:17 PM by Sanjay

Alex,

Got any solution for the permission inheritance? I observed additional symptom while changing registry key permissions - when you right click the subkey of the modified key, you receive a message "The permissions on <xxx> are incorrectly ordered". I came across this KB article:

For Win XP: support.microsoft.com/.../899182

For Win 2000: support.microsoft.com/default.aspx

I observe same behavior in Vista also.

As explained by David, we already have ACE sorting logic in place in PrepareAcesForACL. I am not sure, if these MS KB article is admitting the problem with the OS itself or some ACE sorting logic flaws in their tools referred in the article like Sysprep.exe and Subinacl.exe.

# Setting NTFS Permissions with C#[

Wednesday, October 31, 2007 10:10 PM by wswang

Setting NTFS Permissions with C#[

# re: Setting NTFS Permissions with C#

Thursday, November 01, 2007 9:03 AM by Sanjay

Inheritance and all other things works fine with .Net 2.0, I am yet to sortout issue with 1.1, through GotDotNet sample.

# run an exe on access of folder | answers hiwav

Monday, October 04, 2010 3:47 AM by run an exe on access of folder | answers hiwav

Pingback from  run an exe on access of folder | answers hiwav

# programatically removing ???Include inheritable permissions from this object&#8217;s parent??? checkbox using C# - Programmers Goodies

Pingback from  programatically removing ???Include inheritable permissions from this object&#8217;s parent??? checkbox using C# - Programmers Goodies

# how to set folder ACLs from C# - Programmers Goodies

Thursday, October 20, 2011 2:20 AM by how to set folder ACLs from C# - Programmers Goodies

Pingback from  how to set folder ACLs from C# - Programmers Goodies

# ??????????????????????????????????????? &#8211; .NET?????? / ASP.NET | ???????????????

Pingback from  ??????????????????????????????????????? &#8211; .NET?????? / ASP.NET | ???????????????