zoukankan      html  css  js  c++  java
  • SP的调用者权限

    今天整理以前的笔记,发现还有一些用E文写的笔记。在外企混了几年,E文还是这个德行。这里做个留念


            SP的调用者权限


    What is invoker's right subprogram? According to Oracle document, the answer is
    'use the AUTHID clause, which makes stored procedures and SQL methods execute with the privileges and schema context of the calling user. '

    That is to say, we can create a invoker's right standalone procedure named SP (or function or package) in schema A, let it access some objects without schema name, such as table T. In this way, when a caller name B calls SP, the table B.T will be accessed, instead of A.T

    In order to understand this mechanism better, I'll demonstrate some examples to make some pitfall clear.

    Question 1: Who is the runner?

    When a definer's right subprogram is running, the owner of it is the runner. What about invoker's right one? We can check this information from the USER_USERS view, which describes the current user. Caution: it's not always the same as built-in function USER which shows the session user.

    In a nutshell, when a invoker's right subprogram is called directly, the current user is the session user. Let's jump into the case 1 and 2 below.
    -----------------------------------------------------------------------------------------
    ----- Case 1:
    -- user a
    drop user auth_a cascade;
    create user auth_a identified by test;
    grant connect,resource to auth_a;

    create or replace procedure auth_a.invoker_sp authid current_user is
    l_su varchar2(30);
    l_cu varchar2(30);
    begin
      select user, username into l_su,l_cu from user_users;
      dbms_output.put_line(' SessionUser='||l_su||' CurrentUser='||l_cu);
    end;
    /

    create or replace procedure auth_a.definer_sp authid definer is
    l_su varchar2(30);
    l_cu varchar2(30);
    begin
      select user, username into l_su,l_cu from user_users;
      dbms_output.put_line(' SessionUser='||l_su||' CurrentUser='||l_cu);
    end;
    /

    -- user b
    drop user auth_b cascade;
    create user auth_b identified by test;
    grant connect,resource to auth_b;
    grant execute on auth_a.invoker_sp to auth_b;
    grant execute on auth_a.definer_sp to auth_b;

    SQL> conn auth_b/****@data97
    Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
    Connected as auth_b
     
    SQL> set serveroutput on
    SQL> exec auth_a.invoker_sp
     
     SessionUser=AUTH_B CurrentUser=AUTH_B (within the invoker's right sp,the current user is the session user B, although the owner is A)
     
    PL/SQL procedure successfully completed
     
    SQL> exec auth_a.definer_sp
     
     SessionUser=AUTH_B CurrentUser=AUTH_A (within definer's right sp, the current user is always the owner of subprogram)
     
    PL/SQL procedure successfully completed
     
    -----------------------------------------------------------------------------------------
    Okay, case 1 shows the case when a invoker's right subprogram is directly. And now we'd like to see what happens when it is call indirectly.

    Here we add an extra user T2 who calls invoker's right subprogram in schema A thru another user B.  From experiment result, we know that the current user will be the runner of it's direct caller.

    ---- Case 2:
    -- user b
    drop user auth_b cascade;
    create user auth_b identified by test;
    grant connect,resource to auth_b;
    grant execute on auth_a.invoker_sp to auth_b;
    grant execute on auth_a.definer_sp to auth_b;

    create or replace procedure auth_b.invoker_caller authid current_user is
    l_su varchar2(30);
    l_cu varchar2(30);
    begin
      dbms_output.put_line('invoker call invoker');
      auth_a.invoker_sp();
      dbms_output.put_line('invoker call definer');
      auth_a.definer_sp();
    end;
    /

    create or replace procedure auth_b.definer_caller authid definer is
    l_su varchar2(30);
    l_cu varchar2(30);
    begin
      dbms_output.put_line('definer call invoker');
      auth_a.invoker_sp();
      dbms_output.put_line('definer call definer'); 
      auth_a.definer_sp();
    end;
    /

    SQL> conn T2/****@data97
    Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
    Connected as T2
     
    SQL> set serveroutput on
    SQL> exec auth_b.invoker_caller
     
    invoker call invoker
     SessionUser=T2 CurrentUser=T2 (call path: T2 --> B.invoker's --> A.invoker's, and CU=SU=T2)
    invoker call definer
     SessionUser=T2 CurrentUser=AUTH_A
     
    PL/SQL procedure successfully completed
     
    SQL> exec auth_b.definer_caller
     
    definer call invoker
     SessionUser=T2 CurrentUser=AUTH_B (call path: T2 --> B.definer's --> A.invoker's, and CU=definer's Owner=B)
    definer call definer
     SessionUser=T2 CurrentUser=AUTH_A
     
    PL/SQL procedure successfully completed


    Question 2: Can I use role in procedure?

    As we all know, role is disabled in common subprogram (definer's right). But when we talk about invoker's right subprogram, there's a different story. The privilege checking is postponed till run time, and the role is enabled at this moment. Let me get it straight, if a caller does have some certain privilege NOT thru the explicit grant statement, BUT just thru a role, he still can use this privilege when calling an invoker's right subprogram.
    这里说的disabled并不是role本身不可用,而是通过role获得的privilege不可用。可以理解问,在privilege checking的过程中,通过role获得的privilege被disabled。
    -----------------------------------------------------------------------------------------
    First of all, let's see what happens if B calls invoker's right subprogram when being without a role or explicit privilege.

    ---- Case 3:
    drop table auth_a.t;
    create table auth_a.t (x int);
    create or replace procedure auth_a.invoker_role authid current_user is
    begin
      insert into auth_a.t(x) values(1);
      rollback;
    end;
    /

    grant execute on auth_a.invoker_role to auth_b;

    -- B has no privilige to access A.t
    SQL> conn auth_b/****@data97
    Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
    Connected as auth_b
     
    SQL> exec auth_a.invoker_role
     
    begin auth_a.invoker_role; end;
     
    ORA-01031: insufficient privileges
    ORA-06512: at "AUTH_A.INVOKER_ROLE", line 3
    ORA-06512: at line 2

    (B has no privilige to access A.t, even thought he can access invoker's right procedure residents in schema A)

    -----------------------------------------------------------------------------------------
    Now, we create a role, give it the necessary priviliege and grant it to user B. What'll happen then?

    ---- Case 4:
    -- 
    drop role auth_role;
    create role auth_role;
    grant all on auth_a.t to auth_role;

    grant auth_role to auth_b;


    SQL> conn auth_b/****@data97
    Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
    Connected as auth_b
     
    SQL> exec auth_a.invoker_role
     
    PL/SQL procedure successfully completed
    (with role,  B can do it. The role is enabled)


    -----------------------------------------------------------------------------------------
    The case 4 show the directly calling, and now we try some indiretly calls. We grant role to both user T2 and B, and use T2 to indirectly call A.invoker_role thru B.invoker and B.definer.

    ---- Case 5:
    create or replace procedure auth_b.invoker_call_role authid current_user is
    l_su varchar2(30);
    l_cu varchar2(30);
    begin
      auth_a.invoker_role();
    end;
    /

    create or replace procedure auth_b.definer_call_role authid definer is
    l_su varchar2(30);
    l_cu varchar2(30);
    begin
      auth_a.invoker_role();
    end;
    /

    ----------------------------------------
    SQL> -- T2 has role to access A.t
    SQL> exec auth_a.invoker_role (call path: T2 --> A.invoker's, success)
     
    PL/SQL procedure successfully completed

    ----------------------------------------
    SQL> -- T2 and B both have role
    SQL> exec auth_b.invoker_call_role (call path: T2 --> B.invoker's --> A.invoker's, success)
     
    PL/SQL procedure successfully completed
     
    ----------------------------------------
    SQL> exec auth_b.definer_call_role (call path: T2 --> B.definer's --> A.invoker's, fail)
     
    begin auth_b.definer_call_role; end;
     
    ORA-01031: insufficient privileges
    ORA-06512: at "AUTH_A.INVOKER_ROLE", line 3
    ORA-06512: at "AUTH_B.DEFINER_CALL_ROLE", line 5
    ORA-06512: at line 2

    ---------------------------------------
    SQL> revoke auth_role from auth_b;
    Revoke succeeded
     
    SQL> -- only T2 has role
    SQL> exec auth_b.invoker_call_role (call path: T2 --> B.invoker's --> A.invoker's, success)

    PL/SQL procedure successfully completed

    (from above result, we can see that in a sequence of procedure calling, whenever a definer's right subprogram is called, the role is disabled from this point.)

    -----------------------------------------------------------------------------------------

    Below Case 5 shows that role is enabled in invoker's right subprogram, and now let's dig it deeper to see which roles are there.

    -- Case 6:
    create or replace procedure auth_a.invoker_check_role authid current_user is
    begin
      for x in (select granted_role from user_role_privs order by granted_role) loop
        dbms_output.put_line(x.granted_role);
      end loop;
    end;
    /

    grant execute on auth_a.invoker_check_role to auth_b;

    create or replace procedure auth_b.invoker_call_check_role authid current_user is
    l_su varchar2(30);
    l_cu varchar2(30);
    begin
      auth_a.invoker_check_role();
    end;
    /

    create or replace procedure auth_b.definer_call_check_role authid definer is
    l_su varchar2(30);
    l_cu varchar2(30);
    begin
      auth_a.invoker_check_role();
    end;
    /

    SQL> conn T2/****@data97
    Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
    Connected as T2
     
    SQL> set serveroutput on

    SQL> exec auth_b.invoker_call_check_role (call path: T2 --> B.invoker's --> A.invoker's, current user has all roles from T2. All roles of T2 are enabled in B.involer and A.invoker)
     
    AUTH_ROLE
    CONNECT
    DBA
    JAVAUSERPRIV
    RESOURCE
     
    PL/SQL procedure successfully completed
     
    SQL> exec auth_b.definer_call_check_role (call path: T2 --> B.definer's --> A.invoker's, current user only has roles from B. It means roles of T2 are disabled when T2 called B.definer, and only roles form B can be used in A.invoker)
     
    CONNECT
    RESOURCE
     
    PL/SQL procedure successfully completed

  • 相关阅读:
    定时器应用(函数封装)
    js中的作用域
    js函数传参
    js数据类型转换
    jQuery总结
    少些招数,多些内力
    浏览器中的标签切换事件
    正则表达式之小有名气
    正则表达式之初入江湖
    详解apply
  • 原文地址:https://www.cnblogs.com/wait4friend/p/2334568.html
Copyright © 2011-2022 走看看