Примеры
В данном случае пользователю JOE
достаточно только привилегии SELECT
на таблицу t
.Если бы таблица была создана с привилегиями вызывающего пользователя (INVOKER
), то ещё потребовалось бы выдать привилегию EXECUTE
для таблицы на функцию f
.
SET TERM ^;
CREATE FUNCTION f() RETURNS INT
AS
BEGIN
RETURN 3;
END^
SET TERM ;^
CREATE TABLE t (
i INTEGER,
c COMPUTED BY (i + f())
)
SQL SECURITY DEFINER;
INSERT INTO t VALUES (2);
GRANT SELECT ON TABLE t TO USER joe;
COMMIT;
CONNECT 'inet://localhost:test' USER joe PASSWORD 'pas';
SELECT * FROM t;
В данном случае пользователю JOE
достаточно только привилегии EXECUTE
на процедуру p
.Если бы процедура была создана с привилегиями вызывающего пользователя (опция INVOKER
), то ещё потребовалось бы выдать привилегию INSERT
для процедуры p на таблицу t
.
CREATE TABLE t (i INTEGER);
SET TERM ^;
CREATE PROCEDURE p (i INTEGER)
SQL SECURITY DEFINER
AS
BEGIN
INSERT INTO t VALUES (:i);
END^
SET TERM ;^
GRANT EXECUTE ON PROCEDURE p TO USER joe;
COMMIT;
CONNECT 'inet://localhost:test' USER joe PASSWORD 'pas';
EXECUTE PROCEDURE p(1);
В данном случае пользователю JOE
достаточно только привилегии EXECUTE
на функцию f
.Если бы функция была создана с привилегиями вызывающего пользователя (опция INVOKER
), то ещё потребовалось бы выдать привилегию SELECT
для функции f
на таблицу t
.
CREATE TABLE t (i INTEGER PRIMARY KEY, j INTEGER);
INSERT INTO t(i, j) VALUES(1, 2);
INSERT INTO t(i, j) VALUES(2, 5);
COMMIT;
SET TERM ^;
CREATE FUNCTION f (i INTEGER)
SQL SECURITY DEFINER
AS
DECLARE j INTEGER DEFAULT NULL;
BEGIN
SELECT j
FROM t
WHERE i = :i
INTO j;
RETURN COALESCE(j, 0);
END^
SET TERM ;^
GRANT EXECUTE ON FUNCTION f TO USER joe;
COMMIT;
CONNECT 'inet://localhost:test' USER joe PASSWORD 'pas';
SELECT f(1) AS j FROM RDB$DATABASE;
В данном случае пользователю JOE
достаточно только привилегии INSERT
на таблицу tr
.Если бы триггер была создан с привилегиями вызывающего пользователя (опция INVOKER
), то ещё потребовалось бы выдать привилегию INSERT
для триггера tr_ins
на таблицу t
.
CREATE TABLE tr (i INTEGER);
CREATE TABLE t (i INTEGER);
SET TERM ^;
CREATE TRIGGER tr_ins FOR tr AFTER INSERT
SQL SECURITY DEFINER
AS
BEGIN
INSERT INTO t(i) VALUES(NEW.i);
END^
SET TERM ;^
GRANT INSERT ON TABLE tr TO USER joe;
COMMIT;
CONNECT 'inet://localhost:test' USER joe PASSWORD 'pas';
INSERT INTO tr(i) VALUES(2);
COMMIT;
Тот же самый результат можно получить указав SQL SECURITY DEFINER для таблицы tr.
CREATE TABLE tr (i INTEGER) SQL SECURITY DEFINER;
CREATE TABLE t (i INTEGER);
SET TERM ^;
CREATE TRIGGER tr_ins FOR tr AFTER INSERT
AS
BEGIN
INSERT INTO t(i) VALUES(NEW.i);
END^
SET TERM ;^
GRANT INSERT ON TABLE tr TO USER joe;
COMMIT;
CONNECT 'inet://localhost:test' USER joe PASSWORD 'pas';
INSERT INTO tr(i) VALUES(2);
COMMIT;
SQL SECURITY
, то, для того чтобы наследовать привилегии выполнения у таблицы, необходимо выполнить следующий оператор.
ALTER TRIGGER tr_ins DROP SQL SECURITY;
В данном случае пользователю JOE достаточно только привилегии EXECUTE
на пакет pk
.Если бы пакет была создана с привилегиями вызывающего пользователя (опция INVOKER
), то ещё потребовалось бы выдать привилегию INSERT
для пакета pk
на таблицу t
.
CREATE TABLE t (i INTEGER);
SET TERM ^;
CREATE PACKAGE pk
SQL SECURITY DEFINER
AS
BEGIN
FUNCTION f(i INTEGER) RETURNS INT;
END^
CREATE PACKAGE BODY pk
AS
BEGIN
FUNCTION f(i INTEGER) RETURNS INT
AS
BEGIN
INSERT INTO t VALUES (:i);
RETURN i + 1;
END
END^
SET TERM ;^
GRANT EXECUTE ON PACKAGE pk TO USER joe;
COMMIT;
CONNECT 'inet://localhost:test' USER joe PASSWORD 'pas';
SELECT pk.f(3) FROM rdb$database;
После выполнения данного оператора PSQL модули по умолчанию будут создаваться с опцией SQL SECURITY DEFINER
ALTER DATABASE SET DEFAULT SQL SECURITY DEFINER;