【Oracle】ユーザーアカウントのロック解除手順|ACCOUNT_STATUS 別対処・原因調査・EXPIRED 復旧・再発防止まで解説

【Oracle】ユーザーアカウントのロック解除手順|ACCOUNT_STATUS 別対処・原因調査・EXPIRED 復旧・再発防止まで解説 Oracle

Oracle でログインしようとしたときに ORA-28000: the account is locked が出たら、アカウントがロック状態になっています。原因はパスワードの連続失敗、パスワードの期限切れ、DBA による手動ロックなど様々です。

本記事では、ACCOUNT_STATUS の全状態と対処法ロック原因の特定解除手順再発防止策まで解説します。

この記事でわかること
・ACCOUNT_STATUS の全 9 種の意味と対処法
・ORA-28000(ロック)/ ORA-28001(期限切れ)の違い
・ロック原因の特定(監査ログ / DBA_USERS)
・ALTER USER ACCOUNT UNLOCK の実行手順
・EXPIRED 状態のパスワード再設定
・一括ロック解除スクリプト
・FAILED_LOGIN_ATTEMPTS / PASSWORD_LOCK_TIME の見直し
スポンサーリンク

ACCOUNT_STATUS の全状態と対処法

SQL(ユーザーの状態を確認)
-- ユーザーのアカウント状態を確認
SELECT username, account_status, lock_date, expiry_date, profile
FROM dba_users
WHERE username NOT IN ('SYS','SYSTEM','ANONYMOUS','XDB','DBSNMP','AUDSYS')
ORDER BY account_status, username;
ACCOUNT_STATUS 意味 ログイン 対処法
OPEN 正常 可能 対処不要
LOCKED DBA が手動でロック 不可 ALTER USER … ACCOUNT UNLOCK
LOCKED(TIMED) ログイン失敗で自動ロック 不可(自動解除あり) PASSWORD_LOCK_TIME 経過で自動解除、または手動 UNLOCK
EXPIRED パスワード期限切れ 不可 ALTER USER … IDENTIFIED BY new_password
EXPIRED(GRACE) 猶予期間中 可能(警告あり) 猶予期間内にパスワード変更
EXPIRED & LOCKED 期限切れ + ロック 不可 IDENTIFIED BY + ACCOUNT UNLOCK
EXPIRED(GRACE) & LOCKED 猶予中 + ロック 不可 IDENTIFIED BY + ACCOUNT UNLOCK
EXPIRED(GRACE) & LOCKED(TIMED) 猶予中 + 自動ロック 不可 IDENTIFIED BY + ACCOUNT UNLOCK(または自動解除を待つ)
EXPIRED & LOCKED(TIMED) 期限切れ + 自動ロック 不可 IDENTIFIED BY + ACCOUNT UNLOCK
LOCKED と LOCKED(TIMED) の違い
LOCKED: DBA が ALTER USER ... ACCOUNT LOCK で手動ロック → 手動 UNLOCK 必須
LOCKED(TIMED): FAILED_LOGIN_ATTEMPTS 超過で自動ロック → PASSWORD_LOCK_TIME 経過で自動解除(手動 UNLOCK も可)

ロック解除の手順

LOCKED の解除

SQL(アカウントのアンロック)
-- DBA または SYS で接続
-- sqlplus / as sysdba

-- アカウントをアンロック
ALTER USER hr ACCOUNT UNLOCK;

-- 確認
SELECT username, account_status FROM dba_users WHERE username = 'HR';
-- account_status = OPEN であれば解除完了

EXPIRED の解除(パスワード再設定)

SQL(パスワード再設定 + アンロック)
-- パスワードの再設定(EXPIRED 解除)
ALTER USER hr IDENTIFIED BY new_password;

-- EXPIRED & LOCKED の場合はアンロックも同時に
ALTER USER hr IDENTIFIED BY new_password ACCOUNT UNLOCK;

-- 確認
SELECT username, account_status, expiry_date FROM dba_users WHERE username = 'HR';

LOCKED(TIMED) の解除

SQL(自動解除を待つ or 手動解除)
-- PASSWORD_LOCK_TIME の設定を確認
SELECT resource_name, limit FROM dba_profiles
WHERE profile = (SELECT profile FROM dba_users WHERE username = 'HR')
  AND resource_name = 'PASSWORD_LOCK_TIME';
-- 例: 1(1 日後に自動解除)/ 1/24(1 時間後)

