获取具有“损坏”权限的文件的所有权

时间:2011-03-09 05:24:02

标签: c# file-permissions ntfs ownership

我正在努力克服以下情况。

给定存储在NTFS卷上的目录,其中:

  1. 目录所有者设置为其他人(例如,非特权用户)
  2. 目录DACL配置为允许访问不包含系统或管理员的特定人员组
  3. 目录上的DACL实际上不授予任何人访问权限或取消所有权或更改DACL
  4. (或者简而言之,所有管理员都被锁定在文件夹之外)

    但是!

    1. 我运行的帐户具有管理权限(SeBackupPrivilege,SeSecurityPrivilege)
    2. 现在的DACL可以忽略,因为我正在编写一个新的
    3. 使用其他工具(takeown.exe),我可以访问相关目录。
    4. (或者简而言之,我有权修复DACL /所有者)

      我对以下代码没有任何问题:

      WindowsIdentity privilegedUser = System.Security.Principal.WindowsIdentity.GetCurrent();
      
      // I cannot use File.GetAccessControl() as I get access denied
      // (working as intended! I have no access to read the ACL!)
      // so I have to write a new ACL:
      FileSecurity acl = new FileSecurity();
      acl.SetOwner(admin.User);
      acl.AddAccessRule(new FileSystemAccessRule(privilegedUser.User, FileSystemRights.FullControl, AccessControlType.Allow));
      
      File.SetAccessControl("c:\\path\\to\\broken", acl);
      

      但是, SetAccessControl 调用会抛出 UnauthorizedAccessException 。当我改变它只调整所有者时,同样的事情发生。当我只尝试调整DACL时,同样的事情。

      我通过在Process Explorer中检查生成的进程并验证Administrators组是否设置为“Owner”而不是“Disabled”来验证问题不是UAC。我应该拥有执行此操作的所有必要权限(备份操作员在面对管理员时应该是无关紧要的,但我将其添加进行测试) - 但它只是继续拒绝访问权限。

      相关的technet文档:http://technet.microsoft.com/en-us/library/cc783530%28WS.10%29.aspx

      • “如果您拥有某个对象,则可以授予任何用户或安全组对该对象的任何权限,包括获得所有权的权限。”
      • 所有权可以通过以下方式转移:
        • 当前所有者可以将获取所有权权限授予其他用户,允许该用户随时获得所有权。用户必须实际拥有所有权才能完成转移。 (很遗憾,在这种情况下,所有者无法重新分配所有权。)
        • 管理员可以取得所有权。
        • 具有“还原文件和目录”用户权限的用户可以将所有权分配给任何用户或组。
      • 获取文件和其他对象所有权的另一种情况是,管理员维护系统的需要优先于所有者控制访问权限。通常,只有在当前所有者授予您权限的情况下,才能获取对象的所有权。 NTFS对象的所有者可以允许其他用户通过授予其他用户获取所有权来获得所有权; Active Directory对象的所有者可以授予其他用户“修改所有者”权限。拥有此权限的用户可以在没有当前所有者许可的情况下获得对象的所有权。默认情况下,该权限仅分配给内置Administrators组。管理员通常使用它来在当前所有者不再可用时获取和重新分配资源的所有权。

      我在这里缺少什么?

2 个答案:

答案 0 :(得分:7)

我遇到了同样的问题,只是在这里张贴给其他可能像我一样来这里搜索的人:

您需要在代码中明确启用SeTakeOwnershipPrivilege。我发现Process Privileges对处理这类事情非常有帮助。

以下是它修复我的代码的方法(看起来因为某些原因,即使我有权限,除非我明确启用它,否则进程不会):

using (new ProcessPrivileges.PrivilegeEnabler(Process.GetCurrentProcess(), Privilege.TakeOwnership))
{
    directoryInfo = new DirectoryInfo(path);
    directorySecurity = directoryInfo.GetAccessControl();

    directorySecurity.SetOwner(WindowsIdentity.GetCurrent().User);
    Directory.SetAccessControl(path, directorySecurity);    
}
PS:谢谢西蒙......你的回答给了我一个开始的地方。

答案 1 :(得分:6)

在添加访问权限之前,您需要获得所有权。

using (var user = WindowsIdentity.GetCurrent())
{
    var ownerSecurity = new FileSecurity();
    ownerSecurity.SetOwner(user.User);
    File.SetAccessControl("c:\\path\\to\\broken", ownerSecurity);

    var accessSecurity = new FileSecurity();
    accessSecurity.AddAccessRule(new FileSystemAccessRule(user.User, FileSystemRights.FullControl, AccessControlType.Allow));
    File.SetAccessControl("c:\\path\\to\\broken", accessSecurity);
}

此外,如果您要设置DirectorySecurity,则需要此

using (var user = WindowsIdentity.GetCurrent())
{
    var ownerSecurity = new DirectorySecurity();
    ownerSecurity.SetOwner(user.User);
    Directory.SetAccessControl("c:\\path\\to\\broken", ownerSecurity);

    var accessSecurity = new DirectorySecurity();
    accessSecurity.AddAccessRule(new FileSystemAccessRule(user.User, FileSystemRights.FullControl, AccessControlType.Allow));
    Directory.SetAccessControl("c:\\path\\to\\broken", accessSecurity);
}

如果不起作用,请尝试此

http://blog.mikeobrien.net/2009/11/taking-ownership-and-setting-admin.html