InterBase: тормозология и глюконавтика
Страница 18. Пароли и права доступа. Часть 2


Сначала опишу базовый механизм, а потом отдельно отмечу, как он расширяется в версиях 5.Х с помощью ролей. Чтобы долго не мучиться с терминологией, назовём отдельные элементы прав грантами. Грант - то, что порождается оператором grant и уничтожается оператором revoke. Так же при создании объектов БД автоматически порождаются гранты создателю. Этим дело не ограничивается - для большинства объектов запоминается их владелец.

При каждом обращении пользователя к объекту БД проверяется наличие соответствующих грантов. Или, если делается операция по уничтожению объекта или корректировке метаданных, то проверяется соответствие текущего пользователя владельцу. Единственное исключение - пользователь SYSDBA, для него все эти проверки опускаются.

Гранты хранятся в БД в системной таблице RDB$USER_PRIVILEGES. Вытекающие из них права хранятся в RDB$SECURITY_CLASSES. Хотя теоретически и то, и другое можно править руками, лучше этого не делать, так как там достаточно "тёмных мест", нигде не задокументированных.

Каждый грант характеризуется:

  • Пользователем, которому даются право. Если в качестве такого пользователя указано PUBLIC, значит право даётся всем. Кроме этого можно указать:
    • View имя_представления
    • Procedure имя_процедуры
    • Trigger имя_триггера
  • В таком случае объект БД получит право на операцию независимо от того, какой пользователь её инициировал. В самых последних версиях мне попадалось упоминание о том, что можно давать грант группе пользователей Unix.
  • Пользоватеелм, который даёт право. interbase согласно стандарту SQL отслеживает всю цепочку передачи прав от владельца объекта или администратора. Если кто-то лишается гранта, то автоматически уничтожаются все последующие гранты в этой цепочке. С другой стороны, на одно и то же право пользователь может получить несколько грантов от разных пользователей разными путями. В этом случае право будет действовать, пока жив хоть один грант.
  • Видом операции, на которую даётся право. В качестве них могут выступать:
    • select, insert, update, delete - соответствующие операции над данными.
    • references - означает право сослаться на поля из своей таблицы через foreign key.
    • execute - означает право вызвать процедуру.
    • all означает select, insert, update, delete, references.
  • Объектом БД, над которым можно производить операцию.
  • Списком полей, если объектом является отношение, а правом - update или references.
  • Возможностью получателя передавать этот грант дальше другим пользователям (with grant option, или admin option для ролей).

Ещё раз повторюсь, эти данные заносятся в rdb$user_privileges, исходя из чего автоматически формируются rdb$security_classes. При реальной работе для проверки используется именно последняя таблица, которая может содержать информацию не только вытекающую из грантов - ссылки на неё есть в нескольких местах системных метаданных. Хотя в большинстве случаев на это можно не обращать внимание.

Фундаментальная слабость данной системы заключается в том, что очень неудобно давать права группам (пользователей, процедур, и т. п.) - приходится повторять их для каждого элемента группы. У нас в проекте "Архив" даже была для этой цели разработана специальная программа UserManager. Нормальное решние от Борладна появилось лишь в версии 5.0 (совсем точно - ODS 9.0, которая поддерживается пятёркой).

Решение это называется ролью. Роль - это абстрактный носитель набора грантов. Любые вышеперечисленные виды грантов можно собрать в кучу и передать роли. То есть роль в данном случае будет выступать в качестве получателя грантов.

С другой стороны, роль может выступать в качестве вида права. То есть можно дать роль в качестве права пользователю, процедуре, и т. п. Только здесь есть одна важная и неприятная особенность. В отличие от других видов прав, которые работают сразу же после создания (точнее commit'а), роль начинает работать только тогда, когда пользователь подключается с этой ролью. Зачем понадобилось так ограничивать это дело, не ясно. Ведь это перекрывает значительную часть возможных удобств.

Таким образом, роль является дополнительным свойством соединения с сервером. Все утилиты interbase начиная с версии 5 позволяют ввести параметр role или указать ключ командной строки -role. Кроме этого расширен оператор connect:
connect "база"
user "пользователь"
password "пароль"
role "роль" ...;
При этом роль должна быть одной из тех, что назначены данному пользователю. И в течение всего соединения она будет только одна. Если при подключении роль не указать, то будут действовать лишь гранты, выданные традиционным образом.

 
« Предыдущая статья