-- 手動で即座に解除したい場合
ALTER USER hr ACCOUNT UNLOCK;
ACCOUNT UNLOCK だけでは EXPIRED は解除されない
ACCOUNT_STATUS が EXPIRED & LOCKED の場合、ALTER USER ... ACCOUNT UNLOCK だけではアカウントは EXPIRED 状態のままです。パスワードも再設定する必要があります。ALTER USER hr IDENTIFIED BY password ACCOUNT UNLOCK で両方同時に解除できます。

ロック原因の特定

DBA_USERS で基本情報を確認

SQL(ロック日時の確認)
-- LOCK_DATE でいつロックされたか確認
SELECT username, account_status, lock_date, expiry_date
FROM dba_users
WHERE account_status LIKE '%LOCKED%'
ORDER BY lock_date DESC;

監査ログでログイン失敗を調査

SQL(統合監査: ログイン失敗の履歴)
-- 統合監査(12c 以降)
SELECT dbusername, os_username, userhost,
       event_timestamp, return_code
FROM unified_audit_trail
WHERE action_name = 'LOGON'
  AND return_code <> 0  -- 0 以外 = 失敗
  AND dbusername = 'HR'
ORDER BY event_timestamp DESC
FETCH FIRST 20 ROWS ONLY;

-- return_code の意味:
-- 1017 = パスワード不正
-- 28000 = アカウントロック
-- 28001 = パスワード期限切れ
SQL(伝統的監査: ログイン失敗)
-- 伝統的監査
SELECT username, os_username, userhost,
       timestamp, returncode
FROM dba_audit_trail
WHERE action_name = 'LOGON'
  AND returncode IN (1017, 28000)
  AND username = 'HR'
ORDER BY timestamp DESC;

ログイン失敗の IP アドレスを特定

SQL(どの IP から失敗しているかを集計)
-- IP アドレス別のログイン失敗回数(不正アクセスの調査)
SELECT userhost, dbusername,
       COUNT(*) AS fail_count,
       MAX(event_timestamp) AS last_attempt
FROM unified_audit_trail
WHERE action_name = 'LOGON'
  AND return_code = 1017  -- パスワード不正
  AND event_timestamp >= SYSDATE - 7
GROUP BY userhost, dbusername
ORDER BY fail_count DESC;
ロック原因の特定フロー
(1) DBA_USERS.ACCOUNT_STATUS で状態を確認
(2) LOCK_DATE でいつロックされたか確認
(3) 監査ログで同時刻のログイン失敗を調査
(4) USERHOST でどの端末/IP から失敗しているか特定
(5) アプリケーションの接続設定ミス or 不正アクセスの判断

よくあるロック原因と対処

原因 症状 対処
アプリの接続パスワードが古い 大量のログイン失敗 → LOCKED(TIMED) アプリの接続設定を修正 → ACCOUNT UNLOCK
パスワードの期限切れ EXPIRED → ORA-28001 ALTER USER … IDENTIFIED BY new_password
接続プールの古いセッション プール内の接続が期限切れパスワードでリトライ プールのリフレッシュ設定を確認
ブルートフォース攻撃 不明な IP から大量の失敗 監査ログで IP を特定 → ファイアウォールでブロック
DBA が手動ロック LOCKED(lock_date あり) 意図的なロックか DBA に確認 → ACCOUNT UNLOCK
ユーザーの入力ミス 数回の失敗で LOCKED(TIMED) 自動解除を待つか手動 UNLOCK

一括ロック解除スクリプト

SQL(ロック中の全ユーザーを一括解除)
-- ロック中のユーザーを一括アンロック
BEGIN
    FOR rec IN (
        SELECT username FROM dba_users
        WHERE account_status LIKE '%LOCKED%'
          AND username NOT IN ('SYS','SYSTEM','ANONYMOUS','XDB','DBSNMP','AUDSYS')
    ) LOOP
        EXECUTE IMMEDIATE 'ALTER USER ' || rec.username || ' ACCOUNT UNLOCK';
        DBMS_OUTPUT.PUT_LINE('Unlocked: ' || rec.username);
    END LOOP;
END;
/
SQL(EXPIRED & LOCKED を一括復旧: パスワードは個別に設定必要)
-- EXPIRED 状態のユーザー一覧(パスワード再設定が必要)
SELECT username, account_status, expiry_date
FROM dba_users
WHERE account_status LIKE '%EXPIRED%'
  AND username NOT IN ('SYS','SYSTEM','ANONYMOUS','XDB')
