Oracle Multitenant – SYS*-Privilegien für Pluggable Datenbanken

30. Juni 2018 Aus Von Markus Flechtner

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.markusdba.local" 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.markusdba.local:1521/pdb01.markusdba.local

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.markusdba.loca:1521/pdb01.markusdba.local 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

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

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:

;

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?


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)?


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:


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:


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:

;

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)?


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:


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:


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:

;

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?


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)?


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:


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:


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:

Werbung (Amazon-Partner-Link)