Setting NTFS Permissions with C#

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.

32 Comments

  • thanks for the code ;-)

  • Thanks, this was just what I was looking for.

    Doesn't look difficult after all.

  • There is no Microsoft.Win32.Security package

  • ... right, sorry/thanks.

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

  • This was extremeley helpful, thanks!!!

  • 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



  • 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

  • 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.



  • 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

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

  • 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.

  • 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?

  • 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

  • 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.

  • 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

  • Hi Cumps

    nice to meet you



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









    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

  • 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

  • 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.

  • Awesome Cheers David, worked like a charm.
    It would be nice to see a codeproject article on this.

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

  • 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

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

  • 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

  • Thanks for the code!

  • 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

  • How can i remove inheritance for a directory ?

    Harry

  • thanks! Works great!

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

  • 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));

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

Comments have been disabled for this content.