|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
 |
|
Security Exit - DLL not dound |
« View previous topic :: View next topic » |
Author |
Message
|
sac063 |
Posted: Fri Feb 11, 2005 7:39 am Post subject: Security Exit - DLL not dound |
|
|
Apprentice
Joined: 23 Jan 2004 Posts: 36
|
Hi,
I am trying to run a channel security exit program on the server connection channel. It validates the IP of the client that is requesting connection. The DLL is Ch_Exit.dll and the entry function is ChExit. The SCYEXIT field has value Ch_Exit(ChExit). Both the dll and config are placed in exits folder D:\MQ\Data\Exits.
But, client app. is not able to successfully connect to the server as the channel is giving the folowing errors -
1) Channel program ended abnormally. Channel program 'SECURITY.EXIT.TEST' ended abnormally. Look at previous error messages for channel program 'SECURITY.EXIT.TEST' in the error files to determine the cause of the failure
2) User exit not valid. Channel program 'SECURITY.EXIT.TEST' ended because user exit 'D:\MQ\Data\Exits\Ch_Exit.dll(ChExit)' is not valid. Ensure that the user exit is specified correctly in the channel definition, and that the user exit program is correct and available.
3) The library D:\MQ\Data\Exits\Ch_Exit.dll was not found. The queue manager will continue without this module. The dynamically loadable file D:\MQ\Data\Exits\Ch_Exit.dll was not found. Check that the file exists and is either fully qualified or is in the appropriate directory.
Am I doing anything wrong here? Even if I key in a junk value 'abcd' in the SCYEXIT field it throws an error that D:\MQ\Data\Exits\abcd.dll not found .
Any guidance will be very helpful.
Thanks in advance. |
|
Back to top |
|
 |
clindsey |
Posted: Fri Feb 11, 2005 9:07 am Post subject: |
|
|
Knight
Joined: 12 Jul 2002 Posts: 586 Location: Dallas, Tx
|
It is quite possible that your exit links to another module which cannot be loaded. If a dependent dll cannot be loaded, the error always only points to the high level module.
If you have MS Visual Sudio, it has a tool called "depends". There is a similar tool called NTFilmon that you can download from SysInternals.com.
Use one of these to see if all the dependent dlls can be loaded. If not, they will tell you which one is the problem. You very likely have a PATH problem with one of the dependents.
Charlie |
|
Back to top |
|
 |
sac063 |
Posted: Fri Feb 11, 2005 10:23 am Post subject: |
|
|
Apprentice
Joined: 23 Jan 2004 Posts: 36
|
One DLL was missing - msvcr71d.dll. Probably because it was biult on XP and is being run on Win 2000 server.
But this still does not solve the problem. The set of errors is the same... it says dll not found?? |
|
Back to top |
|
 |
clindsey |
Posted: Fri Feb 11, 2005 11:40 am Post subject: |
|
|
Knight
Joined: 12 Jul 2002 Posts: 586 Location: Dallas, Tx
|
Can you grant the mqm user admin permissions on this box. If you can, give that a try. If it loads, then you know it is user related. Correct the problem and then remove admin permissions.
Charlie |
|
Back to top |
|
 |
oz1ccg |
Posted: Sun Feb 13, 2005 8:05 am Post subject: |
|
|
 Yatiri
Joined: 10 Feb 2002 Posts: 628 Location: Denmark
|
How is your exit path?
You'll locate it in regedit:
\HKEY_LOCAL_MACHINE\SOFTWARE\IBM\MQSeries\CurrentVersion\Configuration\QueueManager\<your-qmgr>\ExitPath
Does that setting match D:\MQ\Data\Exits ???
I've never seen this failure on WMQ because mostly all sysadms. don't mengle with the WebSphere MQ pathes and changing the access...
It could also be you dll, that is not ok, but I don't belive it. You could try another one to see if it's the dll, that is causing the problems.
I know that my BlockIP2 works...... You'll find it here:
http://mrmq.dk/BlockIP2.htm
Just my $0.02  _________________ Regards, Jørgen
Home of BlockIP2, the last free MQ Security exit ver. 3.00
Cert. on WMQ, WBIMB, SWIFT. |
|
Back to top |
|
 |
