È 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.