Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Führen Sie dynamische DDL in PL/SQL-Prozeduren durch Definierer-Rollenberechtigungen aus

Sie können innerhalb einer gespeicherten PL/SQL-Prozedur/Funktion nur dann eine Rolle festlegen, wenn sie über Aufruferrechte verfügt (AUTHID CURRENT_USER )(siehe Dokument) . Das bedeutet, dass Sie ops_user nicht verwenden können, um die Prozedur von admin_user aufzurufen und dann auf die Rollen von admin_user zuzugreifen. Wenn Ihre DBAs darauf bestehen, eine Rolle zur Steuerung von CREATE TABLE zu verwenden Privileg, hier ist der Ansatz, den ich zuvor gesehen habe:

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;

Dadurch wird ops_user vorübergehend die Rolle zugewiesen, nur um Ihren Code auszuführen. Standardmäßig sollte der ops_user nicht in der Lage sein, die Pakettextquelle des admin_user anzuzeigen. Sie könnten den Paketkörper wahrscheinlich umschließen, um das Kennwort weiter zu schützen. Abgesehen von der Passwortsicherheit besteht meine größte Sorge bei diesem Ansatz darin, dass Oracle keine gute Möglichkeit bietet, eine einzelne Rolle zu deaktivieren. Wenn ops_user also andere passwortgeschützte Rollen hat, kann dieser Code beim Wiederherstellungsversuch einen ORA-01979 auslösen sie.

Es gibt also eine Antwort, aber ich würde dennoch empfehlen, das zu tun, was die anderen Kommentatoren vorgeschlagen haben, und Ihrem Administratorbenutzer CREATE TABLE zu gewähren.