Oracle用户的PASSWORD_LIFE_TIME有哪些坑?

前言

oracle用户的 PASSWORD_LIFE_TIME可能应用中都是设置为unlimited,但是关于PASSWORD_LIFE_TIME有几个坑需要大家知道,有时候一不小心可能会造成系统宕机。

请大家先思考如下几个问题?

场景一:数据库初始化时PASSWORD_LIFE_TIME为默认值180天,现在密码还有7天过期,将PASSWORD_LIFE_TIME设置为360,问7天后,用户还能正常登录吗?

场景二:数据库初始化时PASSWORD_LIFE_TIME为默认值180天,现在密码还有7天过期,将PASSWORD_LIFE_TIME设置为unlimited,问7天后,用户还能正常登录吗?

场景三:数据库当前PASSWORD_LIFE_TIME设置为UNLIMITED,为了应对内外审计将PASSWORD_LIFE_TIME为90天,截图,然后改回UNLIMITED,会不会有问题?

1.PASSWORD_LIFE_TIME改长有用吗? 

这里找了一台很久没用的测试机 来看看

SQL> set line 300
SQL>  select * from dba_profiles where profile='DEFAULT' and RESOURCE_NAME like 'PASSWORD_%';  

PROFILE              RESOURCE_NAME             RESOURCE_TYPE    LIMIT
-------------------- ------------------------- ---------------- --------------------------------------------------------------------------------
DEFAULT              PASSWORD_LIFE_TIME        PASSWORD         180
DEFAULT              PASSWORD_REUSE_TIME       PASSWORD         UNLIMITED
DEFAULT              PASSWORD_REUSE_MAX        PASSWORD         UNLIMITED
DEFAULT              PASSWORD_VERIFY_FUNCTION  PASSWORD         NULL
DEFAULT              PASSWORD_LOCK_TIME        PASSWORD         1
DEFAULT              PASSWORD_GRACE_TIME       PASSWORD         7

6 rows selected.
##可以看到目前PASSWORD_LIFE_TIME是默认值180天SQL>  select USERNAME,EXPIRY_DATE,ACCOUNT_STATUS from dba_users where username='MYCIM';  

USERNAME             EXPIRY_DATE         ACCOUNT_STATUS
-------------------- ------------------- --------------------
MYCIM                2024-04-16 15:03:23 OPEN
##密码早已经过期,但是状态还是open的?
SQL>   SELECT name,ctime,ptime,exptime FROM SYS."USER$" WHERE name='MYCIM';##在基表sys.user$看到CTIME是用户创建时间,PTIME是最近一次的密码修改时间,EXPTIME是密码过期时间

NAME                                                         CTIME               PTIME               EXPTIME
------------------------------------------------------------ ------------------- ------------------- -------------------
MYCIM                                                        2023-02-22 10:49:03 2023-10-19 15:03:23 2023-08-28 10:50:26

SQL> conn mycim/mycim
ERROR:
ORA-28002: the password will expire within 7 days
##用户仍然可以连接 提示ORA-28002
Connected.
SQL>

将PASSWORD_LIFE_TIME改长会怎么样?

SQL> alter profile default limit PASSWORD_LIFE_TIME 720;

Profile altered.

SQL>  select USERNAME,EXPIRY_DATE,ACCOUNT_STATUS from dba_users where username='MYCIM';

USERNAME             EXPIRY_DATE         ACCOUNT_STATUS
-------------------- ------------------- --------------------
MYCIM                2025-04-21 14:47:28 EXPIRED(GRACE)
SQL> conn mycim/mycim
ERROR:
ORA-28002: the password will expire within 7 days

##虽然将密码有效期修改的特别长,但是修改后,账号状态变为EXPIRED(GRACE)延缓期,EXPIRY_DATE变为当前日期+7(PASSWORD_GRACE_TIME 的值),登陆仍然ORA-28002
Connected.
SQL>  alter profile default limit PASSWORD_LIFE_TIME  unlimited;

Profile altered.

SQL> select USERNAME,EXPIRY_DATE,ACCOUNT_STATUS from dba_users where username='MYCIM';

