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

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:

Dieser Beitrag wurde unter Multitenant, O-NF12C-DBA, TrivadisContent veröffentlicht. Setze ein Lesezeichen auf den Permalink.