Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C#中编辑DACL?_C#_Windows_Windows Security_Dacl_System.security - Fatal编程技术网

如何在C#中编辑DACL?

如何在C#中编辑DACL?,c#,windows,windows-security,dacl,system.security,C#,Windows,Windows Security,Dacl,System.security,是否有一个模拟的 我需要从Python中重新编写一些测试,我被困在这一部分。在Python中,我可以自由编辑DACL,使用代码< pyy32 32 >代码>(带有C++实现的模块,用于Windows API)。 我可以使用win32security编辑任何ACE 将所有者更改为“所有人”?好的 win32security.SetNamedSecurityInfo("somefile.txt", win32security.SE_FILE_OBJECT,

是否有一个模拟的

我需要从Python中重新编写一些测试,我被困在这一部分。在Python中,我可以自由编辑DACL,使用代码< pyy32 32 >代码>(带有C++实现的模块,用于Windows API)。 我可以使用
win32security
编辑任何ACE

将所有者更改为“所有人”?好的

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)
删除继承的ACE?简单

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)
以及所有那些没有特殊权限的人

但如果我想在C#中做类似的事情。我发现的一种方法是使用纯SDDL更改安全描述符,但如果在没有
SeSecurityPrivilege
权限的情况下调用
setsecuritydescriptorsdlform
则使用
System.security.File.SetAccessControl()
FileSecurity
不起作用。此外,即使使用具有几乎所有权限的管理员令牌,如果我想以“错误”的方式更改某些内容(删除一些继承的ACE),安全描述符也不适用。如果我试图做一些“非常错误”的事情,比如将所有者设置为
Everyone
,就会抛出异常

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);
使用管理员令牌运行:

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

在谷歌搜索了11个小时,然后试图编写一些令人惊叹的代码后,我发现:

// changes SDDL of file:
using System;
using System.Runtime.InteropServices; // DllImport

public class SomeClass
{
    [DllImport("Advapi32.dll", SetLastError = true)]
    static extern void SetFileSecurity(string path, int type_of_sd, IntPtr sd);
    [DllImport("Advapi32.dll", SetLastError = true)]
    static extern bool ConvertStringSecurityDescriptorToSecurityDescriptor(string StringSecurityDescriptor, uint StringSDRevision, out IntPtr SecurityDescriptor, out UIntPtr SecurityDescriptorSize);
    private static void Main()
    {
        string path = @"C:\Some\path\to\file";
        string sddl = "D:AI(A;ID;FA;;;S-1-1-0)"; // set only one ACE: inherited full access to Everyone
        uint sd_revision = 1;  // the only revision of SECURITY_DESCRIPTOR
        int DACL_SECURITY_INFORMATION = 4; // can be changed to change other properties, not DACL, relying on SECURITY_DESCRIPTOR_CONTROL parameters https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa379566%28v=vs.85%29.aspx
        IntPtr sd_ptr = new IntPtr();
        UIntPtr sd_size_ptr = new UIntPtr();
        ConvertStringSecurityDescriptorToSecurityDescriptor(sddl, sd_revision, out sd_ptr, out sd_size_ptr);
        SetFileSecurity(path, DACL_SECURITY_INFORMATION, sd_ptr);
    }
}
此代码将函数从Advapi32.dll右侧导入C#代码。 特别感谢!
已将此代码添加到代码示例中。

您可以使用powershell命令获取文件或文件夹(symlink/junction)的sddl:get acl-path“c:\some\file\u or\u folder”| fl

通过管道将输出转换为fl,将acl转换为详细列表和ssdl格式

对于文件夹“C:\Users\someuser\Application Data”,sddl是

O:SYG:SYD:AI(D;;CC;;;WD)(A;OICIID;FA;;;SY)(A;OICIID;FA;;;BA)(A;OICIID;FA;;;S-1-5-21-261494367-2017529714-1376493066-1xx)

O:SY所有者:NT机构/系统 G:SY组:NT机构/系统 D:AI(D;;CC;;;WD)(A;OICIID;FA;;;SY)(A;OICIID;FA;;;BA)(A;OICIID;FA;;;S-1-5-21-2614944367-2017529714-1376493066-1xx)

“D:”表示DACL “AI”的意思是允许继承

括号内的每个子字符串都是一个访问控制项(ACE)。每个ACE包含六个字段,用分号分隔,表示实际权限。第一个ACE(D;;CC;;;WD)对应于详细列表行:Everyone Deny ReadData。也就是说,D表示拒绝,CC表示读取数据,WD表示所有人。请注意,Microsoft文档中显示的CC代码与SDDL.h中的SDDL_CREATE_CHILD和访问权限值ADS_right_DS_CREATE_CHILD同义。CC如何解释为“ReadData”还不清楚。还请注意,指定“Everyone”是使用代码WD(可能来自“World”)完成的,而不是使用SID

对于那些希望深入研究的人,请参见


祝你好运

请记住使用
LocalFree
(try/finally)释放
sd\u ptr
(您已经描述了如何在PowerShell中获取对象的SDDL(然后继续描述SDDL格式,尽管这不是问题的一部分),但问题是如何在C中编辑对象的DACL。