API: QSYGETPH は IBM API解説書では「プロファイル・ハンドルの取得」
という表題で紹介されているために、うっかり見逃してしまう API であるが、この API によれば
IBM System i の堅牢なユーザー管理システムを利用できる適用業務を構築することができる。
もう少し簡単に説明してみよう。
例えばC/S (クライアント/サーバー) や Web適用業務においてサイン・オンに代わる
ユーザー認証をどのように作成するか? ということである。
ユーザー認証フォーム(HTML)を作成して、エンド・ユーザーにユーザー名やパスワードを
入力させて フォーム SUBMIT したのでは、入力されたユーザーとパスワードは
そのままの形でTCP/IPストリームとしてインターネット回線を流れていくことになり
第三者の傍受によって、いとも簡単にユーザー,パスワードを盗まれてしまうだろう。

このような脆弱なユーザー認証を防ぐにはやはり System i の堅牢なサイン・オンの
システムを利用するに限ることはいうまでも無い。
5250 エミュレータで利用されているサイン・オンによる認証の仕組みは
ここで紹介する API : QSYGETPH によって実現することができる。
つまり QSYGETPH は 5250エミュレータのサインオンの仕組みを再現するための API である。
QSYGETPH とは「プロファイル・ハンドルの取得」という比較的わかりにくい表現で
紹介されているために System i の開発者に利用されている頻度が少ないのではないかと思われる。
「プロファイル・ハンドル」とはユーザー・プロフィールによる環境を構築したときを個別に
識別する識別子のことである。
識別子(ハンドル)とは i5/OS によって重なりのないように自動生成された一意的な値として
生成される。
つまり同じ記号や番号として偶然にも他のものと重なることがないように i5/OS によって
ランダムに発生した記号であり、これによって現在、実行中のユーザー環境を識別するのである。
別の話になるが、あなたも既に自分の Windows PC 上に多くのウィンドウを開いているはずである。
Windows OS は、これらのすべてのウィンドウにやはり「ウィンドウ・ハンドル」と呼ばれる
識別子を持っていて、それらを個別に制御しているのである。
このように複数個、存在する実行中のオブジェクトを識別するための識別子のことを「ハンドル」と呼ぶ。
前置きが長くなってしまったが System i の開発者には「ハンドル」という言葉にはあまり
馴染みがないと思われるので解説した次第である。
仮想ログイン (サイン・オン) の流れ
【解説】
仮想ユーザー環境とは QSYGETPH によってハンドルを取得したときに始まって
QSYRLSPH によってハンドルが解放されるまでのあいだの環境のことである。
つまり QSYGETPH によってサイン・オンされて QSYRLSPH によってサイン・オフされると考えてよい。
ここでは API による仮想ユーザー環境の構築と i5/OS リリース別の考慮点についても
現実的で詳細な解説を加えていこうと思う。
QSYGETPH: プロファイル・ハンドルの取得
必須パラメータ・グループ:
| 1. | ユーザーID | 入力 | Char(10) |
| 2. | パスワード | 入力 | Char(*) |
| 3. | プロファイル・ハンドル | 出力 | Char(12) |
任意選択パラメータ:
| 4. | エラー・コード | 入出力 | Char(*) |
任意選択パラメータ:
| 5. | パスワードの長さ | 入力 | Binary(4) |
| 6. | パスワードの CCSID | 入力 | Binary(4) |
1. ユーザーID
ユーザー・ハンドルを生成する、つまり仮想ログインするユーザー・プロフィールの
10桁の名前。特殊値として *CURRENT を指定すると現在のユーザー名のハンドルを
取得することができる。
現在のユーザー(*CURRENT)を取得する理由は、別のユーザーとしてログインしたいときに
現在のユーザーのハンドルを取得しておいてログインしたユーザーを終了したときに
現在のユーザーに戻すために使用する。
2. パスワード
上記で指定するユーザーのパスワード。OS V5R2M0 までは 10桁であるが
V5R3M0 以上では最大128桁までのパスワードを指定することができる。
また特殊値として *NOPWD とはパスワードがないことを意味する。
例えば HTTP サーバーでの省略時のユーザー : QTMHHTTP はパスワードを持たないので
*NOPWD を指定する必要がある。
また QSYS, QDOC, QSPL, QRJE, … のように、QSYGETPH を使ってもハンドルの取得で
許されていないユーザーも存在する。
3. プロファイル・ハンドル
QSYGETPH によって自動生成される 12 桁のランダム・ストリングとしての
ユーザー環境を識別するための識別子。
5. パスワードの長さ
OS V5R3M0 以降に追加されたパラメータであり、パスワードの長さの指定である。
このパラメータは任意パラメータとして V5R3M0 から初めて紹介されたが
V5R3M0 では必須パラメータであり、正しく指定していないと QSYGETPH は
エラーとなって動作しない。これはOS V5R3M0 のバグであり、とうとう最後まで
IBM によって修正されることはなかった。
弊社が原因不明として苦しめられたバグのひとつである。( V5R3M0 はバグの多い問題のあるリリースであった )
IBM は OS Ver5.4 で、このバグを修正して「任意指定パラメータ」のマニュアルの
とおりに指定していなくてもエラーとはしないように正しい動作に改訂されている。
6. パスワードの CCSID
通常では 65535 を指定しておけばよい。
【 サンプル・ソース:TESTGETPH 】
これはユーザーが任意に入力したユーザーで仮想ログインするプログラムである。
0001.00 H DFTNAME(TESTGETPH) DATEDIT(*YMD/)
0002.00 F********** QSYGETPH のテスト *****************************************
0003.00 F*
0004.00 F**********************************************************************
0005.00 D APIERR DS
0006.00 D GETBYT 1 4B 0 INZ(160)
0007.00 D AVLBYT 5 8B 0 INZ(0)
0008.00 D MSGID 9 15
0009.00 D MSGDTA 17 160
0010.00
0011.00 D SPCBIN DS
0012.00 D INZSIZ 10I 0 INZ(1000)
0013.00 D MSGDTALEN 10I 0 INZ(100)
0014.00 D PGMSTKCNT 10I 0 INZ(1)
0015.00 D USER 10A
0016.00 D PASSWRD 30A
0017.00 D PASSLEN 10I 0
0018.00 D PASSCCSID 10I 0 INZ(65535)
0019.00 D PRFHND 12A
0020.00 D CMDLEN 15P 5 INZ(20)
0021.00
0022.00 * QGPL/QSS1MRI データエリア
0023.00 D LDA UDS 750
0024.00 D OS400 1 6
0025.00 D OTHERS 7 750
0026.00
0027.00 D MSGFFLIB DS
0028.00 D MSGF 10A INZ('QCPFMSG ')
0029.00 D MSGFLIB 10A INZ('QSYS ')
0030.00
0031.00 D USRMSG C CONST(' ユーザー名を入力して -
0032.00 D ください ')
0033.00 D PASMSG C CONST(' パスワードを入力 ')
0034.00 D LOGMSG C CONST(' ログインを成功しました。 ')
0035.00 D ERRMSG C CONST(' エラーが発生しました。 -
0036.00 D JOBLOG を見てください ')
0037.00 D CMD S 80A INZ('DSPJOB OPTION(*STSA)')
0038.00
0039.00 C*(1) OS400 リリースを調べる
0040.00 C *DTAARA DEFINE QSS1MRI LDA
0041.00 C *LOCK IN LDA
0042.00 C UNLOCK LDA
0043.00
0044.00 C*(2) ユーザーとパスワードの入力
0045.00 C USRMSG DSPLY USER
0046.00 C PASMSG DSPLY PASSWRD
0047.00 C ' ' CHECKR PASMSG PASSLEN
0048.00 C PASSLEN IFLT 10
0049.00 C EVAL PASSLEN = 10
0050.00 C END
0051.00
0052.00 C*(3) QSYGETPH によるログイン
0053.00 C OS400 IFLT 'V5R3M0'
0054.00 C*----------------------------------------------------+
0055.00 C CALL(E) 'QSYGETPH'
0056.00 C PARM USER
0057.00 C PARM PASSWRD
0058.00 C PARM PRFHND
0059.00 C PARM APIERR
0060.00 C*----------------------------------------------------+
0061.00 C ELSE
0062.00 C*----------------------------------------------------+
0063.00 C CALL(E) 'QSYGETPH'
0064.00 C PARM USER
0065.00 C PARM PASSWRD
0066.00 C PARM PRFHND
0067.00 C PARM APIERR
0068.00 C PARM PASSLEN
0069.00 C PARM PASSCCSID
0070.00 C END
0071.00 C*----------------------------------------------------+
0072.00 C AVLBYT CABNE *ZEROS SNDERR
0073.00
0074.00 C*(4) 指定したユーザーで JOB を開始する
0075.00 C*----------------------------------------------------+
0076.00 C CALL(E) 'QWTSETP'
0077.00 C PARM PRFHND
0078.00 C PARM APIERR
0079.00 C*----------------------------------------------------+
0080.00 C AVLBYT CABNE *ZEROS SNDERR
0081.00 C LOGMSG DSPLY ANS 1
0082.00
0083.00 C*(5) 変更された JOB を DSPJOB で確認する
0084.00 C*----------------------------------------------------+
0085.00 C CALL(E) 'QCMDEXC'
0086.00 C PARM CMD
0087.00 C PARM CMDLEN
0088.00 C*----------------------------------------------------+
0089.00
0090.00 C*(6) ハンドルを閉じて JOB を終了する
0091.00 C*----------------------------------------------------+
0092.00 C CALL(E) 'QSYRLSPH'
0093.00 C PARM PRFHND
0094.00 C*----------------------------------------------------+
0095.00 C SETON LR
0096.00 C RETURN
0097.00
0098.00 C SNDERR TAG
0099.00 C ERRMSG DSPLY ANS 1
0100.00 C GETBYT SUB 15 MSGDTALEN
0101.00 C*----------------------------------------------------+
0102.00 C CALL(E) 'QMHSNDPM'
0103.00 C PARM MSGID
0104.00 C PARM MSGFFLIB
0105.00 C PARM MSGDTA
0106.00 C PARM MSGDTALEN
0107.00 C PARM '*ESCAPE ' MSGTYPE 10
0108.00 C PARM '* ' PGMQUE 10
0109.00 C PARM PGMSTKCNT
0110.00 C PARM ' ' MSGKEY 4
0111.00 C PARM APIERR
0112.00 C*----------------------------------------------------+
0113.00 C MOVE *ON *INLR
0114.00 C RETURN 
【解説】
このプログラムは OS V3R7M0 - V5R3M0, および V5R3M0 以上での動作をカバーしている。
0022.00 * QGPL/QSS1MRI データエリア
0023.00 D LDA UDS 750
0024.00 D OS400 1 6
0025.00 D OTHERS 7 750
:
0039.00 C*(1) OS400 リリースを調べる
0040.00 C *DTAARA DEFINE QSS1MRI LDA
0041.00 C *LOCK IN LDA
0042.00 C UNLOCK LDA
によって QGPL/QSS1MRI *DTAARA の 1-6 桁に記述されているOS リリースを読み取って、
0052.00 C*(3) QSYGETPH によるログイン 0053.00 C OS400 IFLT 'V5R3M0' 0054.00 C*----------------------------------------------------+ 0055.00 C CALL(E) 'QSYGETPH' 0056.00 C PARM USER 0057.00 C PARM PASSWRD 0058.00 C PARM PRFHND 0059.00 C PARM APIERR 0060.00 C*----------------------------------------------------+ 0061.00 C ELSE 0062.00 C*----------------------------------------------------+ 0063.00 C CALL(E) 'QSYGETPH' 0064.00 C PARM USER 0065.00 C PARM PASSWRD 0066.00 C PARM PRFHND 0067.00 C PARM APIERR 0068.00 C PARM PASSLEN 0069.00 C PARM PASSCCSID 0070.00 C END 0071.00 C*----------------------------------------------------+
のようにして OS V5R3M0 以上であればパスワード長も追加して、それ未満であれば
パスワード長は指定せずに実行する。
これによって
- OS
V5R3M0以降とそれ未満の OS環境の両方をサポート - OS
V5R3M0での OS のバグの回避
の両方ともを解決している。
次に QSYGETPH で取得したハンドルを使って
0074.00 C*(4) 指定したユーザーで JOB を開始する 0075.00 C*----------------------------------------------------+ 0076.00 C CALL(E) 'QWTSETP' 0077.00 C PARM PRFHND 0078.00 C PARM APIERR 0079.00 C*----------------------------------------------------+
によって仮想ユーザー環境が開始されるので
0037.00 D CMD S 80A INZ('DSPJOB OPTION(*STSA)')
:
0083.00 C*(5) 変更された JOB を DSPJOB で確認する
0084.00 C*----------------------------------------------------+
0085.00 C CALL(E) 'QCMDEXC'
0086.00 C PARM CMD
0087.00 C PARM CMDLEN
0088.00 C*----------------------------------------------------+
を実行すると「現行ユーザー・プロファイル」が指定したユーザーであり
元の「ユーザー」とは異なるユーザーでログインされていることを確認することができる。
次はユーザーQTR でサインオンされている環境で、このサンプル・ブログラム TESTGETPH で
MN00 として仮想ログインしたときの DSPJOB OPTION(*STSA) が実行されいる様子である。

RPG の実行例として仮想ログイン環境を示すために DSPJOB コマンドを実行するように
したが CLP の例ではさらに興味深い例を紹介するので、そちらも是非参照して欲しい。