USERNAME             EXPIRY_DATE         ACCOUNT_STATUS
-------------------- ------------------- --------------------
MYCIM                2025-04-21 14:47:28 EXPIRED(GRACE)

SQL>  SELECT name,ctime,ptime,exptime FROM SYS."USER$" WHERE name='MYCIM';

NAME                                                         CTIME               PTIME               EXPTIME
------------------------------------------------------------ ------------------- ------------------- -------------------
MYCIM                                                        2023-02-22 10:49:03 2023-10-19 15:03:23 2025-04-21 14:47:28

##将PASSWORD_LIFE_TIME 设置为unlimited后 都没有改变
SQL> alter user mycim identified by mycim;

User altered.

SQL>  select USERNAME,EXPIRY_DATE,ACCOUNT_STATUS from dba_users where username='MYCIM';

USERNAME             EXPIRY_DATE         ACCOUNT_STATUS
-------------------- ------------------- --------------------
MYCIM                                    OPEN

SQL>  SELECT name,ctime,ptime,exptime FROM SYS."USER$" WHERE name='MYCIM';

NAME                                                         CTIME               PTIME               EXPTIME
------------------------------------------------------------ ------------------- ------------------- -------------------
MYCIM                                                        2023-02-22 10:49:03 2025-04-14 15:29:30 2025-04-21 14:47:28

##修改密码后 账号状态恢复正常,但是基表的EXPTIME并未改变?

2.应对审计短暂改一下PASSWORD_LIFE_TIME会怎么样?

如下是数据库当前profile设置和用户的状态,都是正常的

SQL> select * from dba_profiles where profile='DEFAULT' and RESOURCE_NAME like 'PASSWORD_%';
PROFILE              RESOURCE_NAME             RESOURCE_TYPE    LIMIT
-------------------- ------------------------- ---------------- --------------------------------------------------------------------------------
DEFAULT              PASSWORD_LIFE_TIME        PASSWORD         UNLIMITED
DEFAULT              PASSWORD_REUSE_TIME       PASSWORD         UNLIMITED
DEFAULT              PASSWORD_REUSE_MAX        PASSWORD         UNLIMITED
DEFAULT              PASSWORD_VERIFY_FUNCTION  PASSWORD         NULL
DEFAULT              PASSWORD_LOCK_TIME        PASSWORD         1
DEFAULT              PASSWORD_GRACE_TIME       PASSWORD         7

6 rows selected.

SQL>select USERNAME,EXPIRY_DATE,ACCOUNT_STATUS from dba_users where username='MYCIM';
USERNAME             EXPIRY_DATE         ACCOUNT_STATUS
-------------------- ------------------- --------------------
MYCIM                                    OPEN

SQL>SELECT name,ctime,ptime,exptime FROM SYS."USER$" WHERE name='MYCIM';  ##注意这里的PTIME

NAME                                                         CTIME               PTIME               EXPTIME
------------------------------------------------------------ ------------------- ------------------- -------------------
MYCIM                                                        2023-02-23 09:37:06 2025-04-10 17:15:48 2024-05-02 19:28:51

为了模拟我这里直接将PASSWORD_LIFE_TIME设置为1

SQL>  alter profile default limit PASSWORD_LIFE_TIME 1;

Profile altered.

SQL> select USERNAME,EXPIRY_DATE,ACCOUNT_STATUS from dba_users where username='MYCIM';  ##注意这里的EXPIRY_DATE

USERNAME             EXPIRY_DATE         ACCOUNT_STATUS
-------------------- ------------------- --------------------   
MYCIM                2025-04-11 17:15:48 OPEN

SQL> conn mycim/mycim
ERROR:
ORA-28002: the password will expire within 7 days


Connected.

再将PASSWORD_LIFE_TIME改为unlimited 会恢复正常吗?

SQL>   alter profile default limit PASSWORD_LIFE_TIME unlimited;

Profile altered.

SQL>  select USERNAME,EXPIRY_DATE,ACCOUNT_STATUS from dba_users where username='MYCIM';   ##可以看到用户的EXPIRY_DATE和 ACCOUNT_STATUS都变了

