Enabling Common Users to View Information about specific PDBs

Quando fui pensar em reproduzir este artigo, confesso que criei muita confusão com o recurso que tentarei demonstrar, e precisei assistir minhas aulas umas duas ou três vezes (do curso do Ahmed Baraka, link AQUI) , recorrer à documentação oficial da Oracle (link AQUI)e aos artigos do Tim Hall (link AQUI). Mas o bom disso é tentarmos aprender algo novo sempre, e é isso que faz do nosso trabalho algo desafiador e estimulante.

Quando criamos um common user em nosso ambiente Multitenant, nós usamos o parâmetro CONTAINER=ALL, que significa que aquele usuário está sendo criado em todos os containers (e naqueles que serão criados posteriormente). O mesmo conceito se refere ao conceder privilégios. Quando este valor é declarado, o privilégio é concedido em todos os containers. Caso precise de exemplo, demonstrei NESTE artigo. Até aqui, tudo bem. Observemos nosso usuário abaixo:

[oracle@quiasma ~]$ sqlplus / as sysdba
 
SQL*Plus: Release 18.0.0.0.0 - Production on Tue Apr 13 20:25:27 2021
Version 18.13.0.0.0
 
Copyright (c) 1982, 2018, Oracle.  All rights reserved.
 
 
Connected to:
Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production
Version 18.13.0.0.0
 
SQL> CREATE USER C##BRUNO2 IDENTIFIED BY oracle CONTAINER=ALL;
 
User created.
 
SQL> GRANT CREATE SESSION TO C##BRUNO2 CONTAINER=ALL;
 
Grant succeeded.
 
SQL> col username format a30
SQL> SELECT DISTINCT USERNAME,COMMON FROM CDB_USERS WHERE COMMON='YES' AND USERNAME LIKE '%BRUNO2%';
 
USERNAME                       COM
------------------------------ ---
C##BRUNO2                      YES

Concedendo privilégio na view v$datafile para todos os containers:

SQL> GRANT SELECT ON SYS.V_$DATAFILE TO C##BRUNO2 CONTAINER=ALL;
 
Grant succeeded.

Logado no root container com o usuário criado, percebemos que a consulta retornará apenas os datafiles do root container (que é o current), e não de todos os PDBs:

SQL> CONN C##BRUNO2/oracle
Connected.
SQL> SHOW USER;
USER is "C##BRUNO2"
SQL> SELECT name from v$datafile;
 
NAME
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/oracle/dados/TALAMO/datafile/o1_mf_system_j3w17w26_.dbf
/oracle/dados/TALAMO/datafile/o1_mf_sysaux_j3w1bkdm_.dbf
/oracle/dados/TALAMO/datafile/o1_mf_undotbs1_j3w1cyoh_.dbf
/oracle/dados/TALAMO/datafile/o1_mf_users_j3w1czy4_.dbf

Se quisermos ver os datafiles de algum outro PDB, precisaremos conectar no mesmo:

SQL> CONN C##BRUNO2/oracle@HIPOFISE1
Connected.
SQL> SHOW USER;
USER is "C##BRUNO2"
SQL> SELECT name from v$datafile;
 
NAME
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/oracle/dados/TALAMO/BFC37CDFCB3A0CF9E0536A00A8C0C9C5/datafile/o1_mf_system_j781yvm6_.dbf
/oracle/dados/TALAMO/BFC37CDFCB3A0CF9E0536A00A8C0C9C5/datafile/o1_mf_sysaux_j781yvmc_.dbf
/oracle/dados/TALAMO/BFC37CDFCB3A0CF9E0536A00A8C0C9C5/datafile/o1_mf_undotbs1_j781yvmc_.dbf
/oracle/dados/TALAMO/BFC37CDFCB3A0CF9E0536A00A8C0C9C5/datafile/o1_mf_users_j7824z91_.dbf

