LOCKDOWN PROFILEを試す（Oracle Database 19c)

マルチテナント環境のOracle DatabaseでPDB管理者の権限を制限したい場合があります。特定のOracle Database機能を制限したい場合や、特定の初期化パラメーターの変更を抑止したい場合などです。例えばPDBにはCPU_COUNTの上限を決めたい、PARTITIONINGオプションは使用させたくない等が考えられます。Oracle DatabaseではLOCKDOWN PROFILEと呼ばれる機能でこの制限を行うことができます。

# LOCKDOWN PROFILEとは
LOCKDOWN PROFILEはCDBに管理者権限で接続して作成するオブジェクトです。全PDBで共通の制限を行うこともできますし、PDB単位で変更することができます。制限を行うリソースは以下の３種類が指定できます。

- FEATURE 
　Oracle Databaseの機能を指します。例えばAWS_ACCESS、JAVA、NETWORK_ACCESS, OS_ACCESS等が指定できます。詳しくは[マニュアル](https://docs.oracle.com/cd/F19136_01/sqlrf/ALTER-LOCKDOWN-PROFILE.html#GUID-B4029154-54A8-4B78-97C3-9CED416F1C34)を確認してください。

- OPTION
　Oracle Databaseの有償オプションを指します。DATABASE QUEUINGとPARTITIONINGを指定できます。DATABASE QUEUINGはAdvanced Queuingの機能を指します。

- STATEMENT
　SQL文を制限します。ALTER DATABASE文 / ALTER PLUGGABLE DATABASE文 / ALTER SESSION文 / ALTER SYSTEM文が制限できます。特定の初期化パラメーターのみ制限することもできますし、上限／下限を制限することもできます。

# LOCKDOWN PROFILEの作成と変更

作成にはCREAT LOCKDOWN PROFILE文で行います。全PDBで共通の制限を行うこともできますし、PDB単位で変更することができます。既存のLOCKDOWN PROFILEから新しいオブジェクトを作成することもできます。

```
SQL> CREATE LOCKDOWN PROFILE prof1;

ロックダウン・プロファイルが作成されました。
```

LOCKDOWN PROFILEに制限を付与するにはALTER LOCKDOWN PROFILE文を実行します。

```
SQL> ALTER LOCKDOWN PROFILE prof1 DISABLE FEATURE = ('AWR_ACCESS', 'NETWORK_ACCESS');

ロックダウン・プロファイルが変更されました。

SQL> ALTER LOCKDOWN PROFILE prof1 DISABLE OPTION = ('PARTITIONING');

ロックダウン・プロファイルが変更されました。

SQL> ALTER LOCKDOWN PROFILE prof1 DISABLE STATEMENT = ('ALTER SYSTEM') CLAUSE = ('SET') OPTION = ('CPU_COUNT') MAXVALUE = '2';

ロックダウン・プロファイルが変更されました。
```

上記の例ではまず、FEATUREとしてAWR_ACCESSとNETWORK_ACCESSを制限しています。AWRスナップショットの生成を禁止し、いくつかのネットワーク・プロトコルを利用するPL/SQLパッケージの実行を制限します。
次のALTER LOCKDOWN文ではPARTITIONINGオプションを無効にします。最後に初期化パラメーターCPU_COUNTの上限を2に制限しています。
　作成したLOCKDOWN PROFILEの情報はDBA_LOCKDOWN_PROFILEビューで確認できます。

```
SQL> SELECT RULE_TYPE, RULE, CLAUSE, CLAUSE_OPTION, MAX_VALUE, STATUS, USERS FROM DBA_LOCKDOWN_PROFILES WHERE PROFILE_NAME='PROF1';

RULE_TYPE  RULE                           CLAUSE               CLAUSE_OPT MAX_VALUE            STATUS     USERS
---------- ------------------------------ -------------------- ---------- -------------------- ---------- ------
FEATURE    AWR_ACCESS                                                                          DISABLE    ALL
FEATURE    NETWORK_ACCESS                                                                      DISABLE    ALL
OPTION     PARTITIONING                                                                        DISABLE    ALL
STATEMENT  ALTER SYSTEM                   SET                  CPU_COUNT  2                    DISABLE    ALL
```



# LOCKDOWN PROFILEの有効化
作成したLOCKDOWN PROFILEは初期化パラメータpdb_lockdownに名前を指定します。CDBの初期化パラメーターに指定した場合は全PDBで共通の制限になり、PDB単位で指定した場合はPDB毎の制限になります。

```
SQL> ALTER SYSTEM SET pdb_lockdown = PROF1;

システムが変更されました。
```

上記LOCKDOWN PROFILEの設定を行った場合、PDB管理者（PDBADMIN）にはALTER SYSTEM権限を付与している場合でも初期化パラメータCPU_COUNTの最大値を制限できます。下記の例ではCPU_COUNTを3に変更しようとして失敗していますが、2には変更できています。

```
SQL> SHOW CON_NAME;

CON_NAME
------------------------------
PDB1
SQL> ALTER SYSTEM SET cpu_count = 3;
ALTER SYSTEM SET cpu_count = 3
                          *
行1でエラーが発生しました。:
ORA-01031: 権限が不足しています

SQL> ALTER SYSTEM SET cpu_count = 2;

システムが変更されました。
```

LOCKDOWN PROFILEの制限は初期化パラメーターを変更した瞬間から有効になります。接続中のセッションに対しても制限が有効になります。

# OPTIONの設定
PARTITIONINGオプションを無効にするとCREATE TABLE文でパーティション・テーブルは作成できません。しかし、既存のパーティション・テーブルに対するALTER TABLE文や、SELECT文のPARTITION句は制限されません。以下の例では制限前に作成したPART1テーブルの操作は成功していますが、パーティション・テーブル（PART2）を新規に作成しようとして失敗しています。

```
SQL>  CREATE TABLE part2(c1 NUMBER, c2 VARCHAR2(10)) PARTITION BY LIST(c1)
  2   (
  3       PARTITION p1 VALUES (100),
  4       PARTITION p2 VALUES (200)
  5   );
 CREATE TABLE part2(c1 NUMBER, c2 VARCHAR2(10)) PARTITION BY LIST(c1)
                          *
行1でエラーが発生しました。:
ORA-00439: 機能は有効ではありません: Partitioning

SQL> SELECT * FROM part1 PARTITION (p1);

        C1 C2
---------- ----------
       100 data1

SQL> ALTER TABLE part1 DROP PARTITION p2;

表が変更されました。
```

# PDBADMINユーザーによる制限解除
PDB管理者（PDBADMIN）がPDB単位に指定された初期化パラメーターpdb_lockdownを変更することは自動的に制限されています。

```
SQL> SELECT USER FROM DUAL;

USER
--------------------------------------------------------------------------------
PDBADMIN

SQL> SHOW CON_NAME;

CON_NAME
------------------------------
PDB1
SQL> ALTER SYSTEM SET open_cursors = 500;

システムが変更されました。

SQL> ALTER SYSTEM SET pdb_lockdown = '';
ALTER SYSTEM SET pdb_lockdown = ''
*
行1でエラーが発生しました。:
ORA-01031: 権限が不足しています
```