У меня тут несколько неясный вопрос.
Что мне нужно: чтобы определить, были ли унаследованы разрешения (или, строго говоря, определенный 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 унаследован или нет.
Как воспроизвести:
- Создать объект (файл или папку)
- Проверьте разрешения в проводнике Windows, убедитесь, что они были переданы из родительского объекта (например, с помощью вкладки безопасности диалогового окна свойств файла проводника Windows).
- Проверьте флаги, используя, например, скрипт, который я использовал (INHERITED_ACE НЕ будет установлен ни на одном ACE).
- Измените права доступа к объекту (примените изменения), верните их обратно даже.
- Проверьте флаги (INHERITED_ACE будет там)
- .. недоверчиво покачал головой (я знаю, что сделал)
Извините за довольно длинный пост, надеюсь, что это имеет хоть какой-то смысл.