【问题标题】:change Oracle user account status from EXPIRE(GRACE) to OPEN将 Oracle 用户帐户状态从 EXPIRE(GRACE) 更改为 OPEN
【发布时间】:2011-04-02 07:07:15
【问题描述】:

收到Your password will be expired with in 7 days 的消息后,我将default 配置文件的密码过期天数更改为UNLIMITED。但是部分用户的账号状态还停留在EXPIRE(GRACE)

有什么方法可以在不重置密码的情况下将 Oracle 用户帐户状态从 EXPIRE(GRACE) 更改为 OPEN

【问题讨论】:

    标签: oracle


    【解决方案1】:

    不,您不能直接在不重置密码的情况下将帐户状态从 EXPIRE(GRACE) 更改为 OPEN。

    documentation 说:

    如果您使用 PASSWORD 导致数据库用户的密码过期 EXPIRE,则用户(或 DBA)必须在更改密码之前 过期后尝试登录数据库。


    但是,您可以间接通过将用户的密码哈希重置为现有值来将状态更改为 OPEN。不幸的是,将密码哈希设置为自身具有以下复杂性,并且几乎所有其他解决方案都至少漏掉了其中一个问题:

    1. 不同版本的 Oracle 使用不同类型的哈希。
    2. 用户的个人资料可能会阻止重复使用密码。
    3. 可以更改配置文件限制,但我们必须在最后将值更改回来。
    4. 配置文件值不是微不足道的,因为如果值为DEFAULT,则它是指向DEFAULT 配置文件值的指针。我们可能需要递归检查配置文件。

    下面这个大得离谱的 PL/SQL 块应该可以处理所有这些情况。无论 Oracle 版本或配置文件设置如何,它都应使用相同的密码哈希将任何帐户重置为 OPEN。并且配置文件将更改回原来的限制。

    --Purpose: Change a user from EXPIRED to OPEN by setting a user's password to the same value.
    --This PL/SQL block requires elevated privileges and should be run as SYS.
    --This task is difficult because we need to temporarily change profiles to avoid
    --  errors like "ORA-28007: the password cannot be reused".
    --
    --How to use: Run as SYS in SQL*Plus and enter the username when prompted.
    --  If using another IDE, manually replace the variable two lines below.
    declare
        v_username varchar2(128) := trim(upper('&USERNAME'));
        --Do not change anything below this line.
        v_profile                 varchar2(128);
        v_old_password_reuse_time varchar2(128);
        v_uses_default_for_time   varchar2(3);
        v_old_password_reuse_max  varchar2(128);
        v_uses_default_for_max    varchar2(3);
        v_alter_user_sql          varchar2(4000);
    begin
        --Get user's profile information.
        --(This is tricky because there could be an indirection to the DEFAULT profile.
        select
            profile,
            case when user_password_reuse_time = 'DEFAULT' then default_password_reuse_time else user_password_reuse_time end password_reuse_time,
            case when user_password_reuse_time = 'DEFAULT' then 'Yes' else 'No' end uses_default_for_time,
            case when user_password_reuse_max  = 'DEFAULT' then default_password_reuse_max  else user_password_reuse_max  end password_reuse_max,
            case when user_password_reuse_max  = 'DEFAULT' then 'Yes' else 'No' end uses_default_for_max
        into v_profile, v_old_password_reuse_time, v_uses_default_for_time, v_old_password_reuse_max, v_uses_default_for_max
        from
        (
            --User's profile information.
            select
                dba_profiles.profile,
                max(case when resource_name = 'PASSWORD_REUSE_TIME' then limit else null end) user_password_reuse_time,
                max(case when resource_name = 'PASSWORD_REUSE_MAX' then limit else null end) user_password_reuse_max
            from dba_profiles
            join dba_users
                on dba_profiles.profile = dba_users.profile
            where username = v_username
            group by dba_profiles.profile
        ) users_profile
        cross join
        (
            --Default profile information.
            select
                max(case when resource_name = 'PASSWORD_REUSE_TIME' then limit else null end) default_password_reuse_time,
                max(case when resource_name = 'PASSWORD_REUSE_MAX' then limit else null end) default_password_reuse_max
            from dba_profiles
            where profile = 'DEFAULT'
        ) default_profile;
    
        --Get user's password information.
        select
            'alter user '||name||' identified by values '''||
            spare4 || case when password is not null then ';' else null end || password ||
            ''''
        into v_alter_user_sql
        from sys.user$
        where name = v_username;
    
        --Change profile limits, if necessary.
        if v_old_password_reuse_time <> 'UNLIMITED' then
            execute immediate 'alter profile '||v_profile||' limit password_reuse_time unlimited';
        end if;
    
        if v_old_password_reuse_max <> 'UNLIMITED' then
            execute immediate 'alter profile '||v_profile||' limit password_reuse_max unlimited';
        end if;
    
        --Change the user's password.
        execute immediate v_alter_user_sql;
    
        --Change the profile limits back, if necessary.
        if v_old_password_reuse_time <> 'UNLIMITED' then
            if v_uses_default_for_time = 'Yes' then
                execute immediate 'alter profile '||v_profile||' limit password_reuse_time default';
            else
                execute immediate 'alter profile '||v_profile||' limit password_reuse_time '||v_old_password_reuse_time;
            end if;
        end if;
    
        if v_old_password_reuse_max <> 'UNLIMITED' then
            if v_uses_default_for_max = 'Yes' then
                execute immediate 'alter profile '||v_profile||' limit password_reuse_max default';
            else
                execute immediate 'alter profile '||v_profile||' limit password_reuse_max '||v_old_password_reuse_max;
            end if;
        end if;
    end;
    /
    

    【讨论】:

    • 可以,但您可以在不知道密码的情况下将密码重置为之前的值。
    • @louigi600 我的答案的后半部分使用密码哈希解决了该选项。不幸的是,要制定一个适合所有人的解决方案有点混乱。
    【解决方案2】:

    编译自 jonearles 的回答 http://kishantha.blogspot.com/2010/03/oracle-enterprise-manager-console.htmlhttp://blog.flimatech.com/2011/07/17/changing-oracle-password-in-11g-using-alter-user-identified-by-values/ (Oracle 11g):

    要阻止这种情况在未来发生,请执行以下操作。

    • 以 sysdba 身份登录 sqlplus -> sqlplus "/as sysdba"
    • 执行->ALTER PROFILE DEFAULT LIMIT FAILED_LOGIN_ATTEMPTS UNLIMITED PASSWORD_LIFE_TIME UNLIMITED;

    要重置用户的状态,请运行查询:

    select
    'alter user ' || su.name || ' identified by values'
       || ' ''' || spare4 || ';'    || su.password || ''';'
    from sys.user$ su 
    join dba_users du on ACCOUNT_STATUS like 'EXPIRED%' and su.name = du.username;
    

    并执行部分或全部结果集。

    【讨论】:

    • 我只需要先使 linesize 更大,这样我就可以轻松复制结果:set linesize 200;
    • 这对我有帮助!!谢谢!
    【解决方案3】:
    set long 9999999
    set lin 400
    select DBMS_METADATA.GET_DDL('USER','YOUR_USER_NAME') from dual;
    

    这将输出如下内容:

    SQL> select DBMS_METADATA.GET_DDL('USER','WILIAM') from dual;
    
    DBMS_METADATA.GET_DDL('USER','WILIAM')
    --------------------------------------------------------------------------------
    
       CREATE USER "WILIAM" IDENTIFIED BY VALUES 'S:6680C1468F5F3B36B726CE7620F
    FD9657F0E0E49AE56AAACE847BA368CEB;120F24A4C2554B4F'
          DEFAULT TABLESPACE "USER"
          TEMPORARY TABLESPACE "TEMP"
          PASSWORD EXPIRE
    

    只需将第一部分与 alter user 一起使用:

    ALTER USER "WILIAM" IDENTIFIED BY VALUES 'S:6680C1468F5F3B36B726CE7620F
    FD9657F0E0E49AE56AAACE847BA368CEB;120F24A4C2554B4F';
    

    这将使帐户回到OPEN 状态而不更改密码(只要您从DBMS_METADATA.GET_DDL 的输出中正确剪切和粘贴哈希值),您甚至不需要知道密码是。

    【讨论】:

      【解决方案4】:

      如果您知道该用户的密码,或者您想猜测它,请执行以下操作:

      • connect user/password

      如果此命令连接成功,您将看到“已连接”消息,否则您会看到错误消息。如果您随后成功登录,则意味着您知道密码。 在这种情况下,只需这样做:

      • alter user NAME_OF_THE_USER identified by OLD_PASSWORD;

      这会将密码重置为与以前相同的密码,并重置该用户的 account_status。

      【讨论】:

        【解决方案5】:

        Step-1 需要使用以下查询查找用户详细信息

        SQL> select username, account_status from dba_users where username='BOB';
        
        USERNAME                       ACCOUNT_STATUS
        ------------------------------ --------------------------------
        BOB                            EXPIRED
        

        Step-2 使用以下查询获取用户密码。

        SQL>SELECT 'ALTER USER '|| name ||' IDENTIFIED BY VALUES '''|| spare4 ||';'|| password ||''';' FROM sys.user$ WHERE name='BOB';
        
        ALTER USER BOB IDENTIFIED BY VALUES 'S:9BDD17811E21EFEDFB1403AAB1DD86AB481E;T:602E36430C0D8DF7E1E453;2F9933095143F432';
        

        步骤 -3 在更改查询之上运行

        SQL> ALTER USER BOB IDENTIFIED BY VALUES 'S:9BDD17811E21EFEDFB1403AAB1DD86AB481E;T:602E36430C0D8DF7E1E453;2F9933095143F432';
        User altered.
        

        第 4 步:检查用户帐户状态

        SQL> select username, account_status from dba_users where username='BOB';
        USERNAME                       ACCOUNT_STATUS
        ------------------------------ --------------------------------
        BOB                            OPEN
        

        【讨论】:

          【解决方案6】:

          第一部分(查找用户是否存在)

          --可以检查系统类型帐户,例如 SYS

          1. SQL> select username, account_status from dba_users where username='BOB';

          2. SQL> select username, account_status from dba_users where username like 'BOB%';

          3. SQL> select username, account_status from dba_users where like '%BOB%';

          第二部分更改帐户属性

          SQL> ALTER user [username] account UNLOCK; --解锁被锁定的帐户

          SQL> Alter user [username] IDENTIFIED BY "password"; -- 将更改用户密码

          【讨论】:

            猜你喜欢
            • 2018-08-09
            • 1970-01-01
            • 1970-01-01
            • 2021-09-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-02-26
            相关资源
            最近更新 更多