Oracle Database 12cの新機能である権限分析(Privilege Analysis)機能を試します(実行はOracle Database 19c)。アプリケーション・ユーザーが使用している権限をキャプチャし、必要な権限と不要な権限を視覚化するための機能です。
この機能の利用には従来 Database Vault オプションが必要でしたが、Oracle Database 18c から Enterprise Edition の標準ライセンスで利用できるようになりました。
準備
ここではアプリケーション用のユーザーを作成し、いくつか権限を付与ます。既存のアプリケーションでテストする場合は当然不要です。
SQL> CREATE USER priv1 IDENTIFIED BY priv1 DEFAULT TABLESPACE USERS TEMPORARY TABLESPACE temp;
ユーザーが作成されました。
SQL> GRANT CREATE SESSION, CREATE TABLE, UNLIMITED TABLESPACE, CREATE SEQUENCE, CREATE PROCEDURE TO priv1;
権限付与が成功しました。
DBMS_PRIVILEGE_CAPTURE.CREATE_CAPTUREプロシージャを実行して、権限のキャプチャを行う準備をします。name パラメーターには一意な名前、typeパラメーターには取得するタイプを指定します。
このプロシージャはCAPTURE_ROLEロールを持ったユーザーが実行します。
typeパラメータ | 説明 |
---|---|
G_DATABASE | データベース全体のキャプチャ (SYS以外) |
G_ROLE | 特定のロールをキャプチャ |
G_CONTEXT | 特定のコンテキストの評価式がTRUEになる場合にキャプチャ |
G_ROLE_AND_CONTEXT | 特定のコンテキストの評価式がTRUEになり、指定したロール内の場合にキャプチャ |
descriptionパラメーターにはコメントを記述することができます。roles オプションや context オプションは、typeパラメーターにG_ROLEやG_CONTEXTを指定した時に必要です。
下記の例ではタイプにG_DATABASEを指定してポリシーを作成しています。実際にキャプチャを開始するにはDBMS_PRIVILEGE_CAPTURE.ENABLE_CAPTURE
プロシージャを実行します。
状態の確認はDBA_PRIV_CAPTURESビューを参照しますが、ENABLE_CAPTUREプロシージャとDISABLE_CAPTUREプロシージャを実行する度にレコードが追加されていきます。
SQL> EXEC DBMS_PRIVILEGE_CAPTURE.CREATE_CAPTURE(name=>'db1', type=>DBMS_PRIVILEGE_CAPTURE.G_DATABASE);
PL/SQLプロシージャが正常に完了しました。
SQL> EXEC DBMS_PRIVILEGE_CAPTURE.ENABLE_CAPTURE('db1');
PL/SQLプロシージャが正常に完了しました。
SQL> SELECT NAME, TYPE, ENABLED FROM DBA_PRIV_CAPTURES;
NAME TYPE E
-------------------- -------------------- -
db1 DATABASE Y
ORA$DEPENDENCY DATABASE N
SQL>
アプリケーションの実行
権限のキャプチャが開始されてからアプリケーションを実行します。使用された権限がSYSAUX表領域内に格納されます。下記の例では自動採番列を持ったテーブルの作成、レコードの挿入だけを実行しています。
$ sqlplus priv1/priv1
SQL*Plus: Release 19.0.0.0.0 - Production on 水 10月 9 23:47:02 2019
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle. All rights reserved.
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0
に接続されました。
SQL> CREATE TABLE gen1 (id NUMBER GENERATED ALWAYS AS IDENTITY, val VARCHAR2(10)) ;
表が作成されました。
SQL> INSERT INTO gen1(val) VALUES ('data1');
1行が作成されました。
SQL> COMMIT;
コミットが完了しました。
SQL>
レポート作成
キャプチャが完了したらDBMS_PRIVILEGE_CAPTURE.GENERATE_RESULTプロシージャを実行します。DBMS_PRIVILEGE_CAPTURE.DISABLE_CAPTUREプロシージャによりキャプチャを無効にしないとこのプロシージャは実行できません。
DBMS_PRIVILEGE_CAPTURE.GENERATE_RESULTプロシージャを実行すると、DBA_USED_{PRIVS|SYSPRIVS|OBJPRIVS} ビュー、DBA_UNUSED_{PRIVS|SYSPRIVS|OBJPRIVS} ビューから使用した(または使用しなかった)権限を確認することができるようになります。
これらのビューの検索もはCAPTURE_ROLEロール持ったユーザーが実行します。
SQL> EXEC DBMS_PRIVILEGE_CAPTURE.GENERATE_RESULT('db1');
BEGIN DBMS_PRIVILEGE_CAPTURE.GENERATE_RESULT('db1'); END;
*
行1でエラーが発生しました。:
ORA-47932: 権限の取得db1は有効化されています。 ORA-06512:
"SYS.DBMS_PRIVILEGE_CAPTURE", 行61
ORA-06512: 行1
SQL> EXEC DBMS_PRIVILEGE_CAPTURE.DISABLE_CAPTURE('db1');
PL/SQLプロシージャが正常に完了しました。
SQL> EXEC DBMS_PRIVILEGE_CAPTURE.GENERATE_RESULT('db1');
PL/SQLプロシージャが正常に完了しました。
SQL> SELECT SYS_PRIV, OBJ_PRIV, USER_PRIV, OBJECT_OWNER, OBJECT_NAME FROM DBA_USED_PRIVS WHERE CAPTURE='db1';
SYS_PRIV OBJ_PRIV USER_PRIV OBJECT_OWNER OBJECT_NAME
-------------------- -------------------- ------------------------- ------------------------------ ------------------------------
CREATE SEQUENCE
UNLIMITED TABLESPACE
EXECUTE SYS DBMS_APPLICATION_INFO
CREATE SESSION
SELECT SYS DUAL
EXECUTE SYS DBMS_STANDARD
CREATE TABLE
7行が選択されました。
SQL> SELECT SYS_PRIV, USER_PRIV, OBJ_PRIV, OBJECT_OWNER, OBJECT_NAME FROM DBA_UNUSED_PRIVS WHERE CAPTURE='db1' AND USERNAME='PRIV1';
SYS_PRIV USER_PRIV OBJ_PRIV OBJECT_OWNER OBJECT_NAME
-------------------- ------------------------- -------------------- ------------------------------ ------------------------------
CREATE PROCEDURE
接続時にCREATE SESSIONシステム権限が使用されています。これ以外のシステム権限としてテーブルの作成(CREATE TABLE)と自動採番列の内部で使われるCREATE SEQUENCE権限の使用が出力されています。またクオータ設定が無い表領域内のテーブルに対してレコードを格納したため、UNLIMITED TABLESPACEシステム権限が使用されています。
DBMS_APPLICATION_INFOパッケージ、DUALテーブルに対するアクセスはアプリケーションとしては実行していませんが、SQL*Plus等から自動実行されたプログラムによるものと思われます。
DBA_UNUSED_PRIVSビューからはCREATE PROCEDUREシステム権限が使われていないことがわかります。