Vous ne pouvez définir un rôle dans une procédure/fonction stockée PL/SQL que si elle dispose des droits de l'appelant (AUTHID CURRENT_USER
)(voir doc)
. Ce qui signifie que vous ne pouvez pas utiliser ops_user pour appeler la procédure d'admin_user, puis accéder aux rôles d'admin_user. Si vos DBA insistent pour utiliser un rôle pour contrôler la CREATE TABLE
privilège, voici l'approche que j'ai déjà vue :
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;
Cela accordera temporairement le rôle à ops_user juste pour exécuter votre code. Par défaut, l'ops_user ne doit pas être en mesure d'afficher la source du corps du package de l'admin_user. Vous pouvez probablement envelopper le corps du package pour mieux protéger le mot de passe. Mais à part la sécurité des mots de passe, ma plus grande préoccupation avec cette approche est qu'Oracle ne fournit pas un bon moyen de désactiver un seul rôle, donc si ops_user a d'autres rôles protégés par mot de passe, ce code peut déclencher un ORA-01979 lorsqu'il essaie de restaurer eux.
Donc, il y a une réponse, mais je recommanderais quand même de faire ce que les autres commentateurs ont suggéré et d'accorder CREATE TABLE à votre utilisateur administrateur.