ORDER BY expiry_date;

-- 個別にパスワードを再設定 + アンロック
ALTER USER hr IDENTIFIED BY temp_password ACCOUNT UNLOCK;
ALTER USER app_user IDENTIFIED BY temp_password ACCOUNT UNLOCK;

-- ※ パスワードはセキュリティ上、一括自動生成できないため個別設定が必要
一括アンロックは開発環境でのみ推奨
本番環境で全ユーザーを一括アンロックすると、不正アクセスで意図的にロックしたユーザーまで解除してしまうリスクがあります。本番では個別に原因を確認してからアンロックしてください。

再発防止策

FAILED_LOGIN_ATTEMPTS / PASSWORD_LOCK_TIME の見直し

SQL(プロファイルのパスワードポリシーを確認・変更)
-- 現在の設定を確認
SELECT profile, resource_name, limit
FROM dba_profiles
WHERE resource_name IN ('FAILED_LOGIN_ATTEMPTS', 'PASSWORD_LOCK_TIME')
ORDER BY profile;

-- デフォルト: FAILED_LOGIN_ATTEMPTS=10, PASSWORD_LOCK_TIME=1(日)

-- ロック時間を 30 分に短縮(頻繁にロックされる環境向け)
ALTER PROFILE DEFAULT LIMIT
    FAILED_LOGIN_ATTEMPTS 10
    PASSWORD_LOCK_TIME 1/48;  -- 1/48 日 = 30 分

-- 開発環境: ロックを無効化
ALTER PROFILE dev_profile LIMIT
    FAILED_LOGIN_ATTEMPTS UNLIMITED;

アプリケーション接続ユーザーの対策

SQL(アプリ接続ユーザーの専用プロファイル)
-- アプリ接続ユーザーはロック閾値を高めに設定
CREATE PROFILE app_connection LIMIT
    FAILED_LOGIN_ATTEMPTS 20   -- 接続プールのリトライに耐える
    PASSWORD_LOCK_TIME 1/96    -- 15 分で自動解除
    PASSWORD_LIFE_TIME UNLIMITED;  -- アプリ用は期限なし

ALTER USER app_user PROFILE app_connection;
対策 設定
ロック時間を短縮 PASSWORD_LOCK_TIME 1/48(30 分)/ 1/96(15 分)
失敗回数の閾値を引き上げ FAILED_LOGIN_ATTEMPTS 20(接続プール環境)
開発環境でロック無効化 FAILED_LOGIN_ATTEMPTS UNLIMITED
アプリユーザーのパスワード期限を無制限に PASSWORD_LIFE_TIME UNLIMITED
不正アクセスの検出 監査ログで IP 別の失敗回数を定期監視

パスワード有効期限の詳細は「パスワードの有効期限を無制限にする方法」、プロファイルの全設定は「ユーザープロファイル完全ガイド」、パスワードポリシーのカスタマイズは「パスワードポリシーをカスタマイズする方法」を参照してください。

関連する ORA エラー

エラー 意味 対処
ORA-28000 アカウントがロックされている ALTER USER … ACCOUNT UNLOCK
ORA-28001 パスワードが期限切れ ALTER USER … IDENTIFIED BY new_password
ORA-28002 パスワードは猶予期間内に期限切れ(警告) 猶予期間内にパスワードを変更
ORA-01017 ユーザー名/パスワードが無効 パスワードを確認。連続失敗するとロックされる

実務パターン集

パターン(1): アプリ接続エラーで緊急ロック解除

SQL
-- (1) 状態確認
SELECT username, account_status, lock_date FROM dba_users WHERE username = 'APP_USER';
-- LOCKED(TIMED) / lock_date = 2026-03-30 08:15

-- (2) アンロック
ALTER USER app_user ACCOUNT UNLOCK;

-- (3) 原因調査: 監査ログでログイン失敗を確認
SELECT userhost, COUNT(*) FROM unified_audit_trail
WHERE dbusername = 'APP_USER' AND return_code = 1017
  AND event_timestamp >= SYSDATE - 1
GROUP BY userhost;

-- (4) アプリの接続設定(パスワード)を確認・修正

パターン(2): パスワード期限切れ + ロックの同時解除

SQL
-- EXPIRED & LOCKED の場合
ALTER USER hr IDENTIFIED BY NewSecurePass123 ACCOUNT UNLOCK;

-- 確認
SELECT account_status, expiry_date FROM dba_users WHERE username = 'HR';
-- OPEN / expiry_date = 180 日後

