Присвоение ACL
Чтобы определить, какой DACL следует назначить новому объекту, система защиты использует первое применимое правило из следующего списка.
1. Если вызывающий поток явно предоставляет дескриптор защиты при создании объекта, то система защиты применяет его к объекту. Если у объекта есть имя и он находится в объекте-контейнере (например, именованное событие в каталоге \BaseNamedObjects пространства имен диспетчера объектов), система объединяет в DACL все наследуемые ACE (АСЕ, которые могут быть переданы от контейнера объекта), но только в том случае, если в дескрипторе защиты не установлен флаг SE_DACL_PROTECTED, запрещающий наследование.
2. Если вызывающий поток не предоставляет дескриптор защиты и объекту присваивается имя, система защиты ищет этот дескриптор в контейнере, в котором хранится имя нового объекта. Некоторые ACE каталога объектов могут быть помечены как наследуемые. Это означает, что они должны применяться к новым объектам, создаваемым в данном каталоге. При наличии наследуемых ACE система защиты формирует из них ACL, назначаемый новому объекту. (B АСЕ, наследуемых только объектами-контейнерами, устанавливаются отдельные флаги.)
3. Если дескриптор защиты не определен и объект не наследует какие-либо АСЕ, система защиты извлекает DACL по умолчанию из маркера доступа вызывающего потока и применяет его к новому объекту. B некоторые подсистемы Windows (например, службы, LSA и SAM-объекты) «зашиты» свои DACL, назначаемые ими объектам при создании.
4. Если дескриптор защиты не определен и нет ни наследуемых АСЕ, ни DACL по умолчанию, система создает объект без DACL, что открывает полный доступ к нему любым пользователям и группам. Это правило идентично третьему, если маркер содержит нулевой DACL по умолчанию. Правила, используемые системой при назначении SACL новому объекту,
аналогичны правилам присвоения DACL за двумя исключениями. Первое заключается в том, что наследуемые ACE системного аудита не передаются объектам с дескрипторами защиты, помеченными флагом SE_SACL_PROTEC-TED (DACL точно так же защищается флагом SE_DACL_PROTECTED). Второе исключение: если ACE системного аудита не определены и наследуемого SACL нет, то SACL вообще не присваивается объекту (в маркерах нет SACL по умолчанию).
Когда к контейнеру применяется новый дескриптор защиты, содержащий наследуемые АСЕ, система автоматически передает их в дескрипторы защиты дочерних объектов. (Заметьте, что DACL дескриптора защиты не принимает наследуемые DACL АСЕ, если установлен флаг SE_DACL_PROTECTED, а его SACL не наследует SACL АСЕ, если установлен флаг SE_SACL_PROTECTED.) B соответствии с порядком слияния наследуемых ACE с дескриптором защиты дочернего объекта любые АСЕ, явно примененные к ACL, размещаются до АСЕ, унаследованных объектом. Система использует следующие правила передачи наследуемых АСЕ.
• Если дочерний объект без DACL наследует АСЕ, он получает DACL, содержащий лишь унаследованные АСЕ.
• Если дочерний объект с пустым DACL наследует АСЕ, он также получает DACL, содержащий лишь унаследованные АСЕ.
• Только для объектов в Active Directory: если наследуемый ACE удаляется из родительского объекта, все копии этого ACE автоматически удаляются из всех дочерних объектов.
• Только для объектов в Active Directory: если из DACL дочернего объекта автоматически удалены все АСЕ, у дочернего объекта остается пустой DACL.
Как вы вскоре убедитесь, порядок ACE в ACL является важным аспектом модели защиты Windows.
ПРИМЕЧАНИЕ Как правило, наследование не поддерживается напрямую такими хранилищами объектов, как файловые системы, реестр или Active Directory. Функции Windows API, поддерживающие наследование, в том числе SetSecurityInfo и SetNamedSecurityInfo, реализуют наследование вызовом соответствующих функций из DLL поддержки наследования атрибутов защиты (\Windows\System32\Ntmarta.Dll), которым известно, как устроены эти хранилища объектов.
Определение прав доступа
Для определения прав доступа к объекту используются два алгоритма:
• сравнивающий запрошенные права с максимально возможными для данного объекта и экспортируемый в пользовательский режим в виде Windows-функции GetEffectiveRightsFromAcl\
• проверяющий наличие конкретных прав доступа и активизируемый через Windows-функцию AccessCheck или AccessCheckByType. Первый алгоритм проверяет элементы DACL следующим образом.
1. B отсутствие DACL (DACL = null) объект является незащищенным, и система защиты предоставляет к нему полный доступ.
2. Если у вызывающего потока имеется привилегия на захват объекта во владение (take-ownership privilege), система защиты предоставляет владельцу право на доступ для записи (write-owner access) до анализа DACL (что такое привилегия захвата объекта во владение и право владельца на доступ для записи, мы поясним чуть позже).
3. Если вызывающий поток является владельцем объекта, ему предоставляются права управления чтением (read-control access) и доступа к DACL для записи (write-DACL access).
4. Из маски предоставленных прав доступа удаляется маска доступа каждого ACE типа «доступ отклонен», SID которого совпадает с SID маркера доступа вызывающего потока.
5. K маске предоставленных прав доступа добавляется маска доступа каждого ACE типа «доступ разрешен», SID которого совпадает с SID маркера доступа вызывающего потока (исключение составляют права доступа, в предоставлении которых уже отказано).
После анализа всех элементов DACL рассчитанная маска предоставленных прав доступа возвращается вызывающему потоку как максимальные права доступа. Эта маска отражает полный набор типов доступа, которые этот поток сможет успешно запрашивать при открытии данного объекта.
Все сказанное применимо лишь к той разновидности алгоритма, которая работает в режиме ядра. Его Windows-версия, реализованная функцией GetEffectiveRigbtsFromAcl, отличается отсутствием шага 2, а также тем, что вместо маркера доступа она рассматривает SID единственного пользователя или группы.
Второй алгоритм проверяет, можно ли удовлетворить конкретный запрос на доступ, исходя из маркера доступа вызывающего потока. У каждой Windows-функции открытия защищенных объектов есть параметр, указывающий желательную маску доступа — последний элемент выражения, описывающего защиту объектов. Чтобы определить, имеет ли вызывающий поток право на доступ к защищенному объекту, выполняются следующие операции.
1. B отсутствие DACL (DACL = null) объект является незащищенным, и система защиты предоставляет к нему запрошенный тип доступа.
2. Если у вызывающего потока имеется привилегия на захват объекта во владение, система защиты предоставляет владельцу право на доступ для записи, а затем анализирует DACL. Однако, если такой поток запросил только доступ владельца для записи, система защиты предоставляет этот тип доступа и не просматривает DACL.
3. Если вызывающий поток является владельцем объекта, ему предоставляются права управления чтением и доступа к DACL для записи. Если вызывающий поток запросил только эти права, система защиты предоставляет их без просмотра DACL.
4. Просматриваются все ACE в DACL — от первого к последнему. Обработка ACE выполняется при одном из следующих условий:
a. SID в ACE типа «доступ отклонен» совпадает с незаблокированным SID (SID могут быть незаблокированными и заблокированными) или SID с атрибутом проверки только на запрет в маркере доступа вызывающего потока;
b. SID в ACE типа «доступ разрешен» совпадает с незаблокированным SID в маркере доступа вызывающего потока, и этот SID не имеет атрибута проверки только на запрет;
c. Идет уже второй проход поиска в дескрипторе ограниченных SID, и SID в ACE совпадает с ограниченным SID в маркере доступа вызывающего потока.