-- more old and uneeded code
This commit is contained in:
-252
@@ -1,252 +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>
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef MDB_H
|
||||
#define MDB_H
|
||||
|
||||
/* Generic */
|
||||
#define MDB_CURRENT_API_VERSION 1
|
||||
#define MDB_COMPATIBLE_TO_API 1
|
||||
#define MDB_MAX_API_DESCRIPTION_CHARS 256
|
||||
|
||||
/* Length definitions */
|
||||
#define MDB_MAX_OBJECT_CHARS 256
|
||||
#define MDB_MAX_UTF8_OBJECT_CHARS 768
|
||||
#define MDB_MAX_ATTRIBUTE_VALUE_CHARS 10240
|
||||
#define MDB_MAX_ATTRIBUTE_VALUE_UTF8_CHARS (10240*3)
|
||||
#define MDB_MAX_TREE_CHARS 32
|
||||
#define MDB_MAX_ATTRIBUTE_CHARS 32
|
||||
|
||||
/* Attribute types */
|
||||
#define MDB_ATTR_SYN_STRING 'S'
|
||||
#define MDB_ATTR_SYN_DIST_NAME 'D'
|
||||
#define MDB_ATTR_SYN_BOOL 'B'
|
||||
#define MDB_ATTR_SYN_BINARY 'O'
|
||||
|
||||
/* Little helpers */
|
||||
#define MDB_IS_MDB_API_COMPATIBLE(Handle) (MDBGetAPIVersion(TRUE, NULL, Handle)<=MDB_CURRENT_API_VERSION)
|
||||
#define MDB_CURRENT_CONTEXT "."
|
||||
#define MDBGetLastError(ValueStruct) (ValueStruct->ErrNo)
|
||||
|
||||
/* Depth */
|
||||
#define MDB_SCOPE_BASE 0
|
||||
#define MDB_SCOPE_ONELEVEL 1
|
||||
#define MDB_SCOPE_INFINITE 2
|
||||
|
||||
/* Used for MDBCreateObject */
|
||||
#ifndef __cplusplus
|
||||
#define MDBAddStringAttribute(AttrName, AttrValue, AttrStruct, DataStruct) { unsigned char Temp[MDB_MAX_UTF8_OBJECT_CHARS]; Temp[0]=MDB_ATTR_SYN_STRING; strcpy(Temp+1, (unsigned char *)((AttrName))); MDBAddValue(Temp, (AttrStruct)); MDBAddValue((const unsigned char *)((AttrValue)), (DataStruct)); }
|
||||
#define MDBAddDNAttribute(AttrName, AttrValue, AttrStruct, DataStruct) { unsigned char Temp[MDB_MAX_UTF8_OBJECT_CHARS]; Temp[0]=MDB_ATTR_SYN_DIST_NAME; strcpy(Temp+1, (unsigned char *)((AttrName))); MDBAddValue(Temp, (AttrStruct)); MDBAddValue((const unsigned char *)((AttrValue)), (DataStruct)); }
|
||||
#endif
|
||||
|
||||
#if !defined(MDB_INTERNAL)
|
||||
typedef void * MDBHandle;
|
||||
typedef void MDBEnumStruct;
|
||||
|
||||
typedef struct {
|
||||
unsigned char **Value;
|
||||
unsigned long Used;
|
||||
unsigned long ErrNo;
|
||||
struct _MDBInterfaceStruct *Interface;
|
||||
} MDBValueStruct;
|
||||
#endif
|
||||
|
||||
typedef struct _MDBInterfaceStruct {
|
||||
BOOL (* MDBGetServerInfo)(unsigned char *HostDN, unsigned char *HostTree, MDBValueStruct *V);
|
||||
MDBHandle (* MDBAuthenticate)(const unsigned char *Object, const unsigned char *Password, const unsigned char *Arguments);
|
||||
BOOL (* MDBRelease)(MDBHandle Handle);
|
||||
MDBValueStruct *(* MDBCreateValueStruct)(MDBHandle Handle, const unsigned char *Context);
|
||||
BOOL (* MDBDestroyValueStruct)(MDBValueStruct *V);
|
||||
MDBValueStruct *(* MDBShareContext)(MDBValueStruct *VOld);
|
||||
BOOL (* MDBSetValueStructContext)(const unsigned char *Context, MDBValueStruct *V);
|
||||
MDBEnumStruct *(* MDBCreateEnumStruct)(MDBValueStruct *V);
|
||||
BOOL (* MDBDestroyEnumStruct)(MDBEnumStruct *E, MDBValueStruct *V);
|
||||
BOOL (* MDBAddValue)(const unsigned char *Value, MDBValueStruct *V);
|
||||
BOOL (* MDBFreeValue)(unsigned long Index, MDBValueStruct *V);
|
||||
BOOL (* MDBFreeValues)(MDBValueStruct *V);
|
||||
long (* MDBRead)(const unsigned char *Object, const unsigned char *Attribute, MDBValueStruct *V);
|
||||
const unsigned char *(* MDBReadEx)(const unsigned char *Object, const unsigned char *Attribute, MDBEnumStruct *E, MDBValueStruct *V);
|
||||
long (* MDBReadDN)(const unsigned char *Object, const unsigned char *Attribute, MDBValueStruct *V);
|
||||
BOOL (* MDBWriteTyped)(const unsigned char *Object, const unsigned char *Attribute, const int AttrType, MDBValueStruct *V);
|
||||
BOOL (* MDBWrite)(const unsigned char *Object, const unsigned char *Attribute, MDBValueStruct *V);
|
||||
BOOL (* MDBWriteDN)(const unsigned char *Object, const unsigned char *Attribute, MDBValueStruct *V);
|
||||
BOOL (* MDBClear)(const unsigned char *Object, const unsigned char *Attribute, MDBValueStruct *V);
|
||||
BOOL (* MDBAdd)(const unsigned char *Object, const unsigned char *Attribute, const unsigned char *Value, MDBValueStruct *V);
|
||||
BOOL (* MDBAddDN)(const unsigned char *Object, const unsigned char *Attribute, const unsigned char *Value, MDBValueStruct *V);
|
||||
BOOL (* MDBRemove)(const unsigned char *Object, const unsigned char *Attribute, const unsigned char *Value, MDBValueStruct *V);
|
||||
BOOL (* MDBRemoveDN)(const unsigned char *Object, const unsigned char *Attribute, const unsigned char *Value, MDBValueStruct *V);
|
||||
BOOL (* MDBIsObject)(const unsigned char *Object, MDBValueStruct *V);
|
||||
BOOL (* MDBGetObjectDetails)(const unsigned char *Object, unsigned char *Type, unsigned char *RDN, unsigned char *DN, MDBValueStruct *V);
|
||||
BOOL (* MDBGetObjectDetailsEx)(const unsigned char *Object, MDBValueStruct *Types, unsigned char *RDN, unsigned char *DN, MDBValueStruct *V);
|
||||
BOOL (* MDBVerifyPassword)(const unsigned char *Object, const unsigned char *Password, MDBValueStruct *V);
|
||||
BOOL (* MDBVerifyPasswordEx)(const unsigned char *Object, const unsigned char *Password, MDBValueStruct *V); /* Better error reporting */
|
||||
BOOL (* MDBChangePassword)(const unsigned char *Object, const unsigned char *OldPassword, const unsigned char *NewPassword, MDBValueStruct *V);
|
||||
BOOL (* MDBChangePasswordEx)(const unsigned char *Object, const unsigned char *OldPassword, const unsigned char *NewPassword, MDBValueStruct *V);
|
||||
long (* MDBEnumerateObjects)(const unsigned char *Container, const unsigned char *Type, const unsigned char *Pattern, MDBValueStruct *V);
|
||||
const unsigned char *(* MDBEnumerateObjectsEx)(const unsigned char *Container, const unsigned char *Type, const unsigned char *Pattern, unsigned long Flags, MDBEnumStruct *E, MDBValueStruct *V);
|
||||
BOOL (* MDBAddAddressRestriction)(const unsigned char *Object, const unsigned char *Server, MDBValueStruct *V);
|
||||
const unsigned char *(* MDBEnumerateAttributesEx)(const unsigned char *Object, MDBEnumStruct *E, MDBValueStruct *V);
|
||||
BOOL (* MDBCreateObject)(const unsigned char *Object, const unsigned char *Class, MDBValueStruct *Attribute, MDBValueStruct *Data, MDBValueStruct *V);
|
||||
BOOL (* MDBDeleteObject)(const unsigned char *Object, BOOL Recursive, MDBValueStruct *V);
|
||||
BOOL (* MDBRenameObject)(const unsigned char *ObjectOld, const unsigned char *ObjectNew, MDBValueStruct *V);
|
||||
BOOL (* MDBDefineAttribute)(const unsigned char *Attribute, const unsigned char *ASN1, unsigned long Type, BOOL SingleValue, BOOL ImmediateSync, BOOL Public, MDBValueStruct *V);
|
||||
BOOL (* MDBUndefineAttribute)(const unsigned char *Attribute, MDBValueStruct *V);
|
||||
BOOL (* MDBDefineClass)(const unsigned char *Class, const unsigned char *ASN1, BOOL Container, MDBValueStruct *Superclass, MDBValueStruct *Containment, MDBValueStruct *Naming, MDBValueStruct *Mandatory, MDBValueStruct *Optional, MDBValueStruct *V);
|
||||
BOOL (* MDBAddAttribute)(const unsigned char *Attribute, const unsigned char *Class, MDBValueStruct *V);
|
||||
BOOL (* MDBUndefineClass)(const unsigned char *Class, MDBValueStruct *V);
|
||||
BOOL (* MDBListContainableClasses)(const unsigned char *Container, MDBValueStruct *V);
|
||||
const unsigned char *(* MDBListContainableClassesEx)(const unsigned char *Container, MDBEnumStruct *E, MDBValueStruct *V);
|
||||
BOOL (* MDBGrantObjectRights)(const unsigned char *Object, const unsigned char *TrusteeDN, BOOL Read, BOOL Write, BOOL Delete, BOOL Rename, BOOL Admin, MDBValueStruct *V);
|
||||
BOOL (* MDBGrantAttributeRights)(const unsigned char *Object, const unsigned char *Attribute, const unsigned char *TrusteeDN, BOOL Read, BOOL Write, BOOL Admin, MDBValueStruct *V);
|
||||
char *(* MDBGetBaseDN)(MDBValueStruct *V);
|
||||
BOOL (* MDBCreateAlias)(const unsigned char *Alias, const unsigned char *AliasedObjectDn, MDBValueStruct *V);
|
||||
BOOL (* MDBFindObjects)(const unsigned char *Container,
|
||||
MDBValueStruct *Types,
|
||||
const unsigned char *Pattern,
|
||||
MDBValueStruct *Attributes,
|
||||
int depth,
|
||||
int max,
|
||||
MDBValueStruct *V);
|
||||
BOOL (* Reserved3)(void);
|
||||
BOOL (* Reserved4)(void);
|
||||
BOOL (* Reserved5)(void);
|
||||
BOOL (* Reserved6)(void);
|
||||
BOOL (* Reserved7)(void);
|
||||
BOOL (* Reserved8)(void);
|
||||
BOOL (* Reserved9)(void);
|
||||
BOOL (* Reserved10)(void);
|
||||
BOOL (* Reserved11)(void);
|
||||
BOOL (* Reserved12)(void);
|
||||
BOOL (* Reserved13)(void);
|
||||
BOOL (* Reserved14)(void);
|
||||
BOOL (* Reserved15)(void);
|
||||
BOOL (* Reserved16)(void);
|
||||
BOOL (* Reserved17)(void);
|
||||
BOOL (* Reserved18)(void);
|
||||
BOOL (* Reserved19)(void);
|
||||
} MDBInterfaceStruct;
|
||||
|
||||
typedef struct {
|
||||
unsigned char Error[128];
|
||||
MDBInterfaceStruct Interface;
|
||||
const unsigned char *Arguments;
|
||||
} MDBDriverInitStruct;
|
||||
|
||||
typedef BOOL (* MDBDriverInitFunc)(MDBDriverInitStruct *Init);
|
||||
typedef BOOL (* MDBDriverShutdownFunc)(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Prototypes for generic things */
|
||||
EXPORT BOOL MDBInit(void);
|
||||
EXPORT BOOL MDBShutdown(void);
|
||||
|
||||
EXPORT int MDBGetAPIVersion(BOOL WantCompatibleVersion, unsigned char *Description, MDBHandle Context);
|
||||
EXPORT BOOL MDBGetServerInfo(unsigned char *HostDN, unsigned char *HostTree, MDBValueStruct *V); /* Deprecated */
|
||||
EXPORT char *MDBGetBaseDN(MDBValueStruct *V);
|
||||
|
||||
/* Authentication */
|
||||
EXPORT MDBHandle MDBAuthenticate(const unsigned char *Module, const unsigned char *Object, const unsigned char *Password);
|
||||
EXPORT BOOL MDBRelease(MDBHandle Context);
|
||||
|
||||
/* ValueStruct initialization & manipulation */
|
||||
EXPORT MDBValueStruct *MDBCreateValueStruct(MDBHandle Handle, const unsigned char *Context);
|
||||
EXPORT BOOL MDBDestroyValueStruct(MDBValueStruct *V);
|
||||
EXPORT MDBValueStruct *MDBShareContext(MDBValueStruct *VOld);
|
||||
EXPORT BOOL MDBSetValueStructContext(const unsigned char *Context, MDBValueStruct *V);
|
||||
|
||||
EXPORT MDBEnumStruct *MDBCreateEnumStruct(MDBValueStruct *V);
|
||||
EXPORT BOOL MDBDestroyEnumStruct(MDBEnumStruct *E, MDBValueStruct *V);
|
||||
|
||||
EXPORT BOOL MDBAddValue(const unsigned char *Value, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBFreeValue(unsigned long Index, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBFreeValues(MDBValueStruct *V);
|
||||
|
||||
|
||||
/* Attribute operations */
|
||||
EXPORT long MDBRead(const unsigned char *Object, const unsigned char *Attribute, MDBValueStruct *V);
|
||||
EXPORT const unsigned char *MDBReadEx(const unsigned char *Object, const unsigned char *Attribute, MDBEnumStruct *E, MDBValueStruct *V);
|
||||
EXPORT long MDBReadDN(const unsigned char *Object, const unsigned char *Attribute, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBWriteTyped(const unsigned char *Object, const unsigned char *Attribute, const int AttrType, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBWrite(const unsigned char *Object, const unsigned char *Attribute, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBWriteDN(const unsigned char *Object, const unsigned char *Attribute, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBClear(const unsigned char *Object, const unsigned char *Attribute, MDBValueStruct *V);
|
||||
|
||||
/* Advanced attribute operations */
|
||||
EXPORT BOOL MDBAdd(const unsigned char *Object, const unsigned char *Attribute, const unsigned char *Value, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBAddDN(const unsigned char *Object, const unsigned char *Attribute, const unsigned char *Value, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBRemove(const unsigned char *Object, const unsigned char *Attribute, const unsigned char *Value, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBRemoveDN(const unsigned char *Object, const unsigned char *Attribute, const unsigned char *Value, MDBValueStruct *V);
|
||||
|
||||
/* Object operations */
|
||||
EXPORT BOOL MDBIsObject(const unsigned char *Object, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBGetObjectDetails(const unsigned char *Object, unsigned char *Type, unsigned char *RDN, unsigned char *DN, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBGetObjectDetailsEx(const unsigned char *Object, MDBValueStruct *Types, unsigned char *RDN, unsigned char *DN, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBVerifyPassword(const unsigned char *Object, const unsigned char *Password, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBVerifyPasswordEx(const unsigned char *Object, const unsigned char *Password, MDBValueStruct *V); /* Better error reporting */
|
||||
EXPORT BOOL MDBChangePassword(const unsigned char *Object, const unsigned char *OldPassword, const unsigned char *NewPassword, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBChangePasswordEx(const unsigned char *Object, const unsigned char *OldPassword, const unsigned char *NewPassword, MDBValueStruct *V);
|
||||
EXPORT long MDBEnumerateObjects(const unsigned char *Container, const unsigned char *Type, const unsigned char *Pattern, MDBValueStruct *V);
|
||||
EXPORT const unsigned char *MDBEnumerateObjectsEx(const unsigned char *Container, const unsigned char *Type, const unsigned char *Pattern, unsigned long Flags, MDBEnumStruct *E, MDBValueStruct *V);
|
||||
|
||||
EXPORT BOOL MDBFindObjects(const unsigned char *Container,
|
||||
MDBValueStruct *Types,
|
||||
const unsigned char *Pattern,
|
||||
MDBValueStruct *Attributes,
|
||||
int depth,
|
||||
int max,
|
||||
MDBValueStruct *V);
|
||||
|
||||
|
||||
/* Advanced Object operations */
|
||||
EXPORT const unsigned char *MDBEnumerateAttributesEx(const unsigned char *Object, MDBEnumStruct *E, MDBValueStruct *V);
|
||||
|
||||
/* Object manipulation */
|
||||
EXPORT BOOL MDBCreateAlias(const unsigned char *Alias, const unsigned char *AliasedObjectDn, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBCreateObject(const unsigned char *Object, const unsigned char *Class, MDBValueStruct *Attribute, MDBValueStruct *Data, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBDeleteObject(const unsigned char *Object, BOOL Recursive, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBRenameObject(const unsigned char *ObjectOld, const unsigned char *ObjectNew, MDBValueStruct *V);
|
||||
|
||||
/* Schema manipulation */
|
||||
EXPORT BOOL MDBDefineAttribute(const unsigned char *Attribute, const unsigned char *ASN1, unsigned long Type, BOOL SingleValue, BOOL ImmediateSync, BOOL Public, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBUndefineAttribute(const unsigned char *Attribute, MDBValueStruct *V);
|
||||
|
||||
EXPORT BOOL MDBDefineClass(const unsigned char *Class, const unsigned char *ASN1, BOOL Container, MDBValueStruct *Superclass, MDBValueStruct *Containment, MDBValueStruct *Naming, MDBValueStruct *Mandatory, MDBValueStruct *Optional, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBAddAttribute(const unsigned char *Attribute, const unsigned char *Class, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBUndefineClass(const unsigned char *Class, MDBValueStruct *V);
|
||||
|
||||
EXPORT BOOL MDBListContainableClasses(const unsigned char *Container, MDBValueStruct *V);
|
||||
EXPORT const unsigned char *MDBListContainableClassesEx(const unsigned char *Container, MDBEnumStruct *E, MDBValueStruct *V);
|
||||
|
||||
/* Object rights */
|
||||
EXPORT BOOL MDBGrantObjectRights(const unsigned char *Object, const unsigned char *TrusteeDN, BOOL Read, BOOL Write, BOOL Delete, BOOL Rename, BOOL Admin, MDBValueStruct *V);
|
||||
EXPORT BOOL MDBGrantAttributeRights(const unsigned char *Object, const unsigned char *Attribute, const unsigned char *TrusteeDN, BOOL Read, BOOL Write, BOOL Admin, MDBValueStruct *V);
|
||||
|
||||
/* Debug helper */
|
||||
EXPORT BOOL MDBDumpValueStruct(MDBValueStruct *V);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* MDB_H */
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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=?;"
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user