-- more old and uneeded code

This commit is contained in:
pfelt
2010-07-09 21:21:28 +00:00
parent 86ea1aa72c
commit af762b0d74
13 changed files with 0 additions and 5464 deletions
@@ -1,350 +0,0 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <config.h>
#include <xpl.h>
#include <xplresolve.h>
#include <mdb.h>
#include <msgapi.h>
#include "cmlists.h"
/* Globals */
BOOL ListUnloadOk = TRUE;
ListGlobal List;
static BOOL ReadConfiguration(void);
EXPORT int ListsVerify(ConnMgrCommand *command, ConnMgrResult *result)
{
unsigned long i;
/* Check Allowed List */
if ((XplStrCaseCmp(command->event, CM_EVENT_RELAY) == 0) || (XplStrCaseCmp(command->event, CM_EVENT_CONNECT) == 0)) {
for (i = 0; i < List.allowed.count; i++) {
if ((List.allowed.start[i] <= (long) command->address) && ((long) command->address <= List.allowed.end[i])) {
/* We like the guy */
return(CM_MODULE_ACCEPT | CM_MODULE_PERMANENT | CM_MODULE_FORCE);
}
}
}
/* Check Blocked List */
if (XplStrCaseCmp(command->event, CM_EVENT_CONNECT) == 0) {
for (i = 0; i < List.blocked.count; i++) {
if ((List.blocked.start[i] <= (long) command->address) && ((long) command->address <= List.blocked.end[i])) {
/* We don't like the guy */
return(CM_MODULE_DENY | CM_MODULE_PERMANENT | CM_MODULE_FORCE);
}
}
}
return(0);
}
EXPORT BOOL
CMLISTSInit(CMModuleRegistrationStruct *registration, unsigned char *datadir)
{
if (ListUnloadOk == TRUE) {
XplSafeWrite(List.threadCount, 0);
List.directoryHandle = (MDBHandle) MsgInit();
if (List.directoryHandle) {
ListUnloadOk = FALSE;
List.logHandle = LoggerOpen("cmlist");
if (List.logHandle == NULL) {
XplConsolePrintf("cmlist: Unable to initialize logging. Logging disabled.\r\n");
}
/* Fill out registration information */
registration->priority = 1; /* It is important that the lists are early */
registration->Shutdown = ListsShutdown;
registration->Verify = ListsVerify;
registration->Notify = NULL;
XplSafeIncrement(List.threadCount);
strcpy(List.config.datadir, datadir);
return(ReadConfiguration());
} else {
XplConsolePrintf("cmlist: Failed to obtain directory handle\r\n");
}
}
return(FALSE);
}
static void
AddBlockedAddress(const unsigned char *AddressStart, const unsigned char *AddressEnd)
{
if ((List.blocked.count + 1) > List.blocked.allocated) {
List.blocked.start = MemRealloc(List.blocked.start, (List.blocked.allocated + 5) * sizeof(unsigned long));
List.blocked.end = MemRealloc(List.blocked.end, (List.blocked.allocated + 5) * sizeof(unsigned long));
if (!List.blocked.start || !List.blocked.end) {
LoggerEvent(List.logHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_OUT_OF_MEMORY, LOG_ERROR, 0, __FILE__, NULL, ((List.blocked.allocated+5) + (List.blocked.allocated+5)) * sizeof(unsigned long), __LINE__, NULL, 0);
return;
}
List.blocked.allocated += 5;
}
if ((List.blocked.start[List.blocked.count] = inet_addr(AddressStart)) != -1) {
List.blocked.start[List.blocked.count] = ntohl(List.blocked.start[List.blocked.count]);
if ((List.blocked.end[List.blocked.count] = inet_addr(AddressEnd)) != -1) {
List.blocked.end[List.blocked.count] = ntohl(List.blocked.end[List.blocked.count]);
List.blocked.count++;
}
}
}
static void
FreeBlockedAddresses(void)
{
if (List.blocked.start) {
MemFree(List.blocked.start);
}
List.blocked.start = NULL;
if (List.blocked.end) {
MemFree(List.blocked.end);
}
List.blocked.end = NULL;
List.blocked.allocated = 0;
List.blocked.count = 0;
}
static void
AddAllowedAddress(const unsigned char *AddressStart, const unsigned char *AddressEnd)
{
if ((List.allowed.count + 1) > List.allowed.allocated) {
List.allowed.start = MemRealloc(List.allowed.start, (List.allowed.allocated + 5) * sizeof(unsigned long));
List.allowed.end = MemRealloc(List.allowed.end, (List.allowed.allocated + 5) * sizeof(unsigned long));
if (!List.allowed.start || !List.allowed.end) {
LoggerEvent(List.logHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_OUT_OF_MEMORY, LOG_ERROR, 0, __FILE__, NULL, ((List.allowed.allocated+5) + (List.allowed.allocated+5)) * sizeof(unsigned long), __LINE__, NULL, 0);
return;
}
List.allowed.allocated += 5;
}
if ((List.allowed.start[List.allowed.count] = inet_addr(AddressStart)) != -1) {
List.allowed.start[List.allowed.count] = ntohl(List.allowed.start[List.allowed.count]);
if ((List.allowed.end[List.allowed.count] = inet_addr(AddressEnd)) != -1) {
List.allowed.end[List.allowed.count] = ntohl(List.allowed.end[List.allowed.count]);
List.allowed.count++;
}
}
}
static void
FreeAllowedAddresses(void)
{
if (List.allowed.start) {
MemFree(List.allowed.start);
}
List.allowed.start = NULL;
if (List.allowed.end) {
MemFree(List.allowed.end);
}
List.allowed.end = NULL;
List.allowed.allocated = 0;
List.allowed.count = 0;
}
EXPORT BOOL
ListsShutdown(void)
{
XplSafeDecrement(List.threadCount);
if (ListUnloadOk == FALSE) {
ListUnloadOk = TRUE;
/*
Make sure the library lists are gone before beginning to
shutdown.
*/
while (XplSafeRead(List.threadCount)) {
XplDelay(33);
}
LoggerClose(List.logHandle);
FreeBlockedAddresses();
FreeAllowedAddresses();
#if defined(NETWARE) || defined(LIBC)
XplSignalLocalSemaphore(List.shutdownSemaphore); /* The signal will release main() */
XplWaitOnLocalSemaphore(List.shutdownSemaphore); /* The wait will wait until main() is gone */
XplCloseLocalSemaphore(List.shutdownSemaphore);
#endif
}
return(FALSE);
}
static BOOL
ReadConfiguration(void)
{
MDBValueStruct *config;
const unsigned char *Address;
MDBEnumStruct *e;
unsigned char *ptr;
config = MDBCreateValueStruct(List.directoryHandle, MsgGetServerDN(NULL));
e = MDBCreateEnumStruct(config);
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMLISTS, MSGSRV_A_DISABLED, config)) {
if (atol(config->Value[0]) == 1) {
MDBDestroyValueStruct(config);
ListsShutdown();
return(FALSE);
}
}
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMLISTS, MSGSRV_A_CONFIG_CHANGED, config)) {
List.config.last = atol(config->Value[0]);
MDBFreeValues(config);
} else {
List.config.last = 0;
}
while ((Address = MDBReadEx(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMLISTS, MSGSRV_A_BLOCKED_ADDRESS, e, config)) != NULL) {
ptr = strchr(Address, '-');
if (ptr) {
*ptr = '\0';
AddBlockedAddress(Address, ptr + 1);
*ptr = '-';
} else {
AddBlockedAddress(Address, Address);
}
}
MDBFreeValues(config);
while ((Address = MDBReadEx(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMLISTS, MSGSRV_A_ALLOWED_ADDRESS, e, config)) != NULL) {
ptr = strchr(Address, '-');
if (ptr) {
*ptr = '\0';
AddAllowedAddress(Address, ptr + 1);
*ptr = '-';
} else {
AddAllowedAddress(Address, Address);
}
}
MDBFreeValues(config);
MDBDestroyEnumStruct(e, config);
MDBDestroyValueStruct(config);
if (List.blocked.count == 0 && List.allowed.count == 0) {
#if VERBOSE
XplConsolePrintf("cmlists: No addresses blocked or allowed\n");
#endif
ListsShutdown();
return(FALSE);
}
return(TRUE);
}
/*
Below are "stock" functions that are basically infrastructure.
However, one might want to add initialization code to main
and takedown code to the signal handler
*/
void
ListShutdownSigHandler(int Signal)
{
int oldtgid = XplSetThreadGroupID(List.tgid);
if (ListUnloadOk == FALSE) {
ListUnloadOk = TRUE;
/*
Make sure the library lists are gone before beginning to
shutdown.
*/
while (XplSafeRead(List.threadCount) > 1) {
XplDelay(33);
}
/* Do any required cleanup */
LoggerClose(List.logHandle);
#if defined(NETWARE) || defined(LIBC)
XplSignalLocalSemaphore(List.shutdownSemaphore); /* The signal will release main() */
XplWaitOnLocalSemaphore(List.shutdownSemaphore); /* The wait will wait until main() is gone */
XplCloseLocalSemaphore(List.shutdownSemaphore);
#endif
}
XplSetThreadGroupID(oldtgid);
return;
}
int
_NonAppCheckUnload(void)
{
if (ListUnloadOk == FALSE) {
XplConsolePrintf("\rThis module will automatically be unloaded by the thread that loaded it.\n");
XplConsolePrintf("\rIt does not allow manual unloading.\n");
return(1);
}
return(0);
}
int main(int argc, char *argv[])
{
/* init globals */
List.tgid = XplGetThreadGroupID();
XplRenameThread(GetThreadID(), "Gate Keeper List Module");
XplOpenLocalSemaphore(List.shutdownSemaphore, 0);
XplSignalHandler(ListShutdownSigHandler);
/*
This will "park" the module 'til we get unloaded;
it would not be neccessary to do this on NetWare,
but to prevent from automatically exiting on Unix
we need to keep main around...
*/
XplWaitOnLocalSemaphore(List.shutdownSemaphore);
XplSignalLocalSemaphore(List.shutdownSemaphore);
return(0);
}
@@ -1,73 +0,0 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <ctype.h>
#include <mdb.h>
#include <logger.h>
#include <connmgr.h>
#define PRODUCT_SHORT_NAME "cmlist.nlm"
#define PRODUCT_NAME "Bongo Connection Manager Block and Allow List Module"
typedef struct _ListGlobal {
/* Handles */
void *logHandle;
MDBHandle directoryHandle;
/* Module State */
time_t timeStamp;
int tgid;
BOOL unloadOK;
XplSemaphore shutdownSemaphore;
XplAtomic threadCount;
struct {
long last;
unsigned char datadir[XPL_MAX_PATH + 1];
} config;
struct {
long *start;
long *end;
unsigned long count;
unsigned long allocated;
} blocked;
struct {
long *start;
long *end;
unsigned long count;
unsigned long allocated;
} allowed;
} ListGlobal;
extern ListGlobal List;
/* cmlist.c */
void ListShutdownSigHandler(int Signal);
int _NonAppCheckUnload(void);
EXPORT BOOL CMLISTSInit(CMModuleRegistrationStruct *registration, unsigned char *dataDirectory);
EXPORT BOOL ListsShutdown(void);
EXPORT int ListsVerify(ConnMgrCommand *command, ConnMgrResult *result);
-495
View File
@@ -1,495 +0,0 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <config.h>
#include <xpl.h>
#include <xplresolve.h>
#include <mdb.h>
#include <msgapi.h>
#include <sqlite3.h>
#include "cmrbl.h"
/* Globals */
BOOL RBLUnloadOk = TRUE;
RBLGlobal RBL;
static BOOL ReadConfiguration(void);
EXPORT int RBLVerify(ConnMgrCommand *command, ConnMgrResult *result)
{
unsigned long i;
if (XplStrCaseCmp(command->event, CM_EVENT_CONNECT) == 0) {
XplDnsRecord *dns = NULL;
BOOL blocked = FALSE;
int rc = -1;
int commentID = -1;
/* Check for a cached value */
XplWaitOnLocalSemaphore(RBL.sqlite.semaphore);
sqlite3_bind_int(RBL.sqlite.stmt.get, 1, command->address);
if ((rc = sqlite3_step(RBL.sqlite.stmt.get)) == SQLITE_ROW) {
blocked = sqlite3_column_int(RBL.sqlite.stmt.get, 0);
strncpy(result->comment, sqlite3_column_text(RBL.sqlite.stmt.get, 1), sizeof(result->comment));
}
sqlite3_reset(RBL.sqlite.stmt.get);
XplSignalLocalSemaphore(RBL.sqlite.semaphore);
if (rc != SQLITE_ROW) {
/* Perform the RBL check */
for (i = 0; i < RBL.rbl.count; i++) {
unsigned char buffer[MAXEMAILNAMESIZE];
struct in_addr ip;
ip.s_addr = command->address;
/* address is in host byte order. RBL checks require least significant first. */
snprintf(buffer, sizeof(buffer), "%d.%d.%d.%d.%s",
ip.s_net,
ip.s_host,
ip.s_lh,
ip.s_impno,
RBL.rbl.hosts[i]);
rc = XplDnsResolve(buffer, &dns, XPL_RR_A);
if (dns) {
MemFree(dns);
}
if (rc == XPL_DNS_SUCCESS) {
blocked = TRUE;
commentID = RBL.rbl.ids[i];
strncpy(result->comment, RBL.rbl.comments[i], sizeof(result->comment));
continue;
}
}
/* Store new value */
XplWaitOnLocalSemaphore(RBL.sqlite.semaphore);
/*
Insert the new value into the table. The time for a negative result is a
full day. The time for a positive result is only 15 minutes however,
because a positive result simply means that the servers do not know anything
about the address.
*/
sqlite3_bind_int(RBL.sqlite.stmt.add, 1, command->address);
sqlite3_bind_text(RBL.sqlite.stmt.add, 2, blocked ? RBL.config.blockTimeout : RBL.config.allowTimeout, -1, SQLITE_TRANSIENT);
sqlite3_bind_int(RBL.sqlite.stmt.add, 3, blocked);
sqlite3_bind_int(RBL.sqlite.stmt.add, 4, commentID);
sqlite3_step(RBL.sqlite.stmt.add);
sqlite3_reset(RBL.sqlite.stmt.add);
XplSignalLocalSemaphore(RBL.sqlite.semaphore);
}
if (blocked) {
/* He was blocked by RBL */
return(CM_MODULE_DENY | CM_MODULE_PERMANENT | CM_MODULE_FORCE);
} else {
/* He was not blocked, don't force it though */
return(CM_MODULE_ACCEPT);
}
}
return(0);
}
static void
TransactionController(void *ignored)
{
XplWaitOnLocalSemaphore(RBL.sqlite.semaphore);
if (sqlite3_exec(RBL.sqlite.handle, SQL_BEGIN, NULL, NULL, NULL) != SQLITE_OK) {
XplConsolePrintf("cmrbl: Failed to start transaction controller\n");
}
XplSignalLocalSemaphore(RBL.sqlite.semaphore);
while (!RBLUnloadOk) {
unsigned long i;
for (i = 0; i < 15 && !RBLUnloadOk; i++) {
XplDelay(1000);
}
XplWaitOnLocalSemaphore(RBL.sqlite.semaphore);
if (sqlite3_exec(RBL.sqlite.handle, SQL_SAVE, NULL, NULL, NULL) != SQLITE_OK) {
XplConsolePrintf("cmrbl: Failed to save cache data\n");
}
XplSignalLocalSemaphore(RBL.sqlite.semaphore);
}
XplWaitOnLocalSemaphore(RBL.sqlite.semaphore);
if (sqlite3_exec(RBL.sqlite.handle, SQL_END, NULL, NULL, NULL) != SQLITE_OK) {
XplConsolePrintf("cmrbl: Failed to end transaction controller\n");
}
XplSignalLocalSemaphore(RBL.sqlite.semaphore);
}
EXPORT BOOL
CMRBLInit(CMModuleRegistrationStruct *registration, unsigned char *datadir)
{
if (RBLUnloadOk == TRUE) {
XplSafeWrite(RBL.threadCount, 0);
RBL.directoryHandle = (MDBHandle) MsgInit();
if (RBL.directoryHandle) {
RBLUnloadOk = FALSE;
RBL.logHandle = LoggerOpen("cmrbl");
if (RBL.logHandle == NULL) {
XplConsolePrintf("cmrbl: Unable to initialize logging. Logging disabled.\r\n");
}
/* Fill out registration information */
registration->priority = 1; /* It is important that the rbl are early */
registration->Shutdown = RBLShutdown;
registration->Verify = RBLVerify;
registration->Notify = NULL;
XplSafeIncrement(RBL.threadCount);
strcpy(RBL.config.datadir, datadir);
XplOpenLocalSemaphore(RBL.sqlite.semaphore, 1);
if (ReadConfiguration()) {
unsigned char buffer[XPL_MAX_PATH + 1];
int ccode;
XplThreadID id;
sqlite3_stmt *stmt;
sqlite3_stmt *stmt2;
unsigned long i;
snprintf(buffer, sizeof(buffer), "%s/cache.db", datadir);
if (sqlite3_open(buffer, &RBL.sqlite.handle) != SQLITE_OK) {
printf("cmrbl: Failed to open database: %s\n", sqlite3_errmsg(RBL.sqlite.handle));
}
if (sqlite3_exec(RBL.sqlite.handle, SQL_CREATE, NULL, NULL, NULL) != SQLITE_OK) {
#if 0
printf("bongogatekeeper: %s\n", sqlite3_errmsg(RBL.sqlite.handle));
#endif
sqlite3_exec(RBL.sqlite.handle, SQL_ROLLBACK, NULL, NULL, NULL);
}
if ((sqlite3_prepare(RBL.sqlite.handle, SQL_ADD, -1, &RBL.sqlite.stmt.add, 0) != SQLITE_OK) ||
(sqlite3_prepare(RBL.sqlite.handle, SQL_GET, -1, &RBL.sqlite.stmt.get, 0) != SQLITE_OK) ||
(sqlite3_prepare(RBL.sqlite.handle, SQL_CLEAN, -1, &RBL.sqlite.stmt.clean,0) != SQLITE_OK))
{
printf("cmrbl: Failed to prepare sql: %s\n", sqlite3_errmsg(RBL.sqlite.handle));
}
/* Cleanup */
sqlite3_exec(RBL.sqlite.handle, SQL_COMMENTS_CLEAN1, NULL, NULL, NULL);
sqlite3_prepare(RBL.sqlite.handle, SQL_COMMENTS_CLEAN2, -1, &stmt, 0);
for (i = 0; i < RBL.rbl.count; i++) {
sqlite3_bind_text(stmt, 1, RBL.rbl.hosts[i], -1, SQLITE_TRANSIENT);
sqlite3_step(stmt);
sqlite3_reset(stmt);
}
sqlite3_finalize(stmt);
sqlite3_exec(RBL.sqlite.handle, SQL_COMMENTS_CLEAN3, NULL, NULL, NULL);
/* Ok, add any new ones */
sqlite3_prepare(RBL.sqlite.handle, SQL_COMMENTS_ADD, -1, &stmt, 0);
sqlite3_prepare(RBL.sqlite.handle, SQL_COMMENTS_UPDATE, -1, &stmt2, 0);
for (i = 0; i < RBL.rbl.count; i++) {
sqlite3_bind_text(stmt, 1, RBL.rbl.hosts[i], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 2, RBL.rbl.comments[i], -1, SQLITE_TRANSIENT);
if (sqlite3_step(stmt) != SQLITE_DONE) {
/* It is already there, so just update the comment in case it changed */
sqlite3_bind_text(stmt2, 1, RBL.rbl.comments[i], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt2, 2, RBL.rbl.hosts[i], -1, SQLITE_TRANSIENT);
sqlite3_step(stmt2);
sqlite3_reset(stmt2);
}
sqlite3_reset(stmt);
}
sqlite3_finalize(stmt);
sqlite3_finalize(stmt2);
/* Get the IDs for them */
sqlite3_prepare(RBL.sqlite.handle, SQL_COMMENTS_GET_ID, -1, &stmt, 0);
for (i = 0; i < RBL.rbl.count; i++) {
sqlite3_bind_text(stmt, 1, RBL.rbl.hosts[i], -1, SQLITE_TRANSIENT);
if (sqlite3_step(stmt) == SQLITE_ROW) {
RBL.rbl.ids[i] = sqlite3_column_int(RBL.sqlite.stmt.get, 0);
} else {
RBL.rbl.ids[i] = -1;
}
sqlite3_reset(stmt);
}
sqlite3_finalize(stmt);
/* Begin the transaction controller thread */
XplBeginThread(&id, TransactionController, (1024 * 32), NULL, ccode);
return(TRUE);
}
} else {
XplConsolePrintf("cmrbl: Failed to obtain directory handle\r\n");
}
}
return(FALSE);
}
EXPORT BOOL
RBLShutdown(void)
{
XplSafeDecrement(RBL.threadCount);
if (RBLUnloadOk == FALSE) {
unsigned long i;
RBLUnloadOk = TRUE;
/*
Make sure the library rbl are gone before beginning to
shutdown.
*/
while (XplSafeRead(RBL.threadCount)) {
XplDelay(33);
}
LoggerClose(RBL.logHandle);
sqlite3_finalize(RBL.sqlite.stmt.add);
sqlite3_finalize(RBL.sqlite.stmt.get);
sqlite3_finalize(RBL.sqlite.stmt.clean);
sqlite3_close(RBL.sqlite.handle);
XplCloseLocalSemaphore(RBL.sqlite.semaphore);
for (i = 0; i < RBL.rbl.count; i++) {
MemFree(RBL.rbl.hosts[i]);
MemFree(RBL.rbl.comments[i]);
}
if (RBL.rbl.hosts) {
MemFree(RBL.rbl.hosts);
}
if (RBL.rbl.comments) {
MemFree(RBL.rbl.comments);
}
if (RBL.rbl.ids) {
MemFree(RBL.rbl.ids);
}
#if defined(NETWARE) || defined(LIBC)
XplSignalLocalSemaphore(RBL.shutdownSemaphore); /* The signal will release main() */
XplWaitOnLocalSemaphore(RBL.shutdownSemaphore); /* The wait will wait until main() is gone */
XplCloseLocalSemaphore(RBL.shutdownSemaphore);
#endif
}
return(FALSE);
}
static BOOL
ReadConfiguration(void)
{
MDBValueStruct *config;
config = MDBCreateValueStruct(RBL.directoryHandle, MsgGetServerDN(NULL));
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRBL, MSGSRV_A_DISABLED, config)) {
if (atol(config->Value[0]) == 1) {
MDBDestroyValueStruct(config);
RBLShutdown();
return(FALSE);
}
}
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRBL, MSGSRV_A_CONFIG_CHANGED, config)) {
RBL.config.last = atol(config->Value[0]);
MDBFreeValues(config);
} else {
RBL.config.last = 0;
}
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRBL, MSGSRV_A_RBL_HOST, config) > 0) {
unsigned long i;
for (i = 0; i < RBL.rbl.count; i++) {
MemFree(RBL.rbl.hosts[i]);
MemFree(RBL.rbl.comments[i]);
}
if (RBL.rbl.hosts) {
MemFree(RBL.rbl.hosts);
}
if (RBL.rbl.comments) {
MemFree(RBL.rbl.comments);
}
if (RBL.rbl.ids) {
MemFree(RBL.rbl.ids);
}
RBL.rbl.count = config->Used;
RBL.rbl.hosts = MemMalloc(config->Used * sizeof(char *));
RBL.rbl.comments = MemMalloc(config->Used * sizeof(char *));
RBL.rbl.ids = MemMalloc(config->Used * sizeof(long));
if (!RBL.rbl.hosts || !RBL.rbl.comments || !RBL.rbl.ids) {
LoggerEvent(RBL.logHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_OUT_OF_MEMORY, LOG_ERROR, 0, __FILE__, NULL, config->Used * sizeof(char *) * 2, __LINE__, NULL, 0);
} else {
for (i = 0; i < RBL.rbl.count; i++) {
unsigned char *ptr = strchr(config->Value[i], ';');
if (ptr) {
ptr[0] = '\0';
}
RBL.rbl.hosts[i] = MemStrdup(config->Value[i]);
if (ptr) {
RBL.rbl.comments[i] = MemStrdup(ptr + 1);
} else {
RBL.rbl.comments[i] = MemMalloc(sizeof(BLOCKED_STRING) + strlen(RBL.rbl.hosts[i]));
sprintf(RBL.rbl.comments[i], BLOCKED_STRING, RBL.rbl.hosts[i]);
}
LoggerEvent(RBL.logHandle, LOGGER_SUBSYSTEM_CONFIGURATION, LOGGER_EVENT_CONFIGURATION_STRING, LOG_INFO, 0, "MSGSRV_A_RBL_HOST", config->Value[i], 0, 0, NULL, 0);
}
}
MDBFreeValues(config);
}
/*
Store the timeout strings. It is faster to do this once, instead of storing the long value
and creating the string each time, since it must be a string that is bound to the SQL statement.
*/
snprintf(RBL.config.blockTimeout, sizeof(RBL.config.blockTimeout), "%d minutes", (24 * 60)); /* Default to 1 day for a block */
snprintf(RBL.config.allowTimeout, sizeof(RBL.config.blockTimeout), "%d minutes", 15); /* Default to 15 minutes for allow */
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRBL, MSGSRV_A_CONFIGURATION, config) > 0) {
unsigned long i;
for (i = 0; i < config->Used; i++) {
if (XplStrNCaseCmp(config->Value[i], BLOCK_TIMEOUT_PREFIX, sizeof(BLOCK_TIMEOUT_PREFIX) - 1) == 0) {
snprintf(RBL.config.blockTimeout, sizeof(RBL.config.blockTimeout), "%lu minutes", atol(config->Value[i] + sizeof(BLOCK_TIMEOUT_PREFIX) - 1));
} else if (XplStrNCaseCmp(config->Value[i], ALLOW_TIMEOUT_PREFIX, sizeof(ALLOW_TIMEOUT_PREFIX) - 1) == 0) {
snprintf(RBL.config.allowTimeout, sizeof(RBL.config.allowTimeout), "%lu minutes", atol(config->Value[i] + sizeof(ALLOW_TIMEOUT_PREFIX) - 1));
}
}
}
MDBDestroyValueStruct(config);
if (RBL.rbl.count == 0) {
#if VERBOSE
XplConsolePrintf("cmrbl: No RBL zones configured. RBL check is disabled.\n");
#endif
RBLShutdown();
return(FALSE);
}
return(TRUE);
}
/*
Below are "stock" functions that are basically infrastructure.
However, one might want to add initialization code to main
and takedown code to the signal handler
*/
void
RBLShutdownSigHandler(int Signal)
{
int oldtgid = XplSetThreadGroupID(RBL.tgid);
if (RBLUnloadOk == FALSE) {
RBLUnloadOk = TRUE;
/*
Make sure the library rbl are gone before beginning to
shutdown.
*/
while (XplSafeRead(RBL.threadCount) > 1) {
XplDelay(33);
}
/* Do any required cleanup */
LoggerClose(RBL.logHandle);
#if defined(NETWARE) || defined(LIBC)
XplSignalLocalSemaphore(RBL.shutdownSemaphore); /* The signal will release main() */
XplWaitOnLocalSemaphore(RBL.shutdownSemaphore); /* The wait will wait until main() is gone */
XplCloseLocalSemaphore(RBL.shutdownSemaphore);
#endif
}
XplSetThreadGroupID(oldtgid);
return;
}
int
_NonAppCheckUnload(void)
{
if (RBLUnloadOk == FALSE) {
XplConsolePrintf("\rThis module will automatically be unloaded by the thread that loaded it.\n");
XplConsolePrintf("\rIt does not allow manual unloading.\n");
return(1);
}
return(0);
}
int main(int argc, char *argv[])
{
/* init globals */
RBL.tgid = XplGetThreadGroupID();
XplRenameThread(GetThreadID(), "Gate Keeper RBL Module");
XplOpenLocalSemaphore(RBL.shutdownSemaphore, 0);
XplSignalHandler(RBLShutdownSigHandler);
/*
This will "park" the module 'til we get unloaded;
it would not be neccessary to do this on NetWare,
but to prevent from automatically exiting on Unix
we need to keep main around...
*/
XplWaitOnLocalSemaphore(RBL.shutdownSemaphore);
XplSignalLocalSemaphore(RBL.shutdownSemaphore);
return(0);
}
-123
View File
@@ -1,123 +0,0 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <ctype.h>
#include <mdb.h>
#include <logger.h>
#include <sqlite3.h>
#include <connmgr.h>
#define PRODUCT_SHORT_NAME "cmrbl.nlm"
#define PRODUCT_NAME "Bongo Connection Manager RBL Module"
#define BLOCKED_STRING "Blocked by RBL %s"
typedef struct _RBLGlobal {
/* Handles */
void *logHandle;
MDBHandle directoryHandle;
/* Module State */
time_t timeStamp;
int tgid;
BOOL unloadOK;
XplSemaphore shutdownSemaphore;
XplAtomic threadCount;
struct {
long last;
unsigned char datadir[XPL_MAX_PATH + 1];
unsigned char blockTimeout[256];
unsigned char allowTimeout[256];
} config;
struct {
unsigned char **hosts;
unsigned char **comments;
unsigned long *ids;
unsigned long count;
unsigned long allocated;
} rbl;
struct {
sqlite3 *handle;
XplSemaphore semaphore;
struct {
sqlite3_stmt *add;
sqlite3_stmt *get;
sqlite3_stmt *clean;
} stmt;
} sqlite;
} RBLGlobal;
extern RBLGlobal RBL;
/* cmrbl.c */
void RBLShutdownSigHandler(int Signal);
int _NonAppCheckUnload(void);
EXPORT BOOL CMRBLInit(CMModuleRegistrationStruct *registration, unsigned char *dataDirectory);
EXPORT BOOL RBLShutdown(void);
EXPORT int RBLVerify(ConnMgrCommand *command, ConnMgrResult *result);
/* Config Prefixes */
#define BLOCK_TIMEOUT_PREFIX "RBLBlockTimeout:"
#define ALLOW_TIMEOUT_PREFIX "RBLAllowTimeout:"
/* SQL */
#define SQL_CREATE "BEGIN TRANSACTION;" \
"CREATE TABLE cache (" \
"ip INTEGER PRIMARY KEY NOT NULL," \
"timeout DATETIME," \
"block BOOL," \
"commentID INTEGER" \
");" \
"CREATE TABLE comments (" \
"key INTEGER PRIMARY KEY AUTOINCREMENT," \
"zone TEXT UNIQUE," \
"comment TEXT," \
"keep BOOL default 1" \
");" \
"CREATE INDEX timeout_idx ON cache (timeout);" \
"CREATE INDEX comment_idx ON cache (commentID);"\
"END TRANSACTION;"
#define SQL_ROLLBACK "ROLLBACK;"
#define SQL_ADD "INSERT OR REPLACE INTO cache (ip, timeout, block, commentID) VALUES (?, DATETIME('now', ?), ?, ?);"
#define SQL_GET "SELECT cache.block, comments.comment FROM cache INNER JOIN comments ON cache.commentID=comments.key WHERE ip=? AND julianday('now') < julianday(timeout);"
#define SQL_CLEAN "DELETE FROM cache WHERE julianday('now') >= julianday(timeout);"
#define SQL_BEGIN "BEGIN TRANSACTION;"
#define SQL_END "END TRANSACTION;"
#define SQL_SAVE SQL_CLEAN SQL_END SQL_BEGIN
#define SQL_COMMENTS_CLEAN1 "UPDATE comments SET keep=0;"
#define SQL_COMMENTS_CLEAN2 "UPDATE comments SET keep=1 WHERE zone=?;"
#define SQL_COMMENTS_CLEAN3 "DELETE FROM comments WHERE keep=0"
#define SQL_COMMENTS_ADD "INSERT INTO comments (zone, comment) VALUES (?, ?);"
#define SQL_COMMENTS_UPDATE "UPDATE comments SET comment=? WHERE zone=?;"
#define SQL_COMMENTS_GET_ID "SELECT key FROM comments WHERE zone=?;"
-360
View File
@@ -1,360 +0,0 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <config.h>
#include <xpl.h>
#include <xplresolve.h>
#include <mdb.h>
#include <msgapi.h>
#include <sqlite3.h>
#include "cmrdns.h"
/* Globals */
BOOL RDNSUnloadOk = TRUE;
RDNSGlobal RDNS;
static BOOL ReadConfiguration(void);
EXPORT int RDNSVerify(ConnMgrCommand *command, ConnMgrResult *result)
{
if (XplStrCaseCmp(command->event, CM_EVENT_CONNECT) == 0) {
XplDnsRecord *dns = NULL;
BOOL blocked = FALSE;
int rc = -1;
/* Check for a cached value */
XplWaitOnLocalSemaphore(RDNS.sqlite.semaphore);
sqlite3_bind_int(RDNS.sqlite.stmt.get, 1, command->address);
if ((rc = sqlite3_step(RDNS.sqlite.stmt.get)) == SQLITE_ROW) {
blocked = sqlite3_column_int(RDNS.sqlite.stmt.get, 0);
}
sqlite3_reset(RDNS.sqlite.stmt.get);
XplSignalLocalSemaphore(RDNS.sqlite.semaphore);
if (rc != SQLITE_ROW) {
unsigned char buffer[MAXEMAILNAMESIZE];
struct in_addr ip;
/* Perform the RDNS check */
ip.s_addr = command->address;
/* ip is in host byte order. Reverse DNS requires most significant first. (unless providing the .in-addr.arpa extension) */
snprintf(buffer, sizeof(buffer), "%d.%d.%d.%d",
ip.s_impno,
ip.s_lh,
ip.s_host,
ip.s_net);
rc = XplDnsResolve(buffer, &dns, XPL_RR_PTR);
if (dns) {
MemFree(dns);
}
if (rc != XPL_DNS_SUCCESS) {
/* We don't like the guy */
blocked = TRUE;
}
/* Store new value */
XplWaitOnLocalSemaphore(RDNS.sqlite.semaphore);
/*
Insert the new value into the table. The time for a negative result is a
full day. The time for a positive result is only 15 minutes however,
because a positive result simply means that the servers do not know anything
about the address.
*/
sqlite3_bind_int(RDNS.sqlite.stmt.add, 1, command->address);
sqlite3_bind_text(RDNS.sqlite.stmt.add, 2, blocked ? RDNS.config.blockTimeout : RDNS.config.allowTimeout, -1, SQLITE_TRANSIENT);
sqlite3_bind_int(RDNS.sqlite.stmt.add, 3, blocked);
sqlite3_step(RDNS.sqlite.stmt.add);
sqlite3_reset(RDNS.sqlite.stmt.add);
XplSignalLocalSemaphore(RDNS.sqlite.semaphore);
}
if (blocked) {
/* He was blocked by RDNS */
strncpy(result->comment, CM_COMMENT, sizeof(result->comment));
}
result->detail.connect.requireAuth = blocked;
return(CM_MODULE_ACCEPT);
}
return(0);
}
static void
TransactionController(void *ignored)
{
XplWaitOnLocalSemaphore(RDNS.sqlite.semaphore);
if (sqlite3_exec(RDNS.sqlite.handle, SQL_BEGIN, NULL, NULL, NULL) != SQLITE_OK) {
XplConsolePrintf("cmrdns: Failed to start transaction controller\n");
}
XplSignalLocalSemaphore(RDNS.sqlite.semaphore);
while (!RDNSUnloadOk) {
unsigned long i;
for (i = 0; i < 15 && !RDNSUnloadOk; i++) {
XplDelay(1000);
}
XplWaitOnLocalSemaphore(RDNS.sqlite.semaphore);
if (sqlite3_exec(RDNS.sqlite.handle, SQL_SAVE, NULL, NULL, NULL) != SQLITE_OK) {
XplConsolePrintf("cmrdns: Failed to save cache data\n");
}
XplSignalLocalSemaphore(RDNS.sqlite.semaphore);
}
XplWaitOnLocalSemaphore(RDNS.sqlite.semaphore);
if (sqlite3_exec(RDNS.sqlite.handle, SQL_END, NULL, NULL, NULL) != SQLITE_OK) {
XplConsolePrintf("cmrdns: Failed to end transaction controller\n");
}
XplSignalLocalSemaphore(RDNS.sqlite.semaphore);
}
EXPORT BOOL
CMRDNSInit(CMModuleRegistrationStruct *registration, unsigned char *datadir)
{
if (RDNSUnloadOk == TRUE) {
XplSafeWrite(RDNS.threadCount, 0);
RDNS.directoryHandle = (MDBHandle) MsgInit();
if (RDNS.directoryHandle) {
RDNSUnloadOk = FALSE;
RDNS.logHandle = LoggerOpen("cmrdns");
if (RDNS.logHandle == NULL) {
XplConsolePrintf("cmrdns: Unable to initialize logging. Logging disabled.\r\n");
}
/* Fill out registration information */
registration->priority = 1; /* It is important that the rdns are early */
registration->Shutdown = RDNSShutdown;
registration->Verify = RDNSVerify;
registration->Notify = NULL;
XplSafeIncrement(RDNS.threadCount);
strcpy(RDNS.config.datadir, datadir);
XplOpenLocalSemaphore(RDNS.sqlite.semaphore, 1);
if (ReadConfiguration()) {
unsigned char buffer[XPL_MAX_PATH + 1];
int ccode;
XplThreadID id;
snprintf(buffer, sizeof(buffer), "%s/cache.db", datadir);
if (sqlite3_open(buffer, &RDNS.sqlite.handle) != SQLITE_OK) {
printf("cmrdns: Failed to open database: %s\n", sqlite3_errmsg(RDNS.sqlite.handle));
}
if (sqlite3_exec(RDNS.sqlite.handle, SQL_CREATE, NULL, NULL, NULL) != SQLITE_OK) {
#if 0
printf("bongogatekeeper: %s\n", sqlite3_errmsg(RDNS.sqlite.handle));
#endif
sqlite3_exec(RDNS.sqlite.handle, SQL_ROLLBACK, NULL, NULL, NULL);
}
if ((sqlite3_prepare(RDNS.sqlite.handle, SQL_ADD, -1, &RDNS.sqlite.stmt.add, 0) != SQLITE_OK) ||
(sqlite3_prepare(RDNS.sqlite.handle, SQL_GET, -1, &RDNS.sqlite.stmt.get, 0) != SQLITE_OK) ||
(sqlite3_prepare(RDNS.sqlite.handle, SQL_CLEAN, -1, &RDNS.sqlite.stmt.clean,0) != SQLITE_OK))
{
printf("cmrdns: Failed to prepare sql: %s\n", sqlite3_errmsg(RDNS.sqlite.handle));
}
/* Begin the transaction controller thread */
XplBeginThread(&id, TransactionController, (1024 * 32), NULL, ccode);
return(TRUE);
}
} else {
XplConsolePrintf("cmrdns: Failed to obtain directory handle\r\n");
}
}
return(FALSE);
}
EXPORT BOOL
RDNSShutdown(void)
{
XplSafeDecrement(RDNS.threadCount);
if (RDNSUnloadOk == FALSE) {
RDNSUnloadOk = TRUE;
/*
Make sure the library rdns are gone before beginning to
shutdown.
*/
while (XplSafeRead(RDNS.threadCount)) {
XplDelay(33);
}
LoggerClose(RDNS.logHandle);
sqlite3_finalize(RDNS.sqlite.stmt.add);
sqlite3_finalize(RDNS.sqlite.stmt.get);
sqlite3_finalize(RDNS.sqlite.stmt.clean);
sqlite3_close(RDNS.sqlite.handle);
XplCloseLocalSemaphore(RDNS.sqlite.semaphore);
#if defined(NETWARE) || defined(LIBC)
XplSignalLocalSemaphore(RDNS.shutdownSemaphore); /* The signal will release main() */
XplWaitOnLocalSemaphore(RDNS.shutdownSemaphore); /* The wait will wait until main() is gone */
XplCloseLocalSemaphore(RDNS.shutdownSemaphore);
#endif
}
return(FALSE);
}
static BOOL
ReadConfiguration(void)
{
MDBValueStruct *config;
config = MDBCreateValueStruct(RDNS.directoryHandle, MsgGetServerDN(NULL));
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRDNS, MSGSRV_A_DISABLED, config)) {
if (atol(config->Value[0]) == 1) {
MDBDestroyValueStruct(config);
RDNSShutdown();
return(FALSE);
}
}
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRDNS, MSGSRV_A_CONFIG_CHANGED, config)) {
RDNS.config.last = atol(config->Value[0]);
MDBFreeValues(config);
} else {
RDNS.config.last = 0;
}
/*
Store the timeout strings. It is faster to do this once, instead of storing the long value
and creating the string each time, since it must be a string that is bound to the SQL statement.
*/
snprintf(RDNS.config.blockTimeout, sizeof(RDNS.config.blockTimeout), "%d minutes", (3 * 60)); /* Default to 3 hours */
snprintf(RDNS.config.allowTimeout, sizeof(RDNS.config.blockTimeout), "%d minutes", (3 * 60)); /* Default to 3 hours */
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMRDNS, MSGSRV_A_CONFIGURATION, config) > 0) {
unsigned long i;
for (i = 0; i < config->Used; i++) {
if (XplStrNCaseCmp(config->Value[i], BLOCK_TIMEOUT_PREFIX, sizeof(BLOCK_TIMEOUT_PREFIX) - 1) == 0) {
snprintf(RDNS.config.blockTimeout, sizeof(RDNS.config.blockTimeout), "%lu minutes", atol(config->Value[i] + sizeof(BLOCK_TIMEOUT_PREFIX) - 1));
} else if (XplStrNCaseCmp(config->Value[i], ALLOW_TIMEOUT_PREFIX, sizeof(ALLOW_TIMEOUT_PREFIX) - 1) == 0) {
snprintf(RDNS.config.allowTimeout, sizeof(RDNS.config.allowTimeout), "%lu minutes", atol(config->Value[i] + sizeof(ALLOW_TIMEOUT_PREFIX) - 1));
}
}
}
MDBDestroyValueStruct(config);
return(TRUE);
}
/*
Below are "stock" functions that are basically infrastructure.
However, one might want to add initialization code to main
and takedown code to the signal handler
*/
void
RDNSShutdownSigHandler(int Signal)
{
int oldtgid = XplSetThreadGroupID(RDNS.tgid);
if (RDNSUnloadOk == FALSE) {
RDNSUnloadOk = TRUE;
/*
Make sure the library rdns are gone before beginning to
shutdown.
*/
while (XplSafeRead(RDNS.threadCount) > 1) {
XplDelay(33);
}
/* Do any required cleanup */
LoggerClose(RDNS.logHandle);
#if defined(NETWARE) || defined(LIBC)
XplSignalLocalSemaphore(RDNS.shutdownSemaphore); /* The signal will release main() */
XplWaitOnLocalSemaphore(RDNS.shutdownSemaphore); /* The wait will wait until main() is gone */
XplCloseLocalSemaphore(RDNS.shutdownSemaphore);
#endif
}
XplSetThreadGroupID(oldtgid);
return;
}
int
_NonAppCheckUnload(void)
{
if (RDNSUnloadOk == FALSE) {
XplConsolePrintf("\rThis module will automatically be unloaded by the thread that loaded it.\n");
XplConsolePrintf("\rIt does not allow manual unloading.\n");
return(1);
}
return(0);
}
int main(int argc, char *argv[])
{
/* init globals */
RDNS.tgid = XplGetThreadGroupID();
XplRenameThread(GetThreadID(), "Gate Keeper RDNS Module");
XplOpenLocalSemaphore(RDNS.shutdownSemaphore, 0);
XplSignalHandler(RDNSShutdownSigHandler);
/*
This will "park" the module 'til we get unloaded;
it would not be neccessary to do this on NetWare,
but to prevent from automatically exiting on Unix
we need to keep main around...
*/
XplWaitOnLocalSemaphore(RDNS.shutdownSemaphore);
XplSignalLocalSemaphore(RDNS.shutdownSemaphore);
return(0);
}
@@ -1,99 +0,0 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <ctype.h>
#include <mdb.h>
#include <logger.h>
#include <sqlite3.h>
#include <connmgr.h>
#define PRODUCT_SHORT_NAME "cmrdns.nlm"
#define PRODUCT_NAME "Bongo Connection Manager Reverse DNS Module"
#define CM_COMMENT "Your computer does not have a hostname, access blocked"
typedef struct _RDNSGlobal {
/* Handles */
void *logHandle;
MDBHandle directoryHandle;
/* Module State */
time_t timeStamp;
int tgid;
BOOL unloadOK;
XplSemaphore shutdownSemaphore;
XplAtomic threadCount;
struct {
long last;
unsigned char datadir[XPL_MAX_PATH + 1];
unsigned char blockTimeout[256];
unsigned char allowTimeout[256];
} config;
struct {
sqlite3 *handle;
XplSemaphore semaphore;
struct {
sqlite3_stmt *add;
sqlite3_stmt *get;
sqlite3_stmt *clean;
} stmt;
} sqlite;
} RDNSGlobal;
extern RDNSGlobal RDNS;
/* cmrdns.c */
void RDNSShutdownSigHandler(int Signal);
int _NonAppCheckUnload(void);
EXPORT BOOL CMRDNSInit(CMModuleRegistrationStruct *registration, unsigned char *dataDirectory);
EXPORT BOOL RDNSShutdown(void);
EXPORT int RDNSVerify(ConnMgrCommand *command, ConnMgrResult *result);
/* Config Prefixes */
#define BLOCK_TIMEOUT_PREFIX "RDNSBlockTimeout:"
#define ALLOW_TIMEOUT_PREFIX "RDNSAllowTimeout:"
/* SQL */
#define SQL_CREATE "BEGIN TRANSACTION;" \
"CREATE TABLE cache (" \
"ip INTEGER PRIMARY KEY NOT NULL," \
"timeout DATETIME," \
"block BOOL" \
");" \
"CREATE INDEX timeout_idx ON cache (timeout);" \
"END TRANSACTION;"
#define SQL_ROLLBACK "ROLLBACK;"
#define SQL_ADD "INSERT OR REPLACE INTO cache (ip, timeout, block) VALUES (?, DATETIME('now', ?), ?);"
#define SQL_GET "SELECT block FROM cache WHERE ip=? AND julianday('now') < julianday(timeout);"
#define SQL_CLEAN "DELETE FROM cache WHERE julianday('now') >= julianday(timeout);"
#define SQL_BEGIN "BEGIN TRANSACTION;"
#define SQL_END "END TRANSACTION;"
#define SQL_SAVE SQL_CLEAN SQL_END SQL_BEGIN
-293
View File
@@ -1,293 +0,0 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <config.h>
#include <xpl.h>
#include <xplresolve.h>
#include <mdb.h>
#include <msgapi.h>
#include "cmuser.h"
/* Globals */
BOOL UserUnloadOk = TRUE;
UserGlobal User;
static BOOL ReadConfiguration(void);
static void Cleanup(void *param);
EXPORT BOOL UserNotify(ConnMgrCommand *command)
{
/*
CM_EVENT_AUTHENTICATED
When receieved, create a file in datadir where the name is the ip address
and the conntent is the username.
*/
if (XplStrCaseCmp(command->event, CM_EVENT_AUTHENTICATED) == 0) {
unsigned char buffer[XPL_MAX_PATH + 1];
FILE *addr;
snprintf(buffer, sizeof(buffer), "%s/%07lx", User.config.datadir, command->address);
addr = fopen(buffer, "w");
if (addr) {
fwrite(command->detail.authenticated.user, sizeof(unsigned char), strlen(command->detail.authenticated.user), addr);
fclose(addr);
}
}
return(TRUE);
}
EXPORT int UserVerify(ConnMgrCommand *command, ConnMgrResult *result)
{
/*
CM_EVENT_RELAY
When received, look for a file in datadir with the ip address as the
name, and read the user from the content of the file. Check the time
of the file to see if it has expired.
*/
if (XplStrCaseCmp(command->event, CM_EVENT_RELAY) == 0) {
unsigned char buffer[XPL_MAX_PATH + 1];
struct stat sb;
snprintf(buffer, sizeof(buffer), "%s/%07lx", User.config.datadir, command->address);
if (stat(buffer, &sb) != -1) {
if (sb.st_mtime > time(NULL) - (User.config.timeout * 60)) {
FILE *addr = fopen(buffer, "r");
if (addr) {
int l = fread(result->detail.user, sizeof(unsigned char), MAXEMAILNAMESIZE, addr);
result->detail.user[l] = '\0';
fclose(addr);
return(CM_MODULE_ACCEPT);
}
} else {
unlink(buffer);
}
}
return(CM_MODULE_DENY);
}
return(0);
}
EXPORT BOOL
CMUSERInit(CMModuleRegistrationStruct *registration, unsigned char *datadir)
{
if (UserUnloadOk == TRUE) {
XplSafeWrite(User.threadCount, 0);
User.directoryHandle = (MDBHandle) MsgInit();
if (User.directoryHandle) {
UserUnloadOk = FALSE;
User.logHandle = LoggerOpen("cmuser");
if (User.logHandle == NULL) {
XplConsolePrintf("cmuser: Unable to initialize logging. Logging disabled.\r\n");
}
/* Fill out registration information */
registration->priority = 5;
registration->Shutdown = UserShutdown;
registration->Verify = UserVerify;
registration->Notify = UserNotify;
XplSafeIncrement(User.threadCount);
strcpy(User.config.datadir, datadir);
if (ReadConfiguration()) {
XplThreadID id;
int ccode;
XplBeginThread(&id, Cleanup, (1024 * 32), NULL, ccode);
return(TRUE);
}
} else {
XplConsolePrintf("cmuser: Failed to obtain directory handle\r\n");
}
}
return(FALSE);
}
EXPORT BOOL
UserShutdown(void)
{
XplSafeDecrement(User.threadCount);
if (UserUnloadOk == FALSE) {
UserUnloadOk = TRUE;
/*
Make sure the library users are gone before beginning to
shutdown.
*/
while (XplSafeRead(User.threadCount)) {
XplDelay(33);
}
LoggerClose(User.logHandle);
#if defined(NETWARE) || defined(LIBC)
XplSignalLocalSemaphore(User.shutdownSemaphore); /* The signal will release main() */
XplWaitOnLocalSemaphore(User.shutdownSemaphore); /* The wait will wait until main() is gone */
XplCloseLocalSemaphore(User.shutdownSemaphore);
#endif
}
return(FALSE);
}
static BOOL
ReadConfiguration(void)
{
MDBValueStruct *config;
config = MDBCreateValueStruct(User.directoryHandle, MsgGetServerDN(NULL));
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMUSER, MSGSRV_A_DISABLED, config)) {
if (atol(config->Value[0]) == 1) {
MDBDestroyValueStruct(config);
UserShutdown();
return(FALSE);
}
}
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMUSER, MSGSRV_A_CONFIG_CHANGED, config)) {
User.config.last = atol(config->Value[0]);
MDBFreeValues(config);
} else {
User.config.last = 0;
}
if (MDBRead(MSGSRV_AGENT_CONNMGR "\\" MSGSRV_AGENT_CMUSER, MSGSRV_A_TIMEOUT, config)) {
User.config.timeout = atol(config->Value[0]);
} else {
User.config.timeout = 15;
}
MDBDestroyValueStruct(config);
return(TRUE);
}
static void
Cleanup(void *param)
{
while (!UserUnloadOk) {
int i;
XplDir *dir;
XplDir *dirent;
struct stat sb;
if ((dir = XplOpenDir(User.config.datadir)) != NULL) {
while ((dirent = XplReadDir(dir)) != NULL) {
unsigned char buffer[XPL_MAX_PATH +1 ];
snprintf(buffer, sizeof(buffer), "%s/%s", User.config.datadir, dirent->d_nameDOS);
if ((stat(buffer, &sb) != -1) && (sb.st_mtime < time(NULL) - (User.config.timeout * 60))) {
unlink(buffer);
}
}
XplCloseDir(dir);
}
for (i = 0; i < (User.config.timeout * 60) && !UserUnloadOk; i++) {
XplDelay(1000);
}
}
}
/*
Below are "stock" functions that are basically infrastructure.
However, one might want to add initialization code to main
and takedown code to the signal handler
*/
void
UserShutdownSigHandler(int Signal)
{
int oldtgid = XplSetThreadGroupID(User.tgid);
if (UserUnloadOk == FALSE) {
UserUnloadOk = TRUE;
/*
Make sure the library users are gone before beginning to
shutdown.
*/
while (XplSafeRead(User.threadCount) > 1) {
XplDelay(33);
}
/* Do any required cleanup */
LoggerClose(User.logHandle);
#if defined(NETWARE) || defined(LIBC)
XplSignalLocalSemaphore(User.shutdownSemaphore); /* The signal will release main() */
XplWaitOnLocalSemaphore(User.shutdownSemaphore); /* The wait will wait until main() is gone */
XplCloseLocalSemaphore(User.shutdownSemaphore);
#endif
}
XplSetThreadGroupID(oldtgid);
return;
}
int
_NonAppCheckUnload(void)
{
if (UserUnloadOk == FALSE) {
XplConsolePrintf("\rThis module will automatically be unloaded by the thread that loaded it.\n");
XplConsolePrintf("\rIt does not allow manual unloading.\n");
return(1);
}
return(0);
}
int main(int argc, char *argv[])
{
/* init globals */
User.tgid = XplGetThreadGroupID();
XplRenameThread(GetThreadID(), "Gate Keeper User Module");
XplOpenLocalSemaphore(User.shutdownSemaphore, 0);
XplSignalHandler(UserShutdownSigHandler);
/*
This will "park" the module 'til we get unloaded;
it would not be neccessary to do this on NetWare,
but to prevent from automatically exiting on Unix
we need to keep main around...
*/
XplWaitOnLocalSemaphore(User.shutdownSemaphore);
XplSignalLocalSemaphore(User.shutdownSemaphore);
return(0);
}
@@ -1,61 +0,0 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <ctype.h>
#include <mdb.h>
#include <logger.h>
#include <connmgr.h>
#define PRODUCT_SHORT_NAME "cmuser.nlm"
#define PRODUCT_NAME "Bongo Connection Manager User Authentication Module"
typedef struct _UserGlobal {
/* Handles */
void *logHandle;
MDBHandle directoryHandle;
/* Module State */
time_t timeStamp;
int tgid;
BOOL unloadOK;
XplSemaphore shutdownSemaphore;
XplAtomic threadCount;
struct {
long last;
long timeout;
unsigned char datadir[XPL_MAX_PATH + 1];
} config;
} UserGlobal;
extern UserGlobal User;
/* cmuser.c */
void UserShutdownSigHandler(int Signal);
int _NonAppCheckUnload(void);
EXPORT BOOL CMUSERInit(CMModuleRegistrationStruct *registration, unsigned char *dataDirectory);
EXPORT BOOL UserShutdown(void);
EXPORT BOOL UserNotify(ConnMgrCommand *command);
EXPORT int UserVerify(ConnMgrCommand *command, ConnMgrResult *result);
File diff suppressed because it is too large Load Diff
-42
View File
@@ -1,42 +0,0 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <connmgr.h>
#define CONNMGR_STACK_SPACE (1024 * 32)
#define CONNECTION_TIMEOUT (15 * 60)
/* modules.c */
typedef struct _ModuleStruct {
struct _CMModuleRegistrationStruct registration;
CMInitFunc Init;
XplPluginHandle handle;
struct _ModuleStruct *next;
unsigned char *name;
} ModuleStruct;
void ModulesVerify(ModuleStruct *first, ConnMgrCommand *command, ConnMgrResult *result);
void ModulesNotify(ModuleStruct *first, ConnMgrCommand *command);
ModuleStruct * LoadModules(unsigned char *directory, ModuleStruct *first);
void UnloadModules(ModuleStruct *first);
-212
View File
@@ -1,212 +0,0 @@
/****************************************************************************
* <Novell-copyright>
* Copyright (c) 2001 Novell, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail, you
* may find current contact information at www.novell.com.
* </Novell-copyright>
****************************************************************************/
#include <config.h>
#include <xpl.h>
#include <bongoutil.h>
#include <msgapi.h>
#include "connmgrp.h"
void
ModulesVerify(ModuleStruct *first, ConnMgrCommand *command, ConnMgrResult *result)
{
ModuleStruct *module = first;
result->result = command->detail.policy.default_result;
while (module) {
if (module->registration.Verify) {
int rc = module->registration.Verify(command, result);
if (rc & CM_MODULE_DENY) {
if (rc & CM_MODULE_PERMANENT) {
result->result = CM_RESULT_DENY_PERMANENT;
} else {
result->result = CM_RESULT_DENY_TEMPORARY;
}
}
if (rc & CM_MODULE_FORCE) {
if (rc & CM_MODULE_ACCEPT) {
result->result = CM_RESULT_ALLOWED;
}
return;
}
}
module = module->next;
}
}
void
ModulesNotify(ModuleStruct *first, ConnMgrCommand *command)
{
ModuleStruct *module = first;
while (module) {
if (module->registration.Notify) {
module->registration.Notify(command);
}
module = module->next;
}
}
ModuleStruct *
LoadModules(unsigned char *directory, ModuleStruct *first)
{
XplDir *dir;
XplDir *dirent;
ModuleStruct *result = first;
XplMakeDir(XPL_DEFAULT_DBF_DIR "//connmgr");
if ((dir = XplOpenDir(directory)) != NULL) {
while ((dirent = XplReadDir(dir)) != NULL) {
unsigned char path[XPL_MAX_PATH +1 ];
unsigned char name[XPL_MAX_PATH + 1];
unsigned char *modulename = dirent->d_nameDOS;
ModuleStruct *new = MemMalloc(sizeof(ModuleStruct));
unsigned char datadir[XPL_MAX_PATH + 1];
memset(new, 0, sizeof(ModuleStruct));
if (strlen(modulename) > 3) {
snprintf(path, sizeof(path), "%s/lib%s", directory, modulename);
new->handle = XplLoadDLL(path);
if (!new->handle) {
snprintf(path, sizeof(path), "%s/%s", directory, modulename);
new->handle = XplLoadDLL(path);
}
if (new->handle) {
unsigned char *ptr;
/* Initialize the module */
if (XplStrNCaseCmp(modulename, "lib", 3) == 0) {
BongoStrNCpy(name, modulename + 3, sizeof(name) - strlen("Init"));
} else {
BongoStrNCpy(name, modulename, sizeof(name) - strlen("Init"));
}
ptr = strrchr(name, '.');
if (ptr) {
*ptr = '\0';
}
/* Setup the work directory for the module */
ptr = name;
while (*ptr) {
*ptr = tolower(*ptr);
ptr++;
}
sprintf(datadir, "%s/connmgr/%s", XPL_DEFAULT_DBF_DIR, name);
XplMakeDir(datadir);
ptr = name;
while (*ptr) {
*ptr = toupper(*ptr);
ptr++;
}
strcat(name, "Init");
new->Init = (CMInitFunc)XplGetDLLFunction(modulename, name, new->handle);
name[strlen(name) - 4] = '\0';
#if 0
} else {
/* dlerror() is much more useful when dlopen fails than errno is */
unsigned char *err = dlerror();
if (err) {
XplConsolePrintf("connmgr: XplLoadDLL failed: %s\n", err);
}
XplConsolePrintf("connmgr: could not load module %s/%s, errno: %d %s\n", directory, modulename, errno, strerror(errno));
#endif
}
}
if (new->Init && new->Init(&(new->registration), datadir)) {
new->name = MemStrdup(name);
#if VERBOSE
XplConsolePrintf("connmgr: loaded module: %s\n", new->name);
#endif
if (!result) {
result = new;
} else if (result->registration.priority > new->registration.priority) {
new->next = result;
result = new;
} else {
ModuleStruct *n = result;
/* Find a spot for it */
while (n && n->next) {
if (n->next->registration.priority > new->registration.priority) {
new->next = n->next;
n->next = new;
n = NULL;
}
if (n) {
n = n->next;
}
}
if (n) {
n->next = new;
}
}
} else {
MemFree(new);
}
}
XplCloseDir(dir);
}
return(result);
}
void
UnloadModules(ModuleStruct *first)
{
ModuleStruct *module = first;
while (module) {
ModuleStruct *next = module->next;
if (module->registration.Shutdown) {
module->registration.Shutdown();
}
if (module->handle && module->name) {
XplUnloadDLL(module->name, module->handle);
MemFree(module->name);
}
MemFree(module);
module = next;
}
}
File diff suppressed because it is too large Load Diff