0

创建虚拟专用数据库期间的两个问题。

  1. 运行数据库登录触发器需要哪些权限?用户需要特权吗?
  2. 错误信息:功能有问题,但功能运行良好。

来自用户和表创建的代码:

-- as SYS:
-- in the pdb:
alter session set container = orclpdb;

create user orders identified by orders;
create user vpd_admin identified by vpd_admin;
create user hanna identified by hanna;
create user smith identified by smith;

grant create session to orders, vpd_admin, hanna, smith;
grant create table, unlimited tablespace to orders, vpd_admin;
grant execute on dbms_rls to vpd_admin;
grant create procedure to vpd_admin;

-- in SQL Developer, you can build connections now
-- service name = orclpdb

-- in ORDERS schema:
create table orderinfo2
(ordid number,
product varchar2(10),
custid number);

create table customers
(custid number,
name varchar2(10));

insert into orderinfo2 values (6001, 'coctail', 101);
insert into orderinfo2 values (6002, 'wine', 101);
insert into orderinfo2 values (6003, 'coctail', 102);

insert into customers values (101, 'hanna');
insert into customers values (102, 'smith');

grant select on customers to vpd_admin, hanna, smith;
grant select on orderinfo2 to vpd_admin, hanna, smith;


-- in SYS:
alter session set container = orclpdb;
grant create any trigger to vpd_admin;
grant administer database trigger to vpd_admin;

Package01: custid 到 kod 变量

-- in vpd_admin schema:
create or replace package
    vpd_admin.order_sec_ident
    is procedure kod_variable;
end;
/
 
create or replace package body
    vpd_admin.order_sec_ident
    is procedure
    kod_variable
    is
        kod number;
    begin
        select custid into kod
            from orders.customers where
                trim(upper(name)) =
                sys_context('USERENV', 'SESSION_USER');
        dbms_session.set_context
            ('ORDER_NS', 'KOD_ARG', to_char(kod));
        exception
            when no_data_found then
            dbms_session.set_context
            ('ORDER_NS', 'KOD_ARG', '-1');
    end;
end order_sec_ident;
/

grant execute on order_sec_ident to public;

登录触发器:

create or replace trigger logon_trigger
   after logon
   on database
begin vpd_admin.order_sec_ident.kod_variable;
end;
/

包2:条件纳入政策

create or replace package vpd_admin.orders_cond as
    function cond
    (schema_v varchar2,
    table_v varchar2)
    return varchar2;
    pragma restrict_references (cond, wnds);
end;
/
create or replace package body vpd_admin.orders_cond as
    function cond
    (schema_v varchar2,
    table_v varchar2)
    return varchar2
is
    wherevalue varchar2(2000);
begin
    if
        trim(upper(user)) <> schema_v
        and trim(upper(user)) <> 'SYS'
        and trim(upper(user)) <>'SYSTEM' then
        wherevalue := 'trim(upper(name)) = 
            sys_context (''ORDER_NS'', ''KOD_ARG'')';
    else wherevalue := '1=1';
    end if;
    return wherevalue;
end cond;
end;
/

dbms_rls.add_policy

begin
 dbms_rls.add_policy
 ('orders',
'orderinfo2',
'ord_sec_pol2',
'vpd_admin',
'orders_cond.cond',
'SELECT');
end;
/

问题1:由于logon_trigger,用户无法登录

问题1:用户没有足够的权限运行触发器,需要授予什么权限?

An error was encountered performing the requested operation:

ORA-04088: error during execution of trigger 'VPD_ADMIN.LOGON_TRIGGER'
ORA-00604: error occurred at recursive SQL level 1
ORA-01031: insufficient privileges
ORA-06512: at "SYS.DBMS_SESSION", line 130
ORA-06512: at "VPD_ADMIN.ORDER_SEC_IDENT", line 12
ORA-06512: at line 1
04088. 00000 -  "error during execution of trigger '%s.%s'"
*Cause:    A runtime error occurred during execution of a trigger.
*Action:   Check the triggers which were involved in the operation.
Vendor code 4088
-- (as sys granted dba to smith so I can continue testing)

问题2-1:如何查看跟踪文件?

问题2-2:功能有什么问题?

-- in smith schema:
select * from orders.orderinfo2;

ORA-28113: policy predicate has error
28113. 00000 -  "policy predicate has error"
*Cause:    Policy function generates invalid predicate.
*Action:   Review the trace file for detailed error information.

单独运行功能脚本,它可以工作:

-- in vpd_admin:
create or replace
 function cond
    (schema_v varchar2,
    table_v varchar2)
    return varchar2
is
    wherevalue varchar2(2000);
begin
    if
        trim(upper(user)) <> schema_v
        and trim(upper(user)) <> 'SYS'
        and trim(upper(user)) <>'SYSTEM' then
        wherevalue := 'trim(upper(name)) = 
            sys_context (''ORDER_NS'', ''KOD_ARG'')';
    else wherevalue := '1=1';
    end if;
    return wherevalue;
end cond;
/

declare
    x varchar2(20) := 'aa';
    y varchar2(20) := 'bb';
begin
    dbms_output.put_line(cond(x, y));
end;
/

-- result: trim(upper(name)) = 
            sys_context ('ORDER_NS', 'KOD_ARG')
4

1 回答 1

1

回应:

问题1:用户没有足够的权限运行触发器,需要授予什么权限?

这里的问题是触发器执行但抛出异常。登录中的异常会停止登录并可能对数据库产生广泛影响,这当然是不可取的。因此,登录触发器通常被创建为无异常或仔细控制任何可能的异常。

在此示例中,vpd_admin.order_sec_ident对 进行了一些处理no data found,但可以引发其他异常,并且处理程序本身也可以引发异常。一些实现EXCEPTION WHEN OTHERS在数据库范围内使用登录触发器来确保没有异常。如果在此处解决了触发器中的异常,用户将能够再次登录。

您看到的 priv 问题可能来自DBMS_SESSION.SET_CONTEXT过程中的使用。确保vpd_admin有权访问并在其身份验证中运行上下文设置可以解决 priv 问题。

回应:

问题2-1:如何查看跟踪文件?

警报、跟踪文件条件、位置等是可配置的。文档有更多信息

回应:

问题2-2:功能有什么问题?

orderinfo2没有名称列。子句中的名称'trim(upper(name)) = sys_context ('ORDER_NS', 'KOD_ARG')'在执行时会产生无效的 sql。

orderinfo2 上的策略必须对列有效ordidproductcustid(或有效且不包括任何列,如1=1您的示例中的)。

此异常将通过更改'trim(upper(name)) = sys_context ('ORDER_NS', 'KOD_ARG')'条件来纠正,因此它在如下语句中有效SELECT * FROM ORDERINFO2 WHERE <<predicate>>;

于 2018-07-13T16:53:43.607 回答