RPG

198. API : QSYGETPH 仮想ユーザー・ログインの方法

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 の例ではさらに興味深い例を紹介するので、そちらも是非参照して欲しい。