一直认为调用者权限过程所参考的对象是调用者用户下的对象,所依赖的权限也是调用者拥有的权限,但是现在发现事实并非完全如此。
事实上这个观点对于表、视图是正确的,调用者权限存储过程访问的表和视图是调用者当前用户下的,且权限都来自调用者本身。
但是对于存储过程,却是个例外,调用者权限存储过程中调用的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 过程已成功完成。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/4227/viewspace-718284/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/4227/viewspace-718284/