Compare commits
141 Commits
remove-mdb
..
0.3.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 629034815d | |||
| 09405d9e83 | |||
| 2fd6ea3402 | |||
| 924bff9489 | |||
| 068c0aa700 | |||
| 09a199e94b | |||
| 6cccc8a82b | |||
| 3de6d55404 | |||
| 5b672baffd | |||
| 542e5aab8d | |||
| 113dbce285 | |||
| 4d1e47dcad | |||
| 60073c01ec | |||
| 233fee2c29 | |||
| 0223238bb8 | |||
| 238fa58cdc | |||
| 81d9301e0d | |||
| afc9a21829 | |||
| 85bbccebb7 | |||
| d337c3d486 | |||
| 39d68be761 | |||
| 88f5d2eafd | |||
| 1c9d457e50 | |||
| e7e3999b8a | |||
| 29743facc4 | |||
| 204abc232d | |||
| bf0efbcb3e | |||
| 2d889da6ba | |||
| 54c24172d7 | |||
| 8bd7e42e98 | |||
| 98359611ea | |||
| 55a32cd4e7 | |||
| 701525175d | |||
| 51a8b612db | |||
| 35526da57b | |||
| 4252a2496d | |||
| f9be78b58a | |||
| 5b388b76f4 | |||
| 22741b815e | |||
| 1fc05b93c7 | |||
| e13eeb8e3a | |||
| cc9178ccd6 | |||
| 698cda51d7 | |||
| a05bf36889 | |||
| aa8cdd6ab0 | |||
| c7ad8f8df2 | |||
| 6ce6bd184f | |||
| 95aa64d386 | |||
| 3b1507bc7b | |||
| 2d37fb62db | |||
| 5eb4f67e99 | |||
| cb74eae670 | |||
| 9c52b028ae | |||
| 785476ba0f | |||
| da1c898909 | |||
| f37e40d9aa | |||
| c8f9670d70 | |||
| 50617cbc10 | |||
| a289b56729 | |||
| 8ed1e89fe1 | |||
| ce0211995d | |||
| 05e8852440 | |||
| deb78542ce | |||
| cf114834d9 | |||
| 5878c5116e | |||
| 18441d2231 | |||
| f5b85d0515 | |||
| fbde82b235 | |||
| 168af364e8 | |||
| bbdfc1d6e3 | |||
| b901178411 | |||
| cc2146f14b | |||
| d81014a674 | |||
| 38b5be0c8d | |||
| b186eca218 | |||
| 9010d916ab | |||
| 79673b9d1b | |||
| 8d72093cd6 | |||
| 012f72a874 | |||
| 97eb5c1356 | |||
| 5f533850e0 | |||
| 6a1aa7b881 | |||
| 1d3b79c1e2 | |||
| c8d8cdaf9a | |||
| bd5e101f5f | |||
| 968577911d | |||
| a913e011c4 | |||
| d3ddf20189 | |||
| fb042f0ac5 | |||
| 1764749c58 | |||
| ba713d88e0 | |||
| 17eefc5a79 | |||
| 305477029b | |||
| 78d49fd7a8 | |||
| 1fd6ff820c | |||
| 9370449931 | |||
| 1de36a6c67 | |||
| 67c91f6090 | |||
| c2fbb8f61e | |||
| 4b0476a596 | |||
| ca45b1417f | |||
| 8d1f10ad98 | |||
| 277769e69d | |||
| 8ea2a88dcc | |||
| 41ed4dedc7 | |||
| ace52e75c4 | |||
| a30612eac7 | |||
| 25f1a34250 | |||
| 2bb2877866 | |||
| 9fb528dd0e | |||
| f9f0282aa0 | |||
| af379dd929 | |||
| 2e706f5349 | |||
| 9816a936e2 | |||
| 4973b31a27 | |||
| 2963a454c7 | |||
| 8559b8bdb8 | |||
| 58564815a6 | |||
| 65a20db8f9 | |||
| f4b73dc601 | |||
| a7af92dcc5 | |||
| ff3ec35d27 | |||
| 68e73006b5 | |||
| 01d7e89470 | |||
| 60fdae4c69 | |||
| e355a6fb18 | |||
| 1641302e0d | |||
| d4d0629203 | |||
| 1a59960bd9 | |||
| 087ab3dcb5 | |||
| d59c6e89ff | |||
| afa1db57b0 | |||
| e52ab32f26 | |||
| 145b53ca2c | |||
| b6001cdb0b | |||
| 014f94da0d | |||
| 1e573957ef | |||
| 8826f58c02 | |||
| 741331701e | |||
| 9def52095f | |||
| 26471cf430 |
+2
-9
@@ -89,10 +89,7 @@ clean: clean-recursive
|
||||
# disabled agents
|
||||
# src/agents/mailprox
|
||||
# src/agents/rules
|
||||
|
||||
# src/libs/mdb
|
||||
# src/libs/mdb-file
|
||||
# src/libs/mdb-xldap
|
||||
# src/agents/calcmd
|
||||
|
||||
include_subdirs = \
|
||||
include \
|
||||
@@ -118,7 +115,6 @@ include_subdirs = \
|
||||
src/agents/alarm \
|
||||
src/agents/antispam \
|
||||
src/agents/avirus \
|
||||
src/agents/calcmd \
|
||||
src/agents/collector \
|
||||
src/agents/generic \
|
||||
src/agents/imap \
|
||||
@@ -155,9 +151,6 @@ include src/libs/bongoutil/tests/Bongo.rules
|
||||
include src/libs/connio/Bongo.rules
|
||||
include src/libs/connio/tests/Bongo.rules
|
||||
include src/libs/json/Bongo.rules
|
||||
#include src/libs/mdb/Bongo.rules
|
||||
#include src/libs/mdb-file/Bongo.rules
|
||||
#include src/libs/mdb-xldap/Bongo.rules
|
||||
include src/libs/logger/Bongo.rules
|
||||
include src/libs/streamio/Bongo.rules
|
||||
include src/libs/streamio/codec/Bongo.rules
|
||||
@@ -172,7 +165,7 @@ include src/libs/python/libbongo/Bongo.rules
|
||||
include src/agents/alarm/Bongo.rules
|
||||
include src/agents/antispam/Bongo.rules
|
||||
include src/agents/avirus/Bongo.rules
|
||||
include src/agents/calcmd/Bongo.rules
|
||||
#include src/agents/calcmd/Bongo.rules
|
||||
include src/agents/collector/Bongo.rules
|
||||
include src/agents/generic/Bongo.rules
|
||||
include src/agents/imap/Bongo.rules
|
||||
|
||||
+9
-12
@@ -347,10 +347,16 @@ fi
|
||||
|
||||
for arg in $@; do
|
||||
case $arg in
|
||||
--with-clucene=*import*)
|
||||
rm -f import/clucene/NO-AUTO-GEN
|
||||
;;
|
||||
--with-clucene=*)
|
||||
touch import/clucene/NO-AUTO-GEN
|
||||
echo "Flagging import/clucene as no auto-gen as source is external"
|
||||
;;
|
||||
--with-sqlite3=*import*)
|
||||
rm -f import/sqlite3/NO-AUTO-GEN
|
||||
;;
|
||||
--with-sqlite3=*)
|
||||
touch import/sqlite3/NO-AUTO-GEN
|
||||
echo "Flagging import/sqlite3 as no auto-gen as source is external"
|
||||
@@ -450,18 +456,9 @@ done
|
||||
rm -f import/clucene/NO-AUTO-GEN
|
||||
rm -f import/sqlite3/NO-AUTO-GEN
|
||||
|
||||
SVNREV="`svnversion . 2>/dev/null`"
|
||||
if test x$SVNREV = x; then
|
||||
echo Unable to discern build version
|
||||
echo \#define BONGO_BUILD_BRANCH \"unknown\" > ./include/bongo-buildinfo.h
|
||||
echo \#define BONGO_BUILD_VSTR \"\" >> ./include/bongo-buildinfo.h
|
||||
echo \#define BONGO_BUILD_VER \"0\" >> ./include/bongo-buildinfo.h
|
||||
else
|
||||
echo SVN Rev at $SVNREV
|
||||
echo \#define BONGO_BUILD_BRANCH \"trunk\" > ./include/bongo-buildinfo.h
|
||||
echo \#define BONGO_BUILD_VSTR \"r\" >> ./include/bongo-buildinfo.h
|
||||
echo \#define BONGO_BUILD_VER \"$SVNREV\" >> ./include/bongo-buildinfo.h
|
||||
fi
|
||||
echo \#define BONGO_BUILD_BRANCH \"0.3\" > ./include/bongo-buildinfo.h
|
||||
echo \#define BONGO_BUILD_VSTR \"v\" >> ./include/bongo-buildinfo.h
|
||||
echo \#define BONGO_BUILD_VER \"0\" >> ./include/bongo-buildinfo.h
|
||||
|
||||
conf_flags="--enable-maintainer-mode"
|
||||
|
||||
|
||||
+32
-15
@@ -3,7 +3,7 @@ AC_PREREQ(2.52)
|
||||
|
||||
AC_INIT(src/libs/msgapi/msgapi.c)
|
||||
|
||||
AM_INIT_AUTOMAKE(bongo, 0.1.0)
|
||||
AM_INIT_AUTOMAKE(bongo, 0.3.1)
|
||||
|
||||
# this space is here to trick autogen.sh
|
||||
AM_GNU_GETTEXT([external])
|
||||
@@ -329,11 +329,11 @@ if test "x$PKG_CONFIG" = "xno"; then
|
||||
fi
|
||||
|
||||
have_check=no
|
||||
info_check="Not installed. Unit tests will not be run."
|
||||
info_check="No. Unit tests will not be run."
|
||||
AM_PATH_CHECK(0.9.0,
|
||||
[
|
||||
have_check=yes
|
||||
info_check="Installed. Unit tests may be run."
|
||||
info_check="Yes."
|
||||
AC_DEFINE(BONGO_HAVE_CHECK, [], [Controls how tests that depend on check compile.])
|
||||
],
|
||||
[
|
||||
@@ -384,8 +384,10 @@ import lxml.etree as et
|
||||
if $PYTHON -c "$prog" 1>&AC_FD_CC 2>&AC_FD_CC
|
||||
then
|
||||
AC_MSG_RESULT([Found ElementTree lxml])
|
||||
info_lxml="Yes."
|
||||
else
|
||||
AC_MSG_ERROR([Couldn't find ElementTree lxml module for python])
|
||||
AC_MSG_RESULT([Couldn't find ElementTree lxml module for python])
|
||||
info_lxml="No. CalDAV runtime requires this library"
|
||||
fi
|
||||
|
||||
LIBS_save="$LIBS"
|
||||
@@ -619,9 +621,19 @@ fi
|
||||
# import libraries
|
||||
|
||||
ACX_CLUCENE()
|
||||
if test "x$CLUCENE_LIBS" = "x"; then
|
||||
case "x$CLUCENE_LIBS" in
|
||||
x)
|
||||
info_clucene="import"
|
||||
;;
|
||||
*import*)
|
||||
info_clucene="import"
|
||||
;;
|
||||
*)
|
||||
info_clucene="system"
|
||||
;;
|
||||
esac
|
||||
if test "x$info_clucene" = "ximport"; then
|
||||
AC_MSG_RESULT(Using imported CLucene)
|
||||
info_clucene="import"
|
||||
AC_CONFIG_SUBDIRS([import/clucene])
|
||||
AC_SUBST(CLUCENE_BONGO_API, "1")
|
||||
AC_SUBST(CLUCENE_LIBS, "\$(top_srcdir)/import/clucene/src/libclucene.la")
|
||||
@@ -631,19 +643,27 @@ else
|
||||
AC_MSG_ERROR([Compiling against CLucene system libraries on x86_64 is known to be buggy. Recommend you use --with-clucene=import/clucene])
|
||||
fi
|
||||
AC_MSG_RESULT(Using system CLucene)
|
||||
info_clucene="system"
|
||||
fi
|
||||
|
||||
AC_CHECK_SQLITE3()
|
||||
if test "x$SQLITE_LIBS" = "x"; then
|
||||
case "x$SQLITE_LIBS" in
|
||||
x)
|
||||
info_sqlite="import"
|
||||
;;
|
||||
*import*)
|
||||
info_sqlite="import"
|
||||
;;
|
||||
*)
|
||||
info_sqlite="system"
|
||||
;;
|
||||
esac
|
||||
if test "x$info_sqlite" = "ximport"; then
|
||||
AC_MSG_RESULT(Using imported SQLite)
|
||||
info_sqlite="import"
|
||||
AC_CONFIG_SUBDIRS([import/sqlite3])
|
||||
AC_SUBST(SQLITE_CFLAGS, "-I\$(top_srcdir)/import/sqlite3")
|
||||
AC_SUBST(SQLITE_LIBS, "\$(top_srcdir)/import/sqlite3/libbongosqlite3.la")
|
||||
else
|
||||
AC_MSG_RESULT(Using system SQLite)
|
||||
info_sqlite="system"
|
||||
fi
|
||||
|
||||
info_libical="import"
|
||||
@@ -662,10 +682,7 @@ ac_configure_args="$ac_configure_args --enable-threadsafe --enable-cross-thread-
|
||||
# src/agents/mailprox/Makefile
|
||||
# src/agents/rules/Makefile
|
||||
# src/agents/pluspack/Makefile
|
||||
|
||||
#src/libs/mdb/Makefile
|
||||
#src/libs/mdb-file/Makefile
|
||||
#src/libs/mdb-xldap/Makefile
|
||||
# src/agents/calcmd/Makefile
|
||||
|
||||
AC_OUTPUT([
|
||||
Makefile
|
||||
@@ -684,7 +701,6 @@ init/svc-bongo.solaris-smf
|
||||
src/agents/alarm/Makefile
|
||||
src/agents/antispam/Makefile
|
||||
src/agents/avirus/Makefile
|
||||
src/agents/calcmd/Makefile
|
||||
src/agents/collector/Makefile
|
||||
src/agents/generic/Makefile
|
||||
src/agents/imap/Makefile
|
||||
@@ -751,4 +767,5 @@ Optional libraries:
|
||||
LDAP: ${info_ldap}
|
||||
ODBC: ${info_odbc}
|
||||
Check: ${info_check}
|
||||
lxml: ${info_lxml}
|
||||
])
|
||||
|
||||
+4
-1
@@ -36,8 +36,10 @@ EXPORT BOOL MsgAuthVerifyPassword(const char *user, const char *password);
|
||||
EXPORT int MsgAuthChangePassword(const char *user, const char *oldpassword, const char *newpassword);
|
||||
EXPORT int MsgAuthSetPassword(const char *user, const char *password);
|
||||
EXPORT int MsgAuthGetUserStore(const char *user, struct sockaddr_in *store);
|
||||
EXPORT int MsgAuthInitDB(void);
|
||||
EXPORT int MsgAuthInitDB(void);
|
||||
EXPORT int MsgAuthAddUser(const char *user);
|
||||
EXPORT int MsgAuthUserList(char **list[]);
|
||||
EXPORT void MsgAuthUserListFree(char **list[]);
|
||||
|
||||
// Auth / cookie functions
|
||||
|
||||
@@ -123,6 +125,7 @@ int MsgSQLBindString(MsgSQLStatement *stmt, int var, const char *str, BOOL nulli
|
||||
int MsgSQLExecute(MsgSQLHandle *handle, MsgSQLStatement *_stmt);
|
||||
int MsgSQLResults(MsgSQLHandle *handle, MsgSQLStatement *_stmt);
|
||||
void MsgSQLFinalize(MsgSQLStatement *stmt);
|
||||
int MsgSQLStatementStep(MsgSQLHandle *handle, MsgSQLStatement *_stmt);
|
||||
|
||||
|
||||
// Misc. util functions
|
||||
|
||||
@@ -14,7 +14,19 @@ on execution to specify its action.
|
||||
.TP
|
||||
.BR \-v ", " \-\^\-verbose
|
||||
Show verbose output.
|
||||
.TP
|
||||
.BR \-s ", " \-\^\-silent
|
||||
Non-interactive mode.
|
||||
.SH COMMANDS
|
||||
.BI "user add " USER
|
||||
Add a user to the system.
|
||||
.TP
|
||||
.BR "user list"
|
||||
List the users on the system.
|
||||
.TP
|
||||
.BI "user password " USER
|
||||
Set the password of
|
||||
.I USER
|
||||
.TP
|
||||
.BR install
|
||||
Do the initial Bongo install.
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
# -*- Makefile -*-
|
||||
cmmoduledir = $(libdir)/connmgr
|
||||
cmmodule_LTLIBRARIES :=
|
||||
|
||||
sbin_PROGRAMS += bongoconnmgr
|
||||
|
||||
bongoconnmgr_SOURCES := \
|
||||
src/agents/connmgr/connmgr.c \
|
||||
src/agents/connmgr/connmgrp.h \
|
||||
src/agents/connmgr/modules.c
|
||||
|
||||
bongoconnmgr_LDADD := \
|
||||
libbongomanagement.la \
|
||||
libbongomsgapi.la \
|
||||
libbongomdb.la \
|
||||
libbongologger.la \
|
||||
libbongoconnio.la \
|
||||
libbongomemmgr.la \
|
||||
libbongoutil.la \
|
||||
libbongoxpl.la \
|
||||
$(top_builddir)/import/log4c/log4c/libbongolog4c.la \
|
||||
$(SQLITE_LIBS) \
|
||||
$(PTHREAD_LIBS) \
|
||||
$(ALL_LIBS)
|
||||
|
||||
src/agents/connmgr/all: bongoconnmgr \
|
||||
src/agents/connmgr/cmmodules/rbl/all \
|
||||
src/agents/connmgr/cmmodules/rdns/all \
|
||||
src/agents/connmgr/cmmodules/user/all \
|
||||
src/agents/connmgr/cmmodules/lists/all
|
||||
|
||||
src/agents/connmgr/clean: clean
|
||||
src/agents/connmgr/install:
|
||||
@cd $(top_builddir) && $(MAKE) $(MFLAGS) sbin_PROGRAMS=bongoconnmgr \
|
||||
install-sbinPROGRAMS install-cmmoduleLTLIBRARIES
|
||||
@@ -0,0 +1,19 @@
|
||||
# -*- Makefile -*-
|
||||
cmmodule_LTLIBRARIES += libcmlists.la
|
||||
|
||||
libcmlists_la_SOURCES := \
|
||||
src/agents/connmgr/cmmodules/lists/cmlists.c \
|
||||
src/agents/connmgr/cmmodules/lists/cmlists.h
|
||||
|
||||
libcmlists_la_LDFLAGS := -module -avoid-version
|
||||
libcmlists_la_LIBADD := \
|
||||
libbongomsgapi.la \
|
||||
libbongologger.la \
|
||||
libbongomemmgr.la \
|
||||
libbongomdb.la \
|
||||
libbongoxpl.la \
|
||||
$(PTHREAD_LIBS) \
|
||||
$(ALL_LIBS)
|
||||
|
||||
src/agents/connmgr/cmmodules/lists/all: libcmlists.la
|
||||
src/agents/connmgr/cmmodules/lists/clean: clean
|
||||
@@ -0,0 +1,17 @@
|
||||
# -*- Makefile -*-
|
||||
#
|
||||
# Do not edit!
|
||||
#
|
||||
# (unless this is Makefile.am.subdir)
|
||||
#
|
||||
# This file is a copy of the toplevel Makefile.am.subdir. If changes
|
||||
# need to be made, edit that file, and make update-makefiles, and
|
||||
# check the new files in.
|
||||
#
|
||||
# This is a skeletal automake file. The real automake fules for
|
||||
# building the targets for this directory can be found in the
|
||||
# Bongo.rules file. This file is simply here so that 'make all' can
|
||||
# work in each subdirectory.
|
||||
|
||||
all clean install:
|
||||
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
|
||||
@@ -0,0 +1,350 @@
|
||||
/****************************************************************************
|
||||
* <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);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/****************************************************************************
|
||||
* <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);
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# -*- Makefile -*-
|
||||
cmmodule_LTLIBRARIES += libcmrbl.la
|
||||
|
||||
libcmrbl_la_SOURCES := \
|
||||
src/agents/connmgr/cmmodules/rbl/cmrbl.c \
|
||||
src/agents/connmgr/cmmodules/rbl/cmrbl.h
|
||||
|
||||
libcmrbl_la_CPPFLAGS := $(AM_CPPFLAGS) \
|
||||
$(SQLITE_CFLAGS)
|
||||
|
||||
libcmrbl_la_LDFLAGS := -module -avoid-version
|
||||
libcmrbl_la_LIBADD := \
|
||||
libbongomsgapi.la \
|
||||
libbongologger.la \
|
||||
libbongomemmgr.la \
|
||||
libbongomdb.la \
|
||||
libbongoxpl.la \
|
||||
$(SQLITE_LIBS) \
|
||||
$(PTHREAD_LIBS) \
|
||||
$(ALL_LIBS)
|
||||
|
||||
src/agents/connmgr/cmmodules/rbl/all: libcmrbl.la
|
||||
src/agents/connmgr/cmmodules/rbl/clean: clean
|
||||
@@ -0,0 +1,17 @@
|
||||
# -*- Makefile -*-
|
||||
#
|
||||
# Do not edit!
|
||||
#
|
||||
# (unless this is Makefile.am.subdir)
|
||||
#
|
||||
# This file is a copy of the toplevel Makefile.am.subdir. If changes
|
||||
# need to be made, edit that file, and make update-makefiles, and
|
||||
# check the new files in.
|
||||
#
|
||||
# This is a skeletal automake file. The real automake fules for
|
||||
# building the targets for this directory can be found in the
|
||||
# Bongo.rules file. This file is simply here so that 'make all' can
|
||||
# work in each subdirectory.
|
||||
|
||||
all clean install:
|
||||
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
|
||||
@@ -0,0 +1,495 @@
|
||||
/****************************************************************************
|
||||
* <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);
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/****************************************************************************
|
||||
* <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=?;"
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# -*- Makefile -*-
|
||||
cmmodule_LTLIBRARIES += libcmrdns.la
|
||||
|
||||
libcmrdns_la_SOURCES := \
|
||||
src/agents/connmgr/cmmodules/rdns/cmrdns.c \
|
||||
src/agents/connmgr/cmmodules/rdns/cmrdns.h
|
||||
|
||||
libcmrdns_la_CPPFLAGS := $(AM_CPPFLAGS) \
|
||||
$(SQLITE_CFLAGS)
|
||||
|
||||
libcmrdns_la_LDFLAGS := -module -avoid-version
|
||||
libcmrdns_la_LIBADD := \
|
||||
libbongomsgapi.la \
|
||||
libbongologger.la \
|
||||
libbongomemmgr.la \
|
||||
libbongomdb.la \
|
||||
libbongoxpl.la \
|
||||
$(SQLITE_LIBS) \
|
||||
$(PTHREAD_LIBS) \
|
||||
$(ALL_LIBS)
|
||||
|
||||
src/agents/connmgr/cmmodules/rdns/all: libcmrdns.la
|
||||
src/agents/connmgr/cmmodules/rdns/clean: clean
|
||||
@@ -0,0 +1,17 @@
|
||||
# -*- Makefile -*-
|
||||
#
|
||||
# Do not edit!
|
||||
#
|
||||
# (unless this is Makefile.am.subdir)
|
||||
#
|
||||
# This file is a copy of the toplevel Makefile.am.subdir. If changes
|
||||
# need to be made, edit that file, and make update-makefiles, and
|
||||
# check the new files in.
|
||||
#
|
||||
# This is a skeletal automake file. The real automake fules for
|
||||
# building the targets for this directory can be found in the
|
||||
# Bongo.rules file. This file is simply here so that 'make all' can
|
||||
# work in each subdirectory.
|
||||
|
||||
all clean install:
|
||||
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
|
||||
@@ -0,0 +1,360 @@
|
||||
/****************************************************************************
|
||||
* <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);
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/****************************************************************************
|
||||
* <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
|
||||
@@ -0,0 +1,19 @@
|
||||
# -*- Makefile -*-
|
||||
cmmodule_LTLIBRARIES += libcmuser.la
|
||||
|
||||
libcmuser_la_SOURCES := \
|
||||
src/agents/connmgr/cmmodules/user/cmuser.c \
|
||||
src/agents/connmgr/cmmodules/user/cmuser.h
|
||||
|
||||
libcmuser_la_LDFLAGS := -module -avoid-version
|
||||
libcmuser_la_LIBADD := \
|
||||
libbongomsgapi.la \
|
||||
libbongologger.la \
|
||||
libbongomemmgr.la \
|
||||
libbongomdb.la \
|
||||
libbongoxpl.la \
|
||||
$(PTHREAD_LIBS) \
|
||||
$(ALL_LIBS)
|
||||
|
||||
src/agents/connmgr/cmmodules/user/cmuser/all: libcmuser.la
|
||||
src/agents/connmgr/cmmodules/user/cmuser/clean: clean
|
||||
@@ -0,0 +1,17 @@
|
||||
# -*- Makefile -*-
|
||||
#
|
||||
# Do not edit!
|
||||
#
|
||||
# (unless this is Makefile.am.subdir)
|
||||
#
|
||||
# This file is a copy of the toplevel Makefile.am.subdir. If changes
|
||||
# need to be made, edit that file, and make update-makefiles, and
|
||||
# check the new files in.
|
||||
#
|
||||
# This is a skeletal automake file. The real automake fules for
|
||||
# building the targets for this directory can be found in the
|
||||
# Bongo.rules file. This file is simply here so that 'make all' can
|
||||
# work in each subdirectory.
|
||||
|
||||
all clean install:
|
||||
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
|
||||
@@ -0,0 +1,293 @@
|
||||
/****************************************************************************
|
||||
* <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);
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/****************************************************************************
|
||||
* <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
@@ -0,0 +1,42 @@
|
||||
/****************************************************************************
|
||||
* <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);
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
/****************************************************************************
|
||||
* <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;
|
||||
}
|
||||
}
|
||||
+7
-21
@@ -1272,16 +1272,9 @@ POP3CommandTop(void *param)
|
||||
}
|
||||
|
||||
/* Read message header size */
|
||||
ccode = NMAPSendCommandF(client->store, "PROPGET %llx nmap.mail.headersize\r\n", client->message[id].guid);
|
||||
if (ccode != -1) {
|
||||
ccode = NMAPReadResponse(client->store, client->buffer, CONN_BUFSIZE, TRUE);
|
||||
if (ccode == 2001) {
|
||||
ccode = NMAPReadDecimalPropertyResponse(client->store, "nmap.mail.headersize", &headerSize);
|
||||
}
|
||||
if (ccode != 2001) {
|
||||
return(ConnWriteF(client->conn, "%s %d\r\n",MSGERRNMAP, ccode));
|
||||
}
|
||||
}
|
||||
ccode = NMAPGetDecimalProperty(client->store, client->message[id].guid, "nmap.mail.headersize", &headerSize);
|
||||
if (ccode == -1)
|
||||
return (ConnWriteF(client->conn, "%s %d\r\n", MSGERRNMAP, ccode));
|
||||
|
||||
/* Read the message header */
|
||||
ccode = NMAPSendCommandF(client->store, "READ %llx 0 %lu\r\n", client->message[id].guid, headerSize);
|
||||
@@ -1293,31 +1286,24 @@ POP3CommandTop(void *param)
|
||||
if (ccode != -1) {
|
||||
ccode = ConnReadToConn(client->store, client->conn, count);
|
||||
}
|
||||
|
||||
if (ccode != -1) {
|
||||
ccode = NMAPReadAnswer(client->store, client->buffer, CONN_BUFSIZE, TRUE);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 4220: {
|
||||
ccode = ConnWrite(client->conn, MSGERRNOMSG, sizeof(MSGERRNOMSG) - 1);
|
||||
ccode = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
ccode = ConnWriteF(client->conn, "%s %d\r\n",MSGERRNMAP, ccode);
|
||||
ccode = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ccode != 2001) {
|
||||
ccode = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ccode != 1000) {
|
||||
if (ccode == -1) {
|
||||
return(ccode);
|
||||
}
|
||||
|
||||
@@ -1376,7 +1362,7 @@ POP3CommandTop(void *param)
|
||||
ConnWrite(client->conn, ".\r\n", 3);
|
||||
}
|
||||
|
||||
return(ccode);
|
||||
return(1000);
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@@ -908,7 +908,7 @@ StartOver:
|
||||
unsigned char buffer[1024]; /* FIXME: is this too big? */
|
||||
unsigned char *addrptr;
|
||||
unsigned char *flags = strchr(ptr2+1,' '); /* the original flags */
|
||||
int cnt;
|
||||
int cnt=0;
|
||||
|
||||
aliasing(cur+1, &cnt, buffer);
|
||||
|
||||
|
||||
@@ -223,11 +223,19 @@ StoreCommandSEARCH(StoreClient *client, uint64_t guid, StoreSearchInfo *query)
|
||||
goto finish;
|
||||
case 1:
|
||||
if (!STORE_IS_FOLDER(child.type)) {
|
||||
FindPathToDocument(client, child.collection, child.guid, path, sizeof(path));
|
||||
f = fopen(path, "rb");
|
||||
if (!f) {
|
||||
ccode = ConnWriteStr(client->conn, MSG4224CANTREAD);
|
||||
goto finish;
|
||||
}
|
||||
ccode = SearchDocument(client, &child, query, f);
|
||||
fclose(f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
ccode = ConnWriteStr(client->conn, MSG1000OK);
|
||||
|
||||
finish:
|
||||
if (stmt) DStoreStmtEnd(client->handle, stmt);
|
||||
|
||||
+51
-40
@@ -180,7 +180,6 @@ InitializeDataArea(void)
|
||||
if (unpriv_user != NULL)
|
||||
XplLookupUser(unpriv_user, &uid, &gid);
|
||||
|
||||
XplConsolePrintf(_("Creating directory structure...\n"));
|
||||
for (dir = MSGAPI_DIR_START; dir < MSGAPI_DIR_END; dir++) {
|
||||
char path[XPL_MAX_PATH];
|
||||
if (MsgGetDir(dir, path, XPL_MAX_PATH)) {
|
||||
@@ -191,7 +190,6 @@ InitializeDataArea(void)
|
||||
|
||||
RunAsBongoUser();
|
||||
|
||||
XplConsolePrintf(_("Initializing user database...\n"));
|
||||
if (MsgAuthInit() != 0) {
|
||||
XplConsolePrintf(_("ERROR: Couldn't initialise auth subsystem\n"));
|
||||
exit(1);
|
||||
@@ -212,14 +210,12 @@ InitialStoreConfiguration(void) {
|
||||
|
||||
// attempt to initialise cal lib. This creates cached data, and can be time
|
||||
// consuming: do it now, rather than in the store (for now, at least)
|
||||
XplConsolePrintf(_("Initializing calendar data...\n"));
|
||||
cal_success = BongoCalInit(XPL_DEFAULT_DBF_DIR);
|
||||
if (! cal_success) {
|
||||
XplConsolePrintf(_("ERROR: Couldn't initialise calendar library\n"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
XplConsolePrintf(_("Loading initial store configuration...\n"));
|
||||
LoadDefaultStoreConfiguration();
|
||||
}
|
||||
|
||||
@@ -268,8 +264,6 @@ LoadDefaultStoreConfiguration(void)
|
||||
goto nmapcleanup;
|
||||
}
|
||||
|
||||
XplConsolePrintf(_("Setting default agent configuration...\n"));
|
||||
|
||||
snprintf(path, XPL_MAX_PATH, "%s/conf/default.set", XPL_DEFAULT_DATA_DIR);
|
||||
if (! ImportSystemBackupFile(client, path)) {
|
||||
XplConsolePrintf(_("ERROR: Couldn't setup default configuration\n"));
|
||||
@@ -333,15 +327,14 @@ GenerateCryptoData() {
|
||||
|
||||
// hack: we need to ensure the files below can be saved...
|
||||
if (0 != mkdir(XPL_DEFAULT_DBF_DIR, 0755)) {
|
||||
XplConsolePrintf(_("Couldn't create data directory!\n"));
|
||||
// TODO: check that the directory doesn't already exist.
|
||||
// XplConsolePrintf(_("Couldn't create data directory!\n"));
|
||||
}
|
||||
|
||||
// save a random seed for faster Xpl startup in future.
|
||||
XplConsolePrintf(_("Creating random seed...\n"));
|
||||
XplSaveRandomSeed();
|
||||
|
||||
// various magic params
|
||||
XplConsolePrintf(_("Creating DH parameters...\n"));
|
||||
gnutls_dh_params_init(&dh_params);
|
||||
gnutls_dh_params_generate2(dh_params, 1024);
|
||||
dsize = CERTSIZE;
|
||||
@@ -356,7 +349,6 @@ GenerateCryptoData() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
XplConsolePrintf(_("Creating RSA parameters...\n"));
|
||||
gnutls_rsa_params_init(&rsa_params);
|
||||
gnutls_rsa_params_generate2(rsa_params, 512);
|
||||
dsize = CERTSIZE;
|
||||
@@ -372,7 +364,6 @@ GenerateCryptoData() {
|
||||
}
|
||||
|
||||
// create private key
|
||||
XplConsolePrintf(_("Creating private key...\n"));
|
||||
ret = gnutls_x509_privkey_init(&key);
|
||||
if (ret < 0) {
|
||||
XplConsolePrintf(_("ERROR: %s\n"), gnutls_strerror (ret));
|
||||
@@ -402,7 +393,6 @@ GenerateCryptoData() {
|
||||
}
|
||||
|
||||
// create certificate
|
||||
XplConsolePrintf(_("Creating SSL/TLS certificate...\n"));
|
||||
ret = gnutls_x509_crt_init(&certificate);
|
||||
if (ret < 0) {
|
||||
XplConsolePrintf(_("ERROR: %s\n"), gnutls_strerror(ret));
|
||||
@@ -484,17 +474,38 @@ CheckVersion() {
|
||||
void
|
||||
UserAdd(const char *username)
|
||||
{
|
||||
if (MsgAuthAddUser(username) == 0) {
|
||||
XplConsolePrintf(_("Added user %s\n"), username);
|
||||
} else {
|
||||
XplConsolePrintf(_("Couldn't add user %s\n"), username);
|
||||
}
|
||||
int result = MsgAuthAddUser(username);
|
||||
switch (result) {
|
||||
case 0:
|
||||
XplConsolePrintf(_("Added user %s\n"), username);
|
||||
break;
|
||||
case -1:
|
||||
XplConsolePrintf(_("User %s already exists\n"), username);
|
||||
break;
|
||||
case -2:
|
||||
XplConsolePrintf(_("Auth backend doesn't support adding user\n"));
|
||||
break;
|
||||
default:
|
||||
XplConsolePrintf(_("Couldn't add user %s: internal error\n"), username);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UserList(void)
|
||||
{
|
||||
// TODO
|
||||
char **userlist;
|
||||
int result;
|
||||
|
||||
result = MsgAuthUserList(&userlist);
|
||||
if (result) {
|
||||
int i;
|
||||
|
||||
for (i = 0; userlist[i] != 0; i++) {
|
||||
XplConsolePrintf("%s\n", userlist[i]);
|
||||
}
|
||||
MsgAuthUserListFree(&userlist);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -539,8 +550,8 @@ main(int argc, char *argv[]) {
|
||||
BongoAgent configtool;
|
||||
config.verbose = 0;
|
||||
|
||||
/* this just clears up a warning. we don't need this here */
|
||||
GlobalConfig[0].type = BONGO_JSON_NULL;
|
||||
/* this just clears up a warning. we don't need this here */
|
||||
GlobalConfig[0].type = BONGO_JSON_NULL;
|
||||
|
||||
if (!MemoryManagerOpen("bongo-config")) {
|
||||
XplConsolePrintf("ERROR: Failed to initialize memory manager\n");
|
||||
@@ -633,20 +644,28 @@ main(int argc, char *argv[]) {
|
||||
XplConsolePrintf(_("Couldn't initialise auth subsystem\n"));
|
||||
return 3;
|
||||
}
|
||||
if ((next_arg + 1) >= argc) {
|
||||
XplConsolePrintf(_("USAGE : user [add|password] <username>\n"));
|
||||
if (next_arg >= argc) {
|
||||
XplConsolePrintf(_("USAGE : user [add|password|list] [<username>]\n"));
|
||||
} else {
|
||||
char *command = argv[next_arg++];
|
||||
char *username = argv[next_arg];
|
||||
|
||||
if (! strncmp(command, "add", 3)) {
|
||||
UserAdd(username);
|
||||
} else if (!strncmp(command, "password", 8)) {
|
||||
UserPassword(username);
|
||||
} else if (!strncmp(command, "list", 4)) {
|
||||
if (!strncmp(command, "list", 4)) {
|
||||
UserList();
|
||||
} else {
|
||||
XplConsolePrintf(_("ERROR: Unknown command '%s' on user\n"), command);
|
||||
char *username;
|
||||
if (next_arg >= argc) {
|
||||
XplConsolePrintf(_("USAGE : user %s <username\n"), command);
|
||||
break;
|
||||
}
|
||||
username = argv[next_arg];
|
||||
|
||||
if (! strncmp(command, "add", 3)) {
|
||||
UserAdd(username);
|
||||
} else if (!strncmp(command, "password", 8)) {
|
||||
UserPassword(username);
|
||||
} else {
|
||||
XplConsolePrintf(_("ERROR: Unknown command '%s'\n"), command);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -654,17 +673,9 @@ main(int argc, char *argv[]) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (config.ip) {
|
||||
MemFree(config.ip);
|
||||
}
|
||||
|
||||
if (config.dns) {
|
||||
MemFree(config.dns);
|
||||
}
|
||||
|
||||
if (config.domains) {
|
||||
BongoJsonNodeFree(config.domains);
|
||||
}
|
||||
if (config.ip) MemFree(config.ip);
|
||||
if (config.dns) MemFree(config.dns);
|
||||
if (config.domains) BongoJsonNodeFree(config.domains);
|
||||
|
||||
MemoryManagerClose("bongo-config");
|
||||
exit(0);
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
{ "name": "bongorules", "pri": 5, "enabled": false },
|
||||
{ "name": "bongoimap", "pri": 10, "enabled": true },
|
||||
{ "name": "bongopop3", "pri": 10, "enabled": true },
|
||||
{ "name": "bongocalcmd", "pri": 7, "enabled": true },
|
||||
{ "name": "bongo-standalone", "pri": 10, "enabled": true }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
# -*- Makefile -*-
|
||||
sbin_SCRIPTS += src/apps/setup/bongo-setup
|
||||
|
||||
schemadir = $(XPL_DEFAULT_CONF_DIR)
|
||||
dist_schema_DATA = \
|
||||
src/apps/setup/bongo-setup.xml \
|
||||
src/apps/setup/base-schema.xml \
|
||||
src/apps/setup/bongo-schema.xml
|
||||
|
||||
nodist_schema_DATA = \
|
||||
src/apps/setup/bongo-setup.xml
|
||||
|
||||
dist_noinst_DATA += src/apps/setup/bongo-setup.xml.in
|
||||
|
||||
src/apps/setup/bongo-setup: $(top_builddir)/src/libs/python/bongo-python-wrapper
|
||||
$(INSTALL) -m 755 $< $@
|
||||
|
||||
dist_pkglibexec_SCRIPTS += src/apps/setup/bongo-setup.py
|
||||
|
||||
CLEANFILES += \
|
||||
src/apps/setup/bongo-setup \
|
||||
src/apps/setup/*.pyc
|
||||
|
||||
src/apps/setup/all:
|
||||
src/apps/setup/clean: clean
|
||||
src/apps/setup/install:
|
||||
@cd $(top_builddir) && $(MAKE) $(MFLAGS) \
|
||||
sbin_SCRIPTS=src/apps/setup/bongo-setup \
|
||||
dist_pkglibexec_SCRIPTS=src/apps/setup/bongo-setup.py \
|
||||
install-dist_sbinSCRIPTS install-dist_schemaDATA
|
||||
@@ -1,68 +0,0 @@
|
||||
<schema>
|
||||
<attribute name="Surname" syntax="CaseInsensitiveString" />
|
||||
<attribute name="Given Name" syntax="CaseInsensitiveString" />
|
||||
<attribute name="Title" syntax="CaseInsensitiveString" />
|
||||
<attribute name="Telephone Number" syntax="CaseInsensitiveString" />
|
||||
<attribute name="Facsimile Telephone Number" syntax="CaseInsensitiveString" />
|
||||
<attribute name="SA" syntax="CaseInsensitiveString" />
|
||||
<attribute name="Postal Office Box" syntax="CaseInsensitiveString" />
|
||||
<attribute name="Postal Code" syntax="CaseInsensitiveString" />
|
||||
<attribute name="Postal Address" syntax="CaseInsensitiveString" />
|
||||
<attribute name="Physical Delivery Office Name" syntax="CaseInsensitiveString" />
|
||||
<attribute name="Owner" syntax="CaseInsensitiveString" />
|
||||
<attribute name="O" syntax="CaseInsensitiveString" />
|
||||
<attribute name="OU" syntax="CaseInsensitiveString" />
|
||||
<attribute name="Description" syntax="CaseInsensitiveString" />
|
||||
<attribute name="See Also" syntax="DistinguishedName" />
|
||||
<class name = "Top">
|
||||
</class>
|
||||
<class name="User" super-class="Top">
|
||||
<required-attributes>
|
||||
<attribute name="Surname" />
|
||||
</required-attributes>
|
||||
<allowed-attributes>
|
||||
<attribute name="Given Name" />
|
||||
<attribute name="Title" />
|
||||
<attribute name="Telephone Number" />
|
||||
<attribute name="Facsimile Telephone Number" />
|
||||
<attribute name="SA" />
|
||||
<attribute name="Postal Office Box" />
|
||||
<attribute name="Postal Code" />
|
||||
<attribute name="Postal Address" />
|
||||
<attribute name="Physical Delivery Office Name" />
|
||||
<attribute name="See Also" />
|
||||
<attribute name="Description" />
|
||||
</allowed-attributes>
|
||||
</class>
|
||||
<class name="Organization" super-class="Top">
|
||||
<allowed-attributes>
|
||||
<attribute name="Telephone Number" />
|
||||
<attribute name="Facsimile Telephone Number" />
|
||||
<attribute name="Postal Office Box" />
|
||||
<attribute name="Postal Code" />
|
||||
<attribute name="Postal Address" />
|
||||
<attribute name="Physical Delivery Office Name" />
|
||||
<attribute name="Description" />
|
||||
</allowed-attributes>
|
||||
</class>
|
||||
<class name="OrganizationalUnit" super-class="Top">
|
||||
<allowed-attributes>
|
||||
<attribute name="Telephone Number" />
|
||||
<attribute name="Facsimile Telephone Number" />
|
||||
<attribute name="Postal Office Box" />
|
||||
<attribute name="Postal Code" />
|
||||
<attribute name="Postal Address" />
|
||||
<attribute name="Physical Delivery Office Name" />
|
||||
<attribute name="Description" />
|
||||
</allowed-attributes>
|
||||
</class>
|
||||
<class name="GroupOfNames" super-class="Top">
|
||||
<allowed-attributes>
|
||||
<attribute name="See Also" />
|
||||
<attribute name="Owner" />
|
||||
<attribute name="OU" />
|
||||
<attribute name="O" />
|
||||
<attribute name="Description" />
|
||||
</allowed-attributes>
|
||||
</class>
|
||||
</schema>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,692 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#############################################################################
|
||||
#
|
||||
# Copyright (c) 2006 Novell, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2.1 of the GNU Lesser 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser 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
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
import os, random, signal, socket, string, sys
|
||||
|
||||
from bongo import Xpl, BongoError, Privs
|
||||
from bongo.admin import ManagedSlapd, Util
|
||||
from libbongo.bootstrap import msgapi
|
||||
|
||||
from bongo.Console import wrap
|
||||
|
||||
import re, optparse
|
||||
|
||||
import logging
|
||||
formatter = logging.Formatter("%(levelname)s: %(message)s")
|
||||
console = logging.StreamHandler()
|
||||
console.setFormatter(formatter)
|
||||
logging.root.addHandler(console)
|
||||
|
||||
log = logging.getLogger("bongo-setup")
|
||||
|
||||
# the managed slapd configuration is global, so we can shut it down on
|
||||
# failure
|
||||
slapdConfig = None
|
||||
|
||||
def BongoSetupOptions():
|
||||
parser = optparse.OptionParser()
|
||||
parser.add_option("-n", "--noprompt", action="store_true", help="run non-interactively")
|
||||
parser.add_option("-H", "--hostname", type="string", help="hostname of this Bongo server")
|
||||
parser.add_option("-M", "--maildomain", type="string", help="domain we accept mail for")
|
||||
parser.add_option("-f", "--file", type="string",
|
||||
default=os.path.join(Xpl.DEFAULT_CONF_DIR, "bongo-setup.xml"),
|
||||
help="import objects from XML file FILE")
|
||||
|
||||
group = optparse.OptionGroup(parser, "SSL options")
|
||||
group.add_option("-r", "--cert", type="string", metavar="FILE", help="use certificate file FILE")
|
||||
group.add_option("-k", "--key", type="string", metavar="FILE", help="use private key file FILE")
|
||||
parser.add_option_group(group)
|
||||
|
||||
group = optparse.OptionGroup(parser, "LDAP options", description="options for --mdb-driver=ldap")
|
||||
group.add_option("-u", "--authuser", type="string", help="user for directory authentication")
|
||||
group.add_option("-p", "--authpass", type="string", help="password for directory authentication")
|
||||
parser.add_option_group(group)
|
||||
|
||||
schemas = "ad edir mdb openldap".split()
|
||||
parser.add_option("-S", "--gen-schema", choices=schemas, metavar="TARGET", help="generate schema for TARGET (" + ", ".join(schemas) + ")")
|
||||
parser.add_option("-a", "--noacl", type="string", help="don't set up ACLs")
|
||||
|
||||
dirs = "file ldap managed-slapd".split()
|
||||
parser.add_option("-m", "--mdb-driver", choices=dirs, default="managed-slapd", help="specify directory driver (" + ", ".join(dirs) + ") [default %default]")
|
||||
parser.add_option("-b", "--base", type="string", default="\\Tree", help="base in directory for Bongo")
|
||||
|
||||
parser.add_option("", "--managed-slapd-path", type="string", metavar="PATH",
|
||||
default=Xpl.DEFAULT_SLAPD_PATH,
|
||||
help="path to your slapd binary [default %default]")
|
||||
parser.add_option("", "--managed-slapd-port", type="int", metavar="PORT",
|
||||
default=8983, help="port for managed slapd [default %default]")
|
||||
|
||||
admintool = os.path.join(Xpl.DEFAULT_BIN_DIR, "bongo-admin")
|
||||
|
||||
binpath = os.path.abspath(os.path.dirname(sys.argv[0]))
|
||||
|
||||
if not binpath.startswith(Xpl.DEFAULT_BIN_DIR):
|
||||
adminpath = os.path.abspath(os.path.join(binpath, "..", "bongoadmin",
|
||||
"bongo-admin"))
|
||||
if os.path.exists(adminpath):
|
||||
admintool = adminpath
|
||||
|
||||
parser.add_option("", "--bongo-admin", action="store_const", default=admintool, help=optparse.SUPPRESS_HELP)
|
||||
parser.add_option("", "--debug", action="store_true", help=optparse.SUPPRESS_HELP)
|
||||
|
||||
return parser
|
||||
|
||||
def main():
|
||||
parser = BongoSetupOptions()
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if options.debug:
|
||||
logging.root.setLevel(logging.DEBUG)
|
||||
|
||||
log.debug("bongo-setup options: " + str(options))
|
||||
|
||||
if len(args) > 0:
|
||||
log.error("Unexpected arguments after script flags")
|
||||
sys.stderr.write(parser.get_usage())
|
||||
sys.stderr.write("\n")
|
||||
sys.exit(1)
|
||||
|
||||
if os.getegid() != 0:
|
||||
log.error("%s must be run as root" % os.path.basename(sys.argv[0]))
|
||||
sys.exit(1)
|
||||
|
||||
if not options.noprompt:
|
||||
print wrap("""
|
||||
Welcome to Bongo!
|
||||
|
||||
You will be guided through the setup of a new Bongo installation.
|
||||
|
||||
This tool makes use of %(bongo_admin)s, which you can also use to tweak the system later, or (for experts) to set up Bongo manually.
|
||||
|
||||
See \"%(bongo_setup)s --help\" for command-line options to further automate the setup process.
|
||||
""" % {'bongo_admin' : options.bongo_admin, 'bongo_setup' : sys.argv[0]})
|
||||
|
||||
Input('Press Enter to continue', options=options)
|
||||
|
||||
# make sure our various directories are in good shape permissions-wise
|
||||
for path in [Xpl.DEFAULT_CONF_DIR,
|
||||
Xpl.DEFAULT_STATE_DIR,
|
||||
Xpl.DEFAULT_CACHE_DIR,
|
||||
Xpl.DEFAULT_DBF_DIR,
|
||||
Xpl.DEFAULT_WORK_DIR]:
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
Privs.Chown(path)
|
||||
|
||||
pidfile = os.path.join(Xpl.DEFAULT_WORK_DIR, "bongomanager.pid")
|
||||
if os.path.exists(pidfile):
|
||||
fd = open(pidfile, "r")
|
||||
pid = fd.readline().strip()
|
||||
fd.close()
|
||||
|
||||
# see if the bongomanager pid is still running
|
||||
try:
|
||||
pid = long(pid)
|
||||
r = os.kill(pid, 0)
|
||||
raise BongoError("""A possibly stale bongomanager pid file has been found. Either kill process %d (if it is bongomanager) or remove %s""" % (pid, pidfile))
|
||||
except OSError, e:
|
||||
os.remove(pidfile)
|
||||
|
||||
mdbfile = os.path.join(Xpl.DEFAULT_CONF_DIR, "mdb.conf")
|
||||
|
||||
mdbconf = InspectMDB(mdbfile, options)
|
||||
if mdbconf is None:
|
||||
mdbconf = SetupMDB(mdbfile, options)
|
||||
|
||||
if mdbconf.get("driver") in ("file", "managed-slapd"):
|
||||
if not UpdateSchema(mdbconf, options):
|
||||
raise BongoError(wrap("""Updating the MDB schema has failed."""))
|
||||
|
||||
if ImportObjects(mdbconf, options):
|
||||
raise BongoError("""Importing objects failed, possibly because the directory's schema needs to be updated. When you are done updating the schema in your directory, run %s again to complete Bongo's configuration.""" % sys.argv[0])
|
||||
|
||||
print 'Imported objects from \"%s\".' % options.file
|
||||
SetupACL(mdbconf, options)
|
||||
GeneratePasswords(options)
|
||||
|
||||
print 'Configuring final settings...'
|
||||
from bongo import MDB
|
||||
mdb = MDB.MDB(options.authuser, options.authpass)
|
||||
context = mdb.baseDn
|
||||
|
||||
# include other directory options here once they're supported
|
||||
if mdbconf.get("driver") == "ldap" and not mdbconf.has_key("slapdConfig"):
|
||||
context = Input('Enter default directory context for Bongo users',
|
||||
{}, mdb.baseDn, options)
|
||||
|
||||
while not mdb.IsObject(context):
|
||||
print 'Context does not exist. Please enter a valid context.'
|
||||
context = Input('Enter default directory context for Bongo users',
|
||||
{}, mdb.baseDn, options)
|
||||
|
||||
confprops = {msgapi.DEFAULT_CONTEXT : context}
|
||||
Util.ModifyConfProperties(confprops)
|
||||
|
||||
msgserver = msgapi.GetConfigProperty(msgapi.MESSAGING_SERVER)
|
||||
mdb.SetAttribute(msgserver, msgapi.A_CONTEXT, [context])
|
||||
|
||||
#getting hostname for certificate
|
||||
if options.hostname:
|
||||
hostname = options.hostname
|
||||
else:
|
||||
hostname = Input('Enter the hostname for the mail server hosting Bongo',
|
||||
{}, socket.getfqdn(), options)
|
||||
|
||||
try:
|
||||
mdb.SetAttribute(msgserver, msgapi.A_OFFICIAL_NAME, [hostname])
|
||||
except BongoError:
|
||||
if not hostname in ['localhost', 'localhost.localdomain']:
|
||||
raise
|
||||
|
||||
#getting domain name bongo will accept mail for
|
||||
if options.maildomain:
|
||||
maildomain = options.maildomain
|
||||
else:
|
||||
maildomain = Input('Enter domain name that Bongo will host',
|
||||
{}, socket.getfqdn(), options)
|
||||
|
||||
try:
|
||||
mdb.SetAttribute(msgserver, msgapi.A_OFFICIAL_NAME, [maildomain])
|
||||
except BongoError:
|
||||
if not maildomain in ['localhost', 'localhost.localdomain']:
|
||||
raise
|
||||
|
||||
# Add hosted domain to the smtp agent
|
||||
smtpserver = msgserver + '\\' + msgapi.AGENT_SMTP
|
||||
if(mdb.IsObject(smtpserver)):
|
||||
try:
|
||||
mdb.AddAttribute(smtpserver, msgapi.A_DOMAIN, maildomain)
|
||||
except:
|
||||
print "Couldn't set attribute A_DOMAIN to " + maildomain
|
||||
try:
|
||||
default = socket.gethostbyname(maildomain)
|
||||
except:
|
||||
default = '127.0.0.1'
|
||||
|
||||
ip = Input('Enter IP address on which to run Bongo',
|
||||
{}, default, options)
|
||||
try:
|
||||
mdb.SetAttribute(msgserver, msgapi.A_IP_ADDRESS, [ip])
|
||||
except:
|
||||
print "Couldn't set attribute A_IP_ADDRESS to " + ip
|
||||
|
||||
|
||||
options.hostname = hostname
|
||||
options.ip = ip
|
||||
|
||||
# now we have the hostname and ip, we can setup a sensible cert.
|
||||
SetupCerts(options)
|
||||
|
||||
# shut down the temporary slapd
|
||||
if mdbconf.has_key("slapdConfig"):
|
||||
slapdConfig = mdbconf["slapdConfig"]
|
||||
slapdConfig.killSlapd()
|
||||
|
||||
print
|
||||
print 'Bongo setup is complete!'
|
||||
print 'Now run "bongo-config install" to complete the installation'
|
||||
return
|
||||
|
||||
def ReadMdbConf(mdbfile):
|
||||
fd = open(mdbfile)
|
||||
confstr = fd.readline().strip()
|
||||
fd.close()
|
||||
|
||||
if not re.match("^Driver=", confstr):
|
||||
return None
|
||||
|
||||
arr = confstr.split(" ", 2)
|
||||
driver = arr[0].split("=", 2)
|
||||
|
||||
conf = {"driver" : driver[1].lower()}
|
||||
if len(arr) > 1:
|
||||
for key, val in re.findall("(.*?)=\"(.*?)\"(?:[ |,])?", arr[1]):
|
||||
conf[key.lower()] = val
|
||||
|
||||
return conf
|
||||
|
||||
def WriteMdbConf(mdbfile, mdbconf):
|
||||
mcfile = open(mdbfile, "w")
|
||||
|
||||
drivers = {"managed-slapd" : "ldap"}
|
||||
|
||||
driver = mdbconf.get("driver")
|
||||
if drivers.has_key(driver):
|
||||
driver = drivers[driver]
|
||||
|
||||
confstr = "Driver=MDB" + driver.upper()
|
||||
|
||||
opts = []
|
||||
for optname in ["basedn", "binddn", "password", "port", "host", "tls"]:
|
||||
if not mdbconf.has_key(optname):
|
||||
continue
|
||||
|
||||
opts.append('%s="%s"' % (optname, mdbconf[optname]))
|
||||
|
||||
if len(opts) > 0:
|
||||
confstr = confstr + " " + ",".join(opts)
|
||||
|
||||
mcfile.write(confstr)
|
||||
mcfile.write("\n")
|
||||
mcfile.close()
|
||||
Privs.Chown(mdbfile)
|
||||
|
||||
def LdapToMdb(dn):
|
||||
parts = re.findall("=([^,]+)", dn)
|
||||
parts.reverse()
|
||||
|
||||
return '\\' + '\\'.join(parts)
|
||||
|
||||
def InspectMDB(mdbfile, options):
|
||||
if not os.path.exists(mdbfile):
|
||||
return None
|
||||
|
||||
log.debug("inspecting existing MDB install")
|
||||
|
||||
conf = ReadMdbConf(mdbfile)
|
||||
|
||||
if conf is None:
|
||||
return None
|
||||
|
||||
olddriver = conf["driver"]
|
||||
|
||||
print 'Found an existing %s MDB configuration.' % olddriver
|
||||
choices = {'keep': 'Use the existing \"%s\" configuration' % olddriver,
|
||||
'change': 'Set up MDB differently'}
|
||||
choice = 'keep'
|
||||
if options.noprompt:
|
||||
choice = 'change'
|
||||
|
||||
choice = Input('Enter your choice for MDB', choices, choice, options)
|
||||
|
||||
if choice == 'change':
|
||||
return None
|
||||
|
||||
# at this point, the user wants to reuse the old mdb configuration
|
||||
drivers = {'mdbfile': 'file', 'mdbldap': 'ldap'}
|
||||
|
||||
# if no driver has been specified on the command line, reuse
|
||||
# the old driver
|
||||
if options.mdb_driver is None:
|
||||
conf["driver"] = drivers.get(conf["olddriver"], conf["olddriver"])
|
||||
|
||||
if options.authuser and options.authpass:
|
||||
print 'Using command line credentials...'
|
||||
elif olddriver == 'mdbfile':
|
||||
print 'Using no credentials (for mdbfile)...'
|
||||
else:
|
||||
authuser = conf.get('binddn')
|
||||
authpass = conf.get('password')
|
||||
|
||||
if not authuser and not authpass:
|
||||
print 'Could not determine directory credentials from old MDB configuration.'
|
||||
authuser = Input('Enter the directory admin dn')
|
||||
authpass = Input('Enter the directory admin password')
|
||||
|
||||
if authuser and not options.authuser:
|
||||
# turn the ldap user into an mdb user
|
||||
options.authuser = LdapToMdb(authuser)
|
||||
|
||||
if authpass and not options.authpass:
|
||||
options.authpass = authpass
|
||||
|
||||
return conf
|
||||
|
||||
def GetRandomPassword():
|
||||
pw = ""
|
||||
chars = string.ascii_letters + string.digits
|
||||
for i in range(1, 20):
|
||||
pw = pw + random.choice(chars)
|
||||
return pw
|
||||
|
||||
def DiscoverMDBDriverCB(drivers, parent, children):
|
||||
for child in children:
|
||||
if os.path.isdir(os.path.join(parent, child)):
|
||||
children.remove(child)
|
||||
if (child[:6].lower() == 'libmdb') and (child[-3:].lower() == '.so'):
|
||||
drivers[child[6:-3]] = child.lower()
|
||||
|
||||
def DiscoverMDBDrivers():
|
||||
mdblibpath = "%s/bongomdb/" % Xpl.DEFAULT_LIB_DIR
|
||||
if not os.path.exists(mdblibpath):
|
||||
raise BongoError(wrap("""MDB Driver directory can not be found!"""))
|
||||
drivers = {}
|
||||
os.path.walk(mdblibpath, DiscoverMDBDriverCB, drivers)
|
||||
return drivers
|
||||
|
||||
def SetupMDB(mdbfile, options):
|
||||
drivers = DiscoverMDBDrivers()
|
||||
mdbOptions = {}
|
||||
if drivers.has_key('file'):
|
||||
mdbOptions['file'] = 'use the filesystem as a directory (test systems only)'
|
||||
if drivers.has_key('ldap'):
|
||||
mdbOptions['managed-slapd'] = 'Bongo-managed standalone LDAP server'
|
||||
mdbOptions['ldap'] = 'connect to any LDAP-speaking directory'
|
||||
if drivers.has_key('edir'):
|
||||
mdbOptions['edir'] = 'use native calls to speak to eDirectory'
|
||||
if len(mdbOptions) == 0:
|
||||
raise BongoError(wrap("""No MDB Driver has been found!"""))
|
||||
print 'Which driver would you like to use for the directory?'
|
||||
mdbSelection = Input('Enter your driver selection', mdbOptions, options.mdb_driver, options)
|
||||
|
||||
mdbconf = {}
|
||||
mdbconf["driver"] = mdbSelection
|
||||
|
||||
confprops = {"ManagedSlapd" : 0}
|
||||
|
||||
if mdbSelection == 'file':
|
||||
mdbpath = os.path.join(Xpl.DEFAULT_STATE_DIR, "mdb")
|
||||
if not os.path.exists(mdbpath):
|
||||
os.makedirs(mdbpath)
|
||||
Privs.Chown(mdbpath)
|
||||
options.authpass = "bongo"
|
||||
elif mdbSelection == 'ldap':
|
||||
host = ShellCmd('hostname --long')
|
||||
if host:
|
||||
default = 'dc=' + ',dc='.join(host.split('.'))
|
||||
else:
|
||||
default = 'dc=example,dc=com'
|
||||
|
||||
ldaphost = Input('Enter the hostname or the IP address of the ldap server', default='localhost',
|
||||
options=options)
|
||||
mdbconf["host"] = ldaphost
|
||||
ldapport = Input('Enter the port of the ldap server', default='389',
|
||||
options=options)
|
||||
mdbconf["port"] = ldapport
|
||||
|
||||
basedn = Input('Enter LDAP base for Bongo', default=default,
|
||||
options=options)
|
||||
mdbconf["basedn"] = basedn
|
||||
|
||||
binddn = Input('Enter LDAP admin object', default='cn=admin,'+basedn,
|
||||
options=options)
|
||||
mdbconf["binddn"] = options.authuser = binddn
|
||||
|
||||
bindpw = Input('Enter LDAP admin password', default='bongo',
|
||||
options=options)
|
||||
mdbconf["password"] = options.authpass = bindpw
|
||||
enableTLS = Input('Use TLS on LDAP connections', default='true',
|
||||
options=options)
|
||||
if enableTLS[0:1].lower() == 't':
|
||||
mdbconf["tls"] = '1'
|
||||
elif mdbSelection == 'managed-slapd':
|
||||
ofile = os.path.join(Xpl.DEFAULT_CONF_DIR, "bongo.schema")
|
||||
|
||||
bongoRootpw = GetRandomPassword()
|
||||
|
||||
global slapdConfig
|
||||
slapdConfig = \
|
||||
ManagedSlapd.ConfigSlapd(ofile,
|
||||
options.managed_slapd_path,
|
||||
options.managed_slapd_port,
|
||||
bongoRootpw)
|
||||
|
||||
mdbconf["port"] = options.managed_slapd_port
|
||||
mdbconf["basedn"] = slapdConfig.suffix
|
||||
mdbconf["binddn"] = slapdConfig.rootdn
|
||||
mdbconf["password"] = slapdConfig.password
|
||||
|
||||
slapdConfigFile = os.path.join(Xpl.DEFAULT_CONF_DIR, "bongo-slapd.conf")
|
||||
slapdConfig.writeSlapdConf(slapdConfigFile)
|
||||
|
||||
options.authuser = LdapToMdb(slapdConfig.rootdn)
|
||||
options.authpass = slapdConfig.password
|
||||
|
||||
mdbconf["slapdConfig"] = slapdConfig
|
||||
mdbconf["slapdConfigFile"] = slapdConfigFile
|
||||
|
||||
base = '\\com\\example'
|
||||
confprops = {'BongoServices': '%s\\%s' % (base, msgapi.ROOT),
|
||||
'MessagingServer': '%s\\%s\\%s' % (base,
|
||||
msgapi.ROOT,
|
||||
'Bongo Messaging Server'),
|
||||
'ManagedSlapd': '1',
|
||||
'ManagedSlapdPath': options.managed_slapd_path,
|
||||
'ManagedSlapdPort': str(options.managed_slapd_port)}
|
||||
elif mdbSelection == 'edir':
|
||||
edirhost = Input('Enter the hostname or the IP address of the edirectory (ncp) server', default='localhost',
|
||||
options=options)
|
||||
mdbconf["host"] = edirhost
|
||||
edirport = Input('Enter the port of the edirectory (ncp) server', default='524',
|
||||
options=options)
|
||||
mdbconf["port"] = edirport
|
||||
else:
|
||||
raise BongoError('Invalid driver selection: %s' % mdbSelection)
|
||||
Util.WriteConfProperties(confprops)
|
||||
|
||||
print 'Configured MDB with \"%s\" option.' % mdbSelection
|
||||
WriteMdbConf(mdbfile, mdbconf)
|
||||
return mdbconf
|
||||
|
||||
def ImportObjects(mdbconf, options):
|
||||
print 'Directory setup - importing objects...'
|
||||
|
||||
pid = None
|
||||
if mdbconf.has_key("slapdConfig"):
|
||||
slapdConfig = mdbconf["slapdConfig"]
|
||||
|
||||
log.debug("starting temporary managed slapd process")
|
||||
pid = slapdConfig.startSlapd(mdbconf["slapdConfigFile"])
|
||||
if pid is None:
|
||||
raise BongoError('Error starting temporary slapd process. Check syslog for information about the failure.')
|
||||
|
||||
log.debug("initializing slapd with the base Bongo container")
|
||||
slapdConfig.initSlapd()
|
||||
|
||||
options.file = Input('Enter file for importing objects',
|
||||
default=options.file, options=options)
|
||||
|
||||
authops = GetAdminCmdAuth(options)
|
||||
return AdminCmd(options, authops + ['import', '-f', options.file])
|
||||
|
||||
def UpdateSchema(mdbconf, options):
|
||||
print 'Updating the directory\'s schema...'
|
||||
|
||||
authops = GetAdminCmdAuth(options)
|
||||
|
||||
dirnames = {"file" : "MDB File",
|
||||
"edir" : "Novell eDirectory",
|
||||
"openldap" : "OpenLDAP",
|
||||
"managed-slapd" : "Managed Slapd"}
|
||||
|
||||
driver = mdbconf["driver"]
|
||||
|
||||
print 'Generating schema for %s...' % dirnames.get(driver)
|
||||
|
||||
if driver == 'file' or driver == 'edir':
|
||||
if AdminCmd(options, authops + ['setup-mdb']):
|
||||
return False
|
||||
return True
|
||||
|
||||
elif driver == 'ldap':
|
||||
dirtypes = {'openldap': 'OpenLDAP standalone server',
|
||||
'edir': 'Novell eDirectory',
|
||||
'ad': 'Microsoft Active Directory'}
|
||||
dirtype = Input('Enter your directory selection', dirtypes,
|
||||
'openldap', options)
|
||||
if dirtype == 'openldap':
|
||||
ofile = 'bongo.schema'
|
||||
elif dirtype == 'edir':
|
||||
ofile = 'bongo.sch'
|
||||
elif dirtype == 'ad':
|
||||
ofile = 'bongo.ldf'
|
||||
else:
|
||||
raise BongoError('Invalid directory type')
|
||||
|
||||
print 'A schema file will now be generated, which you will have to'
|
||||
print 'import into your directory manually.'
|
||||
ofile = Input('Enter filename for schema', {}, ofile, options)
|
||||
if AdminCmd(options, authops + ["setup-genschema",
|
||||
"-t", dirtype,
|
||||
"-o", ofile]):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
elif driver == 'managed-slapd':
|
||||
ofile = os.path.join(Xpl.DEFAULT_CONF_DIR, 'bongo.schema')
|
||||
if AdminCmd(options, authops + ["setup-genschema",
|
||||
"-t", "openldap",
|
||||
"-o", ofile]):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def GetAdminCmdAuth(options):
|
||||
authops = []
|
||||
if options.authuser:
|
||||
authops.extend(["-U", options.authuser])
|
||||
if options.authpass:
|
||||
authops.extend(["-P", options.authpass])
|
||||
return authops
|
||||
|
||||
def GetAdminCmdBase(options):
|
||||
if not options.base:
|
||||
return []
|
||||
return ["--base", options.base]
|
||||
|
||||
def SetupACL(mdbconf, options):
|
||||
noacl_drivers = ("managed-slapd")
|
||||
|
||||
if options.noacl or mdbconf["driver"] in noacl_drivers:
|
||||
print 'Skipping access control setup.'
|
||||
return
|
||||
|
||||
print 'Setting up access control...'
|
||||
|
||||
authops = GetAdminCmdAuth(options)
|
||||
baseops = GetAdminCmdBase(options)
|
||||
|
||||
ret = AdminCmd(options, authops + ['setup-rights'] + baseops)
|
||||
if ret != 0:
|
||||
print 'Rights could not be automatically set in the directory.'
|
||||
print 'You will manually have to grant privileges on the base'
|
||||
print 'to the Bongo Messaging Server object.'
|
||||
Input('Press Enter to continue')
|
||||
else:
|
||||
print 'Access control installed.'
|
||||
|
||||
def GeneratePasswords(options):
|
||||
print 'Generating server credentials...'
|
||||
|
||||
authops = GetAdminCmdAuth(options)
|
||||
|
||||
if AdminCmd(options, authops + ['setup-system-credential']) != 0:
|
||||
raise BongoError('Server credential generation failed.')
|
||||
|
||||
print 'Server credentials installed.'
|
||||
|
||||
#TODO: ask for files interactively
|
||||
def SetupCerts(options):
|
||||
authops = GetAdminCmdAuth(options)
|
||||
|
||||
certops = []
|
||||
if options.cert and options.key:
|
||||
print 'Installing provided certificate + key...'
|
||||
certops.append('--cert=\"%s\"' % options.cert)
|
||||
certops.append('--key=\"%s\"' % options.key)
|
||||
|
||||
if not certops:
|
||||
print 'Generating certificate + key...'
|
||||
certops.append('--ip=\"%s\"' % options.ip)
|
||||
certops.append('--domain=\"%s\"' % options.hostname)
|
||||
|
||||
if AdminCmd(options, authops + ['setup-ssl'] + certops) != 0:
|
||||
raise BongoError('Certificate + key installation failed.')
|
||||
|
||||
print 'Certificate + key installed.'
|
||||
|
||||
def AdminCmd(options, args):
|
||||
if not args:
|
||||
raise BongoError('No command specified')
|
||||
|
||||
if options.debug:
|
||||
args = ["--debug"] + args
|
||||
|
||||
log.debug("running %s %s", options.bongo_admin, ' '.join(args))
|
||||
ret = os.spawnv(os.P_WAIT, options.bongo_admin, [options.bongo_admin] + args)
|
||||
|
||||
if ret != 0:
|
||||
log.debug("command failed")
|
||||
|
||||
return ret
|
||||
|
||||
def ShellCmd(cmd):
|
||||
log.debug("running shell command: " + cmd)
|
||||
return os.popen(cmd).read().strip()
|
||||
|
||||
def Input(prompt, choices={}, default=None, options=None):
|
||||
if options and options.noprompt:
|
||||
return default
|
||||
|
||||
nums = []
|
||||
length = 0
|
||||
for key, val in choices.iteritems():
|
||||
nums.append(key)
|
||||
nums.sort()
|
||||
for key in choices.keys():
|
||||
if length < len(key):
|
||||
length = len(key)
|
||||
|
||||
entry = None
|
||||
while entry is None:
|
||||
i = 0
|
||||
for val in nums:
|
||||
i += 1
|
||||
print ' %d: %s - %s' % (i, val.ljust(length), choices[val])
|
||||
if default is None:
|
||||
pstr = prompt + ': '
|
||||
else:
|
||||
pstr = '%s [%s]: ' % (prompt, default)
|
||||
entry = raw_input(pstr)
|
||||
if entry.lower().strip() in choices.keys():
|
||||
entry = entry.lower().strip()
|
||||
elif entry.strip().isdigit() and int(entry.strip()) <= len(nums):
|
||||
entry = nums[int(entry.strip()) - 1]
|
||||
elif not entry.strip():
|
||||
entry = default
|
||||
if default is None:
|
||||
break
|
||||
elif entry and not choices:
|
||||
entry = entry
|
||||
else:
|
||||
entry = None
|
||||
|
||||
return entry
|
||||
|
||||
def Shutdown():
|
||||
if slapdConfig is not None:
|
||||
slapdConfig.killSlapd()
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
Shutdown()
|
||||
except BongoError, e:
|
||||
Shutdown()
|
||||
print wrap("ERROR: " + str(e))
|
||||
sys.exit(1)
|
||||
except KeyboardInterrupt:
|
||||
Shutdown()
|
||||
print
|
||||
sys.exit(1)
|
||||
@@ -1,150 +0,0 @@
|
||||
<setup>
|
||||
<services name="Bongo Services">
|
||||
<messaging-server name="Bongo Messaging Server">
|
||||
<property name="bongo-postmaster">\</property>
|
||||
<property name="context">\</property>
|
||||
<property name="official-name">localhost.localdomain</property>
|
||||
<!--<property name="ip-address">127.0.0.1</property>-->
|
||||
<property name="ssl-tls">1</property>
|
||||
<property name="ssl-allow-chained">0</property>
|
||||
<property name="work-directory">@XPL_DEFAULT_WORK_DIR@</property>
|
||||
<property name="dbf-directory">@XPL_DEFAULT_DBF_DIR@</property>
|
||||
<property name="nls-directory">@XPL_DEFAULT_NLS_DIR@</property>
|
||||
<property name="conn-mgr">Bongo Messaging Server\Connection Manager</property>
|
||||
<agent name="Store Agent" type="store-agent">
|
||||
<property name="module-name">BONGOSTORE.NLM</property>
|
||||
<property name="module-version">1</property>
|
||||
<property name="minimum-space">2048</property>
|
||||
<property name="scms-user-threshold">5</property>
|
||||
<property name="scms-size-threshold">5</property>
|
||||
<property name="message-store">@XPL_DEFAULT_MAIL_DIR@</property>
|
||||
<property name="scms-directory">@XPL_DEFAULT_SCMS_DIR@</property>
|
||||
<property name="client">
|
||||
<value>Address Book Agent</value>
|
||||
</property>
|
||||
</agent>
|
||||
<agent name="Queue Agent" type="queue-agent">
|
||||
<property name="module-name">BONGOQUEUE.NLM</property>
|
||||
<property name="module-version">1</property>
|
||||
|
||||
<!-- Can't comment out when nested under 'property'. Weird.
|
||||
These belong under <property name="client"> when the actual agents are
|
||||
reintroduced to this file.
|
||||
|
||||
<value>Calendar Text Command Agent</value>
|
||||
<value>Itip Agent</value>
|
||||
-->
|
||||
|
||||
<property name="client">
|
||||
<value>Proxy Agent</value>
|
||||
<value>SMTP Agent</value>
|
||||
<value>AntiSpam Agent</value>
|
||||
</property>
|
||||
<property name="quota-message">
|
||||
The user to whom this message was addressed has exceeded the allowed mailbox quota. Please resend the message at a later time.
|
||||
</property>
|
||||
<property name="queue-interval">30</property>
|
||||
<property name="queue-timeout">5</property>
|
||||
<property name="minimum-space">2048</property>
|
||||
<property name="bounce-return">1</property>
|
||||
<property name="bounce-cc-postmaster">0</property>
|
||||
<property name="spool-directory">@XPL_DEFAULT_SPOOL_DIR@</property>
|
||||
</agent>
|
||||
<agent name="Proxy Agent" type="proxy-agent">
|
||||
<property name="module-name">BONGOMAILPROX.NLM</property>
|
||||
<property name="module-version">1</property>
|
||||
<property name="time-interval">3</property>
|
||||
<property name="maximum-items">3</property>
|
||||
<property name="monitored-queue">Queue Agent</property>
|
||||
<property name="queue-server">Queue Agent</property>
|
||||
<property name="store-server">Store Agent</property>
|
||||
</agent>
|
||||
<agent name="SMTP Agent" type="smtp-agent">
|
||||
<property name="module-name">BONGOSMTP.NLM</property>
|
||||
<property name="module-version">1</property>
|
||||
<property name="port">25</property>
|
||||
<property name="ssl-port">465</property>
|
||||
<property name="monitored-queue">Queue Agent</property>
|
||||
<property name="queue-server">Queue Agent</property>
|
||||
<property name="domain">
|
||||
<value>localhost.localdomain</value>
|
||||
<value>localhost</value>
|
||||
</property>
|
||||
<property name="message-limit">0</property>
|
||||
<property name="routing">0</property>
|
||||
<property name="smtp-send-etrn">0</property>
|
||||
<property name="smtp-accept-etrn">1</property>
|
||||
<property name="ube-smtp-after-pop">1</property>
|
||||
<property name="ube-remote-auth-only">1</property>
|
||||
</agent>
|
||||
<agent name="Connection Manager" type="conn-mgr-agent">
|
||||
<property name="module-name">BONGOCONNMGR.NLM</property>
|
||||
<property name="module-version">1</property>
|
||||
<property name="timeout">15</property>
|
||||
<module name="User Module" type="cm-user-module">
|
||||
<property name="module-name">BONGOCMUSER.NLM</property>
|
||||
<property name="module-version">1</property>
|
||||
</module>
|
||||
<module name="Lists Module" type="cm-lists-module">
|
||||
<property name="module-name">BONGOCMLISTS.NLM</property>
|
||||
<property name="module-version">1</property>
|
||||
</module>
|
||||
<module name="RBL Module" type="cm-rbl-module">
|
||||
<property name="module-name">BONGOCMRBL.NLM</property>
|
||||
<property name="module-version">1</property>
|
||||
</module>
|
||||
<module name="RDNS Module" type="cm-rdns-module">
|
||||
<property name="module-name">BONGOCMRDNS.NLM</property>
|
||||
<property name="module-version">1</property>
|
||||
<property name="disabled">1</property>
|
||||
</module>
|
||||
</agent>
|
||||
<agent name="Address Book Agent" type="addressbook-agent">
|
||||
<property name="module-name">BONGOMSGLDAP.NLM</property>
|
||||
<property name="module-version">1</property>
|
||||
<property name="monitored-queue">Queue Agent</property>
|
||||
<property name="port">389</property>
|
||||
<property name="time-interval">1</property>
|
||||
<property name="ldap-options">1</property>
|
||||
</agent>
|
||||
<agent name="AntiSpam Agent" type="antispam-agent">
|
||||
<property name="module-name">BONGOANTISPAM.NLM</property>
|
||||
<property name="module-version">1</property>
|
||||
<property name="monitored-queue">Queue Agent</property>
|
||||
</agent>
|
||||
<!--
|
||||
<agent name="Calendar Text Command Agent" type="calcmd-agent">
|
||||
<property name="module-name">BONGOCALCMD.NLM</property>
|
||||
<property name="module-version">1</property>
|
||||
<property name="monitored-queue">Queue Agent</property>
|
||||
</agent>
|
||||
-->
|
||||
<agent name="Collector Agent" type="collector-agent">
|
||||
<property name="module-name">BONGOCALCMD.NLM</property>
|
||||
<property name="module-version">1</property>
|
||||
</agent>
|
||||
|
||||
<!--
|
||||
<agent name="Itip Agent" type="itip-agent">
|
||||
<property name="module-name">BONGOITIP.NLM</property>
|
||||
<property name="module-version">1</property>
|
||||
<property name="monitored-queue">Queue Agent</property>
|
||||
</agent>
|
||||
-->
|
||||
<agent name="IMAP Agent" type="imap-agent">
|
||||
<property name="module-name">BONGOIMAP.NLM</property>
|
||||
<property name="module-version">1</property>
|
||||
<property name="monitored-queue">Queue Agent</property>
|
||||
<property name="port">143</property>
|
||||
<property name="ssl-port">993</property>
|
||||
</agent>
|
||||
<agent name="POP Agent" type="pop-agent">
|
||||
<property name="module-name">BONGOPOP3.NLM</property>
|
||||
<property name="module-version">1</property>
|
||||
<property name="monitored-queue">Queue Agent</property>
|
||||
<property name="port">110</property>
|
||||
<property name="ssl-port">995</property>
|
||||
</agent>
|
||||
</messaging-server>
|
||||
</services>
|
||||
</setup>
|
||||
@@ -1,7 +0,0 @@
|
||||
# THIS FILE SHOULD NOT BE INSTALLED!
|
||||
|
||||
# It exists only to merge the src/[...]/bongosetup/bongo and src/libs/python/bongo
|
||||
# directories in the Bongo source tree together. In an installed
|
||||
# system, they're going to be in the same place.
|
||||
|
||||
__path__.append(__path__[0] + "/../../../libs/python/bongo")
|
||||
@@ -1,110 +0,0 @@
|
||||
<schema>
|
||||
<class name="User">
|
||||
<allowed-attributes>
|
||||
<attribute name="Novonyx:EMail Address" />
|
||||
<attribute name="Novonyx:Finger Message" />
|
||||
<attribute name="Novonyx:Reply Message" />
|
||||
<attribute name="Bongo:SMSAuthorizedPhones" />
|
||||
<attribute name="Bongo:CalCmdAddressSuffix" />
|
||||
<attribute name="BongoCalendarSubscriptions" />
|
||||
<attribute name="Novonyx:Forwarding Address" />
|
||||
<attribute name="Novonyx:Forwarding Enabled" />
|
||||
<attribute name="NIMS:WapMessageSize" />
|
||||
<attribute name="Novonyx:Vacation Message Enabled" />
|
||||
<attribute name="Novonyx:Reply Message" />
|
||||
<attribute name="Novonyx:Messaging Disabled" />
|
||||
<attribute name="Novonyx:Use Quota" />
|
||||
<attribute name="Novonyx:Quota Value" />
|
||||
<attribute name="Novonyx:Proxy List" />
|
||||
<attribute name="Novonyx:Language" />
|
||||
<attribute name="Novonyx:Color" />
|
||||
<attribute name="Novonyx:Font" />
|
||||
<attribute name="Novonyx:Preferences" />
|
||||
<attribute name="Novonyx:Timeout" />
|
||||
<attribute name="Novonyx:Privacy" />
|
||||
<attribute name="Novonyx:Addressbook Config" />
|
||||
<attribute name="Novonyx:Addressbook URL Public" />
|
||||
<attribute name="Novonyx:Addressbook" />
|
||||
<attribute name="Novonyx:Phrase" />
|
||||
<attribute name="Novonyx:Accounting Data" />
|
||||
<attribute name="Novonyx:Billing Data" />
|
||||
<attribute name="NIMS:Signature" />
|
||||
<attribute name="NIMS:Default Charset" />
|
||||
<attribute name="NIMS:Rule" />
|
||||
<attribute name="NIMS:FeatureSet" />
|
||||
<attribute name="NIMS:ParentObject" />
|
||||
<attribute name="NIMS:Template" />
|
||||
<attribute name="NIMS:Timezone" />
|
||||
<attribute name="NIMS:Locale" />
|
||||
<attribute name="NIMS:PasswordConfig" />
|
||||
<attribute name="NIMS:Title" />
|
||||
<attribute name="NIMS:TOMManager" />
|
||||
<attribute name="NIMS:TOMContexts" />
|
||||
<attribute name="NIMS:TOMDomains" />
|
||||
<attribute name="NIMS:TOMOptions" />
|
||||
<attribute name="WebAdmin:DefaultTemplate" />
|
||||
<attribute name="WebAdmin:DisallowedTemplates" />
|
||||
<attribute name="NetMail:AvailableShares" />
|
||||
<attribute name="NetMail:OwnedShares" />
|
||||
<attribute name="NetMail:AvailableProxies" />
|
||||
<attribute name="NetMail:OwnedProxies" />
|
||||
<attribute name="NetMail:ManagedResources" />
|
||||
</allowed-attributes>
|
||||
</class>
|
||||
<class name="Group">
|
||||
<allowed-attributes>
|
||||
<attribute name="Novonyx:Finger Message" />
|
||||
<attribute name="Novonyx:Messaging Disabled" />
|
||||
<attribute name="NIMS:Rule" />
|
||||
<attribute name="NIMS:FeatureSet" />
|
||||
<attribute name="NIMS:ParentObject" />
|
||||
<attribute name="WebAdmin:DefaultTemplate" />
|
||||
<attribute name="WebAdmin:DisallowedTemplates" />
|
||||
</allowed-attributes>
|
||||
</class>
|
||||
<class name="Organizational Role">
|
||||
<allowed-attributes>
|
||||
<attribute name="Novonyx:Messaging Disabled" />
|
||||
<attribute name="NIMS:ParentObject" />
|
||||
<attribute name="WebAdmin:DefaultTemplate" />
|
||||
<attribute name="WebAdmin:DisallowedTemplates" />
|
||||
</allowed-attributes>
|
||||
</class>
|
||||
<class name="Organization">
|
||||
<allowed-attributes>
|
||||
<attribute name="Novonyx:Domain" />
|
||||
<attribute name="Novonyx:Message Store" />
|
||||
<attribute name="Bongo:Index Store" />
|
||||
<attribute name="Novonyx:Messaging Disabled" />
|
||||
<attribute name="NIMS:Default Charset" />
|
||||
<attribute name="NIMS:Rule" />
|
||||
<attribute name="NIMS:FeatureSet" />
|
||||
<attribute name="NIMS:ParentObject" />
|
||||
<attribute name="WebAdmin:DefaultTemplate" />
|
||||
<attribute name="WebAdmin:DisallowedTemplates" />
|
||||
</allowed-attributes>
|
||||
</class>
|
||||
<class name="Organizational Unit">
|
||||
<allowed-attributes>
|
||||
<attribute name="Novonyx:Domain" />
|
||||
<attribute name="Novonyx:Message Store" />
|
||||
<attribute name="Bongo:Index Store" />
|
||||
<attribute name="Novonyx:Messaging Disabled" />
|
||||
<attribute name="NIMS:Default Charset" />
|
||||
<attribute name="NIMS:Rule" />
|
||||
<attribute name="NIMS:FeatureSet" />
|
||||
<attribute name="NIMS:ParentObject" />
|
||||
<attribute name="WebAdmin:DefaultTemplate" />
|
||||
<attribute name="WebAdmin:DisallowedTemplates" />
|
||||
</allowed-attributes>
|
||||
</class>
|
||||
<class name="NCP Server">
|
||||
<allowed-attributes>
|
||||
<attribute name="Novonyx:Messaging Server" />
|
||||
<attribute name="NIMS:PKeyFile" />
|
||||
<attribute name="NIMS:CAFile" />
|
||||
<attribute name="NetMail:MessagingServer" />
|
||||
<attribute name="WebAdminConfigDN" />
|
||||
</allowed-attributes>
|
||||
</class>
|
||||
</schema>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
# -*- Makefile -*-
|
||||
lib_LTLIBRARIES += libbongoconnmgr.la
|
||||
|
||||
#libbongonmap_la_LDFLAGS := -static
|
||||
libbongoconnmgr_la_SOURCES := \
|
||||
src/libs/connmgr/connmgr.c \
|
||||
src/libs/connmgr/hashcred.c
|
||||
|
||||
src/libs/connmgr/all: libbongoconnmgr.la
|
||||
src/libs/connmgr/clean: clean
|
||||
@@ -0,0 +1,17 @@
|
||||
# -*- Makefile -*-
|
||||
#
|
||||
# Do not edit!
|
||||
#
|
||||
# (unless this is Makefile.am.subdir)
|
||||
#
|
||||
# This file is a copy of the toplevel Makefile.am.subdir. If changes
|
||||
# need to be made, edit that file, and make update-makefiles, and
|
||||
# check the new files in.
|
||||
#
|
||||
# This is a skeletal automake file. The real automake fules for
|
||||
# building the targets for this directory can be found in the
|
||||
# Bongo.rules file. This file is simply here so that 'make all' can
|
||||
# work in each subdirectory.
|
||||
|
||||
all clean install:
|
||||
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
|
||||
@@ -0,0 +1,342 @@
|
||||
/****************************************************************************
|
||||
* <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 <memmgr.h>
|
||||
|
||||
#include <cmlib.h>
|
||||
#include <connmgr.h>
|
||||
#include <msgapi.h>
|
||||
|
||||
struct {
|
||||
unsigned char access[CM_HASH_SIZE];
|
||||
unsigned char pass[XPLHASH_MD5_LENGTH];
|
||||
MDBHandle directoryHandle;
|
||||
|
||||
BOOL debug;
|
||||
unsigned long address;
|
||||
|
||||
XplRWLock lock;
|
||||
unsigned char service[16 + 1];
|
||||
} CMLibrary = {
|
||||
{ '\0' },
|
||||
{ '\0' },
|
||||
NULL,
|
||||
|
||||
FALSE
|
||||
};
|
||||
|
||||
BOOL
|
||||
CMSendCommand(ConnMgrCommand *command, ConnMgrResult *result)
|
||||
{
|
||||
struct sockaddr_in fromSin;
|
||||
struct sockaddr_in toSin;
|
||||
int sock;
|
||||
int tries = 0;
|
||||
|
||||
do {
|
||||
result->result = CM_RESULT_UNKNOWN_ERROR;
|
||||
|
||||
XplRWReadLockAcquire(&CMLibrary.lock);
|
||||
strcpy(command->pass, CMLibrary.pass);
|
||||
XplRWReadLockRelease(&CMLibrary.lock);
|
||||
|
||||
memset(&fromSin, 0, sizeof(struct sockaddr_in));
|
||||
memset(&toSin, 0, sizeof(struct sockaddr_in));
|
||||
sock = IPsocket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (sock >= 0) {
|
||||
toSin.sin_family = AF_INET;
|
||||
toSin.sin_addr.s_addr = CMLibrary.address;
|
||||
toSin.sin_port = htons(CM_PORT);
|
||||
|
||||
fromSin.sin_family = AF_INET;
|
||||
fromSin.sin_addr.s_addr = 0;
|
||||
fromSin.sin_port = 0;
|
||||
|
||||
if (IPbind(sock, (struct sockaddr *)&fromSin, sizeof(fromSin)) == 0) {
|
||||
sendto(sock, (unsigned char *)command, sizeof(ConnMgrCommand), 0, (struct sockaddr*)&toSin, sizeof(toSin));
|
||||
XplIPRead(XPL_INT_TO_PTR(sock), (unsigned char *)result, sizeof(ConnMgrResult), 19);
|
||||
}
|
||||
IPclose(sock);
|
||||
}
|
||||
|
||||
if (result->result == CM_RESULT_MUST_AUTH) {
|
||||
xpl_hash_context ctx;
|
||||
|
||||
// Ensure that we don't walk off the edge of the buffer if garbage was sent
|
||||
result->detail.salt[sizeof(result->detail.salt) - 1] = '\0';
|
||||
|
||||
XplHashNew(&ctx, XPLHASH_MD5);
|
||||
XplHashWrite(&ctx, result->detail.salt, strlen(result->detail.salt));
|
||||
XplHashWrite(&ctx, CMLibrary.access, CM_HASH_SIZE);
|
||||
XplHashFinal(&ctx, XPLHASH_LOWERCASE, command->pass, XPLHASH_MD5_LENGTH);
|
||||
|
||||
/* Store the password so we don't have to generate it every time */
|
||||
XplRWWriteLockAcquire(&CMLibrary.lock);
|
||||
strcpy(CMLibrary.pass, command->pass);
|
||||
XplRWWriteLockRelease(&CMLibrary.lock);
|
||||
} else {
|
||||
return(TRUE);
|
||||
}
|
||||
} while (tries++ < 3);
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
int
|
||||
CMVerifyConnect(unsigned long address, unsigned char *comment, BOOL *requireAuth)
|
||||
{
|
||||
ConnMgrCommand command;
|
||||
ConnMgrResult result;
|
||||
|
||||
memset(&command, 0, sizeof(command));
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
command.command = CM_COMMAND_VERIFY;
|
||||
strcpy(command.event, CM_EVENT_CONNECT);
|
||||
command.address = address;
|
||||
command.detail.policy.default_result = CM_RESULT_ALLOWED;
|
||||
|
||||
CMSendCommand(&command, &result);
|
||||
|
||||
if (result.comment[0] != '\0') {
|
||||
strncpy(comment, result.comment, sizeof(result.comment));
|
||||
} else {
|
||||
comment[0] = '\0';
|
||||
}
|
||||
|
||||
if (requireAuth) {
|
||||
*requireAuth = result.detail.connect.requireAuth;
|
||||
}
|
||||
|
||||
return(result.result);
|
||||
}
|
||||
|
||||
int
|
||||
CMVerifyRelay(unsigned long address, unsigned char *user)
|
||||
{
|
||||
ConnMgrCommand command;
|
||||
ConnMgrResult result;
|
||||
|
||||
memset(&command, 0, sizeof(command));
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
command.command = CM_COMMAND_VERIFY;
|
||||
strcpy(command.event, CM_EVENT_RELAY);
|
||||
command.address = address;
|
||||
command.detail.policy.default_result = CM_RESULT_MUST_AUTH;
|
||||
|
||||
CMSendCommand(&command, &result);
|
||||
|
||||
if (result.result == CM_RESULT_ALLOWED && user) {
|
||||
strncpy(user, result.detail.user, MAXEMAILNAMESIZE);
|
||||
} else {
|
||||
user[0] = '\0';
|
||||
}
|
||||
|
||||
return(result.result);
|
||||
}
|
||||
|
||||
int
|
||||
CMDisconnected(unsigned long address)
|
||||
{
|
||||
ConnMgrCommand command;
|
||||
ConnMgrResult result;
|
||||
|
||||
memset(&command, 0, sizeof(command));
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
command.command = CM_COMMAND_NOTIFY;
|
||||
strcpy(command.event, CM_EVENT_DISCONNECTED);
|
||||
command.address = address;
|
||||
|
||||
CMSendCommand(&command, &result);
|
||||
return(result.result);
|
||||
}
|
||||
|
||||
int
|
||||
CMAuthenticated(unsigned long address, unsigned char *user)
|
||||
{
|
||||
ConnMgrCommand command;
|
||||
ConnMgrResult result;
|
||||
|
||||
memset(&command, 0, sizeof(command));
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
command.command = CM_COMMAND_NOTIFY;
|
||||
strcpy(command.event, CM_EVENT_AUTHENTICATED);
|
||||
command.address = address;
|
||||
|
||||
if (user) {
|
||||
strncpy(command.detail.authenticated.user, user, MAXEMAILNAMESIZE);
|
||||
} else {
|
||||
command.detail.authenticated.user[0] = '\0';
|
||||
}
|
||||
|
||||
CMSendCommand(&command, &result);
|
||||
return(result.result);
|
||||
}
|
||||
|
||||
int
|
||||
CMDelivered(unsigned long address, unsigned long recipients)
|
||||
{
|
||||
ConnMgrCommand command;
|
||||
ConnMgrResult result;
|
||||
|
||||
memset(&command, 0, sizeof(command));
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
command.command = CM_COMMAND_NOTIFY;
|
||||
strcpy(command.event, CM_EVENT_DELIVERED);
|
||||
command.address = address;
|
||||
command.detail.delivered.recipients = recipients;
|
||||
|
||||
CMSendCommand(&command, &result);
|
||||
return(result.result);
|
||||
}
|
||||
|
||||
int
|
||||
CMReceived(unsigned long address, unsigned long local, unsigned long invalid, unsigned long remote)
|
||||
{
|
||||
ConnMgrCommand command;
|
||||
ConnMgrResult result;
|
||||
|
||||
memset(&command, 0, sizeof(command));
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
command.command = CM_COMMAND_NOTIFY;
|
||||
strcpy(command.event, CM_EVENT_RECEIVED);
|
||||
command.address = address;
|
||||
|
||||
command.detail.received.local = local;
|
||||
command.detail.received.invalid = invalid;
|
||||
command.detail.received.remote = remote;
|
||||
|
||||
CMSendCommand(&command, &result);
|
||||
return(result.result);
|
||||
}
|
||||
|
||||
int
|
||||
CMFoundVirus(unsigned long address, unsigned long recipients, unsigned char *name)
|
||||
{
|
||||
ConnMgrCommand command;
|
||||
ConnMgrResult result;
|
||||
|
||||
memset(&command, 0, sizeof(command));
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
command.command = CM_COMMAND_NOTIFY;
|
||||
strcpy(command.event, CM_EVENT_VIRUS_FOUND);
|
||||
command.address = address;
|
||||
command.detail.virus.recipients = recipients;
|
||||
|
||||
if (name) {
|
||||
strncpy(command.detail.virus.name, name, 256);
|
||||
} else {
|
||||
command.detail.virus.name[0] = '\0';
|
||||
}
|
||||
|
||||
CMSendCommand(&command, &result);
|
||||
return(result.result);
|
||||
}
|
||||
|
||||
int
|
||||
CMSpamFound(unsigned long address, unsigned long recipients)
|
||||
{
|
||||
ConnMgrCommand command;
|
||||
ConnMgrResult result;
|
||||
|
||||
memset(&command, 0, sizeof(command));
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
command.command = CM_COMMAND_NOTIFY;
|
||||
strcpy(command.event, CM_EVENT_SPAM_FOUND);
|
||||
command.address = address;
|
||||
command.detail.spam.recipients = recipients;
|
||||
|
||||
CMSendCommand(&command, &result);
|
||||
return(result.result);
|
||||
}
|
||||
|
||||
int
|
||||
CMDOSDetected(unsigned long address, unsigned char *description)
|
||||
{
|
||||
ConnMgrCommand command;
|
||||
ConnMgrResult result;
|
||||
|
||||
memset(&command, 0, sizeof(command));
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
command.command = CM_COMMAND_NOTIFY;
|
||||
strcpy(command.event, CM_EVENT_DOS_DETECTED);
|
||||
command.address = address;
|
||||
|
||||
if (description) {
|
||||
strncpy(command.detail.dos.description, description, 256);
|
||||
} else {
|
||||
command.detail.dos.description[0] = '\0';
|
||||
}
|
||||
|
||||
CMSendCommand(&command, &result);
|
||||
return(result.result);
|
||||
}
|
||||
|
||||
BOOL
|
||||
CMInitialize(MDBHandle directoryHandle, unsigned char *service)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
|
||||
if (directoryHandle) {
|
||||
MDBValueStruct *v;
|
||||
|
||||
CMLibrary.directoryHandle = directoryHandle;
|
||||
|
||||
v = MDBCreateValueStruct(CMLibrary.directoryHandle, NULL);
|
||||
if (v) {
|
||||
MDBRead(MSGSRV_ROOT, MSGSRV_A_ACL, v);
|
||||
if (v->Used) {
|
||||
result = HashCredential(MsgGetServerDN(NULL), v->Value[0], CMLibrary.access);
|
||||
}
|
||||
|
||||
MDBFreeValues(v);
|
||||
|
||||
if (MsgReadIP((unsigned char *) MsgGetServerDN(NULL), MSGSRV_A_CONNMGR, v)) {
|
||||
CMLibrary.address = inet_addr(v->Value[0]);
|
||||
}
|
||||
|
||||
MDBDestroyValueStruct(v);
|
||||
}
|
||||
|
||||
XplRWLockInit(&CMLibrary.lock);
|
||||
}
|
||||
|
||||
if (service) {
|
||||
strncpy(CMLibrary.service, service, 16);
|
||||
CMLibrary.service[16] = '\0';
|
||||
} else {
|
||||
CMLibrary.service[0] = '\0';
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/****************************************************************************
|
||||
* <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>
|
||||
****************************************************************************/
|
||||
|
||||
#if 0
|
||||
#include <config.h>
|
||||
#include <xpl.h>
|
||||
#include <msgapi.h>
|
||||
#include <gatekeeper.h>
|
||||
#include <gklib.h>
|
||||
|
||||
#define ORGANIZATION_BUFFER_SIZE 100
|
||||
|
||||
#define GK_CRED_STORE_SIZE 4096
|
||||
#define GK_CRED_DIGEST_SIZE 16
|
||||
#define GK_CRED_CHUNK_SIZE (GK_CRED_STORE_SIZE * GK_CRED_DIGEST_SIZE) / GK_HASH_SIZE
|
||||
|
||||
static BOOL
|
||||
GetOrgName(unsigned char *Organization)
|
||||
{
|
||||
unsigned long len;
|
||||
unsigned char *ptr;
|
||||
unsigned char *buffer;
|
||||
|
||||
/* get the treename */
|
||||
buffer = MemStrdup(MsgGetServerDN(NULL));
|
||||
if (buffer) {
|
||||
if (buffer[0] == '\\') {
|
||||
ptr = strchr(buffer + 1, '\\');
|
||||
if (ptr) {
|
||||
len = ptr - (buffer + 1);
|
||||
if (len > 0) {
|
||||
if (len < ORGANIZATION_BUFFER_SIZE) {
|
||||
*ptr = '\0';
|
||||
strcpy(Organization, buffer + 1);
|
||||
*ptr = '\\';
|
||||
} else {
|
||||
memcpy(Organization, buffer + 1, ORGANIZATION_BUFFER_SIZE);
|
||||
Organization[ORGANIZATION_BUFFER_SIZE] = '\0';
|
||||
}
|
||||
MemFree(buffer);
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MemFree(buffer);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
BOOL
|
||||
HashCredential(unsigned char *Credential, unsigned char *Hash)
|
||||
{
|
||||
unsigned char organization[ORGANIZATION_BUFFER_SIZE + 1];
|
||||
unsigned char *ptr;
|
||||
unsigned long organizationLen;
|
||||
unsigned long len;
|
||||
|
||||
if (Hash && Credential) {
|
||||
len = strlen(Credential);
|
||||
if (GetOrgName(organization)) {
|
||||
organizationLen = strlen(organization);
|
||||
if (len >= GK_CRED_STORE_SIZE) {
|
||||
unsigned long i;
|
||||
MD5_CTX mdContext;
|
||||
unsigned char digest[GK_CRED_DIGEST_SIZE];
|
||||
unsigned char *srcPtr;
|
||||
unsigned char *dstPtr;
|
||||
unsigned char *dstEnd;
|
||||
|
||||
srcPtr = Credential;
|
||||
dstPtr = Hash;
|
||||
dstEnd = Hash + GK_HASH_SIZE;
|
||||
|
||||
MD5_Init(&mdContext);
|
||||
MD5_Update(&mdContext, srcPtr, GK_CRED_CHUNK_SIZE);
|
||||
MD5_Update(&mdContext, organization, organizationLen);
|
||||
MD5_Final(digest, &mdContext);
|
||||
|
||||
srcPtr += GK_CRED_CHUNK_SIZE;
|
||||
|
||||
for (i = 0; i < GK_CRED_DIGEST_SIZE; i++) {
|
||||
if (dstPtr < dstEnd) {
|
||||
*dstPtr = digest[i];
|
||||
dstPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
MD5_Init(&mdContext);
|
||||
MD5_Update(&mdContext, srcPtr, GK_CRED_CHUNK_SIZE);
|
||||
MD5_Update(&mdContext, Hash, dstPtr - Hash);
|
||||
MD5_Final(digest, &mdContext);
|
||||
|
||||
srcPtr += GK_CRED_CHUNK_SIZE;
|
||||
|
||||
for (i = 0; i < GK_CRED_DIGEST_SIZE; i++) {
|
||||
if (dstPtr < dstEnd) {
|
||||
*dstPtr = digest[i];
|
||||
dstPtr++;
|
||||
}
|
||||
}
|
||||
} while (dstPtr < dstEnd);
|
||||
|
||||
/* Hash now contains a non-terminated 128 byte octet string */
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
XplConsolePrintf("\rGate Keeper credentials are not properly configured!\r\n");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
XplConsolePrintf("\Bongo can not determine what organization it is running on.\r\n");
|
||||
return(FALSE);
|
||||
}
|
||||
return(FALSE);
|
||||
}
|
||||
#endif
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE log4c SYSTEM "">
|
||||
|
||||
<log4c version="0.1.0">
|
||||
<log4c version="0.3.1">
|
||||
|
||||
<config>
|
||||
<bufsize>0</bufsize>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# -*- Makefile -*-
|
||||
mdb_LTLIBRARIES += libmdbfile.la
|
||||
|
||||
libmdbfile_la_SOURCES := \
|
||||
src/libs/mdb-file/mdbfile.c \
|
||||
src/libs/mdb-file/mdbfilep.h
|
||||
|
||||
libmdbfile_la_CPPFLAGS := $(AM_CPPFLAGS) \
|
||||
-DLOCALSTATEDIR=\""$(localstatedir)"\" \
|
||||
-DMDB_INTERNAL
|
||||
|
||||
libmdbfile_la_LDFLAGS := -module -avoid-version
|
||||
libmdbfile_la_LIBADD := \
|
||||
libbongoutil.la \
|
||||
libbongomemmgr.la \
|
||||
libbongoxpl.la
|
||||
|
||||
src/libs/mdb-file/all: libmdbfile.la
|
||||
src/libs/mdb-file/clean: clean
|
||||
@@ -0,0 +1,17 @@
|
||||
# -*- Makefile -*-
|
||||
#
|
||||
# Do not edit!
|
||||
#
|
||||
# (unless this is Makefile.am.subdir)
|
||||
#
|
||||
# This file is a copy of the toplevel Makefile.am.subdir. If changes
|
||||
# need to be made, edit that file, and make update-makefiles, and
|
||||
# check the new files in.
|
||||
#
|
||||
# This is a skeletal automake file. The real automake fules for
|
||||
# building the targets for this directory can be found in the
|
||||
# Bongo.rules file. This file is simply here so that 'make all' can
|
||||
# work in each subdirectory.
|
||||
|
||||
all clean install:
|
||||
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
* <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 MDBP_H
|
||||
#define MDBP_H
|
||||
|
||||
/* Little helpers */
|
||||
#define MDB_CONTEXT_IS_VALID(ValueStruct) (ValueStruct->Flags & MDB_FLAGS_CONTEXT_VALID)
|
||||
|
||||
/* Bit definitions */
|
||||
#define MDB_FLAGS_ALLOCATED_HANDLE (unsigned long)(1<<0) /* The Init function has allocated the handle */
|
||||
#define MDB_FLAGS_CONTEXT_VALID (unsigned long)(1<<1) /* The Context handle is valid */
|
||||
#define MDB_FLAGS_CONTEXT_DUPLICATE (unsigned long)(1<<2) /* The context handle is duplicated, do not free it */
|
||||
#define MDB_FLAGS_BASEDN_CHANGED (unsigned long)(1<<3) /* Caching uses this, if the DN of a context is changed, this is set */
|
||||
|
||||
#define VALUE_ALLOC_SIZE 20
|
||||
#define VALUE_BUFFER_SIZE (10 * 1024)
|
||||
|
||||
#define ERR_NO_SUCH_ENTRY 0xFFFFFDA7
|
||||
#define ERR_NO_SUCH_VALUE 0xFFFFFDA6
|
||||
#define ERR_NO_SUCH_ATTRIBUTE 0xFFFFFDA5
|
||||
#define ERR_NO_SUCH_CLASS 0xFFFFFDA4
|
||||
#define ERR_NO_SUCH_PARTITION 0xFFFFFDA3
|
||||
#define ERR_ENTRY_ALREADY_EXISTS 0xFFFFFDA2
|
||||
#define ERR_NOT_EFFECTIVE_CLASS 0xFFFFFDA1
|
||||
#define ERR_ILLEGAL_ATTRIBUTE 0xFFFFFDA0
|
||||
#define ERR_MISSING_MANDATORY 0xFFFFFD9F
|
||||
#define ERR_ILLEGAL_DS_NAME 0xFFFFFD9E
|
||||
#define ERR_ILLEGAL_CONTAINMENT 0xFFFFFD9D
|
||||
#define ERR_CANT_HAVE_MULTIPLE_VALUES 0xFFFFFD9C
|
||||
#define ERR_SYNTAX_VIOLATION 0xFFFFFD9B
|
||||
#define ERR_DUPLICATE_VALUE 0xFFFFFD9A
|
||||
#define ERR_ATTRIBUTE_ALREADY_EXISTS 0xFFFFFD99
|
||||
#define ERR_MAXIMUM_ENTRIES_EXIST 0xFFFFFD98
|
||||
#define ERR_DATABASE_FORMAT 0xFFFFFD97
|
||||
#define ERR_INCONSISTENT_DATABASE 0xFFFFFD96
|
||||
#define ERR_INVALID_COMPARISON 0xFFFFFD95
|
||||
#define ERR_COMPARISON_FAILED 0xFFFFFD94
|
||||
#define ERR_TRANSACTIONS_DISABLED 0xFFFFFD93
|
||||
#define ERR_INVALID_TRANSPORT 0xFFFFFD92
|
||||
#define ERR_SYNTAX_INVALID_IN_NAME 0xFFFFFD91
|
||||
#define ERR_TRANSPORT_FAILURE 0xFFFFFD8F
|
||||
#define ERR_ALL_REFERRALS_FAILED 0xFFFFFD8E
|
||||
#define ERR_CANT_REMOVE_NAMING_VALUE 0xFFFFFD8D
|
||||
#define ERR_OBJECT_CLASS_VIOLATION 0xFFFFFD8C
|
||||
#define ERR_ENTRY_IS_NOT_LEAF 0xFFFFFD8B
|
||||
#define ERR_DIFFERENT_TREE 0xFFFFFD8A
|
||||
#define ERR_SYSTEM_FAILURE 0xFFFFFD88
|
||||
#define ERR_INVALID_ENTRY_FOR_ROOT 0xFFFFFD87
|
||||
#define ERR_NO_REFERRALS 0xFFFFFD86
|
||||
#define ERR_REMOTE_FAILURE 0xFFFFFD85
|
||||
#define ERR_UNREACHABLE_SERVER 0XFFFFFD84
|
||||
#define ERR_NO_CHARACTER_MAPPING 0XFFFFFD82
|
||||
#define ERR_INCOMPLETE_AUTHENTICATION 0XFFFFFD81
|
||||
#define ERR_INVALID_CERTIFICATE 0xFFFFFD80
|
||||
#define ERR_INVALID_REQUEST 0xFFFFFD7F
|
||||
#define ERR_INVALID_ITERATION 0xFFFFFD7E
|
||||
#define ERR_SCHEMA_IS_NONREMOVABLE 0xFFFFFD7D
|
||||
#define ERR_SCHEMA_IS_IN_USE 0xFFFFFD7C
|
||||
#define ERR_CLASS_ALREADY_EXISTS 0xFFFFFD7B
|
||||
#define ERR_BAD_NAMING_ATTRIBUTES 0xFFFFFD7A
|
||||
#define ERR_INSUFFICIENT_STACK 0xFFFFFD78
|
||||
#define ERR_INSUFFICIENT_BUFFER 0xFFFFFD77
|
||||
#define ERR_AMBIGUOUS_CONTAINMENT 0xFFFFFD76
|
||||
#define ERR_AMBIGUOUS_NAMING 0xFFFFFD75
|
||||
#define ERR_DUPLICATE_MANDATORY 0xFFFFFD74
|
||||
#define ERR_DUPLICATE_OPTIONAL 0xFFFFFD73
|
||||
#define ERR_RECORD_IN_USE 0xFFFFFD6C
|
||||
#define ERR_ENTRY_NOT_CONTAINER 0xFFFFFD64
|
||||
#define ERR_FAILED_AUTHENTICATION 0xFFFFFD63
|
||||
#define ERR_INVALID_CONTEXT 0xFFFFFD62
|
||||
#define ERR_NO_SUCH_PARENT 0xFFFFFD61
|
||||
#define ERR_NO_ACCESS 0xFFFFFD60
|
||||
#define ERR_INVALID_NAME_SERVICE 0xFFFFFD5E
|
||||
#define ERR_INVALID_TASK 0xFFFFFD5D
|
||||
#define ERR_INVALID_CONN_HANDLE 0xFFFFFD5C
|
||||
#define ERR_INVALID_IDENTITY 0xFFFFFD5B
|
||||
#define ERR_DUPLICATE_ACL 0xFFFFFD5A
|
||||
#define ERR_ALIAS_OF_AN_ALIAS 0xFFFFFD57
|
||||
#define ERR_INVALID_RDN 0xFFFFFD4E
|
||||
#define ERR_INCORRECT_BASE_CLASS 0xFFFFFD4C
|
||||
#define ERR_MISSING_REFERENCE 0xFFFFFD4B
|
||||
#define ERR_LOST_ENTRY 0xFFFFFD4A
|
||||
#define ERR_FATAL 0xFFFFFD45
|
||||
|
||||
typedef struct {
|
||||
/* Semi-public; known to the main MDB library */
|
||||
unsigned char Description[128];
|
||||
struct _MDBInterfaceStruct *Interface;
|
||||
|
||||
/* Private */
|
||||
unsigned char Dirname[XPL_MAX_PATH + 1];
|
||||
BOOL ReadOnly;
|
||||
} MDBFILEContextStruct;
|
||||
|
||||
typedef MDBFILEContextStruct *MDBHandle;
|
||||
|
||||
typedef struct {
|
||||
/* Public part, exposed to allow simpler code */
|
||||
unsigned char **Value;
|
||||
unsigned long Used;
|
||||
unsigned long ErrNo;
|
||||
struct _MDBInterfaceStruct *Interface;
|
||||
|
||||
/* Private part, not exposed in public header */
|
||||
unsigned long Flags;
|
||||
unsigned long Allocated;
|
||||
unsigned char *BaseDN;
|
||||
unsigned char Buffer[VALUE_BUFFER_SIZE];
|
||||
unsigned char Path[XPL_MAX_PATH + 1];
|
||||
unsigned char Filename[(XPL_MAX_PATH * 4) + 1];
|
||||
|
||||
MDBFILEContextStruct *Handle;
|
||||
} MDBValueStruct;
|
||||
|
||||
typedef struct {
|
||||
BOOL Initialized;
|
||||
|
||||
unsigned int EntriesLeft;
|
||||
|
||||
FILE *File;
|
||||
|
||||
MDBValueStruct *V;
|
||||
|
||||
unsigned char Buffer[VALUE_BUFFER_SIZE];
|
||||
unsigned char Filename[(XPL_MAX_PATH * 4) + 1];
|
||||
|
||||
unsigned long Offset;
|
||||
} MDBEnumStruct;
|
||||
|
||||
typedef struct _MDBFILEBaseSchemaAttributes {
|
||||
unsigned char *name;
|
||||
unsigned long flags;
|
||||
unsigned long type;
|
||||
unsigned char *asn1;
|
||||
} MDBFILEBaseSchemaAttributes;
|
||||
|
||||
typedef struct _MDBFILEBaseSchemaClasses {
|
||||
unsigned char *name;
|
||||
unsigned long flags;
|
||||
unsigned char *asn1;
|
||||
unsigned char *superClass;
|
||||
unsigned char *containedBy;
|
||||
unsigned char *namedBy;
|
||||
unsigned char *mandatory;
|
||||
unsigned char *optional;
|
||||
} MDBFILEBaseSchemaClasses;
|
||||
|
||||
MDBFILEBaseSchemaAttributes MDBFILEBaseSchemaAttributesList[] = {
|
||||
{ "ACL",64,17,"2.16.840.1.113719.1.1.4.1.2" },
|
||||
{ "Aliased Object Name",69,1,"2.5.4.1" },
|
||||
{ "Back Link",268,23,"2.16.840.1.113719.1.1.4.1.6" },
|
||||
{ "Bindery Property",12,32,"2.16.840.1.113719.1.1.4.1.8" },
|
||||
{ "Bindery Object Restriction",13,8,"2.16.840.1.113719.1.1.4.1.7" },
|
||||
{ "Bindery Type",45,5,"2.16.840.1.113719.1.1.4.1.9" },
|
||||
{ "CA Private Key",93,32,"2.16.840.1.113719.1.1.4.1.11" },
|
||||
{ "CA Public Key",205,32,"2.16.840.1.113719.1.1.4.1.12" },
|
||||
{ "Cartridge",100,3,"2.16.840.1.113719.1.1.4.1.10" },
|
||||
{ "CN",102,3,"2.5.4.3" },
|
||||
{ "Printer Configuration",69,32,"2.16.840.1.113719.1.1.4.1.78" },
|
||||
{ "Convergence",71,8,"2.16.840.1.113719.1.1.4.1.15" },
|
||||
{ "C",103,3,"2.5.4.6" },
|
||||
{ "Default Queue",325,1,"2.16.840.1.113719.1.1.4.1.18" },
|
||||
{ "Description",102,3,"2.5.4.13" },
|
||||
{ "Partition Creation Time",205,19,"2.16.840.1.113719.1.1.4.1.64" },
|
||||
{ "Facsimile Telephone Number",68,11,"2.5.4.23" },
|
||||
{ "High Convergence Sync Interval",69,27,"2.16.840.1.113719.1.1.4.1.117" },
|
||||
{ "Group Membership",580,1,"2.16.840.1.113719.1.1.4.1.25" },
|
||||
{ "Home Directory",71,15,"2.16.840.1.113719.1.1.4.1.26" },
|
||||
{ "Host Device",69,1,"2.16.840.1.113719.1.1.4.1.27" },
|
||||
{ "Host Resource Name",101,3,"2.16.840.1.113719.1.1.4.1.28" },
|
||||
{ "Host Server",69,1,"2.16.840.1.113719.1.1.4.1.29" },
|
||||
{ "Inherited ACL",76,17,"2.16.840.1.113719.1.1.4.1.30" },
|
||||
{ "L",102,3,"2.5.4.7" },
|
||||
{ "Login Allowed Time Map",71,32,"2.16.840.1.113719.1.1.4.1.39" },
|
||||
{ "Login Disabled",69,7,"2.16.840.1.113719.1.1.4.1.40" },
|
||||
{ "Login Expiration Time",69,24,"2.16.840.1.113719.1.1.4.1.41" },
|
||||
{ "Login Grace Limit",69,8,"2.16.840.1.113719.1.1.4.1.42" },
|
||||
{ "Login Grace Remaining",69,22,"2.16.840.1.113719.1.1.4.1.43" },
|
||||
{ "Login Intruder Address",69,12,"2.16.840.1.113719.1.1.4.1.44" },
|
||||
{ "Login Intruder Attempts",69,22,"2.16.840.1.113719.1.1.4.1.45" },
|
||||
{ "Login Intruder Limit",69,8,"2.16.840.1.113719.1.1.4.1.46" },
|
||||
{ "Intruder Attempt Reset Interval",69,27,"2.16.840.1.113719.1.1.4.1.31" },
|
||||
{ "Login Intruder Reset Time",69,24,"2.16.840.1.113719.1.1.4.1.47" },
|
||||
{ "Login Maximum Simultaneous",69,8,"2.16.840.1.113719.1.1.4.1.48" },
|
||||
{ "Login Script",69,21,"2.16.840.1.113719.1.1.4.1.49" },
|
||||
{ "Login Time",5,24,"2.16.840.1.113719.1.1.4.1.50" },
|
||||
{ "Member",68,1,"2.5.4.31" },
|
||||
{ "Memory",69,8,"2.16.840.1.113719.1.1.4.1.52" },
|
||||
{ "EMail Address",228,14,"0.9.2342.19200300.100.1.3" },
|
||||
{ "Network Address",68,12,"2.16.840.1.113719.1.1.4.1.55" },
|
||||
{ "Network Address Restriction",68,12,"2.16.840.1.113719.1.1.4.1.56" },
|
||||
{ "Notify",68,25,"2.16.840.1.113719.1.1.4.1.57" },
|
||||
{ "Obituary",76,32,"2.16.840.1.113719.1.1.4.1.114" },
|
||||
{ "Object Class",196,20,"2.5.4.0" },
|
||||
{ "Operator",324,1,"2.16.840.1.113719.1.1.4.1.59" },
|
||||
{ "OU",102,3,"2.5.4.11" },
|
||||
{ "O",102,3,"2.5.4.10" },
|
||||
{ "Owner",68,1,"2.5.4.32" },
|
||||
{ "Page Description Language",102,4,"2.16.840.1.113719.1.1.4.1.63" },
|
||||
{ "Passwords Used",86,32,"2.16.840.1.113719.1.1.4.1.65" },
|
||||
{ "Password Allow Change",69,7,"2.16.840.1.113719.1.1.4.1.66" },
|
||||
{ "Password Expiration Interval",69,27,"2.16.840.1.113719.1.1.4.1.67" },
|
||||
{ "Password Expiration Time",69,24,"2.16.840.1.113719.1.1.4.1.68" },
|
||||
{ "Password Minimum Length",69,8,"2.16.840.1.113719.1.1.4.1.69" },
|
||||
{ "Password Required",69,7,"2.16.840.1.113719.1.1.4.1.70" },
|
||||
{ "Password Unique Required",69,7,"2.16.840.1.113719.1.1.4.1.71" },
|
||||
{ "Path",68,15,"2.16.840.1.113719.1.1.4.1.72" },
|
||||
{ "Physical Delivery Office Name",102,3,"2.5.4.19" },
|
||||
{ "Postal Address",68,18,"2.5.4.16" },
|
||||
{ "Postal Code",102,3,"2.5.4.17" },
|
||||
{ "Postal Office Box",102,3,"2.5.4.18" },
|
||||
{ "Print Job Configuration",69,21,"2.16.840.1.113719.1.1.4.1.80" },
|
||||
{ "Printer Control",69,21,"2.16.840.1.113719.1.1.4.1.79" },
|
||||
{ "Private Key",93,32,"2.16.840.1.113719.1.1.4.1.82" },
|
||||
{ "Profile",69,1,"2.16.840.1.113719.1.1.4.1.83" },
|
||||
{ "Public Key",205,32,"2.16.840.1.113719.1.1.4.1.84" },
|
||||
{ "Queue",68,25,"2.16.840.1.113719.1.1.4.1.85" },
|
||||
{ "Queue Directory",359,3,"2.16.840.1.113719.1.1.4.1.86" },
|
||||
{ "Reference",1052,1,"2.16.840.1.113719.1.1.4.1.115" },
|
||||
{ "Replica",204,16,"2.16.840.1.113719.1.1.4.1.88" },
|
||||
{ "Resource",68,1,"2.16.840.1.113719.1.1.4.1.89" },
|
||||
{ "Role Occupant",68,1,"2.5.4.33" },
|
||||
{ "Higher Privileges",836,1,"2.16.840.1.113719.1.1.4.1.116" },
|
||||
{ "Security Equals",836,1,"2.16.840.1.113719.1.1.4.1.92" },
|
||||
{ "See Also",68,1,"2.5.4.34" },
|
||||
{ "Serial Number",102,4,"2.16.840.1.113719.1.1.4.1.94" },
|
||||
{ "Server",324,1,"2.16.840.1.113719.1.1.4.1.95" },
|
||||
{ "S",102,3,"2.5.4.8" },
|
||||
{ "Status",197,8,"2.16.840.1.113719.1.1.4.1.98" },
|
||||
{ "SA",102,3,"2.5.4.9" },
|
||||
{ "Supported Typefaces",102,3,"2.16.840.1.113719.1.1.4.1.102" },
|
||||
{ "Supported Services",102,3,"2.16.840.1.113719.1.1.4.1.101" },
|
||||
{ "Surname",230,3,"2.5.4.4" },
|
||||
{ "Telephone Number",100,10,"2.5.4.20" },
|
||||
{ "Title",102,3,"2.5.4.12" },
|
||||
{ "Unknown",4,0,"2.16.840.1.113719.1.1.4.1.109" },
|
||||
{ "User",324,1,"2.16.840.1.113719.1.1.4.1.111" },
|
||||
{ "Version",231,3,"2.16.840.1.113719.1.1.4.1.112" },
|
||||
{ "Account Balance",69,22,"2.16.840.1.113719.1.1.4.1.1" },
|
||||
{ "Allow Unlimited Credit",69,7,"2.16.840.1.113719.1.1.4.1.4" },
|
||||
{ "Low Convergence Reset Time",69,24,"2.16.840.1.113719.1.1.4.1.118" },
|
||||
{ "Minimum Account Balance",69,8,"2.16.840.1.113719.1.1.4.1.54" },
|
||||
{ "Low Convergence Sync Interval",69,27,"2.16.840.1.113719.1.1.4.1.104" },
|
||||
{ "Device",68,1,"2.16.840.1.113719.1.1.4.1.21" },
|
||||
{ "Message Server",69,1,"2.16.840.1.113719.1.1.4.1.53" },
|
||||
{ "Language",69,6,"2.16.840.1.113719.1.1.4.1.34" },
|
||||
{ "Supported Connections",69,8,"2.16.840.1.113719.1.1.4.1.100" },
|
||||
{ "Type Creator Map",69,21,"2.16.840.1.113719.1.1.4.1.107" },
|
||||
{ "UID",69,8,"2.16.840.1.113719.1.1.4.1.108" },
|
||||
{ "GID",69,8,"2.16.840.1.113719.1.1.4.1.24" },
|
||||
{ "Unknown Base Class",39,3,"2.16.840.1.113719.1.1.4.1.110" },
|
||||
{ "Received Up To",204,19,"2.16.840.1.113719.1.1.4.1.87" },
|
||||
{ "Synchronized Up To",1164,19,"2.16.840.1.113719.1.1.4.1.33" },
|
||||
{ "Authority Revocation",77,32,"2.16.840.1.113719.1.1.4.1.5" },
|
||||
{ "Certificate Revocation",77,32,"2.16.840.1.113719.1.1.4.1.13" },
|
||||
{ "Cross Certificate Pair",68,32,"2.16.840.1.113719.1.1.4.1.17" },
|
||||
{ "Locked By Intruder",69,7,"2.16.840.1.113719.1.1.4.1.37" },
|
||||
{ "Printer",68,25,"2.16.840.1.113719.1.1.4.1.77" },
|
||||
{ "Detect Intruder",69,7,"2.16.840.1.113719.1.1.4.1.20" },
|
||||
{ "Lockout After Detection",69,7,"2.16.840.1.113719.1.1.4.1.38" },
|
||||
{ "Intruder Lockout Reset Interval",69,27,"2.16.840.1.113719.1.1.4.1.32" },
|
||||
{ "Server Holds",68,26,"2.16.840.1.113719.1.1.4.1.96" },
|
||||
{ "SAP Name",103,3,"2.16.840.1.113719.1.1.4.1.91" },
|
||||
{ "Volume",69,1,"2.16.840.1.113719.1.1.4.1.113" },
|
||||
{ "Last Login Time",13,24,"2.16.840.1.113719.1.1.4.1.35" },
|
||||
{ "Print Server",69,25,"2.16.840.1.113719.1.1.4.1.81" },
|
||||
{ "NNS Domain",102,3,"2.16.840.1.113719.1.1.4.1.119" },
|
||||
{ "Full Name",102,3,"2.16.840.1.113719.1.1.4.1.120" },
|
||||
{ "Partition Control",204,25,"2.16.840.1.113719.1.1.4.1.121" },
|
||||
{ "Revision",2189,22,"2.16.840.1.113719.1.1.4.1.122" },
|
||||
{ "Certificate Validity Interval",71,27,"2.16.840.1.113719.1.1.4.1.123" },
|
||||
{ "External Synchronizer",68,32,"2.16.840.1.113719.1.1.4.1.124" },
|
||||
{ "Messaging Database Location",69,15,"2.16.840.1.113719.1.1.4.1.125" },
|
||||
{ "Message Routing Group",68,1,"2.16.840.1.113719.1.1.4.1.126" },
|
||||
{ "Messaging Server",68,1,"2.16.840.1.113719.1.1.4.1.127" },
|
||||
{ "Postmaster",68,1,"2.16.840.1.113719.1.1.4.1.128" },
|
||||
{ "Mailbox Location",197,1,"2.16.840.1.113719.1.1.4.1.162" },
|
||||
{ "Mailbox ID",231,3,"2.16.840.1.113719.1.1.4.1.163" },
|
||||
{ "External Name",69,32,"2.16.840.1.113719.1.1.4.1.164" },
|
||||
{ "Security Flags",69,8,"2.16.840.1.113719.1.1.4.1.165" },
|
||||
{ "Messaging Server Type",103,3,"2.16.840.1.113719.1.1.4.1.166" },
|
||||
{ "Last Referenced Time",1029,19,"2.16.840.1.113719.1.1.4.1.167" },
|
||||
{ "Given Name",230,3,"2.5.4.42" },
|
||||
{ "Initials",230,3,"2.5.4.43" },
|
||||
{ "Generational Qualifier",231,3,"2.16.840.1.113719.1.1.4.1.170" },
|
||||
{ "Profile Membership",580,1,"2.16.840.1.113719.1.1.4.1.171" },
|
||||
{ "DS Revision",197,8,"2.16.840.1.113719.1.1.4.1.172" },
|
||||
{ "Supported Gateway",102,3,"2.16.840.1.113719.1.1.4.1.173" },
|
||||
{ "Equivalent To Me",324,1,"2.16.840.1.113719.1.1.4.1.174" },
|
||||
{ "Replica Up To",1164,32,"2.16.840.1.113719.1.1.4.1.175" },
|
||||
{ "Partition Status",1164,32,"2.16.840.1.113719.1.1.4.1.176" },
|
||||
{ "Permanent Config Parms",196,32,"2.16.840.1.113719.1.1.4.1.177" },
|
||||
{ "Timezone",133,32,"2.16.840.1.113719.1.1.4.1.178" },
|
||||
{ "Bindery Restriction Level",5,8,"2.16.840.1.113719.1.1.4.1.179" },
|
||||
{ "Transitive Vector",2252,32,"2.16.840.1.113719.1.1.4.1.180" },
|
||||
{ "T",102,3,"2.16.840.1.113719.1.1.4.1.181" },
|
||||
{ "Purge Vector",3212,19,"2.16.840.1.113719.1.1.4.1.183" },
|
||||
{ "Synchronization Tolerance",196,19,"2.16.840.1.113719.1.1.4.1.184" },
|
||||
{ "Password Management",69,0,"2.16.840.1.113719.1.1.4.1.185" },
|
||||
{ "Used By",332,15,"2.16.840.1.113719.1.1.4.1.186" },
|
||||
{ "Uses",332,15,"2.16.840.1.113719.1.1.4.1.187" },
|
||||
{ "Obituary Notify",76,32,"2.16.840.1.113719.1.1.4.1.500" },
|
||||
{ "GUID",207,32,"2.16.840.1.113719.1.1.4.1.501" },
|
||||
{ "Other GUID",198,32,"2.16.840.1.113719.1.1.4.1.502" },
|
||||
{ NULL,0,0,NULL },
|
||||
};
|
||||
|
||||
MDBFILEBaseSchemaClasses MDBFILEBaseSchemaClassesList[] = {
|
||||
{ "[Nothing]",3,NULL,NULL,NULL,NULL,NULL,NULL },
|
||||
{ "Top",3,"2.5.6.0",NULL,NULL,"T","Object Class,T","CA Public Key,Private Key,Certificate Validity Interval,Authority Revocation,Last Referenced Time,Equivalent To Me,ACL,Back Link,Bindery Property,Obituary,Reference,Revision,Cross Certificate Pair,Certificate Revocation,Used By,GUID,Other GUID" },
|
||||
{ "Tree Root",3,"2.16.840.1.113719.1.1.6.1.32","Top","[Nothing]",NULL,NULL,NULL },
|
||||
{ "Alias",2,"2.5.6.1","Top",NULL,NULL,"Aliased Object Name",NULL },
|
||||
{ "Country",3,"2.5.6.2","Top","Top,Tree Root,[Nothing]","C","C","Description" },
|
||||
{ "Locality",3,"2.5.6.3","Top","Locality,Country,Organizational Unit,Organization","L,S",NULL,"Description,L,See Also,S,SA" },
|
||||
{ "Organization",3,"2.5.6.4",NULL,"Top,Tree Root,Country,Locality,[Nothing]","O","O","Description,Facsimile Telephone Number,L,Login Script,EMail Address,Physical Delivery Office Name,Postal Address,Postal Code,Postal Office Box,Print Job Configuration,Printer Control,See Also,S,SA,Telephone Number,Login Intruder Limit,Intruder Attempt Reset Interval,Detect Intruder,Lockout After Detection,Intruder Lockout Reset Interval" },
|
||||
{ "Organizational Unit",3,"2.5.6.5",NULL,"Locality,Organization,Organizational Unit","OU","OU","Description,Facsimile Telephone Number,L,Login Script,EMail Address,Physical Delivery Office Name,Postal Address,Postal Code,Postal Office Box,Print Job Configuration,Printer Control,See Also,S,SA,Telephone Number,Login Intruder Limit,Intruder Attempt Reset Interval,Detect Intruder,Lockout After Detection,Intruder Lockout Reset Interval" },
|
||||
{ "Organizational Role",2,"2.5.6.8","Top","Organization,Organizational Unit","CN","CN","Description,Facsimile Telephone Number,L,EMail Address,OU,Physical Delivery Office Name,Postal Address,Postal Code,Postal Office Box,Role Occupant,See Also,S,SA,Telephone Number,Mailbox Location,Mailbox ID" },
|
||||
{ "Group",2,"2.5.6.17","Top","Organization,Organizational Unit","CN","CN","Description,L,Member,OU,O,Owner,See Also,GID,Full Name,EMail Address,Mailbox Location,Mailbox ID,Profile,Profile Membership,Login Script" },
|
||||
{ "Person",2,"2.5.6.6",NULL,"Organization,Organizational Unit","CN","CN","Description,See Also,Telephone Number,Full Name,Given Name,Initials,Generational Qualifier" },
|
||||
{ "Organizational Person",2,"2.5.6.7","Person","Organization,Organizational Unit","CN,OU",NULL,"Facsimile Telephone Number,L,EMail Address,OU,Physical Delivery Office Name,Postal Address,Postal Code,Postal Office Box,S,SA,Title,Mailbox Location,Mailbox ID" },
|
||||
{ "User",2,"2.5.6.10","Organizational Person",NULL,NULL,NULL,"Group Membership,Home Directory,Login Allowed Time Map,Login Disabled,Login Expiration Time,Login Grace Limit,Login Grace Remaining,Login Intruder Address,Login Intruder Attempts,Login Intruder Reset Time,Login Maximum Simultaneous,Login Script,Login Time,Network Address Restriction,Network Address,Passwords Used,Password Allow Change,Password Expiration Interval,Password Expiration Time,Password Minimum Length,Password Required,Password Unique Required,Print Job Configuration,Private Key,Profile,Public Key,Security Equals,Account Balance,Allow Unlimited Credit,Minimum Account Balance,Message Server,Language,UID,Locked By Intruder,Server Holds,Last Login Time,Type Creator Map,Higher Privileges,Printer Control,Security Flags,Profile Membership,Timezone" },
|
||||
{ "Device",2,"2.16.840.1.113719.1.1.6.1.6","Top","Organization,Organizational Unit","CN","CN","Description,L,Network Address,OU,O,Owner,See Also,Serial Number" },
|
||||
{ "Computer",2,"2.16.840.1.113719.1.1.6.1.4","Device",NULL,NULL,NULL,"Operator,Server,Status" },
|
||||
{ "Printer",2,"2.16.840.1.113719.1.1.6.1.17","Device",NULL,NULL,NULL,"Cartridge,Printer Configuration,Default Queue,Host Device,Print Server,Memory,Network Address Restriction,Notify,Operator,Page Description Language,Queue,Status,Supported Typefaces" },
|
||||
{ "Resource",0,"2.16.840.1.113719.1.1.6.1.21","TOp","Organization,Organizational Unit","CN","CN","Description,Host Resource Name,L,OU,O,See Also,Uses" },
|
||||
{ "Queue",2,"2.16.840.1.113719.1.1.6.1.20","Resource",NULL,NULL,"Queue Directory","Device,Operator,Server,User,Network Address,Volume,Host Server" },
|
||||
{ "Bindery Queue",2,"2.16.840.1.113719.1.1.6.1.3","Queue",NULL,"CN","Bindery Type",NULL },
|
||||
{ "Volume",2,"2.16.840.1.113719.1.1.6.1.26","Resource",NULL,NULL,"Host Server","Status" },
|
||||
{ "Directory Map",2,"2.16.840.1.113719.1.1.6.1.7","Resource",NULL,NULL,"Host Server","Path" },
|
||||
{ "Profile",2,"2.16.840.1.113719.1.1.6.1.19","Top","Organization,Organizational Unit","CN","CN,Login Script","Description,L,OU,O,See Also,Full Name" },
|
||||
{ "Server",0,"2.16.840.1.113719.1.1.6.1.22","Top","Organization,Organizational Unit","CN","CN","Description,Host Device,L,OU,O,Private Key,Public Key,Resource,See Also,Status,User,Version,Network Address,Account Balance,Allow Unlimited Credit,Minimum Account Balance,Full Name,Security Equals,Security Flags,Timezone" },
|
||||
{ "NCP Server",2,"2.16.840.1.113719.1.1.6.1.10","Server",NULL,NULL,NULL,"Operator,Supported Services,Messaging Server,DS Revision,Permanent Config Parms" },
|
||||
{ "Print Server",2,"2.16.840.1.113719.1.1.6.1.18","Server",NULL,NULL,NULL,"Operator,Printer,SAP Name" },
|
||||
{ "CommExec",2,"2.16.840.1.113719.1.1.6.1.31","Server",NULL,NULL,NULL,"Network Address Restriction" },
|
||||
{ "Bindery Object",2,"2.16.840.1.113719.1.1.6.1.2","Top","Organization,Organizational Unit","CN,Bindery Type","Bindery Object Restriction,Bindery Type,CN",NULL },
|
||||
{ "Unknown",3,"2.16.840.1.113719.1.1.6.1.24","Top",NULL,NULL,NULL,NULL },
|
||||
{ "Partition",0,"2.16.840.1.113719.1.1.6.1.15",NULL,NULL,NULL,NULL,"Convergence,Partition Creation Time,Replica,Inherited ACL,Low Convergence Sync Interval,Received Up To,Synchronized Up To,Authority Revocation,Certificate Revocation,CA Private Key,CA Public Key,Cross Certificate Pair,Low Convergence Reset Time,High Convergence Sync Interval,Partition Control,Replica Up To,Partition Status,Transitive Vector,Purge Vector,Synchronization Tolerance,Obituary Notify,Local Received Up To" },
|
||||
{ "AFP Server",2,"2.16.840.1.113719.1.1.6.1.0","Server",NULL,NULL,NULL,"Serial Number,Supported Connections" },
|
||||
{ "Messaging Server",2,"2.16.840.1.113719.1.1.6.1.27","Server",NULL,NULL,NULL,"Messaging Database Location,Message Routing Group,Postmaster,Supported Services,Messaging Server Type,Supported Gateway" },
|
||||
{ "Message Routing Group",2,"2.16.840.1.113719.1.1.6.1.28","Group",NULL,NULL,NULL,NULL },
|
||||
{ "External Entity",2,"2.16.840.1.113719.1.1.6.1.29","Top","Organization,Organizational Unit","CN,OU","CN","Description,See Also,Facsimile Telephone Number,L,EMail Address,OU,Physical Delivery Office Name,Postal Address,Postal Code,Postal Office Box,S,SA,Title,External Name,Mailbox Location,Mailbox ID" },
|
||||
{ "List",2,"2.16.840.1.113719.1.1.6.1.30","Top","Organization,Organizational Unit","CN","CN","Description,L,Member,OU,O,EMail Address,Mailbox Location,Mailbox ID,Owner,See Also,Full Name" },
|
||||
{ NULL,0,NULL,NULL,NULL,NULL,NULL,NULL }
|
||||
};
|
||||
|
||||
#endif /* MDBP_H */
|
||||
@@ -0,0 +1,33 @@
|
||||
# -*- Makefile -*-
|
||||
if HAVE_LDAP
|
||||
mdb_LTLIBRARIES += libmdbldap.la
|
||||
endif
|
||||
|
||||
libmdbldap_la_SOURCES := \
|
||||
src/libs/mdb-xldap/valarray.c \
|
||||
src/libs/mdb-xldap/schema.c \
|
||||
src/libs/mdb-xldap/mdbldap.c \
|
||||
src/libs/mdb-xldap/mdbldapp.h
|
||||
|
||||
libmdbldap_la_CPPFLAGS := $(AM_CPPFLAGS) \
|
||||
-DLOCALSTATEDIR=\""$(localstatedir)"\" \
|
||||
-DMDB_INTERNAL
|
||||
|
||||
libmdbldap_la_LDFLAGS = -module -avoid-version
|
||||
libmdbldap_la_LIBADD := \
|
||||
$(LDAP_LIBS) \
|
||||
libbongoutil.la \
|
||||
libbongoxpl.la \
|
||||
libbongomemmgr.la \
|
||||
libbongostreamio.la \
|
||||
$(top_builddir)/import/log4c/log4c/libbongolog4c.la
|
||||
|
||||
if HAVE_LDAP
|
||||
src/libs/mdb-xldap/all: libmdbldap.la
|
||||
src/libs/mdb-xldap/install:
|
||||
@cd $(top_builddir) && $(MAKE) $(MFLAGS) mdb_LTLIBRARIES=libmdbldap.la install-mdbLTLIBRARIES
|
||||
else
|
||||
src/libs/mdb-xldap/all:
|
||||
src/libs/mdb-xldap/install:
|
||||
endif
|
||||
src/libs/mdb-xldap/clean: clean
|
||||
@@ -0,0 +1,17 @@
|
||||
# -*- Makefile -*-
|
||||
#
|
||||
# Do not edit!
|
||||
#
|
||||
# (unless this is Makefile.am.subdir)
|
||||
#
|
||||
# This file is a copy of the toplevel Makefile.am.subdir. If changes
|
||||
# need to be made, edit that file, and make update-makefiles, and
|
||||
# check the new files in.
|
||||
#
|
||||
# This is a skeletal automake file. The real automake fules for
|
||||
# building the targets for this directory can be found in the
|
||||
# Bongo.rules file. This file is simply here so that 'make all' can
|
||||
# work in each subdirectory.
|
||||
|
||||
all clean install:
|
||||
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,146 @@
|
||||
#define LDAP_DEPRECATED 1
|
||||
#include <ldap.h>
|
||||
#include <config.h>
|
||||
#include <xpl.h>
|
||||
|
||||
/* compatibility with different client libraries */
|
||||
#ifndef LDAP_CONST
|
||||
#define LDAP_CONST const
|
||||
#endif
|
||||
#ifndef LDAP_OPT_SUCCESS
|
||||
#define LDAP_OPT_SUCCESS 0
|
||||
#endif
|
||||
#ifndef LDAP_EXOP_MODIFY_PASSWD
|
||||
#define LDAP_EXOP_MODIFY_PASSWD "1.3.6.1.4.1.4203.1.11.1"
|
||||
#endif
|
||||
#ifndef LDAP_TAG_EXOP_MODIFY_PASSWD_ID
|
||||
#define LDAP_TAG_EXOP_MODIFY_PASSWD_ID ((ber_tag_t) 0x80U)
|
||||
#endif
|
||||
#ifndef LDAP_TAG_EXOP_MODIFY_PASSWD_OLD
|
||||
#define LDAP_TAG_EXOP_MODIFY_PASSWD_OLD ((ber_tag_t) 0x81U)
|
||||
#endif
|
||||
#ifndef LDAP_TAG_EXOP_MODIFY_PASSWD_NEW
|
||||
#define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW ((ber_tag_t) 0x82U)
|
||||
#endif
|
||||
#ifndef LBER_USE_DER
|
||||
#define LBER_USE_DER 0x01
|
||||
#endif
|
||||
|
||||
#define MDBLDAP_FLAGS_ALLOCATED_HANDLE (unsigned long)(1 << 0)
|
||||
#define MDBLDAP_FLAGS_CONTEXT_VALID (unsigned long)(1 << 1)
|
||||
#define MDBLDAP_FLAGS_CONTEXT_DUPLICATE (unsigned long)(1 << 2)
|
||||
#define MDBLDAP_FLAGS_BASEDB_CHANGED (unsigned long)(1 << 3)
|
||||
|
||||
#define MDBLDAP_MIN_CONNECTIONS 4
|
||||
#define MDBLDAP_MAX_CONNECTIONS 8
|
||||
|
||||
#define MDBLDAP_DEFAULT_CACHE_SIZE 512
|
||||
|
||||
#define VALUE_ALLOC_SIZE 20
|
||||
|
||||
typedef struct {
|
||||
unsigned char Description[128];
|
||||
struct _MDBInterfaceStruct *Interface;
|
||||
char *binddn;
|
||||
char *passwd;
|
||||
|
||||
struct {
|
||||
int next;
|
||||
int min;
|
||||
int max;
|
||||
XplMutex mutex;
|
||||
LDAP **list;
|
||||
} conn;
|
||||
} MDBLDAPContextStruct;
|
||||
|
||||
typedef MDBLDAPContextStruct *MDBHandle;
|
||||
|
||||
typedef struct {
|
||||
unsigned char **Value;
|
||||
unsigned long Used;
|
||||
unsigned long ErrNo;
|
||||
struct _MDBInterfaceStruct *Interface;
|
||||
|
||||
MDBLDAPContextStruct *context;
|
||||
LDAP *ldap;
|
||||
unsigned char *base;
|
||||
unsigned char *lastDn;
|
||||
unsigned long allocated;
|
||||
BOOL duplicate;
|
||||
} MDBValueStruct;
|
||||
|
||||
typedef struct {
|
||||
char **vals;
|
||||
int next;
|
||||
int count;
|
||||
} MDBEnumStruct;
|
||||
|
||||
#ifndef MDB_INTERNAL
|
||||
#define MDB_INTERNAL
|
||||
#endif
|
||||
|
||||
#include <mdb.h>
|
||||
|
||||
/* schema.c */
|
||||
|
||||
typedef struct {
|
||||
char *val;
|
||||
char *oid;
|
||||
char **names;
|
||||
int namecnt;
|
||||
char *desc;
|
||||
char *equality;
|
||||
char *syntax;
|
||||
char *sup;
|
||||
BOOL singleval;
|
||||
int refcnt;
|
||||
BOOL visited;
|
||||
} MDBLDAPSchemaAttr;
|
||||
|
||||
typedef enum {
|
||||
TYPE_ABSTRACT,
|
||||
TYPE_AUXILIARY,
|
||||
TYPE_STRUCTURAL
|
||||
} ClassTypeEnum;
|
||||
|
||||
typedef struct {
|
||||
char *val;
|
||||
char *oid;
|
||||
char **names;
|
||||
char *desc;
|
||||
char **sup;
|
||||
char **must;
|
||||
char **may;
|
||||
char *naming;
|
||||
ClassTypeEnum type;
|
||||
int refcnt;
|
||||
BOOL visited;
|
||||
} MDBLDAPSchemaClass;
|
||||
|
||||
#define MDBLDAP_SYNTAX_DN(syntax) \
|
||||
!strncmp((syntax), "1.3.6.1.4.1.1466.115.121.1.12", 29)
|
||||
|
||||
#define MDBLDAP_SYNTAX_STRING(syntax) \
|
||||
!strncmp((syntax), "1.3.6.1.4.1.1466.115.121.1.15", 29)
|
||||
|
||||
BOOL ParseAttributeTypeDescription(char *ptr, MDBLDAPSchemaAttr *attr);
|
||||
BOOL ParseObjectClassDescription(char *ptr, MDBLDAPSchemaClass *class);
|
||||
|
||||
/* valarray.c */
|
||||
typedef char * (* TranslateFunction) (const char *val, const char *opt);
|
||||
inline char **NewValArray(int size);
|
||||
inline void FreeValArray(char **vals);
|
||||
inline int CountValArray(char **vals);
|
||||
inline char **CopyValArray(char **vals);
|
||||
inline BOOL ExpandValArray(char ***vals, int size);
|
||||
inline unsigned int ValueStructToValArray(MDBValueStruct *v, char **vals);
|
||||
inline int ValArrayToValueStruct(char **vals, MDBValueStruct *v);
|
||||
inline char **TranslateValArray(char **in, TranslateFunction transfunc, char *opt);
|
||||
inline unsigned int TranslateValueStructToValArray(MDBValueStruct *v, char **vals, TranslateFunction transfunc, char *opt);
|
||||
inline int TranslateValArrayToValueStruct(char **vals, MDBValueStruct *v, TranslateFunction transfunc, char *opt);
|
||||
|
||||
BOOL MDBLDAPAddValue(const unsigned char *Value, MDBValueStruct *V);
|
||||
BOOL MDBLDAPFreeValues(MDBValueStruct * V);
|
||||
|
||||
EXPORT BOOL MDBLDAPInit(MDBDriverInitStruct *Init);
|
||||
EXPORT void MDBLDAPShutdown(void);
|
||||
@@ -0,0 +1,286 @@
|
||||
#include <string.h>
|
||||
#include "mdbldapp.h"
|
||||
|
||||
#define CHARS_WHITESPACE " \t\n\f\r"
|
||||
#define CHARS_DIGIT "0123456789"
|
||||
#define CHARS_ALPHA_UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
#define CHARS_ALPHA_LOWER "abcdefghijklmnopqrstuvwxyz"
|
||||
#define CHARS_ALPHA CHARS_ALPHA_UPPER CHARS_ALPHA_LOWER
|
||||
#define CHARS_ALPHANUM CHARS_DIGIT CHARS_ALPHA
|
||||
#define CHARS_WORD "_" CHARS_ALPHANUM
|
||||
#define CHARS_WHSP CHARS_WHITESPACE
|
||||
#define CHARS_OID "-." CHARS_WORD
|
||||
|
||||
/**
|
||||
* Find the first character not among the characters in 'except'.
|
||||
*/
|
||||
static char *strnot(const char *string, const char *except) {
|
||||
char *s = (char *) string;
|
||||
char *e = (char *) except;
|
||||
|
||||
while (*s != '\0') {
|
||||
while (*e != '\0') {
|
||||
if (*s == *e) {
|
||||
s++;
|
||||
break;
|
||||
}
|
||||
e++;
|
||||
}
|
||||
if (*e == '\0') {
|
||||
break;
|
||||
}
|
||||
e = (char *) except;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if c is among the characters in 'accept'.
|
||||
*/
|
||||
static int charin(int c, const char *accept) {
|
||||
char *a = (char *) accept;
|
||||
|
||||
while (*a != '\0') {
|
||||
if (c == *a) {
|
||||
return 1;
|
||||
}
|
||||
a++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *ParseOid(char *ptr, char **oid) {
|
||||
if (!charin(*ptr, CHARS_OID)) {
|
||||
return NULL;
|
||||
}
|
||||
*oid = ptr;
|
||||
if (!(ptr = strchr(ptr, ' '))) {
|
||||
return NULL;
|
||||
}
|
||||
*ptr++ = '\0';
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static char *ParseQdescr(char *ptr, char **qdescr) {
|
||||
if (*ptr != '\'') {
|
||||
return NULL;
|
||||
}
|
||||
*qdescr = ++ptr;
|
||||
if (!(ptr = strchr(ptr, '\''))) {
|
||||
return NULL;
|
||||
}
|
||||
*ptr++ = '\0';
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static char *ParseNoidlen(char *ptr, char **noidlen) {
|
||||
/* Active Directory sometimes (incorrectly) uses quotes here */
|
||||
if (*ptr == '\'') {
|
||||
return ParseQdescr(ptr, noidlen);
|
||||
}
|
||||
|
||||
if (!charin(*ptr, CHARS_OID)) {
|
||||
return NULL;
|
||||
}
|
||||
*noidlen = ptr;
|
||||
if (!(ptr = strchr(ptr, ' '))) {
|
||||
}
|
||||
*ptr++ = '\0';
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static char *ParseOids(char *ptr, char ***oids) {
|
||||
int inc = 4;
|
||||
int idx = 0;
|
||||
|
||||
*oids = NewValArray(inc);
|
||||
if (!*oids) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (*ptr == '(') {
|
||||
ptr = strnot(ptr + 1, CHARS_WHSP);
|
||||
while (ptr && *ptr != ')') {
|
||||
if (!(idx % inc)) {
|
||||
if (!ExpandValArray(oids, idx + inc)) {
|
||||
FreeValArray(*oids);
|
||||
free(*oids);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (!(ptr = ParseOid(ptr, &((*oids)[idx++]))) ||
|
||||
!(ptr = strnot(ptr, "$" CHARS_WHSP))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ptr || *ptr != ')') {
|
||||
FreeValArray(*oids);
|
||||
free(*oids);
|
||||
return NULL;
|
||||
}
|
||||
} else if (charin(*ptr, CHARS_OID)) {
|
||||
ptr = ParseOid(ptr, &((*oids)[idx++]));
|
||||
} else {
|
||||
FreeValArray(*oids);
|
||||
free(*oids);
|
||||
return NULL;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static char *ParseQdescrs(char *ptr, char ***qdescrs) {
|
||||
int inc = 4;
|
||||
int idx = 0;
|
||||
|
||||
*qdescrs = NewValArray(inc);
|
||||
if (!*qdescrs) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (*ptr == '(') {
|
||||
ptr = strnot(ptr + 1, CHARS_WHSP);
|
||||
while (ptr && *ptr != ')') {
|
||||
if (!(idx % inc)) {
|
||||
if (!ExpandValArray(qdescrs, idx + inc)) {
|
||||
FreeValArray(*qdescrs);
|
||||
free(*qdescrs);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (!(ptr = ParseQdescr(ptr, &((*qdescrs)[idx++]))) ||
|
||||
!(ptr = strnot(ptr, CHARS_WHSP))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ptr || *ptr != ')') {
|
||||
FreeValArray(*qdescrs);
|
||||
free(*qdescrs);
|
||||
return NULL;
|
||||
}
|
||||
} else if (*ptr == '\'') {
|
||||
if (!(ptr = ParseQdescr(ptr, &((*qdescrs)[idx++])))) {
|
||||
FreeValArray(*qdescrs);
|
||||
free(*qdescrs);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
FreeValArray(*qdescrs);
|
||||
free(*qdescrs);
|
||||
return NULL;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
BOOL ParseAttributeTypeDescription(char *ptr, MDBLDAPSchemaAttr *attr) {
|
||||
char *tmp;
|
||||
|
||||
ptr = strnot(ptr, CHARS_WHSP);
|
||||
if (*ptr != '(') {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!(ptr = strnot(ptr + 1, CHARS_WHSP)) ||
|
||||
!(ptr = ParseOid(ptr, &attr->oid))) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((tmp = strstr(ptr, "NAME"))) {
|
||||
ptr = tmp;
|
||||
if (!(ptr = strnot(ptr + 4, CHARS_WHSP)) ||
|
||||
!(ptr = ParseQdescrs(ptr, &attr->names))) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((tmp = strstr(ptr, "SUP"))) {
|
||||
ptr = tmp;
|
||||
if (!(ptr = strnot(ptr + 3, CHARS_WHSP)) ||
|
||||
!(ptr = ParseOid(ptr, &attr->sup))) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((tmp = strstr(ptr, "EQUALITY"))) {
|
||||
ptr = tmp;
|
||||
if (!(ptr = strnot(ptr + 8, CHARS_WHSP)) ||
|
||||
!(ptr = ParseOid(ptr, &attr->equality))) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((tmp = strstr(ptr, "SYNTAX"))) {
|
||||
ptr = tmp;
|
||||
if (!(ptr = strnot(ptr + 6, CHARS_WHSP)) ||
|
||||
!(ptr = ParseNoidlen(ptr, &attr->syntax))) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(ptr = strnot(ptr, CHARS_WHSP)) &&
|
||||
!strncmp(ptr, "SINGLE-VALUE", 12)) {
|
||||
attr->singleval = TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL ParseObjectClassDescription(char *ptr, MDBLDAPSchemaClass *class) {
|
||||
char *tmp;
|
||||
|
||||
ptr = strnot(ptr, CHARS_WHSP);
|
||||
if (*ptr != '(') {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!(ptr = strnot(ptr + 1, CHARS_WHSP)) ||
|
||||
!(ptr = ParseOid(ptr, &class->oid))) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((tmp = strstr(ptr, "NAME"))) {
|
||||
ptr = tmp;
|
||||
if (!(ptr = strnot(ptr + 4, CHARS_WHSP)) ||
|
||||
!(ptr = ParseQdescrs(ptr, &class->names))) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((tmp = strstr(ptr, "SUP"))) {
|
||||
ptr = tmp;
|
||||
if (!(ptr = strnot(ptr + 3, CHARS_WHSP)) ||
|
||||
!(ptr = ParseOids(ptr, &class->sup))) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
ptr = strnot(ptr, CHARS_WHSP);
|
||||
if (!strncmp(ptr, "ABSTRACT", 8) ||
|
||||
!strncmp(ptr, "STRUCTURAL", 10) ||
|
||||
!strncmp(ptr, "AUXILIARY", 9)) {
|
||||
type = ptr;
|
||||
if (!(ptr = strchr(ptr, ' '))) {
|
||||
return FALSE;
|
||||
}
|
||||
*ptr++ = '\0';
|
||||
}
|
||||
*/
|
||||
|
||||
if ((tmp = strstr(ptr, "MUST"))) {
|
||||
ptr = tmp;
|
||||
if (!(ptr = strnot(ptr + 4, CHARS_WHSP)) ||
|
||||
!(ptr = ParseOids(ptr, &class->must))) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((tmp = strstr(ptr, "MAY"))) {
|
||||
ptr = tmp;
|
||||
if (!(ptr = strnot(ptr + 3, CHARS_WHSP)) ||
|
||||
!(ptr = ParseOids(ptr, &class->may))) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
/****************************************************************************
|
||||
* <Novell-copyright>
|
||||
* Copyright (c) 2006 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 "mdbldapp.h"
|
||||
|
||||
/**
|
||||
* Functions for handling char ** arrays.
|
||||
*/
|
||||
|
||||
inline char **
|
||||
NewValArray(int size)
|
||||
{
|
||||
char **vals;
|
||||
|
||||
vals = malloc(sizeof(char *) * (size + 1));
|
||||
if (vals) {
|
||||
memset(vals, 0, sizeof(char *) * (size + 1));
|
||||
}
|
||||
return vals;
|
||||
}
|
||||
|
||||
inline void
|
||||
FreeValArray(char **vals)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; vals[i]; i++) {
|
||||
free(vals[i]);
|
||||
vals[i] = NULL;
|
||||
}
|
||||
/*free(vals);*/
|
||||
}
|
||||
|
||||
inline int
|
||||
CountValArray(char **vals)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; vals[i]; i++);
|
||||
return i;
|
||||
}
|
||||
|
||||
inline char **
|
||||
CopyValArray(char **vals)
|
||||
{
|
||||
char **dup;
|
||||
int count;
|
||||
int i;
|
||||
|
||||
count = CountValArray(vals);
|
||||
dup = NewValArray(count);
|
||||
if (dup) {
|
||||
for (i = 0; vals[i]; i++) {
|
||||
dup[i] = strdup(vals[i]);
|
||||
if (!dup[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < count) {
|
||||
FreeValArray(dup);
|
||||
free(dup);
|
||||
dup = NULL;
|
||||
}
|
||||
}
|
||||
return dup;
|
||||
}
|
||||
|
||||
inline BOOL
|
||||
ExpandValArray(char ***vals, int size)
|
||||
{
|
||||
char **tmps;
|
||||
char **ptr;
|
||||
int count;
|
||||
int ext;
|
||||
|
||||
count = CountValArray(*vals);
|
||||
ext = size - count;
|
||||
if (ext > 0) {
|
||||
tmps = realloc(*vals, (sizeof(char *) * (size + 1)));
|
||||
if (tmps) {
|
||||
ptr = tmps + count + 1;
|
||||
memset(ptr, 0, (sizeof(char *) * ext));
|
||||
*vals = tmps;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
inline unsigned int
|
||||
ValueStructToValArray(MDBValueStruct *v, char **vals)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < v->Used; i++) {
|
||||
vals[i] = strdup((char *)(v->Value[i]));
|
||||
if (!vals[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < v->Used) {
|
||||
FreeValArray(vals);
|
||||
return 0;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
inline int
|
||||
ValArrayToValueStruct(char **vals, MDBValueStruct *v)
|
||||
{
|
||||
int i;
|
||||
int count;
|
||||
|
||||
count = CountValArray(vals);
|
||||
for (i = 0; vals[i]; i++) {
|
||||
if (!MDBLDAPAddValue((unsigned char *)(vals[i]), v)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < count) {
|
||||
return 0;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
inline char **
|
||||
TranslateValArray(char **in, TranslateFunction transfunc, char *opt)
|
||||
{
|
||||
char **out;
|
||||
int count;
|
||||
int i;
|
||||
|
||||
count = CountValArray(in);
|
||||
out = NewValArray(count);
|
||||
|
||||
if (out) {
|
||||
for (i = 0; in[i]; i++) {
|
||||
out[i] = transfunc(in[i], opt);
|
||||
if (!out[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < count) {
|
||||
FreeValArray(out);
|
||||
free(out);
|
||||
out = NULL;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
inline unsigned int
|
||||
TranslateValueStructToValArray(MDBValueStruct *v, char **vals,
|
||||
TranslateFunction transfunc, char *opt)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < v->Used; i++) {
|
||||
vals[i] = transfunc((char *)(v->Value[i]), opt);
|
||||
if (!vals[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < v->Used) {
|
||||
FreeValArray(vals);
|
||||
return 0;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
inline int
|
||||
TranslateValArrayToValueStruct(char **vals, MDBValueStruct *v,
|
||||
TranslateFunction transfunc, char *opt)
|
||||
{
|
||||
char *val;
|
||||
int count;
|
||||
int i;
|
||||
|
||||
count = CountValArray(vals);
|
||||
for (i = 0; vals[i]; i++) {
|
||||
val = transfunc(vals[i], opt);
|
||||
if (val) {
|
||||
if (!MDBLDAPAddValue((unsigned char *)val, v)) {
|
||||
break;
|
||||
}
|
||||
free(val);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < count) {
|
||||
return 0;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
# -*- Makefile -*-
|
||||
mdbdir = $(libdir)/bongomdb
|
||||
mdb_LTLIBRARIES :=
|
||||
|
||||
lib_LTLIBRARIES += libbongomdb.la
|
||||
|
||||
libbongomdb_la_SOURCES := \
|
||||
src/libs/mdb/mdb.c \
|
||||
src/libs/mdb/mdbp.h
|
||||
|
||||
libbongomdb_la_CPPFLAGS := $(AM_CPPFLAGS) \
|
||||
-DDRIVER_EXTENSION=\"$(SHARED_POSTFIX)\" \
|
||||
-DSYSCONF_DIR=\""$(sysconfdir)"\" \
|
||||
-DDRIVER_DIR=\""$(libdir)/bongomdb"\"
|
||||
|
||||
libbongomdb_la_LIBADD := \
|
||||
libbongoxpl.la \
|
||||
$(DL_LIBS)
|
||||
|
||||
src/libs/mdb/all: libbongomdb.la
|
||||
src/libs/mdb/clean: clean
|
||||
@@ -0,0 +1,17 @@
|
||||
# -*- Makefile -*-
|
||||
#
|
||||
# Do not edit!
|
||||
#
|
||||
# (unless this is Makefile.am.subdir)
|
||||
#
|
||||
# This file is a copy of the toplevel Makefile.am.subdir. If changes
|
||||
# need to be made, edit that file, and make update-makefiles, and
|
||||
# check the new files in.
|
||||
#
|
||||
# This is a skeletal automake file. The real automake fules for
|
||||
# building the targets for this directory can be found in the
|
||||
# Bongo.rules file. This file is simply here so that 'make all' can
|
||||
# work in each subdirectory.
|
||||
|
||||
all clean install:
|
||||
@cd $(top_builddir) && $(MAKE) $(MFLAGS) $(subdir)/$@
|
||||
@@ -0,0 +1,887 @@
|
||||
/*
|
||||
* <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>
|
||||
*/
|
||||
|
||||
/* We use bongo-specific keys/dirs here rather than mdb, so that we don't conflict before
|
||||
* we merge */
|
||||
|
||||
#include <config.h>
|
||||
#include <xpl.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
/* Local modification, bongo's xpl no longer defines these */
|
||||
|
||||
#include <mdb.h>
|
||||
#include "mdbp.h"
|
||||
|
||||
/* Globals */
|
||||
LONG Tid;
|
||||
LONG TGid;
|
||||
XplSemaphore ShutdownSemaphore;
|
||||
BOOL MDBInitialized = FALSE;
|
||||
BOOL MDBLoading = FALSE;
|
||||
BOOL MDBFailed = FALSE;
|
||||
|
||||
|
||||
#define ChopNL(String) { unsigned char *pTr; pTr=strchr((String), 0x0a); if (pTr) *pTr='\0'; pTr=strrchr((String), 0x0d); if (pTr) *pTr='\0'; }
|
||||
|
||||
#if defined(NETWARE)
|
||||
#define MDB_CONFIG_INIT
|
||||
#define MDB_CONFIG_FILE "sys:/etc/mdb.cfg"
|
||||
unsigned char DriverDir[XPL_MAX_PATH+1] = "sys:\\system";
|
||||
#elif defined(WIN32)
|
||||
#define MDB_CONFIG_INIT { \
|
||||
HKEY HKey; \
|
||||
GetWindowsDirectory(MDB_CONFIG_FILE, sizeof(MDB_CONFIG_FILE)); \
|
||||
strcat(MDB_CONFIG_FILE, "/mdb.cfg"); \
|
||||
\
|
||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Bongo\\MDB", 0, KEY_READ, &HKey)==ERROR_SUCCESS) { \
|
||||
DWORD BufSize=XPL_MAX_PATH; \
|
||||
RegQueryValueEx(HKey, "DriverDir", NULL, NULL, DriverDir, &BufSize); \
|
||||
RegCloseKey(HKey); \
|
||||
} \
|
||||
}
|
||||
|
||||
unsigned char MDB_CONFIG_FILE[256+1];
|
||||
unsigned char DriverDir[XPL_MAX_PATH+1] = "C:\\program files\\Bongo\\MDB";
|
||||
#elif defined(SUSE) || defined(LINUX) || defined(S390RH) || defined(REDHAT) || defined(SOLARIS) || defined(MACOSX)
|
||||
#define MDB_CONFIG_INIT
|
||||
#define MDB_CONFIG_FILE XPL_DEFAULT_CONF_DIR "/mdb.conf"
|
||||
unsigned char DriverDir[XPL_MAX_PATH+1] = DRIVER_DIR;
|
||||
#endif
|
||||
|
||||
typedef struct _MDBDriverStruct {
|
||||
unsigned char Driver[256];
|
||||
BOOL Primary;
|
||||
MDBDriverInitFunc Init;
|
||||
MDBDriverShutdownFunc Shutdown;
|
||||
MDBInterfaceStruct Interface;
|
||||
XplPluginHandle Handle;
|
||||
void *Data;
|
||||
} MDBDriverStruct;
|
||||
|
||||
typedef struct {
|
||||
unsigned char Module[XPL_MAX_PATH];
|
||||
unsigned char Driver[XPL_MAX_PATH];
|
||||
unsigned char Arguments[512];
|
||||
} MDBModuleStruct;
|
||||
|
||||
unsigned long MDBDriverCount = 0;
|
||||
MDBDriverStruct *MDBDrivers = NULL;
|
||||
|
||||
unsigned long MDBModuleCount = 0;
|
||||
unsigned long MDBModuleAlloc = 0;
|
||||
MDBModuleStruct *MDBModules = NULL;
|
||||
|
||||
unsigned long MDBDefaultDriver = 0;
|
||||
|
||||
static unsigned long
|
||||
MDBFindDriver(const unsigned char *Driver)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
for (i=0; i<MDBDriverCount; i++) {
|
||||
if (XplStrCaseCmp(MDBDrivers[i].Driver, Driver)==0) {
|
||||
return(i);
|
||||
}
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
static XplPluginHandle
|
||||
MDBGetDriverHandle(const unsigned char *Driver)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
for (i=0; i<MDBDriverCount; i++) {
|
||||
if (XplStrCaseCmp(MDBDrivers[i].Driver, Driver)==0) {
|
||||
return(MDBDrivers[i].Handle);
|
||||
}
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
MDBInitDriver (MDBDriverStruct *Driver,
|
||||
const unsigned char *Arguments,
|
||||
unsigned char *Error)
|
||||
|
||||
{
|
||||
unsigned char FuncName[XPL_MAX_PATH+sizeof ("Shutdown")];
|
||||
MDBDriverInitStruct Init;
|
||||
|
||||
strcpy (FuncName, Driver->Driver);
|
||||
strcat (FuncName, "Init");
|
||||
|
||||
/* FIXME: what do we do about DriverName here */
|
||||
Driver->Init=(MDBDriverInitFunc)XplGetDLLFunction(DriverName, FuncName, Driver->Handle);
|
||||
|
||||
if (!Driver->Init) {
|
||||
if (Error) sprintf(Error, "Driver %s, missing Init function", Driver->Driver);
|
||||
if (Driver->Primary) {
|
||||
XplUnloadDLL(Driver->Driver, Driver->Handle);
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Grab the shutdown function */
|
||||
strcpy(FuncName, Driver->Driver);
|
||||
strcat(FuncName, "Shutdown");
|
||||
|
||||
Driver->Shutdown=(MDBDriverShutdownFunc)XplGetDLLFunction(DriverName, FuncName, Driver->Handle);
|
||||
if (!Driver->Shutdown) {
|
||||
if (Error) sprintf(Error, "Driver %s, missing Shutdown function", Driver->Driver);
|
||||
if (Driver->Primary) {
|
||||
XplUnloadDLL(Driver->Driver, Driver->Handle);
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
memset(&Init, 0, sizeof(Init));
|
||||
Init.Arguments=Arguments;
|
||||
|
||||
if (!Driver->Init(&Init)) {
|
||||
if (Error) sprintf(Error, "Driver %s, Init failed with: %s", Driver->Driver, Init.Error);
|
||||
Driver->Shutdown();
|
||||
/* Can't unload for now; dclient creates a bunch of threads and they go to hell if we unload this dll */
|
||||
//XplUnloadDLL(Driver->Driver, Driver->Handle);
|
||||
return(-1);
|
||||
}
|
||||
memcpy(&Driver->Interface, &Init.Interface, sizeof(MDBInterfaceStruct));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static unsigned long
|
||||
MDBLoadDriver(const unsigned char *DriverNameIn, const unsigned char *Arguments, unsigned char *Error)
|
||||
{
|
||||
unsigned char DriverName[XPL_MAX_PATH+1];
|
||||
unsigned char Name[XPL_MAX_PATH+1];
|
||||
|
||||
unsigned char *ptr;
|
||||
MDBDriverStruct *Driver;
|
||||
|
||||
/* First, make sure there's enough space in our list */
|
||||
MDBDrivers=realloc(MDBDrivers, sizeof(MDBDriverStruct)*(MDBDriverCount+1));
|
||||
if (!MDBDrivers) {
|
||||
return(-1);
|
||||
}
|
||||
Driver=&MDBDrivers[MDBDriverCount];
|
||||
memset(Driver, 0, sizeof(MDBDriverStruct));
|
||||
|
||||
strcpy(DriverName, DriverNameIn);
|
||||
|
||||
ptr=DriverName;
|
||||
while (*ptr) {
|
||||
*ptr=tolower(*ptr);
|
||||
ptr++;
|
||||
}
|
||||
|
||||
TryAgain:
|
||||
if ((strchr(DriverNameIn, '/')==NULL) && (strchr(DriverNameIn, '\\')==NULL)) {
|
||||
if ((strlen(DriverName)<5) || (XplStrNCaseCmp(DriverName+strlen(DriverName)-strlen(DRIVER_EXTENSION), DRIVER_EXTENSION, strlen(DRIVER_EXTENSION))!=0)) {
|
||||
ptr=strrchr(DriverName, '.');
|
||||
if (ptr && XplStrNCaseCmp(ptr,".NLM", 4)==0) {
|
||||
strcpy(ptr, DRIVER_EXTENSION);
|
||||
goto TryAgain;
|
||||
} else {
|
||||
/* No period means possibly no extension, let's add our default extension */
|
||||
strcat(DriverName, DRIVER_EXTENSION);
|
||||
goto TryAgain;
|
||||
}
|
||||
if (Error) strcpy(Error, "Bad driver extension");
|
||||
return(-1);
|
||||
}
|
||||
} else {
|
||||
unsigned char *ptr;
|
||||
|
||||
if ((ptr=strrchr(DriverNameIn, '/'))==NULL) {
|
||||
ptr=strrchr(DriverNameIn, '\\');
|
||||
}
|
||||
ptr++;
|
||||
strcpy(DriverName, ptr);
|
||||
}
|
||||
|
||||
strcpy(Name, DriverName);
|
||||
Name[strlen(Name)-strlen(DRIVER_EXTENSION)]='\0';
|
||||
ptr=Name;
|
||||
while (*ptr) {
|
||||
*ptr=toupper(*ptr);
|
||||
ptr++;
|
||||
}
|
||||
|
||||
Driver->Handle=MDBGetDriverHandle(DriverName);
|
||||
|
||||
if (!Driver->Handle) {
|
||||
if (!(strchr(DriverNameIn, '/')==NULL) && (strchr(DriverNameIn, '\\')==NULL)) {
|
||||
/* Use the absolute path if it was passed */
|
||||
Driver->Handle=XplLoadDLL(DriverNameIn);
|
||||
} else {
|
||||
|
||||
/* Otherwise try <name> then lib<name> */
|
||||
unsigned char Path[XPL_MAX_PATH + 1];
|
||||
|
||||
sprintf(Path, "%s%c%s", DriverDir, XPL_DIR_SEPARATOR, DriverName);
|
||||
|
||||
Driver->Handle=XplLoadDLL(Path);
|
||||
if (!Driver->Handle) {
|
||||
sprintf(Path, "%s%clib%s", DriverDir, XPL_DIR_SEPARATOR, DriverName);
|
||||
Driver->Handle=XplLoadDLL(Path);
|
||||
|
||||
}
|
||||
}
|
||||
Driver->Primary=TRUE;
|
||||
}
|
||||
|
||||
if (!Driver->Handle) {
|
||||
if (Error) sprintf(Error, "Could not load driver, error %d", errno);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Give the module a chance to initialize */
|
||||
|
||||
strcpy(Driver->Driver, Name);
|
||||
if (MDBInitDriver (Driver, Arguments, Error) == 0) {
|
||||
|
||||
//XplConsolePrintf("MDBDriver '%s', successfully loaded\n", DriverName);
|
||||
return(MDBDriverCount++);
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT int
|
||||
MDBGetAPIVersion(BOOL WantCompatibleVersion, unsigned char *Description, MDBHandle Context)
|
||||
{
|
||||
if (Description) {
|
||||
if (Context) {
|
||||
strncpy(Description, ((MDBContextCacheStruct *)Context)->Description, MDB_MAX_API_DESCRIPTION_CHARS-1);
|
||||
} else {
|
||||
strcpy(Description, "<undefined>");
|
||||
}
|
||||
}
|
||||
|
||||
if (WantCompatibleVersion) {
|
||||
return(MDB_COMPATIBLE_TO_API);
|
||||
} else {
|
||||
return(MDB_CURRENT_API_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT BOOL
|
||||
MDBGetServerInfo(unsigned char *HostDN, unsigned char *HostTree, MDBValueStruct *V)
|
||||
{
|
||||
if (!V) {
|
||||
return(MDBDrivers[MDBDefaultDriver].Interface.MDBGetServerInfo(HostDN, HostTree, V));
|
||||
} else {
|
||||
return(V->Interface->MDBGetServerInfo(HostDN, HostTree, V));
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT char *
|
||||
MDBGetBaseDN(MDBValueStruct *V)
|
||||
{
|
||||
if (!V) {
|
||||
return(MDBDrivers[MDBDefaultDriver].Interface.MDBGetBaseDN(V));
|
||||
} else {
|
||||
return(V->Interface->MDBGetBaseDN(V));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Authentication */
|
||||
EXPORT MDBHandle
|
||||
MDBAuthenticate(const unsigned char *Module, const unsigned char *Object, const unsigned char *Password)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned long Driver=MDBDefaultDriver;
|
||||
MDBHandle Handle;
|
||||
unsigned char *Arguments=NULL;
|
||||
|
||||
for (i=0; i<MDBModuleCount; i++) {
|
||||
if (XplStrCaseCmp(Module, MDBModules[i].Module)==0) {
|
||||
Driver=MDBFindDriver(MDBModules[i].Driver);
|
||||
if (Driver!=(unsigned long)-1) {
|
||||
Arguments=MDBModules[Driver].Arguments;
|
||||
} else {
|
||||
Driver=MDBDefaultDriver;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Handle=MDBDrivers[Driver].Interface.MDBAuthenticate(Object, Password, Arguments);
|
||||
if (Handle) {
|
||||
((MDBContextCacheStruct *)Handle)->Interface=&MDBDrivers[Driver].Interface;
|
||||
}
|
||||
return(Handle);
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBRelease(MDBHandle Handle)
|
||||
{
|
||||
if (Handle) {
|
||||
return(((MDBContextCacheStruct *)Handle)->Interface->MDBRelease(Handle));
|
||||
} else {
|
||||
return(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EXPORT MDBValueStruct
|
||||
*MDBCreateValueStruct(MDBHandle Handle, const unsigned char *Context)
|
||||
{
|
||||
MDBValueStruct *V;
|
||||
|
||||
V=((MDBContextCacheStruct *)Handle)->Interface->MDBCreateValueStruct(Handle, Context);
|
||||
|
||||
if (V) {
|
||||
V->Interface=((MDBContextCacheStruct *)Handle)->Interface;
|
||||
}
|
||||
return(V);
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBDestroyValueStruct(MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBDestroyValueStruct(V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT MDBValueStruct
|
||||
*MDBShareContext(MDBValueStruct *VOld)
|
||||
{
|
||||
MDBValueStruct *VNew;
|
||||
|
||||
VNew=VOld->Interface->MDBShareContext(VOld);
|
||||
if (VNew) {
|
||||
VNew->Interface=VOld->Interface;
|
||||
}
|
||||
return(VNew);
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBSetValueStructContext(const unsigned char *Context, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBSetValueStructContext(Context, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT MDBEnumStruct
|
||||
*MDBCreateEnumStruct(MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBCreateEnumStruct(V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBDestroyEnumStruct(MDBEnumStruct *E, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBDestroyEnumStruct(E, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBAddValue(const unsigned char *Value, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBAddValue(Value, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBFreeValue(unsigned long Index, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBFreeValue(Index, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBFreeValues(MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBFreeValues(V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT long
|
||||
MDBRead(const unsigned char *Object, const unsigned char *Attribute, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBRead(Object, Attribute, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT const unsigned char
|
||||
*MDBReadEx(const unsigned char *Object, const unsigned char *Attribute, MDBEnumStruct *E, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBReadEx(Object, Attribute, E, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT long
|
||||
MDBReadDN(const unsigned char *Object, const unsigned char *Attribute, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBReadDN(Object, Attribute, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBWriteTyped(const unsigned char *Object, const unsigned char *Attribute, const int AttrType, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBWriteTyped(Object, Attribute, AttrType, V));
|
||||
}
|
||||
|
||||
EXPORT BOOL
|
||||
MDBWrite(const unsigned char *Object, const unsigned char *Attribute, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBWrite(Object, Attribute, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBWriteDN(const unsigned char *Object, const unsigned char *Attribute, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBWriteDN(Object, Attribute, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBClear(const unsigned char *Object, const unsigned char *Attribute, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBClear(Object, Attribute, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBAdd(const unsigned char *Object, const unsigned char *Attribute, const unsigned char *Value, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBAdd(Object, Attribute, Value, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBAddDN(const unsigned char *Object, const unsigned char *Attribute, const unsigned char *Value, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBAddDN(Object, Attribute, Value, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBRemove(const unsigned char *Object, const unsigned char *Attribute, const unsigned char *Value, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBRemove(Object, Attribute, Value, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBRemoveDN(const unsigned char *Object, const unsigned char *Attribute, const unsigned char *Value, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBRemoveDN(Object, Attribute, Value, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBIsObject(const unsigned char *Object, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBIsObject(Object, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBGetObjectDetails(const unsigned char *Object, unsigned char *Type, unsigned char *RDN, unsigned char *DN, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBGetObjectDetails(Object, Type, RDN, DN, V));
|
||||
}
|
||||
|
||||
EXPORT BOOL
|
||||
MDBGetObjectDetailsEx(const unsigned char *Object, MDBValueStruct *Types, unsigned char *RDN, unsigned char *DN, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBGetObjectDetailsEx(Object, Types, RDN, DN, V));
|
||||
}
|
||||
|
||||
EXPORT BOOL
|
||||
MDBVerifyPassword(const unsigned char *Object, const unsigned char *Password, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBVerifyPassword(Object, Password, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBVerifyPasswordEx(const unsigned char *Object, const unsigned char *Password, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBVerifyPasswordEx(Object, Password, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBChangePassword(const unsigned char *Object, const unsigned char *OldPassword, const unsigned char *NewPassword, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBChangePassword(Object, OldPassword, NewPassword, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBChangePasswordEx(const unsigned char *Object, const unsigned char *OldPassword, const unsigned char *NewPassword, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBChangePasswordEx(Object, OldPassword, NewPassword, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT long
|
||||
MDBEnumerateObjects(const unsigned char *Container, const unsigned char *Type, const unsigned char *Pattern, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBEnumerateObjects(Container, Type, Pattern, 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)
|
||||
{
|
||||
return(V->Interface->MDBEnumerateObjectsEx(Container, Type, Pattern, Flags, E, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT const unsigned char
|
||||
*MDBEnumerateAttributesEx(const unsigned char *Object, MDBEnumStruct *E, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBEnumerateAttributesEx(Object, E, V));
|
||||
}
|
||||
|
||||
EXPORT BOOL
|
||||
MDBCreateAlias(const unsigned char *Alias, const unsigned char *AliasedObjectDn, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBCreateAlias(Alias, AliasedObjectDn, V));
|
||||
}
|
||||
|
||||
EXPORT BOOL
|
||||
MDBCreateObject(const unsigned char *Object, const unsigned char *Class, MDBValueStruct *Attribute, MDBValueStruct *Data, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBCreateObject(Object, Class, Attribute, Data, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBDeleteObject(const unsigned char *Object, BOOL Recursive, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBDeleteObject(Object, Recursive, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBRenameObject(const unsigned char *ObjectOld, const unsigned char *ObjectNew, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBRenameObject(ObjectOld, ObjectNew, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBDefineAttribute(const unsigned char *Attribute, const unsigned char *ASN1, unsigned long Type, BOOL SingleValue, BOOL ImmediateSync, BOOL Public, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBDefineAttribute(Attribute, ASN1, Type, SingleValue, ImmediateSync, Public, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBUndefineAttribute(const unsigned char *Attribute, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBUndefineAttribute(Attribute, 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)
|
||||
{
|
||||
return(V->Interface->MDBDefineClass(Class, ASN1, Container, Superclass, Containment, Naming, Mandatory, Optional, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBAddAttribute(const unsigned char *Attribute, const unsigned char *Class, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBAddAttribute(Attribute, Class, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBUndefineClass(const unsigned char *Class, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBUndefineClass(Class, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBListContainableClasses(const unsigned char *Container, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBListContainableClasses(Container, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT const unsigned char
|
||||
*MDBListContainableClassesEx(const unsigned char *Container, MDBEnumStruct *E, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBListContainableClassesEx(Container, E, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBGrantObjectRights(const unsigned char *Object, const unsigned char *TrusteeDN, BOOL Read, BOOL Write, BOOL Delete, BOOL Rename, BOOL Admin, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBGrantObjectRights(Object, TrusteeDN, Read, Write, Delete, Rename, Admin, V));
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBGrantAttributeRights(const unsigned char *Object, const unsigned char *Attribute, const unsigned char *TrusteeDN, BOOL Read, BOOL Write, BOOL Admin, MDBValueStruct *V)
|
||||
{
|
||||
return(V->Interface->MDBGrantAttributeRights(Object, Attribute, TrusteeDN, Read, Write, Admin, V));
|
||||
}
|
||||
|
||||
EXPORT BOOL
|
||||
MDBFindObjects(const unsigned char *Container,
|
||||
MDBValueStruct *Types,
|
||||
const unsigned char *Pattern,
|
||||
MDBValueStruct *Attributes,
|
||||
int depth,
|
||||
int max,
|
||||
MDBValueStruct *V)
|
||||
{
|
||||
if (V->Interface->MDBFindObjects) {
|
||||
return(V->Interface->MDBFindObjects(Container, Types, Pattern, Attributes, depth, max, V));
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT BOOL
|
||||
MDBDumpValueStruct(MDBValueStruct *V)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
if (!V->Used) {
|
||||
XplConsolePrintf("No data in structure\n");
|
||||
}
|
||||
XplConsolePrintf("ValueStruct: Used:%lu\n", V->Used);
|
||||
for (i=0; i<V->Used; i++) {
|
||||
XplConsolePrintf("Value[%02lu] %-25s", i, V->Value[i]);
|
||||
if (((i+1) % 2)==0) {
|
||||
XplConsolePrintf("\n");
|
||||
} else {
|
||||
XplConsolePrintf(" | ");
|
||||
}
|
||||
}
|
||||
XplConsolePrintf("\r\n");
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Config format:
|
||||
|
||||
DriverDir=<Directory>
|
||||
Default=<Drivername>
|
||||
Driver=<Drivername> [DriverArguments]
|
||||
Module <Modulename>=<Drivername> [DriverArguments]
|
||||
*/
|
||||
|
||||
static BOOL
|
||||
MDBReadConfiguration(void)
|
||||
{
|
||||
FILE *Handle;
|
||||
unsigned char Buffer[1024];
|
||||
unsigned char Error[XPL_MAX_PATH*2];
|
||||
unsigned char DefaultDriverName[XPL_MAX_PATH+1] = "";
|
||||
|
||||
MDB_CONFIG_INIT;
|
||||
Handle=fopen(MDB_CONFIG_FILE, "rb");
|
||||
if (!Handle) {
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
while (!ferror(Handle) && !feof(Handle)) {
|
||||
if (fgets(Buffer, sizeof(Buffer), Handle)!=NULL) {
|
||||
ChopNL(Buffer);
|
||||
if (XplStrNCaseCmp(Buffer, "DriverDir=", 10)==0) {
|
||||
strcpy(DriverDir, Buffer+10);
|
||||
} else if (XplStrNCaseCmp(Buffer, "Module ", 7)==0) {
|
||||
unsigned char *Module;
|
||||
unsigned char *Driver;
|
||||
unsigned char *Arguments;
|
||||
|
||||
if ((MDBModuleCount+1)>MDBModuleAlloc) {
|
||||
MDBModules=realloc(MDBModules, sizeof(MDBModuleStruct)*(MDBModuleAlloc+10));
|
||||
if (!MDBModules) {
|
||||
fclose(Handle);
|
||||
return(FALSE);
|
||||
}
|
||||
MDBModuleAlloc+=10;
|
||||
}
|
||||
|
||||
Module=Buffer+7;
|
||||
Driver=strchr(Module, '=');
|
||||
if (Driver) {
|
||||
*Driver='\0';
|
||||
Driver++;
|
||||
if ((Arguments=strchr(Driver, ' '))!=NULL) {
|
||||
*Arguments='\0';
|
||||
Arguments++;
|
||||
}
|
||||
strcpy(MDBModules[MDBModuleCount].Module, Module);
|
||||
strcpy(MDBModules[MDBModuleCount].Driver, Driver);
|
||||
if (Arguments) {
|
||||
strcpy(MDBModules[MDBModuleCount].Arguments, Arguments);
|
||||
} else {
|
||||
MDBModules[MDBModuleCount].Arguments[0]='\0';
|
||||
}
|
||||
MDBModuleCount++;
|
||||
}
|
||||
} else if (XplStrNCaseCmp(Buffer, "Driver=", 7)==0) {
|
||||
unsigned char *Arguments;
|
||||
|
||||
if ((Arguments=strchr(Buffer+7, ' '))!=NULL) {
|
||||
*Arguments='\0';
|
||||
Arguments++;
|
||||
}
|
||||
|
||||
if (MDBLoadDriver(Buffer+7, Arguments, Error)==(unsigned long)-1) {
|
||||
XplConsolePrintf("\rDriver %s failed to load:%s\n", Buffer+7, Error);
|
||||
fclose(Handle);
|
||||
return(FALSE);
|
||||
}
|
||||
} else if (XplStrNCaseCmp(Buffer, "Default=", 8)==0) {
|
||||
strcpy(DefaultDriverName, Buffer+8);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(Handle);
|
||||
|
||||
if (DefaultDriverName[0]!='\0') {
|
||||
MDBDefaultDriver=MDBFindDriver(DefaultDriverName);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
EXPORT BOOL
|
||||
MDBInit(void)
|
||||
{
|
||||
if (MDBFailed) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!MDBInitialized && !MDBLoading) {
|
||||
MDBLoading=TRUE;
|
||||
/* Read configuration */
|
||||
if (!MDBReadConfiguration()) {
|
||||
unsigned char Error[XPL_MAX_PATH*2];
|
||||
|
||||
if ((MDBLoadDriver("MDBDS", NULL, Error)==(unsigned long)-1) && (MDBLoadDriver("MDBREG", NULL, Error)==(unsigned long)-1) && (MDBLoadDriver("MDBFILE", NULL, Error)==(unsigned long)-1)) {
|
||||
MDBLoading = FALSE;
|
||||
MDBFailed = TRUE;
|
||||
XplConsolePrintf("Failed to load any MDB driver\n");
|
||||
|
||||
/* INSERT "fake" MDB driver here */
|
||||
return(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
MDBInitialized=TRUE;
|
||||
}
|
||||
|
||||
while (!MDBInitialized) {
|
||||
XplDelay(100);
|
||||
}
|
||||
|
||||
return(MDBInitialized);
|
||||
}
|
||||
|
||||
|
||||
EXPORT BOOL
|
||||
MDBShutdown(void)
|
||||
{
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
#if defined(NETWARE)
|
||||
void
|
||||
MDBSigHandler(int Signal)
|
||||
{
|
||||
int OldTGid;
|
||||
unsigned long i;
|
||||
|
||||
OldTGid=XplSetThreadGroupID(TGid);
|
||||
|
||||
XplSignalLocalSemaphore(ShutdownSemaphore);
|
||||
XplWaitOnLocalSemaphore(ShutdownSemaphore);
|
||||
|
||||
/* Do any required cleanup */
|
||||
for (i=0; i<MDBDriverCount; i++) {
|
||||
MDBDrivers[i].Shutdown();
|
||||
XplUnloadDLL(MDBDrivers[i].Driver, MDBDrivers[i].Handle);
|
||||
}
|
||||
if (MDBDrivers) {
|
||||
free(MDBDrivers);
|
||||
}
|
||||
if (MDBModules) {
|
||||
free(MDBModules);
|
||||
}
|
||||
|
||||
XplCloseLocalSemaphore(ShutdownSemaphore);
|
||||
XplSetThreadGroupID(OldTGid);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
Tid=XplGetThreadID();
|
||||
TGid=XplGetThreadGroupID();
|
||||
|
||||
signal(SIGTERM, MDBSigHandler);
|
||||
|
||||
/*
|
||||
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...
|
||||
*/
|
||||
|
||||
MDBInit();
|
||||
|
||||
XplOpenLocalSemaphore(ShutdownSemaphore, 0);
|
||||
XplWaitOnLocalSemaphore(ShutdownSemaphore);
|
||||
XplSignalLocalSemaphore(ShutdownSemaphore);
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(WIN32)
|
||||
BOOL WINAPI
|
||||
DllMain(HINSTANCE hInst, DWORD Reason, LPVOID Reserved)
|
||||
{
|
||||
if (Reason==DLL_PROCESS_ATTACH) {
|
||||
DisableThreadLibraryCalls(hInst);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* <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 MDBP_H
|
||||
#define MDBP_H
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned char Description[128];
|
||||
struct _MDBInterfaceStruct *Interface;
|
||||
} MDBContextCacheStruct;
|
||||
|
||||
|
||||
#endif /* MDBP_H */
|
||||
@@ -18,6 +18,7 @@ typedef struct {
|
||||
MsgSQLStatement find_user;
|
||||
MsgSQLStatement auth_user;
|
||||
MsgSQLStatement add_user;
|
||||
MsgSQLStatement list_user;
|
||||
MsgSQLStatement set_password;
|
||||
} MsgAuthStatements;
|
||||
|
||||
@@ -26,7 +27,7 @@ MsgAuthStatements msgauth_stmts;
|
||||
int
|
||||
AuthODBC_Init(void)
|
||||
{
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -74,7 +75,7 @@ AuthSqlite_Install(void)
|
||||
|
||||
dcode = sqlite3_exec (handle->db,
|
||||
"PRAGMA user_version=0;"
|
||||
"CREATE TABLE users (username TEXT DEFAULT NULL,"
|
||||
"CREATE TABLE users (username TEXT DEFAULT NULL UNIQUE,"
|
||||
" password TEXT DEFAULT NULL"
|
||||
");"
|
||||
"INSERT INTO users (username, password)"
|
||||
@@ -200,7 +201,7 @@ AuthSqlite_AddUser(const char *user)
|
||||
handle = MsgSQLOpen(path, NULL, 1000);
|
||||
if (NULL == handle) {
|
||||
Log(LOG_ERROR, "Cannot open user db '%s'", path);
|
||||
return -1;
|
||||
return -10;
|
||||
}
|
||||
|
||||
stmt = MsgSQLPrepare (handle,
|
||||
@@ -209,12 +210,12 @@ AuthSqlite_AddUser(const char *user)
|
||||
|
||||
if (NULL == stmt) {
|
||||
Log(LOG_ERROR, "Unable to prepare SQL statement in AddUser");
|
||||
return 1;
|
||||
return -11;
|
||||
}
|
||||
|
||||
if (MsgSQLBindString(stmt, 1, user, TRUE)) return -2;
|
||||
if (MsgSQLExecute(handle, stmt)) return -3;
|
||||
|
||||
if (MsgSQLBindString(stmt, 1, user, TRUE)) return -12;
|
||||
if (MsgSQLExecute(handle, stmt)) return -13;
|
||||
|
||||
MsgSQLFinalize(stmt);
|
||||
MsgSQLClose(handle);
|
||||
|
||||
@@ -230,12 +231,12 @@ AuthSqlite_SetPassword(const char *user, const char *password)
|
||||
MsgSQLHandle *handle;
|
||||
|
||||
if (AuthSqlite_GenerateHash(user, password, hash, XPLHASH_SHA1_LENGTH + 1) != 0)
|
||||
return -1;
|
||||
return -10;
|
||||
AuthSqlite_GetDbPath(path, XPL_MAX_PATH);
|
||||
handle = MsgSQLOpen(path, NULL, 1000);
|
||||
if (NULL == handle) {
|
||||
Log(LOG_ERROR, "Cannot open user db '%s'", path);
|
||||
return -2;
|
||||
return -11;
|
||||
}
|
||||
|
||||
stmt = MsgSQLPrepare (handle,
|
||||
@@ -243,12 +244,12 @@ AuthSqlite_SetPassword(const char *user, const char *password)
|
||||
&msgauth_stmts.set_password);
|
||||
if (NULL == stmt) {
|
||||
Log(LOG_ERROR, "Unable to prepare SQL in SetPassword()");
|
||||
return 1;
|
||||
return -12;
|
||||
}
|
||||
|
||||
if (MsgSQLBindString(stmt, 1, hash, TRUE)) return -3;
|
||||
if (MsgSQLBindString(stmt, 2, user, TRUE)) return -3;
|
||||
if (MsgSQLExecute(handle, stmt)) return -3;
|
||||
if (MsgSQLBindString(stmt, 1, hash, TRUE)) return -13;
|
||||
if (MsgSQLBindString(stmt, 2, user, TRUE)) return -13;
|
||||
if (MsgSQLExecute(handle, stmt)) return -14;
|
||||
|
||||
MsgSQLFinalize(stmt);
|
||||
MsgSQLClose(handle);
|
||||
@@ -267,18 +268,49 @@ AuthSqlite_GetUserStore(const char *user, struct sockaddr_in *store)
|
||||
}
|
||||
|
||||
int
|
||||
AuthSqlite_UserList(BongoArray **list)
|
||||
AuthSqlite_UserList(char **list[])
|
||||
{
|
||||
/* TODO
|
||||
BongoArray *userlist;
|
||||
char **userlist;
|
||||
MsgSQLStatement *stmt;
|
||||
char path[XPL_MAX_PATH + 1];
|
||||
MsgSQLHandle *handle;
|
||||
int users = 0;
|
||||
int alloc = 10;
|
||||
|
||||
userlist = BongoArrayNew(sizeof (char *), 0);
|
||||
AuthSqlite_GetDbPath(path, XPL_MAX_PATH);
|
||||
handle = MsgSQLOpen(path, NULL, 1000);
|
||||
|
||||
char *admin = strdup("admin");
|
||||
BongoArrayAppendValue(userlist, admin);
|
||||
if (NULL == handle) {
|
||||
Log(LOG_ERROR, "Cannot open user db '%s'", path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
stmt = MsgSQLPrepare (handle, "SELECT username FROM users;",
|
||||
&msgauth_stmts.list_user);
|
||||
if (NULL == stmt) {
|
||||
Log(LOG_ERROR, "Unable to prepare SQL statement in ListUser");
|
||||
return 1;
|
||||
}
|
||||
|
||||
userlist = MemMalloc(sizeof(char *) * alloc);
|
||||
{
|
||||
int result;
|
||||
while (1 == (result = MsgSQLStatementStep(handle, stmt))) {
|
||||
userlist[users] = strdup((char *) sqlite3_column_text(stmt->stmt, 0));
|
||||
users++;
|
||||
if (users == alloc) {
|
||||
alloc += 10;
|
||||
userlist = MemRealloc(userlist, sizeof(char *) * alloc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MsgSQLFinalize(stmt);
|
||||
MsgSQLClose(handle);
|
||||
|
||||
userlist[users] = 0;
|
||||
|
||||
*list = userlist;
|
||||
*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,6 @@ int AuthSqlite_VerifyPassword(const char *user, const char *password);
|
||||
int AuthSqlite_AddUser(const char *user);
|
||||
int AuthSqlite_SetPassword(const char *user, const char *password);
|
||||
int AuthSqlite_GetUserStore(const char *user, struct sockaddr_in *store);
|
||||
int AuthSqlite_UserList(BongoArray **list);
|
||||
int AuthSqlite_UserList(char **list[]);
|
||||
int AuthSqlite_InterfaceVersion(void);
|
||||
int AuthODBC_Init(void);
|
||||
|
||||
@@ -153,7 +153,7 @@ MsgAuthVerifyPassword(const char *user, const char *password)
|
||||
|
||||
f = (AuthPlugin_VerifyPassword *)&function->func;
|
||||
result = (*f)(user, password);
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* "Write" functions below */
|
||||
@@ -169,9 +169,14 @@ MsgAuthAddUser(const char *user)
|
||||
MsgAuthAPIFunction *function;
|
||||
AuthPlugin_AddUser *f;
|
||||
int result;
|
||||
|
||||
result = MsgAuthFindUser(user);
|
||||
if (result == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
function = &pluginapi[Func_AddUser];
|
||||
if (! function->available) return FALSE;
|
||||
if (! function->available) return -2;
|
||||
|
||||
f = (AuthPlugin_AddUser *)&function->func;
|
||||
result = (*f)(user);
|
||||
@@ -259,8 +264,28 @@ MsgAuthGetUserStore(const char *user, struct sockaddr_in *store)
|
||||
* \return Whether this was successful
|
||||
*/
|
||||
int
|
||||
MsgAuthUserList(BongoArray **list)
|
||||
MsgAuthUserList(char **list[])
|
||||
{
|
||||
return -1;
|
||||
MsgAuthAPIFunction *function;
|
||||
AuthPlugin_UserList *f;
|
||||
int result;
|
||||
|
||||
function = &pluginapi[Func_UserList];
|
||||
if (! function->available) return FALSE;
|
||||
|
||||
f = (AuthPlugin_UserList *)&function->func;
|
||||
result = (*f)(list);
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
MsgAuthUserListFree(char **list[])
|
||||
{
|
||||
char **users = *list;
|
||||
int i;
|
||||
|
||||
for (i = 0; users[i] != 0x0; i++) {
|
||||
MemFree(users[i]);
|
||||
}
|
||||
MemFree(users);
|
||||
}
|
||||
|
||||
@@ -654,18 +654,17 @@ MsgCollectUser(const char *user)
|
||||
void
|
||||
MsgCollectAllUsers(void)
|
||||
{
|
||||
BongoArray *users;
|
||||
int i;
|
||||
char **userlist;
|
||||
int result, i;
|
||||
|
||||
if (MsgAuthUserList(&users) < 0)
|
||||
return;
|
||||
result = MsgAuthUserList(&userlist);
|
||||
if (! result) return;
|
||||
|
||||
for(i = 0; i < BongoArrayCount(users); i++) {
|
||||
char *user = BongoArrayIndex(users, char *, i);
|
||||
MsgCollectUser(user);
|
||||
for (i = 0; userlist[i] != 0; i++) {
|
||||
MsgCollectUser(userlist[i]);
|
||||
}
|
||||
|
||||
BongoArrayFree(users, TRUE);
|
||||
MsgAuthUserListFree(&userlist);
|
||||
}
|
||||
|
||||
size_t
|
||||
|
||||
@@ -13,6 +13,7 @@ typedef int (* AuthPlugin_VerifyPassword)(const char *user, const char *password
|
||||
typedef int (* AuthPlugin_AddUser)(const char *user);
|
||||
typedef int (* AuthPlugin_ChangePassword)(const char *user, const char *oldpassword, const char *newpassword);
|
||||
typedef int (* AuthPlugin_SetPassword)(const char *user, const char *password);
|
||||
typedef int (* AuthPlugin_UserList)(char **list[]);
|
||||
typedef int (* AuthPlugin_GetUserStore)(const char *user, struct sockaddr_in *store);
|
||||
typedef int (* AuthPlugin_Install)(void);
|
||||
typedef int (* AuthPlugin_Init)(void);
|
||||
@@ -27,7 +28,7 @@ enum {
|
||||
Func_SetPassword = 6,
|
||||
Func_GetUserStore = 7,
|
||||
Func_Install = 8,
|
||||
Func_Init = 9
|
||||
Func_Init = 9
|
||||
};
|
||||
|
||||
static MsgAuthAPIFunction pluginapi[] = {
|
||||
|
||||
@@ -269,6 +269,30 @@ MsgSQLExecute(MsgSQLHandle *handle, MsgSQLStatement *_stmt)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
MsgSQLStatementStep(MsgSQLHandle *handle, MsgSQLStatement *_stmt)
|
||||
{
|
||||
sqlite3_stmt *stmt = _stmt->stmt;
|
||||
int count = 1 + handle->lockTimeoutMs / MSGSQL_STMT_SLEEP_MS;
|
||||
int dbg;
|
||||
while (count--) {
|
||||
switch ((dbg = sqlite3_step(stmt))) {
|
||||
case SQLITE_ROW:
|
||||
return 1;
|
||||
case SQLITE_DONE:
|
||||
return 0;
|
||||
case SQLITE_BUSY:
|
||||
XplDelay(MSGSQL_STMT_SLEEP_MS);
|
||||
continue;
|
||||
default:
|
||||
XplConsolePrintf("Sql: %s", sqlite3_errmsg(handle->db));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
MsgSQLResults(MsgSQLHandle *handle, MsgSQLStatement *_stmt)
|
||||
{
|
||||
|
||||
@@ -157,14 +157,14 @@ class AgentHandler(HawkeyeHandler):
|
||||
# It's a hostlist, and arraytype is the default port
|
||||
# Check if value has port and/or weighting
|
||||
defaultweight = 1
|
||||
defultport = arraytype
|
||||
|
||||
defaultport = arraytype
|
||||
|
||||
if dobj.count(':') == 1:
|
||||
# Port and hostname
|
||||
dobj = dobj + ":" + defaultweight
|
||||
elif dobj.count(':') == 0:
|
||||
# Only hostname
|
||||
dobj = dobj + ":" + defaultport + ":" + defaultweight
|
||||
dobj = dobj + ":" + str(defaultport) + ":" + str(defaultweight)
|
||||
|
||||
# Otherwise, type was string (default).
|
||||
|
||||
@@ -215,11 +215,7 @@ class AgentHandler(HawkeyeHandler):
|
||||
nkey["revertbox"] = key + "-normal"
|
||||
nkey["revertjs"] = "$('" + nkey["revertbox"] + "').hide(); $('" + nkey["selectorid"] + "').show();"
|
||||
|
||||
strthingy = ""
|
||||
for value in config[key]:
|
||||
strthingy += value + ","
|
||||
|
||||
nkey["strvalue"] = strthingy
|
||||
nkey["strvalue"] = ','.join(config[key])
|
||||
|
||||
rkeys.append(nkey)
|
||||
|
||||
|
||||
@@ -95,6 +95,20 @@ class AliasHandler(HawkeyeHandler):
|
||||
else:
|
||||
self.SetVariable("domainwide", None)
|
||||
|
||||
# handle the email->username mapping config
|
||||
mapping_value = 0
|
||||
if data.has_key("username-mapping"):
|
||||
mapping_value = int(data["username-mapping"])
|
||||
if mapping_value < 0 or mapping_value > 2:
|
||||
mapping_value = 0
|
||||
self.SetVariable("username-mapping", mapping_value)
|
||||
for i in [0, 1, 2]:
|
||||
select = "username-mapping-%d" % i
|
||||
if i == mapping_value:
|
||||
self.SetVariable(select, "selected")
|
||||
else:
|
||||
self.SetVariable(select, None)
|
||||
|
||||
self.SetVariable("useraliasestxt", aliases_txt)
|
||||
self.SetVariable("useraliases", tpl_aliases)
|
||||
self.SetVariable("domainalias", domainalias)
|
||||
@@ -134,6 +148,9 @@ class AliasHandler(HawkeyeHandler):
|
||||
elif key == "domainalias":
|
||||
# Actual domain alias val
|
||||
config["domainalias"] = value
|
||||
elif key == "username-mapping":
|
||||
# Mapping scheme wanted
|
||||
config["username-mapping"] = int(value)
|
||||
elif key == "useralias":
|
||||
# User aliases
|
||||
# Split this, and set array as value.
|
||||
|
||||
@@ -52,7 +52,10 @@ class SundialPath(object):
|
||||
|
||||
self.sundialpath = '/'.join(pathparts)
|
||||
|
||||
if len(splituri) != 3:
|
||||
if splituri[-1] == '':
|
||||
splituri.pop()
|
||||
|
||||
if len(splituri) < 2:
|
||||
raise HttpError(404)
|
||||
|
||||
# The user the calendar belongs to.
|
||||
@@ -62,7 +65,10 @@ class SundialPath(object):
|
||||
self.calendar = urllib.unquote(splituri[1])
|
||||
|
||||
# The file name.
|
||||
self.filename = splituri[2]
|
||||
try:
|
||||
self.filename = splituri[2]
|
||||
except IndexError:
|
||||
self.filename = ''
|
||||
|
||||
if self.filename != '':
|
||||
# This shop only serves up iCalendar.
|
||||
|
||||
@@ -47,6 +47,16 @@
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding-right: 16px;">Default address to username mapping</td>
|
||||
<td>
|
||||
<select name="username-mapping">
|
||||
<option value="0" tal:attributes="selected username-mapping-0">Local part (before @) is the username</option>
|
||||
<option value="1" tal:attributes="selected username-mapping-1">Full e-mail address is the username</option>
|
||||
<option value="2" tal:attributes="selected username-mapping-2">Domain part (after @) is the username</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
@@ -974,9 +974,10 @@ Dragonfly.start = function ()
|
||||
// Don't use showElement - not nice to non-divs
|
||||
$('admin-link').style.display = 'inline';
|
||||
}
|
||||
|
||||
$('makeDumpLink-a').href = 'javascript:void(console.sendLog("user/' + d.userName + '/sendlog/all", true));';
|
||||
|
||||
|
||||
if ($('makeDumpLink-a')) {
|
||||
$('makeDumpLink-a').href = 'javascript:void(console.sendLog("user/' + d.userName + '/sendlog/all", true));';
|
||||
}
|
||||
removeElementClass (document.body, 'login');
|
||||
|
||||
d._handleResize();
|
||||
|
||||
@@ -220,7 +220,7 @@ MochiKit.Async.Deferred.prototype = {
|
||||
if (!(err instanceof Error)) {
|
||||
err = new MochiKit.Async.GenericError(err);
|
||||
}
|
||||
logError ('Error firing Deferred: ', err.message);
|
||||
console.error ('Error firing Deferred: ', err.message);
|
||||
res = err;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user