{"id":250,"date":"2011-01-18T19:13:21","date_gmt":"2011-01-19T00:13:21","guid":{"rendered":"http:\/\/www.capitalware.biz\/rl_blog\/?p=250"},"modified":"2020-10-08T17:43:33","modified_gmt":"2020-10-08T21:43:33","slug":"mq-exit-programming-tips","status":"publish","type":"post","link":"https:\/\/www.capitalware.com\/rl_blog\/?p=250","title":{"rendered":"MQ Exit Programming Tips"},"content":{"rendered":"<p>Here are some things that MQ Exit developers need to be aware of:<\/p>\n<p>1. Most people have never developed and will never develop an MQ Exit.  Developing a MQ Exit is an &#8216;advanced topic&#8217; &#8211; hence, you <strong><em>SHOULD<\/em><\/strong> have experience developing Windows DLLs or Unix shared Libraries and understand the concept of parallel processing (i.e. threading).  Test, search, test again, search again.  Google is now man&#8217;s best friend.  <strong><em>USE IT<\/em><\/strong>.<\/p>\n<p>2. Windows XP, 7, 2003 and 2008 have restrictions on system accounts (MUSR_MQADMIN is a system account!!!) for what files or directories that account can access ( i.e. On WinXP, the Exit cannot write to C:\\ )  So, if in your exit, the code is writing to C:\\myexit.log, and you have a problem then <strong><em>TRY ANOTHER DIRECTORY<\/em><\/strong> (even try another file name).<\/p>\n<p>3. MQ Exit Library names are <strong><em>CASE SENSITIVE<\/em><\/strong>.<\/p>\n<ul>e.g.<br \/>\nC:\\Program Files\\IBM\\MQ\\Exits64\\testexit(<strong>SECEXIT<\/strong>)<br \/>\nis <strong><em>NOT<\/em><\/strong> the same as<br \/>\nC:\\Program Files\\IBM\\MQ\\Exits64\\testexit(<strong>SecExit<\/strong>)\n<\/ul>\n<p>4. Do NOT write a large convoluted exit before testing it.  Start with a VERY SIMPLE EXIT and then move to a more complex exit.<\/p>\n<p>5. Before you post a question (on MQ ListServer or mqseries.net) about your MQ security exit, make sure you have tested the following VERY, VERY BASIC MQ security exit.  Note: If you cannot get this to work, you should give your MQ exit development project to someone else (Do not post why or complain!!).<\/p>\n<p>You can download the source code from <strong><a href=\"http:\/\/www.capitalware.com\/dl\/code\/c\/testexit.zip\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a><\/strong>.  Copy the following code to a file and call the file: testexit.c<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\/**\r\n *  TestExit for debugging MQ exit issue.\r\n *\r\n *  Location of:\r\n *  Unix\/Linux:   \/var\/mqm\/exits64\/testexit(SecExit)\r\n *\r\n *  Windows DLL:  C:\\Program Files\\IBM\\MQ\\Exits64\\testexit(SecExit)\r\n *\r\n *  MQSC command for Unix\/Linux queue manager:\r\n *  DEFINE CHANNEL ('APP.CH01') CHLTYPE(SVRCONN) +\r\n *         TRPTYPE(TCP) +\r\n *         SENDEXIT('\/var\/mqm\/exits64\/testexit(SecExit)') +\r\n *         SENDDATA(' ') +\r\n *         REPLACE\r\n *\r\n *  MQSC command for Windows queue manager:\r\n *  DEFINE CHANNEL ('APP.CH01') CHLTYPE(SVRCONN) +\r\n *         TRPTYPE(TCP) +\r\n *         SENDEXIT('C:\\Program Files\\IBM\\MQ\\Exits64\\testexit(SecExit)') +\r\n *         SENDDATA(' ') +\r\n *         REPLACE\r\n *\/\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;string.h&gt;\r\n#include &lt;time.h&gt;\r\n#if defined (_WIN32)\r\n#include &lt;windows.h&gt;\r\n#include &lt;lm.h&gt;\r\n#endif\r\n\r\n#include &lt;cmqc.h&gt;\r\n#include &lt;cmqxc.h&gt;\r\n\r\n#if defined (_WIN32)\r\n__declspec (dllexport) void MQENTRY SecExit(PMQCXP  pChannelExitParms,\r\n                                   PMQCD   pChannelDefinition,\r\n                                   PMQLONG pDataLength,\r\n                                   PMQLONG pAgentBufferLength,\r\n                                   PMQBYTE pAgentBuffer,\r\n                                   PMQLONG pExitBufferLength,\r\n                                   PMQPTR  pExitBufferAddr);\r\n#else\r\nextern void MQENTRY MQStart(void) {;}\r\n#endif\r\n\r\nvoid MQENTRY SecExit( PMQCXP  pChannelExitParms,\r\n                  PMQCD   pChannelDefinition,\r\n                  PMQLONG pDataLength,\r\n                  PMQLONG pAgentBufferLength,\r\n                  PMQVOID pAgentBuffer,\r\n                  PMQLONG pExitBufferLength,\r\n                  PMQPTR  pExitBufferAddr)\r\n{\r\n   char       outBuff&#x5B;512];\r\n   char       tempChl&#x5B; MQ_CHANNEL_NAME_LENGTH + 1];\r\n   FILE*      fh;\r\n   struct tm  *newtime;\r\n   time_t     tclock;\r\n   char       *timeBuff;\r\n   PMQCXP     pParms = pChannelExitParms;\r\n   PMQCD      pChDef = pChannelDefinition;\r\n\r\n   \/\/ Attention newbie user: Make sure you select a valid directory and filename!!!\r\n\r\n\/\/   fh = fopen(&quot;C:\\\\Program Files\\\\IBM\\\\MQ\\\\Exits64\\\\testexit.log&quot;, &quot;a+&quot;);\r\n   fh = fopen(&quot;C:\\\\Temp\\\\testexit.log&quot;, &quot;a+&quot;);\r\n\r\n   time( &amp;tclock );\r\n   newtime = localtime( &amp;tclock );\r\n   timeBuff = asctime(newtime);\r\n   timeBuff&#x5B;strlen(timeBuff) - 1] = 0x00;\r\n\r\n   fprintf(fh, &quot;%s : Now entering the security exit.\\n&quot;, timeBuff);\r\n\r\n   memcpy(tempChl, pChannelDefinition-&gt;ChannelName, MQ_CHANNEL_NAME_LENGTH);\r\n   tempChl&#x5B;MQ_CHANNEL_NAME_LENGTH] = 0x00;\r\n   fprintf(fh, &quot;%s : Channel name is %s\\n&quot;, timeBuff, tempChl);\r\n\r\n   if (pParms-&gt;ExitId == MQXT_CHANNEL_SEC_EXIT)\r\n   {\r\n      switch (pParms-&gt;ExitReason)\r\n      {\r\n         case MQXR_INIT:\r\n              pParms-&gt;ExitResponse = MQXCC_OK;\r\n              fprintf(fh, &quot;%s : MQXR_INIT - Channel Initialization\\n&quot;, timeBuff);\r\n              break;\r\n         case MQXR_INIT_SEC:\r\n              pParms-&gt;ExitResponse = MQXCC_OK;\r\n              fprintf(fh, &quot;%s : MQXR_INIT_SEC  - Initialize Security\\n&quot;, timeBuff);\r\n              break;\r\n         case MQXR_SEC_MSG:\r\n              pParms-&gt;ExitResponse = MQXCC_OK;\r\n              fprintf(fh, &quot;%s : MQXR_SEC_MSG - Security Message\\n&quot;, timeBuff);\r\n              break;\r\n         case MQXR_SEC_PARMS:\r\n              pParms-&gt;ExitResponse = MQXCC_OK;\r\n              fprintf(fh, &quot;%s : MQXR_SEC_PARMS - Security Parameters\\n&quot;, timeBuff);\r\n              break;\r\n         case MQXR_TERM:\r\n              pParms-&gt;ExitResponse = MQXCC_OK;\r\n              fprintf(fh, &quot;%s : MQXR_TERM - Channel Terminating\\n&quot;, timeBuff);\r\n              break;\r\n         default:\r\n              pParms-&gt;ExitResponse = MQXCC_SUPPRESS_FUNCTION;\r\n              fprintf(fh, &quot;%s : ERROR - Unknown Exit Reason\\n&quot;, timeBuff);\r\n              break;\r\n      }\r\n   }\r\n   else\r\n   {\r\n      pParms-&gt;ExitResponse = MQXCC_SUPPRESS_FUNCTION;\r\n      fprintf(fh, &quot;%s : ERROR - Not invoked by a security exit.\\n&quot;, timeBuff);\r\n      return;\r\n   }\r\n\r\n   fprintf(fh, &quot;%s : Now exiting the security exit.\\n\\n&quot;, timeBuff);\r\n   fclose(fh);\r\n\r\n   return;\r\n}<\/pre>\n<p>6. Read the IBM MQ Intercommunication manual for how to compile the security exit (e.g. testexit.c) for your particular platform.<\/p>\n<p>7. Here is the channel definition for this MQ security exit to run on Windows:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">DEFINE CHANNEL ('TEST.EXIT') CHLTYPE(SVRCONN) +\r\n      TRPTYPE(TCP) +\r\n      SCYEXIT('C:\\Program Files\\IBM\\MQ\\Exits64\\testexit(SecExit)') +\r\n      SCYDATA(' ') +\r\n      REPLACE<\/pre>\n<p>8. Consult the following web page that contains several security exits that may help you out: <br \/>\n<a href=\"https:\/\/www.capitalware.com\/mq_code_c.html#exitcode\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/www.capitalware.com\/mq_code_c.html#exitcode<\/a><\/p>\n<p>9. Buy vs Build: You and your management should seriously review the costs associated with building your own security exit \/ solution.  A company can easily spend $50,000 to $100,000 or more building an MQ security solution but they could have spent a fraction of the money if they would have purchased Capitalware&#8217;s <strong><a href=\"https:\/\/www.capitalware.com\/mqausx_overview.html\" target=\"_blank\" rel=\"noopener noreferrer\">MQ Authenticate User Security Exit<\/a><\/strong> or <strong><a href=\"https:\/\/www.capitalware.com\/mqssx_overview.html\" target=\"_blank\" rel=\"noopener noreferrer\">MQ Standard Security Exit<\/a><\/strong>.  Also, who will support the internally build custom solution in years to come?  Food for thought.<\/p>\n<p>10. Last but not least: <strong><em>Read The Manual<\/em><\/strong> (RTM). In particular read IBM MQ Programming Guide, IBM MQ Programming Reference, IBM MQ Intercommunication and  IBM MQ Messages and Codes manuals<\/p>\n<p>Regards,<br \/>\nRoger Lacroix<br \/>\nCapitalware Inc.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Here are some things that MQ Exit developers need to be aware of: 1. Most people have never developed and will never develop an MQ Exit. Developing a MQ Exit is an &#8216;advanced topic&#8217; &#8211; hence, you SHOULD have experience developing Windows DLLs or Unix shared Libraries and understand the concept of parallel processing (i.e. [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7,4,26],"tags":[],"class_list":["post-250","post","type-post","status-publish","format-standard","hentry","category-c","category-mq","category-programming"],"_links":{"self":[{"href":"https:\/\/www.capitalware.com\/rl_blog\/index.php?rest_route=\/wp\/v2\/posts\/250","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.capitalware.com\/rl_blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.capitalware.com\/rl_blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.capitalware.com\/rl_blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.capitalware.com\/rl_blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=250"}],"version-history":[{"count":19,"href":"https:\/\/www.capitalware.com\/rl_blog\/index.php?rest_route=\/wp\/v2\/posts\/250\/revisions"}],"predecessor-version":[{"id":6312,"href":"https:\/\/www.capitalware.com\/rl_blog\/index.php?rest_route=\/wp\/v2\/posts\/250\/revisions\/6312"}],"wp:attachment":[{"href":"https:\/\/www.capitalware.com\/rl_blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=250"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.capitalware.com\/rl_blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=250"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.capitalware.com\/rl_blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=250"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}