Link to home
Start Free TrialLog in
Avatar of tosmserversupport
tosmserversupport

asked on

How to remove/modify an inherited permission.

Hi all,

I am working on implementing a automated file creation system.

the program does the following:
1. creates a folder in a fileshare with a user's username (jdoe for John Doe accessed via \\server\share\jdoe\).
2. the user is given modify rights to the folder, subfolder, and files.
3. a subfolder that will hold web content is created under the user's folder.
4. specific file permissions are set on this folder
     a. The user is not able to delete the web content folder
     b. the user is not able to delete a subfolder if files are in the subfolder
     c. aside from these permissions the user has modified "modify" access.

I have figured out and coded how to do everything above but i am still running into a problem. the webfolder i create is inheriting modify permissions. meaning that the special permissions i create are being overwritten by the inheritied permission.  

The folder needs all other inherited permissions (admins have full control, etc...) but i need to modify or remove the users inherited permissions. Is this possible in C#?

I can run a search and find the inherited permission but cannot remove or modify it because it is inherited. Am i missing a function to remove the inherited status of a permission?

I will attach a code snippet showing the permission creation thus far.

Thank you
using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Text;
 
namespace pwp_migration_script
{
    class Program
    {
        /* --Inheritance and propagation flags for folder permissions-- */
        static InheritanceFlags IFlag_ThisFolderSubfoldersAndFiles = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;
        static PropagationFlags PFlag_ThisFolderSubfoldersAndFiles = PropagationFlags.None;
 
        static InheritanceFlags IFlag_SubfodlersAndFiles = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;
        static PropagationFlags PFlag_SubfoldersAndFiles = PropagationFlags.InheritOnly;
 
        static InheritanceFlags IFlag_ThisFolderAndSubfolders = InheritanceFlags.ContainerInherit;
        static PropagationFlags PFlag_ThisFolderAndSubfolders = PropagationFlags.None;
 
        static InheritanceFlags IFlag_SubfoldersOnly = InheritanceFlags.ContainerInherit;
        static PropagationFlags PFlag_SubfoldersOnly = PropagationFlags.InheritOnly;
 
        static InheritanceFlags IFlag_ThisFolderAndFiles = InheritanceFlags.ObjectInherit;
        static PropagationFlags PFlag_ThisFolderAndFiles = PropagationFlags.None;
 
        static InheritanceFlags IFlag_ThisFolderOnly = InheritanceFlags.None;
        static PropagationFlags PFlag_ThisFolderOnly = PropagationFlags.None;
 
        static InheritanceFlags IFlag_FilesOnly = InheritanceFlags.ObjectInherit;
        static PropagationFlags PFlag_FilesOnly = PropagationFlags.InheritOnly;
        /* ---- */
 
        /* --Access Masks for Folder Permissions-- */
        /* --Access masks are created using a bit mask - 32 bytes are used to set permissions on win32 Objects--*/
        /* --For file and folder permissions only the first 20 are used to set advanced permissions -- */
        /* ---- */
        /* --0: Read data / list directory-- */
        /* --1: Write data / Add file-- */
        /* --2: Append data / Add subdirectory-- */
        /* --3: Read Ext. Attrib.-- */
        /* --4: Write Ext. Attrib.-- */
        /* --5: Execute file / Travese directory-- */
        /* --6: Delete Child Objects-- */
        /* --7: Read Attributes-- */
        /* --8: Write Attributes-- */
        /* --9-15: Unused - will ALWAYS be 0 -- */
        /* --16: Delete-- */
        /* --17: Read perms -- */
        /* --18: Write Perms-- */
        /* --19: Change Owner-- */
        /* --20: Synchronize-- */
        /* ---- */
        /* --So if you wanted to give a user full control you would enter a 1 in each bit (except for position 9-15 whish will ALWAYS be 0)-- */
        /* --|----------------------------------------------------------------|-- */
        /* --| 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 |-- */
        /* --| -------------------------------------------------------------- |-- */
        /* --| 1  1  1  1  1  0  0  0  0  0  0  0  1  1  1  1  1  1  1  1  1  |-- */
        /* --|----------------------------------------------------------------|-- */
        /* ---- */
        /* --Now that you have a bit mask take this binary number and convert it to hex to make it shorter-- */
        /* --1 1111 0000 0001 1111 1111 in binary is 1F 01FF in hex so this is the access mask to give a user full control.-- */
        /* --Use this to create any needed access masks.-- */
        /* ---- */
        static FileSystemRights AccessMask_IUSR_ThisFolderSubFolderAndFiles = (FileSystemRights)0x200A9;
        static FileSystemRights AccessMask_User_ThisFolderOnly = (FileSystemRights)0x200AF;
        static FileSystemRights AccessMask_User_SubfoldersOnly = (FileSystemRights)0x301BF;
        static FileSystemRights AccessMask_User_FilesOnly = (FileSystemRights)0x3019F;
        /* ---- */
 
