Получите общие разрешения для папок (например, GENERIC_ALL), используя Java AclFileAttributeView

1

Я использую AclFileAttributeView из Java7 для чтения разрешений папки в каталоге Windows. Проблема в том, что я не могу получить полный обзор, потому что AclFileAttributeView не возвращает общие разрешения, такие как GENERIC_ALL, GENERIC_WRITE, GENERIC_READ и GENERIC_EXECUTE (четыре старших бита в маске доступа). Фактически, когда дело доходит до общих разрешений, это дает мне неправильную информацию о других AclEntries для того же члена. Позвольте мне привести пример:

Когда я использую такой инструмент, как AccessChk, чтобы перечислить AclEntries c:\windows для учетной записи System, я получаю следующее:

[2] ACCESS_ALLOWED_ACE_TYPE: NT AUTHORITY\SYSTEM
  FILE_ADD_FILE
  FILE_ADD_SUBDIRECTORY
  FILE_LIST_DIRECTORY
  FILE_READ_ATTRIBUTES
  FILE_READ_EA
  FILE_TRAVERSE
  FILE_WRITE_ATTRIBUTES
  FILE_WRITE_EA
  DELETE
  SYNCHRONIZE
  READ_CONTROL
[3] ACCESS_ALLOWED_ACE_TYPE: NT AUTHORITY\SYSTEM
    [OBJECT_INHERIT_ACE]
    [CONTAINER_INHERIT_ACE]
    [INHERIT_ONLY_ACE]
  GENERIC_ALL

Как вы можете видеть, первый AclEntry применяется только к самой папке и не имеет специальных разрешений WRITE_ACL и WRITE_OWNER. Второй AclEntry применяется только к подпапкам и файлам и содержит общее разрешение GENERIC_ALL. Именно так я вижу это на вкладке "Безопасность" проводника Windows. Две записи для учетной записи "Система" относятся только к папке (с подмножеством разрешений), а одно относится к подпапкам/файлам с полным контролем.

Теперь я запускаю свою java-программу, используя следующий код:

AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class);
System.out.println(view.getAcl());

Это дает мне следующие результаты для учетной записи системы:

  • NT AUTHORITY\SYSTEM: READ_DATA/WRITE_DATA/APPEND_DATA/READ_NAMED_ATTRS/WRITE_NAMED_ATTRS/EXECUTE/DELETE_CHILD/READ_ATTRIBUTES/WRITE_ATTRIBUTES/DELETE/READ_ACL/WRITE_ACL/WRITE_OWNER/SYNCHRONIZE: ALLOW
  • NT AUTHORITY\SYSTEM: FILE_INHERIT/DIRECTORY_INHERIT/INHERIT_ONLY: ALLOW

Первый AclEntry применяется только к самой папке и содержит все специальные разрешения, включая WRITE_ACL и WRITE_OWNER, что неверно! Второй AclEntry не показывает никаких разрешений, потому что на нем есть GENERIC_ALL!

Я не уверен, где это происходит не так, кажется, что JRE просто декодирует бит-маску ACE, заданную ОС (sun.nio.fs.WindowsSecurityDescriptor.decode).

Кто-нибудь испытал эти же проблемы? Я попробую другие JRE, возможно, это имеет значение.

  • 0
    Что касается появления WRITE_ACL, Java может вставлять это, потому что право собственности на объект неявно дает вам это разрешение. То же самое можно сказать и о WRITE_OWNER, я не уверен. Не знаете, почему второй ACL пуст - разве цель функции состоит в том, чтобы предоставить вам информацию о доступе к этому конкретному объекту и, таким образом, исключается доступ только по наследству?
  • 0
    Возможно, нативная часть C ++ JVM выполняет некоторую дополнительную логику, но, насколько я вижу, она использует нативный метод WindowsNativeDispatcher.GetAce для получения битовой маски, а затем вызывает WindowsSecurityDescriptor.decode, где биты переводятся в флаги и разрешения. , Я думаю, что это вызывает проблему, четыре старших разряда (для общих разрешений) не используются в этом методе. Так что я боюсь, что это просто отсутствует в JVM, он должен (по крайней мере) преобразовать общие разрешения в специальные разрешения. Возможно, кто-то знает про библиотеку для чтения разрешений NTFS?
Теги:
directory
permissions
acl

2 ответа

1
Лучший ответ

Я тоже столкнулся с этой проблемой. Как выясняется, спецификация для AclFileAttributeView заявляет, что она предназначена для совместимости с RFC 3530: протокол сетевой файловой системы (NFS) версии 4. В RFC 3530 нет поддержки значений GENERIC_ *. Я также посмотрел источник кода JDK (из загруженного здесь проекта OpenJDK), который запускает JVM. Хотя мне кажется, что был бы способ сделать JVM совместимым путем сопоставления соответствующих флагов RFC 3530 с и из GENERIC_ *, у сопровождающих явно нет. Это причина вашей пустой записи. NT AUTHORITY\SYSTEM: FILE_INHERIT/DIRECTORY_INHERIT/INHERIT_ONLY: ALLOW

