2009-05-26 8 views
5

У меня есть несколько неясный вопрос.Надежный способ определить, были ли права наследования ntfs унаследованы

Что мне нужно: Чтобы определить, унаследовано ли разрешение (или, строго говоря, конкретное ACE файла DACL) файла/папки.

Как я попытался это решить: используя привязки winapi для python (точнее, модуль win32security). Вот урезанная версия, которая делает именно это, - она ​​просто берет путь к файлу в качестве аргумента и печатает ACE один за другим, указывая, какие флаги установлены.

#!/usr/bin/env python 
from win32security import * 
import sys 

def decode_flags(flags): 
    _flags = { 
     SE_DACL_PROTECTED:"SE_DACL_PROTECTED", 
     SE_DACL_AUTO_INHERITED:"SE_DACL_AUTO_INHERITED", 
     OBJECT_INHERIT_ACE:"OBJECT_INHERIT_ACE", 
     CONTAINER_INHERIT_ACE:"CONTAINER_INHERIT_ACE", 
     INHERIT_ONLY_ACE:"INHERIT_ONLY_ACE", 
     NO_INHERITANCE:"NO_INHERITANCE", 
     NO_PROPAGATE_INHERIT_ACE:"NO_PROPAGATE_INHERIT_ACE", 
     INHERITED_ACE:"INHERITED_ACE" 
    } 
    for key in _flags.keys(): 
     if (flags & key): 
      print '\t','\t',_flags[key],"is set!" 


def main(argv): 
    target = argv[0] 
    print target 

    security_descriptor = GetFileSecurity(target,DACL_SECURITY_INFORMATION) 

    dacl = security_descriptor.GetSecurityDescriptorDacl() 

    for ace_index in range(dacl.GetAceCount()): 
     (ace_type,ace_flags),access_mask,sid = dacl.GetAce(ace_index) 
     name,domain,account_type = LookupAccountSid(None,sid) 
     print '\t',domain+'\\'+name,hex(ace_flags) 
     decode_flags(ace_flags) 


if __name__ == '__main__': 
    main(sys.argv[1:]) 

достаточно просто - получить дескриптор безопасности, получить DACL из него затем перебирать АСЕ в DACL. Здесь действительно важный бит - это флаг доступа INHERITED_ACE. Он должен быть установлен, когда ACE наследуется и не устанавливается явно.

Когда вы создаете папку/файл, его ACL заполняется ACE в соответствии с ACE родительского объекта (папки), которые настроены для распространения на дочерние. Однако, если вы не внесете каких-либо изменений в список доступа, флаг INHERITED_ACE НЕ будет установлен! Но унаследованные разрешения есть, и они работают.

Если у вас есть какие-либо незначительные изменения (скажем, добавьте запись в список доступа, примените изменения и удалите ее), появляется волшебный значок (поведение никоим образом не меняется, хотя оно работало до этого и работает потом)! Я хочу найти источник этого поведения флага INHERITED_ACE и, может быть, найти другой способ , чтобы определить, была ли ACE унаследована или нет.

Как воспроизвести:

  1. Создать объект (файл или папку)
  2. Проверьте права доступа в проводнике Windows видеть, что они распространяются от родительского объекта (используя, например, вкладка безопасности файла диалог свойств окна Explorer).
  3. Проверьте флаги, используя, например, скрипт, который я использовал (INHERITED_ACE НЕ будет установлено ни на какие ACE).
  4. Изменение разрешений объекта (применить изменения), изменить их обратно.
  5. Проверьте флаги (INHERITED_ACE будет там)
  6. ..shake головой в неверии (я знаю, что я сделал)

Извините за несколько длительный пост, надеюсь, что это делает по крайней мере, немного смысл.

+0

Я обновил свой ответ. Это, кажется, проблема с библиотеками Python ... –

ответ

0

На моем Win XP Home Edition этот код не работает вообще :-)

я получаю эту трассировку стека:

Traceback (most recent call last):
File "C:\1.py", line 37, in main(sys.argv[1:])
File "C:\1.py", line 29, in main for ace_index in range(dacl.GetAceCount()):

AttributeError: 'NoneType' object has no attribute 'GetAceCount'

Вы можете просто попробовать «подталкивают» DACL должны быть заполнены? Я имею в виду, если вы знаете, что это сработает после того, как вы немного измените его ... сделайте небольшое изменение программным путем, добавьте заглушку ACE и удалите ее. Ты можешь?

ОБНОВЛЕНИЕ. Я провел эксперимент с программой C# на своем рабочем компьютере (с Win XP Prof), и я должен сказать вам, что способ получения этой информации безопасности .net действительно работает. Поэтому, когда я создаю новый файл, моя программа на C# обнаруживает, что ACE были наследованы, а ваш код на Python этого не делает.

Вот пример вывода из моих пробегов:

C:>csharp_tricks.exe 2.txt

FullControl --> IsInherited: True

FullControl --> IsInherited: True

ReadAndExecute, Synchronize --> IsInherited: True


C:>1.py 2.txt