sac063 |
Posted: Tue Feb 15, 2005 10:32 am Post subject: |
|
|
Apprentice
Joined: 23 Jan 2004 Posts: 36
|
Many Thanks for the help. The dll had error. I sorted out all the run-time errors. But now the log says dll cannot be loaded -
1) Channel program ended abnormally. Channel program 'SECURITY.EXIT.TEST' ended abnormally.
Look at previous error messages for channel program 'SECURITY.EXIT.TEST' in the error files to determine the cause of the failure.
2) User exit not valid. Channel program 'SECURITY.EXIT.TEST' ended because user exit 'NewTrial(ChExit)' is not valid.
Ensure that the user exit is specified correctly in the channel definition, and that the user exit program is correct and available.
3) The system could not dynamically load the library NewTrial. The system return code was 998. The queue manager will continue without this module. This message applies to Windows NT and Windows 2000 systems only. The dynamically loadable file NewTrial failed to load correctly due to an internal error. The MQ error recording routine has been called.
Check that the file has not been corrupted then use the standard facilities supplied with your system to record the problem identifier, and to save the generated output files. Contact your IBM support center. Do not discard these files until the problem has been resolved.
Bound by policies to use this code!! I am pasting the code from the dll below. Is something wrong with the exit program? Why can't the dll be loaded. The windows help pointed to some files like stdole*.tlb that have to be present in system32 folder. I have done this too.
// NewTrial.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
**********************************************************************/
/* */
/* Module Name: chexit.c */
/**********************************************************************/
/* */
/* MQ Security Channel Exit */
/* */
/* Description: This channel Exit routine checks if a incoming */
/* Client is allowed to establish a connection. */
/* A valid client-connection must be setup in the */
/* configfile $CONFIG_FILE. */
/* */
/* On the check-list of the security-exit are: */
/* */
/* - MQ-Port of the incoming client */
/* - MQ-Server Name */
/* - MQ-Channel Name */
/* - incoming IP-address */
/* */
**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cmqc.h"
#include "cmqxc.h"
#include <time.h>
#define CONFIG_FILE "%sconf/chexit.conf"
#define LOG_FILE "%slogs/chexit_log"
#define LOG_FILE_PATHNAME_LENGTH 100
#define LENGTH_DATE_TIME 50
#define LENGTH_CHANNEL_NAME 20
#define LENGTH_QMGR_NAME 48
#define LENGTH_CONNECTION_NAME 264
#define LENGTH_LEVEL 9
#define LENGTH_PORT 9
#define MAX_LINE_LENGTH 200
#define LENGTH_SESSION_ID 20
#define BINARY_PATH_LENGTH 1024
#ifdef MQ_VERSION_5_1
char chExitVersion[] = "Version 1.4 (compiled with MQSeries V5.1)";
#else
char chExitVersion[] = "Version 1.4 (compiled with MQSeries V5.0)";
#endif
char errExitCode1[] = "err-ExitCode: -1 'cannot open logfile '";
char errExitCode2[] = "err-ExitCode: -2 'format-error within the MQCD-structure'";
char errExitCode3[] = "err-ExitCode: -3 'no PORT is set in the environment'";
char errExitCode4[] = "err-ExitCode: -4 'cannot open config-file'";
char errExitCode5[] = "err-ExitCode: -5 'validation failed no access allowed'";
char errExitCode6[] = "err------------------------------------------------------------";
char errReasonCode1[] = "err-ReasonCode: 1 'PORT-mismatch'";
char errReasonCode2[] = "err-ReasonCode: 10 'ConnectionName-mismatch'";
char errReasonCode3[] = "err-ReasonCode: 20 'ConnectionName-mismatch <= format-error'";
char errReasonCode4[] = "err-ReasonCode: 100 'QMgrName-mismatch'";
char errReasonCode5[] = "err-ReasonCode: 1000 'ChannelName-mismatch'";
char EXT_ChannelName[LENGTH_CHANNEL_NAME+1];
char EXT_QMgrName[LENGTH_QMGR_NAME];
char EXT_ConnectionName[LENGTH_CONNECTION_NAME];
char CheckLevelOfChannel[LENGTH_LEVEL];
char MQListenerPort[LENGTH_PORT];
char ChannelName[LENGTH_CHANNEL_NAME+1];
char QMgrName[LENGTH_QMGR_NAME+1];
char ConnectionName[LENGTH_CONNECTION_NAME+1];
char actualMQPort[LENGTH_PORT];
char actualSESSION_ID[LENGTH_SESSION_ID];
char log_file[LOG_FILE_PATHNAME_LENGTH];
char dummy[1000];
char pathPrefix[BINARY_PATH_LENGTH];
char configFilePath[BINARY_PATH_LENGTH];
char logFilePath[BINARY_PATH_LENGTH];
int debugMode1 = 0;
int debugMode2 = 0;
void cutBlancsAndSpecialChar(char* a, char* b, int maxn)
{
int i;
for(i=0; i < maxn; i++) {
if(*b != ' ' && *b != '\0' && *b != '\f' && *b != '\n' && *b != '\r' && *b != '\t' ) {
*a++ = *b++;
}
*a = '\0';
}
}
int compare(FILE* fp)
{
int nerror=0;
int len=0;
int i=0;
int ndot=0;
if(strcmp(MQListenerPort, actualMQPort)) {
if(debugMode2) {
fprintf(fp, "ERROR in compare: PORT-mismatch : allowed <%s> real <%s> \n" ,
MQListenerPort, actualMQPort);
}
nerror+=1;
}
if(strcmp(EXT_ConnectionName, ConnectionName)) {
if(debugMode2) {
fprintf(fp, "ERROR in compare: ConnectionName-mismatch : allowed <%s> real <%s> \n" ,
EXT_ConnectionName, ConnectionName);
}
len=strlen(EXT_ConnectionName);
for(i=0; i < len; i++)
if(EXT_ConnectionName[i]=='.')
ndot++;
if(ndot == 3) {
if(strncmp(EXT_ConnectionName, ConnectionName, len)) {
if(debugMode2) {
fprintf(fp, "ERROR in compare: ConnectionName-mismatch : allowed <%s> real <%s> \n" ,
EXT_ConnectionName, ConnectionName);
}
nerror+=10;
}
}
else {
if(debugMode2) {
fprintf(fp, "Format-ERROR in compare: ConnectionName-mismatch : allowed <%s> (for ex. xxx.yyy.zzz. be aware of the 3 dots !!! real <%s> \n" ,
EXT_ConnectionName, ConnectionName);
}
nerror+=20;
}
}
if(strcmp(EXT_QMgrName, QMgrName)) {
if(debugMode2) {
fprintf(fp, "ERROR in compare: QMgrName-mismatch : allowed <%s> real <%s> \n" ,
EXT_QMgrName, QMgrName);
}
nerror+=100;
}
if(strcmp(EXT_ChannelName, ChannelName)) {
if(debugMode2) {
fprintf(fp, "ERROR in compare: ChannelName-mismatch : allowed <%s> real <%s> \n" ,
EXT_ChannelName, ChannelName);
}
nerror+=1000;
}
return(nerror);
}
void extractData(char *str, FILE* flog) {
char *next=NULL;
if(next=strtok(str, " ")) {
strcpy(dummy, next);
cutBlancsAndSpecialChar(MQListenerPort, dummy, strlen(dummy));
}
if(next=strtok(NULL, " ")) {
strcpy(dummy, next);
cutBlancsAndSpecialChar(EXT_ConnectionName, dummy, strlen(dummy));
}
if(next=strtok(NULL, " ")) {
strcpy(dummy, next);
cutBlancsAndSpecialChar(EXT_QMgrName, dummy, strlen(dummy));
}
if(next=strtok(NULL, " ")) {
strcpy(dummy, next);
cutBlancsAndSpecialChar(EXT_ChannelName, dummy, strlen(dummy));
if (strlen(dummy) > LENGTH_CHANNEL_NAME + 1 && debugMode2) {
fprintf(flog, "Format-ERROR in extractData: channel-name \"%s\" too long !! (%d chars allowed) \n", dummy, LENGTH_CHANNEL_NAME);
}
}
}
int check(FILE* flog)
{
char *readLine=NULL;
FILE* fconf=NULL;
int nerror=0;
char str[MAX_LINE_LENGTH];
if ((fconf = fopen(configFilePath, "r")) == 0) {
fprintf(flog, "ERROR unable to open config file \"%s\"\n", configFilePath);
return(-1);
}
while(readLine=fgets(str, MAX_LINE_LENGTH, fconf)) {
if(str[0] != '#') {
extractData(str, flog);
nerror=compare(flog);
if(!nerror) {
break;
}
}
}
return(nerror);
}
int analyse(FILE* fp, MQCD *MQCD_ptr)
{
cutBlancsAndSpecialChar(ChannelName, (char*)MQCD_ptr->ChannelName, LENGTH_CHANNEL_NAME);
cutBlancsAndSpecialChar(QMgrName, (char*)MQCD_ptr->QMgrName, LENGTH_QMGR_NAME);
cutBlancsAndSpecialChar(ConnectionName, (char*)MQCD_ptr->ConnectionName, LENGTH_CONNECTION_NAME);
return(0);
}
void printTagMQPXP(FILE *fp, MQCXP *p)
{
int i;
if(fp) {
fprintf(fp, "\n\n-------Start--ExitReturnParameter------------\n");
fprintf(fp, "StrucId: %c%c%c%c\n", p->StrucId[0],p->StrucId[1],p->StrucId[2],p->StrucId[3]);
fprintf(fp, "Version: %d\n", p->Version);
fprintf(fp, "ExitId: %d\n", p->ExitId);
fprintf(fp, "ExitReason: %d\n", p->ExitReason);
fprintf(fp, "ExitResponse: %d\n", p->ExitResponse);
fprintf(fp, "ExitResponse2: %d\n", p->ExitResponse2);
fprintf(fp, "Feedback: %d\n", p->Feedback);
fprintf(fp, "ExitNumber: %d\n", p->ExitNumber);
fprintf(fp, "MaxSegmentLength: %d\n", p->MaxSegmentLength);
fprintf(fp, "MsgRetryCount: %d\n", p->MsgRetryCount);
fprintf(fp, "MsgRetryInterval: %d\n", p->MsgRetryInterval);
fprintf(fp, "MsgRetryReason: %d\n", p->MsgRetryReason);
fprintf(fp, "HeaderLength: %x\n", p->HeaderLength);
fprintf(fp, "FAPLevel: %x\n", p->FAPLevel);
fprintf(fp, "CapabilityFlags: %x\n", p->CapabilityFlags);
fprintf(fp, "PartnerName: <%48s>\n", p->PartnerName);
fprintf(fp, "ExitUserArea: <%16s>\n", p->ExitUserArea);
fprintf(fp, "ExitData: <%32s>\n", p->ExitData);
fprintf(fp, "\n\n-------End----ExitReturnParameter------------\n");
}
}
void MQStart() {;} /* dummy entry point */
void MQENTRY ChExit ( PMQVOID pChannelExitParms,
PMQVOID pChannelDefinition,
PMQLONG pDataLength,
PMQLONG pAgentBufferLength,
PMQVOID pAgentBuffer,
PMQLONG pExitBufferLength,
PMQPTR pExitBufferAddr)
{
int myerrors=0;
int errorFlag=0;
int len=0;
time_t t;
char DateTime[LENGTH_DATE_TIME];
char SecurityExitString[1024];
char *searchPointer;
FILE *fp=NULL;
FILE *fmap=NULL;
MQCD *MQCD_ptr = (MQCD*)pChannelDefinition;
MQCXP *MQCXP_ptr = (MQCXP*)pChannelExitParms;
MQCXP_ptr->ExitResponse=MQXCC_OK;
MQCXP_ptr->ExitResponse2=MQXR2_DEFAULT_CONTINUATION;
MQCXP_ptr->Version=MQCXP_CURRENT_VERSION;
/* localize paths */
strncpy(SecurityExitString, MQCD_ptr->SecurityExit, BINARY_PATH_LENGTH);
searchPointer = strrchr(SecurityExitString, '(');
*searchPointer = '\0';
searchPointer = strrchr(SecurityExitString, '/');
if (searchPointer == NULL) {
strcpy(pathPrefix, "");
}
else {
strncpy(pathPrefix, SecurityExitString, searchPointer - SecurityExitString + 1);
}
sprintf(configFilePath, CONFIG_FILE, pathPrefix);
sprintf(logFilePath, LOG_FILE, pathPrefix);
t = time(NULL);
strftime(DateTime, 50, "_%Y-%m-%d", localtime(&t));
sprintf(log_file, "%s%s", logFilePath, DateTime);
if ((fp = fopen(log_file, "a")) == 0) {
fprintf(stderr, "CANNOT OPEN LOG_FILE \"%s\"\n", log_file);
errorFlag=-1;
}
else {
if(MQCD_ptr->SecurityUserData) {
len = strlen(MQCD_ptr->SecurityUserData);
if(len >= 5) {
if (!strncmp(MQCD_ptr->SecurityUserData, "DEBUG", 5)) {
debugMode1 = 1;
}
else if (!strncmp(MQCD_ptr->SecurityUserData, "COMPA", 5)) {
debugMode2 = 1;
}
}
}
t = time(NULL);
strftime(DateTime, 50, "%c", localtime(&t));
if (MQCXP_ptr->ExitReason == MQXR_INIT) {
/* checks the incoming structure of the user-exit */
if(analyse(fp, MQCD_ptr)) {
errorFlag=-2;
}
if(getenv("SESSION")) {
strcpy(actualSESSION_ID, getenv("SESSION"));
}
else {
strcpy(actualSESSION_ID,"......");
}
/* PORT set ? */
if(getenv("PORT")) {
strcpy(actualMQPort, getenv("PORT"));
}
else {
strcpy(actualMQPort,"NULL");
errorFlag=-3;
}
/* compare incoming values against setup */
if(myerrors=check(fp)) {
if(myerrors < 0)
errorFlag=-4;
else
errorFlag=-5;
}
if( errorFlag ) {
MQCXP_ptr->ExitResponse= MQXCC_CLOSE_CHANNEL;
}
fprintf(fp, "START%9.9s %24.24s %10.10s %20.20s %15.15s %5s %3d %3d %3d %2d %5d\n",
actualSESSION_ID, DateTime, QMgrName, ChannelName, ConnectionName, actualMQPort,
MQCXP_ptr->ExitId, MQCXP_ptr->ExitReason,
MQCXP_ptr->ExitResponse, MQCXP_ptr->ExitResponse2, myerrors);
}
else if (MQCXP_ptr->ExitReason == MQXR_TERM) {
fprintf(fp, "END %9.9s %24.24s %10.10s %20.20s %15.15s %5s %3d %3d %3d %2d %5d\n",
actualSESSION_ID, DateTime, QMgrName, ChannelName, ConnectionName, actualMQPort,
MQCXP_ptr->ExitId, MQCXP_ptr->ExitReason,
MQCXP_ptr->ExitResponse, MQCXP_ptr->ExitResponse2, myerrors);
}
if(debugMode1) {
printTagMQPXP(fp, MQCXP_ptr);
}
fflush(fp);
}
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
MQCD channelDefinitions;
MQCXP channelExitParms;
PMQVOID channelExitParms_p = &channelExitParms;
PMQVOID channelDefinitions_p = &channelDefinitions;
PMQLONG dummy_long;
PMQVOID dummy_void;
PMQPTR exit_buffer_adr;
char ChannelName[100];
char QMgrName[100];
char ConnectionName[100];
char myPort[100];
int i;
strcpy(ChannelName, "SECURITY.EXIT.TEST");
strcpy(QMgrName, "DIUKLMB");
strcpy(ConnectionName, "172.16.107.197");
strcpy(channelDefinitions.ChannelName, ChannelName);
strcpy(channelDefinitions.ConnectionName, ConnectionName);
strcpy(channelDefinitions.QMgrName, QMgrName);
ChExit ( channelExitParms_p,
channelDefinitions_p,
0,
0,
NULL,
0,
NULL);
return TRUE;
}
Thanks for reading this bigg post and for giudance in advance  |
|
Back to top |
|
 |
