1. Start
  2. Unternehmen
  3. Blog
  4. DBAs auf PDB-Ebene einrichten

DBAs auf PDB-Ebene einrichten

Im heutigen Blog geht es mal wieder um Multitenant, und um Security. Seit der Einführung von Multitenant und Pluggable Databases gibt es auch eine Art neuen Datenbanknutzer, den PDBADMIN. Genau der wird das Thema sein. Die Idee hinter diesem Nutzer ist, dass jede PDB einen eigenen Administrator haben soll, der diese PDB verwaltet. Wird eine neue leere PDB angelegt, muss zwingend dieser Benutzer definiert werden, wie man der Dokumentation entnehmen kann.

Wie zu sehen, können dem Administrator noch Rollen zugewiesen werden. Dieser Teil ist jedoch optional. 

Wie genau funktioniert das nun aber? Die Dokumentation bringt auch da Licht ins Dunkle.

ADMIN USER

Use this clause to create an administrative user who can be granted the privileges required to perform administrative tasks on the PDB. For admin_user_name, specify name of the user to be created. Use the IDENTIFIED BY clause to specify the password for admin_user_name. Oracle Database creates a local user in the PDB and grants the PDB_DBA local role to that user.

 

pdb_dba_roles

This clause lets you grant one or more roles to the PDB_DBA role. Use this clause to grant roles that have the privileges required by the administrative user of the PDB. For role, specify a predefined role. For a list of predefined roles, refer to Oracle Database Security Guide.

You can also use the GRANT statement to grant roles to the PDB_DBA role after the PDB has been created. Until you have granted the appropriate privileges to the PDB_DBA role, the SYS and SYSTEM users can perform administrative tasks on a PDB.

Heißt also, der Administratornutzer wird in der PDB angelegt und erhält immer die PDB_DBA Rolle zugewiesen.

An der Stelle muss noch erwähnt werden, dass man nicht immer einen PDB-Admin-Nutzer haben muss. Wird die PDB durch ein Cloning oder Plug einer non-CDB erstellt, dann existiert kein solcher Nutzer. Man kann bzw. sollte diesen dann aber im Zuge der Migration mit anlegen und ihm die PDB_DBA-Rolle geben. 

Was hat der Nutzer dann am Ende also nun für Berechtigungen, wenn man sonst keine weiteren Rollen angibt? 

 

SQL> create pluggable database ORCL12PDB3 admin user pdbadmin identified by "********";

Pluggable database created.

SQL> alter pluggable database ORCL12PDB3 open;

Pluggable database altered.

