Часто бывает удобно объединять пользователей в группы, чтобы облегчить управление привилегиями: таким образом, привилегии могут быть предоставлены группе в целом или отозваны у нее. В Digital Q.DataBase это делается путем создания роли, представляющей группу, и последующего предоставления членства в групповой роли отдельным ролям пользователей.
Чтобы создать групповую роль, сначала создайте саму роль:
CREATE ROLE имя;
Обычно роль, используемая в качестве группы, не имеет атрибута LOGIN,
хотя вы можете установить его, если пожелаете.
Как только групповая роль создана, вы можете добавлять и удалять членов с помощью
команд GRANT и
REVOKE:
GRANTгрупповая_рольTOроль1, ... ; REVOKEгрупповая_рольFROMроль1, ... ;
Вы также можете предоставлять членство другим групповым ролям (поскольку на самом деле нет
никакого различия между групповыми и негрупповыми ролями). База
данных не позволит вам создавать циклические цепочки членства. Также
не разрешается предоставлять членство в роли роли PUBLIC.
Члены групповой роли могут использовать привилегии этой роли двумя
способами. Во-первых, роли-члены, которым было предоставлено членство с
опцией SET, могут выполнить команду
SET ROLE, чтобы
временно «стать» групповой ролью. В этом состоянии сессия
базы данных имеет доступ к привилегиям групповой роли, а не исходной роли входа, и любые созданные объекты базы данных
считаются принадлежащими групповой роли, а не роли входа. Во-вторых, роли-члены, которым членство было предоставлено с
опцией INHERIT, автоматически получают доступ к
привилегиям тех ролей, членами которых они являются (напрямую или косвенно), хотя
цепочка останавливается на членстве, в котором отсутствует опция наследования. В качестве примера предположим, что мы выполнили:
CREATE ROLE joe LOGIN; CREATE ROLE admin; CREATE ROLE wheel; CREATE ROLE island; GRANT admin TO joe WITH INHERIT TRUE; GRANT wheel TO admin WITH INHERIT FALSE; GRANT island TO joe WITH INHERIT TRUE, SET FALSE;
Сразу после подключения под ролью joe сессия базы
данных будет иметь доступ к привилегиям, предоставленным непосредственно joe,
плюс любые привилегии, предоставленные admin и
island, потому что joe
«наследует» эти привилегии. Однако привилегии,
предоставленные wheel, недоступны, потому что, хотя
joe является косвенным членом wheel, это
членство осуществляется через admin, которое было предоставлено с использованием
WITH INHERIT FALSE. После:
SET ROLE admin;
сессия будет иметь доступ только к тем привилегиям, которые предоставлены
admin, а не к тем, что предоставлены joe или
island. После:
SET ROLE wheel;
сессия будет иметь доступ только к тем привилегиям, которые предоставлены
wheel, а не к тем, что предоставлены joe
или admin. Исходное состояние привилегий может быть восстановлено
любой из команд:
SET ROLE joe; SET ROLE NONE; RESET ROLE;
Команда SET ROLE всегда позволяет выбрать любую роль,
членом которой (прямым или косвенным) является исходная роль входа,
при условии, что существует цепочка предоставления прав членства, каждое из которых имеет
SET TRUE (что является значением по умолчанию).
Таким образом, в приведенном выше примере не обязательно становиться
admin перед тем, как стать wheel.
С другой стороны, стать ролью island невозможно вовсе;
joe может получить доступ к этим привилегиям только через наследование.
В стандарте SQL существует четкое различие между пользователями и ролями,
при этом пользователи не наследуют привилегии автоматически, в то время как роли наследуют. Такого
поведения можно добиться в Digital Q.DataBase, присваивая
ролям, используемым в качестве SQL-ролей, атрибут INHERIT, в то время как
ролям, используемым в качестве SQL-пользователей, — атрибут NOINHERIT.
Однако по умолчанию Digital Q.DataBase присваивает всем ролям
атрибут INHERIT для обратной совместимости с версиями до 8.1, в которых пользователи всегда имели доступ к разрешениям, предоставленным группам,
членами которых они являлись.
Атрибуты роли LOGIN, SUPERUSER,
CREATEDB и CREATEROLE можно рассматривать как
специальные привилегии, но они никогда не наследуются, как обычные привилегии
на объекты базы данных. Вы должны фактически выполнить SET ROLE для
конкретной роли, имеющей один из этих атрибутов, чтобы воспользоваться им. Продолжая приведенный выше пример, мы могли бы
предоставить CREATEDB и CREATEROLE роли
admin. Тогда сессия, подключающаяся под ролью joe,
не получит эти привилегии сразу, а только после выполнения
SET ROLE admin.
Чтобы уничтожить групповую роль, используйте команду DROP ROLE:
DROP ROLE имя;
Любое членство в групповой роли автоматически аннулируется (но на сами роли-члены это никак иначе не влияет).