mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-20 22:59:34 -05:00
Move experimental Back-BDB2 to Attic
This commit is contained in:
parent
252ccfddbc
commit
4a1f646682
44 changed files with 686 additions and 9915 deletions
65
configure.in
65
configure.in
|
|
@ -142,10 +142,7 @@ OL_ARG_ENABLE(wrappers,[ --enable-wrappers enable tcp wrapper support], no)dn
|
||||||
OL_ARG_ENABLE(dynamic,[ --enable-dynamic enable linking built binaries with dynamic libs], no)dnl
|
OL_ARG_ENABLE(dynamic,[ --enable-dynamic enable linking built binaries with dynamic libs], no)dnl
|
||||||
|
|
||||||
dnl SLAPD Backend options
|
dnl SLAPD Backend options
|
||||||
OL_ARG_ENABLE(bdb2,[ --enable-bdb2 enable bdb2 backend], no)dnl
|
OL_ARG_ENABLE(dnssrv,[ --enable-dnssrv enable dnssrv backend], no)dnl
|
||||||
OL_ARG_WITH(bdb2_module,[ --with-bdb2-module module type], static,
|
|
||||||
[static dynamic])
|
|
||||||
OL_ARG_ENABLE(dnssrv,[ --enable-dnssrv enable bdb2 backend], no)dnl
|
|
||||||
OL_ARG_WITH(dnssrv_module,[ --with-dnssrv-module module type], static,
|
OL_ARG_WITH(dnssrv_module,[ --with-dnssrv-module module type], static,
|
||||||
[static dynamic])
|
[static dynamic])
|
||||||
OL_ARG_ENABLE(ldap,[ --enable-ldap enable ldap backend], no)dnl
|
OL_ARG_ENABLE(ldap,[ --enable-ldap enable ldap backend], no)dnl
|
||||||
|
|
@ -191,9 +188,6 @@ dnl General "enable" options
|
||||||
# validate options
|
# validate options
|
||||||
if test $ol_enable_slapd = no ; then
|
if test $ol_enable_slapd = no ; then
|
||||||
dnl SLAPD was specificallly disabled
|
dnl SLAPD was specificallly disabled
|
||||||
if test $ol_enable_bdb2 = yes ; then
|
|
||||||
AC_MSG_WARN([slapd disabled, ignoring --enable-bdb2 argument])
|
|
||||||
fi
|
|
||||||
if test $ol_enable_dnssrv = yes ; then
|
if test $ol_enable_dnssrv = yes ; then
|
||||||
AC_MSG_WARN([slapd disabled, ignoring --enable-dnssrv argument])
|
AC_MSG_WARN([slapd disabled, ignoring --enable-dnssrv argument])
|
||||||
fi
|
fi
|
||||||
|
|
@ -245,9 +239,6 @@ if test $ol_enable_slapd = no ; then
|
||||||
if test $ol_with_ldbm_type != auto ; then
|
if test $ol_with_ldbm_type != auto ; then
|
||||||
AC_MSG_WARN([slapd disabled, ignoring --with-ldbm-type argument])
|
AC_MSG_WARN([slapd disabled, ignoring --with-ldbm-type argument])
|
||||||
fi
|
fi
|
||||||
if test $ol_with_bdb2_module != static ; then
|
|
||||||
AC_MSG_WARN([slapd disabled, ignoring --with-bdb2-module argument])
|
|
||||||
fi
|
|
||||||
if test $ol_with_dnssrv_module != static ; then
|
if test $ol_with_dnssrv_module != static ; then
|
||||||
AC_MSG_WARN([slapd disabled, ignoring --with-dnssrv-module argument])
|
AC_MSG_WARN([slapd disabled, ignoring --with-dnssrv-module argument])
|
||||||
fi
|
fi
|
||||||
|
|
@ -277,7 +268,6 @@ if test $ol_enable_slapd = no ; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# force settings to no
|
# force settings to no
|
||||||
ol_enable_bdb2=no
|
|
||||||
ol_enable_dnssrv=no
|
ol_enable_dnssrv=no
|
||||||
ol_enable_ldap=no
|
ol_enable_ldap=no
|
||||||
ol_enable_ldbm=no
|
ol_enable_ldbm=no
|
||||||
|
|
@ -299,7 +289,6 @@ if test $ol_enable_slapd = no ; then
|
||||||
ol_with_ldbm_api=no
|
ol_with_ldbm_api=no
|
||||||
ol_with_ldbm_type=no
|
ol_with_ldbm_type=no
|
||||||
|
|
||||||
ol_with_bdb2_module=static
|
|
||||||
ol_with_dnssrv_module=static
|
ol_with_dnssrv_module=static
|
||||||
ol_with_ldap_module=static
|
ol_with_ldap_module=static
|
||||||
ol_with_ldbm_module=static
|
ol_with_ldbm_module=static
|
||||||
|
|
@ -326,10 +315,6 @@ elif test $ol_enable_ldbm = no ; then
|
||||||
AC_MSG_WARN([LDBM disabled, ignoring --with-ldbm-module argument])
|
AC_MSG_WARN([LDBM disabled, ignoring --with-ldbm-module argument])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test $ol_enable_bdb2 = yes ; then
|
|
||||||
AC_MSG_ERROR([BDB2 requires --enable-ldbm])
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test $ol_enable_modules != yes -a \
|
if test $ol_enable_modules != yes -a \
|
||||||
$ol_enable_dnssrv = no -a \
|
$ol_enable_dnssrv = no -a \
|
||||||
$ol_enable_ldap = no -a \
|
$ol_enable_ldap = no -a \
|
||||||
|
|
@ -345,27 +330,8 @@ elif test $ol_enable_ldbm = no ; then
|
||||||
ol_with_ldbm_type=no
|
ol_with_ldbm_type=no
|
||||||
ol_with_ldbm_module=static
|
ol_with_ldbm_module=static
|
||||||
|
|
||||||
elif test $ol_enable_bdb2 = yes ; then
|
|
||||||
dnl SLAPD with BDB2
|
|
||||||
|
|
||||||
if test $ol_with_ldbm_api != auto -a \
|
|
||||||
$ol_with_ldbm_api != berkeley ; then
|
|
||||||
AC_MSG_ERROR([BDB2 requires LDBM API berkeley or auto])
|
|
||||||
fi
|
|
||||||
|
|
||||||
ol_with_ldbm_api=db2
|
|
||||||
|
|
||||||
else
|
else
|
||||||
dnl SLAPD with LDBM
|
dnl SLAPD with LDBM
|
||||||
|
|
||||||
if test $ol_enable_bdb2 != no ; then
|
|
||||||
if test $ol_with_ldbm_api != auto -a \
|
|
||||||
$ol_with_ldbm_api != berkeley ; then
|
|
||||||
AC_MSG_WARN([BDB2 requires LDBM api berkeley or auto])
|
|
||||||
ol_enable_bdb2=no
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test $ol_with_ldbm_api = gdbm -a \
|
if test $ol_with_ldbm_api = gdbm -a \
|
||||||
$ol_with_ldbm_type = btree ; then
|
$ol_with_ldbm_type = btree ; then
|
||||||
AC_MSG_ERROR([GDBM only supports LDBM type hash])
|
AC_MSG_ERROR([GDBM only supports LDBM type hash])
|
||||||
|
|
@ -426,7 +392,6 @@ BUILD_SLURPD=no
|
||||||
BUILD_QUIPU=no
|
BUILD_QUIPU=no
|
||||||
BUILD_THREAD=no
|
BUILD_THREAD=no
|
||||||
|
|
||||||
BUILD_BDB2=no
|
|
||||||
BUILD_DNSSRV=no
|
BUILD_DNSSRV=no
|
||||||
BUILD_LDAP=no
|
BUILD_LDAP=no
|
||||||
BUILD_LDBM=no
|
BUILD_LDBM=no
|
||||||
|
|
@ -436,7 +401,6 @@ BUILD_SHELL=no
|
||||||
BUILD_SQL=no
|
BUILD_SQL=no
|
||||||
BUILD_TCL=no
|
BUILD_TCL=no
|
||||||
|
|
||||||
BUILD_BDB2_DYNAMIC=static
|
|
||||||
BUILD_DNSSRV_DYNAMIC=static
|
BUILD_DNSSRV_DYNAMIC=static
|
||||||
BUILD_LDAP_DYNAMIC=static
|
BUILD_LDAP_DYNAMIC=static
|
||||||
BUILD_LDBM_DYNAMIC=static
|
BUILD_LDBM_DYNAMIC=static
|
||||||
|
|
@ -646,7 +610,6 @@ if test $ol_enable_modules != no ; then
|
||||||
fi
|
fi
|
||||||
ol_link_modules=yes
|
ol_link_modules=yes
|
||||||
else
|
else
|
||||||
ol_with_bdb2_module=static
|
|
||||||
ol_with_dnssrv_module=static
|
ol_with_dnssrv_module=static
|
||||||
ol_with_ldap_module=static
|
ol_with_ldap_module=static
|
||||||
ol_with_ldbm_module=static
|
ol_with_ldbm_module=static
|
||||||
|
|
@ -1732,16 +1695,6 @@ if test $ol_link_ldbm = no -a $ol_enable_ldbm != no ; then
|
||||||
ol_enable_ldbm=no
|
ol_enable_ldbm=no
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl ----------------------------------------------------------------
|
|
||||||
ol_link_bdb2=no
|
|
||||||
if test $ol_enable_bdb2 != no ; then
|
|
||||||
if test $ol_enable_bdb2 = yes -a $ol_link_ldbm != berkeley ; then
|
|
||||||
AC_MSG_ERROR(BDB2 requires LDBM BerkeleyDB 2)
|
|
||||||
elif test $ol_link_ldbm = berkeley ; then
|
|
||||||
ol_link_bdb2=$ol_link_ldbm
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
dnl ----------------------------------------------------------------
|
dnl ----------------------------------------------------------------
|
||||||
if test $ol_enable_dynamic = yes -a $enable_shared = yes ; then
|
if test $ol_enable_dynamic = yes -a $enable_shared = yes ; then
|
||||||
LINK_BINS_DYNAMIC="yes"
|
LINK_BINS_DYNAMIC="yes"
|
||||||
|
|
@ -2194,19 +2147,6 @@ if test "$ol_link_modules" != no ; then
|
||||||
SLAPD_MODULES_LDFLAGS="-dlopen self"
|
SLAPD_MODULES_LDFLAGS="-dlopen self"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$ol_link_bdb2" != no ; then
|
|
||||||
AC_DEFINE(SLAPD_BDB2,1,[define to support BDB2 backend])
|
|
||||||
BUILD_SLAPD=yes
|
|
||||||
BUILD_BDB2=yes
|
|
||||||
if test "$ol_with_bdb2_module" != static ; then
|
|
||||||
AC_DEFINE(SLAPD_BDB2_DYNAMIC,1,
|
|
||||||
[define to support dynamic BDB2 backend])
|
|
||||||
BUILD_BDB2=mod
|
|
||||||
BUILD_BDB2_DYNAMIC=shared
|
|
||||||
SLAPD_MODULES_LIST="$SLAPD_MODULES_LIST -dlopen \$(SLAP_DIR)back-bdb2/back_bdb2.la"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "$ol_link_dnssrv" != no ; then
|
if test "$ol_link_dnssrv" != no ; then
|
||||||
AC_DEFINE(SLAPD_DNSSRV,1,[define to support DNS SRV backend])
|
AC_DEFINE(SLAPD_DNSSRV,1,[define to support DNS SRV backend])
|
||||||
BUILD_SLAPD=yes
|
BUILD_SLAPD=yes
|
||||||
|
|
@ -2343,7 +2283,6 @@ AC_SUBST(LT_LIB_LINKAGE)
|
||||||
AC_SUBST(DYN_EXT)
|
AC_SUBST(DYN_EXT)
|
||||||
|
|
||||||
AC_SUBST(BUILD_SLAPD)
|
AC_SUBST(BUILD_SLAPD)
|
||||||
AC_SUBST(BUILD_BDB2)
|
|
||||||
AC_SUBST(BUILD_DNSSRV)
|
AC_SUBST(BUILD_DNSSRV)
|
||||||
AC_SUBST(BUILD_LDAP)
|
AC_SUBST(BUILD_LDAP)
|
||||||
AC_SUBST(BUILD_LDBM)
|
AC_SUBST(BUILD_LDBM)
|
||||||
|
|
@ -2353,7 +2292,6 @@ AC_SUBST(BUILD_SLAPD)
|
||||||
AC_SUBST(BUILD_SHELL)
|
AC_SUBST(BUILD_SHELL)
|
||||||
AC_SUBST(BUILD_SQL)
|
AC_SUBST(BUILD_SQL)
|
||||||
AC_SUBST(BUILD_TCL)
|
AC_SUBST(BUILD_TCL)
|
||||||
AC_SUBST(BUILD_BDB2_DYNAMIC)
|
|
||||||
AC_SUBST(BUILD_DNSSRV_DYNAMIC)
|
AC_SUBST(BUILD_DNSSRV_DYNAMIC)
|
||||||
AC_SUBST(BUILD_LDAP_DYNAMIC)
|
AC_SUBST(BUILD_LDAP_DYNAMIC)
|
||||||
AC_SUBST(BUILD_LDBM_DYNAMIC)
|
AC_SUBST(BUILD_LDBM_DYNAMIC)
|
||||||
|
|
@ -2429,7 +2367,6 @@ libraries/liblunicode/Makefile:build/top.mk:libraries/liblunicode/Makefile.in:bu
|
||||||
libraries/liblutil/Makefile:build/top.mk:libraries/liblutil/Makefile.in:build/lib.mk:build/lib-static.mk \
|
libraries/liblutil/Makefile:build/top.mk:libraries/liblutil/Makefile.in:build/lib.mk:build/lib-static.mk \
|
||||||
servers/Makefile:build/top.mk:servers/Makefile.in:build/dir.mk \
|
servers/Makefile:build/top.mk:servers/Makefile.in:build/dir.mk \
|
||||||
servers/slapd/Makefile:build/top.mk:servers/slapd/Makefile.in:build/srv.mk \
|
servers/slapd/Makefile:build/top.mk:servers/slapd/Makefile.in:build/srv.mk \
|
||||||
servers/slapd/back-bdb2/Makefile:build/top.mk:servers/slapd/back-bdb2/Makefile.in:build/mod.mk \
|
|
||||||
servers/slapd/back-dnssrv/Makefile:build/top.mk:servers/slapd/back-dnssrv/Makefile.in:build/mod.mk \
|
servers/slapd/back-dnssrv/Makefile:build/top.mk:servers/slapd/back-dnssrv/Makefile.in:build/mod.mk \
|
||||||
servers/slapd/back-ldap/Makefile:build/top.mk:servers/slapd/back-ldap/Makefile.in:build/mod.mk \
|
servers/slapd/back-ldap/Makefile:build/top.mk:servers/slapd/back-ldap/Makefile.in:build/mod.mk \
|
||||||
servers/slapd/back-ldbm/Makefile:build/top.mk:servers/slapd/back-ldbm/Makefile.in:build/mod.mk \
|
servers/slapd/back-ldbm/Makefile:build/top.mk:servers/slapd/back-ldbm/Makefile.in:build/mod.mk \
|
||||||
|
|
|
||||||
|
|
@ -875,12 +875,6 @@
|
||||||
/* define to support modules */
|
/* define to support modules */
|
||||||
#undef SLAPD_MODULES
|
#undef SLAPD_MODULES
|
||||||
|
|
||||||
/* define to support BDB2 backend */
|
|
||||||
#undef SLAPD_BDB2
|
|
||||||
|
|
||||||
/* define to support dynamic BDB2 backend */
|
|
||||||
#undef SLAPD_BDB2_DYNAMIC
|
|
||||||
|
|
||||||
/* define to support DNS SRV backend */
|
/* define to support DNS SRV backend */
|
||||||
#undef SLAPD_DNSSRV
|
#undef SLAPD_DNSSRV
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -264,9 +264,6 @@ typedef signed int ssize_t;
|
||||||
/* define this for ACL Group support */
|
/* define this for ACL Group support */
|
||||||
#define SLAPD_ACLGROUPS 1
|
#define SLAPD_ACLGROUPS 1
|
||||||
|
|
||||||
/* define this to use SLAPD Berkeley DB2 backend */
|
|
||||||
/* #define SLAPD_BDB2 1 */
|
|
||||||
|
|
||||||
/* define this for ClearText password support */
|
/* define this for ClearText password support */
|
||||||
#define SLAPD_CLEARTEXT 1
|
#define SLAPD_CLEARTEXT 1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# $OpenLDAP$
|
|
||||||
|
|
||||||
SRCS = idl.c add.c search.c cache.c dbcache.c dn2id.c entry.c id2entry.c \
|
|
||||||
index.c id2children.c nextid.c abandon.c compare.c group.c \
|
|
||||||
modify.c modrdn.c delete.c init.c config.c bind.c attr.c \
|
|
||||||
filterindex.c unbind.c close.c alias.c startup.c \
|
|
||||||
timing.c porter.c txn.c tools.c
|
|
||||||
OBJS = idl.lo add.lo search.lo cache.lo dbcache.lo dn2id.lo entry.lo id2entry.lo \
|
|
||||||
index.lo id2children.lo nextid.lo abandon.lo compare.lo group.lo \
|
|
||||||
modify.lo modrdn.lo delete.lo init.lo config.lo bind.lo attr.lo \
|
|
||||||
filterindex.lo unbind.lo close.lo alias.lo startup.lo \
|
|
||||||
timing.lo porter.lo txn.lo tools.lo
|
|
||||||
|
|
||||||
LDAP_INCDIR= ../../../include
|
|
||||||
LDAP_LIBDIR= ../../../libraries
|
|
||||||
|
|
||||||
BUILD_OPT = "--enable-bdb2"
|
|
||||||
BUILD_MOD = @BUILD_BDB2@
|
|
||||||
LINKAGE = @BUILD_BDB2_DYNAMIC@
|
|
||||||
|
|
||||||
LIBBASE = back_bdb2
|
|
||||||
|
|
||||||
XINCPATH = -I.. -I$(srcdir)/..
|
|
||||||
XDEFS = $(MODULES_CPPFLAGS)
|
|
||||||
|
|
||||||
all-local-lib: ../.backend
|
|
||||||
|
|
||||||
../.backend: lib$(LIBBASE).a
|
|
||||||
@touch $@
|
|
||||||
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
/* abandon.c - ldbm backend abandon routine */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/string.h>
|
|
||||||
#include <ac/time.h>
|
|
||||||
#include <ac/unistd.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*ARGSUSED*/
|
|
||||||
static int
|
|
||||||
bdb2i_back_abandon_internal(
|
|
||||||
BackendDB *be,
|
|
||||||
Connection *c,
|
|
||||||
Operation *o,
|
|
||||||
int msgid )
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_abandon(
|
|
||||||
BackendDB *be,
|
|
||||||
Connection *conn,
|
|
||||||
Operation *op,
|
|
||||||
int msgid )
|
|
||||||
{
|
|
||||||
struct timeval time1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
bdb2i_start_timing( be->bd_info, &time1 );
|
|
||||||
|
|
||||||
ret = bdb2i_back_abandon_internal( be, conn, op, msgid );
|
|
||||||
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "ABND", conn, op );
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,315 +0,0 @@
|
||||||
/* add.c - ldap bdb2 back-end add routine */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/socket.h>
|
|
||||||
#include <ac/string.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
#include "proto-back-bdb2.h"
|
|
||||||
|
|
||||||
static DB_LOCK lock;
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
bdb2i_back_add_internal(
|
|
||||||
BackendDB *be,
|
|
||||||
Connection *conn,
|
|
||||||
Operation *op,
|
|
||||||
Entry *e
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
char *pdn;
|
|
||||||
Entry *p = NULL;
|
|
||||||
int rc;
|
|
||||||
struct timeval time1;
|
|
||||||
|
|
||||||
Debug(LDAP_DEBUG_ARGS, "==> bdb2i_back_add: %s\n", e->e_dn, 0, 0);
|
|
||||||
|
|
||||||
if ( ( bdb2i_dn2id( be, e->e_ndn ) ) != NOID ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_ALREADY_EXISTS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( schema_check_entry( e ) != 0 ) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "entry failed schema check\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
|
|
||||||
send_ldap_result( conn, op, LDAP_OBJECT_CLASS_VIOLATION,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the parent dn and see if the corresponding entry exists.
|
|
||||||
* If the parent does not exist, only allow the "root" user to
|
|
||||||
* add the entry.
|
|
||||||
*/
|
|
||||||
|
|
||||||
pdn = dn_parent( be, e->e_ndn );
|
|
||||||
|
|
||||||
if( pdn != NULL && *pdn != '\0' ) {
|
|
||||||
Entry *matched = NULL;
|
|
||||||
|
|
||||||
assert( *pdn != '\0' );
|
|
||||||
|
|
||||||
/* get parent with writer lock */
|
|
||||||
if ( (p = bdb2i_dn2entry_w( be, pdn, &matched )) == NULL ) {
|
|
||||||
char *matched_dn;
|
|
||||||
struct berval **refs;
|
|
||||||
|
|
||||||
if( matched != NULL ) {
|
|
||||||
matched_dn = ch_strdup( matched->e_dn );
|
|
||||||
refs = is_entry_referral( matched )
|
|
||||||
? get_entry_referrals( be, conn, op, matched )
|
|
||||||
: NULL;
|
|
||||||
|
|
||||||
bdb2i_cache_return_entry_w( &li->li_cache, matched );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
matched_dn = NULL;
|
|
||||||
refs = default_referral;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "parent does not exist\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
|
|
||||||
send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
|
|
||||||
matched_dn, NULL, NULL, NULL );
|
|
||||||
|
|
||||||
if ( matched != NULL ) {
|
|
||||||
ber_bvecfree( refs );
|
|
||||||
free( matched_dn );
|
|
||||||
}
|
|
||||||
|
|
||||||
free( pdn );
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(pdn);
|
|
||||||
|
|
||||||
if ( ! access_allowed( be, conn, op, p,
|
|
||||||
"children", NULL, ACL_WRITE ) )
|
|
||||||
{
|
|
||||||
/* free parent and writer lock */
|
|
||||||
bdb2i_cache_return_entry_w( &li->li_cache, p );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
|
|
||||||
0, 0 );
|
|
||||||
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ( is_entry_alias( p ) ) {
|
|
||||||
/* parent is an alias, don't allow add */
|
|
||||||
|
|
||||||
/* free parent and writer lock */
|
|
||||||
bdb2i_cache_return_entry_w( &li->li_cache, p );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "parent is alias\n", 0,
|
|
||||||
0, 0 );
|
|
||||||
send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( is_entry_referral( p ) ) {
|
|
||||||
/* parent is an referral, don't allow add */
|
|
||||||
char *matched_dn = ch_strdup( matched->e_dn );
|
|
||||||
struct berval **refs = is_entry_referral( matched )
|
|
||||||
? get_entry_referrals( be, conn, op, matched )
|
|
||||||
: NULL;
|
|
||||||
|
|
||||||
/* free parent and writer lock */
|
|
||||||
bdb2i_cache_return_entry_w( &li->li_cache, p );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "parent is referral\n", 0,
|
|
||||||
0, 0 );
|
|
||||||
send_ldap_result( conn, op, LDAP_REFERRAL,
|
|
||||||
matched_dn, NULL, refs, NULL );
|
|
||||||
|
|
||||||
ber_bvecfree( refs );
|
|
||||||
free( matched_dn );
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if(pdn != NULL) {
|
|
||||||
assert( *pdn == '\0' );
|
|
||||||
free(pdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* no parent, must be adding entry to root */
|
|
||||||
if ( !be_isroot( be, op->o_ndn ) && !be_issuffix(be, "") ) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "%s add denied\n",
|
|
||||||
pdn == NULL ? "suffix" : "entry at root",
|
|
||||||
0, 0 );
|
|
||||||
|
|
||||||
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
e->e_id = bdb2i_next_id( be );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Try to add the entry to the cache, assign it a new dnid.
|
|
||||||
*/
|
|
||||||
bdb2i_start_timing( be->bd_info, &time1 );
|
|
||||||
|
|
||||||
rc = bdb2i_cache_add_entry_rw( &li->li_cache, e, CACHE_WRITE_LOCK );
|
|
||||||
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "ADD-CACHE", conn, op );
|
|
||||||
|
|
||||||
if ( rc != 0 ) {
|
|
||||||
if( p != NULL) {
|
|
||||||
/* free parent and writer lock */
|
|
||||||
bdb2i_cache_return_entry_w( &li->li_cache, p );
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ANY, "cache_add_entry_lock failed\n", 0, 0,
|
|
||||||
0 );
|
|
||||||
|
|
||||||
send_ldap_result( conn, op,
|
|
||||||
rc > 0 ? LDAP_ALREADY_EXISTS : LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = -1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Add the entry to the attribute indexes, then add it to
|
|
||||||
* the id2entry and dn2id index.
|
|
||||||
*/
|
|
||||||
|
|
||||||
bdb2i_start_timing( be->bd_info, &time1 );
|
|
||||||
|
|
||||||
/* attribute indexes */
|
|
||||||
if ( bdb2i_index_add_entry( be, e ) != 0 ) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "bdb2i_index_add_entry failed\n", 0,
|
|
||||||
0, 0 );
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "ADD-INDEX", conn, op );
|
|
||||||
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "ADD-INDEX", conn, op );
|
|
||||||
|
|
||||||
bdb2i_start_timing( be->bd_info, &time1 );
|
|
||||||
|
|
||||||
/* dn2id index */
|
|
||||||
if ( bdb2i_dn2id_add( be, e->e_ndn, e->e_id ) != 0 ) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "bdb2i_dn2id_add failed\n", 0,
|
|
||||||
0, 0 );
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "ADD-DN2ID", conn, op );
|
|
||||||
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "ADD-DN2ID", conn, op );
|
|
||||||
|
|
||||||
bdb2i_start_timing( be->bd_info, &time1 );
|
|
||||||
|
|
||||||
/* id2entry index */
|
|
||||||
if ( bdb2i_id2entry_add( be, e ) != 0 ) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "bdb2i_id2entry_add failed\n", 0,
|
|
||||||
0, 0 );
|
|
||||||
(void) bdb2i_dn2id_delete( be, e->e_ndn, e->e_id );
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "ADD-ID2ENTRY", conn, op );
|
|
||||||
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "ADD-ID2ENTRY", conn, op );
|
|
||||||
|
|
||||||
send_ldap_result( conn, op, LDAP_SUCCESS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
rc = 0;
|
|
||||||
|
|
||||||
return_results:;
|
|
||||||
if (p != NULL) {
|
|
||||||
/* free parent and writer lock */
|
|
||||||
bdb2i_cache_return_entry_w( &li->li_cache, p );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( rc ) {
|
|
||||||
/* free entry and writer lock */
|
|
||||||
bdb2i_cache_return_entry_w( &li->li_cache, e );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_add(
|
|
||||||
BackendDB *be,
|
|
||||||
Connection *conn,
|
|
||||||
Operation *op,
|
|
||||||
Entry *e
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
struct timeval time1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
bdb2i_start_timing( be->bd_info, &time1 );
|
|
||||||
|
|
||||||
if ( bdb2i_enter_backend_w( &lock ) != 0 ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check, if a new default attribute index will be created,
|
|
||||||
in which case we have to open the index file BEFORE TP */
|
|
||||||
switch ( slapMode & SLAP_MODE ) {
|
|
||||||
case SLAP_SERVER_MODE:
|
|
||||||
case SLAP_TOOL_MODE:
|
|
||||||
bdb2i_check_default_attr_index_add( li, e );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = bdb2i_back_add_internal( be, conn, op, e );
|
|
||||||
|
|
||||||
/* if the operation was successful, we will delay the unlock */
|
|
||||||
if ( ret )
|
|
||||||
(void) bdb2i_leave_backend_w( lock );
|
|
||||||
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "ADD", conn, op );
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_release_add_lock( void )
|
|
||||||
{
|
|
||||||
(void) bdb2i_leave_backend_w( lock );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,286 +0,0 @@
|
||||||
/* $OpenLDAP$ */
|
|
||||||
/*
|
|
||||||
* Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
|
|
||||||
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ac/string.h>
|
|
||||||
#include <ac/socket.h>
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
#include "proto-back-bdb2.h"
|
|
||||||
|
|
||||||
static char* get_alias_dn(
|
|
||||||
Entry *e,
|
|
||||||
int *err,
|
|
||||||
char **errmsg );
|
|
||||||
|
|
||||||
static char* new_superior(
|
|
||||||
char *dn,
|
|
||||||
char *oldSup,
|
|
||||||
char *newSup );
|
|
||||||
|
|
||||||
static int dnlist_subordinate(
|
|
||||||
char** dnlist,
|
|
||||||
char *dn );
|
|
||||||
|
|
||||||
Entry *bdb2i_deref_r(
|
|
||||||
Backend* be,
|
|
||||||
Entry* alias,
|
|
||||||
char* dn,
|
|
||||||
int* err,
|
|
||||||
Entry** matched,
|
|
||||||
char** text )
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
Entry *entry;
|
|
||||||
Entry *sup;
|
|
||||||
unsigned depth;
|
|
||||||
char **dnlist;
|
|
||||||
|
|
||||||
assert( ( alias != NULL && dn == NULL ) || ( alias == NULL && dn != NULL ) );
|
|
||||||
|
|
||||||
*matched = NULL;
|
|
||||||
*err = LDAP_SUCCESS;
|
|
||||||
*text = NULL;
|
|
||||||
|
|
||||||
if( alias == NULL ) {
|
|
||||||
dn = ch_strdup( dn );
|
|
||||||
entry = bdb2i_dn2entry_r( be, dn, &sup );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
dn = ch_strdup( alias->e_ndn );
|
|
||||||
entry = alias;
|
|
||||||
sup = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
dnlist = NULL;
|
|
||||||
charray_add( &dnlist, dn );
|
|
||||||
|
|
||||||
for( depth=0 ; ; depth++ ) {
|
|
||||||
if( entry != NULL ) {
|
|
||||||
Entry *newe;
|
|
||||||
char *aliasDN;
|
|
||||||
|
|
||||||
/* have entry, may be an alias */
|
|
||||||
|
|
||||||
if( !is_entry_alias( entry ) ) {
|
|
||||||
/* entry is not an alias */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* entry is alias */
|
|
||||||
if( depth > be->be_max_deref_depth ) {
|
|
||||||
*matched = entry;
|
|
||||||
entry = NULL;
|
|
||||||
*err = LDAP_ALIAS_DEREF_PROBLEM;
|
|
||||||
*text = "maximum deref depth exceeded";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* deref entry */
|
|
||||||
aliasDN = get_alias_dn( entry, err, text );
|
|
||||||
|
|
||||||
if( aliasDN == NULL ) {
|
|
||||||
*matched = entry;
|
|
||||||
entry = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check if aliasDN is a subordinate of any DN in our list */
|
|
||||||
if( dnlist_subordinate( dnlist, aliasDN ) ) {
|
|
||||||
*matched = entry;
|
|
||||||
entry = NULL;
|
|
||||||
*err = LDAP_ALIAS_PROBLEM;
|
|
||||||
*text = "circular alias";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* attempt to dereference alias */
|
|
||||||
|
|
||||||
newe = bdb2i_dn2entry_r( be, aliasDN, &sup );
|
|
||||||
|
|
||||||
if( newe != NULL ) {
|
|
||||||
free( dn );
|
|
||||||
bdb2i_cache_return_entry_r(&li->li_cache, entry );
|
|
||||||
entry = newe;
|
|
||||||
dn = ch_strdup( entry->e_ndn );
|
|
||||||
charray_add( &dnlist, dn );
|
|
||||||
continue;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( sup != NULL ) {
|
|
||||||
bdb2i_cache_return_entry_r(&li->li_cache, entry );
|
|
||||||
entry = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* no newe and no superior, we're done */
|
|
||||||
break;
|
|
||||||
|
|
||||||
} else if( sup != NULL ) {
|
|
||||||
/* have superior, may be an alias */
|
|
||||||
Entry *newe;
|
|
||||||
Entry *newSup;
|
|
||||||
char *supDN;
|
|
||||||
char *aliasDN;
|
|
||||||
|
|
||||||
if( !is_entry_alias( sup ) ) {
|
|
||||||
/* entry is not an alias */
|
|
||||||
*matched = sup;
|
|
||||||
sup = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* entry is alias */
|
|
||||||
if( depth > be->be_max_deref_depth ) {
|
|
||||||
*matched = sup;
|
|
||||||
entry = NULL;
|
|
||||||
*err = LDAP_ALIAS_DEREF_PROBLEM;
|
|
||||||
*text = "maximum deref depth exceeded";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* deref entry */
|
|
||||||
supDN = get_alias_dn( sup, err, text );
|
|
||||||
|
|
||||||
if( supDN == NULL ) {
|
|
||||||
*matched = sup;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
aliasDN = new_superior( dn, sup->e_ndn, supDN );
|
|
||||||
|
|
||||||
if( aliasDN == NULL ) {
|
|
||||||
free(aliasDN);
|
|
||||||
*matched = sup;
|
|
||||||
*err = LDAP_ALIAS_PROBLEM;
|
|
||||||
*text = "superior alias problem";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check if aliasDN is a subordinate of any DN in our list */
|
|
||||||
if( dnlist_subordinate( dnlist, aliasDN ) ) {
|
|
||||||
free(aliasDN);
|
|
||||||
*matched = entry;
|
|
||||||
entry = NULL;
|
|
||||||
*err = LDAP_ALIAS_PROBLEM;
|
|
||||||
*text = "subordinate circular alias";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* attempt to dereference alias */
|
|
||||||
newe = bdb2i_dn2entry_r( be, aliasDN, &newSup );
|
|
||||||
|
|
||||||
if( newe != NULL ) {
|
|
||||||
free(aliasDN);
|
|
||||||
free( dn );
|
|
||||||
bdb2i_cache_return_entry_r(&li->li_cache, sup );
|
|
||||||
entry = newe;
|
|
||||||
dn = ch_strdup( entry->e_ndn );
|
|
||||||
charray_add( &dnlist, dn );
|
|
||||||
continue;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( newSup != NULL ) {
|
|
||||||
free( dn );
|
|
||||||
bdb2i_cache_return_entry_r(&li->li_cache, sup );
|
|
||||||
sup = newSup;
|
|
||||||
dn = aliasDN;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/* no newe and no superior, we're done */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free( dn );
|
|
||||||
charray_free( dnlist );
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static char* get_alias_dn(
|
|
||||||
Entry *e,
|
|
||||||
int *err,
|
|
||||||
char **errmsg )
|
|
||||||
{
|
|
||||||
Attribute *a = attr_find( e->e_attrs, "aliasedobjectname" );
|
|
||||||
|
|
||||||
if( a == NULL ) {
|
|
||||||
/*
|
|
||||||
* there was an aliasedobjectname defined but no data.
|
|
||||||
*/
|
|
||||||
*err = LDAP_ALIAS_PROBLEM;
|
|
||||||
*errmsg = "alias missing aliasedObjectName attribute";
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* aliasedObjectName should be SINGLE-VALUED with a single value.
|
|
||||||
*/
|
|
||||||
if ( a->a_vals[0] == NULL || a->a_vals[0]->bv_val == NULL ) {
|
|
||||||
/*
|
|
||||||
* there was an aliasedobjectname defined but no data.
|
|
||||||
*/
|
|
||||||
*err = LDAP_ALIAS_PROBLEM;
|
|
||||||
*errmsg = "alias missing aliasedObjectName value";
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( a->a_vals[1] != NULL ) {
|
|
||||||
*err = LDAP_ALIAS_PROBLEM;
|
|
||||||
*errmsg = "alias has multivalued aliasedObjectName";
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a->a_vals[0]->bv_val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char* new_superior(
|
|
||||||
char *dn,
|
|
||||||
char *oldSup,
|
|
||||||
char *newSup )
|
|
||||||
{
|
|
||||||
char *newDN;
|
|
||||||
size_t dnlen, olen, nlen;
|
|
||||||
assert( dn && oldSup && newSup );
|
|
||||||
|
|
||||||
dnlen = strlen( dn );
|
|
||||||
olen = strlen( oldSup );
|
|
||||||
nlen = strlen( newSup );
|
|
||||||
|
|
||||||
newDN = ch_malloc( dnlen - olen + nlen + 1 );
|
|
||||||
|
|
||||||
memcpy( newDN, dn, dnlen - olen );
|
|
||||||
memcpy( &newDN[dnlen - olen], newSup, nlen );
|
|
||||||
newDN[dnlen - olen + nlen] = '\0';
|
|
||||||
|
|
||||||
return newDN;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dnlist_subordinate(
|
|
||||||
char** dnlist,
|
|
||||||
char *dn )
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
assert( dnlist );
|
|
||||||
|
|
||||||
for( i = 0; dnlist[i] != NULL; i++ ) {
|
|
||||||
if( dn_issuffix( dnlist[i], dn ) ) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,174 +0,0 @@
|
||||||
/* attr.c - backend routines for dealing with attributes */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/socket.h>
|
|
||||||
#include <ac/string.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
|
|
||||||
static int
|
|
||||||
ainfo_type_cmp(
|
|
||||||
char *type,
|
|
||||||
struct attrinfo *a
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return( strcasecmp( type, a->ai_type ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
ainfo_cmp(
|
|
||||||
struct attrinfo *a,
|
|
||||||
struct attrinfo *b
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return( strcasecmp( a->ai_type, b->ai_type ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Called when a duplicate "index" line is encountered.
|
|
||||||
*
|
|
||||||
* returns 1 => original from init code, indexmask updated
|
|
||||||
* 2 => original not from init code, warn the user
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int
|
|
||||||
ainfo_dup(
|
|
||||||
struct attrinfo *a,
|
|
||||||
struct attrinfo *b
|
|
||||||
)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* if the duplicate definition is because we initialized the attr,
|
|
||||||
* just add what came from the config file. otherwise, complain.
|
|
||||||
*/
|
|
||||||
if ( a->ai_indexmask & INDEX_FROMINIT ) {
|
|
||||||
a->ai_indexmask |= b->ai_indexmask;
|
|
||||||
|
|
||||||
return( 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( 2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
bdb2i_attr_masks(
|
|
||||||
struct ldbminfo *li,
|
|
||||||
char *type,
|
|
||||||
int *indexmask,
|
|
||||||
int *syntaxmask
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct attrinfo *a;
|
|
||||||
|
|
||||||
*indexmask = 0;
|
|
||||||
*syntaxmask = 0;
|
|
||||||
if ( (a = (struct attrinfo *) avl_find( li->li_attrs, type,
|
|
||||||
(AVL_CMP) ainfo_type_cmp )) == NULL ) {
|
|
||||||
if ( (a = (struct attrinfo *) avl_find( li->li_attrs, "default",
|
|
||||||
(AVL_CMP) ainfo_type_cmp )) == NULL ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*indexmask = a->ai_indexmask;
|
|
||||||
if ( strcasecmp( a->ai_type, "default" ) == 0 ) {
|
|
||||||
*syntaxmask = attr_syntax( type );
|
|
||||||
} else {
|
|
||||||
*syntaxmask = a->ai_syntaxmask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* BDB2 changed */
|
|
||||||
void
|
|
||||||
bdb2i_attr_index_config(
|
|
||||||
struct ldbminfo *li,
|
|
||||||
const char *fname,
|
|
||||||
int lineno,
|
|
||||||
int argc,
|
|
||||||
char **argv,
|
|
||||||
int init
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
char **attrs, **indexes;
|
|
||||||
struct attrinfo *a;
|
|
||||||
|
|
||||||
attrs = str2charray( argv[0], "," );
|
|
||||||
if ( argc > 1 ) {
|
|
||||||
indexes = str2charray( argv[1], "," );
|
|
||||||
}
|
|
||||||
for ( i = 0; attrs[i] != NULL; i++ ) {
|
|
||||||
a = (struct attrinfo *) ch_malloc( sizeof(struct attrinfo) );
|
|
||||||
a->ai_type = ch_strdup( attrs[i] );
|
|
||||||
a->ai_syntaxmask = attr_syntax( a->ai_type );
|
|
||||||
if ( argc == 1 ) {
|
|
||||||
a->ai_indexmask = (INDEX_PRESENCE | INDEX_EQUALITY |
|
|
||||||
INDEX_APPROX | INDEX_SUB);
|
|
||||||
} else {
|
|
||||||
a->ai_indexmask = 0;
|
|
||||||
for ( j = 0; indexes[j] != NULL; j++ ) {
|
|
||||||
if ( strncasecmp( indexes[j], "pres", 4 )
|
|
||||||
== 0 ) {
|
|
||||||
a->ai_indexmask |= INDEX_PRESENCE;
|
|
||||||
} else if ( strncasecmp( indexes[j], "eq", 2 )
|
|
||||||
== 0 ) {
|
|
||||||
a->ai_indexmask |= INDEX_EQUALITY;
|
|
||||||
} else if ( strncasecmp( indexes[j], "approx",
|
|
||||||
6 ) == 0 ) {
|
|
||||||
a->ai_indexmask |= INDEX_APPROX;
|
|
||||||
} else if ( strncasecmp( indexes[j], "sub", 3 )
|
|
||||||
== 0 ) {
|
|
||||||
a->ai_indexmask |= INDEX_SUB;
|
|
||||||
} else if ( strncasecmp( indexes[j], "none", 4 )
|
|
||||||
== 0 ) {
|
|
||||||
if ( a->ai_indexmask != 0 ) {
|
|
||||||
fprintf( stderr,
|
|
||||||
"%s: line %d: index type \"none\" cannot be combined with other types\n",
|
|
||||||
fname, lineno );
|
|
||||||
}
|
|
||||||
a->ai_indexmask = 0;
|
|
||||||
} else {
|
|
||||||
fprintf( stderr,
|
|
||||||
"%s: line %d: unknown index type \"%s\" (ignored)\n",
|
|
||||||
fname, lineno, indexes[j] );
|
|
||||||
fprintf( stderr,
|
|
||||||
"valid index types are \"pres\", \"eq\", \"approx\", or \"sub\"\n" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( init ) {
|
|
||||||
a->ai_indexmask |= INDEX_FROMINIT;
|
|
||||||
} else {
|
|
||||||
if ( a->ai_indexmask )
|
|
||||||
bdb2i_txn_attr_config( li, a->ai_type, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (avl_insert( &li->li_attrs, (caddr_t) a,
|
|
||||||
(AVL_CMP) ainfo_cmp, (AVL_DUP) ainfo_dup ))
|
|
||||||
{
|
|
||||||
case 1: /* duplicate - updating init version */
|
|
||||||
free( a->ai_type );
|
|
||||||
free( (char *) a );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2: /* user duplicate - ignore and warn */
|
|
||||||
fprintf( stderr,
|
|
||||||
"%s: line %d: duplicate index definition for attr \"%s\" (ignored)\n",
|
|
||||||
fname, lineno, a->ai_type );
|
|
||||||
free( a->ai_type );
|
|
||||||
free( (char *) a );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:; /* inserted ok */
|
|
||||||
/* FALL */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
charray_free( attrs );
|
|
||||||
if ( argc > 1 )
|
|
||||||
charray_free( indexes );
|
|
||||||
}
|
|
||||||
|
|
@ -1,201 +0,0 @@
|
||||||
/* back-bdb2.h - ldap bdb2 back-end header file */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#ifndef _BACK_BDB2_H_
|
|
||||||
#define _BACK_BDB2_H_
|
|
||||||
|
|
||||||
#include "ldbm.h"
|
|
||||||
#include "db.h"
|
|
||||||
|
|
||||||
LDAP_BEGIN_DECL
|
|
||||||
|
|
||||||
#define DEFAULT_CACHE_SIZE 1000
|
|
||||||
|
|
||||||
/* since DEFAULT_DB_PAGE_SIZE is 1K, we have 128K,
|
|
||||||
which is suggested by Sleepycat */
|
|
||||||
#define DEFAULT_DBCACHE_SIZE (128 * DEFAULT_DB_PAGE_SIZE)
|
|
||||||
|
|
||||||
#define DEFAULT_DB_DIRECTORY LDAP_RUNDIR LDAP_DIRSEP "openldap-bdb2"
|
|
||||||
#define DEFAULT_DB_HOME DEFAULT_DB_DIRECTORY
|
|
||||||
#define DEFAULT_MODE 0600
|
|
||||||
|
|
||||||
#define SUBLEN 3
|
|
||||||
|
|
||||||
#define DN_BASE_PREFIX '='
|
|
||||||
#define DN_ONE_PREFIX '@'
|
|
||||||
#define DN_SUBTREE_PREFIX '?'
|
|
||||||
|
|
||||||
#define BDB2_SUFFIX ".bdb2"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* there is a single index for each attribute. these prefixes ensure
|
|
||||||
* that there is no collision among keys.
|
|
||||||
*/
|
|
||||||
#define EQ_PREFIX '=' /* prefix for equality keys */
|
|
||||||
#define APPROX_PREFIX '~' /* prefix for approx keys */
|
|
||||||
#define SUB_PREFIX '*' /* prefix for substring keys */
|
|
||||||
#define CONT_PREFIX '\\' /* prefix for continuation keys */
|
|
||||||
|
|
||||||
/* allow 3 characters per byte + PREFIX + EOS */
|
|
||||||
#define CONT_SIZE ( sizeof(long)*3 + 1 + 1 )
|
|
||||||
|
|
||||||
|
|
||||||
#define UNKNOWN_PREFIX '?' /* prefix for unknown keys */
|
|
||||||
|
|
||||||
#define DEFAULT_BLOCKSIZE 8192
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This structure represents an id block on disk and an id list
|
|
||||||
* in core.
|
|
||||||
*
|
|
||||||
* The fields have the following meanings:
|
|
||||||
*
|
|
||||||
* b_nmax maximum number of ids in this block. if this is == ALLIDSBLOCK,
|
|
||||||
* then this block represents all ids.
|
|
||||||
* b_nids current number of ids in use in this block. if this
|
|
||||||
* is == INDBLOCK, then this block is an indirect block
|
|
||||||
* containing a list of other blocks containing actual ids.
|
|
||||||
* the list is terminated by an id of NOID.
|
|
||||||
* b_ids a list of the actual ids themselves
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef ID ID_BLOCK;
|
|
||||||
|
|
||||||
#define ID_BLOCK_NMAX_OFFSET 0
|
|
||||||
#define ID_BLOCK_NIDS_OFFSET 1
|
|
||||||
#define ID_BLOCK_IDS_OFFSET 2
|
|
||||||
|
|
||||||
/* all ID_BLOCK macros operate on a pointer to a ID_BLOCK */
|
|
||||||
|
|
||||||
#define ID_BLOCK_NMAX(b) ((b)[ID_BLOCK_NMAX_OFFSET])
|
|
||||||
#define ID_BLOCK_NIDS(b) ((b)[ID_BLOCK_NIDS_OFFSET])
|
|
||||||
#define ID_BLOCK_ID(b, n) ((b)[ID_BLOCK_IDS_OFFSET+(n)])
|
|
||||||
|
|
||||||
#define ID_BLOCK_NOID(b, n) (ID_BLOCK_ID((b),(n)) == NOID)
|
|
||||||
|
|
||||||
#define ID_BLOCK_ALLIDS_VALUE 0
|
|
||||||
#define ID_BLOCK_ALLIDS(b) (ID_BLOCK_NMAX(b) == ID_BLOCK_ALLIDS_VALUE)
|
|
||||||
|
|
||||||
#define ID_BLOCK_INDIRECT_VALUE 0
|
|
||||||
#define ID_BLOCK_INDIRECT(b) (ID_BLOCK_NIDS(b) == ID_BLOCK_INDIRECT_VALUE)
|
|
||||||
|
|
||||||
/* for the in-core cache of entries */
|
|
||||||
struct cache {
|
|
||||||
int c_maxsize;
|
|
||||||
int c_cursize;
|
|
||||||
Avlnode *c_dntree;
|
|
||||||
Avlnode *c_idtree;
|
|
||||||
Entry *c_lruhead; /* lru - add accessed entries here */
|
|
||||||
Entry *c_lrutail; /* lru - rem lru entries from here */
|
|
||||||
ldap_pvt_thread_mutex_t c_mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CACHE_READ_LOCK 0
|
|
||||||
#define CACHE_WRITE_LOCK 1
|
|
||||||
|
|
||||||
/* for the cache of open index files (re-used for txn) */
|
|
||||||
struct dbcache {
|
|
||||||
int dbc_refcnt;
|
|
||||||
int dbc_maxids;
|
|
||||||
int dbc_maxindirect;
|
|
||||||
long dbc_blksize;
|
|
||||||
char *dbc_name;
|
|
||||||
LDBM dbc_db;
|
|
||||||
|
|
||||||
struct dbcache *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct dbcache BDB2_TXN_FILES;
|
|
||||||
typedef struct dbcache DBCache;
|
|
||||||
|
|
||||||
|
|
||||||
/* for the cache of attribute information (which are indexed, etc.) */
|
|
||||||
struct attrinfo {
|
|
||||||
char *ai_type; /* type name (cn, sn, ...) */
|
|
||||||
int ai_indexmask; /* how the attr is indexed */
|
|
||||||
#define INDEX_PRESENCE 0x0001
|
|
||||||
#define INDEX_EQUALITY 0x0002
|
|
||||||
#define INDEX_APPROX 0x0004
|
|
||||||
#define INDEX_SUB 0x0008
|
|
||||||
#define INDEX_UNKNOWN 0x0010
|
|
||||||
#define INDEX_FROMINIT 0x1000
|
|
||||||
int ai_syntaxmask; /* what kind of syntax */
|
|
||||||
/* ...from slap.h...
|
|
||||||
#define SYNTAX_CIS 0x01
|
|
||||||
#define SYNTAX_CES 0x02
|
|
||||||
#define SYNTAX_BIN 0x04
|
|
||||||
... etc. ...
|
|
||||||
*/
|
|
||||||
};
|
|
||||||
|
|
||||||
/* TP stuff */
|
|
||||||
|
|
||||||
typedef struct _bdb2_txn_head {
|
|
||||||
|
|
||||||
/* log size and timer to control checkpoints */
|
|
||||||
u_int32_t txn_log;
|
|
||||||
u_int32_t txn_time;
|
|
||||||
|
|
||||||
/* a list of all DB files in use */
|
|
||||||
BDB2_TXN_FILES *dbFiles;
|
|
||||||
|
|
||||||
/* we have five fixed files */
|
|
||||||
#define BDB2_DB_DN_FILE 0
|
|
||||||
#define BDB2_DB_DN2ID_FILE 1
|
|
||||||
#define BDB2_DB_ID2ENTRY_FILE 2
|
|
||||||
#define BDB2_DB_ID2CHILDREN_FILE 3
|
|
||||||
#define BDB2_DB_OC_IDX_FILE 4
|
|
||||||
|
|
||||||
/* a database handle for the NEXTID file
|
|
||||||
(must be opened like all DB files at startup
|
|
||||||
and closed on shutdown */
|
|
||||||
LDBM nextidFile;
|
|
||||||
|
|
||||||
/* is the default attribute index set to non-none */
|
|
||||||
int withDefIDX;
|
|
||||||
#define BDB2_WITH_DEF_IDX 1
|
|
||||||
|
|
||||||
/* a handle for the backend's environment */
|
|
||||||
DB_ENV **dbenvH;
|
|
||||||
|
|
||||||
} BDB2_TXN_HEAD;
|
|
||||||
|
|
||||||
|
|
||||||
/* end of TP stuff */
|
|
||||||
|
|
||||||
|
|
||||||
/* the private description of a backend type */
|
|
||||||
struct ldbtype {
|
|
||||||
char *lty_dbhome;
|
|
||||||
size_t lty_mpsize;
|
|
||||||
int lty_betiming;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define with_timing(bi) (((struct ldbtype *) \
|
|
||||||
(bi)->bi_private)->lty_betiming == 1)
|
|
||||||
|
|
||||||
/* The DB environment */
|
|
||||||
extern DB_ENV bdb2i_dbEnv;
|
|
||||||
|
|
||||||
|
|
||||||
/* the private description of a database */
|
|
||||||
struct ldbminfo {
|
|
||||||
ID li_nextid;
|
|
||||||
char *li_nextid_file;
|
|
||||||
int li_mode;
|
|
||||||
char *li_directory;
|
|
||||||
struct cache li_cache;
|
|
||||||
Avlnode *li_attrs;
|
|
||||||
int li_dbcachesize;
|
|
||||||
|
|
||||||
/* a list of all files of the database */
|
|
||||||
BDB2_TXN_HEAD li_txn_head;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#include "proto-back-bdb2.h"
|
|
||||||
|
|
||||||
LDAP_END_DECL
|
|
||||||
|
|
||||||
#endif /* _back_bdb2_h_ */
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
# Microsoft Developer Studio Project File - Name="backbdb2" - Package Owner=<4>
|
|
||||||
# Microsoft Developer Studio Generated Build File, Format Version 5.00
|
|
||||||
# ** DO NOT EDIT **
|
|
||||||
|
|
||||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
|
||||||
|
|
||||||
CFG=backbdb2 - Win32 Debug
|
|
||||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
|
||||||
!MESSAGE use the Export Makefile command and run
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE NMAKE /f "backbdb2.mak".
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE You can specify a configuration when running NMAKE
|
|
||||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE NMAKE /f "backbdb2.mak" CFG="backbdb2 - Win32 Debug"
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE Possible choices for configuration are:
|
|
||||||
!MESSAGE
|
|
||||||
!MESSAGE "backbdb2 - Win32 Release" (based on "Win32 (x86) Static Library")
|
|
||||||
!MESSAGE "backbdb2 - Win32 Debug" (based on "Win32 (x86) Static Library")
|
|
||||||
!MESSAGE
|
|
||||||
|
|
||||||
# Begin Project
|
|
||||||
# PROP Scc_ProjName ""
|
|
||||||
# PROP Scc_LocalPath ""
|
|
||||||
CPP=cl.exe
|
|
||||||
|
|
||||||
!IF "$(CFG)" == "backbdb2 - Win32 Release"
|
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
|
||||||
# PROP BASE Use_Debug_Libraries 0
|
|
||||||
# PROP BASE Output_Dir "Release"
|
|
||||||
# PROP BASE Intermediate_Dir "Release"
|
|
||||||
# PROP BASE Target_Dir ""
|
|
||||||
# PROP Use_MFC 0
|
|
||||||
# PROP Use_Debug_Libraries 0
|
|
||||||
# PROP Output_Dir "Release"
|
|
||||||
# PROP Intermediate_Dir "Release"
|
|
||||||
# PROP Target_Dir ""
|
|
||||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
|
||||||
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
|
||||||
BSC32=bscmake.exe
|
|
||||||
# ADD BASE BSC32 /nologo
|
|
||||||
# ADD BSC32 /nologo
|
|
||||||
LIB32=link.exe -lib
|
|
||||||
# ADD BASE LIB32 /nologo
|
|
||||||
# ADD LIB32 /nologo
|
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "backbdb2 - Win32 Debug"
|
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
|
||||||
# PROP BASE Use_Debug_Libraries 1
|
|
||||||
# PROP BASE Output_Dir "Debug"
|
|
||||||
# PROP BASE Intermediate_Dir "Debug"
|
|
||||||
# PROP BASE Target_Dir ""
|
|
||||||
# PROP Use_MFC 0
|
|
||||||
# PROP Use_Debug_Libraries 1
|
|
||||||
# PROP Output_Dir "Debug"
|
|
||||||
# PROP Intermediate_Dir "Debug"
|
|
||||||
# PROP Target_Dir ""
|
|
||||||
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
|
|
||||||
# ADD CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
|
|
||||||
BSC32=bscmake.exe
|
|
||||||
# ADD BASE BSC32 /nologo
|
|
||||||
# ADD BSC32 /nologo
|
|
||||||
LIB32=link.exe -lib
|
|
||||||
# ADD BASE LIB32 /nologo
|
|
||||||
# ADD LIB32 /nologo
|
|
||||||
|
|
||||||
!ENDIF
|
|
||||||
|
|
||||||
# Begin Target
|
|
||||||
|
|
||||||
# Name "backbdb2 - Win32 Release"
|
|
||||||
# Name "backbdb2 - Win32 Debug"
|
|
||||||
# End Target
|
|
||||||
# End Project
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
Microsoft Developer Studio Workspace File, Format Version 5.00
|
|
||||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
Project: "backbdb2"=".\backbdb2.dsp" - Package Owner=<4>
|
|
||||||
|
|
||||||
Package=<5>
|
|
||||||
{{{
|
|
||||||
}}}
|
|
||||||
|
|
||||||
Package=<4>
|
|
||||||
{{{
|
|
||||||
}}}
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
Global:
|
|
||||||
|
|
||||||
Package=<5>
|
|
||||||
{{{
|
|
||||||
}}}
|
|
||||||
|
|
||||||
Package=<3>
|
|
||||||
{{{
|
|
||||||
}}}
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
|
|
@ -1,313 +0,0 @@
|
||||||
/* bind.c - bdb2 backend bind and unbind routines */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/krb.h>
|
|
||||||
#include <ac/socket.h>
|
|
||||||
#include <ac/string.h>
|
|
||||||
#include <ac/unistd.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
#include "proto-back-bdb2.h"
|
|
||||||
|
|
||||||
static int
|
|
||||||
bdb2i_back_bind_internal(
|
|
||||||
BackendDB *be,
|
|
||||||
Connection *conn,
|
|
||||||
Operation *op,
|
|
||||||
char *dn,
|
|
||||||
int method,
|
|
||||||
struct berval *cred,
|
|
||||||
char** edn
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
Entry *e;
|
|
||||||
Attribute *a;
|
|
||||||
int rc;
|
|
||||||
Entry *matched;
|
|
||||||
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
|
|
||||||
char krbname[MAX_K_NAME_SZ + 1];
|
|
||||||
AUTH_DAT ad;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Debug(LDAP_DEBUG_ARGS, "==> bdb2_back_bind: dn: %s\n", dn, 0, 0);
|
|
||||||
|
|
||||||
*edn = NULL;
|
|
||||||
|
|
||||||
/* get entry with reader lock */
|
|
||||||
if ( (e = bdb2i_dn2entry_r( be, dn, &matched )) == NULL ) {
|
|
||||||
char *matched_dn = NULL;
|
|
||||||
struct berval **refs = NULL;
|
|
||||||
|
|
||||||
if ( matched != NULL ) {
|
|
||||||
matched_dn = ch_strdup( matched->e_dn );
|
|
||||||
refs = is_entry_referral( matched )
|
|
||||||
? get_entry_referrals( be, conn, op, matched )
|
|
||||||
: NULL;
|
|
||||||
bdb2i_cache_return_entry_r( &li->li_cache, matched );
|
|
||||||
} else {
|
|
||||||
refs = default_referral;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allow noauth binds */
|
|
||||||
rc = 1;
|
|
||||||
if ( method == LDAP_AUTH_SIMPLE ) {
|
|
||||||
if( cred->bv_len == 0 ) {
|
|
||||||
/* SUCCESS */
|
|
||||||
send_ldap_result( conn, op, LDAP_SUCCESS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
|
|
||||||
} else if ( be_isroot_pw( be, dn, cred ) ) {
|
|
||||||
/* front end will send result */
|
|
||||||
*edn = ch_strdup( be_root_dn( be ) );
|
|
||||||
rc = 0;
|
|
||||||
|
|
||||||
} else if ( refs != NULL ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_REFERRAL,
|
|
||||||
matched_dn, NULL, refs, NULL );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if ( method == LDAP_AUTH_SASL ) {
|
|
||||||
if( mech != NULL && strcasecmp(mech,"DIGEST-MD5") == 0 ) {
|
|
||||||
/* insert DIGEST calls here */
|
|
||||||
send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if ( refs != NULL ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_REFERRAL,
|
|
||||||
matched_dn, NULL, refs, NULL );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( matched != NULL ) {
|
|
||||||
ber_bvecfree( refs );
|
|
||||||
free( matched_dn );
|
|
||||||
}
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
|
|
||||||
*edn = ch_strdup( e->e_dn );
|
|
||||||
|
|
||||||
/* check for deleted */
|
|
||||||
|
|
||||||
if ( ! access_allowed( be, conn, op, e,
|
|
||||||
"entry", NULL, ACL_AUTH ) )
|
|
||||||
{
|
|
||||||
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
rc = 1;
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( is_entry_alias( e ) ) {
|
|
||||||
/* entry is a alias, don't allow bind */
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "entry is alias\n", 0,
|
|
||||||
0, 0 );
|
|
||||||
|
|
||||||
send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
|
|
||||||
rc = 1;
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ( is_entry_referral( e ) ) {
|
|
||||||
/* entry is a referral, don't allow bind */
|
|
||||||
struct berval **refs = get_entry_referrals( be,
|
|
||||||
conn, op, e );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
|
|
||||||
0, 0 );
|
|
||||||
|
|
||||||
if( refs != NULL ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_REFERRAL,
|
|
||||||
e->e_dn, NULL, refs, NULL );
|
|
||||||
} else {
|
|
||||||
send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
ber_bvecfree( refs );
|
|
||||||
|
|
||||||
rc = 1;
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ( method ) {
|
|
||||||
case LDAP_AUTH_SIMPLE:
|
|
||||||
if ( cred->bv_len == 0 ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_SUCCESS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
|
|
||||||
/* stop front end from sending result */
|
|
||||||
rc = 1;
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for root dn/passwd */
|
|
||||||
if ( be_isroot_pw( be, dn, cred ) ) {
|
|
||||||
/* front end will send result */
|
|
||||||
if( *edn != NULL ) free( *edn );
|
|
||||||
*edn = ch_strdup( be_root_dn( be ) );
|
|
||||||
rc = 0;
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! access_allowed( be, conn, op, e,
|
|
||||||
"userpassword", NULL, ACL_AUTH ) )
|
|
||||||
{
|
|
||||||
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
|
|
||||||
NULL, NULL, NULL, NULL);
|
|
||||||
rc = 1;
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (a = attr_find( e->e_attrs, "userpassword" )) == NULL ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
|
|
||||||
NULL, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
/* stop front end from sending result */
|
|
||||||
rc = 1;
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( slap_passwd_check( a, cred ) != 0 ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
|
|
||||||
NULL, NULL, NULL, NULL);
|
|
||||||
/* stop front end from sending result */
|
|
||||||
rc = 1;
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
rc = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
|
|
||||||
case LDAP_AUTH_KRBV41:
|
|
||||||
if ( bdb2i_krbv4_ldap_auth( be, cred, &ad ) != LDAP_SUCCESS ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
|
|
||||||
NULL, NULL, NULL, NULL);
|
|
||||||
rc = 1;
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! access_allowed( be, conn, op, e,
|
|
||||||
"krbname", NULL, ACL_AUTH ) )
|
|
||||||
{
|
|
||||||
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
|
|
||||||
NULL, NULL, NULL, NULL);
|
|
||||||
rc = 1;
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf( krbname, "%s%s%s@%s", ad.pname, *ad.pinst ? "."
|
|
||||||
: "", ad.pinst, ad.prealm );
|
|
||||||
|
|
||||||
if ( (a = attr_find( e->e_attrs, "krbname" )) == NULL ) {
|
|
||||||
/*
|
|
||||||
* no krbName values present: check against DN
|
|
||||||
*/
|
|
||||||
if ( strcasecmp( dn, krbname ) == 0 ) {
|
|
||||||
rc = 0; /* XXX wild ass guess */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
|
|
||||||
NULL, NULL, NULL, NULL);
|
|
||||||
rc = 1;
|
|
||||||
goto return_results;
|
|
||||||
} else { /* look for krbName match */
|
|
||||||
struct berval krbval;
|
|
||||||
|
|
||||||
krbval.bv_val = krbname;
|
|
||||||
krbval.bv_len = strlen( krbname );
|
|
||||||
|
|
||||||
if ( value_find( a->a_vals, &krbval, a->a_syntax, 3 ) != 0 ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
|
|
||||||
NULL, NULL, NULL, NULL);
|
|
||||||
rc = 1;
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rc = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LDAP_AUTH_KRBV42:
|
|
||||||
send_ldap_result( conn, op, LDAP_SUCCESS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
/* stop front end from sending result */
|
|
||||||
rc = 1;
|
|
||||||
goto return_results;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case LDAP_AUTH_SASL:
|
|
||||||
/* insert sasl code here */
|
|
||||||
|
|
||||||
default:
|
|
||||||
send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
|
|
||||||
NULL, "auth method not supported", NULL, NULL );
|
|
||||||
rc = 1;
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
return_results:;
|
|
||||||
/* free entry and reader lock */
|
|
||||||
bdb2i_cache_return_entry_r( &li->li_cache, e );
|
|
||||||
|
|
||||||
/* front end with send result on success (rc==0) */
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_bind(
|
|
||||||
BackendDB *be,
|
|
||||||
Connection *conn,
|
|
||||||
Operation *op,
|
|
||||||
char *dn,
|
|
||||||
char *ndn,
|
|
||||||
int method,
|
|
||||||
char *mech,
|
|
||||||
struct berval *cred,
|
|
||||||
char** edn
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DB_LOCK lock;
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
struct timeval time1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
bdb2i_start_timing( be->bd_info, &time1 );
|
|
||||||
|
|
||||||
if ( bdb2i_enter_backend_r( &lock ) != 0 ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
return( 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = bdb2i_back_bind_internal( be, conn, op, ndn, method, mech, cred, edn );
|
|
||||||
|
|
||||||
(void) bdb2i_leave_backend_r( lock );
|
|
||||||
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "BIND", conn, op );
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,590 +0,0 @@
|
||||||
/* cache.c - routines to maintain an in-core cache of entries */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/errno.h>
|
|
||||||
#include <ac/string.h>
|
|
||||||
#include <ac/socket.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
|
|
||||||
/* LDBM backend specific entry info -- visible only to the cache */
|
|
||||||
struct ldbm_entry_info {
|
|
||||||
/*
|
|
||||||
* These items are specific to the LDBM backend and should
|
|
||||||
* be hidden.
|
|
||||||
*/
|
|
||||||
int lei_state; /* for the cache */
|
|
||||||
#define CACHE_ENTRY_UNDEFINED 0
|
|
||||||
#define CACHE_ENTRY_CREATING 1
|
|
||||||
#define CACHE_ENTRY_READY 2
|
|
||||||
#define CACHE_ENTRY_DELETED 3
|
|
||||||
|
|
||||||
int lei_refcnt; /* # threads ref'ing this entry */
|
|
||||||
Entry *lei_lrunext; /* for cache lru list */
|
|
||||||
Entry *lei_lruprev;
|
|
||||||
};
|
|
||||||
#define LEI(e) ((struct ldbm_entry_info *) ((e)->e_private))
|
|
||||||
|
|
||||||
static int cache_delete_entry_internal(struct cache *cache, Entry *e);
|
|
||||||
#ifdef LDAP_DEBUG
|
|
||||||
static void lru_print(struct cache *cache);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int
|
|
||||||
cache_entry_private_init( Entry*e )
|
|
||||||
{
|
|
||||||
assert( e->e_private == NULL );
|
|
||||||
|
|
||||||
if( e->e_private != NULL ) {
|
|
||||||
/* this should never happen */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
e->e_private = ch_calloc(1, sizeof(struct ldbm_entry_info));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
cache_entry_private_destroy( Entry*e )
|
|
||||||
{
|
|
||||||
assert( e->e_private );
|
|
||||||
|
|
||||||
free( e->e_private );
|
|
||||||
e->e_private = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
bdb2i_cache_return_entry_rw( struct cache *cache, Entry *e, int rw )
|
|
||||||
{
|
|
||||||
/* set cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_lock( &cache->c_mutex );
|
|
||||||
|
|
||||||
assert( e->e_private );
|
|
||||||
|
|
||||||
LEI(e)->lei_refcnt--;
|
|
||||||
|
|
||||||
if ( LEI(e)->lei_state == CACHE_ENTRY_CREATING ) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"====> bdb2i_cache_return_entry_%s( %ld ): created (%d)\n",
|
|
||||||
rw ? "w" : "r", e->e_id, LEI(e)->lei_refcnt );
|
|
||||||
|
|
||||||
LEI(e)->lei_state = CACHE_ENTRY_READY;
|
|
||||||
|
|
||||||
} else if ( LEI(e)->lei_state == CACHE_ENTRY_DELETED ) {
|
|
||||||
if( LEI(e)->lei_refcnt > 0 ) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"====> bdb2i_cache_return_entry_%s( %ld ): delete pending (%d)\n",
|
|
||||||
rw ? "w" : "r", e->e_id, LEI(e)->lei_refcnt );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"====> bdb2i_cache_return_entry_%s( %ld ): deleted (%d)\n",
|
|
||||||
rw ? "w" : "r", e->e_id, LEI(e)->lei_refcnt );
|
|
||||||
|
|
||||||
cache_entry_private_destroy( e );
|
|
||||||
entry_free( e );
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"====> bdb2i_cache_return_entry_%s( %ld ): returned (%d)\n",
|
|
||||||
rw ? "w" : "r", e->e_id, LEI(e)->lei_refcnt);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* free cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LRU_DELETE( cache, e ) { \
|
|
||||||
if ( LEI(e)->lei_lruprev != NULL ) { \
|
|
||||||
LEI(LEI(e)->lei_lruprev)->lei_lrunext = LEI(e)->lei_lrunext; \
|
|
||||||
} else { \
|
|
||||||
(cache)->c_lruhead = LEI(e)->lei_lrunext; \
|
|
||||||
} \
|
|
||||||
if ( LEI(e)->lei_lrunext != NULL ) { \
|
|
||||||
LEI(LEI(e)->lei_lrunext)->lei_lruprev = LEI(e)->lei_lruprev; \
|
|
||||||
} else { \
|
|
||||||
(cache)->c_lrutail = LEI(e)->lei_lruprev; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LRU_ADD( cache, e ) { \
|
|
||||||
LEI(e)->lei_lrunext = (cache)->c_lruhead; \
|
|
||||||
if ( LEI(e)->lei_lrunext != NULL ) { \
|
|
||||||
LEI(LEI(e)->lei_lrunext)->lei_lruprev = (e); \
|
|
||||||
} \
|
|
||||||
(cache)->c_lruhead = (e); \
|
|
||||||
LEI(e)->lei_lruprev = NULL; \
|
|
||||||
if ( (cache)->c_lrutail == NULL ) { \
|
|
||||||
(cache)->c_lrutail = (e); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* bdb2i_cache_add_entry_rw - create and lock an entry in the cache
|
|
||||||
* returns: 0 entry has been created and locked
|
|
||||||
* 1 entry already existed
|
|
||||||
* -1 something bad happened
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
bdb2i_cache_add_entry_rw(
|
|
||||||
struct cache *cache,
|
|
||||||
Entry *e,
|
|
||||||
int rw
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
Entry *ee;
|
|
||||||
|
|
||||||
/* set cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_lock( &cache->c_mutex );
|
|
||||||
|
|
||||||
assert( e->e_private == NULL );
|
|
||||||
|
|
||||||
if( cache_entry_private_init(e) != 0 ) {
|
|
||||||
/* free cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"====> bdb2i_cache_add_entry( %ld ): \"%s\": private init failed!\n",
|
|
||||||
e->e_id, e->e_dn, 0 );
|
|
||||||
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( avl_insert( &cache->c_dntree, (caddr_t) e,
|
|
||||||
(AVL_CMP) entry_dn_cmp, avl_dup_error ) != 0 )
|
|
||||||
{
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"====> bdb2i_cache_add_entry( %ld ): \"%s\": already in dn cache\n",
|
|
||||||
e->e_id, e->e_dn, 0 );
|
|
||||||
|
|
||||||
cache_entry_private_destroy(e);
|
|
||||||
|
|
||||||
/* free cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
|
|
||||||
return( 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* id tree */
|
|
||||||
if ( avl_insert( &cache->c_idtree, (caddr_t) e,
|
|
||||||
(AVL_CMP) entry_id_cmp, avl_dup_error ) != 0 )
|
|
||||||
{
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"====> bdb2i_cache_add_entry( %ld ): \"%s\": already in id cache\n",
|
|
||||||
e->e_id, e->e_dn, 0 );
|
|
||||||
|
|
||||||
/* delete from dn tree inserted above */
|
|
||||||
if ( avl_delete( &cache->c_dntree, (caddr_t) e,
|
|
||||||
(AVL_CMP) entry_dn_cmp ) == NULL )
|
|
||||||
{
|
|
||||||
Debug( LDAP_DEBUG_ANY, "====> can't delete from dn cache\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
cache_entry_private_destroy(e);
|
|
||||||
|
|
||||||
/* free cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* put the entry into 'CREATING' state */
|
|
||||||
/* will be marked after when entry is returned */
|
|
||||||
LEI(e)->lei_state = CACHE_ENTRY_CREATING;
|
|
||||||
LEI(e)->lei_refcnt = 1;
|
|
||||||
|
|
||||||
/* lru */
|
|
||||||
LRU_ADD( cache, e );
|
|
||||||
if ( ++cache->c_cursize > cache->c_maxsize ) {
|
|
||||||
/*
|
|
||||||
* find the lru entry not currently in use and delete it.
|
|
||||||
* in case a lot of entries are in use, only look at the
|
|
||||||
* first 10 on the tail of the list.
|
|
||||||
*/
|
|
||||||
i = 0;
|
|
||||||
while ( cache->c_lrutail != NULL &&
|
|
||||||
LEI(cache->c_lrutail)->lei_refcnt != 0 &&
|
|
||||||
i < 10 )
|
|
||||||
{
|
|
||||||
/* move this in-use entry to the front of the q */
|
|
||||||
ee = cache->c_lrutail;
|
|
||||||
LRU_DELETE( cache, ee );
|
|
||||||
LRU_ADD( cache, ee );
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* found at least one to delete - try to get back under
|
|
||||||
* the max cache size.
|
|
||||||
*/
|
|
||||||
while ( cache->c_lrutail != NULL &&
|
|
||||||
LEI(cache->c_lrutail)->lei_refcnt == 0 &&
|
|
||||||
cache->c_cursize > cache->c_maxsize )
|
|
||||||
{
|
|
||||||
e = cache->c_lrutail;
|
|
||||||
|
|
||||||
/* delete from cache and lru q */
|
|
||||||
cache_delete_entry_internal( cache, e );
|
|
||||||
cache_entry_private_destroy( e );
|
|
||||||
entry_free( e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* free cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* cache_update_entry - update a LOCKED entry which has been deleted.
|
|
||||||
* returns: 0 entry has been created and locked
|
|
||||||
* 1 entry already existed
|
|
||||||
* -1 something bad happened
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
bdb2i_cache_update_entry(
|
|
||||||
struct cache *cache,
|
|
||||||
Entry *e
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
Entry *ee;
|
|
||||||
|
|
||||||
/* set cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_lock( &cache->c_mutex );
|
|
||||||
|
|
||||||
assert( e->e_private );
|
|
||||||
|
|
||||||
if ( avl_insert( &cache->c_dntree, (caddr_t) e,
|
|
||||||
(AVL_CMP) entry_dn_cmp, avl_dup_error ) != 0 )
|
|
||||||
{
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"====> bdb2i_cache_add_entry( %ld ): \"%s\": already in dn cache\n",
|
|
||||||
e->e_id, e->e_dn, 0 );
|
|
||||||
|
|
||||||
/* free cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
|
|
||||||
return( 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* id tree */
|
|
||||||
if ( avl_insert( &cache->c_idtree, (caddr_t) e,
|
|
||||||
(AVL_CMP) entry_id_cmp, avl_dup_error ) != 0 )
|
|
||||||
{
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"====> bdb2i_cache_update_entry( %ld ): \"%s\": already in id cache\n",
|
|
||||||
e->e_id, e->e_dn, 0 );
|
|
||||||
|
|
||||||
/* delete from dn tree inserted above */
|
|
||||||
if ( avl_delete( &cache->c_dntree, (caddr_t) e,
|
|
||||||
(AVL_CMP) entry_dn_cmp ) == NULL )
|
|
||||||
{
|
|
||||||
Debug( LDAP_DEBUG_ANY, "====> can't delete from dn cache\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* free cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* put the entry into 'CREATING' state */
|
|
||||||
/* will be marked after when entry is returned */
|
|
||||||
LEI(e)->lei_state = CACHE_ENTRY_CREATING;
|
|
||||||
|
|
||||||
/* lru */
|
|
||||||
LRU_ADD( cache, e );
|
|
||||||
if ( ++cache->c_cursize > cache->c_maxsize ) {
|
|
||||||
/*
|
|
||||||
* find the lru entry not currently in use and delete it.
|
|
||||||
* in case a lot of entries are in use, only look at the
|
|
||||||
* first 10 on the tail of the list.
|
|
||||||
*/
|
|
||||||
i = 0;
|
|
||||||
while ( cache->c_lrutail != NULL &&
|
|
||||||
LEI(cache->c_lrutail)->lei_refcnt != 0 &&
|
|
||||||
i < 10 )
|
|
||||||
{
|
|
||||||
/* move this in-use entry to the front of the q */
|
|
||||||
ee = cache->c_lrutail;
|
|
||||||
LRU_DELETE( cache, ee );
|
|
||||||
LRU_ADD( cache, ee );
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* found at least one to delete - try to get back under
|
|
||||||
* the max cache size.
|
|
||||||
*/
|
|
||||||
while ( cache->c_lrutail != NULL &&
|
|
||||||
LEI(cache->c_lrutail)->lei_refcnt == 0 &&
|
|
||||||
cache->c_cursize > cache->c_maxsize )
|
|
||||||
{
|
|
||||||
e = cache->c_lrutail;
|
|
||||||
|
|
||||||
/* delete from cache and lru q */
|
|
||||||
cache_delete_entry_internal( cache, e );
|
|
||||||
cache_entry_private_destroy( e );
|
|
||||||
entry_free( e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* free cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* bdb2i_cache_find_entry_dn2id - find an entry in the cache, given dn
|
|
||||||
*/
|
|
||||||
|
|
||||||
ID
|
|
||||||
bdb2i_cache_find_entry_dn2id(
|
|
||||||
BackendDB *be,
|
|
||||||
struct cache *cache,
|
|
||||||
const char *dn
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Entry e, *ep;
|
|
||||||
ID id;
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
e.e_dn = (char *) dn;
|
|
||||||
e.e_ndn = ch_strdup( dn );
|
|
||||||
(void) dn_normalize( e.e_ndn );
|
|
||||||
|
|
||||||
try_again:
|
|
||||||
/* set cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_lock( &cache->c_mutex );
|
|
||||||
|
|
||||||
if ( (ep = (Entry *) avl_find( cache->c_dntree, (caddr_t) &e,
|
|
||||||
(AVL_CMP) entry_dn_cmp )) != NULL )
|
|
||||||
{
|
|
||||||
int state;
|
|
||||||
count++;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ep now points to an unlocked entry
|
|
||||||
* we do not need to lock the entry if we only
|
|
||||||
* check the state, refcnt, LRU, and id.
|
|
||||||
*/
|
|
||||||
|
|
||||||
assert( ep->e_private );
|
|
||||||
|
|
||||||
/* save id */
|
|
||||||
id = ep->e_id;
|
|
||||||
state = LEI(ep)->lei_state;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* entry is deleted or not fully created yet
|
|
||||||
*/
|
|
||||||
if ( state != CACHE_ENTRY_READY ) {
|
|
||||||
assert(state != CACHE_ENTRY_UNDEFINED);
|
|
||||||
|
|
||||||
/* free cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
|
|
||||||
|
|
||||||
Debug(LDAP_DEBUG_TRACE,
|
|
||||||
"====> bdb2i_cache_find_entry_dn2id(\"%s\"): %ld (not ready) %d\n",
|
|
||||||
dn, id, state);
|
|
||||||
|
|
||||||
ldap_pvt_thread_yield();
|
|
||||||
goto try_again;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* lru */
|
|
||||||
LRU_DELETE( cache, ep );
|
|
||||||
LRU_ADD( cache, ep );
|
|
||||||
|
|
||||||
/* free cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
|
|
||||||
|
|
||||||
Debug(LDAP_DEBUG_TRACE,
|
|
||||||
"====> bdb2i_cache_find_entry_dn2id(\"%s\"): %ld (%d tries)\n",
|
|
||||||
dn, id, count);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/* free cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
|
|
||||||
|
|
||||||
id = NOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(e.e_ndn);
|
|
||||||
|
|
||||||
return( id );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* cache_find_entry_id - find an entry in the cache, given id
|
|
||||||
*/
|
|
||||||
|
|
||||||
Entry *
|
|
||||||
bdb2i_cache_find_entry_id(
|
|
||||||
struct cache *cache,
|
|
||||||
ID id,
|
|
||||||
int rw
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Entry e;
|
|
||||||
Entry *ep;
|
|
||||||
int count=0;
|
|
||||||
|
|
||||||
e.e_id = id;
|
|
||||||
|
|
||||||
try_again:
|
|
||||||
/* set cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_lock( &cache->c_mutex );
|
|
||||||
|
|
||||||
if ( (ep = (Entry *) avl_find( cache->c_idtree, (caddr_t) &e,
|
|
||||||
(AVL_CMP) entry_id_cmp )) != NULL )
|
|
||||||
{
|
|
||||||
int state;
|
|
||||||
|
|
||||||
assert( ep->e_private );
|
|
||||||
|
|
||||||
state = LEI(ep)->lei_state;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* entry is deleted or not fully created yet
|
|
||||||
*/
|
|
||||||
if ( state != CACHE_ENTRY_READY ) {
|
|
||||||
ID ep_id = ep->e_id;
|
|
||||||
|
|
||||||
assert(state != CACHE_ENTRY_UNDEFINED);
|
|
||||||
|
|
||||||
/* free cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
|
|
||||||
|
|
||||||
Debug(LDAP_DEBUG_TRACE,
|
|
||||||
"====> bdb2i_cache_find_entry_id( %ld ): %ld (not ready) %d\n",
|
|
||||||
id, ep_id, state);
|
|
||||||
|
|
||||||
ldap_pvt_thread_yield();
|
|
||||||
goto try_again;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* lru */
|
|
||||||
LRU_DELETE( cache, ep );
|
|
||||||
LRU_ADD( cache, ep );
|
|
||||||
|
|
||||||
LEI(ep)->lei_refcnt++;
|
|
||||||
|
|
||||||
/* free cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
|
|
||||||
|
|
||||||
Debug(LDAP_DEBUG_TRACE,
|
|
||||||
"====> bdb2i_cache_find_entry_id( %ld ) \"%s\" (found) (%d tries)\n",
|
|
||||||
id, ep->e_dn, count);
|
|
||||||
|
|
||||||
return( ep );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* free cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
|
|
||||||
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* cache_delete_entry - delete the entry e from the cache. the caller
|
|
||||||
* should have obtained e (increasing its ref count) via a call to one
|
|
||||||
* of the cache_find_* routines. the caller should *not* call the
|
|
||||||
* cache_return_entry() routine prior to calling cache_delete_entry().
|
|
||||||
* it performs this function.
|
|
||||||
*
|
|
||||||
* returns: 0 e was deleted ok
|
|
||||||
* 1 e was not in the cache
|
|
||||||
* -1 something bad happened
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
bdb2i_cache_delete_entry(
|
|
||||||
struct cache *cache,
|
|
||||||
Entry *e
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
/* set cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_lock( &cache->c_mutex );
|
|
||||||
|
|
||||||
assert( e->e_private );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "====> bdb2i_cache_delete_entry( %ld )\n",
|
|
||||||
e->e_id, 0, 0 );
|
|
||||||
|
|
||||||
rc = cache_delete_entry_internal( cache, e );
|
|
||||||
|
|
||||||
/* free cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
cache_delete_entry_internal(
|
|
||||||
struct cache *cache,
|
|
||||||
Entry *e
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int rc = 0; /* return code */
|
|
||||||
|
|
||||||
/* dn tree */
|
|
||||||
if ( avl_delete( &cache->c_dntree, (caddr_t) e, (AVL_CMP) entry_dn_cmp )
|
|
||||||
== NULL )
|
|
||||||
{
|
|
||||||
rc = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* id tree */
|
|
||||||
if ( avl_delete( &cache->c_idtree, (caddr_t) e, (AVL_CMP) entry_id_cmp )
|
|
||||||
== NULL )
|
|
||||||
{
|
|
||||||
rc = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rc != 0) {
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* lru */
|
|
||||||
LRU_DELETE( cache, e );
|
|
||||||
cache->c_cursize--;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* flag entry to be freed later by a call to cache_return_entry()
|
|
||||||
*/
|
|
||||||
LEI(e)->lei_state = CACHE_ENTRY_DELETED;
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef LDAP_DEBUG
|
|
||||||
|
|
||||||
static void
|
|
||||||
lru_print( struct cache *cache )
|
|
||||||
{
|
|
||||||
Entry *e;
|
|
||||||
|
|
||||||
fprintf( stderr, "LRU queue (head to tail):\n" );
|
|
||||||
for ( e = cache->c_lruhead; e != NULL; e = LEI(e)->lei_lrunext ) {
|
|
||||||
fprintf( stderr, "\tdn \"%20s\" id %ld refcnt %d\n",
|
|
||||||
e->e_dn, e->e_id, LEI(e)->lei_refcnt );
|
|
||||||
}
|
|
||||||
fprintf( stderr, "LRU queue (tail to head):\n" );
|
|
||||||
for ( e = cache->c_lrutail; e != NULL; e = LEI(e)->lei_lruprev ) {
|
|
||||||
fprintf( stderr, "\tdn \"%20s\" id %ld refcnt %d\n",
|
|
||||||
e->e_dn, e->e_id, LEI(e)->lei_refcnt );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
/* close.c - close bdb2 backend database */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/socket.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
|
|
||||||
static int
|
|
||||||
bdb2i_back_db_close_internal( BackendDB *be )
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
DB_LOCK lock;
|
|
||||||
|
|
||||||
/* since close will probably write the NEXTID file,
|
|
||||||
wee need transaction control */
|
|
||||||
if ( bdb2i_enter_backend_w( &lock ) != 0 ) {
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( li->li_nextid != NOID ) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "bdb2 backend saving nextid\n", 0, 0, 0 );
|
|
||||||
if ( bdb2i_next_id_save( be ) < 0 ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY, "bdb2 backend nextid save failed!\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* before closing all files, leave the backend (thus commiting
|
|
||||||
all writes) and set a last checkpoint */
|
|
||||||
(void) bdb2i_leave_backend_w( lock );
|
|
||||||
(void) bdb2i_set_txn_checkpoint( bdb2i_dbEnv.tx_info, 1 );
|
|
||||||
|
|
||||||
/* close all DB files */
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "bdb2 backend closing DB files\n", 0, 0, 0 );
|
|
||||||
bdb2i_txn_close_files( be );
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "bdb2 backend done closing DB files\n", 0, 0, 0 );
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_db_close( BackendDB *be )
|
|
||||||
{
|
|
||||||
struct timeval time1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
bdb2i_start_timing( be->bd_info, &time1 );
|
|
||||||
|
|
||||||
ret = bdb2i_back_db_close_internal( be );
|
|
||||||
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "CLOSE", NULL, NULL );
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
/* compare.c - bdb2 backend compare routine */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/socket.h>
|
|
||||||
#include <ac/string.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
#include "proto-back-bdb2.h"
|
|
||||||
|
|
||||||
static int
|
|
||||||
bdb2i_back_compare_internal(
|
|
||||||
BackendDB *be,
|
|
||||||
Connection *conn,
|
|
||||||
Operation *op,
|
|
||||||
char *dn,
|
|
||||||
Ava *ava
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
Entry *matched;
|
|
||||||
Entry *e;
|
|
||||||
Attribute *a;
|
|
||||||
int rc;
|
|
||||||
int manageDSAit = get_manageDSAit( op );
|
|
||||||
|
|
||||||
/* get entry with reader lock */
|
|
||||||
if ( (e = bdb2i_dn2entry_r( be, dn, &matched )) == NULL ) {
|
|
||||||
char *matched_dn = NULL;
|
|
||||||
struct berval **refs = NULL;
|
|
||||||
|
|
||||||
if ( matched != NULL ) {
|
|
||||||
matched_dn = ch_strdup( matched->e_dn );
|
|
||||||
refs = is_entry_referral( matched )
|
|
||||||
? get_entry_referrals( be, conn, op, matched )
|
|
||||||
: NULL;
|
|
||||||
bdb2i_cache_return_entry_r( &li->li_cache, matched );
|
|
||||||
} else {
|
|
||||||
refs = default_referral;
|
|
||||||
}
|
|
||||||
|
|
||||||
send_ldap_result( conn, op, LDAP_REFERRAL,
|
|
||||||
matched_dn, NULL, refs, NULL );
|
|
||||||
|
|
||||||
if( matched != NULL ) {
|
|
||||||
ber_bvecfree( refs );
|
|
||||||
free( matched_dn );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!manageDSAit && is_entry_referral( e ) ) {
|
|
||||||
/* entry is a referral, don't allow add */
|
|
||||||
struct berval **refs = get_entry_referrals( be,
|
|
||||||
conn, op, e );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
|
|
||||||
0, 0 );
|
|
||||||
|
|
||||||
send_ldap_result( conn, op, LDAP_REFERRAL,
|
|
||||||
e->e_dn, NULL, refs, NULL );
|
|
||||||
|
|
||||||
ber_bvecfree( refs );
|
|
||||||
|
|
||||||
rc = 1;
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! access_allowed( be, conn, op, e,
|
|
||||||
ava->ava_type, &ava->ava_value, ACL_COMPARE ) )
|
|
||||||
{
|
|
||||||
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
rc = 1;
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (a = attr_find( e->e_attrs, ava->ava_type )) == NULL ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_NO_SUCH_ATTRIBUTE,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
rc = 1;
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( value_find( a->a_vals, &ava->ava_value, a->a_syntax, 1 ) == 0 )
|
|
||||||
send_ldap_result( conn, op, LDAP_COMPARE_TRUE,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
else
|
|
||||||
send_ldap_result( conn, op, LDAP_COMPARE_FALSE,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
|
|
||||||
rc = 0;
|
|
||||||
|
|
||||||
return_results:;
|
|
||||||
bdb2i_cache_return_entry_r( &li->li_cache, e );
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_compare(
|
|
||||||
BackendDB *be,
|
|
||||||
Connection *conn,
|
|
||||||
Operation *op,
|
|
||||||
char *dn,
|
|
||||||
char *ndn,
|
|
||||||
Ava *ava
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DB_LOCK lock;
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
struct timeval time1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
bdb2i_start_timing( be->bd_info, &time1 );
|
|
||||||
|
|
||||||
if ( bdb2i_enter_backend_r( &lock ) != 0 ) {
|
|
||||||
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
return( 1 );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = bdb2i_back_compare_internal( be, conn, op, ndn, ava );
|
|
||||||
(void) bdb2i_leave_backend_r( lock );
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "CMP", conn, op );
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,198 +0,0 @@
|
||||||
/* config.c - bdb2 backend configuration file routine */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/socket.h>
|
|
||||||
#include <ac/string.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
|
|
||||||
static int
|
|
||||||
bdb2i_back_config_internal(
|
|
||||||
BackendInfo *bi,
|
|
||||||
const char *fname,
|
|
||||||
int lineno,
|
|
||||||
int argc,
|
|
||||||
char **argv
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ldbtype *lty = (struct ldbtype *) bi->bi_private;
|
|
||||||
|
|
||||||
if ( lty == NULL ) {
|
|
||||||
fprintf( stderr, "%s: line %d: ldbm backend type info is null!\n",
|
|
||||||
fname, lineno );
|
|
||||||
return( 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* directory where DB control files live */
|
|
||||||
if ( strcasecmp( argv[0], "home" ) == 0 ) {
|
|
||||||
if ( argc < 2 ) {
|
|
||||||
fprintf( stderr,
|
|
||||||
"%s: line %d: missing dir in \"home <dir>\" line\n",
|
|
||||||
fname, lineno );
|
|
||||||
return( 1 );
|
|
||||||
}
|
|
||||||
lty->lty_dbhome = ch_strdup( argv[1] );
|
|
||||||
|
|
||||||
/* size of the DB memory pool */
|
|
||||||
} else if ( strcasecmp( argv[0], "mpoolsize" ) == 0 ) {
|
|
||||||
if ( argc < 2 ) {
|
|
||||||
fprintf( stderr,
|
|
||||||
"%s: line %d: missing size in \"mpoolsize <size>\" line\n",
|
|
||||||
fname, lineno );
|
|
||||||
return( 1 );
|
|
||||||
}
|
|
||||||
lty->lty_mpsize = (size_t) atoi( argv[1] );
|
|
||||||
/* we should at least have the suggested 128k */
|
|
||||||
if ( lty->lty_mpsize < DEFAULT_DBCACHE_SIZE )
|
|
||||||
lty->lty_mpsize = DEFAULT_DBCACHE_SIZE;
|
|
||||||
|
|
||||||
/* anything else */
|
|
||||||
} else {
|
|
||||||
fprintf( stderr,
|
|
||||||
"%s: line %d: unknown directive \"%s\" in ldbm backend definition (ignored)\n",
|
|
||||||
fname, lineno, argv[0] );
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_config(
|
|
||||||
BackendInfo *bi,
|
|
||||||
const char *fname,
|
|
||||||
int lineno,
|
|
||||||
int argc,
|
|
||||||
char **argv
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct timeval time1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
bdb2i_start_timing( bi, &time1 );
|
|
||||||
|
|
||||||
ret = bdb2i_back_config_internal( bi, fname, lineno, argc, argv );
|
|
||||||
bdb2i_stop_timing( bi, time1, "BE-CONFIG", NULL, NULL );
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
bdb2i_back_db_config_internal(
|
|
||||||
BackendDB *be,
|
|
||||||
const char *fname,
|
|
||||||
int lineno,
|
|
||||||
int argc,
|
|
||||||
char **argv
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
|
|
||||||
if ( li == NULL ) {
|
|
||||||
fprintf( stderr, "%s: line %d: ldbm database info is null!\n",
|
|
||||||
fname, lineno );
|
|
||||||
return( 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* directory where database files live */
|
|
||||||
if ( strcasecmp( argv[0], "directory" ) == 0 ) {
|
|
||||||
if ( argc < 2 ) {
|
|
||||||
fprintf( stderr,
|
|
||||||
"%s: line %d: missing dir in \"directory <dir>\" line\n",
|
|
||||||
fname, lineno );
|
|
||||||
return( 1 );
|
|
||||||
}
|
|
||||||
li->li_directory = ch_strdup( argv[1] );
|
|
||||||
|
|
||||||
li->li_nextid_file =
|
|
||||||
ch_malloc( strlen(li->li_directory) + sizeof("/NEXTID") + 1 );
|
|
||||||
|
|
||||||
strcpy(li->li_nextid_file, li->li_directory);
|
|
||||||
strcat(li->li_nextid_file, "/NEXTID");
|
|
||||||
|
|
||||||
/* mode with which to create new database files */
|
|
||||||
} else if ( strcasecmp( argv[0], "mode" ) == 0 ) {
|
|
||||||
if ( argc < 2 ) {
|
|
||||||
fprintf( stderr,
|
|
||||||
"%s: line %d: missing mode in \"mode <mode>\" line\n",
|
|
||||||
fname, lineno );
|
|
||||||
return( 1 );
|
|
||||||
}
|
|
||||||
li->li_mode = strtol( argv[1], NULL, 0 );
|
|
||||||
|
|
||||||
/* attribute to index */
|
|
||||||
} else if ( strcasecmp( argv[0], "index" ) == 0 ) {
|
|
||||||
if ( argc < 2 ) {
|
|
||||||
fprintf( stderr,
|
|
||||||
"%s: line %d: missing attr in \"index <attr> [pres,eq,approx,sub]\" line\n",
|
|
||||||
fname, lineno );
|
|
||||||
return( 1 );
|
|
||||||
} else if ( argc > 3 ) {
|
|
||||||
fprintf( stderr,
|
|
||||||
"%s: line %d: extra junk after \"index <attr> [pres,eq,approx,sub]\" line (ignored)\n",
|
|
||||||
fname, lineno );
|
|
||||||
}
|
|
||||||
bdb2i_attr_index_config( li, fname, lineno, argc - 1, &argv[1], 0 );
|
|
||||||
|
|
||||||
/* size of the cache in entries */
|
|
||||||
} else if ( strcasecmp( argv[0], "cachesize" ) == 0 ) {
|
|
||||||
if ( argc < 2 ) {
|
|
||||||
fprintf( stderr,
|
|
||||||
"%s: line %d: missing size in \"cachesize <size>\" line\n",
|
|
||||||
fname, lineno );
|
|
||||||
return( 1 );
|
|
||||||
}
|
|
||||||
li->li_cache.c_maxsize = atoi( argv[1] );
|
|
||||||
|
|
||||||
/* size of each dbcache in bytes */
|
|
||||||
} else if ( strcasecmp( argv[0], "dbcachesize" ) == 0 ) {
|
|
||||||
if ( argc < 2 ) {
|
|
||||||
fprintf( stderr,
|
|
||||||
"%s: line %d: missing size in \"dbcachesize <size>\" line\n",
|
|
||||||
fname, lineno );
|
|
||||||
return( 1 );
|
|
||||||
}
|
|
||||||
li->li_dbcachesize = atoi( argv[1] );
|
|
||||||
/* we should at least have the suggested 128k */
|
|
||||||
if ( li->li_dbcachesize < DEFAULT_DBCACHE_SIZE )
|
|
||||||
li->li_dbcachesize = DEFAULT_DBCACHE_SIZE;
|
|
||||||
|
|
||||||
/* anything else */
|
|
||||||
} else {
|
|
||||||
fprintf( stderr,
|
|
||||||
"%s: line %d: unknown directive \"%s\" in ldbm database definition (ignored)\n",
|
|
||||||
fname, lineno, argv[0] );
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_db_config(
|
|
||||||
BackendDB *be,
|
|
||||||
const char *fname,
|
|
||||||
int lineno,
|
|
||||||
int argc,
|
|
||||||
char **argv
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct timeval time1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
bdb2i_start_timing( be->bd_info, &time1 );
|
|
||||||
|
|
||||||
ret = bdb2i_back_db_config_internal( be, fname, lineno, argc, argv );
|
|
||||||
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "DB-CONFIG", NULL, NULL );
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,187 +0,0 @@
|
||||||
/* ldbmcache.c - maintain a cache of open bdb2 files */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/errno.h>
|
|
||||||
#include <ac/socket.h>
|
|
||||||
#include <ac/string.h>
|
|
||||||
#include <ac/time.h>
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_PARAM_H
|
|
||||||
#include <sys/param.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
|
|
||||||
struct dbcache *
|
|
||||||
bdb2i_cache_open(
|
|
||||||
BackendDB *be,
|
|
||||||
char *name,
|
|
||||||
char *suffix,
|
|
||||||
int flags
|
|
||||||
)
|
|
||||||
{
|
|
||||||
/* all files are open, so return handle from file cache */
|
|
||||||
switch ( slapMode & SLAP_MODE ) {
|
|
||||||
|
|
||||||
case SLAP_SERVER_MODE:
|
|
||||||
case SLAP_TOOL_MODE:
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
char buf[MAXPATHLEN];
|
|
||||||
|
|
||||||
/* use short name */
|
|
||||||
sprintf( buf, "%s%s", name, suffix );
|
|
||||||
return( bdb2i_get_db_file_cache( li, buf ));
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/* if not SERVER or TOOL, who else would ask?
|
|
||||||
NO ONE, so return error */
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_cache_open: database user (%d) unknown -- cannot open \"%s%s\".\n",
|
|
||||||
slapMode, name, suffix );
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
bdb2i_cache_close( BackendDB *be, struct dbcache *db )
|
|
||||||
{
|
|
||||||
/* all files stay open until SERVER or TOOL shut down */
|
|
||||||
switch ( slapMode & SLAP_MODE ) {
|
|
||||||
case SLAP_SERVER_MODE:
|
|
||||||
case SLAP_TOOL_MODE:
|
|
||||||
return;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/* if unknown user, complain */
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_cache_close: database user (%d) unknown -- ignored.\n",
|
|
||||||
slapMode, 0, 0 );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
bdb2i_cache_really_close( BackendDB *be, struct dbcache *db )
|
|
||||||
{
|
|
||||||
/* all files stay open until SERVER or TOOL shut down */
|
|
||||||
switch ( slapMode & SLAP_MODE ) {
|
|
||||||
case SLAP_SERVER_MODE:
|
|
||||||
case SLAP_TOOL_MODE:
|
|
||||||
return;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/* if unknown user, complain */
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_cache_really_close: database user (%d) unknown -- ignored.\n",
|
|
||||||
slapMode, 0, 0 );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
bdb2i_cache_flush_all( BackendDB *be )
|
|
||||||
{
|
|
||||||
/* if SERVER or TOOL, syncing is done by TP, or during shutdown */
|
|
||||||
switch ( slapMode & SLAP_MODE ) {
|
|
||||||
|
|
||||||
case SLAP_SERVER_MODE:
|
|
||||||
case SLAP_TOOL_MODE:
|
|
||||||
return;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/* if unknown user, complain */
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_cache_flush_all: database user (%d) unknown -- ignored.\n",
|
|
||||||
slapMode, 0, 0 );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Datum
|
|
||||||
bdb2i_cache_fetch(
|
|
||||||
struct dbcache *db,
|
|
||||||
Datum key
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Datum data;
|
|
||||||
|
|
||||||
ldbm_datum_init( data );
|
|
||||||
|
|
||||||
data = bdb2i_db_fetch( db->dbc_db, key );
|
|
||||||
|
|
||||||
return( data );
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_cache_store(
|
|
||||||
struct dbcache *db,
|
|
||||||
Datum key,
|
|
||||||
Datum data,
|
|
||||||
int flags
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
struct timeval time1;
|
|
||||||
|
|
||||||
#ifdef LDBM_DEBUG
|
|
||||||
Statslog( LDAP_DEBUG_STATS,
|
|
||||||
"=> bdb2i_cache_store(): key.dptr=%s, key.dsize=%d\n",
|
|
||||||
key.dptr, key.dsize, 0, 0, 0 );
|
|
||||||
|
|
||||||
Statslog( LDAP_DEBUG_STATS,
|
|
||||||
"=> bdb2i_cache_store(): key.dptr=0x%08x, data.dptr=0x%0 8x\n",
|
|
||||||
key.dptr, data.dptr, 0, 0, 0 );
|
|
||||||
|
|
||||||
Statslog( LDAP_DEBUG_STATS,
|
|
||||||
"=> bdb2i_cache_store(): data.dptr=%s, data.dsize=%d\n",
|
|
||||||
data.dptr, data.dsize, 0, 0, 0 );
|
|
||||||
|
|
||||||
Statslog( LDAP_DEBUG_STATS,
|
|
||||||
"=> bdb2i_cache_store(): flags=0x%08x\n",
|
|
||||||
flags, 0, 0, 0, 0 );
|
|
||||||
#endif /* LDBM_DEBUG */
|
|
||||||
|
|
||||||
if ( slapMode & SLAP_TIMED_MODE )
|
|
||||||
bdb2i_uncond_start_timing( &time1 );
|
|
||||||
|
|
||||||
rc = bdb2i_db_store( db->dbc_db, key, data, flags );
|
|
||||||
|
|
||||||
if ( slapMode & SLAP_TIMED_MODE ) {
|
|
||||||
char buf[BUFSIZ];
|
|
||||||
char buf2[BUFSIZ];
|
|
||||||
|
|
||||||
*buf2 = '\0';
|
|
||||||
if ( !( strcasecmp( db->dbc_name, "dn.bdb2" )))
|
|
||||||
sprintf( buf2, " [%s]", key.dptr );
|
|
||||||
sprintf( buf, "ADD-BDB2( %s%s )", db->dbc_name, buf2 );
|
|
||||||
bdb2i_uncond_stop_timing( time1, buf,
|
|
||||||
NULL, NULL, LDAP_DEBUG_TRACE );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_cache_delete(
|
|
||||||
struct dbcache *db,
|
|
||||||
Datum key
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = bdb2i_db_delete( db->dbc_db, key );
|
|
||||||
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
|
|
@ -1,200 +0,0 @@
|
||||||
/* delete.c - bdb2 backend delete routine */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/string.h>
|
|
||||||
#include <ac/socket.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
#include "proto-back-bdb2.h"
|
|
||||||
|
|
||||||
static int
|
|
||||||
bdb2i_back_delete_internal(
|
|
||||||
BackendDB *be,
|
|
||||||
Connection *conn,
|
|
||||||
Operation *op,
|
|
||||||
char *dn
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
Entry *matched = NULL;
|
|
||||||
char *pdn = NULL;
|
|
||||||
Entry *e, *p = NULL;
|
|
||||||
int rc = -1, manageDSAit;
|
|
||||||
|
|
||||||
Debug(LDAP_DEBUG_ARGS, "==> bdb2i_back_delete: %s\n", dn, 0, 0);
|
|
||||||
|
|
||||||
/* get entry with writer lock */
|
|
||||||
if ( (e = bdb2i_dn2entry_w( be, dn, &matched )) == NULL ) {
|
|
||||||
char *matched_dn = NULL;
|
|
||||||
struct berval **refs = NULL;
|
|
||||||
|
|
||||||
Debug(LDAP_DEBUG_ARGS, "<=- bdb2i_back_delete: no such object %s\n",
|
|
||||||
dn, 0, 0);
|
|
||||||
|
|
||||||
if ( matched != NULL ) {
|
|
||||||
matched_dn = ch_strdup( matched->e_dn );
|
|
||||||
refs = is_entry_referral( matched )
|
|
||||||
? get_entry_referrals( be, conn, op, matched )
|
|
||||||
: NULL;
|
|
||||||
bdb2i_cache_return_entry_r( &li->li_cache, matched );
|
|
||||||
} else {
|
|
||||||
refs = default_referral;
|
|
||||||
}
|
|
||||||
|
|
||||||
send_ldap_result( conn, op, LDAP_REFERRAL,
|
|
||||||
matched_dn, NULL, refs, NULL );
|
|
||||||
|
|
||||||
if( matched != NULL ) {
|
|
||||||
ber_bvecfree( refs );
|
|
||||||
free( matched_dn );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!manageDSAit && is_entry_referral( e ) ) {
|
|
||||||
/* entry is a referral, don't allow add */
|
|
||||||
struct berval **refs = get_entry_referrals( be,
|
|
||||||
conn, op, e );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
|
|
||||||
0, 0 );
|
|
||||||
|
|
||||||
send_ldap_result( conn, op, LDAP_REFERRAL,
|
|
||||||
e->e_dn, NULL, refs, NULL );
|
|
||||||
|
|
||||||
ber_bvecfree( refs );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ( bdb2i_has_children( be, e ) ) {
|
|
||||||
Debug(LDAP_DEBUG_ARGS, "<=- bdb2i_back_delete: non leaf %s\n",
|
|
||||||
dn, 0, 0);
|
|
||||||
send_ldap_result( conn, op, LDAP_NOT_ALLOWED_ON_NONLEAF,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SLAPD_CHILD_MODIFICATION_WITH_ENTRY_ACL
|
|
||||||
if ( ! access_allowed( be, conn, op, e,
|
|
||||||
"entry", NULL, ACL_WRITE ) )
|
|
||||||
{
|
|
||||||
Debug(LDAP_DEBUG_ARGS,
|
|
||||||
"<=- bdb2i_back_delete: insufficient access %s\n",
|
|
||||||
dn, 0, 0);
|
|
||||||
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* find parent's entry */
|
|
||||||
if( (pdn = dn_parent( be, e->e_ndn )) != NULL ) {
|
|
||||||
if( (p = bdb2i_dn2entry_w( be, pdn, &matched )) == NULL) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"<=- bdb2i_back_delete: parent does not exist\n", 0, 0, 0);
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check parent for "children" acl */
|
|
||||||
if ( ! access_allowed( be, conn, op, p,
|
|
||||||
"children", NULL, ACL_WRITE ) )
|
|
||||||
{
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"<=- bdb2i_back_delete: no access to parent\n", 0, 0, 0 );
|
|
||||||
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/* no parent, must be root to delete */
|
|
||||||
if( ! be_isroot( be, op->o_ndn ) ) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"<=- bdb2i_back_delete: no parent & not root\n", 0, 0, 0);
|
|
||||||
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* delete from dn2id mapping */
|
|
||||||
if ( bdb2i_dn2id_delete( be, e->e_ndn, e->e_id ) != 0 ) {
|
|
||||||
Debug(LDAP_DEBUG_ARGS,
|
|
||||||
"<=- bdb2i_back_delete: operations error %s\n",
|
|
||||||
dn, 0, 0);
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* delete from disk and cache */
|
|
||||||
if ( bdb2i_id2entry_delete( be, e ) != 0 ) {
|
|
||||||
Debug(LDAP_DEBUG_ARGS,
|
|
||||||
"<=- bdb2i_back_delete: operations error %s\n",
|
|
||||||
dn, 0, 0);
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
send_ldap_result( conn, op, LDAP_SUCCESS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
rc = 0;
|
|
||||||
|
|
||||||
return_results:;
|
|
||||||
if ( pdn != NULL ) free(pdn);
|
|
||||||
|
|
||||||
if( p != NULL ) {
|
|
||||||
/* free parent and writer lock */
|
|
||||||
bdb2i_cache_return_entry_w( &li->li_cache, p );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* free entry and writer lock */
|
|
||||||
bdb2i_cache_return_entry_w( &li->li_cache, e );
|
|
||||||
|
|
||||||
if ( matched != NULL ) free(matched);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_delete(
|
|
||||||
BackendDB *be,
|
|
||||||
Connection *conn,
|
|
||||||
Operation *op,
|
|
||||||
char *dn,
|
|
||||||
char *ndn
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DB_LOCK lock;
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
struct timeval time1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
bdb2i_start_timing( be->bd_info, &time1 );
|
|
||||||
|
|
||||||
if ( bdb2i_enter_backend_w( &lock ) != 0 ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = bdb2i_back_delete_internal( be, conn, op, ndn );
|
|
||||||
(void) bdb2i_leave_backend_w( lock );
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "DEL", conn, op );
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,305 +0,0 @@
|
||||||
/* dn2id.c - routines to deal with the dn2id index */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/string.h>
|
|
||||||
#include <ac/socket.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
#include "proto-back-bdb2.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_dn2id_add(
|
|
||||||
BackendDB *be,
|
|
||||||
const char *dn,
|
|
||||||
ID id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int rc, flags;
|
|
||||||
struct dbcache *db;
|
|
||||||
Datum key, data;
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> bdb2i_dn2id_add( \"%s\", %ld )\n", dn, id, 0 );
|
|
||||||
|
|
||||||
if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX, LDBM_WRCREAT ))
|
|
||||||
== NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY, "Could not open/create dn2id%s\n",
|
|
||||||
BDB2_SUFFIX, 0, 0 );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
ldbm_datum_init( key );
|
|
||||||
key.dsize = strlen( dn ) + 2;
|
|
||||||
key.dptr = ch_malloc( key.dsize );
|
|
||||||
sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
|
|
||||||
|
|
||||||
ldbm_datum_init( data );
|
|
||||||
data.dptr = (char *) &id;
|
|
||||||
data.dsize = sizeof(ID);
|
|
||||||
|
|
||||||
flags = LDBM_INSERT;
|
|
||||||
rc = bdb2i_cache_store( db, key, data, flags );
|
|
||||||
|
|
||||||
free( key.dptr );
|
|
||||||
|
|
||||||
if ( rc != -1 ) {
|
|
||||||
char *pdn = dn_parent( NULL, dn );
|
|
||||||
|
|
||||||
if( pdn != NULL ) {
|
|
||||||
ldbm_datum_init( key );
|
|
||||||
key.dsize = strlen( pdn ) + 2;
|
|
||||||
key.dptr = ch_malloc( key.dsize );
|
|
||||||
sprintf( key.dptr, "%c%s", DN_ONE_PREFIX, pdn );
|
|
||||||
rc = bdb2i_idl_insert_key( be, db, key, id );
|
|
||||||
free( key.dptr );
|
|
||||||
free( pdn );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( rc != -1 ) {
|
|
||||||
char **subtree = dn_subtree( NULL, dn );
|
|
||||||
|
|
||||||
if( subtree != NULL ) {
|
|
||||||
int i;
|
|
||||||
for( i=0; subtree[i] != NULL; i++ ) {
|
|
||||||
ldbm_datum_init( key );
|
|
||||||
key.dsize = strlen( subtree[i] ) + 2;
|
|
||||||
key.dptr = ch_malloc( key.dsize );
|
|
||||||
sprintf( key.dptr, "%c%s", DN_SUBTREE_PREFIX, subtree[i] );
|
|
||||||
|
|
||||||
rc = bdb2i_idl_insert_key( be, db, key, id );
|
|
||||||
|
|
||||||
free( key.dptr );
|
|
||||||
}
|
|
||||||
|
|
||||||
charray_free( subtree );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bdb2i_cache_close( be, db );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id_add %d\n", rc, 0, 0 );
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
|
|
||||||
ID
|
|
||||||
bdb2i_dn2id(
|
|
||||||
BackendDB *be,
|
|
||||||
const char *dn
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
struct dbcache *db;
|
|
||||||
ID id;
|
|
||||||
Datum key, data;
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> bdb2i_dn2id( \"%s\" )\n", dn, 0, 0 );
|
|
||||||
|
|
||||||
/* first check the cache */
|
|
||||||
if ( (id = bdb2i_cache_find_entry_dn2id( be, &li->li_cache, dn )) != NOID ) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id %ld (in cache)\n", id,
|
|
||||||
0, 0 );
|
|
||||||
return( id );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX, LDBM_WRCREAT ))
|
|
||||||
== NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY, "<= bdb2i_dn2id could not open dn2id%s\n",
|
|
||||||
BDB2_SUFFIX, 0, 0 );
|
|
||||||
return( NOID );
|
|
||||||
}
|
|
||||||
|
|
||||||
ldbm_datum_init( key );
|
|
||||||
|
|
||||||
key.dsize = strlen( dn ) + 2;
|
|
||||||
key.dptr = ch_malloc( key.dsize );
|
|
||||||
sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
|
|
||||||
|
|
||||||
data = bdb2i_cache_fetch( db, key );
|
|
||||||
|
|
||||||
bdb2i_cache_close( be, db );
|
|
||||||
|
|
||||||
free( key.dptr );
|
|
||||||
|
|
||||||
if ( data.dptr == NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id NOID\n", 0, 0, 0 );
|
|
||||||
return( NOID );
|
|
||||||
}
|
|
||||||
|
|
||||||
(void) memcpy( (char *) &id, data.dptr, sizeof(ID) );
|
|
||||||
|
|
||||||
ldbm_datum_free( db->dbc_db, data );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id %ld\n", id, 0, 0 );
|
|
||||||
return( id );
|
|
||||||
}
|
|
||||||
|
|
||||||
ID_BLOCK *
|
|
||||||
bdb2i_dn2idl(
|
|
||||||
BackendDB *be,
|
|
||||||
const char *dn,
|
|
||||||
int prefix )
|
|
||||||
{
|
|
||||||
struct dbcache *db;
|
|
||||||
Datum key;
|
|
||||||
ID_BLOCK *idl;
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> bdb2i_dn2idl( \"%c%s\" )\n", prefix, dn, 0 );
|
|
||||||
|
|
||||||
if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX, LDBM_WRCREAT ))
|
|
||||||
== NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"<= bdb2i_dn2idl could not open dn2id%s\n", BDB2_SUFFIX,
|
|
||||||
0, 0 );
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
ldbm_datum_init( key );
|
|
||||||
|
|
||||||
key.dsize = strlen( dn ) + 2;
|
|
||||||
key.dptr = ch_malloc( key.dsize );
|
|
||||||
sprintf( key.dptr, "%c%s", prefix, dn );
|
|
||||||
|
|
||||||
idl = bdb2i_idl_fetch( be, db, key );
|
|
||||||
|
|
||||||
free( key.dptr );
|
|
||||||
|
|
||||||
bdb2i_cache_close( be, db );
|
|
||||||
|
|
||||||
return( idl );
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_dn2id_delete(
|
|
||||||
BackendDB *be,
|
|
||||||
const char *dn,
|
|
||||||
ID id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct dbcache *db;
|
|
||||||
Datum key;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> bdb2i_dn2id_delete( \"%s\", %ld )\n",
|
|
||||||
dn, id, 0 );
|
|
||||||
|
|
||||||
if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX, LDBM_WRCREAT ))
|
|
||||||
== NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"<= bdb2i_dn2id_delete could not open dn2id%s\n", BDB2_SUFFIX,
|
|
||||||
0, 0 );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
char *pdn = dn_parent( NULL, dn );
|
|
||||||
|
|
||||||
if( pdn != NULL ) {
|
|
||||||
ldbm_datum_init( key );
|
|
||||||
key.dsize = strlen( pdn ) + 2;
|
|
||||||
key.dptr = ch_malloc( key.dsize );
|
|
||||||
sprintf( key.dptr, "%c%s", DN_ONE_PREFIX, pdn );
|
|
||||||
(void) bdb2i_idl_delete_key( be, db, key, id );
|
|
||||||
free( key.dptr );
|
|
||||||
free( pdn );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
char **subtree = dn_subtree( NULL, dn );
|
|
||||||
|
|
||||||
if( subtree != NULL ) {
|
|
||||||
int i;
|
|
||||||
for( i=0; subtree[i] != NULL; i++ ) {
|
|
||||||
ldbm_datum_init( key );
|
|
||||||
key.dsize = strlen( subtree[i] ) + 2;
|
|
||||||
key.dptr = ch_malloc( key.dsize );
|
|
||||||
sprintf( key.dptr, "%c%s", DN_SUBTREE_PREFIX, subtree[i] );
|
|
||||||
|
|
||||||
(void) bdb2i_idl_delete_key( be, db, key, id );
|
|
||||||
|
|
||||||
free( key.dptr );
|
|
||||||
}
|
|
||||||
|
|
||||||
charray_free( subtree );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ldbm_datum_init( key );
|
|
||||||
|
|
||||||
key.dsize = strlen( dn ) + 2;
|
|
||||||
key.dptr = ch_malloc( key.dsize );
|
|
||||||
sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
|
|
||||||
|
|
||||||
rc = bdb2i_cache_delete( db, key );
|
|
||||||
|
|
||||||
free( key.dptr );
|
|
||||||
|
|
||||||
bdb2i_cache_close( be, db );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id_delete %d\n", rc, 0, 0 );
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* dn2entry - look up dn in the cache/indexes and return the corresponding
|
|
||||||
* entry.
|
|
||||||
*/
|
|
||||||
|
|
||||||
Entry *
|
|
||||||
bdb2i_dn2entry_rw(
|
|
||||||
BackendDB *be,
|
|
||||||
const char *dn,
|
|
||||||
Entry **matched,
|
|
||||||
int rw
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
ID id;
|
|
||||||
Entry *e = NULL;
|
|
||||||
char *pdn;
|
|
||||||
|
|
||||||
Debug(LDAP_DEBUG_TRACE, "dn2entry_%s: dn: \"%s\"\n",
|
|
||||||
rw ? "w" : "r", dn, 0);
|
|
||||||
|
|
||||||
if( matched != NULL ) {
|
|
||||||
/* caller cares about match */
|
|
||||||
*matched = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (id = bdb2i_dn2id( be, dn )) != NOID &&
|
|
||||||
(e = bdb2i_id2entry_rw( be, id, rw )) != NULL )
|
|
||||||
{
|
|
||||||
return( e );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( id != NOID ) {
|
|
||||||
Debug(LDAP_DEBUG_ANY,
|
|
||||||
"dn2entry_%s: no entry for valid id (%ld), dn \"%s\"\n",
|
|
||||||
rw ? "w" : "r", id, dn);
|
|
||||||
/* must have been deleted from underneath us */
|
|
||||||
/* treat as if NOID was found */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* caller doesn't care about match */
|
|
||||||
if( matched == NULL ) return NULL;
|
|
||||||
|
|
||||||
/* entry does not exist - see how much of the dn does exist */
|
|
||||||
/* dn_parent checks returns NULL if dn is suffix */
|
|
||||||
if ( (pdn = dn_parent( be, dn )) != NULL ) {
|
|
||||||
/* get entry with reader lock */
|
|
||||||
if ( (e = bdb2i_dn2entry_r( be, pdn, matched )) != NULL ) {
|
|
||||||
*matched = e;
|
|
||||||
}
|
|
||||||
free( pdn );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
/* entry.c - ldbm backend entry_release routine */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/socket.h>
|
|
||||||
#include <ac/string.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
#include "proto-back-bdb2.h"
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_entry_release_rw(
|
|
||||||
BackendDB *be,
|
|
||||||
Entry *e,
|
|
||||||
int rw
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
|
|
||||||
/* free entry and reader or writer lock */
|
|
||||||
bdb2i_cache_return_entry_rw( &li->li_cache, e, rw );
|
|
||||||
bdb2i_release_add_lock();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
/* $OpenLDAP$ */
|
|
||||||
#ifndef _BDB2_EXTERNAL_H
|
|
||||||
#define _BDB2_EXTERNAL_H
|
|
||||||
|
|
||||||
LDAP_BEGIN_DECL
|
|
||||||
|
|
||||||
extern int bdb2_back_initialize LDAP_P(( BackendInfo *bi ));
|
|
||||||
extern int bdb2_back_open LDAP_P(( BackendInfo *bi ));
|
|
||||||
extern int bdb2_back_close LDAP_P(( BackendInfo *bi ));
|
|
||||||
extern int bdb2_back_destroy LDAP_P(( BackendInfo *bi ));
|
|
||||||
|
|
||||||
extern int bdb2_back_config LDAP_P(( BackendInfo *bt,
|
|
||||||
const char *fname, int lineno, int argc, char **argv ));
|
|
||||||
|
|
||||||
extern int bdb2_back_db_init LDAP_P(( BackendDB *bd ));
|
|
||||||
extern int bdb2_back_db_open LDAP_P(( BackendDB *bd ));
|
|
||||||
extern int bdb2_back_db_close LDAP_P(( BackendDB *bd ));
|
|
||||||
extern int bdb2_back_db_destroy LDAP_P(( BackendDB *bd ));
|
|
||||||
|
|
||||||
extern int bdb2_back_db_config LDAP_P(( BackendDB *bd,
|
|
||||||
const char *fname, int lineno, int argc, char **argv ));
|
|
||||||
|
|
||||||
extern int bdb2_back_bind LDAP_P(( BackendDB *bd,
|
|
||||||
Connection *conn, Operation *op,
|
|
||||||
const char *dn, const char *ndn, int method,
|
|
||||||
struct berval *cred, char** edn ));
|
|
||||||
|
|
||||||
extern int bdb2_back_unbind LDAP_P(( BackendDB *bd,
|
|
||||||
Connection *conn, Operation *op ));
|
|
||||||
|
|
||||||
extern int bdb2_back_search LDAP_P(( BackendDB *bd,
|
|
||||||
Connection *conn, Operation *op,
|
|
||||||
const char *base, const char *nbase,
|
|
||||||
int scope, int deref, int sizelimit, int timelimit,
|
|
||||||
Filter *filter, const char *filterstr,
|
|
||||||
char **attrs, int attrsonly ));
|
|
||||||
|
|
||||||
extern int bdb2_back_compare LDAP_P((BackendDB *bd,
|
|
||||||
Connection *conn, Operation *op,
|
|
||||||
const char *dn, const char *ndn,
|
|
||||||
Ava *ava ));
|
|
||||||
|
|
||||||
extern int bdb2_back_modify LDAP_P(( BackendDB *bd,
|
|
||||||
Connection *conn, Operation *op,
|
|
||||||
const char *dn, const char *ndn,
|
|
||||||
Modifications *ml ));
|
|
||||||
|
|
||||||
extern int bdb2_back_modrdn LDAP_P(( BackendDB *bd,
|
|
||||||
Connection *conn, Operation *op,
|
|
||||||
const char *dn, const char *ndn,
|
|
||||||
const char *newrdn, int deleteoldrdn,
|
|
||||||
const char *newSuperior ));
|
|
||||||
|
|
||||||
extern int bdb2_back_add LDAP_P(( BackendDB *bd,
|
|
||||||
Connection *conn, Operation *op, Entry *e ));
|
|
||||||
|
|
||||||
extern int bdb2_back_delete LDAP_P(( BackendDB *bd,
|
|
||||||
Connection *conn, Operation *op,
|
|
||||||
const char *dn, const char *ndn ));
|
|
||||||
|
|
||||||
extern int bdb2_back_abandon LDAP_P(( BackendDB *bd,
|
|
||||||
Connection *conn, Operation *op, int msgid ));
|
|
||||||
|
|
||||||
extern int bdb2_back_group LDAP_P(( BackendDB *bd,
|
|
||||||
Entry *target, const char* gr_ndn, const char* op_ndn,
|
|
||||||
const char* objectclassValue, const char* groupattrName));
|
|
||||||
|
|
||||||
/* hooks for slap tools */
|
|
||||||
extern int bdb2_tool_entry_open LDAP_P(( BackendDB *be, int mode ));
|
|
||||||
extern int bdb2_tool_entry_close LDAP_P(( BackendDB *be ));
|
|
||||||
extern ID bdb2_tool_entry_first LDAP_P(( BackendDB *be ));
|
|
||||||
extern ID bdb2_tool_entry_next LDAP_P(( BackendDB *be ));
|
|
||||||
extern Entry* bdb2_tool_entry_get LDAP_P(( BackendDB *be, ID id ));
|
|
||||||
extern ID bdb2_tool_entry_put LDAP_P(( BackendDB *be, Entry *e ));
|
|
||||||
extern int bdb2_tool_index_attr LDAP_P(( BackendDB *be, char* type ));
|
|
||||||
extern int bdb2_tool_index_change LDAP_P(( BackendDB *be, char* type,
|
|
||||||
struct berval **bv, ID id, int op ));
|
|
||||||
extern int bdb2_tool_sync LDAP_P(( BackendDB *be ));
|
|
||||||
|
|
||||||
LDAP_END_DECL
|
|
||||||
|
|
||||||
#endif /* _BDB2_EXTERNAL_H */
|
|
||||||
|
|
||||||
|
|
@ -1,370 +0,0 @@
|
||||||
/* filterindex.c - generate the list of candidate entries from a filter */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/socket.h>
|
|
||||||
#include <ac/string.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
|
|
||||||
static ID_BLOCK *ava_candidates( BackendDB *be, Ava *ava, int type );
|
|
||||||
static ID_BLOCK *presence_candidates( BackendDB *be, char *type );
|
|
||||||
static ID_BLOCK *approx_candidates( BackendDB *be, Ava *ava );
|
|
||||||
static ID_BLOCK *list_candidates( BackendDB *be, Filter *flist, int ftype );
|
|
||||||
static ID_BLOCK *substring_candidates( BackendDB *be, Filter *f );
|
|
||||||
static ID_BLOCK *substring_comp_candidates( BackendDB *be, char *type, char *val, int prepost );
|
|
||||||
|
|
||||||
ID_BLOCK *
|
|
||||||
bdb2i_filter_candidates(
|
|
||||||
BackendDB *be,
|
|
||||||
Filter *f
|
|
||||||
)
|
|
||||||
{
|
|
||||||
ID_BLOCK *result, *tmp1, *tmp2;
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> bdb2i_filter_candidates\n", 0, 0, 0 );
|
|
||||||
|
|
||||||
result = NULL;
|
|
||||||
switch ( f->f_choice ) {
|
|
||||||
case SLAPD_FILTER_DN_ONE:
|
|
||||||
Debug( LDAP_DEBUG_FILTER, "\tDN ONE\n", 0, 0, 0 );
|
|
||||||
result = bdb2i_dn2idl( be, f->f_dn, DN_SUBTREE_PREFIX );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SLAPD_FILTER_DN_SUBTREE:
|
|
||||||
Debug( LDAP_DEBUG_FILTER, "\tDN SUBTREE\n", 0, 0, 0 );
|
|
||||||
result = bdb2i_dn2idl( be, f->f_dn, DN_SUBTREE_PREFIX );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LDAP_FILTER_EQUALITY:
|
|
||||||
Debug( LDAP_DEBUG_FILTER, "\tEQUALITY\n", 0, 0, 0 );
|
|
||||||
result = ava_candidates( be, &f->f_ava, LDAP_FILTER_EQUALITY );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LDAP_FILTER_SUBSTRINGS:
|
|
||||||
Debug( LDAP_DEBUG_FILTER, "\tSUBSTRINGS\n", 0, 0, 0 );
|
|
||||||
result = substring_candidates( be, f );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LDAP_FILTER_GE:
|
|
||||||
Debug( LDAP_DEBUG_FILTER, "\tGE\n", 0, 0, 0 );
|
|
||||||
result = ava_candidates( be, &f->f_ava, LDAP_FILTER_GE );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LDAP_FILTER_LE:
|
|
||||||
Debug( LDAP_DEBUG_FILTER, "\tLE\n", 0, 0, 0 );
|
|
||||||
result = ava_candidates( be, &f->f_ava, LDAP_FILTER_LE );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LDAP_FILTER_PRESENT:
|
|
||||||
Debug( LDAP_DEBUG_FILTER, "\tPRESENT\n", 0, 0, 0 );
|
|
||||||
result = presence_candidates( be, f->f_type );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LDAP_FILTER_APPROX:
|
|
||||||
Debug( LDAP_DEBUG_FILTER, "\tAPPROX\n", 0, 0, 0 );
|
|
||||||
result = approx_candidates( be, &f->f_ava );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LDAP_FILTER_AND:
|
|
||||||
Debug( LDAP_DEBUG_FILTER, "\tAND\n", 0, 0, 0 );
|
|
||||||
result = list_candidates( be, f->f_and, LDAP_FILTER_AND );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LDAP_FILTER_OR:
|
|
||||||
Debug( LDAP_DEBUG_FILTER, "\tOR\n", 0, 0, 0 );
|
|
||||||
result = list_candidates( be, f->f_or, LDAP_FILTER_OR );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LDAP_FILTER_NOT:
|
|
||||||
Debug( LDAP_DEBUG_FILTER, "\tNOT\n", 0, 0, 0 );
|
|
||||||
tmp1 = bdb2i_idl_allids( be );
|
|
||||||
tmp2 = bdb2i_filter_candidates( be, f->f_not );
|
|
||||||
result = bdb2i_idl_notin( be, tmp1, tmp2 );
|
|
||||||
bdb2i_idl_free( tmp2 );
|
|
||||||
bdb2i_idl_free( tmp1 );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= bdb2i_filter_candidates %ld\n",
|
|
||||||
result ? ID_BLOCK_NIDS(result) : 0, 0, 0 );
|
|
||||||
return( result );
|
|
||||||
}
|
|
||||||
|
|
||||||
static ID_BLOCK *
|
|
||||||
ava_candidates(
|
|
||||||
BackendDB *be,
|
|
||||||
Ava *ava,
|
|
||||||
int type
|
|
||||||
)
|
|
||||||
{
|
|
||||||
ID_BLOCK *idl;
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> ava_candidates 0x%x\n", type, 0, 0 );
|
|
||||||
|
|
||||||
switch ( type ) {
|
|
||||||
case LDAP_FILTER_EQUALITY:
|
|
||||||
idl = bdb2i_index_read( be, ava->ava_type, INDEX_EQUALITY,
|
|
||||||
ava->ava_value.bv_val );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LDAP_FILTER_GE:
|
|
||||||
idl = bdb2i_idl_allids( be );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LDAP_FILTER_LE:
|
|
||||||
idl = bdb2i_idl_allids( be );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= ava_candidates %ld\n",
|
|
||||||
idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
|
|
||||||
return( idl );
|
|
||||||
}
|
|
||||||
|
|
||||||
static ID_BLOCK *
|
|
||||||
presence_candidates(
|
|
||||||
BackendDB *be,
|
|
||||||
char *type
|
|
||||||
)
|
|
||||||
{
|
|
||||||
ID_BLOCK *idl;
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> presence_candidates\n", 0, 0, 0 );
|
|
||||||
|
|
||||||
idl = bdb2i_index_read( be, type, INDEX_PRESENCE, "*" );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= presence_candidates %ld\n",
|
|
||||||
idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
|
|
||||||
return( idl );
|
|
||||||
}
|
|
||||||
|
|
||||||
static ID_BLOCK *
|
|
||||||
approx_candidates(
|
|
||||||
BackendDB *be,
|
|
||||||
Ava *ava
|
|
||||||
)
|
|
||||||
{
|
|
||||||
char *w, *c;
|
|
||||||
ID_BLOCK *idl, *tmp;
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> approx_candidates\n", 0, 0, 0 );
|
|
||||||
|
|
||||||
idl = NULL;
|
|
||||||
for ( w = first_word( ava->ava_value.bv_val ); w != NULL;
|
|
||||||
w = next_word( w ) ) {
|
|
||||||
c = phonetic( w );
|
|
||||||
if ( (tmp = bdb2i_index_read( be, ava->ava_type, INDEX_APPROX, c ))
|
|
||||||
== NULL ) {
|
|
||||||
free( c );
|
|
||||||
bdb2i_idl_free( idl );
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= approx_candidates NULL\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
free( c );
|
|
||||||
|
|
||||||
if ( idl == NULL ) {
|
|
||||||
idl = tmp;
|
|
||||||
} else {
|
|
||||||
idl = bdb2i_idl_intersection( be, idl, tmp );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= approx_candidates %ld\n",
|
|
||||||
idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
|
|
||||||
return( idl );
|
|
||||||
}
|
|
||||||
|
|
||||||
static ID_BLOCK *
|
|
||||||
list_candidates(
|
|
||||||
BackendDB *be,
|
|
||||||
Filter *flist,
|
|
||||||
int ftype
|
|
||||||
)
|
|
||||||
{
|
|
||||||
ID_BLOCK *idl, *tmp, *tmp2;
|
|
||||||
Filter *f;
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> list_candidates 0x%x\n", ftype, 0, 0 );
|
|
||||||
|
|
||||||
idl = NULL;
|
|
||||||
for ( f = flist; f != NULL; f = f->f_next ) {
|
|
||||||
if ( (tmp = bdb2i_filter_candidates( be, f )) == NULL &&
|
|
||||||
ftype == LDAP_FILTER_AND ) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"<= list_candidates NULL\n", 0, 0, 0 );
|
|
||||||
bdb2i_idl_free( idl );
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp2 = idl;
|
|
||||||
if ( idl == NULL ) {
|
|
||||||
idl = tmp;
|
|
||||||
} else if ( ftype == LDAP_FILTER_AND ) {
|
|
||||||
idl = bdb2i_idl_intersection( be, idl, tmp );
|
|
||||||
bdb2i_idl_free( tmp );
|
|
||||||
bdb2i_idl_free( tmp2 );
|
|
||||||
} else {
|
|
||||||
idl = bdb2i_idl_union( be, idl, tmp );
|
|
||||||
bdb2i_idl_free( tmp );
|
|
||||||
bdb2i_idl_free( tmp2 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= list_candidates %ld\n",
|
|
||||||
idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
|
|
||||||
return( idl );
|
|
||||||
}
|
|
||||||
|
|
||||||
static ID_BLOCK *
|
|
||||||
substring_candidates(
|
|
||||||
BackendDB *be,
|
|
||||||
Filter *f
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
ID_BLOCK *idl, *tmp, *tmp2;
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> substring_candidates\n", 0, 0, 0 );
|
|
||||||
|
|
||||||
idl = NULL;
|
|
||||||
|
|
||||||
/* initial */
|
|
||||||
if ( f->f_sub_initial != NULL ) {
|
|
||||||
if ( (int) strlen( f->f_sub_initial ) < SUBLEN - 1 ) {
|
|
||||||
idl = bdb2i_idl_allids( be );
|
|
||||||
} else if ( (idl = substring_comp_candidates( be, f->f_sub_type,
|
|
||||||
f->f_sub_initial, '^' )) == NULL ) {
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* final */
|
|
||||||
if ( f->f_sub_final != NULL ) {
|
|
||||||
if ( (int) strlen( f->f_sub_final ) < SUBLEN - 1 ) {
|
|
||||||
tmp = bdb2i_idl_allids( be );
|
|
||||||
} else if ( (tmp = substring_comp_candidates( be, f->f_sub_type,
|
|
||||||
f->f_sub_final, '$' )) == NULL ) {
|
|
||||||
bdb2i_idl_free( idl );
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( idl == NULL ) {
|
|
||||||
idl = tmp;
|
|
||||||
} else {
|
|
||||||
tmp2 = idl;
|
|
||||||
idl = bdb2i_idl_intersection( be, idl, tmp );
|
|
||||||
bdb2i_idl_free( tmp );
|
|
||||||
bdb2i_idl_free( tmp2 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( i = 0; f->f_sub_any != NULL && f->f_sub_any[i] != NULL; i++ ) {
|
|
||||||
if ( (int) strlen( f->f_sub_any[i] ) < SUBLEN ) {
|
|
||||||
tmp = bdb2i_idl_allids( be );
|
|
||||||
} else if ( (tmp = substring_comp_candidates( be, f->f_sub_type,
|
|
||||||
f->f_sub_any[i], 0 )) == NULL ) {
|
|
||||||
bdb2i_idl_free( idl );
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( idl == NULL ) {
|
|
||||||
idl = tmp;
|
|
||||||
} else {
|
|
||||||
tmp2 = idl;
|
|
||||||
idl = bdb2i_idl_intersection( be, idl, tmp );
|
|
||||||
bdb2i_idl_free( tmp );
|
|
||||||
bdb2i_idl_free( tmp2 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= substring_candidates %ld\n",
|
|
||||||
idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
|
|
||||||
return( idl );
|
|
||||||
}
|
|
||||||
|
|
||||||
static ID_BLOCK *
|
|
||||||
substring_comp_candidates(
|
|
||||||
BackendDB *be,
|
|
||||||
char *type,
|
|
||||||
char *val,
|
|
||||||
int prepost
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int i, len;
|
|
||||||
ID_BLOCK *idl, *tmp, *tmp2;
|
|
||||||
char *p;
|
|
||||||
char buf[SUBLEN + 1];
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> substring_comp_candidates\n", 0, 0, 0 );
|
|
||||||
|
|
||||||
len = strlen( val );
|
|
||||||
idl = NULL;
|
|
||||||
|
|
||||||
/* prepend ^ for initial substring */
|
|
||||||
if ( prepost == '^' ) {
|
|
||||||
buf[0] = '^';
|
|
||||||
for ( i = 0; i < SUBLEN - 1; i++ ) {
|
|
||||||
buf[i + 1] = val[i];
|
|
||||||
}
|
|
||||||
buf[SUBLEN] = '\0';
|
|
||||||
|
|
||||||
if ( (idl = bdb2i_index_read( be, type, INDEX_SUB, buf )) == NULL ) {
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
} else if ( prepost == '$' ) {
|
|
||||||
p = val + len - SUBLEN + 1;
|
|
||||||
for ( i = 0; i < SUBLEN - 1; i++ ) {
|
|
||||||
buf[i] = p[i];
|
|
||||||
}
|
|
||||||
buf[SUBLEN - 1] = '$';
|
|
||||||
buf[SUBLEN] = '\0';
|
|
||||||
|
|
||||||
if ( (idl = bdb2i_index_read( be, type, INDEX_SUB, buf )) == NULL ) {
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( p = val; p < (val + len - SUBLEN + 1); p++ ) {
|
|
||||||
for ( i = 0; i < SUBLEN; i++ ) {
|
|
||||||
buf[i] = p[i];
|
|
||||||
}
|
|
||||||
buf[SUBLEN] = '\0';
|
|
||||||
|
|
||||||
if ( (tmp = bdb2i_index_read( be, type, INDEX_SUB, buf )) == NULL ) {
|
|
||||||
bdb2i_idl_free( idl );
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( idl == NULL ) {
|
|
||||||
idl = tmp;
|
|
||||||
} else {
|
|
||||||
tmp2 = idl;
|
|
||||||
idl = bdb2i_idl_intersection( be, idl, tmp );
|
|
||||||
bdb2i_idl_free( tmp );
|
|
||||||
bdb2i_idl_free( tmp2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* break if no candidates */
|
|
||||||
if( idl == NULL ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if we're down to two (or less) matches, stop searching */
|
|
||||||
if( ID_BLOCK_NIDS(idl) < 3 ) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "substring_comp_candidates: "
|
|
||||||
"down to a %ld matches, stopped search\n",
|
|
||||||
(long) ID_BLOCK_NIDS(idl), 0, 0 );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= substring_comp_candidates %ld\n",
|
|
||||||
idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
|
|
||||||
return( idl );
|
|
||||||
}
|
|
||||||
|
|
@ -1,182 +0,0 @@
|
||||||
/* group.c - bdb2 backend acl group routine */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/socket.h>
|
|
||||||
#include <ac/string.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
#include "proto-back-bdb2.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* return 0 IFF op_dn is a value in member attribute
|
|
||||||
* of entry with gr_dn AND that entry has an objectClass
|
|
||||||
* value of groupOfNames
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
bdb2i_back_group_internal(
|
|
||||||
BackendDB *be,
|
|
||||||
Entry *target,
|
|
||||||
const char *gr_ndn,
|
|
||||||
const char *op_ndn,
|
|
||||||
const char *objectclassValue,
|
|
||||||
const char *groupattrName
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
Entry *e;
|
|
||||||
int rc = 1;
|
|
||||||
Attribute *attr;
|
|
||||||
struct berval bv;
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ARGS,
|
|
||||||
"=> bdb2i_back_group: gr dn: \"%s\"\n",
|
|
||||||
gr_ndn, 0, 0 );
|
|
||||||
Debug( LDAP_DEBUG_ARGS,
|
|
||||||
"=> bdb2i_back_group: op dn: \"%s\"\n",
|
|
||||||
op_ndn, 0, 0 );
|
|
||||||
Debug( LDAP_DEBUG_ARGS,
|
|
||||||
"=> bdb2i_back_group: objectClass: \"%s\" attrName: \"%s\"\n",
|
|
||||||
objectclassValue, groupattrName, 0 );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ARGS,
|
|
||||||
"=> bdb2i_back_group: tr dn: \"%s\"\n",
|
|
||||||
target->e_ndn, 0, 0 );
|
|
||||||
|
|
||||||
if (strcmp(target->e_ndn, gr_ndn) == 0) {
|
|
||||||
/* we already have a LOCKED copy of the entry */
|
|
||||||
e = target;
|
|
||||||
Debug( LDAP_DEBUG_ARGS,
|
|
||||||
"=> bdb2i_back_group: target is group: \"%s\"\n",
|
|
||||||
gr_ndn, 0, 0 );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/* can we find group entry with reader lock */
|
|
||||||
if ((e = bdb2i_dn2entry_r(be, gr_ndn, NULL )) == NULL) {
|
|
||||||
Debug( LDAP_DEBUG_ACL,
|
|
||||||
"=> bdb2i_back_group: cannot find group: \"%s\"\n",
|
|
||||||
gr_ndn, 0, 0 );
|
|
||||||
return( 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ACL,
|
|
||||||
"=> bdb2i_back_group: found group: \"%s\"\n",
|
|
||||||
gr_ndn, 0, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find it's objectClass and member attribute values
|
|
||||||
* make sure this is a group entry
|
|
||||||
* finally test if we can find op_dn in the member attribute value list
|
|
||||||
*/
|
|
||||||
|
|
||||||
rc = 1;
|
|
||||||
|
|
||||||
if ((attr = attr_find(e->e_attrs, "objectclass")) == NULL) {
|
|
||||||
Debug( LDAP_DEBUG_ACL,
|
|
||||||
"<= bdb2i_back_group: failed to find objectClass\n", 0, 0, 0 );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
bv.bv_val = "ALIAS";
|
|
||||||
bv.bv_len = sizeof("ALIAS")-1;
|
|
||||||
|
|
||||||
if (value_find(attr->a_vals, &bv, attr->a_syntax, 1) != 0) {
|
|
||||||
Debug( LDAP_DEBUG_ACL,
|
|
||||||
"<= bdb2i_back_group: group is an alias\n", 0, 0, 0 );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
bv.bv_val = "REFERRAL";
|
|
||||||
bv.bv_len = sizeof("REFERRAL")-1;
|
|
||||||
|
|
||||||
if (value_find(attr->a_vals, &bv, attr->a_syntax, 1) != 0) {
|
|
||||||
Debug( LDAP_DEBUG_ACL,
|
|
||||||
"<= bdb2i_back_group: group is a referral\n", 0, 0, 0 );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
bv.bv_val = (char *) objectclassValue;
|
|
||||||
bv.bv_len = strlen( bv.bv_val );
|
|
||||||
|
|
||||||
if (value_find(attr->a_vals, &bv, attr->a_syntax, 1) != 0) {
|
|
||||||
Debug( LDAP_DEBUG_ACL,
|
|
||||||
"<= bdb2i_back_group: failed to find %s in objectClass\n",
|
|
||||||
objectclassValue, 0, 0 );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((attr = attr_find(e->e_attrs, groupattrName)) == NULL) {
|
|
||||||
Debug( LDAP_DEBUG_ACL,
|
|
||||||
"<= bdb2i_back_group: failed to find %s\n",
|
|
||||||
groupattrName, 0, 0 );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ACL,
|
|
||||||
"<= bdb2i_back_group: found objectClass %s and %s\n",
|
|
||||||
objectclassValue, groupattrName, 0 );
|
|
||||||
|
|
||||||
|
|
||||||
bv.bv_val = (char *) op_ndn;
|
|
||||||
bv.bv_len = strlen( op_ndn );
|
|
||||||
|
|
||||||
if (value_find( attr->a_vals, &bv, attr->a_syntax, 1) != 0 ) {
|
|
||||||
Debug( LDAP_DEBUG_ACL,
|
|
||||||
"<= bdb2i_back_group: \"%s\" not in \"%s\": %s\n",
|
|
||||||
op_ndn, gr_ndn, groupattrName );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ACL,
|
|
||||||
"<= bdb2i_back_group: \"%s\" is in \"%s\": %s\n",
|
|
||||||
op_ndn, gr_ndn, groupattrName );
|
|
||||||
rc = 0;
|
|
||||||
|
|
||||||
return_results:
|
|
||||||
if( target != e ) {
|
|
||||||
/* free entry and reader lock */
|
|
||||||
bdb2i_cache_return_entry_r( &li->li_cache, e );
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ARGS, "bdb2i_back_group: rc: %d\n", rc, 0, 0 );
|
|
||||||
return(rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_group(
|
|
||||||
BackendDB *be,
|
|
||||||
Entry *target,
|
|
||||||
const char *gr_ndn,
|
|
||||||
const char *op_ndn,
|
|
||||||
const char *objectclassValue,
|
|
||||||
const char *groupattrName
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DB_LOCK lock;
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
struct timeval time1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
bdb2i_start_timing( be->bd_info, &time1 );
|
|
||||||
|
|
||||||
if ( bdb2i_enter_backend_r( &lock ) != 0 ) {
|
|
||||||
|
|
||||||
return( 1 );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = bdb2i_back_group_internal( be, target, gr_ndn, op_ndn,
|
|
||||||
objectclassValue, groupattrName );
|
|
||||||
|
|
||||||
(void) bdb2i_leave_backend_r( lock );
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "GRP", NULL, NULL );
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
/* id2children.c - routines to deal with the id2children index */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ac/string.h>
|
|
||||||
|
|
||||||
#include <ac/socket.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_has_children(
|
|
||||||
BackendDB *be,
|
|
||||||
Entry *p
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct dbcache *db;
|
|
||||||
Datum key;
|
|
||||||
int rc = 0;
|
|
||||||
ID_BLOCK *idl;
|
|
||||||
|
|
||||||
ldbm_datum_init( key );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> bdb2i_has_children( %ld )\n", p->e_id , 0, 0 );
|
|
||||||
|
|
||||||
if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX,
|
|
||||||
LDBM_WRCREAT )) == NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"<= bdb2i_has_children: could not open \"dn2id" BDB2_SUFFIX "\"\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
key.dsize = strlen( p->e_ndn ) + 2;
|
|
||||||
key.dptr = ch_malloc( key.dsize );
|
|
||||||
sprintf( key.dptr, "%c%s", DN_ONE_PREFIX, p->e_ndn );
|
|
||||||
|
|
||||||
idl = bdb2i_idl_fetch( be, db, key );
|
|
||||||
|
|
||||||
free( key.dptr );
|
|
||||||
|
|
||||||
bdb2i_cache_close( be, db );
|
|
||||||
|
|
||||||
if( idl != NULL ) {
|
|
||||||
bdb2i_idl_free( idl );
|
|
||||||
rc = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= bdb2i_has_children( %ld ): %s\n",
|
|
||||||
p->e_id, rc ? "yes" : "no", 0 );
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
|
|
@ -1,178 +0,0 @@
|
||||||
/* id2entry.c - routines to deal with the id2entry index */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/socket.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This routine adds (or updates) an entry on disk.
|
|
||||||
* The cache should already be updated.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_id2entry_add( BackendDB *be, Entry *e )
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
struct dbcache *db;
|
|
||||||
Datum key, data;
|
|
||||||
int len, rc, flags;
|
|
||||||
|
|
||||||
ldbm_datum_init( key );
|
|
||||||
ldbm_datum_init( data );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> bdb2i_id2entry_add( %ld, \"%s\" )\n", e->e_id,
|
|
||||||
e->e_dn, 0 );
|
|
||||||
|
|
||||||
if ( (db = bdb2i_cache_open( be, "id2entry", BDB2_SUFFIX, LDBM_WRCREAT ))
|
|
||||||
== NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY, "Could not open/create id2entry%s\n",
|
|
||||||
BDB2_SUFFIX, 0, 0 );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
key.dptr = (char *) &e->e_id;
|
|
||||||
key.dsize = sizeof(ID);
|
|
||||||
|
|
||||||
ldap_pvt_thread_mutex_lock( &entry2str_mutex );
|
|
||||||
data.dptr = entry2str( e, &len );
|
|
||||||
data.dsize = len + 1;
|
|
||||||
|
|
||||||
/* store it */
|
|
||||||
flags = LDBM_REPLACE;
|
|
||||||
rc = bdb2i_cache_store( db, key, data, flags );
|
|
||||||
|
|
||||||
ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
|
|
||||||
|
|
||||||
bdb2i_cache_close( be, db );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= bdb2i_id2entry_add %d\n", rc, 0, 0 );
|
|
||||||
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_id2entry_delete( BackendDB *be, Entry *e )
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
struct dbcache *db;
|
|
||||||
Datum key;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
Debug(LDAP_DEBUG_TRACE, "=> bdb2i_id2entry_delete( %ld, \"%s\" )\n", e->e_id,
|
|
||||||
e->e_dn, 0 );
|
|
||||||
|
|
||||||
#ifdef notdef
|
|
||||||
#ifdef LDAP_DEBUG
|
|
||||||
/* check for writer lock */
|
|
||||||
assert(ldap_pvt_thread_rdwr_writers(&e->e_rdwr) == 1);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ldbm_datum_init( key );
|
|
||||||
|
|
||||||
if ( (db = bdb2i_cache_open( be, "id2entry", BDB2_SUFFIX, LDBM_WRCREAT ))
|
|
||||||
== NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY, "Could not open/create id2entry%s\n",
|
|
||||||
BDB2_SUFFIX, 0, 0 );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( bdb2i_cache_delete_entry( &li->li_cache, e ) != 0 ) {
|
|
||||||
Debug(LDAP_DEBUG_ANY, "could not delete %ld (%s) from cache\n",
|
|
||||||
e->e_id, e->e_dn, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
key.dptr = (char *) &e->e_id;
|
|
||||||
key.dsize = sizeof(ID);
|
|
||||||
|
|
||||||
rc = bdb2i_cache_delete( db, key );
|
|
||||||
|
|
||||||
bdb2i_cache_close( be, db );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= bdb2i_id2entry_delete %d\n", rc, 0, 0 );
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns entry with reader/writer lock */
|
|
||||||
Entry *
|
|
||||||
bdb2i_id2entry_rw( BackendDB *be, ID id, int rw )
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
struct dbcache *db;
|
|
||||||
Datum key, data;
|
|
||||||
Entry *e;
|
|
||||||
|
|
||||||
ldbm_datum_init( key );
|
|
||||||
ldbm_datum_init( data );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> bdb2i_id2entry_%s( %ld )\n",
|
|
||||||
rw ? "w" : "r", id, 0 );
|
|
||||||
|
|
||||||
if ( (e = bdb2i_cache_find_entry_id( &li->li_cache, id, rw )) != NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= bdb2i_id2entry_%s( %ld ) 0x%lx (cache)\n",
|
|
||||||
rw ? "w" : "r", id, (unsigned long)e );
|
|
||||||
return( e );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (db = bdb2i_cache_open( be, "id2entry", BDB2_SUFFIX, LDBM_WRCREAT ))
|
|
||||||
== NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY, "Could not open id2entry%s\n",
|
|
||||||
BDB2_SUFFIX, 0, 0 );
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
key.dptr = (char *) &id;
|
|
||||||
key.dsize = sizeof(ID);
|
|
||||||
|
|
||||||
data = bdb2i_cache_fetch( db, key );
|
|
||||||
|
|
||||||
if ( data.dptr == NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= bdb2i_id2entry_%s( %ld ) not found\n",
|
|
||||||
rw ? "w" : "r", id, 0 );
|
|
||||||
bdb2i_cache_close( be, db );
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
e = str2entry( data.dptr );
|
|
||||||
|
|
||||||
ldbm_datum_free( db->dbc_db, data );
|
|
||||||
bdb2i_cache_close( be, db );
|
|
||||||
|
|
||||||
if ( e == NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= bdb2i_id2entry_%s( %ld ) (failed)\n",
|
|
||||||
rw ? "w" : "r", id, 0 );
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
e->e_id = id;
|
|
||||||
|
|
||||||
if ( bdb2i_cache_add_entry_rw( &li->li_cache, e, rw ) != 0 ) {
|
|
||||||
entry_free( e );
|
|
||||||
|
|
||||||
/* see if it got added underneath us */
|
|
||||||
if((e = bdb2i_cache_find_entry_id( &li->li_cache, id, rw )) != NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"<= bdb2i_id2entry_%s( %ld ) 0x%lx (cache)\n",
|
|
||||||
rw ? "w" : "r", id, (unsigned long)e );
|
|
||||||
return( e );
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"<= bdb2i_id2entry_%s( %ld ) (cache add failed)\n",
|
|
||||||
rw ? "w" : "r", id, 0 );
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= bdb2i_id2entry_%s( %ld ) 0x%lx (disk)\n",
|
|
||||||
rw ? "w" : "r", id, (unsigned long) e );
|
|
||||||
|
|
||||||
return( e );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,394 +0,0 @@
|
||||||
/* index.c - routines for dealing with attribute indexes */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/string.h>
|
|
||||||
#include <ac/socket.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
|
|
||||||
static int add_value(BackendDB *be, struct dbcache *db, char *type, int indextype, char *val, ID id);
|
|
||||||
static int index2prefix(int indextype);
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_index_add_entry(
|
|
||||||
BackendDB *be,
|
|
||||||
Entry *e
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Attribute *ap;
|
|
||||||
struct berval bv;
|
|
||||||
struct berval *bvals[2];
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> index_add( %ld, \"%s\" )\n", e->e_id,
|
|
||||||
e->e_dn, 0 );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* dn index entry - make it look like an attribute so it works
|
|
||||||
* with bdb2i_index_add_values() call
|
|
||||||
*/
|
|
||||||
|
|
||||||
bv.bv_val = ch_strdup( e->e_ndn );
|
|
||||||
bv.bv_len = strlen( bv.bv_val );
|
|
||||||
bvals[0] = &bv;
|
|
||||||
bvals[1] = NULL;
|
|
||||||
|
|
||||||
/* add the dn to the indexes */
|
|
||||||
{
|
|
||||||
char *dn = ch_strdup( "dn" );
|
|
||||||
bdb2i_index_add_values( be, dn, bvals, e->e_id );
|
|
||||||
free( dn );
|
|
||||||
}
|
|
||||||
|
|
||||||
free( bv.bv_val );
|
|
||||||
|
|
||||||
/* add each attribute to the indexes */
|
|
||||||
for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) {
|
|
||||||
bdb2i_index_add_values( be, ap->a_type, ap->a_vals, e->e_id );
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= index_add( %ld, \"%s\" ) 0\n", e->e_id,
|
|
||||||
e->e_ndn, 0 );
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_index_add_mods(
|
|
||||||
BackendDB *be,
|
|
||||||
LDAPModList *ml,
|
|
||||||
ID id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
for ( ; ml != NULL; ml = ml->ml_next ) {
|
|
||||||
LDAPMod *mod = &ml->ml_mod;
|
|
||||||
|
|
||||||
switch ( mod->mod_op & ~LDAP_MOD_BVALUES ) {
|
|
||||||
case LDAP_MOD_ADD:
|
|
||||||
case LDAP_MOD_REPLACE:
|
|
||||||
rc = bdb2i_index_add_values( be, mod->mod_type,
|
|
||||||
mod->mod_bvalues, id );
|
|
||||||
break;
|
|
||||||
case LDAP_MOD_SOFTADD:
|
|
||||||
case LDAP_MOD_DELETE:
|
|
||||||
rc = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( rc != 0 ) {
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
ID_BLOCK *
|
|
||||||
bdb2i_index_read(
|
|
||||||
BackendDB *be,
|
|
||||||
char *type,
|
|
||||||
int indextype,
|
|
||||||
char *val
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct dbcache *db;
|
|
||||||
Datum key;
|
|
||||||
ID_BLOCK *idl;
|
|
||||||
int indexmask, syntax;
|
|
||||||
char prefix;
|
|
||||||
char *realval, *tmpval;
|
|
||||||
char buf[BUFSIZ];
|
|
||||||
|
|
||||||
char *at_cn;
|
|
||||||
|
|
||||||
ldbm_datum_init( key );
|
|
||||||
|
|
||||||
prefix = index2prefix( indextype );
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> bdb2i_index_read( \"%c%s\" -> \"%s\" )\n",
|
|
||||||
prefix, type, val );
|
|
||||||
|
|
||||||
bdb2i_attr_masks( be->be_private, type, &indexmask, &syntax );
|
|
||||||
if ( ! (indextype & indexmask) ) {
|
|
||||||
idl = bdb2i_idl_allids( be );
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"<= bdb2i_index_read %ld candidates (allids - not indexed)\n",
|
|
||||||
idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
|
|
||||||
return( idl );
|
|
||||||
}
|
|
||||||
|
|
||||||
attr_normalize( type );
|
|
||||||
at_cn = at_canonical_name(type);
|
|
||||||
|
|
||||||
if ( at_cn == NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"<= bdb2i_index_read no canonical name for type \"%s\"\n",
|
|
||||||
type != NULL ? type : "(NULL)", 0, 0 );
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (db = bdb2i_cache_open( be, at_cn, BDB2_SUFFIX, LDBM_WRCREAT ))
|
|
||||||
== NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"<= bdb2i_index_read NULL (could not open %s%s)\n", at_cn,
|
|
||||||
BDB2_SUFFIX, 0 );
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
realval = val;
|
|
||||||
tmpval = NULL;
|
|
||||||
if ( prefix != UNKNOWN_PREFIX ) {
|
|
||||||
unsigned int len = strlen( val );
|
|
||||||
|
|
||||||
if ( (len + 2) < sizeof(buf) ) {
|
|
||||||
realval = buf;
|
|
||||||
} else {
|
|
||||||
/* value + prefix + null */
|
|
||||||
tmpval = (char *) ch_malloc( len + 2 );
|
|
||||||
realval = tmpval;
|
|
||||||
}
|
|
||||||
|
|
||||||
realval[0] = prefix;
|
|
||||||
strcpy( &realval[1], val );
|
|
||||||
}
|
|
||||||
|
|
||||||
key.dptr = realval;
|
|
||||||
key.dsize = strlen( realval ) + 1;
|
|
||||||
|
|
||||||
idl = bdb2i_idl_fetch( be, db, key );
|
|
||||||
if ( tmpval != NULL ) {
|
|
||||||
free( tmpval );
|
|
||||||
}
|
|
||||||
|
|
||||||
bdb2i_cache_close( be, db );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<= bdb2i_index_read %ld candidates\n",
|
|
||||||
idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
|
|
||||||
return( idl );
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
add_value(
|
|
||||||
BackendDB *be,
|
|
||||||
struct dbcache *db,
|
|
||||||
char *type,
|
|
||||||
int indextype,
|
|
||||||
char *val,
|
|
||||||
ID id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
Datum key;
|
|
||||||
char *tmpval = NULL;
|
|
||||||
char *realval = val;
|
|
||||||
char buf[BUFSIZ];
|
|
||||||
|
|
||||||
char prefix = index2prefix( indextype );
|
|
||||||
|
|
||||||
ldbm_datum_init( key );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> add_value( \"%c%s\" )\n", prefix, val, 0 );
|
|
||||||
|
|
||||||
if ( prefix != UNKNOWN_PREFIX ) {
|
|
||||||
unsigned int len = strlen( val );
|
|
||||||
|
|
||||||
if ( (len + 2) < sizeof(buf) ) {
|
|
||||||
realval = buf;
|
|
||||||
} else {
|
|
||||||
/* value + prefix + null */
|
|
||||||
tmpval = (char *) ch_malloc( len + 2 );
|
|
||||||
realval = tmpval;
|
|
||||||
}
|
|
||||||
realval[0] = prefix;
|
|
||||||
strcpy( &realval[1], val );
|
|
||||||
}
|
|
||||||
|
|
||||||
key.dptr = realval;
|
|
||||||
key.dsize = strlen( realval ) + 1;
|
|
||||||
|
|
||||||
rc = bdb2i_idl_insert_key( be, db, key, id );
|
|
||||||
|
|
||||||
if ( tmpval != NULL ) {
|
|
||||||
free( tmpval );
|
|
||||||
}
|
|
||||||
|
|
||||||
ldap_pvt_thread_yield();
|
|
||||||
|
|
||||||
/* Debug( LDAP_DEBUG_TRACE, "<= add_value %d\n", rc, 0, 0 ); */
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_index_add_values(
|
|
||||||
BackendDB *be,
|
|
||||||
char *type,
|
|
||||||
struct berval **vals,
|
|
||||||
ID id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
char *val, *p, *code, *w;
|
|
||||||
unsigned i, j, len;
|
|
||||||
int indexmask, syntax;
|
|
||||||
char buf[SUBLEN + 1];
|
|
||||||
char vbuf[BUFSIZ];
|
|
||||||
char *bigbuf;
|
|
||||||
struct dbcache *db;
|
|
||||||
|
|
||||||
char *at_cn;
|
|
||||||
|
|
||||||
if( vals == NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"=> bdb2i_index_add_values( \"%s\", NULL, %ld )\n",
|
|
||||||
type, id, 0 );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> bdb2i_index_add_values( \"%s\", %ld )\n",
|
|
||||||
type, id, 0 );
|
|
||||||
attr_normalize( type );
|
|
||||||
bdb2i_attr_masks( be->be_private, type, &indexmask, &syntax );
|
|
||||||
if ( indexmask == 0 ) {
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
at_cn = at_canonical_name(type);
|
|
||||||
|
|
||||||
if ( at_cn == NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"<= bdb2i_index_add_values no canonical name for type \"%s\"\n",
|
|
||||||
type != NULL ? type : "(NULL)", 0, 0 );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (db = bdb2i_cache_open( be, at_cn, BDB2_SUFFIX, LDBM_WRCREAT ))
|
|
||||||
== NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"<= bdb2i_index_add_values -1 (could not open/create %s%s)\n",
|
|
||||||
at_cn, BDB2_SUFFIX, 0 );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( i = 0; vals[i] != NULL; i++ ) {
|
|
||||||
/*
|
|
||||||
* presence index entry
|
|
||||||
*/
|
|
||||||
if ( indexmask & INDEX_PRESENCE ) {
|
|
||||||
add_value( be, db, at_cn, INDEX_PRESENCE, "*", id );
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "*** bdb2i_index_add_values syntax 0x%x syntax bin 0x%x\n",
|
|
||||||
syntax, SYNTAX_BIN, 0 );
|
|
||||||
if ( syntax & SYNTAX_BIN ) {
|
|
||||||
bdb2i_cache_close( be, db );
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
bigbuf = NULL;
|
|
||||||
len = vals[i]->bv_len;
|
|
||||||
|
|
||||||
/* value + null */
|
|
||||||
if ( len + 2 > sizeof(vbuf) ) {
|
|
||||||
bigbuf = (char *) ch_malloc( len + 1 );
|
|
||||||
val = bigbuf;
|
|
||||||
} else {
|
|
||||||
val = vbuf;
|
|
||||||
}
|
|
||||||
(void) memcpy( val, vals[i]->bv_val, len );
|
|
||||||
val[len] = '\0';
|
|
||||||
|
|
||||||
value_normalize( val, syntax );
|
|
||||||
|
|
||||||
/* value_normalize could change the length of val */
|
|
||||||
len = strlen( val );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* equality index entry
|
|
||||||
*/
|
|
||||||
if ( indexmask & INDEX_EQUALITY ) {
|
|
||||||
add_value( be, db, at_cn, INDEX_EQUALITY, val, id );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* approximate index entry
|
|
||||||
*/
|
|
||||||
if ( indexmask & INDEX_APPROX ) {
|
|
||||||
for ( w = first_word( val ); w != NULL;
|
|
||||||
w = next_word( w ) ) {
|
|
||||||
if ( (code = phonetic( w )) != NULL ) {
|
|
||||||
add_value( be, db, at_cn, INDEX_APPROX,
|
|
||||||
code, id );
|
|
||||||
free( code );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* substrings index entry
|
|
||||||
*/
|
|
||||||
if ( indexmask & INDEX_SUB ) {
|
|
||||||
/* leading and trailing */
|
|
||||||
if ( len > SUBLEN - 2 ) {
|
|
||||||
buf[0] = '^';
|
|
||||||
for ( j = 0; j < SUBLEN - 1; j++ ) {
|
|
||||||
buf[j + 1] = val[j];
|
|
||||||
}
|
|
||||||
buf[SUBLEN] = '\0';
|
|
||||||
|
|
||||||
add_value( be, db, at_cn, INDEX_SUB, buf, id );
|
|
||||||
|
|
||||||
p = val + len - SUBLEN + 1;
|
|
||||||
for ( j = 0; j < SUBLEN - 1; j++ ) {
|
|
||||||
buf[j] = p[j];
|
|
||||||
}
|
|
||||||
buf[SUBLEN - 1] = '$';
|
|
||||||
buf[SUBLEN] = '\0';
|
|
||||||
|
|
||||||
add_value( be, db, at_cn, INDEX_SUB, buf, id );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* any */
|
|
||||||
for ( p = val; p < (val + len - SUBLEN + 1); p++ ) {
|
|
||||||
for ( j = 0; j < SUBLEN; j++ ) {
|
|
||||||
buf[j] = p[j];
|
|
||||||
}
|
|
||||||
buf[SUBLEN] = '\0';
|
|
||||||
|
|
||||||
add_value( be, db, at_cn, INDEX_SUB, buf, id );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( bigbuf != NULL ) {
|
|
||||||
free( bigbuf );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bdb2i_cache_close( be, db );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
index2prefix( int indextype )
|
|
||||||
{
|
|
||||||
int prefix;
|
|
||||||
|
|
||||||
switch ( indextype ) {
|
|
||||||
case INDEX_EQUALITY:
|
|
||||||
prefix = EQ_PREFIX;
|
|
||||||
break;
|
|
||||||
case INDEX_APPROX:
|
|
||||||
prefix = APPROX_PREFIX;
|
|
||||||
break;
|
|
||||||
case INDEX_SUB:
|
|
||||||
prefix = SUB_PREFIX;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
prefix = UNKNOWN_PREFIX;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return( prefix );
|
|
||||||
}
|
|
||||||
|
|
@ -1,253 +0,0 @@
|
||||||
/* init.c - initialize bdb2 backend */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/string.h>
|
|
||||||
#include <ac/socket.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
|
|
||||||
#ifdef SLAPD_BDB2_DYNAMIC
|
|
||||||
|
|
||||||
int back_bdb2_LTX_init_module(int argc, char *argv[]) {
|
|
||||||
BackendInfo bi;
|
|
||||||
|
|
||||||
memset( &bi, 0, sizeof(bi) );
|
|
||||||
bi.bi_type = "bdb2";
|
|
||||||
bi.bi_init = bdb2_back_initialize;
|
|
||||||
|
|
||||||
backend_add(&bi);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* SLAPD_BDB2_DYNAMIC */
|
|
||||||
|
|
||||||
static int
|
|
||||||
bdb2i_back_init_private(
|
|
||||||
BackendInfo *bi
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ldbtype *bt;
|
|
||||||
|
|
||||||
/* allocate backend-type-specific stuff */
|
|
||||||
bt = (struct ldbtype *) ch_calloc( 1, sizeof(struct ldbtype) );
|
|
||||||
|
|
||||||
bt->lty_dbhome = DEFAULT_DB_HOME;
|
|
||||||
bt->lty_mpsize = DEFAULT_DBCACHE_SIZE;
|
|
||||||
|
|
||||||
if ( slapMode & SLAP_TIMED_MODE )
|
|
||||||
bt->lty_betiming = 1;
|
|
||||||
|
|
||||||
bi->bi_private = bt;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_initialize(
|
|
||||||
BackendInfo *bi
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
static char *controls[] = {
|
|
||||||
LDAP_CONTROL_MANAGEDSAIT,
|
|
||||||
/* LDAP_CONTROL_X_CHANGE_PASSWD, */
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
bi->bi_controls = controls;
|
|
||||||
|
|
||||||
bi->bi_open = bdb2_back_open;
|
|
||||||
bi->bi_config = bdb2_back_config;
|
|
||||||
bi->bi_close = bdb2_back_close;
|
|
||||||
bi->bi_destroy = bdb2_back_destroy;
|
|
||||||
|
|
||||||
bi->bi_db_init = bdb2_back_db_init;
|
|
||||||
bi->bi_db_config = bdb2_back_db_config;
|
|
||||||
bi->bi_db_open = bdb2_back_db_open;
|
|
||||||
bi->bi_db_close = bdb2_back_db_close;
|
|
||||||
bi->bi_db_destroy = bdb2_back_db_destroy;
|
|
||||||
|
|
||||||
bi->bi_op_bind = bdb2_back_bind;
|
|
||||||
bi->bi_op_unbind = bdb2_back_unbind;
|
|
||||||
bi->bi_op_search = bdb2_back_search;
|
|
||||||
bi->bi_op_compare = bdb2_back_compare;
|
|
||||||
bi->bi_op_modify = bdb2_back_modify;
|
|
||||||
bi->bi_op_modrdn = bdb2_back_modrdn;
|
|
||||||
bi->bi_op_add = bdb2_back_add;
|
|
||||||
bi->bi_op_delete = bdb2_back_delete;
|
|
||||||
bi->bi_op_abandon = bdb2_back_abandon;
|
|
||||||
|
|
||||||
bi->bi_extended = 0;
|
|
||||||
|
|
||||||
bi->bi_entry_release_rw = bdb2_back_entry_release_rw;
|
|
||||||
bi->bi_acl_group = bdb2_back_group;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* hooks for slap tools
|
|
||||||
*/
|
|
||||||
bi->bi_tool_entry_open = bdb2_tool_entry_open;
|
|
||||||
bi->bi_tool_entry_close = bdb2_tool_entry_close;
|
|
||||||
bi->bi_tool_entry_first = bdb2_tool_entry_first;
|
|
||||||
bi->bi_tool_entry_next = bdb2_tool_entry_next;
|
|
||||||
bi->bi_tool_entry_get = bdb2_tool_entry_get;
|
|
||||||
bi->bi_tool_entry_put = bdb2_tool_entry_put;
|
|
||||||
bi->bi_tool_index_attr = bdb2_tool_index_attr;
|
|
||||||
bi->bi_tool_index_change = bdb2_tool_index_change;
|
|
||||||
bi->bi_tool_sync = bdb2_tool_sync;
|
|
||||||
|
|
||||||
#ifdef HAVE_CYRUS_SASL
|
|
||||||
bi->bi_sasl_authorize = 0;
|
|
||||||
bi->bi_sasl_getsecret = 0;
|
|
||||||
bi->bi_sasl_putsecret = 0;
|
|
||||||
#endif /* HAVE_CYRUS_SASL */
|
|
||||||
|
|
||||||
bi->bi_connection_init = 0;
|
|
||||||
bi->bi_connection_destroy = 0;
|
|
||||||
|
|
||||||
ret = bdb2i_back_init_private( bi );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "bdb2_back_initialize: done (%d).\n", ret, 0, 0 );
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_destroy(
|
|
||||||
BackendInfo *bi
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_open(
|
|
||||||
BackendInfo *bi
|
|
||||||
)
|
|
||||||
{
|
|
||||||
static int initialized = 0;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if ( initialized++ ) {
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"bdb2_back_open: backend already initialized.\n", 0, 0, 0 );
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize the underlying database system */
|
|
||||||
rc = bdb2i_back_startup( bi );
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_close(
|
|
||||||
BackendInfo *bi
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
/* close the underlying database system */
|
|
||||||
rc = bdb2i_back_shutdown( bi );
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* BDB2 changed */
|
|
||||||
static int
|
|
||||||
bdb2i_back_db_init_internal(
|
|
||||||
BackendDB *be
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ldbminfo *li;
|
|
||||||
char *argv[ 4 ];
|
|
||||||
|
|
||||||
/* allocate backend-database-specific stuff */
|
|
||||||
li = (struct ldbminfo *) ch_calloc( 1, sizeof(struct ldbminfo) );
|
|
||||||
|
|
||||||
/* arrange to read nextid later (on first request for it) */
|
|
||||||
li->li_nextid = NOID;
|
|
||||||
#if SLAPD_NEXTID_CHUNK > 1
|
|
||||||
li->li_nextid_wrote = NOID;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* default cache size */
|
|
||||||
li->li_cache.c_maxsize = DEFAULT_CACHE_SIZE;
|
|
||||||
|
|
||||||
/* default database cache size */
|
|
||||||
li->li_dbcachesize = DEFAULT_DBCACHE_SIZE;
|
|
||||||
|
|
||||||
/* default file creation mode */
|
|
||||||
li->li_mode = DEFAULT_MODE;
|
|
||||||
|
|
||||||
/* default database directory */
|
|
||||||
li->li_directory = DEFAULT_DB_DIRECTORY;
|
|
||||||
|
|
||||||
argv[ 0 ] = "objectclass";
|
|
||||||
argv[ 1 ] = "eq";
|
|
||||||
argv[ 2 ] = NULL;
|
|
||||||
bdb2i_attr_index_config( li, "ldbm objectclass initialization",
|
|
||||||
0, 2, argv, 1 );
|
|
||||||
|
|
||||||
/* initialize the cache mutex */
|
|
||||||
ldap_pvt_thread_mutex_init( &li->li_cache.c_mutex );
|
|
||||||
|
|
||||||
/* initialize the TP file head */
|
|
||||||
if ( bdb2i_txn_head_init( &li->li_txn_head ) != 0 )
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
be->be_private = li;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_db_init(
|
|
||||||
BackendDB *be
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct timeval time1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
bdb2i_start_timing( be->bd_info, &time1 );
|
|
||||||
|
|
||||||
ret = bdb2i_back_db_init_internal( be );
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "DB-INIT", NULL, NULL );
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_db_open(
|
|
||||||
BackendDB *be
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = bdb2_back_db_startup( be );
|
|
||||||
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_db_destroy(
|
|
||||||
BackendDB *be
|
|
||||||
)
|
|
||||||
{
|
|
||||||
/* should free/destroy every in be_private */
|
|
||||||
free( be->be_private );
|
|
||||||
be->be_private = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,324 +0,0 @@
|
||||||
/* modify.c - bdb2 backend modify routine */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/string.h>
|
|
||||||
#include <ac/socket.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
#include "proto-back-bdb2.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_back_modify_internal(
|
|
||||||
BackendDB *be,
|
|
||||||
Connection *conn,
|
|
||||||
Operation *op,
|
|
||||||
char *dn,
|
|
||||||
LDAPModList *modlist,
|
|
||||||
Entry *e
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
LDAPModList *ml;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
Debug(LDAP_DEBUG_ARGS, "bdb2i_back_modify:\n", 0, 0, 0);
|
|
||||||
|
|
||||||
if ( !acl_check_modlist( be, conn, op, e, modlist )) {
|
|
||||||
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto error_return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( ml = modlist; ml != NULL; ml = ml->ml_next ) {
|
|
||||||
LDAPMod *mod = &ml->ml_mod;
|
|
||||||
|
|
||||||
switch ( mod->mod_op & ~LDAP_MOD_BVALUES ) {
|
|
||||||
case LDAP_MOD_ADD:
|
|
||||||
err = bdb2i_add_values( e, mod, op->o_ndn );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LDAP_MOD_DELETE:
|
|
||||||
err = bdb2i_delete_values( e, mod, op->o_ndn );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LDAP_MOD_REPLACE:
|
|
||||||
err = bdb2i_replace_values( e, mod, op->o_ndn );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LDAP_MOD_SOFTADD:
|
|
||||||
/* Avoid problems in index_add_mods()
|
|
||||||
* We need to add index if necessary.
|
|
||||||
*/
|
|
||||||
mod->mod_op = LDAP_MOD_ADD;
|
|
||||||
if ( (err = bdb2i_add_values( e, mod, op->o_ndn ))
|
|
||||||
== LDAP_TYPE_OR_VALUE_EXISTS ) {
|
|
||||||
|
|
||||||
err = LDAP_SUCCESS;
|
|
||||||
mod->mod_op = LDAP_MOD_SOFTADD;
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( err != LDAP_SUCCESS ) {
|
|
||||||
/* unlock entry, delete from cache */
|
|
||||||
send_ldap_result( conn, op, err,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto error_return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check that the entry still obeys the schema */
|
|
||||||
if ( schema_check_entry( e ) != 0 ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY, "entry failed schema check\n", 0, 0, 0 );
|
|
||||||
send_ldap_result( conn, op, LDAP_OBJECT_CLASS_VIOLATION,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto error_return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for abandon */
|
|
||||||
ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
|
|
||||||
if ( op->o_abandon ) {
|
|
||||||
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
|
|
||||||
goto error_return;
|
|
||||||
}
|
|
||||||
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
|
|
||||||
|
|
||||||
/* modify indexes */
|
|
||||||
if ( bdb2i_index_add_mods( be, modlist, e->e_id ) != 0 ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto error_return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for abandon */
|
|
||||||
ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
|
|
||||||
if ( op->o_abandon ) {
|
|
||||||
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
|
|
||||||
goto error_return;
|
|
||||||
}
|
|
||||||
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
|
|
||||||
|
|
||||||
/* change the entry itself */
|
|
||||||
if ( bdb2i_id2entry_add( be, e ) != 0 ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto error_return;
|
|
||||||
}
|
|
||||||
|
|
||||||
send_ldap_result( conn, op, LDAP_SUCCESS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
return( 0 );
|
|
||||||
|
|
||||||
error_return:;
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_modify(
|
|
||||||
BackendDB *be,
|
|
||||||
Connection *conn,
|
|
||||||
Operation *op,
|
|
||||||
char *dn,
|
|
||||||
char *ndn,
|
|
||||||
LDAPModList *modlist
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DB_LOCK lock;
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
struct timeval time1;
|
|
||||||
int ret, manageDSAit;
|
|
||||||
Entry *matched;
|
|
||||||
Entry *e;
|
|
||||||
|
|
||||||
bdb2i_start_timing( be->bd_info, &time1 );
|
|
||||||
|
|
||||||
if ( bdb2i_enter_backend_w( &lock ) != 0 ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check, if a new default attribute index will be created,
|
|
||||||
in which case we have to open the index file BEFORE TP */
|
|
||||||
switch ( slapMode & SLAP_MODE ) {
|
|
||||||
case SLAP_SERVER_MODE:
|
|
||||||
case SLAP_TOOL_MODE:
|
|
||||||
bdb2i_check_default_attr_index_mod( li, modlist );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (e = bdb2i_dn2entry_w( be, ndn, &matched )) == NULL ) {
|
|
||||||
char *matched_dn = NULL;
|
|
||||||
struct berval **refs = NULL;
|
|
||||||
|
|
||||||
if ( matched != NULL ) {
|
|
||||||
matched_dn = ch_strdup( matched->e_dn );
|
|
||||||
refs = is_entry_referral( matched )
|
|
||||||
? get_entry_referrals( be, conn, op, matched )
|
|
||||||
: NULL;
|
|
||||||
bdb2i_cache_return_entry_r( &li->li_cache, matched );
|
|
||||||
} else {
|
|
||||||
refs = default_referral;
|
|
||||||
}
|
|
||||||
|
|
||||||
send_ldap_result( conn, op, LDAP_REFERRAL,
|
|
||||||
matched_dn, NULL, refs, NULL );
|
|
||||||
|
|
||||||
if( matched != NULL ) {
|
|
||||||
ber_bvecfree( refs );
|
|
||||||
free( matched_dn );
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = -1;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!manageDSAit && is_entry_referral( e ) ) {
|
|
||||||
/* entry is a referral, don't allow add */
|
|
||||||
struct berval **refs = get_entry_referrals( be,
|
|
||||||
conn, op, e );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
|
|
||||||
0, 0 );
|
|
||||||
|
|
||||||
send_ldap_result( conn, op, LDAP_REFERRAL,
|
|
||||||
e->e_dn, NULL, refs, NULL );
|
|
||||||
|
|
||||||
bdb2i_cache_return_entry_w( &li->li_cache, e );
|
|
||||||
|
|
||||||
ber_bvecfree( refs );
|
|
||||||
|
|
||||||
ret = -1;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = bdb2i_back_modify_internal( be, conn, op, ndn, modlist, e );
|
|
||||||
bdb2i_cache_return_entry_w( &li->li_cache, e );
|
|
||||||
|
|
||||||
done:
|
|
||||||
(void) bdb2i_leave_backend_w( lock );
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "MOD", conn, op );
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_add_values(
|
|
||||||
Entry *e,
|
|
||||||
LDAPMod *mod,
|
|
||||||
char *dn
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
Attribute *a;
|
|
||||||
|
|
||||||
/* check if the values we're adding already exist */
|
|
||||||
if ( (a = attr_find( e->e_attrs, mod->mod_type )) != NULL ) {
|
|
||||||
for ( i = 0; mod->mod_bvalues[i] != NULL; i++ ) {
|
|
||||||
if ( value_find( a->a_vals, mod->mod_bvalues[i],
|
|
||||||
a->a_syntax, 3 ) == 0 ) {
|
|
||||||
return( LDAP_TYPE_OR_VALUE_EXISTS );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* no - add them */
|
|
||||||
if( attr_merge( e, mod->mod_type, mod->mod_bvalues ) != 0 ) {
|
|
||||||
return( LDAP_CONSTRAINT_VIOLATION );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( LDAP_SUCCESS );
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_delete_values(
|
|
||||||
Entry *e,
|
|
||||||
LDAPMod *mod,
|
|
||||||
char *dn
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int i, j, k, found;
|
|
||||||
Attribute *a;
|
|
||||||
|
|
||||||
/* delete the entire attribute */
|
|
||||||
if ( mod->mod_bvalues == NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_ARGS, "removing entire attribute %s\n",
|
|
||||||
mod->mod_type, 0, 0 );
|
|
||||||
return( attr_delete( &e->e_attrs, mod->mod_type ) ?
|
|
||||||
LDAP_NO_SUCH_ATTRIBUTE : LDAP_SUCCESS );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* delete specific values - find the attribute first */
|
|
||||||
if ( (a = attr_find( e->e_attrs, mod->mod_type )) == NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_ARGS, "could not find attribute %s\n",
|
|
||||||
mod->mod_type, 0, 0 );
|
|
||||||
return( LDAP_NO_SUCH_ATTRIBUTE );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find each value to delete */
|
|
||||||
for ( i = 0; mod->mod_bvalues[i] != NULL; i++ ) {
|
|
||||||
found = 0;
|
|
||||||
for ( j = 0; a->a_vals[j] != NULL; j++ ) {
|
|
||||||
if ( value_cmp( mod->mod_bvalues[i], a->a_vals[j],
|
|
||||||
a->a_syntax, 3 ) != 0 ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
found = 1;
|
|
||||||
|
|
||||||
/* found a matching value - delete it */
|
|
||||||
ber_bvfree( a->a_vals[j] );
|
|
||||||
for ( k = j + 1; a->a_vals[k] != NULL; k++ ) {
|
|
||||||
a->a_vals[k - 1] = a->a_vals[k];
|
|
||||||
}
|
|
||||||
a->a_vals[k - 1] = NULL;
|
|
||||||
|
|
||||||
/* delete the entire attribute, if no values remain */
|
|
||||||
if ( a->a_vals[0] == NULL) {
|
|
||||||
Debug( LDAP_DEBUG_ARGS,
|
|
||||||
"removing entire attribute %s\n",
|
|
||||||
mod->mod_type, 0, 0 );
|
|
||||||
if ( attr_delete( &e->e_attrs, mod->mod_type ) ) {
|
|
||||||
return LDAP_NO_SUCH_ATTRIBUTE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* looked through them all w/o finding it */
|
|
||||||
if ( ! found ) {
|
|
||||||
Debug( LDAP_DEBUG_ARGS,
|
|
||||||
"could not find value for attr %s\n",
|
|
||||||
mod->mod_type, 0, 0 );
|
|
||||||
return( LDAP_NO_SUCH_ATTRIBUTE );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return( LDAP_SUCCESS );
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_replace_values(
|
|
||||||
Entry *e,
|
|
||||||
LDAPMod *mod,
|
|
||||||
char *dn
|
|
||||||
)
|
|
||||||
{
|
|
||||||
(void) attr_delete( &e->e_attrs, mod->mod_type );
|
|
||||||
|
|
||||||
if ( mod->mod_bvalues != NULL &&
|
|
||||||
attr_merge( e, mod->mod_type, mod->mod_bvalues ) != 0 )
|
|
||||||
{
|
|
||||||
return( LDAP_CONSTRAINT_VIOLATION );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( LDAP_SUCCESS );
|
|
||||||
}
|
|
||||||
|
|
@ -1,493 +0,0 @@
|
||||||
/* modrdn.c - bdb2 backend modrdn routine */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LDAP v3 newSuperior support.
|
|
||||||
*
|
|
||||||
* Copyright 1999, Juan C. Gomez, All rights reserved.
|
|
||||||
* This software is not subject to any license of Silicon Graphics
|
|
||||||
* Inc. or Purdue University.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms are permitted
|
|
||||||
* without restriction or fee of any kind as long as this notice
|
|
||||||
* is preserved.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/string.h>
|
|
||||||
#include <ac/socket.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
#include "proto-back-bdb2.h"
|
|
||||||
|
|
||||||
static int
|
|
||||||
bdb2i_back_modrdn_internal(
|
|
||||||
BackendDB *be,
|
|
||||||
Connection *conn,
|
|
||||||
Operation *op,
|
|
||||||
char *dn,
|
|
||||||
char *newrdn,
|
|
||||||
int deleteoldrdn,
|
|
||||||
char *newSuperior
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
Entry *matched = NULL;
|
|
||||||
char *p_dn = NULL, *p_ndn = NULL;
|
|
||||||
char *new_dn = NULL, *new_ndn = NULL;
|
|
||||||
char sep[2];
|
|
||||||
Entry *e, *p = NULL;
|
|
||||||
int rc = -1, manageDSAit;
|
|
||||||
/* Added to support LDAP v2 correctly (deleteoldrdn thing) */
|
|
||||||
char *new_rdn_val = NULL; /* Val of new rdn */
|
|
||||||
char *new_rdn_type = NULL; /* Type of new rdn */
|
|
||||||
char *old_rdn = NULL; /* Old rdn's attr type & val */
|
|
||||||
char *old_rdn_type = NULL; /* Type of old rdn attr. */
|
|
||||||
char *old_rdn_val = NULL; /* Old rdn attribute value */
|
|
||||||
struct berval add_bv; /* Stores new rdn att */
|
|
||||||
struct berval *add_bvals[2]; /* Stores new rdn att */
|
|
||||||
struct berval del_bv; /* Stores old rdn att */
|
|
||||||
struct berval *del_bvals[2]; /* Stores old rdn att */
|
|
||||||
LDAPModList mod[2]; /* Used to delete old rdn */
|
|
||||||
/* Added to support newSuperior */
|
|
||||||
Entry *np = NULL; /* newSuperior Entry */
|
|
||||||
char *np_dn = NULL; /* newSuperior dn */
|
|
||||||
char *np_ndn = NULL; /* newSuperior ndn */
|
|
||||||
char *new_parent_dn = NULL; /* np_dn, p_dn, or NULL */
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "==>ldbm_back_modrdn(newSuperior=%s)\n",
|
|
||||||
(newSuperior ? newSuperior : "NULL"),
|
|
||||||
0, 0 );
|
|
||||||
|
|
||||||
/* get entry with writer lock */
|
|
||||||
if ( (e = bdb2i_dn2entry_w( be, dn, &matched )) == NULL ) {
|
|
||||||
char *matched_dn = NULL;
|
|
||||||
struct berval **refs = NULL;
|
|
||||||
|
|
||||||
if ( matched != NULL ) {
|
|
||||||
matched_dn = ch_strdup( matched->e_dn );
|
|
||||||
refs = is_entry_referral( matched )
|
|
||||||
? get_entry_referrals( be, conn, op, matched )
|
|
||||||
: NULL;
|
|
||||||
bdb2i_cache_return_entry_r( &li->li_cache, matched );
|
|
||||||
} else {
|
|
||||||
refs = default_referral;
|
|
||||||
}
|
|
||||||
|
|
||||||
send_ldap_result( conn, op, LDAP_REFERRAL,
|
|
||||||
matched_dn, NULL, refs, NULL );
|
|
||||||
|
|
||||||
if( matched != NULL ) {
|
|
||||||
ber_bvecfree( refs );
|
|
||||||
free( matched_dn );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!manageDSAit && is_entry_referral( e ) ) {
|
|
||||||
/* entry is a referral, don't allow add */
|
|
||||||
struct berval **refs = get_entry_referrals( be,
|
|
||||||
conn, op, e );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
|
|
||||||
0, 0 );
|
|
||||||
|
|
||||||
send_ldap_result( conn, op, LDAP_REFERRAL,
|
|
||||||
e->e_dn, NULL, refs, NULL );
|
|
||||||
|
|
||||||
ber_bvecfree( refs );
|
|
||||||
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SLAPD_CHILD_MODIFICATION_WITH_ENTRY_ACL
|
|
||||||
/* check parent for "children" acl */
|
|
||||||
if ( ! access_allowed( be, conn, op, e,
|
|
||||||
"entry", NULL, ACL_WRITE ) )
|
|
||||||
{
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "no access to entry\n", 0,
|
|
||||||
0, 0 );
|
|
||||||
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( (p_ndn = dn_parent( be, e->e_ndn )) != NULL ) {
|
|
||||||
/* parent + rdn + separator(s) + null */
|
|
||||||
if( (p = bdb2i_dn2entry_w( be, p_ndn, &matched )) == NULL) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "parent does not exist\n",
|
|
||||||
0, 0, 0);
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check parent for "children" acl */
|
|
||||||
if ( ! access_allowed( be, conn, op, p,
|
|
||||||
"children", NULL, ACL_WRITE ) )
|
|
||||||
{
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
|
|
||||||
0, 0 );
|
|
||||||
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
p_dn = dn_parent( be, e->e_dn );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: parent dn=%s\n",
|
|
||||||
p_dn, 0, 0 );
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/* no parent, modrdn entry directly under root */
|
|
||||||
if( ! be_isroot( be, op->o_ndn ) ) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "no parent & not root\n",
|
|
||||||
0, 0, 0);
|
|
||||||
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"ldbm_back_modrdn: no parent!, working on root\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
new_parent_dn = p_dn; /* New Parent unless newSuperior given */
|
|
||||||
|
|
||||||
if ( (np_dn = newSuperior) != NULL) {
|
|
||||||
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"ldbm_back_modrdn: new parent requested...\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
|
|
||||||
np_ndn = ch_strdup( np_dn );
|
|
||||||
(void) dn_normalize( np_ndn );
|
|
||||||
|
|
||||||
/* newSuperior == oldParent?, if so ==> ERROR */
|
|
||||||
|
|
||||||
/* newSuperior == entry being moved?, if so ==> ERROR */
|
|
||||||
|
|
||||||
/* Get Entry with dn=newSuperior. Does newSuperior exist? */
|
|
||||||
|
|
||||||
if( (np = bdb2i_dn2entry_w( be, np_ndn, &matched )) == NULL) {
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"ldbm_back_modrdn: newSup(ndn=%s) not here!\n",
|
|
||||||
np_ndn, 0, 0);
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"ldbm_back_modrdn: wr to new parent OK np=%p, id=%d\n",
|
|
||||||
np, np->e_id, 0 );
|
|
||||||
|
|
||||||
/* check newSuperior for "children" acl */
|
|
||||||
if ( !access_allowed( be, conn, op, np, "children", NULL,
|
|
||||||
ACL_WRITE ) )
|
|
||||||
{
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"ldbm_back_modrdn: no wr to newSup children\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"ldbm_back_modrdn: wr to new parent's children OK\n",
|
|
||||||
0, 0 , 0 );
|
|
||||||
|
|
||||||
|
|
||||||
new_parent_dn = np_dn;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build target dn and make sure target entry doesn't exist already. */
|
|
||||||
|
|
||||||
build_new_dn( &new_dn, e->e_dn, new_parent_dn, newrdn );
|
|
||||||
|
|
||||||
|
|
||||||
new_ndn = ch_strdup( new_dn );
|
|
||||||
(void) dn_normalize( new_ndn );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: new ndn=%s\n",
|
|
||||||
new_ndn, 0, 0 );
|
|
||||||
|
|
||||||
/* check for abandon */
|
|
||||||
ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
|
|
||||||
if ( op->o_abandon ) {
|
|
||||||
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
|
|
||||||
|
|
||||||
if ( (bdb2i_dn2id ( be, new_ndn ) ) != NOID ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_ALREADY_EXISTS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get attribute type and attribute value of our new rdn, we will
|
|
||||||
* need to add that to our new entry
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( (new_rdn_type = rdn_attr_type( newrdn )) == NULL ) {
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"ldbm_back_modrdn: can't figure out type of newrdn\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (new_rdn_val = rdn_attr_value( newrdn )) == NULL ) {
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"ldbm_back_modrdn: can't figure out val of newrdn\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"ldbm_back_modrdn: new_rdn_val=%s, new_rdn_type=%s\n",
|
|
||||||
new_rdn_val, new_rdn_type, 0 );
|
|
||||||
|
|
||||||
/* Retrieve the old rdn from the entry's dn */
|
|
||||||
|
|
||||||
if ( (old_rdn = dn_rdn( be, dn )) == NULL ) {
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"ldbm_back_modrdn: can't figure out old_rdn from dn\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (old_rdn_type = rdn_attr_type( old_rdn )) == NULL ) {
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"ldbm_back_modrdn: can't figure out the old_rdn type\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( strcasecmp( old_rdn_type, new_rdn_type ) != 0 ) {
|
|
||||||
|
|
||||||
/* Not a big deal but we may say something */
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"ldbm_back_modrdn: old_rdn_type=%s, new_rdn_type=%s!\n",
|
|
||||||
old_rdn_type, new_rdn_type, 0 );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "ldbm_back_modrdn: DN_X500\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
|
|
||||||
/* Add new attribute value to the entry.
|
|
||||||
*/
|
|
||||||
|
|
||||||
add_bvals[0] = &add_bv; /* Array of bervals */
|
|
||||||
add_bvals[1] = NULL;
|
|
||||||
|
|
||||||
add_bv.bv_val = new_rdn_val;
|
|
||||||
add_bv.bv_len = strlen(new_rdn_val);
|
|
||||||
|
|
||||||
mod[0].ml_type = new_rdn_type;
|
|
||||||
mod[0].ml_bvalues = add_bvals;
|
|
||||||
mod[0].ml_op = LDAP_MOD_SOFTADD;
|
|
||||||
mod[0].ml_next = NULL;
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"ldbm_back_modrdn: adding new rdn attr val =%s\n",
|
|
||||||
new_rdn_val, 0, 0 );
|
|
||||||
|
|
||||||
/* Remove old rdn value if required */
|
|
||||||
|
|
||||||
if (deleteoldrdn) {
|
|
||||||
|
|
||||||
del_bvals[0] = &del_bv; /* Array of bervals */
|
|
||||||
del_bvals[1] = NULL;
|
|
||||||
/* Get value of old rdn */
|
|
||||||
|
|
||||||
if ((old_rdn_val = rdn_attr_value( old_rdn ))
|
|
||||||
== NULL) {
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"ldbm_back_modrdn: can't figure out old_rdn_val from old_rdn\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove old value of rdn as an attribute. */
|
|
||||||
|
|
||||||
del_bv.bv_val = old_rdn_val;
|
|
||||||
del_bv.bv_len = strlen(old_rdn_val);
|
|
||||||
|
|
||||||
mod[0].ml_next = &mod[1];
|
|
||||||
mod[1].ml_type = old_rdn_type;
|
|
||||||
mod[1].ml_bvalues = del_bvals;
|
|
||||||
mod[1].ml_op = LDAP_MOD_DELETE;
|
|
||||||
mod[1].ml_next = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"ldbm_back_modrdn: removing old_rdn_val=%s\n",
|
|
||||||
old_rdn_val, 0, 0 );
|
|
||||||
|
|
||||||
}/* if (deleteoldrdn) */
|
|
||||||
|
|
||||||
/* check for abandon */
|
|
||||||
ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
|
|
||||||
if ( op->o_abandon ) {
|
|
||||||
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
|
|
||||||
|
|
||||||
/* delete old one */
|
|
||||||
if ( bdb2i_dn2id_delete( be, e->e_ndn, e->e_id ) != 0 ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
(void) bdb2i_cache_delete_entry( &li->li_cache, e );
|
|
||||||
|
|
||||||
free( e->e_dn );
|
|
||||||
free( e->e_ndn );
|
|
||||||
e->e_dn = new_dn;
|
|
||||||
e->e_ndn = new_ndn;
|
|
||||||
new_dn = NULL;
|
|
||||||
new_ndn = NULL;
|
|
||||||
|
|
||||||
/* add new one */
|
|
||||||
if ( bdb2i_dn2id_add( be, e->e_ndn, e->e_id ) != 0 ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* modify memory copy of entry */
|
|
||||||
if ( bdb2i_back_modify_internal( be, conn, op, dn, &mod[0], e )
|
|
||||||
!= 0 ) {
|
|
||||||
|
|
||||||
goto return_results;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
(void) bdb2i_cache_update_entry( &li->li_cache, e );
|
|
||||||
|
|
||||||
/* NOTE: after this you must not free new_dn or new_ndn!
|
|
||||||
* They are used by cache.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* id2entry index */
|
|
||||||
if ( bdb2i_id2entry_add( be, e ) != 0 ) {
|
|
||||||
entry_free( e );
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
goto return_results;
|
|
||||||
}
|
|
||||||
|
|
||||||
send_ldap_result( conn, op, LDAP_SUCCESS,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
rc = 0;
|
|
||||||
|
|
||||||
return_results:
|
|
||||||
if( new_dn != NULL ) free( new_dn );
|
|
||||||
if( new_ndn != NULL ) free( new_ndn );
|
|
||||||
|
|
||||||
/* NOTE:
|
|
||||||
* new_dn and new_ndn are not deallocated because they are used by
|
|
||||||
* the cache entry.
|
|
||||||
*/
|
|
||||||
if( p_dn != NULL ) free( p_dn );
|
|
||||||
if( p_ndn != NULL ) free( p_ndn );
|
|
||||||
|
|
||||||
/* LDAP v2 supporting correct attribute handling. */
|
|
||||||
if( new_rdn_type != NULL ) free(new_rdn_type);
|
|
||||||
if( new_rdn_val != NULL ) free(new_rdn_val);
|
|
||||||
if( old_rdn != NULL ) free(old_rdn);
|
|
||||||
if( old_rdn_type != NULL ) free(old_rdn_type);
|
|
||||||
if( old_rdn_val != NULL ) free(old_rdn_val);
|
|
||||||
|
|
||||||
/* LDAP v3 Support */
|
|
||||||
if ( np_dn != NULL ) free( np_dn );
|
|
||||||
if ( np_ndn != NULL ) free( np_ndn );
|
|
||||||
|
|
||||||
if( p != NULL ) {
|
|
||||||
/* free parent and writer lock */
|
|
||||||
bdb2i_cache_return_entry_w( &li->li_cache, p );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* free entry and writer lock */
|
|
||||||
bdb2i_cache_return_entry_w( &li->li_cache, e );
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_modrdn(
|
|
||||||
BackendDB *be,
|
|
||||||
Connection *conn,
|
|
||||||
Operation *op,
|
|
||||||
char *dn,
|
|
||||||
char *ndn,
|
|
||||||
char *newrdn,
|
|
||||||
int deleteoldrdn,
|
|
||||||
char *newSuperior
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DB_LOCK lock;
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
struct timeval time1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
bdb2i_start_timing( be->bd_info, &time1 );
|
|
||||||
|
|
||||||
if ( bdb2i_enter_backend_w( &lock ) != 0 ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = bdb2i_back_modrdn_internal( be, conn, op, ndn,
|
|
||||||
newrdn, deleteoldrdn,
|
|
||||||
newSuperior );
|
|
||||||
|
|
||||||
(void) bdb2i_leave_backend_w( lock );
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "MODRDN", conn, op );
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
||||||
/* id.c - keep track of the next id to be given out */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/socket.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_PARAM_H
|
|
||||||
#include <sys/param.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
|
|
||||||
/* reading and writing NEXTID is handled in txn.c */
|
|
||||||
#define next_id_read(be) bdb2i_get_nextid( (be) )
|
|
||||||
#define next_id_write(be,id) bdb2i_put_nextid( (be), (id) )
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_next_id_save( BackendDB *be )
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
ID id = bdb2i_next_id_get( be );
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = next_id_write( be, id );
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
ID
|
|
||||||
bdb2i_next_id( BackendDB *be )
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
ID id;
|
|
||||||
|
|
||||||
/* first time in here since startup - try to read the nexid */
|
|
||||||
if ( li->li_nextid == NOID ) {
|
|
||||||
li->li_nextid = next_id_read( be );
|
|
||||||
|
|
||||||
if ( li->li_nextid == NOID ) {
|
|
||||||
li->li_nextid = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
id = li->li_nextid++;
|
|
||||||
|
|
||||||
(void) next_id_write( be, li->li_nextid );
|
|
||||||
|
|
||||||
return( id );
|
|
||||||
}
|
|
||||||
|
|
||||||
ID
|
|
||||||
bdb2i_next_id_get( BackendDB *be )
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
ID id;
|
|
||||||
|
|
||||||
/* first time in here since startup - try to read the nexid */
|
|
||||||
if ( li->li_nextid == NOID ) {
|
|
||||||
li->li_nextid = next_id_read( be );
|
|
||||||
|
|
||||||
if ( li->li_nextid == NOID ) {
|
|
||||||
li->li_nextid = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
id = li->li_nextid;
|
|
||||||
|
|
||||||
return( id );
|
|
||||||
}
|
|
||||||
|
|
@ -1,143 +0,0 @@
|
||||||
/* porter.c - port functions of the bdb2 backend */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ac/errno.h>
|
|
||||||
|
|
||||||
#include <ac/string.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
|
|
||||||
#define PORTER_OBJ "bdb2_backend"
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_enter_backend_rw( DB_LOCK *lock, int writer )
|
|
||||||
{
|
|
||||||
u_int32_t locker;
|
|
||||||
db_lockmode_t lock_type;
|
|
||||||
DBT lock_dbt;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
switch ( slapMode & SLAP_MODE ) {
|
|
||||||
|
|
||||||
case SLAP_SERVER_MODE:
|
|
||||||
case SLAP_TOOL_MODE:
|
|
||||||
if ( ( ret = lock_id( bdb2i_dbEnv.lk_info, &locker )) != 0 ) {
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_enter_backend(): unable to get locker id -- %s\n",
|
|
||||||
strerror( ret ), 0, 0 );
|
|
||||||
return( ret );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
lock_type = writer ? DB_LOCK_WRITE : DB_LOCK_READ;
|
|
||||||
lock_dbt.data = PORTER_OBJ;
|
|
||||||
lock_dbt.size = strlen( PORTER_OBJ );
|
|
||||||
|
|
||||||
switch ( ( ret = lock_get( bdb2i_dbEnv.lk_info, locker, 0,
|
|
||||||
&lock_dbt, lock_type, lock ))) {
|
|
||||||
|
|
||||||
case 0:
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"bdb2i_enter_backend() -- %s lock granted\n",
|
|
||||||
writer ? "write" : "read", 0, 0 );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DB_LOCK_NOTGRANTED:
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_enter_backend() -- %s lock NOT granted\n",
|
|
||||||
writer ? "write" : "read", 0, 0 );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DB_LOCK_DEADLOCK:
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_enter_backend() -- %s lock returned DEADLOCK\n",
|
|
||||||
writer ? "write" : "read", 0, 0 );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ret = errno;
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_enter_backend() -- %s lock returned ERROR: %s\n",
|
|
||||||
writer ? "write" : "read", strerror( ret ), 0 );
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if we are a writer and we have the backend lock,
|
|
||||||
start transaction control */
|
|
||||||
if ( writer && ( ret == 0 )) {
|
|
||||||
|
|
||||||
ret = bdb2i_start_transction( bdb2i_dbEnv.tx_info );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_leave_backend_rw( DB_LOCK lock, int writer )
|
|
||||||
{
|
|
||||||
/* since one or more error can occure,
|
|
||||||
we must have several return codes that are or'ed at the end */
|
|
||||||
int ret_transaction = 0;
|
|
||||||
int ret_lock = 0;
|
|
||||||
|
|
||||||
/* if we are a writer, finish the transaction */
|
|
||||||
if ( writer ) {
|
|
||||||
|
|
||||||
ret_transaction = bdb2i_finish_transaction();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check whether checkpointing is needed */
|
|
||||||
ret_transaction |= bdb2i_set_txn_checkpoint( bdb2i_dbEnv.tx_info, 0 );
|
|
||||||
|
|
||||||
/* now release the lock */
|
|
||||||
switch ( slapMode & SLAP_MODE ) {
|
|
||||||
|
|
||||||
case SLAP_SERVER_MODE:
|
|
||||||
case SLAP_TOOL_MODE:
|
|
||||||
switch( ( ret_lock = lock_put( bdb2i_dbEnv.lk_info, lock ))) {
|
|
||||||
|
|
||||||
case 0:
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"bdb2i_leave_backend() -- %s lock released\n",
|
|
||||||
writer ? "write" : "read", 0, 0 );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DB_LOCK_NOTHELD:
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_leave_backend() -- %s lock NOT held\n",
|
|
||||||
writer ? "write" : "read", 0, 0 );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DB_LOCK_DEADLOCK:
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_leave_backend() -- %s lock returned DEADLOCK\n",
|
|
||||||
writer ? "write" : "read", 0, 0 );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ret_lock = errno;
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_leave_backend() -- %s lock returned ERROR: %s\n",
|
|
||||||
writer ? "write" : "read", strerror( ret_lock ), 0 );
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return( ret_transaction | ret_lock );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,251 +0,0 @@
|
||||||
/* $OpenLDAP$ */
|
|
||||||
#ifndef _PROTO_BACK_BDB2
|
|
||||||
#define _PROTO_BACK_BDB2
|
|
||||||
|
|
||||||
#include <ldap_cdefs.h>
|
|
||||||
|
|
||||||
#include <ac/time.h> /* Needed in add.c compare.c struct timeval */
|
|
||||||
|
|
||||||
#include "external.h"
|
|
||||||
|
|
||||||
LDAP_BEGIN_DECL
|
|
||||||
|
|
||||||
/*
|
|
||||||
* add.c
|
|
||||||
*/
|
|
||||||
int bdb2i_release_add_lock LDAP_P(());
|
|
||||||
|
|
||||||
/*
|
|
||||||
* alias.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
Entry * bdb2i_deref_r LDAP_P((
|
|
||||||
Backend *be,
|
|
||||||
Entry *e,
|
|
||||||
char *dn,
|
|
||||||
int *err,
|
|
||||||
Entry **matched,
|
|
||||||
char **text ));
|
|
||||||
|
|
||||||
#define deref_entry_r( be, e, err, matched, text ) \
|
|
||||||
bdb2i_deref_r( be, e, NULL, err, matched, text )
|
|
||||||
#define deref_dn_r( be, dn, err, matched, text ) \
|
|
||||||
bdb2i_deref_r( be, NULL, dn, err, matched, text )
|
|
||||||
|
|
||||||
/*
|
|
||||||
* attr.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
void bdb2i_attr_masks LDAP_P(( struct ldbminfo *li, char *type, int *indexmask,
|
|
||||||
int *syntaxmask ));
|
|
||||||
void bdb2i_attr_index_config LDAP_P(( struct ldbminfo *li,
|
|
||||||
const char *fname,
|
|
||||||
int lineno, int argc, char **argv, int init ));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* cache.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
int bdb2i_cache_add_entry_rw LDAP_P(( struct cache *cache, Entry *e, int rw ));
|
|
||||||
int bdb2i_cache_update_entry LDAP_P(( struct cache *cache, Entry *e ));
|
|
||||||
void bdb2i_cache_return_entry_rw LDAP_P(( struct cache *cache, Entry *e,
|
|
||||||
int rw ));
|
|
||||||
#define bdb2i_cache_return_entry_r(c, e) bdb2i_cache_return_entry_rw((c), (e), 0)
|
|
||||||
#define bdb2i_cache_return_entry_w(c, e) bdb2i_cache_return_entry_rw((c), (e), 1)
|
|
||||||
|
|
||||||
ID bdb2i_cache_find_entry_dn2id LDAP_P(( BackendDB *be, struct cache *cache,
|
|
||||||
const char *dn ));
|
|
||||||
Entry * bdb2i_cache_find_entry_id LDAP_P(( struct cache *cache, ID id, int rw ));
|
|
||||||
int bdb2i_cache_delete_entry LDAP_P(( struct cache *cache, Entry *e ));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* dbcache.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct dbcache * bdb2i_cache_open LDAP_P(( BackendDB *be, char *name, char *suffix,
|
|
||||||
int flags ));
|
|
||||||
void bdb2i_cache_close LDAP_P(( BackendDB *be, struct dbcache *db ));
|
|
||||||
void bdb2i_cache_really_close LDAP_P(( BackendDB *be, struct dbcache *db ));
|
|
||||||
void bdb2i_cache_flush_all LDAP_P(( BackendDB *be ));
|
|
||||||
Datum bdb2i_cache_fetch LDAP_P(( struct dbcache *db, Datum key ));
|
|
||||||
int bdb2i_cache_store LDAP_P(( struct dbcache *db, Datum key, Datum data, int flags ));
|
|
||||||
int bdb2i_cache_delete LDAP_P(( struct dbcache *db, Datum key ));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* dn2id.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
int bdb2i_dn2id_add LDAP_P(( BackendDB *be, const char *dn, ID id ));
|
|
||||||
ID bdb2i_dn2id LDAP_P(( BackendDB *be, const char *dn ));
|
|
||||||
int bdb2i_dn2id_delete LDAP_P(( BackendDB *be, const char *dn, ID id ));
|
|
||||||
|
|
||||||
ID_BLOCK *
|
|
||||||
bdb2i_dn2idl LDAP_P((
|
|
||||||
BackendDB *be,
|
|
||||||
const char *dn,
|
|
||||||
int prefix ));
|
|
||||||
|
|
||||||
Entry * bdb2i_dn2entry_rw LDAP_P((
|
|
||||||
BackendDB *be,
|
|
||||||
const char *dn,
|
|
||||||
Entry **matched,
|
|
||||||
int rw ));
|
|
||||||
|
|
||||||
#define bdb2i_dn2entry_r(be, dn, m) bdb2i_dn2entry_rw((be), (dn), (m), 0)
|
|
||||||
#define bdb2i_dn2entry_w(be, dn, m) bdb2i_dn2entry_rw((be), (dn), (m), 1)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* entry.c
|
|
||||||
*/
|
|
||||||
int bdb2_back_entry_release_rw LDAP_P(( BackendDB *be, Entry *e, int rw ));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* filterindex.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
ID_BLOCK * bdb2i_filter_candidates LDAP_P(( BackendDB *be, Filter *f ));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* id2children.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
int bdb2i_has_children LDAP_P(( BackendDB *be, Entry *p ));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* id2entry.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
int bdb2i_id2entry_add LDAP_P(( BackendDB *be, Entry *e ));
|
|
||||||
int bdb2i_id2entry_delete LDAP_P(( BackendDB *be, Entry *e ));
|
|
||||||
|
|
||||||
Entry * bdb2i_id2entry_rw LDAP_P(( BackendDB *be, ID id, int rw ));
|
|
||||||
#define bdb2i_id2entry_r(be, id) bdb2i_id2entry_rw((be), (id), 0)
|
|
||||||
#define bdb2i_id2entry_w(be, id) bdb2i_id2entry_rw((be), (id), 1)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* idl.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
ID_BLOCK * bdb2i_idl_alloc LDAP_P(( unsigned int nids ));
|
|
||||||
ID_BLOCK * bdb2i_idl_allids LDAP_P(( BackendDB *be ));
|
|
||||||
void bdb2i_idl_free LDAP_P(( ID_BLOCK *idl ));
|
|
||||||
ID_BLOCK * bdb2i_idl_fetch LDAP_P(( BackendDB *be, struct dbcache *db, Datum key ));
|
|
||||||
int bdb2i_idl_insert_key LDAP_P(( BackendDB *be, struct dbcache *db, Datum key, ID id ));
|
|
||||||
int bdb2i_idl_insert LDAP_P(( ID_BLOCK **idl, ID id, unsigned int maxids ));
|
|
||||||
int bdb2i_idl_delete_key LDAP_P(( BackendDB *be, struct dbcache *db, Datum key, ID id ));
|
|
||||||
ID_BLOCK * bdb2i_idl_intersection LDAP_P(( BackendDB *be, ID_BLOCK *a, ID_BLOCK *b ));
|
|
||||||
ID_BLOCK * bdb2i_idl_union LDAP_P(( BackendDB *be, ID_BLOCK *a, ID_BLOCK *b ));
|
|
||||||
ID_BLOCK * bdb2i_idl_notin LDAP_P(( BackendDB *be, ID_BLOCK *a, ID_BLOCK *b ));
|
|
||||||
ID bdb2i_idl_firstid LDAP_P(( ID_BLOCK *idl, ID *cursor ));
|
|
||||||
ID bdb2i_idl_nextid LDAP_P(( ID_BLOCK *idl, ID *cursor ));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* index.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
int bdb2i_index_add_entry LDAP_P(( BackendDB *be, Entry *e ));
|
|
||||||
int bdb2i_index_add_mods LDAP_P(( BackendDB *be, Modifications *ml, ID id ));
|
|
||||||
ID_BLOCK * bdb2i_index_read LDAP_P(( BackendDB *be, char *type, int indextype, char *val ));
|
|
||||||
int bdb2i_index_add_values LDAP_P(( BackendDB *be, char *type, struct berval **vals, ID id ));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* kerberos.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
|
|
||||||
/* bdb2i_krbv4_ldap_auth LDAP_P(( BackendDB *be, struct berval *cred, AUTH_DAT *ad )); */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* modify.c
|
|
||||||
* These prototypes are placed here because they are used by modify and
|
|
||||||
* modify rdn which are implemented in different files.
|
|
||||||
*
|
|
||||||
* We need bdb2i_back_modify_internal here because of LDAP modrdn & modify use
|
|
||||||
* it. If we do not add this, there would be a bunch of code replication
|
|
||||||
* here and there and of course the likelihood of bugs increases.
|
|
||||||
* Juan C. Gomez (gomez@engr.sgi.com) 05/18/99
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
int bdb2i_add_values LDAP_P(( Entry *e, LDAPMod *mod, char *dn ));
|
|
||||||
int bdb2i_delete_values LDAP_P(( Entry *e, LDAPMod *mod, char *dn ));
|
|
||||||
int bdb2i_replace_values LDAP_P(( Entry *e, LDAPMod *mod, char *dn ));
|
|
||||||
int bdb2i_back_modify_internal LDAP_P((Backend *be, Connection *conn, Operation *op,
|
|
||||||
char *dn, Modifications *mods, Entry *e));
|
|
||||||
/*
|
|
||||||
* nextid.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
ID bdb2i_next_id LDAP_P(( BackendDB *be ));
|
|
||||||
void bdb2i_next_id_return LDAP_P(( BackendDB *be, ID id ));
|
|
||||||
ID bdb2i_next_id_get LDAP_P(( BackendDB *be ));
|
|
||||||
int bdb2i_next_id_save LDAP_P(( BackendDB *be ));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* startup.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
int bdb2i_back_startup LDAP_P(( BackendInfo *bi ));
|
|
||||||
int bdb2i_back_shutdown LDAP_P(( BackendInfo *bi ));
|
|
||||||
int bdb2i_back_db_startup LDAP_P(( BackendDB *be ));
|
|
||||||
int bdb2i_back_db_shutdown LDAP_P(( BackendDB *be ));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* timing.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
void bdb2i_uncond_start_timing LDAP_P(( struct timeval *time1 ));
|
|
||||||
#define bdb2i_start_timing(bi,time1) if ( with_timing( bi )) bdb2i_uncond_start_timing( (time1) )
|
|
||||||
void bdb2i_uncond_stop_timing LDAP_P(( struct timeval time1,
|
|
||||||
char *func, Connection *conn, Operation *op, int level ));
|
|
||||||
#define bdb2i_stop_timing(bi,time1,func,conn,op) if ( with_timing( bi )) bdb2i_uncond_stop_timing( (time1), (func), (conn), (op), LDAP_DEBUG_ANY )
|
|
||||||
|
|
||||||
/*
|
|
||||||
* porter.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
int bdb2i_enter_backend_rw LDAP_P(( DB_LOCK *lock, int writer ));
|
|
||||||
#define bdb2i_enter_backend_r(lock) bdb2i_enter_backend_rw((lock), 0 )
|
|
||||||
#define bdb2i_enter_backend_w(lock) bdb2i_enter_backend_rw((lock), 1 )
|
|
||||||
int bdb2i_leave_backend_rw LDAP_P(( DB_LOCK lock, int writer ));
|
|
||||||
#define bdb2i_leave_backend_r(lock) bdb2i_leave_backend_rw((lock), 0 )
|
|
||||||
#define bdb2i_leave_backend_w(lock) bdb2i_leave_backend_rw((lock), 1 )
|
|
||||||
|
|
||||||
/*
|
|
||||||
* txn.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
int bdb2i_txn_head_init LDAP_P(( BDB2_TXN_HEAD *head ));
|
|
||||||
void bdb2i_txn_attr_config LDAP_P((
|
|
||||||
struct ldbminfo *li,
|
|
||||||
char *attr,
|
|
||||||
int open ));
|
|
||||||
int bdb2i_txn_open_files LDAP_P(( BackendDB *be ));
|
|
||||||
void bdb2i_txn_close_files LDAP_P(( BackendDB *be ));
|
|
||||||
BDB2_TXN_FILES *bdb2i_get_db_file_cache LDAP_P((
|
|
||||||
struct ldbminfo *li,
|
|
||||||
char *name ));
|
|
||||||
int bdb2i_check_additional_attr_index LDAP_P(( struct ldbminfo *li ));
|
|
||||||
void bdb2i_check_default_attr_index_add LDAP_P((
|
|
||||||
struct ldbminfo *li,
|
|
||||||
Entry *e ));
|
|
||||||
void bdb2i_check_default_attr_index_mod LDAP_P((
|
|
||||||
struct ldbminfo *li,
|
|
||||||
Modifications *modlist ));
|
|
||||||
ID bdb2i_get_nextid LDAP_P(( BackendDB *be ));
|
|
||||||
int bdb2i_put_nextid LDAP_P(( BackendDB *be, ID id ));
|
|
||||||
LDBM bdb2i_db_open LDAP_P(( char *name, int type, int rw, int mode,
|
|
||||||
int dbcachesize ));
|
|
||||||
int bdb2i_db_store LDAP_P(( LDBM ldbm, Datum key, Datum data, int flags ));
|
|
||||||
int bdb2i_db_delete LDAP_P(( LDBM ldbm, Datum key ));
|
|
||||||
Datum bdb2i_db_fetch LDAP_P(( LDBM ldbm, Datum key ));
|
|
||||||
Datum bdb2i_db_firstkey LDAP_P(( LDBM ldbm, DBC **dbch ));
|
|
||||||
Datum bdb2i_db_nextkey LDAP_P(( LDBM ldbm, Datum key, DBC *dbcp ));
|
|
||||||
int bdb2i_start_transction LDAP_P(( DB_TXNMGR *txmgr ));
|
|
||||||
int bdb2i_finish_transaction LDAP_P(( ));
|
|
||||||
int bdb2i_set_txn_checkpoint LDAP_P(( DB_TXNMGR *txmgr, int forced ));
|
|
||||||
|
|
||||||
|
|
||||||
LDAP_END_DECL
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,483 +0,0 @@
|
||||||
/* search.c - bdb2 backend search function */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/string.h>
|
|
||||||
#include <ac/socket.h>
|
|
||||||
#include <ac/time.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
#include "proto-back-bdb2.h"
|
|
||||||
|
|
||||||
static ID_BLOCK *base_candidate(
|
|
||||||
Backend *be, Entry *e );
|
|
||||||
|
|
||||||
static ID_BLOCK *search_candidates(
|
|
||||||
Backend *be, Entry *e, Filter *filter,
|
|
||||||
int scope, int deref, int manageDSAit );
|
|
||||||
|
|
||||||
static int
|
|
||||||
bdb2i_back_search_internal(
|
|
||||||
BackendDB *be,
|
|
||||||
Connection *conn,
|
|
||||||
Operation *op,
|
|
||||||
char *base,
|
|
||||||
int scope,
|
|
||||||
int deref,
|
|
||||||
int slimit,
|
|
||||||
int tlimit,
|
|
||||||
Filter *filter,
|
|
||||||
char *filterstr,
|
|
||||||
char **attrs,
|
|
||||||
int attrsonly
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
int rc, err;
|
|
||||||
char *text;
|
|
||||||
time_t stoptime;
|
|
||||||
ID_BLOCK *candidates;
|
|
||||||
ID id, cursor;
|
|
||||||
Entry *e;
|
|
||||||
struct berval **v2refs = NULL;
|
|
||||||
Entry *matched = NULL;
|
|
||||||
char *realbase = NULL;
|
|
||||||
int nentries = 0;
|
|
||||||
int manageDSAit = get_manageDSAit( op );
|
|
||||||
|
|
||||||
Debug(LDAP_DEBUG_TRACE, "=> bdb2_back_search\n", 0, 0, 0);
|
|
||||||
|
|
||||||
/* get entry with reader lock */
|
|
||||||
if ( deref & LDAP_DEREF_FINDING ) {
|
|
||||||
e = deref_dn_r( be, base, &err, &matched, &text );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
e = bdb2i_dn2entry_r( be, base, &matched );
|
|
||||||
err = e != NULL ? LDAP_SUCCESS : LDAP_REFERRAL;
|
|
||||||
text = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( e == NULL ) {
|
|
||||||
char *matched_dn = NULL;
|
|
||||||
struct berval **refs = NULL;
|
|
||||||
|
|
||||||
if ( matched != NULL ) {
|
|
||||||
matched_dn = ch_strdup( matched->e_dn );
|
|
||||||
|
|
||||||
refs = is_entry_referral( matched )
|
|
||||||
? get_entry_referrals( be, conn, op, matched )
|
|
||||||
: NULL;
|
|
||||||
|
|
||||||
bdb2i_cache_return_entry_r( &li->li_cache, matched );
|
|
||||||
} else {
|
|
||||||
refs = default_referral;
|
|
||||||
}
|
|
||||||
|
|
||||||
send_ldap_result( conn, op, err,
|
|
||||||
matched_dn, text, refs, NULL );
|
|
||||||
|
|
||||||
if( matched != NULL ) {
|
|
||||||
ber_bvecfree( refs );
|
|
||||||
free( matched_dn );
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!manageDSAit && is_entry_referral( e ) ) {
|
|
||||||
/* entry is a referral, don't allow add */
|
|
||||||
char *matched_dn = ch_strdup( e->e_dn );
|
|
||||||
struct berval **refs = get_entry_referrals( be,
|
|
||||||
conn, op, e );
|
|
||||||
|
|
||||||
bdb2i_cache_return_entry_r( &li->li_cache, e );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
|
|
||||||
0, 0 );
|
|
||||||
|
|
||||||
send_ldap_result( conn, op, LDAP_REFERRAL,
|
|
||||||
matched_dn, NULL, refs, NULL );
|
|
||||||
|
|
||||||
ber_bvecfree( refs );
|
|
||||||
free( matched_dn );
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( tlimit == 0 && be_isroot( be, op->o_ndn ) ) {
|
|
||||||
tlimit = -1; /* allow root to set no limit */
|
|
||||||
} else {
|
|
||||||
tlimit = (tlimit > be->be_timelimit || tlimit < 1) ?
|
|
||||||
be->be_timelimit : tlimit;
|
|
||||||
stoptime = op->o_time + tlimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( slimit == 0 && be_isroot( be, op->o_ndn ) ) {
|
|
||||||
slimit = -1; /* allow root to set no limit */
|
|
||||||
} else {
|
|
||||||
slimit = (slimit > be->be_sizelimit || slimit < 1) ?
|
|
||||||
be->be_sizelimit : slimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( scope == LDAP_SCOPE_BASE) {
|
|
||||||
candidates = base_candidate( be, e );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
candidates = search_candidates( be, e, filter,
|
|
||||||
scope, deref, manageDSAit );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* need normalized dn below */
|
|
||||||
realbase = ch_strdup( e->e_ndn );
|
|
||||||
bdb2i_cache_return_entry_r( &li->li_cache, e );
|
|
||||||
|
|
||||||
if ( candidates == NULL ) {
|
|
||||||
/* no candidates */
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "no candidates\n", 0,
|
|
||||||
0, 0 );
|
|
||||||
|
|
||||||
send_search_result( conn, op,
|
|
||||||
LDAP_SUCCESS,
|
|
||||||
NULL, NULL, NULL, NULL, 0 );
|
|
||||||
|
|
||||||
rc = 1;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( id = bdb2i_idl_firstid( candidates, &cursor ); id != NOID;
|
|
||||||
id = bdb2i_idl_nextid( candidates, &cursor ) )
|
|
||||||
{
|
|
||||||
int scopeok = 0;
|
|
||||||
|
|
||||||
/* check for abandon */
|
|
||||||
ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
|
|
||||||
|
|
||||||
if ( op->o_abandon ) {
|
|
||||||
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
|
|
||||||
rc = 0;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
|
|
||||||
|
|
||||||
/* check time limit */
|
|
||||||
if ( tlimit != -1 && slap_get_time() > stoptime ) {
|
|
||||||
send_search_result( conn, op, LDAP_TIMELIMIT_EXCEEDED,
|
|
||||||
NULL, NULL, v2refs, NULL, nentries );
|
|
||||||
rc = 0;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the entry with reader lock */
|
|
||||||
e = bdb2i_id2entry_r( be, id );
|
|
||||||
|
|
||||||
if ( e == NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_ARGS, "search: candidate %ld not found\n",
|
|
||||||
id, 0, 0 );
|
|
||||||
|
|
||||||
goto loop_continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( deref & LDAP_DEREF_SEARCHING && is_entry_alias( e ) ) {
|
|
||||||
Entry *matched;
|
|
||||||
int err;
|
|
||||||
char *text;
|
|
||||||
|
|
||||||
e = deref_entry_r( be, e, &err, &matched, &text );
|
|
||||||
|
|
||||||
if( e == NULL ) {
|
|
||||||
e = matched;
|
|
||||||
goto loop_continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( e->e_id == id ) {
|
|
||||||
/* circular loop */
|
|
||||||
goto loop_continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* need to skip alias which deref into scope */
|
|
||||||
if( scope & LDAP_SCOPE_ONELEVEL ) {
|
|
||||||
char *pdn = dn_parent( NULL, e->e_ndn );
|
|
||||||
if ( pdn != NULL ) {
|
|
||||||
if( strcmp( pdn, realbase ) ) {
|
|
||||||
free( pdn );
|
|
||||||
goto loop_continue;
|
|
||||||
}
|
|
||||||
free(pdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if ( dn_issuffix( e->e_ndn, realbase ) ) {
|
|
||||||
/* alias is within scope */
|
|
||||||
Debug( LDAP_DEBUG_ARGS, "search: \"%s\" in subtree\n",
|
|
||||||
e->e_dn, 0, 0 );
|
|
||||||
goto loop_continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
scopeok = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* if it's a referral, add it to the list of referrals. only do
|
|
||||||
* this for non-base searches, and don't check the filter
|
|
||||||
* explicitly here since it's only a candidate anyway.
|
|
||||||
*/
|
|
||||||
if ( !manageDSAit && scope != LDAP_SCOPE_BASE &&
|
|
||||||
is_entry_referral( e ) )
|
|
||||||
{
|
|
||||||
struct berval **refs = get_entry_referrals(
|
|
||||||
be, conn, op, e );
|
|
||||||
|
|
||||||
send_search_reference( be, conn, op,
|
|
||||||
e, refs, scope, NULL, &v2refs );
|
|
||||||
|
|
||||||
ber_bvecfree( refs );
|
|
||||||
|
|
||||||
goto loop_continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if it matches the filter and scope, send it */
|
|
||||||
if ( test_filter( be, conn, op, e, filter ) == LDAP_COMPARE_TRUE ) {
|
|
||||||
char *dn;
|
|
||||||
|
|
||||||
/* check scope */
|
|
||||||
if ( !scopeok && scope == LDAP_SCOPE_ONELEVEL ) {
|
|
||||||
if ( (dn = dn_parent( be, e->e_ndn )) != NULL ) {
|
|
||||||
(void) dn_normalize( dn );
|
|
||||||
scopeok = (dn == realbase)
|
|
||||||
? 1
|
|
||||||
: (strcmp( dn, realbase ) ? 0 : 1 );
|
|
||||||
free( dn );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
scopeok = (realbase == NULL || *realbase == '\0');
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if ( !scopeok && scope == LDAP_SCOPE_SUBTREE ) {
|
|
||||||
dn = ch_strdup( e->e_ndn );
|
|
||||||
scopeok = dn_issuffix( dn, realbase );
|
|
||||||
free( dn );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
scopeok = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( scopeok ) {
|
|
||||||
/* check size limit */
|
|
||||||
if ( --slimit == -1 ) {
|
|
||||||
bdb2i_cache_return_entry_r( &li->li_cache, e );
|
|
||||||
send_search_result( conn, op,
|
|
||||||
LDAP_SIZELIMIT_EXCEEDED, NULL, NULL,
|
|
||||||
v2refs, NULL, nentries );
|
|
||||||
rc = 0;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e) {
|
|
||||||
switch ( send_search_entry( be, conn, op, e,
|
|
||||||
attrs, attrsonly, NULL ) ) {
|
|
||||||
case 0: /* entry sent ok */
|
|
||||||
nentries++;
|
|
||||||
break;
|
|
||||||
case 1: /* entry not sent */
|
|
||||||
break;
|
|
||||||
case -1: /* connection closed */
|
|
||||||
bdb2i_cache_return_entry_r( &li->li_cache, e );
|
|
||||||
rc = 0;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "candidate %ld scope not okay\n",
|
|
||||||
id, 0, 0 );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "candidate %ld does match filter\n",
|
|
||||||
id, 0, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
loop_continue:
|
|
||||||
if( e != NULL ) {
|
|
||||||
/* free reader lock */
|
|
||||||
bdb2i_cache_return_entry_r( &li->li_cache, e );
|
|
||||||
}
|
|
||||||
|
|
||||||
ldap_pvt_thread_yield();
|
|
||||||
}
|
|
||||||
send_search_result( conn, op,
|
|
||||||
v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
|
|
||||||
NULL, NULL, v2refs, NULL, nentries );
|
|
||||||
|
|
||||||
rc = 0;
|
|
||||||
|
|
||||||
done:
|
|
||||||
bdb2i_idl_free( candidates );
|
|
||||||
|
|
||||||
ber_bvecfree( v2refs );
|
|
||||||
if( realbase ) free( realbase );
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_search(
|
|
||||||
BackendDB *be,
|
|
||||||
Connection *conn,
|
|
||||||
Operation *op,
|
|
||||||
char *base,
|
|
||||||
char *nbase,
|
|
||||||
int scope,
|
|
||||||
int deref,
|
|
||||||
int slimit,
|
|
||||||
int tlimit,
|
|
||||||
Filter *filter,
|
|
||||||
char *filterstr,
|
|
||||||
char **attrs,
|
|
||||||
int attrsonly
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DB_LOCK lock;
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
struct timeval time1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
bdb2i_start_timing( be->bd_info, &time1 );
|
|
||||||
|
|
||||||
if ( bdb2i_enter_backend_r( &lock ) != 0 ) {
|
|
||||||
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
|
|
||||||
NULL, NULL, NULL, NULL );
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = bdb2i_back_search_internal( be, conn, op, nbase, scope, deref,
|
|
||||||
slimit, tlimit, filter, filterstr, attrs, attrsonly );
|
|
||||||
|
|
||||||
(void) bdb2i_leave_backend_r( lock );
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "SRCH", conn, op );
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static ID_BLOCK *
|
|
||||||
base_candidate(
|
|
||||||
Backend *be,
|
|
||||||
Entry *e
|
|
||||||
)
|
|
||||||
{
|
|
||||||
ID_BLOCK *idl;
|
|
||||||
|
|
||||||
Debug(LDAP_DEBUG_TRACE, "base_candidates: base: \"%s\"\n",
|
|
||||||
e->e_dn, 0, 0);
|
|
||||||
|
|
||||||
idl = bdb2i_idl_alloc( 1 );
|
|
||||||
bdb2i_idl_insert( &idl, e->e_id, 1 );
|
|
||||||
|
|
||||||
return( idl );
|
|
||||||
}
|
|
||||||
|
|
||||||
static ID_BLOCK *
|
|
||||||
search_candidates(
|
|
||||||
Backend *be,
|
|
||||||
Entry *e,
|
|
||||||
Filter *filter,
|
|
||||||
int scope,
|
|
||||||
int deref,
|
|
||||||
int manageDSAit
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
ID_BLOCK *candidates;
|
|
||||||
Filter *f, *rf, *af, *lf;
|
|
||||||
|
|
||||||
Debug(LDAP_DEBUG_TRACE, "search_candidates: base=\"%s\" s=%d d=%d\n",
|
|
||||||
e->e_ndn, scope, deref );
|
|
||||||
|
|
||||||
f = NULL;
|
|
||||||
|
|
||||||
if( !manageDSAit ) {
|
|
||||||
/* match referrals */
|
|
||||||
rf = (Filter *) ch_malloc( sizeof(Filter) );
|
|
||||||
rf->f_next = NULL;
|
|
||||||
rf->f_choice = LDAP_FILTER_OR;
|
|
||||||
rf->f_or = (Filter *) ch_malloc( sizeof(Filter) );
|
|
||||||
rf->f_or->f_choice = LDAP_FILTER_EQUALITY;
|
|
||||||
rf->f_or->f_avtype = ch_strdup( "objectclass" );
|
|
||||||
rf->f_or->f_avvalue.bv_val = ch_strdup( "REFERRAL" );
|
|
||||||
rf->f_or->f_avvalue.bv_len = sizeof("REFERRAL")-1;
|
|
||||||
rf->f_or->f_next = filter;
|
|
||||||
f = rf;
|
|
||||||
} else {
|
|
||||||
rf = NULL;
|
|
||||||
f = filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( deref & LDAP_DEREF_SEARCHING ) {
|
|
||||||
/* match aliases */
|
|
||||||
af = (Filter *) ch_malloc( sizeof(Filter) );
|
|
||||||
af->f_next = NULL;
|
|
||||||
af->f_choice = LDAP_FILTER_OR;
|
|
||||||
af->f_or = (Filter *) ch_malloc( sizeof(Filter) );
|
|
||||||
af->f_or->f_choice = LDAP_FILTER_EQUALITY;
|
|
||||||
af->f_or->f_avtype = ch_strdup( "objectclass" );
|
|
||||||
af->f_or->f_avvalue.bv_val = ch_strdup( "ALIAS" );
|
|
||||||
af->f_or->f_avvalue.bv_len = sizeof("ALIAS")-1;
|
|
||||||
af->f_or->f_next = f;
|
|
||||||
f = af;
|
|
||||||
} else {
|
|
||||||
af = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( scope == LDAP_SCOPE_SUBTREE ) {
|
|
||||||
lf = (Filter *) ch_malloc( sizeof(Filter) );
|
|
||||||
lf->f_next = NULL;
|
|
||||||
lf->f_choice = LDAP_FILTER_AND;
|
|
||||||
lf->f_and = (Filter *) ch_malloc( sizeof(Filter) );
|
|
||||||
|
|
||||||
lf->f_and->f_choice = SLAPD_FILTER_DN_SUBTREE;
|
|
||||||
lf->f_and->f_dn = e->e_ndn;
|
|
||||||
|
|
||||||
lf->f_and->f_next = f;
|
|
||||||
f = lf;
|
|
||||||
|
|
||||||
} else if ( scope == LDAP_SCOPE_ONELEVEL ) {
|
|
||||||
lf = (Filter *) ch_malloc( sizeof(Filter) );
|
|
||||||
lf->f_next = NULL;
|
|
||||||
lf->f_choice = LDAP_FILTER_AND;
|
|
||||||
lf->f_and = (Filter *) ch_malloc( sizeof(Filter) );
|
|
||||||
|
|
||||||
lf->f_and->f_choice = SLAPD_FILTER_DN_ONE;
|
|
||||||
lf->f_and->f_dn = e->e_ndn;
|
|
||||||
|
|
||||||
lf->f_and->f_next = f;
|
|
||||||
f = lf;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
lf = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
candidates = bdb2i_filter_candidates( be, f );
|
|
||||||
|
|
||||||
/* free up filter additions we allocated above */
|
|
||||||
if( lf != NULL ) {
|
|
||||||
free( lf->f_and );
|
|
||||||
free( lf );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( af != NULL ) {
|
|
||||||
af->f_or->f_next = NULL;
|
|
||||||
filter_free( af );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( rf != NULL ) {
|
|
||||||
rf->f_or->f_next = NULL;
|
|
||||||
filter_free( rf );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( candidates );
|
|
||||||
}
|
|
||||||
|
|
@ -1,260 +0,0 @@
|
||||||
/* startup.c - startup/shutdown bdb2 backend */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/string.h>
|
|
||||||
#include <ac/socket.h>
|
|
||||||
#include <ac/unistd.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_PARAM_H
|
|
||||||
#include <sys/param.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_DIRECT_H
|
|
||||||
#include <direct.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
|
|
||||||
#include "db.h"
|
|
||||||
|
|
||||||
static void remove_old_locks( char *home );
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
bdb2i_db_errcall( const char *prefix, char *message )
|
|
||||||
{
|
|
||||||
Debug( LDAP_DEBUG_ANY, "bdb2_db_errcall(): %s %s", prefix, message, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* startup/shutdown per backend type */
|
|
||||||
|
|
||||||
static int
|
|
||||||
bdb2i_back_startup_internal(
|
|
||||||
BackendInfo *bi
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ldbtype *lty = (struct ldbtype *) bi->bi_private;
|
|
||||||
u_int32_t envFlags;
|
|
||||||
int err = 0;
|
|
||||||
char *home;
|
|
||||||
|
|
||||||
/* set the flags for a full-feldged transaction schema */
|
|
||||||
envFlags = ( DB_CREATE | DB_THREAD | DB_INIT_TXN | DB_INIT_LOG |
|
|
||||||
DB_INIT_LOCK | DB_INIT_MPOOL );
|
|
||||||
|
|
||||||
/* make sure, dbhome is an absolute path */
|
|
||||||
if ( *lty->lty_dbhome != *LDAP_DIRSEP ) {
|
|
||||||
char cwd[MAXPATHLEN];
|
|
||||||
|
|
||||||
(void) getcwd( cwd, MAXPATHLEN );
|
|
||||||
sprintf( cwd, "%s" LDAP_DIRSEP "%s",
|
|
||||||
cwd, lty->lty_dbhome );
|
|
||||||
free( lty->lty_dbhome );
|
|
||||||
lty->lty_dbhome = ch_strdup( cwd );
|
|
||||||
|
|
||||||
}
|
|
||||||
home = lty->lty_dbhome;
|
|
||||||
|
|
||||||
/* general initialization of the environment */
|
|
||||||
memset( &bdb2i_dbEnv, 0, sizeof( DB_ENV ));
|
|
||||||
bdb2i_dbEnv.db_errcall = bdb2i_db_errcall;
|
|
||||||
bdb2i_dbEnv.db_errpfx = "==>";
|
|
||||||
|
|
||||||
/* initialize the lock subsystem */
|
|
||||||
bdb2i_dbEnv.lk_max = 0;
|
|
||||||
|
|
||||||
/* remove old locking tables */
|
|
||||||
remove_old_locks( home );
|
|
||||||
|
|
||||||
/* initialize the mpool subsystem */
|
|
||||||
bdb2i_dbEnv.mp_size = lty->lty_mpsize;
|
|
||||||
|
|
||||||
/* now do the db_appinit */
|
|
||||||
if ( ( err = db_appinit( home, NULL, &bdb2i_dbEnv, envFlags )) ) {
|
|
||||||
char error[BUFSIZ];
|
|
||||||
|
|
||||||
if ( err < 0 ) sprintf( error, "%ld\n", (long) err );
|
|
||||||
else sprintf( error, "%s\n", strerror( err ));
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_back_startup(): FATAL error in db_appinit() : %s\n",
|
|
||||||
error, 0, 0 );
|
|
||||||
return( 1 );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
bdb2i_back_shutdown_internal(
|
|
||||||
BackendInfo *bi
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ldbtype *lty = (struct ldbtype *) bi->bi_private;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
/* remove old locking tables */
|
|
||||||
bdb2i_dbEnv.db_errpfx = "bdb2i_back_shutdown(): lock_unlink:";
|
|
||||||
if ( ( err = lock_unlink( NULL, 1, &bdb2i_dbEnv )) != 0 )
|
|
||||||
Debug( LDAP_DEBUG_ANY, "bdb2i_back_shutdown(): lock_unlink: %s\n",
|
|
||||||
strerror( err ), 0, 0);
|
|
||||||
|
|
||||||
/* remove old memory pool */
|
|
||||||
bdb2i_dbEnv.db_errpfx = "bdb2i_back_shutdown(): memp_unlink:";
|
|
||||||
if ( ( err = memp_unlink( NULL, 1, &bdb2i_dbEnv )) != 0 )
|
|
||||||
Debug( LDAP_DEBUG_ANY, "bdb2i_back_shutdown(): memp_unlink: %s\n",
|
|
||||||
strerror( err ), 0, 0);
|
|
||||||
|
|
||||||
(void) db_appexit( &bdb2i_dbEnv );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_back_startup(
|
|
||||||
BackendInfo *bi
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct timeval time1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
bdb2i_start_timing( bi, &time1 );
|
|
||||||
|
|
||||||
ret = bdb2i_back_startup_internal( bi );
|
|
||||||
bdb2i_stop_timing( bi, time1, "BE-START", NULL, NULL );
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_back_shutdown(
|
|
||||||
BackendInfo *bi
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct timeval time1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
bdb2i_start_timing( bi, &time1 );
|
|
||||||
|
|
||||||
ret = bdb2i_back_shutdown_internal( bi );
|
|
||||||
bdb2i_stop_timing( bi, time1, "BE-SHUTDOWN", NULL, NULL );
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* startup/shutdown per backend database */
|
|
||||||
|
|
||||||
static int
|
|
||||||
bdb2i_back_db_startup_internal(
|
|
||||||
BackendDB *be
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
|
|
||||||
/* if the data directory is not an absolute path, have it relative
|
|
||||||
to the current working directory (which should not be configured !) */
|
|
||||||
if ( *li->li_directory != *LDAP_DIRSEP ) {
|
|
||||||
char cwd[MAXPATHLEN];
|
|
||||||
|
|
||||||
(void) getcwd( cwd, MAXPATHLEN );
|
|
||||||
sprintf( cwd, "%s" LDAP_DIRSEP "%s",
|
|
||||||
cwd, li->li_directory );
|
|
||||||
|
|
||||||
free( li->li_directory );
|
|
||||||
li->li_directory = ch_strdup( cwd );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if there are more index files, add them to the DB file list */
|
|
||||||
if ( bdb2i_check_additional_attr_index( li ) != 0 )
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* now open all DB files */
|
|
||||||
if ( bdb2i_txn_open_files( be ) != 0 )
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
bdb2i_back_db_shutdown_internal(
|
|
||||||
BackendDB *be
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_db_startup(
|
|
||||||
BackendDB *be
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct timeval time1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
bdb2i_start_timing( be->bd_info, &time1 );
|
|
||||||
|
|
||||||
ret = bdb2i_back_db_startup_internal( be );
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "DB-START", NULL, NULL );
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_db_shutdown(
|
|
||||||
BackendDB *be
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct timeval time1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
bdb2i_start_timing( be->bd_info, &time1 );
|
|
||||||
|
|
||||||
ret = bdb2i_back_db_shutdown_internal( be );
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "DB-SHUTDOWN", NULL, NULL );
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
remove_old_locks( char *home )
|
|
||||||
{
|
|
||||||
DB_ENV dbEnv;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
memset( &dbEnv, 0, sizeof( DB_ENV ));
|
|
||||||
dbEnv.db_errcall = bdb2i_db_errcall;
|
|
||||||
dbEnv.db_errpfx = "remove_old_locks(): db_appinit:";
|
|
||||||
dbEnv.lk_max = 0;
|
|
||||||
|
|
||||||
if ( ( err = db_appinit( home, NULL, &dbEnv, 0 )) != 0 )
|
|
||||||
Debug( LDAP_DEBUG_ANY, "remove_old_locks(): db_appinit: %s\n",
|
|
||||||
strerror( err ), 0, 0);
|
|
||||||
|
|
||||||
dbEnv.db_errpfx = "remove_old_locks(): lock_unlink:";
|
|
||||||
if ( ( err = lock_unlink( NULL, 1, &dbEnv )) != 0 )
|
|
||||||
Debug( LDAP_DEBUG_ANY, "remove_old_locks(): lock_unlink: %s\n",
|
|
||||||
strerror( err ), 0, 0);
|
|
||||||
|
|
||||||
dbEnv.db_errpfx = "remove_old_locks(): db_appexit:";
|
|
||||||
if ( ( err = db_appexit( &dbEnv )) != 0 )
|
|
||||||
Debug( LDAP_DEBUG_ANY, "remove_old_locks(): db_appexit: %s\n",
|
|
||||||
strerror( err ), 0, 0);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
||||||
/* timing.c - timing bdb2 backend */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/string.h>
|
|
||||||
#include <ac/time.h>
|
|
||||||
#include <ac/unistd.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
|
|
||||||
|
|
||||||
static char *
|
|
||||||
bdb2i_elapsed( struct timeval firsttime, struct timeval secondtime )
|
|
||||||
{
|
|
||||||
long int elapsedmicrosec, elapsedsec;
|
|
||||||
char elapsed_string[BUFSIZ];
|
|
||||||
|
|
||||||
elapsedsec = secondtime.tv_sec - firsttime.tv_sec;
|
|
||||||
elapsedmicrosec = secondtime.tv_usec - firsttime.tv_usec;
|
|
||||||
if(elapsedmicrosec < 0) {
|
|
||||||
elapsedmicrosec += 1000000;
|
|
||||||
elapsedsec -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf( elapsed_string, "%ld.%.6ld", elapsedsec, elapsedmicrosec );
|
|
||||||
return( ch_strdup( elapsed_string ));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
bdb2i_uncond_start_timing(
|
|
||||||
struct timeval *time1
|
|
||||||
)
|
|
||||||
{
|
|
||||||
gettimeofday( time1, NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
bdb2i_uncond_stop_timing(
|
|
||||||
struct timeval time1,
|
|
||||||
char *func,
|
|
||||||
Connection *conn,
|
|
||||||
Operation *op,
|
|
||||||
int level
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct timeval time2;
|
|
||||||
char *elapsed_time;
|
|
||||||
char buf[BUFSIZ];
|
|
||||||
|
|
||||||
*buf = '\0';
|
|
||||||
|
|
||||||
gettimeofday( &time2, NULL);
|
|
||||||
elapsed_time = bdb2i_elapsed( time1, time2 );
|
|
||||||
|
|
||||||
if ( conn != NULL ) sprintf( buf, "conn=%d ", conn->c_connid );
|
|
||||||
if ( op != NULL ) sprintf( buf, "%sop=%d ", buf, op->o_opid );
|
|
||||||
|
|
||||||
Debug( level, "%s%s elapsed=%s\n", buf, func, elapsed_time );
|
|
||||||
|
|
||||||
free( elapsed_time );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,246 +0,0 @@
|
||||||
/* tools.c - tools for slap tools */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
/*
|
|
||||||
* Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
|
|
||||||
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <ac/string.h>
|
|
||||||
#include <ac/socket.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
|
|
||||||
static LDBMCursor *cursorp = NULL;
|
|
||||||
static DBCache *id2entry = NULL;
|
|
||||||
|
|
||||||
int bdb2_tool_entry_open(
|
|
||||||
BackendDB *be, int mode )
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
int flags;
|
|
||||||
|
|
||||||
assert( slapMode & SLAP_TOOL_MODE );
|
|
||||||
assert( id2entry == NULL );
|
|
||||||
|
|
||||||
switch( mode ) {
|
|
||||||
case 1:
|
|
||||||
flags = LDBM_WRCREAT;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
#ifdef TRUNCATE_MODE
|
|
||||||
flags = LDBM_NEWDB;
|
|
||||||
#else
|
|
||||||
flags = LDBM_WRCREAT;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
flags = LDBM_READER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (id2entry = bdb2i_cache_open( be, "id2entry", BDB2_SUFFIX, flags ))
|
|
||||||
== NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY, "Could not open/create id2entry" BDB2_SUFFIX "\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bdb2_tool_entry_close(
|
|
||||||
BackendDB *be )
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
|
|
||||||
assert( slapMode & SLAP_TOOL_MODE );
|
|
||||||
assert( id2entry != NULL );
|
|
||||||
|
|
||||||
bdb2i_cache_close( be, id2entry );
|
|
||||||
id2entry = NULL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ID bdb2_tool_entry_first(
|
|
||||||
BackendDB *be )
|
|
||||||
{
|
|
||||||
Datum key;
|
|
||||||
ID id;
|
|
||||||
|
|
||||||
assert( slapMode & SLAP_TOOL_MODE );
|
|
||||||
assert( id2entry != NULL );
|
|
||||||
|
|
||||||
key = ldbm_firstkey( id2entry->dbc_db, &cursorp );
|
|
||||||
|
|
||||||
if( key.dptr == NULL ) {
|
|
||||||
return NOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy( &id, key.dptr, key.dsize );
|
|
||||||
|
|
||||||
ldbm_datum_free( id2entry->dbc_db, key );
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
ID bdb2_tool_entry_next(
|
|
||||||
BackendDB *be )
|
|
||||||
{
|
|
||||||
Datum key;
|
|
||||||
ID id;
|
|
||||||
|
|
||||||
assert( slapMode & SLAP_TOOL_MODE );
|
|
||||||
assert( id2entry != NULL );
|
|
||||||
|
|
||||||
/* allow for NEXTID */
|
|
||||||
ldbm_datum_init( key );
|
|
||||||
|
|
||||||
key = ldbm_nextkey( id2entry->dbc_db, key, cursorp );
|
|
||||||
|
|
||||||
if( key.dptr == NULL ) {
|
|
||||||
return NOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy( &id, key.dptr, key.dsize );
|
|
||||||
|
|
||||||
ldbm_datum_free( id2entry->dbc_db, key );
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
Entry* bdb2_tool_entry_get( BackendDB *be, ID id )
|
|
||||||
{
|
|
||||||
Entry *e;
|
|
||||||
Datum key, data;
|
|
||||||
assert( slapMode & SLAP_TOOL_MODE );
|
|
||||||
assert( id2entry != NULL );
|
|
||||||
|
|
||||||
ldbm_datum_init( key );
|
|
||||||
|
|
||||||
key.dptr = (char *) &id;
|
|
||||||
key.dsize = sizeof(ID);
|
|
||||||
|
|
||||||
data = bdb2i_cache_fetch( id2entry, key );
|
|
||||||
|
|
||||||
if ( data.dptr == NULL ) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
e = str2entry( data.dptr );
|
|
||||||
ldbm_datum_free( id2entry->dbc_db, data );
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
ID bdb2_tool_entry_put(
|
|
||||||
BackendDB *be,
|
|
||||||
Entry *e )
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
Datum key, data;
|
|
||||||
int rc, len;
|
|
||||||
|
|
||||||
assert( slapMode & SLAP_TOOL_MODE );
|
|
||||||
assert( id2entry != NULL );
|
|
||||||
|
|
||||||
if( bdb2i_next_id_get( be ) == NOID ) {
|
|
||||||
return NOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
e->e_id = li->li_nextid++;
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "=> bdb2_tool_entry_put( %ld, \"%s\" )\n",
|
|
||||||
e->e_id, e->e_dn, 0 );
|
|
||||||
|
|
||||||
rc = bdb2i_index_add_entry( be, e );
|
|
||||||
|
|
||||||
if( rc != 0 ) {
|
|
||||||
return NOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = bdb2i_dn2id_add( be, e->e_ndn, e->e_id );
|
|
||||||
|
|
||||||
if( rc != 0 ) {
|
|
||||||
return NOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
ldbm_datum_init( key );
|
|
||||||
ldbm_datum_init( data );
|
|
||||||
|
|
||||||
key.dptr = (char *) &e->e_id;
|
|
||||||
key.dsize = sizeof(ID);
|
|
||||||
|
|
||||||
data.dptr = entry2str( e, &len );
|
|
||||||
data.dsize = len + 1;
|
|
||||||
|
|
||||||
/* store it */
|
|
||||||
rc = bdb2i_cache_store( id2entry, key, data, LDBM_REPLACE );
|
|
||||||
|
|
||||||
if( rc != 0 ) {
|
|
||||||
(void) bdb2i_dn2id_delete( be, e->e_ndn, e->e_id );
|
|
||||||
return NOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
return e->e_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bdb2_tool_index_attr(
|
|
||||||
BackendDB *be,
|
|
||||||
char* type )
|
|
||||||
{
|
|
||||||
static DBCache *db = NULL;
|
|
||||||
int indexmask, syntaxmask;
|
|
||||||
char * at_cn;
|
|
||||||
|
|
||||||
assert( slapMode & SLAP_TOOL_MODE );
|
|
||||||
|
|
||||||
bdb2i_attr_masks( be->be_private, type, &indexmask, &syntaxmask );
|
|
||||||
|
|
||||||
attr_normalize( type );
|
|
||||||
at_cn = at_canonical_name( type );
|
|
||||||
|
|
||||||
if ( (db = bdb2i_cache_open( be, at_cn, LDBM_SUFFIX, LDBM_NEWDB ))
|
|
||||||
== NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"<= index_read NULL (could not open %s%s)\n", at_cn,
|
|
||||||
BDB2_SUFFIX, 0 );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bdb2i_cache_close( be, db );
|
|
||||||
|
|
||||||
return indexmask != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bdb2_tool_index_change(
|
|
||||||
BackendDB *be,
|
|
||||||
char* type,
|
|
||||||
struct berval **bv,
|
|
||||||
ID id,
|
|
||||||
int op )
|
|
||||||
{
|
|
||||||
assert( slapMode & SLAP_TOOL_MODE );
|
|
||||||
|
|
||||||
bdb2i_index_add_values( be,
|
|
||||||
type, bv, id );
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bdb2_tool_sync( BackendDB *be )
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
|
|
||||||
assert( slapMode & SLAP_TOOL_MODE );
|
|
||||||
|
|
||||||
if ( li->li_nextid != NOID ) {
|
|
||||||
bdb2i_next_id_save( be );
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,823 +0,0 @@
|
||||||
/* txn.c - TP support functions of the bdb2 backend */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_PARAM_H
|
|
||||||
#include <sys/param.h>
|
|
||||||
#endif
|
|
||||||
#include "txn.h"
|
|
||||||
|
|
||||||
/* default DB files */
|
|
||||||
char *bdb2i_fixed_filenames[] = {
|
|
||||||
"id2entry",
|
|
||||||
"dn2id",
|
|
||||||
"objectclass",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_txn_head_init( BDB2_TXN_HEAD *head )
|
|
||||||
{
|
|
||||||
int dbFile;
|
|
||||||
BDB2_TXN_FILES **fileNodeH;
|
|
||||||
|
|
||||||
/* for each fixed DB file allocate a file descriptor node and
|
|
||||||
initialize the file's name */
|
|
||||||
fileNodeH = &head->dbFiles;
|
|
||||||
|
|
||||||
for ( dbFile = 0; bdb2i_fixed_filenames[dbFile] != NULL; dbFile++ ) {
|
|
||||||
char fileName[MAXPATHLEN];
|
|
||||||
|
|
||||||
*fileNodeH = (BDB2_TXN_FILES *) ch_calloc( 1, sizeof( BDB2_TXN_FILES ));
|
|
||||||
|
|
||||||
if ( *fileNodeH == NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY, "bdb2i_txn_head_init(): out of memory!\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
return( 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf( fileName, "%s" BDB2_SUFFIX, bdb2i_fixed_filenames[dbFile] );
|
|
||||||
(*fileNodeH)->dbc_name = ch_strdup( fileName );
|
|
||||||
|
|
||||||
fileNodeH = &(*fileNodeH)->next;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set defaults for checkpointing */
|
|
||||||
head->txn_log = BDB2_TXN_CHKP_MAX_LOG;
|
|
||||||
head->txn_time = BDB2_TXN_CHKP_MAX_TIME;
|
|
||||||
|
|
||||||
/* initialize the txn_dirty_mutex */
|
|
||||||
ldap_pvt_thread_mutex_init( &txn_dirty_mutex );
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
bdb2i_init_db_file_cache( struct ldbminfo *li, BDB2_TXN_FILES *fileinfo )
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
char buf[MAXPATHLEN];
|
|
||||||
|
|
||||||
fileinfo->dbc_refcnt = 1;
|
|
||||||
|
|
||||||
sprintf( buf, "%s" LDAP_DIRSEP "%s",
|
|
||||||
li->li_directory, fileinfo->dbc_name );
|
|
||||||
|
|
||||||
if ( stat( buf, &st ) == 0 ) {
|
|
||||||
fileinfo->dbc_blksize = st.st_blksize;
|
|
||||||
} else {
|
|
||||||
fileinfo->dbc_blksize = DEFAULT_BLOCKSIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
fileinfo->dbc_maxids = ( fileinfo->dbc_blksize / sizeof( ID )) -
|
|
||||||
ID_BLOCK_IDS_OFFSET;
|
|
||||||
fileinfo->dbc_maxindirect = ( SLAPD_LDBM_MIN_MAXIDS /
|
|
||||||
fileinfo->dbc_maxids ) + 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* create a DB file cache entry for a specified index attribute
|
|
||||||
(if not already done); the function is called during config
|
|
||||||
file read for all index'ed attributes; if "default" index with
|
|
||||||
a non-none selection is given, this is remembered for run-time
|
|
||||||
extension of the list of index files; the function is also
|
|
||||||
called before add or modify operations to check for putative
|
|
||||||
new "default" index files; at that time, files are also opened
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
bdb2i_txn_attr_config(
|
|
||||||
struct ldbminfo *li,
|
|
||||||
char *attr,
|
|
||||||
int open )
|
|
||||||
{
|
|
||||||
BDB2_TXN_HEAD *head = &li->li_txn_head;
|
|
||||||
|
|
||||||
/* the "attribute" 'default' is special */
|
|
||||||
if ( strcasecmp( attr, "default" )) {
|
|
||||||
|
|
||||||
/* create a new index file node, if the index is not known already */
|
|
||||||
BDB2_TXN_FILES **fileNodeH;
|
|
||||||
char fileName[MAXPATHLEN];
|
|
||||||
|
|
||||||
sprintf( fileName, "%s%s", attr, BDB2_SUFFIX );
|
|
||||||
|
|
||||||
/* search for the end of the list or a node describing
|
|
||||||
the current attribute */
|
|
||||||
for ( fileNodeH = &head->dbFiles;
|
|
||||||
( *fileNodeH && strcasecmp( (*fileNodeH)->dbc_name, fileName ));
|
|
||||||
fileNodeH = &(*fileNodeH)->next ) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* unless we have that attribute already... */
|
|
||||||
if ( *fileNodeH == NULL ) {
|
|
||||||
BDB2_TXN_FILES *p;
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"bdb2i_txn_attr_config(): adding node for \"%s\"\n",
|
|
||||||
fileName, 0, 0 );
|
|
||||||
|
|
||||||
/* if we're out of memory, we have to see, how to exit... */
|
|
||||||
if ( ( *fileNodeH = p = (BDB2_TXN_FILES *)
|
|
||||||
ch_calloc( 1, sizeof( BDB2_TXN_FILES )) ) == NULL ) {
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_txn_attr_config(): out of memory -- FATAL.\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
|
|
||||||
/* during configuration (no files are opened)
|
|
||||||
we can just exit, otherwise we kill ourself and
|
|
||||||
hope to shutdown cleanly... */
|
|
||||||
if ( open ) {
|
|
||||||
pthread_kill( pthread_self(), LDAP_SIGUSR1 );
|
|
||||||
} else {
|
|
||||||
exit( EXIT_FAILURE );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p->dbc_name = ch_strdup( fileName );
|
|
||||||
|
|
||||||
/* if requested for, we have to open the DB file */
|
|
||||||
/* BUT NOT "objectclass", 'cause that's a default index ! */
|
|
||||||
if ( open && strcasecmp( fileName, "objectclass" )) {
|
|
||||||
|
|
||||||
/* re-use filename to get the complete path */
|
|
||||||
sprintf( fileName, "%s" LDAP_DIRSEP "%s",
|
|
||||||
li->li_directory, p->dbc_name );
|
|
||||||
|
|
||||||
/* since we have an mpool, we should not define a cache size */
|
|
||||||
p->dbc_db = bdb2i_db_open( fileName, DB_TYPE,
|
|
||||||
LDBM_WRCREAT, li->li_mode, 0 );
|
|
||||||
|
|
||||||
/* if the files could not be opened, something is wrong;
|
|
||||||
complain */
|
|
||||||
if ( p->dbc_db == NULL ) {
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_txn_open_files(): couldn't open file \"%s\" -- FATAL.\n",
|
|
||||||
p->dbc_name, 0, 0 );
|
|
||||||
pthread_kill( pthread_self(), LDAP_SIGUSR1 );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bdb2i_init_db_file_cache( li, p );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"bdb2i_txn_attr_config(): NEW INDEX FILE \"%s\"\n",
|
|
||||||
p->dbc_name, 0, 0 );
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else { /* it is "attribute" 'default' */
|
|
||||||
|
|
||||||
head->withDefIDX = BDB2_WITH_DEF_IDX;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* open the NEXTID file for read/write; if it does not exist,
|
|
||||||
create it (access to the file must be preceeded by a rewind)
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
bdb2i_open_nextid( BackendDB *be )
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
BDB2_TXN_HEAD *head = &li->li_txn_head;
|
|
||||||
LDBM db = NULL;
|
|
||||||
DB_INFO dbinfo;
|
|
||||||
char fileName[MAXPATHLEN];
|
|
||||||
|
|
||||||
sprintf( fileName, "%s" LDAP_DIRSEP "%s",
|
|
||||||
li->li_directory, NEXTID_NAME );
|
|
||||||
|
|
||||||
/* try to open the file for read and write */
|
|
||||||
memset( &dbinfo, 0, sizeof( dbinfo ));
|
|
||||||
dbinfo.db_pagesize = DEFAULT_DB_PAGE_SIZE;
|
|
||||||
dbinfo.db_malloc = ldbm_malloc;
|
|
||||||
|
|
||||||
(void) db_open( fileName, DB_RECNO, DB_CREATE | DB_THREAD,
|
|
||||||
li->li_mode, &bdb2i_dbEnv, &dbinfo, &db );
|
|
||||||
|
|
||||||
if ( db == NULL ) {
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_open_nextid: could not open \"%s\"\n",
|
|
||||||
NEXTID_NAME, 0, 0 );
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the file is open for read/write */
|
|
||||||
head->nextidFile = db;
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* open all DB during startup of the backend (necessary due to TP)
|
|
||||||
additional files may be opened during slapd life-time due to
|
|
||||||
default indexes (must be configured in slapd.conf;
|
|
||||||
see bdb2i_txn_attr_config)
|
|
||||||
also, set the counter and timer for TP checkpointing
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
bdb2i_txn_open_files( BackendDB *be )
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
BDB2_TXN_HEAD *head = &li->li_txn_head;
|
|
||||||
BDB2_TXN_FILES *dbFile;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
for ( dbFile = head->dbFiles; dbFile; dbFile = dbFile->next ) {
|
|
||||||
char fileName[MAXPATHLEN];
|
|
||||||
|
|
||||||
sprintf( fileName, "%s" LDAP_DIRSEP "%s",
|
|
||||||
li->li_directory, dbFile->dbc_name );
|
|
||||||
|
|
||||||
/* since we have an mpool, we should not define a cache size */
|
|
||||||
dbFile->dbc_db = bdb2i_db_open( fileName, DB_TYPE,
|
|
||||||
LDBM_WRCREAT, li->li_mode, 0 );
|
|
||||||
|
|
||||||
/* if the files could not be opened, something is wrong; complain */
|
|
||||||
if ( dbFile->dbc_db == NULL ) {
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_txn_open_files(): couldn't open file \"%s\" -- FATAL.\n",
|
|
||||||
dbFile->dbc_name, 0, 0 );
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize the file info */
|
|
||||||
bdb2i_init_db_file_cache( li, dbFile );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "bdb2i_txn_open_files(): OPEN INDEX \"%s\"\n",
|
|
||||||
dbFile->dbc_name, 0, 0 );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = bdb2i_open_nextid( be );
|
|
||||||
|
|
||||||
txn_max_pending_log = head->txn_log;
|
|
||||||
txn_max_pending_time = head->txn_time;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* close all DB files during shutdown of the backend */
|
|
||||||
void
|
|
||||||
bdb2i_txn_close_files( BackendDB *be )
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
BDB2_TXN_HEAD *head = &li->li_txn_head;
|
|
||||||
BDB2_TXN_FILES *dbFile;
|
|
||||||
|
|
||||||
for ( dbFile = head->dbFiles; dbFile; dbFile = dbFile->next ) {
|
|
||||||
|
|
||||||
ldbm_close( dbFile->dbc_db );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( head->nextidFile )
|
|
||||||
ldbm_close( head->nextidFile );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* get the db_cache structure associated with a specified
|
|
||||||
DB file (replaces the on-the-fly opening of files in cache_open()
|
|
||||||
*/
|
|
||||||
BDB2_TXN_FILES *
|
|
||||||
bdb2i_get_db_file_cache( struct ldbminfo *li, char *name )
|
|
||||||
{
|
|
||||||
BDB2_TXN_HEAD *head = &li->li_txn_head;
|
|
||||||
BDB2_TXN_FILES *dbFile;
|
|
||||||
int dbFileNum;
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "bdb2i_get_db_file_cache(): looking for file %s\n",
|
|
||||||
name, 0, 0 );
|
|
||||||
|
|
||||||
for ( dbFile = head->dbFiles; dbFile; dbFile = dbFile->next ) {
|
|
||||||
|
|
||||||
/* we've got it */
|
|
||||||
if ( !strcasecmp( dbFile->dbc_name, name )) return( dbFile );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_get_db_file_cache(): UPS, could't find \"%s\" \n", name, 0, 0 );
|
|
||||||
|
|
||||||
/* ups, we couldn't find the file */
|
|
||||||
return( NULL );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* check for new attribute indexes, that might have been created
|
|
||||||
during former runs of slapd */
|
|
||||||
/* this is called during startup of the slapd server */
|
|
||||||
int
|
|
||||||
bdb2i_check_additional_attr_index( struct ldbminfo *li )
|
|
||||||
{
|
|
||||||
DIR *datadir;
|
|
||||||
struct dirent *file;
|
|
||||||
|
|
||||||
if ( ( datadir = opendir( li->li_directory ) ) == NULL ) {
|
|
||||||
int err = errno;
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_check_additional_attr_index(): ERROR while opening datadir: %s\n",
|
|
||||||
strerror( err ), 0, 0 );
|
|
||||||
return( 1 );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( file = readdir( datadir ); file; file = readdir( datadir )) {
|
|
||||||
char filename[MAXPATHLEN];
|
|
||||||
int namelen;
|
|
||||||
|
|
||||||
strcpy( filename, file->d_name );
|
|
||||||
namelen = strlen( filename );
|
|
||||||
|
|
||||||
if ( namelen > strlen( BDB2_SUFFIX )) {
|
|
||||||
|
|
||||||
if ( !strcasecmp( filename + namelen - strlen( BDB2_SUFFIX ),
|
|
||||||
BDB2_SUFFIX )) {
|
|
||||||
|
|
||||||
*(filename + namelen - strlen( BDB2_SUFFIX )) = '\0';
|
|
||||||
bdb2i_txn_attr_config( li, filename, 0 );
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "INDEX FILE: %s\n", filename, 0, 0 );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
closedir( datadir );
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* check for the addition of new attribute indexes during add */
|
|
||||||
/* this is called after startup of the slapd server */
|
|
||||||
/* DON'T WORRY ABOUT ACCESS RIGHTS, THAT MIGHT PREVENT US
|
|
||||||
FROM ADDING ATTRIBUTES LATER ON */
|
|
||||||
void
|
|
||||||
bdb2i_check_default_attr_index_add( struct ldbminfo *li, Entry *e )
|
|
||||||
{
|
|
||||||
BDB2_TXN_HEAD *head = &li->li_txn_head;
|
|
||||||
|
|
||||||
if ( head->withDefIDX == BDB2_WITH_DEF_IDX ) {
|
|
||||||
Attribute *ap;
|
|
||||||
|
|
||||||
for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) {
|
|
||||||
if ( strcasecmp( ap->a_type, "objectclass" ))
|
|
||||||
bdb2i_txn_attr_config( li, ap->a_type, 1 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* check for the addition of new attribute indexes during modify */
|
|
||||||
/* this is called after startup of the slapd server */
|
|
||||||
/* DON'T WORRY ABOUT ACCESS RIGHTS, THAT MIGHT PREVENT US
|
|
||||||
FROM ADDING ATTRIBUTES LATER ON */
|
|
||||||
void
|
|
||||||
bdb2i_check_default_attr_index_mod( struct ldbminfo *li, LDAPModList *modlist )
|
|
||||||
{
|
|
||||||
BDB2_TXN_HEAD *head = &li->li_txn_head;
|
|
||||||
|
|
||||||
if ( head->withDefIDX == BDB2_WITH_DEF_IDX ) {
|
|
||||||
LDAPModList *ml;
|
|
||||||
char *default_attrs[] = { "modifytimestamp", "modifiersname", NULL };
|
|
||||||
int attr;
|
|
||||||
|
|
||||||
for ( ml = modlist; ml != NULL; ml = ml->ml_next ) {
|
|
||||||
LDAPMod *mod = &ml->ml_mod;
|
|
||||||
|
|
||||||
if (( mod->mod_op & ~LDAP_MOD_BVALUES ) == LDAP_MOD_ADD )
|
|
||||||
if ( strcasecmp( mod->mod_type, "objectclass" ))
|
|
||||||
bdb2i_txn_attr_config( li, mod->mod_type, 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* these attributes are default when modifying */
|
|
||||||
for ( attr = 0; default_attrs[attr]; attr++ ) {
|
|
||||||
bdb2i_txn_attr_config( li, default_attrs[attr], 1 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* get the next ID from the NEXTID file */
|
|
||||||
ID
|
|
||||||
bdb2i_get_nextid( BackendDB *be )
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
BDB2_TXN_HEAD *head = &li->li_txn_head;
|
|
||||||
ID id;
|
|
||||||
Datum key;
|
|
||||||
Datum data;
|
|
||||||
db_recno_t rec = NEXTID_RECNO;
|
|
||||||
|
|
||||||
ldbm_datum_init( key );
|
|
||||||
ldbm_datum_init( data );
|
|
||||||
|
|
||||||
key.data = &rec;
|
|
||||||
key.size = sizeof( rec );
|
|
||||||
|
|
||||||
data = bdb2i_db_fetch( head->nextidFile, key );
|
|
||||||
if ( data.data == NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"next_id_read: could not get nextid from \"%s\"\n",
|
|
||||||
NEXTID_NAME, 0, 0 );
|
|
||||||
return NOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
id = atol( data.data );
|
|
||||||
ldbm_datum_free( head->nextidFile, data );
|
|
||||||
|
|
||||||
if ( id < 1 ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"next_id_read %ld: return non-positive integer\n",
|
|
||||||
id, 0, 0 );
|
|
||||||
return NOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
return( id );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_put_nextid( BackendDB *be, ID id )
|
|
||||||
{
|
|
||||||
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
|
|
||||||
BDB2_TXN_HEAD *head = &li->li_txn_head;
|
|
||||||
int rc, flags;
|
|
||||||
Datum key;
|
|
||||||
Datum data;
|
|
||||||
db_recno_t rec = NEXTID_RECNO;
|
|
||||||
char buf[20];
|
|
||||||
|
|
||||||
sprintf( buf, "%ld\n", id );
|
|
||||||
|
|
||||||
ldbm_datum_init( key );
|
|
||||||
ldbm_datum_init( data );
|
|
||||||
|
|
||||||
key.data = &rec;
|
|
||||||
key.size = sizeof( rec );
|
|
||||||
|
|
||||||
data.data = &buf;
|
|
||||||
data.size = sizeof( buf );
|
|
||||||
|
|
||||||
flags = LDBM_REPLACE;
|
|
||||||
if (( rc = bdb2i_db_store( head->nextidFile, key, data, flags )) != 0 ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY, "next_id_write(%ld): store failed (%d)\n",
|
|
||||||
id, rc, 0 );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* BDB2 backend-private functions of libldbm */
|
|
||||||
LDBM
|
|
||||||
bdb2i_db_open(
|
|
||||||
char *name,
|
|
||||||
int type,
|
|
||||||
int rw,
|
|
||||||
int mode,
|
|
||||||
int dbcachesize )
|
|
||||||
{
|
|
||||||
LDBM ret = NULL;
|
|
||||||
DB_INFO dbinfo;
|
|
||||||
|
|
||||||
memset( &dbinfo, 0, sizeof( dbinfo ));
|
|
||||||
if ( bdb2i_dbEnv.mp_info == NULL )
|
|
||||||
dbinfo.db_cachesize = dbcachesize;
|
|
||||||
dbinfo.db_pagesize = DEFAULT_DB_PAGE_SIZE;
|
|
||||||
dbinfo.db_malloc = ldbm_malloc;
|
|
||||||
|
|
||||||
(void) db_open( name, type, rw, mode, &bdb2i_dbEnv, &dbinfo, &ret );
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_db_store( LDBM ldbm, Datum key, Datum data, int flags )
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = (*ldbm->put)( ldbm, txnid, &key, &data, flags );
|
|
||||||
rc = (-1 ) * rc;
|
|
||||||
|
|
||||||
if ( txnid != NULL ) {
|
|
||||||
|
|
||||||
/* if the store was OK, set the dirty flag,
|
|
||||||
otherwise set the abort flag */
|
|
||||||
if ( rc == 0 ) {
|
|
||||||
|
|
||||||
txn_dirty = 1;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_db_store: transaction failed: aborted.\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
txn_do_abort = 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2i_db_delete( LDBM ldbm, Datum key )
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = (*ldbm->del)( ldbm, txnid, &key, 0 );
|
|
||||||
rc = (-1 ) * rc;
|
|
||||||
|
|
||||||
if ( txnid != NULL ) {
|
|
||||||
|
|
||||||
/* if the delete was OK, set the dirty flag,
|
|
||||||
otherwise set the abort flag */
|
|
||||||
if ( rc == 0 ) {
|
|
||||||
|
|
||||||
txn_dirty = 1;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_db_delete: transaction failed: aborted.\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
txn_do_abort = 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Datum
|
|
||||||
bdb2i_db_fetch( LDBM ldbm, Datum key )
|
|
||||||
{
|
|
||||||
Datum data;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
ldbm_datum_init( data );
|
|
||||||
data.flags = DB_DBT_MALLOC;
|
|
||||||
|
|
||||||
if ( (rc = (*ldbm->get)( ldbm, txnid, &key, &data, 0 )) != 0 ) {
|
|
||||||
if (( txnid != NULL ) && ( rc != DB_NOTFOUND )) {
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_db_fetch: transaction failed: aborted.\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
txn_do_abort = 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
if ( data.dptr ) free( data.dptr );
|
|
||||||
data.dptr = NULL;
|
|
||||||
data.dsize = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return( data );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Datum
|
|
||||||
bdb2i_db_firstkey( LDBM ldbm, DBC **dbch )
|
|
||||||
{
|
|
||||||
Datum key, data;
|
|
||||||
int rc;
|
|
||||||
DBC *dbci;
|
|
||||||
|
|
||||||
ldbm_datum_init( key );
|
|
||||||
ldbm_datum_init( data );
|
|
||||||
|
|
||||||
key.flags = data.flags = DB_DBT_MALLOC;
|
|
||||||
|
|
||||||
#if defined( DB_VERSION_MAJOR ) && defined( DB_VERSION_MINOR ) && \
|
|
||||||
DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6
|
|
||||||
|
|
||||||
if ( (*ldbm->cursor)( ldbm, txnid, &dbci ))
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
if ( (*ldbm->cursor)( ldbm, txnid, &dbci, 0 ))
|
|
||||||
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
if ( txnid != NULL ) {
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_db_firstkey: transaction failed: aborted.\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
txn_do_abort = 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
key.flags = 0;
|
|
||||||
return( key );
|
|
||||||
} else {
|
|
||||||
*dbch = dbci;
|
|
||||||
if ( (*dbci->c_get)( dbci, &key, &data, DB_NEXT ) == 0 ) {
|
|
||||||
ldbm_datum_free( ldbm, data );
|
|
||||||
} else {
|
|
||||||
if ( txnid != NULL ) {
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_db_firstkey: transaction failed: aborted.\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
txn_do_abort = 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
ldbm_datum_free( ldbm, key );
|
|
||||||
key.flags = 0;
|
|
||||||
key.dptr = NULL;
|
|
||||||
key.dsize = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return( key );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Datum
|
|
||||||
bdb2i_db_nextkey( LDBM ldbm, Datum key, DBC *dbcp )
|
|
||||||
{
|
|
||||||
Datum data;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
ldbm_datum_init( data );
|
|
||||||
ldbm_datum_free( ldbm, key );
|
|
||||||
key.flags = data.flags = DB_DBT_MALLOC;
|
|
||||||
|
|
||||||
if ( (*dbcp->c_get)( dbcp, &key, &data, DB_NEXT ) == 0 ) {
|
|
||||||
ldbm_datum_free( ldbm, data );
|
|
||||||
} else {
|
|
||||||
if ( txnid != NULL ) {
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_db_nextkey: transaction failed: aborted.\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
txn_do_abort = 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
key.flags = 0;
|
|
||||||
key.dptr = NULL;
|
|
||||||
key.dsize = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return( key );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Transaction control of write access */
|
|
||||||
/* Since these functions are only used by one writer at a time,
|
|
||||||
we do not have any concurrency (locking) problem */
|
|
||||||
|
|
||||||
/* initialize a new transaction */
|
|
||||||
int
|
|
||||||
bdb2i_start_transction( DB_TXNMGR *txmgr )
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
txnid = NULL;
|
|
||||||
txn_do_abort = 0;
|
|
||||||
|
|
||||||
if (( rc = txn_begin( txmgr, NULL, &txnid )) != 0 ) {
|
|
||||||
int err = errno;
|
|
||||||
Debug( LDAP_DEBUG_ANY, "bdb2i_start_transction failed: %d: errno=%s\n",
|
|
||||||
rc, strerror( err ), 0 );
|
|
||||||
|
|
||||||
if ( txnid != NULL )
|
|
||||||
(void) txn_abort( txnid );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"bdb2i_start_transaction: transaction started.\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* finish the transaction */
|
|
||||||
int
|
|
||||||
bdb2i_finish_transaction()
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
/* if transaction was NOT selected, just return */
|
|
||||||
if ( txnid == NULL ) return( 0 );
|
|
||||||
|
|
||||||
/* if nothing was wrong so far, we can try to commit the transaction */
|
|
||||||
/* complain, if the commit fails */
|
|
||||||
if (( txn_do_abort == 0 ) && ( txn_commit( txnid )) != 0 ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_finish_transaction: transaction commit failed: aborted.\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
txn_do_abort = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if anything went wrong, we have to abort the transaction */
|
|
||||||
if ( txn_do_abort ) {
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_finish_transaction: transaction aborted.\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
(void) txn_abort( txnid );
|
|
||||||
rc = -1;
|
|
||||||
} else {
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"bdb2i_finish_transaction: transaction commited.\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* XXX do NOT free the txnid memory !!! */
|
|
||||||
txnid = NULL;
|
|
||||||
txn_do_abort = 0;
|
|
||||||
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* set a checkpoint
|
|
||||||
either forced (during shutdown) or when logsize or time are exceeded
|
|
||||||
(is called by reader and writer, so protect txn_dirty)
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
bdb2i_set_txn_checkpoint( DB_TXNMGR *txmgr, int forced )
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
/* set dirty mutex */
|
|
||||||
ldap_pvt_thread_mutex_lock( &txn_dirty_mutex );
|
|
||||||
|
|
||||||
if ( txn_dirty ) {
|
|
||||||
int rc;
|
|
||||||
u_int32_t logsize;
|
|
||||||
u_int32_t mins;
|
|
||||||
time_t now;
|
|
||||||
|
|
||||||
logsize = forced ? (u_int32_t) 0 : txn_max_pending_log;
|
|
||||||
mins = forced ? (u_int32_t) 0 : txn_max_pending_time;
|
|
||||||
|
|
||||||
now = slap_get_time();
|
|
||||||
|
|
||||||
rc = txn_checkpoint( txmgr, logsize, mins );
|
|
||||||
|
|
||||||
/* if checkpointing was successful, reset txn_dirty */
|
|
||||||
if ( rc == 0 ) {
|
|
||||||
DB_TXN_STAT *statp = NULL;
|
|
||||||
|
|
||||||
/* check whether the checkpoint was actually written;
|
|
||||||
if so, unset the txn_dirty flag */
|
|
||||||
if (( rc = txn_stat( txmgr, &statp, ldbm_malloc )) == 0 ) {
|
|
||||||
|
|
||||||
if ( statp && ( statp->st_time_ckp >= now )) {
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
|
||||||
"bdb2i_set_txn_checkpoint succeded.\n",
|
|
||||||
0, 0, 0 );
|
|
||||||
txn_dirty = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( statp ) free( statp );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Debug( LDAP_DEBUG_ANY,
|
|
||||||
"bdb2i_set_txn_checkpoint: txn_stat failed: %d\n",
|
|
||||||
rc, 0, 0 );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Debug( LDAP_DEBUG_ANY, "bdb2i_set_txn_checkpoint failed: %d\n",
|
|
||||||
rc, 0, 0 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* release dirty mutex */
|
|
||||||
ldap_pvt_thread_mutex_unlock( &txn_dirty_mutex );
|
|
||||||
|
|
||||||
return( rc );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
/* txn.h - Header for TP support functions of the bdb2 backend */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#ifndef _BDB2_TXN_H_
|
|
||||||
#define _BDB2_TXN_H_
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include <ac/dirent.h>
|
|
||||||
#include <ac/errno.h>
|
|
||||||
#include <ac/signal.h>
|
|
||||||
#include <ac/socket.h>
|
|
||||||
#include <ac/string.h>
|
|
||||||
#include <ac/time.h>
|
|
||||||
#include <ac/unistd.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* the DB environment for the backend */
|
|
||||||
DB_ENV bdb2i_dbEnv;
|
|
||||||
|
|
||||||
|
|
||||||
/* variables for transaction support */
|
|
||||||
DB_TXN *txnid = NULL;
|
|
||||||
int txn_do_abort = 0;
|
|
||||||
|
|
||||||
u_int32_t txn_max_pending_log;
|
|
||||||
u_int32_t txn_max_pending_time;
|
|
||||||
int txn_dirty = 0;
|
|
||||||
ldap_pvt_thread_mutex_t txn_dirty_mutex;
|
|
||||||
|
|
||||||
/* defaults for checkpointing */
|
|
||||||
#define BDB2_TXN_CHKP_MAX_LOG 2000 /* checkpoint every 2MB lock file
|
|
||||||
(approx. 20 ADD TXNs) */
|
|
||||||
#define BDB2_TXN_CHKP_MAX_TIME 5 /* checkpoint after 5 minutes */
|
|
||||||
|
|
||||||
|
|
||||||
/* the name of the file and the record number of the NEXTID datum */
|
|
||||||
#define NEXTID_NAME "NEXTID"
|
|
||||||
#define NEXTID_RECNO (db_recno_t) 1
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _BDB2_TXN_H_ */
|
|
||||||
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
/* unbind.c - handle an ldap unbind operation */
|
|
||||||
/* $OpenLDAP$ */
|
|
||||||
|
|
||||||
#include "portable.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ac/socket.h>
|
|
||||||
|
|
||||||
#include "slap.h"
|
|
||||||
#include "back-bdb2.h"
|
|
||||||
|
|
||||||
static int
|
|
||||||
bdb2i_back_unbind_internal(
|
|
||||||
BackendDB *be,
|
|
||||||
Connection *conn,
|
|
||||||
Operation *op
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
bdb2_back_unbind(
|
|
||||||
BackendDB *be,
|
|
||||||
Connection *conn,
|
|
||||||
Operation *op
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct timeval time1;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
bdb2i_start_timing( be->bd_info, &time1 );
|
|
||||||
|
|
||||||
ret = bdb2i_back_unbind_internal( be, conn, op );
|
|
||||||
bdb2i_stop_timing( be->bd_info, time1, "UNBIND", conn, op );
|
|
||||||
|
|
||||||
return( ret );
|
|
||||||
}
|
|
||||||
|
|
@ -594,7 +594,6 @@ idl_insert_key(
|
||||||
* ID off the end of it.
|
* ID off the end of it.
|
||||||
*/
|
*/
|
||||||
rc = idl_insert( &tmp, id, db->dbc_maxids );
|
rc = idl_insert( &tmp, id, db->dbc_maxids );
|
||||||
assert( rc == 0 );
|
|
||||||
|
|
||||||
#ifdef SLAPD_SCHEMA_NOT_COMPAT
|
#ifdef SLAPD_SCHEMA_NOT_COMPAT
|
||||||
k3.dptr = ch_malloc(k2.dsize);
|
k3.dptr = ch_malloc(k2.dsize);
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
#
|
#
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
BUILD_LDBM = @BUILD_LDBM@
|
BUILD_LDBM = @BUILD_LDBM@
|
||||||
BUILD_BDB2 = @BUILD_BDB2@
|
|
||||||
BUILD_QUIPU = @BUILD_QUIPU@
|
BUILD_QUIPU = @BUILD_QUIPU@
|
||||||
|
|
||||||
LDAP_INCDIR= ../../../include
|
LDAP_INCDIR= ../../../include
|
||||||
|
|
@ -35,7 +34,6 @@ XXXLIBS = $(LTHREAD_LIBS) $(MODULES_LIBS)
|
||||||
|
|
||||||
PROGRAMS=ldif slappasswd slapadd slapcat slapindex
|
PROGRAMS=ldif slappasswd slapadd slapcat slapindex
|
||||||
LDBMPROGRAMS=centipede sizecount
|
LDBMPROGRAMS=centipede sizecount
|
||||||
BDB2PROGRAMS=
|
|
||||||
QUIPUPROGRAMS=chlog2replog edb2ldif
|
QUIPUPROGRAMS=chlog2replog edb2ldif
|
||||||
|
|
||||||
# CPPFLAGS will include the defines for dynamic libs in Mingw32.
|
# CPPFLAGS will include the defines for dynamic libs in Mingw32.
|
||||||
|
|
@ -48,8 +46,6 @@ XSRCS = edb2-vers.c
|
||||||
|
|
||||||
LDBMSRCS = centipede.c sizecount.c
|
LDBMSRCS = centipede.c sizecount.c
|
||||||
|
|
||||||
BDB2SRCS =
|
|
||||||
|
|
||||||
QUIPUSRCS = edb2ldif.c ldapsyntax.c chlog2replog.c
|
QUIPUSRCS = edb2ldif.c ldapsyntax.c chlog2replog.c
|
||||||
SLAPD_OBJS = ../config.o ../ch_malloc.o ../backend.o ../charray.o \
|
SLAPD_OBJS = ../config.o ../ch_malloc.o ../backend.o ../charray.o \
|
||||||
../module.o ../aclparse.o ../filterentry.o \
|
../module.o ../aclparse.o ../filterentry.o \
|
||||||
|
|
@ -65,7 +61,7 @@ SLAPOBJS = $(SLAPD_OBJS) slapcommon.o mimic.o
|
||||||
EDB2LDIFSRCS = edb2ldif.c ldapsyntax.c
|
EDB2LDIFSRCS = edb2ldif.c ldapsyntax.c
|
||||||
EDB2LDIFOBJS = edb2ldif.o ldapsyntax.o
|
EDB2LDIFOBJS = edb2ldif.o ldapsyntax.o
|
||||||
|
|
||||||
UNIX_PRGS = build-ldbm build-bdb2 build-quipu
|
UNIX_PRGS = build-ldbm build-quipu
|
||||||
|
|
||||||
all-local: build-progs $(@PLAT@_PRGS)
|
all-local: build-progs $(@PLAT@_PRGS)
|
||||||
|
|
||||||
|
|
@ -77,12 +73,6 @@ ldbm-tools-no:
|
||||||
|
|
||||||
ldbm-tools-yes ldbm-tools-mod: $(LDBMPROGRAMS)
|
ldbm-tools-yes ldbm-tools-mod: $(LDBMPROGRAMS)
|
||||||
|
|
||||||
build-bdb2: bdb2-tools-$(BUILD_BDB2)
|
|
||||||
bdb2-tools-no:
|
|
||||||
@echo "run configure with --enable-bdb2 to build BDB2 tools"
|
|
||||||
|
|
||||||
bdb2-tools-yes bdb2-tools-mod: $(BDB2PROGRAMS)
|
|
||||||
|
|
||||||
build-quipu: quipu-tools-$(BUILD_QUIPU)
|
build-quipu: quipu-tools-$(BUILD_QUIPU)
|
||||||
quipu-tools-no:
|
quipu-tools-no:
|
||||||
@echo "run configure with --enable-quipu to build QUIPU tools"
|
@echo "run configure with --enable-quipu to build QUIPU tools"
|
||||||
|
|
@ -116,10 +106,6 @@ centipede: centipede.o $(SLAPD_LIBDEPEND)
|
||||||
sizecount: sizecount.o ../phonetic.o ../ch_malloc.o $(SLAPD_LIBDEPEND)
|
sizecount: sizecount.o ../phonetic.o ../ch_malloc.o $(SLAPD_LIBDEPEND)
|
||||||
$(LTLINK) -o $@ sizecount.o ../phonetic.o ../ch_malloc.o $(LIBS)
|
$(LTLINK) -o $@ sizecount.o ../phonetic.o ../ch_malloc.o $(LIBS)
|
||||||
|
|
||||||
#
|
|
||||||
# BDBM Specific Tools
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# QUIPU Specific Tools
|
# QUIPU Specific Tools
|
||||||
#
|
#
|
||||||
|
|
@ -134,27 +120,23 @@ chlog2replog: chlog2replog.o ../lock.o ../ch_malloc.o $(SLAPD_LIBDEPEND)
|
||||||
$(LTLINK) -o $@ chlog2replog.o ../lock.o ../ch_malloc.o $(LIBS)
|
$(LTLINK) -o $@ chlog2replog.o ../lock.o ../ch_malloc.o $(LIBS)
|
||||||
|
|
||||||
clean-local: FORCE
|
clean-local: FORCE
|
||||||
$(RM) $(PROGRAMS) $(LDBMPROGRAMS) $(BDB2PROGRAMS) $(QUIPUPROGRAMS) \
|
$(RM) $(PROGRAMS) $(LDBMPROGRAMS) $(QUIPUPROGRAMS) \
|
||||||
$(XPROGRAMS) $(XSRCS) *.o core .libs/* *.exe
|
$(XPROGRAMS) $(XSRCS) *.o core .libs/* *.exe
|
||||||
|
|
||||||
depend-local: FORCE
|
depend-local: FORCE
|
||||||
DEPEND_LDBM= ; DEPEND_BDB2= ; DEPEND_QUIPU= ; \
|
DEPEND_LDBM= ; DEPEND_QUIPU= ; \
|
||||||
if [ "$(BUILD_LDBM)" != "no" ]; then \
|
if [ "$(BUILD_LDBM)" != "no" ]; then \
|
||||||
DEPEND_LDBM="$(LDBMSRCS)"; \
|
DEPEND_LDBM="$(LDBMSRCS)"; \
|
||||||
fi; \
|
fi; \
|
||||||
if [ "$(BUILD_BDB2)" != "no" ]; then \
|
|
||||||
DEPEND_BDB2="$(BDBMSRCS)"; \
|
|
||||||
fi; \
|
|
||||||
if [ "$(BUILD_QUIPU)" != "no" ]; then \
|
if [ "$(BUILD_QUIPU)" != "no" ]; then \
|
||||||
DEPEND_QUIPU="$(QUIPUINCLUDEFLAG) $(QUIPUSRCS)"; \
|
DEPEND_QUIPU="$(QUIPUINCLUDEFLAG) $(QUIPUSRCS)"; \
|
||||||
fi; \
|
fi; \
|
||||||
$(MKDEP) $(DEFS) $(DEFINES) $(SRCS) $$DEPEND_QUIPU \
|
$(MKDEP) $(DEFS) $(DEFINES) $(SRCS) $$DEPEND_QUIPU $$DEPEND_LDBM
|
||||||
$$DEPEND_LDBM $$DEPEND_BDB2
|
|
||||||
|
|
||||||
install-local: install-ldbm-$(BUILD_LDBM) install-bdb2-$(BUILD_BDB2) \
|
install-local: install-ldbm-$(BUILD_LDBM) \
|
||||||
install-quipu-$(BUILD_QUIPU)
|
install-quipu-$(BUILD_QUIPU)
|
||||||
|
|
||||||
install-ldbm-no install-bdb2-no install-quipu-no:
|
install-ldbm-no install-quipu-no:
|
||||||
|
|
||||||
install-ldbm-yes install-ldbm-mod: FORCE
|
install-ldbm-yes install-ldbm-mod: FORCE
|
||||||
-$(MKDIR) $(DESTDIR)$(sbindir)
|
-$(MKDIR) $(DESTDIR)$(sbindir)
|
||||||
|
|
@ -163,9 +145,6 @@ install-ldbm-yes install-ldbm-mod: FORCE
|
||||||
$$bin$(EXEEXT) $(DESTDIR)$(sbindir); \
|
$$bin$(EXEEXT) $(DESTDIR)$(sbindir); \
|
||||||
done
|
done
|
||||||
|
|
||||||
install-bdb2-yes install-bdb2-mod: FORCE
|
|
||||||
@-$(MKDIR) $(DESTDIR)$(sbindir)
|
|
||||||
|
|
||||||
install-quipu-yes: FORCE
|
install-quipu-yes: FORCE
|
||||||
@-$(MKDIR) $(DESTDIR)$(sbindir)
|
@-$(MKDIR) $(DESTDIR)$(sbindir)
|
||||||
for bin in edb2ldif chlog2replog; do \
|
for bin in edb2ldif chlog2replog; do \
|
||||||
|
|
|
||||||
|
|
@ -4,31 +4,22 @@
|
||||||
##
|
##
|
||||||
## tests Makefile.in for OpenLDAP
|
## tests Makefile.in for OpenLDAP
|
||||||
SUBDIRS= progs
|
SUBDIRS= progs
|
||||||
|
BUILD_LDBM=@BUILD_LDBM@
|
||||||
BUILD_BDB2 = @BUILD_BDB2@
|
|
||||||
|
|
||||||
test: tests
|
test: tests
|
||||||
tests: bdb2 ldbm
|
tests: ldbm
|
||||||
|
|
||||||
bdb2: test-bdb2
|
|
||||||
test-bdb2: FORCE
|
|
||||||
@-$(LN_S) $(srcdir)/data data
|
|
||||||
@-$(LN_S) $(top_srcdir)/servers/slapd/schema schema
|
|
||||||
@if test "$(BUILD_BDB2)" = "yes" ; then \
|
|
||||||
echo "Initiating LDAP tests..." ; \
|
|
||||||
$(MKDIR) test-db test-repl || true; \
|
|
||||||
$(srcdir)/scripts/all $(srcdir) bdb2 ; \
|
|
||||||
else \
|
|
||||||
echo "run configure with --enable-bdb2" ; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
ldbm: test-ldbm
|
ldbm: test-ldbm
|
||||||
test-ldbm: FORCE
|
test-ldbm: FORCE
|
||||||
@-$(LN_S) $(srcdir)/data data
|
@-$(LN_S) $(srcdir)/data data
|
||||||
@-$(LN_S) $(top_srcdir)/servers/slapd/schema schema
|
@-$(LN_S) $(top_srcdir)/servers/slapd/schema schema
|
||||||
@echo "Initiating LDAP tests..."
|
@if test "$(BUILD_LDBM)" = "yes" ; then \
|
||||||
@-$(MKDIR) test-db test-repl || true
|
echo "Initiating LDAP tests for LDBM..." ; \
|
||||||
@$(srcdir)/scripts/all $(srcdir) ldbm
|
$(MKDIR) test-db test-repl || true; \
|
||||||
|
$(srcdir)/scripts/all $(srcdir) ldbm ; \
|
||||||
|
else \
|
||||||
|
echo "run configure with --enable-ldbm" ; \
|
||||||
|
fi
|
||||||
|
|
||||||
passwd: test-passwd
|
passwd: test-passwd
|
||||||
test-passwd: FORCE
|
test-passwd: FORCE
|
||||||
|
|
@ -46,18 +37,6 @@ test-nis-schema-ldbm:
|
||||||
$(MKDIR) test-db test-repl ; \
|
$(MKDIR) test-db test-repl ; \
|
||||||
$(srcdir)/scripts/startup_nis_ldap_server.sh $(srcdir) ldbm
|
$(srcdir)/scripts/startup_nis_ldap_server.sh $(srcdir) ldbm
|
||||||
|
|
||||||
test-nis-schema-bdb2:
|
|
||||||
@-$(LN_S) $(srcdir)/data data
|
|
||||||
@-$(LN_S) $(top_srcdir)/servers/slapd/schema schema
|
|
||||||
@echo "Initiating LDAP server with NIS schema & DB2 backend..."; \
|
|
||||||
@if test "$(BUILD_BDB2)" = "yes" ; then \
|
|
||||||
echo "Initiating LDAP tests..." ; \
|
|
||||||
$(MKDIR) test-db test-repl ; \
|
|
||||||
$(srcdir)/scripts/startup_nis_ldap_server.sh $(srcdir) bdb2 ; \
|
|
||||||
else \
|
|
||||||
echo "run configure with --enable-bdb2" ; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
clean-local: FORCE
|
clean-local: FORCE
|
||||||
-$(RM) test-db/[!C]* test-repl/[!C]* *leak *gmon *core
|
-$(RM) test-db/[!C]* test-repl/[!C]* *leak *gmon *core
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue