oracle - 使用 DBMS_CRYPTO 但表存在时出现奇怪的 ORA-942
问题描述
这很奇怪,也不容易解释,所以请多多包涵。
Linux x86_64 上的 Oracle 12.2.0.1。
我们有一个名为的用户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:表或视图不存在
引用的表确实存在。
对 proc 的调用p1
确认与 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
呼叫,它也可以正常工作。
CREATE TABLE
调用的实际包/过程在如上运行时会创建许多表,但在任何stmt中调用 DBMS_CRYPTO 的情况下会失败。
如果我直接授予batch
用户CREATE ANY TABLE
,SELECT ANY TABLE
和EXECUTE ANY PROCEDURE
privs 并直接将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;
/
然后将stmtDBMS_CRYPTO.HASH(cc,2)
中的替换为then 就可以了!!!CREATE TABLE
batch.crypto_hash(cc)
因此,对于被引用的表的授权肯定不是问题,但更可能是 DBMS_CRYPTO 工作方式的内部问题。也许它在某处读取了一个查找表。在此之前我也尝试过GRANT EXECUTE ON UTL_I18N to batch
,但没有奏效。
所以我有一个解决方法,但我仍然想知道为什么会发生这种情况。
解决方案
你这样做:
... FROM ARCHIVE.table_b
应该从该表中选择的用户必须对其具有SELECT
特权。可以授予
- 通过角色
- 直接地
如果您通过角色授予特权,它可以工作——但不适用于命名的 PL/SQL 过程。它将在匿名 PL/SQL 中工作,但不能在过程、函数、包中工作,所以 - 检查并可能直接授予SELECT
该table_b
用户。
推荐阅读
- php - 如何为视图中的非唯一记录设置相同的颜色
- flutter - 为什么我的资产图像第一次加载但第二次在我用颤振构建我的应用程序时加载
- python - PyCharm 无法导入模块
- python - 在 kivymd 中使用 arabic_reshaper 和 bidi.algorithm
- excel - 如何为列中的每个“新”值创建一个新的工作簿?
- jquery - Fotorama jQuery 插件的缩放功能
- python - 检查字符串的“alpha”部分是否仅包含特定的字符序列 - python
- react-native - 图像不适合屏幕 React-native
- python - Python中的空间循环
- php - 事件 assertDispatched 无法断言循环内生成的事件