実践習得 IBM MQの基本
接続モード(2)クライアント接続(1)
クライアント接続(クライアント・モード)で実行されるアプリケーションをMQIクライアント(MQが提供するAPIであるMQIをリモート(クライアント)から実行)と呼びます。 前回まではバインド接続を中心にご説明しましたが(若干クライアント接続についても触れました)、今回はクライアント接続を中心にご説明します。
※本連載は最新のmqpgf/mqpcfに基づいて改定されることがあります。常に最新バージョンをダウンロードしてご使用ください。
データ変換がサポートされないマシン間のチャネル接続
前回「Ex. 6.4」の実施前に、MQクライアントのデフォルトのコードページとキューマネージャーのCCSID(CodedCharSetId)間でコード変換が可能でない場合、2539 MQRC_CHANNEL_CONFIG_ERRORで接続に失敗する場合の対処方法として、キューマネージャーのCCSIDをクライアントのコードページに合わせる方法をご紹介しました。 キューマネージャーのCCSIDを変更すると、MQMDのCodedCharSetIdフィールドにMQCCSI_Q_MGR(デフォルト)を設定しているバインド・モードのアプリケーションのMQPUT/MQGETの呼び出しに影響します。 バインド・モードでMQCCSI_Q_MGRが指定されてる場合、MQPUTするメッセージのMQMD.CodedCharSetIdはキューマネージャーで変更されたCCSIDが設定されるようになります。 また、バインド・モードでMQCCSI_Q_MGRを指定してMQGET時にデータ変換を実施している場合は、キュー上のメッセージのCCSIDとキューマネージャーで変更されたCCSID間で行われるようになります。 この影響を回避したい場合は、ccsid.tbl(MQ9.0以上はccsid_part2.tbl)を使用した、"デフォルトのデータ変換"を使用することができます。
※"デフォルトのデータ変換"の機能はクライアント接続だけではなく、サーバー間の接続にも有効です。
ccsid.tbl/ccsid_part2.tblは、Unix系のOSでは"/var/mqm/conv/table/"、Windowsでは"C:\ProgramData\IBM\MQ\conv\table\"配下にあります。 "qmgrs"以下のディレクトリ(キューマネージャー毎のディレクトリ)ではないので、このワークディレクトリを使用する全てのインストールで稼働するキューマネージャーにこのファイルの変更が影響する点に注意してください。 下記2行がデフォルトのデータ変換の設定で、1行名がEBCDIC(5カラム目が"1")、2行目がASCIIタイプ(5カラム目が"2")のコード用です。
#default 0 500 1 1 0
#default 0 850 1 2 0
デフォルトの状態は、先頭に"#"が指定されてコメント・アウトされているのでそれを削除して"デフォルトのデータ変換"を有効にします。 注意点は、データ変換が両方ともASCII系の文字コードである場合でも、かならず2行ともコメント・アウトを外すようにする必要があることです。 そうしないと、"デフォルトのデータ変換"は機能しません。 今回はCCSID=932(Windows)とCCSID=819(UNIX英語モード)間を例としますが、その場合、両方ともASCII系の文字コードですが、その場合でもECDCIC用とASCII用の2行を必ず有効にします。 そして、ASCII用の行のCCISD(3カラム目)を'950'から'932'に変更します。 このテーブルの変更を有効にするには、キューマネージャーの再起動が必要です。
default 0 500 1 1 0
default 0 932 1 2 0
"デフォルトのデータ変換"を有効にする前、有効にした後のパケット・トレースを取得してどのように変わったか比較してみます。 MQ通信でのパケット・トレースの見方については、機会を改めてご説明いたします。
Ex. 7.1 デフォルトのデータ変換有効化時の挙動
下記は"デフォルトのデータ変換"を有効にする前の、チャネル接続時にチャネル間のネゴシエーションでキューマネージャー側から出力される"INITIAL_DATA"の"Transmission Segment Header(TSH)"部、と"Initil Data(ID)"部の一部です。 CCSIDとしてキューマネージャーのCCSIDプロパティの設定値である、'819'がTSH.CCSIDに出力されています。 そして、ID.IniErrFlg1に"0x01, Invalid CCSID"が設定されています。 この後、接続は失敗しクローズされます。
テスト結果7.1.1
>mqpgfc -qm SampleQM -q SampleQ -x nnn.nnn.nnn.nnn(nnnn) -tr
[2018/08/15 17:15:09.225] MQCONNX start qmgr:SampleQM Options:0x00000000
[2018/08/15 17:15:09.373] MQCONNX stop hcon:-1 qmgr:SampleQM CompCd=02 ReasonCd=2539
MQCONNX fail : SampleQM CompCd=02 ReasonCd=2539
!!! Queue Manager Connect Fail SampleQM !!!
パケット・トレース抜粋:
WebSphere MQ (INITIAL_DATA)
Transmission Segment Header
StructID..: TSH
MQSegmLen.: 268
Byte order: Big endian (0x01)
SegmType..: INITIAL_DATA (0x01)
Ctl Flag 1: 0x02, Error
Ctl Flag 2: 0x00
LUW Ident.: 0000000000000000
Encoding..: 111-273 (FLT_IEEE_NORMAL/DEC_NORMAL/INT_NORMAL)
CCSID.....: (819)
Reserved..: 0x0000
Initial Data
Structid..: ID
FAP level.: 13
CapFlag1..: 0x25, MQ request, Split messages, Message sequence
ECapFlag1.: 0x00
IniErrFlg1: 0x01, Invalid CCSID
次は"デフォルトのデータ変換"を有効にした後の、同じ部分です。 CCSIDとしてccsid.tbl/ccsid_part2.tblに設定した'932'がTSH.CCSIDに出力されています。 そして、ID.IniErrFlg1の"0x01, Invalid CCSID"は出力されなくなっています。 この後、接続は成功しMQメッセージのやり取りが行われます。
テスト結果7.1.2
>mqpgfc -qm SampleQM -q SampleQ -m test -x 16.147.169.198(18551) -tr
[2018/08/15 17:20:05.932] MQCONNX start qmgr:SampleQM Options:0x00000000
[2018/08/15 17:20:06.144] MQCONNX stop hcon:33554438 qmgr:SampleQM CompCd=00 ReasonCd=00
[2018/08/15 17:20:06.145] MQOPEN start hcon:33554438 ObjectName:SampleQ Options:0x00000010
[2018/08/15 17:20:06.214] MQOPEN stop hcon:33554438 ObjectName:SampleQ CompCd=00 ReasonCd=00
[2018/08/15 17:20:06.215] 1: message length: 4 put message: test
[2018/08/15 17:20:06.218] MQPUT start hcon:33554438 Options:0x00000000
[2018/08/15 17:20:06.234] MQPUT stop hcon:33554438 CompCd=00 ReasonCd=00
[2018/08/15 17:20:06.239] MQCLOSE start hcon:33554438 Options:0x00000000
[2018/08/15 17:20:06.251] MQCLOSE stop hcon:33554438 CompCd=00 ReasonCd=00
[2018/08/15 17:20:06.257] MQDISC start hcon:33554438
[2018/08/15 17:20:06.281] MQDISC stop hcon:-1 CompCd=00 ReasonCd=00
パケット・トレース抜粋:
WebSphere MQ (INITIAL_DATA)
Transmission Segment Header
StructID..: TSH
MQSegmLen.: 268
Byte order: Little endian (0x02)
SegmType..: INITIAL_DATA (0x01)
Ctl Flag 1: 0x02, Error
Ctl Flag 2: 0x00
LUW Ident.: 0000000000000000
Encoding..: 222-546 (FLT_IEEE_REVERSED/DEC_REVERSED/INT_REVERSED)
CCSID.....: (932)
Reserved..: 0x0000
Initial Data
Structid..: ID
FAP level.: 13
CapFlag1..: 0x25, MQ request, Split messages, Message sequence
ECapFlag1.: 0x00
IniErrFlg1: 0x80, Invalid HB interval
クライアント-サーバー間でデータ変換がサポートされない場合の他の回避策
クライアント接続の場合で、クライアントとサーバー間のデータ変換がサポートされない場合に、MQCCSID環境変数を使用する方法があります。 クライアントのデフォルトのCCSIDは、クライアント・マシンのロケールのコード・ページになります。 この環境変数にCCSIDを設定することで、この値をオーバライドできます。 但し、この方法では、MQMDのCCSIDもこの環境変数に設定した値になることに注意してください。
Ex. 7.2 クライアント側で環境変数MQCCSIDにキューマネージャーのCCSIDを設定する。
コード・ページ819のクライアントと932のキューマネージャー間でテストしてみます。
テスト結果7.2
$ unset MQCCSID
$ mqpgfc -qm SampleQM -q SampleQ -m test
$ MQCONN fail : SampleQM CompCd=02 ReasonCd=2539
!!! Queue Manager Connect Fail SampleQM !!!
/home/okaqm9/work/cprog/mqpgf: mqrc 2539
2539 0x000009eb MQRC_CHANNEL_CONFIG_ERROR
$
$ export MQCCSID=932
$ mqpgfc -qm SampleQM -q SampleQ -m test
[18/08/27 17:52:28.062106] 1: message length: 4 put message: test
$ mqpgfc -qm SampleQM -q SampleQ -br
message number: 1
*StrucId[MD ] Version[2] Report[0] MsgType[8] Expiry[-1] Feedback[0] Encoding[273] CodedCharSetId[932] Format[ ] Priority[0] Persistence[0] MsgId[0x414D512053616D706C65514D202020204B71835B23926C02] CorrelId[0x000000000000000000000000000000000000000000000000] BackoutCount[0] ReplyToQ[ ] ReplyToQMgr[SampleQM ] UserIdentifier[pulsar ] AccountingToken[0x16010515000000F99C8959835A305AE2E39508EC03000000000000000000000B] ApplIdentityData[ ] PutApplType[13] PutApplName[mqpgfc ] PutDate[20180827] PutTime[08522237] ApplOriginData[ ]
GroupId[0x000000000000000000000000000000000000000000000000] MsgSeqNumber[1] Offset[0] MsgFlags[0] OriginalLength[-1]
data length: 4
00000000: 7465 7374 'test '
メッセージ・チャネル・エージェント・ユーザーID(MCAUSER)とアクセス権の設定について
「Ex. 6.4」では、デフォルトのサーバー接続チャネル(SYSTEM.DEF.SVRCONN)のメッセージ・チャネル・エージェント・ユーザーID(MCAUSER)にMQの管理ユーザーである'mqm'を設定しました。 MCAUSERは、MCA が IBM MQリソースへのアクセスの許可に使用するユーザー IDですので、どんなユーザーで接続しても'mqm'ユーザーの権限でMQリソースへのアクセスが可能になっていまいます。 これは、セキュリティー上問題になる場合があります。
Ex. 7.3 クライアント接続ユーザーのアクセス権の設定
まず、SYSTEM.DEF.SVRCONNのMCAUSERをブランクに戻します。 サーバー接続チャネルのMQCAUSERをブランクにすると、デフォルトではクライアント・アプリケーション(mqpgfc)の実行ユーザーが使用されます。 runmqscでパラメータにブランクを設定する場合は、1文字の半角スペースをシングルクォートで囲みます。
MQSC > alter chl(SYSTEM.DEF.SVRCONN) chltype(svrconn) mcauser(' ')
4 : alter chl(SYSTEM.DEF.SVRCONN) chltype(svrconn) mcauser(' ')
AMQ8016: IBM MQ channel changed.
もし、そのユーザーがサーバー側に存在しない場合は、キューマネージャーのエラーログに下記エラーが出力されます。
/var/mqm/qmgrs/SampleQM/errors/AMQERR01.LOG(Unix系のOSの場合のデフォルト)
....
AMQ9557: Queue Manager User ID initialization failed for 'pulsar'.
EXPLANATION:
The call to initialize the User ID 'pulsar' failed with CompCode 2 and
2035.
ACTION:
Correct the error and try again.
----- cmqxrsrv.c : 2318 -------------------------------------------------------
$ mqrc 2035
2035 0x000007f3 MQRC_NOT_AUTHORIZED
対応するユーザーがサーバー側に存在しない場合は作成します。
テストの為に、mqmグループやWindowsのAdministratorsグループに所属しないユーザーでアクセス権を設定してみてください。
MQ for HP NonStopの場合は、次の様にaltmqusrコマンドで、MQプリンシパル(pulsar)をNonStop OSユーザーID(pulsar.plsgrp)にマップします。
$ altmqusr -m SampleQM -p pulsar -u pulsar.plsgrp Username mapping for queue manager 'SampleQM' $ dspmqusr -m SampleQM Username mapping for Queue Manager 'SampleQM' Principal Userid Username Alias GroupName GroupType 0.1 mqm 171.255 MQM.MANAGER n MQM a nobody 0.0 pulsar 101.101 PULSAR.PLSGRP n PLSGRP a
ユーザーを作成後、MQリソースへのアクセス権を付加します。 アクセス権が不足している場合、次のように対象のオブジェクトと不足しているアクセス権がエラー・ログに表示されます。
....
AMQ8077: Entity 'pulsar' has insufficient authority to access object
'SampleQM'.
EXPLANATION:
The specified entity is not authorized to access the required object. The
following requested permissions are unauthorized: connect
....
AMQ8077: Entity 'pulsar' has insufficient authority to access object
'SampleQ'.
EXPLANATION:
The specified entity is not authorized to access the required object. The
following requested permissions are unauthorized: put
....
ここでは、キューマネージャーへの"connect"権限と、キュー(SampleQ)への"put"および"get"の権限を付与します。 権限の一覧と詳細については、製品のマニュアルを参照してください。
$ setmqaut -m SampleQM -t qmgr -p pulsar +connect
The setmqaut command completed successfully.
$ dspmqaut -m SampleQM -t qmgr -p pulsar
Entity pulsar has the following authorizations for object SampleQM:
connect
$ setmqaut -m SampleQM -t queue -n SampleQ -p pulsar +put +get
The setmqaut command completed successfully.
$ dspmqaut -m SampleQM -t queue -n SampleQ -p pulsar
Entity pulsar has the following authorizations for object SampleQ:
get
put
正常に接続、PUT/GETできるか確認してみます。
テスト結果7.3
$ mqpgfc -qm SampleQM -q SampleQ -m test -x nnn.nnn.nnn.nnn(nnnn)
[2018/08/17 13:30:39.208] 1: message length: 4 put message: test
$ mqpgfc -qm SampleQM -q SampleQ -xnnn.nnn.nnn.nnn(nnnn)
[2018/08/17 13:31:07.036] 1: message length: 4 get message : test
この例では、"Principal name"(-p)に権限をあたえましたが、"User group name"(-g)に権限を付与する方法もあります。
オブジェクト権限マネージャー (OAM)の設定の詳細についてはここではご説明しませんが、一つだけ注意点を挙げておきます。
MQ7.5までは、グループ単位でアクセス権が設定されましたが(Windowsはユーザー単位)、MQ8.0からはユーザー単位でも設定できるようになっています。
間違いやすい点ですが、デフォルトでは" -p Principal name"でアクセス権を設定した場合、そのユーザー(Principal)が所属するグループに権限が設定されます。
qm.iniの「Service:」スタンザに「SecurityPolicy」パラメータを追加し、"user"を設定して、キューマネージャーを再起動することで、このモードが変更されます。
デフォルトの場合と、「Service:」スタンザに「SecurityPolicy=user」を設定した場合のOAMの権限設定をダンプして比較してみます。
※dspmqautの結果は標準エラーに出力されますので、表示をファイルに保存する場合は、標準エラーをリダイレクト("2>")します。
$ dmpmqaut -m SampleQM 2> SampleQM.aut
出力内容の確認:
※デフォルト(group)の場合:
....
- - - - - - - -
profile: self
object type: qmgr
entity: PLSGRP
entity type: group
authority: connect
- - - - - - - -
....
- - - - - - - -
profile: SampleQ
object type: queue
entity: PLSGRP
entity type: group
authority: get put
- - - - - - - -
※「Service:」スタンザに「SecurityPolicy=user」を設定した場合:
....
- - - - - - - -
profile: self
object type: qmgr
entity: pulsar
entity type: principal
authority: connect
- - - - - - - -
....
- - - - - - - -
profile: SampleQ
object type: queue
entity: pulsar
entity type: principal
authority: get put
- - - - - - - -
....
1番目では、グループ("PLSGRP")に、2番目はユーザー("pulsar")のみに権限が設定されています。
システムの要件に合わせてアクセス権を設定してください。
デフォルトのチャネル認証レコード
チャネル認証レコードは、MQ7.1から使用可能です。 「Ex. 6.4」では、チャネル認証レコードを無効化してテストを実施しました。 チャネル認証レコードの設定方法には多くのバリエーションがありますのが、ここではデフォルトのチャネル認証レコードの設定内容について簡単に触れます。
チャネル認証レコードを有効化している場合、下記3つのデフォルトで設定されているチャネル認証レコードが検査されます。
$ mqpcf mqsc -qm SampleQM -s "dis chlauth(*) all" 1: AMQ8878: Display channel authentication record details. CHLAUTH(SYSTEM.ADMIN.SVRCONN) TYPE(ADDRESSMAP) DESCR(Default rule to allow MQ Explorer access) CUSTOM( ) ADDRESS(*) USERSRC(CHANNEL) CHCKCLNT(ASQMGR) ALTDATE(2018-06-25) ALTTIME(10.56.47) 2: AMQ8878: Display channel authentication record details. CHLAUTH(SYSTEM.*) TYPE(ADDRESSMAP) DESCR(Default rule to disable all SYSTEM channels) CUSTOM( ) ADDRESS(*) USERSRC(NOACCESS) WARN(NO) ALTDATE(2018-06-25) ALTTIME(10.56.47) 3: AMQ8878: Display channel authentication record details. CHLAUTH(*) TYPE(BLOCKUSER) DESCR(Default rule to disallow privileged users) CUSTOM( ) USERLIST(*MQADMIN) WARN(NO) ALTDATE(2018-06-25) ALTTIME(10.56.47)
*オプションの説明
mqsc: MQSCコマンドの実行
-s : MQSCコマンド文字列
1番目のレコードは、"SYSTEM.ADMIN.SVRCONN"というチャネルの為のものです(CHLAUTH(SYSTEM.ADMIN.SVRCONN))。
これは通常MQ Explorerの接続用に定義されているものです。
mqpgfcでチャネル名を指定しなかった場合は、デフォルトで"SYSTEM.DEF.SVRCONN"が使用されますので、mqpgfcを使用したテストではこのレコードは関係がありません。
2番目のレコードは、"SYSTEM."で始まる全てのチャネルが対象です(CHLAUTH(SYSTEM.*))。
ブロックする対象のアドレスは全てのアドレスです(TYPE(ADDRESSMAP) ADDRESS(*))。
合致する接続は、キュー・マネージャーにアクセスできず、チャネルは即停止します(USERSRC(NOACCESS))。
チャネル認証レコードを無効化する前にmqpgfcが理由コード2035で接続に失敗している場合は、このチェネル認証レコードが該当しています。
3番目のレコードは、全てのチャネルが対象です(CHLAUTH(*) )。
USERLISTに指定されているユーザーをブロックします(TYPE(BLOCKUSER))。
USERLISTの"*MQADMIN"は特殊値で、下記のユーザーをブロックします。
Windows: | mqmグループ、Administratorsグループ、およびSYSTEMユーザー |
Unix系のOS: | mqmグループ |
上記の管理ユーザーでmqpgfcを実行していた場合は、この認証レコードも該当します。 この認証レコードが該当する場合、useridでブロックされたことがエラー・ログに表示されます。
....
AMQ9776: Channel was blocked by userid
EXPLANATION:
The inbound channel 'SampleQM.MQICHL' was blocked from address 'nnn.nnn.nnn.nnn'
because the active values of the channel were mapped to a userid which should
be blocked. The active values of the channel were 'MCAUSER(pulsar)
CLNTUSER(pulsar)'.
デフォルトの設定で接続するには、サーバー接続チャネルを新規作成して、管理ユーザー以外のユーザーを使用すれば良いことになります。 ユーザー(サーバー側)の所属するグループを変更する場合、その変更をキューマネージャーが認識される為には、キューマネージャーの再起動もしくは、"refresh security"の実行が必要です。
$ mqpcf mqsc -qm SampleQM -s "refresh security"
1: AMQ8560: IBM MQ security cache refreshed.
*オプションの説明
mqsc: MQSCコマンドの実行
-s : MQSCコマンド文字列
Ex. 7.4 チャネル名を指定して接続する。
チャネル認証レコードを有効に戻します。
$ mqpcf mqsc -qm SampleQM -s "alter qmgr chlauth(enabled)>
1: AMQ8005: IBM MQ queue manager changed.
新規にサーバー接続チャネルを作成します。
$ mqpcf mqsc -qm SampleQM -s "def chl(SampleQM.MQICHL) chltype(svrconn)"
1: AMQ8014: IBM MQ channel created.
接続するチャネル名を指定して、mqpgfcを実行します。
テスト結果7.4
>mqpgfc -qm SampleQM -q SampleQ -m test -x nnn.nnn.nnn.nnn(nnnn) -ch SampleQM.MQICHL
[2018/08/20 16:03:39.323] 1: message length: 4 put message: test
*オプションの説明
-ch: 接続チャネル名
デフォルトの接続認証
接続認証は、MQ8.0から使用可能です。 「Ex. 6.4」では、一旦接続認証を無効化しました。 ここでは、接続認証の機能や構成設定方法の詳細については解説しませんが、クライアント接続に関してのデフォルトの設定内容について簡単にご説明します。
ブランクに設定したCONNAUTHプロパティをデフォルトの"SYSTEM.DEFAULT.AUTHINFO.IDPWOS"にもどします。 変更後、キューマネージャーのセキュリティ情報をリフレッシュします。
$ mqpcf mqsc -qm SampleQM -s "alter qmgr connauth(SYSTEM.DEFAULT.AUTHINFO.IDPWOS)"
1: AMQ8005: IBM MQ queue manager changed.
$ mqpcf mqsc -qm SampleQM -s "refresh security type(connauth)"
1: AMQ8560: IBM MQ security cache refreshed.
$ mqpcf qmgr -qm SampleQM CONNAUTH
1: QMNAME(SampleQM) CONNAUTH(SYSTEM.DEFAULT.AUTHINFO.IDPWOS)
デフォルトの「認証情報 (AUTHINFO) オブジェクト」(SYSTEM.DEFAULT.AUTHINFO.IDPWOS)の設定内容を確認します。
$ mqpcf mqsc -qm SampleQM -s "dis authinfo(SYSTEM.DEFAULT.AUTHINFO.IDPWOS)" 1: AMQ8566: Display authentication information details. AUTHINFO(SYSTEM.DEFAULT.AUTHINFO.IDPWOS) AUTHTYPE(IDPWOS) ADOPTCTX(NO) DESCR( ) CHCKCLNT(REQDADM) CHCKLOCL(OPTIONAL) FAILDLAY(1) ALTDATE(2018-06-25) ALTTIME(10.56.47)
AUTHTYPEは、MQCSP構造体に設定されたUserIdとPasswordの認証方法を示しています。 下記が設定可能です。
IDPWOS | ローカル・サーバーのOSを使用してユーザーIDとパスワードを認証します。 |
IDPWLDAP | LDAP サーバーを使用してユーザーIDとパスワードを認証します。 |
CHCKCLNT (クライアント接続検査)は、クライアント接続の検査方法に使用されます。
下記が設定可能です。
NONE | ユーザーIDとパスワードを検査しない。 |
OPTIONAL | ユーザーIDとパスワードが提供された場合のみ検査する。 |
REQUIRED | 接続時に必ずユーザーIDとパスワードを検査する。 |
REQDADM | 特権ユーザーは必ずユーザーIDとパスワードを検査するが、それ以外は任意(OPTIONALと同じ)。 |
つまり、クライアント接続で、特権ユーザーを使用しない場合は、ユーザー/パスワードを指定すると、検査が行われます。
Ex. 7.5 MQCSPにユーザー/パスワードを指定して接続する。
mqpgfは"-cu"および"-cp"でそれぞれMQCSPに設定するユーザーとパスワードを指定できます。 これらを指定すると、mqpgfは、MQCSP.CSPUserIdPtr、MQCSP.CSPPasswordPtrにそれぞれの文字列のポインターを、MQCSP.CSPUserIdLength、MQCSP.CSPPasswordLengthにそれぞれの文字列の長さを自動的に設定します。 認証を実施させるには、MQCSP.AuthenticationTypeにMQCSP_AUTH_USER_ID_AND_PWDを指定することが必要です。 mqpgfは、MQCSP_AUTH_*が引数に指定されると、それをMQCSP.AuthenticationTypeに設定し、さらにMQCSPを参照させる為に、MQCNO.SecurityParmsPtrにMQCSPへのポインターを自動的に設定します。 また、このMQCNO.SecurityParmsPtrの指定はMQCNO_VERSION_5以上が必要な点に注意してください。 MQCNOのデフォルトはMQCNO_VERSION_1です(※mqpgf(c)では-xで"接続名"が指定された時、自動的にMQCNO_VERSION_2を使用します)。 MQCNOのバージョンがMQCNO_VERSION_5未満の場合は、認証が行われません。
整理すると、キューマネージャーにユーザー/パスワードを認証させるにはアプリケーションは最低限下記を行うことが必要です。
- 1.MQCSP.CSPUserIdPtrに認証させるユーザーIDの文字列を設定する。
- 2.MQCSP.CSPPasswordPtrに認証させるユーザーのパスワードの文字列を設定する。
- 3.MQCSP.CSPUserIdLengthにユーザーIDの文字列の長さを設定する。
- 4.MQCSP.CSPPasswordLengthにパスワードの文字列の長さを設定する。
- 5.MQCSP.AuthenticationTypeにMQCSP_AUTH_USER_ID_AND_PWDを指定する。
- 6.MQCNO.VersionにMQCNO_VERSION_5以上を設定する。
テスト結果7.5
>mqpgfc -qm SampleQM -q SampleQ -m test -x nnn.nnn.nnn.nnn(nnnnn) -ch SampleQM.MQICHL -cu pulsar -cp correctPW MQCSP_AUTH_USER_ID_AND_PWD MQCNO_VERSION_5
[2018/08/23 14:50:46.286] 1: message length: 4 put message: test
>mqpgfc -qm SampleQM -q SampleQ -m test -x nnn.nnn.nnn.nnn(nnnnn) -ch SampleQM.MQICHL -cu pulsar -cp wrongPW MQCSP_AUTH_USER_ID_AND_PWD MQCNO_VERSION_5
MQCONNX fail : SampleQM CompCd=02 ReasonCd=2035
!!! Queue Manager Connect Fail SampleQM !!!
>mqrc 2035
2035 0x000007f3 MQRC_NOT_AUTHORIZED
>mqpgfc -qm SampleQM -q SampleQ -m test -x nnn.nnn.nnn.nnn(nnnnn) -ch SampleQM.MQICHL -cu pulsar -cp wrongPW MQCSP_AUTH_USER_ID_AND_PWD
[2018/08/23 14:51:02.293] 1: message length: 4 put message: test
上記の最後の例は、間違ったパスワードを指定していますが、MQCNO_VERSION_5が指定されていないので、MQCNO_VERSION_2(-xで"接続名"が指定された時のデフォルト)が使用され、MQCSPに指定されたユーザーとパスワードが認証されなかった為、その結果としてPUTが成功しています。
いろいろと試して見てください。
クライアント接続の一般的な方法
クライアント接続は、次に示す方法のいずれかを使用します。
1. MQCONNX()にチャネル情報を指定 | MQクライアント・アプリケーションが実行時にクライアント接続チャネルの定義を指定する方法です。 MQCONNX()に指定するMQCNO構造体からクライアント接続チャネルの定義を含むチャネル定義構造体MQCDを参照させます。 |
2. MQSERVER環境変数を使用 | クライアント・アプリケーションが稼働しているマシン側で、クライアントのチャネルの定義をこの環境変数に設定します。 |
3. 環境変数でCCDTを参照 | クライアント接続する為のチャネル定義と認証情報を持ったファイルであるチャネル定義テーブル(CCDT)をMQCHLLIB/MQCHLTAB環境変数で参照させる方法です。 |
4. mqclient.iniにチャネル情報を設定 | クライアント構成ファイル(mqclient.ini)のCHANNELSスタンザにMQSERVER環境変数と同等のクライアント・チャネルに関する情報を設定します。 |
5. mqclient.iniでCCDTを参照 | クライアント構成ファイル(mqclient.ini)のCHANNELSスタンザにMQCHLLIB/MQCHLTAB環境変数と同等のCCDTへの参照情報を設定します。 |
クライアント接続については、これまでにも「Ex. 6.4」では、MQ_CONNECT_TYPE環境変数をCLIENTに設定する方法、「Ex. 6.5」では、接続オプションにMQCNO_CLIENT_BINDINGを指定してクライアント接続を試行させる方法をご紹介しました。それらは、上の補足的な説明です。
「4.」と「5.」のクライアント構成ファイルの使用は、「2.」と「3.」の環境変数と同等のものを、mqclient.iniのスタンザに設定するというもので、機能的には環境変数の場合と同様です。
同時に設定される場合は環境変数が優先されます。
これらのそれぞれが同時に設定された場合についての優先順位は次の様になります。
- 1.「1. MQCONNX()にチャネル情報を指定」
- 2.「2. MQSERVER環境変数を使用」
- 3.「4. mqclient.iniにチャネル情報を設定(MQSERVERと同等の設定)」
- 4.「3. 環境変数でCCDTを参照(MQCHLLIB/MQCHLTAB環境変数で参照)」
- 5.「5. mqclient.iniでCCDTを参照(MQCHLLIB/MQCHLTABと同等の設定)」
以上の様に、クライアント接続の構成には多くのバリエーションがありますので、システムに最適なものを選択して使用します。
前提として、これらの全ての方式で、「Ex. 7.3」でご紹介したサーバー側でのサーバー接続チャネル(CHLTYPE(SVRCONN)」がクライアントで指定するチャネル名と同じ名前で作成ずみであること、および「対向側キューマネージャーとの接続の作成」で作成方法ご紹介した接続するポートを監視するリスナー(runmqlsr)が正常に起動されていることが必要です。
リスナーはサーバー間の接続で使用しているものがあれば新規に作成する必要はありません。(同じポートを使用)
MQCONNX()にチャネル情報を指定する。
システム固有の環境ファイルに設定したパラメータで接続をしたい時などにこの方法が使用できます。 下記がMQCONNX()にチャネル情報を指定してクライアント接続をする為の手順です。
- 1. MQCDをMQCD_CLIENT_CONN_DEFAULTで初期化
- 2. MQCDの必要なフィールドを設定
- 3. MQCNOにMQCDの参照を設定
MQCDをMQCD_CLIENT_CONN_DEFAULTで初期化後、最低限、次のフィールドを設定します。
チャネル名(ChannelName): | クライアント接続で使用するチャネル名 |
接続名(ConnectionName): | ipaddr or hostname(port) |
バージョン(Version): | MQCD_VERSION_2またはそれ以上 |
MQCNOにMQCDを参照させるには、MQCNO.ClientConnPtrにMQCDのポインタを設定します。
MQSERVER環境変数の設定方法
もっともシンプルな方法です。 優先順位も高いのでよくテストで使用されます。 下記の形式で設定します。
Windows: | SET MQSERVER=ChannelName/TransportType/ConnectionName |
Unix系OS: | export MQSERVER=ChannelName/TransportType/ConnectionName |
下記は設定例です。 ConnectionNameの形式は"ipaddr or hostname(port)"です。 Unix/Linuxの場合はシングルクォートで囲みます。
SET MQSERVER=SampleQM.MQICHL/TCP/9.20.4.56(1415) *Windows
export MQSERVER=SampleQM.MQICHL/TCP/'9.20.4.56(1415)' *Unix/Linux
mqclient.iniに同等の定義を設定する場合はCHANNELSスタンザのServerConnectionParmsに同じ形式で設定します。 mqclient.iniは、デフォルトでは下記にあります。
Windows(MQ7.5以前): | C:¥Program Files¥IBM¥WebSphere MQ\mqclient.ini |
Windows(MQ8.0以上): | C:\ProgramData\IBM\MQ\mqclient.ini |
Unix系のOS: | /var/mqm/mqclient.ini |
MQ8 for HP NonStop: | $MQINST/mqclient.ini |
下記が設定例です。 mqlient.iniでは、Unix/Linuxの場合でも環境変数の場合の様にConnectionNameをシングルクォートで囲む必要はありません。
CHANNELS:
ServerConnectionParms=SampleQM.MQICHL/TCP/9.20.4.56(1415)
クライアント・チャネル定義テーブルの使用方法
MQ7.5まではこのクライアント・チャネル定義テーブル(CCDT)をサーバー側(キューマネージャー)で作成する必要がありましたが、MQ8.0からはクライアント側で作成ができるようになりました。 クライアント側で作成するにはMQクライアントをインストールしたマシンでrunmqscに"-n"オプションのみを指定して起動します。 次はクライアント・チャネルの作成例です。
$ runmqsc -n
5724-H72 (C) Copyright IBM Corp. 1994, 2014.
Starting local MQSC for 'AMQCLCHL.TAB'.
MQSC > def chl(SampleQM.MQICHL) chltype(clntconn) conname('nnn.nnn.nnn.nnn(nnnn)') QMNAME('SampleQM')
1 : def chl(SampleQM.MQICHL) chltype(clntconn) conname('nnn.nnn.nnn.nnn(nnnn)') QMNAME('SampleQM')
AMQ8014: IBM MQ channel created.
MQSC >
チャネル定義テーブルはデフォルトでは、ワーク・ディレクトリ(上記デフォルトのmqclient.iniと同じ場所)に作成されます。 MQCHLLIBとMQCHLTABが設定されている場合は、MQCHLLIBが示すディレクトリにMQCHLTABで指定されている名前で作成されます。 MQクライアント・アプリケーションの実行時にMQCHLLIBとMQCHLTABが設定されていない場合は、デフォルトでワーク・ディレクトリのAMQCLCHL.TABが参照されます。
mqclient.iniに同等の定義を設定する場合はCHANNELSスタンザのChannelDefinitionDirectoryにチャネル定義テーブルのパス、ChannelDefinitionFileにチャネル定義テーブルのファイル名を設定します。
CHANNELS:
ChannelDefinitionDirectory=/var/clientfiles
ChannelDefinitionFile=PULSAR.TAB
チャネル定義テーブルを使用すると、キューマネージャー・グループを作成することができ、他の方法では実現できない多くの機能を利用することができます。 次回は、その具体的な利用方法についてご紹介する予定です。