2.txt

BUILTIN\Administrators 0x0

NT AUTHORITY\SYSTEM 0x0

BUILTIN\Users 0x0

Мой C# класс:

public class InheritedAce 
{ 
    public static string GetDACLReport(string path) 
    { 
     StringBuilder result = new StringBuilder(); 
     FileSecurity fs = new FileSecurity(path, AccessControlSections.Access); 
     foreach (var rule in fs.GetAccessRules(true, true, typeof(SecurityIdentifier)).OfType<FileSystemAccessRule>()) 
     { 
      result.AppendFormat("{0} --> IsInherited: {1}", rule.FileSystemRights, rule.IsInherited); 
      result.AppendLine(); 
     } 

     return result.ToString(); 
    } 
} 

Таким образом, кажется, ошибка в библиотеке питон pywin32 безопасности. Может быть, они не делают все необходимые системные вызовы ...

+0

Да, это определенно не будет работать в домашнем издании. Разрешения ntfs там недоступны, насколько я знаю (поэтому вы получаете None в результате GetSecurityDescriptorDacl). Вы, возможно, верны в своем предположении, что я должен просто использовать заглушку ACE для того, чтобы исправить DACL. Однако рассмотрим тот факт, что мне нужно запустить такой код на огромном корпоративном файловом сервере (подумайте, миллионы объектов). Что, если я (или вы) ошибался в моем предположении? Что, если что-то испортится? Я не собираюсь записывать данные такого рода, если это абсолютно неизбежно. – shylent

+0

Я не могу поверить, что ваш ответ на самом деле получил никого. Во всяком случае, большое спасибо за ваши усилия. У меня нет возможности проверить правильность вашего предложения (нет среды), но, тем не менее, он выглядит довольно солидно для меня. Я обойду эту проблему, проверив ACE в списке доступа к родительскому объекту. Спасибо за эти усилия, вы заработали эту награду :) – shylent

+0

Ну, ACE можно просто скопировать на детские узлы, а не наследовать ... Но если это соответствует вашим потребностям, я не вижу проблем :-) Тем не менее, имея эти доказательства, вы может, вероятно, представить ошибку для разработки python ... –

1

Вы можете использовать рамки .Net

System.Security.AccessControl 

Это охватывает ACL и DACL и SACL.

+0

Использование .Net, к сожалению, не может быть и речи. В любом случае, изучив записи msdn в System.Security.AccessControl, я пришел к выводу, что, по существу, он не предоставляет дополнительной функциональности над API C (по крайней мере, не в той области, в которой я заинтересован), - мой вопрос был а не о том, как извлекать флаги наследования, - это тривиально, а скорее о несогласованности флага INHERITED_ACE. – shylent

1

Я думаю, что оригинальный плакат видит поведение подробно в

This newsgroup posting

Обратите внимание, что флаги управления, установленные на контейнере можно изменить, просто un-ticking и re-ticking поле наследования в графическом интерфейсе.

Обратите внимание, что простое добавление ACE в DACL с использованием инструментов Microsoft также изменит флаги управления.

Обратите внимание, что GUI, cacls и icacls НЕ ДОЛЖНЫ полагаться, когда дело доходит до наследования из-за множества тонких ошибок, как обсуждалось в проводке новостей.

Кажется, что «старый» способ управления наследованием заключался в использовании флажков управления на контейнере в сочетании с флагами ACE, связанными с наследованием.

«Новый» способ не использует флаги управления на контейнере и вместо этого использует дубликаты ACE; один для управления доступом к объекту, а второй - для контроля того, что наследуется дочерними объектами.

НО, похоже, что существующие инструменты Microsoft (например, Vista) не могут работать «новым» способом, поэтому, когда вы делаете простые изменения с помощью этих инструментов, он использует старый способ использования флажков управления на контейнер.

Если вы создаете новый раздел на Vista, а затем создать новую папку, а затем посмотреть на флаги и АСЕ, это будет выглядеть как этот

ControlFlags : 0x8004 
Owner : BUILTIN\Administrators 
Group : WS1\None 
S-1-5-32-544 : BUILTIN\Administrators : 0x0 : 0x0 : 0x1F01FF 
S-1-5-32-544 : BUILTIN\Administrators : 0x0 : 0xB : 0x10000000 
S-1-5-18 : NT AUTHORITY\SYSTEM : 0x0 : 0x0 : 0x1F01FF 
S-1-5-18 : NT AUTHORITY\SYSTEM : 0x0 : 0xB : 0x10000000 
S-1-5-11 : NT AUTHORITY\Authenticated Users : 0x0 : 0x0 : 0x1301BF 
S-1-5-11 : NT AUTHORITY\Authenticated Users : 0x0 : 0xB : 0xE0010000 
S-1-5-32-545 : BUILTIN\Users : 0x0 : 0x0 : 0x1200A9 
S-1-5-32-545 : BUILTIN\Users : 0x0 : 0xB : 0xA0000000 

Обратите внимание на ControlFlags и дублированные АСЕ.