O cerne deste recurso está aqui: poder alterar nosso usuário para que possa consultar os dados de todos os containers caso queira, ou apenas algu container em específico, utilizando o parâmetro CONTAINER_DATA. Abaixo farei uma alteração em nossos usuário e definirei o valor deste parâmetro para ALL, que significa que todos os containers (inclusive os criados posteriormente) serão contemplados:

SQL> conn / as sysdba
Connected.
SQL> SHOW CON_ID CON_NAME
 
CON_ID
------------------------------
1
 
CON_NAME
------------------------------
CDB$ROOT
SQL> ALTER USER C##BRUNO2 SET CONTAINER_DATA=ALL FOR V_$DATAFILE CONTAINER=CURRENT;
 
User altered.

Realizando teste:

SQL> conn C##BRUNO2/oracle@TALAMO
Connected.
SQL> SHOW USER;
USER is "C##BRUNO2"
SQL> SELECT name from v$datafile;
 
NAME
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/oracle/dados/TALAMO/datafile/o1_mf_system_j3w17w26_.dbf
/oracle/dados/TALAMO/datafile/o1_mf_sysaux_j3w1bkdm_.dbf
/oracle/dados/TALAMO/datafile/o1_mf_undotbs1_j3w1cyoh_.dbf
/oracle/dados/TALAMO/datafile/o1_mf_system_j3w1q776_.dbf
/oracle/dados/TALAMO/datafile/o1_mf_sysaux_j3w1q76z_.dbf
/oracle/dados/TALAMO/datafile/o1_mf_users_j3w1czy4_.dbf
/oracle/dados/TALAMO/datafile/o1_mf_undotbs1_j3w1q779_.dbf
/oracle/dados/TALAMO/BFC37CDFCB3A0CF9E0536A00A8C0C9C5/datafile/o1_mf_system_j781yvm6_.dbf
/oracle/dados/TALAMO/BFC37CDFCB3A0CF9E0536A00A8C0C9C5/datafile/o1_mf_sysaux_j781yvmc_.dbf
/oracle/dados/TALAMO/BFC37CDFCB3A0CF9E0536A00A8C0C9C5/datafile/o1_mf_undotbs1_j781yvmc_.dbf
/oracle/dados/TALAMO/BFC37CDFCB3A0CF9E0536A00A8C0C9C5/datafile/o1_mf_users_j7824z91_.dbf
/oracle/dados/TALAMO/BFE3BC783DEA324EE0536A00A8C0486E/datafile/o1_mf_system_j7d9759c_.dbf
/oracle/dados/TALAMO/BFE3BC783DEA324EE0536A00A8C0486E/datafile/o1_mf_sysaux_j7d9759j_.dbf
/oracle/dados/TALAMO/BFE3BC783DEA324EE0536A00A8C0486E/datafile/o1_mf_undotbs1_j7d9759k_.dbf
 
14 rows selected.

Agora imaginemos que temos um common user que por algum motivo, não pode ter acesso à um PDB em específico. Com este recurso, podemos configurar o acesso aos outros PDBs, exceto aquele que não desejamos. Vejamos os PDBs que possuo em meu laboratório:

SQL> conn / as sysdba
Connected.
SQL> COL NAME FOR A40
SQL> SELECT NAME,OPEN_MODE,GUID FROM V$PDBS;
 
NAME                                     OPEN_MODE  GUID
---------------------------------------- ---------- --------------------------------
PDB$SEED                                 READ ONLY  BC8B772AA6A82204E0536B00A8C0CF6B
HIPOFISE1                                READ WRITE BFC37CDFCB3A0CF9E0536A00A8C0C9C5
HIPOFISE2                                READ WRITE BFE3BC783DEA324EE0536A00A8C0486E

Vamos simular que não queremos que nosso common user tenha acesso à v$datafile do PDB HIPOFISE2. Podemos realizar a seguinte alteração:

