I have a program that is occassionally getting Dr. Watson errors: Exception: access violation (0xc0000005, Address: 0x00401948.
I know this is a lot to ask, but I've included the c code below. Can anyone see anything obvious that could be causing this?
Thanks,
James
/* File: arealdap.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ldap.h>
#include "area.h"
/*****************************************************************************/
/* */
/* Action Request System External Authentication (AREA) Sample */
/* */
/*****************************************************************************/
/* Description: This is a sample external authentication server based on */
/* LDAP. */
/* */
/* This example uses the Netscape LDAP SDK available from Netscape */
/* Communications Corporation. Schema and attribute names reflect those */
/* commonly found on a Netscape Directory Server. Your own configuration */
/* may differ. */
/* */
/* Possible enhancements to this example: */
/* */
/* + Cache user and/or group membership information so that we do not */
/* have to go to the LDAP server for every request. */
/* */
/* + and/or, be smarter about when to flush the AR Server's cache of user*/
/* user information. */
/* */
/* + Generalize to work with other directory configurations and schemas. */
/* */
/*****************************************************************************/
#define MAX_HOST_LEN 50
#define MAX_PEOPLEBASE_LEN 25
#define MAX_GROUPBASE_LEN 25
char MY_HOST[MAX_HOST_LEN];
char temp_port[10];
int MY_PORT;
char MY_PEOPLEBASE[MAX_PEOPLEBASE_LEN];
char MY_GROUPBASE[MAX_GROUPBASE_LEN];
FILE *fp, *ff;
struct tm *local;
time_t t;
char file_name[80], date[80], month[80], day[80], systime[80], year[80], form_date[80],temp[80];
char date1, date2, date3, date4, date5, date6, date7, date8;
/*****************************************************************************/
/* */
/* AREAInitializationCallback */
/* */
/*****************************************************************************/
/* Description: This function is called by main() which is defined in the */
/* Action Request System External Authentication (AREA) core library. */
/* */
/* A customized authentication server must define this function. Any */
/* global information or resources should be initialized here. */
/* */
/* A return value of zero signifies success. A non-zero return value */
/* will cause the process to exit() with the return value as the exit */
/* code. */
/* */
/*****************************************************************************/
int AREAInitializationCallback(
int argc,
char *argv[]
)
{
//get time
t = time(NULL);
local = localtime(&t);
strcpy(date, asctime(local));
sscanf(date, "%*s %s %s %s %s", month, day, systime, year);
sscanf(systime, "%c%c%c%c%c%c%c%c", &date1, &date2, &date3, &date4, &date5, &date6, &date7, &date8);
systime[0] = date1;
systime[1] = date2;
systime[2] = date4;
systime[3] = date5;
systime[4] = date7;
systime[5] = date8;
systime[6] = 0;
if (strcmp(month, "Jan"
== 0)
{
strcpy(month, "01"
;
}
else if (strcmp(month, "Feb"
== 0)
{
strcpy(month, "02"
;
}
if (strcmp(month, "Mar"
== 0)
{
strcpy(month, "03"
;
}
else if (strcmp(month, "Apr"
== 0)
{
strcpy(month, "04"
;
}
if (strcmp(month, "May"
== 0)
{
strcpy(month, "05"
;
}
else if (strcmp(month, "Jun"
== 0)
{
strcpy(month, "06"
;
}
if (strcmp(month, "Jul"
== 0)
{
strcpy(month, "07"
;
}
else if (strcmp(month, "Aug"
== 0)
{
strcpy(month, "08"
;
}
else if (strcmp(month, "Sep"
== 0)
{
strcpy(month, "09"
;
}
else if (strcmp(month, "Oct"
== 0)
{
strcpy(month, "10"
;
}
if (strcmp(month, "Nov"
== 0)
{
strcpy(month, "11"
;
}
else if (strcmp(month, "Dec"
== 0)
{
strcpy(month, "12"
;
}
if (strlen(day) == 1) /* If the day is already two characters, no need to do anything. */
{
strcpy(temp, "0"
; /* add the leading "0" */
strcat(temp, day); /* put on the single digit day */
strcpy(day, temp); /* copy the two digit version back in the original */
}
strcpy(file_name, "arealdap.log."
;
strcat(file_name, month);
strcat(file_name, day);
strcat(file_name, year);
strcat(file_name, "-"
;
strcat(file_name, systime);
strcat(file_name, ".log"
;
/* See if the file arealdap.log exists, without modifying it */
if ((fp = fopen("arealdap.log", "r"
) == NULL)
{
/* File doesn't exist, open it for writing */
if ((fp = fopen("arealdap.log", "w"
) == NULL)
{
/* File didn't open correctly due to an error */
/* Do any error handling here */
}
else
{
/* File opened successfully for writing */
}
}
else
{
/* File exists. Close it, since we want to rename it. */
fclose(fp);
/* rename the old file */
rename("arealdap.log", file_name);
/* Open a new file for writing */
if ((fp = fopen("arealdap.log", "w"
) == NULL)
{
/* File didn't open correctly due to an error */
}
else
{
/* File opened successfully for writing */
}
}
if (argc != 4)
{
printf("Usage: arealdap [LDAP HOST] [LDAP PORT] [BASE DN]\n"
;
fprintf(fp,"Parameters not found. \n"
;
exit(1);
}
MY_HOST[0] = '\0';
MY_PEOPLEBASE[0] = '\0';
strcpy(MY_HOST, argv[1]);
MY_PORT = atoi(argv[2]);
strcpy(MY_PEOPLEBASE, argv[3]);
fprintf(fp,"Log started %s",date);
fprintf(fp,"MY_HOST is %s\n", MY_HOST);
fprintf(fp,"MY_PORT is %d\n", MY_PORT);
fprintf(fp,"MY_PEOPLEBASE is %s\n", MY_PEOPLEBASE);
fclose(fp);
/* This sample has the data allocated and deallocated with every request */
/* from the AR System server. As such, we have nothing to do here. */
return 0;
}
/*****************************************************************************/
/* */
/* AREAVerifyLoginCallback */
/* */
/*****************************************************************************/
/* Description: This function is called by the AREA core library whenever a */
/* request is made by the AR System Server to authenticate a user. */
/* */
/* The basic idea is to authenticate (also known as "binding"
with the */
/* the LDAP server. If this is successful, we go on to get other */
/* information such as e-mail address and group membership. */
/* */
/*****************************************************************************/
void AREAVerifyLoginCallback(
ARNameType user,
ARNameType password,
ARNameType networkAddr,
AREAResponseStruct **response
)
{
LDAP *ld;
LDAPMessage *result, *e;
char *dn;
char *email;
char search[64];
char filter[256];
ARBoolean valid;
ARBoolean found;
static char *attrs[3] = {"cn", "uniquemember", NULL};
*response = (AREAResponseStruct *) malloc (sizeof(AREAResponseStruct));
if (*response == NULL)
return;
/* Initialize as a failed login */
(*response)->licenseMask = AREA_LICENSE_MASK_ALL;
(*response)->licenseWrite = AR_LICENSE_TYPE_NONE;
(*response)->licenseFTS = AR_LICENSE_TYPE_NONE;
(*response)->licenseRes1 = AR_LICENSE_TYPE_NONE;
(*response)->groups = NULL;
(*response)->notifyMech = AR_NOTIFY_NONE;
(*response)->email = NULL;
(*response)->loginStatus = AREA_LOGIN_FAILED;
(*response)->messageText = NULL;
(*response)->logText = NULL;
(*response)->modTime = 0;
fp = fopen("arealdap.log", "a"
;
fprintf(fp,"-------------------------------------------\n"
;
t = time(NULL);
local = localtime(&t);
fprintf(fp,"%s",asctime(local));
fprintf(fp,"Start to validate user: %s\n",user);
ld = ldap_init(MY_HOST, MY_PORT);
/* get a handle to an LDAP connection */
if (ld == NULL)
return;
else
fprintf (fp,"Got handle to LDAP Connection.\n"
;
/*
* Authenticate to the directory to do the search.
*/
if ( ldap_simple_bind_s( ld, NULL, NULL ) != LDAP_SUCCESS)
return;
else
fprintf (fp,"Bind to LDAP successful.\n"
;
sprintf(search, "%s", MY_PEOPLEBASE);
sprintf(filter, "(cn=%s)", user);
if (ldap_search_s(ld, search, LDAP_SCOPE_SUBTREE,
filter, NULL, 0, &result) != LDAP_SUCCESS)
return;
else
fprintf (fp,"LDAP Search Successful.\n"
;
/*
* Run through the attributes of each entry looking for a match.
*/
valid = FALSE;
found = FALSE;
email = NULL;
for (e = ldap_first_entry(ld, result); e != NULL; e = ldap_next_entry(ld, e))
{
found = TRUE;
dn = ldap_get_dn(ld, e);
if (dn == NULL)
{
continue;
}
if ((dn[0] == '\0') || (password[0] == '\0'))
{
continue;
}
if (ldap_simple_bind_s(ld, dn, password) != LDAP_SUCCESS)
{
continue;
}
valid = TRUE;
}
ldap_unbind(ld);
if ((found == TRUE) && (valid == TRUE))
{
fprintf(fp,"Found user and the password is good.\n"
;
/*
* We found a match and the password is good.
*/
(*response)->licenseMask = '\0';
(*response)->licenseWrite = '\0';
(*response)->licenseFTS = '\0';
(*response)->licenseRes1 = '\0';
(*response)->groups = NULL;
(*response)->notifyMech = '\0';
(*response)->email = NULL;
(*response)->loginStatus = AREA_LOGIN_SUCCESS;
(*response)->messageText = NULL;
}
else if (found == TRUE)
{
fprintf(fp, "User found, but password is bad.\n"
;
/*
* We found a match and the password is bad.
*/
(*response)->loginStatus = AREA_LOGIN_FAILED;
(*response)->messageText = NULL;
(void) free (email);
}
else
{
fprintf(fp,"User Not Found.\n"
;
/*
* Otherwise, we do not know the user.
*/
(*response)->loginStatus = AREA_LOGIN_UNKNOWN_USER;
(*response)->messageText = NULL;
(void) free (email);
}
fclose(fp);
return;
}
/*****************************************************************************/
/* */
/* AREANeedToSyncCallback */
/* */
/*****************************************************************************/
/* Description: This function is called by the AREA core library */
/* periodically at the request of the AR System server. */
/* */
/* A customized authentication server must define this function. Any */
/* global information or resources accessed here must be protected with */
/* appropriate mutual exclusion locks to be multi-thread safe. */
/* */
/* A non-zero return value will instruct the AR System server to flush */
/* its cache of user information. */
/* */
/*****************************************************************************/
int AREANeedToSyncCallback(void)
{
return 0;
}
/*****************************************************************************/
/* */
/* AREAFreeCallback */
/* */
/*****************************************************************************/
/* Description: This function is called by the AREA core library after a */
/* response is made to the AR System Server to authenticate a user. */
/* */
/* A pointer to the response structure returned by */
/* AREAVerifyLoginCallback() is passed as a parameter. */
/* */
/* A customized authentication server must define this function. Any */
/* global information or resources accessed here must be protected with */
/* appropriate mutual exclusion locks to be multi-thread safe. */
/* */
/* A customized authentication server must return a response. A NULL */
/* response will be interpreted as a failed login attempt. */
/* */
/*****************************************************************************/
void AREAFreeCallback(
AREAResponseStruct *response
)
{
/* Since we allocated the response in AREAVerifyLoginCallback(), we */
/* should free it here. */
if (response != NULL)
{
if (response->email != NULL)
(void) free(response->email);
(void) free (response);
}
return;
}
/*****************************************************************************/
/* */
/* AREATerminationCallback */
/* */
/*****************************************************************************/
/* Description: This function is called by the AREA core library after a */
/* response is made to the AR System Server to authenticate a user. */
/* */
/* Resources created in AREAInitializationCallback may be destroyed here. */
/* */
/* A customized authentication server must define this function. Any */
/* global information or resources accessed here must be protected with */
/* appropriate mutual exclusion locks to be multi-thread safe. */
/* */
/*****************************************************************************/
void AREATerminationCallback(void)
{
/* We have nothing to do here since we did not allocate or create any */
/* global resources in AREAInitializationCallback(). */
return;
}
I know this is a lot to ask, but I've included the c code below. Can anyone see anything obvious that could be causing this?
Thanks,
James
/* File: arealdap.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ldap.h>
#include "area.h"
/*****************************************************************************/
/* */
/* Action Request System External Authentication (AREA) Sample */
/* */
/*****************************************************************************/
/* Description: This is a sample external authentication server based on */
/* LDAP. */
/* */
/* This example uses the Netscape LDAP SDK available from Netscape */
/* Communications Corporation. Schema and attribute names reflect those */
/* commonly found on a Netscape Directory Server. Your own configuration */
/* may differ. */
/* */
/* Possible enhancements to this example: */
/* */
/* + Cache user and/or group membership information so that we do not */
/* have to go to the LDAP server for every request. */
/* */
/* + and/or, be smarter about when to flush the AR Server's cache of user*/
/* user information. */
/* */
/* + Generalize to work with other directory configurations and schemas. */
/* */
/*****************************************************************************/
#define MAX_HOST_LEN 50
#define MAX_PEOPLEBASE_LEN 25
#define MAX_GROUPBASE_LEN 25
char MY_HOST[MAX_HOST_LEN];
char temp_port[10];
int MY_PORT;
char MY_PEOPLEBASE[MAX_PEOPLEBASE_LEN];
char MY_GROUPBASE[MAX_GROUPBASE_LEN];
FILE *fp, *ff;
struct tm *local;
time_t t;
char file_name[80], date[80], month[80], day[80], systime[80], year[80], form_date[80],temp[80];
char date1, date2, date3, date4, date5, date6, date7, date8;
/*****************************************************************************/
/* */
/* AREAInitializationCallback */
/* */
/*****************************************************************************/
/* Description: This function is called by main() which is defined in the */
/* Action Request System External Authentication (AREA) core library. */
/* */
/* A customized authentication server must define this function. Any */
/* global information or resources should be initialized here. */
/* */
/* A return value of zero signifies success. A non-zero return value */
/* will cause the process to exit() with the return value as the exit */
/* code. */
/* */
/*****************************************************************************/
int AREAInitializationCallback(
int argc,
char *argv[]
)
{
//get time
t = time(NULL);
local = localtime(&t);
strcpy(date, asctime(local));
sscanf(date, "%*s %s %s %s %s", month, day, systime, year);
sscanf(systime, "%c%c%c%c%c%c%c%c", &date1, &date2, &date3, &date4, &date5, &date6, &date7, &date8);
systime[0] = date1;
systime[1] = date2;
systime[2] = date4;
systime[3] = date5;
systime[4] = date7;
systime[5] = date8;
systime[6] = 0;
if (strcmp(month, "Jan"
{
strcpy(month, "01"
}
else if (strcmp(month, "Feb"
{
strcpy(month, "02"
}
if (strcmp(month, "Mar"
{
strcpy(month, "03"
}
else if (strcmp(month, "Apr"
{
strcpy(month, "04"
}
if (strcmp(month, "May"
{
strcpy(month, "05"
}
else if (strcmp(month, "Jun"
{
strcpy(month, "06"
}
if (strcmp(month, "Jul"
{
strcpy(month, "07"
}
else if (strcmp(month, "Aug"
{
strcpy(month, "08"
}
else if (strcmp(month, "Sep"
{
strcpy(month, "09"
}
else if (strcmp(month, "Oct"
{
strcpy(month, "10"
}
if (strcmp(month, "Nov"
{
strcpy(month, "11"
}
else if (strcmp(month, "Dec"
{
strcpy(month, "12"
}
if (strlen(day) == 1) /* If the day is already two characters, no need to do anything. */
{
strcpy(temp, "0"
strcat(temp, day); /* put on the single digit day */
strcpy(day, temp); /* copy the two digit version back in the original */
}
strcpy(file_name, "arealdap.log."
strcat(file_name, month);
strcat(file_name, day);
strcat(file_name, year);
strcat(file_name, "-"
strcat(file_name, systime);
strcat(file_name, ".log"
/* See if the file arealdap.log exists, without modifying it */
if ((fp = fopen("arealdap.log", "r"
{
/* File doesn't exist, open it for writing */
if ((fp = fopen("arealdap.log", "w"
{
/* File didn't open correctly due to an error */
/* Do any error handling here */
}
else
{
/* File opened successfully for writing */
}
}
else
{
/* File exists. Close it, since we want to rename it. */
fclose(fp);
/* rename the old file */
rename("arealdap.log", file_name);
/* Open a new file for writing */
if ((fp = fopen("arealdap.log", "w"
{
/* File didn't open correctly due to an error */
}
else
{
/* File opened successfully for writing */
}
}
if (argc != 4)
{
printf("Usage: arealdap [LDAP HOST] [LDAP PORT] [BASE DN]\n"
fprintf(fp,"Parameters not found. \n"
exit(1);
}
MY_HOST[0] = '\0';
MY_PEOPLEBASE[0] = '\0';
strcpy(MY_HOST, argv[1]);
MY_PORT = atoi(argv[2]);
strcpy(MY_PEOPLEBASE, argv[3]);
fprintf(fp,"Log started %s",date);
fprintf(fp,"MY_HOST is %s\n", MY_HOST);
fprintf(fp,"MY_PORT is %d\n", MY_PORT);
fprintf(fp,"MY_PEOPLEBASE is %s\n", MY_PEOPLEBASE);
fclose(fp);
/* This sample has the data allocated and deallocated with every request */
/* from the AR System server. As such, we have nothing to do here. */
return 0;
}
/*****************************************************************************/
/* */
/* AREAVerifyLoginCallback */
/* */
/*****************************************************************************/
/* Description: This function is called by the AREA core library whenever a */
/* request is made by the AR System Server to authenticate a user. */
/* */
/* The basic idea is to authenticate (also known as "binding"
/* the LDAP server. If this is successful, we go on to get other */
/* information such as e-mail address and group membership. */
/* */
/*****************************************************************************/
void AREAVerifyLoginCallback(
ARNameType user,
ARNameType password,
ARNameType networkAddr,
AREAResponseStruct **response
)
{
LDAP *ld;
LDAPMessage *result, *e;
char *dn;
char *email;
char search[64];
char filter[256];
ARBoolean valid;
ARBoolean found;
static char *attrs[3] = {"cn", "uniquemember", NULL};
*response = (AREAResponseStruct *) malloc (sizeof(AREAResponseStruct));
if (*response == NULL)
return;
/* Initialize as a failed login */
(*response)->licenseMask = AREA_LICENSE_MASK_ALL;
(*response)->licenseWrite = AR_LICENSE_TYPE_NONE;
(*response)->licenseFTS = AR_LICENSE_TYPE_NONE;
(*response)->licenseRes1 = AR_LICENSE_TYPE_NONE;
(*response)->groups = NULL;
(*response)->notifyMech = AR_NOTIFY_NONE;
(*response)->email = NULL;
(*response)->loginStatus = AREA_LOGIN_FAILED;
(*response)->messageText = NULL;
(*response)->logText = NULL;
(*response)->modTime = 0;
fp = fopen("arealdap.log", "a"
fprintf(fp,"-------------------------------------------\n"
t = time(NULL);
local = localtime(&t);
fprintf(fp,"%s",asctime(local));
fprintf(fp,"Start to validate user: %s\n",user);
ld = ldap_init(MY_HOST, MY_PORT);
/* get a handle to an LDAP connection */
if (ld == NULL)
return;
else
fprintf (fp,"Got handle to LDAP Connection.\n"
/*
* Authenticate to the directory to do the search.
*/
if ( ldap_simple_bind_s( ld, NULL, NULL ) != LDAP_SUCCESS)
return;
else
fprintf (fp,"Bind to LDAP successful.\n"
sprintf(search, "%s", MY_PEOPLEBASE);
sprintf(filter, "(cn=%s)", user);
if (ldap_search_s(ld, search, LDAP_SCOPE_SUBTREE,
filter, NULL, 0, &result) != LDAP_SUCCESS)
return;
else
fprintf (fp,"LDAP Search Successful.\n"
/*
* Run through the attributes of each entry looking for a match.
*/
valid = FALSE;
found = FALSE;
email = NULL;
for (e = ldap_first_entry(ld, result); e != NULL; e = ldap_next_entry(ld, e))
{
found = TRUE;
dn = ldap_get_dn(ld, e);
if (dn == NULL)
{
continue;
}
if ((dn[0] == '\0') || (password[0] == '\0'))
{
continue;
}
if (ldap_simple_bind_s(ld, dn, password) != LDAP_SUCCESS)
{
continue;
}
valid = TRUE;
}
ldap_unbind(ld);
if ((found == TRUE) && (valid == TRUE))
{
fprintf(fp,"Found user and the password is good.\n"
/*
* We found a match and the password is good.
*/
(*response)->licenseMask = '\0';
(*response)->licenseWrite = '\0';
(*response)->licenseFTS = '\0';
(*response)->licenseRes1 = '\0';
(*response)->groups = NULL;
(*response)->notifyMech = '\0';
(*response)->email = NULL;
(*response)->loginStatus = AREA_LOGIN_SUCCESS;
(*response)->messageText = NULL;
}
else if (found == TRUE)
{
fprintf(fp, "User found, but password is bad.\n"
/*
* We found a match and the password is bad.
*/
(*response)->loginStatus = AREA_LOGIN_FAILED;
(*response)->messageText = NULL;
(void) free (email);
}
else
{
fprintf(fp,"User Not Found.\n"
/*
* Otherwise, we do not know the user.
*/
(*response)->loginStatus = AREA_LOGIN_UNKNOWN_USER;
(*response)->messageText = NULL;
(void) free (email);
}
fclose(fp);
return;
}
/*****************************************************************************/
/* */
/* AREANeedToSyncCallback */
/* */
/*****************************************************************************/
/* Description: This function is called by the AREA core library */
/* periodically at the request of the AR System server. */
/* */
/* A customized authentication server must define this function. Any */
/* global information or resources accessed here must be protected with */
/* appropriate mutual exclusion locks to be multi-thread safe. */
/* */
/* A non-zero return value will instruct the AR System server to flush */
/* its cache of user information. */
/* */
/*****************************************************************************/
int AREANeedToSyncCallback(void)
{
return 0;
}
/*****************************************************************************/
/* */
/* AREAFreeCallback */
/* */
/*****************************************************************************/
/* Description: This function is called by the AREA core library after a */
/* response is made to the AR System Server to authenticate a user. */
/* */
/* A pointer to the response structure returned by */
/* AREAVerifyLoginCallback() is passed as a parameter. */
/* */
/* A customized authentication server must define this function. Any */
/* global information or resources accessed here must be protected with */
/* appropriate mutual exclusion locks to be multi-thread safe. */
/* */
/* A customized authentication server must return a response. A NULL */
/* response will be interpreted as a failed login attempt. */
/* */
/*****************************************************************************/
void AREAFreeCallback(
AREAResponseStruct *response
)
{
/* Since we allocated the response in AREAVerifyLoginCallback(), we */
/* should free it here. */
if (response != NULL)
{
if (response->email != NULL)
(void) free(response->email);
(void) free (response);
}
return;
}
/*****************************************************************************/
/* */
/* AREATerminationCallback */
/* */
/*****************************************************************************/
/* Description: This function is called by the AREA core library after a */
/* response is made to the AR System Server to authenticate a user. */
/* */
/* Resources created in AREAInitializationCallback may be destroyed here. */
/* */
/* A customized authentication server must define this function. Any */
/* global information or resources accessed here must be protected with */
/* appropriate mutual exclusion locks to be multi-thread safe. */
/* */
/*****************************************************************************/
void AREATerminationCallback(void)
{
/* We have nothing to do here since we did not allocate or create any */
/* global resources in AREAInitializationCallback(). */
return;
}