Zend Serverのoci8

Oracleインタフェース案件で、Zend Server for IBM iのoci8モジュールを使用しているが、この度Oracle側の更新で嵌ったので、備忘として。

開発内容

  • Oracle : 11g → 12c へ更新
  • 該当PHPプログラムを12cの新DBに対応させる

環境

本番環境

  • OS : IBM i V7R1M0
  • Zend Server for IBM i : 5.5
  • OCI8 : 2.0.8
  • Oracle Run-time Client Library Version : 10.2.0.5.0
  • Oracle Compile-time Instant Client Version :10.2
  • Oracle : 12.1

開発環境

  • OS : Windows 10
  • Zend Server for Windows : 9.1
  • OCI8 : 2.1.8
  • Oracle Run-time Client Library Version : 12.1.0.2.0
  • Oracle Compile-time Instant Client Version :12.1
  • Oracle : 12.2 (Vagrant上)

ORA-28040(認証プロトコル・エラー)

ORA-28040(認証プロトコル・エラー)までの流れ

  • 12c上にDB接続ユーザーを作成
  • 開発環境で、oci8で12c接続プログラムを開発し問題なく動作
  • 同プログラムを本番環境へデプロイ
  • 本番環境でプログラム実行
  • ORA-28040(認証プロトコル・エラー)

開発環境では、正常に接続できたOracleに対して、本番環境では、28040 ORA-28040: No matching authentication protocolが発生。

この場合、oci8のバージョン自体は最新でも、Oracle Run-time Client Library Version が、Windows版 Zend Server(12系)とIBM i版(10系)で、異なる事が原因と考えられる。
対処方法として、sqlnet.ora($ORACLE_HOME/network/admin/sqlnet.ora) を次の様に変更する事で、下位バージョンのクライアントと互換性を保つことが出来る。

指定は認証バージョンであり、Oracleのバージョンではない。

cd $ORACLE_HOME(/opt/oracle/product/12.2.0.1/dbhome_1)/network/admin
sudo vi sqlnet.ora

----- ファイル編集 -----
NAME.DIRECTORY_PATH= (TNSNAMES, EZCONNECT, HOSTNAME)
## ↓を追加
SQLNET.ALLOWED_LOGON_VERSION_SERVER=11(※認証バージョン)
認証バージョン 生成パスワードのバージョン
12a 12c
12 12c,11g
11 12c,11g,10g
10~8 11と同じ

変更後にリスナーの再起動を行う。

嵌ったポイント

ORA-01017: invalid username/password;

前述のORA-28040までは、直ぐに気づき対処出来たが、この後にORA-01017: invalid username/password; logon deniedが発生し、少し躓いた。

普段Oracleを使用しない私は、SQLNET.ALLOWED_LOGON_VERSION_SERVER設定を、てっきりスイッチだと思っていたが、Oracleユーザーにパスワード・バージョンはキャッシュされており、SQLNET.ALLOWED_LOGON_VERSION_SERVER設定後に作成されたユーザーでないと、認証バージョンが反映されていない。

SQLNET.ALLOWED_LOGON_VERSION_SERVER設定前に作成したユーザーに、パスワード・バージョンを反映させたい場合は、該当ユーザーのパスワード更新が必要となる。

パスワード更新後は無事接続出来た。
ユーザーに登録されているパスワード・バージョンの確認する場合は、SQL*PlusSQL Developerを使用して、次のSQLを実行する。

select 
 username,password_versions 
from dba_users where account_status='OPEN'
;