查V$PWFILE_USERS是唯一可靠途径,它直接列出密码文件中被授予SYSDBA/SYSOPER权限的用户,不依赖数据字典、角色或默认设置,且字段sysdba/sysoper为布尔值;但需注意该视图仅反映“存在”而非“可用”,须结合实际连接测试与OS组权限检查。
查 V$PWFILE_USERS 是最直接的方式
oracle 中能以 sysdba 或 sysoper 身份登录的用户,必须显式被授予该权限,并记录在密码文件中。数据库启动时只读取这个文件,不走数据字典校验。所以查 v$pwfile_users 是唯一可靠途径——它不依赖当前会话角色、不依赖 dba 角色授权状态,也不受 default role 设置影响。
执行以下语句即可列出所有具备系统级登录能力的用户:
SELECT username, sysdba, sysoper FROM V$PWFILE_USERS;
注意:sysdba 和 sysoper 列是 TRUE/FALSE 值(不是字符串),表示是否启用对应权限。常见错误是误以为 GRANT SYSDBA TO user 后就能立刻查到,其实必须用 ORAPWD 工具重建密码文件并重启实例(或使用 ALTER DATABASE OPEN RESETLOGS 等操作触发重载)才能生效。
DBA_SYS_PRIVS 里查不到 SYSDBA 权限
DBA_SYS_PRIVS 只存普通系统权限,比如 CREATE SESSION、ALTER SYSTEM,但 SYSDBA 和 SYSOPER 不是系统权限(system privilege),而是“身份认证级别”(authentication privilege)。它们不走 GRANT/REVOKE 流程,也不写入数据字典视图。
如果你在 DBA_SYS_PRIVS 里搜 'SYSDBA',结果永远为空;同样,USER_SYS_PRIVS 和 SESSION_PRIVS 也完全不包含这两项。
容易踩的坑:
- 用
SELECT * FROM DBA_SYS_PRIVS WHERE PRIVILEGE = 'SYSDBA'—— 语法合法但返回空,误导判断 - 用
SHOW USER查当前会话用户后就认为“只有这个用户有 SYSDBA”——错,这只是当前连接身份,不代表全库唯一 - 依赖
DBA_ROLE_PRIVS查DBA角色成员来推断高危权限——DBA角色不等于SYSDBA,前者是对象+系统权限集合,后者是底层登录凭证控制
确认用户是否真能用 SYSDBA 登录,得试连
光看 V$PWFILE_USERS 还不够:它只说明“被加进密码文件”,但不保证用户账户未锁定、密码未过期、或未被 ALTER USER ... ACCOUNT LOCK。
最稳妥的验证方式是实际尝试连接:
sqlplus / as sysdba
然后在 SQL*Plus 里执行:
CONNECT username/password AS SYSDBA
如果报 ORA-01017: invalid username/password 或 ORA-28000: the account is locked,说明虽然在密码文件里,但不可用。生产环境排查高危账号时,必须把「存在」和「可用」分开验证。
另外注意:本地连接(/ as sysdba)默认走操作系统认证,不查密码文件;远程连接才强制依赖密码文件。所以远程测试更反映真实风险面。
别漏掉隐式拥有 SYSDBA 的 OS 用户
Oracle 允许将操作系统组(如 Linux 的 dba 组)配置为等价于 SYSDBA。只要用户属于该组,且数据库参数 remote_login_passwordfile=EXCLUSIVE 或 SHARED,就能免密登录。
检查方式:
- Linux/Unix:
id -Gn $USER看是否含dba组 - 数据库内:
SELECT value FROM v$parameter WHERE name = 'remote_login_passwordfile'; - OS 组映射配置在
$ORACLE_HOME/rdbms/admin/sql.bsq或文档中定义,无法通过 SQL 直接查出,需结合运维文档确认
这类权限不会出现在 V$PWFILE_USERS,也不会记入审计日志(除非开启 OS 认证审计),是最容易被忽略的高危入口。


















