メニューボタン
IBMi海外記事2008.02.14

CLコマンド出口点プログラムによるセキュリティ強化

ダン・リール 著

制御言語(CL: Control Language)は常に、妥当性チェック・プログラムとコマンド処理プログラムを備えていました。IBMは長年にわたって、プロンプト上書き、プロンプト選択、プロンプト制御プログラムなどを追加してきました。以前、V4R5の頃、IBMはCLの機能をさらに強化したコマンド・アナライザ出口プログラムを追加しましたが、さらに重要なのは、こうしたプログラムはシステムのセキュリティを強化することができるということです。

実装されて以来見過ごされてきた新しい出口点プログラムが主に2つありますが、これらは便利な監査機能や制御機能をシステムに追加するものです。i5/OSの登録機能(WRKREGINF)にはコマンド・アナライザ変更(Command Analyzer Change)とコマンド・アナライザ取り出し(Command Analyzer Retrieve)という2つのCLコマンド出口点があります。本稿ではまず、CLコマンドの使用を制御するのに利用できるコマンド・アナライザ変更(Command Analyzer Change)の出口点について説明し、次に、コマンドの使用をリアルタイムで監査できる取り出し出口点について述べます。

コマンド・アナライザ変更

この出口点を使用すると、CLコマンドが実行される前に割り込みをかけ、独自のカスタム処理を実行させることができます。独自のカスタム処理は、コマンドのパラメータ値を変更するだけという単純なものの場合もあれば、全く異なるライブラリの全く異なるCLコマンドを実行するような場合もあります。

WRKJOBコマンドを制御する簡単な出口プログラムの例を見てみましょう。この例では、WRKJOBコマンドが *USERというユーザー・クラスを持つあるユーザーによって実行されている場合、この出口プログラムはコマンド・アナライザに対して、代わりにDSPJOBコマンドを実行するよう指示します。セキュリティ上の目的のために、この機能を使用してWRKJOBコマンドを非*USERクラスのユーザーに対してのみその使用を制限することができます。WRKJOBコマンドを使用するとユーザーはジョブの変更、保留、終了ができるのに対し、DSPJOBコマンドではこれらのいずれのオプションも使用できません。WRKJOBコマンドに対するこうした予防措置により、システムのセキュリティが強化されます。どのコマンドを制御するか、どのコマンド・パラメータを強要するのかを決めるのは皆さんの想像力にお任せしますが、その可能性は無限です。

出口点と出口プログラムの再検討

出口点とは、アプリケーションがオプションとして外部プログラムを呼び出し、カスタマイズされた処理を実行できるポイントのことです。i5/OSコマンド・アナライザには、自作したプログラムをフックしてコマンド処理ロジックに引き込むことができる出口点があります。出口プログラムとそこで呼び出されるコマンドを識別するには、Add Exit Program (ADDEXITPGM)コマンドを使用し、この出口プログラムが使用されるコマンド名とライブラリ及び、この特定のコマンドを処理する出口プログラムの名前とライブラリを指定します。

コマンド・アナライザに対してコマンドを実行する要求がくると、アナライザは出口点のレジストリをチェックして、要求されたコマンドに対して出口プログラムが割り当てられているかどうかを調べます。もし出口プログラムが割り当てられていれば、その出口プログラムが呼び出され、要求されたコマンドに関する情報を含んだパラメータが渡されます。次に、呼び出された出口プログラムはその渡された情報を処理して適切なアクションを取ります。
各出口点には名前と出口点インタフェースが割り当てられています。出口点インタフェースは、コマンド・アナライザが出口プログラムと交換する入出力パラメータのリストにすぎません。コマンド・アナライザ変更コマンド出口点用の出口点の名前はQIBM_QCA_CHG_COMMANDです。

この出口点は、コマンド・アナライザがコマンドを要求する前、しかも妥当性チェック・プログラムが呼び出される前に発生します。この出口点用の出口点インタフェースの名前はCHGC0100です。この出口点インタフェースは、皆さんの出口プログラムが別々のパラメータを渡されるのではなく、1つの大きなデータの塊として渡されるという点において、一般の出口点インタフェースと異なります。皆さんのプログラムは、CHGC0100パラメータの各データ要素を構文解析する必要があります。さらに、皆さんの出口プログラムには2つのパラメータが追加で渡されます(図1)。

