In einer Container-Datenbank können SYSDBA-, SYSOPER-Rechte etc. auf PDB-Ebene vergeben werden. Dies ermöglicht es, PDB-Administratoren mit ihren lokalen Rechten eine PDB zu öffnen oder zu schließen. Wie funktioniert das und wo werden diese Privilegien-Informationen gespeichert?
English translation of this post
Vergabe von SYS*-Rechten auf PDB-Ebene
SQL> show user USER is "SYS" SQL> alter session set container=PDB01; Session altered. SQL> create user localadmin identified by manager; User created. SQL> grant sysdba to localadmin; Grant succeeded.
Fertig.
Anmerkung: Voraussetzung dafür ist eine Password-Datei im Oracle 12c-Format. Dazu muss eine Password-Datei mit dem Parameter „format=..“ angelegt werden. Zur Auswahl stehen „12c“ und „12.2“. Wenn man „12.2“ wählt, dann werden die Passworte auch gegen Komplexitätsregeln geprüft (siehe auch MOS-Note 2294754.1). Vorhandene Password-Dateien im älteren Format können in das neue Format konvertiert werden (siehe auch MOS-Note 2112456.1).
Jetzt schließen wir die PDB und öffnen sie wieder als LOCALADMIN:
Öffnen einer PDB als lokaler SYSDBA
Auch wenn die PDB geschlossen ist, ist der Default-Service der PDB immer noch beim Listener registriert:
SQL> host lsnrctl status LSNRCTL for Linux: Version 12.2.0.1.0 - Production on 27-JUN-2018 19:15:39 Copyright (c) 1991, 2016, Oracle. All rights reserved. Connecting to (ADDRESS=(PROTOCOL=IPC)(KEY=LISTENER)) STATUS of the LISTENER ------------------------ Alias LISTENER Version TNSLSNR for Linux: Version 12.2.0.1.0 - Production Start Date 27-JUN-2018 19:09:37 [..] Service "pdb01.trivadistraining.com" has 1 instance(s). Instance "TVDCDB1", status READY, has 1 handler(s) for this service... [..]
Dadurch kann sich ein lokaler (PDB)-SYSDBA an die PDB anmelden. Applikationen (genauer: Nicht-SYSDBA/SYSOPER-Anmeldungen) können sich nicht an die PDB anmelden:
SQL> connect localadmin/manager@omt.trivadistraining.com:1521/pdb01.trivadistraining.com ERROR: ORA-01033: ORACLE initialization or shutdown in progress Process ID: 0 Session ID: 0 Serial number: 0 Warning: You are no longer connected to ORACLE.
Die Anmeldung als SYSDBA funktioniert:
SQL> connect localadmin/manager@omt.trivadistraining.com:1521/pdb01.trivadistraining.com as sysdba Connected. SQL> alter database open; Database altered. SQL> show pdbs CON_ID CON_NAME OPEN MODE RESTRICTED ---------- ------------------------------ ---------- ---------- 7 PDB01 READ WRITE NO
Wo wird nun die Information über die SYSDBA-Rechte gespeichert?
SQL> connect / as sysdba Connected. SQL> select con_id,username,sysdba from v$pwfile_users; CON_ID USERNAME SYSDB ---------- ------------------------- ----- 0 SYS TRUE 1 SYSDG FALSE 1 SYSBACKUP FALSE 1 SYSKM FALSE 7 LOCALADMIN TRUE
Anscheinend befindet sich die Information in der Password-Datei. Schauen wir uns die Password-Datei einmal genauer an:
SQL> host ls -ltr $ORACLE_HOME/dbs/orapw* lrwxrwxrwx. 1 oracle oinstall 48 Mar 10 2017 /u00/app/oracle/product/12.2.0.1/dbs/orapwTVDCDB1 -> /u00/app/oracle/admin/TVDCDB1/pfile/orapwTVDCDB1 SQL> host ls -ltr /u00/app/oracle/admin/TVDCDB1/pfile/orapwTVDCDB1 -rw-r-----. 1 oracle oinstall 5632 Apr 1 18:42 /u00/app/oracle/admin/TVDCDB1/pfile/orapwTVDCDB1 SQL> host strings /u00/app/oracle/admin/TVDCDB1/pfile/orapwTVDCDB1 ]\[Z ORACLE Remote Password file ( yr {#Z SYSDG 9pVQ\ SYSBACKUP nk{^ SYSKM EuU[ DE\o
Der Benutzer LOCALADMIN erscheint also in der V$PWFILE_USERS aber die Information wird offensichtlich nicht in der Password-Datei abgelegt.
Es gibt aber eine Data Dictionary View, die diese Informationen enthält:
SQL> desc CDB_LOCAL_ADMIN_PRIVS Name Null? Type ----------------------------------------- -------- ---------------------------- CON_ID NOT NULL NUMBER CON_NAME NOT NULL VARCHAR2(128) GRANTEE NOT NULL VARCHAR2(128) SYSDBA VARCHAR2(5) SYSOPER VARCHAR2(5) SYSASM VARCHAR2(5) SYSBACKUP VARCHAR2(5) SYSDG VARCHAR2(5) SYSKM VARCHAR2(5) SQL> column con_name format a30 SQL> column grantee format a30 SQL> select con_id,con_name,grantee,sysdba from CDB_LOCAL_ADMIN_PRIVS 2 order by con_id; CON_ID CON_NAME GRANTEE SYSDB ---------- ------------------------------ ------------------------------ ----- 7 PDB01 LOCALADMIN TRUE
Diese Konfiguration ist sinnvoll: Die Passwort-Datei wird benötigt, um einen Benutzer zu authentifizieren, wenn die Container-Datenbank nicht geöffnet ist. Wenn Sie sich aber als SYSDBA mit einer PDB verbinden wollen, um die PDB zu öffnen, muss zumindest die CDB$ROOT geöffnet sein. Damit ist das Dat Dictiomary der CDB$ROOT zugänglich. Das Speichern der Informationen außerhalb der Datenbank (in einer Passwort-Datei) ist nicht erforderlich.
Hinweis: CDB_LOCAL_ADMIN_PRIVS wird im 12.1 Security Guide (https://docs.oracle.com/database/121/DBSEG/authorization.htm#BEGIN) erwähnt; ist aber nicht in der Oracle 12.2 Referenz dokumentiert.
Wenn man sich die Definition der View CDB_LOCAL_ADMIN_PRIVS anschaut, dann stellt man fest, dass sie auf der Tabelle CDB_LOCAL_ADMINAUTH$ beruht:
SQL> desc cdb_local_adminauth$ Name Null? Type —————————————– ——– —————————- CON_UID NOT NULL NUMBER GRANTEE$ NOT NULL VARCHAR2(128) PRIVILEGES NOT NULL NUMBER PASSWD NOT NULL VARCHAR2(4000) FLAGS NOT NULL NUMBER SPARE1 NUMBER SPARE2 VARCHAR2(128) LCOUNT NUMBER ASTATUS NUMBER EXPTIME DATE LTIME DATE LSLTIME DATE PASSWD_PROFILE VARCHAR2(128) PASSWD_LIMIT VARCHAR2(4000) FED_PRIVILEGES NOT NULL NUMBER EXT_USERNAME VARCHAR2(4000)
Und dort gibt es auch unseren Benutzer LOCALADMIN:
SQL> show con_name CON_NAME ------------------------------ CDB$ROOT SQL> column grantee$ format a30 SQL> select con_uid,grantee$ from CDB_LOCAL_ADMINAUTH$; CON_UID GRANTEE$ ---------- ------------------------------ 1343596567 LOCALADMIN
Wie wird die Tabelle CDB_LOCAL_ADMINAUTH$ gespeichert?
SQL> select con_id,owner,object_type,sharing from cdb_objects 2 where object_name='CDB_LOCAL_ADMINAUTH$'; CON_ID OWNER OBJECT_TYPE SHARING ---------- ---------- ----------------------- ------------------ 1 SYS TABLE METADATA LINK 5 SYS TABLE METADATA LINK 3 SYS TABLE METADATA LINK 4 SYS TABLE METADATA LINK
Es ist also eine Metadata-Linked-Tabelle, d.h. die Definition liegt im CDB$ROOT und die Daten liegen im jeweiligen Container.
In welchen Containern sind nun Daten gespeichert?
SQL> select con_id from cdb_segments where segment_name='CDB_LOCAL_ADMINAUTH$'; CON_ID ---------- 1
Effektiv werden Daten also nur im Root-Container CDB$ROOT gespeichert. Wie erwartet.
Was passiert nun, wenn wir die PDB aushängen (UNPLUG) und in eine andere CDB wieder einhängen (PLUG)?
SQL> alter pluggable database pdb01 close; Pluggable database altered. SQL> alter pluggable database PDB01 unplug into '/home/oracle/pdb01.xml'; Pluggable database altered. SQL> select con_uid,grantee$ from CDB_LOCAL_ADMINAUTH$; CON_UID GRANTEE$ ---------- ------------------------------ 1343596567 LOCALADMIN SQL> drop pluggable database pdb01 keep datafiles; Pluggable database dropped. SQL> select con_uid,grantee$ from CDB_LOCAL_ADMINAUTH$; no rows selected
Nachdem wir die PDN gedroppt haben, ist auch der Datensatz in CDB_LOCAL_ADMINAUTH$ gelöscht.
Werfen wir nun einen Blick in die Manifest-Datei:
SQL> host grep -i LOCALADMIN /home/oracle/pdb01.xml SQL> host grep -i SYSDBA /home/oracle/pdb01.xml
Es gibt also keine Information zum LOCALADMIN und seinen SYSDBA-Rechten in der XML-Datei.
Jetzt hängen wir die PDB in eine andere CDB ein:
SQL> select con_uid,grantee$ from CDB_LOCAL_ADMINAUTH$; no rows selected SQL> create pluggable database PDB01 using '/home/oracle/pdb01.xml'; Pluggable database created. SQL> select con_uid,grantee$ from CDB_LOCAL_ADMINAUTH$; no rows selected SQL> alter pluggable database PDB01 open; Pluggable database altered. SQL> column grantee$ format a30 SQL> select con_uid,grantee$ from CDB_LOCAL_ADMINAUTH$; CON_UID GRANTEE$ ---------- ------------------------------ 245011485 LOCALADMIN
Der Benutzer LOCALADMIN hat also wieder seine SYSDBA-Rechte.
Es scheint also so, dass die Information über die SYSDBA-Rechte beim Aushängen vom CDB$ROOT in die PDB geschrieben wird und dann später – wenn die PDB in eine andere CDB eingehängt wird – von der PDB in den Root-Container der neuen CDB zurückgeschrieben wird.
Links:
- Administrative privileges like SYSDBA – https://laurentschneider.com/wordpress/2017/11/administrative-privileges-like-sysdba.html
- OraFaq Forum: PDB SYSOPER/SYSDBA privileges – http://httpw.orafaq.net/forum/m/665902/