代码改变世界

What Are Invoker's Rights and Definer's Rights In Oracle ?

2020-03-18 19:12  askscuti  阅读(269)  评论(0编辑  收藏  举报

This example assumes the following

  • 数据库有两个用户 TOM 和 NATASHA
  • TOM 用户下有张表 TOM_DATE
  • TOM 用户下有个存储过程 TOM_PRO_INSERT(过程中用到表 TOM_DATE)
  • TOM 用户把存储过程的 EXECUTE 权限授权给 NATASHA

实验脚本如下

# 创建 TOM 用户

[oracle@henry ~]$ sqlplus sys/oracle@pdb1 as sysdba

SQL*Plus: Release 12.2.0.1.0 Production on Wed Mar 18 18:08:18 2020

Copyright (c) 1982, 2016, Oracle.  All rights reserved.

Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

SQL> create user tom identified by tom;

User created.

SQL> grant dba to tom;

Grant succeeded.

# 创建 NATASHA 用户

SQL> create user natasha identified by natasha;

User created.

SQL> grant connect,resource to natasha;

Grant succeeded.

# TOM 下创建表 TOM_DATE

SQL> conn tom/tom@pdb1;
Connected.
SQL> create table tom_date(rq date default sysdate);

Table created.

# TOM 下创建存储过程 TOM_PRO_INSERT

SQL> create or replace procedure tom_pro_insert
  2  as
  3  begin
  4  insert into tom_date values(default);
  5  end;
  6  /

Procedure created.

# TOM 对 NATASHA 进行存储过程执行授权

SQL> grant execute on tom_pro_insert to natasha;

Grant succeeded.

There Is A Problem

这里你回顾下权限知识点(系统权限、对象权限、角色权限),TOM 用户创建的存储过程,TOM 当然可以执行。执行存储过程查看结果:

SQL> show user;
USER is "TOM"
SQL> exec tom_pro_insert;

PL/SQL procedure successfully completed.

SQL> select * from tom_date;

RQ
-------------------
2020-03-18 18:20:38

因为 TOM 把该存储过程的执行权限给了 NATASHA,所以 NATASHA 也当然可以执行啦。切换 NATASHA 执行存储过程:

SQL> conn natasha/natasha@pdb1;
Connected.
SQL> show user
USER is "NATASHA"
SQL> exec tom.tom_pro_insert;

PL/SQL procedure successfully completed.

SQL> commit;

Commit complete.

存储过程执行成功,但里面有个小细节。TOM 用户授权的是存储过程给 NATASHA,而存储过程里面涉及到表 TOM_DATE 对 NATASHA 是没有任何权限的。但是 NATASHA 依然可以通过该存储过程对表进行插入操作。那请问?用户 NATASHA 成功执行存储过程后,她可以直接查询 TOM 用户下的 TOM_DATE 表吗?

SQL> show user
USER is "NATASHA"
SQL> select * from tom.tom_date;
select * from tom.tom_date
                  *
ERROR at line 1:
ORA-00942: table or view does not exist

显然不阔以!但执行存储过程后,数据确实被插入了,切换 TOM 查看数据。

SQL> conn tom/tom@pdb1
Connected.
SQL> show user
USER is "TOM"
SQL> select * from tom_date;

RQ
-------------------
2020-03-18 18:20:38
2020-03-18 18:23:23

这个问题你看清楚了吗?所以接下来引入 Definer's Rights (定义者权限)和 Invoker's Rights (调用者权限)

What Are Invoker's Rights and Definer's Rights

  • Definer's Rights

如果你在创建存储过程或者函数的时候,是这样定义的:

CREATE OR REPLACE PROCEDURE askscuti 
    AS ...

# 或者带了授权标识

CREATE OR REPLACE PROCEDURE askscuti AUTHID DEFINER
    AS ...

上面两句命令是一样的,就是用定义者的权限定义的存储过程,第一句默认缺省的授权标识就是 DEFINER ,如果该存储过程的执行权限授权给了其他用户,那么其他用户可以执行该存储过程(即使存储过程里面涉及到的对象对于被授权用户没有任何权限)。文章开头做的那个实验,指的就是这种情况。

  • Invoker's Rights

如果你在创建存储过程或者函数的时候,是这样定义的:

CREATE OR REPLACE PROCEDURE askscuti AUTHID CURRENT_USER
    AS ...

授权标识定义成了 CURRENT_USER,就是用调用者的权限定义的存储过程,如果该存储过程的执行权限授权给了其他用户,但是被授权的这个用户对存储过程里面的对象没有权限的话,存储过程是无法执行成功的。通过下面这个实验看下。

通过实验理解 Invoker's Rights

# TOM 下创建表 TOM_DATE_T

SQL> conn tom/tom@pdb1;
Connected.
SQL> create table tom_date_t(rq date default sysdate);

Table created.

# TOM 下创建存储过程 TOM_PRO_INSERT_INVOKER

SQL> create or replace procedure tom_pro_insert_invoker AUTHID CURRENT_USER
  2  as
  3  begin
  4  insert into tom_date_t values(default);
  5  end;
  6  /

Procedure created.

# TOM 对 NATASHA 进行存储过程执行授权

SQL> grant execute on tom_pro_insert_invoker to natasha;

Grant succeeded.

TOM 执行该存储过程并查询表

SQL> show user
USER is "TOM"
SQL> exec tom_pro_insert_invoker;

PL/SQL procedure successfully completed.

SQL> select * from tom_date_t;

RQ
-------------------
2020-03-18 19:00:48

现在你觉得 NATASHA 用户可以执行这个存储过程吗?

SQL> conn natasha/natasha@pdb1;
Connected.
SQL> show user
USER is "NATASHA"
SQL> exec tom.tom_pro_insert_invoker;
BEGIN tom.tom_pro_insert_invoker; END;

*
ERROR at line 1:
ORA-00942: table or view does not exist
ORA-06512: at "TOM.TOM_PRO_INSERT_INVOKER", line 4
ORA-06512: at line 1

这里你对比下和第一次实验的区别。因为第二次创建的存储过程使用的授权标识为 Invoker's Rights 调用者权限。因此即使授权了存储过程的执行权限,因着 NATASHA 没有存储过程中所涉及到的对象权限(表 tom_date_t),所以执行失败。

最后来道题目瞅瞅

In your multitenant container database (CDB) containing pluggable database (PDBs), the
HR user executes the following commands to create and grant privileges on a procedure:
CREATE OR REPLACE PROCEDURE create_test_v (
v_emp_id NUMBER, 
v_ename VARCHAR2, 
v_SALARY NUMBER, 
v_dept_id NUMBER)
BEGIN
INSERT INTO hr.test VALUES (V_emp_id, V_ename, V_salary, V_dept_id); 
END;
/
GRANT EXECUTE ON CREATE_TEST_V TO john, jim, smith, king;
How can you prevent users having the EXECUTE privilege on the CREATE_TEST_V procedure from inserting values into tables on which they do not have any privileges?

A. Create the CREATE_TEST_V procedure with definer's rights.
B. Grant the EXECUTE privilege to users with GRANT OPTION on the CREATE_TEST_V procedure.
C. Create the CREATE_TEST_V procedure with invoker's rights.
D. Create the CREATE_TEST_V procedure as part of a package and grant users the EXECUTE privilege the package.

你觉得答案是哪个?Answer: 我是白色的 -> C