トップ > DBA上級 マルチテナント > 5章
5章 CDBでの権限管理
本章では権限の管理について学んで行きましょう。CDB、PDB上で権限の範囲が異なる為、しっかりと理解して行きましょう。

権限とロール


本章ではマルチコンテナデータベースの権限とロールの管理についてご紹介していきます。

マルチコンテナデータベースでの権限付与ではCONTAINER句があることが注意点です。
前回の章「CDB,PDBのユーザ」でもご紹介しましたが、CONTAINER句にはALL,CURRENTがあります。

[構文] CDBの権限付与
 SQL> GRANT 権限名 TO ユーザ名 [CONTAINER=ALL|CURRENT];

デフォルトはCURRENTであり、GRANTコマンドを実行したDBのみ権限を付与します。
ALLを指定した場合は、現在のCDB,PDBの他に、今後作成するPDBについても権限が有効になります。
またローカルユーザにはCONTAINER=ALLで権限付与はエラーになります。

  SQL> grant resource to local_user container = all;
  grant resource to local_user container = all
  *
  ERROR at line 1:
  ORA-65030: one may not grant a Common Privilege to a Local User or Role


では共通ユーザのC##COMM_USERにCREATE SESSION権限を付与してみます。

  SQL> show user
  
  USER is "SYS"

  SQL> show con_name

  CON_NAME
  ------------------------------
  CDB$ROOT

  SQL> select * from dba_sys_privs
    2  where grantee in ('C##COMM_USER') order by grantee;

  no rows selected

  SQL> grant create session to c##comm_user container = current;

  Grant succeeded.

  SQL> select * from dba_sys_privs
    2  where grantee in ('C##COMM_USER') order by grantee;

  GRANTEE         PRIVILEGE                                ADM COM
  --------------- ---------------------------------------- --- ---
  C##COMM_USER    CREATE SESSION                           NO  NO


  SQL> conn c##comm_user/comm_user
  Connected.

  SQL> show user
  USER is "C##COMM_USER"

  SQL> conn c##comm_user/comm_user@pdb1
  
  ERROR:
  ORA-01045: user C##COMM_USER lacks CREATE SESSION privilege; logon denied


  Warning: You are no longer connected to ORACLE.


