Every couple of months, I get an email from someone asking me if they can use MQAUSX client-side security exit with IBM MQ V8 or V9 to perform authentication via CONNAUTH. The answer is no – the MQAUSX client-side security exit only works with the MQAUSX server-side security exit.
IBM added the MQCSP (Connection Security Parameters) structure in MQ V6, so that applications could send a UserId and Password (in plain text) to a remote queue manager. At that time, the queue manager would not do anything with the UserId and Password except pass it to a channel security exit (i.e. MQAUSX), if one was in use.
In MQ V7, MQ had an explosion of new MQ API verbs. MQ V6 had 13 verbs and MQ v7.0 introduced 12 new API verbs (basically, the verb count doubled). Why IBM did not enhance or add new MQCONN/MQCONNX verbs to include a UserId and Password for MQ V7, V7.1 or V7.5 is debatable. But when IBM introduced CONNAUTH in MQ V8, IBM absolutely should have made the developers life easier by introducing new MQCONN/MQCONNX verbs.
Since, IBM is not interested or unwilling to introduce 2 new MQ API verbs, I will.
Here are the standard MQCONN and MQCONNX verbs:
MQCONN(QMgrName, &Hconn, &CompCode, &Reason); MQCONNX(QMgrName, &ConnectOpts, &Hconn, &CompCode, &Reason);
Today, I will introduce 2 new MQ verbs: MQCONNU and MQCONNUX for MQ applications written in C.
MQCONNU(UserId, Password, QMgrName, &Hconn, &CompCode, &Reason); MQCONNUX(UserId, Password, QMgrName, &ConnectOpts, &Hconn, &CompCode, &Reason);
I have created a C source file called ‘mqconnu.c’ that has the prototypes and code to handle the new MQ verbs. All the developer needs to do is include the ‘mqconnu.c’ in their MQ C applications then they can use the new MQ verbs.
I have created 2 MQ tester programs to demonstrate the 2 new MQ verbs called: ‘test_mqconnu.c’ and ‘test_mqconnux.c’. You can download a zip file that contains the 3 files from here.
So, lets have a look at the ‘test_mqconnu.c’ program:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <cmqc.h> #include "mqconnu.c" /* prototypes and code for MQCONNU and MQCONNUX */ int main(int argc, char **argv) { MQHCONN Hcon; /* connection handle */ MQLONG CompCode; /* completion code */ MQLONG Reason; /* reason code */ char QMgrName[MQ_Q_MGR_NAME_LENGTH+1]; char userId[64]; char passwd[64]; if (argc != 4) { printf("test_mqconnu QMgrName userid password\n"); return(1); } printf("test_mqconnu start\n"); strncpy(QMgrName, argv[1], MQ_Q_MGR_NAME_LENGTH); strncpy(userId, argv[2], sizeof(userId)); strncpy(passwd, argv[3], sizeof(passwd)); printf("Using values:\n"); printf(" QMgrName : %s\n", QMgrName); printf(" UserID : %s\n", userId); printf(" Password : %s\n", passwd); MQCONNU(userId, /* UserId */ passwd, /* Password */ QMgrName, /* queue manager */ &Hcon, /* connection handle */ &CompCode, /* completion code */ &Reason); /* reason code */ printf("MQCONNU CC=%d RC=%d\n", CompCode, Reason); if (CompCode == MQCC_OK) { MQDISC(&Hcon, /* connection handle */ &CompCode, /* completion code */ &Reason); /* reason code */ printf("MQDISC CC=%d RC=%d\n", CompCode, Reason); } printf("test_mqconnu end\n"); return(0); }
As you can see, MQCONNU is a direct replacement for MQCONN with the added benefit of passing the UserId and Password to MQ.
Now lets have a look at the ‘test_mqconnux.c’ program:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <cmqc.h> #include <cmqxc.h> #include "mqconnu.c" /* prototypes and code for MQCONNU and MQCONNUX */ int main(int argc, char **argv) { MQHCONN Hcon; /* connection handle */ MQLONG CompCode; /* completion code */ MQLONG Reason; /* reason code */ MQCNO cno = {MQCNO_DEFAULT}; /* MQCONNX options */ MQCD cd = {MQCD_CLIENT_CONN_DEFAULT}; char QMgrName[MQ_Q_MGR_NAME_LENGTH+1]; char userId[64]; char passwd[64]; if (argc != 6) { printf("test_mqconnux QMgrName ChlName hostname(port) userid password\n"); return(1); } printf("test_mqconnux start\n"); strncpy(QMgrName, argv[1], MQ_Q_MGR_NAME_LENGTH); strncpy(cd.ChannelName, argv[2], MQ_CHANNEL_NAME_LENGTH); strncpy(cd.ConnectionName, argv[3], MQ_CONN_NAME_LENGTH); strncpy(userId, argv[4], sizeof(userId)); strncpy(passwd, argv[5], sizeof(passwd)); printf("Using values:\n"); printf(" QMgrName : %s\n", QMgrName); printf(" ChannelName: %s\n", cd.ChannelName); printf(" hostname : %s\n", cd.ConnectionName); printf(" UserID : %s\n", userId); printf(" Password : %s\n", passwd); /* Point the MQCNO to the client connection definition */ cno.ClientConnPtr = &cd; cno.Version = MQCNO_VERSION_5; MQCONNUX(userId, /* UserId */ passwd, /* Password */ QMgrName, /* queue manager */ &cno, /* options for connection */ &Hcon, /* connection handle */ &CompCode, /* completion code */ &Reason); /* reason code */ printf("MQCONNUX CC=%d RC=%d\n", CompCode, Reason); if (CompCode == MQCC_OK) { MQDISC(&Hcon, /* connection handle */ &CompCode, /* completion code */ &Reason); /* reason code */ printf("MQDISC CC=%d RC=%d\n", CompCode, Reason); } printf("test_mqconnux end\n"); return(0); }
As you can see, MQCONNUX is a direct replacement for MQCONNX with the added benefit of passing the UserId and Password to MQ.
The new MQCONNU and MQCONNUX verbs can be used in any C MQ application that wants to pass a UserId and Password to MQ for authentication. The 2 new verbs can be used in MQ applications on any platform where the MQ client code-base supports MQCSP structure.
As mentioned above, you can download a zip file that contains the 3 files from here.
Regards,
Roger Lacroix
Capitalware Inc.
2 Responses to MQ API Verbs that IBM Forgot!!