Надежный способ определить, были ли права ntfs унаследованы - PullRequest
5 голосов
/ 26 мая 2009

У меня тут несколько неясный вопрос.

Что мне нужно: чтобы определить, были ли унаследованы разрешения (или, строго говоря, определенный 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, а затем перебрать ACE в DACL. Здесь действительно важен бит доступа INHERITED_ACE. Это должно быть установлено, когда ACE наследуется и не устанавливается явно.

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

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

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

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

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

Ответы [ 3 ]

1 голос
/ 06 февраля 2010

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

Публикация этой группы новостей

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

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

Также обратите внимание, что на GUI, cacls и icacls нельзя полагаться, когда дело доходит до наследования из-за множества мелких ошибок, как обсуждалось в публикации группы новостей.

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

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

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

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

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 и дублированные ACE.

1 голос
/ 24 июня 2009

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

System.Security.AccessControl

Это относится к ACL, DACL и SACL.

0 голосов
/ 25 июня 2009

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

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

Traceback (последний последний вызов):
Файл "C: \ 1.py", строка 37, в Основной (sys.argv [1:])
Файл "C: \ 1.py", строка 29, в основном для ace_index в диапазоне (dacl.GetAceCount ()):

AttributeError: у объекта 'NoneType' нет атрибута '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 \ Администраторы 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();
    }
}

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

...