RogerLacroix |
Posted: Tue Feb 15, 2005 9:33 pm Post subject: |
|
|
 Jedi Knight
Joined: 15 May 2001 Posts: 3264 Location: London, ON Canada
|
Hi,
First off, if you want people to read your code then use the BBCode of [code ] ... [/code ] to wrap our code.
Secondly, MQ is VERY picky about how it calls your exit but on Windows it MUST look like:
Code: |
extern void MQENTRY MQStart(void) {;}
#if defined (WIN32)
__declspec (dllexport) void MQENTRY SECEXIT (PMQCXP pChannelExitParms,
PMQCD pChannelDefinition,
PMQLONG pDataLength,
PMQLONG pAgentBufferLength,
PMQBYTE pAgentBuffer,
PMQLONG pExitBufferLength,
PMQPTR pExitBufferAddr);
#endif
void MQENTRY SECEXIT ( PMQCXP pChannelExitParms,
PMQCD pChannelDefinition,
PMQLONG pDataLength,
PMQLONG pAgentBufferLength,
PMQVOID pAgentBuffer,
PMQLONG pExitBufferLength,
PMQPTR pExitBufferAddr)
{
// your code
} |
Doing what you did will not work.
Regards,
Roger Lacroix _________________ Capitalware: Transforming tomorrow into today.
Connected to MQ!
Twitter |
|
Back to top |
|
 |
|
|
 |
|
Page 1 of 1 |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|
|
|