SQL> connect pdbadmin/********@vm160/orcl12pdb3.support.robotron.de
Connected.
SQL> select * from session_roles;

ROLE
--------------------------------------------------------------------------------
PDB_DBA

SQL> select * from session_privs;

PRIVILEGE
----------------------------------------
SET CONTAINER
CREATE PLUGGABLE DATABASE
CREATE SESSION

 

Im Grunde darf der PDBADMIN also praktisch nichts außer sich an der PDB anzumelden. Wir können dem Nutzer also an der Stelle nur nachträglich weitere Rechte geben in dem wir die nötigen Rechte entweder direkt an den Benutzer oder die Rolle PDB_ADMIN granten.

Besser ist es also, direkt beim Anlegen einer PDB die benötigten Rollen festzulegen. Es können eine oder auch mehrere Rollen angegeben werden, nicht aber Systemprivilegien. Diese müssen im Nachgang feingranular vergeben werden.

 

SQL> create pluggable database orcl12pdb2 admin user pdbadmin identified by "********" roles=(CONNECT, RESOURCE);

Pluggable database created.

SQL> alter  pluggable database orcl12pdb2 open;

Pluggable database altered.

SQL> connect pdbadmin/********@vm160/orcl12pdb2.support.robotron.de
Connected.
SQL> select * from session_roles;

ROLE
--------------------------------------------------------------------------------
CONNECT
RESOURCE
PDB_DBA
SODA_APP

SQL> select * from session_privs;

PRIVILEGE
----------------------------------------
CREATE SESSION
CREATE TABLE
CREATE CLUSTER
CREATE SEQUENCE
CREATE PROCEDURE
CREATE TRIGGER
CREATE TYPE
CREATE OPERATOR
CREATE INDEXTYPE
CREATE PLUGGABLE DATABASE
SET CONTAINER

11 rows selected.

 

Soll der PDBADMIN ein richtiger DBA werden, dann geben wir ihm natürlich die DBA-Rolle. Damit sollte der Nutzer dann vollumfänglich mit Rechten ausgestattet sein.

 

SQL> create pluggable database orcl12pdb1 admin user pdbadmin identified by "********" roles=(DBA);

Pluggable database created.

SQL> alter pluggable database orcl12pdb1 open;

Pluggable database altered.

SQL> connect pdbadmin/********@vm160/orcl12pdb1.support.robotron.de
Connected.
SQL> select * from session_roles;

ROLE
--------------------------------------------------------------------------------
DBA
PDB_DBA
SELECT_CATALOG_ROLE
EXECUTE_CATALOG_ROLE
CAPTURE_ADMIN
EXP_FULL_DATABASE
IMP_FULL_DATABASE
DATAPUMP_EXP_FULL_DATABASE
DATAPUMP_IMP_FULL_DATABASE
GATHER_SYSTEM_STATISTICS
OPTIMIZER_PROCESSING_RATE
EM_EXPRESS_BASIC
EM_EXPRESS_ALL
SCHEDULER_ADMIN
HS_ADMIN_SELECT_ROLE
HS_ADMIN_EXECUTE_ROLE
XDBADMIN
XDB_SET_INVOKER
WM_ADMIN_ROLE
JAVA_ADMIN
JAVA_DEPLOY
OLAP_XS_ADMIN
OLAP_DBA

23 rows selected.

SQL> select count(*) from session_privs;

  COUNT(*)
----------
       238

 

Einzige Einschränkung hierbei ist die Tatsache, dass der PDBADMIN sich eher wie SYSTEM in non-CDB Datenbanken verhält. Er ist eben nicht SYS und darf daher auch keine Rechte auf SYS-Objekte an andere Nutzer weitergeben, obwohl er "GRANT ANY" Privilegien besitzt. 

 

SQL> show user
USER is "PDBADMIN"
SQL> select * from session_privs where privilege like 'GRANT%';

PRIVILEGE
----------------------------------------
GRANT ANY ROLE
GRANT ANY PRIVILEGE
GRANT ANY OBJECT PRIVILEGE

SQL> grant execute on sys.dbms_lock to test;
grant execute on sys.dbms_lock to test
                     *
ERROR at line 1:
ORA-01031: insufficient privileges


SQL> grant select on sys.v_$session to test;
grant select on sys.v_$session to test
                    *
ERROR at line 1:
ORA-01031: insufficient privileges

 

An dieser Stelle kommt man also nicht umhin, den SYS-Benutzer zu bemühen, um die Rechte zu vergeben. Man kann die Rechte beispielsweise an den PDBADMIN geben und die Weitergabe an andere Nutzer erlauben. 

 

SQL> conn / as sysdba
Connected.
SQL> alter session set container=orcl12pdb1;

Session altered.

SQL> grant select on sys.v_$session to pdbadmin with grant option;

Grant succeeded.

SQL> grant execute on dbms_lock to pdbadmin with grant option;

Grant succeeded.

SQL> connect pdbadmin/********@vm160/orcl12pdb1.support.robotron.de
Connected.
SQL> grant execute on dbms_lock to test;

Grant succeeded.

SQL> grant select on sys.v_$session to test;

Grant succeeded.

 

Nur Objekte im SYS-Schema darf man mit dem PDBADMIN nach wie vor nicht anlegen. Manchmal braucht man das aber, z.B. für eine Password Verify Function, die im SYS-Schema liegen soll damit das Profile Zugriff darauf hat. Aber muss die Funktion tatsächlich im SYS-Schema liegen?

 

SQL> show user
USER is "PDBADMIN"
SQL> REM password verify function von Oracle im Schema PDBADMIN anlegen
SQL> @?/rdbms/admin/catpvf

SQL> create profile RDS_PROFILE limit password_verify_function  ORA12C_STIG_VERIFY_FUNCTION;

Profile created.

SQL> alter user test profile RDS_PROFILE;

User altered.

SQL> connect test/test@vm160/orcl12pdb1.support.robotron.de
Connected.
SQL> alter user test identified by "Test" replace "test";
alter user test identified by "Test" replace "test"
*
ERROR at line 1:
ORA-28003: password verification for the specified password failed
ORA-20001: Password length less than 15


SQL> alter user test identified by "G4nz_K0mpliziert!" replace "test";

User altered.

 

Offenbar funktioniert die Password Verify Function auch, wenn sie nich im SYS-Schema ist. Damit ist dieses Security Feature auch ohne Verwendung von SYS nutzbar. 

Am Ende kann man den PDBADMIN recht gut mit Rechten ausstatten um die täglichen administrativen Arbeiten in einer PDB zu übernehmen. Lediglich das Granten von Rechten auf SYS-Objekte wie Views oder Packages bleibt ein Thema. Hier wird zumindest zum initialen Setup der echte SYS-Nutzer benötigt. Das sollte in den meisten Fällen kein Problem sein, es sei denn, man hat keinen Zugriff darauf wie beispielsweise in der Autonomous Database in der Oracle Cloud. Dort erhält man nur einen PDBADMIN mit doch recht weitreichenden Berechtigungen. Hat Oracle daran gedacht?

 

SQL> show user
USER is "ADMIN"
SQL> show con_name

CON_NAME
------------------------------
PPA2OTADQX9XMML_MMIATP
SQL> select host_name from v$instance;

HOST_NAME
----------------------------------------------------------------


SQL> select owner, privilege, count(*) anz from dba_tab_privs where grantable='YES' and grantee=user group by owner, privilege
  2  order by 1,2;

OWNER                PRIVILEGE                                       ANZ
-------------------- ---------------------------------------- ----------
AUDSYS               EXECUTE                                           1
AUDSYS               READ                                              8
C##ADP$SERVICE       EXECUTE                                           6
C##ADP$SERVICE       READ                                             17
C##ADP$SERVICE       UNDER                                             1
C##CLOUD$SERVICE     EXECUTE                                       11168
C##CLOUD$SERVICE     READ                                             33
C##CLOUD$SERVICE     SELECT                                           17
CTXSYS               EXECUTE                                          10
CTXSYS               READ                                              4
CTXSYS               SELECT                                            1
DVSYS                SELECT                                            1
GSMADMIN_INTERNAL    EXECUTE                                          15
GSMADMIN_INTERNAL    READ                                              3
LBACSYS              EXECUTE                                          35
LBACSYS              READ                                             19
LBACSYS              SELECT                                           38
MDSYS                SELECT                                            1
OUTLN                SELECT                                            3
SYS                  EXECUTE                                        1313
SYS                  FLASHBACK                                        14
SYS                  READ                                           1695
SYS                  SELECT                                         4718
SYS                  USE                                               1
SYS                  WRITE                                             2
SYSTEM               READ                                              1
SYSTEM               SELECT                                            8
XDB                  DELETE                                            4
XDB                  EXECUTE                                          13
XDB                  INSERT                                            4
XDB                  READ                                              1
XDB                  SELECT                                            5
XDB                  UPDATE                                            3

33 rows selected.


SQL> create user test identified by "G4nz_K0mpliziert!";

User created.

SQL> grant create session to test;

Grant succeeded.

SQL> grant execute on dbms_lock to test;

Grant succeeded.

SQL> grant select on v$session to test;

Grant succeeded.

SQL> conn test/"G4nz_K0mpliziert!"@mmiatp_high
Connected.
SQL> show user
USER is "TEST"
SQL> show con_name

CON_NAME
------------------------------
PPA2OTADQX9XMML_MMIATP

SQL> select sid, username from v$session;

       SID USERNAME
---------- --------------------
     10457 TEST

SQL> set timing on
SQL> exec dbms_lock.sleep(10);

PL/SQL procedure successfully completed.

Elapsed: 00:00:10.04

 

Offenbar ja, den der ADMIN Benutzer in der PDB meiner Autonomous Database hat ganz offenbar zahlreiche Objektberechtigungen, die er auch weitergeben darf. Inwiefern die dann nützlich sind, ist ein anderes Thema, wie man an der Beispielabfrage auf V$SESSION sieht. 

Fazit: Man kann die Berechtiungen innerhalb der PDB recht gut steuern und einstellen, muss sich aber des Themas SYS-Objekt-Berechtigungen bewusst sein. Aber auch dieses Thema ist lösbar. Weiterhin sollte bei der Migration von non-CDBs immer direkt ein PDBADMIN-Nutzer eingerichtet werden um später darauf zurückgreifen zu können.

Update 09.12.2022

Heute gibt es noch ein Update zu dem oben beschriebenen Vorgehen. Unsere Kollegin Berit Richert hat das Thema Password Verify Function nochmals näher beleuchtet. Dabei hat sich herausgestellt, dass die verwendete Funktion ORA12C_STIG_VERIFY_FUNCTION bereits initial mit vorhanden ist. Daher kann man auch ein Profile mit dieser Funktion erstellen. Selbst definierte Password Verify Functions müssen aber im SYS-Schema liegen, das sagt auch die Dokumentation:

PASSWORD_VERIFY_FUNCTION

You can pass a PL/SQL password complexity verification script as an argument to CREATE PROFILE by specifying PASSWORD_VERIFY_FUNCTION. Oracle Database provides a default script, but you can write your own function or use third-party software instead.

For function, specify the name of the password complexity verification routine. The function must exist in the SYS schema and you must have EXECUTE privilege on the function.

Specify NULL to indicate that no password verification is performed.

Da führt auch leider kein Weg daran vorbei. Auch mit einem Public Synonym kann man das nicht umgehen, wir haben es getestet.

 

SQL> create or replace function rds_pw_verify(username in varchar2, password in varchar2, old_password in varchar2) return boolean
  2  is
  3  begin
  4    return false;
  5  end;
  6  /

Function created.

SQL> create profile RDS_PROFILE limit password_verify_function  rds_pw_verify;
create profile RDS_PROFILE limit password_verify_function  rds_pw_verify
*
ERROR at line 1:
ORA-07443: function RDS_PW_VERIFY not found


SQL> create public synonym rds_pw_verify for rds_pw_verify;

Synonym created.

SQL> create profile RDS_PROFILE limit password_verify_function  rds_pw_verify;
create profile RDS_PROFILE limit password_verify_function  rds_pw_verify
*
ERROR at line 1:
ORA-07443: function RDS_PW_VERIFY not found

 

 Es  bleibt also tatsächlich nur die Möglichkeit, als SYS eine Password Verify Function anzulegen. Möglicherweise ist das von Oracle auch so gewollt, damit die lokalen PDBADMINs nicht selbstständig das Securitylevel der Datenbank negativ beeinflussen können.

Kommentare

Keine Kommentare

Kommentar schreiben

* Diese Felder sind erforderlich