登録されている他の出口点と同様に、ADDEXITPGMコマンドを使用して自分の出口点プログラムを追加することができます。変更コマンド出口点の場合、以下の例のように、PGMDTAパラメータにコマンドとコマンドが存在するライブラリの名前を指定する必要があります。

ADDEXITPGM EXITPNT(QIBM_QCA_CHG_COMMAND) +
      FORMAT(CHGC0100)  +
      PGMNBR(1)  +
      PGM(MYLIB/WRKJOBEXIT)   +
      TEXT('Exit program for WRKJOB')    +
      PGMDTA(*JOB 20 'WRKJOB QSYS')

上記の例のように、PGMDTAパラメータを長さ20字で指定します。そのうちの最初の10字はコマンド名で、次の10字はコマンドライブラリになります。コマンド・アナライザは、QSYSライブラリ中にあるWRKJOBコマンドを実行するようリクエストがあるときは必ず、MYLIBライブラリ中のWRKJOBEXIT出口プログラムを使用するように指示されています。

出口プログラムを定義できない特定のコマンドがあります。これらのコマンドにはCLコンパイラ・ダイレクト文、QSYS38ライブラリ中のコマンド、などがあります。出口プログラムを登録できないコマンドの一覧は以下のとおりです。

・CALL
・CALLPRC
・CHGVAR
・CNLRCV
・COPYRIGHT
・DCL
・DCLF
・DO
・ENDDO
・ENDPGM
・ENDRCV
・GOTO
・IF
・MONMSG
・PGM
・RCVF
・RETURN
・RTVxxx
・SNDF
・SNDRCVF
・TFRCTL
・WAIT

WRKJOBコマンド用に使用できる出口プログラムの例を図2に示します。この出口プログラムは、WRKJOBコマンドを実行したユーザーが*USERクラスに属しているかどうかをチェックします。もし*USERクラスに属しているユーザーであれば、代わりにDSPJOBコマンドを実行するようにコマンド・アナライザに対して指示します。この例の機能はごく簡単なものですが、独自のCLコマンド用出口プログラムを書く際の難しい部分を扱っています。

注記:このプログラムはV5R2およびそれ以前のバージョンのCL文法で記述されていますので、V5R3あるいはそれ以後のバージョンにアップグレードされていない方でも利用できます。V5R3またはそれ以後のバージョンをお使いの場合、このプログラムは動作しますが、V5R3の整数データ・タイプを含む文法に更新することをお勧めします。

WRKJOBコマンド出口プログラムの考察

この出口プログラムは前述の3つのパラメータを受け取っているのがお分かりいただけるでしょう。最初のパラメータには、構文を解析して個々のフィールドに渡すべきデータ構造が含まれています。これらのフィールドは、構文解析されたデータを保存するのに使用するために定義されています。保存されたデータはさらに構文解析されて要素パーツに分解されます。今回の例では、コマンド文字列を構文解析してコマンドに対するオフセットを判断するのに若干付加的な作業が発生しています。この例ではこの情報は必要ありませんし、使用しませんが、この例のコードは皆さんが独自の出口プログラムを記述する際のテンプレートとして使えるようになっています。コマンドを構文解析することでコマンドのパラメータを修正し、変更したコマンド中の他のコマンドのパラメータを制御することも選択できます。

次に、このコマンドを出口プログラムで変更可能であるかどうかを判断するための変更インジケータが必要になります。QSYS/WRKJOBコマンドのように、コマンドがコマンド・アナライザに渡されたときにライブラリに登録可能なものであれば、出口プログラムによって変更することはできず、変更インジケータの値は0になります。これはそういう設計になっているためです。コマンドを変更できないケースはこの他にもいくつかあります。こうした例は以下のようなコマンドで構成されています。

  • すべてのCL取り出しコマンド(RTVxxx)のようにパラメータの定義にRTNVAL(*YES)が指定されているもの
  • パラメータの定義にDSPINPUT(*NO)またはDSPINPUT (*PROMPT)が指定されているもの
  • IBMが提供しているシステム状態プログラムで実行されているもの

