Is there an analog of the SetFileSecurity function?
I need to re-write some tests from Python and I'm stuck on this part. In Python I can freely edit a DACL with pywin32 (modules with a C++ implementation to work with Windows API).
I can edit any ACE with win32security.
Change owner to Everyone? Okay.
win32security.SetNamedSecurityInfo("somefile.txt", win32security.SE_FILE_OBJECT,
win32security.OWNER_SECURITY_INFORMATION,
win32security.ConvertStringSidToSid("S-1-1-0"))
sd.SetSecurityDescriptorDacl(1, dacl, 0)
win32security.SetFileSecurity(filename, win32security.DACL_SECURITY_INFORMATION, sd)
Remove an inherited ACE? Easy.
sd = win32security.GetFileSecurity("", win32security.DACL_SECURITY_INFORMATION)
dacl = SECURITY_DESCRIPTOR.GetSecurityDescriptorDacl()
dacl.DeleteAce(0)
sd.SetSecurityDescriptorDacl(1, dacl, 0) # may not be necessary
win32security.SetFileSecurity(filename, win32security.DACL_SECURITY_INFORMATION, sd)
And all of those without some special permissions.
But if I want to do something like this in C#. One way I found is changing a security descriptor with pure SDDL, but using System.Security.File.SetAccessControl() with FileSecurity doesn't work if SetSecurityDescriptorSddlForm was called without the SeSecurityPrivilege privilege. Also, even using an administrator token with nearly all privileges, if I want to change something in a "wrong" way (delete some inherited ACEs), the security descriptor doesn't apply. If I try to do something "very wrong", like set the owner to Everyone, an exception will be thrown.
var sddl_everyone_owner = @"O:S-1-1-0G:DUD:P";
var path = @"C:\Users\someuser\test.txt";
FileSecurity fs_edit = new FileSecurity();
fs_edit.SetSecurityDescriptorSddlForm(sddl_everyone_owner);
File.SetAccessControl(path, fs_edit);
Run with administrator token:
Unhandled Exception: System.InvalidOperationException: The security identifier is not
allowed to be the owner of this object.
at System.Security.AccessControl.NativeObjectSecurity.Persist(String name, SafeHandle
handle,
AccessControlSections includeSections, Object exceptionContext)
at System.Security.AccessControl.NativeObjectSecurity.Persist(String name,
AccessControlSections includeSections, Object exceptionContext)
at System.Security.AccessControl.NativeObjectSecurity.Persist(String name,
AccessControlSections includeSections)
at System.Security.AccessControl.FileSystemSecurity.Persist(String fullPath)
at System.IO.File.SetAccessControl(String path, FileSecurity fileSecurity)
at rtest.Program.Main(String[] args) in C:\somepath\Program.cs:line 52
After 11 hours of googling, then trying to write some woking code i have this:
This code import functions from Advapi32.dll right to C# code. Special thanks to PInvoke.net! Added this code to code samples.