Страница 18 из 38 Сначала опишу базовый механизм, а потом отдельно отмечу, как он расширяется в версиях 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 "роль" ...; При этом роль должна быть одной из тех, что назначены данному пользователю. И в течение всего соединения она будет только одна. Если при подключении роль не указать, то будут действовать лишь гранты, выданные традиционным образом. |