调用者存储过程访问权限问题

一直认为调用者权限过程所参考的对象是调用者用户下的对象,所依赖的权限也是调用者拥有的权限,但是现在发现事实并非完全如此。
事实上这个观点对于表、视图是正确的,调用者权限存储过程访问的表和视图是调用者当前用户下的,且权限都来自调用者本身。
但是对于存储过程,却是个例外,调用者权限存储过程中调用的OWNER用户下的存储过程,对于调用者而言,即使没有权限也是可以访问的。
描述有点抽象,看一个简单的例子:

SQL> CONN SYSTEM/MANAGER
已连接。
SQL> CREATE USER U1 IDENTIFIED BY U1 DEFAULT TABLESPACE USERS;
用户已创建。
SQL> GRANT CREATE SESSION TO U1;
授权成功。
SQL> CONN TEST/TEST 
已连接。
SQL> CREATE OR REPLACE PROCEDURE P_1 AUTHID CURRENT_USER AS
2 BEGIN
3 NULL;
4 END;
5 /
过程已创建。
SQL> CREATE OR REPLACE PROCEDURE P_2 AUTHID CURRENT_USER AS
2 BEGIN
3 P_1;
4 END;
5 /
过程已创建。
SQL> GRANT EXECUTE ON P_2 TO U1;
授权成功。
SQL> CONN U1/U1
已连接。
SQL> EXEC TEST.P_1
BEGIN TEST.P_1; END;
*1 行出现错误:
ORA-06550: 第 1,7 列:
PLS-00201: 必须声明标识符 'TEST.P_1'
ORA-06550: 第 1,7 列:
PL/SQL: Statement ignored
 
SQL> EXEC TEST.P_2
PL/SQL 过程已成功完成。

创建一个只有CREATE SESSION权限的用户。在另外一个用户下,创建两个调用者权限的存储过程,其中P_2调用P_1。将存储过程P_2的执行权限授权给P_1。用新创建的用户登录,可以看到,用户没有权限执行P_1,但是用户可以执行P_2,这意味着用户通过P_2的执行权限,调用了存储过程OWNER用户下调用者本没有权限的存储过程P_1。
这对于定义者权限存储过程是顺理成章的,但是对于调用者存储过程而言,对象的访问权限是在调用时判断,因此由调用者确定访问的对象和权限。没有想到,Oracle这里的对象的范围并不包含存储过程。
第一个过程是否是调用者权限并不重要,将其改为定义者权限,结果依旧:

SQL> CONN TEST/TEST
已连接。
SQL> CREATE OR REPLACE PROCEDURE P_1 AS
2 BEGIN
3 NULL;
4 END;
5 /
过程已创建。
SQL> CREATE OR REPLACE PROCEDURE P_2 AUTHID CURRENT_USER AS
2 BEGIN
3 P_1;
4 END;
5 /
过程已创建。
SQL> CONN U1/U1
已连接。
SQL> EXEC TEST.P_2
PL/SQL 过程已成功完成。
This entry was posted in ORACLE and tagged , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *