Oracle DAC 基於 存取控制列表 (ACL) 實現,核心區分兩類權限:
CREATE TABLE、ALTER SYSTEM、SELECT ANY TABLE。SELECT ON scott.emp、EXECUTE ON pkg_util。
CREATE TABLE "SYS"."SYSAUTH$" (
"GRANTEE#" NUMBER NOT NULL, -- 被授權者 USER#/ROLE#
"PRIVILEGE#" NUMBER NOT NULL, -- 權限代碼(負數=系統權限,正數=角色 ID)
"SEQUENCE#" NUMBER NOT NULL, -- 授權序號(時間戳概念)
"OPTION$" NUMBER -- 是否可轉授 (ADMIN OPTION)
) TABLESPACE "SYSTEM";
WITH RECURSIVE priv_tree(grantee#, privilege#, option$) AS (
-- 基礎:直接授予使用者的系統權限
SELECT grantee#, privilege#, option$
FROM sys.sysauth$
WHERE grantee# = (SELECT user# FROM sys.user$ WHERE name = 'SCOTT')
AND privilege# < 0
UNION ALL
-- 遞迴:角色轉授的系統權限
SELECT sa.grantee#, sa.privilege#, sa.option$
FROM sys.sysauth$ sa
JOIN priv_tree pt ON sa.grantee# = pt.privilege# -- 角色 ID = 權限代碼
WHERE sa.privilege# < 0
)
SELECT DISTINCT p.name AS privilege_name
FROM priv_tree pt
JOIN system_privilege_map p ON p.privilege = -pt.privilege#;
CREATE TABLE "SYS"."OBJAUTH$" (
"OBJ#" NUMBER NOT NULL, -- 物件 ID
"GRANTOR#" NUMBER NOT NULL, -- 授權者 USER#
"GRANTEE#" NUMBER NOT NULL, -- 被授權者 USER#/ROLE#
"PRIVILEGE#" NUMBER NOT NULL, -- 權限代碼(正數對應 table_privilege_map)
"SEQUENCE#" NUMBER NOT NULL, -- 授權序號
"PARENT" ROWID, -- 父授權記錄 ROWID(級聯回收用)
"OPTION$" NUMBER, -- GRANT OPTION
"COL#" NUMBER -- 欄位層級授權時的欄位號(表級為 0)
) TABLESPACE "SYSTEM";
GRANT SELECT(sal) ON emp TO hr)。| 視圖 | 用途 |
|---|---|
| DBA_SYS_PRIVS | 使用者/角色直接系統權限 |
| DBA_TAB_PRIVS | 物件權限(含轉授鏈) |
| DBA_ROLE_PRIVS | 角色授予關係 |
| ROLE_SYS_PRIVS / ROLE_TAB_PRIVS | 角色擁有的權限 |
| SESSION_PRIVS | 當前 Session 擁有的系統權限 |
DBA_TAB_PRIVS 中 GRANTOR != 'SYS' 的記錄,排查非預期轉授。CASCADE CONSTRAINTS,自動處理依賴約束。PDB 區域權限,注意 CONTAINER=ALL/CURRENT 子句。嚴禁直接 DML 修改 SYSAUTH$、OBJAUTH$。所有權限變更必須透過
GRANT/REVOKE指令,確保字典一致性、審計記錄、共用游標失效等機制正常運作。