查谁有dba角色必须用dba_role_privs视图,因dba是预定义角色而非系统或对象权限,且需关注admin_option、default_role、common等关键字段以准确评估权限效力。
查谁有dba角色,必须用 dba_role_privs 视图
直接查 dba_role_privs 是唯一可靠方式,因为这张表明确记录「谁(grantee)被授予了哪个角色(granted_role)」。dba 是一个预定义角色,不是系统权限,所以不会出现在 dba_sys_privs 里;它也不是对象权限,也不会出现在 dba_tab_privs 中。
常见错误是误以为查 DBA_SYS_PRIVS WHERE PRIVILEGE LIKE '%ADMIN%' 能找到 DBA 用户——这只会漏掉、误导,甚至返回一堆无关的系统权限。
-
GRANTEE字段值区分大小写,但 Oracle 默认以大写存储用户名/角色名;若曾用双引号创建小写用户(如"app_dev"),必须原样匹配 -
GRANTED_ROLE = 'DBA'必须全大写,Oracle 角色名默认不区分大小写但视图中统一存为大写 - 结果中
ADMIN_OPTION = 'YES'表示该用户可把 DBA 角色再授给他人,属于高危配置,需重点标记
执行前先确认你有查 DBA_ROLE_PRIVS 的权限
不是所有 DBA 都能查这张表。你必须拥有 SELECT ANY DICTIONARY 权限,或已被授予 SELECT_CATALOG_ROLE 角色。否则会报错:ORA-00942: table or view does not exist。
没权限时别硬试,改用更安全的替代方案:
- 用
USER_ROLE_PRIVS查当前登录用户拥有的角色(包括是否含 DBA) - 用
SESSION_ROLES看当前会话已激活的角色(注意:有些角色可能未设为默认,需SET ROLE才生效) - 如果连
USER_ROLE_PRIVS都查不到,说明当前用户连自己的角色信息都无权读取,应联系更高权限账号协助
DBA_ROLE_PRIVS 查询结果里容易被忽略的关键字段
除了 GRANTEE 和 GRANTED_ROLE,下面三个字段决定权限实际效力:
-
ADMIN_OPTION:为'YES'时,该用户可将 DBA 角色再授予别人。这是链式授权入口,比普通 DBA 更危险 -
DEFAULT_ROLE:为'YES'表示该角色在登录后自动启用;若为'NO',即使被授予 DBA,也需手动SET ROLE DBA才能生效 -
COMMON(仅多租户环境):为'YES'表示该授权在 CDB 和所有 PDB 生效;为'NO'则只在当前容器有效
漏看 DEFAULT_ROLE = 'NO' 可能导致误判“某人没 DBA 权限”,其实只是没激活;而忽略 COMMON = 'NO' 在多租户迁移或审计时会漏掉 PDB 层级的 DBA 授权。
快速定位高风险 DBA 授权的 SQL 模板
生产环境排查时,别只跑 SELECT * FROM DBA_ROLE_PRIVS WHERE GRANTED_ROLE = 'DBA'。加过滤条件才能直击问题:
SELECT GRANTEE, ADMIN_OPTION, DEFAULT_ROLE, COMMON
FROM DBA_ROLE_PRIVS
WHERE GRANTED_ROLE = 'DBA'
AND GRANTEE NOT IN ('SYS', 'SYSTEM') -- 排除内置账户
AND (ADMIN_OPTION = 'YES' OR DEFAULT_ROLE = 'NO');
这条语句专门揪出两类异常:可转授 DBA 的非核心账户,以及虽被授 DBA 却无法自动使用的账户(后者常是权限配置疏漏的表现)。
真正难处理的不是“谁有 DBA”,而是“谁有且能滥用 DBA”——ADMIN_OPTION = 'YES' 和跨容器 COMMON = 'YES' 同时存在时,权限扩散面最难收敛。











