grant create job不足以控制定时任务权限,因为它仅允许用户在自身schema中提交dbms_job任务,无法禁用、删除他人job,也不能管理dbms_scheduler对象(需显式manage scheduler系统权限),且二者权限体系完全独立。

为什么 GRANT CREATE JOB 不足以控制定时任务权限
因为 CREATE JOB 只允许用户在自己 schema 下提交 DBMS_JOB 任务,但无法禁用、删除、修改他人 job,也不能查看 DBA_JOBS 或调用 DBMS_JOB.BROKEN 等管理操作。更重要的是,它完全不约束 DBMS_SCHEDULER —— Oracle 10g 起默认启用的调度器,其权限体系独立于 DBMS_JOB。
常见错觉是:给了 CREATE JOB 就等于给了“定时任务能力”。实际生产中,用户仍可能绕过限制,直接用 DBMS_SCHEDULER.CREATE_JOB 创建高权限作业(只要他有执行该包的权限)。
-
DBMS_JOB权限链极短,仅依赖CREATE JOB和EXECUTE权限,但功能弱、已弃用 -
DBMS_SCHEDULER需要显式MANAGE SCHEDULER才能创建/启停/删 job,否则会报ORA-27486: insufficient privileges - 即使没授
MANAGE SCHEDULER,若用户有EXECUTE ON DBMS_SCHEDULER,仍可能通过CREATE_JOB提交作业——但立即失败,因缺少底层对象操作权
如何真正禁止用户创建任何定时任务
必须双管齐下,封死两条路径:DBMS_JOB 和 DBMS_SCHEDULER。只 revoke 其中一个,用户大概率能绕过。
执行以下语句(需 SYS 或具备 ADMIN OPTION 的管理员身份):
REVOKE CREATE JOB FROM username; REVOKE MANAGE SCHEDULER FROM username;
注意:MANAGE SCHEDULER 是系统权限,不是角色;DBA_SCHEDULER_ROLE 在 12c+ 已废弃,且默认不含调度控制权,不能替代。
- 如果用户已有
UNLIMITED TABLESPACE或DBA角色,先收回这些高权限——它们隐含MANAGE SCHEDULER - 检查是否误授了
EXECUTE ON DBMS_SCHEDULER:查DBA_TAB_PRIVS,若有则一并REVOKE -
CREATE JOB权限本身不带执行能力,但若用户还能连到数据库并写 PL/SQL,就可能利用其他用户已建好的 job 做间接调用,所以必须从源头掐断
验证用户是否真被限制住
不要只查权限视图,要实测。用目标用户账号登录后尝试:
- 运行
DBMS_JOB.SUBMIT→ 应报ORA-01031: insufficient privileges - 运行
DBMS_SCHEDULER.CREATE_JOB→ 应报ORA-27486: insufficient privileges - 查询
USER_JOBS或USER_SCHEDULER_JOBS是允许的(只读视图),但插入、更新、删除作业操作全部失败
特别注意:DBMS_SCHEDULER.ENABLE、.DISABLE、.DROP_JOB 这些过程调用,哪怕参数合法,只要缺 MANAGE SCHEDULER,一律报 ORA-27486,不是包不存在或语法错。
容易被忽略的绕过点:存储过程封装 + 调用者权限
最隐蔽的风险不是用户自己写 job,而是他创建一个 DEFINER'S RIGHTS 存储过程,里面调用 DBMS_SCHEDULER.CREATE_JOB,然后让别人(比如有权限的运维账号)来执行它。
这类绕过无法靠 revoke 权限拦截,必须靠代码审查和权限最小化原则:
- 禁止普通用户拥有
CREATE PROCEDURE权限,或至少禁用CREATE ANY PROCEDURE - 对已存在的存储过程,检查其 AUTHID 属性:
AUTHID DEFINER表示以定义者权限运行,风险极高;应强制使用AUTHID CURRENT_USER - 定期扫描
DBA_SOURCE中含DBMS_JOB或DBMS_SCHEDULER关键字的过程,人工确认调用上下文
真正的限制不在命令行能不能敲,而在执行链路里有没有未被审计的“权限跳板”。











