必须显式将自定义密码验证函数绑定到profile才能生效,Oracle不会自动调用同名函数;执行utlpwdmg.sql需SYS AS SYSDBA、resource_limit=TRUE、正确路径和@命令;绑定后仅新改密生效。
为什么改了 utlpwdmg.sql 还不生效
不是脚本没运行,而是函数根本没被 profile 调用。oracle 不会自动扫描数据库里所有叫 verify_function 的函数——它只认 password_verify_function 字段里明确写的那个名字。常见现象是:你改完脚本、重新执行了一遍,dba_profiles 里查出来还是 null 或旧函数名,甚至测试改密码时连长度检查都不触发。
- 必须先确认用户实际使用的 profile:
SELECT profile FROM dba_users WHERE username = 'YOUR_USER'; - 再查该 profile 绑定的函数:
SELECT resource_name, limit FROM dba_profiles WHERE profile = 'DEFAULT' AND resource_name = 'PASSWORD_VERIFY_FUNCTION'; - 如果
limit是NULL,说明校验压根没开;如果是VERIFY_FUNCTION_11G,而你刚编译了ora12c_strong_verify_function,那新逻辑完全不会执行
怎样用 @?/rdbms/admin/utlpwdmg.sql 正确加载验证函数
这个脚本不是普通 SQL 文件,权限和路径错一点就白干。它定义的是数据库级回调函数,必须由 Oracle 内核在特定上下文中调用,所以对执行环境有硬性要求。
- 连接方式必须是
SYS AS SYSDBA(仅AS SYSOPER或普通 DBA 角色不行) -
RESOURCE_LIMIT参数必须为TRUE:SHOW PARAMETER resource_limit查,若为FALSE,先执行ALTER SYSTEM SET resource_limit = TRUE; - 路径必须准确:Oracle 12c+ 自带的脚本在
$ORACLE_HOME/rdbms/admin/utlpwdmg.sql,别用网上下载的同名文件覆盖,版本不匹配会导致编译失败或校验项缺失 - 命令必须是
@?/rdbms/admin/utlpwdmg.sql(注意是@,不是START或直接粘贴内容),否则函数不会被创建或替换
如何把自定义函数绑定到 profile 上
脚本执行成功后,函数只是“躺在数据库里”,必须显式告诉 profile 去调用它。Oracle 不会自动把最新编译的函数设为默认——这一步漏掉,前面所有操作等于零。
- 确认函数已存在:
SELECT object_name, status FROM dba_objects WHERE object_type = 'FUNCTION' AND object_name IN ('VERIFY_FUNCTION', 'ORA12C_STRONG_VERIFY_FUNCTION'); - 绑定到 profile:
ALTER PROFILE DEFAULT LIMIT PASSWORD_VERIFY_FUNCTION ORA12C_STRONG_VERIFY_FUNCTION;(12c+ 推荐用这个;11g 及更早用VERIFY_FUNCTION) - 如果要用自建函数(如
my_password_test),必须先用SYS创建该函数,再用同样语法绑定:ALTER PROFILE DEFAULT LIMIT PASSWORD_VERIFY_FUNCTION my_password_test; - 注意大小写:函数名区分大小写,
ORA12C_STRONG_VERIFY_FUNCTION和ora12c_strong_verify_function是两个不同对象
修改阈值时哪些参数能动、哪些不能碰
utlpwdmg.sql 里最常被改的是硬编码阈值,但改法不对会直接关掉全部校验。关键不是“能不能改”,而是“怎么改才不破坏函数逻辑流”。
- 可安全调整:
min_length、min_uppercase、min_lowercase、min_digits、min_special(11g);12c+ 对应的是length、upper、lower、digit、special - 禁止删除或注释掉
RETURN TRUE;之前的任意校验分支——否则函数可能提前返回TRUE,等于跳过所有检查 - 别加
DBMS_OUTPUT.PUT_LINE:密码校验发生在登录鉴权阶段,此时输出不可见,还可能因权限问题报ORA-06502 - 特殊字符限制是硬编码的:
ORA12C_STRONG_VERIFY_FUNCTION只允许_ $ #,改脚本也绕不开,这是函数内部逻辑决定的
ALTER USER ... IDENTIFIED BY,但这会中断业务——稳妥做法是先在测试用户上验证,再安排维护窗口批量处理。


















