I am working with vendor application that uses Oracle database. To save the content it uses database tables, which are queried by using views. I do not have any control over that code. Because of security I gave access to those views to special reporting user, which can only select entries from it.
Whenever some major change is made in the application it drops the appropriate view and creates it anew. Of course all grants are lost and since the changes are made rarely it is easy to forget to backup up and restore them afterwards.
I consulted DBA and he suggested to write a trigger to save grants in temporary table, after which the entries can be used to restore grants. Saving part works fine as expected:
create or replace TRIGGER RECORD_GRANTS_ONDROP
BEFORE DROP ON MYUSER.SCHEMA
BEGIN
IF ora_dict_obj_owner = 'MYUSER' and ora_dict_obj_name not like 'TEMP_PRIV%' and ora_dict_obj_type='VIEW' then
EXECUTE IMMEDIATE 'CREATE TABLE TEMP_PRIV AS SELECT ''GRANT '' || PRIVILEGE || '' ON MYUSER.'' || TABLE_NAME || '' TO '' || GRANTEE PRIVILEGE_x FROM USER_TAB_PRIVS WHERE GRANTEE not in (''MYUSER'',''PUBLIC'') AND TABLE_NAME=''' || ora_dict_obj_name || '''';
ELSE null;
END IF;
END;
As a result I get a table with all grants assigned to the said view. For restoring I wanted to run similar trigger:
create or replace TRIGGER RESTORE_GRANTS_AFTERCREATE
AFTER CREATE ON MYUSER.SCHEMA
BEGIN
IF ora_dict_obj_owner = 'MYUSER' and ora_dict_obj_type='VIEW' then
FOR loop_counter IN (select '''' || privilege_x || '''' AS privilege_x from temp_priv)
LOOP
EXECUTE IMMEDIATE loop_counter.privilege_x;
DBMS_OUTPUT.PUT_LINE(loop_counter.privilege_x);
END LOOP;
ELSE null;
END IF;
NULL;
END;
I will note here that is just basic test of concept without any proper checks, so just focus on the big issue here.
When I try to create a view now I get an error:
Error report -
ORA-00604: error occurred at recursive SQL level 1
ORA-00900: invalid SQL statement
ORA-06512: at line 5
00604. 00000 - "error occurred at recursive SQL level %s"
*Cause: An error occurred while processing a recursive SQL statement
(a statement applying to internal dictionary tables).
*Action: If the situation described in the next error on the stack
can be corrected, do so; otherwise contact Oracle Support.
This can only mean that the view is not created at the time when trigger tries to add grants. Syntax wise I successfully ran the command:
BEGIN
EXECUTE IMMEDIATE 'GRANT SELECT ON MYUSER.CR_STATUS_TABLE TO SOMEUSER';
END
But when I try to run it using for, or just by itself in 'after create' trigger I get the same error. Does anyone knows how to approach this, and I would like to avoid jobs at all costs if possible.