Для отмены привилегий, которые все пользователи получили как пользователь PUBLIC, просто трактуйте PUBLIC, как и любого другого пользователя. Например, следующий оператор отменяет полномочия INSERT и DELETE К таблице DEPARTMENT у всех пользователей:
REVOKE SELECT, INSERT, UPDATE
ON DEPARTMENT
FROM PUBLIC;
После выполнения этого оператора привилегии INSERT и DELETE К таблице DEPARTMENT сохраняются у владельца этой таблицы и у пользователя SYSDBA, равно как и у имевших эти привилегии хранимых процедур, просмотров и триггеров. Отмена привилегий у PUBLIC также не убирает привилегии у пользователей, которые имеют их как собственные права.
Отмена права предоставлять привилегии
Для отмены права у пользователя предоставлять конкретную привилегию, но сохранить у него эту привилегию, используйте REVOKE GRANT OPTION:
REVOKE GRANT OPTION
FOR <привилегия> [, <привилегия> [,...]]
ON <таблица> | <объект>
FROM <пользователь> ;
Например, следующий оператор отменяет право предоставлять привилегию SELECT к таблице DEPARTMENT у пользователя HPOTTER и сохраняет у него привилегию SELECT:
REVOKE GRANT OPTION
FOR SELECT
ON DEPARTMENT
FROM HPOTTER;
Выполнение этого оператора приведет к каскадным отменам у всех других пользователей, которые получили право предоставлять эту привилегию от HPOTTER.
Скрипты безопасности
Если вы до сих пор задержались на этой главе, нет сомнений, что вы пришли к заключению, что реализация привилегий SQL требует набора большого объема текста. Что ж, вы правы. В действительности мы не используем интерактивные методы для выполнения этой работы. Мы пишем скрипты - или, иначе, мы пишем хранимые процедуры, которые пишут для нас скрипты.
Как правило, если мы имеем хорошо работающую схему привилегий, мы можем генерировать множество скриптов, которые формируют роли и общие полномочия. Обычно вручную написанный скрипт предназначен для полномочий EXECUTE, поскольку для этого довольно сложно создать нужную формулу.
С появлением в Firebird 1.5 оператора EXECUTE PROCEDURE, который позволяет нам обойти невозможность в Firebird выполнения операторов DDL в PSQL, мы можем выполнить групповую загрузку полномочий прямо в базу данных из хранимой процедуры. Пример подобной процедуры представлен в листинге 35.2 далее в этой главе.
Существует множество инструментов с графическим интерфейсом для тех, кто их любит. У большинства есть средства, автоматически формирующие скрипты безопасности; некоторые создают и устанавливают полномочия только для вас.
Создание скрипта
Автор предпочитает генерировать скрипт безопасности. Он может быть протестирован и аннотирован, он является документом, нужным для контроля качества, и дающим основу для распространения у пользователей. Пример подобного скрипта представлен в листинге 35.1.
Для скрипта мы можем использовать внешний файл, в который помещен скрипт - инструкции и примеры см. в главе 16, примеры также содержатся в главе 30. Однако процедура PERMSCRIPT, описанная здесь, разработана для выполнения в isql и для передачи ее выхода в текстовый файл.
Листинг 35.1. Процедура для генерации скрипта полномочий
/* (с) Helen Borrie 2004, free for use and inodxfication
under the Initial Developer's Public License */
SET TERM ^
CREATE PROCEDURE PERMSCRIPT(
CMD VARCHAR (6) ,/* введите 'G' or 'R' */
PRIV CHAR (10) , /* привилегия или 'ALL' или 'ANY' */
USR VARCHAR(31), /* имя пользователя */
ROLENAME VARCHAR(31), /* роль, существующая или нет */
GRANTOPT SMALLINT,
/* 1 для 'WITH GRANT[ADMIN] OPTION' */
CREATE ROLE SMALLINT) /* 1 для создания новой роли ROLENAME */
RETURNS (PERM VARCHAR(80)) /* теоретический оператор полномочия */
AS
DECLARE VARIABLE RELNAME VARCHAR (31); /* для имени таблицы или просмотра */
DECLARE VARIABLE STRING VARCHAR(80) = ''; /* используется в процедуре */
DECLARE VARIABLE STUB VARCHAR(60) = ''; /* используется в процедуре */
DECLARE VARIABLE VUSR VARCHAR(31) ; /* имя пользователя для 'TO' или 'FROM' */
DECLARE VARIABLE COMMENTS CHAR(20) = '/* */';
BEGIN
/* Необходимо для некоторых редакторов пользовательского интерфейса */
IF (ROLENAME = '') THEN ROLENAME = NULL;
IF (USR = '') THEN USR = NULL;
IF (PRIV = '') THEN PRIV = NULL;
/* Недостаточно данных для выполнения работы */
IF ( (PRIV IS NULL AND ROLENAME IS NULL) OR USR IS NULL) THEN EXIT;
/* Если это имя роли, мы будем с ней работать */
IF (ROLENAME IS NOT NULL) THEN
BEGIN
/* Если задано имя роли, то создается роль, если она требуется */
IF (CREATE_ROLE = 1) THEN BEGIN
PERM = 'CREATE ROLE ' || ROLENAME || ' ; ' ;
SUSPEND;
PERM = 'COMMIT; ' ;
SUSPEND;
PERM = COMMENTS;
SUSPEND;
END
VUSR = ROLENAME;
END
/* Если существует имя роли, мы применим полномочия к этой роли и предоставим эту роль указанному пользователю */
ELSE
/* Нас не интересует роль: полномочия только для пользователя */
VUSR = USR;
/* Выяснение - этот скрипт GRANT или REVOKE */
IF (CMD STARTING WITH 'G') THEN
STUB = 'GRANT';
ELSE
STUB = 'REVOKE ';
IF (ROLENAME IS NOT NULL) THEN
BEGIN
IF (STUB = 'GRANT') THEN
BEGIN
/* Предоставление роли пользователю */