首页 > Linux操作系统 > Linux操作系统 > 所有者权限和调用者权限(一)
在Oracle中,系统权限、对象权限以及他们的集合角色权限,是一个相对复杂的安全体系。在前一篇《使用Role权限体系》(http://space.itpub.net/17203031/viewspace-691917)中,已经进行初步介绍。存储过程作为Schema对象下的程序单元,在进行Role处理时有一些特殊之处。今天我们继续介绍存储过程的权限体系:所有者权限和调用者权限。
在存储过程中,我们常常面对这样一个场景:用户A下有一个存储过程(或者函数体、包体)P,中间引用了对象X。在编译存储过程时,是要求用户A有对象X的权限的,如果没有,则系统报编译错误。当成功进行编译之后,用户A将执行execute存储过程P的权限赋给了用户B。但是用户B这时候不一定拥有X的使用权限,此时B能够成功执行存储过程P呢?我们通过一个简单实验,来证实一下。
实验环境准备
先准备用户test,除了具备基本的connect和resource角色权限之外,处于实验目的,赋给select any dictionary的系统权限给test。
SQL> conn sys/sys@otstest as sysdba;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as SYS
SQL>
SQL> create user test
2 identified by test;
User created
SQL> grant resource to test;
Grant succeeded
SQL> grant connect to test;
Grant succeeded
SQL> grant select any dictionary to test;
Grant succeeded
Select any dictionary的系统权限意味着用户可以访问数据字典视图层面的视图对象数据,而且不会因为存储过程对角色权限的剥离效应而受到影响。
SQL> conn test/test@otstest;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as test
SQL> select count(*) from dba_objects;
COUNT(*)
----------
53305
SQL> create or replace procedure p_test_nc
2 is
3 i number;
4 begin
5 select count(*)
6 into i
7 from dba_objects;
8
9 dbms_output.put_line(to_char(i));
10 end;
11 /
Procedure created
SQL> set serveroutput on size 1000;
SQL> exec p_test_nc;
53306
PL/SQL procedure successfully completed
可见,授予select any dictionary的用户test可以对dba_objects视图进行访问操作。同时,存储过程p_test_nc也可以顺利的编译执行。
实验一——所有者权限
准备好的实验环境,我们准备进行第一个项目实验。建立一个新用户ts,只有执行test用户下p_test_nc存储过程权限,但是没有访问dba_objects视图权限,看实际效果。
SQL> conn sys/sys@otstest as sysdba;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as SYS
SQL> create user ts
2 identified by ts;
User created
SQL> grant resource to ts;
Grant succeeded
SQL> grant connect to ts;
Grant succeeded
//用户ts只具有基本的连接和创建对象权限。
SQL> conn test/test@otstest;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as test
//将p_test_nc执行权限授权给ts
SQL> grant execute on p_test_nc to ts;
Grant succeeded
之后,我们检查ts用户下,p_test_nc的执行情况。
SQL> conn ts/ts@otstest;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as ts
SQL> select count(*) from dba_objects;
select count(*) from dba_objects
//ts用户没有dba_objects权限,显示访问必然没有结果;
ORA-00942: 表或视图不存在
SQL> set serveroutput on size 1000;
SQL> exec test.p_test_nc;
53306
PL/SQL procedure successfully completed
结果显而易见,ts虽然没有访问dba_objects权限,但是因为拥有执行p_test_nc的权限,在执行p_test_nc的时候,也是可以在方法中访问到dba_objects。显然,此时ts在p_test_nc上借用了test用户对于dba_objects用户的权限,也就是对象所有者权限。
进一步证明我们的实验,可以进行些变化。
--当所有者权限失去时,即使调用者拥有权限也是无用的。
SQL> conn sys/sys@otstest as sysdba;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as SYS
//回收了test用户上的select any dictionary权限,此时test对dba_objects对象权限消失;
SQL> revoke select any dictionary from test;
Revoke succeeded
//赋予ts用户select any dictionary权限,这样ts就能访问dba_objects了;
SQL> grant select any dictionary to ts;
Grant succeeded
SQL> conn ts/ts@otstest;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as ts
SQL> set serveroutput on size 1000;
SQL> select count(*) from dba_objects; //可以访问对象
COUNT(*)
----------
53306
SQL> exec test.p_test_nc;
begin test.p_test_nc; end;
ORA-06550: 第 1 行, 第 12 列:
PLS-00905: 对象 TEST.P_TEST_NC 无效
ORA-06550: 第 1 行, 第 7 列:
PL/SQL: Statement ignored
我们看到了一些“诡异现象”,ts用户拥有dba_objects对象访问权限,同时也有执行p_test_nc的权限,但是执行的时候却报错,认为对象无效。
唯一的原因就是因为test用户失去了dba_objects对象的权限。而ts在调用p_test_nc时使用的是dba_objects的权限。
上面,我们就介绍了Oracle在存储过程中使用的权限配置“所有者权限”。简单的说,当执行一个程序体(存储过程、函数和包等)的时候,方法体内部使用的权限体系为当前该程序体所有者的权限体系,而与调用方法的用户无关。存储过程p_test_nc此时,无论是谁在执行,权限体系都是该存储过程的所有者test的权限。
所有者权限是Oracle使用的默认权限选择方式,在使用的时候很方便。使用者只要拥有简单的对象执行权限就可以了,无需顾及自己是否有权限访问方法中使用的对象。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/17203031/viewspace-692161/ ,如需转载,请注明出处,否则将追究法律责任。