Составители:
Представьте, например, что вы разрабатываете базу данных, содержащую инфор-
мацию о заработках сотрудников. Для защиты этой информации можно использовать
ваши собственные списки ACL; содержащие сведения о том, кто имеет доступ к данным
о зарплате. Если база данных получает запрос от неавторизированного источника, сис-
тема может внести сообщение об этом в журнал аудита, полностью запретить доступ к
базе данных или передать обратившемуся клиенту все запрашиваемые им данные за ис-
ключением секретной информации, вместо которой будет передан символ звездочки.
Рассмотрим принцип построения списков ACL [1]. Список ACL - это область па-
мяти, содержащая заголовок ACL и некоторое количество (или ни одной) записей АСЕ.
В свою очередь, запись АСЕ включает в себя ACE_HEADER и одну из структур:
ACCESS_ALLOWED_ACE (соответствует разрешающей записи) или
ACCESS_DENIED_ACE (соответствует запрещающей записи). При заполнении списков
АСЕ в Windows NT 4.0 (и в более ранних версиях) следовало следить за тем, чтобы за-
писи типа ACCESS_DENIED_ACE располагались в списке раньше, чем все остальные
записи. Дело в том, что запрещающие записи имеют больший вес, чем разрешающие за-
писи. Если в списке ACL одна запись разрешает некоторому пользователю доступ к
объекту, а другая запись запрещает этому же пользователю доступ к этому же объекту,
то в силу вступает именно запрещающая запись. В этом случае разрешающая запись иг-
норируется, и пользователь теряет право на доступ к объекту. В Windows NT 4.0 это ус-
ловие выполнялось только в случае, если запрещающие записи располагались в начале
списка ACL.
Одной из проблем, возникающих при работе с ACL, является то обстоятельство,
что для того, чтобы сформировать список ACL, вы должны вычислить его точный раз-
мер. Список ACL должен обладать размером, достаточным для того, чтобы вместить в
себя все АСЕ. Однако разные записи АСЕ могут включать в себя разное количество
байт. Таким образом, задача вычисления размера ACL может оказаться непростой.
Размер записи АСЕ зависит от ее типа и длины SID, который в ней содержится.
Для записей АСЕ, разрешающих доступ, длина записи составляет:
L= sizeof(ACCESS_ALLOWED_ACE) - sizeof(ACCESS_ALLOWED_ACE.SidStart) +
GetLengthSid((PSID)ace.SidStart);
Как видно, к длине заголовка (за вычетом длины первой части SID) добавляется
длина SID.
Таким образом, размер ACL равняется размеру структуры ACL плюс сумма разме-
ров всех АСЕ, входящих в список. Зачастую возникает соблазн не тратить время на рас-
четы, а просто зарезервировать достаточно большой буфер в памяти и предположить,
что выделенного места должно хватить для размещения всего списка. В общем случае
такой подход не запрещается - ACL может обладать размером, большим, чем размер,
достаточный для хранения всех его записей.
Когда вы получили достаточно объемный буфер, вы должны инициализировать
ACL при помощи вызова InitializeAcl. После этого можно добавлять в список записи
АСЕ. Для этого служат функции AddAccessDeniedAce и AddAccessAllowedAce. Каждая
из этих функций принимает в качестве аргументов указатель на буфер ACL, константу
ACL_REVISION, права, которые вы намерены предоставить или отменить, а также ука-
затель на SID. Этот SID идентифицирует пользователя или группу, которым соответст-
вует АСЕ. Получить SID можно при помощи вызова LookupAccountName.
Помните, что записи АСЕ, запрещающие доступ, следует добавлять в список в
первую очередь, в противном случае Windows NT 4.0 и более ранние версии NT будут
некорректно обрабатывать взаимоисключающие АСЕ. Чтобы пояснить ситуацию, рас-
смотрим следующий простой пример. Допустим, я являюсь членом группы ТЕСН, а
158
Представьте, например, что вы разрабатываете базу данных, содержащую инфор-
мацию о заработках сотрудников. Для защиты этой информации можно использовать
ваши собственные списки ACL; содержащие сведения о том, кто имеет доступ к данным
о зарплате. Если база данных получает запрос от неавторизированного источника, сис-
тема может внести сообщение об этом в журнал аудита, полностью запретить доступ к
базе данных или передать обратившемуся клиенту все запрашиваемые им данные за ис-
ключением секретной информации, вместо которой будет передан символ звездочки.
Рассмотрим принцип построения списков ACL [1]. Список ACL - это область па-
мяти, содержащая заголовок ACL и некоторое количество (или ни одной) записей АСЕ.
В свою очередь, запись АСЕ включает в себя ACE_HEADER и одну из структур:
ACCESS_ALLOWED_ACE (соответствует разрешающей записи) или
ACCESS_DENIED_ACE (соответствует запрещающей записи). При заполнении списков
АСЕ в Windows NT 4.0 (и в более ранних версиях) следовало следить за тем, чтобы за-
писи типа ACCESS_DENIED_ACE располагались в списке раньше, чем все остальные
записи. Дело в том, что запрещающие записи имеют больший вес, чем разрешающие за-
писи. Если в списке ACL одна запись разрешает некоторому пользователю доступ к
объекту, а другая запись запрещает этому же пользователю доступ к этому же объекту,
то в силу вступает именно запрещающая запись. В этом случае разрешающая запись иг-
норируется, и пользователь теряет право на доступ к объекту. В Windows NT 4.0 это ус-
ловие выполнялось только в случае, если запрещающие записи располагались в начале
списка ACL.
Одной из проблем, возникающих при работе с ACL, является то обстоятельство,
что для того, чтобы сформировать список ACL, вы должны вычислить его точный раз-
мер. Список ACL должен обладать размером, достаточным для того, чтобы вместить в
себя все АСЕ. Однако разные записи АСЕ могут включать в себя разное количество
байт. Таким образом, задача вычисления размера ACL может оказаться непростой.
Размер записи АСЕ зависит от ее типа и длины SID, который в ней содержится.
Для записей АСЕ, разрешающих доступ, длина записи составляет:
L= sizeof(ACCESS_ALLOWED_ACE) - sizeof(ACCESS_ALLOWED_ACE.SidStart) +
GetLengthSid((PSID)ace.SidStart);
Как видно, к длине заголовка (за вычетом длины первой части SID) добавляется
длина SID.
Таким образом, размер ACL равняется размеру структуры ACL плюс сумма разме-
ров всех АСЕ, входящих в список. Зачастую возникает соблазн не тратить время на рас-
четы, а просто зарезервировать достаточно большой буфер в памяти и предположить,
что выделенного места должно хватить для размещения всего списка. В общем случае
такой подход не запрещается - ACL может обладать размером, большим, чем размер,
достаточный для хранения всех его записей.
Когда вы получили достаточно объемный буфер, вы должны инициализировать
ACL при помощи вызова InitializeAcl. После этого можно добавлять в список записи
АСЕ. Для этого служат функции AddAccessDeniedAce и AddAccessAllowedAce. Каждая
из этих функций принимает в качестве аргументов указатель на буфер ACL, константу
ACL_REVISION, права, которые вы намерены предоставить или отменить, а также ука-
затель на SID. Этот SID идентифицирует пользователя или группу, которым соответст-
вует АСЕ. Получить SID можно при помощи вызова LookupAccountName.
Помните, что записи АСЕ, запрещающие доступ, следует добавлять в список в
первую очередь, в противном случае Windows NT 4.0 и более ранние версии NT будут
некорректно обрабатывать взаимоисключающие АСЕ. Чтобы пояснить ситуацию, рас-
смотрим следующий простой пример. Допустим, я являюсь членом группы ТЕСН, а
158
Страницы
- « первая
- ‹ предыдущая
- …
- 154
- 155
- 156
- 157
- 158
- …
- следующая ›
- последняя »