USERNAME             EXPIRY_DATE         ACCOUNT_STATUS
-------------------- ------------------- --------------------
MYCIM                2025-04-22 09:11:33 EXPIRED(GRACE)

SQL>  SELECT name,ctime,ptime,exptime FROM SYS."USER$" WHERE name='MYCIM';

NAME                                                         CTIME               PTIME               EXPTIME
------------------------------------------------------------ ------------------- ------------------- -------------------
MYCIM                                                        2023-02-23 09:37:06 2025-04-10 17:15:48 2025-04-22 09:11:33

这里就一定需要修改用户的密码才能恢复

SQL> alter user mycim identified by mycim;

User altered.

SQL> select USERNAME,EXPIRY_DATE,ACCOUNT_STATUS from dba_users where username='MYCIM';

USERNAME             EXPIRY_DATE         ACCOUNT_STATUS
-------------------- ------------------- --------------------
MYCIM                                    OPEN

3.EXPIRY_DATE如何计算?

如果要理清EXPIRY_DATE和EXPTIME的逻辑关系 需要看一下DBA_USERS这个视图的ddl sql,通过SQL可以找到EXPIRY_DATE和EXPTIME的对应关系,以及整个的计算逻辑才能真正的理清。


  CREATE OR REPLACE FORCE VIEW "SYS"."DBA_USERS" ("USERNAME", "USER_ID", "PASSWORD", "ACCOUNT_STATUS", "LOCK_DATE", "EXPIRY_DATE", "DEFAULT_TABLESPACE", "TEMPORARY_TABLESPACE", "CREATED", "PROFILE", "INITIAL_RSRC_CONSUMER_GROUP", "EXTERNAL_NAME", "PASSWORD_VERSIONS", "EDITIONS_ENABLED", "AUTHENTICATION_TYPE") AS 
  select u.name, u.user#,
       decode(u.password, 'GLOBAL', u.password,
                          'EXTERNAL', u.password,
                          NULL),
       m.status,
       decode(u.astatus, 4, u.ltime,
                         5, u.ltime,
                         6, u.ltime,
                         8, u.ltime,
                         9, u.ltime,
                         10, u.ltime, to_date(NULL)),
       decode(u.astatus,
              1, u.exptime,
              2, u.exptime,
              5, u.exptime,
              6, u.exptime,
              9, u.exptime,
              10, u.exptime,
              decode(u.ptime, '', to_date(NULL),
                decode(pr.limit#, 2147483647, to_date(NULL),
                 decode(pr.limit#, 0,
                   decode(dp.limit#, 2147483647, to_date(NULL), u.ptime +
                     dp.limit#/86400),
                   u.ptime + pr.limit#/86400)))),
       dts.name, tts.name, u.ctime, p.name,
       nvl(cgm.consumer_group, 'DEFAULT_CONSUMER_GROUP'),
       u.ext_username,
       decode(length(u.password),16,'10G ',NULL)||NVL2(u.spare4, '11G ' ,NULL),
       decode(bitand(u.spare1, 16),
              16, 'Y',
                  'N'),
       decode(u.password, 'GLOBAL',   'GLOBAL',
                          'EXTERNAL', 'EXTERNAL',
                          'PASSWORD')
       from sys.user$ u left outer join sys.resource_group_mapping$ cgm
            on (cgm.attribute = 'ORACLE_USER' and cgm.status = 'ACTIVE' and
                cgm.value = u.name),
            sys.ts$ dts, sys.ts$ tts, sys.profname$ p,
            sys.user_astatus_map m, sys.profile$ pr, sys.profile$ dp
       where u.datats# = dts.ts#
       and u.resource$ = p.profile#
       and u.tempts# = tts.ts#
       and u.astatus = m.status#
       and u.type# = 1
       and u.resource$ = pr.profile#
       and dp.profile# = 0
       and dp.type#=1
       and dp.resource#=1
       and pr.type# = 1
       and pr.resource# = 1

过期时间计算关键部分为如下decode部分

decode(u.astatus,
  1, u.exptime,
  2, u.exptime,
  5, u.exptime,
  6, u.exptime,
  9, u.exptime,
  10, u.exptime,
 -- astatus的状态为1,2,5,6,9,10时两个值是一样的, -- 其他情况:动态计算
  decode(u.ptime, '', to_date(NULL),
    decode(pr.limit#, 2147483647, to_date(NULL),
      decode(pr.limit#, 0,
        decode(dp.limit#, 2147483647, to_date(NULL), u.ptime + dp.limit#/86400),
        u.ptime + pr.limit#/86400))))

astatus的状态为1,2,5,6,9,10时 EXPIRY_DATE和EXPTIME两个值是一样的,用户的状态可以查看如下系统表,也就是只有当状态为OPEN,LOCKED(TIMED),LOCKED时才会动态计算。

SELECT * FROM sys.user_astatus_map ORDER BY status#;0	OPEN
1	EXPIRED
2	EXPIRED(GRACE)
4	LOCKED(TIMED)
5	EXPIRED & LOCKED(TIMED)
6	EXPIRED(GRACE) & LOCKED(TIMED)
8	LOCKED
9	EXPIRED & LOCKED
10	EXPIRED(GRACE) & LOCKED

参数介绍

  • u.ptime: 用户上次修改密码的时间(来自 user$ 表)

  • pr.limit#: 用户当前配置的 PROFILE 中 PASSWORD_LIFE_TIME(密码有效期),单位是秒(来自 profile$ 表)

  • dp.limit#: 默认 PROFILE 的 PASSWORD_LIFE_TIME 值(对应 profile#=0)

  • 2147483647: 相当于无限(UNLIMITED)的标识数值

计算逻辑

  1. decode(u.ptime, '', to_date(NULL), ...)

    • 如果 u.ptime 是空字符串,表示用户从未修改过密码 → EXPIRY_DATE 为 NULL

  2. 否则,继续往下判断:

    • decode(pr.limit#, 2147483647, to_date(NULL), ...)

      • 如果该用户当前 PROFILE 的密码有效期为 UNLIMITED → EXPIRY_DATE 为 NULL

  3. 否则,继续判断:

    • decode(pr.limit#, 0, ...)

      • 如果当前 PROFILE 的密码有效期为 0(特殊值,视为"未设置"):

        • 判断默认 PROFILE(profile# = 0)中的 PASSWORD_LIFE_TIME 是否为 UNLIMITED(2147483647):

          • 如果是 → NULL

          • 否则 → u.ptime + dp.limit#/86400(将秒换算为天加上)

  4. 否则(即 pr.limit# > 0 且不为特殊值):

    • 使用 u.ptime + pr.limit#/86400 计算密码过期时间

简单一个图为如下

4. oracle用户密码过期时间影响因子

A.用户的状态

EXPIRED类的状态DBA_USERS.EXPIRY_DATE均是和基表user$.exptime相同,其他OPEN和LOCK类均是要动态计算

ASTATUS 值状态名称说明DBA_USERS.EXPIRY_DATE 是否显示 EXPTIME
0OPEN账号正常,无过期无锁定❌ 否(进入动态计算)
4LOCKED(TIMED)被自动锁定(通常因登录失败次数过多)❌ 否(进入动态计算)
8LOCKED被手动锁定❌ 否(进入动态计算)
1EXPIRED密码已过期✅ 是
2EXPIRED(GRACE)密码过期宽限期中✅ 是
5EXPIRED & LOCKED(TIMED)密码过期 + 自动锁定✅ 是
6EXPIRED(GRACE) & LOCKED(TIMED)密码宽限期中 + 自动锁定✅ 是
9EXPIRED & LOCKED密码过期 + 手动锁定✅ 是
10EXPIRED(GRACE) & LOCKED宽限期中 + 手动锁定✅ 是

B.动态计算影响因子

影响因素为PASSWORD_LIFE_TIME 和PTIME(最后一次密码修改时间) 如果用户状态是EXPIRED类,那么想恢复正常一定要修改密码。

5.检查密码有效期的脚本

1.检查最近七天即将密码过期的账号(适用11G-19C)

SELECT
	u.username,
	u.account_status,
	u.profile,
	p.limit AS password_life_time,
	u.expiry_date,
	TRUNC(u.expiry_date - SYSDATE) AS days_until_expire
FROM
	dba_users u
JOIN
  dba_profiles p
  ON
	u.profile = p.profile
WHERE
	p.resource_name = 'PASSWORD_LIFE_TIME'
	AND p.limit != 'UNLIMITED'
	AND u.username NOT IN ('SYS', 'SYSTEM')
	AND u.expiry_date < SYSDATE + 7
ORDER BY
	days_until_expire;

2.批量“刷新”密码有效期(密码不变,重置生效时间)仅适用于11G

该sql谨慎使用 因为用了基表SYS.USER$的password,官方不建议。

 BEGIN
  FOR usr IN (
    SELECT username FROM dba_users
    WHERE account_status = 'OPEN'
      AND username NOT IN ('SYS', 'SYSTEM')  -- 排除系统用户
  ) LOOP
    EXECUTE IMMEDIATE 'ALTER USER ' || usr.username || ' IDENTIFIED BY VALUES (SELECT password FROM sys.user$ WHERE name = ''' || usr.username || ''')';
  END LOOP;
END;
/

总结

如果不了解用户密码的过期时间的计算逻辑,很可能遇到前面这几个坑,特别是场景三中在面对审计时,以为将PASSWORD_LIFE_TIME 改一下截个图,再改回去就完事了?实际上可能留了一个大坑,甚至造成系统宕机的风险,特别是对于应用账号,只有应用使用,ORA-28002不影响系统运行,直到账号过期无法使用,造成应用宕机,所以针对PASSWORD_LIFE_TIME 的修改大家要谨慎,涉及到修改PASSWORD_LIFE_TIME 参数后一定要检查用户的状态。

参考文档:ORA-28002 On User Connection Immediately After PASSWORD_LIFE_TIME Changed (Doc ID 162818.1)

<think>好的,用户现在想查询Oracle数据库中idle_time的值。根据之前的对话历史,用户之前询问了关于_resource_manager_always_on参数的问题,现在转向了idle_time的设置。我需要结合提供的引用内容来解答。 首先,用户提到的引用[1]和引用[2]都提到了IDLE_TIME参数的作用,即控制用户会话的空闲时间,防止过多的空闲连接导致资源问题。引用[3]展示了在PostgreSQL中的例子,但用户现在关注的是Oracle,所以可能需要忽略这个引用,或者仅作为对比。引用[4]提到了将idle_time设置为unlimited,这可能和用户的问题相关,但用户当前的问题只是查询当前值,而不是设置。 用户的需求是查询idle_time的值,因此需要提供具体的SQL查询方法。根据Oracle的知识,idle_time用户配置文件(profile)中的一个参数,每个用户都会被分配一个profile,而profile中的参数包括IDLE_TIME。因此,查询方法应该涉及DBA_PROFILES视图。 需要确认用户是否有DBA权限,如果没有,可能需要使用USER_PROFILES或者ALL_PROFILES视图。但一般情况下,建议使用DBA_PROFILES,并提醒用户需要相应权限。 另外,可能需要解释默认的DEFAULT profile,因为大多数用户可能使用默认配置。同时,用户可能需要了解如何修改这个参数,但当前问题只是查询,所以是否需要提供修改方法作为补充?根据用户的问题,他们只询问查询,但根据之前的回答风格,可能需要简要提及后续步骤,比如修改的方法,但需要明确区分查询和修改。 还需要注意,IDLE_TIME的单位是分钟,这点需要明确指出,避免用户误解。此外,如果值为UNLIMITED,表示没有限制,这也是引用[4]中提到的情况,用户可能需要知道如何检查是否设置为无限。 可能的查询语句示例包括: 1. 查询所有profile的IDLE_TIME设置: SELECT profile, resource_name, limit FROM dba_profiles WHERE resource_name = 'IDLE_TIME'; 2. 查询当前用户使用的profile及其IDLE_TIME: SELECT profile FROM dba_users WHERE username = 'YOUR_USERNAME'; 然后结合第一个查询来获取具体的限制值。 此外,需要提醒用户注意权限问题,如果无法访问DBA视图,可能需要使用USER_PROFILES。同时,如果用户遇到ORA-00018错误(如引用[2]所述),可能需要调整IDLE_TIME或处理空闲会话,但用户当前的问题只是查询,所以这部分可以作为后续建议。 总结步骤: 1. 使用DBA_PROFILES视图查询所有配置文件的IDLE_TIME。 2. 检查特定用户的profile分配情况。 3. 解释结果中的UNLIMITED和具体数值的含义。 4. 提示修改方法(如果需要),但用户当前不需要,所以可能放在相关问题里。 需要确保回答结构清晰,先给出查询方法,再解释结果,注意事项,并生成相关问题。同时,要引用提供的引用内容,比如引用[1]和[2]提到的IDLE_TIME的作用和相关问题,引用[4]提到的UNLIMITED的情况。</think>### Oracle 数据库查询 `IDLE_TIME` 值的详细方法 #### 1. **理解 `IDLE_TIME` 的作用** `IDLE_TIME` 是 Oracle 用户配置文件(Profile)中的核心参数,用于**限制用户会话的最大空闲时间**(单位:分钟)。若会话空闲时间超过该值,Oracle 会自动终止连接,释放资源,避免因空闲会话堆积导致 `ORA-00018`(超出最大会话数)等错误[^2][^3]。 #### 2. **查询方法** ##### (1) **查询所有配置文件的 `IDLE_TIME` 设置** 通过系统视图 `DBA_PROFILES` 可查看所有 Profile 的资源配置,需具备 **DBA 权限**: ```sql SELECT profile, resource_name, limit FROM dba_profiles WHERE resource_name = 'IDLE_TIME'; ``` **示例输出**: ``` PROFILE RESOURCE_NAME LIMIT ------------ ---------------- -------- DEFAULT IDLE_TIME 60 APP_USER IDLE_TIME UNLIMITED ``` - **`DEFAULT` Profile**:Oracle 默认配置文件,通常所有用户默认继承此配置。 - **`LIMIT` 字段**:若值为 `UNLIMITED`,表示不限制空闲时间[^4];若为数值(如 `60`),表示空闲超时时间(分钟)。 ##### (2) **查询当前用户的 `IDLE_TIME`** 若需查看当前用户的 Profile 分配及具体限制: ```sql -- 查看当前用户的 Profile SELECT profile FROM dba_users WHERE username = 'YOUR_USERNAME'; -- 结合步骤 (1) 的查询结果匹配具体限制 ``` #### 3. **关键注意事项** - **权限要求**:若用户无 `DBA_PROFILES` 访问权限,可使用 `USER_PROFILES` 视图(仅查看当前用户的 Profile)。 - **默认值**:Oracle 默认 Profile 的 `IDLE_TIME` 通常为 `UNLIMITED`,但部分安全策略可能将其设为固定值(如 `60`)[^1]。 - **动态生效**:`IDLE_TIME` 的修改需在用户下次登录后生效,已有会话不受影响。 #### 4. **修改 `IDLE_TIME`(可选扩展)** 若需调整空闲超时时间(例如设为 30 分钟): ```sql ALTER PROFILE your_profile_name LIMIT IDLE_TIME 30; ``` --- ### 相关问题 1. **如何避免 `ORA-00018` 错误与空闲会话管理?** 2. **Oracle Profile 中 `PASSWORD_LIFE_TIME` 的作用及配置方法?** 3. **如何批量终止 Oracle 数据库中的空闲会话?** --- **引用说明**: - 关于 `IDLE_TIME` 的默认配置和性能优化建议参考了连接管理策略[^1]。 - `ORA-00018` 错误与空闲会话的关联性分析来自实际案例[^2]。 - `UNLIMITED` 设置的应用场景与用户权限管理相关[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潇湘秦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值