SQL> ALTER USER C##BRUNO2 SET CONTAINER_DATA=(CDB$ROOT, HIPOFISE1) FOR V_$DATAFILE CONTAINER=CURRENT;
 
User altered.

Percebemos que o usuário não consegue retornar as informações do PDB HIPOFISE2:

SQL> CONN C##BRUNO2/oracle@TALAMO
Connected.
SQL> COL NAME FOR A100
SQL> SELECT NAME FROM V$DATAFILE;
 
NAME
----------------------------------------------------------------------------------------------------
/oracle/dados/TALAMO/datafile/o1_mf_system_j3w17w26_.dbf
/oracle/dados/TALAMO/datafile/o1_mf_sysaux_j3w1bkdm_.dbf
/oracle/dados/TALAMO/datafile/o1_mf_undotbs1_j3w1cyoh_.dbf
/oracle/dados/TALAMO/datafile/o1_mf_users_j3w1czy4_.dbf
/oracle/dados/TALAMO/BFC37CDFCB3A0CF9E0536A00A8C0C9C5/datafile/o1_mf_system_j781yvm6_.dbf
/oracle/dados/TALAMO/BFC37CDFCB3A0CF9E0536A00A8C0C9C5/datafile/o1_mf_sysaux_j781yvmc_.dbf
/oracle/dados/TALAMO/BFC37CDFCB3A0CF9E0536A00A8C0C9C5/datafile/o1_mf_undotbs1_j781yvmc_.dbf
/oracle/dados/TALAMO/BFC37CDFCB3A0CF9E0536A00A8C0C9C5/datafile/o1_mf_users_j7824z91_.dbf
 
8 rows selected.

Para finalizar, caso precisemos consultar as configurações a nível de CONTAINER_DATA, podemos usar a query abaixo:

column username format a10 
column default_attr format a7 
column owner format a6 
column object_name format a11 
column all_containers format a3 
column container_name format a10 
column con_id format 999 
set pages 100 
set line 200 
SELECT USERNAME, DEFAULT_ATTR, OWNER, OBJECT_NAME, ALL_CONTAINERS, CONTAINER_NAME, CON_ID 
FROM CDB_CONTAINER_DATA WHERE username NOT IN ('GSMADMIN_INTERNAL', 'APPQOSSYS', 'DBSNMP') ORDER BY USERNAME;
SQL> CONN / AS SYSDBA
Connected.
SQL> column username format a10
column default_attr format a7
column owner format a6
column object_name format a11
column all_containers format a3
column container_name format a10
column con_id format 999
set pages 100
set line 200
SELECT USERNAME, DEFAULT_ATTR, OWNER, OBJECT_NAME, ALL_CONTAINERS, CONTAINER_NAME, CON_ID
FROM CDB_CONTAINER_DATA WHERE username NOT IN ('GSMADMIN_INTERNAL', 'APPQOSSYS', 'DBSNMP') ORDER BY USERNAME;SQL> SQL> SQL> SQL> SQL> SQL> SQL> SQL> SQL>   2
 
USERNAME   DEFAULT OWNER  OBJECT_NAME ALL CONTAINER_ CON_ID
---------- ------- ------ ----------- --- ---------- ------
C##BRUNO2  N       SYS    V_$DATAFILE N   CDB$ROOT        1
C##BRUNO2  N       SYS    V_$DATAFILE N   HIPOFISE1       1
C##BRUNO2  Y                          Y                   1
DBSFWUSER  Y                          Y                   1
SYS        Y                          Y                   1
SYSBACKUP  Y                          Y                   1
SYSDG      Y                          Y                   1
SYSRAC     Y                          Y                   1
SYSTEM     Y                          Y                   1
 
9 rows selected.

Obs: Este procedimento foi criado pelo senhor Ahmed Baraka (www.ahmedbaraka.com) e foi apenas reproduzido por mim em um laboratório pessoal para fins de aprendizado.

Leave a Comment

Your email address will not be published.