バージョンV4R5の時にIBMは、*SYSTEMという新しい修飾子値を導入しました。この修飾子の目的は、オブジェクトに対して一種の「非修飾」修飾参照を許可することでした。たとえば、コマンドが「*SYSTEM/WRKJOB」と指定された場合、QSYSライブラリ中のWRKJOBコマンドが使用されます。QSYSを明示的に指定していなくても、*SYSTEM修飾子はこのオブジェクトをQSYSライブラリから取得します。自分のアプリケーション中のコマンドを修飾させた上でなお出口プログラムを使用してコマンドを変更したい場合は、*SYSTEM修飾子を使用することができ、これは実際にはQSYSライブラリへ修飾することになります。

その次のコードで、WRKJOBコマンドを実行しているユーザーが*USERクラスに属する場合の代替コマンドとして、QSYS/DSPJOBが設定されています。これで出口プログラムは終了します。

出口プログラムでコマンド文字列を保存するために使用されているCL変数が2,000バイトの長さであることに気づかれたかもしれません。V5R3以前のバージョンでは、CL文字変数は2,000バイトまでとなっていましたが、現在は9,999バイトとなっています。今回の例のWRKJOBコマンド文字列を保持するには2,000バイトで充分ですが、出口点インタフェースで処理できるコマンド文字列の実際の長さは32,000バイトです。

このサンプル・プログラムはCLで記述されているので、出口プログラムが読みやすく、理解しやすくなっています。出口プログラムをどれか特定の言語で書かなければならないということはありませんし、ILE統合言語環境用に書かれる必要もありませんが、もちろん、そういうことも可能です。

リアルタイム環境での監査コマンドの使用方法

あなたのシステム上のオブジェクトを誰かが回復しようとしたときに警告して欲しいと思いませんか。あるいは、誰かがTCP/IPサーバー・プログラムを起動したとか、特定のライブラリを保存したとかというのを知りたくはありませんか。従来は、こうしたイベントをリアルタイムに収集するのは困難でしたが、慎重な使用を要するコマンドを監視するi5/OSの機能により、こうしたタスクは普通に行えるようになりました。

本節では、コマンドの実行をリアルタイムに監視、監査することのできる出口点である、コマンド・アナライザ取り出し出口点について説明します。コマンドの使用状況を監視する方法は他にもありますが、ここでご紹介する方法は実装が最も簡単で、しかもかなりの強度があると考えています。

取り出し出口点は、前述のコマンド・アナライザ変更出口点と異なり、コマンド・アナライザに対して情報を送り返すことはできません。これにより、この出口点の機能はロギングと監査機能に制限されます。

本節で使用する出口プログラムの例は、誰かがRestore Object (RSTOBJ)コマンドを実行すると必ず呼び出されます。このプログラムはコマンド情報を取り出し、RSTOBJコマンド文字列やシステムのQHST履歴ログ中にあるその他の有益な情報を記録します。もちろん、このコマンド文字列データで他にもいろいろなことができますが、ここであげる簡単な例は、コマンド出口プログラムの作成と登録のプロセスを説明するのを目的としています。

コマンド・アナライザ取り出し出口点

コマンド・アナライザ取り出しコマンド出口点の名前はQIBM_QCA_RTV_COMMANDです。この出口点は、コマンド・アナライザがその作業のほとんどを終え、制御をコマンド処理プログラム(CPP: Command Processing Program)に渡す直前に発生します。

この出口プログラムはCPPに制御が渡る前に呼び出されるので、出口プログラムはコマンドが正常に終了したのか異常終了したのかを予測することはできません。コマンドが実行されたことが分かるだけで、CPPの結果がどうなるのかについて全く分かりませんし、それにどのような影響を与える可能性があるのか(つまり処理は失敗なのかあるいは成功なのか)も分かりません。

この出口点の出口点インタフェースの名前はRTVC0100です。この出口点インタフェースは、前節で説明したCHGC0100インタフェースに似ています。ここでも、皆さんが作成される出口プログラムは、RTVC0100パラメータの個々のデータ要素を構文解析する必要があります(図3)。 出口点プログラムはADDEXITPGMコマンドを使用してコマンドに追加します。取り出しコマンド出口点の場合、次の例のように、PGMDTAパラメータ中のコマンド名とそのコマンドが存在しているライブラリを指定する必要があります。

ADDEXITPGM EXITPNT(QIBM_QCA_RTV_COMMAND)   +
       FORMAT(RTVC0100)         +<
       PGMNBR(1)              +
       PGM(MYLIB/RSTOBJEXIT)     +
       TEXT('Exit program for RSTOBJ')  +
       PGMDTA(*JOB 20 'RSTOBJ QSYS')

