查DBA_USERS的ACCOUNT_STATUS字段可判断Oracle用户是否被锁定,值为LOCKED或LOCKED(TIMED)即不可登录,需DBA权限;注意EXPIRED & LOCKED状态无lock_date但实际已锁,解锁需ALTER USER ... ACCOUNT UNLOCK。 查
DBA_USERS里的ACCOUNT_STATUS字段就能知道哪些用户被锁在Oracle数据库里,判断一个用户账户是否被锁定,最权威、最直接的依据,就是查询dba_users视图中的account_status字段。只要这个字段的值显示为LOCKED或者LOCKED(TIMED),那就意味着该账户目前无法登录。
这里有个前提需要注意:查询DBA_USERS视图通常需要DBA权限。普通用户是看不到其他用户账户状态的。动手之前,最好先确认自己拥有SELECT_CATALOG_ROLE或DBA这类角色权限。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
一个常用的查询语句是这样的:
SELECT username, account_status, lock_date, expiry_date, created
FROM dba_users
WHERE account_status IN ('LOCKED', 'LOCKED(TIMED)')
ORDER BY lock_date DESC;
LOCKED:这通常表示管理员手动执行了ALTER USER ... ACCOUNT LOCK命令。这种锁定没有自动解锁机制,必须手动干预。LOCKED(TIMED):这种状态往往是触发了安全策略。比如,连续多次登录失败(密码输错)后,系统根据FAILED_LOGIN_ATTEMPTS参数自动锁定了账户。lock_date字段为空,并不绝对代表账户没锁。在某些特定场景下(例如密码过期后的首次登录失败),账户状态可能已经变为锁定,但lock_date并未更新。所以,最终还是要以account_status字段为准。ACCOUNT_STATUS显示EXPIRED & LOCKED却查不到lock_date这个问题经常让人困惑。账户可能先因为密码过期(状态变为EXPIRED),随后又因为一次错误的登录尝试,触发了锁定机制,从而形成了一个复合状态:EXPIRED & LOCKED。关键在于,Oracle并不会为这种由密码过期间接引发的“逻辑锁定”单独记录一个时间戳,因此lock_date字段很可能仍然是NULL。
账户一旦处于这个状态,用户是无法登录的。而且,仅仅重置密码并不能解决问题——必须先执行解锁操作:
ALTER USER scott ACCOUNT UNLOCK;
expiry_date(密码过期日期)。ALTER USER scott IDENTIFIED BY newpass。PASSWORD_LOCK_TIME这个参数的值。它决定了账户在因登录失败被锁后,自动解锁的等待时长(单位是天)。DBA_USERS查锁定用户时容易漏掉的三类情况如果只盯着ACCOUNT_STATUS里带“LOCKED”字样的记录,可能会漏掉一些实际上已经“名存实亡”的账户。下面这三类情况值得警惕:
ACCOUNT_STATUS = 'EXPIRED(GRACE)':密码已过期,但处于宽限期内。此时用户仍然可以登录并修改密码。然而,如果在宽限期内用户没有进行任何操作,那么下一次登录尝试就会直接导致账户变成EXPIRED & LOCKED状态。DEFAULT,但该profile中FAILED_LOGIN_ATTEMPTS参数值为0:这可不是“无限次尝试”的意思。恰恰相反,值为0意味着任何一次登录失败都会立即锁定账户,而不是默认的允许失败10次。CREATE SESSION权限,但其关联的profile中RESOURCE_LIMIT参数被设为FALSE:这种情况下,即使你在profile里配置了FAILED_LOGIN_ATTEMPTS,整个账户锁定机制也不会生效。这是一个常见的配置陷阱。因此,更稳妥的做法是,将用户状态和其profile的配置关联起来检查:
SELECT u.username, u.account_status, u.profile, p.failed_login_attempts, p.password_lock_time FROM dba_users u, dba_profiles p WHERE u.profile = p.profile AND p.resource_name = 'FAILED_LOGIN_ATTEMPTS' AND u.account_status LIKE '%LOCKED%';
USERNAME大小写和特殊字符陷阱Oracle数据库默认将用户名以大写形式存储。但是,如果在创建用户时使用了双引号(例如"MyUser"),那么DBA_USERS.USERNAME字段就会原样保留大小写和引号。如果直接用字符串拼接SQL语句,很容易因为大小写不匹配或引号问题而导致执行失败。
一个安全的做法是,先用DUMP()函数对用户名进行预检:
SELECT username, DUMP(username) FROM dba_users WHERE account_status LIKE '%LOCKED%';
Typ=1 Len=6: 77,121,85,115,101,114(都是ASCII码),说明用户名是标准的大写格式,可以相对放心地拼接SQL。EXECUTE IMMEDIATE执行动态生成的语句。更稳妥的流程是:先导出待解锁的用户列表,经过人工仔细核对确认后,再分批执行解锁命令。说到底,锁定几个用户账户本身或许不是大问题。真正的麻烦在于,锁了之后,却没人清楚是在什么时候、因为触发了哪条安全规则、被谁(或系统)锁定的。DBA_USERS视图并不记录锁定原因。要追溯根源,通常需要结合审计日志(DBA_AUDIT_TRAIL)或会话连接信息(V$SESSION_CONNECT_INFO)来进行回溯分析。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述