撤销WITH ADMIN OPTION不能级联回收下游权限,必须显式逐个撤销B、C等用户的权限;它不能单独移除,只能随系统权限或角色一并撤销;需通过dba_sys_privs等视图人工追溯授权链路。

撤销 WITH ADMIN OPTION 本身不能用 REVOKE 带 CASCADE
很多人以为 REVOKE ... FROM user 会自动剥离被该用户转授出去的权限,但 Oracle 对 WITH ADMIN OPTION 的处理是「不级联」的。也就是说:你撤掉 A 的 CREATE SESSION WITH ADMIN OPTION,B、C 从 A 那里获得的 CREATE SESSION 依然有效,不会被连带收回。
这是因为 WITH ADMIN OPTION 只控制「能否再授权」,不绑定下游权限的生命周期。撤销它只是拿走 A 的「再授权资格」,不影响已发生的授权结果。
-
REVOKE CREATE SESSION FROM a;→ A 失去该系统权限,也不能再授给别人 - B 和 C 仍保有
CREATE SESSION,且仍可继续授予他人(只要他们自己也有WITH ADMIN OPTION) - 想让 B/C 的权限失效?必须显式执行
REVOKE CREATE SESSION FROM b;和REVOKE CREATE SESSION FROM c;
WITH ADMIN OPTION 只能随系统权限一起被撤销
WITH ADMIN OPTION 不是独立权限,无法单独移除。它依附于系统权限或角色授权动作。所以你不能写 REVOKE ADMIN OPTION FROM a; —— 这条语法根本不存在,Oracle 会报 ORA-00995: missing or invalid synonym name 或类似错误。
真正能做的只有两件事:
- 撤销整个系统权限:
REVOKE CREATE SESSION FROM a; - 撤销角色授权:
REVOKE dw_manager FROM a;(如果当初是用GRANT dw_manager TO a WITH ADMIN OPTION授的)
注意:即使角色本身带 WITH ADMIN OPTION,撤销角色时也不会触发级联回收其下游分配——和系统权限一样,下游用户保留该角色。
怎么查谁被谁用 WITH ADMIN OPTION 授权过?
Oracle 不提供直接视图列出「谁通过谁的 ADMIN OPTION 获得了权限」,但你可以组合查询定位链路:
- 查 A 拥有哪些带
ADMIN OPTION的系统权限:SELECT * FROM dba_sys_privs WHERE grantee = 'A' AND admin_option = 'YES'; - 查谁从 A 那里拿到了系统权限(不管是否级联):
SELECT * FROM dba_sys_privs WHERE grantor = 'A'; - 查 A 授予了哪些角色并带
ADMIN OPTION:SELECT * FROM dba_role_privs WHERE grantee = 'A' AND admin_option = 'YES'; - 查谁从 A 那里收到了角色:
SELECT * FROM dba_role_privs WHERE grantor = 'A';
这些结果要人工比对才能还原授权路径。没有视图能自动告诉你「B 的 CREATE TABLE 是不是源自 A 的 WITH ADMIN OPTION」。
真正危险的是忘记清理下游权限
最容易被忽略的点是:DBA 撤销高权限账号(如 SYSDBA 或 CREATE ANY TABLE)时,只盯着源头,却没检查它曾经转授给多少人。那些用户可能仍在生产环境建表、删表、甚至创建新用户。
所以操作前务必:
- 先跑一遍
dba_sys_privs和dba_role_privs查询,确认所有下游接收者 - 评估是否真要保留他们的权限;如果不需要,逐个
REVOKE - 尤其注意
PUBLIC用户——GRANT ... TO PUBLIC WITH ADMIN OPTION虽然语法允许,但实际无效(Oracle 忽略ADMIN OPTION对PUBLIC的设置),这点常被误用
没有自动化级联,就得靠人肉追查。这是 WITH ADMIN OPTION 权限模型最实际的约束。


