取り出しコマンド出口点に対しては、連続するプログラムごとにPGMNBRパラメータを1つずつ増やしていくことで、コマンド1個当たり最大で10個のプログラムを登録できます。そうすることで、一連のプログラムやサード・パーティー製、あるいはベンダー提供の出口プログラムを実行しながら同時に、皆さんが作成されたプログラムを実行させることもできます。

例に示した通り、PGMDTAパラメータにはデータを長さ20字で指定します。そのうちの最初の10字はコマンド名で、次の10字はコマンドライブラリになります。コマンド・アナライザは、QSYSライブラリ中にあるRSTOBJコマンドを実行するような要求があると必ずMYLIBライブラリ中のRSTOBJEXIT出口プログラムを使用するように、指示されています。

RSTOBJコマンド用に使用できる出口プログラムの例を図4に示します。この出口プログラムは、RSTOBJコマンドが使用されるたびにメッセージ・キューに対してメッセージを送信します。またこの出口プログラムは、QHST履歴ログに対してもメッセージを送信します。このプログラム中で行なわれる処理は極めて単純ですが、皆さんが独自の出口プログラムを作成される際のテンプレートとして利用できます。

RSTOBJコマンド用に使用できる出口プログラムの例を図4に示します。この出口プログラムは、RSTOBJコマンドが使用されるたびにメッセージ・キューに対してメッセージを送信します。またこの出口プログラムは、QHST履歴ログに対してもメッセージを送信します。このプログラム中で行なわれる処理は極めて単純ですが、皆さんが独自の出口プログラムを作成される際のテンプレートとして利用できます。

ここで紹介した出口プログラムがRSTOBJコマンドの使用を監視するためだけに登録されたものであるという点に注意してください。ただし、同じプログラムを使用して、各RSTxxxコマンド(RSTLIB、RST、RSTLICPGMなど)用に同じ出口点プログラムを追加することで、すべてのRSTxxxコマンドを監視することも可能です。

RSTOBJコマンド出口プログラムの考察

この出口プログラムはパラメータを1つだけ受け付けます。前述した通り、このパラメータにはRTVC0100というデータ構造が含まれており、これを構文解析して個々のフィールドに分ける必要があります。RTVC0100フォーマットのデータを構文解析した後に保存するのに使用されるフィールドが、図4に定義されています。RTVC0100フォーマットはさらに構文解析されて要素パーツに分解されます。

次に、元のコマンドがコマンド・アナライザ変更出口プログラムで置き換えられたかどうかを判断します。置き換えられていれば、実行されるコマンド文字列は、&OFFSETRという変数に保存されているオフセット部分にあります。置き換えられていなければ、コマンドへのオフセットは、&OFFSETOという変数中にあります。お分かりの通り、置換オフセット(&OFFSETR)の値が0(ゼロ)であるかどうかを調べることで判断することができます。置換オフセットが0であれば、コマンドが変更コマンド出口プログラムで置き換えられていないということです。

さらにコードの下のほうを見ると、RSTOBJコマンドを実行しているジョブからユーザーとジョブ名が取り出されています。この情報は収集されて、送信される情報メッセージの中に含められます。メッセージはRESTOREとQHSTという2つのメッセージ・キューに送信されます。皆さんの個々の要件に合わせて、このコードの部分を置き換えて使用してください。

RSTOBJコマンドが何度か実行された後のメッセージ表示画面を、図5に示します。同じ情報がQHST履歴ログにも書き出され、RSTOBJコマンドを使用したことに対する監査作業を支援します。

出口点

過去のいくつかのリリースにおいてIBMは数々の出口点を追加してきました。コマンド出口点とそれらをカスタマイズした処理に慣れてくるにしたがって、他の出口点についても深く踏み込んでみたくなるでしょう。保存関数や回復関数、ユーザー・プロフィール保守、FTP、ODBC、リモート・コマンドなどといった関数用のネットワーク・アクセス制御など、あらゆる種類の出口点があります。また、多くの出口プログラムを作成したり保守したりするのが億劫であれば、サード・パーティー製ソフトウェアもたくさん出回っています。

あわせて読みたい記事

PAGE TOP