Oracle
 sql >> Database >  >> RDS >> Oracle

Esegui DDL dinamico nella procedura PL/SQL tramite i permessi del ruolo di definizione

È possibile impostare un ruolo all'interno di una procedura/funzione memorizzata PL/SQL solo se dispone di Invoker's Rights (AUTHID CURRENT_USER )(vedi documento) . Ciò significa che non puoi utilizzare ops_user per chiamare la procedura di admin_user e quindi accedere ai ruoli di admin_user. Se i tuoi DBA insistono nell'usare un ruolo per controllare CREATE TABLE privilegio, ecco l'approccio che ho visto prima:

create or replace package admin_user.role_test authid current_user is
    procedure test_permissions;
end role_test;
/
create or replace package body admin_user.role_test is
    procedure test_permissions is
        v_query_string VARCHAR2(400 CHAR) := 'begin 
dbms_output.put_line(''after'');
for r in (select role from session_roles) loop 
    dbms_output.put_line(r.role); 
end loop;
end;';
    begin
        dbms_output.put_line('before');
        for r in (select role from session_roles) loop
            dbms_output.put_line(r.role);
        end loop;
        DBMS_SESSION.SET_ROLE('CREATE_TABLE_ROLE IDENTIFIED BY "SECRET_PASSWORD"');
        execute immediate v_query_string;
        DBMS_SESSION.SET_ROLE('ALL EXCEPT CREATE_TABLE_ROLE'); -- restore defaults
    end;
end role_test;
/
grant execute on admin_user.role_test to ops_user;

Questo concederà temporaneamente il ruolo a ops_user solo per eseguire il tuo codice. Per impostazione predefinita, ops_user non dovrebbe essere in grado di visualizzare l'origine del corpo del pacchetto di admin_user. Probabilmente potresti avvolgere il corpo del pacchetto per proteggere ulteriormente la password. Ma a parte la sicurezza delle password, la mia più grande preoccupazione con questo approccio è che Oracle non fornisce un bel modo per disabilitare un singolo ruolo, quindi se ops_user ha altri ruoli protetti da password, questo codice potrebbe generare un ORA-01979 quando tenta di ripristinare loro.

Quindi, c'è una risposta, ma consiglierei comunque di fare ciò che hanno suggerito gli altri commentatori e di concedere CREATE TABLE al tuo utente amministratore.