        static void CreateMyPublicWeb(string path, string username)
        {
            
            string iusr = "IUSR_mypublicweb";
            SecurityIdentifier IUSRsid = getSidByUserName(iusr);
            SecurityIdentifier UserSid = getSidByUserName(username);
 
            if (!Directory.Exists(path + "\\mypublicweb"))
            {
 
 
                DirectoryInfo newDir = Directory.CreateDirectory(path + "\\mypublicweb");
                DirectorySecurity dSec = newDir.GetAccessControl();
 
                dSec.AddAccessRule(new FileSystemAccessRule(IUSRsid, AccessMask_IUSR_ThisFolderSubFolderAndFiles, IFlag_ThisFolderSubfoldersAndFiles,PFlag_ThisFolderSubfoldersAndFiles, AccessControlType.Allow));
                dSec.AddAccessRule(new FileSystemAccessRule(UserSid, AccessMask_User_ThisFolderOnly, IFlag_ThisFolderOnly, PFlag_ThisFolderOnly,AccessControlType.Allow));
                dSec.AddAccessRule(new FileSystemAccessRule(UserSid, AccessMask_User_SubfoldersOnly, IFlag_SubfoldersOnly, PFlag_SubfoldersOnly, AccessControlType.Allow));
                dSec.AddAccessRule(new FileSystemAccessRule(UserSid, AccessMask_User_FilesOnly, IFlag_FilesOnly, PFlag_FilesOnly, AccessControlType.Allow));
                newDir.SetAccessControl(dSec);
 
                Console.WriteLine("Webfolder Created.");
            }
        }
 
        static SecurityIdentifier getSidByUserName(string user)
        {
            DirectoryEntry ad = new DirectoryEntry("LDAP://DOMAIN/blah");
            DirectorySearcher search = new DirectorySearcher(ad);
            search.Filter = "(&(objectCategory=person)(sAMAccountName=" + user + "))";
            SearchResultCollection result = search.FindAll();
            if (result.Count != 1)
            {
                Console.WriteLine("Invalid Username");
                return null;
            }
            else
            {
                return  new SecurityIdentifier((byte[])result[0].Properties["objectSid"][0], 0);
            }
        }
    }
}

Open in new window

SOLUTION
Avatar of graye
graye
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of tosmserversupport
tosmserversupport

ASKER

Sorry it took me so long to get back with you. I did some research and found that there is a function that allows you to remove inherited permissions and copy them.

it is called SetAccessRuleProtection(bool isProtected, bool PreserveInheritience)

the first boolean sets whether to inherit parent objects (false to inherit, true to notinherit)
the second tells whether to copy the variables to the ACL (true to copy, false to not copy)

so to turn off inheritence and copy the inherited permissions to the object call the function with both arguments as true. As soon as inheritence is turned off you can remove a user from the acl using the DirectorySecurity.PurgeAccessRules(IdentityReference sid) commmand.

Thank you again for the help.

In case anyone else has problems similar to mine i am going to attatch my code. The code might look a little jumbled since i put several different functions into one to make it easier for everyone to see what i am doing.
static void CreateMyPublicWeb(string path, string username)
        {
            
            string user = "mypublicweb";
            SecurityIdentifier sid = getSidByUserName(user);
            SecurityIdentifier eRaiderSid = getSidByUserName(username);
 
            if (!Directory.Exists(path + "\\mypublicweb"))
            {
                DirectoryInfo di = Directory.CreateDirectory(path + "\\mypublicweb");
                DirectorySecurity dSec = di.GetAccessControl();
                //below command turns off inheritence and copies inherited aces to the object.
                dSec.SetAccessRuleProtection(true, true);
                di.SetAccessControl(dSec);
            }
            else
            {
                DirectoryInfo di = new DirectoryInfo(path + "\\mypublicweb");
                DirectorySecurity dSec = di.GetAccessControl();
                dSec.SetAccessRuleProtection(true, true);
                di.SetAccessControl(dSec);
            }
            
            DirectoryInfo dinfo = new DirectoryInfo(path + "\\mypublicweb");
            DirectorySecurity dSecurity = dinfo.GetAccessControl();
 
            //this loop looks for permissions i want to reset/create.
            foreach (FileSystemAccessRule ace in dSecurity.GetAccessRules(true,true,typeof(SecurityIdentifier)))
            {
                if (ace.IdentityReference == eRaiderSid || ace.IdentityReference == sid)
                {
                    //if it finds an ace with the sid i want to create/reset i remove all aces for that user.
                    dSecurity.PurgeAccessRules(ace.IdentityReference);
                    dinfo.SetAccessControl(dSecurity);
                }
            }
            //create/reset the permissions. 
            dSecurity.AddAccessRule(new FileSystemAccessRule(sid, AccessMask_IUSR_ThisFolderSubFolderAndFiles, IFlag_ThisFolderSubfoldersAndFiles, PFlag_ThisFolderSubfoldersAndFiles, AccessControlType.Allow));
            dSecurity.AddAccessRule(new FileSystemAccessRule(eRaiderSid, AccessMask_User_ThisFolderOnly, IFlag_ThisFolderOnly, PFlag_ThisFolderOnly, AccessControlType.Allow));
            dSecurity.AddAccessRule(new FileSystemAccessRule(eRaiderSid, AccessMask_User_SubfoldersOnly, IFlag_SubfoldersOnly, PFlag_SubfoldersOnly, AccessControlType.Allow));
            dSecurity.AddAccessRule(new FileSystemAccessRule(eRaiderSid, AccessMask_User_FilesOnly, IFlag_FilesOnly, PFlag_FilesOnly, AccessControlType.Allow));
            dinfo.SetAccessControl(dSecurity);

Open in new window

graye was able to help me down the right path to finding what i needed. thanks graye :)