Получение прав на файлы с «битыми» разрешениями - PullRequest
9 голосов
/ 09 марта 2011

Я пытаюсь преодолеть следующую ситуацию.

Имеется каталог, хранящийся на томе NTFS, где:

  1. Владельцем каталога является другой пользователь (например, непривилегированный пользователь)
  2. Каталог DACL настроен для разрешения доступа к определенной группе людей, которая не включает систему или администраторов
  3. DACL в каталоге на самом деле не предоставляет никому права ни вступать во владение, ни изменять DACL

(или короче говоря, все администраторы заблокированы из папки)

Но!

  1. У моей учетной записи есть права администратора (SeBackupPrivilege, SeSecurityPrivilege)
  2. Существующий DACL можно игнорировать, так как я все равно пишу новый
  3. Используя другие инструменты (takeown.exe), я могу получить доступ к соответствующему каталогу.

(или короче говоря, у меня есть доступ, чтобы исправить 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, то же самое.

Я проверил, что проблема не в UAC, проверив результирующий процесс в Process Explorer, и убедился, что группе «Администраторы» задано значение «Владелец» вместо «Отключено». Я должен иметь все необходимые права для этого (операторы резервного копирования должны быть посторонними в лице администраторов, но я добавил его для тестирования) - но он просто выбрасывает отказ в доступе.

Соответствующая техническая документация: http://technet.microsoft.com/en-us/library/cc783530%28WS.10%29.aspx

  • «Если вы являетесь владельцем объекта, вы можете предоставить любому пользователю или группе безопасности любое разрешение на этот объект, включая разрешение на владение.»
  • Право собственности может быть передано следующими способами:
    • Текущий владелец может предоставить другому пользователю право на передачу прав на владение, что позволит ему в любое время стать владельцем. Пользователь должен фактически вступить во владение, чтобы закончить передачу. (К сожалению, владелец не может передать право собственности в этой ситуации.)
    • Администратор может стать владельцем.
    • Пользователь, имеющий право на восстановление файлов и каталогов, может назначить владельца любому пользователю или группе.
  • Возможность взять на себя ответственность за файлы и другие объекты - это еще один случай, когда потребность администратора в поддержке системы имеет приоритет над правом владельца контролировать доступ. Как правило, вы можете стать владельцем объекта, только если его текущий владелец разрешит вам это сделать. Владельцы объектов NTFS могут разрешить другому пользователю вступать во владение, предоставив другому пользователю разрешение на владение; Владельцы объектов Active Directory могут предоставить другому пользователю разрешение «Изменить владельца». Пользователь, обладающий этой привилегией, может стать владельцем объекта без разрешения текущего владельца. По умолчанию привилегия назначается только встроенной группе администраторов. Обычно он используется администраторами для принятия и переназначения владения ресурсами, когда их текущий владелец больше не доступен.

Что мне здесь не хватает?

Ответы [ 2 ]

7 голосов
/ 20 мая 2011

У меня была такая же проблема, и я просто писал здесь для всех, кто может прийти сюда в поисках, как я:

Вам необходимо явно включить 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: Спасибо, Саймон. Твой ответ дал мне место для начала.

6 голосов
/ 28 марта 2011

Вам необходимо вступить во владение, прежде чем добавить доступ.

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

...