I need to remove certain accounts (like the "Everyone" trustee or some global group that is giving everyone access to a folder) from an ACL on a particular subfolder of a share. I get a DirectorySecurity
object, get and loop through the AuthorizationRuleCollection
, remove the AccessRule
in question from the ACL, and then I call SetAccessControl
to apply the changes. Everything works fine if the target folder is small, but if it has a lot of child folders and files, it can take forever to apply the changes (much longer than to just do it manually). I only want to deal with the ACL on the target folder. Is there a way to do this using the .NET DirectorySecurity
classes? Or do I have to resort to the Win32 API or some other solution?
Here is a snippet of code. The call to dirInfo.SetAccessControl(dirSec)
is where it hangs when the folder size is very large.
DirectoryInfo dirInfo = new DirectoryInfo(path);
DirectorySecurity dirSec = dirInfo.GetAccessControl();
AuthorizationRuleCollection acl = dirSec.GetAccessRules(true, true,
typeof(System.Security.Principal.NTAccount));
foreach (FileSystemAccessRule ace in acl)
{
if (groupsToRemove.Contains(ace.IdentityReference.Value))
{
dirSec.RemoveAccessRuleSpecific(ace);
dirInfo.SetAccessControl(dirSec);
}
}
In your code, you are applying the updates to the ACL every interation of your loop, this gets very expensive. Have you tried moving
dirInfo.SetAccessControl(dirSec);
outside theforeach
? This should invoke theSetAccessControl
method on yourDirectoryInfo
object once, applying all the changes in one pass, like this: