Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil
Шрифт:
* Необходимо создать роль.
* Выдать этой роли достаточные права.
* Назначить конкретным пользователям эту роль.
* При подсоединении к базе данных указать, помимо имени пользователя, ту роль, права которой будет иметь в течение времени данного соединения пользователь. То, что роль явно указывается при подсоединении, позволяет иметь для каждого пользователя набор ролей и менять их при каждом сеансе в зависимости от характера выполняемой работы.
Приведем пример использования ролей Для начала создадим роль с именем READER, которая будет иметь права для чтения данных:
CREATE ROLE READER;
Выдадим этой роли
GRANT Select ON Table_example TO READER;
Присвоим эту роль пользователю TESTUSER, чтобы он мог указать ее при подсоединении к базе данных (если этого не сделать, то возникнет ошибка авторизации):
GRANT READER TO testuser;
Теперь мы можем указать эту роль при подсоединении к базе данных. Все современные библиотеки доступа, описанные в данной книге, имеют специальную •опцию для использования роли пользователя в течение соединения. За подробностями обращайтесь к соответствующим главам. В общем виде, например при подсоединении через isql, указание роли выглядит так:
CONNECT 'server:Disk\Path\database.gdb' USER 'username'
PASSWORD 'password' ROLE ' rolename';
Для нашего примера и тестовой базы данных firstbase.gdb строка соединения по TCP/IP будет выглядеть следующим образом:
CONNECT 'localhost:C:\Database\firstbase.gdb' USER 'sysdba'
PASSWORD 'masterkey' ROLE 'READER';
Использование ролей, которое возможно в InterBase начиная с версии 5.х.. позволяет значительно упростить управление правами пользователей InterBase.
Аннулирование прав
Совершенно очевидно, что поскольку права могут быть выданы, то их можно и отобрать. Для этого существует команда REVOKE. В принципе она представляет собой копию GRANT, только с обратным действием. Формат команды REVOKE для различных объектов базы данных похож на GRANT. Например, чтобы отобрать право чтения таблицы table_example у пользователя TESTUSER, достаточно написать;
REVOKE Select ON Table_example FROM testuser;
Точно так же, как и в GRANT, в REVOKE можно перечислять пользователей и права через запят\ю, применять "псевдонимы" ALL для удаления все\ прав (вне зависимости от того, есть они или нет) и PUBLIC для аннулирования прав сразу > всех пользователей. С помощью REVOKE можно также лишить пользователя назначенной ему роли или аннулировать какие-то права у самой роли. Совершенно очевиден также тот факт, что невозможно как-то ограничить или расширить права пользователя SYSDBA. Если бы это было возможно, то в системе защиты InterBase содержалось бы явное противоречие: пользователь SYSDBA мог бы отобрать права на раздачу прав сам у себя, соответственно без права их восстановить! Таким образом, следует помнить, что пользователь SYSDBA всегда обладает всеми возможными правами.
Не будем утомлять читателя демонстрацией примеров употребление всех возможных применений REVOKE.Теперь мы перейдем к значительно более важному вопросу - к идеологии применения прав.
Как правильно раздавать и аннулировать права
Предыдущее разделы описывали практические примеры раздачи и аннулирования на объекты базы данных. Однако система безопасности - это всегда иерархическая система, в которой есть более ответственные пользователи, раздающие различные права менее ответственным.
Сейчас настало время прояснить схемы раздачи прав. Прежде всего необходимо ввести понятие владельца
Обычно все объекты в период разработки базы данных создаются одним пользователем - SYSDBA. С применением этого же пользователя, как правило, производится вся разработка клиентского приложения. В результате получается, что все объекты всегда доступны. Когда появляется необходимость ввести разграничения по пользователям, необходимо регулировать множество прав, причем не всегда можно заранее сказать, какие права и на какие объекты могут понадобиться для нормальной работы приложения. Из-за этого начинающие разработчики часто считают права на объекты "излишеством" и стараются придумать собственные системы безопасности, не утруждая себя изучением уже существующей. Если вы не хотите попасть в их число, то мы рекомендовали бы вам попытаться разобраться в этой ситуации.
Итак, по умолчанию права на любой объект в InterBase, будь то таблица, представление или хранимая процедура, имеет только его владелец, а также системный администратор SYSDBA. Соответственно раздавать права по умолчанию может только владелец объекта. Любой другой пользователь, не являющийся владельцем объекта, не сможет выдать другому пользователю права на этот объект, если только владелец объекта не передал другому пользователю соответствующие права со специальной опцией WITH GRANT OPTION. Указание этой опции в конце обычного предложения GRANT означает, что пользователь не только получает эти права, но и сможет передавать их другому пользователю Например:
GRANT Select ON Table_example TO testuser WITH GRANT OPTION;
Теперь пользователь testuser может не только выбирать записи из таблицы Table_example, но также передавать право Select (и только его!) другим пользователям.
Если теперь пользователь testuser выдаст права пользователю newuser, затем владелец базы данных отберет право на SELECT у пользователя testuser. то автоматически newuser также потеряет права на Select. To есть все права, выданные пользователем testuser, будут аннулированы.
Для того чтобы не возникало проблем с правами, после этапа активного изменения метаданных лучше всего отказаться от использования SYSDBA как основного пользователя, а создать "специального" пользователя и применять его для разработки клиентского приложения.
Передача прав
Часто случается так, что во время разработки базы данных программист динамически добавляет необходимые права каким-либо пользователям, однако документировать вносимые изменения забывает. Для того чтобы выяснить права какого-либо пользователя, можно извлечь данные из системных таблиц InterBase. Для извлечения всех прав пользователя TESTUSER можно употребить следующий SQL-запрос
SELECT RDB$USER, RDB$GRANTOR, RDB$PRIVILEGE,
RDB$GRANT_OPTION, RDB$RELATION_NAME, RDB$FIELD_NAME, RDB$USER_TYPE, RDB$OBJECT_TYPE
FROM RDB$USER_PRIVILEGES
WHERE RDB$USER = 'TESTUSER'
В результате этого запроса получим таблицу, содержащую все права, выданные пользователю TESTUSER Применяя механизмы поиска и замены в любом текстовом редакторе, можно легко превратить возвращаемую таблицу в полноценные команды GRANT, получив, таким образом, скрипт, который можно будет использовать для "раздачи прав".