Это очень странно и нелегко объяснить, поэтому, пожалуйста, потерпите меня.
Oracle 12.2.0.1 в Linux x86_64.
У нас есть пользователь с именем BATCH
, у которого минимальные привилегии.
CREATE USER batch IDENTIFIED BY batch
DEFAULT TABLESPACE users
QUOTA UNLIMITED ON users;
GRANT CREATE SESSION TO batch;
GRANT EXECUTE ON DBMS_CRYPTO TO batch;
Пакет PLSQL в схеме с именем ATLED
:
CREATE OR REPLACE PACKAGE ALTED.the_pkh AUTHID current_user AS
PROCEDURE crttab;
END;
/
CREATE OR REPLACE PACKAGE BODY ALTED.the_pkh AS
PROCEDURE crttab IS
BEGIN
EXECUTE IMMEDIATE 'CREATE TABLE atled.the_tab AS SELECT id, DBMS_CRYPTO.HASH(cc,2) AS cc FROM ARCHIVE.table_b';
END crttab;
END;
/
Мы используем Контроль доступа на основе кода (функция CBAC - 12c), чтобы ограничивать / контролировать / разрешать определенные стандартные действия для беззубого пользователя, поэтому мы создаем процедуру-обертку, предоставляя ей высокую привилегированную роль и предоставьте выполнение для этого пакетному пользователю:
CREATE OR REPLACE PROCEDURE ALTED.wrapper_crttab AS
PROCEDURE p1 IS
CURSOR c1 is SELECT * FROM SESSION_PRIVS;
BEGIN
FOR r1 IN c1 LOOP
DBMS_OUTPUT.PUT_LINE( r1.privilege );
END LOOP;
END;
BEGIN
p1;
ALTED.the_pkh.crttab;
END;
/
GRANT IMP_FULL_DATABASE TO ALTED;
GRANT IMP_FULL_DATABASE ALTED.wrapper_crttab;
GRANT EXECUTE ON ALTED.wrapper_crttab TO batch;
Теперь давайте запустим это:
CONN batch/batch
SET SERVEROUTPUT ON
EXEC ALTED.wrapper_crttab;
Это вызывает ошибку:
Ошибка в строке 1:
ORA-00942: таблица или представление не существует
Таблицы, на которые есть ссылки, существуют.
Вызов в p1
proc подтверждает, что присутствуют все привилегии, связанные с IMP_FULL_DATABASE, включая CREATE ANY TABLE
, DROP ANY TABLE
, EXECUTE ANY PROCEDURE
.
Если я сделаю это:
GRANT CREATE ANY TABLE TO batch;
GRANT SELECT ANY TABLE TO batch;
CONN batch/batch
EXEC EXECUTE IMMEDIATE 'CREATE TABLE atled.the_tab AS SELECT id, DBMS_CRYPTO.HASH(cc,2) AS cc FROM ARCHIVE.table_b;
Это работает.
Если я изменил CREATE TABLE
stmt для удаления вызова DBMS_CRYPTO
, он также будет работать.
Фактический пакет / proc, который вызывается, создает несколько таблиц в порядке при запуске, как описано выше, но не работает в случае, когда DBMS_CRYPTO вызывается в любом CREATE TABLE
stmt.
Если я предоставлю пользователю batch
права доступа CREATE ANY TABLE
, SELECT ANY TABLE
и EXECUTE ANY PROCEDURE
напрямую и выполню команду CREATE TABLE
как пакетную, то это тоже будет работать.
Так что это не (я думаю) прямая ошибка ORA-942, а что-то, связанное с цепочкой привилегий для DBMS_CRYPTO, и только при выполнении в хранимой процедуре пакета, но что именно я не знаю.
ОБНОВЛЕНИЕ 1
Если я создаю оболочку для DBMS_CRYPTO.HASH следующим образом:
CREATE OR REPLACE FUNCTION batch.crypto_hash ( pcc IN CLOB ) RETURN VARCHAR2 IS
BEGIN
RETURN DBMS_CRYPTO.HASH(pcc,2);
END;
/
Затем замените DBMS_CRYPTO.HASH(cc,2)
в CREATE TABLE
stmt на batch.crypto_hash(cc)
, тогда это работает !!!
Итак, ОПРЕДЕЛЕННО не проблема с разрешениями на ссылки на таблицы, а скорее что-то внутреннее с тем, как работает DBMS_CRYPTO. Возможно, он где-то читает справочную таблицу. До этого я тоже пробовал GRANT EXECUTE ON UTL_I18N to batch
, но это не сработало.
Так что у меня есть обходной путь, но я все еще хотел бы знать, почему это происходит.