Хуже того, JVM НЕ поддерживает флаги SE_DACL_PROTECTED и SE_SACL_PROTECTED из дескрипторов безопасности Windows (которые устанавливаются через мета-флаги (UN) PROTECTED_ (S/D) ACL_SECURITY_INFORMATION, как указано в комментариях здесь. Если вы используете инструмент AccessChk, это фактически показывает эффективный список ACE, а не фактический список ACE, который AclFileAttributeView и другие инструменты Windows (посмотрите на FileTest.) Вот почему число ACE отличается. В моем случае у меня было 9 ACE, но AccessChk показал 5. 4 из тех 9, где действительно дублируется значение SID (пользователя или группы), в котором 1-й ACE для данного SID имел разрешения, а второй ACE для данного SID не имел разрешений NO, но только SE_DACL_PROTECTED установлен или не установлен.

Я не совсем уверен, что вы хотели сделать с этими ACL, но у меня может быть решение для вас в зависимости от ваших намерений. Я пошел дальше и внесла изменения в проект JNA, чтобы начать позволять более точно изменять дескрипторы безопасности Windows. Вы можете увидеть мой слит запрос тянуть здесь. Я не знаю, как часто они публикуют версии для публичного репо Maven, поэтому вам может потребоваться загрузить и скомпилировать источник напрямую, чтобы получить эти изменения. См. GetNamedSecurityInfo для получения SD объекта. Затем вы можете использовать API-интерфейс справки в AdvApi32Util для maninuplate объектов SECURITY_DESCRIPTOR. См. public static SECURITY_DESCRIPTOR_RELATIVE getFileSecurityDescriptor(File file, boolean getSACL), чтобы получить SD в самостоятельный формат, а затем этот объект позволяет вам переходить ACE в ACL.

  • 0
    Я скомпилировал последний источник, и getFileSecurityDescriptor работает очень хорошо. Ранее я использовал метод setAcl в JRE для изменения ACL, но он опирается на старый метод setFileSecurity API и не распространяет изменения в подпапках и файлах. Я попробую ваш setFileSecurityDescriptor из проекта JNA (так как он опирается на setnamedsecurityinfo). Также было бы неплохо иметь вспомогательный метод, который добавляет или удаляет ACE из структуры SECURITY_DESCRIPTOR_RELATIVE .... какие-либо планы на это?
  • 0
    На данный момент нет. Проблема в том, что в основном это один смежный байтовый массив, а члены - это просто указатели на этот массив. Манипулировать на месте будет сложно. Вероятно, лучше всего сделать это на копии объекта, используя новый конструктор, который принимает владельца, группу, dacl, sacl и использует API более низкого уровня, такие как SetEntriesInAcl . У меня есть планы по манипулированию ACL, но, вероятно, 3-4 месяца.
1

Я закончил использовать рефлексию, чтобы получить маску доступа ACE (используя sun.nio.fs.WindowsNativeDispatcher.GetAce). С маской доступа я проверяю четыре бита высокого порядка, чтобы определить общие разрешения.

Это также позволяет мне получить бит INHERITED_ACE, который недоступен в спецификации JRE. Я получаю "сырую" информацию ACL, которая намного больше, чем вкладка "Безопасность Windows". Например, мой диск c:\дает мне два ACE для BUILT-IN\Administrators, один с разрешениями GENERIC_ALL и распространением в подпапки и файлы (а не сам контейнер) и один с применимыми специальными разрешениями без флагов вообще ( применяется только к текущему контейнеру). Это то, как Windows использует эти общие разрешения. То же самое относится и к подпапкам, например к каталогу Program Files, распространяются общие разрешения, и каждый субконтейнер имеет отдельный ACE для фактических специальных разрешений, которые применяются только к самому контейнеру.

Об инструменте AccessChck вы уверены, что используете параметр -l? Это дает гораздо больше информации и "сырой" информации ACL.

Я уже использую проект JNA для извлечения локальных групп с сервера. Спасибо за отзыв о AdvApi32Util! Я буду смотреть в него. Как ваш опыт использования метода setACL в JRE?

Я использую все это, чтобы выпустить инструмент, который объединяет членство в группе из LDAP с информацией ACL, найденной в каталогах и файлах. Вся эта информация сохраняется в локальной базе данных (или внешней) и может использоваться для создания обзоров. Этот обзор предлагает множество опций фильтра и отображает информацию о разрешении для определенного пользователя или группы пользователей (включая членство в вложенной группе). Поскольку все сохраняется в базе данных, оно дает вам обзор в секундах, а не сканирование всей сети каждый раз. Вы также можете отслеживать разрешения, отображать, откуда происходят разрешения, из какого членства в группе или из какой папки и т.д. Он будет содержать функцию для изменения одного ACE, но основное внимание уделяется разрешениям просмотра.

Инструмент готов к тестированию;) Сообщите мне, если вам интересно... Инструмент не будет бесплатным, потому что мне потребовалось много времени, чтобы написать, но дайте мне знать, если вам интересно. Я могу получить вам лицензию. Для быстрого просмотра см. Следующие ссылки. Не обращайте внимания на веб-сайт, он все еще упоминает старую версию инструмента.

Сканировать скриншот
Обзор скриншотов

Анализатор разрешений 64 бит
Анализатор разрешений 32bit
Анализатор разрешений 64 бит с встроенным JRE
Анализатор разрешений 32bit с встроенным JRE

Ещё вопросы

Сообщество Overcoder
Наверх
Меню