FGA политика аудита: ORA-28138: Ошибка в предикате политики

Пытаюсь настроить аудит изменений строк таблицы определёнными пользователями.

От пользователя system пишу так:

BEGIN
   DBMS_FGA.add_policy (
        object_schema   => 'system',
        object_name     => 'my_fga_table',
        policy_name     => 'my_fga_policy_1',
        statement_types => 'SELECT, INSERT, DELETE, UPDATE',
        audit_condition => 'USER=''REFEREE_1'' OR USER=''REFEREE_2'''
   );
END;

От пользователя REFEREE_1 пытаюсь изменить таблицу:

UPDATE SYSTEM.my_fga_table SET points=90 WHERE boxer_name='BOXER_1';

Но получаю ошибку:

Error at Command Line : 1 Column : 15
Error report -
SQL Error: ORA-28138: Ошибка в предикате политики
28138. 00000 -  "Error in Policy Predicate"
*Cause:    An invalid policy predicate was specified.
*Action:   Please specify a valide policy Predicate for the FGA policy

В чём проблема?


Ответы (1 шт):

Автор решения: 0xdb

Проблема, как и сказано в ошибке, в предикате. Если посмотреть в трейс файл сессии, то сообщение об ошибке может содержать больше информации - что не так с предикатом:

select value from v$diag_info where name = 'Default Trace File';

FGA Policy FGA_POLICY_1
FGA supports simple predicates only - error 28138

На предикат заданный в параметре audit_condition наложено ряд ограничений, о которах упомянуто в документации:

The expression must not combine conditions using operators such as AND and OR.

Поддерживаются только простые предикаты, их нельзя комбинировать с AND или OR.

Одно из возможных решений, использовать несколько правил с более простыми предикатами.

Возможно использовать функции, например, следуещее будет работать:

audit_condition => q'[regexp_like (user, 'referee_(1|2)', 'i')]' 

Или создать свою функцию для условия в предикате:

create or replace function system.validateUserFga (u varchar2) return char is
begin 
    return case when lower (u) in ('referee_1', 'referee_2') then 'y' else 'n' end;
end;
/
begin
    dbms_fga.add_policy (
        object_schema   =>'system',
        object_name     =>'t',
        policy_name     =>'fga_policy_1',
        statement_types =>'insert',
        audit_condition =>q'[system.validateUserFga (user) = 'y']'); 
end;
/

Запись аудита для заданного пользователя:

insert into system.t values (1);

1 row inserted.

select policy_name, sql_text
from dba_fga_audit_trail
/
POLICY_NAME      SQL_TEXT                        
---------------- --------------------------------
FGA_POLICY_1     insert into system.t values (1) 
→ Ссылка