パターン(3): 全ロックユーザーの一覧と一括解除(開発環境)

SQL
-- ロック中のユーザー一覧
SELECT username, account_status, lock_date, profile
FROM dba_users
WHERE account_status LIKE '%LOCKED%'
  AND username NOT IN ('SYS','SYSTEM')
ORDER BY lock_date;

-- 開発環境: 一括アンロック
BEGIN
    FOR rec IN (
        SELECT username FROM dba_users
        WHERE account_status LIKE '%LOCKED%'
          AND username NOT IN ('SYS','SYSTEM','ANONYMOUS','XDB')
    ) LOOP
        EXECUTE IMMEDIATE 'ALTER USER ' || rec.username || ' ACCOUNT UNLOCK';
    END LOOP;
END;
/

パターン(4): ロック状態の定期監視

SQL(ロック発生を検知するアラート SQL)
-- LOCKED 状態のユーザーを検知(日次バッチで実行)
SELECT username, account_status, lock_date
FROM dba_users
WHERE account_status LIKE '%LOCKED%'
  AND lock_date >= SYSDATE - 1
  AND username NOT IN ('SYS','SYSTEM','ANONYMOUS','XDB');
-- 結果があればアラート通知

よくある質問

QLOCKED(TIMED) は何もしなくても自動で解除されますか?
Aはい。PASSWORD_LOCK_TIME に設定された時間が経過すると自動的に OPEN に戻ります。デフォルトは 1 日(24 時間)です。1/24 なら 1 時間、1/48 なら 30 分で自動解除されます。手動で即座に解除したい場合は ALTER USER ... ACCOUNT UNLOCK を実行してください。
QACCOUNT UNLOCK してもまたすぐロックされます
Aアプリケーションが古いパスワードでリトライし続けている可能性が高いです。監査ログで失敗元の IP / ホストを特定し、アプリの接続設定を修正してください。根本原因を解決しないとアンロック後に再びロックされます。
Qパスワードを変更せずに EXPIRED を解除できますか?
A同じパスワードで ALTER USER hr IDENTIFIED BY 同じパスワード を実行すれば EXPIRED は解除されます。ただし PASSWORD_REUSE 制約がある場合は拒否されることがあります。その場合は一時的に別パスワードにしてから元に戻してください。
QSYS ユーザーもロックされることはありますか?
Aはい。DBA_USERS 上は LOCKED になります。ただし sqlplus / as sysdba(OS 認証)はパスワード認証をバイパスするため、SYS がロックされてもサーバー上からログインできます。
QFAILED_LOGIN_ATTEMPTS を UNLIMITED にするのは安全ですか?
Aブルートフォース攻撃への耐性がなくなるため、本番環境では推奨しません。開発環境や、ファイアウォールで IP 制限が厳格に行われている環境であれば許容できます。本番では 10〜20 回程度に設定し、PASSWORD_LOCK_TIME を短め(15〜30 分)にするのがバランスの良い設定です。
Qアカウントロックの履歴はどこに記録されますか?
A監査機能が有効であれば、LOGON の失敗が監査ログ(UNIFIED_AUDIT_TRAIL / DBA_AUDIT_TRAIL)に記録されます。return_code = 28000(ロック)や 1017(パスワード不正)で検索してください。DBA_USERS の LOCK_DATE 列でロックされた日時も確認できます。

まとめ

アカウントロック解除の要点をまとめます。

状態 対処コマンド
LOCKED ALTER USER user ACCOUNT UNLOCK
LOCKED(TIMED) PASSWORD_LOCK_TIME 経過で自動解除 / ALTER USER user ACCOUNT UNLOCK
EXPIRED ALTER USER user IDENTIFIED BY new_password
EXPIRED & LOCKED ALTER USER user IDENTIFIED BY new_password ACCOUNT UNLOCK
ロック原因の特定 DBA_USERS.LOCK_DATE + 監査ログ(return_code = 1017 / 28000)
再発防止: ロック時間を短縮 ALTER PROFILE … LIMIT PASSWORD_LOCK_TIME 1/48
再発防止: アプリ用プロファイル FAILED_LOGIN_ATTEMPTS 20 + PASSWORD_LIFE_TIME UNLIMITED

ユーザーの作成と権限付与は「ユーザー作成と権限付与の完全ガイド」、パスワード有効期限は「パスワードの有効期限を無制限にする方法」、接続制限は「ユーザーごとに接続制限を設定する方法」も併せて参照してください。