例ではCONTAINER句にCURRENTを指定して付与している為、
共通ユーザ(C##COMM_USER)はルートDB(CDB)のみログインが出来ます。
そのため、PDB1にログインしようとしてもエラーとなります。

  SQL> grant create session to c##comm_user container = all;

  Grant succeeded.

  SQL> select * from dba_sys_privs
    2  where grantee in ('C##COMM_USER') order by grantee;

  GRANTEE         PRIVILEGE                                ADM COM
  --------------- ---------------------------------------- --- ---
  C##COMM_USER    CREATE SESSION                           NO  YES
  C##COMM_USER    CREATE SESSION                           NO  NO


  SQL> conn c##comm_user/comm_user@pdb1
  Connected.

  SQL> select * from user_sys_privs
    2  where username in ('C##COMM_USER') order by username;

  USERNAME
  --------------------------------------------------------------------------------
  PRIVILEGE                                ADM COM
  ---------------------------------------- --- ---
  C##COMM_USER
  CREATE SESSION                           NO  YES


例ではCONTAINER句にALLを指定して付与している為、共通ユーザ(C##COMM_USER)はルートDB(CDB)だけでなくその他のPDBにも接続が可能です。
また権限の確認をしていますが、今回2行表示されています。

CREATE SESSION権限は同じでもCONTAINER=ALL,CONTAINER=CURRENTで付与した場合、別々の権限としてみなされるようです。
またPDB1でも権限を確認していますが、CONTAINER=ALLで付与した権限のみ表示されています。
CONTAINER=ALLで付与した権限はCOMMON列にYESと表示されます。

ではローカルユーザ(PDB1,PDB2)のLOCAL_USERにCREATE SESSION権限を付与してみます。

  SQL> show con_name

  CON_NAME
  ------------------------------
  CDB$ROOT

  SQL> select * from dba_sys_privs
    2  where grantee in ('LOCAL_USER') order by grantee;

  no rows selected

  SQL> grant create session to local_user;
  grant create session to local_user
                          *
  ERROR at line 1:
  ORA-01917: user or role 'LOCAL_USER' does not exist


  SQL> grant create session to local_user container = all;
  grant create session to local_user container = all
                          *
  ERROR at line 1:
  ORA-01917: user or role 'LOCAL_USER' does not exist


ローカルユーザはルートDB(CDB$ROOT)への権限付与は許可されていない為、
エラーとなりました。では次にPDBに接続して権限を付与してみましょう。

  SQL> alter session set container = pdb1;

  Session altered.

  SQL> show con_name

  CON_NAME
  ------------------------------
  PDB1

  SQL> grant create session to local_user container = all;
  grant create session to local_user container = all
  *
  ERROR at line 1:
  ORA-65030: one may not grant a Common Privilege to a Local User or Role

  SQL> grant create session to local_user;

  Grant succeeded.

  SQL> select * from dba_sys_privs
    2  where grantee in ('LOCAL_USER') order by grantee;

  GRANTEE         PRIVILEGE                                ADM COM
  --------------- ---------------------------------------- --- ---
  LOCAL_USER      CREATE SESSION                           NO  NO

  SQL> conn local_user/local_user@pdb1
  Connected.

  SQL> show con_name

  CON_NAME
  ------------------------------
  PDB1



CONTAINER=ALLではエラーとなりましたが、デフォルトCONTAINER=CURRENTでは付与が成功しました。

SET CONTAINER権限



SET CONTAINER権限は別のPDBへ接続する為の権限です。
別PDBへの切替は以下のコマンドで実施します。

  SQL> ALTER SESSION SET CONTAINER = PDB名;



ロールの管理


次にロールについてご紹介していきます。
ロールもユーザと同様、共通ロール、ローカルロールの2種類が存在します。

共通ロール
ルートDB(CDB$ROOT)およびその他のPDB上に作成されるロール。
ルートDB(CDB$ROOT)でのみ作成可能接頭辞はC##で始まる必要がある。

ローカルロール
PDBで作成し、その作成したPDBのみに存在するロール

注意点は以下のとおりです。
・共通ユーザーは、共通ロールを作成して、他の共通ユーザーおよび
 ローカル・ユーザーに付与できます。

・ロール(ローカルまたは共通)は、ローカル・ユーザーまたはロールに
 対してローカルに付与できます。

・共通ロールをローカルに付与する場合、その共通ロールの権限は、
 ロールが付与されるコンテナ内にのみ適用されます。

・ローカル・ユーザーは共通ロールを作成できませんが、共通ユーザーおよびロール
 他のローカル・ユーザーに共通ロールを付与できます

・共通ロールをCDBルートまたはアプリケーション・ルートで作成する場合、
 CONTAINER = ALL句がデフォルトです。


共通ロールの作成


共通ロールはルートDB上で作成する必要があり接頭辞はC##が必要です。

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

  CON_NAME
  ------------------------------
  CDB$ROOT

  SQL> CREATE ROLE c##comm_role;
  
  SQL> GRANT dba TO c##comm_role;

  SQL> SELECT role,common FROM dba_roles WHERE role = 'C##COMM_ROLE';

  ROLE                           COM
  ------------------------------ ---
  C##COMM_ROLE                   YES


  SQL> SELECT * FROM dba_role_privs WHERE grantee = 'C##COMM_ROLE';

  GRANTEE              GRANTED_ROLE         ADM DEF COM
  -------------------- -------------------- --- --- ---
  C##COMM_ROLE         DBA                  NO  YES NO


GRANTコマンドのCONTAINER句はデフォルトCURRENTでした。
その為、ルートDBのみDBAロールを共通ロールに付与しています。
次にPDB1にログインし、共通ロールに権限を付与します。

  SQL> alter session set container = pdb1;

  Session altered.

  SQL> SELECT * FROM dba_role_privs WHERE grantee = 'C##COMM_ROLE';

  no rows selected

  SQL> show con_name

  CON_NAME
  ------------------------------
  PDB1

  SQL> SELECT * FROM dba_role_privs WHERE grantee = 'C##COMM_ROLE';

  no rows selected

  SQL> GRANT create user,drop user to C##COMM_ROLE;

  Grant succeeded.

  SQL> SELECT * FROM role_sys_privs where role = 'C##COMM_ROLE';

  ROLE                           PRIVILEGE                                ADM COM
  ------------------------------ ---------------------------------------- --- ---
  C##COMM_ROLE                   DROP USER                                NO  NO
  C##COMM_ROLE                   CREATE USER                              NO  NO


PDB1でCREATE ROLE、DROP ROLE権限を付与しました。
このように共通ロールは各DBごとに権限を割り当てることが出来ます。


ローカルロールの作成


ローカルロールは特にいつもの作成方法と変わりはありません。

  SQL> show con_name

  CON_NAME
  ------------------------------
  PDB1

  SQL> CREATE ROLE LOCAL_ROLE;

  Role created.

  SQL> GRANT create session TO local_role;

  Grant succeeded.

  SQL> SELECT * FROM role_sys_privs WHERE role = 'LOCAL_ROLE';

  ROLE                           PRIVILEGE                                ADM COM
  ------------------------------ ---------------------------------------- --- ---
  LOCAL_ROLE                     CREATE SESSION                           NO  NO


ちなみにローカルロールに対し、CONTAINER=ALLはエラーとなります。

  SQL> GRANT SELECT ANY DICTIONARY TO LOCAL_USER CONTAINER = ALL;
  GRANT SELECT ANY DICTIONARY TO LOCAL_USER CONTAINER = ALL
  *
  ERROR at line 1:
  ORA-65030: one may not grant a Common Privilege to a Local User or Role


ローカルロールを共通ロールに付与することも可能です。

  SQL> GRANT LOCAL_ROLE TO C##COMM_ROLE;

  Grant succeeded.

  SQL> SELECT * FROM dba_role_privs WHERE grantee = 'C##COMM_ROLE';

  GRANTEE              GRANTED_ROLE         ADM DEF COM
  -------------------- -------------------- --- --- ---
  C##COMM_ROLE         LOCAL_ROLE           NO  YES NO


ちなみにローカルロールをCONTAINER=ALLで付与はできません。

  SQL> REVOKE LOCAL_ROLE FROM C##COMM_ROLE;

  Revoke succeeded.

  SQL> GRANT LOCAL_ROLE TO C##COMM_ROLE CONTAINER = ALL;
  GRANT LOCAL_ROLE TO C##COMM_ROLE CONTAINER = ALL
  *
  ERROR at line 1:
  ORA-65032: a Local Role may only be granted or revoked within the current
  Container


逆に共通ロールをローカルロールに付与することもできますがCONTAINER=CURRENTのみです。

  SQL> GRANT C##COMM_ROLE TO LOCAL_ROLE;

  Grant succeeded.

  SQL> REVOKE C##COMM_ROLE FROM LOCAL_ROLE;

  Revoke succeeded.

  SQL> GRANT C##COMM_ROLE TO LOCAL_ROLE CONTAINER = ALL;
  GRANT C##COMM_ROLE TO LOCAL_ROLE CONTAINER = ALL
  *
  ERROR at line 1:
  ORA-65030: one may not grant a Common Privilege to a Local User or Role


上記のように共通ロールに対しCONTAINER = ALLで付与するとエラーとなります。


ユーザへのロール付与


ロールの付与に関しては特に制限はありません。
共通ロール、ローカルロールは共通ユーザ、ローカルユーザに付与が可能です。

  SQL> GRANT LOCAL_ROLE TO C##COMM_USER;

  Grant succeeded.

  SQL> GRANT C##COMM_ROLE TO LOCAL_ROLE;

  Grant succeeded.


共通ロールをローカルユーザに、ローカルロールを共通ユーザに付与が出来ました。

以上がロールの管理方法となります。いかかでしたでしょうか。通常のロールと変わりはありませんでした。