2011-03-09 101 views
8

我试图克服以下情况。取得拥有'已损坏'权限的文件的所有权

鉴于存储在NTFS卷,其中上的目录:

  1. 目录所有者设置为他人(例如,非特权用户)
  2. DACL被配置为允许访问的目录不包括该目录的系统或管理员
  3. 的DACL的特定人群实际授予任何人访问或者采取所有权或更改DACL

(或简而言之,所有管理员已被锁定在文件夹外)

但是!

  1. 我下运行的帐户具有
  2. 现有DACL可以,因为我反正写一个新的
  3. 使用其他工具(takeown.exe)被忽略管理权限(SeBackupPrivilege,SeSecurityPrivilege权限),我可以访问有问题的目录。

(或短,我有机会来修复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中检查生成的进程来验证问题不是UAC,并且验证了管理员组已设置为“所有者”而不是“已禁用”。我应该有这样做的所有必要的权利(备份操作员应该是无关的管理员,但我加入它的测试) - 但它只是不断抛出访问被拒绝。

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

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

我在这里错过了什么?

+0

具有完全相同的问题。你有没有设法找到解决办法? – Maverik 2011-05-20 14:57:43

+0

参见http://stackoverflow.com/questions/5368825/taking-ownership-of-a-file-or-folder和http://stackoverflow.com/questions/153087/getting-setting-file-owner-in -c-sharp – 2011-12-14 17:05:24

回答

6

我有同样的问题,只是张贴在这里对于可能来我这里搜索的任何其他人:

您需要在代码中明确启用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:感谢西蒙..你答案给了我一个从一开始的地方。

+0

这确实是我的问题!好醇'UAC。是的,谢谢西蒙先生,如果没有别的。 – 2011-08-18 04:50:36

+1

我有这个问题,我甚至没有启用UAC ...但这工作! – emfurry 2011-08-28 21:42:20

+1

这与UAC无关。在UAC推出之前,特权一直以这种方式运作;如果你想使用它们,你必须先启用它们。 (假定程序员不能错误地使用权限。) – 2014-10-12 21:25:17

5

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

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

+0

谢谢,西蒙。我一直在努力。我阅读了马克的MSDN文章,我很高兴我这样做了,但这是你的文章节省了一天的时间。 – 2013-11-20 13:28:37

+0

Mike O'Briens博客中的代码为我完美工作。 – David 2015-04-19 23:23:07

相关问题