Removing all ACLs from a file and starting over
-
Sunday, July 05, 2009 9:58 PM
Using CACLS, I can simply replace all existing permissions on a file with new permissions. I'm trying to do the same thing in a .Net app. I most recently tried the code below with no success. I have tried various forms of the code where I am casting to a FileSystemAccessRule but nothing I tried worked.
Has anyone successfully done something similar? Any ideas appreciated.
class Program { static void Main(string[] args) { SetWorkingACL(@"C:\Users\Public\Desktop\PublicTestMusic\Folder.jpg"); } private static void SetWorkingACL(string folderImage) { FileSecurity fs = File.GetAccessControl(folderImage); AuthorizationRuleCollection rules = fs.GetAccessRules(true, true, typeof(NTAccount)); foreach (AuthorizationRule rule in rules) { if (rule is AccessRule) { fs.RemoveAccessRule((FileSystemAccessRule)rule); } } fs.AddAccessRule(new FileSystemAccessRule(@"Administrators", FileSystemRights.FullControl, AccessControlType.Allow)); fs.AddAccessRule(new FileSystemAccessRule(@"Users", FileSystemRights.ReadAndExecute, AccessControlType.Allow)); File.SetAccessControl(folderImage, fs); } }- Edited by Dale At Work Sunday, July 05, 2009 10:31 PM
Answers
-
Friday, July 10, 2009 3:40 AMModerator
Yes, you're right, we are not supposed to remove the inherited permissions (not just in .NET).
The approach to workaround is to add deny access rules to override the inherited allow rules counterpart.
For example, I have a file with 3 inherited permissions:
Administrators-- FullControl
System-- FullControl
Users-- ReadAndExecute
As I want "Administrators" and "Users" remain unchanged, I just need to deny "System"'s FullControl like this:
private static void SetWorkingACL(string folderImage) { FileSecurity fs = File.GetAccessControl(folderImage); AuthorizationRuleCollection rules = fs.GetAccessRules(true, true, typeof(NTAccount)); foreach (AuthorizationRule rule in rules) { if (rule is FileSystemAccessRule) { fs.RemoveAccessRule((FileSystemAccessRule)rule); } } //Remain unchanged //fs.AddAccessRule(new FileSystemAccessRule(@"Administrators", FileSystemRights.FullControl, AccessControlType.Deny)); //fs.AddAccessRule(new FileSystemAccessRule(@"Users", FileSystemRights.ReadAndExecute, AccessControlType.Deny)); fs.AddAccessRule(new FileSystemAccessRule(@"System", FileSystemRights.FullControl, AccessControlType.Deny)); File.SetAccessControl(folderImage, fs); }
Thanks.
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com- Edited by Figo FeiModerator Friday, July 10, 2009 3:52 AM
- Marked As Answer by Figo FeiModerator Monday, July 13, 2009 11:05 AM
-
Friday, July 10, 2009 6:49 PM
First you need to call SetAccessRuleProtection method to remove inherited permissions, then add your new permissions. Following code snippet worked successfully.
FileSecurity fs = File.GetAccessControl(folderImage);
AuthorizationRuleCollection rules = fs.GetAccessRules(true, true, typeof(NTAccount));
fs.SetAccessRuleProtection(
true, false);
//passing true for first parameter protects the new permission from inheritance, and second parameter removes the existing inherited permissions
fs.AddAccessRule(
new FileSystemAccessRule(@"Administrators", FileSystemRights.FullControl, AccessControlType.Allow));
fs.AddAccessRule(
new FileSystemAccessRule(@"Users", FileSystemRights.ReadAndExecute, AccessControlType.Allow));
File.SetAccessControl(folderImage, fs);
- Proposed As Answer by ssaranv Friday, July 10, 2009 7:38 PM
- Marked As Answer by Dale At Work Saturday, July 11, 2009 4:15 AM
All Replies
-
Sunday, July 05, 2009 10:02 PM
Just FYI, I also tried another version where I created a new instance of the FileSecurity object, thinking that would eliminate all the existing permissions. It didn't change a thing when I was done.
FileSecurity fs = new FileSecurity(); fs.AddAccessRule(new FileSystemAccessRule(@"Administrators", FileSystemRights.FullControl, AccessControlType.Allow)); fs.AddAccessRule(new FileSystemAccessRule(@"Users", FileSystemRights.ReadAndExecute, AccessControlType.Allow)); File.SetAccessControl(folderImage, fs); -
Thursday, July 09, 2009 9:56 AMModerator
So the code is going to grant the permission of the picture to the account, right?
Please check out the ACL of the file, is there any deny policy applied to it?
Deny permission will over-look allow ones, so we need to remove those "denies" in order to access the file.
Such as:
FileSecurity fSecurity = System.IO.File.GetAccessControl(@"E:\acltest.txt"); //Remove write deny policy as follows fSecurity.RemoveAccessRule(new FileSystemAccessRule(@"Administrators", FileSystemRights.Write, AccessControlType.Deny)); File.SetAccessControl(@"E:\acltest.txt", fSecurity);Hope it helps.
Thanks.
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com- Edited by Figo FeiModerator Thursday, July 09, 2009 9:58 AM
-
Friday, July 10, 2009 1:20 AMI see when I read my original post that I wasn't really clear. My goal is to remove all access except the two permissions in my sample. The end result I want is for Administrators to have full control and Users to have read only. No other permissions should exist. The problem is, when I run the code in my sample, no changes are made to the permissions on the file. I can still see the inherited permissions in Windows Explorer and in the FileSecurity object in code.
Any ideas?
Thanks.
Dale -
Friday, July 10, 2009 2:57 AMA little more that I determined. If I use the code in the original post to grant access to an account that does not have inherited access, the code works - at least for adding the access. If the account already has inherited access then no change is made to the account's permissions on the file.
When I add an account in this way, then the call to RemoveAccessRule works to remove the access.
It appears right now that the only thing that doesn't work is removing inherited permissions.
How can I remove inherited permissions in .Net?
Thanks. -
Friday, July 10, 2009 3:40 AMModerator
Yes, you're right, we are not supposed to remove the inherited permissions (not just in .NET).
The approach to workaround is to add deny access rules to override the inherited allow rules counterpart.
For example, I have a file with 3 inherited permissions:
Administrators-- FullControl
System-- FullControl
Users-- ReadAndExecute
As I want "Administrators" and "Users" remain unchanged, I just need to deny "System"'s FullControl like this:
private static void SetWorkingACL(string folderImage) { FileSecurity fs = File.GetAccessControl(folderImage); AuthorizationRuleCollection rules = fs.GetAccessRules(true, true, typeof(NTAccount)); foreach (AuthorizationRule rule in rules) { if (rule is FileSystemAccessRule) { fs.RemoveAccessRule((FileSystemAccessRule)rule); } } //Remain unchanged //fs.AddAccessRule(new FileSystemAccessRule(@"Administrators", FileSystemRights.FullControl, AccessControlType.Deny)); //fs.AddAccessRule(new FileSystemAccessRule(@"Users", FileSystemRights.ReadAndExecute, AccessControlType.Deny)); fs.AddAccessRule(new FileSystemAccessRule(@"System", FileSystemRights.FullControl, AccessControlType.Deny)); File.SetAccessControl(folderImage, fs); }
Thanks.
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
Send us any feedback you have about the help from MSFT at fbmsdn@microsoft.com- Edited by Figo FeiModerator Friday, July 10, 2009 3:52 AM
- Marked As Answer by Figo FeiModerator Monday, July 13, 2009 11:05 AM
-
Friday, July 10, 2009 6:49 PM
First you need to call SetAccessRuleProtection method to remove inherited permissions, then add your new permissions. Following code snippet worked successfully.
FileSecurity fs = File.GetAccessControl(folderImage);
AuthorizationRuleCollection rules = fs.GetAccessRules(true, true, typeof(NTAccount));
fs.SetAccessRuleProtection(
true, false);
//passing true for first parameter protects the new permission from inheritance, and second parameter removes the existing inherited permissions
fs.AddAccessRule(
new FileSystemAccessRule(@"Administrators", FileSystemRights.FullControl, AccessControlType.Allow));
fs.AddAccessRule(
new FileSystemAccessRule(@"Users", FileSystemRights.ReadAndExecute, AccessControlType.Allow));
File.SetAccessControl(folderImage, fs);
- Proposed As Answer by ssaranv Friday, July 10, 2009 7:38 PM
- Marked As Answer by Dale At Work Saturday, July 11, 2009 4:15 AM
-
Saturday, July 11, 2009 4:25 AM
That was the solution I was looking for; it works perfectly. Of course I had to include my loop along with your solution. That way any other unexpected and explicit permissions are removed, leaving me with exactly what I want. Thanks for your help, srimathi and Figo.
FileSecurity fs = File.GetAccessControl(folderImage); fs.SetAccessRuleProtection(true, false); AuthorizationRuleCollection rules = fs.GetAccessRules(true, true, typeof(NTAccount)); foreach (AuthorizationRule rule in rules) { if (rule is AccessRule) { fs.RemoveAccessRule((FileSystemAccessRule)rule); } } fs.AddAccessRule(new FileSystemAccessRule(@"ServerAdmin", FileSystemRights.FullControl, AccessControlType.Allow)); fs.AddAccessRule(new FileSystemAccessRule(@"Users", FileSystemRights.ReadAndExecute, AccessControlType.Allow)); File.SetAccessControl(folderImage, fs);

