From 6ba33e85d96d4d1e638aa908bebc0f6b4230893e Mon Sep 17 00:00:00 2001 From: zengwefeng Date: Thu, 28 Oct 2021 16:46:31 +0800 Subject: [PATCH 1/3] sync some patches from upstream community and fix CVES --- CVE-2020-25709.patch | 25 + CVE-2020-25710.patch | 26 + CVE-2021-27212.patch | 28 + backport-Fix-test-suite.patch | 71 + backport-ITS-9010-More-BDB-HDB-cleanup.patch | 406 + backport-ITS-9010-regenerate-configure.patch | 1783 ++ backport-delete-back-bdb-back-hdb.patch | 22206 +++++++++++++++++ openldap.spec | 19 +- 8 files changed, 24563 insertions(+), 1 deletion(-) create mode 100644 CVE-2020-25709.patch create mode 100644 CVE-2020-25710.patch create mode 100644 CVE-2021-27212.patch create mode 100644 backport-Fix-test-suite.patch create mode 100644 backport-ITS-9010-More-BDB-HDB-cleanup.patch create mode 100644 backport-ITS-9010-regenerate-configure.patch create mode 100644 backport-delete-back-bdb-back-hdb.patch diff --git a/CVE-2020-25709.patch b/CVE-2020-25709.patch new file mode 100644 index 0000000..6aa13ca --- /dev/null +++ b/CVE-2020-25709.patch @@ -0,0 +1,25 @@ +From 67670f4544e28fb09eb7319c39f404e1d3229e65 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Mon, 2 Nov 2020 13:12:10 +0000 +Subject: [PATCH] ITS#9383 remove assert in certificateListValidate + +--- + servers/slapd/schema_init.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c +index ea0d67aa62..28f9e71a16 100644 +--- a/servers/slapd/schema_init.c ++++ b/servers/slapd/schema_init.c +@@ -371,8 +371,7 @@ certificateListValidate( Syntax *syntax, struct berval *in ) + /* Optional version */ + if ( tag == LBER_INTEGER ) { + tag = ber_get_int( ber, &version ); +- assert( tag == LBER_INTEGER ); +- if ( version != SLAP_X509_V2 ) return LDAP_INVALID_SYNTAX; ++ if ( tag != LBER_INTEGER || version != SLAP_X509_V2 ) return LDAP_INVALID_SYNTAX; + } + tag = ber_skip_tag( ber, &len ); /* Signature Algorithm */ + if ( tag != LBER_SEQUENCE ) return LDAP_INVALID_SYNTAX; +-- +GitLab diff --git a/CVE-2020-25710.patch b/CVE-2020-25710.patch new file mode 100644 index 0000000..3edfe42 --- /dev/null +++ b/CVE-2020-25710.patch @@ -0,0 +1,26 @@ +From bdb0d459187522a6063df13871b82ba8dcc6efe2 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Mon, 2 Nov 2020 16:01:14 +0000 +Subject: [PATCH] ITS#9384 remove assert in obsolete csnNormalize23() + +--- + servers/slapd/schema_init.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c +index 5812bc4b66..ea0d67aa62 100644 +--- a/servers/slapd/schema_init.c ++++ b/servers/slapd/schema_init.c +@@ -5327,8 +5327,8 @@ csnNormalize23( + } + *ptr = '\0'; + +- assert( ptr == &bv.bv_val[bv.bv_len] ); +- if ( csnValidate( syntax, &bv ) != LDAP_SUCCESS ) { ++ if ( ptr != &bv.bv_val[bv.bv_len] || ++ csnValidate( syntax, &bv ) != LDAP_SUCCESS ) { + return LDAP_INVALID_SYNTAX; + } + +-- +GitLab diff --git a/CVE-2021-27212.patch b/CVE-2021-27212.patch new file mode 100644 index 0000000..663cae6 --- /dev/null +++ b/CVE-2021-27212.patch @@ -0,0 +1,28 @@ +From 3539fc33212b528c56b716584f2c2994af7c30b0 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Sat, 6 Feb 2021 20:52:06 +0000 +Subject: [PATCH] ITS#9454 fix issuerAndThisUpdateCheck + +Reference:https://git.openldap.org/openldap/openldap/-/commit/3539fc33212b528c56b716584f2c2994af7c30b0 + +--- + servers/slapd/schema_init.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c +index 466899625..914df70eb 100644 +--- a/servers/slapd/schema_init.c ++++ b/servers/slapd/schema_init.c +@@ -3975,6 +3975,8 @@ issuerAndThisUpdateCheck( + break; + } + } ++ if ( tu->bv_len < STRLENOF("YYYYmmddHHmmssZ") ) return LDAP_INVALID_SYNTAX; ++ + x.bv_val += tu->bv_len + 1; + x.bv_len -= tu->bv_len + 1; + + +-- +GitLab + diff --git a/backport-Fix-test-suite.patch b/backport-Fix-test-suite.patch new file mode 100644 index 0000000..cc8f72e --- /dev/null +++ b/backport-Fix-test-suite.patch @@ -0,0 +1,71 @@ +From 70f87370f99e78ac3874501bfe5124dbb86185a8 Mon Sep 17 00:00:00 2001 +From: zhangqiumiao +Date: Fri, 25 Sep 2020 21:56:43 +0800 +Subject: [PATCH] backport Fix test suite + +--- + tests/data/monitor2.out | 3 --- + tests/scripts/test052-memberof | 2 +- + tests/scripts/test056-monitor | 11 ++--------- + 3 files changed, 3 insertions(+), 13 deletions(-) + +diff --git a/tests/data/monitor2.out b/tests/data/monitor2.out +index 26e9ce9..20209d1 100644 +--- a/tests/data/monitor2.out ++++ b/tests/data/monitor2.out +@@ -10,9 +10,6 @@ structuralObjectClass: monitoredObject + monitorIsShadow: FALSE + namingContexts: o=OpenLDAP Project,l=Internet + readOnly: FALSE +-olmBDBEntryCache: 0 +-olmBDBDNCache: 0 +-olmBDBIDLCache: 0 + entryDN: cn=Database 1,cn=Databases,cn=Monitor + + dn: cn=Database 2,cn=Databases,cn=Monitor +diff --git a/tests/scripts/test052-memberof b/tests/scripts/test052-memberof +index a73a929..1dba946 100755 +--- a/tests/scripts/test052-memberof ++++ b/tests/scripts/test052-memberof +@@ -72,7 +72,7 @@ EOF + fi + fi + +-indexInclude="" mainInclude="" " nullExclude="" ++indexInclude="" mainInclude="" nullExclude="" + test $INDEXDB = indexdb || indexInclude="# " + test $MAINDB = maindb || mainInclude="# " + case $BACKEND in +diff --git a/tests/scripts/test056-monitor b/tests/scripts/test056-monitor +index 7a87eaa..0e1ba20 100755 +--- a/tests/scripts/test056-monitor ++++ b/tests/scripts/test056-monitor +@@ -85,7 +85,7 @@ echo "Using ldapsearch to read database monitor entries..." + $LDAPSEARCH -S "" -b "$DATABASESMONITORDN" -h $LOCALHOST -p $PORT1 \ + 'objectclass=*' \ + structuralObjectClass entryDN namingContexts readOnly \ +- monitorIsShadow monitorContext ++ monitorIsShadow monitorContext \ + > $SEARCHOUT 2>&1 + RC=$? + +@@ -98,15 +98,8 @@ fi + echo "Filtering ldapsearch results..." + $LDIFFILTER -b monitor < $SEARCHOUT > $SEARCHFLT + +-TMPMONITOROUT2=$MONITOROUT2 +-case $BACKEND in +-*) +- TMPMONITOROUT2=$TESTDIR/monitor2.out +- ;; +-esac +- + echo "Comparing filter output..." +-$CMP $SEARCHFLT $TMPMONITOROUT2 > $CMPOUT ++$CMP $SEARCHFLT $MONITOROUT2 > $CMPOUT + + if test $? != 0 ; then + echo "comparison failed - database monitor output is not correct" +-- +2.19.1 + diff --git a/backport-ITS-9010-More-BDB-HDB-cleanup.patch b/backport-ITS-9010-More-BDB-HDB-cleanup.patch new file mode 100644 index 0000000..9739b8c --- /dev/null +++ b/backport-ITS-9010-More-BDB-HDB-cleanup.patch @@ -0,0 +1,406 @@ +From ac37a67536d37ae059ed120f00b540429be6b4e0 Mon Sep 17 00:00:00 2001 +From: zhangqiumiao +Date: Sun, 27 Sep 2020 15:01:05 +0800 +Subject: [PATCH] backport ITS#9010 More BDB/HDB cleanup + +--- + doc/guide/admin/aspell.en.pws | 7 - + tests/data/regressions/its4337/config.out | 129 ------------------ + tests/data/regressions/its4337/its4337 | 157 ---------------------- + tests/data/regressions/its4337/slapd.conf | 36 ----- + 4 files changed, 329 deletions(-) + delete mode 100644 tests/data/regressions/its4337/config.out + delete mode 100755 tests/data/regressions/its4337/its4337 + delete mode 100644 tests/data/regressions/its4337/slapd.conf + +diff --git a/doc/guide/admin/aspell.en.pws b/doc/guide/admin/aspell.en.pws +index ae777e2..ec24572 100644 +--- a/doc/guide/admin/aspell.en.pws ++++ b/doc/guide/admin/aspell.en.pws +@@ -220,8 +220,6 @@ AVAs + associatedDomain + organizationalRole + initgroups +-olcDbCachesize +-olcDbCacheSize + ETCDIR + colaligns + olcReadOnly +@@ -426,10 +424,8 @@ txt + UTR + XER + roomNumber +-olcDbIDLcacheSize + namespace + LDAPControl +-dbconfig + olcAttributeOptions + dsaparam + searchResult +@@ -965,7 +961,6 @@ unwillingToPerform + PhotoURI + MyCompany + mkdep +-idlcachesize + irresponsive + PasswordModify + readOnly +@@ -1183,7 +1178,6 @@ monitorRuntimeConfig + olcAuditlogFile + namingContexts + referralAttrDN +-idlecachesize + moddn + calloc + LDFLAGS +@@ -1375,7 +1369,6 @@ spasswd + sprintf + monitorCounterObject + Instanstantiation +-olcDbConfig + olcLastMod + vals + param +diff --git a/tests/data/regressions/its4337/config.out b/tests/data/regressions/its4337/config.out +deleted file mode 100644 +index bdcbbe5..0000000 +--- a/tests/data/regressions/its4337/config.out ++++ /dev/null +@@ -1,129 +0,0 @@ +-# Searching databases __before__ append... +-dn: olcDatabase={-1}frontend,cn=config +-objectClass: olcDatabaseConfig +-objectClass: olcFrontendConfig +-olcDatabase: {-1}frontend +-olcAddContentAcl: FALSE +-olcLastMod: TRUE +-olcMaxDerefDepth: 0 +-olcReadOnly: FALSE +-olcSchemaDN: cn=Subschema +-olcSyncUseSubentry: FALSE +-olcMonitoring: FALSE +- +-dn: olcDatabase={0}config,cn=config +-objectClass: olcDatabaseConfig +-olcDatabase: {0}config +-olcAccess: {0}to * by * none +-olcAddContentAcl: TRUE +-olcLastMod: TRUE +-olcMaxDerefDepth: 15 +-olcReadOnly: FALSE +-olcRootDN: cn=config +-olcRootPW: config +-olcSyncUseSubentry: FALSE +-olcMonitoring: FALSE +- +-dn: olcDatabase={1}monitor,cn=config +-objectClass: olcDatabaseConfig +-olcDatabase: {1}monitor +-olcAddContentAcl: FALSE +-olcLastMod: TRUE +-olcMaxDerefDepth: 15 +-olcReadOnly: FALSE +-olcSyncUseSubentry: FALSE +-olcMonitoring: FALSE +- +-# Searching databases __after__ append... +-dn: olcDatabase={-1}frontend,cn=config +-objectClass: olcDatabaseConfig +-objectClass: olcFrontendConfig +-olcDatabase: {-1}frontend +-olcAddContentAcl: FALSE +-olcLastMod: TRUE +-olcMaxDerefDepth: 0 +-olcReadOnly: FALSE +-olcSchemaDN: cn=Subschema +-olcSyncUseSubentry: FALSE +-olcMonitoring: FALSE +- +-dn: olcDatabase={0}config,cn=config +-objectClass: olcDatabaseConfig +-olcDatabase: {0}config +-olcAccess: {0}to * by * none +-olcAddContentAcl: TRUE +-olcLastMod: TRUE +-olcMaxDerefDepth: 15 +-olcReadOnly: FALSE +-olcRootDN: cn=config +-olcRootPW: config +-olcSyncUseSubentry: FALSE +-olcMonitoring: FALSE +- +-dn: olcDatabase={1}monitor,cn=config +-objectClass: olcDatabaseConfig +-olcDatabase: {1}monitor +-olcAddContentAcl: FALSE +-olcLastMod: TRUE +-olcMaxDerefDepth: 15 +-olcReadOnly: FALSE +-olcSyncUseSubentry: FALSE +-olcMonitoring: FALSE +- +-dn: olcDatabase={2}bdb,cn=config +-objectClass: olcDatabaseConfig +-objectClass: olcBdbConfig +-olcDatabase: {2}bdb +-olcDbDirectory: ./testrun/db.1.a +-olcSuffix: dc=com +- +-# Searching databases __after__ insert... +-dn: olcDatabase={-1}frontend,cn=config +-objectClass: olcDatabaseConfig +-objectClass: olcFrontendConfig +-olcDatabase: {-1}frontend +-olcAddContentAcl: FALSE +-olcLastMod: TRUE +-olcMaxDerefDepth: 0 +-olcReadOnly: FALSE +-olcSchemaDN: cn=Subschema +-olcSyncUseSubentry: FALSE +-olcMonitoring: FALSE +- +-dn: olcDatabase={0}config,cn=config +-objectClass: olcDatabaseConfig +-olcDatabase: {0}config +-olcAccess: {0}to * by * none +-olcAddContentAcl: TRUE +-olcLastMod: TRUE +-olcMaxDerefDepth: 15 +-olcReadOnly: FALSE +-olcRootDN: cn=config +-olcRootPW: config +-olcSyncUseSubentry: FALSE +-olcMonitoring: FALSE +- +-dn: olcDatabase={1}bdb,cn=config +-objectClass: olcDatabaseConfig +-objectClass: olcBdbConfig +-olcDatabase: {1}bdb +-olcDbDirectory: ./testrun/db.2.a +-olcSuffix: dc=org +- +-dn: olcDatabase={2}monitor,cn=config +-objectClass: olcDatabaseConfig +-olcDatabase: {2}monitor +-olcAddContentAcl: FALSE +-olcLastMod: TRUE +-olcMaxDerefDepth: 15 +-olcReadOnly: FALSE +-olcSyncUseSubentry: FALSE +-olcMonitoring: FALSE +- +-dn: olcDatabase={3}bdb,cn=config +-objectClass: olcDatabaseConfig +-objectClass: olcBdbConfig +-olcDatabase: {3}bdb +-olcDbDirectory: ./testrun/db.1.a +-olcSuffix: dc=com +- +diff --git a/tests/data/regressions/its4337/its4337 b/tests/data/regressions/its4337/its4337 +deleted file mode 100755 +index 66bc716..0000000 +--- a/tests/data/regressions/its4337/its4337 ++++ /dev/null +@@ -1,157 +0,0 @@ +-#! /bin/sh +-# $OpenLDAP$ +-## This work is part of OpenLDAP Software . +-## +-## Copyright 1998-2020 The OpenLDAP Foundation. +-## All rights reserved. +-## +-## Redistribution and use in source and binary forms, with or without +-## modification, are permitted only as authorized by the OpenLDAP +-## Public License. +-## +-## A copy of this license is available in the file LICENSE in the +-## top-level directory of the distribution or, alternatively, at +-## . +- +-echo "running defines.sh" +-. $SRCDIR/scripts/defines.sh +- +-if test $BACKEND != "bdb" ; then +- echo "BDB backend not available, test skipped" +- exit 0 +-fi +- +-mkdir -p $TESTDIR $DBDIR1 $DBDIR2 $DBDIR3 $TESTDIR/slapd.d +- +-ITS=4337 +-ITSDIR=$DATADIR/regressions/its$ITS +- +-echo "Starting slapd on TCP/IP port $PORT1..." +-. $CONFFILTER $BACKEND $MONITORDB < $ITSDIR/slapd.conf > $CONF1 +-#$SLAPD -f $CONF1 -F $TESTDIR/slapd.d -h $URI1 -d $LVL $TIMING > $LOG1 2>&1 & +-$SLAPD -f $CONF1 -h $URI1 -d $LVL $TIMING > $LOG1 2>&1 & +-PID=$! +-if test $WAIT != 0 ; then +- echo PID $PID +- read foo +-fi +-KILLPIDS="$PID" +- +-sleep 1 +- +-echo "Using ldapsearch to check that slapd is running..." +-for i in 0 1 2 3 4 5; do +- $LDAPSEARCH -s base -b "$MONITOR" -h $LOCALHOST -p $PORT1 \ +- 'objectclass=*' > /dev/null 2>&1 +- RC=$? +- if test $RC = 0 ; then +- break +- fi +- echo "Waiting 5 seconds for slapd to start..." +- sleep 5 +-done +- +-if test $RC != 0 ; then +- echo "ldapsearch failed ($RC)!" +- test $KILLSERVERS != no && kill -HUP $KILLPIDS +- exit $RC +-fi +- +-cat /dev/null > $TESTOUT +-cat /dev/null > $SEARCHOUT +- +-echo "Searching databases..." +-echo "# Searching databases __before__ append..." >> $SEARCHOUT +-$LDAPSEARCH -h $LOCALHOST -p $PORT1 \ +- -D "cn=config" -w "config" -b "cn=config" \ +- '(objectClass=olcDatabaseConfig)' >> $SEARCHOUT 2>> $TESTOUT +-RC=$? +-if test $RC != 0 ; then +- echo "ldapsearch failed ($RC)!" +- test $KILLSERVERS != no && kill -HUP $KILLPIDS +- exit $RC +-fi +- +-echo "Appending a database..." +-$LDAPADD -v -D "cn=config" -w "config" -h $LOCALHOST -p $PORT1 \ +- >> $TESTOUT 2>&1 << EOMODS +-dn: olcDatabase=bdb,cn=config +-objectClass: olcDatabaseConfig +-objectClass: olcBdbConfig +-olcDatabase: bdb +-olcSuffix: dc=com +-olcDbDirectory: ./testrun/db.1.a +-EOMODS +-RC=$? +-if test $RC != 0 ; then +- echo "ldapadd failed ($RC)!" +- test $KILLSERVERS != no && kill -HUP $KILLPIDS +- exit $RC +-fi +- +-echo "Searching databases..." +-echo "# Searching databases __after__ append..." >> $SEARCHOUT +-$LDAPSEARCH -h $LOCALHOST -p $PORT1 \ +- -D "cn=config" -w "config" -b "cn=config" \ +- '(objectClass=olcDatabaseConfig)' >> $SEARCHOUT 2>> $TESTOUT +-RC=$? +-if test $RC != 0 ; then +- echo "ldapsearch failed ($RC)!" +- test $KILLSERVERS != no && kill -HUP $KILLPIDS +- exit $RC +-fi +- +-echo "Inserting a database..." +-$LDAPADD -v -D "cn=config" -w "config" -h $LOCALHOST -p $PORT1 \ +- >> $TESTOUT 2>&1 << EOMODS +-dn: olcDatabase={1}bdb,cn=config +-objectClass: olcDatabaseConfig +-objectClass: olcBdbConfig +-olcDatabase: {1}bdb +-olcSuffix: dc=org +-olcDbDirectory: ./testrun/db.2.a +-EOMODS +-RC=$? +-if test $RC != 0 ; then +- echo "ldapadd failed ($RC)!" +- test $KILLSERVERS != no && kill -HUP $KILLPIDS +- if test $RC = 53 ; then +- echo "TODO" +- exit 0 +- fi +- exit $RC +-fi +- +-echo "Searching databases..." +-echo "# Searching databases __after__ insert..." >> $SEARCHOUT +-$LDAPSEARCH -h $LOCALHOST -p $PORT1 \ +- -D "cn=config" -w "config" -b "cn=config" \ +- '(objectClass=olcDatabaseConfig)' >> $SEARCHOUT 2>> $TESTOUT +-RC=$? +-if test $RC != 0 ; then +- echo "ldapsearch failed ($RC)!" +- test $KILLSERVERS != no && kill -HUP $KILLPIDS +- exit $RC +-fi +- +-test $KILLSERVERS != no && kill -HUP $KILLPIDS +- +-LDIF=$ITSDIR/config.out +- +-echo "Filtering ldapsearch results..." +-$LDIFFILTER < $SEARCHOUT > $SEARCHFLT +-echo "Filtering original ldif..." +-$LDIFFILTER < $LDIF > $LDIFFLT +-echo "Comparing filter output..." +-$CMP $SEARCHFLT $LDIFFLT > $CMPOUT +- +-if test $? != 0 ; then +- echo "Comparison failed" +- exit 1 +-fi +- +-echo ">>>>> Test succeeded" +- +-test $KILLSERVERS != no && wait +- +-exit 0 +diff --git a/tests/data/regressions/its4337/slapd.conf b/tests/data/regressions/its4337/slapd.conf +deleted file mode 100644 +index ee3108a..0000000 +--- a/tests/data/regressions/its4337/slapd.conf ++++ /dev/null +@@ -1,36 +0,0 @@ +-# stand-alone slapd config -- for testing (with indexing) +-# $OpenLDAP$ +-## This work is part of OpenLDAP Software . +-## +-## Copyright 1998-2020 The OpenLDAP Foundation. +-## All rights reserved. +-## +-## Redistribution and use in source and binary forms, with or without +-## modification, are permitted only as authorized by the OpenLDAP +-## Public License. +-## +-## A copy of this license is available in the file LICENSE in the +-## top-level directory of the distribution or, alternatively, at +-## . +- +-include @SCHEMADIR@/core.schema +-include @SCHEMADIR@/cosine.schema +-include @SCHEMADIR@/inetorgperson.schema +-include @SCHEMADIR@/openldap.schema +-include @SCHEMADIR@/nis.schema +-include @DATADIR@/test.schema +- +-# +-pidfile @TESTDIR@/slapd.2.pid +-argsfile @TESTDIR@/slapd.2.args +- +-#mod#modulepath ../servers/slapd/back-@BACKEND@/:../servers/slapd/overlays +-#mod#moduleload back_@BACKEND@.la +- +-#monitormod#modulepath ../servers/slapd/back-monitor/ +-#monitormod#moduleload back_monitor.la +- +-database config +-rootpw config +- +-#monitor#database monitor +-- +2.19.1 + diff --git a/backport-ITS-9010-regenerate-configure.patch b/backport-ITS-9010-regenerate-configure.patch new file mode 100644 index 0000000..1ec1ee1 --- /dev/null +++ b/backport-ITS-9010-regenerate-configure.patch @@ -0,0 +1,1783 @@ +From 14c7c8f3579a8c0a802aaac72841efed3d01445f Mon Sep 17 00:00:00 2001 +From: zhangqiumiao +Date: Sun, 27 Sep 2020 14:25:21 +0800 +Subject: [PATCH] backport ITS#9010 regenerate configure + +--- + configure | 1565 +++++------------------------------------------------ + 1 file changed, 148 insertions(+), 1417 deletions(-) + +diff --git a/configure b/configure +index 5f05f1c..5c5097a 100755 +--- a/configure ++++ b/configure +@@ -667,7 +667,6 @@ LUTIL_LIBS + LTHREAD_LIBS + SLAPD_NDB_INCS + SLAPD_NDB_LIBS +-BDB_LIBS + SLAPD_LIBS + LDAP_LIBS + BUILD_VALSORT +@@ -704,9 +703,7 @@ BUILD_MONITOR + BUILD_META + BUILD_MDB + BUILD_LDAP +-BUILD_HDB + BUILD_DNSSRV +-BUILD_BDB + SLAPD_SLAPI_DEPEND + BUILD_SLAPI + BUILD_SLAPD +@@ -764,6 +761,7 @@ DLLTOOL + AS + AR + CC ++moduledir + ldap_subdir + top_builddir + OPENLDAP_RELEASE_DATE +@@ -852,6 +850,7 @@ ac_user_opts=' + enable_option_checking + enable_silent_rules + with_subdir ++with_moduledir + enable_debug + enable_dynamic + enable_syslog +@@ -881,9 +880,7 @@ enable_slp + enable_wrappers + enable_xxslapbackends + enable_backends +-enable_bdb + enable_dnssrv +-enable_hdb + enable_ldap + enable_mdb + enable_meta +@@ -1583,9 +1580,7 @@ SLAPD (Standalone LDAP Daemon) Options: + + SLAPD Backend Options: + --enable-backends enable all available backends no|yes|mod +- --enable-bdb enable Berkeley DB backend no|yes|mod [yes] + --enable-dnssrv enable dnssrv backend no|yes|mod [no] +- --enable-hdb enable Hierarchical DB backend no|yes|mod [yes] + --enable-ldap enable ldap backend no|yes|mod [no] + --enable-mdb enable mdb database backend no|yes|mod [yes] + --enable-meta enable metadirectory backend no|yes|mod [no] +@@ -1637,6 +1632,7 @@ Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-subdir=DIR change default subdirectory used for installs ++ --with-moduledir=DIR change default module subdirectory used for installs + --with-cyrus-sasl with Cyrus SASL support [auto] + --with-fetch with fetch(3) URL support [auto] + --with-threads with threads [auto] +@@ -3570,6 +3566,24 @@ esac + fi + + ++ ++moduledir="openldap" ++ ++ ++# Check whether --with-moduledir was given. ++if test "${with_moduledir+set}" = set; then : ++ withval=$with_moduledir; case "$withval" in ++ no) moduledir="" ++ ;; ++ yes) ++ ;; ++ *) ++ moduledir="$withval" ++ ;; ++esac ++ ++fi ++ + # OpenLDAP --enable-debug + + # Check whether --enable-debug was given. +@@ -4126,9 +4140,7 @@ fi + + # end --enable-wrappers + +-Backends="bdb \ +- dnssrv \ +- hdb \ ++Backends="dnssrv \ + ldap \ + mdb \ + meta \ +@@ -4167,27 +4179,6 @@ if test "${enable_backends+set}" = set; then : + fi + + # end --enable-backends +-# OpenLDAP --enable-bdb +- +- # Check whether --enable-bdb was given. +-if test "${enable_bdb+set}" = set; then : +- enableval=$enable_bdb; +- ol_arg=invalid +- for ol_val in no yes mod ; do +- if test "$enableval" = "$ol_val" ; then +- ol_arg="$ol_val" +- fi +- done +- if test "$ol_arg" = "invalid" ; then +- as_fn_error $? "bad value $enableval for --enable-bdb" "$LINENO" 5 +- fi +- ol_enable_bdb="$ol_arg" +- +-else +- ol_enable_bdb=${ol_enable_backends:-yes} +-fi +- +-# end --enable-bdb + # OpenLDAP --enable-dnssrv + + # Check whether --enable-dnssrv was given. +@@ -4209,27 +4200,6 @@ else + fi + + # end --enable-dnssrv +-# OpenLDAP --enable-hdb +- +- # Check whether --enable-hdb was given. +-if test "${enable_hdb+set}" = set; then : +- enableval=$enable_hdb; +- ol_arg=invalid +- for ol_val in no yes mod ; do +- if test "$enableval" = "$ol_val" ; then +- ol_arg="$ol_val" +- fi +- done +- if test "$ol_arg" = "invalid" ; then +- as_fn_error $? "bad value $enableval for --enable-hdb" "$LINENO" 5 +- fi +- ol_enable_hdb="$ol_arg" +- +-else +- ol_enable_hdb=${ol_enable_backends:-yes} +-fi +- +-# end --enable-hdb + # OpenLDAP --enable-ldap + + # Check whether --enable-ldap was given. +@@ -5108,9 +5078,7 @@ $as_echo "$as_me: WARNING: slapd disabled, ignoring --enable-$i argument" >&2;} + ol_enable_rewrite=no + + elif test $ol_enable_modules != yes && +- test $ol_enable_bdb = no && + test $ol_enable_dnssrv = no && +- test $ol_enable_hdb = no && + test $ol_enable_ldap = no && + test $ol_enable_mdb = no && + test $ol_enable_meta = no && +@@ -5150,11 +5118,22 @@ if test $ol_enable_spasswd = yes ; then + ol_with_cyrus_sasl=yes + fi + ++ + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 + $as_echo "done" >&6; } + ++case $moduledir in ++ /*|\\*) ++ ;; ++ *) ++ moduledir=$libexecdir/$moduledir ++ ;; ++esac ++ ++ ++ ++ + LDAP_LIBS= +-BDB_LIBS= + SLAPD_NDB_LIBS= + SLAPD_NDB_INCS= + LTHREAD_LIBS= +@@ -5169,9 +5148,7 @@ BUILD_THREAD=no + BUILD_SLAPI=no + SLAPD_SLAPI_DEPEND= + +-BUILD_BDB=no + BUILD_DNSSRV=no +-BUILD_HDB=no + BUILD_LDAP=no + BUILD_MDB=no + BUILD_META=no +@@ -22937,1388 +22914,178 @@ else + ol_cv_func_gethostbyaddr_r_nargs=0 + fi + +-ol_link_bdb=no + +-if test $ol_enable_bdb/$ol_enable_hdb != no/no; then +- ol_cv_berkeley_db=no +-for ac_header in db.h +-do : +- ac_fn_c_check_header_mongrel "$LINENO" "db.h" "ac_cv_header_db_h" "$ac_includes_default" +-if test "x$ac_cv_header_db_h" = xyes; then : +- cat >>confdefs.h <<_ACEOF +-#define HAVE_DB_H 1 +-_ACEOF +- +-fi +- +-done +- +-if test $ac_cv_header_db_h = yes; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB major version in db.h" >&5 +-$as_echo_n "checking for Berkeley DB major version in db.h... " >&6; } +-if ${ol_cv_bdb_major+:} false; then : +- $as_echo_n "(cached) " >&6 ++if test $ol_enable_dynamic = yes && test $enable_shared = yes ; then ++ BUILD_LIBS_DYNAMIC=shared ++ $as_echo "#define LDAP_LIBS_DYNAMIC 1" >>confdefs.h ++ LTSTATIC="" + else +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#include +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif +-__db_version DB_VERSION_MAJOR +- +-_ACEOF +- set X `eval "$ac_cpp -P conftest.$ac_ext" | $EGREP __db_version` none none +- ol_cv_bdb_major=${3} +- ++ BUILD_LIBS_DYNAMIC=static ++ LTSTATIC="-static" + fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_bdb_major" >&5 +-$as_echo "$ol_cv_bdb_major" >&6; } +-case $ol_cv_bdb_major in [1-9]*) : ;; *) +- as_fn_error $? "Unknown Berkeley DB major version in db.h" "$LINENO" 5 ;; +-esac +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB minor version in db.h" >&5 +-$as_echo_n "checking for Berkeley DB minor version in db.h... " >&6; } +-if ${ol_cv_bdb_minor+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#include +-#ifndef DB_VERSION_MINOR +-# define DB_VERSION_MINOR 0 +-#endif +-__db_version DB_VERSION_MINOR + ++if test $ol_enable_wrappers != no ; then ++ for ac_header in tcpd.h ++do : ++ ac_fn_c_check_header_mongrel "$LINENO" "tcpd.h" "ac_cv_header_tcpd_h" "$ac_includes_default" ++if test "x$ac_cv_header_tcpd_h" = x""yes; then : ++ cat >>confdefs.h <<_ACEOF ++#define HAVE_TCPD_H 1 + _ACEOF +- set X `eval "$ac_cpp -P conftest.$ac_ext" | $EGREP __db_version` none none +- ol_cv_bdb_minor=${3} +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_bdb_minor" >&5 +-$as_echo "$ol_cv_bdb_minor" >&6; } +-case $ol_cv_bdb_minor in [0-9]*) : ;; *) +- as_fn_error $? "Unknown Berkeley DB minor version in db.h" "$LINENO" 5 ;; +-esac + +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Berkeley DB version supported by BDB/HDB backends" >&5 +-$as_echo_n "checking if Berkeley DB version supported by BDB/HDB backends... " >&6; } +-if ${ol_cv_bdb_compat+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TCP wrappers library" >&5 ++$as_echo_n "checking for TCP wrappers library... " >&6; } ++ save_LIBS="$LIBS" ++ LIBS="$LIBS -lwrap" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + +-#include ++#include ++int allow_severity = 0; ++int deny_severity = 0; + +- /* this check could be improved */ +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif +-#ifndef DB_VERSION_MINOR +-# define DB_VERSION_MINOR 0 +-#endif +-#ifndef DB_VERSION_PATCH +-# define DB_VERSION_PATCH 0 +-#endif ++struct request_info *req; + +-#define DB_VERSION_FULL ((DB_VERSION_MAJOR<<16)|(DB_VERSION_MINOR<<8)|DB_VERSION_PATCH) ++int ++main () ++{ + +-/* require 4.4 or later, but less than 6.0.20 */ +-#if DB_VERSION_FULL >= 0x040400 && DB_VERSION_FULL < 0x060014 +- __db_version_compat +-#endif +-#if DB_VERSION_FULL >= 0x060014 +-#error "BerkeleyDB 6.0.20+ license is incompatible with LDAP" +-#endif ++hosts_access(req) + ++ ; ++ return 0; ++} + _ACEOF +-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | +- $EGREP "__db_version_compat" >/dev/null 2>&1; then : +- ol_cv_bdb_compat=yes +-else +- ol_cv_bdb_compat=no +-fi +-rm -f conftest* +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_bdb_compat" >&5 +-$as_echo "$ol_cv_bdb_compat" >&6; } +- +- +- if test $ol_cv_bdb_compat != yes ; then +- as_fn_error $? "BerkeleyDB version incompatible with BDB/HDB backends" "$LINENO" 5 +- fi +- +- ol_cv_lib_db=no +- +-if test $ol_cv_bdb_major = 5 ; then +- if test $ol_cv_lib_db = no ; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb-5.$ol_cv_bdb_minor)" >&5 +-$as_echo_n "checking for Berkeley DB link (-ldb-5.$ol_cv_bdb_minor)... " >&6; } +-if ${ol_cv_db_db_5_dot_m+:} false; then : +- $as_echo_n "(cached) " >&6 ++if ac_fn_c_try_link "$LINENO"; then : ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: -lwrap" >&5 ++$as_echo "-lwrap" >&6; } ++ have_wrappers=yes ++ LIBS="$save_LIBS" + else +- +- ol_DB_LIB=-ldb-5.$ol_cv_bdb_minor +- ol_LIBS=$LIBS +- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++ LIBS="$LIBS -lnsl" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + +-#ifdef HAVE_DB_185_H +-# include +-#else +-# include +-#endif +- +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif ++#include ++int allow_severity = 0; ++int deny_severity = 0; + +-#ifndef NULL +-#define NULL ((void*)0) +-#endif ++struct request_info *req; + + int + main () + { + +-#if DB_VERSION_MAJOR > 2 +- db_env_create( NULL, 0 ); +-#elif DB_VERSION_MAJOR > 1 +- db_appexit( NULL ); +-#else +- (void) dbopen( NULL, 0, 0, 0, NULL); +-#endif ++hosts_access(req) + + ; + return 0; + } + _ACEOF + if ac_fn_c_try_link "$LINENO"; then : +- ol_cv_db_db_5_dot_m=yes ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: -lwrap -lnsl" >&5 ++$as_echo "-lwrap -lnsl" >&6; } ++ have_wrappers=yes ++ LIBS="$save_LIBS -lnsl" + else +- ol_cv_db_db_5_dot_m=no ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++ have_wrappers=no ++ LIBS=$save_LIBS + fi + rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +- +- LIBS="$ol_LIBS" +- + fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db_5_dot_m" >&5 +-$as_echo "$ol_cv_db_db_5_dot_m" >&6; } +- +- if test $ol_cv_db_db_5_dot_m = yes ; then +- ol_cv_lib_db=-ldb-5.$ol_cv_bdb_minor +- fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++else ++ have_wrappers=no + fi + +- if test $ol_cv_lib_db = no ; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb5$ol_cv_bdb_minor)" >&5 +-$as_echo_n "checking for Berkeley DB link (-ldb5$ol_cv_bdb_minor)... " >&6; } +-if ${ol_cv_db_db5m+:} false; then : +- $as_echo_n "(cached) " >&6 +-else ++done + +- ol_DB_LIB=-ldb5$ol_cv_bdb_minor +- ol_LIBS=$LIBS +- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" + +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ ++ if test $have_wrappers = yes ; then + +-#ifdef HAVE_DB_185_H +-# include +-#else +-# include +-#endif ++$as_echo "#define HAVE_TCPD 1" >>confdefs.h + +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif ++ WRAP_LIBS="-lwrap" ++ elif test $ol_enable_wrappers = yes ; then ++ as_fn_error "could not find TCP wrappers, select appropriate options or disable" "$LINENO" 5 ++ else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: could not find TCP wrappers, support disabled" >&5 ++$as_echo "$as_me: WARNING: could not find TCP wrappers, support disabled" >&2;} ++ WRAP_LIBS="" ++ fi ++fi + +-#ifndef NULL +-#define NULL ((void*)0) +-#endif ++if test $ol_enable_syslog != no ; then ++ ac_fn_c_check_func "$LINENO" "openlog" "ac_cv_func_openlog" ++if test "x$ac_cv_func_openlog" = x""yes; then : + +-int +-main () +-{ ++fi + +-#if DB_VERSION_MAJOR > 2 +- db_env_create( NULL, 0 ); +-#elif DB_VERSION_MAJOR > 1 +- db_appexit( NULL ); +-#else +- (void) dbopen( NULL, 0, 0, 0, NULL); +-#endif ++ if test $ac_cv_func_openlog = no && test $ol_enable_syslog = yes; then ++ { as_fn_set_status select appropriate options or disable ++as_fn_error "could not find syslog" "$LINENO" 5; } ++ fi ++ ol_enable_syslog=$ac_cv_func_openlog ++fi + +- ; +- return 0; +-} ++ol_link_sql=no ++if test $ol_enable_sql != no ; then ++ for ac_header in sql.h sqlext.h ++do : ++ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ++ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" ++eval as_val=\$$as_ac_Header ++ if test "x$as_val" = x""yes; then : ++ cat >>confdefs.h <<_ACEOF ++#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 + _ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ol_cv_db_db5m=yes ++ + else +- ol_cv_db_db5m=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext + +- LIBS="$ol_LIBS" ++ as_fn_error "could not locate SQL headers" "$LINENO" 5 + + fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db5m" >&5 +-$as_echo "$ol_cv_db_db5m" >&6; } + +- if test $ol_cv_db_db5m = yes ; then +- ol_cv_lib_db=-ldb5$ol_cv_bdb_minor ++done ++ ++ ++ sql_LIBS="$LIBS" ++ LIBS="$LTHREAD_LIBS $LIBS" ++ ++ if test $ol_with_odbc = auto ; then ++ ol_with_odbc="iodbc unixodbc odbc32" + fi +-fi + +- if test $ol_cv_lib_db = no ; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb-5$ol_cv_bdb_minor)" >&5 +-$as_echo_n "checking for Berkeley DB link (-ldb-5$ol_cv_bdb_minor)... " >&6; } +-if ${ol_cv_db_db_5m+:} false; then : ++ for odbc in $ol_with_odbc ; do ++ if test $ol_link_sql = no ; then ++ case $odbc in ++ iodbc) ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SQLDriverConnect in -liodbc" >&5 ++$as_echo_n "checking for SQLDriverConnect in -liodbc... " >&6; } ++if test "${ac_cv_lib_iodbc_SQLDriverConnect+set}" = set; then : + $as_echo_n "(cached) " >&6 + else +- +- ol_DB_LIB=-ldb-5$ol_cv_bdb_minor +- ol_LIBS=$LIBS +- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-liodbc $LIBS" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + +-#ifdef HAVE_DB_185_H +-# include +-#else +-# include +-#endif +- +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif +- +-#ifndef NULL +-#define NULL ((void*)0) ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" + #endif +- ++char SQLDriverConnect (); + int + main () + { +- +-#if DB_VERSION_MAJOR > 2 +- db_env_create( NULL, 0 ); +-#elif DB_VERSION_MAJOR > 1 +- db_appexit( NULL ); +-#else +- (void) dbopen( NULL, 0, 0, 0, NULL); +-#endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ol_cv_db_db_5m=yes +-else +- ol_cv_db_db_5m=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- +- LIBS="$ol_LIBS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db_5m" >&5 +-$as_echo "$ol_cv_db_db_5m" >&6; } +- +- if test $ol_cv_db_db_5m = yes ; then +- ol_cv_lib_db=-ldb-5$ol_cv_bdb_minor +- fi +-fi +- +- if test $ol_cv_lib_db = no ; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb-5-$ol_cv_bdb_minor)" >&5 +-$as_echo_n "checking for Berkeley DB link (-ldb-5-$ol_cv_bdb_minor)... " >&6; } +-if ${ol_cv_db_db_5_m+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- ol_DB_LIB=-ldb-5-$ol_cv_bdb_minor +- ol_LIBS=$LIBS +- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#ifdef HAVE_DB_185_H +-# include +-#else +-# include +-#endif +- +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif +- +-#ifndef NULL +-#define NULL ((void*)0) +-#endif +- +-int +-main () +-{ +- +-#if DB_VERSION_MAJOR > 2 +- db_env_create( NULL, 0 ); +-#elif DB_VERSION_MAJOR > 1 +- db_appexit( NULL ); +-#else +- (void) dbopen( NULL, 0, 0, 0, NULL); +-#endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ol_cv_db_db_5_m=yes +-else +- ol_cv_db_db_5_m=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- +- LIBS="$ol_LIBS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db_5_m" >&5 +-$as_echo "$ol_cv_db_db_5_m" >&6; } +- +- if test $ol_cv_db_db_5_m = yes ; then +- ol_cv_lib_db=-ldb-5-$ol_cv_bdb_minor +- fi +-fi +- +- if test $ol_cv_lib_db = no ; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb-5)" >&5 +-$as_echo_n "checking for Berkeley DB link (-ldb-5)... " >&6; } +-if ${ol_cv_db_db_5+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- ol_DB_LIB=-ldb-5 +- ol_LIBS=$LIBS +- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#ifdef HAVE_DB_185_H +-# include +-#else +-# include +-#endif +- +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif +- +-#ifndef NULL +-#define NULL ((void*)0) +-#endif +- +-int +-main () +-{ +- +-#if DB_VERSION_MAJOR > 2 +- db_env_create( NULL, 0 ); +-#elif DB_VERSION_MAJOR > 1 +- db_appexit( NULL ); +-#else +- (void) dbopen( NULL, 0, 0, 0, NULL); +-#endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ol_cv_db_db_5=yes +-else +- ol_cv_db_db_5=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- +- LIBS="$ol_LIBS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db_5" >&5 +-$as_echo "$ol_cv_db_db_5" >&6; } +- +- if test $ol_cv_db_db_5 = yes ; then +- ol_cv_lib_db=-ldb-5 +- fi +-fi +- +- if test $ol_cv_lib_db = no ; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb5)" >&5 +-$as_echo_n "checking for Berkeley DB link (-ldb5)... " >&6; } +-if ${ol_cv_db_db5+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- ol_DB_LIB=-ldb5 +- ol_LIBS=$LIBS +- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#ifdef HAVE_DB_185_H +-# include +-#else +-# include +-#endif +- +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif +- +-#ifndef NULL +-#define NULL ((void*)0) +-#endif +- +-int +-main () +-{ +- +-#if DB_VERSION_MAJOR > 2 +- db_env_create( NULL, 0 ); +-#elif DB_VERSION_MAJOR > 1 +- db_appexit( NULL ); +-#else +- (void) dbopen( NULL, 0, 0, 0, NULL); +-#endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ol_cv_db_db5=yes +-else +- ol_cv_db_db5=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- +- LIBS="$ol_LIBS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db5" >&5 +-$as_echo "$ol_cv_db_db5" >&6; } +- +- if test $ol_cv_db_db5 = yes ; then +- ol_cv_lib_db=-ldb5 +- fi +-fi +- +-elif test $ol_cv_bdb_major = 4 ; then +- if test $ol_cv_lib_db = no ; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb-4.$ol_cv_bdb_minor)" >&5 +-$as_echo_n "checking for Berkeley DB link (-ldb-4.$ol_cv_bdb_minor)... " >&6; } +-if ${ol_cv_db_db_4_dot_m+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- ol_DB_LIB=-ldb-4.$ol_cv_bdb_minor +- ol_LIBS=$LIBS +- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#ifdef HAVE_DB_185_H +-# include +-#else +-# include +-#endif +- +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif +- +-#ifndef NULL +-#define NULL ((void*)0) +-#endif +- +-int +-main () +-{ +- +-#if DB_VERSION_MAJOR > 2 +- db_env_create( NULL, 0 ); +-#elif DB_VERSION_MAJOR > 1 +- db_appexit( NULL ); +-#else +- (void) dbopen( NULL, 0, 0, 0, NULL); +-#endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ol_cv_db_db_4_dot_m=yes +-else +- ol_cv_db_db_4_dot_m=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- +- LIBS="$ol_LIBS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db_4_dot_m" >&5 +-$as_echo "$ol_cv_db_db_4_dot_m" >&6; } +- +- if test $ol_cv_db_db_4_dot_m = yes ; then +- ol_cv_lib_db=-ldb-4.$ol_cv_bdb_minor +- fi +-fi +- +- if test $ol_cv_lib_db = no ; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb4$ol_cv_bdb_minor)" >&5 +-$as_echo_n "checking for Berkeley DB link (-ldb4$ol_cv_bdb_minor)... " >&6; } +-if ${ol_cv_db_db4m+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- ol_DB_LIB=-ldb4$ol_cv_bdb_minor +- ol_LIBS=$LIBS +- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#ifdef HAVE_DB_185_H +-# include +-#else +-# include +-#endif +- +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif +- +-#ifndef NULL +-#define NULL ((void*)0) +-#endif +- +-int +-main () +-{ +- +-#if DB_VERSION_MAJOR > 2 +- db_env_create( NULL, 0 ); +-#elif DB_VERSION_MAJOR > 1 +- db_appexit( NULL ); +-#else +- (void) dbopen( NULL, 0, 0, 0, NULL); +-#endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ol_cv_db_db4m=yes +-else +- ol_cv_db_db4m=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- +- LIBS="$ol_LIBS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db4m" >&5 +-$as_echo "$ol_cv_db_db4m" >&6; } +- +- if test $ol_cv_db_db4m = yes ; then +- ol_cv_lib_db=-ldb4$ol_cv_bdb_minor +- fi +-fi +- +- if test $ol_cv_lib_db = no ; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb-4$ol_cv_bdb_minor)" >&5 +-$as_echo_n "checking for Berkeley DB link (-ldb-4$ol_cv_bdb_minor)... " >&6; } +-if ${ol_cv_db_db_4m+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- ol_DB_LIB=-ldb-4$ol_cv_bdb_minor +- ol_LIBS=$LIBS +- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#ifdef HAVE_DB_185_H +-# include +-#else +-# include +-#endif +- +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif +- +-#ifndef NULL +-#define NULL ((void*)0) +-#endif +- +-int +-main () +-{ +- +-#if DB_VERSION_MAJOR > 2 +- db_env_create( NULL, 0 ); +-#elif DB_VERSION_MAJOR > 1 +- db_appexit( NULL ); +-#else +- (void) dbopen( NULL, 0, 0, 0, NULL); +-#endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ol_cv_db_db_4m=yes +-else +- ol_cv_db_db_4m=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- +- LIBS="$ol_LIBS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db_4m" >&5 +-$as_echo "$ol_cv_db_db_4m" >&6; } +- +- if test $ol_cv_db_db_4m = yes ; then +- ol_cv_lib_db=-ldb-4$ol_cv_bdb_minor +- fi +-fi +- +- if test $ol_cv_lib_db = no ; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb-4-$ol_cv_bdb_minor)" >&5 +-$as_echo_n "checking for Berkeley DB link (-ldb-4-$ol_cv_bdb_minor)... " >&6; } +-if ${ol_cv_db_db_4_m+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- ol_DB_LIB=-ldb-4-$ol_cv_bdb_minor +- ol_LIBS=$LIBS +- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#ifdef HAVE_DB_185_H +-# include +-#else +-# include +-#endif +- +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif +- +-#ifndef NULL +-#define NULL ((void*)0) +-#endif +- +-int +-main () +-{ +- +-#if DB_VERSION_MAJOR > 2 +- db_env_create( NULL, 0 ); +-#elif DB_VERSION_MAJOR > 1 +- db_appexit( NULL ); +-#else +- (void) dbopen( NULL, 0, 0, 0, NULL); +-#endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ol_cv_db_db_4_m=yes +-else +- ol_cv_db_db_4_m=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- +- LIBS="$ol_LIBS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db_4_m" >&5 +-$as_echo "$ol_cv_db_db_4_m" >&6; } +- +- if test $ol_cv_db_db_4_m = yes ; then +- ol_cv_lib_db=-ldb-4-$ol_cv_bdb_minor +- fi +-fi +- +- if test $ol_cv_lib_db = no ; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb-4)" >&5 +-$as_echo_n "checking for Berkeley DB link (-ldb-4)... " >&6; } +-if ${ol_cv_db_db_4+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- ol_DB_LIB=-ldb-4 +- ol_LIBS=$LIBS +- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#ifdef HAVE_DB_185_H +-# include +-#else +-# include +-#endif +- +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif +- +-#ifndef NULL +-#define NULL ((void*)0) +-#endif +- +-int +-main () +-{ +- +-#if DB_VERSION_MAJOR > 2 +- db_env_create( NULL, 0 ); +-#elif DB_VERSION_MAJOR > 1 +- db_appexit( NULL ); +-#else +- (void) dbopen( NULL, 0, 0, 0, NULL); +-#endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ol_cv_db_db_4=yes +-else +- ol_cv_db_db_4=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- +- LIBS="$ol_LIBS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db_4" >&5 +-$as_echo "$ol_cv_db_db_4" >&6; } +- +- if test $ol_cv_db_db_4 = yes ; then +- ol_cv_lib_db=-ldb-4 +- fi +-fi +- +- if test $ol_cv_lib_db = no ; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb4)" >&5 +-$as_echo_n "checking for Berkeley DB link (-ldb4)... " >&6; } +-if ${ol_cv_db_db4+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- ol_DB_LIB=-ldb4 +- ol_LIBS=$LIBS +- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#ifdef HAVE_DB_185_H +-# include +-#else +-# include +-#endif +- +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif +- +-#ifndef NULL +-#define NULL ((void*)0) +-#endif +- +-int +-main () +-{ +- +-#if DB_VERSION_MAJOR > 2 +- db_env_create( NULL, 0 ); +-#elif DB_VERSION_MAJOR > 1 +- db_appexit( NULL ); +-#else +- (void) dbopen( NULL, 0, 0, 0, NULL); +-#endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ol_cv_db_db4=yes +-else +- ol_cv_db_db4=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- +- LIBS="$ol_LIBS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db4" >&5 +-$as_echo "$ol_cv_db_db4" >&6; } +- +- if test $ol_cv_db_db4 = yes ; then +- ol_cv_lib_db=-ldb4 +- fi +-fi +- +-fi +-if test $ol_cv_lib_db = no ; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb)" >&5 +-$as_echo_n "checking for Berkeley DB link (-ldb)... " >&6; } +-if ${ol_cv_db_db+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- ol_DB_LIB=-ldb +- ol_LIBS=$LIBS +- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#ifdef HAVE_DB_185_H +-# include +-#else +-# include +-#endif +- +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif +- +-#ifndef NULL +-#define NULL ((void*)0) +-#endif +- +-int +-main () +-{ +- +-#if DB_VERSION_MAJOR > 2 +- db_env_create( NULL, 0 ); +-#elif DB_VERSION_MAJOR > 1 +- db_appexit( NULL ); +-#else +- (void) dbopen( NULL, 0, 0, 0, NULL); +-#endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ol_cv_db_db=yes +-else +- ol_cv_db_db=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- +- LIBS="$ol_LIBS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db" >&5 +-$as_echo "$ol_cv_db_db" >&6; } +- +- if test $ol_cv_db_db = yes ; then +- ol_cv_lib_db=-ldb +- fi +-fi +- +-if test $ol_cv_lib_db = no ; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (default)" >&5 +-$as_echo_n "checking for Berkeley DB link (default)... " >&6; } +-if ${ol_cv_db_none+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- ol_DB_LIB= +- ol_LIBS=$LIBS +- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#ifdef HAVE_DB_185_H +-# include +-#else +-# include +-#endif +- +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif +- +-#ifndef NULL +-#define NULL ((void*)0) +-#endif +- +-int +-main () +-{ +- +-#if DB_VERSION_MAJOR > 2 +- db_env_create( NULL, 0 ); +-#elif DB_VERSION_MAJOR > 1 +- db_appexit( NULL ); +-#else +- (void) dbopen( NULL, 0, 0, 0, NULL); +-#endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ol_cv_db_none=yes +-else +- ol_cv_db_none=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- +- LIBS="$ol_LIBS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_none" >&5 +-$as_echo "$ol_cv_db_none" >&6; } +- +- if test $ol_cv_db_none = yes ; then +- ol_cv_lib_db=yes +- fi +-fi +- +- +- if test "$ol_cv_lib_db" != no ; then +- ol_cv_berkeley_db=yes +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB library and header version match" >&5 +-$as_echo_n "checking for Berkeley DB library and header version match... " >&6; } +-if ${ol_cv_berkeley_db_version+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- ol_LIBS="$LIBS" +- LIBS="$LTHREAD_LIBS $LIBS" +- if test $ol_cv_lib_db != yes ; then +- LIBS="$ol_cv_lib_db $LIBS" +- fi +- +- if test "$cross_compiling" = yes; then : +- ol_cv_berkeley_db_version=cross +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#ifdef HAVE_DB_185_H +- choke me; +-#else +-#include +-#endif +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif +-#ifndef NULL +-#define NULL ((void *)0) +-#endif +-main() +-{ +-#if DB_VERSION_MAJOR > 1 +- char *version; +- int major, minor, patch; +- +- version = db_version( &major, &minor, &patch ); +- +- if( major != DB_VERSION_MAJOR || +- minor != DB_VERSION_MINOR || +- patch != DB_VERSION_PATCH ) +- { +- printf("Berkeley DB version mismatch\n" +- "\theader: %s\n\tlibrary: %s\n", +- DB_VERSION_STRING, version); +- return 1; +- } +-#endif +- +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_run "$LINENO"; then : +- ol_cv_berkeley_db_version=yes +-else +- ol_cv_berkeley_db_version=no +-fi +-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext +-fi +- +- +- LIBS="$ol_LIBS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_berkeley_db_version" >&5 +-$as_echo "$ol_cv_berkeley_db_version" >&6; } +- +- if test $ol_cv_berkeley_db_version = no ; then +- as_fn_error $? "Berkeley DB version mismatch" "$LINENO" 5 +- fi +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB thread support" >&5 +-$as_echo_n "checking for Berkeley DB thread support... " >&6; } +-if ${ol_cv_berkeley_db_thread+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- ol_LIBS="$LIBS" +- LIBS="$LTHREAD_LIBS $LIBS" +- if test $ol_cv_lib_db != yes ; then +- LIBS="$ol_cv_lib_db $LIBS" +- fi +- +- if test "$cross_compiling" = yes; then : +- ol_cv_berkeley_db_thread=cross +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#ifdef HAVE_DB_185_H +- choke me; +-#else +-#include +-#endif +-#ifndef NULL +-#define NULL ((void *)0) +-#endif +-main() +-{ +- int rc; +- u_int32_t flags = DB_CREATE | +-#ifdef DB_PRIVATE +- DB_PRIVATE | +-#endif +- DB_THREAD; +- +-#if DB_VERSION_MAJOR > 2 +- DB_ENV *env = NULL; +- +- rc = db_env_create( &env, 0 ); +- +- flags |= DB_INIT_MPOOL; +-#ifdef DB_MPOOL_PRIVATE +- flags |= DB_MPOOL_PRIVATE; +-#endif +- +- if( rc ) { +- printf("BerkeleyDB: %s\n", db_strerror(rc) ); +- return rc; +- } +- +-#if (DB_VERSION_MAJOR > 3) || (DB_VERSION_MINOR >= 1) +- rc = (env->open)( env, NULL, flags, 0 ); +-#else +- rc = (env->open)( env, NULL, NULL, flags, 0 ); +-#endif +- +- if ( rc == 0 ) { +- rc = env->close( env, 0 ); +- } +- +- if( rc ) { +- printf("BerkeleyDB: %s\n", db_strerror(rc) ); +- return rc; +- } +- +-#else +- DB_ENV env; +- memset( &env, '\0', sizeof(env) ); +- +- rc = db_appinit( NULL, NULL, &env, flags ); +- +- if( rc == 0 ) { +- db_appexit( &env ); +- } +- +- unlink("__db_mpool.share"); +- unlink("__db_lock.share"); +-#endif +- +- return rc; +-} +-_ACEOF +-if ac_fn_c_try_run "$LINENO"; then : +- ol_cv_berkeley_db_thread=yes +-else +- ol_cv_berkeley_db_thread=no +-fi +-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext +-fi +- +- +- LIBS="$ol_LIBS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_berkeley_db_thread" >&5 +-$as_echo "$ol_cv_berkeley_db_thread" >&6; } +- +- if test $ol_cv_berkeley_db_thread != no ; then +- +-$as_echo "#define HAVE_BERKELEY_DB_THREAD 1" >>confdefs.h +- +- fi +- +- fi +-fi +- +- +- if test $ol_cv_berkeley_db = no ; then +- as_fn_error $? "BDB/HDB: BerkeleyDB not available" "$LINENO" 5 +- fi +- +- +-$as_echo "#define HAVE_BERKELEY_DB 1" >>confdefs.h +- +- +- if test $ol_cv_lib_db != yes ; then +- BDB_LIBS="$BDB_LIBS $ol_cv_lib_db" +- fi +- +- if test $ol_enable_bdb/$ol_enable_hdb != mod/mod ; then +- if test $ol_enable_bdb = yes -o $ol_enable_hdb = yes ; then +- SLAPD_LIBS="$SLAPD_LIBS \$(BDB_LIBS)" +- fi +- fi +- +- ol_link_bdb=yes +-fi +- +- +-if test $ol_enable_dynamic = yes && test $enable_shared = yes ; then +- BUILD_LIBS_DYNAMIC=shared +- +-$as_echo "#define LDAP_LIBS_DYNAMIC 1" >>confdefs.h +- +- LTSTATIC="" +-else +- BUILD_LIBS_DYNAMIC=static +- LTSTATIC="-static" +-fi +- +-if test $ol_enable_wrappers != no ; then +- for ac_header in tcpd.h +-do : +- ac_fn_c_check_header_mongrel "$LINENO" "tcpd.h" "ac_cv_header_tcpd_h" "$ac_includes_default" +-if test "x$ac_cv_header_tcpd_h" = xyes; then : +- cat >>confdefs.h <<_ACEOF +-#define HAVE_TCPD_H 1 +-_ACEOF +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TCP wrappers library" >&5 +-$as_echo_n "checking for TCP wrappers library... " >&6; } +- save_LIBS="$LIBS" +- LIBS="$LIBS -lwrap" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#include +-int allow_severity = 0; +-int deny_severity = 0; +- +-struct request_info *req; +- +-int +-main () +-{ +- +-hosts_access(req) +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: -lwrap" >&5 +-$as_echo "-lwrap" >&6; } +- have_wrappers=yes +- LIBS="$save_LIBS" +-else +- +- LIBS="$LIBS -lnsl" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#include +-int allow_severity = 0; +-int deny_severity = 0; +- +-struct request_info *req; +- +-int +-main () +-{ +- +-hosts_access(req) +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: -lwrap -lnsl" >&5 +-$as_echo "-lwrap -lnsl" >&6; } +- have_wrappers=yes +- LIBS="$save_LIBS -lnsl" +-else +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- have_wrappers=no +- LIBS=$save_LIBS +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +-else +- have_wrappers=no +-fi +- +-done +- +- +- if test $have_wrappers = yes ; then +- +-$as_echo "#define HAVE_TCPD 1" >>confdefs.h +- +- WRAP_LIBS="-lwrap" +- elif test $ol_enable_wrappers = yes ; then +- as_fn_error $? "could not find TCP wrappers, select apppropriate options or disable" "$LINENO" 5 +- else +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: could not find TCP wrappers, support disabled" >&5 +-$as_echo "$as_me: WARNING: could not find TCP wrappers, support disabled" >&2;} +- WRAP_LIBS="" +- fi +-fi +- +-if test $ol_enable_syslog != no ; then +- ac_fn_c_check_func "$LINENO" "openlog" "ac_cv_func_openlog" +-if test "x$ac_cv_func_openlog" = xyes; then : +- +-fi +- +- if test $ac_cv_func_openlog = no && test $ol_enable_syslog = yes; then +- as_fn_error select appropriate options or disable "could not find syslog" "$LINENO" 5 +- fi +- ol_enable_syslog=$ac_cv_func_openlog +-fi +- +-ol_link_sql=no +-if test $ol_enable_sql != no ; then +- for ac_header in sql.h sqlext.h +-do : +- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +-ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : +- cat >>confdefs.h <<_ACEOF +-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +-_ACEOF +- +-else +- +- as_fn_error $? "could not locate SQL headers" "$LINENO" 5 +- +-fi +- +-done +- +- +- sql_LIBS="$LIBS" +- LIBS="$LTHREAD_LIBS $LIBS" +- +- if test $ol_with_odbc = auto ; then +- ol_with_odbc="iodbc unixodbc odbc32" +- fi +- +- for odbc in $ol_with_odbc ; do +- if test $ol_link_sql = no ; then +- case $odbc in +- iodbc) +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SQLDriverConnect in -liodbc" >&5 +-$as_echo_n "checking for SQLDriverConnect in -liodbc... " >&6; } +-if ${ac_cv_lib_iodbc_SQLDriverConnect+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_check_lib_save_LIBS=$LIBS +-LIBS="-liodbc $LIBS" +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-/* Override any GCC internal prototype to avoid an error. +- Use char because int might match the return type of a GCC +- builtin and then its argument prototype would still apply. */ +-#ifdef __cplusplus +-extern "C" +-#endif +-char SQLDriverConnect (); +-int +-main () +-{ +-return SQLDriverConnect (); ++return SQLDriverConnect (); + ; + return 0; + } +@@ -26763,23 +25530,6 @@ _ACEOF + + fi + +-if test "$ol_enable_bdb" != no ; then +- BUILD_SLAPD=yes +- BUILD_BDB=$ol_enable_bdb +- if test "$ol_enable_bdb" = mod ; then +- SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-bdb" +- MFLAG=SLAPD_MOD_DYNAMIC +- else +- SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-bdb" +- MFLAG=SLAPD_MOD_STATIC +- fi +- +-cat >>confdefs.h <<_ACEOF +-#define SLAPD_BDB $MFLAG +-_ACEOF +- +-fi +- + if test "$ol_enable_dnssrv" != no ; then + BUILD_SLAPD=yes + BUILD_DNSSRV=$ol_enable_dnssrv +@@ -26797,23 +25547,6 @@ _ACEOF + + fi + +-if test "$ol_enable_hdb" != no ; then +- BUILD_SLAPD=yes +- BUILD_HDB=$ol_enable_hdb +- if test "$ol_enable_hdb" = mod ; then +- SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-hdb" +- MFLAG=SLAPD_MOD_DYNAMIC +- else +- SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-hdb" +- MFLAG=SLAPD_MOD_STATIC +- fi +- +-cat >>confdefs.h <<_ACEOF +-#define SLAPD_HDB $MFLAG +-_ACEOF +- +-fi +- + if test "$ol_enable_ldap" != no ; then + BUILD_SLAPD=yes + BUILD_LDAP=$ol_enable_ldap +@@ -27447,7 +26180,7 @@ fi + + + +-ac_config_files="$ac_config_files Makefile:build/top.mk:Makefile.in:build/dir.mk doc/Makefile:build/top.mk:doc/Makefile.in:build/dir.mk doc/man/Makefile:build/top.mk:doc/man/Makefile.in:build/dir.mk doc/man/man1/Makefile:build/top.mk:doc/man/man1/Makefile.in:build/man.mk doc/man/man3/Makefile:build/top.mk:doc/man/man3/Makefile.in:build/man.mk doc/man/man5/Makefile:build/top.mk:doc/man/man5/Makefile.in:build/man.mk doc/man/man8/Makefile:build/top.mk:doc/man/man8/Makefile.in:build/man.mk clients/Makefile:build/top.mk:clients/Makefile.in:build/dir.mk clients/tools/Makefile:build/top.mk:clients/tools/Makefile.in:build/rules.mk include/Makefile:build/top.mk:include/Makefile.in libraries/Makefile:build/top.mk:libraries/Makefile.in:build/dir.mk libraries/liblber/Makefile:build/top.mk:libraries/liblber/Makefile.in:build/lib.mk:build/lib-shared.mk libraries/libldap/Makefile:build/top.mk:libraries/libldap/Makefile.in:build/lib.mk:build/lib-shared.mk libraries/libldap_r/Makefile:build/top.mk:libraries/libldap_r/Makefile.in:build/lib.mk:build/lib-shared.mk libraries/liblunicode/Makefile:build/top.mk:libraries/liblunicode/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 libraries/librewrite/Makefile:build/top.mk:libraries/librewrite/Makefile.in:build/lib.mk:build/lib-static.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/back-bdb/Makefile:build/top.mk:servers/slapd/back-bdb/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-hdb/Makefile:build/top.mk:servers/slapd/back-hdb/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-ldif/Makefile:build/top.mk:servers/slapd/back-ldif/Makefile.in:build/mod.mk servers/slapd/back-mdb/Makefile:build/top.mk:servers/slapd/back-mdb/Makefile.in:build/mod.mk servers/slapd/back-meta/Makefile:build/top.mk:servers/slapd/back-meta/Makefile.in:build/mod.mk servers/slapd/back-monitor/Makefile:build/top.mk:servers/slapd/back-monitor/Makefile.in:build/mod.mk servers/slapd/back-ndb/Makefile:build/top.mk:servers/slapd/back-ndb/Makefile.in:build/mod.mk servers/slapd/back-null/Makefile:build/top.mk:servers/slapd/back-null/Makefile.in:build/mod.mk servers/slapd/back-passwd/Makefile:build/top.mk:servers/slapd/back-passwd/Makefile.in:build/mod.mk servers/slapd/back-perl/Makefile:build/top.mk:servers/slapd/back-perl/Makefile.in:build/mod.mk servers/slapd/back-relay/Makefile:build/top.mk:servers/slapd/back-relay/Makefile.in:build/mod.mk servers/slapd/back-shell/Makefile:build/top.mk:servers/slapd/back-shell/Makefile.in:build/mod.mk servers/slapd/back-sock/Makefile:build/top.mk:servers/slapd/back-sock/Makefile.in:build/mod.mk servers/slapd/back-sql/Makefile:build/top.mk:servers/slapd/back-sql/Makefile.in:build/mod.mk servers/slapd/shell-backends/Makefile:build/top.mk:servers/slapd/shell-backends/Makefile.in:build/srv.mk servers/slapd/slapi/Makefile:build/top.mk:servers/slapd/slapi/Makefile.in:build/lib.mk:build/lib-shared.mk servers/slapd/overlays/Makefile:build/top.mk:servers/slapd/overlays/Makefile.in:build/lib.mk tests/Makefile:build/top.mk:tests/Makefile.in:build/dir.mk tests/run tests/progs/Makefile:build/top.mk:tests/progs/Makefile.in:build/rules.mk" ++ac_config_files="$ac_config_files Makefile:build/top.mk:Makefile.in:build/dir.mk doc/Makefile:build/top.mk:doc/Makefile.in:build/dir.mk doc/man/Makefile:build/top.mk:doc/man/Makefile.in:build/dir.mk doc/man/man1/Makefile:build/top.mk:doc/man/man1/Makefile.in:build/man.mk doc/man/man3/Makefile:build/top.mk:doc/man/man3/Makefile.in:build/man.mk doc/man/man5/Makefile:build/top.mk:doc/man/man5/Makefile.in:build/man.mk doc/man/man8/Makefile:build/top.mk:doc/man/man8/Makefile.in:build/man.mk clients/Makefile:build/top.mk:clients/Makefile.in:build/dir.mk clients/tools/Makefile:build/top.mk:clients/tools/Makefile.in:build/rules.mk include/Makefile:build/top.mk:include/Makefile.in libraries/Makefile:build/top.mk:libraries/Makefile.in:build/dir.mk libraries/liblber/Makefile:build/top.mk:libraries/liblber/Makefile.in:build/lib.mk:build/lib-shared.mk libraries/libldap/Makefile:build/top.mk:libraries/libldap/Makefile.in:build/lib.mk:build/lib-shared.mk libraries/libldap_r/Makefile:build/top.mk:libraries/libldap_r/Makefile.in:build/lib.mk:build/lib-shared.mk libraries/liblunicode/Makefile:build/top.mk:libraries/liblunicode/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 libraries/librewrite/Makefile:build/top.mk:libraries/librewrite/Makefile.in:build/lib.mk:build/lib-static.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/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-ldif/Makefile:build/top.mk:servers/slapd/back-ldif/Makefile.in:build/mod.mk servers/slapd/back-mdb/Makefile:build/top.mk:servers/slapd/back-mdb/Makefile.in:build/mod.mk servers/slapd/back-meta/Makefile:build/top.mk:servers/slapd/back-meta/Makefile.in:build/mod.mk servers/slapd/back-monitor/Makefile:build/top.mk:servers/slapd/back-monitor/Makefile.in:build/mod.mk servers/slapd/back-ndb/Makefile:build/top.mk:servers/slapd/back-ndb/Makefile.in:build/mod.mk servers/slapd/back-null/Makefile:build/top.mk:servers/slapd/back-null/Makefile.in:build/mod.mk servers/slapd/back-passwd/Makefile:build/top.mk:servers/slapd/back-passwd/Makefile.in:build/mod.mk servers/slapd/back-perl/Makefile:build/top.mk:servers/slapd/back-perl/Makefile.in:build/mod.mk servers/slapd/back-relay/Makefile:build/top.mk:servers/slapd/back-relay/Makefile.in:build/mod.mk servers/slapd/back-shell/Makefile:build/top.mk:servers/slapd/back-shell/Makefile.in:build/mod.mk servers/slapd/back-sock/Makefile:build/top.mk:servers/slapd/back-sock/Makefile.in:build/mod.mk servers/slapd/back-sql/Makefile:build/top.mk:servers/slapd/back-sql/Makefile.in:build/mod.mk servers/slapd/shell-backends/Makefile:build/top.mk:servers/slapd/shell-backends/Makefile.in:build/srv.mk servers/slapd/slapi/Makefile:build/top.mk:servers/slapd/slapi/Makefile.in:build/lib.mk:build/lib-shared.mk servers/slapd/overlays/Makefile:build/top.mk:servers/slapd/overlays/Makefile.in:build/lib.mk tests/Makefile:build/top.mk:tests/Makefile.in:build/dir.mk tests/run tests/progs/Makefile:build/top.mk:tests/progs/Makefile.in:build/rules.mk" + + + ac_config_commands="$ac_config_commands default" +@@ -28411,9 +27144,7 @@ do + "libraries/librewrite/Makefile") CONFIG_FILES="$CONFIG_FILES libraries/librewrite/Makefile:build/top.mk:libraries/librewrite/Makefile.in:build/lib.mk:build/lib-static.mk" ;; + "servers/Makefile") CONFIG_FILES="$CONFIG_FILES servers/Makefile:build/top.mk:servers/Makefile.in:build/dir.mk" ;; + "servers/slapd/Makefile") CONFIG_FILES="$CONFIG_FILES servers/slapd/Makefile:build/top.mk:servers/slapd/Makefile.in:build/srv.mk" ;; +- "servers/slapd/back-bdb/Makefile") CONFIG_FILES="$CONFIG_FILES servers/slapd/back-bdb/Makefile:build/top.mk:servers/slapd/back-bdb/Makefile.in:build/mod.mk" ;; + "servers/slapd/back-dnssrv/Makefile") CONFIG_FILES="$CONFIG_FILES servers/slapd/back-dnssrv/Makefile:build/top.mk:servers/slapd/back-dnssrv/Makefile.in:build/mod.mk" ;; +- "servers/slapd/back-hdb/Makefile") CONFIG_FILES="$CONFIG_FILES servers/slapd/back-hdb/Makefile:build/top.mk:servers/slapd/back-hdb/Makefile.in:build/mod.mk" ;; + "servers/slapd/back-ldap/Makefile") CONFIG_FILES="$CONFIG_FILES servers/slapd/back-ldap/Makefile:build/top.mk:servers/slapd/back-ldap/Makefile.in:build/mod.mk" ;; + "servers/slapd/back-ldif/Makefile") CONFIG_FILES="$CONFIG_FILES servers/slapd/back-ldif/Makefile:build/top.mk:servers/slapd/back-ldif/Makefile.in:build/mod.mk" ;; + "servers/slapd/back-mdb/Makefile") CONFIG_FILES="$CONFIG_FILES servers/slapd/back-mdb/Makefile:build/top.mk:servers/slapd/back-mdb/Makefile.in:build/mod.mk" ;; +-- +2.19.1 + diff --git a/backport-delete-back-bdb-back-hdb.patch b/backport-delete-back-bdb-back-hdb.patch new file mode 100644 index 0000000..6eb148b --- /dev/null +++ b/backport-delete-back-bdb-back-hdb.patch @@ -0,0 +1,22206 @@ +From 8897fff4f352923b91e776bf9bc0bf8dbd636e85 Mon Sep 17 00:00:00 2001 +From: zhangqiumiao +Date: Fri, 25 Sep 2020 21:54:05 +0800 +Subject: [PATCH] backport delete back-bdb/back-hdb + +--- + INSTALL | 3 - + build/openldap.m4 | 292 --- + build/top.mk | 1 - + configure.in | 74 +- + contrib/slapd-modules/allowed/allowed.c | 2 +- + contrib/slapd-modules/nssov/README | 4 +- + contrib/slapd-modules/nssov/slapo-nssov.5 | 2 +- + doc/guide/admin/appendix-changes.sdf | 27 +- + doc/guide/admin/appendix-common-errors.sdf | 10 +- + doc/guide/admin/aspell.en.pws | 7 - + doc/guide/admin/backends.sdf | 47 +- + doc/guide/admin/install.sdf | 17 - + doc/guide/admin/intro.sdf | 12 +- + doc/guide/admin/maintenance.sdf | 86 +- + doc/guide/admin/monitoringslapd.sdf | 25 +- + doc/guide/admin/overlays.sdf | 6 +- + doc/guide/admin/replication.sdf | 12 +- + doc/guide/admin/slapdconf2.sdf | 237 +-- + doc/guide/admin/slapdconfig.sdf | 218 ++- + doc/guide/admin/tuning.sdf | 175 +- + doc/guide/preamble.sdf | 2 - + doc/guide/release/install.sdf | 2 +- + doc/man/man5/slapd-bdb.5 | 286 --- + doc/man/man5/slapd-bdb.5.links | 1 - + doc/man/man5/slapd-config.5 | 8 +- + doc/man/man5/slapd-mdb.5 | 7 +- + doc/man/man5/slapd-sql.5 | 2 +- + doc/man/man5/slapd.access.5 | 9 +- + doc/man/man5/slapd.backends.5 | 35 +- + doc/man/man5/slapd.conf.5 | 7 +- + doc/man/man5/slapd.overlays.5 | 6 +- + doc/man/man8/slapcat.8 | 2 - + doc/man/man8/slapschema.8 | 3 +- + include/portable.hin | 12 - + servers/slapd/DB_CONFIG | 28 - + servers/slapd/Makefile.in | 12 +- + servers/slapd/alock.c | 718 ------- + servers/slapd/alock.h | 74 - + servers/slapd/back-bdb/Makefile.in | 53 - + servers/slapd/back-bdb/add.c | 547 ------ + servers/slapd/back-bdb/attr.c | 441 ----- + servers/slapd/back-bdb/back-bdb.h | 377 ---- + servers/slapd/back-bdb/bind.c | 166 -- + servers/slapd/back-bdb/cache.c | 1692 ----------------- + servers/slapd/back-bdb/compare.c | 143 -- + servers/slapd/back-bdb/config.c | 951 --------- + servers/slapd/back-bdb/dbcache.c | 210 -- + servers/slapd/back-bdb/delete.c | 605 ------ + servers/slapd/back-bdb/dn2entry.c | 84 - + servers/slapd/back-bdb/dn2id.c | 1215 ------------ + servers/slapd/back-bdb/error.c | 62 - + servers/slapd/back-bdb/extended.c | 54 - + servers/slapd/back-bdb/filterindex.c | 1183 ------------ + servers/slapd/back-bdb/id2entry.c | 446 ----- + servers/slapd/back-bdb/idl.c | 1570 --------------- + servers/slapd/back-bdb/idl.h | 75 - + servers/slapd/back-bdb/index.c | 574 ------ + servers/slapd/back-bdb/init.c | 874 --------- + servers/slapd/back-bdb/key.c | 104 - + servers/slapd/back-bdb/modify.c | 835 -------- + servers/slapd/back-bdb/modrdn.c | 842 -------- + servers/slapd/back-bdb/monitor.c | 724 ------- + servers/slapd/back-bdb/nextid.c | 80 - + servers/slapd/back-bdb/operational.c | 151 -- + servers/slapd/back-bdb/proto-bdb.h | 678 ------- + servers/slapd/back-bdb/referral.c | 152 -- + servers/slapd/back-bdb/search.c | 1388 -------------- + servers/slapd/back-bdb/tools.c | 1327 ------------- + servers/slapd/back-bdb/trans.c | 56 - + servers/slapd/back-hdb/Makefile.in | 70 - + servers/slapd/back-hdb/back-bdb.h | 31 - + servers/slapd/back-monitor/init.c | 8 +- + servers/slapd/bconfig.c | 2 +- + servers/slapd/dn.c | 3 +- + servers/slapd/overlays/pcache.c | 4 +- + servers/slapd/slap.h | 1 - + servers/slapd/slapd.ldif | 3 +- + tests/Makefile.in | 36 - + tests/README | 2 - + tests/data/regressions/its4184/its4184 | 4 - + tests/data/regressions/its4448/its4448 | 16 - + tests/data/slapd-proxyauthz.conf | 4 - + tests/data/slapd-proxycache.conf | 4 - + tests/data/slapd-ref-slave.conf | 2 - + tests/data/slapd.conf | 2 - + tests/run.in | 8 +- + tests/scripts/test023-refint | 97 +- + tests/scripts/test025-limits | 2 +- + tests/scripts/test036-meta-concurrency | 16 - + tests/scripts/test040-subtree-rename | 5 - + tests/scripts/test043-delta-syncrepl | 2 +- + tests/scripts/test052-memberof | 4 +- + tests/scripts/test056-monitor | 6 +- + tests/scripts/test057-memberof-refint | 9 +- + .../test061-syncreplication-initiation | 1 - + 95 files changed, 418 insertions(+), 20054 deletions(-) + delete mode 100644 doc/man/man5/slapd-bdb.5 + delete mode 100644 doc/man/man5/slapd-bdb.5.links + delete mode 100644 servers/slapd/DB_CONFIG + delete mode 100644 servers/slapd/alock.c + delete mode 100644 servers/slapd/alock.h + delete mode 100644 servers/slapd/back-bdb/Makefile.in + delete mode 100644 servers/slapd/back-bdb/add.c + delete mode 100644 servers/slapd/back-bdb/attr.c + delete mode 100644 servers/slapd/back-bdb/back-bdb.h + delete mode 100644 servers/slapd/back-bdb/bind.c + delete mode 100644 servers/slapd/back-bdb/cache.c + delete mode 100644 servers/slapd/back-bdb/compare.c + delete mode 100644 servers/slapd/back-bdb/config.c + delete mode 100644 servers/slapd/back-bdb/dbcache.c + delete mode 100644 servers/slapd/back-bdb/delete.c + delete mode 100644 servers/slapd/back-bdb/dn2entry.c + delete mode 100644 servers/slapd/back-bdb/dn2id.c + delete mode 100644 servers/slapd/back-bdb/error.c + delete mode 100644 servers/slapd/back-bdb/extended.c + delete mode 100644 servers/slapd/back-bdb/filterindex.c + delete mode 100644 servers/slapd/back-bdb/id2entry.c + delete mode 100644 servers/slapd/back-bdb/idl.c + delete mode 100644 servers/slapd/back-bdb/idl.h + delete mode 100644 servers/slapd/back-bdb/index.c + delete mode 100644 servers/slapd/back-bdb/init.c + delete mode 100644 servers/slapd/back-bdb/key.c + delete mode 100644 servers/slapd/back-bdb/modify.c + delete mode 100644 servers/slapd/back-bdb/modrdn.c + delete mode 100644 servers/slapd/back-bdb/monitor.c + delete mode 100644 servers/slapd/back-bdb/nextid.c + delete mode 100644 servers/slapd/back-bdb/operational.c + delete mode 100644 servers/slapd/back-bdb/proto-bdb.h + delete mode 100644 servers/slapd/back-bdb/referral.c + delete mode 100644 servers/slapd/back-bdb/search.c + delete mode 100644 servers/slapd/back-bdb/tools.c + delete mode 100644 servers/slapd/back-bdb/trans.c + delete mode 100644 servers/slapd/back-hdb/Makefile.in + delete mode 100644 servers/slapd/back-hdb/back-bdb.h + +diff --git a/INSTALL b/INSTALL +index e8a4fb3..0805e1c 100644 +--- a/INSTALL ++++ b/INSTALL +@@ -73,9 +73,6 @@ Making and Installing the OpenLDAP Distribution + + 6. Test the standalone system: + +- This step requires the standalone LDAP server, slapd(8), with HDB +- and/or BDB support. +- + % make test + + If all goes well, the system has been built as configured. If +diff --git a/build/openldap.m4 b/build/openldap.m4 +index 80fda16..fd768aa 100644 +--- a/build/openldap.m4 ++++ b/build/openldap.m4 +@@ -243,298 +243,6 @@ OL_RESOLVER_TRY(ol_cv_resolver_none) + OL_RESOLVER_TRY(ol_cv_resolver_resolv,[-lresolv]) + OL_RESOLVER_TRY(ol_cv_resolver_bind,[-lbind]) + ]) +-dnl +-dnl ==================================================================== +-dnl Berkeley DB macros +-dnl +-dnl -------------------------------------------------------------------- +-dnl Try to link +-AC_DEFUN([OL_BERKELEY_DB_TRY], +-[if test $ol_cv_lib_db = no ; then +- AC_CACHE_CHECK([for Berkeley DB link (]ifelse($2,,default,$2)[)],[$1], +-[ +- ol_DB_LIB=ifelse($2,,,$2) +- ol_LIBS=$LIBS +- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" +- +- AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +-#ifdef HAVE_DB_185_H +-# include +-#else +-# include +-#endif +- +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif +- +-#ifndef NULL +-#define NULL ((void*)0) +-#endif +-]], [[ +-#if DB_VERSION_MAJOR > 2 +- db_env_create( NULL, 0 ); +-#elif DB_VERSION_MAJOR > 1 +- db_appexit( NULL ); +-#else +- (void) dbopen( NULL, 0, 0, 0, NULL); +-#endif +-]])],[$1=yes],[$1=no]) +- +- LIBS="$ol_LIBS" +-]) +- +- if test $$1 = yes ; then +- ol_cv_lib_db=ifelse($2,,yes,$2) +- fi +-fi +-]) +-dnl +-dnl -------------------------------------------------------------------- +-dnl Get major and minor version from +-AC_DEFUN([OL_BDB_HEADER_VERSION], +-[AC_CACHE_CHECK([for Berkeley DB major version in db.h], [ol_cv_bdb_major],[ +- AC_LANG_CONFTEST([ +-#include +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif +-__db_version DB_VERSION_MAJOR +-]) +- set X `eval "$ac_cpp -P conftest.$ac_ext" | $EGREP __db_version` none none +- ol_cv_bdb_major=${3} +-]) +-case $ol_cv_bdb_major in [[1-9]]*) : ;; *) +- AC_MSG_ERROR([Unknown Berkeley DB major version in db.h]) ;; +-esac +- +-dnl Determine minor version +-AC_CACHE_CHECK([for Berkeley DB minor version in db.h], [ol_cv_bdb_minor],[ +- AC_LANG_CONFTEST([ +-#include +-#ifndef DB_VERSION_MINOR +-# define DB_VERSION_MINOR 0 +-#endif +-__db_version DB_VERSION_MINOR +-]) +- set X `eval "$ac_cpp -P conftest.$ac_ext" | $EGREP __db_version` none none +- ol_cv_bdb_minor=${3} +-]) +-case $ol_cv_bdb_minor in [[0-9]]*) : ;; *) +- AC_MSG_ERROR([Unknown Berkeley DB minor version in db.h]) ;; +-esac +-]) +-dnl +-dnl -------------------------------------------------------------------- +-dnl Try to locate appropriate library +-AC_DEFUN([OL_BERKELEY_DB_LINK], +-[ol_cv_lib_db=no +- +-if test $ol_cv_bdb_major = 5 ; then +- OL_BERKELEY_DB_TRY(ol_cv_db_db_5_dot_m,[-ldb-5.$ol_cv_bdb_minor]) +- OL_BERKELEY_DB_TRY(ol_cv_db_db5m,[-ldb5$ol_cv_bdb_minor]) +- OL_BERKELEY_DB_TRY(ol_cv_db_db_5m,[-ldb-5$ol_cv_bdb_minor]) +- OL_BERKELEY_DB_TRY(ol_cv_db_db_5_m,[-ldb-5-$ol_cv_bdb_minor]) +- OL_BERKELEY_DB_TRY(ol_cv_db_db_5,[-ldb-5]) +- OL_BERKELEY_DB_TRY(ol_cv_db_db5,[-ldb5]) +-elif test $ol_cv_bdb_major = 4 ; then +- OL_BERKELEY_DB_TRY(ol_cv_db_db_4_dot_m,[-ldb-4.$ol_cv_bdb_minor]) +- OL_BERKELEY_DB_TRY(ol_cv_db_db4m,[-ldb4$ol_cv_bdb_minor]) +- OL_BERKELEY_DB_TRY(ol_cv_db_db_4m,[-ldb-4$ol_cv_bdb_minor]) +- OL_BERKELEY_DB_TRY(ol_cv_db_db_4_m,[-ldb-4-$ol_cv_bdb_minor]) +- OL_BERKELEY_DB_TRY(ol_cv_db_db_4,[-ldb-4]) +- OL_BERKELEY_DB_TRY(ol_cv_db_db4,[-ldb4]) +-fi +-OL_BERKELEY_DB_TRY(ol_cv_db_db,[-ldb]) +-OL_BERKELEY_DB_TRY(ol_cv_db_none) +-]) +-dnl +-dnl -------------------------------------------------------------------- +-dnl Check if Berkeley DB version +-AC_DEFUN([OL_BERKELEY_DB_VERSION], +-[AC_CACHE_CHECK([for Berkeley DB library and header version match], [ol_cv_berkeley_db_version], [ +- ol_LIBS="$LIBS" +- LIBS="$LTHREAD_LIBS $LIBS" +- if test $ol_cv_lib_db != yes ; then +- LIBS="$ol_cv_lib_db $LIBS" +- fi +- +- AC_RUN_IFELSE([AC_LANG_SOURCE([[ +-#ifdef HAVE_DB_185_H +- choke me; +-#else +-#include +-#endif +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif +-#ifndef NULL +-#define NULL ((void *)0) +-#endif +-main() +-{ +-#if DB_VERSION_MAJOR > 1 +- char *version; +- int major, minor, patch; +- +- version = db_version( &major, &minor, &patch ); +- +- if( major != DB_VERSION_MAJOR || +- minor != DB_VERSION_MINOR || +- patch != DB_VERSION_PATCH ) +- { +- printf("Berkeley DB version mismatch\n" +- "\theader: %s\n\tlibrary: %s\n", +- DB_VERSION_STRING, version); +- return 1; +- } +-#endif +- +- return 0; +-}]])],[ol_cv_berkeley_db_version=yes],[ol_cv_berkeley_db_version=no],[ol_cv_berkeley_db_version=cross]) +- +- LIBS="$ol_LIBS" +-]) +- +- if test $ol_cv_berkeley_db_version = no ; then +- AC_MSG_ERROR([Berkeley DB version mismatch]) +- fi +-])dnl +-dnl +-dnl -------------------------------------------------------------------- +-dnl Check if Berkeley DB supports DB_THREAD +-AC_DEFUN([OL_BERKELEY_DB_THREAD], +-[AC_CACHE_CHECK([for Berkeley DB thread support], [ol_cv_berkeley_db_thread], [ +- ol_LIBS="$LIBS" +- LIBS="$LTHREAD_LIBS $LIBS" +- if test $ol_cv_lib_db != yes ; then +- LIBS="$ol_cv_lib_db $LIBS" +- fi +- +- AC_RUN_IFELSE([AC_LANG_SOURCE([[ +-#ifdef HAVE_DB_185_H +- choke me; +-#else +-#include +-#endif +-#ifndef NULL +-#define NULL ((void *)0) +-#endif +-main() +-{ +- int rc; +- u_int32_t flags = DB_CREATE | +-#ifdef DB_PRIVATE +- DB_PRIVATE | +-#endif +- DB_THREAD; +- +-#if DB_VERSION_MAJOR > 2 +- DB_ENV *env = NULL; +- +- rc = db_env_create( &env, 0 ); +- +- flags |= DB_INIT_MPOOL; +-#ifdef DB_MPOOL_PRIVATE +- flags |= DB_MPOOL_PRIVATE; +-#endif +- +- if( rc ) { +- printf("BerkeleyDB: %s\n", db_strerror(rc) ); +- return rc; +- } +- +-#if (DB_VERSION_MAJOR > 3) || (DB_VERSION_MINOR >= 1) +- rc = (env->open)( env, NULL, flags, 0 ); +-#else +- rc = (env->open)( env, NULL, NULL, flags, 0 ); +-#endif +- +- if ( rc == 0 ) { +- rc = env->close( env, 0 ); +- } +- +- if( rc ) { +- printf("BerkeleyDB: %s\n", db_strerror(rc) ); +- return rc; +- } +- +-#else +- DB_ENV env; +- memset( &env, '\0', sizeof(env) ); +- +- rc = db_appinit( NULL, NULL, &env, flags ); +- +- if( rc == 0 ) { +- db_appexit( &env ); +- } +- +- unlink("__db_mpool.share"); +- unlink("__db_lock.share"); +-#endif +- +- return rc; +-}]])],[ol_cv_berkeley_db_thread=yes],[ol_cv_berkeley_db_thread=no],[ol_cv_berkeley_db_thread=cross]) +- +- LIBS="$ol_LIBS" +-]) +- +- if test $ol_cv_berkeley_db_thread != no ; then +- AC_DEFINE(HAVE_BERKELEY_DB_THREAD, 1, +- [define if Berkeley DB has DB_THREAD support]) +- fi +-])dnl +-dnl +-dnl -------------------------------------------------------------------- +-dnl Find any DB +-AC_DEFUN([OL_BERKELEY_DB], +-[ol_cv_berkeley_db=no +-AC_CHECK_HEADERS(db.h) +-if test $ac_cv_header_db_h = yes; then +- OL_BDB_HEADER_VERSION +- OL_BDB_COMPAT +- +- if test $ol_cv_bdb_compat != yes ; then +- AC_MSG_ERROR([BerkeleyDB version incompatible with BDB/HDB backends]) +- fi +- +- OL_BERKELEY_DB_LINK +- if test "$ol_cv_lib_db" != no ; then +- ol_cv_berkeley_db=yes +- OL_BERKELEY_DB_VERSION +- OL_BERKELEY_DB_THREAD +- fi +-fi +-]) +-dnl -------------------------------------------------------------------- +-dnl Check for version compatility with back-bdb +-AC_DEFUN([OL_BDB_COMPAT], +-[AC_CACHE_CHECK([if Berkeley DB version supported by BDB/HDB backends], [ol_cv_bdb_compat],[ +- AC_EGREP_CPP(__db_version_compat,[ +-#include +- +- /* this check could be improved */ +-#ifndef DB_VERSION_MAJOR +-# define DB_VERSION_MAJOR 1 +-#endif +-#ifndef DB_VERSION_MINOR +-# define DB_VERSION_MINOR 0 +-#endif +-#ifndef DB_VERSION_PATCH +-# define DB_VERSION_PATCH 0 +-#endif +- +-#define DB_VERSION_FULL ((DB_VERSION_MAJOR<<16)|(DB_VERSION_MINOR<<8)|DB_VERSION_PATCH) +- +-/* require 4.4 or later, but less than 6.0.20 */ +-#if DB_VERSION_FULL >= 0x040400 && DB_VERSION_FULL < 0x060014 +- __db_version_compat +-#endif +-#if DB_VERSION_FULL >= 0x060014 +-#error "BerkeleyDB 6.0.20+ license is incompatible with LDAP" +-#endif +- ], [ol_cv_bdb_compat=yes], [ol_cv_bdb_compat=no])]) +-]) + + dnl + dnl ==================================================================== +diff --git a/build/top.mk b/build/top.mk +index 6850121..a25c5fc 100644 +--- a/build/top.mk ++++ b/build/top.mk +@@ -159,7 +159,6 @@ LDAP_LIBDIR= $(top_builddir)/libraries + LUTIL_LIBS = @LUTIL_LIBS@ + LTHREAD_LIBS = @LTHREAD_LIBS@ + +-BDB_LIBS = @BDB_LIBS@ + SLAPD_NDB_LIBS = @SLAPD_NDB_LIBS@ + + LDAP_LIBLBER_LA = $(LDAP_LIBDIR)/liblber/liblber.la +diff --git a/configure.in b/configure.in +index c70241a..065eae3 100644 +--- a/configure.in ++++ b/configure.in +@@ -282,9 +282,7 @@ OL_ARG_ENABLE(wrappers,[ --enable-wrappers enable tcp wrapper support], no) + + dnl ---------------------------------------------------------------- + dnl SLAPD Backend Options +-Backends="bdb \ +- dnssrv \ +- hdb \ ++Backends="dnssrv \ + ldap \ + mdb \ + meta \ +@@ -303,12 +301,8 @@ SLAPD Backend Options:]) + + OL_ARG_ENABLE(backends,[ --enable-backends enable all available backends], + --, [no yes mod])dnl +-OL_ARG_ENABLE(bdb,[ --enable-bdb enable Berkeley DB backend], +- yes, [no yes mod], ol_enable_backends)dnl + OL_ARG_ENABLE(dnssrv,[ --enable-dnssrv enable dnssrv backend], + no, [no yes mod], ol_enable_backends)dnl +-OL_ARG_ENABLE(hdb,[ --enable-hdb enable Hierarchical DB backend], +- yes, [no yes mod], ol_enable_backends)dnl + OL_ARG_ENABLE(ldap,[ --enable-ldap enable ldap backend], + no, [no yes mod], ol_enable_backends)dnl + OL_ARG_ENABLE(mdb,[ --enable-mdb enable mdb database backend], +@@ -471,9 +465,7 @@ if test $ol_enable_slapd = no ; then + ol_enable_rewrite=no + + elif test $ol_enable_modules != yes && +- test $ol_enable_bdb = no && + test $ol_enable_dnssrv = no && +- test $ol_enable_hdb = no && + test $ol_enable_ldap = no && + test $ol_enable_mdb = no && + test $ol_enable_meta = no && +@@ -518,7 +510,6 @@ AC_MSG_RESULT(done) + dnl ---------------------------------------------------------------- + dnl Initialize vars + LDAP_LIBS= +-BDB_LIBS= + SLAPD_NDB_LIBS= + SLAPD_NDB_INCS= + LTHREAD_LIBS= +@@ -533,9 +524,7 @@ BUILD_THREAD=no + BUILD_SLAPI=no + SLAPD_SLAPI_DEPEND= + +-BUILD_BDB=no + BUILD_DNSSRV=no +-BUILD_HDB=no + BUILD_LDAP=no + BUILD_MDB=no + BUILD_META=no +@@ -1867,36 +1856,6 @@ else + ol_cv_func_gethostbyaddr_r_nargs=0 + fi + +-dnl ---------------------------------------------------------------- +-ol_link_bdb=no +- +-if test $ol_enable_bdb/$ol_enable_hdb != no/no; then +- OL_BERKELEY_DB +- +- if test $ol_cv_berkeley_db = no ; then +- AC_MSG_ERROR(BDB/HDB: BerkeleyDB not available) +- fi +- +- AC_DEFINE(HAVE_BERKELEY_DB,1, +- [define this if Berkeley DB is available]) +- +- dnl $ol_cv_lib_db should be yes or -ldb +- dnl (it could be no, but that would be an error +- if test $ol_cv_lib_db != yes ; then +- BDB_LIBS="$BDB_LIBS $ol_cv_lib_db" +- fi +- +- dnl link BDB library to slapd when there is a +- dnl static BDB based backend in use +- if test $ol_enable_bdb/$ol_enable_hdb != mod/mod ; then +- if test $ol_enable_bdb = yes -o $ol_enable_hdb = yes ; then +- SLAPD_LIBS="$SLAPD_LIBS \$(BDB_LIBS)" +- fi +- fi +- +- ol_link_bdb=yes +-fi +- + dnl ---------------------------------------------------------------- + + if test $ol_enable_dynamic = yes && test $enable_shared = yes ; then +@@ -2610,19 +2569,6 @@ if test "$ol_enable_monitor" != no ; then + AC_DEFINE_UNQUOTED(SLAPD_MONITOR,$MFLAG,[define to support cn=Monitor backend]) + fi + +-if test "$ol_enable_bdb" != no ; then +- BUILD_SLAPD=yes +- BUILD_BDB=$ol_enable_bdb +- if test "$ol_enable_bdb" = mod ; then +- SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-bdb" +- MFLAG=SLAPD_MOD_DYNAMIC +- else +- SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-bdb" +- MFLAG=SLAPD_MOD_STATIC +- fi +- AC_DEFINE_UNQUOTED(SLAPD_BDB,$MFLAG,[define to support BDB backend]) +-fi +- + if test "$ol_enable_dnssrv" != no ; then + BUILD_SLAPD=yes + BUILD_DNSSRV=$ol_enable_dnssrv +@@ -2636,19 +2582,6 @@ if test "$ol_enable_dnssrv" != no ; then + AC_DEFINE_UNQUOTED(SLAPD_DNSSRV,$MFLAG,[define to support DNS SRV backend]) + fi + +-if test "$ol_enable_hdb" != no ; then +- BUILD_SLAPD=yes +- BUILD_HDB=$ol_enable_hdb +- if test "$ol_enable_hdb" = mod ; then +- SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-hdb" +- MFLAG=SLAPD_MOD_DYNAMIC +- else +- SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-hdb" +- MFLAG=SLAPD_MOD_STATIC +- fi +- AC_DEFINE_UNQUOTED(SLAPD_HDB,$MFLAG,[define to support HDB backend]) +-fi +- + if test "$ol_enable_ldap" != no ; then + BUILD_SLAPD=yes + BUILD_LDAP=$ol_enable_ldap +@@ -3076,9 +3009,7 @@ dnl slapi + AC_SUBST(BUILD_SLAPI) + AC_SUBST(SLAPD_SLAPI_DEPEND) + dnl backends +- AC_SUBST(BUILD_BDB) + AC_SUBST(BUILD_DNSSRV) +- AC_SUBST(BUILD_HDB) + AC_SUBST(BUILD_LDAP) + AC_SUBST(BUILD_MDB) + AC_SUBST(BUILD_META) +@@ -3117,7 +3048,6 @@ dnl overlays + + AC_SUBST(LDAP_LIBS) + AC_SUBST(SLAPD_LIBS) +-AC_SUBST(BDB_LIBS) + AC_SUBST(SLAPD_NDB_LIBS) + AC_SUBST(SLAPD_NDB_INCS) + AC_SUBST(LTHREAD_LIBS) +@@ -3181,9 +3111,7 @@ AC_CONFIG_FILES([Makefile:build/top.mk:Makefile.in:build/dir.mk] + [libraries/librewrite/Makefile:build/top.mk:libraries/librewrite/Makefile.in:build/lib.mk:build/lib-static.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/back-bdb/Makefile:build/top.mk:servers/slapd/back-bdb/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-hdb/Makefile:build/top.mk:servers/slapd/back-hdb/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-ldif/Makefile:build/top.mk:servers/slapd/back-ldif/Makefile.in:build/mod.mk] + [servers/slapd/back-mdb/Makefile:build/top.mk:servers/slapd/back-mdb/Makefile.in:build/mod.mk] +diff --git a/contrib/slapd-modules/allowed/allowed.c b/contrib/slapd-modules/allowed/allowed.c +index 5f2810f..8ca0889 100644 +--- a/contrib/slapd-modules/allowed/allowed.c ++++ b/contrib/slapd-modules/allowed/allowed.c +@@ -27,7 +27,7 @@ + * Caveats: + * - right now, the overlay assumes that all values of the objectClass + * attribute will be returned in rs->sr_entry; this may not be true +- * in general, but it usually is for back-bdb/back-hdb. To generalize, ++ * in general, but it usually is for back-mdb. To generalize, + * the search request should be analyzed, and if allowedAttributes or + * allowedAttributesEffective are requested, add objectClass to the + * requested attributes +diff --git a/contrib/slapd-modules/nssov/README b/contrib/slapd-modules/nssov/README +index ced3872..f8538f9 100644 +--- a/contrib/slapd-modules/nssov/README ++++ b/contrib/slapd-modules/nssov/README +@@ -21,7 +21,7 @@ To use the overlay, add: + moduleload nssov.so + ... + +- database hdb ++ database mdb + ... + overlay nssov + +@@ -65,7 +65,7 @@ See the nss-ldapd/README for the original attribute names used in this code. + The overlay also supports dynamic configuration in cn=config. The layout + of the config entry is + +- dn: olcOverlay={0}nssov,ocDatabase={1}hdb,cn=config ++ dn: olcOverlay={0}nssov,ocDatabase={1}mdb,cn=config + objectClass: olcOverlayConfig + objectClass: olcNssOvConfig + olcOverlay: {0}nssov +diff --git a/contrib/slapd-modules/nssov/slapo-nssov.5 b/contrib/slapd-modules/nssov/slapo-nssov.5 +index 816b661..83621bd 100644 +--- a/contrib/slapd-modules/nssov/slapo-nssov.5 ++++ b/contrib/slapd-modules/nssov/slapo-nssov.5 +@@ -278,7 +278,7 @@ of the config entry is + .LP + .RS + .nf +- dn: olcOverlay={0}nssov,ocDatabase={1}hdb,cn=config ++ dn: olcOverlay={0}nssov,ocDatabase={1}mdb,cn=config + objectClass: olcOverlayConfig + objectClass: olcNssOvConfig + olcOverlay: {0}nssov +diff --git a/doc/guide/admin/appendix-changes.sdf b/doc/guide/admin/appendix-changes.sdf +index 5006672..7fe91d1 100644 +--- a/doc/guide/admin/appendix-changes.sdf ++++ b/doc/guide/admin/appendix-changes.sdf +@@ -147,11 +147,6 @@ search over 500 thousand entries per second. The search was on an unindexed + attribute using a filter that would not match any entry, forcing slapd to examine + every entry in the DB, testing the filter for a match. + +-Essentially the slapd entry cache in back-bdb/back-hdb is so efficient the search +-processing time is almost invisible; the runtime is limited only by the memory +-bandwidth of the machine. (The search data rate corresponds to about 3.5GB/sec; +-the memory bandwidth on the machine is only about 4GB/sec due to ECC and register latency.) +- + H3: New overlays + + * slapo-constraint (Attribute value constraints) +@@ -199,21 +194,13 @@ H3: New build options + * Support for building against GnuTLS + + +-H2: Obsolete Features Removed From 2.4 +- +-These features were strongly deprecated in 2.3 and removed in 2.4. +- +-H3: Slurpd ++H2: Obsolete Features Removed From 2.5 + +-Please read the {{SECT:Replication}} section as to why this is no longer in +-OpenLDAP ++These features were strongly deprecated in 2.4 and removed in 2.5. + +-H3: back-ldbm ++H3: back-bdb and back-hdb + +-back-ldbm was both slow and unreliable. Its byzantine indexing code was +-prone to spontaneous corruption, as were the underlying database libraries +-that were commonly used (e.g. GDBM or NDBM). back-bdb and back-hdb are +-superior in every aspect, with simplified indexing to avoid index corruption, +-fine-grained locking for greater concurrency, hierarchical caching for +-greater performance, streamlined on-disk format for greater efficiency +-and portability, and full transaction support for greater reliability. ++back-bdb and back-hdb were signficantly slower than back-mdb and ++required significant tuning of multiple parameters to maximize ++performance. back-mdb requires no tuning and provides all the ++functionality previously provided via back-bdb and back-hdb. +diff --git a/doc/guide/admin/appendix-common-errors.sdf b/doc/guide/admin/appendix-common-errors.sdf +index 23eef9b..5ead0e1 100644 +--- a/doc/guide/admin/appendix-common-errors.sdf ++++ b/doc/guide/admin/appendix-common-errors.sdf +@@ -636,7 +636,7 @@ values of . + + H3: ldap_*: Internal (implementation specific) error (80) - additional info: entry index delete failed + +-This seems to be related with wrong ownership of the BDB's dir (/var/lib/ldap) ++This seems to be related with wrong ownership of the MDB's dir (/var/lib/ldap) + and files. The files must be owned by the user that slapd runs as. + + > chown -R ldap:ldap /var/lib/ldap +@@ -652,11 +652,3 @@ immediately and client gets an error : + > SASL/GSSAPI authentication started ldap_sasl_interactive_bind_s: Can't contact LDAP server (-1) + + Then check the slapd service, it stopped. +- +-This may come from incompatible of using different versions of BerkeleyDB for +-installing of SASL and installing of OpenLDAP. The problem arises in case of +-using multiple version of BerkeleyDB. Solution: - Check which version of +-BerkeleyDB when install Cyrus SASL. +- +-Reinstall OpenLDAP with the version of BerkeleyDB above. +- +diff --git a/doc/guide/admin/aspell.en.pws b/doc/guide/admin/aspell.en.pws +index f486703..ae777e2 100644 +--- a/doc/guide/admin/aspell.en.pws ++++ b/doc/guide/admin/aspell.en.pws +@@ -102,7 +102,6 @@ NOSYNC + env + pagedResultsControl + dup +-hdb + LDIFv + syslog + monitorTimestamp +@@ -887,7 +886,6 @@ proxyAttrSet + proxyAttrset + mary + crlcheck +-olcBdbConfig + kadmin + mech + slapcat +@@ -1190,7 +1188,6 @@ moddn + calloc + LDFLAGS + attributeOrValueExists +-olcHdbConfig + bsize + auditObject + dnssrv +@@ -1492,7 +1489,6 @@ ghenry + odbcinst + reqType + slapover +-BerkeleyDB's + attributename + lwrap + reqStart +@@ -1628,7 +1624,6 @@ DSAIT + olcHidden + mySNMP + metainformation +-BerkeleyDB + ldapuri + auditAbandon + RANDFILE +@@ -1662,7 +1657,6 @@ olcPasswordHash + ldapc + loopback + ldapi +-BDB's + GETREALM + functionalities + noplain +@@ -1670,7 +1664,6 @@ NOECHOPROMPT + AES + ldaps + notoc +-bdb + LDAPv + IPsec + olcServerID +diff --git a/doc/guide/admin/backends.sdf b/doc/guide/admin/backends.sdf +index 38e9ae2..6e005a6 100644 +--- a/doc/guide/admin/backends.sdf ++++ b/doc/guide/admin/backends.sdf +@@ -14,38 +14,9 @@ name of the module for a backend is usually of the form: + + > back_.la + +-So for example, if you need to load the {{hdb}} backend, you would configure ++So for example, if you need to load the {{mdb}} backend, you would configure + +-> moduleload back_hdb.la +- +-H2: Berkeley DB Backends +- +- +-H3: Overview +- +-The {{hdb}} backend to {{slapd}}(8) is a backend for a +-normal {{slapd}} database. It uses the Oracle Berkeley DB ({{TERM:BDB}}) +-package to store data. It makes extensive use of indexing and caching +-(see the {{SECT:Tuning}} section) to speed data access. +- +-{{hdb}} is a variant of the original {{bdb}} backend which was first written for use with BDB. +-{{hdb}} uses a hierarchical database layout which supports subtree renames. +-It is otherwise identical to the {{bdb}} +-behavior, and all the same configuration options apply. +- +-Note: An {{hdb}} database needs a large {{idlcachesize}} for good search performance, +-typically three times the {{cachesize}} (entry cache size) or larger. +- +-Note: The {{hdb}} backend has superseded the {{bdb}} backend, and both will +-soon be deprecated in favor of the new {{mdb}} backend. See below. +- +-H3: back-bdb/back-hdb Configuration +- +-MORE LATER +- +-H3: Further Information +- +-{{slapd-bdb}}(5) ++ moduleload back_mdb.la + + H2: LDAP + +@@ -199,16 +170,16 @@ H3: Overview + The {{mdb}} backend to {{slapd}}(8) is the recommended primary backend for a + normal {{slapd}} database. It uses OpenLDAP's own + Lightning Memory-Mapped Database ({{TERM:LMDB}}) +-library to store data and is intended to replace the Berkeley DB backends. ++library to store data and replace the BerkeleyDB backends used in older ++OpenLDAP releases. + +-It supports indexing like the BDB backends, but it uses no caching and requires +-no tuning to deliver maximum search performance. Like {{hdb}}, it is also +-fully hierarchical and supports subtree renames in constant time. ++It supports indexing, it uses no caching and requires no tuning to deliver ++maximum search performance. It is fully hierarchical and supports subtree ++renames in constant time. + + H3: back-mdb Configuration + +-Unlike the BDB backends, the {{mdb}} backend can be instantiated with very few +-configuration lines: ++The {{mdb}} backend can be instantiated with very few configuration lines: + + > include ./schema/core.schema + > +@@ -490,7 +461,7 @@ distribute information between different sites/applications that use RDBMSes + and/or LDAP. Or whatever else... + + It is {{B:NOT}} designed as a general-purpose backend that uses RDBMS instead of +-BerkeleyDB (as the standard BDB backend does), though it can be used as such with ++LMDB (as the standard back-mdb backend does), though it can be used as such with + several limitations. Please see {{SECT: LDAP vs RDBMS}} for discussion. + + The idea is to use some meta-information to translate LDAP queries to SQL queries, +diff --git a/doc/guide/admin/install.sdf b/doc/guide/admin/install.sdf +index 9c47b24..4b4e85e 100644 +--- a/doc/guide/admin/install.sdf ++++ b/doc/guide/admin/install.sdf +@@ -118,23 +118,6 @@ OpenLDAP's {{slapd}}(8) {{TERM:MDB}} primary database backend uses the {{TERM:LM + software included with the OpenLDAP source. There is no need to download any + additional software to have {{MDB}} support. + +-OpenLDAP's {{slapd}}(8) {{TERM:BDB}} and {{TERM:HDB}} deprecated database backends +-require {{ORG[expand]Oracle}}'s Berkeley DB. +-If not available at configure time, you will not be able to build +-{{slapd}}(8) with these deprecated database backends. +- +-Your operating system may provide a supported version of +-Berkeley DB in the base system or as an optional +-software component. If not, you'll have to obtain and +-install it yourself. Berkeley DB is available from +-{{ORG[expand]Oracle}}'s Berkeley DB download page if required. +- +-There are several versions available from {{ORG[expand]Oracle}}. +-Berkeley DB version 6.0.20 and later uses a software license that is +-incompatible with LDAP technology and should not be used with OpenLDAP. +- +-Note: Please see {{SECT:Recommended OpenLDAP Software Dependency Versions}} for +-more information. + + + H3: Threads +diff --git a/doc/guide/admin/intro.sdf b/doc/guide/admin/intro.sdf +index c3dd92f..6aa2149 100644 +--- a/doc/guide/admin/intro.sdf ++++ b/doc/guide/admin/intro.sdf +@@ -346,7 +346,7 @@ really have a "directory". + + Existing commercial LDAP server implementations that use a relational database + are either from the first kind or the third. I don't know of any implementation +-that uses a relational database to do inefficiently what BDB does efficiently. ++that uses a relational database to do inefficiently what LMDB does efficiently. + For those who are interested in "third way" (exposing EXISTING data from RDBMS + as LDAP tree, having some limitations compared to classic LDAP model, but making + it possible to interoperate between LDAP and SQL applications): +@@ -403,15 +403,9 @@ tags. + {{B:Choice of database backends}}: {{slapd}} comes with a variety + of different database backends you can choose from. They include + {{TERM:MDB}}, a hierarchical high-performance transactional database backend; +-{{TERM:BDB}}, a high-performance transactional database backend (deprecated); +-{{TERM:HDB}}, a hierarchical high-performance transactional +-backend (deprecated); {{SHELL}}, a backend interface to arbitrary shell scripts; ++{{SHELL}}, a backend interface to arbitrary shell scripts; + and PASSWD, a simple backend interface to the {{passwd}}(5) file. +-The MDB backend utilizes {{TERM:LMDB}}, a high performance replacement +-for {{ORG[expand]Oracle}}'s Berkeley DB. +-The BDB and HDB backends utilize {{ORG[expand]Oracle}} Berkeley DB. These +-backends have been deprecated as LMDB provides significantly higher read +-and write throughput and data reliability. ++The MDB backend utilizes {{TERM:LMDB}}. + + {{B:Multiple database instances}}: {{slapd}} can be configured to + serve multiple databases at the same time. This means that a single +diff --git a/doc/guide/admin/maintenance.sdf b/doc/guide/admin/maintenance.sdf +index deb14b9..3b7503f 100644 +--- a/doc/guide/admin/maintenance.sdf ++++ b/doc/guide/admin/maintenance.sdf +@@ -14,23 +14,7 @@ Backup strategies largely depend on the amount of change in the database + and how much of that change an administrator might be willing to lose in a + catastrophic failure. There are two basic methods that can be used: + +-1. Backup the Berkeley database itself and periodically back up the transaction +-log files: +- +-Berkeley DB produces transaction logs that can be used to reconstruct +-changes from a given point in time. For example, if an administrator were willing to only +-lose one hour's worth of changes, they could take down the server in +-the middle of the night, copy the Berkeley database files offsite, and bring +-the server back online. Then, on an hourly basis, they could force a +-database checkpoint, capture the log files that have been generated in the +-past hour, and copy them offsite. The accumulated log files, in combination +-with the previous database backup, could be used with db_recover to +-reconstruct the database up to the time the last collection of log files was +-copied offsite. This method affords good protection, with minimal space +-overhead. +- +- +-2. Periodically run slapcat and back up the LDIF file: ++1. Periodically run slapcat and back up the LDIF file: + + Slapcat can be run while slapd is active. However, one runs the risk of an + inconsistent database- not from the point of slapd, but from the point of +@@ -46,73 +30,11 @@ files can be rather large and the accumulation of the day's backups could + add up to a substantial amount of space. + + You can use {{slapcat}}(8) to generate an LDIF file for each of your {{slapd}}(8) +-back-bdb or back-hdb databases. ++back-mdb databases. + + > slapcat -f slapd.conf -b "dc=example,dc=com" + +-For back-bdb and back-hdb, this command may be ran while slapd(8) is running. +- +-MORE on actual Berkeley DB backups later covering db_recover etc. +- +-H2: Berkeley DB Logs +- +-Berkeley DB log files grow, and the administrator has to deal with it. The +-procedure is known as log file archival or log file rotation. +- +-Note: The actual log file rotation is handled by the Berkeley DB engine. +- +-Logs of current transactions need to be stored into files so that the database +-can be recovered in the event of an application crash. Administrators can change +-the size limit of a single log file (by default 10MB), and have old log files +-removed automatically, by setting up DB environment (see below). The reason +-Berkeley DB never deletes any log files by default is that the administrator +-may wish to backup the log files before removal to make database recovery +-possible even after a catastrophic failure, such as file system corruption. +- +-Log file names are {{F:log.XXXXXXXXXX}} (X is a digit). By default the log files +-are located in the BDB backend directory. The {{F:db_archive}} tool knows what +-log files are used in current transactions, and what are not. Administrators can +-move unused log files to a backup media, and delete them. To have them removed +-automatically, place set_flags {{DB_LOG_AUTOREMOVE}} directive in {{F:DB_CONFIG}}. +- +-Note: If the log files are removed automatically, recovery after a catastrophic +-failure is likely to be impossible. +- +-The files with names {{F:__db.001}}, {{F:__db.002}}, etc are just shared memory +-regions (or whatever). These ARE NOT 'logs', they must be left alone. Don't be +-afraid of them, they do not grow like logs do. +- +-To understand the {{F:db_archive}} interface, the reader should refer to +-chapter 9 of the Berkeley DB guide. In particular, the following chapters are +-recommended: +- +-* Database and log file archival - {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/ref/transapp/archival.html}} +-* Log file removal - {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/ref/transapp/logfile.html}} +-* Recovery procedures - {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/ref/transapp/recovery.html}} +-* Hot failover - {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/ref/transapp/hotfail.html}} +-* Complete list of Berkeley DB flags - {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/api_c/env_set_flags.html}} +- +-Advanced installations can use special environment settings to fine-tune some +-Berkeley DB options (change the log file limit, etc). This can be done by using +-the {{F:DB_CONFIG}} file. This magic file can be created in BDB backend directory +-set up by {{slapd.conf}}(5). More information on this file can be found in File +-naming chapter. Specific directives can be found in C Interface, look for +-{{DB_ENV->set_XXXX}} calls. +- +-Note: options set in {{F:DB_CONFIG}} file override options set by OpenLDAP. +-Use them with extreme caution. Do not use them unless You know what You are doing. +- +-The advantages of {{F:DB_CONFIG}} usage can be the following: +- +-* to keep data files and log files on different mediums (i.e. disks) to improve +- performance and/or reliability; +-* to fine-tune some specific options (such as shared memory region sizes); +-* to set the log file limit (please read Log file limits before doing this). +- +-To figure out the best-practice BDB backup scenario, the reader is highly +-recommended to read the whole Chapter 9: Berkeley DB Transactional Data Store Applications. +-This chapter is a set of small pages with examples in C language. Non-programming +-people can skip these examples without loss of knowledge. ++For back-mdb this command may be ran while slapd(8) is running. + + + H2: Checkpointing +@@ -148,7 +70,7 @@ type are: + +{{B: slapcat the current data out}} + + .{{S: }} +-+{{B: Clear out the current data directory (/usr/local/var/openldap-data/) leaving DB_CONFIG in place}} +++{{B: Clear out the current data directory (/usr/local/var/openldap-data/)}} + + .{{S: }} + +{{B: Perform the software upgrades}} +diff --git a/doc/guide/admin/monitoringslapd.sdf b/doc/guide/admin/monitoringslapd.sdf +index 2781e47..bca2ec5 100644 +--- a/doc/guide/admin/monitoringslapd.sdf ++++ b/doc/guide/admin/monitoringslapd.sdf +@@ -214,11 +214,10 @@ backends, as well as backends loaded by modules. For example: + > monitoredInfo: config + > monitoredInfo: ldif + > monitoredInfo: monitor +-> monitoredInfo: bdb +-> monitoredInfo: hdb ++> monitoredInfo: mdb + +-This indicates the {{config}}, {{ldif}}, {{monitor}}, {{bdb}}, +-and {{hdb}} backends are available. ++This indicates the {{config}}, {{ldif}}, {{monitor}}, ++and {{mdb}} backends are available. + + The {{EX:cn=Backends,cn=Monitor}} object is also a container + for available backend objects. Each available backend object +@@ -242,21 +241,7 @@ contains information about a particular backend. For example: + > seeAlso: cn=Database 2,cn=Databases,cn=Monitor + > + > dn: cn=Backend 3,cn=Backends,cn=Monitor +-> monitoredInfo: bdb +-> monitorRuntimeConfig: TRUE +-> supportedControl: 1.3.6.1.1.12 +-> supportedControl: 2.16.840.1.113730.3.4.2 +-> supportedControl: 1.3.6.1.4.1.4203.666.5.2 +-> supportedControl: 1.2.840.113556.1.4.319 +-> supportedControl: 1.3.6.1.1.13.1 +-> supportedControl: 1.3.6.1.1.13.2 +-> supportedControl: 1.3.6.1.4.1.4203.1.10.1 +-> supportedControl: 1.2.840.113556.1.4.1413 +-> supportedControl: 1.3.6.1.4.1.4203.666.11.7.2 +-> seeAlso: cn=Database 1,cn=Databases,cn=Monitor +-> +-> dn: cn=Backend 4,cn=Backends,cn=Monitor +-> monitoredInfo: hdb ++> monitoredInfo: mdb + > monitorRuntimeConfig: TRUE + > supportedControl: 1.3.6.1.1.12 + > supportedControl: 2.16.840.1.113730.3.4.2 +@@ -271,7 +256,7 @@ contains information about a particular backend. For example: + For each of these objects, monitorInfo indicates which backend the + information in the object is about. For instance, the {{EX:cn=Backend + 3,cn=Backends,cn=Monitor}} object contains (in the example) information +-about the {{bdb}} backend. ++about the {{mdb}} backend. + + !block table + Attribute|Description +diff --git a/doc/guide/admin/overlays.sdf b/doc/guide/admin/overlays.sdf +index 2eb115b..712cd1b 100644 +--- a/doc/guide/admin/overlays.sdf ++++ b/doc/guide/admin/overlays.sdf +@@ -743,9 +743,9 @@ H4: Setting cache parameters + This directive enables proxy caching and sets general cache + parameters. The parameter specifies which underlying database + is to be used to hold cached entries. It should be set to +-{{EX:mdb}}, {{EX:hdb}}, or {{EX:bdb}}. The parameter +-specifies the total number of entries which may be held in the cache. +-The parameter specifies the total number of attribute sets ++{{EX:mdb}}. The parameter specifies the ++total number of entries which may be held in the cache. The ++ parameter specifies the total number of attribute sets + (as specified by the {{EX:pcacheAttrset}} directive) that may be + defined. The parameter specifies the maximum number of + entries in a cacheable query. The specifies the consistency +diff --git a/doc/guide/admin/replication.sdf b/doc/guide/admin/replication.sdf +index 87139b5..bbc91e4 100644 +--- a/doc/guide/admin/replication.sdf ++++ b/doc/guide/admin/replication.sdf +@@ -225,8 +225,8 @@ in the replication context. + + The syncrepl engine, which is a consumer-side replication engine, + can work with any backends. The LDAP Sync provider can be configured +-as an overlay on any backend, but works best with the {{back-bdb}}, +-{{back-hdb}}, or {{back-mdb}} backends. ++as an overlay on any backend, but works best with the {{back-mdb}}, ++backends. + + The LDAP Sync provider maintains a {{EX:contextCSN}} for each + database as the current synchronization state indicator of the +@@ -423,9 +423,6 @@ writes have to go to just one of the mirror nodes at a time + server (slapd in proxy mode) or device (hardware load balancer) + is needed to manage which provider is currently active + * Backups are managed slightly differently +-- If backing up the Berkeley database itself and periodically backing up the +-transaction log files, then the same member of the mirror pair needs to be +-used to collect logfiles until the next database backup is taken + + For configuration, please see the {{SECT:MirrorMode}} section below + +@@ -762,10 +759,7 @@ H4: Delta-syncrepl Consumer configuration + + + The above configuration assumes that you have a replicator identity defined +-in your database that can be used to bind to the provider. In addition, +-all of the databases (primary, replica, and the accesslog +-storage database) should also have properly tuned {{DB_CONFIG}} files that meet +-your needs. ++in your database that can be used to bind to the provider. + + Note: An accesslog database is unique to a given master. It should + never be replicated. +diff --git a/doc/guide/admin/slapdconf2.sdf b/doc/guide/admin/slapdconf2.sdf +index cb51d88..8a3e969 100644 +--- a/doc/guide/admin/slapdconf2.sdf ++++ b/doc/guide/admin/slapdconf2.sdf +@@ -69,7 +69,7 @@ used to configure the software. + the schema that is hard-coded in slapd). + .. Child entries of {{EX:cn=schema,cn=config}} contain user schema as + loaded from config files or added at runtime. +-* Backend-specific configuration ++* Backend-specific configuration + * Database-specific configuration + .. Overlays are defined in children of the Database entry. + .. Databases and Overlays may also have other miscellaneous children. +@@ -207,7 +207,7 @@ Level Keyword Description + !endblock + + The desired log level can be input as a single integer that +-combines the (ORed) desired levels, both in decimal or in hexadecimal ++combines the (ORed) desired levels, both in decimal or in hexadecimal + notation, as a list of integers (that are ORed internally), or as a list of the names that are shown between brackets, such that + + > olcLogLevel 129 +@@ -364,10 +364,8 @@ supported backend types listed in Table 5.2. + !block table; align=Center; coltags="EX,N"; \ + title="Table 5.2: Database Backends" + Types Description +-bdb Berkeley DB transactional backend (deprecated) + config Slapd configuration backend + dnssrv DNS SRV backend +-hdb Hierarchical variant of bdb backend (deprecated) + ldap Lightweight Directory Access Protocol (Proxy) backend + ldif Lightweight Data Interchange Format backend + mdb Memory-Mapped DB backend +@@ -381,7 +379,7 @@ sql SQL Programmable backend + + \Example: + +-> olcBackend: bdb ++> olcBackend: mdb + + There are no other directives defined for this entry. Specific backend + types may define additional attributes for their particular use but so +@@ -391,9 +389,9 @@ not appear in any actual configurations. + + H4: Sample Entry + +-> dn: olcBackend=bdb,cn=config ++> dn: olcBackend=mdb,cn=config + > objectClass: olcBackendConfig +-> olcBackend: bdb ++> olcBackend: mdb + + + H3: Database-specific Directives +@@ -421,9 +419,9 @@ databases. + + \Example: + +-> olcDatabase: bdb ++> olcDatabase: mdb + +-This marks the beginning of a new {{TERM:BDB}} database instance. ++This marks the beginning of a new {{TERM:MDB}} database instance. + + + H4: olcAccess: to [ by [] [] ]+ +@@ -642,7 +640,7 @@ schema conformance. The default is off. + The {{EX:binddn}} parameter gives the DN to bind as for the + syncrepl searches to the provider slapd. It should be a DN + which has read access to the replication content in the +-master database. ++master database. + + The {{EX:bindmethod}} is {{EX:simple}} or {{EX:sasl}}, + depending on whether simple password-based authentication or +@@ -683,8 +681,8 @@ conforms to the obsolete {{changelog}} format. If the {{EX:syncdata}} + parameter is omitted or set to {{EX:"default"}} then the log + parameters are ignored. + +-The {{syncrepl}} replication mechanism is supported by the {{bdb}}, +-{{hdb}}, and {{mdb}} backends. ++The {{syncrepl}} replication mechanism is supported by the {{mdb}} ++backend. + + See the {{SECT:LDAP Sync Replication}} chapter of this guide for + more information on how to use this directive. +@@ -731,21 +729,20 @@ H4: Sample Entries + >olcRootDN: cn=Manager,dc=example,dc=com + + +-H3: BDB and HDB Database Directives ++H3: MDB Database Directives + +-Directives in this category apply to both the {{TERM:BDB}} +-and the {{TERM:HDB}} database. ++Directives in this category apply to the {{TERM:MDB}} ++database backend. + They are used in an olcDatabase entry in addition to the generic + database directives defined above. For a complete reference +-of BDB/HDB configuration directives, see {{slapd-bdb}}(5). In +-addition to the {{EX:olcDatabaseConfig}} objectClass, BDB and HDB +-database entries must have the {{EX:olcBdbConfig}} and +-{{EX:olcHdbConfig}} objectClass, respectively. ++of MDB configuration directives, see {{slapd-mdb}}(5). In ++addition to the {{EX:olcDatabaseConfig}} objectClass, MDB ++database entries must have the {{EX:olcMdbConfig}} objectClass. + + + H4: olcDbDirectory: + +-This directive specifies the directory where the BDB files ++This directive specifies the directory where the MDB files + containing the database and associated indices live. + + \Default: +@@ -753,98 +750,48 @@ containing the database and associated indices live. + > olcDbDirectory: /usr/local/var/openldap-data + + +-H4: olcDbCachesize: +- +-This directive specifies the size in entries of the in-memory +-cache maintained by the BDB backend database instance. +- +-\Default: +- +-> olcDbCachesize: 1000 +- +- + H4: olcDbCheckpoint: + +-This directive specifies how often to checkpoint the BDB transaction log. +-A checkpoint operation flushes the database buffers to disk and writes a +-checkpoint record in the log. ++This directive specifies the frequency for flushing the database disk ++buffers. This directive is only needed if the {{olcDbNoSync}} option is ++{{EX:TRUE}}. + The checkpoint will occur if either data has been written or + minutes have passed since the last checkpoint. Both arguments default + to zero, in which case they are ignored. When the argument is + non-zero, an internal task will run every minutes to perform the +-checkpoint. See the Berkeley DB reference guide for more details. ++checkpoint. Note: currently the _kbyte_ setting is unimplemented. + + \Example: + + > olcDbCheckpoint: 1024 10 + + +-H4: olcDbConfig: ++H4: olcDbEnvFlags: {nosync,nometasync,writemap,mapasync,nordahead} + +-This attribute specifies a configuration directive to be placed in the +-{{EX:DB_CONFIG}} file of the database directory. At server startup time, if +-no such file exists yet, the {{EX:DB_CONFIG}} file will be created and the +-settings in this attribute will be written to it. If the file exists, +-its contents will be read and displayed in this attribute. The attribute +-is multi-valued, to accommodate multiple configuration directives. No default +-is provided, but it is essential to use proper settings here to get the +-best server performance. ++This option specifies flags for finer-grained control of the LMDB library's ++operation. + +-Any changes made to this attribute will be written to the {{EX:DB_CONFIG}} +-file and will cause the database environment to be reset so the changes +-can take immediate effect. If the environment cache is large and has not +-been recently checkpointed, this reset operation may take a long time. It +-may be advisable to manually perform a single checkpoint using the Berkeley DB +-{{db_checkpoint}} utility before using LDAP Modify to change this +-attribute. ++* {{F:nosync}}: This is exactly the same as the dbnosync directive. + +-\Example: ++* {{F:nometasync}}: Flush the data on a commit, but skip the sync of the meta ++page. This mode is slightly faster than doing a full sync, but can ++potentially lose the last committed transaction if the operating system ++crashes. If both nometasync and nosync are set, the nosync flag takes ++precedence. + +-> olcDbConfig: set_cachesize 0 10485760 0 +-> olcDbConfig: set_lg_bsize 2097512 +-> olcDbConfig: set_lg_dir /var/tmp/bdb-log +-> olcDbConfig: set_flags DB_LOG_AUTOREMOVE +- +-In this example, the BDB cache is set to 10MB, the BDB transaction log +-buffer size is set to 2MB, and the transaction log files are to be stored +-in the /var/tmp/bdb-log directory. Also a flag is set to tell BDB to +-delete transaction log files as soon as their contents have been +-checkpointed and they are no longer needed. Without this setting the +-transaction log files will continue to accumulate until some other +-cleanup procedure removes them. See the Berkeley DB documentation for the +-{{EX:db_archive}} command for details. For a complete list of Berkeley DB +-flags please see - {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/api_c/env_set_flags.html}} +- +-Ideally the BDB cache must be +-at least as large as the working set of the database, the log buffer size +-should be large enough to accommodate most transactions without overflowing, +-and the log directory must be on a separate physical disk from the main +-database files. And both the database directory and the log directory +-should be separate from disks used for regular system activities such as +-the root, boot, or swap filesystems. See the FAQ-o-Matic and the Berkeley DB +-documentation for more details. ++* {{F:writemap}}: Use a writable memory map instead of just read-only. This ++speeds up write operations but makes the database vulnerable to corruption in ++case any bugs in slapd cause stray writes into the mmap region. + ++* {{F:mapasync}}: When using a writable memory map and performing flushes on ++each commit, use an asynchronous flush instead of a synchronous flush (the ++default). This option has no effect if writemap has not been set. It also has ++no effect if nosync is set. + +-H4: olcDbNosync: { TRUE | FALSE } +- +-This option causes on-disk database contents to not be immediately +-synchronized with in memory changes upon change. Setting this option +-to {{EX:TRUE}} may improve performance at the expense of data integrity. This +-directive has the same effect as using +-> olcDbConfig: set_flags DB_TXN_NOSYNC +- +- +-H4: olcDbIDLcacheSize: +- +-Specify the size of the in-memory index cache, in index slots. The +-default is zero. A larger value will speed up frequent searches of +-indexed entries. The optimal size will depend on the data and search +-characteristics of the database, but using a number three times +-the entry cache size is a good starting point. +- +-\Example: +- +-> olcDbIDLcacheSize: 3000 ++* {{F:nordahead}}: Turn off file readahead. Usually the OS performs readahead ++on every read request. This usually boosts read performance but can be ++harmful to random access read performance if the system's memory is full and ++the DB is larger than RAM. This option is not implemented on Windows. + + + H4: olcDbIndex: { | default} [pres,eq,approx,sub,none] +@@ -874,7 +821,7 @@ matches do not use an index. However, some attributes do support + indexing for inequality matches, based on the equality index. + + A substring index can be more explicitly specified as {{EX:subinitial}}, +-{{EX:subany}}, or {{EX:subfinal}}, corresponding to the three ++{{EX:subany}}, or {{EX:subfinal}}, corresponding to the three + possible components + of a substring match filter. A subinitial index only indexes + substrings that appear at the beginning of an attribute value. +@@ -890,7 +837,7 @@ attribute that inherits from {{EX:name}} to be indexed. + By default, no indices are maintained. It is generally advised + that minimally an equality index upon objectClass be maintained. + +-> olcDbindex: objectClass eq ++> olcDbIndex: objectClass eq + + Additional indices should be configured corresponding to the + most common searches that are used on the database. +@@ -907,18 +854,24 @@ stopped before the index task completes, indexing will have to be + manually completed using the slapindex tool. + + +-H4: olcDbLinearIndex: { TRUE | FALSE } ++H4: olcDbMaxReaders: ++ ++This directive specifies the maximum number of threads that may have ++concurrent read access to the database. Tools such as slapcat count as a ++single thread, in addition to threads in any active slapd processes. The ++default is 126. ++ + +-If this setting is {{EX:TRUE}} slapindex will index one attribute +-at a time. The default settings is {{EX:FALSE}} in which case all +-indexed attributes of an entry are processed at the same time. When +-enabled, each indexed attribute is processed individually, using +-multiple passes through the entire database. This option improves +-slapindex performance when the database size exceeds the BDB cache +-size. When the BDB cache is large enough, this option is not needed +-and will decrease performance. Also by default, slapadd performs +-full indexing and so a separate slapindex run is not needed. With +-this option, slapadd does no indexing and slapindex must be used. ++H4: olcDbMaxSize: ++ ++This directive specifies the maximum size of the database in bytes. A memory ++map of this size is allocated at startup time and the database will not be ++allowed to grow beyond this size. The default is 10485760 bytes (10MB). This ++setting may be changed upward if the configured limit needs to be increased. ++ ++Note: It is important to set this to as large a value as possible, (relative ++to anticipated growth of the actual data over time) since growing the size ++later may not be practical when the system is under heavy load. + + + H4: olcDbMode: { | } +@@ -932,6 +885,18 @@ created database index files should have. This can be in the form + > olcDbMode: 0600 + + ++H4: olcDbRtxnsize: ++ ++This directive specifies the maximum number of entries to process in a single ++read transaction when executing a large search. Long-lived read transactions ++prevent old database pages from being reused in write transactions, and so ++can cause significant growth of the database file when there is heavy write ++traffic. This setting causes the read transaction in large searches to be ++released and reacquired after the given number of entries has been read, to ++give writers the opportunity to reclaim old database pages. The default is ++10000. ++ ++ + H4: olcDbSearchStack: + + Specify the depth of the stack used for search filter evaluation. +@@ -955,33 +920,21 @@ to take effect. + > olcDbSearchStack: 16 + + +-H4: olcDbShmKey: +- +-Specify a key for a shared memory BDB environment. By default the BDB +-environment uses memory mapped files. If a non-zero value is specified, +-it will be used as the key to identify a shared memory region that will +-house the environment. +- +-\Example: ++H4: olcDbNosync: { TRUE | FALSE } + +-> olcDbShmKey: 42 ++This directive causes on-disk database contents to not be immediately ++synchronized with in memory changes upon change. Setting this option ++to {{EX:TRUE}} may improve performance at the expense of data integrity. + + + H4: Sample Entry + +->dn: olcDatabase=hdb,cn=config ++>dn: olcDatabase=mdb,cn=config + >objectClass: olcDatabaseConfig +->objectClass: olcHdbConfig +->olcDatabase: hdb ++>objectClass: olcMdbConfig ++>olcDatabase: mdb + >olcSuffix: dc=example,dc=com + >olcDbDirectory: /usr/local/var/openldap-data +->olcDbCacheSize: 1000 +->olcDbCheckpoint: 1024 10 +->olcDbConfig: set_cachesize 0 10485760 0 +->olcDbConfig: set_lg_bsize 2097152 +->olcDbConfig: set_lg_dir /var/tmp/bdb-log +->olcDbConfig: set_flags DB_LOG_AUTOREMOVE +->olcDbIDLcacheSize: 3000 + >olcDbIndex: objectClass eq + + +@@ -989,7 +942,7 @@ H2: Configuration Example + + The following is an example configuration, interspersed + with explanatory text. It defines two databases to handle +-different parts of the {{TERM:X.500}} tree; both are {{TERM:BDB}} ++different parts of the {{TERM:X.500}} tree; both are {{TERM:MDB}} + database instances. The line numbers shown are provided for + reference only and are not included in the actual file. First, the + global configuration section: +@@ -999,7 +952,7 @@ E: 2. dn: cn=config + E: 3. objectClass: olcGlobal + E: 4. cn: config + E: 5. olcReferral: ldap://root.openldap.org +-E: 6. ++E: 6. + + Line 1 is a comment. Lines 2-4 identify this as the global + configuration entry. +@@ -1013,7 +966,7 @@ E: 7. # internal schema + E: 8. dn: cn=schema,cn=config + E: 9. objectClass: olcSchemaConfig + E: 10. cn: schema +-E: 11. ++E: 11. + + Line 7 is a comment. Lines 8-10 identify this as the root of + the schema subtree. The actual schema definitions in this entry +@@ -1022,7 +975,7 @@ Line 11 is a blank line, indicating the end of this entry. + + E: 12. # include the core schema + E: 13. include: file:///usr/local/etc/openldap/schema/core.ldif +-E: 14. ++E: 14. + + Line 12 is a comment. Line 13 is an LDIF include directive which + accesses the {{core}} schema definitions in LDIF format. Line 14 +@@ -1037,7 +990,7 @@ E: 16. dn: olcDatabase=frontend,cn=config + E: 17. objectClass: olcDatabaseConfig + E: 18. olcDatabase: frontend + E: 19. olcAccess: to * by * read +-E: 20. ++E: 20. + + Line 15 is a comment. Lines 16-18 identify this entry as the global + database entry. Line 19 is a global access control. It applies to all +@@ -1066,16 +1019,16 @@ inaccessible.) + + Line 28 is a blank line. + +-The next entry defines a BDB backend that will handle queries for things ++The next entry defines an MDB backend that will handle queries for things + in the "dc=example,dc=com" portion of the tree. Indices are to be maintained + for several attributes, and the {{EX:userPassword}} attribute is to be + protected from unauthorized access. + +-E: 29. # BDB definition for example.com +-E: 30. dn: olcDatabase=bdb,cn=config ++E: 29. # MDB definition for example.com ++E: 30. dn: olcDatabase=mdb,cn=config + E: 31. objectClass: olcDatabaseConfig +-E: 32. objectClass: olcBdbConfig +-E: 33. olcDatabase: bdb ++E: 32. objectClass: olcMdbConfig ++E: 33. olcDatabase: mdb + E: 34. olcSuffix: dc=example,dc=com + E: 35. olcDbDirectory: /usr/local/var/openldap-data + E: 36. olcRootDN: cn=Manager,dc=example,dc=com +@@ -1092,7 +1045,7 @@ E: 46. olcAccess: to * + E: 47. by self write + E: 48. by dn.base="cn=Admin,dc=example,dc=com" write + E: 49. by * read +-E: 50. ++E: 50. + + Line 29 is a comment. Lines 30-33 identify this entry as a BDB database + configuration entry. Line 34 specifies the DN suffix +@@ -1116,16 +1069,16 @@ entry, but may be read by all users (authenticated or not). + Line 50 is a blank line, indicating the end of this entry. + + The next entry defines another +-BDB database. This one handles queries involving the ++MDB database. This one handles queries involving the + {{EX:dc=example,dc=net}} subtree but is managed by the same entity + as the first database. Note that without line 60, the read access + would be allowed due to the global access rule at line 19. + +-E: 51. # BDB definition for example.net +-E: 52. dn: olcDatabase=bdb,cn=config ++E: 51. # MDB definition for example.net ++E: 52. dn: olcDatabase=mdb,cn=config + E: 53. objectClass: olcDatabaseConfig +-E: 54. objectClass: olcBdbConfig +-E: 55. olcDatabase: bdb ++E: 54. objectClass: olcMdbConfig ++E: 55. olcDatabase: mdb + E: 56. olcSuffix: dc=example,dc=net + E: 57. olcDbDirectory: /usr/local/var/openldap-data-net + E: 58. olcRootDN: cn=Manager,dc=example,dc=com +diff --git a/doc/guide/admin/slapdconfig.sdf b/doc/guide/admin/slapdconfig.sdf +index d943eb9..8b1162c 100644 +--- a/doc/guide/admin/slapdconfig.sdf ++++ b/doc/guide/admin/slapdconfig.sdf +@@ -90,7 +90,7 @@ H4: access to [ by [] [] ]+ + + This directive grants access (specified by ) to a set + of entries and/or attributes (specified by ) by one or more +-requestors (specified by ). See the {{SECT:Access Control}} section of ++requestors (specified by ). See the {{SECT:Access Control}} section of + this guide for basic usage. + + !if 0 +@@ -162,7 +162,7 @@ Level Keyword Description + !endblock + + The desired log level can be input as a single integer that +-combines the (ORed) desired levels, both in decimal or in hexadecimal ++combines the (ORed) desired levels, both in decimal or in hexadecimal + notation, as a list of integers (that are ORed internally), or as a list of the names that are shown between brackets, such that + + > loglevel 129 +@@ -264,9 +264,7 @@ supported backend types listed in Table 6.2. + !block table; align=Center; coltags="EX,N"; \ + title="Table 6.2: Database Backends" + Types Description +-bdb Berkeley DB transactional backend (deprecated) + dnssrv DNS SRV backend +-hdb Hierarchical variant of bdb backend (deprecated) + ldap Lightweight Directory Access Protocol (Proxy) backend + mdb Memory-Mapped DB backend + meta Meta Directory backend +@@ -507,7 +505,7 @@ defaults for these parameters come from {{ldap.conf}}(5). + The {{EX:binddn}} parameter gives the DN to bind as for the + syncrepl searches to the provider slapd. It should be a DN + which has read access to the replication content in the +-master database. ++master database. + + The {{EX:bindmethod}} is {{EX:simple}} or {{EX:sasl}}, + depending on whether simple password-based authentication or +@@ -564,8 +562,7 @@ conforms to the obsolete {{changelog}} format. If the {{EX:syncdata}} + parameter is omitted or set to {{EX:"default"}} then the log + parameters are ignored. + +-The {{syncrepl}} replication mechanism is supported by the {{bdb}}, +-{{hdb}}, and {{mdb}} backends. ++The {{syncrepl}} replication mechanism is supported by the {{mdb}} backends. + + See the {{SECT:LDAP Sync Replication}} chapter of this guide for + more information on how to use this directive. +@@ -584,19 +581,18 @@ If specified multiple times, each {{TERM:URL}} is provided. + > updateref ldap://master.example.net + + +-H3: BDB and HDB Database Directives ++H3: MDB Database Directives + +-Directives in this category only apply to both the {{TERM:BDB}} +-and the {{TERM:HDB}} database. +-That is, they must follow a "database bdb" or "database hdb" line +-and come before any +-subsequent "backend" or "database" line. For a complete reference +-of BDB/HDB configuration directives, see {{slapd-bdb}}(5). ++Directives in this category only apply to the {{TERM:MDB}} ++database backend. ++That is, they must follow a "database mdb" line ++and come before any subsequent "backend" or "database" lines. ++For a complete reference of MDB configuration directives, see {{slapd-mdb}}(5). + + + H4: directory + +-This directive specifies the directory where the BDB files ++This directive specifies the directory where the MDB files + containing the database and associated indices live. + + \Default: +@@ -604,11 +600,189 @@ containing the database and associated indices live. + > directory /usr/local/var/openldap-data + + ++H4: checkpoint ++ ++This directive specifies the frequency for flushing the database disk ++buffers. This directive is only needed if the {{dbnosync}} option is ++{{EX:TRUE}}. ++The checkpoint will occur if either data has been written or ++ minutes have passed since the last checkpoint. Both arguments default ++to zero, in which case they are ignored. When the argument is ++non-zero, an internal task will run every minutes to perform the ++checkpoint. Note: currently the _kbyte_ setting is unimplemented. ++ ++\Example: ++ ++> checkpoint: 1024 10 ++ ++H4: dbnosync: { TRUE | FALSE } ++ ++This directive causes on-disk database contents to not be immediately ++synchronized with in memory changes upon change. Setting this option ++to {{EX:TRUE}} may improve performance at the expense of data integrity. ++ ++ ++H4: envflags: {nosync,nometasync,writemap,mapasync,nordahead} ++ ++This option specifies flags for finer-grained control of the LMDB library's ++operation. ++ ++* {{F:nosync}}: This is exactly the same as the dbnosync directive. ++ ++* {{F:nometasync}}: Flush the data on a commit, but skip the sync of the meta ++page. This mode is slightly faster than doing a full sync, but can ++potentially lose the last committed transaction if the operating system ++crashes. If both nometasync and nosync are set, the nosync flag takes ++precedence. ++ ++* {{F:writemap}}: Use a writable memory map instead of just read-only. This ++speeds up write operations but makes the database vulnerable to corruption in ++case any bugs in slapd cause stray writes into the mmap region. ++ ++* {{F:mapasync}}: When using a writable memory map and performing flushes on ++each commit, use an asynchronous flush instead of a synchronous flush (the ++default). This option has no effect if writemap has not been set. It also has ++no effect if nosync is set. ++ ++* {{F:nordahead}}: Turn off file readahead. Usually the OS performs readahead ++on every read request. This usually boosts read performance but can be ++harmful to random access read performance if the system's memory is full and ++the DB is larger than RAM. This option is not implemented on Windows. ++ ++ ++H4: index: { | default} [pres,eq,approx,sub,none] ++ ++This directive specifies the indices to maintain for the given ++attribute. If only an {{EX:}} is given, the default ++indices are maintained. The index keywords correspond to the ++common types of matches that may be used in an LDAP search filter. ++ ++\Example: ++ ++> index: default pres,eq ++> index: uid ++> index: cn,sn pres,eq,sub ++> index: objectClass eq ++ ++The first line sets the default set of indices to maintain to ++present and equality. The second line causes the default (pres,eq) ++set of indices to be maintained for the {{EX:uid}} attribute type. ++The third line causes present, equality, and substring indices to ++be maintained for {{EX:cn}} and {{EX:sn}} attribute types. The ++fourth line causes an equality index for the {{EX:objectClass}} ++attribute type. ++ ++There is no index keyword for inequality matches. Generally these ++matches do not use an index. However, some attributes do support ++indexing for inequality matches, based on the equality index. ++ ++A substring index can be more explicitly specified as {{EX:subinitial}}, ++{{EX:subany}}, or {{EX:subfinal}}, corresponding to the three ++possible components ++of a substring match filter. A subinitial index only indexes ++substrings that appear at the beginning of an attribute value. ++A subfinal index only indexes substrings that appear at the end ++of an attribute value, while subany indexes substrings that occur ++anywhere in a value. ++ ++Note that by default, setting an index for an attribute also ++affects every subtype of that attribute. E.g., setting an equality ++index on the {{EX:name}} attribute causes {{EX:cn}}, {{EX:sn}}, and every other ++attribute that inherits from {{EX:name}} to be indexed. ++ ++By default, no indices are maintained. It is generally advised ++that minimally an equality index upon objectClass be maintained. ++ ++> index: objectClass eq ++ ++Additional indices should be configured corresponding to the ++most common searches that are used on the database. ++Presence indexing should not be configured for an attribute ++unless the attribute occurs very rarely in the database, and ++presence searches on the attribute occur very frequently during ++normal use of the directory. Most applications don't use presence ++searches, so usually presence indexing is not very useful. ++ ++ ++H4: maxreaders: ++ ++This directive specifies the maximum number of threads that may have ++concurrent read access to the database. Tools such as slapcat count as a ++single thread, in addition to threads in any active slapd processes. The ++default is 126. ++ ++ ++H4: maxsize: ++ ++This directive specifies the maximum size of the database in bytes. A memory ++map of this size is allocated at startup time and the database will not be ++allowed to grow beyond this size. The default is 10485760 bytes (10MB). This ++setting may be changed upward if the configured limit needs to be increased. ++ ++Note: It is important to set this to as large a value as possible, (relative ++to anticipated growth of the actual data over time) since growing the size ++later may not be practical when the system is under heavy load. ++ ++ ++H4: mode: { | } ++ ++This directive specifies the file protection mode that newly ++created database index files should have. This can be in the form ++{{EX:0600}} or {{EX:-rw-------}} ++ ++\Default: ++ ++> mode: 0600 ++ ++ ++H4: rtxnsize: ++ ++This directive specifies the maximum number of entries to process in a single ++read transaction when executing a large search. Long-lived read transactions ++prevent old database pages from being reused in write transactions, and so ++can cause significant growth of the database file when there is heavy write ++traffic. This setting causes the read transaction in large searches to be ++released and reacquired after the given number of entries has been read, to ++give writers the opportunity to reclaim old database pages. The default is ++10000. ++ ++ ++H4: searchstack: ++ ++Specify the depth of the stack used for search filter evaluation. ++Search filters are evaluated on a stack to accommodate nested {{EX:AND}} / ++{{EX:OR}} clauses. An individual stack is allocated for each server thread. ++The depth of the stack determines how complex a filter can be evaluated ++without requiring any additional memory allocation. Filters that are ++nested deeper than the search stack depth will cause a separate stack to ++be allocated for that particular search operation. These separate allocations ++can have a major negative impact on server performance, but specifying ++too much stack will also consume a great deal of memory. Each search ++uses 512K bytes per level on a 32-bit machine, or 1024K bytes per level ++on a 64-bit machine. The default stack depth is 16, thus 8MB or 16MB ++per thread is used on 32 and 64 bit machines, respectively. Also the ++512KB size of a single stack slot is set by a compile-time constant which ++may be changed if needed; the code must be recompiled for the change ++to take effect. ++ ++\Default: ++ ++> searchstack: 16 ++ ++ ++H4: Sample Entry ++ ++>database mdb ++>suffix: "dc=example,dc=com" ++>directory: /usr/local/var/openldap-data ++>index: objectClass eq ++ ++ + H2: Configuration File Example + + The following is an example configuration file, interspersed + with explanatory text. It defines two databases to handle +-different parts of the {{TERM:X.500}} tree; both are {{TERM:BDB}} ++different parts of the {{TERM:X.500}} tree; both are {{TERM:MDB}} + database instances. The line numbers shown are provided for + reference only and are not included in the actual file. First, the + global configuration section: +@@ -617,7 +791,7 @@ E: 1. # example config file - global configuration section + E: 2. include /usr/local/etc/schema/core.schema + E: 3. referral ldap://root.openldap.org + E: 4. access to * by * read +- ++ + Line 1 is a comment. Line 2 includes another config file + which contains {{core}} schema definitions. + The {{EX:referral}} directive on line 3 +@@ -629,7 +803,7 @@ Line 4 is a global access control. It applies to all + entries (after any applicable database-specific access + controls). + +-The next section of the configuration file defines a BDB ++The next section of the configuration file defines a MDB + backend that will handle queries for things in the + "dc=example,dc=com" portion of the tree. The + database is to be replicated to two slave slapds, one on +@@ -637,8 +811,8 @@ truelies, the other on judgmentday. Indices are to be + maintained for several attributes, and the {{EX:userPassword}} + attribute is to be protected from unauthorized access. + +-E: 5. # BDB definition for the example.com +-E: 6. database bdb ++E: 5. # MDB definition for the example.com ++E: 6. database mdb + E: 7. suffix "dc=example,dc=com" + E: 8. directory /usr/local/var/openldap-data + E: 9. rootdn "cn=Manager,dc=example,dc=com" +@@ -683,8 +857,8 @@ BDB database. This one handles queries involving the + as the first database. Note that without line 39, the read access + would be allowed due to the global access rule at line 4. + +-E: 33. # BDB definition for example.net +-E: 34. database bdb ++E: 33. # MDB definition for example.net ++E: 34. database mdb + E: 35. suffix "dc=example,dc=net" + E: 36. directory /usr/local/var/openldap-data-net + E: 37. rootdn "cn=Manager,dc=example,dc=com" +diff --git a/doc/guide/admin/tuning.sdf b/doc/guide/admin/tuning.sdf +index 7074561..795c5ce 100644 +--- a/doc/guide/admin/tuning.sdf ++++ b/doc/guide/admin/tuning.sdf +@@ -27,10 +27,6 @@ H3: Memory + + Scale your cache to use available memory and increase system memory if you can. + +-See {{SECT:Caching}} for BDB cache tuning hints. +-Note that LMDB uses no cache of its own and has no tuning options, so the Caching +-section can be ignored when using LMDB. +- + + H3: Disks + +@@ -39,15 +35,7 @@ types perform best with your workload. (On our own Linux testing, EXT2 and JFS + tend to provide better write performance than everything else, including + newer filesystems like EXT4, BTRFS, etc.) + +-Use fast subsystems. Put each database and logs on separate disks +-(for BDB this is configurable via {{DB_CONFIG}}): +- +-> # Data Directory +-> set_data_dir /data/db +-> +-> # Transaction Log settings +-> set_lg_dir /logs +- ++Use fast subsystems. Put each database on separate disks + + H3: Network Topology + +@@ -131,7 +119,7 @@ H3: What to watch out for + + The most common message you'll see that you should pay attention to is: + +-> "<= bdb_equality_candidates: (foo) index_param failed (18)" ++> "<= mdb_equality_candidates: (foo) index_param failed (18)" + + That means that some application tried to use an equality filter ({{foo=}}) + and attribute {{foo}} does not have an equality index. If you see a lot of these +@@ -163,165 +151,6 @@ For syslog-ng, add or modify the following line in {{syslog-ng.conf}}: + where n is the number of lines which will be buffered before a write. + + +-H2: Caching +- +-We all know what caching is, don't we? +- +-In brief, "A cache is a block of memory for temporary storage of data likely +-to be used again" - {{URL:http://en.wikipedia.org/wiki/Cache}} +- +-There are 3 types of caches, BerkeleyDB's own cache, {{slapd}}(8) +-entry cache and {{TERM:IDL}} (IDL) cache. +- +- +-H3: Berkeley DB Cache +- +-There are two ways to tune for the BDB cachesize: +- +-(a) BDB cache size necessary to load the database via slapadd in optimal time +- +-(b) BDB cache size necessary to have a high performing running slapd once the data is loaded +- +-For (a), the optimal cachesize is the size of the entire database. If you +-already have the database loaded, this is simply a +- +-> du -c -h *.bdb +- +-in the directory containing the OpenLDAP ({{/usr/local/var/openldap-data}}) data. +- +-For (b), the optimal cachesize is just the size of the {{id2entry.bdb}} file, +-plus about 10% for growth. +- +-The tuning of {{DB_CONFIG}} should be done for each BDB type database +-instantiated (back-bdb, back-hdb). +- +-Note that while the {{TERM:BDB}} cache is just raw chunks of memory and +-configured as a memory size, the {{slapd}}(8) entry cache holds parsed entries, +-and the size of each entry is variable. +- +-There is also an IDL cache which is used for Index Data Lookups. +-If you can fit all of your database into slapd's entry cache, and all of your +-index lookups fit in the IDL cache, that will provide the maximum throughput. +- +-If not, but you can fit the entire database into the BDB cache, then you +-should do that and shrink the slapd entry cache as appropriate. +- +-Failing that, you should balance the BDB cache against the entry cache. +- +-It is worth noting that it is not absolutely necessary to configure a BerkeleyDB +-cache equal in size to your entire database. All that you need is a cache +-that's large enough for your "working set." +- +-That means, large enough to hold all of the most frequently accessed data, +-plus a few less-frequently accessed items. +- +-For more information, please see: {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/ref/am_conf/cachesize.html}} +- +-H4: Calculating Cachesize +- +-The back-bdb database lives in two main files, {{F:dn2id.bdb}} and {{F:id2entry.bdb}}. +-These are B-tree databases. We have never documented the back-bdb internal +-layout before, because it didn't seem like something anyone should have to worry +-about, nor was it necessarily cast in stone. But here's how it works today, +-in OpenLDAP 2.4. +- +-A B-tree is a balanced tree; it stores data in its leaf nodes and bookkeeping +-data in its interior nodes (If you don't know what tree data structures look +- like in general, Google for some references, because that's getting far too +-elementary for the purposes of this discussion). +- +-For decent performance, you need enough cache memory to contain all the nodes +-along the path from the root of the tree down to the particular data item +-you're accessing. That's enough cache for a single search. For the general case, +-you want enough cache to contain all the internal nodes in the database. +- +-> db_stat -d +- +-will tell you how many internal pages are present in a database. You should +-check this number for both dn2id and id2entry. +- +-Also note that {{id2entry}} always uses 16KB per "page", while {{dn2id}} uses whatever +-the underlying filesystem uses, typically 4 or 8KB. To avoid thrashing, +-your cache must be at least as large as the number of internal pages in both +-the {{dn2id}} and {{id2entry}} databases, plus some extra space to accommodate +-the actual leaf data pages. +- +-For example, in my OpenLDAP 2.4 test database, I have an input LDIF file that's +-about 360MB. With the back-hdb backend this creates a {{dn2id.bdb}} that's 68MB, +-and an {{id2entry}} that's 800MB. db_stat tells me that {{dn2id}} uses 4KB pages, has +-433 internal pages, and 6378 leaf pages. The id2entry uses 16KB pages, has 52 +-internal pages, and 45912 leaf pages. In order to efficiently retrieve any +-single entry in this database, the cache should be at least +- +-> (433+1) * 4KB + (52+1) * 16KB in size: 1736KB + 848KB =~ 2.5MB. +- +-This doesn't take into account other library overhead, so this is even lower +-than the barest minimum. The default cache size, when nothing is configured, +-is only 256KB. +- +-This 2.5MB number also doesn't take indexing into account. Each indexed +-attribute results in another database file. Earlier versions of OpenLDAP +-kept these index databases in Hash format, but from OpenLDAP 2.2 onward +-the index databases are in B-tree format so the same procedure can +-be used to calculate the necessary amount of cache for each index database. +- +-For example, if your only index is for the objectClass attribute and db_stat +-reveals that {{objectClass.bdb}} has 339 internal pages and uses 4096 byte +-pages, the additional cache needed for just this attribute index is +- +-> (339+1) * 4KB =~ 1.3MB. +- +-With only this index enabled, I'd figure at least a 4MB cache for this backend. +-(Of course you're using a single cache shared among all of the database files, +-so the cache pages will most likely get used for something other than what you +-accounted for, but this gives you a fighting chance.) +- +-With this 4MB cache I can slapcat this entire database on my 1.3GHz PIII in +-1 minute, 40 seconds. With the cache doubled to 8MB, it still takes the same 1:40s. +-Once you've got enough cache to fit the B-tree internal pages, increasing it +-further won't have any effect until the cache really is large enough to hold +-100% of the data pages. I don't have enough free RAM to hold all the 800MB +-id2entry data, so 4MB is good enough. +- +-With back-bdb and back-hdb you can use "db_stat -m" to check how well the +-database cache is performing. +- +-For more information on {{db_stat}}: {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/utility/db_stat.html}} +- +-H3: {{slapd}}(8) Entry Cache (cachesize) +- +-The {{slapd}}(8) entry cache operates on decoded entries. The rationale - entries +-in the entry cache can be used directly, giving the fastest response. If an entry +-isn't in the entry cache but can be extracted from the BDB page cache, that will +-avoid an I/O but it will still require parsing, so this will be slower. +- +-If the entry is in neither cache then BDB will have to flush some of its current +-cached pages and bring in the needed pages, resulting in a couple of expensive +-I/Os as well as parsing. +- +-The most optimal value is of course, the entire number of entries in the database. +-However, most directory servers don't consistently serve out their entire database, so setting this to a lesser number that more closely matches the believed working set of data is +-sufficient. This is the second most important parameter for the DB. +- +-As far as balancing the entry cache vs the BDB cache - parsed entries in memory +-are generally about twice as large as they are on disk. +- +-As we have already mentioned, not having a proper database cache size will +-cause performance issues. These issues are not an indication of corruption +-occurring in the database. It is merely the fact that the cache is thrashing +-itself that causes performance/response time to slowdown. +- +- +-H3: {{TERM:IDL}} Cache (idlcachesize) +- +-Each IDL holds the search results from a given query, so the IDL cache will +-end up holding the most frequently requested search results. For back-bdb, +-it is generally recommended to match the "cachesize" setting. For back-hdb, +-it is generally recommended to be 3x"cachesize". +- +-{NOTE: The idlcachesize setting directly affects search performance} +- +- + H2: {{slapd}}(8) Threads + + {{slapd}}(8) can process requests via a configurable number of threads, which +diff --git a/doc/guide/preamble.sdf b/doc/guide/preamble.sdf +index b4cc0dd..aa84f9b 100644 +--- a/doc/guide/preamble.sdf ++++ b/doc/guide/preamble.sdf +@@ -167,7 +167,6 @@ AuthcId|Authentication Identity + AuthzDN|Authorization DN + AuthzId|Authorization Identity + BCP|Best Current Practice +-BDB|Berkeley DB (Backend) + BER|Basic Encoding Rules + BNF|Backus-Naur Form + C|The C Programming Language +@@ -201,7 +200,6 @@ FYI|For Your Information + GSER|Generic String Encoding Rules + GSS-API|Generic Security Service Application Program Interface + GSSAPI|SASL Kerberos V GSS-API Authentication Mechanism +-HDB|Hierarchical Database (Backend) + I-D|Internet-Draft + IA5|International Alphabet 5 + IDNA|Internationalized Domain Names in Applications +diff --git a/doc/guide/release/install.sdf b/doc/guide/release/install.sdf +index 6770e6a..83c95ae 100644 +--- a/doc/guide/release/install.sdf ++++ b/doc/guide/release/install.sdf +@@ -84,7 +84,7 @@ if you have not done so already. + + Test the standalone system: + + .This step requires the standalone LDAP server, {{slapd}}(8), +-with {{HDB}} and/or {{BDB}} support. ++with {{MDB}} support. + + E: % make test + +diff --git a/doc/man/man5/slapd-bdb.5 b/doc/man/man5/slapd-bdb.5 +deleted file mode 100644 +index 3c8ad9c..0000000 +--- a/doc/man/man5/slapd-bdb.5 ++++ /dev/null +@@ -1,286 +0,0 @@ +-.TH SLAPD-BDB 5 "RELEASEDATE" "OpenLDAP LDVERSION" +-.\" Copyright 1998-2020 The OpenLDAP Foundation All Rights Reserved. +-.\" Copying restrictions apply. See COPYRIGHT/LICENSE. +-.\" $OpenLDAP$ +-.SH NAME +-slapd\-bdb, slapd\-hdb \- Berkeley DB backends to slapd +-.SH SYNOPSIS +-.B ETCDIR/slapd.conf +-.SH DESCRIPTION +-The \fBbdb\fP backend to +-.BR slapd (8) +-uses the Oracle Berkeley DB (BDB) package to store data. +-It makes extensive use of indexing and caching to speed data access. +-.LP +-Note that BDB is deprecated and support will be dropped in future +-OpenLDAP releases. Installations should use the \fBmdb\fP +-backend instead. +-.LP +-\fBhdb\fP is a variant of +-the \fBbdb\fP backend that uses a hierarchical database layout which +-supports subtree renames. It is both more space-efficient and more +-execution-efficient than the \fBbdb\fP backend. It is otherwise identical +-to the \fBbdb\fP behavior, and all the same configuration options apply. +-.LP +-It is noted that these options are intended to complement +-Berkeley DB configuration options set in the environment's +-.B DB_CONFIG +-file. See Berkeley DB documentation for details on +-.B DB_CONFIG +-configuration options. +-Where there is overlap, settings in +-.B DB_CONFIG +-take precedence. +-.SH CONFIGURATION +-These +-.B slapd.conf +-options apply to the \fBbdb\fP and \fBhdb\fP backend database. +-That is, they must follow a "database bdb" or "database hdb" line and +-come before any subsequent "backend" or "database" lines. +-Other database options are described in the +-.BR slapd.conf (5) +-manual page. +-.TP +-.BI cachesize \ +-Specify the size in entries of the in-memory entry cache maintained +-by the \fBbdb\fP or \fBhdb\fP backend database instance. +-The default is 1000 entries. +-.TP +-.BI cachefree \ +-Specify the number of entries to free from the entry cache when the +-cache reaches the \fBcachesize\fP limit. +-The default is 1 entry. +-.TP +-.BI checkpoint \ \ +-Specify the frequency for checkpointing the database transaction log. +-A checkpoint operation flushes the database buffers to disk and writes +-a checkpoint record in the log. +-The checkpoint will occur if either \fI\fP data has been written or +-\fI\fP minutes have passed since the last checkpoint. +-Both arguments default to zero, in which case they are ignored. When +-the \fI\fP argument is non-zero, an internal task will run every +-\fI\fP minutes to perform the checkpoint. +-See the Berkeley DB reference guide for more details. +-.TP +-.B checksum +-Enable checksum validation of DB pages whenever they are read from disk. +-This setting can only be configured before any database files are created. +-.TP +-.BI cryptfile \ +-Specify the pathname of a file containing an encryption key to use for +-encrypting the database. Encryption is performed using Berkeley DB's +-implementation of AES. Note that encryption can only be configured before +-any database files are created, and changing the key can only be done +-after destroying the current database and recreating it. Encryption is +-not enabled by default, and some distributions of Berkeley DB do not +-support encryption. +-.TP +-.BI cryptkey \ +-Specify an encryption key to use for encrypting the database. This option +-may be used when a separate +-.I cryptfile +-is not desired. Only one of +-.B cryptkey +-or +-.B cryptfile +-may be configured. +-.TP +-.BI dbconfig \ +-Specify a configuration directive to be placed in the +-.B DB_CONFIG +-file of the database directory. The +-.B dbconfig +-directive is just a convenience +-to allow all necessary configuration to be set in the +-.B slapd.conf +-file. +-The options set using this directive will only be written to the +-.B DB_CONFIG +-file if no such file existed at server startup time, otherwise +-they are completely ignored. This allows one +-to set initial values without overwriting/destroying a +-.B DB_CONFIG +-file that was already customized through other means. +-This directive may be specified multiple times, as needed. +-For example: +-.RS +-.nf +- dbconfig set_cachesize 0 1048576 0 +- dbconfig set_lg_bsize 2097152 +-.fi +-.RE +-.TP +-.B dbnosync +-Specify that on-disk database contents should not be immediately +-synchronized with in memory changes. +-Enabling this option may improve performance at the expense of data +-security. +-See the Berkeley DB reference guide for more details. +-.TP +-\fBdbpagesize \fR \fI \fR +-Specify the page size to use for a particular database file, in units +-of 1024 bytes. The default for the +-.B id2entry +-file is 16, the default for all other files depends on the size of the +-underlying filesystem's block size (typically 4 or 8). +-The maximum that BerkeleyDB supports is 64. This +-setting usually should not need to be changed, but if BerkeleyDB's +-"db_stat \-d" shows a large amount of overflow pages in use in a file, +-setting a larger size may increase performance at the expense of +-data integrity. This setting only takes effect when a database is +-being newly created. See the Berkeley DB reference guide for more details. +-.TP +-.BI directory \ +-Specify the directory where the BDB files containing this database and +-associated indexes live. +-A separate directory must be specified for each database. +-The default is +-.BR LOCALSTATEDIR/openldap\-data . +-.TP +-.B dirtyread +-Allow reads of modified but not yet committed data. +-Usually transactions are isolated to prevent other operations from +-accessing uncommitted data. +-This option may improve performance, but may also return inconsistent +-results if the data comes from a transaction that is later aborted. +-In this case, the modified data is discarded and a subsequent search +-will return a different result. +-.TP +-.BI dncachesize \ +-Specify the maximum number of DNs in the in-memory DN cache. +-Ideally this cache should be +-large enough to contain the DNs of every entry in the database. If +-set to a smaller value than the \fBcachesize\fP it will be silently +-increased to equal the \fBcachesize\fP. The default value is 0 which +-means unlimited, i.e. the DN cache will grow without bound. +- +-It should be noted that the \fBDN cache\fP is allowed to temporarily +-grow beyond the configured size. It does this if many entries are +-locked when it tries to do a purge, because that means they're +-legitimately in use. Also, the \fBDN cache\fP never purges entries +-that have cached children, so depending on the shape of the DIT, it +-could have lots of cached DNs over the defined limit. +-.TP +-.BI idlcachesize \ +-Specify the size of the in-memory index cache, in index slots. The +-default is zero. A larger value will speed up frequent searches of +-indexed entries. An \fBhdb\fP database needs a large \fBidlcachesize\fP +-for good search performance, typically three times the +-.B cachesize +-(entry cache size) +-or larger. +-.TP +-\fBindex \fR{\fI\fR|\fBdefault\fR} [\fBpres\fR,\fBeq\fR,\fBapprox\fR,\fBsub\fR,\fI\fR] +-Specify the indexes to maintain for the given attribute (or +-list of attributes). +-Some attributes only support a subset of indexes. +-If only an \fI\fP is given, the indices specified for \fBdefault\fR +-are maintained. +-Note that setting a default does not imply that all attributes will be +-indexed. Also, for best performance, an +-.B eq +-index should always be configured for the +-.B objectClass +-attribute. +- +-A number of special index parameters may be specified. +-The index type +-.B sub +-can be decomposed into +-.BR subinitial , +-.BR subany ,\ and +-.B subfinal +-indices. +-The special type +-.B nolang +-may be specified to disallow use of this index by language subtypes. +-The special type +-.B nosubtypes +-may be specified to disallow use of this index by named subtypes. +-Note: changing \fBindex\fP settings in +-.BR slapd.conf (5) +-requires rebuilding indices, see +-.BR slapindex (8); +-changing \fBindex\fP settings +-dynamically by LDAPModifying "cn=config" automatically causes rebuilding +-of the indices online in a background task. +-.TP +-.B linearindex +-Tell +-.B slapindex +-to index one attribute at a time. By default, all indexed +-attributes in an entry are processed at the same time. With this option, +-each indexed attribute is processed individually, using multiple passes +-through the entire database. This option improves +-.B slapindex +-performance +-when the database size exceeds the \fBdbcache\fP size. When the \fBdbcache\fP is +-large enough, this option is not needed and will decrease performance. +-Also by default, +-.B slapadd +-performs full indexing and so a separate +-.B slapindex +-run is not needed. With this option, +-.B slapadd +-does no indexing and +-.B slapindex +-must be used. +-.TP +-.BR lockdetect \ { oldest | youngest | fewest | random | default } +-Specify which transaction to abort when a deadlock is detected. +-The default is +-.BR random . +-.TP +-.BI mode \ +-Specify the file protection mode that newly created database +-index files should have. +-The default is 0600. +-.TP +-.BI searchstack \ +-Specify the depth of the stack used for search filter evaluation. +-Search filters are evaluated on a stack to accommodate nested AND / OR +-clauses. An individual stack is assigned to each server thread. +-The depth of the stack determines how complex a filter can be +-evaluated without requiring any additional memory allocation. Filters that +-are nested deeper than the search stack depth will cause a separate +-stack to be allocated for that particular search operation. These +-allocations can have a major negative impact on server performance, +-but specifying too much stack will also consume a great deal of memory. +-Each search stack uses 512K bytes per level. The default stack depth +-is 16, thus 8MB per thread is used. +-.TP +-.BI shm_key \ +-Specify a key for a shared memory BDB environment. By default the +-BDB environment uses memory mapped files. If a non-zero value is +-specified, it will be used as the key to identify a shared memory +-region that will house the environment. +-.SH ACCESS CONTROL +-The +-.B bdb +-and +-.B hdb +-backends honor access control semantics as indicated in +-.BR slapd.access (5). +-.SH FILES +-.TP +-.B ETCDIR/slapd.conf +-default +-.B slapd +-configuration file +-.TP +-.B DB_CONFIG +-Berkeley DB configuration file +-.SH SEE ALSO +-.BR slapd.conf (5), +-.BR slapd\-config (5), +-.BR slapd\-mdb (5), +-.BR slapd (8), +-.BR slapadd (8), +-.BR slapcat (8), +-.BR slapindex (8), +-Berkeley DB documentation. +-.SH ACKNOWLEDGEMENTS +-.so ../Project +-Originally begun by Kurt Zeilenga. Caching mechanisms originally designed +-by Jong-Hyuk Choi. Completion and subsequent work, as well as +-back-hdb, by Howard Chu. +diff --git a/doc/man/man5/slapd-bdb.5.links b/doc/man/man5/slapd-bdb.5.links +deleted file mode 100644 +index 3bc8c40..0000000 +--- a/doc/man/man5/slapd-bdb.5.links ++++ /dev/null +@@ -1 +0,0 @@ +-slapd-hdb.5 +diff --git a/doc/man/man5/slapd-config.5 b/doc/man/man5/slapd-config.5 +index 5753292..3061dcf 100644 +--- a/doc/man/man5/slapd-config.5 ++++ b/doc/man/man5/slapd-config.5 +@@ -1123,10 +1123,8 @@ The entry must be named + and must have the olcBackendConfig objectClass. + + should be one of +-.BR bdb , + .BR config , + .BR dnssrv , +-.BR hdb , + .BR ldap , + .BR ldif , + .BR mdb , +@@ -2059,10 +2057,10 @@ olcDatabase: config + olcRootPW: {SSHA}XKYnrjvGT3wZFQrDD5040US592LxsdLy + olcAccess: to * by * none + +-dn: olcDatabase=bdb,cn=config ++dn: olcDatabase=mdb,cn=config + objectClass: olcDatabaseConfig +-objectClass: olcBdbConfig +-olcDatabase: bdb ++objectClass: olcMdbConfig ++olcDatabase: mdb + olcSuffix: "dc=our\-domain,dc=com" + # The database directory MUST exist prior to + # running slapd AND should only be accessible +diff --git a/doc/man/man5/slapd-mdb.5 b/doc/man/man5/slapd-mdb.5 +index 62146b0..8955bbb 100644 +--- a/doc/man/man5/slapd-mdb.5 ++++ b/doc/man/man5/slapd-mdb.5 +@@ -14,11 +14,8 @@ It relies completely on the underlying operating system for memory + management and does no caching of its own. It is the recommended + primary database backend. + .LP +-The \fBmdb\fP backend is similar to the \fBhdb\fP backend in that +-it uses a hierarchical database layout which +-supports subtree renames. It is both more space-efficient and more +-execution-efficient than the \fBbdb\fP backend, while being overall +-much simpler to manage. ++The \fBmdb\fP backend uses a hierarchical database layout which ++supports subtree renames. + .SH CONFIGURATION + These + .B slapd.conf +diff --git a/doc/man/man5/slapd-sql.5 b/doc/man/man5/slapd-sql.5 +index 8492553..ccfa3a4 100644 +--- a/doc/man/man5/slapd-sql.5 ++++ b/doc/man/man5/slapd-sql.5 +@@ -19,7 +19,7 @@ sites/applications that use RDBMSes and/or LDAP. + Or whatever else... + .LP + It is NOT designed as a general-purpose backend that uses RDBMS instead +-of BerkeleyDB (as the standard BDB backend does), though it can be ++of MDB (as the standard MDB backend does), though it can be + used as such with several limitations. + You can take a look at + .B http://www.openldap.org/faq/index.cgi?file=378 +diff --git a/doc/man/man5/slapd.access.5 b/doc/man/man5/slapd.access.5 +index c62158b..ebad05a 100644 +--- a/doc/man/man5/slapd.access.5 ++++ b/doc/man/man5/slapd.access.5 +@@ -920,9 +920,8 @@ identity, control is passed straight to the subsequent rules. + + .SH OPERATION REQUIREMENTS + Operations require different privileges on different portions of entries. +-The following summary applies to primary MDB database backend and the +-deprecated BDB and HDB backends. Requirements for other backends may +-(and often do) differ. ++The following summary applies to primary MDB database backend. Requirements ++for other backends may (and often do) differ. + + .LP + The +@@ -1085,9 +1084,7 @@ Access control to search entries is checked by the frontend, + so it is fully honored by all backends; for all other operations + and for the discovery phase of the search operation, + full ACL semantics is only supported by the primary backends, i.e. +-.BR back\-bdb (5), +-and +-.BR back\-hdb (5). ++.BR back\-mdb (5). + + Some other backend, like + .BR back\-sql (5), +diff --git a/doc/man/man5/slapd.backends.5 b/doc/man/man5/slapd.backends.5 +index b9f9190..25a70e6 100644 +--- a/doc/man/man5/slapd.backends.5 ++++ b/doc/man/man5/slapd.backends.5 +@@ -19,14 +19,6 @@ corresponding + .BR slapd\- (5) + manual pages. + .TP +-.B bdb +-This was the recommended primary backend through OpenLDAP 2.3, but it has +-since been superseded by the +-.BR mdb +-backend. It takes care to configure it properly. +-It uses the transactional database interface of the Oracle Berkeley +-DB (BDB) package to store data. +-.TP + .B config + This backend is used to manage the configuration of slapd at run-time. + Unlike other backends, only a single instance of the +@@ -41,22 +33,6 @@ This backend is experimental. + It serves up referrals based upon SRV resource records held in the + Domain Name System. + .TP +-.B hdb +-This was the recommended primary backend through OpenLDAP 2.4.40 but it has +-since been superseded by the +-.BR mdb +-backend. It takes care to configure it properly. +-.B hdb +-is a variant of the +-.B bdb +-backend that uses a hierarchical database +-layout. +-This layout stores entry DNs more efficiently than the +-.B bdb +-backend, +-using less space and requiring less work to create, delete, and rename +-entries. It is also one of the few backends to support subtree renames. +-.TP + .B ldap + This backend acts as a proxy to forward incoming requests to another + LDAP server. +@@ -68,14 +44,9 @@ Its usage should be limited to very simple databases, where performance + is not a requirement. This backend also supports subtree renames. + .TP + .B mdb +-This is the recommended primary backend, superseding +-.BR hdb . ++This is the recommended primary backend. + This backend uses OpenLDAP's own MDB transactional database +-library. It is extremely compact and extremely efficient, delivering +-much higher performance than the Berkeley DB backends while using +-significantly less memory. Also, unlike Berkeley DB, MDB is crash proof, +-and requires no special tuning or maintenance. +-This backend also supports subtree renames. ++library. This backend also supports subtree renames. + .TP + .B meta + This backend performs basic LDAP proxying with respect to a set of +@@ -138,10 +109,8 @@ ETCDIR/slapd.d + default slapd configuration directory + .SH SEE ALSO + .BR ldap (3), +-.BR slapd\-bdb (5), + .BR slapd\-config (5), + .BR slapd\-dnssrv (5), +-.BR slapd\-hdb (5), + .BR slapd\-ldap (5), + .BR slapd\-ldif (5), + .BR slapd\-mdb (5), +diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5 +index 78b2415..0fa62ce 100644 +--- a/doc/man/man5/slapd.conf.5 ++++ b/doc/man/man5/slapd.conf.5 +@@ -1250,10 +1250,8 @@ type of backend. + .B backend + Mark the beginning of a backend definition. + should be one of +-.BR bdb , + .BR config , + .BR dnssrv , +-.BR hdb , + .BR ldap , + .BR ldif , + .BR mdb , +@@ -1280,10 +1278,8 @@ option are mandatory for each database. + .B database + Mark the beginning of a new database instance definition. + should be one of +-.BR bdb , + .BR config , + .BR dnssrv , +-.BR hdb , + .BR ldap , + .BR ldif , + .BR mdb , +@@ -1593,8 +1589,7 @@ By default, mirrormode is off. + This option enables database-specific monitoring in the entry related + to the current database in the "cn=Databases,cn=Monitor" subtree + of the monitor database, if the monitor database is enabled. +-Currently, only the BDB and the HDB databases provide database-specific +-monitoring. ++Currently, only the MDB databases provide database-specific monitoring. + The default depends on the backend type. + .TP + .B overlay +diff --git a/doc/man/man5/slapd.overlays.5 b/doc/man/man5/slapd.overlays.5 +index 2345d81..8ca9783 100644 +--- a/doc/man/man5/slapd.overlays.5 ++++ b/doc/man/man5/slapd.overlays.5 +@@ -91,7 +91,7 @@ password resets, etc. + .B refint + Referential Integrity. + This overlay can be used with a backend database such as +-.BR slapd\-bdb (5) ++.BR slapd\-mdb (5) + to maintain the cohesiveness of a schema which utilizes reference + attributes. + .TP +@@ -121,7 +121,7 @@ replication, including persistent search functionality. + .B translucent + Translucent Proxy. + This overlay can be used with a backend database such as +-.BR slapd\-bdb (5) ++.BR slapd\-mdb (5) + to create a "translucent proxy". + Content of entries retrieved from a remote LDAP server can be partially + overridden by the database. +@@ -129,7 +129,7 @@ overridden by the database. + .B unique + Attribute Uniqueness. + This overlay can be used with a backend database such as +-.BR slapd\-bdb (5) ++.BR slapd\-mdb (5) + to enforce the uniqueness of some or all attributes within a subtree. + .TP + .B valsort +diff --git a/doc/man/man8/slapcat.8 b/doc/man/man8/slapcat.8 +index bd22637..a80ad36 100644 +--- a/doc/man/man8/slapcat.8 ++++ b/doc/man/man8/slapcat.8 +@@ -177,8 +177,6 @@ mode) when you do this to ensure consistency of the database. It is + always safe to run + .B slapcat + with the +-.BR slapd\-bdb (5), +-.BR slapd\-hdb (5), + .BR slapd\-mdb (5), + and + .BR slapd\-null (5) +diff --git a/doc/man/man8/slapschema.8 b/doc/man/man8/slapschema.8 +index 704ab0c..f4ea0cd 100644 +--- a/doc/man/man8/slapschema.8 ++++ b/doc/man/man8/slapschema.8 +@@ -168,8 +168,7 @@ mode) when you do this to ensure consistency of the database. It is + always safe to run + .B slapschema + with the +-.BR slapd\-bdb (5), +-.BR slapd\-hdb (5), ++.BR slapd\-mdb (5), + and + .BR slapd\-null (5) + backends. +diff --git a/include/portable.hin b/include/portable.hin +index 3169f03..1b1be1a 100644 +--- a/include/portable.hin ++++ b/include/portable.hin +@@ -99,12 +99,6 @@ + /* Define to 1 if you have the `bcopy' function. */ + #undef HAVE_BCOPY + +-/* define this if Berkeley DB is available */ +-#undef HAVE_BERKELEY_DB +- +-/* define if Berkeley DB has DB_THREAD support */ +-#undef HAVE_BERKELEY_DB_THREAD +- + /* Define to 1 if you have the header file. */ + #undef HAVE_BITS_TYPES_H + +@@ -924,9 +918,6 @@ + /* define to support per-object ACIs */ + #undef SLAPD_ACI_ENABLED + +-/* define to support BDB backend */ +-#undef SLAPD_BDB +- + /* define to support cleartext passwords */ + #undef SLAPD_CLEARTEXT + +@@ -936,9 +927,6 @@ + /* define to support DNS SRV backend */ + #undef SLAPD_DNSSRV + +-/* define to support HDB backend */ +-#undef SLAPD_HDB +- + /* define to support LDAP backend */ + #undef SLAPD_LDAP + +diff --git a/servers/slapd/DB_CONFIG b/servers/slapd/DB_CONFIG +deleted file mode 100644 +index d0f2c68..0000000 +--- a/servers/slapd/DB_CONFIG ++++ /dev/null +@@ -1,28 +0,0 @@ +-# $OpenLDAP$ +-# Example DB_CONFIG file for use with slapd(8) BDB/HDB databases. +-# +-# See the Oracle Berkeley DB documentation +-# +-# for detail description of DB_CONFIG syntax and semantics. +-# +-# Hints can also be found in the OpenLDAP Software FAQ +-# +-# in particular: +-# +- +-# Note: most DB_CONFIG settings will take effect only upon rebuilding +-# the DB environment. +- +-# one 0.25 GB cache +-set_cachesize 0 268435456 1 +- +-# Data Directory +-#set_data_dir db +- +-# Transaction Log settings +-set_lg_regionmax 262144 +-set_lg_bsize 2097152 +-#set_lg_dir logs +- +-# Note: special DB_CONFIG flags are no longer needed for "quick" +-# slapadd(8) or slapindex(8) access (see their -q option). +diff --git a/servers/slapd/Makefile.in b/servers/slapd/Makefile.in +index b20564d..9a9f589 100644 +--- a/servers/slapd/Makefile.in ++++ b/servers/slapd/Makefile.in +@@ -38,7 +38,7 @@ SRCS = main.c globals.c bconfig.c config.c daemon.c \ + backglue.c backover.c ctxcsn.c ldapsync.c frontend.c \ + slapadd.c slapcat.c slapcommon.c slapdn.c slapindex.c \ + slappasswd.c slaptest.c slapauth.c slapacl.c component.c \ +- aci.c alock.c txn.c slapschema.c \ ++ aci.c txn.c slapschema.c \ + $(@PLAT@_SRCS) + + OBJS = main.o globals.o bconfig.o config.o daemon.o \ +@@ -56,7 +56,7 @@ OBJS = main.o globals.o bconfig.o config.o daemon.o \ + backglue.o backover.o ctxcsn.o ldapsync.o frontend.o \ + slapadd.o slapcat.o slapcommon.o slapdn.o slapindex.o \ + slappasswd.o slaptest.o slapauth.o slapacl.o component.o \ +- aci.o alock.o txn.o slapschema.o \ ++ aci.o txn.o slapschema.o \ + $(@PLAT@_OBJS) + + LDAP_INCDIR= ../../include -I$(srcdir) -I$(srcdir)/slapi -I. +@@ -366,14 +366,8 @@ veryclean-local-srv: FORCE + fi; \ + done + +-install-dbc-maybe: install-dbc-@BUILD_BDB@ install-dbc-@BUILD_HDB@ +- +-install-dbc-yes: install-db-config +-install-dbc-mod: install-db-config +-install-dbc-no: +- + install-local-srv: install-slapd install-tools \ +- install-conf install-dbc-maybe install-schema install-tools ++ install-conf install-schema install-tools + + install-slapd: FORCE + -$(MKDIR) $(DESTDIR)$(libexecdir) +diff --git a/servers/slapd/alock.c b/servers/slapd/alock.c +deleted file mode 100644 +index 4e85fad..0000000 +--- a/servers/slapd/alock.c ++++ /dev/null +@@ -1,718 +0,0 @@ +-/* alock.c - access lock library */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2005-2020 The OpenLDAP Foundation. +- * Portions Copyright 2004-2005 Symas Corporation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +-/* ACKNOWLEDGEMENTS: +- * This work was initially developed by Emily Backes at Symas +- * Corporation for inclusion in OpenLDAP Software. +- */ +- +-#include "portable.h" +- +-#if SLAPD_BDB || SLAPD_HDB +- +-#include +-#include "alock.h" +-#include "lutil.h" +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#ifdef HAVE_SYS_FILE_H +-#include +-#endif +-#include +- +-#ifdef _WIN32 +-#include +-#include +-#include +-#endif +- +- +-static int +-alock_grab_lock ( int fd, int slot ) +-{ +- int res; +- +-#if defined( HAVE_LOCKF ) +- res = lseek (fd, (off_t) (ALOCK_SLOT_SIZE * slot), SEEK_SET); +- if (res == -1) return -1; +- res = lockf (fd, F_LOCK, (off_t) ALOCK_SLOT_SIZE); +-#elif defined( HAVE_FCNTL ) +- struct flock lock_info; +- (void) memset ((void *) &lock_info, 0, sizeof (struct flock)); +- +- lock_info.l_type = F_WRLCK; +- lock_info.l_whence = SEEK_SET; +- lock_info.l_start = (off_t) (ALOCK_SLOT_SIZE * slot); +- lock_info.l_len = (off_t) ALOCK_SLOT_SIZE; +- +- res = fcntl (fd, F_SETLKW, &lock_info); +-#elif defined( _WIN32 ) +- OVERLAPPED ov; +- HANDLE hh = _get_osfhandle ( fd ); +- ov.hEvent = 0; +- ov.Offset = ALOCK_SLOT_SIZE*slot; +- ov.OffsetHigh = 0; +- res = LockFileEx( hh, LOCKFILE_EXCLUSIVE_LOCK, 0, +- ALOCK_SLOT_SIZE, 0, &ov ) ? 0 : -1; +-#else +-# error alock needs lockf, fcntl, or LockFile[Ex] +-#endif +- if (res == -1) { +- assert (errno != EDEADLK); +- return -1; +- } +- return 0; +-} +- +-static int +-alock_release_lock ( int fd, int slot ) +-{ +- int res; +- +-#if defined( HAVE_LOCKF ) +- res = lseek (fd, (off_t) (ALOCK_SLOT_SIZE * slot), SEEK_SET); +- if (res == -1) return -1; +- res = lockf (fd, F_ULOCK, (off_t) ALOCK_SLOT_SIZE); +- if (res == -1) return -1; +-#elif defined ( HAVE_FCNTL ) +- struct flock lock_info; +- (void) memset ((void *) &lock_info, 0, sizeof (struct flock)); +- +- lock_info.l_type = F_UNLCK; +- lock_info.l_whence = SEEK_SET; +- lock_info.l_start = (off_t) (ALOCK_SLOT_SIZE * slot); +- lock_info.l_len = (off_t) ALOCK_SLOT_SIZE; +- +- res = fcntl (fd, F_SETLKW, &lock_info); +- if (res == -1) return -1; +-#elif defined( _WIN32 ) +- HANDLE hh = _get_osfhandle ( fd ); +- if ( !UnlockFile ( hh, ALOCK_SLOT_SIZE*slot, 0, +- ALOCK_SLOT_SIZE, 0 )) +- return -1; +-#else +-# error alock needs lockf, fcntl, or LockFile[Ex] +-#endif +- +- return 0; +-} +- +-static int +-alock_share_lock ( int fd, int slot ) +-{ +- int res; +- +-#if defined( HAVE_LOCKF ) +- res = 0; /* lockf has no shared locks */ +-#elif defined ( HAVE_FCNTL ) +- struct flock lock_info; +- (void) memset ((void *) &lock_info, 0, sizeof (struct flock)); +- +- /* The shared lock replaces the existing lock */ +- lock_info.l_type = F_RDLCK; +- lock_info.l_whence = SEEK_SET; +- lock_info.l_start = (off_t) (ALOCK_SLOT_SIZE * slot); +- lock_info.l_len = (off_t) ALOCK_SLOT_SIZE; +- +- res = fcntl (fd, F_SETLK, &lock_info); +- if (res == -1) return -1; +-#elif defined( _WIN32 ) +- OVERLAPPED ov; +- HANDLE hh = _get_osfhandle ( fd ); +- +- /* Windows locks are mandatory, not advisory. +- * We must downgrade the lock to allow future +- * callers to read the slot data. +- * +- * First acquire a shared lock. Unlock will +- * release the existing exclusive lock. +- */ +- ov.hEvent = 0; +- ov.Offset = ALOCK_SLOT_SIZE*slot; +- ov.OffsetHigh = 0; +- LockFileEx (hh, 0, 0, ALOCK_SLOT_SIZE, 0, &ov); +- UnlockFile (hh, ALOCK_SLOT_SIZE*slot, 0, ALOCK_SLOT_SIZE, 0); +-#else +-# error alock needs lockf, fcntl, or LockFile[Ex] +-#endif +- +- return 0; +-} +- +-static int +-alock_test_lock ( int fd, int slot ) +-{ +- int res; +- +-#if defined( HAVE_LOCKF ) +- res = lseek (fd, (off_t) (ALOCK_SLOT_SIZE * slot), SEEK_SET); +- if (res == -1) return -1; +- +- res = lockf (fd, F_TEST, (off_t) ALOCK_SLOT_SIZE); +- if (res == -1) { +- if (errno == EACCES || errno == EAGAIN) { +- return ALOCK_LOCKED; +- } else { +- return -1; +- } +- } +-#elif defined( HAVE_FCNTL ) +- struct flock lock_info; +- (void) memset ((void *) &lock_info, 0, sizeof (struct flock)); +- +- lock_info.l_type = F_WRLCK; +- lock_info.l_whence = SEEK_SET; +- lock_info.l_start = (off_t) (ALOCK_SLOT_SIZE * slot); +- lock_info.l_len = (off_t) ALOCK_SLOT_SIZE; +- +- res = fcntl (fd, F_GETLK, &lock_info); +- if (res == -1) return -1; +- +- if (lock_info.l_type != F_UNLCK) return ALOCK_LOCKED; +-#elif defined( _WIN32 ) +- OVERLAPPED ov; +- HANDLE hh = _get_osfhandle ( fd ); +- ov.hEvent = 0; +- ov.Offset = ALOCK_SLOT_SIZE*slot; +- ov.OffsetHigh = 0; +- if( !LockFileEx( hh, +- LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY, 0, +- ALOCK_SLOT_SIZE, 0, &ov )) { +- int err = GetLastError(); +- if ( err == ERROR_LOCK_VIOLATION ) +- return ALOCK_LOCKED; +- else +- return -1; +- } +-#else +-# error alock needs lockf, fcntl, or LockFile +-#endif +- +- return 0; +-} +- +-/* Read a 64bit LE value */ +-static unsigned long int +-alock_read_iattr ( unsigned char * bufptr ) +-{ +- unsigned long int val = 0; +- int count; +- +- assert (bufptr != NULL); +- +- bufptr += sizeof (unsigned long int); +- for (count=0; count <= (int) sizeof (unsigned long int); ++count) { +- val <<= 8; +- val += (unsigned long int) *bufptr--; +- } +- +- return val; +-} +- +-/* Write a 64bit LE value */ +-static void +-alock_write_iattr ( unsigned char * bufptr, +- unsigned long int val ) +-{ +- int count; +- +- assert (bufptr != NULL); +- +- for (count=0; count < 8; ++count) { +- *bufptr++ = (unsigned char) (val & 0xff); +- val >>= 8; +- } +-} +- +-static int +-alock_read_slot ( alock_info_t * info, +- alock_slot_t * slot_data ) +-{ +- unsigned char slotbuf [ALOCK_SLOT_SIZE]; +- int res, size, size_total, err; +- +- assert (info != NULL); +- assert (slot_data != NULL); +- assert (info->al_slot > 0); +- +- res = lseek (info->al_fd, +- (off_t) (ALOCK_SLOT_SIZE * info->al_slot), +- SEEK_SET); +- if (res == -1) return -1; +- +- size_total = 0; +- while (size_total < ALOCK_SLOT_SIZE) { +- size = read (info->al_fd, +- slotbuf + size_total, +- ALOCK_SLOT_SIZE - size_total); +- if (size == 0) return -1; +- if (size < 0) { +- err = errno; +- if (err != EINTR && err != EAGAIN) return -1; +- } else { +- size_total += size; +- } +- } +- +- if (alock_read_iattr (slotbuf) != ALOCK_MAGIC) { +- return -1; +- } +- slot_data->al_lock = alock_read_iattr (slotbuf+8); +- slot_data->al_stamp = alock_read_iattr (slotbuf+16); +- slot_data->al_pid = alock_read_iattr (slotbuf+24); +- +- if (slot_data->al_appname) ber_memfree (slot_data->al_appname); +- slot_data->al_appname = ber_memcalloc (1, ALOCK_MAX_APPNAME); +- if (slot_data->al_appname == NULL) { +- return -1; +- } +- strncpy (slot_data->al_appname, (char *)slotbuf+32, ALOCK_MAX_APPNAME-1); +- (slot_data->al_appname) [ALOCK_MAX_APPNAME-1] = '\0'; +- +- return 0; +-} +- +-static int +-alock_write_slot ( alock_info_t * info, +- alock_slot_t * slot_data ) +-{ +- unsigned char slotbuf [ALOCK_SLOT_SIZE]; +- int res, size, size_total, err; +- +- assert (info != NULL); +- assert (slot_data != NULL); +- assert (info->al_slot > 0); +- +- (void) memset ((void *) slotbuf, 0, ALOCK_SLOT_SIZE); +- +- alock_write_iattr (slotbuf, ALOCK_MAGIC); +- assert (alock_read_iattr (slotbuf) == ALOCK_MAGIC); +- alock_write_iattr (slotbuf+8, slot_data->al_lock); +- alock_write_iattr (slotbuf+16, slot_data->al_stamp); +- alock_write_iattr (slotbuf+24, slot_data->al_pid); +- +- if (slot_data->al_appname) +- strncpy ((char *)slotbuf+32, slot_data->al_appname, ALOCK_MAX_APPNAME-1); +- slotbuf[ALOCK_SLOT_SIZE-1] = '\0'; +- +- res = lseek (info->al_fd, +- (off_t) (ALOCK_SLOT_SIZE * info->al_slot), +- SEEK_SET); +- if (res == -1) return -1; +- +- size_total = 0; +- while (size_total < ALOCK_SLOT_SIZE) { +- size = write (info->al_fd, +- slotbuf + size_total, +- ALOCK_SLOT_SIZE - size_total); +- if (size == 0) return -1; +- if (size < 0) { +- err = errno; +- if (err != EINTR && err != EAGAIN) return -1; +- } else { +- size_total += size; +- } +- } +- +- return 0; +-} +- +-static int +-alock_query_slot ( alock_info_t * info ) +-{ +- int res, nosave; +- alock_slot_t slot_data; +- +- assert (info != NULL); +- assert (info->al_slot > 0); +- +- (void) memset ((void *) &slot_data, 0, sizeof (alock_slot_t)); +- alock_read_slot (info, &slot_data); +- +- if (slot_data.al_appname != NULL) ber_memfree (slot_data.al_appname); +- slot_data.al_appname = NULL; +- +- nosave = slot_data.al_lock & ALOCK_NOSAVE; +- +- if ((slot_data.al_lock & ALOCK_SMASK) == ALOCK_UNLOCKED) +- return slot_data.al_lock; +- +- res = alock_test_lock (info->al_fd, info->al_slot); +- if (res < 0) return -1; +- if (res > 0) { +- if ((slot_data.al_lock & ALOCK_SMASK) == ALOCK_UNIQUE) { +- return slot_data.al_lock; +- } else { +- return ALOCK_LOCKED | nosave; +- } +- } +- +- return ALOCK_DIRTY | nosave; +-} +- +-int +-alock_open ( alock_info_t * info, +- const char * appname, +- const char * envdir, +- int locktype ) +-{ +- struct stat statbuf; +- alock_info_t scan_info; +- alock_slot_t slot_data; +- char * filename; +- int res, max_slot; +- int dirty_count, live_count, nosave; +- char *ptr; +- +- assert (info != NULL); +- assert (appname != NULL); +- assert (envdir != NULL); +- assert ((locktype & ALOCK_SMASK) >= 1 && (locktype & ALOCK_SMASK) <= 2); +- +- slot_data.al_lock = locktype; +- slot_data.al_stamp = time(NULL); +- slot_data.al_pid = getpid(); +- slot_data.al_appname = ber_memcalloc (1, ALOCK_MAX_APPNAME); +- if (slot_data.al_appname == NULL) { +- return ALOCK_UNSTABLE; +- } +- strncpy (slot_data.al_appname, appname, ALOCK_MAX_APPNAME-1); +- slot_data.al_appname [ALOCK_MAX_APPNAME-1] = '\0'; +- +- filename = ber_memcalloc (1, strlen (envdir) + strlen ("/alock") + 1); +- if (filename == NULL ) { +- ber_memfree (slot_data.al_appname); +- return ALOCK_UNSTABLE; +- } +- ptr = lutil_strcopy(filename, envdir); +- lutil_strcopy(ptr, "/alock"); +-#ifdef _WIN32 +- { HANDLE handle = CreateFile (filename, GENERIC_READ|GENERIC_WRITE, +- FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, +- FILE_ATTRIBUTE_NORMAL, NULL); +- info->al_fd = _open_osfhandle (handle, 0); +- } +-#else +- info->al_fd = open (filename, O_CREAT|O_RDWR, 0666); +-#endif +- ber_memfree (filename); +- if (info->al_fd < 0) { +- ber_memfree (slot_data.al_appname); +- return ALOCK_UNSTABLE; +- } +- info->al_slot = 0; +- +- res = alock_grab_lock (info->al_fd, 0); +- if (res == -1) { +- close (info->al_fd); +- ber_memfree (slot_data.al_appname); +- return ALOCK_UNSTABLE; +- } +- +- res = fstat (info->al_fd, &statbuf); +- if (res == -1) { +- close (info->al_fd); +- ber_memfree (slot_data.al_appname); +- return ALOCK_UNSTABLE; +- } +- +- max_slot = (statbuf.st_size + ALOCK_SLOT_SIZE - 1) / ALOCK_SLOT_SIZE; +- dirty_count = 0; +- live_count = 0; +- nosave = 0; +- scan_info.al_fd = info->al_fd; +- for (scan_info.al_slot = 1; +- scan_info.al_slot < max_slot; +- ++ scan_info.al_slot) { +- if (scan_info.al_slot != info->al_slot) { +- res = alock_query_slot (&scan_info); +- +- if (res & ALOCK_NOSAVE) { +- nosave = ALOCK_NOSAVE; +- res ^= ALOCK_NOSAVE; +- } +- if (res == ALOCK_UNLOCKED +- && info->al_slot == 0) { +- info->al_slot = scan_info.al_slot; +- +- } else if (res == ALOCK_LOCKED) { +- ++live_count; +- +- } else if (res == ALOCK_UNIQUE +- && (( locktype & ALOCK_SMASK ) == ALOCK_UNIQUE +- || nosave )) { +- close (info->al_fd); +- ber_memfree (slot_data.al_appname); +- return ALOCK_BUSY; +- +- } else if (res == ALOCK_DIRTY) { +- ++dirty_count; +- +- } else if (res == -1) { +- close (info->al_fd); +- ber_memfree (slot_data.al_appname); +- return ALOCK_UNSTABLE; +- +- } +- } +- } +- +- if (dirty_count && live_count) { +- close (info->al_fd); +- ber_memfree (slot_data.al_appname); +- return ALOCK_UNSTABLE; +- } +- +- if (info->al_slot == 0) info->al_slot = max_slot + 1; +- res = alock_grab_lock (info->al_fd, +- info->al_slot); +- if (res == -1) { +- close (info->al_fd); +- ber_memfree (slot_data.al_appname); +- return ALOCK_UNSTABLE; +- } +- res = alock_write_slot (info, &slot_data); +- ber_memfree (slot_data.al_appname); +- if (res == -1) { +- close (info->al_fd); +- return ALOCK_UNSTABLE; +- } +- alock_share_lock (info->al_fd, info->al_slot); +- +- res = alock_release_lock (info->al_fd, 0); +- if (res == -1) { +- close (info->al_fd); +- return ALOCK_UNSTABLE; +- } +- +- if (dirty_count) return ALOCK_RECOVER | nosave; +- return ALOCK_CLEAN | nosave; +-} +- +-int +-alock_scan ( alock_info_t * info ) +-{ +- struct stat statbuf; +- alock_info_t scan_info; +- int res, max_slot; +- int dirty_count, live_count, nosave; +- +- assert (info != NULL); +- +- scan_info.al_fd = info->al_fd; +- +- res = alock_grab_lock (info->al_fd, 0); +- if (res == -1) { +- close (info->al_fd); +- return ALOCK_UNSTABLE; +- } +- +- res = fstat (info->al_fd, &statbuf); +- if (res == -1) { +- close (info->al_fd); +- return ALOCK_UNSTABLE; +- } +- +- max_slot = (statbuf.st_size + ALOCK_SLOT_SIZE - 1) / ALOCK_SLOT_SIZE; +- dirty_count = 0; +- live_count = 0; +- nosave = 0; +- for (scan_info.al_slot = 1; +- scan_info.al_slot < max_slot; +- ++ scan_info.al_slot) { +- if (scan_info.al_slot != info->al_slot) { +- res = alock_query_slot (&scan_info); +- +- if (res & ALOCK_NOSAVE) { +- nosave = ALOCK_NOSAVE; +- res ^= ALOCK_NOSAVE; +- } +- +- if (res == ALOCK_LOCKED) { +- ++live_count; +- +- } else if (res == ALOCK_DIRTY) { +- ++dirty_count; +- +- } else if (res == -1) { +- close (info->al_fd); +- return ALOCK_UNSTABLE; +- +- } +- } +- } +- +- res = alock_release_lock (info->al_fd, 0); +- if (res == -1) { +- close (info->al_fd); +- return ALOCK_UNSTABLE; +- } +- +- if (dirty_count) { +- if (live_count) { +- close (info->al_fd); +- return ALOCK_UNSTABLE; +- } else { +- return ALOCK_RECOVER | nosave; +- } +- } +- +- return ALOCK_CLEAN | nosave; +-} +- +-int +-alock_close ( alock_info_t * info, int nosave ) +-{ +- alock_slot_t slot_data; +- int res; +- +- if ( !info->al_slot ) +- return ALOCK_CLEAN; +- +- (void) memset ((void *) &slot_data, 0, sizeof(alock_slot_t)); +- +- res = alock_grab_lock (info->al_fd, 0); +- if (res == -1) { +-fail: +- /* Windows doesn't clean up locks immediately when a process exits. +- * Make sure we release our locks, to prevent stale locks from +- * hanging around. +- */ +- alock_release_lock (info->al_fd, 0); +- close (info->al_fd); +- return ALOCK_UNSTABLE; +- } +- +- /* mark our slot as clean */ +- res = alock_read_slot (info, &slot_data); +- if (res == -1) { +- if (slot_data.al_appname != NULL) +- ber_memfree (slot_data.al_appname); +- goto fail; +- } +- slot_data.al_lock = ALOCK_UNLOCKED; +- if ( nosave ) +- slot_data.al_lock |= ALOCK_NOSAVE; +- /* since we have slot 0 locked, we don't need our slot lock */ +- res = alock_release_lock (info->al_fd, info->al_slot); +- if (res == -1) { +- goto fail; +- } +- res = alock_write_slot (info, &slot_data); +- if (res == -1) { +- if (slot_data.al_appname != NULL) +- ber_memfree (slot_data.al_appname); +- goto fail; +- } +- if (slot_data.al_appname != NULL) { +- ber_memfree (slot_data.al_appname); +- slot_data.al_appname = NULL; +- } +- +- res = alock_release_lock (info->al_fd, 0); +- if (res == -1) { +- close (info->al_fd); +- return ALOCK_UNSTABLE; +- } +- +- res = close (info->al_fd); +- if (res == -1) return ALOCK_UNSTABLE; +- +- return ALOCK_CLEAN; +-} +- +-int +-alock_recover ( alock_info_t * info ) +-{ +- struct stat statbuf; +- alock_slot_t slot_data; +- alock_info_t scan_info; +- int res, max_slot; +- +- assert (info != NULL); +- +- scan_info.al_fd = info->al_fd; +- +- (void) memset ((void *) &slot_data, 0, sizeof(alock_slot_t)); +- +- res = alock_grab_lock (info->al_fd, 0); +- if (res == -1) { +- goto fail; +- } +- +- res = fstat (info->al_fd, &statbuf); +- if (res == -1) { +- goto fail; +- } +- +- max_slot = (statbuf.st_size + ALOCK_SLOT_SIZE - 1) / ALOCK_SLOT_SIZE; +- for (scan_info.al_slot = 1; +- scan_info.al_slot < max_slot; +- ++ scan_info.al_slot) { +- if (scan_info.al_slot != info->al_slot) { +- res = alock_query_slot (&scan_info) & ~ALOCK_NOSAVE; +- +- if (res == ALOCK_LOCKED +- || res == ALOCK_UNIQUE) { +- /* recovery attempt on an active db? */ +- goto fail; +- +- } else if (res == ALOCK_DIRTY) { +- /* mark it clean */ +- res = alock_read_slot (&scan_info, &slot_data); +- if (res == -1) { +- goto fail; +- } +- slot_data.al_lock = ALOCK_UNLOCKED; +- res = alock_write_slot (&scan_info, &slot_data); +- if (res == -1) { +- if (slot_data.al_appname != NULL) +- ber_memfree (slot_data.al_appname); +- goto fail; +- } +- if (slot_data.al_appname != NULL) { +- ber_memfree (slot_data.al_appname); +- slot_data.al_appname = NULL; +- } +- +- } else if (res == -1) { +- goto fail; +- +- } +- } +- } +- +- res = alock_release_lock (info->al_fd, 0); +- if (res == -1) { +- close (info->al_fd); +- return ALOCK_UNSTABLE; +- } +- +- return ALOCK_CLEAN; +- +-fail: +- alock_release_lock (info->al_fd, 0); +- close (info->al_fd); +- return ALOCK_UNSTABLE; +-} +- +-#endif /* SLAPD_BDB || SLAPD_HDB */ +diff --git a/servers/slapd/alock.h b/servers/slapd/alock.h +deleted file mode 100644 +index 56f03d8..0000000 +--- a/servers/slapd/alock.h ++++ /dev/null +@@ -1,74 +0,0 @@ +-/* alock.h - access lock header */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2005-2020 The OpenLDAP Foundation. +- * Portions Copyright 2004-2005 Symas Corporation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +-/* ACKNOWLEDGEMENTS: +- * This work was initially developed by Emily Backes at Symas +- * Corporation for inclusion in OpenLDAP Software. +- */ +- +-#ifndef _ALOCK_H_ +-#define _ALOCK_H_ +- +-#include "portable.h" +-#include +-#include +- +-/* environment states (all the slots together) */ +-#define ALOCK_CLEAN (0) +-#define ALOCK_RECOVER (1) +-#define ALOCK_BUSY (2) +-#define ALOCK_UNSTABLE (3) +- +-/* lock user types and states */ +-#define ALOCK_UNLOCKED (0) +-#define ALOCK_LOCKED (1) +-#define ALOCK_UNIQUE (2) +-#define ALOCK_DIRTY (3) +- +-#define ALOCK_SMASK 3 +- +-/* lock/state where recovery is not available */ +-#define ALOCK_NOSAVE 4 +- +-/* constants */ +-#define ALOCK_SLOT_SIZE (1024) +-#define ALOCK_SLOT_IATTRS (4) +-#define ALOCK_MAX_APPNAME (ALOCK_SLOT_SIZE - 8 * ALOCK_SLOT_IATTRS) +-#define ALOCK_MAGIC (0x12345678) +- +-LDAP_BEGIN_DECL +- +-typedef struct alock_info { +- int al_fd; +- int al_slot; +-} alock_info_t; +- +-typedef struct alock_slot { +- unsigned int al_lock; +- time_t al_stamp; +- pid_t al_pid; +- char * al_appname; +-} alock_slot_t; +- +-LDAP_SLAPD_F (int) alock_open LDAP_P(( alock_info_t * info, const char * appname, +- const char * envdir, int locktype )); +-LDAP_SLAPD_F (int) alock_scan LDAP_P(( alock_info_t * info )); +-LDAP_SLAPD_F (int) alock_close LDAP_P(( alock_info_t * info, int nosave )); +-LDAP_SLAPD_F (int) alock_recover LDAP_P(( alock_info_t * info )); +- +-LDAP_END_DECL +- +-#endif +diff --git a/servers/slapd/back-bdb/Makefile.in b/servers/slapd/back-bdb/Makefile.in +deleted file mode 100644 +index 8529202..0000000 +--- a/servers/slapd/back-bdb/Makefile.in ++++ /dev/null +@@ -1,53 +0,0 @@ +-# Makefile.in for back-bdb +-# $OpenLDAP$ +-## This work is part of OpenLDAP Software . +-## +-## Copyright 1998-2020 The OpenLDAP Foundation. +-## All rights reserved. +-## +-## Redistribution and use in source and binary forms, with or without +-## modification, are permitted only as authorized by the OpenLDAP +-## Public License. +-## +-## A copy of this license is available in the file LICENSE in the +-## top-level directory of the distribution or, alternatively, at +-## . +- +-SRCS = init.c tools.c config.c \ +- add.c bind.c compare.c delete.c modify.c modrdn.c search.c \ +- extended.c referral.c operational.c \ +- attr.c index.c key.c dbcache.c filterindex.c \ +- dn2entry.c dn2id.c error.c id2entry.c idl.c \ +- nextid.c cache.c trans.c monitor.c +- +-OBJS = init.lo tools.lo config.lo \ +- add.lo bind.lo compare.lo delete.lo modify.lo modrdn.lo search.lo \ +- extended.lo referral.lo operational.lo \ +- attr.lo index.lo key.lo dbcache.lo filterindex.lo \ +- dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo \ +- nextid.lo cache.lo trans.lo monitor.lo +- +-LDAP_INCDIR= ../../../include +-LDAP_LIBDIR= ../../../libraries +- +-BUILD_OPT = "--enable-bdb" +-BUILD_MOD = @BUILD_BDB@ +- +-mod_DEFS = -DSLAPD_IMPORT +-MOD_DEFS = $(@BUILD_BDB@_DEFS) +-MOD_LIBS = $(BDB_LIBS) +- +-shared_LDAP_LIBS = $(LDAP_LIBLDAP_R_LA) $(LDAP_LIBLBER_LA) +-NT_LINK_LIBS = -L.. -lslapd $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS) +-UNIX_LINK_LIBS = $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS) +- +-LIBBASE = back_bdb +- +-XINCPATH = -I.. -I$(srcdir)/.. +-XDEFS = $(MODULES_CPPFLAGS) +- +-all-local-lib: ../.backend +- +-../.backend: lib$(LIBBASE).a +- @touch $@ +- +diff --git a/servers/slapd/back-bdb/add.c b/servers/slapd/back-bdb/add.c +deleted file mode 100644 +index d842b55..0000000 +--- a/servers/slapd/back-bdb/add.c ++++ /dev/null +@@ -1,547 +0,0 @@ +-/* add.c - ldap BerkeleyDB back-end add routine */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +-#include +- +-#include "back-bdb.h" +- +-int +-bdb_add(Operation *op, SlapReply *rs ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- struct berval pdn; +- Entry *p = NULL, *oe = op->ora_e; +- EntryInfo *ei; +- char textbuf[SLAP_TEXT_BUFLEN]; +- size_t textlen = sizeof textbuf; +- AttributeDescription *children = slap_schema.si_ad_children; +- AttributeDescription *entry = slap_schema.si_ad_entry; +- DB_TXN *ltid = NULL, *lt2; +- ID eid = NOID; +- struct bdb_op_info opinfo = {{{ 0 }}}; +- int subentry; +- DB_LOCK lock; +- +- int num_retries = 0; +- int success; +- +- LDAPControl **postread_ctrl = NULL; +- LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS]; +- int num_ctrls = 0; +- +-#ifdef LDAP_X_TXN +- int settle = 0; +-#endif +- +- Debug(LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(bdb_add) ": %s\n", +- op->ora_e->e_name.bv_val, 0, 0); +- +-#ifdef LDAP_X_TXN +- if( op->o_txnSpec ) { +- /* acquire connection lock */ +- ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); +- if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) { +- rs->sr_text = "invalid transaction identifier"; +- rs->sr_err = LDAP_X_TXN_ID_INVALID; +- goto txnReturn; +- } else if( op->o_conn->c_txn == CONN_TXN_SETTLE ) { +- settle=1; +- goto txnReturn; +- } +- +- if( op->o_conn->c_txn_backend == NULL ) { +- op->o_conn->c_txn_backend = op->o_bd; +- +- } else if( op->o_conn->c_txn_backend != op->o_bd ) { +- rs->sr_text = "transaction cannot span multiple database contexts"; +- rs->sr_err = LDAP_AFFECTS_MULTIPLE_DSAS; +- goto txnReturn; +- } +- +- /* insert operation into transaction */ +- +- rs->sr_text = "transaction specified"; +- rs->sr_err = LDAP_X_TXN_SPECIFY_OKAY; +- +-txnReturn: +- /* release connection lock */ +- ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); +- +- if( !settle ) { +- send_ldap_result( op, rs ); +- return rs->sr_err; +- } +- } +-#endif +- +- ctrls[num_ctrls] = 0; +- +- /* check entry's schema */ +- rs->sr_err = entry_schema_check( op, op->ora_e, NULL, +- get_relax(op), 1, NULL, &rs->sr_text, textbuf, textlen ); +- if ( rs->sr_err != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_add) ": entry failed schema check: " +- "%s (%d)\n", rs->sr_text, rs->sr_err, 0 ); +- goto return_results; +- } +- +- /* add opattrs to shadow as well, only missing attrs will actually +- * be added; helps compatibility with older OL versions */ +- rs->sr_err = slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 ); +- if ( rs->sr_err != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_add) ": entry failed op attrs add: " +- "%s (%d)\n", rs->sr_text, rs->sr_err, 0 ); +- goto return_results; +- } +- +- if ( get_assert( op ) && +- ( test_filter( op, op->ora_e, get_assertion( op )) != LDAP_COMPARE_TRUE )) +- { +- rs->sr_err = LDAP_ASSERTION_FAILED; +- goto return_results; +- } +- +- subentry = is_entry_subentry( op->ora_e ); +- +- if( 0 ) { +-retry: /* transaction retry */ +- if( p ) { +- /* free parent and reader lock */ +- if ( p != (Entry *)&slap_entry_root ) { +- bdb_unlocked_cache_return_entry_r( bdb, p ); +- } +- p = NULL; +- } +- rs->sr_err = TXN_ABORT( ltid ); +- ltid = NULL; +- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); +- opinfo.boi_oe.oe_key = NULL; +- op->o_do_not_cache = opinfo.boi_acl_cache; +- if( rs->sr_err != 0 ) { +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- if ( op->o_abandon ) { +- rs->sr_err = SLAPD_ABANDON; +- goto return_results; +- } +- bdb_trans_backoff( ++num_retries ); +- } +- +- /* begin transaction */ +- rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, <id, +- bdb->bi_db_opflags ); +- rs->sr_text = NULL; +- if( rs->sr_err != 0 ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_add) ": txn_begin failed: %s (%d)\n", +- db_strerror(rs->sr_err), rs->sr_err, 0 ); +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": txn1 id: %x\n", +- ltid->id(ltid), 0, 0 ); +- +- opinfo.boi_oe.oe_key = bdb; +- opinfo.boi_txn = ltid; +- opinfo.boi_err = 0; +- opinfo.boi_acl_cache = op->o_do_not_cache; +- LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.boi_oe, oe_next ); +- +- /* +- * Get the parent dn and see if the corresponding entry exists. +- */ +- if ( be_issuffix( op->o_bd, &op->ora_e->e_nname ) ) { +- pdn = slap_empty_bv; +- } else { +- dnParent( &op->ora_e->e_nname, &pdn ); +- } +- +- /* get entry or parent */ +- rs->sr_err = bdb_dn2entry( op, ltid, &op->ora_e->e_nname, &ei, +- 1, &lock ); +- switch( rs->sr_err ) { +- case 0: +- rs->sr_err = LDAP_ALREADY_EXISTS; +- goto return_results; +- case DB_NOTFOUND: +- break; +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- case LDAP_BUSY: +- rs->sr_text = "ldap server busy"; +- goto return_results; +- default: +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- +- p = ei->bei_e; +- if ( !p ) +- p = (Entry *)&slap_entry_root; +- +- if ( !bvmatch( &pdn, &p->e_nname ) ) { +- rs->sr_matched = ber_strdup_x( p->e_name.bv_val, +- op->o_tmpmemctx ); +- rs->sr_ref = is_entry_referral( p ) +- ? get_entry_referrals( op, p ) +- : NULL; +- if ( p != (Entry *)&slap_entry_root ) +- bdb_unlocked_cache_return_entry_r( bdb, p ); +- p = NULL; +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_add) ": parent " +- "does not exist\n", 0, 0, 0 ); +- +- rs->sr_err = LDAP_REFERRAL; +- rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; +- goto return_results; +- } +- +- rs->sr_err = access_allowed( op, p, +- children, NULL, ACL_WADD, NULL ); +- +- if ( ! rs->sr_err ) { +- switch( opinfo.boi_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- +- if ( p != (Entry *)&slap_entry_root ) +- bdb_unlocked_cache_return_entry_r( bdb, p ); +- p = NULL; +- +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_add) ": no write access to parent\n", +- 0, 0, 0 ); +- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; +- rs->sr_text = "no write access to parent"; +- goto return_results;; +- } +- +- if ( p != (Entry *)&slap_entry_root ) { +- if ( is_entry_subentry( p ) ) { +- bdb_unlocked_cache_return_entry_r( bdb, p ); +- p = NULL; +- /* parent is a subentry, don't allow add */ +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_add) ": parent is subentry\n", +- 0, 0, 0 ); +- rs->sr_err = LDAP_OBJECT_CLASS_VIOLATION; +- rs->sr_text = "parent is a subentry"; +- goto return_results;; +- } +- +- if ( is_entry_alias( p ) ) { +- bdb_unlocked_cache_return_entry_r( bdb, p ); +- p = NULL; +- /* parent is an alias, don't allow add */ +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_add) ": parent is alias\n", +- 0, 0, 0 ); +- rs->sr_err = LDAP_ALIAS_PROBLEM; +- rs->sr_text = "parent is an alias"; +- goto return_results;; +- } +- +- if ( is_entry_referral( p ) ) { +- /* parent is a referral, don't allow add */ +- rs->sr_matched = ber_strdup_x( p->e_name.bv_val, +- op->o_tmpmemctx ); +- rs->sr_ref = get_entry_referrals( op, p ); +- bdb_unlocked_cache_return_entry_r( bdb, p ); +- p = NULL; +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_add) ": parent is referral\n", +- 0, 0, 0 ); +- +- rs->sr_err = LDAP_REFERRAL; +- rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; +- goto return_results; +- } +- +- } +- +- if ( subentry ) { +- /* FIXME: */ +- /* parent must be an administrative point of the required kind */ +- } +- +- /* free parent and reader lock */ +- if ( p != (Entry *)&slap_entry_root ) { +- if ( p->e_nname.bv_len ) { +- struct berval ppdn; +- +- /* ITS#5326: use parent's DN if differs from provided one */ +- dnParent( &op->ora_e->e_name, &ppdn ); +- if ( !dn_match( &p->e_name, &ppdn ) ) { +- struct berval rdn; +- struct berval newdn; +- +- dnRdn( &op->ora_e->e_name, &rdn ); +- +- build_new_dn( &newdn, &p->e_name, &rdn, NULL ); +- if ( op->ora_e->e_name.bv_val != op->o_req_dn.bv_val ) +- ber_memfree( op->ora_e->e_name.bv_val ); +- op->ora_e->e_name = newdn; +- +- /* FIXME: should check whether +- * dnNormalize(newdn) == e->e_nname ... */ +- } +- } +- +- bdb_unlocked_cache_return_entry_r( bdb, p ); +- } +- p = NULL; +- +- rs->sr_err = access_allowed( op, op->ora_e, +- entry, NULL, ACL_WADD, NULL ); +- +- if ( ! rs->sr_err ) { +- switch( opinfo.boi_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_add) ": no write access to entry\n", +- 0, 0, 0 ); +- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; +- rs->sr_text = "no write access to entry"; +- goto return_results;; +- } +- +- /* +- * Check ACL for attribute write access +- */ +- if (!acl_check_modlist(op, oe, op->ora_modlist)) { +- switch( opinfo.boi_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_add) ": no write access to attribute\n", +- 0, 0, 0 ); +- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; +- rs->sr_text = "no write access to attribute"; +- goto return_results;; +- } +- +- if ( eid == NOID ) { +- rs->sr_err = bdb_next_id( op->o_bd, &eid ); +- if( rs->sr_err != 0 ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_add) ": next_id failed (%d)\n", +- rs->sr_err, 0, 0 ); +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- op->ora_e->e_id = eid; +- } +- +- /* nested transaction */ +- rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, <2, +- bdb->bi_db_opflags ); +- rs->sr_text = NULL; +- if( rs->sr_err != 0 ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_add) ": txn_begin(2) failed: " +- "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 ); +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": txn2 id: %x\n", +- lt2->id(lt2), 0, 0 ); +- +- /* dn2id index */ +- rs->sr_err = bdb_dn2id_add( op, lt2, ei, op->ora_e ); +- if ( rs->sr_err != 0 ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_add) ": dn2id_add failed: %s (%d)\n", +- db_strerror(rs->sr_err), rs->sr_err, 0 ); +- +- switch( rs->sr_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- case DB_KEYEXIST: +- rs->sr_err = LDAP_ALREADY_EXISTS; +- break; +- default: +- rs->sr_err = LDAP_OTHER; +- } +- goto return_results; +- } +- +- /* attribute indexes */ +- rs->sr_err = bdb_index_entry_add( op, lt2, op->ora_e ); +- if ( rs->sr_err != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_add) ": index_entry_add failed\n", +- 0, 0, 0 ); +- switch( rs->sr_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- default: +- rs->sr_err = LDAP_OTHER; +- } +- rs->sr_text = "index generation failed"; +- goto return_results; +- } +- +- /* id2entry index */ +- rs->sr_err = bdb_id2entry_add( op->o_bd, lt2, op->ora_e ); +- if ( rs->sr_err != 0 ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_add) ": id2entry_add failed\n", +- 0, 0, 0 ); +- switch( rs->sr_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- default: +- rs->sr_err = LDAP_OTHER; +- } +- rs->sr_text = "entry store failed"; +- goto return_results; +- } +- +- if ( TXN_COMMIT( lt2, 0 ) != 0 ) { +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "txn_commit(2) failed"; +- goto return_results; +- } +- +- /* post-read */ +- if( op->o_postread ) { +- if( postread_ctrl == NULL ) { +- postread_ctrl = &ctrls[num_ctrls++]; +- ctrls[num_ctrls] = NULL; +- } +- if ( slap_read_controls( op, rs, op->ora_e, +- &slap_post_read_bv, postread_ctrl ) ) +- { +- Debug( LDAP_DEBUG_TRACE, +- "<=- " LDAP_XSTRING(bdb_add) ": post-read " +- "failed!\n", 0, 0, 0 ); +- if ( op->o_postread & SLAP_CONTROL_CRITICAL ) { +- /* FIXME: is it correct to abort +- * operation if control fails? */ +- goto return_results; +- } +- } +- } +- +- if ( op->o_noop ) { +- if (( rs->sr_err=TXN_ABORT( ltid )) != 0 ) { +- rs->sr_text = "txn_abort (no-op) failed"; +- } else { +- rs->sr_err = LDAP_X_NO_OPERATION; +- ltid = NULL; +- goto return_results; +- } +- +- } else { +- struct berval nrdn; +- +- /* pick the RDN if not suffix; otherwise pick the entire DN */ +- if (pdn.bv_len) { +- nrdn.bv_val = op->ora_e->e_nname.bv_val; +- nrdn.bv_len = pdn.bv_val - op->ora_e->e_nname.bv_val - 1; +- } else { +- nrdn = op->ora_e->e_nname; +- } +- +- bdb_cache_add( bdb, ei, op->ora_e, &nrdn, ltid, &lock ); +- +- if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) { +- rs->sr_text = "txn_commit failed"; +- } else { +- rs->sr_err = LDAP_SUCCESS; +- } +- } +- +- ltid = NULL; +- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); +- opinfo.boi_oe.oe_key = NULL; +- +- if ( rs->sr_err != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_add) ": %s : %s (%d)\n", +- rs->sr_text, db_strerror(rs->sr_err), rs->sr_err ); +- rs->sr_err = LDAP_OTHER; +- goto return_results; +- } +- +- Debug(LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_add) ": added%s id=%08lx dn=\"%s\"\n", +- op->o_noop ? " (no-op)" : "", +- op->ora_e->e_id, op->ora_e->e_dn ); +- +- rs->sr_text = NULL; +- if( num_ctrls ) rs->sr_ctrls = ctrls; +- +-return_results: +- success = rs->sr_err; +- send_ldap_result( op, rs ); +- +- if( ltid != NULL ) { +- TXN_ABORT( ltid ); +- } +- if ( opinfo.boi_oe.oe_key ) { +- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); +- } +- +- if( success == LDAP_SUCCESS ) { +- /* We own the entry now, and it can be purged at will +- * Check to make sure it's the same entry we entered with. +- * Possibly a callback may have mucked with it, although +- * in general callbacks should treat the entry as read-only. +- */ +- bdb_cache_deref( oe->e_private ); +- if ( op->ora_e == oe ) +- op->ora_e = NULL; +- +- if ( bdb->bi_txn_cp_kbyte ) { +- TXN_CHECKPOINT( bdb->bi_dbenv, +- bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 ); +- } +- } +- +- slap_graduate_commit_csn( op ); +- +- if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) { +- slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx ); +- slap_sl_free( *postread_ctrl, op->o_tmpmemctx ); +- } +- return rs->sr_err; +-} +diff --git a/servers/slapd/back-bdb/attr.c b/servers/slapd/back-bdb/attr.c +deleted file mode 100644 +index 5d9990d..0000000 +--- a/servers/slapd/back-bdb/attr.c ++++ /dev/null +@@ -1,441 +0,0 @@ +-/* attr.c - backend routines for dealing with attributes */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +- +-#include +-#include +- +-#include "slap.h" +-#include "back-bdb.h" +-#include "config.h" +-#include "lutil.h" +- +-/* Find the ad, return -1 if not found, +- * set point for insertion if ins is non-NULL +- */ +-int +-bdb_attr_slot( struct bdb_info *bdb, AttributeDescription *ad, int *ins ) +-{ +- unsigned base = 0, cursor = 0; +- unsigned n = bdb->bi_nattrs; +- int val = 0; +- +- while ( 0 < n ) { +- unsigned pivot = n >> 1; +- cursor = base + pivot; +- +- val = SLAP_PTRCMP( ad, bdb->bi_attrs[cursor]->ai_desc ); +- if ( val < 0 ) { +- n = pivot; +- } else if ( val > 0 ) { +- base = cursor + 1; +- n -= pivot + 1; +- } else { +- return cursor; +- } +- } +- if ( ins ) { +- if ( val > 0 ) +- ++cursor; +- *ins = cursor; +- } +- return -1; +-} +- +-static int +-ainfo_insert( struct bdb_info *bdb, AttrInfo *a ) +-{ +- int x; +- int i = bdb_attr_slot( bdb, a->ai_desc, &x ); +- +- /* Is it a dup? */ +- if ( i >= 0 ) +- return -1; +- +- bdb->bi_attrs = ch_realloc( bdb->bi_attrs, ( bdb->bi_nattrs+1 ) * +- sizeof( AttrInfo * )); +- if ( x < bdb->bi_nattrs ) +- AC_MEMCPY( &bdb->bi_attrs[x+1], &bdb->bi_attrs[x], +- ( bdb->bi_nattrs - x ) * sizeof( AttrInfo *)); +- bdb->bi_attrs[x] = a; +- bdb->bi_nattrs++; +- return 0; +-} +- +-AttrInfo * +-bdb_attr_mask( +- struct bdb_info *bdb, +- AttributeDescription *desc ) +-{ +- int i = bdb_attr_slot( bdb, desc, NULL ); +- return i < 0 ? NULL : bdb->bi_attrs[i]; +-} +- +-int +-bdb_attr_index_config( +- struct bdb_info *bdb, +- const char *fname, +- int lineno, +- int argc, +- char **argv, +- struct config_reply_s *c_reply) +-{ +- int rc = 0; +- int i; +- slap_mask_t mask; +- char **attrs; +- char **indexes = NULL; +- +- attrs = ldap_str2charray( argv[0], "," ); +- +- if( attrs == NULL ) { +- fprintf( stderr, "%s: line %d: " +- "no attributes specified: %s\n", +- fname, lineno, argv[0] ); +- return LDAP_PARAM_ERROR; +- } +- +- if ( argc > 1 ) { +- indexes = ldap_str2charray( argv[1], "," ); +- +- if( indexes == NULL ) { +- fprintf( stderr, "%s: line %d: " +- "no indexes specified: %s\n", +- fname, lineno, argv[1] ); +- rc = LDAP_PARAM_ERROR; +- goto done; +- } +- } +- +- if( indexes == NULL ) { +- mask = bdb->bi_defaultmask; +- +- } else { +- mask = 0; +- +- for ( i = 0; indexes[i] != NULL; i++ ) { +- slap_mask_t index; +- rc = slap_str2index( indexes[i], &index ); +- +- if( rc != LDAP_SUCCESS ) { +- if ( c_reply ) +- { +- snprintf(c_reply->msg, sizeof(c_reply->msg), +- "index type \"%s\" undefined", indexes[i] ); +- +- fprintf( stderr, "%s: line %d: %s\n", +- fname, lineno, c_reply->msg ); +- } +- rc = LDAP_PARAM_ERROR; +- goto done; +- } +- +- mask |= index; +- } +- } +- +- if( !mask ) { +- if ( c_reply ) +- { +- snprintf(c_reply->msg, sizeof(c_reply->msg), +- "no indexes selected" ); +- fprintf( stderr, "%s: line %d: %s\n", +- fname, lineno, c_reply->msg ); +- } +- rc = LDAP_PARAM_ERROR; +- goto done; +- } +- +- for ( i = 0; attrs[i] != NULL; i++ ) { +- AttrInfo *a; +- AttributeDescription *ad; +- const char *text; +-#ifdef LDAP_COMP_MATCH +- ComponentReference* cr = NULL; +- AttrInfo *a_cr = NULL; +-#endif +- +- if( strcasecmp( attrs[i], "default" ) == 0 ) { +- bdb->bi_defaultmask |= mask; +- continue; +- } +- +-#ifdef LDAP_COMP_MATCH +- if ( is_component_reference( attrs[i] ) ) { +- rc = extract_component_reference( attrs[i], &cr ); +- if ( rc != LDAP_SUCCESS ) { +- if ( c_reply ) +- { +- snprintf(c_reply->msg, sizeof(c_reply->msg), +- "index component reference\"%s\" undefined", +- attrs[i] ); +- fprintf( stderr, "%s: line %d: %s\n", +- fname, lineno, c_reply->msg ); +- } +- goto done; +- } +- cr->cr_indexmask = mask; +- /* +- * After extracting a component reference +- * only the name of a attribute will be remaining +- */ +- } else { +- cr = NULL; +- } +-#endif +- ad = NULL; +- rc = slap_str2ad( attrs[i], &ad, &text ); +- +- if( rc != LDAP_SUCCESS ) { +- if ( c_reply ) +- { +- snprintf(c_reply->msg, sizeof(c_reply->msg), +- "index attribute \"%s\" undefined", +- attrs[i] ); +- +- fprintf( stderr, "%s: line %d: %s\n", +- fname, lineno, c_reply->msg ); +- } +- goto done; +- } +- +- if( ad == slap_schema.si_ad_entryDN || slap_ad_is_binary( ad ) ) { +- if (c_reply) { +- snprintf(c_reply->msg, sizeof(c_reply->msg), +- "index of attribute \"%s\" disallowed", attrs[i] ); +- fprintf( stderr, "%s: line %d: %s\n", +- fname, lineno, c_reply->msg ); +- } +- rc = LDAP_UNWILLING_TO_PERFORM; +- goto done; +- } +- +- if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) && !( +- ad->ad_type->sat_approx +- && ad->ad_type->sat_approx->smr_indexer +- && ad->ad_type->sat_approx->smr_filter ) ) +- { +- if (c_reply) { +- snprintf(c_reply->msg, sizeof(c_reply->msg), +- "approx index of attribute \"%s\" disallowed", attrs[i] ); +- fprintf( stderr, "%s: line %d: %s\n", +- fname, lineno, c_reply->msg ); +- } +- rc = LDAP_INAPPROPRIATE_MATCHING; +- goto done; +- } +- +- if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) && !( +- ad->ad_type->sat_equality +- && ad->ad_type->sat_equality->smr_indexer +- && ad->ad_type->sat_equality->smr_filter ) ) +- { +- if (c_reply) { +- snprintf(c_reply->msg, sizeof(c_reply->msg), +- "equality index of attribute \"%s\" disallowed", attrs[i] ); +- fprintf( stderr, "%s: line %d: %s\n", +- fname, lineno, c_reply->msg ); +- } +- rc = LDAP_INAPPROPRIATE_MATCHING; +- goto done; +- } +- +- if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) && !( +- ad->ad_type->sat_substr +- && ad->ad_type->sat_substr->smr_indexer +- && ad->ad_type->sat_substr->smr_filter ) ) +- { +- if (c_reply) { +- snprintf(c_reply->msg, sizeof(c_reply->msg), +- "substr index of attribute \"%s\" disallowed", attrs[i] ); +- fprintf( stderr, "%s: line %d: %s\n", +- fname, lineno, c_reply->msg ); +- } +- rc = LDAP_INAPPROPRIATE_MATCHING; +- goto done; +- } +- +- Debug( LDAP_DEBUG_CONFIG, "index %s 0x%04lx\n", +- ad->ad_cname.bv_val, mask, 0 ); +- +- a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) ); +- +-#ifdef LDAP_COMP_MATCH +- a->ai_cr = NULL; +-#endif +- a->ai_desc = ad; +- +- if ( bdb->bi_flags & BDB_IS_OPEN ) { +- a->ai_indexmask = 0; +- a->ai_newmask = mask; +- } else { +- a->ai_indexmask = mask; +- a->ai_newmask = 0; +- } +- +-#ifdef LDAP_COMP_MATCH +- if ( cr ) { +- a_cr = bdb_attr_mask( bdb, ad ); +- if ( a_cr ) { +- /* +- * AttrInfo is already in AVL +- * just add the extracted component reference +- * in the AttrInfo +- */ +- rc = insert_component_reference( cr, &a_cr->ai_cr ); +- if ( rc != LDAP_SUCCESS) { +- fprintf( stderr, " error during inserting component reference in %s ", attrs[i]); +- rc = LDAP_PARAM_ERROR; +- goto done; +- } +- continue; +- } else { +- rc = insert_component_reference( cr, &a->ai_cr ); +- if ( rc != LDAP_SUCCESS) { +- fprintf( stderr, " error during inserting component reference in %s ", attrs[i]); +- rc = LDAP_PARAM_ERROR; +- goto done; +- } +- } +- } +-#endif +- rc = ainfo_insert( bdb, a ); +- if( rc ) { +- if ( bdb->bi_flags & BDB_IS_OPEN ) { +- AttrInfo *b = bdb_attr_mask( bdb, ad ); +- /* If there is already an index defined for this attribute +- * it must be replaced. Otherwise we end up with multiple +- * olcIndex values for the same attribute */ +- if ( b->ai_indexmask & BDB_INDEX_DELETING ) { +- /* If we were editing this attr, reset it */ +- b->ai_indexmask &= ~BDB_INDEX_DELETING; +- /* If this is leftover from a previous add, commit it */ +- if ( b->ai_newmask ) +- b->ai_indexmask = b->ai_newmask; +- b->ai_newmask = a->ai_newmask; +- ch_free( a ); +- rc = 0; +- continue; +- } +- } +- if (c_reply) { +- snprintf(c_reply->msg, sizeof(c_reply->msg), +- "duplicate index definition for attr \"%s\"", +- attrs[i] ); +- fprintf( stderr, "%s: line %d: %s\n", +- fname, lineno, c_reply->msg ); +- } +- +- rc = LDAP_PARAM_ERROR; +- goto done; +- } +- } +- +-done: +- ldap_charray_free( attrs ); +- if ( indexes != NULL ) ldap_charray_free( indexes ); +- +- return rc; +-} +- +-static int +-bdb_attr_index_unparser( void *v1, void *v2 ) +-{ +- AttrInfo *ai = v1; +- BerVarray *bva = v2; +- struct berval bv; +- char *ptr; +- +- slap_index2bvlen( ai->ai_indexmask, &bv ); +- if ( bv.bv_len ) { +- bv.bv_len += ai->ai_desc->ad_cname.bv_len + 1; +- ptr = ch_malloc( bv.bv_len+1 ); +- bv.bv_val = lutil_strcopy( ptr, ai->ai_desc->ad_cname.bv_val ); +- *bv.bv_val++ = ' '; +- slap_index2bv( ai->ai_indexmask, &bv ); +- bv.bv_val = ptr; +- ber_bvarray_add( bva, &bv ); +- } +- return 0; +-} +- +-static AttributeDescription addef = { NULL, NULL, BER_BVC("default") }; +-static AttrInfo aidef = { &addef }; +- +-void +-bdb_attr_index_unparse( struct bdb_info *bdb, BerVarray *bva ) +-{ +- int i; +- +- if ( bdb->bi_defaultmask ) { +- aidef.ai_indexmask = bdb->bi_defaultmask; +- bdb_attr_index_unparser( &aidef, bva ); +- } +- for ( i=0; ibi_nattrs; i++ ) +- bdb_attr_index_unparser( bdb->bi_attrs[i], bva ); +-} +- +-void +-bdb_attr_info_free( AttrInfo *ai ) +-{ +-#ifdef LDAP_COMP_MATCH +- free( ai->ai_cr ); +-#endif +- free( ai ); +-} +- +-void +-bdb_attr_index_destroy( struct bdb_info *bdb ) +-{ +- int i; +- +- for ( i=0; ibi_nattrs; i++ ) +- bdb_attr_info_free( bdb->bi_attrs[i] ); +- +- free( bdb->bi_attrs ); +-} +- +-void bdb_attr_index_free( struct bdb_info *bdb, AttributeDescription *ad ) +-{ +- int i; +- +- i = bdb_attr_slot( bdb, ad, NULL ); +- if ( i >= 0 ) { +- bdb_attr_info_free( bdb->bi_attrs[i] ); +- bdb->bi_nattrs--; +- for (; ibi_nattrs; i++) +- bdb->bi_attrs[i] = bdb->bi_attrs[i+1]; +- } +-} +- +-void bdb_attr_flush( struct bdb_info *bdb ) +-{ +- int i; +- +- for ( i=0; ibi_nattrs; i++ ) { +- if ( bdb->bi_attrs[i]->ai_indexmask & BDB_INDEX_DELETING ) { +- int j; +- bdb_attr_info_free( bdb->bi_attrs[i] ); +- bdb->bi_nattrs--; +- for (j=i; jbi_nattrs; j++) +- bdb->bi_attrs[j] = bdb->bi_attrs[j+1]; +- i--; +- } +- } +-} +diff --git a/servers/slapd/back-bdb/back-bdb.h b/servers/slapd/back-bdb/back-bdb.h +deleted file mode 100644 +index 84897cd..0000000 +--- a/servers/slapd/back-bdb/back-bdb.h ++++ /dev/null +@@ -1,377 +0,0 @@ +-/* back-bdb.h - bdb back-end header file */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#ifndef _BACK_BDB_H_ +-#define _BACK_BDB_H_ +- +-#include +-#include "slap.h" +-#include +-#include "alock.h" +- +-LDAP_BEGIN_DECL +- +-#define DB_VERSION_FULL ((DB_VERSION_MAJOR << 24) | (DB_VERSION_MINOR << 16) | DB_VERSION_PATCH) +- +-#define DN_BASE_PREFIX SLAP_INDEX_EQUALITY_PREFIX +-#define DN_ONE_PREFIX '%' +-#define DN_SUBTREE_PREFIX '@' +- +-#define DBTzero(t) (memset((t), 0, sizeof(DBT))) +-#define DBT2bv(t,bv) ((bv)->bv_val = (t)->data, \ +- (bv)->bv_len = (t)->size) +-#define bv2DBT(bv,t) ((t)->data = (bv)->bv_val, \ +- (t)->size = (bv)->bv_len ) +- +-#define BDB_TXN_RETRIES 16 +- +-#define BDB_MAX_ADD_LOOP 30 +- +-#define BDB_SUFFIX ".bdb" +-#define BDB_ID2ENTRY 0 +-#define BDB_DN2ID 1 +-#define BDB_NDB 2 +- +-/* The bdb on-disk entry format is pretty space-inefficient. Average +- * sized user entries are 3-4K each. You need at least two entries to +- * fit into a single database page, more is better. 64K is BDB's +- * upper bound. Smaller pages are better for concurrency. +- */ +-#ifndef BDB_ID2ENTRY_PAGESIZE +-#define BDB_ID2ENTRY_PAGESIZE 16384 +-#endif +- +-#define DEFAULT_CACHE_SIZE 1000 +- +-/* The default search IDL stack cache depth */ +-#define DEFAULT_SEARCH_STACK_DEPTH 16 +- +-/* The minimum we can function with */ +-#define MINIMUM_SEARCH_STACK_DEPTH 8 +- +-typedef struct bdb_idl_cache_entry_s { +- struct berval kstr; +- ID *idl; +- DB *db; +- int idl_flags; +- struct bdb_idl_cache_entry_s* idl_lru_prev; +- struct bdb_idl_cache_entry_s* idl_lru_next; +-} bdb_idl_cache_entry_t; +- +-/* BDB backend specific entry info */ +-typedef struct bdb_entry_info { +- struct bdb_entry_info *bei_parent; +- ID bei_id; +- +- /* we use the bei_id as a lockobj, but we need to make the size != 4 +- * to avoid conflicting with BDB's internal locks. So add a byte here +- * that is always zero. +- */ +- short bei_lockpad; +- +- short bei_state; +-#define CACHE_ENTRY_DELETED 1 +-#define CACHE_ENTRY_NO_KIDS 2 +-#define CACHE_ENTRY_NOT_LINKED 4 +-#define CACHE_ENTRY_NO_GRANDKIDS 8 +-#define CACHE_ENTRY_LOADING 0x10 +-#define CACHE_ENTRY_WALKING 0x20 +-#define CACHE_ENTRY_ONELEVEL 0x40 +-#define CACHE_ENTRY_REFERENCED 0x80 +-#define CACHE_ENTRY_NOT_CACHED 0x100 +- int bei_finders; +- +- /* +- * remaining fields require backend cache lock to access +- */ +- struct berval bei_nrdn; +-#ifdef BDB_HIER +- struct berval bei_rdn; +- int bei_modrdns; /* track renames */ +- int bei_ckids; /* number of kids cached */ +- int bei_dkids; /* number of kids on-disk, plus 1 */ +-#endif +- Entry *bei_e; +- Avlnode *bei_kids; +-#ifdef SLAP_ZONE_ALLOC +- struct bdb_info *bei_bdb; +- int bei_zseq; +-#endif +- ldap_pvt_thread_mutex_t bei_kids_mutex; +- +- struct bdb_entry_info *bei_lrunext; /* for cache lru list */ +- struct bdb_entry_info *bei_lruprev; +-} EntryInfo; +-#undef BEI +-#define BEI(e) ((EntryInfo *) ((e)->e_private)) +- +-/* for the in-core cache of entries */ +-typedef struct bdb_cache { +- EntryInfo *c_eifree; /* free list */ +- Avlnode *c_idtree; +- EntryInfo *c_lruhead; /* lru - add accessed entries here */ +- EntryInfo *c_lrutail; /* lru - rem lru entries from here */ +- EntryInfo c_dntree; +- ID c_maxsize; +- ID c_cursize; +- ID c_minfree; +- ID c_eimax; +- ID c_eiused; /* EntryInfo's in use */ +- ID c_leaves; /* EntryInfo leaf nodes */ +- int c_purging; +- DB_TXN *c_txn; /* used by lru cleaner */ +- ldap_pvt_thread_rdwr_t c_rwlock; +- ldap_pvt_thread_mutex_t c_lru_mutex; +- ldap_pvt_thread_mutex_t c_count_mutex; +- ldap_pvt_thread_mutex_t c_eifree_mutex; +-#ifdef SLAP_ZONE_ALLOC +- void *c_zctx; +-#endif +-} Cache; +- +-#define CACHE_READ_LOCK 0 +-#define CACHE_WRITE_LOCK 1 +- +-#define BDB_INDICES 128 +- +-struct bdb_db_info { +- struct berval bdi_name; +- DB *bdi_db; +-}; +- +-struct bdb_db_pgsize { +- struct bdb_db_pgsize *bdp_next; +- struct berval bdp_name; +- int bdp_size; +-}; +- +-#ifdef LDAP_DEVEL +-#define BDB_MONITOR_IDX +-#endif /* LDAP_DEVEL */ +- +-typedef struct bdb_monitor_t { +- void *bdm_cb; +- struct berval bdm_ndn; +-} bdb_monitor_t; +- +-/* From ldap_rq.h */ +-struct re_s; +- +-struct bdb_info { +- DB_ENV *bi_dbenv; +- +- /* DB_ENV parameters */ +- /* The DB_ENV can be tuned via DB_CONFIG */ +- char *bi_dbenv_home; +- u_int32_t bi_dbenv_xflags; /* extra flags */ +- int bi_dbenv_mode; +- +- int bi_ndatabases; +- int bi_db_opflags; /* db-specific flags */ +- struct bdb_db_info **bi_databases; +- ldap_pvt_thread_mutex_t bi_database_mutex; +- struct bdb_db_pgsize *bi_pagesizes; +- +- slap_mask_t bi_defaultmask; +- Cache bi_cache; +- struct bdb_attrinfo **bi_attrs; +- int bi_nattrs; +- void *bi_search_stack; +- int bi_search_stack_depth; +- int bi_linear_index; +- +- int bi_txn_cp; +- u_int32_t bi_txn_cp_min; +- u_int32_t bi_txn_cp_kbyte; +- struct re_s *bi_txn_cp_task; +- struct re_s *bi_index_task; +- +- u_int32_t bi_lock_detect; +- long bi_shm_key; +- +- ID bi_lastid; +- ldap_pvt_thread_mutex_t bi_lastid_mutex; +- ID bi_idl_cache_max_size; +- ID bi_idl_cache_size; +- Avlnode *bi_idl_tree; +- bdb_idl_cache_entry_t *bi_idl_lru_head; +- bdb_idl_cache_entry_t *bi_idl_lru_tail; +- ldap_pvt_thread_rdwr_t bi_idl_tree_rwlock; +- ldap_pvt_thread_mutex_t bi_idl_tree_lrulock; +- alock_info_t bi_alock_info; +- char *bi_db_config_path; +- BerVarray bi_db_config; +- char *bi_db_crypt_file; +- struct berval bi_db_crypt_key; +- bdb_monitor_t bi_monitor; +- +-#ifdef BDB_MONITOR_IDX +- ldap_pvt_thread_mutex_t bi_idx_mutex; +- Avlnode *bi_idx; +-#endif /* BDB_MONITOR_IDX */ +- +- int bi_flags; +-#define BDB_IS_OPEN 0x01 +-#define BDB_HAS_CONFIG 0x02 +-#define BDB_UPD_CONFIG 0x04 +-#define BDB_DEL_INDEX 0x08 +-#define BDB_RE_OPEN 0x10 +-#define BDB_CHKSUM 0x20 +-#ifdef BDB_HIER +- int bi_modrdns; /* number of modrdns completed */ +- ldap_pvt_thread_mutex_t bi_modrdns_mutex; +-#endif +-}; +- +-#define bi_id2entry bi_databases[BDB_ID2ENTRY] +-#define bi_dn2id bi_databases[BDB_DN2ID] +- +- +-struct bdb_lock_info { +- struct bdb_lock_info *bli_next; +- DB_LOCK bli_lock; +- ID bli_id; +- int bli_flag; +-}; +-#define BLI_DONTFREE 1 +- +-struct bdb_op_info { +- OpExtra boi_oe; +- DB_TXN* boi_txn; +- struct bdb_lock_info *boi_locks; /* used when no txn */ +- u_int32_t boi_err; +- char boi_acl_cache; +- char boi_flag; +-}; +-#define BOI_DONTFREE 1 +- +-#define DB_OPEN(db, file, name, type, flags, mode) \ +- ((db)->open)(db, file, name, type, flags, mode) +- +-#if DB_VERSION_MAJOR < 4 +-#define LOCK_DETECT(env,f,t,a) lock_detect(env, f, t, a) +-#define LOCK_GET(env,i,f,o,m,l) lock_get(env, i, f, o, m, l) +-#define LOCK_PUT(env,l) lock_put(env, l) +-#define TXN_CHECKPOINT(env,k,m,f) txn_checkpoint(env, k, m, f) +-#define TXN_BEGIN(env,p,t,f) txn_begin((env), p, t, f) +-#define TXN_PREPARE(txn,gid) txn_prepare((txn), (gid)) +-#define TXN_COMMIT(txn,f) txn_commit((txn), (f)) +-#define TXN_ABORT(txn) txn_abort((txn)) +-#define TXN_ID(txn) txn_id(txn) +-#define XLOCK_ID(env, locker) lock_id(env, locker) +-#define XLOCK_ID_FREE(env, locker) lock_id_free(env, locker) +-#else +-#define LOCK_DETECT(env,f,t,a) (env)->lock_detect(env, f, t, a) +-#define LOCK_GET(env,i,f,o,m,l) (env)->lock_get(env, i, f, o, m, l) +-#define LOCK_PUT(env,l) (env)->lock_put(env, l) +-#define TXN_CHECKPOINT(env,k,m,f) (env)->txn_checkpoint(env, k, m, f) +-#define TXN_BEGIN(env,p,t,f) (env)->txn_begin((env), p, t, f) +-#define TXN_PREPARE(txn,g) (txn)->prepare((txn), (g)) +-#define TXN_COMMIT(txn,f) (txn)->commit((txn), (f)) +-#define TXN_ABORT(txn) (txn)->abort((txn)) +-#define TXN_ID(txn) (txn)->id(txn) +-#define XLOCK_ID(env, locker) (env)->lock_id(env, locker) +-#define XLOCK_ID_FREE(env, locker) (env)->lock_id_free(env, locker) +- +-/* BDB 4.1.17 adds txn arg to db->open */ +-#if DB_VERSION_FULL >= 0x04010011 +-#undef DB_OPEN +-#define DB_OPEN(db, file, name, type, flags, mode) \ +- ((db)->open)(db, NULL, file, name, type, flags, mode) +-#endif +- +-/* #undef BDB_LOG_DEBUG */ +- +-#ifdef BDB_LOG_DEBUG +- +-/* env->log_printf appeared in 4.4 */ +-#if DB_VERSION_FULL >= 0x04040000 +-#define BDB_LOG_PRINTF(env,txn,fmt,...) (env)->log_printf((env),(txn),(fmt),__VA_ARGS__) +-#else +-extern int __db_logmsg(const DB_ENV *env, DB_TXN *txn, const char *op, u_int32_t flags, +- const char *fmt,...); +-#define BDB_LOG_PRINTF(env,txn,fmt,...) __db_logmsg((env),(txn),"DIAGNOSTIC",0,(fmt),__VA_ARGS__) +-#endif +- +-/* !BDB_LOG_DEBUG */ +-#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ +- (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__STRICT_ANSI__)) +-#define BDB_LOG_PRINTF(a,b,c,...) +-#else +-#define BDB_LOG_PRINTF (void) /* will evaluate and discard the arguments */ +- +-#endif /* BDB_LOG_DEBUG */ +- +-#endif +- +-#ifndef DB_BUFFER_SMALL +-#define DB_BUFFER_SMALL ENOMEM +-#endif +- +-#define BDB_CSN_COMMIT 0 +-#define BDB_CSN_ABORT 1 +-#define BDB_CSN_RETRY 2 +- +-/* Copy an ID "src" to pointer "dst" in big-endian byte order */ +-#define BDB_ID2DISK( src, dst ) \ +- do { int i0; ID tmp; unsigned char *_p; \ +- tmp = (src); _p = (unsigned char *)(dst); \ +- for ( i0=sizeof(ID)-1; i0>=0; i0-- ) { \ +- _p[i0] = tmp & 0xff; tmp >>= 8; \ +- } \ +- } while(0) +- +-/* Copy a pointer "src" to a pointer "dst" from big-endian to native order */ +-#define BDB_DISK2ID( src, dst ) \ +- do { unsigned i0; ID tmp = 0; unsigned char *_p; \ +- _p = (unsigned char *)(src); \ +- for ( i0=0; i0. +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +-#include +-#include +- +-#include "back-bdb.h" +- +-int +-bdb_bind( Operation *op, SlapReply *rs ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- Entry *e; +- Attribute *a; +- EntryInfo *ei; +- +- AttributeDescription *password = slap_schema.si_ad_userPassword; +- +- DB_TXN *rtxn; +- DB_LOCK lock; +- +- Debug( LDAP_DEBUG_ARGS, +- "==> " LDAP_XSTRING(bdb_bind) ": dn: %s\n", +- op->o_req_dn.bv_val, 0, 0); +- +- /* allow noauth binds */ +- switch ( be_rootdn_bind( op, NULL ) ) { +- case LDAP_SUCCESS: +- /* frontend will send result */ +- return rs->sr_err = LDAP_SUCCESS; +- +- default: +- /* give the database a chance */ +- /* NOTE: this behavior departs from that of other backends, +- * since the others, in case of password checking failure +- * do not give the database a chance. If an entry with +- * rootdn's name does not exist in the database the result +- * will be the same. See ITS#4962 for discussion. */ +- break; +- } +- +- rs->sr_err = bdb_reader_get(op, bdb->bi_dbenv, &rtxn); +- switch(rs->sr_err) { +- case 0: +- break; +- default: +- rs->sr_text = "internal error"; +- send_ldap_result( op, rs ); +- return rs->sr_err; +- } +- +-dn2entry_retry: +- /* get entry with reader lock */ +- rs->sr_err = bdb_dn2entry( op, rtxn, &op->o_req_ndn, &ei, 1, +- &lock ); +- +- switch(rs->sr_err) { +- case DB_NOTFOUND: +- case 0: +- break; +- case LDAP_BUSY: +- send_ldap_error( op, rs, LDAP_BUSY, "ldap_server_busy" ); +- return LDAP_BUSY; +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto dn2entry_retry; +- default: +- send_ldap_error( op, rs, LDAP_OTHER, "internal error" ); +- return rs->sr_err; +- } +- +- e = ei->bei_e; +- if ( rs->sr_err == DB_NOTFOUND ) { +- if( e != NULL ) { +- bdb_cache_return_entry_r( bdb, e, &lock ); +- e = NULL; +- } +- +- rs->sr_err = LDAP_INVALID_CREDENTIALS; +- send_ldap_result( op, rs ); +- +- return rs->sr_err; +- } +- +- ber_dupbv( &op->oq_bind.rb_edn, &e->e_name ); +- +- /* check for deleted */ +- if ( is_entry_subentry( e ) ) { +- /* entry is an subentry, don't allow bind */ +- Debug( LDAP_DEBUG_TRACE, "entry is subentry\n", 0, +- 0, 0 ); +- rs->sr_err = LDAP_INVALID_CREDENTIALS; +- goto done; +- } +- +- if ( is_entry_alias( e ) ) { +- /* entry is an alias, don't allow bind */ +- Debug( LDAP_DEBUG_TRACE, "entry is alias\n", 0, 0, 0 ); +- rs->sr_err = LDAP_INVALID_CREDENTIALS; +- goto done; +- } +- +- if ( is_entry_referral( e ) ) { +- Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0, +- 0, 0 ); +- rs->sr_err = LDAP_INVALID_CREDENTIALS; +- goto done; +- } +- +- switch ( op->oq_bind.rb_method ) { +- case LDAP_AUTH_SIMPLE: +- a = attr_find( e->e_attrs, password ); +- if ( a == NULL ) { +- rs->sr_err = LDAP_INVALID_CREDENTIALS; +- goto done; +- } +- +- if ( slap_passwd_check( op, e, a, &op->oq_bind.rb_cred, +- &rs->sr_text ) != 0 ) +- { +- /* failure; stop front end from sending result */ +- rs->sr_err = LDAP_INVALID_CREDENTIALS; +- goto done; +- } +- +- rs->sr_err = 0; +- break; +- +- default: +- assert( 0 ); /* should not be reachable */ +- rs->sr_err = LDAP_STRONG_AUTH_NOT_SUPPORTED; +- rs->sr_text = "authentication method not supported"; +- } +- +-done: +- /* free entry and reader lock */ +- if( e != NULL ) { +- bdb_cache_return_entry_r( bdb, e, &lock ); +- } +- +- if ( rs->sr_err ) { +- send_ldap_result( op, rs ); +- if ( rs->sr_ref ) { +- ber_bvarray_free( rs->sr_ref ); +- rs->sr_ref = NULL; +- } +- } +- /* front end will send result on success (rs->sr_err==0) */ +- return rs->sr_err; +-} +diff --git a/servers/slapd/back-bdb/cache.c b/servers/slapd/back-bdb/cache.c +deleted file mode 100644 +index 51161fe..0000000 +--- a/servers/slapd/back-bdb/cache.c ++++ /dev/null +@@ -1,1692 +0,0 @@ +-/* cache.c - routines to maintain an in-core cache of entries */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +- +-#include +-#include +-#include +- +-#include "slap.h" +- +-#include "back-bdb.h" +- +-#include "ldap_rq.h" +- +-#ifdef BDB_HIER +-#define bdb_cache_lru_purge hdb_cache_lru_purge +-#endif +-static void bdb_cache_lru_purge( struct bdb_info *bdb ); +- +-static int bdb_cache_delete_internal(Cache *cache, EntryInfo *e, int decr); +-#ifdef LDAP_DEBUG +-#define SLAPD_UNUSED +-#ifdef SLAPD_UNUSED +-static void bdb_lru_print(Cache *cache); +-static void bdb_idtree_print(Cache *cache); +-#endif +-#endif +- +-/* For concurrency experiments only! */ +-#if 0 +-#define ldap_pvt_thread_rdwr_wlock(a) 0 +-#define ldap_pvt_thread_rdwr_wunlock(a) 0 +-#define ldap_pvt_thread_rdwr_rlock(a) 0 +-#define ldap_pvt_thread_rdwr_runlock(a) 0 +-#endif +- +-#if 0 +-#define ldap_pvt_thread_mutex_trylock(a) 0 +-#endif +- +-static EntryInfo * +-bdb_cache_entryinfo_new( Cache *cache ) +-{ +- EntryInfo *ei = NULL; +- +- if ( cache->c_eifree ) { +- ldap_pvt_thread_mutex_lock( &cache->c_eifree_mutex ); +- if ( cache->c_eifree ) { +- ei = cache->c_eifree; +- cache->c_eifree = ei->bei_lrunext; +- ei->bei_finders = 0; +- ei->bei_lrunext = NULL; +- } +- ldap_pvt_thread_mutex_unlock( &cache->c_eifree_mutex ); +- } +- if ( !ei ) { +- ei = ch_calloc(1, sizeof(EntryInfo)); +- ldap_pvt_thread_mutex_init( &ei->bei_kids_mutex ); +- } +- +- ei->bei_state = CACHE_ENTRY_REFERENCED; +- +- return ei; +-} +- +-static void +-bdb_cache_entryinfo_free( Cache *cache, EntryInfo *ei ) +-{ +- free( ei->bei_nrdn.bv_val ); +- BER_BVZERO( &ei->bei_nrdn ); +-#ifdef BDB_HIER +- free( ei->bei_rdn.bv_val ); +- BER_BVZERO( &ei->bei_rdn ); +- ei->bei_modrdns = 0; +- ei->bei_ckids = 0; +- ei->bei_dkids = 0; +-#endif +- ei->bei_parent = NULL; +- ei->bei_kids = NULL; +- ei->bei_lruprev = NULL; +- +-#if 0 +- ldap_pvt_thread_mutex_lock( &cache->c_eifree_mutex ); +- ei->bei_lrunext = cache->c_eifree; +- cache->c_eifree = ei; +- ldap_pvt_thread_mutex_unlock( &cache->c_eifree_mutex ); +-#else +- ldap_pvt_thread_mutex_destroy( &ei->bei_kids_mutex ); +- ch_free( ei ); +-#endif +-} +- +-#define LRU_DEL( c, e ) do { \ +- if ( e == e->bei_lruprev ) { \ +- (c)->c_lruhead = (c)->c_lrutail = NULL; \ +- } else { \ +- if ( e == (c)->c_lruhead ) (c)->c_lruhead = e->bei_lruprev; \ +- if ( e == (c)->c_lrutail ) (c)->c_lrutail = e->bei_lruprev; \ +- e->bei_lrunext->bei_lruprev = e->bei_lruprev; \ +- e->bei_lruprev->bei_lrunext = e->bei_lrunext; \ +- } \ +- e->bei_lruprev = NULL; \ +-} while ( 0 ) +- +-/* Note - we now use a Second-Chance / Clock algorithm instead of +- * Least-Recently-Used. This tremendously improves concurrency +- * because we no longer need to manipulate the lists every time an +- * entry is touched. We only need to lock the lists when adding +- * or deleting an entry. It's now a circular doubly-linked list. +- * We always append to the tail, but the head traverses the circle +- * during a purge operation. +- */ +-static void +-bdb_cache_lru_link( struct bdb_info *bdb, EntryInfo *ei ) +-{ +- +- /* Already linked, ignore */ +- if ( ei->bei_lruprev ) +- return; +- +- /* Insert into circular LRU list */ +- ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_lru_mutex ); +- +- ei->bei_lruprev = bdb->bi_cache.c_lrutail; +- if ( bdb->bi_cache.c_lrutail ) { +- ei->bei_lrunext = bdb->bi_cache.c_lrutail->bei_lrunext; +- bdb->bi_cache.c_lrutail->bei_lrunext = ei; +- if ( ei->bei_lrunext ) +- ei->bei_lrunext->bei_lruprev = ei; +- } else { +- ei->bei_lrunext = ei->bei_lruprev = ei; +- bdb->bi_cache.c_lruhead = ei; +- } +- bdb->bi_cache.c_lrutail = ei; +- ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_lru_mutex ); +-} +- +-#ifdef NO_THREADS +-#define NO_DB_LOCK +-#endif +- +-/* #define NO_DB_LOCK 1 */ +-/* Note: The BerkeleyDB locks are much slower than regular +- * mutexes or rdwr locks. But the BDB implementation has the +- * advantage of using a fixed size lock table, instead of +- * allocating a lock object per entry in the DB. That's a +- * key benefit for scaling. It also frees us from worrying +- * about undetectable deadlocks between BDB activity and our +- * own cache activity. It's still worth exploring faster +- * alternatives though. +- */ +- +-/* Atomically release and reacquire a lock */ +-int +-bdb_cache_entry_db_relock( +- struct bdb_info *bdb, +- DB_TXN *txn, +- EntryInfo *ei, +- int rw, +- int tryOnly, +- DB_LOCK *lock ) +-{ +-#ifdef NO_DB_LOCK +- return 0; +-#else +- int rc; +- DBT lockobj; +- DB_LOCKREQ list[2]; +- +- if ( !lock ) return 0; +- +- DBTzero( &lockobj ); +- lockobj.data = &ei->bei_id; +- lockobj.size = sizeof(ei->bei_id) + 1; +- +- list[0].op = DB_LOCK_PUT; +- list[0].lock = *lock; +- list[1].op = DB_LOCK_GET; +- list[1].lock = *lock; +- list[1].mode = rw ? DB_LOCK_WRITE : DB_LOCK_READ; +- list[1].obj = &lockobj; +- rc = bdb->bi_dbenv->lock_vec(bdb->bi_dbenv, TXN_ID(txn), tryOnly ? DB_LOCK_NOWAIT : 0, +- list, 2, NULL ); +- +- if (rc && !tryOnly) { +- Debug( LDAP_DEBUG_TRACE, +- "bdb_cache_entry_db_relock: entry %ld, rw %d, rc %d\n", +- ei->bei_id, rw, rc ); +- } else { +- *lock = list[1].lock; +- } +- return rc; +-#endif +-} +- +-static int +-bdb_cache_entry_db_lock( struct bdb_info *bdb, DB_TXN *txn, EntryInfo *ei, +- int rw, int tryOnly, DB_LOCK *lock ) +-{ +-#ifdef NO_DB_LOCK +- return 0; +-#else +- int rc; +- DBT lockobj; +- int db_rw; +- +- if ( !lock ) return 0; +- +- if (rw) +- db_rw = DB_LOCK_WRITE; +- else +- db_rw = DB_LOCK_READ; +- +- DBTzero( &lockobj ); +- lockobj.data = &ei->bei_id; +- lockobj.size = sizeof(ei->bei_id) + 1; +- +- rc = LOCK_GET(bdb->bi_dbenv, TXN_ID(txn), tryOnly ? DB_LOCK_NOWAIT : 0, +- &lockobj, db_rw, lock); +- if (rc && !tryOnly) { +- Debug( LDAP_DEBUG_TRACE, +- "bdb_cache_entry_db_lock: entry %ld, rw %d, rc %d\n", +- ei->bei_id, rw, rc ); +- } +- return rc; +-#endif /* NO_DB_LOCK */ +-} +- +-int +-bdb_cache_entry_db_unlock ( struct bdb_info *bdb, DB_LOCK *lock ) +-{ +-#ifdef NO_DB_LOCK +- return 0; +-#else +- int rc; +- +- if ( !lock || lock->mode == DB_LOCK_NG ) return 0; +- +- rc = LOCK_PUT ( bdb->bi_dbenv, lock ); +- return rc; +-#endif +-} +- +-void +-bdb_cache_return_entry_rw( struct bdb_info *bdb, Entry *e, +- int rw, DB_LOCK *lock ) +-{ +- EntryInfo *ei; +- int free = 0; +- +- ei = e->e_private; +- if ( ei && ( ei->bei_state & CACHE_ENTRY_NOT_CACHED )) { +- bdb_cache_entryinfo_lock( ei ); +- if ( ei->bei_state & CACHE_ENTRY_NOT_CACHED ) { +- /* Releasing the entry can only be done when +- * we know that nobody else is using it, i.e we +- * should have an entry_db writelock. But the +- * flag is only set by the thread that loads the +- * entry, and only if no other threads has found +- * it while it was working. All other threads +- * clear the flag, which mean that we should be +- * the only thread using the entry if the flag +- * is set here. +- */ +- ei->bei_e = NULL; +- ei->bei_state ^= CACHE_ENTRY_NOT_CACHED; +- free = 1; +- } +- bdb_cache_entryinfo_unlock( ei ); +- } +- bdb_cache_entry_db_unlock( bdb, lock ); +- if ( free ) { +- e->e_private = NULL; +- bdb_entry_return( e ); +- } +-} +- +-static int +-bdb_cache_entryinfo_destroy( EntryInfo *e ) +-{ +- ldap_pvt_thread_mutex_destroy( &e->bei_kids_mutex ); +- free( e->bei_nrdn.bv_val ); +-#ifdef BDB_HIER +- free( e->bei_rdn.bv_val ); +-#endif +- free( e ); +- return 0; +-} +- +-/* Do a length-ordered sort on normalized RDNs */ +-static int +-bdb_rdn_cmp( const void *v_e1, const void *v_e2 ) +-{ +- const EntryInfo *e1 = v_e1, *e2 = v_e2; +- int rc = e1->bei_nrdn.bv_len - e2->bei_nrdn.bv_len; +- if (rc == 0) { +- rc = strncmp( e1->bei_nrdn.bv_val, e2->bei_nrdn.bv_val, +- e1->bei_nrdn.bv_len ); +- } +- return rc; +-} +- +-static int +-bdb_id_cmp( const void *v_e1, const void *v_e2 ) +-{ +- const EntryInfo *e1 = v_e1, *e2 = v_e2; +- return e1->bei_id - e2->bei_id; +-} +- +-static int +-bdb_id_dup_err( void *v1, void *v2 ) +-{ +- EntryInfo *e2 = v2; +- e2->bei_lrunext = v1; +- return -1; +-} +- +-/* Create an entryinfo in the cache. Caller must release the locks later. +- */ +-static int +-bdb_entryinfo_add_internal( +- struct bdb_info *bdb, +- EntryInfo *ei, +- EntryInfo **res ) +-{ +- EntryInfo *ei2 = NULL; +- +- *res = NULL; +- +- ei2 = bdb_cache_entryinfo_new( &bdb->bi_cache ); +- +- bdb_cache_entryinfo_lock( ei->bei_parent ); +- ldap_pvt_thread_rdwr_wlock( &bdb->bi_cache.c_rwlock ); +- +- ei2->bei_id = ei->bei_id; +- ei2->bei_parent = ei->bei_parent; +-#ifdef BDB_HIER +- ei2->bei_rdn = ei->bei_rdn; +-#endif +-#ifdef SLAP_ZONE_ALLOC +- ei2->bei_bdb = bdb; +-#endif +- +- /* Add to cache ID tree */ +- if (avl_insert( &bdb->bi_cache.c_idtree, ei2, bdb_id_cmp, +- bdb_id_dup_err )) { +- EntryInfo *eix = ei2->bei_lrunext; +- bdb_cache_entryinfo_free( &bdb->bi_cache, ei2 ); +- ei2 = eix; +-#ifdef BDB_HIER +- /* It got freed above because its value was +- * assigned to ei2. +- */ +- ei->bei_rdn.bv_val = NULL; +-#endif +- } else { +- int rc; +- +- bdb->bi_cache.c_eiused++; +- ber_dupbv( &ei2->bei_nrdn, &ei->bei_nrdn ); +- +- /* This is a new leaf node. But if parent had no kids, then it was +- * a leaf and we would be decrementing that. So, only increment if +- * the parent already has kids. +- */ +- if ( ei->bei_parent->bei_kids || !ei->bei_parent->bei_id ) +- bdb->bi_cache.c_leaves++; +- rc = avl_insert( &ei->bei_parent->bei_kids, ei2, bdb_rdn_cmp, +- avl_dup_error ); +-#ifdef BDB_HIER +- /* it's possible for hdb_cache_find_parent to beat us to it */ +- if ( !rc ) { +- ei->bei_parent->bei_ckids++; +- } +-#endif +- } +- +- *res = ei2; +- return 0; +-} +- +-/* Find the EntryInfo for the requested DN. If the DN cannot be found, return +- * the info for its closest ancestor. *res should be NULL to process a +- * complete DN starting from the tree root. Otherwise *res must be the +- * immediate parent of the requested DN, and only the RDN will be searched. +- * The EntryInfo is locked upon return and must be unlocked by the caller. +- */ +-int +-bdb_cache_find_ndn( +- Operation *op, +- DB_TXN *txn, +- struct berval *ndn, +- EntryInfo **res ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- EntryInfo ei, *eip, *ei2; +- int rc = 0; +- char *ptr; +- +- /* this function is always called with normalized DN */ +- if ( *res ) { +- /* we're doing a onelevel search for an RDN */ +- ei.bei_nrdn.bv_val = ndn->bv_val; +- ei.bei_nrdn.bv_len = dn_rdnlen( op->o_bd, ndn ); +- eip = *res; +- } else { +- /* we're searching a full DN from the root */ +- ptr = ndn->bv_val + ndn->bv_len - op->o_bd->be_nsuffix[0].bv_len; +- ei.bei_nrdn.bv_val = ptr; +- ei.bei_nrdn.bv_len = op->o_bd->be_nsuffix[0].bv_len; +- /* Skip to next rdn if suffix is empty */ +- if ( ei.bei_nrdn.bv_len == 0 ) { +- for (ptr = ei.bei_nrdn.bv_val - 2; ptr > ndn->bv_val +- && !DN_SEPARATOR(*ptr); ptr--) /* empty */; +- if ( ptr >= ndn->bv_val ) { +- if (DN_SEPARATOR(*ptr)) ptr++; +- ei.bei_nrdn.bv_len = ei.bei_nrdn.bv_val - ptr; +- ei.bei_nrdn.bv_val = ptr; +- } +- } +- eip = &bdb->bi_cache.c_dntree; +- } +- +- for ( bdb_cache_entryinfo_lock( eip ); eip; ) { +- eip->bei_state |= CACHE_ENTRY_REFERENCED; +- ei.bei_parent = eip; +- ei2 = (EntryInfo *)avl_find( eip->bei_kids, &ei, bdb_rdn_cmp ); +- if ( !ei2 ) { +- DBC *cursor; +- int len = ei.bei_nrdn.bv_len; +- +- if ( BER_BVISEMPTY( ndn )) { +- *res = eip; +- return LDAP_SUCCESS; +- } +- +- ei.bei_nrdn.bv_len = ndn->bv_len - +- (ei.bei_nrdn.bv_val - ndn->bv_val); +- eip->bei_finders++; +- bdb_cache_entryinfo_unlock( eip ); +- +- BDB_LOG_PRINTF( bdb->bi_dbenv, NULL, "slapd Reading %s", +- ei.bei_nrdn.bv_val ); +- +- cursor = NULL; +- rc = bdb_dn2id( op, &ei.bei_nrdn, &ei, txn, &cursor ); +- if (rc) { +- bdb_cache_entryinfo_lock( eip ); +- eip->bei_finders--; +- if ( cursor ) cursor->c_close( cursor ); +- *res = eip; +- return rc; +- } +- +- BDB_LOG_PRINTF( bdb->bi_dbenv, NULL, "slapd Read got %s(%d)", +- ei.bei_nrdn.bv_val, ei.bei_id ); +- +- /* DN exists but needs to be added to cache */ +- ei.bei_nrdn.bv_len = len; +- rc = bdb_entryinfo_add_internal( bdb, &ei, &ei2 ); +- /* add_internal left eip and c_rwlock locked */ +- eip->bei_finders--; +- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock ); +- if ( cursor ) cursor->c_close( cursor ); +- if ( rc ) { +- *res = eip; +- return rc; +- } +- } +- bdb_cache_entryinfo_lock( ei2 ); +- if ( ei2->bei_state & CACHE_ENTRY_DELETED ) { +- /* In the midst of deleting? Give it a chance to +- * complete. +- */ +- bdb_cache_entryinfo_unlock( ei2 ); +- bdb_cache_entryinfo_unlock( eip ); +- ldap_pvt_thread_yield(); +- bdb_cache_entryinfo_lock( eip ); +- *res = eip; +- return DB_NOTFOUND; +- } +- bdb_cache_entryinfo_unlock( eip ); +- +- eip = ei2; +- +- /* Advance to next lower RDN */ +- for (ptr = ei.bei_nrdn.bv_val - 2; ptr > ndn->bv_val +- && !DN_SEPARATOR(*ptr); ptr--) /* empty */; +- if ( ptr >= ndn->bv_val ) { +- if (DN_SEPARATOR(*ptr)) ptr++; +- ei.bei_nrdn.bv_len = ei.bei_nrdn.bv_val - ptr - 1; +- ei.bei_nrdn.bv_val = ptr; +- } +- if ( ptr < ndn->bv_val ) { +- *res = eip; +- break; +- } +- } +- +- return rc; +-} +- +-#ifdef BDB_HIER +-/* Walk up the tree from a child node, looking for an ID that's already +- * been linked into the cache. +- */ +-int +-hdb_cache_find_parent( +- Operation *op, +- DB_TXN *txn, +- ID id, +- EntryInfo **res ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- EntryInfo ei, eip, *ei2 = NULL, *ein = NULL, *eir = NULL; +- int rc, add; +- +- ei.bei_id = id; +- ei.bei_kids = NULL; +- ei.bei_ckids = 0; +- +- for (;;) { +- rc = hdb_dn2id_parent( op, txn, &ei, &eip.bei_id ); +- if ( rc ) break; +- +- /* Save the previous node, if any */ +- ei2 = ein; +- +- /* Create a new node for the current ID */ +- ein = bdb_cache_entryinfo_new( &bdb->bi_cache ); +- ein->bei_id = ei.bei_id; +- ein->bei_kids = ei.bei_kids; +- ein->bei_nrdn = ei.bei_nrdn; +- ein->bei_rdn = ei.bei_rdn; +- ein->bei_ckids = ei.bei_ckids; +-#ifdef SLAP_ZONE_ALLOC +- ein->bei_bdb = bdb; +-#endif +- ei.bei_ckids = 0; +- add = 1; +- +- /* This node is not fully connected yet */ +- ein->bei_state |= CACHE_ENTRY_NOT_LINKED; +- +- /* If this is the first time, save this node +- * to be returned later. +- */ +- if ( eir == NULL ) { +- eir = ein; +- ein->bei_finders++; +- } +- +-again: +- /* Insert this node into the ID tree */ +- ldap_pvt_thread_rdwr_wlock( &bdb->bi_cache.c_rwlock ); +- if ( avl_insert( &bdb->bi_cache.c_idtree, (caddr_t)ein, +- bdb_id_cmp, bdb_id_dup_err ) ) { +- EntryInfo *eix = ein->bei_lrunext; +- +- if ( bdb_cache_entryinfo_trylock( eix )) { +- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock ); +- ldap_pvt_thread_yield(); +- goto again; +- } +- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock ); +- +- /* Someone else created this node just before us. +- * Free our new copy and use the existing one. +- */ +- bdb_cache_entryinfo_free( &bdb->bi_cache, ein ); +- +- /* if it was the node we were looking for, just return it */ +- if ( eir == ein ) { +- *res = eix; +- rc = 0; +- break; +- } +- +- ein = ei2; +- ei2 = eix; +- add = 0; +- +- /* otherwise, link up what we have and return */ +- goto gotparent; +- } +- +- /* If there was a previous node, link it to this one */ +- if ( ei2 ) ei2->bei_parent = ein; +- +- /* Look for this node's parent */ +-par2: +- if ( eip.bei_id ) { +- ei2 = (EntryInfo *) avl_find( bdb->bi_cache.c_idtree, +- (caddr_t) &eip, bdb_id_cmp ); +- } else { +- ei2 = &bdb->bi_cache.c_dntree; +- } +- if ( ei2 && bdb_cache_entryinfo_trylock( ei2 )) { +- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock ); +- ldap_pvt_thread_yield(); +- ldap_pvt_thread_rdwr_wlock( &bdb->bi_cache.c_rwlock ); +- goto par2; +- } +- if ( add ) +- bdb->bi_cache.c_eiused++; +- if ( ei2 && ( ei2->bei_kids || !ei2->bei_id )) +- bdb->bi_cache.c_leaves++; +- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock ); +- +-gotparent: +- /* Got the parent, link in and we're done. */ +- if ( ei2 ) { +- bdb_cache_entryinfo_lock( eir ); +- ein->bei_parent = ei2; +- +- if ( avl_insert( &ei2->bei_kids, (caddr_t)ein, bdb_rdn_cmp, +- avl_dup_error) == 0 ) +- ei2->bei_ckids++; +- +- /* Reset all the state info */ +- for (ein = eir; ein != ei2; ein=ein->bei_parent) +- ein->bei_state &= ~CACHE_ENTRY_NOT_LINKED; +- +- bdb_cache_entryinfo_unlock( ei2 ); +- eir->bei_finders--; +- +- *res = eir; +- break; +- } +- ei.bei_kids = NULL; +- ei.bei_id = eip.bei_id; +- ei.bei_ckids = 1; +- avl_insert( &ei.bei_kids, (caddr_t)ein, bdb_rdn_cmp, +- avl_dup_error ); +- } +- return rc; +-} +- +-/* Used by hdb_dn2idl when loading the EntryInfo for all the children +- * of a given node +- */ +-int hdb_cache_load( +- struct bdb_info *bdb, +- EntryInfo *ei, +- EntryInfo **res ) +-{ +- EntryInfo *ei2; +- int rc; +- +- /* See if we already have this one */ +- bdb_cache_entryinfo_lock( ei->bei_parent ); +- ei2 = (EntryInfo *)avl_find( ei->bei_parent->bei_kids, ei, bdb_rdn_cmp ); +- bdb_cache_entryinfo_unlock( ei->bei_parent ); +- +- if ( !ei2 ) { +- /* Not found, add it */ +- struct berval bv; +- +- /* bei_rdn was not malloc'd before, do it now */ +- ber_dupbv( &bv, &ei->bei_rdn ); +- ei->bei_rdn = bv; +- +- rc = bdb_entryinfo_add_internal( bdb, ei, res ); +- bdb_cache_entryinfo_unlock( ei->bei_parent ); +- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock ); +- } else { +- /* Found, return it */ +- *res = ei2; +- return 0; +- } +- return rc; +-} +-#endif +- +-/* This is best-effort only. If all entries in the cache are +- * busy, they will all be kept. This is unlikely to happen +- * unless the cache is very much smaller than the working set. +- */ +-static void +-bdb_cache_lru_purge( struct bdb_info *bdb ) +-{ +- DB_LOCK lock, *lockp; +- EntryInfo *elru, *elnext = NULL; +- int islocked; +- ID eicount, ecount; +- ID count, efree, eifree = 0; +-#ifdef LDAP_DEBUG +- int iter; +-#endif +- +- /* Wait for the mutex; we're the only one trying to purge. */ +- ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_lru_mutex ); +- +- if ( bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize ) { +- efree = bdb->bi_cache.c_cursize - bdb->bi_cache.c_maxsize; +- efree += bdb->bi_cache.c_minfree; +- } else { +- efree = 0; +- } +- +- /* maximum number of EntryInfo leaves to cache. In slapcat +- * we always free all leaf nodes. +- */ +- +- if ( slapMode & SLAP_TOOL_READONLY ) { +- eifree = bdb->bi_cache.c_leaves; +- } else if ( bdb->bi_cache.c_eimax && +- bdb->bi_cache.c_leaves > bdb->bi_cache.c_eimax ) { +- eifree = bdb->bi_cache.c_minfree * 10; +- if ( eifree >= bdb->bi_cache.c_leaves ) +- eifree /= 2; +- } +- +- if ( !efree && !eifree ) { +- ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_lru_mutex ); +- bdb->bi_cache.c_purging = 0; +- return; +- } +- +- if ( bdb->bi_cache.c_txn ) { +- lockp = &lock; +- } else { +- lockp = NULL; +- } +- +- count = 0; +- eicount = 0; +- ecount = 0; +-#ifdef LDAP_DEBUG +- iter = 0; +-#endif +- +- /* Look for an unused entry to remove */ +- for ( elru = bdb->bi_cache.c_lruhead; elru; elru = elnext ) { +- elnext = elru->bei_lrunext; +- +- if ( bdb_cache_entryinfo_trylock( elru )) +- goto bottom; +- +- /* This flag implements the clock replacement behavior */ +- if ( elru->bei_state & ( CACHE_ENTRY_REFERENCED )) { +- elru->bei_state &= ~CACHE_ENTRY_REFERENCED; +- bdb_cache_entryinfo_unlock( elru ); +- goto bottom; +- } +- +- /* If this node is in the process of linking into the cache, +- * or this node is being deleted, skip it. +- */ +- if (( elru->bei_state & ( CACHE_ENTRY_NOT_LINKED | +- CACHE_ENTRY_DELETED | CACHE_ENTRY_LOADING | +- CACHE_ENTRY_ONELEVEL )) || +- elru->bei_finders > 0 ) { +- bdb_cache_entryinfo_unlock( elru ); +- goto bottom; +- } +- +- if ( bdb_cache_entryinfo_trylock( elru->bei_parent )) { +- bdb_cache_entryinfo_unlock( elru ); +- goto bottom; +- } +- +- /* entryinfo is locked */ +- islocked = 1; +- +- /* If we can successfully writelock it, then +- * the object is idle. +- */ +- if ( bdb_cache_entry_db_lock( bdb, +- bdb->bi_cache.c_txn, elru, 1, 1, lockp ) == 0 ) { +- +- /* Free entry for this node if it's present */ +- if ( elru->bei_e ) { +- ecount++; +- +- /* the cache may have gone over the limit while we +- * weren't looking, so double check. +- */ +- if ( !efree && ecount > bdb->bi_cache.c_maxsize ) +- efree = bdb->bi_cache.c_minfree; +- +- if ( count < efree ) { +- elru->bei_e->e_private = NULL; +-#ifdef SLAP_ZONE_ALLOC +- bdb_entry_return( bdb, elru->bei_e, elru->bei_zseq ); +-#else +- bdb_entry_return( elru->bei_e ); +-#endif +- elru->bei_e = NULL; +- count++; +- } else { +- /* Keep this node cached, skip to next */ +- bdb_cache_entry_db_unlock( bdb, lockp ); +- goto next; +- } +- } +- bdb_cache_entry_db_unlock( bdb, lockp ); +- +- /* +- * If it is a leaf node, and we're over the limit, free it. +- */ +- if ( elru->bei_kids ) { +- /* Drop from list, we ignore it... */ +- LRU_DEL( &bdb->bi_cache, elru ); +- } else if ( eicount < eifree ) { +- /* Too many leaf nodes, free this one */ +- bdb_cache_delete_internal( &bdb->bi_cache, elru, 0 ); +- bdb_cache_delete_cleanup( &bdb->bi_cache, elru ); +- islocked = 0; +- eicount++; +- } /* Leave on list until we need to free it */ +- } +- +-next: +- if ( islocked ) { +- bdb_cache_entryinfo_unlock( elru ); +- bdb_cache_entryinfo_unlock( elru->bei_parent ); +- } +- +- if ( count >= efree && eicount >= eifree ) +- break; +-bottom: +- if ( elnext == bdb->bi_cache.c_lruhead ) +- break; +-#ifdef LDAP_DEBUG +- iter++; +-#endif +- } +- +- if ( count || ecount > bdb->bi_cache.c_cursize ) { +- ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_count_mutex ); +- /* HACK: we seem to be losing track, fix up now */ +- if ( ecount > bdb->bi_cache.c_cursize ) +- bdb->bi_cache.c_cursize = ecount; +- bdb->bi_cache.c_cursize -= count; +- ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex ); +- } +- bdb->bi_cache.c_lruhead = elnext; +- ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_lru_mutex ); +- bdb->bi_cache.c_purging = 0; +-} +- +-/* +- * cache_find_id - find an entry in the cache, given id. +- * The entry is locked for Read upon return. Call with flag ID_LOCKED if +- * the supplied *eip was already locked. +- */ +- +-int +-bdb_cache_find_id( +- Operation *op, +- DB_TXN *tid, +- ID id, +- EntryInfo **eip, +- int flag, +- DB_LOCK *lock ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- Entry *ep = NULL; +- int rc = 0, load = 0; +- EntryInfo ei = { 0 }; +- +- ei.bei_id = id; +- +-#ifdef SLAP_ZONE_ALLOC +- slap_zh_rlock(bdb->bi_cache.c_zctx); +-#endif +- /* If we weren't given any info, see if we have it already cached */ +- if ( !*eip ) { +-again: ldap_pvt_thread_rdwr_rlock( &bdb->bi_cache.c_rwlock ); +- *eip = (EntryInfo *) avl_find( bdb->bi_cache.c_idtree, +- (caddr_t) &ei, bdb_id_cmp ); +- if ( *eip ) { +- /* If the lock attempt fails, the info is in use */ +- if ( bdb_cache_entryinfo_trylock( *eip )) { +- int del = (*eip)->bei_state & CACHE_ENTRY_DELETED; +- ldap_pvt_thread_rdwr_runlock( &bdb->bi_cache.c_rwlock ); +- /* If this node is being deleted, treat +- * as if the delete has already finished +- */ +- if ( del ) { +- return DB_NOTFOUND; +- } +- /* otherwise, wait for the info to free up */ +- ldap_pvt_thread_yield(); +- goto again; +- } +- /* If this info isn't hooked up to its parent yet, +- * unlock and wait for it to be fully initialized +- */ +- if ( (*eip)->bei_state & CACHE_ENTRY_NOT_LINKED ) { +- bdb_cache_entryinfo_unlock( *eip ); +- ldap_pvt_thread_rdwr_runlock( &bdb->bi_cache.c_rwlock ); +- ldap_pvt_thread_yield(); +- goto again; +- } +- flag |= ID_LOCKED; +- } +- ldap_pvt_thread_rdwr_runlock( &bdb->bi_cache.c_rwlock ); +- } +- +- /* See if the ID exists in the database; add it to the cache if so */ +- if ( !*eip ) { +-#ifndef BDB_HIER +- rc = bdb_id2entry( op->o_bd, tid, id, &ep ); +- if ( rc == 0 ) { +- rc = bdb_cache_find_ndn( op, tid, +- &ep->e_nname, eip ); +- if ( *eip ) flag |= ID_LOCKED; +- if ( rc ) { +- ep->e_private = NULL; +-#ifdef SLAP_ZONE_ALLOC +- bdb_entry_return( bdb, ep, (*eip)->bei_zseq ); +-#else +- bdb_entry_return( ep ); +-#endif +- ep = NULL; +- } +- } +-#else +- rc = hdb_cache_find_parent(op, tid, id, eip ); +- if ( rc == 0 ) flag |= ID_LOCKED; +-#endif +- } +- +- /* Ok, we found the info, do we have the entry? */ +- if ( rc == 0 ) { +- if ( !( flag & ID_LOCKED )) { +- bdb_cache_entryinfo_lock( *eip ); +- flag |= ID_LOCKED; +- } +- +- if ( (*eip)->bei_state & CACHE_ENTRY_DELETED ) { +- rc = DB_NOTFOUND; +- } else { +- (*eip)->bei_finders++; +- (*eip)->bei_state |= CACHE_ENTRY_REFERENCED; +- if ( flag & ID_NOENTRY ) { +- bdb_cache_entryinfo_unlock( *eip ); +- return 0; +- } +- /* Make sure only one thread tries to load the entry */ +-load1: +-#ifdef SLAP_ZONE_ALLOC +- if ((*eip)->bei_e && !slap_zn_validate( +- bdb->bi_cache.c_zctx, (*eip)->bei_e, (*eip)->bei_zseq)) { +- (*eip)->bei_e = NULL; +- (*eip)->bei_zseq = 0; +- } +-#endif +- if ( !(*eip)->bei_e && !((*eip)->bei_state & CACHE_ENTRY_LOADING)) { +- load = 1; +- (*eip)->bei_state |= CACHE_ENTRY_LOADING; +- flag |= ID_CHKPURGE; +- } +- +- if ( !load ) { +- /* Clear the uncached state if we are not +- * loading it, i.e it is already cached or +- * another thread is currently loading it. +- */ +- if ( (*eip)->bei_state & CACHE_ENTRY_NOT_CACHED ) { +- (*eip)->bei_state ^= CACHE_ENTRY_NOT_CACHED; +- flag |= ID_CHKPURGE; +- } +- } +- +- if ( flag & ID_LOCKED ) { +- bdb_cache_entryinfo_unlock( *eip ); +- flag ^= ID_LOCKED; +- } +- rc = bdb_cache_entry_db_lock( bdb, tid, *eip, load, 0, lock ); +- if ( (*eip)->bei_state & CACHE_ENTRY_DELETED ) { +- rc = DB_NOTFOUND; +- bdb_cache_entry_db_unlock( bdb, lock ); +- bdb_cache_entryinfo_lock( *eip ); +- (*eip)->bei_finders--; +- bdb_cache_entryinfo_unlock( *eip ); +- } else if ( rc == 0 ) { +- if ( load ) { +- if ( !ep) { +- rc = bdb_id2entry( op->o_bd, tid, id, &ep ); +- } +- if ( rc == 0 ) { +- ep->e_private = *eip; +-#ifdef BDB_HIER +- while ( (*eip)->bei_state & CACHE_ENTRY_NOT_LINKED ) +- ldap_pvt_thread_yield(); +- bdb_fix_dn( ep, 0 ); +-#endif +- bdb_cache_entryinfo_lock( *eip ); +- +- (*eip)->bei_e = ep; +-#ifdef SLAP_ZONE_ALLOC +- (*eip)->bei_zseq = *((ber_len_t *)ep - 2); +-#endif +- ep = NULL; +- if ( flag & ID_NOCACHE ) { +- /* Set the cached state only if no other thread +- * found the info while we were loading the entry. +- */ +- if ( (*eip)->bei_finders == 1 ) { +- (*eip)->bei_state |= CACHE_ENTRY_NOT_CACHED; +- flag ^= ID_CHKPURGE; +- } +- } +- bdb_cache_entryinfo_unlock( *eip ); +- bdb_cache_lru_link( bdb, *eip ); +- } +- if ( rc == 0 ) { +- /* If we succeeded, downgrade back to a readlock. */ +- rc = bdb_cache_entry_db_relock( bdb, tid, +- *eip, 0, 0, lock ); +- } else { +- /* Otherwise, release the lock. */ +- bdb_cache_entry_db_unlock( bdb, lock ); +- } +- } else if ( !(*eip)->bei_e ) { +- /* Some other thread is trying to load the entry, +- * wait for it to finish. +- */ +- bdb_cache_entry_db_unlock( bdb, lock ); +- bdb_cache_entryinfo_lock( *eip ); +- flag |= ID_LOCKED; +- goto load1; +-#ifdef BDB_HIER +- } else { +- /* Check for subtree renames +- */ +- rc = bdb_fix_dn( (*eip)->bei_e, 1 ); +- if ( rc ) { +- bdb_cache_entry_db_relock( bdb, +- tid, *eip, 1, 0, lock ); +- /* check again in case other modifier did it already */ +- if ( bdb_fix_dn( (*eip)->bei_e, 1 ) ) +- rc = bdb_fix_dn( (*eip)->bei_e, 2 ); +- bdb_cache_entry_db_relock( bdb, +- tid, *eip, 0, 0, lock ); +- } +-#endif +- } +- bdb_cache_entryinfo_lock( *eip ); +- (*eip)->bei_finders--; +- if ( load ) +- (*eip)->bei_state ^= CACHE_ENTRY_LOADING; +- bdb_cache_entryinfo_unlock( *eip ); +- } +- } +- } +- if ( flag & ID_LOCKED ) { +- bdb_cache_entryinfo_unlock( *eip ); +- } +- if ( ep ) { +- ep->e_private = NULL; +-#ifdef SLAP_ZONE_ALLOC +- bdb_entry_return( bdb, ep, (*eip)->bei_zseq ); +-#else +- bdb_entry_return( ep ); +-#endif +- } +- if ( rc == 0 ) { +- int purge = 0; +- +- if (( flag & ID_CHKPURGE ) || bdb->bi_cache.c_eimax ) { +- ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_count_mutex ); +- if ( flag & ID_CHKPURGE ) { +- bdb->bi_cache.c_cursize++; +- if ( !bdb->bi_cache.c_purging && bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize ) { +- purge = 1; +- bdb->bi_cache.c_purging = 1; +- } +- } else if ( !bdb->bi_cache.c_purging && bdb->bi_cache.c_eimax && bdb->bi_cache.c_leaves > bdb->bi_cache.c_eimax ) { +- purge = 1; +- bdb->bi_cache.c_purging = 1; +- } +- ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex ); +- } +- if ( purge ) +- bdb_cache_lru_purge( bdb ); +- } +- +-#ifdef SLAP_ZONE_ALLOC +- if (rc == 0 && (*eip)->bei_e) { +- slap_zn_rlock(bdb->bi_cache.c_zctx, (*eip)->bei_e); +- } +- slap_zh_runlock(bdb->bi_cache.c_zctx); +-#endif +- return rc; +-} +- +-int +-bdb_cache_children( +- Operation *op, +- DB_TXN *txn, +- Entry *e ) +-{ +- int rc; +- +- if ( BEI(e)->bei_kids ) { +- return 0; +- } +- if ( BEI(e)->bei_state & CACHE_ENTRY_NO_KIDS ) { +- return DB_NOTFOUND; +- } +- rc = bdb_dn2id_children( op, txn, e ); +- if ( rc == DB_NOTFOUND ) { +- BEI(e)->bei_state |= CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS; +- } +- return rc; +-} +- +-/* Update the cache after a successful database Add. */ +-int +-bdb_cache_add( +- struct bdb_info *bdb, +- EntryInfo *eip, +- Entry *e, +- struct berval *nrdn, +- DB_TXN *txn, +- DB_LOCK *lock ) +-{ +- EntryInfo *new, ei; +- int rc, purge = 0; +-#ifdef BDB_HIER +- struct berval rdn = e->e_name; +-#endif +- +- ei.bei_id = e->e_id; +- ei.bei_parent = eip; +- ei.bei_nrdn = *nrdn; +- ei.bei_lockpad = 0; +- +-#if 0 +- /* Lock this entry so that bdb_add can run to completion. +- * It can only fail if BDB has run out of lock resources. +- */ +- rc = bdb_cache_entry_db_lock( bdb, txn, &ei, 0, 0, lock ); +- if ( rc ) { +- bdb_cache_entryinfo_unlock( eip ); +- return rc; +- } +-#endif +- +-#ifdef BDB_HIER +- if ( nrdn->bv_len != e->e_nname.bv_len ) { +- char *ptr = ber_bvchr( &rdn, ',' ); +- assert( ptr != NULL ); +- rdn.bv_len = ptr - rdn.bv_val; +- } +- ber_dupbv( &ei.bei_rdn, &rdn ); +- if ( eip->bei_dkids ) eip->bei_dkids++; +-#endif +- +- if (eip->bei_parent) { +- bdb_cache_entryinfo_lock( eip->bei_parent ); +- eip->bei_parent->bei_state &= ~CACHE_ENTRY_NO_GRANDKIDS; +- bdb_cache_entryinfo_unlock( eip->bei_parent ); +- } +- +- rc = bdb_entryinfo_add_internal( bdb, &ei, &new ); +- /* bdb_csn_commit can cause this when adding the database root entry */ +- if ( new->bei_e ) { +- new->bei_e->e_private = NULL; +-#ifdef SLAP_ZONE_ALLOC +- bdb_entry_return( bdb, new->bei_e, new->bei_zseq ); +-#else +- bdb_entry_return( new->bei_e ); +-#endif +- } +- new->bei_e = e; +- e->e_private = new; +- new->bei_state |= CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS; +- eip->bei_state &= ~CACHE_ENTRY_NO_KIDS; +- bdb_cache_entryinfo_unlock( eip ); +- +- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock ); +- ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_count_mutex ); +- ++bdb->bi_cache.c_cursize; +- if ( bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize && +- !bdb->bi_cache.c_purging ) { +- purge = 1; +- bdb->bi_cache.c_purging = 1; +- } +- ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex ); +- +- new->bei_finders = 1; +- bdb_cache_lru_link( bdb, new ); +- +- if ( purge ) +- bdb_cache_lru_purge( bdb ); +- +- return rc; +-} +- +-void bdb_cache_deref( +- EntryInfo *ei +- ) +-{ +- bdb_cache_entryinfo_lock( ei ); +- ei->bei_finders--; +- bdb_cache_entryinfo_unlock( ei ); +-} +- +-int +-bdb_cache_modify( +- struct bdb_info *bdb, +- Entry *e, +- Attribute *newAttrs, +- DB_TXN *txn, +- DB_LOCK *lock ) +-{ +- EntryInfo *ei = BEI(e); +- int rc; +- /* Get write lock on data */ +- rc = bdb_cache_entry_db_relock( bdb, txn, ei, 1, 0, lock ); +- +- /* If we've done repeated mods on a cached entry, then e_attrs +- * is no longer contiguous with the entry, and must be freed. +- */ +- if ( ! rc ) { +- if ( (void *)e->e_attrs != (void *)(e+1) ) { +- attrs_free( e->e_attrs ); +- } +- e->e_attrs = newAttrs; +- } +- return rc; +-} +- +-/* +- * Change the rdn in the entryinfo. Also move to a new parent if needed. +- */ +-int +-bdb_cache_modrdn( +- struct bdb_info *bdb, +- Entry *e, +- struct berval *nrdn, +- Entry *new, +- EntryInfo *ein, +- DB_TXN *txn, +- DB_LOCK *lock ) +-{ +- EntryInfo *ei = BEI(e), *pei; +- int rc; +-#ifdef BDB_HIER +- struct berval rdn; +-#endif +- +- /* Get write lock on data */ +- rc = bdb_cache_entry_db_relock( bdb, txn, ei, 1, 0, lock ); +- if ( rc ) return rc; +- +- /* If we've done repeated mods on a cached entry, then e_attrs +- * is no longer contiguous with the entry, and must be freed. +- */ +- if ( (void *)e->e_attrs != (void *)(e+1) ) { +- attrs_free( e->e_attrs ); +- } +- e->e_attrs = new->e_attrs; +- if( e->e_nname.bv_val < e->e_bv.bv_val || +- e->e_nname.bv_val > e->e_bv.bv_val + e->e_bv.bv_len ) +- { +- ch_free(e->e_name.bv_val); +- ch_free(e->e_nname.bv_val); +- } +- e->e_name = new->e_name; +- e->e_nname = new->e_nname; +- +- /* Lock the parent's kids AVL tree */ +- pei = ei->bei_parent; +- bdb_cache_entryinfo_lock( pei ); +- avl_delete( &pei->bei_kids, (caddr_t) ei, bdb_rdn_cmp ); +- free( ei->bei_nrdn.bv_val ); +- ber_dupbv( &ei->bei_nrdn, nrdn ); +- +-#ifdef BDB_HIER +- free( ei->bei_rdn.bv_val ); +- +- rdn = e->e_name; +- if ( nrdn->bv_len != e->e_nname.bv_len ) { +- char *ptr = ber_bvchr(&rdn, ','); +- assert( ptr != NULL ); +- rdn.bv_len = ptr - rdn.bv_val; +- } +- ber_dupbv( &ei->bei_rdn, &rdn ); +- +- /* If new parent, decrement kid counts */ +- if ( ein ) { +- pei->bei_ckids--; +- if ( pei->bei_dkids ) { +- pei->bei_dkids--; +- if ( pei->bei_dkids < 2 ) +- pei->bei_state |= CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS; +- } +- } +-#endif +- +- if (!ein) { +- ein = ei->bei_parent; +- } else { +- ei->bei_parent = ein; +- bdb_cache_entryinfo_unlock( pei ); +- bdb_cache_entryinfo_lock( ein ); +- +- /* new parent now has kids */ +- if ( ein->bei_state & CACHE_ENTRY_NO_KIDS ) +- ein->bei_state ^= CACHE_ENTRY_NO_KIDS; +- /* grandparent has grandkids */ +- if ( ein->bei_parent ) +- ein->bei_parent->bei_state &= ~CACHE_ENTRY_NO_GRANDKIDS; +-#ifdef BDB_HIER +- /* parent might now have grandkids */ +- if ( ein->bei_state & CACHE_ENTRY_NO_GRANDKIDS && +- !(ei->bei_state & CACHE_ENTRY_NO_KIDS)) +- ein->bei_state ^= CACHE_ENTRY_NO_GRANDKIDS; +- +- ein->bei_ckids++; +- if ( ein->bei_dkids ) ein->bei_dkids++; +-#endif +- } +- +-#ifdef BDB_HIER +- /* Record the generation number of this change */ +- ldap_pvt_thread_mutex_lock( &bdb->bi_modrdns_mutex ); +- bdb->bi_modrdns++; +- ei->bei_modrdns = bdb->bi_modrdns; +- ldap_pvt_thread_mutex_unlock( &bdb->bi_modrdns_mutex ); +-#endif +- +- avl_insert( &ein->bei_kids, ei, bdb_rdn_cmp, avl_dup_error ); +- bdb_cache_entryinfo_unlock( ein ); +- return rc; +-} +-/* +- * cache_delete - delete the entry e from the cache. +- * +- * returns: 0 e was deleted ok +- * 1 e was not in the cache +- * -1 something bad happened +- */ +-int +-bdb_cache_delete( +- struct bdb_info *bdb, +- Entry *e, +- DB_TXN *txn, +- DB_LOCK *lock ) +-{ +- EntryInfo *ei = BEI(e); +- int rc, busy = 0, counter = 0; +- +- assert( e->e_private != NULL ); +- +- /* Lock the entry's info */ +- bdb_cache_entryinfo_lock( ei ); +- +- /* Set this early, warn off any queriers */ +- ei->bei_state |= CACHE_ENTRY_DELETED; +- +- if (( ei->bei_state & ( CACHE_ENTRY_NOT_LINKED | +- CACHE_ENTRY_LOADING | CACHE_ENTRY_ONELEVEL )) || +- ei->bei_finders > 0 ) +- busy = 1; +- +- bdb_cache_entryinfo_unlock( ei ); +- +- while ( busy && counter < 1000) { +- ldap_pvt_thread_yield(); +- busy = 0; +- bdb_cache_entryinfo_lock( ei ); +- if (( ei->bei_state & ( CACHE_ENTRY_NOT_LINKED | +- CACHE_ENTRY_LOADING | CACHE_ENTRY_ONELEVEL )) || +- ei->bei_finders > 0 ) +- busy = 1; +- bdb_cache_entryinfo_unlock( ei ); +- counter ++; +- } +- if( busy ) { +- bdb_cache_entryinfo_lock( ei ); +- ei->bei_state ^= CACHE_ENTRY_DELETED; +- bdb_cache_entryinfo_unlock( ei ); +- return DB_LOCK_DEADLOCK; +- } +- +- /* Get write lock on the data */ +- rc = bdb_cache_entry_db_relock( bdb, txn, ei, 1, 0, lock ); +- if ( rc ) { +- bdb_cache_entryinfo_lock( ei ); +- /* couldn't lock, undo and give up */ +- ei->bei_state ^= CACHE_ENTRY_DELETED; +- bdb_cache_entryinfo_unlock( ei ); +- return rc; +- } +- +- Debug( LDAP_DEBUG_TRACE, "====> bdb_cache_delete( %ld )\n", +- e->e_id, 0, 0 ); +- +- /* set lru mutex */ +- ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_lru_mutex ); +- +- bdb_cache_entryinfo_lock( ei->bei_parent ); +- bdb_cache_entryinfo_lock( ei ); +- rc = bdb_cache_delete_internal( &bdb->bi_cache, e->e_private, 1 ); +- bdb_cache_entryinfo_unlock( ei ); +- +- /* free lru mutex */ +- ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_lru_mutex ); +- +- return( rc ); +-} +- +-void +-bdb_cache_delete_cleanup( +- Cache *cache, +- EntryInfo *ei ) +-{ +- /* Enter with ei locked */ +- +- /* already freed? */ +- if ( !ei->bei_parent ) return; +- +- if ( ei->bei_e ) { +- ei->bei_e->e_private = NULL; +-#ifdef SLAP_ZONE_ALLOC +- bdb_entry_return( ei->bei_bdb, ei->bei_e, ei->bei_zseq ); +-#else +- bdb_entry_return( ei->bei_e ); +-#endif +- ei->bei_e = NULL; +- } +- +- bdb_cache_entryinfo_unlock( ei ); +- bdb_cache_entryinfo_free( cache, ei ); +-} +- +-static int +-bdb_cache_delete_internal( +- Cache *cache, +- EntryInfo *e, +- int decr ) +-{ +- int rc = 0; /* return code */ +- int decr_leaf = 0; +- +- /* already freed? */ +- if ( !e->bei_parent ) { +- assert(0); +- return -1; +- } +- +-#ifdef BDB_HIER +- e->bei_parent->bei_ckids--; +- if ( decr && e->bei_parent->bei_dkids ) e->bei_parent->bei_dkids--; +-#endif +- /* dn tree */ +- if ( avl_delete( &e->bei_parent->bei_kids, (caddr_t) e, bdb_rdn_cmp ) +- == NULL ) +- { +- rc = -1; +- assert(0); +- } +- if ( e->bei_parent->bei_kids ) +- decr_leaf = 1; +- +- ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock ); +- /* id tree */ +- if ( avl_delete( &cache->c_idtree, (caddr_t) e, bdb_id_cmp )) { +- cache->c_eiused--; +- if ( decr_leaf ) +- cache->c_leaves--; +- } else { +- rc = -1; +- assert(0); +- } +- ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock ); +- bdb_cache_entryinfo_unlock( e->bei_parent ); +- +- if ( rc == 0 ){ +- /* lru */ +- LRU_DEL( cache, e ); +- +- if ( e->bei_e ) { +- ldap_pvt_thread_mutex_lock( &cache->c_count_mutex ); +- cache->c_cursize--; +- ldap_pvt_thread_mutex_unlock( &cache->c_count_mutex ); +- } +- } +- +- return( rc ); +-} +- +-static void +-bdb_entryinfo_release( void *data ) +-{ +- EntryInfo *ei = (EntryInfo *)data; +- if ( ei->bei_kids ) { +- avl_free( ei->bei_kids, NULL ); +- } +- if ( ei->bei_e ) { +- ei->bei_e->e_private = NULL; +-#ifdef SLAP_ZONE_ALLOC +- bdb_entry_return( ei->bei_bdb, ei->bei_e, ei->bei_zseq ); +-#else +- bdb_entry_return( ei->bei_e ); +-#endif +- } +- bdb_cache_entryinfo_destroy( ei ); +-} +- +-void +-bdb_cache_release_all( Cache *cache ) +-{ +- /* set cache write lock */ +- ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock ); +- /* set lru mutex */ +- ldap_pvt_thread_mutex_lock( &cache->c_lru_mutex ); +- +- Debug( LDAP_DEBUG_TRACE, "====> bdb_cache_release_all\n", 0, 0, 0 ); +- +- avl_free( cache->c_dntree.bei_kids, NULL ); +- avl_free( cache->c_idtree, bdb_entryinfo_release ); +- for (;cache->c_eifree;cache->c_eifree = cache->c_lruhead) { +- cache->c_lruhead = cache->c_eifree->bei_lrunext; +- bdb_cache_entryinfo_destroy(cache->c_eifree); +- } +- cache->c_cursize = 0; +- cache->c_eiused = 0; +- cache->c_leaves = 0; +- cache->c_idtree = NULL; +- cache->c_lruhead = NULL; +- cache->c_lrutail = NULL; +- cache->c_dntree.bei_kids = NULL; +- +- /* free lru mutex */ +- ldap_pvt_thread_mutex_unlock( &cache->c_lru_mutex ); +- /* free cache write lock */ +- ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock ); +-} +- +-#ifdef LDAP_DEBUG +-static void +-bdb_lru_count( Cache *cache ) +-{ +- EntryInfo *e; +- int ei = 0, ent = 0, nc = 0; +- +- for ( e = cache->c_lrutail; ; ) { +- ei++; +- if ( e->bei_e ) { +- ent++; +- if ( e->bei_state & CACHE_ENTRY_NOT_CACHED ) +- nc++; +- fprintf( stderr, "ei %d entry %p dn %s\n", ei, (void *) e->bei_e, e->bei_e->e_name.bv_val ); +- } +- e = e->bei_lrunext; +- if ( e == cache->c_lrutail ) +- break; +- } +- fprintf( stderr, "counted %d entryInfos and %d entries, %d notcached\n", +- ei, ent, nc ); +- ei = 0; +- for ( e = cache->c_lrutail; ; ) { +- ei++; +- e = e->bei_lruprev; +- if ( e == cache->c_lrutail ) +- break; +- } +- fprintf( stderr, "counted %d entryInfos (on lruprev)\n", ei ); +-} +- +-#ifdef SLAPD_UNUSED +-static void +-bdb_lru_print( Cache *cache ) +-{ +- EntryInfo *e; +- +- fprintf( stderr, "LRU circle head: %p\n", (void *) cache->c_lruhead ); +- fprintf( stderr, "LRU circle (tail forward):\n" ); +- for ( e = cache->c_lrutail; ; ) { +- fprintf( stderr, "\t%p, %p id %ld rdn \"%s\"\n", +- (void *) e, (void *) e->bei_e, e->bei_id, e->bei_nrdn.bv_val ); +- e = e->bei_lrunext; +- if ( e == cache->c_lrutail ) +- break; +- } +- fprintf( stderr, "LRU circle (tail backward):\n" ); +- for ( e = cache->c_lrutail; ; ) { +- fprintf( stderr, "\t%p, %p id %ld rdn \"%s\"\n", +- (void *) e, (void *) e->bei_e, e->bei_id, e->bei_nrdn.bv_val ); +- e = e->bei_lruprev; +- if ( e == cache->c_lrutail ) +- break; +- } +-} +- +-static int +-bdb_entryinfo_print(void *data, void *arg) +-{ +- EntryInfo *e = data; +- fprintf( stderr, "\t%p, %p id %ld rdn \"%s\"\n", +- (void *) e, (void *) e->bei_e, e->bei_id, e->bei_nrdn.bv_val ); +- return 0; +-} +- +-static void +-bdb_idtree_print(Cache *cache) +-{ +- avl_apply( cache->c_idtree, bdb_entryinfo_print, NULL, -1, AVL_INORDER ); +-} +-#endif +-#endif +- +-static void +-bdb_reader_free( void *key, void *data ) +-{ +- /* DB_ENV *env = key; */ +- DB_TXN *txn = data; +- +- if ( txn ) TXN_ABORT( txn ); +-} +- +-/* free up any keys used by the main thread */ +-void +-bdb_reader_flush( DB_ENV *env ) +-{ +- void *data; +- void *ctx = ldap_pvt_thread_pool_context(); +- +- if ( !ldap_pvt_thread_pool_getkey( ctx, env, &data, NULL ) ) { +- ldap_pvt_thread_pool_setkey( ctx, env, NULL, 0, NULL, NULL ); +- bdb_reader_free( env, data ); +- } +-} +- +-int +-bdb_reader_get( Operation *op, DB_ENV *env, DB_TXN **txn ) +-{ +- int i, rc; +- void *data; +- void *ctx; +- +- if ( !env || !txn ) return -1; +- +- /* If no op was provided, try to find the ctx anyway... */ +- if ( op ) { +- ctx = op->o_threadctx; +- } else { +- ctx = ldap_pvt_thread_pool_context(); +- } +- +- /* Shouldn't happen unless we're single-threaded */ +- if ( !ctx ) { +- *txn = NULL; +- return 0; +- } +- +- if ( ldap_pvt_thread_pool_getkey( ctx, env, &data, NULL ) ) { +- for ( i=0, rc=1; rc != 0 && i<4; i++ ) { +- rc = TXN_BEGIN( env, NULL, txn, DB_READ_COMMITTED ); +- if (rc) ldap_pvt_thread_yield(); +- } +- if ( rc != 0) { +- return rc; +- } +- data = *txn; +- if ( ( rc = ldap_pvt_thread_pool_setkey( ctx, env, +- data, bdb_reader_free, NULL, NULL ) ) ) { +- TXN_ABORT( *txn ); +- Debug( LDAP_DEBUG_ANY, "bdb_reader_get: err %s(%d)\n", +- db_strerror(rc), rc, 0 ); +- +- return rc; +- } +- } else { +- *txn = data; +- } +- return 0; +-} +diff --git a/servers/slapd/back-bdb/compare.c b/servers/slapd/back-bdb/compare.c +deleted file mode 100644 +index 4d7d45f..0000000 +--- a/servers/slapd/back-bdb/compare.c ++++ /dev/null +@@ -1,143 +0,0 @@ +-/* compare.c - bdb backend compare routine */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +-#include +- +-#include "back-bdb.h" +- +-int +-bdb_compare( Operation *op, SlapReply *rs ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- Entry *e = NULL; +- EntryInfo *ei; +- int manageDSAit = get_manageDSAit( op ); +- +- DB_TXN *rtxn; +- DB_LOCK lock; +- +- rs->sr_err = bdb_reader_get(op, bdb->bi_dbenv, &rtxn); +- switch(rs->sr_err) { +- case 0: +- break; +- default: +- send_ldap_error( op, rs, LDAP_OTHER, "internal error" ); +- return rs->sr_err; +- } +- +-dn2entry_retry: +- /* get entry */ +- rs->sr_err = bdb_dn2entry( op, rtxn, &op->o_req_ndn, &ei, 1, +- &lock ); +- +- switch( rs->sr_err ) { +- case DB_NOTFOUND: +- case 0: +- break; +- case LDAP_BUSY: +- rs->sr_text = "ldap server busy"; +- goto return_results; +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto dn2entry_retry; +- default: +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- +- e = ei->bei_e; +- if ( rs->sr_err == DB_NOTFOUND ) { +- if ( e != NULL ) { +- /* return referral only if "disclose" is granted on the object */ +- if ( ! access_allowed( op, e, slap_schema.si_ad_entry, +- NULL, ACL_DISCLOSE, NULL ) ) +- { +- rs->sr_err = LDAP_NO_SUCH_OBJECT; +- +- } else { +- rs->sr_matched = ch_strdup( e->e_dn ); +- rs->sr_ref = is_entry_referral( e ) +- ? get_entry_referrals( op, e ) +- : NULL; +- rs->sr_err = LDAP_REFERRAL; +- } +- +- bdb_cache_return_entry_r( bdb, e, &lock ); +- e = NULL; +- +- } else { +- rs->sr_ref = referral_rewrite( default_referral, +- NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); +- rs->sr_err = rs->sr_ref ? LDAP_REFERRAL : LDAP_NO_SUCH_OBJECT; +- } +- +- send_ldap_result( op, rs ); +- +- ber_bvarray_free( rs->sr_ref ); +- free( (char *)rs->sr_matched ); +- rs->sr_ref = NULL; +- rs->sr_matched = NULL; +- +- goto done; +- } +- +- if (!manageDSAit && is_entry_referral( e ) ) { +- /* return referral only if "disclose" is granted on the object */ +- if ( !access_allowed( op, e, slap_schema.si_ad_entry, +- NULL, ACL_DISCLOSE, NULL ) ) +- { +- rs->sr_err = LDAP_NO_SUCH_OBJECT; +- } else { +- /* entry is a referral, don't allow compare */ +- rs->sr_ref = get_entry_referrals( op, e ); +- rs->sr_err = LDAP_REFERRAL; +- rs->sr_matched = e->e_name.bv_val; +- } +- +- Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0, 0, 0 ); +- +- send_ldap_result( op, rs ); +- +- ber_bvarray_free( rs->sr_ref ); +- rs->sr_ref = NULL; +- rs->sr_matched = NULL; +- goto done; +- } +- +- rs->sr_err = slap_compare_entry( op, e, op->orc_ava ); +- +-return_results: +- send_ldap_result( op, rs ); +- +- switch ( rs->sr_err ) { +- case LDAP_COMPARE_FALSE: +- case LDAP_COMPARE_TRUE: +- rs->sr_err = LDAP_SUCCESS; +- break; +- } +- +-done: +- /* free entry */ +- if ( e != NULL ) { +- bdb_cache_return_entry_r( bdb, e, &lock ); +- } +- +- return rs->sr_err; +-} +diff --git a/servers/slapd/back-bdb/config.c b/servers/slapd/back-bdb/config.c +deleted file mode 100644 +index c3c8315..0000000 +--- a/servers/slapd/back-bdb/config.c ++++ /dev/null +@@ -1,951 +0,0 @@ +-/* config.c - bdb backend configuration file routine */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +-#include +-#include +-#include +- +-#include "back-bdb.h" +- +-#include "config.h" +- +-#include "lutil.h" +-#include "ldap_rq.h" +- +-#ifdef DB_DIRTY_READ +-# define SLAP_BDB_ALLOW_DIRTY_READ +-#endif +- +-#define bdb_cf_gen BDB_SYMBOL(cf_gen) +-#define bdb_cf_cleanup BDB_SYMBOL(cf_cleanup) +-#define bdb_checkpoint BDB_SYMBOL(checkpoint) +-#define bdb_online_index BDB_SYMBOL(online_index) +- +-static ConfigDriver bdb_cf_gen; +- +-enum { +- BDB_CHKPT = 1, +- BDB_CONFIG, +- BDB_CRYPTFILE, +- BDB_CRYPTKEY, +- BDB_DIRECTORY, +- BDB_NOSYNC, +- BDB_DIRTYR, +- BDB_INDEX, +- BDB_LOCKD, +- BDB_SSTACK, +- BDB_MODE, +- BDB_PGSIZE, +- BDB_CHECKSUM +-}; +- +-static ConfigTable bdbcfg[] = { +- { "directory", "dir", 2, 2, 0, ARG_STRING|ARG_MAGIC|BDB_DIRECTORY, +- bdb_cf_gen, "( OLcfgDbAt:0.1 NAME 'olcDbDirectory' " +- "DESC 'Directory for database content' " +- "EQUALITY caseIgnoreMatch " +- "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, +- { "cachefree", "size", 2, 2, 0, ARG_ULONG|ARG_OFFSET, +- (void *)offsetof(struct bdb_info, bi_cache.c_minfree), +- "( OLcfgDbAt:1.11 NAME 'olcDbCacheFree' " +- "DESC 'Number of extra entries to free when max is reached' " +- "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, +- { "cachesize", "size", 2, 2, 0, ARG_ULONG|ARG_OFFSET, +- (void *)offsetof(struct bdb_info, bi_cache.c_maxsize), +- "( OLcfgDbAt:1.1 NAME 'olcDbCacheSize' " +- "DESC 'Entry cache size in entries' " +- "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, +- { "checkpoint", "kbyte> <[pres,eq,approx,sub]", 2, 3, 0, ARG_MAGIC|BDB_INDEX, +- bdb_cf_gen, "( OLcfgDbAt:0.2 NAME 'olcDbIndex' " +- "DESC 'Attribute index parameters' " +- "EQUALITY caseIgnoreMatch " +- "SYNTAX OMsDirectoryString )", NULL, NULL }, +- { "linearindex", NULL, 1, 2, 0, ARG_ON_OFF|ARG_OFFSET, +- (void *)offsetof(struct bdb_info, bi_linear_index), +- "( OLcfgDbAt:1.7 NAME 'olcDbLinearIndex' " +- "DESC 'Index attributes one at a time' " +- "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL }, +- { "lockdetect", "policy", 2, 2, 0, ARG_MAGIC|BDB_LOCKD, +- bdb_cf_gen, "( OLcfgDbAt:1.8 NAME 'olcDbLockDetect' " +- "DESC 'Deadlock detection algorithm' " +- "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, +- { "mode", "mode", 2, 2, 0, ARG_MAGIC|BDB_MODE, +- bdb_cf_gen, "( OLcfgDbAt:0.3 NAME 'olcDbMode' " +- "DESC 'Unix permissions of database files' " +- "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, +- { "searchstack", "depth", 2, 2, 0, ARG_INT|ARG_MAGIC|BDB_SSTACK, +- bdb_cf_gen, "( OLcfgDbAt:1.9 NAME 'olcDbSearchStack' " +- "DESC 'Depth of search stack in IDLs' " +- "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, +- { "shm_key", "key", 2, 2, 0, ARG_LONG|ARG_OFFSET, +- (void *)offsetof(struct bdb_info, bi_shm_key), +- "( OLcfgDbAt:1.10 NAME 'olcDbShmKey' " +- "DESC 'Key for shared memory region' " +- "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, +- { NULL, NULL, 0, 0, 0, ARG_IGNORED, +- NULL, NULL, NULL, NULL } +-}; +- +-static ConfigOCs bdbocs[] = { +- { +-#ifdef BDB_HIER +- "( OLcfgDbOc:1.2 " +- "NAME 'olcHdbConfig' " +- "DESC 'HDB backend configuration' " +-#else +- "( OLcfgDbOc:1.1 " +- "NAME 'olcBdbConfig' " +- "DESC 'BDB backend configuration' " +-#endif +- "SUP olcDatabaseConfig " +- "MUST olcDbDirectory " +- "MAY ( olcDbCacheSize $ olcDbCheckpoint $ olcDbChecksum $ " +- "olcDbConfig $ olcDbCryptFile $ olcDbCryptKey $ " +- "olcDbNoSync $ olcDbDirtyRead $ olcDbIDLcacheSize $ " +- "olcDbIndex $ olcDbLinearIndex $ olcDbLockDetect $ " +- "olcDbMode $ olcDbSearchStack $ olcDbShmKey $ " +- "olcDbCacheFree $ olcDbDNcacheSize $ olcDbPageSize ) )", +- Cft_Database, bdbcfg }, +- { NULL, 0, NULL } +-}; +- +-static slap_verbmasks bdb_lockd[] = { +- { BER_BVC("default"), DB_LOCK_DEFAULT }, +- { BER_BVC("oldest"), DB_LOCK_OLDEST }, +- { BER_BVC("random"), DB_LOCK_RANDOM }, +- { BER_BVC("youngest"), DB_LOCK_YOUNGEST }, +- { BER_BVC("fewest"), DB_LOCK_MINLOCKS }, +- { BER_BVNULL, 0 } +-}; +- +-/* perform periodic checkpoints */ +-static void * +-bdb_checkpoint( void *ctx, void *arg ) +-{ +- struct re_s *rtask = arg; +- struct bdb_info *bdb = rtask->arg; +- +- TXN_CHECKPOINT( bdb->bi_dbenv, bdb->bi_txn_cp_kbyte, +- bdb->bi_txn_cp_min, 0 ); +- ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); +- ldap_pvt_runqueue_stoptask( &slapd_rq, rtask ); +- ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); +- return NULL; +-} +- +-/* reindex entries on the fly */ +-static void * +-bdb_online_index( void *ctx, void *arg ) +-{ +- struct re_s *rtask = arg; +- BackendDB *be = rtask->arg; +- struct bdb_info *bdb = be->be_private; +- +- Connection conn = {0}; +- OperationBuffer opbuf; +- Operation *op; +- +- DBC *curs; +- DBT key, data; +- DB_TXN *txn; +- DB_LOCK lock; +- ID id, nid; +- EntryInfo *ei; +- int rc, getnext = 1; +- int i; +- +- connection_fake_init( &conn, &opbuf, ctx ); +- op = &opbuf.ob_op; +- +- op->o_bd = be; +- +- DBTzero( &key ); +- DBTzero( &data ); +- +- id = 1; +- key.data = &nid; +- key.size = key.ulen = sizeof(ID); +- key.flags = DB_DBT_USERMEM; +- +- data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; +- data.dlen = data.ulen = 0; +- +- while ( 1 ) { +- if ( slapd_shutdown ) +- break; +- +- rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &txn, bdb->bi_db_opflags ); +- if ( rc ) +- break; +- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_online_index) ": txn id: %x\n", +- txn->id(txn), 0, 0 ); +- if ( getnext ) { +- getnext = 0; +- BDB_ID2DISK( id, &nid ); +- rc = bdb->bi_id2entry->bdi_db->cursor( +- bdb->bi_id2entry->bdi_db, txn, &curs, bdb->bi_db_opflags ); +- if ( rc ) { +- TXN_ABORT( txn ); +- break; +- } +- rc = curs->c_get( curs, &key, &data, DB_SET_RANGE ); +- curs->c_close( curs ); +- if ( rc ) { +- TXN_ABORT( txn ); +- if ( rc == DB_NOTFOUND ) +- rc = 0; +- if ( rc == DB_LOCK_DEADLOCK ) { +- ldap_pvt_thread_yield(); +- continue; +- } +- break; +- } +- BDB_DISK2ID( &nid, &id ); +- } +- +- ei = NULL; +- rc = bdb_cache_find_id( op, txn, id, &ei, 0, &lock ); +- if ( rc ) { +- TXN_ABORT( txn ); +- if ( rc == DB_LOCK_DEADLOCK ) { +- ldap_pvt_thread_yield(); +- continue; +- } +- if ( rc == DB_NOTFOUND ) { +- id++; +- getnext = 1; +- continue; +- } +- break; +- } +- if ( ei->bei_e ) { +- rc = bdb_index_entry( op, txn, BDB_INDEX_UPDATE_OP, ei->bei_e ); +- if ( rc ) { +- TXN_ABORT( txn ); +- if ( rc == DB_LOCK_DEADLOCK ) { +- ldap_pvt_thread_yield(); +- continue; +- } +- break; +- } +- rc = TXN_COMMIT( txn, 0 ); +- txn = NULL; +- } +- id++; +- getnext = 1; +- } +- +- for ( i = 0; i < bdb->bi_nattrs; i++ ) { +- if ( bdb->bi_attrs[ i ]->ai_indexmask & BDB_INDEX_DELETING +- || bdb->bi_attrs[ i ]->ai_newmask == 0 ) +- { +- continue; +- } +- bdb->bi_attrs[ i ]->ai_indexmask = bdb->bi_attrs[ i ]->ai_newmask; +- bdb->bi_attrs[ i ]->ai_newmask = 0; +- } +- +- ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); +- ldap_pvt_runqueue_stoptask( &slapd_rq, rtask ); +- bdb->bi_index_task = NULL; +- ldap_pvt_runqueue_remove( &slapd_rq, rtask ); +- ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); +- +- return NULL; +-} +- +-/* Cleanup loose ends after Modify completes */ +-static int +-bdb_cf_cleanup( ConfigArgs *c ) +-{ +- struct bdb_info *bdb = c->be->be_private; +- int rc = 0; +- BerVarray bva; +- +- if ( bdb->bi_flags & BDB_DEL_INDEX ) { +- bdb_attr_flush( bdb ); +- bdb->bi_flags ^= BDB_DEL_INDEX; +- } +- +- if ( bdb->bi_flags & BDB_RE_OPEN ) { +- bdb->bi_flags ^= BDB_RE_OPEN; +- bva = bdb->bi_db_config; +- bdb->bi_db_config = NULL; +- rc = c->be->bd_info->bi_db_close( c->be, &c->reply ); +- if ( rc == 0 ) { +- if ( bdb->bi_flags & BDB_UPD_CONFIG ) { +- if ( bva ) { +- int i; +- FILE *f = fopen( bdb->bi_db_config_path, "w" ); +- if ( f ) { +- bdb->bi_db_config = bva; +- bva = NULL; +- for (i=0; bdb->bi_db_config[i].bv_val; i++) +- fprintf( f, "%s\n", bdb->bi_db_config[i].bv_val ); +- fclose( f ); +- } else { +- ber_bvarray_free( bva ); +- } +- } else { +- unlink( bdb->bi_db_config_path ); +- } +- bdb->bi_flags ^= BDB_UPD_CONFIG; +- } +- rc = c->be->bd_info->bi_db_open( c->be, &c->reply ); +- } +- /* If this fails, we need to restart */ +- if ( rc ) { +- slapd_shutdown = 2; +- snprintf( c->cr_msg, sizeof( c->cr_msg ), +- "failed to reopen database, rc=%d", rc ); +- Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_cf_cleanup) +- ": %s\n", c->cr_msg, 0, 0 ); +- rc = LDAP_OTHER; +- } +- } +- return rc; +-} +- +-static int +-bdb_cf_gen( ConfigArgs *c ) +-{ +- struct bdb_info *bdb = c->be->be_private; +- int rc; +- +- if ( c->op == SLAP_CONFIG_EMIT ) { +- rc = 0; +- switch( c->type ) { +- case BDB_MODE: { +- char buf[64]; +- struct berval bv; +- bv.bv_len = snprintf( buf, sizeof(buf), "0%o", bdb->bi_dbenv_mode ); +- if ( bv.bv_len > 0 && bv.bv_len < sizeof(buf) ) { +- bv.bv_val = buf; +- value_add_one( &c->rvalue_vals, &bv ); +- } else { +- rc = 1; +- } +- } break; +- +- case BDB_CHKPT: +- if ( bdb->bi_txn_cp ) { +- char buf[64]; +- struct berval bv; +- bv.bv_len = snprintf( buf, sizeof(buf), "%ld %ld", +- (long) bdb->bi_txn_cp_kbyte, (long) bdb->bi_txn_cp_min ); +- if ( bv.bv_len > 0 && bv.bv_len < sizeof(buf) ) { +- bv.bv_val = buf; +- value_add_one( &c->rvalue_vals, &bv ); +- } else { +- rc = 1; +- } +- } else { +- rc = 1; +- } +- break; +- +- case BDB_CRYPTFILE: +- if ( bdb->bi_db_crypt_file ) { +- c->value_string = ch_strdup( bdb->bi_db_crypt_file ); +- } else { +- rc = 1; +- } +- break; +- +- /* If a crypt file has been set, its contents are copied here. +- * But we don't want the key to be incorporated here. +- */ +- case BDB_CRYPTKEY: +- if ( !bdb->bi_db_crypt_file && !BER_BVISNULL( &bdb->bi_db_crypt_key )) { +- value_add_one( &c->rvalue_vals, &bdb->bi_db_crypt_key ); +- } else { +- rc = 1; +- } +- break; +- +- case BDB_DIRECTORY: +- if ( bdb->bi_dbenv_home ) { +- c->value_string = ch_strdup( bdb->bi_dbenv_home ); +- } else { +- rc = 1; +- } +- break; +- +- case BDB_CONFIG: +- if ( !( bdb->bi_flags & BDB_IS_OPEN ) +- && !bdb->bi_db_config ) +- { +- char buf[SLAP_TEXT_BUFLEN]; +- FILE *f = fopen( bdb->bi_db_config_path, "r" ); +- struct berval bv; +- +- if ( f ) { +- bdb->bi_flags |= BDB_HAS_CONFIG; +- while ( fgets( buf, sizeof(buf), f )) { +- ber_str2bv( buf, 0, 1, &bv ); +- if ( bv.bv_len > 0 && bv.bv_val[bv.bv_len-1] == '\n' ) { +- bv.bv_len--; +- bv.bv_val[bv.bv_len] = '\0'; +- } +- /* shouldn't need this, but ... */ +- if ( bv.bv_len > 0 && bv.bv_val[bv.bv_len-1] == '\r' ) { +- bv.bv_len--; +- bv.bv_val[bv.bv_len] = '\0'; +- } +- ber_bvarray_add( &bdb->bi_db_config, &bv ); +- } +- fclose( f ); +- } +- } +- if ( bdb->bi_db_config ) { +- int i; +- struct berval bv; +- +- bv.bv_val = c->log; +- for (i=0; !BER_BVISNULL(&bdb->bi_db_config[i]); i++) { +- bv.bv_len = sprintf( bv.bv_val, "{%d}%s", i, +- bdb->bi_db_config[i].bv_val ); +- value_add_one( &c->rvalue_vals, &bv ); +- } +- } +- if ( !c->rvalue_vals ) rc = 1; +- break; +- +- case BDB_NOSYNC: +- if ( bdb->bi_dbenv_xflags & DB_TXN_NOSYNC ) +- c->value_int = 1; +- break; +- +- case BDB_CHECKSUM: +- if ( bdb->bi_flags & BDB_CHKSUM ) +- c->value_int = 1; +- break; +- +- case BDB_INDEX: +- bdb_attr_index_unparse( bdb, &c->rvalue_vals ); +- if ( !c->rvalue_vals ) rc = 1; +- break; +- +- case BDB_LOCKD: +- rc = 1; +- if ( bdb->bi_lock_detect != DB_LOCK_DEFAULT ) { +- int i; +- for (i=0; !BER_BVISNULL(&bdb_lockd[i].word); i++) { +- if ( bdb->bi_lock_detect == (u_int32_t)bdb_lockd[i].mask ) { +- value_add_one( &c->rvalue_vals, &bdb_lockd[i].word ); +- rc = 0; +- break; +- } +- } +- } +- break; +- +- case BDB_SSTACK: +- c->value_int = bdb->bi_search_stack_depth; +- break; +- +- case BDB_PGSIZE: { +- struct bdb_db_pgsize *ps; +- char buf[SLAP_TEXT_BUFLEN]; +- struct berval bv; +- int rc = 1; +- +- bv.bv_val = buf; +- for ( ps = bdb->bi_pagesizes; ps; ps = ps->bdp_next ) { +- bv.bv_len = sprintf( buf, "%s %d", ps->bdp_name.bv_val, +- ps->bdp_size / 1024 ); +- value_add_one( &c->rvalue_vals, &bv ); +- rc = 0; +- +- } +- break; +- } +- } +- return rc; +- } else if ( c->op == LDAP_MOD_DELETE ) { +- rc = 0; +- switch( c->type ) { +- case BDB_MODE: +-#if 0 +- /* FIXME: does it make any sense to change the mode, +- * if we don't exec a chmod()? */ +- bdb->bi_dbenv_mode = SLAPD_DEFAULT_DB_MODE; +- break; +-#endif +- +- /* single-valued no-ops */ +- case BDB_LOCKD: +- case BDB_SSTACK: +- break; +- +- case BDB_CHKPT: +- if ( bdb->bi_txn_cp_task ) { +- struct re_s *re = bdb->bi_txn_cp_task; +- bdb->bi_txn_cp_task = NULL; +- ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); +- if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ) ) +- ldap_pvt_runqueue_stoptask( &slapd_rq, re ); +- ldap_pvt_runqueue_remove( &slapd_rq, re ); +- ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); +- } +- bdb->bi_txn_cp = 0; +- break; +- case BDB_CONFIG: +- if ( c->valx < 0 ) { +- ber_bvarray_free( bdb->bi_db_config ); +- bdb->bi_db_config = NULL; +- } else { +- int i = c->valx; +- ch_free( bdb->bi_db_config[i].bv_val ); +- for (; bdb->bi_db_config[i].bv_val; i++) +- bdb->bi_db_config[i] = bdb->bi_db_config[i+1]; +- } +- bdb->bi_flags |= BDB_UPD_CONFIG|BDB_RE_OPEN; +- c->cleanup = bdb_cf_cleanup; +- break; +- /* Doesn't really make sense to change these on the fly; +- * the entire DB must be dumped and reloaded +- */ +- case BDB_CRYPTFILE: +- if ( bdb->bi_db_crypt_file ) { +- ch_free( bdb->bi_db_crypt_file ); +- bdb->bi_db_crypt_file = NULL; +- } +- /* FALLTHRU */ +- case BDB_CRYPTKEY: +- if ( !BER_BVISNULL( &bdb->bi_db_crypt_key )) { +- ch_free( bdb->bi_db_crypt_key.bv_val ); +- BER_BVZERO( &bdb->bi_db_crypt_key ); +- } +- break; +- case BDB_DIRECTORY: +- bdb->bi_flags |= BDB_RE_OPEN; +- bdb->bi_flags ^= BDB_HAS_CONFIG; +- ch_free( bdb->bi_dbenv_home ); +- bdb->bi_dbenv_home = NULL; +- ch_free( bdb->bi_db_config_path ); +- bdb->bi_db_config_path = NULL; +- c->cleanup = bdb_cf_cleanup; +- ldap_pvt_thread_pool_purgekey( bdb->bi_dbenv ); +- break; +- case BDB_NOSYNC: +- bdb->bi_dbenv->set_flags( bdb->bi_dbenv, DB_TXN_NOSYNC, 0 ); +- break; +- case BDB_CHECKSUM: +- bdb->bi_flags &= ~BDB_CHKSUM; +- break; +- case BDB_INDEX: +- if ( c->valx == -1 ) { +- int i; +- +- /* delete all */ +- for ( i = 0; i < bdb->bi_nattrs; i++ ) { +- bdb->bi_attrs[i]->ai_indexmask |= BDB_INDEX_DELETING; +- } +- bdb->bi_defaultmask = 0; +- bdb->bi_flags |= BDB_DEL_INDEX; +- c->cleanup = bdb_cf_cleanup; +- +- } else { +- struct berval bv, def = BER_BVC("default"); +- char *ptr; +- +- for (ptr = c->line; !isspace( (unsigned char) *ptr ); ptr++); +- +- bv.bv_val = c->line; +- bv.bv_len = ptr - bv.bv_val; +- if ( bvmatch( &bv, &def )) { +- bdb->bi_defaultmask = 0; +- +- } else { +- int i; +- char **attrs; +- char sep; +- +- sep = bv.bv_val[ bv.bv_len ]; +- bv.bv_val[ bv.bv_len ] = '\0'; +- attrs = ldap_str2charray( bv.bv_val, "," ); +- +- for ( i = 0; attrs[ i ]; i++ ) { +- AttributeDescription *ad = NULL; +- const char *text; +- AttrInfo *ai; +- +- slap_str2ad( attrs[ i ], &ad, &text ); +- /* if we got here... */ +- assert( ad != NULL ); +- +- ai = bdb_attr_mask( bdb, ad ); +- /* if we got here... */ +- assert( ai != NULL ); +- +- ai->ai_indexmask |= BDB_INDEX_DELETING; +- bdb->bi_flags |= BDB_DEL_INDEX; +- c->cleanup = bdb_cf_cleanup; +- } +- +- bv.bv_val[ bv.bv_len ] = sep; +- ldap_charray_free( attrs ); +- } +- } +- break; +- /* doesn't make sense on the fly; the DB file must be +- * recreated +- */ +- case BDB_PGSIZE: { +- struct bdb_db_pgsize *ps, **prev; +- int i; +- +- for ( i = 0, prev = &bdb->bi_pagesizes, ps = *prev; ps; +- prev = &ps->bdp_next, ps = ps->bdp_next, i++ ) { +- if ( c->valx == -1 || i == c->valx ) { +- *prev = ps->bdp_next; +- ch_free( ps ); +- ps = *prev; +- if ( i == c->valx ) break; +- } +- } +- } +- break; +- } +- return rc; +- } +- +- switch( c->type ) { +- case BDB_MODE: +- if ( ASCII_DIGIT( c->argv[1][0] ) ) { +- long mode; +- char *next; +- errno = 0; +- mode = strtol( c->argv[1], &next, 0 ); +- if ( errno != 0 || next == c->argv[1] || next[0] != '\0' ) { +- fprintf( stderr, "%s: " +- "unable to parse mode=\"%s\".\n", +- c->log, c->argv[1] ); +- return 1; +- } +- bdb->bi_dbenv_mode = mode; +- +- } else { +- char *m = c->argv[1]; +- int who, what, mode = 0; +- +- if ( strlen( m ) != STRLENOF("-rwxrwxrwx") ) { +- return 1; +- } +- +- if ( m[0] != '-' ) { +- return 1; +- } +- +- m++; +- for ( who = 0; who < 3; who++ ) { +- for ( what = 0; what < 3; what++, m++ ) { +- if ( m[0] == '-' ) { +- continue; +- } else if ( m[0] != "rwx"[what] ) { +- return 1; +- } +- mode += ((1 << (2 - what)) << 3*(2 - who)); +- } +- } +- bdb->bi_dbenv_mode = mode; +- } +- break; +- case BDB_CHKPT: { +- long l; +- bdb->bi_txn_cp = 1; +- if ( lutil_atolx( &l, c->argv[1], 0 ) != 0 ) { +- fprintf( stderr, "%s: " +- "invalid kbyte \"%s\" in \"checkpoint\".\n", +- c->log, c->argv[1] ); +- return 1; +- } +- bdb->bi_txn_cp_kbyte = l; +- if ( lutil_atolx( &l, c->argv[2], 0 ) != 0 ) { +- fprintf( stderr, "%s: " +- "invalid minutes \"%s\" in \"checkpoint\".\n", +- c->log, c->argv[2] ); +- return 1; +- } +- bdb->bi_txn_cp_min = l; +- /* If we're in server mode and time-based checkpointing is enabled, +- * submit a task to perform periodic checkpoints. +- */ +- if ((slapMode & SLAP_SERVER_MODE) && bdb->bi_txn_cp_min ) { +- struct re_s *re = bdb->bi_txn_cp_task; +- if ( re ) { +- re->interval.tv_sec = bdb->bi_txn_cp_min * 60; +- } else { +- if ( c->be->be_suffix == NULL || BER_BVISNULL( &c->be->be_suffix[0] ) ) { +- fprintf( stderr, "%s: " +- "\"checkpoint\" must occur after \"suffix\".\n", +- c->log ); +- return 1; +- } +- ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); +- bdb->bi_txn_cp_task = ldap_pvt_runqueue_insert( &slapd_rq, +- bdb->bi_txn_cp_min * 60, bdb_checkpoint, bdb, +- LDAP_XSTRING(bdb_checkpoint), c->be->be_suffix[0].bv_val ); +- ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); +- } +- } +- } break; +- +- case BDB_CONFIG: { +- char *ptr = c->line; +- struct berval bv; +- +- if ( c->op == SLAP_CONFIG_ADD ) { +- ptr += STRLENOF("dbconfig"); +- while (!isspace((unsigned char)*ptr)) ptr++; +- while (isspace((unsigned char)*ptr)) ptr++; +- } +- +- if ( bdb->bi_flags & BDB_IS_OPEN ) { +- bdb->bi_flags |= BDB_UPD_CONFIG|BDB_RE_OPEN; +- c->cleanup = bdb_cf_cleanup; +- } else { +- /* If we're just starting up... +- */ +- FILE *f; +- /* If a DB_CONFIG file exists, or we don't know the path +- * to the DB_CONFIG file, ignore these directives +- */ +- if (( bdb->bi_flags & BDB_HAS_CONFIG ) || !bdb->bi_db_config_path ) +- break; +- f = fopen( bdb->bi_db_config_path, "a" ); +- if ( f ) { +- /* FIXME: EBCDIC probably needs special handling */ +- fprintf( f, "%s\n", ptr ); +- fclose( f ); +- } +- } +- ber_str2bv( ptr, 0, 1, &bv ); +- ber_bvarray_add( &bdb->bi_db_config, &bv ); +- } +- break; +- +- case BDB_CRYPTFILE: +- rc = lutil_get_filed_password( c->value_string, &bdb->bi_db_crypt_key ); +- if ( rc == 0 ) { +- bdb->bi_db_crypt_file = c->value_string; +- } +- break; +- +- /* Cannot set key if file was already set */ +- case BDB_CRYPTKEY: +- if ( bdb->bi_db_crypt_file ) { +- rc = 1; +- } else { +- bdb->bi_db_crypt_key = c->value_bv; +- } +- break; +- +- case BDB_DIRECTORY: { +- FILE *f; +- char *ptr, *testpath; +- int len; +- +- len = strlen( c->value_string ); +- testpath = ch_malloc( len + STRLENOF(LDAP_DIRSEP) + STRLENOF("DUMMY") + 1 ); +- ptr = lutil_strcopy( testpath, c->value_string ); +- *ptr++ = LDAP_DIRSEP[0]; +- strcpy( ptr, "DUMMY" ); +- f = fopen( testpath, "w" ); +- if ( f ) { +- fclose( f ); +- unlink( testpath ); +- } +- ch_free( testpath ); +- if ( !f ) { +- snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid path: %s", +- c->log, strerror( errno )); +- Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); +- return -1; +- } +- +- if ( bdb->bi_dbenv_home ) +- ch_free( bdb->bi_dbenv_home ); +- bdb->bi_dbenv_home = c->value_string; +- +- /* See if a DB_CONFIG file already exists here */ +- if ( bdb->bi_db_config_path ) +- ch_free( bdb->bi_db_config_path ); +- bdb->bi_db_config_path = ch_malloc( len + +- STRLENOF(LDAP_DIRSEP) + STRLENOF("DB_CONFIG") + 1 ); +- ptr = lutil_strcopy( bdb->bi_db_config_path, bdb->bi_dbenv_home ); +- *ptr++ = LDAP_DIRSEP[0]; +- strcpy( ptr, "DB_CONFIG" ); +- +- f = fopen( bdb->bi_db_config_path, "r" ); +- if ( f ) { +- bdb->bi_flags |= BDB_HAS_CONFIG; +- fclose(f); +- } +- } +- break; +- +- case BDB_NOSYNC: +- if ( c->value_int ) +- bdb->bi_dbenv_xflags |= DB_TXN_NOSYNC; +- else +- bdb->bi_dbenv_xflags &= ~DB_TXN_NOSYNC; +- if ( bdb->bi_flags & BDB_IS_OPEN ) { +- bdb->bi_dbenv->set_flags( bdb->bi_dbenv, DB_TXN_NOSYNC, +- c->value_int ); +- } +- break; +- +- case BDB_CHECKSUM: +- if ( c->value_int ) +- bdb->bi_flags |= BDB_CHKSUM; +- else +- bdb->bi_flags &= ~BDB_CHKSUM; +- break; +- +- case BDB_INDEX: +- rc = bdb_attr_index_config( bdb, c->fname, c->lineno, +- c->argc - 1, &c->argv[1], &c->reply); +- +- if( rc != LDAP_SUCCESS ) return 1; +- if (( bdb->bi_flags & BDB_IS_OPEN ) && !bdb->bi_index_task ) { +- /* Start the task as soon as we finish here. Set a long +- * interval (10 hours) so that it only gets scheduled once. +- */ +- if ( c->be->be_suffix == NULL || BER_BVISNULL( &c->be->be_suffix[0] ) ) { +- fprintf( stderr, "%s: " +- "\"index\" must occur after \"suffix\".\n", +- c->log ); +- return 1; +- } +- ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); +- bdb->bi_index_task = ldap_pvt_runqueue_insert( &slapd_rq, 36000, +- bdb_online_index, c->be, +- LDAP_XSTRING(bdb_online_index), c->be->be_suffix[0].bv_val ); +- ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); +- } +- break; +- +- case BDB_LOCKD: +- rc = verb_to_mask( c->argv[1], bdb_lockd ); +- if ( BER_BVISNULL(&bdb_lockd[rc].word) ) { +- fprintf( stderr, "%s: " +- "bad policy (%s) in \"lockDetect \" line\n", +- c->log, c->argv[1] ); +- return 1; +- } +- bdb->bi_lock_detect = (u_int32_t)rc; +- break; +- +- case BDB_SSTACK: +- if ( c->value_int < MINIMUM_SEARCH_STACK_DEPTH ) { +- fprintf( stderr, +- "%s: depth %d too small, using %d\n", +- c->log, c->value_int, MINIMUM_SEARCH_STACK_DEPTH ); +- c->value_int = MINIMUM_SEARCH_STACK_DEPTH; +- } +- bdb->bi_search_stack_depth = c->value_int; +- break; +- +- case BDB_PGSIZE: { +- struct bdb_db_pgsize *ps, **prev; +- int i, s; +- +- s = atoi(c->argv[2]); +- if ( s < 1 || s > 64 ) { +- snprintf( c->cr_msg, sizeof( c->cr_msg ), +- "%s: size must be > 0 and <= 64: %d", +- c->log, s ); +- Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); +- return -1; +- } +- i = strlen(c->argv[1]); +- ps = ch_malloc( sizeof(struct bdb_db_pgsize) + i + 1 ); +- ps->bdp_next = NULL; +- ps->bdp_name.bv_len = i; +- ps->bdp_name.bv_val = (char *)(ps+1); +- strcpy( ps->bdp_name.bv_val, c->argv[1] ); +- ps->bdp_size = s * 1024; +- for ( prev = &bdb->bi_pagesizes; *prev; prev = &(*prev)->bdp_next ) +- ; +- *prev = ps; +- } +- break; +- } +- return 0; +-} +- +-int bdb_back_init_cf( BackendInfo *bi ) +-{ +- int rc; +- bi->bi_cf_ocs = bdbocs; +- +- rc = config_register_schema( bdbcfg, bdbocs ); +- if ( rc ) return rc; +- return 0; +-} +diff --git a/servers/slapd/back-bdb/dbcache.c b/servers/slapd/back-bdb/dbcache.c +deleted file mode 100644 +index 9a35b71..0000000 +--- a/servers/slapd/back-bdb/dbcache.c ++++ /dev/null +@@ -1,210 +0,0 @@ +-/* dbcache.c - manage cache of open databases */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +- +-#include +-#include +-#include +-#include +-#include +- +-#include "slap.h" +-#include "back-bdb.h" +-#include "lutil_hash.h" +- +-#ifdef BDB_INDEX_USE_HASH +-/* Pass-thru hash function. Since the indexer is already giving us hash +- * values as keys, we don't need BDB to re-hash them. +- */ +-static u_int32_t +-bdb_db_hash( +- DB *db, +- const void *bytes, +- u_int32_t length +-) +-{ +- u_int32_t ret = 0; +- unsigned char *dst = (unsigned char *)&ret; +- const unsigned char *src = (const unsigned char *)bytes; +- +- if ( length > sizeof(u_int32_t) ) +- length = sizeof(u_int32_t); +- +- while ( length ) { +- *dst++ = *src++; +- length--; +- } +- return ret; +-} +-#define BDB_INDEXTYPE DB_HASH +-#else +-#define BDB_INDEXTYPE DB_BTREE +-#endif +- +-/* If a configured size is found, return it, otherwise return 0 */ +-int +-bdb_db_findsize( +- struct bdb_info *bdb, +- struct berval *name +-) +-{ +- struct bdb_db_pgsize *bp; +- int rc; +- +- for ( bp = bdb->bi_pagesizes; bp; bp=bp->bdp_next ) { +- rc = strncmp( name->bv_val, bp->bdp_name.bv_val, name->bv_len ); +- if ( !rc ) { +- if ( name->bv_len == bp->bdp_name.bv_len ) +- return bp->bdp_size; +- if ( name->bv_len < bp->bdp_name.bv_len && +- bp->bdp_name.bv_val[name->bv_len] == '.' ) +- return bp->bdp_size; +- } +- } +- return 0; +-} +- +-int +-bdb_db_cache( +- Backend *be, +- struct berval *name, +- DB **dbout ) +-{ +- int i, flags; +- int rc; +- struct bdb_info *bdb = (struct bdb_info *) be->be_private; +- struct bdb_db_info *db; +- char *file; +- +- *dbout = NULL; +- +- for( i=BDB_NDB; i < bdb->bi_ndatabases; i++ ) { +- if( !ber_bvcmp( &bdb->bi_databases[i]->bdi_name, name) ) { +- *dbout = bdb->bi_databases[i]->bdi_db; +- return 0; +- } +- } +- +- ldap_pvt_thread_mutex_lock( &bdb->bi_database_mutex ); +- +- /* check again! may have been added by another thread */ +- for( i=BDB_NDB; i < bdb->bi_ndatabases; i++ ) { +- if( !ber_bvcmp( &bdb->bi_databases[i]->bdi_name, name) ) { +- *dbout = bdb->bi_databases[i]->bdi_db; +- ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex ); +- return 0; +- } +- } +- +- if( i >= BDB_INDICES ) { +- ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex ); +- return -1; +- } +- +- db = (struct bdb_db_info *) ch_calloc(1, sizeof(struct bdb_db_info)); +- +- ber_dupbv( &db->bdi_name, name ); +- +- rc = db_create( &db->bdi_db, bdb->bi_dbenv, 0 ); +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, +- "bdb_db_cache: db_create(%s) failed: %s (%d)\n", +- bdb->bi_dbenv_home, db_strerror(rc), rc ); +- ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex ); +- ch_free( db ); +- return rc; +- } +- +- if( !BER_BVISNULL( &bdb->bi_db_crypt_key )) { +- rc = db->bdi_db->set_flags( db->bdi_db, DB_ENCRYPT ); +- if ( rc ) { +- Debug( LDAP_DEBUG_ANY, +- "bdb_db_cache: db set_flags(DB_ENCRYPT)(%s) failed: %s (%d)\n", +- bdb->bi_dbenv_home, db_strerror(rc), rc ); +- ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex ); +- db->bdi_db->close( db->bdi_db, 0 ); +- ch_free( db ); +- return rc; +- } +- } +- +- if( bdb->bi_flags & BDB_CHKSUM ) { +- rc = db->bdi_db->set_flags( db->bdi_db, DB_CHKSUM ); +- if ( rc ) { +- Debug( LDAP_DEBUG_ANY, +- "bdb_db_cache: db set_flags(DB_CHKSUM)(%s) failed: %s (%d)\n", +- bdb->bi_dbenv_home, db_strerror(rc), rc ); +- ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex ); +- db->bdi_db->close( db->bdi_db, 0 ); +- ch_free( db ); +- return rc; +- } +- } +- +- /* If no explicit size set, use the FS default */ +- flags = bdb_db_findsize( bdb, name ); +- if ( flags ) +- rc = db->bdi_db->set_pagesize( db->bdi_db, flags ); +- +-#ifdef BDB_INDEX_USE_HASH +- rc = db->bdi_db->set_h_hash( db->bdi_db, bdb_db_hash ); +-#endif +- rc = db->bdi_db->set_flags( db->bdi_db, DB_DUP | DB_DUPSORT ); +- +- file = ch_malloc( db->bdi_name.bv_len + sizeof(BDB_SUFFIX) ); +- strcpy( file, db->bdi_name.bv_val ); +- strcpy( file+db->bdi_name.bv_len, BDB_SUFFIX ); +- +-#ifdef HAVE_EBCDIC +- __atoe( file ); +-#endif +- flags = DB_CREATE | DB_THREAD; +-#ifdef DB_AUTO_COMMIT +- if ( !( slapMode & SLAP_TOOL_QUICK )) +- flags |= DB_AUTO_COMMIT; +-#endif +- /* Cannot Truncate when Transactions are in use */ +- if ( (slapMode & (SLAP_TOOL_QUICK|SLAP_TRUNCATE_MODE)) == +- (SLAP_TOOL_QUICK|SLAP_TRUNCATE_MODE)) +- flags |= DB_TRUNCATE; +- +- rc = DB_OPEN( db->bdi_db, +- file, NULL /* name */, +- BDB_INDEXTYPE, bdb->bi_db_opflags | flags, bdb->bi_dbenv_mode ); +- +- ch_free( file ); +- +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, +- "bdb_db_cache: db_open(%s) failed: %s (%d)\n", +- name->bv_val, db_strerror(rc), rc ); +- ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex ); +- db->bdi_db->close( db->bdi_db, 0 ); +- ch_free( db ); +- return rc; +- } +- +- bdb->bi_databases[i] = db; +- bdb->bi_ndatabases = i+1; +- +- *dbout = db->bdi_db; +- +- ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex ); +- return 0; +-} +diff --git a/servers/slapd/back-bdb/delete.c b/servers/slapd/back-bdb/delete.c +deleted file mode 100644 +index f4f6e23..0000000 +--- a/servers/slapd/back-bdb/delete.c ++++ /dev/null +@@ -1,605 +0,0 @@ +-/* delete.c - bdb backend delete routine */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +-#include +- +-#include "lutil.h" +-#include "back-bdb.h" +- +-int +-bdb_delete( Operation *op, SlapReply *rs ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- Entry *matched = NULL; +- struct berval pdn = {0, NULL}; +- Entry *e = NULL; +- Entry *p = NULL; +- EntryInfo *ei = NULL, *eip = NULL; +- int manageDSAit = get_manageDSAit( op ); +- AttributeDescription *children = slap_schema.si_ad_children; +- AttributeDescription *entry = slap_schema.si_ad_entry; +- DB_TXN *ltid = NULL, *lt2; +- struct bdb_op_info opinfo = {{{ 0 }}}; +- ID eid; +- +- DB_LOCK lock, plock; +- +- int num_retries = 0; +- +- int rc; +- +- LDAPControl **preread_ctrl = NULL; +- LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS]; +- int num_ctrls = 0; +- +- int parent_is_glue = 0; +- int parent_is_leaf = 0; +- +-#ifdef LDAP_X_TXN +- int settle = 0; +-#endif +- +- Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(bdb_delete) ": %s\n", +- op->o_req_dn.bv_val, 0, 0 ); +- +-#ifdef LDAP_X_TXN +- if( op->o_txnSpec ) { +- /* acquire connection lock */ +- ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); +- if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) { +- rs->sr_text = "invalid transaction identifier"; +- rs->sr_err = LDAP_X_TXN_ID_INVALID; +- goto txnReturn; +- } else if( op->o_conn->c_txn == CONN_TXN_SETTLE ) { +- settle=1; +- goto txnReturn; +- } +- +- if( op->o_conn->c_txn_backend == NULL ) { +- op->o_conn->c_txn_backend = op->o_bd; +- +- } else if( op->o_conn->c_txn_backend != op->o_bd ) { +- rs->sr_text = "transaction cannot span multiple database contexts"; +- rs->sr_err = LDAP_AFFECTS_MULTIPLE_DSAS; +- goto txnReturn; +- } +- +- /* insert operation into transaction */ +- +- rs->sr_text = "transaction specified"; +- rs->sr_err = LDAP_X_TXN_SPECIFY_OKAY; +- +-txnReturn: +- /* release connection lock */ +- ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); +- +- if( !settle ) { +- send_ldap_result( op, rs ); +- return rs->sr_err; +- } +- } +-#endif +- +- ctrls[num_ctrls] = 0; +- +- /* allocate CSN */ +- if ( BER_BVISNULL( &op->o_csn ) ) { +- struct berval csn; +- char csnbuf[LDAP_PVT_CSNSTR_BUFSIZE]; +- +- csn.bv_val = csnbuf; +- csn.bv_len = sizeof(csnbuf); +- slap_get_csn( op, &csn, 1 ); +- } +- +- if( 0 ) { +-retry: /* transaction retry */ +- if( e != NULL ) { +- bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e); +- e = NULL; +- } +- if( p != NULL ) { +- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p); +- p = NULL; +- } +- Debug( LDAP_DEBUG_TRACE, +- "==> " LDAP_XSTRING(bdb_delete) ": retrying...\n", +- 0, 0, 0 ); +- rs->sr_err = TXN_ABORT( ltid ); +- ltid = NULL; +- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); +- opinfo.boi_oe.oe_key = NULL; +- op->o_do_not_cache = opinfo.boi_acl_cache; +- if( rs->sr_err != 0 ) { +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- if ( op->o_abandon ) { +- rs->sr_err = SLAPD_ABANDON; +- goto return_results; +- } +- parent_is_glue = 0; +- parent_is_leaf = 0; +- bdb_trans_backoff( ++num_retries ); +- } +- +- /* begin transaction */ +- rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, <id, +- bdb->bi_db_opflags ); +- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_delete) ": txn1 id: %x\n", +- ltid->id(ltid), 0, 0 ); +- rs->sr_text = NULL; +- if( rs->sr_err != 0 ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_delete) ": txn_begin failed: " +- "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 ); +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- +- opinfo.boi_oe.oe_key = bdb; +- opinfo.boi_txn = ltid; +- opinfo.boi_err = 0; +- opinfo.boi_acl_cache = op->o_do_not_cache; +- LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.boi_oe, oe_next ); +- +- if ( !be_issuffix( op->o_bd, &op->o_req_ndn ) ) { +- dnParent( &op->o_req_ndn, &pdn ); +- } +- +- /* get entry */ +- rs->sr_err = bdb_dn2entry( op, ltid, &op->o_req_ndn, &ei, 1, +- &lock ); +- +- switch( rs->sr_err ) { +- case 0: +- case DB_NOTFOUND: +- break; +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- case LDAP_BUSY: +- rs->sr_text = "ldap server busy"; +- goto return_results; +- default: +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- +- if ( rs->sr_err == 0 ) { +- e = ei->bei_e; +- eip = ei->bei_parent; +- } else { +- matched = ei->bei_e; +- } +- +- /* FIXME : dn2entry() should return non-glue entry */ +- if ( e == NULL || ( !manageDSAit && is_entry_glue( e ))) { +- Debug( LDAP_DEBUG_ARGS, +- "<=- " LDAP_XSTRING(bdb_delete) ": no such object %s\n", +- op->o_req_dn.bv_val, 0, 0); +- +- if ( matched != NULL ) { +- rs->sr_matched = ch_strdup( matched->e_dn ); +- rs->sr_ref = is_entry_referral( matched ) +- ? get_entry_referrals( op, matched ) +- : NULL; +- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, matched); +- matched = NULL; +- +- } else { +- rs->sr_ref = referral_rewrite( default_referral, NULL, +- &op->o_req_dn, LDAP_SCOPE_DEFAULT ); +- } +- +- rs->sr_err = LDAP_REFERRAL; +- rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; +- goto return_results; +- } +- +- rc = bdb_cache_find_id( op, ltid, eip->bei_id, &eip, 0, &plock ); +- switch( rc ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- case 0: +- case DB_NOTFOUND: +- break; +- default: +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- if ( eip ) p = eip->bei_e; +- +- if ( pdn.bv_len != 0 ) { +- if( p == NULL || !bvmatch( &pdn, &p->e_nname )) { +- Debug( LDAP_DEBUG_TRACE, +- "<=- " LDAP_XSTRING(bdb_delete) ": parent " +- "does not exist\n", 0, 0, 0 ); +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "could not locate parent of entry"; +- goto return_results; +- } +- +- /* check parent for "children" acl */ +- rs->sr_err = access_allowed( op, p, +- children, NULL, ACL_WDEL, NULL ); +- +- if ( !rs->sr_err ) { +- switch( opinfo.boi_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- +- Debug( LDAP_DEBUG_TRACE, +- "<=- " LDAP_XSTRING(bdb_delete) ": no write " +- "access to parent\n", 0, 0, 0 ); +- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; +- rs->sr_text = "no write access to parent"; +- goto return_results; +- } +- +- } else { +- /* no parent, must be root to delete */ +- if( ! be_isroot( op ) ) { +- if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv ) +- || be_shadow_update( op ) ) { +- p = (Entry *)&slap_entry_root; +- +- /* check parent for "children" acl */ +- rs->sr_err = access_allowed( op, p, +- children, NULL, ACL_WDEL, NULL ); +- +- p = NULL; +- +- if ( !rs->sr_err ) { +- switch( opinfo.boi_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- +- Debug( LDAP_DEBUG_TRACE, +- "<=- " LDAP_XSTRING(bdb_delete) +- ": no access to parent\n", +- 0, 0, 0 ); +- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; +- rs->sr_text = "no write access to parent"; +- goto return_results; +- } +- +- } else { +- Debug( LDAP_DEBUG_TRACE, +- "<=- " LDAP_XSTRING(bdb_delete) +- ": no parent and not root\n", 0, 0, 0 ); +- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; +- goto return_results; +- } +- } +- } +- +- if ( get_assert( op ) && +- ( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE )) +- { +- rs->sr_err = LDAP_ASSERTION_FAILED; +- goto return_results; +- } +- +- rs->sr_err = access_allowed( op, e, +- entry, NULL, ACL_WDEL, NULL ); +- +- if ( !rs->sr_err ) { +- switch( opinfo.boi_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- +- Debug( LDAP_DEBUG_TRACE, +- "<=- " LDAP_XSTRING(bdb_delete) ": no write access " +- "to entry\n", 0, 0, 0 ); +- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; +- rs->sr_text = "no write access to entry"; +- goto return_results; +- } +- +- if ( !manageDSAit && is_entry_referral( e ) ) { +- /* entry is a referral, don't allow delete */ +- rs->sr_ref = get_entry_referrals( op, e ); +- +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_delete) ": entry is referral\n", +- 0, 0, 0 ); +- +- rs->sr_err = LDAP_REFERRAL; +- rs->sr_matched = ch_strdup( e->e_name.bv_val ); +- rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; +- goto return_results; +- } +- +- /* pre-read */ +- if( op->o_preread ) { +- if( preread_ctrl == NULL ) { +- preread_ctrl = &ctrls[num_ctrls++]; +- ctrls[num_ctrls] = NULL; +- } +- if( slap_read_controls( op, rs, e, +- &slap_pre_read_bv, preread_ctrl ) ) +- { +- Debug( LDAP_DEBUG_TRACE, +- "<=- " LDAP_XSTRING(bdb_delete) ": pre-read " +- "failed!\n", 0, 0, 0 ); +- if ( op->o_preread & SLAP_CONTROL_CRITICAL ) { +- /* FIXME: is it correct to abort +- * operation if control fails? */ +- goto return_results; +- } +- } +- } +- +- /* nested transaction */ +- rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, <2, +- bdb->bi_db_opflags ); +- rs->sr_text = NULL; +- if( rs->sr_err != 0 ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_delete) ": txn_begin(2) failed: " +- "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 ); +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_delete) ": txn2 id: %x\n", +- lt2->id(lt2), 0, 0 ); +- +- BDB_LOG_PRINTF( bdb->bi_dbenv, lt2, "slapd Starting delete %s(%d)", +- e->e_nname.bv_val, e->e_id ); +- +- /* Can't do it if we have kids */ +- rs->sr_err = bdb_cache_children( op, lt2, e ); +- if( rs->sr_err != DB_NOTFOUND ) { +- switch( rs->sr_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- case 0: +- Debug(LDAP_DEBUG_ARGS, +- "<=- " LDAP_XSTRING(bdb_delete) +- ": non-leaf %s\n", +- op->o_req_dn.bv_val, 0, 0); +- rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF; +- rs->sr_text = "subordinate objects must be deleted first"; +- break; +- default: +- Debug(LDAP_DEBUG_ARGS, +- "<=- " LDAP_XSTRING(bdb_delete) +- ": has_children failed: %s (%d)\n", +- db_strerror(rs->sr_err), rs->sr_err, 0 ); +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- } +- goto return_results; +- } +- +- /* delete from dn2id */ +- rs->sr_err = bdb_dn2id_delete( op, lt2, eip, e ); +- if ( rs->sr_err != 0 ) { +- Debug(LDAP_DEBUG_TRACE, +- "<=- " LDAP_XSTRING(bdb_delete) ": dn2id failed: " +- "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 ); +- switch( rs->sr_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- rs->sr_text = "DN index delete failed"; +- rs->sr_err = LDAP_OTHER; +- goto return_results; +- } +- +- /* delete indices for old attributes */ +- rs->sr_err = bdb_index_entry_del( op, lt2, e ); +- if ( rs->sr_err != LDAP_SUCCESS ) { +- Debug(LDAP_DEBUG_TRACE, +- "<=- " LDAP_XSTRING(bdb_delete) ": index failed: " +- "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 ); +- switch( rs->sr_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- rs->sr_text = "entry index delete failed"; +- rs->sr_err = LDAP_OTHER; +- goto return_results; +- } +- +- /* fixup delete CSN */ +- if ( !SLAP_SHADOW( op->o_bd )) { +- struct berval vals[2]; +- +- assert( !BER_BVISNULL( &op->o_csn ) ); +- vals[0] = op->o_csn; +- BER_BVZERO( &vals[1] ); +- rs->sr_err = bdb_index_values( op, lt2, slap_schema.si_ad_entryCSN, +- vals, 0, SLAP_INDEX_ADD_OP ); +- if ( rs->sr_err != LDAP_SUCCESS ) { +- switch( rs->sr_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- rs->sr_text = "entryCSN index update failed"; +- rs->sr_err = LDAP_OTHER; +- goto return_results; +- } +- } +- +- /* delete from id2entry */ +- rs->sr_err = bdb_id2entry_delete( op->o_bd, lt2, e ); +- if ( rs->sr_err != 0 ) { +- Debug( LDAP_DEBUG_TRACE, +- "<=- " LDAP_XSTRING(bdb_delete) ": id2entry failed: " +- "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 ); +- switch( rs->sr_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- rs->sr_text = "entry delete failed"; +- rs->sr_err = LDAP_OTHER; +- goto return_results; +- } +- +- if ( pdn.bv_len != 0 ) { +- parent_is_glue = is_entry_glue(p); +- rs->sr_err = bdb_cache_children( op, lt2, p ); +- if ( rs->sr_err != DB_NOTFOUND ) { +- switch( rs->sr_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- case 0: +- break; +- default: +- Debug(LDAP_DEBUG_ARGS, +- "<=- " LDAP_XSTRING(bdb_delete) +- ": has_children failed: %s (%d)\n", +- db_strerror(rs->sr_err), rs->sr_err, 0 ); +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- parent_is_leaf = 1; +- } +- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p); +- p = NULL; +- } +- +- BDB_LOG_PRINTF( bdb->bi_dbenv, lt2, "slapd Commit1 delete %s(%d)", +- e->e_nname.bv_val, e->e_id ); +- +- if ( TXN_COMMIT( lt2, 0 ) != 0 ) { +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "txn_commit(2) failed"; +- goto return_results; +- } +- +- eid = e->e_id; +- +-#if 0 /* Do we want to reclaim deleted IDs? */ +- ldap_pvt_thread_mutex_lock( &bdb->bi_lastid_mutex ); +- if ( e->e_id == bdb->bi_lastid ) { +- bdb_last_id( op->o_bd, ltid ); +- } +- ldap_pvt_thread_mutex_unlock( &bdb->bi_lastid_mutex ); +-#endif +- +- if( op->o_noop ) { +- if ( ( rs->sr_err = TXN_ABORT( ltid ) ) != 0 ) { +- rs->sr_text = "txn_abort (no-op) failed"; +- } else { +- rs->sr_err = LDAP_X_NO_OPERATION; +- ltid = NULL; +- goto return_results; +- } +- } else { +- +- BDB_LOG_PRINTF( bdb->bi_dbenv, ltid, "slapd Cache delete %s(%d)", +- e->e_nname.bv_val, e->e_id ); +- +- rc = bdb_cache_delete( bdb, e, ltid, &lock ); +- switch( rc ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- +- rs->sr_err = TXN_COMMIT( ltid, 0 ); +- } +- ltid = NULL; +- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); +- opinfo.boi_oe.oe_key = NULL; +- +- BDB_LOG_PRINTF( bdb->bi_dbenv, NULL, "slapd Committed delete %s(%d)", +- e->e_nname.bv_val, e->e_id ); +- +- if( rs->sr_err != 0 ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_delete) ": txn_%s failed: %s (%d)\n", +- op->o_noop ? "abort (no-op)" : "commit", +- db_strerror(rs->sr_err), rs->sr_err ); +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "commit failed"; +- +- goto return_results; +- } +- +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_delete) ": deleted%s id=%08lx dn=\"%s\"\n", +- op->o_noop ? " (no-op)" : "", +- eid, op->o_req_dn.bv_val ); +- rs->sr_err = LDAP_SUCCESS; +- rs->sr_text = NULL; +- if( num_ctrls ) rs->sr_ctrls = ctrls; +- +-return_results: +- if ( rs->sr_err == LDAP_SUCCESS && parent_is_glue && parent_is_leaf ) { +- op->o_delete_glue_parent = 1; +- } +- +- if ( p ) +- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p); +- +- /* free entry */ +- if( e != NULL ) { +- if ( rs->sr_err == LDAP_SUCCESS ) { +- /* Free the EntryInfo and the Entry */ +- bdb_cache_entryinfo_lock( BEI(e) ); +- bdb_cache_delete_cleanup( &bdb->bi_cache, BEI(e) ); +- } else { +- bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e); +- } +- } +- +- if( ltid != NULL ) { +- TXN_ABORT( ltid ); +- } +- if ( opinfo.boi_oe.oe_key ) { +- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); +- } +- +- send_ldap_result( op, rs ); +- slap_graduate_commit_csn( op ); +- +- if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) { +- slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx ); +- slap_sl_free( *preread_ctrl, op->o_tmpmemctx ); +- } +- +- if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp_kbyte ) { +- TXN_CHECKPOINT( bdb->bi_dbenv, +- bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 ); +- } +- return rs->sr_err; +-} +diff --git a/servers/slapd/back-bdb/dn2entry.c b/servers/slapd/back-bdb/dn2entry.c +deleted file mode 100644 +index 41d1dc9..0000000 +--- a/servers/slapd/back-bdb/dn2entry.c ++++ /dev/null +@@ -1,84 +0,0 @@ +-/* dn2entry.c - routines to deal with the dn2id / id2entry glue */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +-#include +- +-#include "back-bdb.h" +- +-/* +- * dn2entry - look up dn in the cache/indexes and return the corresponding +- * entry. If the requested DN is not found and matched is TRUE, return info +- * for the closest ancestor of the DN. Otherwise e is NULL. +- */ +- +-int +-bdb_dn2entry( +- Operation *op, +- DB_TXN *tid, +- struct berval *dn, +- EntryInfo **e, +- int matched, +- DB_LOCK *lock ) +-{ +- EntryInfo *ei = NULL; +- int rc, rc2; +- +- Debug(LDAP_DEBUG_TRACE, "bdb_dn2entry(\"%s\")\n", +- dn->bv_val, 0, 0 ); +- +- *e = NULL; +- +- rc = bdb_cache_find_ndn( op, tid, dn, &ei ); +- if ( rc ) { +- if ( matched && rc == DB_NOTFOUND ) { +- /* Set the return value, whether we have its entry +- * or not. +- */ +- *e = ei; +- if ( ei && ei->bei_id ) { +- rc2 = bdb_cache_find_id( op, tid, ei->bei_id, +- &ei, ID_LOCKED, lock ); +- if ( rc2 ) rc = rc2; +- } else if ( ei ) { +- bdb_cache_entryinfo_unlock( ei ); +- memset( lock, 0, sizeof( *lock )); +- lock->mode = DB_LOCK_NG; +- } +- } else if ( ei ) { +- bdb_cache_entryinfo_unlock( ei ); +- } +- } else { +- rc = bdb_cache_find_id( op, tid, ei->bei_id, &ei, ID_LOCKED, +- lock ); +- if ( rc == 0 ) { +- *e = ei; +- } else if ( matched && rc == DB_NOTFOUND ) { +- /* always return EntryInfo */ +- if ( ei->bei_parent ) { +- ei = ei->bei_parent; +- rc2 = bdb_cache_find_id( op, tid, ei->bei_id, &ei, 0, +- lock ); +- if ( rc2 ) rc = rc2; +- } +- *e = ei; +- } +- } +- +- return rc; +-} +diff --git a/servers/slapd/back-bdb/dn2id.c b/servers/slapd/back-bdb/dn2id.c +deleted file mode 100644 +index 7b54024..0000000 +--- a/servers/slapd/back-bdb/dn2id.c ++++ /dev/null +@@ -1,1215 +0,0 @@ +-/* dn2id.c - routines to deal with the dn2id index */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +-#include +- +-#include "back-bdb.h" +-#include "idl.h" +-#include "lutil.h" +- +-#ifndef BDB_HIER +-int +-bdb_dn2id_add( +- Operation *op, +- DB_TXN *txn, +- EntryInfo *eip, +- Entry *e ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- DB *db = bdb->bi_dn2id->bdi_db; +- int rc; +- DBT key, data; +- ID nid; +- char *buf; +- struct berval ptr, pdn; +- +- Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_add 0x%lx: \"%s\"\n", +- e->e_id, e->e_ndn, 0 ); +- assert( e->e_id != NOID ); +- +- DBTzero( &key ); +- key.size = e->e_nname.bv_len + 2; +- key.ulen = key.size; +- key.flags = DB_DBT_USERMEM; +- buf = op->o_tmpalloc( key.size, op->o_tmpmemctx ); +- key.data = buf; +- buf[0] = DN_BASE_PREFIX; +- ptr.bv_val = buf + 1; +- ptr.bv_len = e->e_nname.bv_len; +- AC_MEMCPY( ptr.bv_val, e->e_nname.bv_val, e->e_nname.bv_len ); +- ptr.bv_val[ptr.bv_len] = '\0'; +- +- DBTzero( &data ); +- data.data = &nid; +- data.size = sizeof( nid ); +- BDB_ID2DISK( e->e_id, &nid ); +- +- /* store it -- don't override */ +- rc = db->put( db, txn, &key, &data, DB_NOOVERWRITE ); +- if( rc != 0 ) { +- char buf[ SLAP_TEXT_BUFLEN ]; +- snprintf( buf, sizeof( buf ), "%s => bdb_dn2id_add dn=\"%s\" ID=0x%lx", +- op->o_log_prefix, e->e_name.bv_val, e->e_id ); +- Debug( LDAP_DEBUG_ANY, "%s: put failed: %s %d\n", +- buf, db_strerror(rc), rc ); +- goto done; +- } +- +-#ifndef BDB_MULTIPLE_SUFFIXES +- if( !be_issuffix( op->o_bd, &ptr )) +-#endif +- { +- buf[0] = DN_SUBTREE_PREFIX; +- rc = db->put( db, txn, &key, &data, DB_NOOVERWRITE ); +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, +- "=> bdb_dn2id_add 0x%lx: subtree (%s) put failed: %d\n", +- e->e_id, ptr.bv_val, rc ); +- goto done; +- } +- +-#ifdef BDB_MULTIPLE_SUFFIXES +- if( !be_issuffix( op->o_bd, &ptr )) +-#endif +- { +- dnParent( &ptr, &pdn ); +- +- key.size = pdn.bv_len + 2; +- key.ulen = key.size; +- pdn.bv_val[-1] = DN_ONE_PREFIX; +- key.data = pdn.bv_val-1; +- ptr = pdn; +- +- rc = bdb_idl_insert_key( op->o_bd, db, txn, &key, e->e_id ); +- +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, +- "=> bdb_dn2id_add 0x%lx: parent (%s) insert failed: %d\n", +- e->e_id, ptr.bv_val, rc ); +- goto done; +- } +- } +- +-#ifndef BDB_MULTIPLE_SUFFIXES +- while( !be_issuffix( op->o_bd, &ptr )) +-#else +- for (;;) +-#endif +- { +- ptr.bv_val[-1] = DN_SUBTREE_PREFIX; +- +- rc = bdb_idl_insert_key( op->o_bd, db, txn, &key, e->e_id ); +- +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, +- "=> bdb_dn2id_add 0x%lx: subtree (%s) insert failed: %d\n", +- e->e_id, ptr.bv_val, rc ); +- break; +- } +-#ifdef BDB_MULTIPLE_SUFFIXES +- if( be_issuffix( op->o_bd, &ptr )) break; +-#endif +- dnParent( &ptr, &pdn ); +- +- key.size = pdn.bv_len + 2; +- key.ulen = key.size; +- key.data = pdn.bv_val - 1; +- ptr = pdn; +- } +- } +- +-done: +- op->o_tmpfree( buf, op->o_tmpmemctx ); +- Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_add 0x%lx: %d\n", e->e_id, rc, 0 ); +- return rc; +-} +- +-int +-bdb_dn2id_delete( +- Operation *op, +- DB_TXN *txn, +- EntryInfo *eip, +- Entry *e ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- DB *db = bdb->bi_dn2id->bdi_db; +- char *buf; +- DBT key; +- struct berval pdn, ptr; +- int rc; +- +- Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_delete 0x%lx: \"%s\"\n", +- e->e_id, e->e_ndn, 0 ); +- +- DBTzero( &key ); +- key.size = e->e_nname.bv_len + 2; +- buf = op->o_tmpalloc( key.size, op->o_tmpmemctx ); +- key.data = buf; +- key.flags = DB_DBT_USERMEM; +- buf[0] = DN_BASE_PREFIX; +- ptr.bv_val = buf+1; +- ptr.bv_len = e->e_nname.bv_len; +- AC_MEMCPY( ptr.bv_val, e->e_nname.bv_val, e->e_nname.bv_len ); +- ptr.bv_val[ptr.bv_len] = '\0'; +- +- /* delete it */ +- rc = db->del( db, txn, &key, 0 ); +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, "=> bdb_dn2id_delete 0x%lx: delete failed: %s %d\n", +- e->e_id, db_strerror(rc), rc ); +- goto done; +- } +- +-#ifndef BDB_MULTIPLE_SUFFIXES +- if( !be_issuffix( op->o_bd, &ptr )) +-#endif +- { +- buf[0] = DN_SUBTREE_PREFIX; +- rc = bdb_idl_delete_key( op->o_bd, db, txn, &key, e->e_id ); +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, +- "=> bdb_dn2id_delete 0x%lx: subtree (%s) delete failed: %d\n", +- e->e_id, ptr.bv_val, rc ); +- goto done; +- } +- +-#ifdef BDB_MULTIPLE_SUFFIXES +- if( !be_issuffix( op->o_bd, &ptr )) +-#endif +- { +- dnParent( &ptr, &pdn ); +- +- key.size = pdn.bv_len + 2; +- key.ulen = key.size; +- pdn.bv_val[-1] = DN_ONE_PREFIX; +- key.data = pdn.bv_val - 1; +- ptr = pdn; +- +- rc = bdb_idl_delete_key( op->o_bd, db, txn, &key, e->e_id ); +- +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, +- "=> bdb_dn2id_delete 0x%lx: parent (%s) delete failed: %d\n", +- e->e_id, ptr.bv_val, rc ); +- goto done; +- } +- } +- +-#ifndef BDB_MULTIPLE_SUFFIXES +- while( !be_issuffix( op->o_bd, &ptr )) +-#else +- for (;;) +-#endif +- { +- ptr.bv_val[-1] = DN_SUBTREE_PREFIX; +- +- rc = bdb_idl_delete_key( op->o_bd, db, txn, &key, e->e_id ); +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, +- "=> bdb_dn2id_delete 0x%lx: subtree (%s) delete failed: %d\n", +- e->e_id, ptr.bv_val, rc ); +- goto done; +- } +-#ifdef BDB_MULTIPLE_SUFFIXES +- if( be_issuffix( op->o_bd, &ptr )) break; +-#endif +- dnParent( &ptr, &pdn ); +- +- key.size = pdn.bv_len + 2; +- key.ulen = key.size; +- key.data = pdn.bv_val - 1; +- ptr = pdn; +- } +- } +- +-done: +- op->o_tmpfree( buf, op->o_tmpmemctx ); +- Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_delete 0x%lx: %d\n", e->e_id, rc, 0 ); +- return rc; +-} +- +-int +-bdb_dn2id( +- Operation *op, +- struct berval *dn, +- EntryInfo *ei, +- DB_TXN *txn, +- DBC **cursor ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- DB *db = bdb->bi_dn2id->bdi_db; +- int rc; +- DBT key, data; +- ID nid; +- +- Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id(\"%s\")\n", dn->bv_val, 0, 0 ); +- +- DBTzero( &key ); +- key.size = dn->bv_len + 2; +- key.data = op->o_tmpalloc( key.size, op->o_tmpmemctx ); +- ((char *)key.data)[0] = DN_BASE_PREFIX; +- AC_MEMCPY( &((char *)key.data)[1], dn->bv_val, key.size - 1 ); +- +- /* store the ID */ +- DBTzero( &data ); +- data.data = &nid; +- data.ulen = sizeof(ID); +- data.flags = DB_DBT_USERMEM; +- +- rc = db->cursor( db, txn, cursor, bdb->bi_db_opflags ); +- +- /* fetch it */ +- if ( !rc ) +- rc = (*cursor)->c_get( *cursor, &key, &data, DB_SET ); +- +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id: get failed: %s (%d)\n", +- db_strerror( rc ), rc, 0 ); +- } else { +- BDB_DISK2ID( &nid, &ei->bei_id ); +- Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id: got id=0x%lx\n", +- ei->bei_id, 0, 0 ); +- } +- op->o_tmpfree( key.data, op->o_tmpmemctx ); +- return rc; +-} +- +-int +-bdb_dn2id_children( +- Operation *op, +- DB_TXN *txn, +- Entry *e ) +-{ +- DBT key, data; +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- DB *db = bdb->bi_dn2id->bdi_db; +- ID id; +- int rc; +- +- Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_children(\"%s\")\n", +- e->e_nname.bv_val, 0, 0 ); +- DBTzero( &key ); +- key.size = e->e_nname.bv_len + 2; +- key.data = op->o_tmpalloc( key.size, op->o_tmpmemctx ); +- ((char *)key.data)[0] = DN_ONE_PREFIX; +- AC_MEMCPY( &((char *)key.data)[1], e->e_nname.bv_val, key.size - 1 ); +- +- if ( bdb->bi_idl_cache_size ) { +- rc = bdb_idl_cache_get( bdb, db, &key, NULL ); +- if ( rc != LDAP_NO_SUCH_OBJECT ) { +- op->o_tmpfree( key.data, op->o_tmpmemctx ); +- return rc; +- } +- } +- /* we actually could do a empty get... */ +- DBTzero( &data ); +- data.data = &id; +- data.ulen = sizeof(id); +- data.flags = DB_DBT_USERMEM; +- data.doff = 0; +- data.dlen = sizeof(id); +- +- rc = db->get( db, txn, &key, &data, bdb->bi_db_opflags ); +- op->o_tmpfree( key.data, op->o_tmpmemctx ); +- +- Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_children(\"%s\"): %s (%d)\n", +- e->e_nname.bv_val, +- rc == 0 ? "" : ( rc == DB_NOTFOUND ? "no " : +- db_strerror(rc) ), rc ); +- +- return rc; +-} +- +-int +-bdb_dn2idl( +- Operation *op, +- DB_TXN *txn, +- struct berval *ndn, +- EntryInfo *ei, +- ID *ids, +- ID *stack ) +-{ +- int rc; +- DBT key; +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- DB *db = bdb->bi_dn2id->bdi_db; +- int prefix = ( op->ors_scope == LDAP_SCOPE_ONELEVEL ) +- ? DN_ONE_PREFIX : DN_SUBTREE_PREFIX; +- +- Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2idl(\"%s\")\n", +- ndn->bv_val, 0, 0 ); +- +-#ifndef BDB_MULTIPLE_SUFFIXES +- if ( prefix == DN_SUBTREE_PREFIX +- && ( ei->bei_id == 0 || +- ( ei->bei_parent->bei_id == 0 && op->o_bd->be_suffix[0].bv_len ))) { +- BDB_IDL_ALL(bdb, ids); +- return 0; +- } +-#endif +- +- DBTzero( &key ); +- key.size = ndn->bv_len + 2; +- key.ulen = key.size; +- key.flags = DB_DBT_USERMEM; +- key.data = op->o_tmpalloc( key.size, op->o_tmpmemctx ); +- ((char *)key.data)[0] = prefix; +- AC_MEMCPY( &((char *)key.data)[1], ndn->bv_val, key.size - 1 ); +- +- BDB_IDL_ZERO( ids ); +- rc = bdb_idl_fetch_key( op->o_bd, db, txn, &key, ids, NULL, 0 ); +- +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_dn2idl: get failed: %s (%d)\n", +- db_strerror( rc ), rc, 0 ); +- +- } else { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_dn2idl: id=%ld first=%ld last=%ld\n", +- (long) ids[0], +- (long) BDB_IDL_FIRST( ids ), (long) BDB_IDL_LAST( ids ) ); +- } +- +- op->o_tmpfree( key.data, op->o_tmpmemctx ); +- return rc; +-} +- +-#else /* BDB_HIER */ +-/* Management routines for a hierarchically structured database. +- * +- * Instead of a ldbm-style dn2id database, we use a hierarchical one. Each +- * entry in this database is a struct diskNode, keyed by entryID and with +- * the data containing the RDN and entryID of the node's children. We use +- * a B-Tree with sorted duplicates to store all the children of a node under +- * the same key. Also, the first item under the key contains the entry's own +- * rdn and the ID of the node's parent, to allow bottom-up tree traversal as +- * well as top-down. To keep this info first in the list, the high bit of all +- * subsequent nrdnlen's is always set. This means we can only accomodate +- * RDNs up to length 32767, but that's fine since full DNs are already +- * restricted to 8192. +- * +- * The diskNode is a variable length structure. This definition is not +- * directly usable for in-memory manipulation. +- */ +-typedef struct diskNode { +- unsigned char nrdnlen[2]; +- char nrdn[1]; +- char rdn[1]; /* variable placement */ +- unsigned char entryID[sizeof(ID)]; /* variable placement */ +-} diskNode; +- +-/* Sort function for the sorted duplicate data items of a dn2id key. +- * Sorts based on normalized RDN, in length order. +- */ +-int +-hdb_dup_compare( +- DB *db, +- const DBT *usrkey, +- const DBT *curkey +-) +-{ +- diskNode *un, *cn; +- int rc; +- +- un = (diskNode *)usrkey->data; +- cn = (diskNode *)curkey->data; +- +- /* data is not aligned, cannot compare directly */ +- rc = un->nrdnlen[0] - cn->nrdnlen[0]; +- if ( rc ) return rc; +- rc = un->nrdnlen[1] - cn->nrdnlen[1]; +- if ( rc ) return rc; +- +- return strcmp( un->nrdn, cn->nrdn ); +-} +- +-/* This function constructs a full DN for a given entry. +- */ +-int hdb_fix_dn( +- Entry *e, +- int checkit ) +-{ +- EntryInfo *ei; +- int rlen = 0, nrlen = 0; +- char *ptr, *nptr; +- int max = 0; +- +- if ( !e->e_id ) +- return 0; +- +- /* count length of all DN components */ +- for ( ei = BEI(e); ei && ei->bei_id; ei=ei->bei_parent ) { +- rlen += ei->bei_rdn.bv_len + 1; +- nrlen += ei->bei_nrdn.bv_len + 1; +- if (ei->bei_modrdns > max) max = ei->bei_modrdns; +- } +- +- /* See if the entry DN was invalidated by a subtree rename */ +- if ( checkit ) { +- if ( BEI(e)->bei_modrdns >= max ) { +- return 0; +- } +- /* We found a mismatch, tell the caller to lock it */ +- if ( checkit == 1 ) { +- return 1; +- } +- /* checkit == 2. do the fix. */ +- free( e->e_name.bv_val ); +- free( e->e_nname.bv_val ); +- } +- +- e->e_name.bv_len = rlen - 1; +- e->e_nname.bv_len = nrlen - 1; +- e->e_name.bv_val = ch_malloc(rlen); +- e->e_nname.bv_val = ch_malloc(nrlen); +- ptr = e->e_name.bv_val; +- nptr = e->e_nname.bv_val; +- for ( ei = BEI(e); ei && ei->bei_id; ei=ei->bei_parent ) { +- ptr = lutil_strcopy(ptr, ei->bei_rdn.bv_val); +- nptr = lutil_strcopy(nptr, ei->bei_nrdn.bv_val); +- if ( ei->bei_parent ) { +- *ptr++ = ','; +- *nptr++ = ','; +- } +- } +- BEI(e)->bei_modrdns = max; +- if ( ptr > e->e_name.bv_val ) ptr[-1] = '\0'; +- if ( nptr > e->e_nname.bv_val ) nptr[-1] = '\0'; +- +- return 0; +-} +- +-/* We add two elements to the DN2ID database - a data item under the parent's +- * entryID containing the child's RDN and entryID, and an item under the +- * child's entryID containing the parent's entryID. +- */ +-int +-hdb_dn2id_add( +- Operation *op, +- DB_TXN *txn, +- EntryInfo *eip, +- Entry *e ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- DB *db = bdb->bi_dn2id->bdi_db; +- DBT key, data; +- ID nid; +- int rc, rlen, nrlen; +- diskNode *d; +- char *ptr; +- +- Debug( LDAP_DEBUG_TRACE, "=> hdb_dn2id_add 0x%lx: \"%s\"\n", +- e->e_id, e->e_ndn, 0 ); +- +- nrlen = dn_rdnlen( op->o_bd, &e->e_nname ); +- if (nrlen) { +- rlen = dn_rdnlen( op->o_bd, &e->e_name ); +- } else { +- nrlen = e->e_nname.bv_len; +- rlen = e->e_name.bv_len; +- } +- +- d = op->o_tmpalloc(sizeof(diskNode) + rlen + nrlen, op->o_tmpmemctx); +- d->nrdnlen[1] = nrlen & 0xff; +- d->nrdnlen[0] = (nrlen >> 8) | 0x80; +- ptr = lutil_strncopy( d->nrdn, e->e_nname.bv_val, nrlen ); +- *ptr++ = '\0'; +- ptr = lutil_strncopy( ptr, e->e_name.bv_val, rlen ); +- *ptr++ = '\0'; +- BDB_ID2DISK( e->e_id, ptr ); +- +- DBTzero(&key); +- DBTzero(&data); +- key.size = sizeof(ID); +- key.flags = DB_DBT_USERMEM; +- BDB_ID2DISK( eip->bei_id, &nid ); +- +- key.data = &nid; +- +- /* Need to make dummy root node once. Subsequent attempts +- * will fail harmlessly. +- */ +- if ( eip->bei_id == 0 ) { +- diskNode dummy = {{0, 0}, "", "", ""}; +- data.data = &dummy; +- data.size = sizeof(diskNode); +- data.flags = DB_DBT_USERMEM; +- +- db->put( db, txn, &key, &data, DB_NODUPDATA ); +- } +- +- data.data = d; +- data.size = sizeof(diskNode) + rlen + nrlen; +- data.flags = DB_DBT_USERMEM; +- +- rc = db->put( db, txn, &key, &data, DB_NODUPDATA ); +- +- if (rc == 0) { +- BDB_ID2DISK( e->e_id, &nid ); +- BDB_ID2DISK( eip->bei_id, ptr ); +- d->nrdnlen[0] ^= 0x80; +- +- rc = db->put( db, txn, &key, &data, DB_NODUPDATA ); +- } +- +- /* Update all parents' IDL cache entries */ +- if ( rc == 0 && bdb->bi_idl_cache_size ) { +- ID tmp[2]; +- char *ptr = ((char *)&tmp[1])-1; +- key.data = ptr; +- key.size = sizeof(ID)+1; +- tmp[1] = eip->bei_id; +- *ptr = DN_ONE_PREFIX; +- bdb_idl_cache_add_id( bdb, db, &key, e->e_id ); +- if ( eip->bei_parent ) { +- *ptr = DN_SUBTREE_PREFIX; +- for (; eip && eip->bei_parent->bei_id; eip = eip->bei_parent) { +- tmp[1] = eip->bei_id; +- bdb_idl_cache_add_id( bdb, db, &key, e->e_id ); +- } +- /* Handle DB with empty suffix */ +- if ( !op->o_bd->be_suffix[0].bv_len && eip ) { +- tmp[1] = eip->bei_id; +- bdb_idl_cache_add_id( bdb, db, &key, e->e_id ); +- } +- } +- } +- +- op->o_tmpfree( d, op->o_tmpmemctx ); +- Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id_add 0x%lx: %d\n", e->e_id, rc, 0 ); +- +- return rc; +-} +- +-int +-hdb_dn2id_delete( +- Operation *op, +- DB_TXN *txn, +- EntryInfo *eip, +- Entry *e ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- DB *db = bdb->bi_dn2id->bdi_db; +- DBT key, data; +- DBC *cursor; +- diskNode *d; +- int rc; +- ID nid; +- unsigned char dlen[2]; +- +- Debug( LDAP_DEBUG_TRACE, "=> hdb_dn2id_delete 0x%lx: \"%s\"\n", +- e->e_id, e->e_ndn, 0 ); +- +- DBTzero(&key); +- key.size = sizeof(ID); +- key.ulen = key.size; +- key.flags = DB_DBT_USERMEM; +- BDB_ID2DISK( eip->bei_id, &nid ); +- +- DBTzero(&data); +- data.size = sizeof(diskNode) + BEI(e)->bei_nrdn.bv_len - sizeof(ID) - 1; +- data.ulen = data.size; +- data.dlen = data.size; +- data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; +- +- key.data = &nid; +- +- d = op->o_tmpalloc( data.size, op->o_tmpmemctx ); +- d->nrdnlen[1] = BEI(e)->bei_nrdn.bv_len & 0xff; +- d->nrdnlen[0] = (BEI(e)->bei_nrdn.bv_len >> 8) | 0x80; +- dlen[0] = d->nrdnlen[0]; +- dlen[1] = d->nrdnlen[1]; +- memcpy( d->nrdn, BEI(e)->bei_nrdn.bv_val, BEI(e)->bei_nrdn.bv_len+1 ); +- data.data = d; +- +- rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags ); +- if ( rc ) goto func_leave; +- +- /* Delete our ID from the parent's list */ +- rc = cursor->c_get( cursor, &key, &data, DB_GET_BOTH_RANGE ); +- if ( rc == 0 ) { +- if ( dlen[1] == d->nrdnlen[1] && dlen[0] == d->nrdnlen[0] && +- !strcmp( d->nrdn, BEI(e)->bei_nrdn.bv_val )) +- rc = cursor->c_del( cursor, 0 ); +- else +- rc = DB_NOTFOUND; +- } +- +- /* Delete our ID from the tree. With sorted duplicates, this +- * will leave any child nodes still hanging around. This is OK +- * for modrdn, which will add our info back in later. +- */ +- if ( rc == 0 ) { +- BDB_ID2DISK( e->e_id, &nid ); +- rc = cursor->c_get( cursor, &key, &data, DB_SET ); +- if ( rc == 0 ) +- rc = cursor->c_del( cursor, 0 ); +- } +- +- cursor->c_close( cursor ); +-func_leave: +- op->o_tmpfree( d, op->o_tmpmemctx ); +- +- /* Delete IDL cache entries */ +- if ( rc == 0 && bdb->bi_idl_cache_size ) { +- ID tmp[2]; +- char *ptr = ((char *)&tmp[1])-1; +- key.data = ptr; +- key.size = sizeof(ID)+1; +- tmp[1] = eip->bei_id; +- *ptr = DN_ONE_PREFIX; +- bdb_idl_cache_del_id( bdb, db, &key, e->e_id ); +- if ( eip ->bei_parent ) { +- *ptr = DN_SUBTREE_PREFIX; +- for (; eip && eip->bei_parent->bei_id; eip = eip->bei_parent) { +- tmp[1] = eip->bei_id; +- bdb_idl_cache_del_id( bdb, db, &key, e->e_id ); +- } +- /* Handle DB with empty suffix */ +- if ( !op->o_bd->be_suffix[0].bv_len && eip ) { +- tmp[1] = eip->bei_id; +- bdb_idl_cache_del_id( bdb, db, &key, e->e_id ); +- } +- } +- } +- Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id_delete 0x%lx: %d\n", e->e_id, rc, 0 ); +- return rc; +-} +- +- +-int +-hdb_dn2id( +- Operation *op, +- struct berval *in, +- EntryInfo *ei, +- DB_TXN *txn, +- DBC **cursor ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- DB *db = bdb->bi_dn2id->bdi_db; +- DBT key, data; +- int rc = 0, nrlen; +- diskNode *d; +- char *ptr; +- unsigned char dlen[2]; +- ID idp, parentID; +- +- Debug( LDAP_DEBUG_TRACE, "=> hdb_dn2id(\"%s\")\n", in->bv_val, 0, 0 ); +- +- nrlen = dn_rdnlen( op->o_bd, in ); +- if (!nrlen) nrlen = in->bv_len; +- +- DBTzero(&key); +- key.size = sizeof(ID); +- key.data = &idp; +- key.ulen = sizeof(ID); +- key.flags = DB_DBT_USERMEM; +- parentID = ( ei->bei_parent != NULL ) ? ei->bei_parent->bei_id : 0; +- BDB_ID2DISK( parentID, &idp ); +- +- DBTzero(&data); +- data.size = sizeof(diskNode) + nrlen - sizeof(ID) - 1; +- data.ulen = data.size * 3; +- data.dlen = data.ulen; +- data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; +- +- rc = db->cursor( db, txn, cursor, bdb->bi_db_opflags ); +- if ( rc ) return rc; +- +- d = op->o_tmpalloc( data.size * 3, op->o_tmpmemctx ); +- d->nrdnlen[1] = nrlen & 0xff; +- d->nrdnlen[0] = (nrlen >> 8) | 0x80; +- dlen[0] = d->nrdnlen[0]; +- dlen[1] = d->nrdnlen[1]; +- ptr = lutil_strncopy( d->nrdn, in->bv_val, nrlen ); +- *ptr = '\0'; +- data.data = d; +- +- rc = (*cursor)->c_get( *cursor, &key, &data, DB_GET_BOTH_RANGE ); +- if ( rc == 0 && (dlen[1] != d->nrdnlen[1] || dlen[0] != d->nrdnlen[0] || +- strncmp( d->nrdn, in->bv_val, nrlen ))) { +- rc = DB_NOTFOUND; +- } +- if ( rc == 0 ) { +- ptr = (char *) data.data + data.size - sizeof(ID); +- BDB_DISK2ID( ptr, &ei->bei_id ); +- ei->bei_rdn.bv_len = data.size - sizeof(diskNode) - nrlen; +- ptr = d->nrdn + nrlen + 1; +- ber_str2bv( ptr, ei->bei_rdn.bv_len, 1, &ei->bei_rdn ); +- if ( ei->bei_parent != NULL && !ei->bei_parent->bei_dkids ) { +- db_recno_t dkids; +- /* How many children does the parent have? */ +- /* FIXME: do we need to lock the parent +- * entryinfo? Seems safe... +- */ +- (*cursor)->c_count( *cursor, &dkids, 0 ); +- ei->bei_parent->bei_dkids = dkids; +- } +- } +- +- op->o_tmpfree( d, op->o_tmpmemctx ); +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id: get failed: %s (%d)\n", +- db_strerror( rc ), rc, 0 ); +- } else { +- Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id: got id=0x%lx\n", +- ei->bei_id, 0, 0 ); +- } +- +- return rc; +-} +- +-int +-hdb_dn2id_parent( +- Operation *op, +- DB_TXN *txn, +- EntryInfo *ei, +- ID *idp ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- DB *db = bdb->bi_dn2id->bdi_db; +- DBT key, data; +- DBC *cursor; +- int rc = 0; +- diskNode *d; +- char *ptr; +- ID nid; +- +- DBTzero(&key); +- key.size = sizeof(ID); +- key.data = &nid; +- key.ulen = sizeof(ID); +- key.flags = DB_DBT_USERMEM; +- BDB_ID2DISK( ei->bei_id, &nid ); +- +- DBTzero(&data); +- data.flags = DB_DBT_USERMEM; +- +- rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags ); +- if ( rc ) return rc; +- +- data.ulen = sizeof(diskNode) + (SLAP_LDAPDN_MAXLEN * 2); +- d = op->o_tmpalloc( data.ulen, op->o_tmpmemctx ); +- data.data = d; +- +- rc = cursor->c_get( cursor, &key, &data, DB_SET ); +- if ( rc == 0 ) { +- if (d->nrdnlen[0] & 0x80) { +- rc = LDAP_OTHER; +- } else { +- db_recno_t dkids; +- ptr = (char *) data.data + data.size - sizeof(ID); +- BDB_DISK2ID( ptr, idp ); +- ei->bei_nrdn.bv_len = (d->nrdnlen[0] << 8) | d->nrdnlen[1]; +- ber_str2bv( d->nrdn, ei->bei_nrdn.bv_len, 1, &ei->bei_nrdn ); +- ei->bei_rdn.bv_len = data.size - sizeof(diskNode) - +- ei->bei_nrdn.bv_len; +- ptr = d->nrdn + ei->bei_nrdn.bv_len + 1; +- ber_str2bv( ptr, ei->bei_rdn.bv_len, 1, &ei->bei_rdn ); +- /* How many children does this node have? */ +- cursor->c_count( cursor, &dkids, 0 ); +- ei->bei_dkids = dkids; +- } +- } +- cursor->c_close( cursor ); +- op->o_tmpfree( d, op->o_tmpmemctx ); +- return rc; +-} +- +-int +-hdb_dn2id_children( +- Operation *op, +- DB_TXN *txn, +- Entry *e ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- DB *db = bdb->bi_dn2id->bdi_db; +- DBT key, data; +- DBC *cursor; +- int rc; +- ID id; +- diskNode d; +- +- DBTzero(&key); +- key.size = sizeof(ID); +- key.data = &e->e_id; +- key.flags = DB_DBT_USERMEM; +- BDB_ID2DISK( e->e_id, &id ); +- +- /* IDL cache is in host byte order */ +- if ( bdb->bi_idl_cache_size ) { +- rc = bdb_idl_cache_get( bdb, db, &key, NULL ); +- if ( rc != LDAP_NO_SUCH_OBJECT ) { +- return rc; +- } +- } +- +- key.data = &id; +- DBTzero(&data); +- data.data = &d; +- data.ulen = sizeof(d); +- data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; +- data.dlen = sizeof(d); +- +- rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags ); +- if ( rc ) return rc; +- +- rc = cursor->c_get( cursor, &key, &data, DB_SET ); +- if ( rc == 0 ) { +- db_recno_t dkids; +- rc = cursor->c_count( cursor, &dkids, 0 ); +- if ( rc == 0 ) { +- BEI(e)->bei_dkids = dkids; +- if ( dkids < 2 ) rc = DB_NOTFOUND; +- } +- } +- cursor->c_close( cursor ); +- return rc; +-} +- +-/* bdb_dn2idl: +- * We can't just use bdb_idl_fetch_key because +- * 1 - our data items are longer than just an entry ID +- * 2 - our data items are sorted alphabetically by nrdn, not by ID. +- * +- * We descend the tree recursively, so we define this cookie +- * to hold our necessary state information. The bdb_dn2idl_internal +- * function uses this cookie when calling itself. +- */ +- +-struct dn2id_cookie { +- struct bdb_info *bdb; +- Operation *op; +- DB_TXN *txn; +- EntryInfo *ei; +- ID *ids; +- ID *tmp; +- ID *buf; +- DB *db; +- DBC *dbc; +- DBT key; +- DBT data; +- ID dbuf; +- ID id; +- ID nid; +- int rc; +- int depth; +- char need_sort; +- char prefix; +-}; +- +-static int +-apply_func( +- void *data, +- void *arg ) +-{ +- EntryInfo *ei = data; +- ID *idl = arg; +- +- bdb_idl_append_one( idl, ei->bei_id ); +- return 0; +-} +- +-static int +-hdb_dn2idl_internal( +- struct dn2id_cookie *cx +-) +-{ +- BDB_IDL_ZERO( cx->tmp ); +- +- if ( cx->bdb->bi_idl_cache_size ) { +- char *ptr = ((char *)&cx->id)-1; +- +- cx->key.data = ptr; +- cx->key.size = sizeof(ID)+1; +- if ( cx->prefix == DN_SUBTREE_PREFIX ) { +- ID *ids = cx->depth ? cx->tmp : cx->ids; +- *ptr = cx->prefix; +- cx->rc = bdb_idl_cache_get(cx->bdb, cx->db, &cx->key, ids); +- if ( cx->rc == LDAP_SUCCESS ) { +- if ( cx->depth ) { +- bdb_idl_delete( cx->tmp, cx->id ); /* ITS#6983, drop our own ID */ +- bdb_idl_append( cx->ids, cx->tmp ); +- cx->need_sort = 1; +- } +- return cx->rc; +- } +- } +- *ptr = DN_ONE_PREFIX; +- cx->rc = bdb_idl_cache_get(cx->bdb, cx->db, &cx->key, cx->tmp); +- if ( cx->rc == LDAP_SUCCESS ) { +- goto gotit; +- } +- if ( cx->rc == DB_NOTFOUND ) { +- return cx->rc; +- } +- } +- +- bdb_cache_entryinfo_lock( cx->ei ); +- +- /* If number of kids in the cache differs from on-disk, load +- * up all the kids from the database +- */ +- if ( cx->ei->bei_ckids+1 != cx->ei->bei_dkids ) { +- EntryInfo ei; +- db_recno_t dkids = cx->ei->bei_dkids; +- ei.bei_parent = cx->ei; +- +- /* Only one thread should load the cache */ +- while ( cx->ei->bei_state & CACHE_ENTRY_ONELEVEL ) { +- bdb_cache_entryinfo_unlock( cx->ei ); +- ldap_pvt_thread_yield(); +- bdb_cache_entryinfo_lock( cx->ei ); +- if ( cx->ei->bei_ckids+1 == cx->ei->bei_dkids ) { +- goto synced; +- } +- } +- +- cx->ei->bei_state |= CACHE_ENTRY_ONELEVEL; +- +- bdb_cache_entryinfo_unlock( cx->ei ); +- +- cx->rc = cx->db->cursor( cx->db, NULL, &cx->dbc, +- cx->bdb->bi_db_opflags ); +- if ( cx->rc ) +- goto done_one; +- +- cx->data.data = &cx->dbuf; +- cx->data.ulen = sizeof(ID); +- cx->data.dlen = sizeof(ID); +- cx->data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; +- +- /* The first item holds the parent ID. Ignore it. */ +- cx->key.data = &cx->nid; +- cx->key.size = sizeof(ID); +- cx->rc = cx->dbc->c_get( cx->dbc, &cx->key, &cx->data, DB_SET ); +- if ( cx->rc ) { +- cx->dbc->c_close( cx->dbc ); +- goto done_one; +- } +- +- /* If the on-disk count is zero we've never checked it. +- * Count it now. +- */ +- if ( !dkids ) { +- cx->dbc->c_count( cx->dbc, &dkids, 0 ); +- cx->ei->bei_dkids = dkids; +- } +- +- cx->data.data = cx->buf; +- cx->data.ulen = BDB_IDL_UM_SIZE * sizeof(ID); +- cx->data.flags = DB_DBT_USERMEM; +- +- if ( dkids > 1 ) { +- /* Fetch the rest of the IDs in a loop... */ +- while ( (cx->rc = cx->dbc->c_get( cx->dbc, &cx->key, &cx->data, +- DB_MULTIPLE | DB_NEXT_DUP )) == 0 ) { +- u_int8_t *j; +- size_t len; +- void *ptr; +- DB_MULTIPLE_INIT( ptr, &cx->data ); +- while (ptr) { +- DB_MULTIPLE_NEXT( ptr, &cx->data, j, len ); +- if (j) { +- EntryInfo *ei2; +- diskNode *d = (diskNode *)j; +- short nrlen; +- +- BDB_DISK2ID( j + len - sizeof(ID), &ei.bei_id ); +- nrlen = ((d->nrdnlen[0] ^ 0x80) << 8) | d->nrdnlen[1]; +- ei.bei_nrdn.bv_len = nrlen; +- /* nrdn/rdn are set in-place. +- * hdb_cache_load will copy them as needed +- */ +- ei.bei_nrdn.bv_val = d->nrdn; +- ei.bei_rdn.bv_len = len - sizeof(diskNode) +- - ei.bei_nrdn.bv_len; +- ei.bei_rdn.bv_val = d->nrdn + ei.bei_nrdn.bv_len + 1; +- bdb_idl_append_one( cx->tmp, ei.bei_id ); +- hdb_cache_load( cx->bdb, &ei, &ei2 ); +- } +- } +- } +- } +- +- cx->rc = cx->dbc->c_close( cx->dbc ); +-done_one: +- bdb_cache_entryinfo_lock( cx->ei ); +- cx->ei->bei_state &= ~CACHE_ENTRY_ONELEVEL; +- bdb_cache_entryinfo_unlock( cx->ei ); +- if ( cx->rc ) +- return cx->rc; +- +- } else { +- /* The in-memory cache is in sync with the on-disk data. +- * do we have any kids? +- */ +-synced: +- cx->rc = 0; +- if ( cx->ei->bei_ckids > 0 ) { +- /* Walk the kids tree; order is irrelevant since bdb_idl_sort +- * will sort it later. +- */ +- avl_apply( cx->ei->bei_kids, apply_func, +- cx->tmp, -1, AVL_POSTORDER ); +- } +- bdb_cache_entryinfo_unlock( cx->ei ); +- } +- +- if ( !BDB_IDL_IS_RANGE( cx->tmp ) && cx->tmp[0] > 3 ) +- bdb_idl_sort( cx->tmp, cx->buf ); +- if ( cx->bdb->bi_idl_cache_max_size && !BDB_IDL_IS_ZERO( cx->tmp )) { +- char *ptr = ((char *)&cx->id)-1; +- cx->key.data = ptr; +- cx->key.size = sizeof(ID)+1; +- *ptr = DN_ONE_PREFIX; +- bdb_idl_cache_put( cx->bdb, cx->db, &cx->key, cx->tmp, cx->rc ); +- } +- +-gotit: +- if ( !BDB_IDL_IS_ZERO( cx->tmp )) { +- if ( cx->prefix == DN_SUBTREE_PREFIX ) { +- bdb_idl_append( cx->ids, cx->tmp ); +- cx->need_sort = 1; +- if ( !(cx->ei->bei_state & CACHE_ENTRY_NO_GRANDKIDS)) { +- ID *save, idcurs; +- EntryInfo *ei = cx->ei; +- int nokids = 1; +- save = cx->op->o_tmpalloc( BDB_IDL_SIZEOF( cx->tmp ), +- cx->op->o_tmpmemctx ); +- BDB_IDL_CPY( save, cx->tmp ); +- +- idcurs = 0; +- cx->depth++; +- for ( cx->id = bdb_idl_first( save, &idcurs ); +- cx->id != NOID; +- cx->id = bdb_idl_next( save, &idcurs )) { +- EntryInfo *ei2; +- cx->ei = NULL; +- if ( bdb_cache_find_id( cx->op, cx->txn, cx->id, &cx->ei, +- ID_NOENTRY, NULL )) +- continue; +- if ( cx->ei ) { +- ei2 = cx->ei; +- if ( !( ei2->bei_state & CACHE_ENTRY_NO_KIDS )) { +- BDB_ID2DISK( cx->id, &cx->nid ); +- hdb_dn2idl_internal( cx ); +- if ( !BDB_IDL_IS_ZERO( cx->tmp )) +- nokids = 0; +- } +- bdb_cache_entryinfo_lock( ei2 ); +- ei2->bei_finders--; +- bdb_cache_entryinfo_unlock( ei2 ); +- } +- } +- cx->depth--; +- cx->op->o_tmpfree( save, cx->op->o_tmpmemctx ); +- if ( nokids ) { +- bdb_cache_entryinfo_lock( ei ); +- ei->bei_state |= CACHE_ENTRY_NO_GRANDKIDS; +- bdb_cache_entryinfo_unlock( ei ); +- } +- } +- /* Make sure caller knows it had kids! */ +- cx->tmp[0]=1; +- +- cx->rc = 0; +- } else { +- BDB_IDL_CPY( cx->ids, cx->tmp ); +- } +- } +- return cx->rc; +-} +- +-int +-hdb_dn2idl( +- Operation *op, +- DB_TXN *txn, +- struct berval *ndn, +- EntryInfo *ei, +- ID *ids, +- ID *stack ) +-{ +- struct bdb_info *bdb = (struct bdb_info *)op->o_bd->be_private; +- struct dn2id_cookie cx; +- +- Debug( LDAP_DEBUG_TRACE, "=> hdb_dn2idl(\"%s\")\n", +- ndn->bv_val, 0, 0 ); +- +-#ifndef BDB_MULTIPLE_SUFFIXES +- if ( op->ors_scope != LDAP_SCOPE_ONELEVEL && +- ( ei->bei_id == 0 || +- ( ei->bei_parent->bei_id == 0 && op->o_bd->be_suffix[0].bv_len ))) +- { +- BDB_IDL_ALL( bdb, ids ); +- return 0; +- } +-#endif +- +- cx.id = ei->bei_id; +- BDB_ID2DISK( cx.id, &cx.nid ); +- cx.ei = ei; +- cx.bdb = bdb; +- cx.db = cx.bdb->bi_dn2id->bdi_db; +- cx.prefix = (op->ors_scope == LDAP_SCOPE_ONELEVEL) ? +- DN_ONE_PREFIX : DN_SUBTREE_PREFIX; +- cx.ids = ids; +- cx.tmp = stack; +- cx.buf = stack + BDB_IDL_UM_SIZE; +- cx.op = op; +- cx.txn = txn; +- cx.need_sort = 0; +- cx.depth = 0; +- +- if ( cx.prefix == DN_SUBTREE_PREFIX ) { +- ids[0] = 1; +- ids[1] = cx.id; +- } else { +- BDB_IDL_ZERO( ids ); +- } +- if ( cx.ei->bei_state & CACHE_ENTRY_NO_KIDS ) +- return LDAP_SUCCESS; +- +- DBTzero(&cx.key); +- cx.key.ulen = sizeof(ID); +- cx.key.size = sizeof(ID); +- cx.key.flags = DB_DBT_USERMEM; +- +- DBTzero(&cx.data); +- +- hdb_dn2idl_internal(&cx); +- if ( cx.need_sort ) { +- char *ptr = ((char *)&cx.id)-1; +- if ( !BDB_IDL_IS_RANGE( cx.ids ) && cx.ids[0] > 3 ) +- bdb_idl_sort( cx.ids, cx.tmp ); +- cx.key.data = ptr; +- cx.key.size = sizeof(ID)+1; +- *ptr = cx.prefix; +- cx.id = ei->bei_id; +- if ( cx.bdb->bi_idl_cache_max_size ) +- bdb_idl_cache_put( cx.bdb, cx.db, &cx.key, cx.ids, cx.rc ); +- } +- +- if ( cx.rc == DB_NOTFOUND ) +- cx.rc = LDAP_SUCCESS; +- +- return cx.rc; +-} +-#endif /* BDB_HIER */ +diff --git a/servers/slapd/back-bdb/error.c b/servers/slapd/back-bdb/error.c +deleted file mode 100644 +index cf823ec..0000000 +--- a/servers/slapd/back-bdb/error.c ++++ /dev/null +@@ -1,62 +0,0 @@ +-/* error.c - BDB errcall routine */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +-#include +- +-#include "slap.h" +-#include "back-bdb.h" +- +-#if DB_VERSION_FULL < 0x04030000 +-void bdb_errcall( const char *pfx, char * msg ) +-#else +-void bdb_errcall( const DB_ENV *env, const char *pfx, const char * msg ) +-#endif +-{ +-#ifdef HAVE_EBCDIC +- if ( msg[0] > 0x7f ) +- __etoa( msg ); +-#endif +- Debug( LDAP_DEBUG_ANY, "bdb(%s): %s\n", pfx, msg, 0 ); +-} +- +-#if DB_VERSION_FULL >= 0x04030000 +-void bdb_msgcall( const DB_ENV *env, const char *msg ) +-{ +-#ifdef HAVE_EBCDIC +- if ( msg[0] > 0x7f ) +- __etoa( msg ); +-#endif +- Debug( LDAP_DEBUG_TRACE, "bdb: %s\n", msg, 0, 0 ); +-} +-#endif +- +-#ifdef HAVE_EBCDIC +- +-#undef db_strerror +- +-/* Not re-entrant! */ +-char *ebcdic_dberror( int rc ) +-{ +- static char msg[1024]; +- +- strcpy( msg, db_strerror( rc ) ); +- __etoa( msg ); +- return msg; +-} +-#endif +diff --git a/servers/slapd/back-bdb/extended.c b/servers/slapd/back-bdb/extended.c +deleted file mode 100644 +index 74d85df..0000000 +--- a/servers/slapd/back-bdb/extended.c ++++ /dev/null +@@ -1,54 +0,0 @@ +-/* extended.c - bdb backend extended routines */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +-#include +- +-#include "back-bdb.h" +-#include "lber_pvt.h" +- +-static struct exop { +- struct berval *oid; +- BI_op_extended *extended; +-} exop_table[] = { +- { NULL, NULL } +-}; +- +-int +-bdb_extended( Operation *op, SlapReply *rs ) +-/* struct berval *reqoid, +- struct berval *reqdata, +- char **rspoid, +- struct berval **rspdata, +- LDAPControl *** rspctrls, +- const char** text, +- BerVarray *refs +-) */ +-{ +- int i; +- +- for( i=0; exop_table[i].extended != NULL; i++ ) { +- if( ber_bvcmp( exop_table[i].oid, &op->oq_extended.rs_reqoid ) == 0 ) { +- return (exop_table[i].extended)( op, rs ); +- } +- } +- +- rs->sr_text = "not supported within naming context"; +- return rs->sr_err = LDAP_UNWILLING_TO_PERFORM; +-} +- +diff --git a/servers/slapd/back-bdb/filterindex.c b/servers/slapd/back-bdb/filterindex.c +deleted file mode 100644 +index c04c68c..0000000 +--- a/servers/slapd/back-bdb/filterindex.c ++++ /dev/null +@@ -1,1183 +0,0 @@ +-/* filterindex.c - generate the list of candidate entries from a filter */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +-#include +- +-#include "back-bdb.h" +-#include "idl.h" +-#ifdef LDAP_COMP_MATCH +-#include +-#endif +- +-static int presence_candidates( +- Operation *op, +- DB_TXN *rtxn, +- AttributeDescription *desc, +- ID *ids ); +- +-static int equality_candidates( +- Operation *op, +- DB_TXN *rtxn, +- AttributeAssertion *ava, +- ID *ids, +- ID *tmp ); +-static int inequality_candidates( +- Operation *op, +- DB_TXN *rtxn, +- AttributeAssertion *ava, +- ID *ids, +- ID *tmp, +- int gtorlt ); +-static int approx_candidates( +- Operation *op, +- DB_TXN *rtxn, +- AttributeAssertion *ava, +- ID *ids, +- ID *tmp ); +-static int substring_candidates( +- Operation *op, +- DB_TXN *rtxn, +- SubstringsAssertion *sub, +- ID *ids, +- ID *tmp ); +- +-static int list_candidates( +- Operation *op, +- DB_TXN *rtxn, +- Filter *flist, +- int ftype, +- ID *ids, +- ID *tmp, +- ID *stack ); +- +-static int +-ext_candidates( +- Operation *op, +- DB_TXN *rtxn, +- MatchingRuleAssertion *mra, +- ID *ids, +- ID *tmp, +- ID *stack); +- +-#ifdef LDAP_COMP_MATCH +-static int +-comp_candidates ( +- Operation *op, +- DB_TXN *rtxn, +- MatchingRuleAssertion *mra, +- ComponentFilter *f, +- ID *ids, +- ID *tmp, +- ID *stack); +- +-static int +-ava_comp_candidates ( +- Operation *op, +- DB_TXN *rtxn, +- AttributeAssertion *ava, +- AttributeAliasing *aa, +- ID *ids, +- ID *tmp, +- ID *stack); +-#endif +- +-int +-bdb_filter_candidates( +- Operation *op, +- DB_TXN *rtxn, +- Filter *f, +- ID *ids, +- ID *tmp, +- ID *stack ) +-{ +- int rc = 0; +-#ifdef LDAP_COMP_MATCH +- AttributeAliasing *aa; +-#endif +- Debug( LDAP_DEBUG_FILTER, "=> bdb_filter_candidates\n", 0, 0, 0 ); +- +- if ( f->f_choice & SLAPD_FILTER_UNDEFINED ) { +- BDB_IDL_ZERO( ids ); +- goto out; +- } +- +- switch ( f->f_choice ) { +- case SLAPD_FILTER_COMPUTED: +- switch( f->f_result ) { +- case SLAPD_COMPARE_UNDEFINED: +- /* This technically is not the same as FALSE, but it +- * certainly will produce no matches. +- */ +- /* FALL THRU */ +- case LDAP_COMPARE_FALSE: +- BDB_IDL_ZERO( ids ); +- break; +- case LDAP_COMPARE_TRUE: { +- struct bdb_info *bdb = (struct bdb_info *)op->o_bd->be_private; +- BDB_IDL_ALL( bdb, ids ); +- } break; +- case LDAP_SUCCESS: +- /* this is a pre-computed scope, leave it alone */ +- break; +- } +- break; +- case LDAP_FILTER_PRESENT: +- Debug( LDAP_DEBUG_FILTER, "\tPRESENT\n", 0, 0, 0 ); +- rc = presence_candidates( op, rtxn, f->f_desc, ids ); +- break; +- +- case LDAP_FILTER_EQUALITY: +- Debug( LDAP_DEBUG_FILTER, "\tEQUALITY\n", 0, 0, 0 ); +-#ifdef LDAP_COMP_MATCH +- if ( is_aliased_attribute && ( aa = is_aliased_attribute ( f->f_ava->aa_desc ) ) ) { +- rc = ava_comp_candidates ( op, rtxn, f->f_ava, aa, ids, tmp, stack ); +- } +- else +-#endif +- { +- rc = equality_candidates( op, rtxn, f->f_ava, ids, tmp ); +- } +- break; +- +- case LDAP_FILTER_APPROX: +- Debug( LDAP_DEBUG_FILTER, "\tAPPROX\n", 0, 0, 0 ); +- rc = approx_candidates( op, rtxn, f->f_ava, ids, tmp ); +- break; +- +- case LDAP_FILTER_SUBSTRINGS: +- Debug( LDAP_DEBUG_FILTER, "\tSUBSTRINGS\n", 0, 0, 0 ); +- rc = substring_candidates( op, rtxn, f->f_sub, ids, tmp ); +- break; +- +- case LDAP_FILTER_GE: +- /* if no GE index, use pres */ +- Debug( LDAP_DEBUG_FILTER, "\tGE\n", 0, 0, 0 ); +- if( f->f_ava->aa_desc->ad_type->sat_ordering && +- ( f->f_ava->aa_desc->ad_type->sat_ordering->smr_usage & SLAP_MR_ORDERED_INDEX ) ) +- rc = inequality_candidates( op, rtxn, f->f_ava, ids, tmp, LDAP_FILTER_GE ); +- else +- rc = presence_candidates( op, rtxn, f->f_ava->aa_desc, ids ); +- break; +- +- case LDAP_FILTER_LE: +- /* if no LE index, use pres */ +- Debug( LDAP_DEBUG_FILTER, "\tLE\n", 0, 0, 0 ); +- if( f->f_ava->aa_desc->ad_type->sat_ordering && +- ( f->f_ava->aa_desc->ad_type->sat_ordering->smr_usage & SLAP_MR_ORDERED_INDEX ) ) +- rc = inequality_candidates( op, rtxn, f->f_ava, ids, tmp, LDAP_FILTER_LE ); +- else +- rc = presence_candidates( op, rtxn, f->f_ava->aa_desc, ids ); +- break; +- +- case LDAP_FILTER_NOT: +- /* no indexing to support NOT filters */ +- Debug( LDAP_DEBUG_FILTER, "\tNOT\n", 0, 0, 0 ); +- { struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- BDB_IDL_ALL( bdb, ids ); +- } +- break; +- +- case LDAP_FILTER_AND: +- Debug( LDAP_DEBUG_FILTER, "\tAND\n", 0, 0, 0 ); +- rc = list_candidates( op, rtxn, +- f->f_and, LDAP_FILTER_AND, ids, tmp, stack ); +- break; +- +- case LDAP_FILTER_OR: +- Debug( LDAP_DEBUG_FILTER, "\tOR\n", 0, 0, 0 ); +- rc = list_candidates( op, rtxn, +- f->f_or, LDAP_FILTER_OR, ids, tmp, stack ); +- break; +- case LDAP_FILTER_EXT: +- Debug( LDAP_DEBUG_FILTER, "\tEXT\n", 0, 0, 0 ); +- rc = ext_candidates( op, rtxn, f->f_mra, ids, tmp, stack ); +- break; +- default: +- Debug( LDAP_DEBUG_FILTER, "\tUNKNOWN %lu\n", +- (unsigned long) f->f_choice, 0, 0 ); +- /* Must not return NULL, otherwise extended filters break */ +- { struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- BDB_IDL_ALL( bdb, ids ); +- } +- } +- +-out: +- Debug( LDAP_DEBUG_FILTER, +- "<= bdb_filter_candidates: id=%ld first=%ld last=%ld\n", +- (long) ids[0], +- (long) BDB_IDL_FIRST( ids ), +- (long) BDB_IDL_LAST( ids ) ); +- +- return rc; +-} +- +-#ifdef LDAP_COMP_MATCH +-static int +-comp_list_candidates( +- Operation *op, +- DB_TXN *rtxn, +- MatchingRuleAssertion* mra, +- ComponentFilter *flist, +- int ftype, +- ID *ids, +- ID *tmp, +- ID *save ) +-{ +- int rc = 0; +- ComponentFilter *f; +- +- Debug( LDAP_DEBUG_FILTER, "=> comp_list_candidates 0x%x\n", ftype, 0, 0 ); +- for ( f = flist; f != NULL; f = f->cf_next ) { +- /* ignore precomputed scopes */ +- if ( f->cf_choice == SLAPD_FILTER_COMPUTED && +- f->cf_result == LDAP_SUCCESS ) { +- continue; +- } +- BDB_IDL_ZERO( save ); +- rc = comp_candidates( op, rtxn, mra, f, save, tmp, save+BDB_IDL_UM_SIZE ); +- +- if ( rc != 0 ) { +- if ( ftype == LDAP_COMP_FILTER_AND ) { +- rc = 0; +- continue; +- } +- break; +- } +- +- if ( ftype == LDAP_COMP_FILTER_AND ) { +- if ( f == flist ) { +- BDB_IDL_CPY( ids, save ); +- } else { +- bdb_idl_intersection( ids, save ); +- } +- if( BDB_IDL_IS_ZERO( ids ) ) +- break; +- } else { +- if ( f == flist ) { +- BDB_IDL_CPY( ids, save ); +- } else { +- bdb_idl_union( ids, save ); +- } +- } +- } +- +- if( rc == LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_FILTER, +- "<= comp_list_candidates: id=%ld first=%ld last=%ld\n", +- (long) ids[0], +- (long) BDB_IDL_FIRST(ids), +- (long) BDB_IDL_LAST(ids) ); +- +- } else { +- Debug( LDAP_DEBUG_FILTER, +- "<= comp_list_candidates: undefined rc=%d\n", +- rc, 0, 0 ); +- } +- +- return rc; +-} +- +-static int +-comp_equality_candidates ( +- Operation *op, +- DB_TXN *rtxn, +- MatchingRuleAssertion *mra, +- ComponentAssertion *ca, +- ID *ids, +- ID *tmp, +- ID *stack) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- DB *db; +- int i; +- int rc; +- slap_mask_t mask; +- struct berval prefix = {0, NULL}; +- struct berval *keys = NULL; +- MatchingRule *mr = mra->ma_rule; +- Syntax *sat_syntax; +- ComponentReference* cr_list, *cr; +- AttrInfo *ai; +- +- BDB_IDL_ALL( bdb, ids ); +- +- if ( !ca->ca_comp_ref ) +- return 0; +- +- ai = bdb_attr_mask( op->o_bd->be_private, mra->ma_desc ); +- if( ai ) { +- cr_list = ai->ai_cr; +- } +- else { +- return 0; +- } +- /* find a component reference to be indexed */ +- sat_syntax = ca->ca_ma_rule->smr_syntax; +- for ( cr = cr_list ; cr ; cr = cr->cr_next ) { +- if ( cr->cr_string.bv_len == ca->ca_comp_ref->cr_string.bv_len && +- strncmp( cr->cr_string.bv_val, ca->ca_comp_ref->cr_string.bv_val,cr->cr_string.bv_len ) == 0 ) +- break; +- } +- +- if ( !cr ) +- return 0; +- +- rc = bdb_index_param( op->o_bd, mra->ma_desc, LDAP_FILTER_EQUALITY, +- &db, &mask, &prefix ); +- +- if( rc != LDAP_SUCCESS ) { +- return 0; +- } +- +- if( !mr ) { +- return 0; +- } +- +- if( !mr->smr_filter ) { +- return 0; +- } +- +- rc = (ca->ca_ma_rule->smr_filter)( +- LDAP_FILTER_EQUALITY, +- cr->cr_indexmask, +- sat_syntax, +- ca->ca_ma_rule, +- &prefix, +- &ca->ca_ma_value, +- &keys, op->o_tmpmemctx ); +- +- if( rc != LDAP_SUCCESS ) { +- return 0; +- } +- +- if( keys == NULL ) { +- return 0; +- } +- for ( i= 0; keys[i].bv_val != NULL; i++ ) { +- rc = bdb_key_read( op->o_bd, db, rtxn, &keys[i], tmp, NULL, 0 ); +- +- if( rc == DB_NOTFOUND ) { +- BDB_IDL_ZERO( ids ); +- rc = 0; +- break; +- } else if( rc != LDAP_SUCCESS ) { +- break; +- } +- +- if( BDB_IDL_IS_ZERO( tmp ) ) { +- BDB_IDL_ZERO( ids ); +- break; +- } +- +- if ( i == 0 ) { +- BDB_IDL_CPY( ids, tmp ); +- } else { +- bdb_idl_intersection( ids, tmp ); +- } +- +- if( BDB_IDL_IS_ZERO( ids ) ) +- break; +- } +- ber_bvarray_free_x( keys, op->o_tmpmemctx ); +- +- Debug( LDAP_DEBUG_TRACE, +- "<= comp_equality_candidates: id=%ld, first=%ld, last=%ld\n", +- (long) ids[0], +- (long) BDB_IDL_FIRST(ids), +- (long) BDB_IDL_LAST(ids) ); +- return( rc ); +-} +- +-static int +-ava_comp_candidates ( +- Operation *op, +- DB_TXN *rtxn, +- AttributeAssertion *ava, +- AttributeAliasing *aa, +- ID *ids, +- ID *tmp, +- ID *stack ) +-{ +- MatchingRuleAssertion mra; +- +- mra.ma_rule = ava->aa_desc->ad_type->sat_equality; +- if ( !mra.ma_rule ) { +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- BDB_IDL_ALL( bdb, ids ); +- return 0; +- } +- mra.ma_desc = aa->aa_aliased_ad; +- mra.ma_rule = ava->aa_desc->ad_type->sat_equality; +- +- return comp_candidates ( op, rtxn, &mra, ava->aa_cf, ids, tmp, stack ); +-} +- +-static int +-comp_candidates ( +- Operation *op, +- DB_TXN *rtxn, +- MatchingRuleAssertion *mra, +- ComponentFilter *f, +- ID *ids, +- ID *tmp, +- ID *stack) +-{ +- int rc; +- +- if ( !f ) return LDAP_PROTOCOL_ERROR; +- +- Debug( LDAP_DEBUG_FILTER, "comp_candidates\n", 0, 0, 0 ); +- switch ( f->cf_choice ) { +- case SLAPD_FILTER_COMPUTED: +- rc = f->cf_result; +- break; +- case LDAP_COMP_FILTER_AND: +- rc = comp_list_candidates( op, rtxn, mra, f->cf_and, LDAP_COMP_FILTER_AND, ids, tmp, stack ); +- break; +- case LDAP_COMP_FILTER_OR: +- rc = comp_list_candidates( op, rtxn, mra, f->cf_or, LDAP_COMP_FILTER_OR, ids, tmp, stack ); +- break; +- case LDAP_COMP_FILTER_NOT: +- /* No component indexing supported for NOT filter */ +- Debug( LDAP_DEBUG_FILTER, "\tComponent NOT\n", 0, 0, 0 ); +- { +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- BDB_IDL_ALL( bdb, ids ); +- } +- rc = LDAP_PROTOCOL_ERROR; +- break; +- case LDAP_COMP_FILTER_ITEM: +- rc = comp_equality_candidates( op, rtxn, mra, f->cf_ca, ids, tmp, stack ); +- break; +- default: +- { +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- BDB_IDL_ALL( bdb, ids ); +- } +- rc = LDAP_PROTOCOL_ERROR; +- } +- +- return( rc ); +-} +-#endif +- +-static int +-ext_candidates( +- Operation *op, +- DB_TXN *rtxn, +- MatchingRuleAssertion *mra, +- ID *ids, +- ID *tmp, +- ID *stack) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- +-#ifdef LDAP_COMP_MATCH +- /* +- * Currently Only Component Indexing for componentFilterMatch is supported +- * Indexing for an extensible filter is not supported yet +- */ +- if ( mra->ma_cf ) { +- return comp_candidates ( op, rtxn, mra, mra->ma_cf, ids, tmp, stack); +- } +-#endif +- if ( mra->ma_desc == slap_schema.si_ad_entryDN ) { +- int rc; +- EntryInfo *ei; +- +- BDB_IDL_ZERO( ids ); +- if ( mra->ma_rule == slap_schema.si_mr_distinguishedNameMatch ) { +- ei = NULL; +- rc = bdb_cache_find_ndn( op, rtxn, &mra->ma_value, &ei ); +- if ( rc == LDAP_SUCCESS ) +- bdb_idl_insert( ids, ei->bei_id ); +- if ( ei ) +- bdb_cache_entryinfo_unlock( ei ); +- return 0; +- } else if ( mra->ma_rule && mra->ma_rule->smr_match == +- dnRelativeMatch && dnIsSuffix( &mra->ma_value, +- op->o_bd->be_nsuffix )) { +- int scope; +- if ( mra->ma_rule == slap_schema.si_mr_dnSuperiorMatch ) { +- struct berval pdn; +- ei = NULL; +- dnParent( &mra->ma_value, &pdn ); +- bdb_cache_find_ndn( op, rtxn, &pdn, &ei ); +- if ( ei ) { +- bdb_cache_entryinfo_unlock( ei ); +- while ( ei && ei->bei_id ) { +- bdb_idl_insert( ids, ei->bei_id ); +- ei = ei->bei_parent; +- } +- } +- return 0; +- } +- if ( mra->ma_rule == slap_schema.si_mr_dnSubtreeMatch ) +- scope = LDAP_SCOPE_SUBTREE; +- else if ( mra->ma_rule == slap_schema.si_mr_dnOneLevelMatch ) +- scope = LDAP_SCOPE_ONELEVEL; +- else if ( mra->ma_rule == slap_schema.si_mr_dnSubordinateMatch ) +- scope = LDAP_SCOPE_SUBORDINATE; +- else +- scope = LDAP_SCOPE_BASE; +- if ( scope > LDAP_SCOPE_BASE ) { +- ei = NULL; +- rc = bdb_cache_find_ndn( op, rtxn, &mra->ma_value, &ei ); +- if ( ei ) +- bdb_cache_entryinfo_unlock( ei ); +- if ( rc == LDAP_SUCCESS ) { +- int sc = op->ors_scope; +- op->ors_scope = scope; +- rc = bdb_dn2idl( op, rtxn, &mra->ma_value, ei, ids, +- stack ); +- op->ors_scope = sc; +- } +- return 0; +- } +- } +- } +- +- BDB_IDL_ALL( bdb, ids ); +- return 0; +-} +- +-static int +-list_candidates( +- Operation *op, +- DB_TXN *rtxn, +- Filter *flist, +- int ftype, +- ID *ids, +- ID *tmp, +- ID *save ) +-{ +- int rc = 0; +- Filter *f; +- +- Debug( LDAP_DEBUG_FILTER, "=> bdb_list_candidates 0x%x\n", ftype, 0, 0 ); +- for ( f = flist; f != NULL; f = f->f_next ) { +- /* ignore precomputed scopes */ +- if ( f->f_choice == SLAPD_FILTER_COMPUTED && +- f->f_result == LDAP_SUCCESS ) { +- continue; +- } +- BDB_IDL_ZERO( save ); +- rc = bdb_filter_candidates( op, rtxn, f, save, tmp, +- save+BDB_IDL_UM_SIZE ); +- +- if ( rc != 0 ) { +- if ( rc == DB_LOCK_DEADLOCK ) +- return rc; +- +- if ( ftype == LDAP_FILTER_AND ) { +- rc = 0; +- continue; +- } +- break; +- } +- +- +- if ( ftype == LDAP_FILTER_AND ) { +- if ( f == flist ) { +- BDB_IDL_CPY( ids, save ); +- } else { +- bdb_idl_intersection( ids, save ); +- } +- if( BDB_IDL_IS_ZERO( ids ) ) +- break; +- } else { +- if ( f == flist ) { +- BDB_IDL_CPY( ids, save ); +- } else { +- bdb_idl_union( ids, save ); +- } +- } +- } +- +- if( rc == LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_FILTER, +- "<= bdb_list_candidates: id=%ld first=%ld last=%ld\n", +- (long) ids[0], +- (long) BDB_IDL_FIRST(ids), +- (long) BDB_IDL_LAST(ids) ); +- +- } else { +- Debug( LDAP_DEBUG_FILTER, +- "<= bdb_list_candidates: undefined rc=%d\n", +- rc, 0, 0 ); +- } +- +- return rc; +-} +- +-static int +-presence_candidates( +- Operation *op, +- DB_TXN *rtxn, +- AttributeDescription *desc, +- ID *ids ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- DB *db; +- int rc; +- slap_mask_t mask; +- struct berval prefix = {0, NULL}; +- +- Debug( LDAP_DEBUG_TRACE, "=> bdb_presence_candidates (%s)\n", +- desc->ad_cname.bv_val, 0, 0 ); +- +- BDB_IDL_ALL( bdb, ids ); +- +- if( desc == slap_schema.si_ad_objectClass ) { +- return 0; +- } +- +- rc = bdb_index_param( op->o_bd, desc, LDAP_FILTER_PRESENT, +- &db, &mask, &prefix ); +- +- if( rc == LDAP_INAPPROPRIATE_MATCHING ) { +- /* not indexed */ +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_presence_candidates: (%s) not indexed\n", +- desc->ad_cname.bv_val, 0, 0 ); +- return 0; +- } +- +- if( rc != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_presence_candidates: (%s) index_param " +- "returned=%d\n", +- desc->ad_cname.bv_val, rc, 0 ); +- return 0; +- } +- +- if( prefix.bv_val == NULL ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_presence_candidates: (%s) no prefix\n", +- desc->ad_cname.bv_val, 0, 0 ); +- return -1; +- } +- +- rc = bdb_key_read( op->o_bd, db, rtxn, &prefix, ids, NULL, 0 ); +- +- if( rc == DB_NOTFOUND ) { +- BDB_IDL_ZERO( ids ); +- rc = 0; +- } else if( rc != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_presense_candidates: (%s) " +- "key read failed (%d)\n", +- desc->ad_cname.bv_val, rc, 0 ); +- goto done; +- } +- +- Debug(LDAP_DEBUG_TRACE, +- "<= bdb_presence_candidates: id=%ld first=%ld last=%ld\n", +- (long) ids[0], +- (long) BDB_IDL_FIRST(ids), +- (long) BDB_IDL_LAST(ids) ); +- +-done: +- return rc; +-} +- +-static int +-equality_candidates( +- Operation *op, +- DB_TXN *rtxn, +- AttributeAssertion *ava, +- ID *ids, +- ID *tmp ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- DB *db; +- int i; +- int rc; +- slap_mask_t mask; +- struct berval prefix = {0, NULL}; +- struct berval *keys = NULL; +- MatchingRule *mr; +- +- Debug( LDAP_DEBUG_TRACE, "=> bdb_equality_candidates (%s)\n", +- ava->aa_desc->ad_cname.bv_val, 0, 0 ); +- +- if ( ava->aa_desc == slap_schema.si_ad_entryDN ) { +- EntryInfo *ei = NULL; +- rc = bdb_cache_find_ndn( op, rtxn, &ava->aa_value, &ei ); +- if ( rc == LDAP_SUCCESS ) { +- /* exactly one ID can match */ +- ids[0] = 1; +- ids[1] = ei->bei_id; +- } +- if ( ei ) { +- bdb_cache_entryinfo_unlock( ei ); +- } +- if ( rc == DB_NOTFOUND ) { +- BDB_IDL_ZERO( ids ); +- rc = 0; +- } +- return rc; +- } +- +- BDB_IDL_ALL( bdb, ids ); +- +- rc = bdb_index_param( op->o_bd, ava->aa_desc, LDAP_FILTER_EQUALITY, +- &db, &mask, &prefix ); +- +- if ( rc == LDAP_INAPPROPRIATE_MATCHING ) { +- Debug( LDAP_DEBUG_ANY, +- "<= bdb_equality_candidates: (%s) not indexed\n", +- ava->aa_desc->ad_cname.bv_val, 0, 0 ); +- return 0; +- } +- +- if( rc != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_ANY, +- "<= bdb_equality_candidates: (%s) " +- "index_param failed (%d)\n", +- ava->aa_desc->ad_cname.bv_val, rc, 0 ); +- return 0; +- } +- +- mr = ava->aa_desc->ad_type->sat_equality; +- if( !mr ) { +- return 0; +- } +- +- if( !mr->smr_filter ) { +- return 0; +- } +- +- rc = (mr->smr_filter)( +- LDAP_FILTER_EQUALITY, +- mask, +- ava->aa_desc->ad_type->sat_syntax, +- mr, +- &prefix, +- &ava->aa_value, +- &keys, op->o_tmpmemctx ); +- +- if( rc != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_equality_candidates: (%s, %s) " +- "MR filter failed (%d)\n", +- prefix.bv_val, ava->aa_desc->ad_cname.bv_val, rc ); +- return 0; +- } +- +- if( keys == NULL ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_equality_candidates: (%s) no keys\n", +- ava->aa_desc->ad_cname.bv_val, 0, 0 ); +- return 0; +- } +- +- for ( i= 0; keys[i].bv_val != NULL; i++ ) { +- rc = bdb_key_read( op->o_bd, db, rtxn, &keys[i], tmp, NULL, 0 ); +- +- if( rc == DB_NOTFOUND ) { +- BDB_IDL_ZERO( ids ); +- rc = 0; +- break; +- } else if( rc != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_equality_candidates: (%s) " +- "key read failed (%d)\n", +- ava->aa_desc->ad_cname.bv_val, rc, 0 ); +- break; +- } +- +- if( BDB_IDL_IS_ZERO( tmp ) ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_equality_candidates: (%s) NULL\n", +- ava->aa_desc->ad_cname.bv_val, 0, 0 ); +- BDB_IDL_ZERO( ids ); +- break; +- } +- +- if ( i == 0 ) { +- BDB_IDL_CPY( ids, tmp ); +- } else { +- bdb_idl_intersection( ids, tmp ); +- } +- +- if( BDB_IDL_IS_ZERO( ids ) ) +- break; +- } +- +- ber_bvarray_free_x( keys, op->o_tmpmemctx ); +- +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_equality_candidates: id=%ld, first=%ld, last=%ld\n", +- (long) ids[0], +- (long) BDB_IDL_FIRST(ids), +- (long) BDB_IDL_LAST(ids) ); +- return( rc ); +-} +- +- +-static int +-approx_candidates( +- Operation *op, +- DB_TXN *rtxn, +- AttributeAssertion *ava, +- ID *ids, +- ID *tmp ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- DB *db; +- int i; +- int rc; +- slap_mask_t mask; +- struct berval prefix = {0, NULL}; +- struct berval *keys = NULL; +- MatchingRule *mr; +- +- Debug( LDAP_DEBUG_TRACE, "=> bdb_approx_candidates (%s)\n", +- ava->aa_desc->ad_cname.bv_val, 0, 0 ); +- +- BDB_IDL_ALL( bdb, ids ); +- +- rc = bdb_index_param( op->o_bd, ava->aa_desc, LDAP_FILTER_APPROX, +- &db, &mask, &prefix ); +- +- if ( rc == LDAP_INAPPROPRIATE_MATCHING ) { +- Debug( LDAP_DEBUG_ANY, +- "<= bdb_approx_candidates: (%s) not indexed\n", +- ava->aa_desc->ad_cname.bv_val, 0, 0 ); +- return 0; +- } +- +- if( rc != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_ANY, +- "<= bdb_approx_candidates: (%s) " +- "index_param failed (%d)\n", +- ava->aa_desc->ad_cname.bv_val, rc, 0 ); +- return 0; +- } +- +- mr = ava->aa_desc->ad_type->sat_approx; +- if( !mr ) { +- /* no approx matching rule, try equality matching rule */ +- mr = ava->aa_desc->ad_type->sat_equality; +- } +- +- if( !mr ) { +- return 0; +- } +- +- if( !mr->smr_filter ) { +- return 0; +- } +- +- rc = (mr->smr_filter)( +- LDAP_FILTER_APPROX, +- mask, +- ava->aa_desc->ad_type->sat_syntax, +- mr, +- &prefix, +- &ava->aa_value, +- &keys, op->o_tmpmemctx ); +- +- if( rc != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_approx_candidates: (%s, %s) " +- "MR filter failed (%d)\n", +- prefix.bv_val, ava->aa_desc->ad_cname.bv_val, rc ); +- return 0; +- } +- +- if( keys == NULL ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_approx_candidates: (%s) no keys (%s)\n", +- prefix.bv_val, ava->aa_desc->ad_cname.bv_val, 0 ); +- return 0; +- } +- +- for ( i= 0; keys[i].bv_val != NULL; i++ ) { +- rc = bdb_key_read( op->o_bd, db, rtxn, &keys[i], tmp, NULL, 0 ); +- +- if( rc == DB_NOTFOUND ) { +- BDB_IDL_ZERO( ids ); +- rc = 0; +- break; +- } else if( rc != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_approx_candidates: (%s) " +- "key read failed (%d)\n", +- ava->aa_desc->ad_cname.bv_val, rc, 0 ); +- break; +- } +- +- if( BDB_IDL_IS_ZERO( tmp ) ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_approx_candidates: (%s) NULL\n", +- ava->aa_desc->ad_cname.bv_val, 0, 0 ); +- BDB_IDL_ZERO( ids ); +- break; +- } +- +- if ( i == 0 ) { +- BDB_IDL_CPY( ids, tmp ); +- } else { +- bdb_idl_intersection( ids, tmp ); +- } +- +- if( BDB_IDL_IS_ZERO( ids ) ) +- break; +- } +- +- ber_bvarray_free_x( keys, op->o_tmpmemctx ); +- +- Debug( LDAP_DEBUG_TRACE, "<= bdb_approx_candidates %ld, first=%ld, last=%ld\n", +- (long) ids[0], +- (long) BDB_IDL_FIRST(ids), +- (long) BDB_IDL_LAST(ids) ); +- return( rc ); +-} +- +-static int +-substring_candidates( +- Operation *op, +- DB_TXN *rtxn, +- SubstringsAssertion *sub, +- ID *ids, +- ID *tmp ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- DB *db; +- int i; +- int rc; +- slap_mask_t mask; +- struct berval prefix = {0, NULL}; +- struct berval *keys = NULL; +- MatchingRule *mr; +- +- Debug( LDAP_DEBUG_TRACE, "=> bdb_substring_candidates (%s)\n", +- sub->sa_desc->ad_cname.bv_val, 0, 0 ); +- +- BDB_IDL_ALL( bdb, ids ); +- +- rc = bdb_index_param( op->o_bd, sub->sa_desc, LDAP_FILTER_SUBSTRINGS, +- &db, &mask, &prefix ); +- +- if ( rc == LDAP_INAPPROPRIATE_MATCHING ) { +- Debug( LDAP_DEBUG_ANY, +- "<= bdb_substring_candidates: (%s) not indexed\n", +- sub->sa_desc->ad_cname.bv_val, 0, 0 ); +- return 0; +- } +- +- if( rc != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_ANY, +- "<= bdb_substring_candidates: (%s) " +- "index_param failed (%d)\n", +- sub->sa_desc->ad_cname.bv_val, rc, 0 ); +- return 0; +- } +- +- mr = sub->sa_desc->ad_type->sat_substr; +- +- if( !mr ) { +- return 0; +- } +- +- if( !mr->smr_filter ) { +- return 0; +- } +- +- rc = (mr->smr_filter)( +- LDAP_FILTER_SUBSTRINGS, +- mask, +- sub->sa_desc->ad_type->sat_syntax, +- mr, +- &prefix, +- sub, +- &keys, op->o_tmpmemctx ); +- +- if( rc != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_substring_candidates: (%s) " +- "MR filter failed (%d)\n", +- sub->sa_desc->ad_cname.bv_val, rc, 0 ); +- return 0; +- } +- +- if( keys == NULL ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_substring_candidates: (0x%04lx) no keys (%s)\n", +- mask, sub->sa_desc->ad_cname.bv_val, 0 ); +- return 0; +- } +- +- for ( i= 0; keys[i].bv_val != NULL; i++ ) { +- rc = bdb_key_read( op->o_bd, db, rtxn, &keys[i], tmp, NULL, 0 ); +- +- if( rc == DB_NOTFOUND ) { +- BDB_IDL_ZERO( ids ); +- rc = 0; +- break; +- } else if( rc != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_substring_candidates: (%s) " +- "key read failed (%d)\n", +- sub->sa_desc->ad_cname.bv_val, rc, 0 ); +- break; +- } +- +- if( BDB_IDL_IS_ZERO( tmp ) ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_substring_candidates: (%s) NULL\n", +- sub->sa_desc->ad_cname.bv_val, 0, 0 ); +- BDB_IDL_ZERO( ids ); +- break; +- } +- +- if ( i == 0 ) { +- BDB_IDL_CPY( ids, tmp ); +- } else { +- bdb_idl_intersection( ids, tmp ); +- } +- +- if( BDB_IDL_IS_ZERO( ids ) ) +- break; +- } +- +- ber_bvarray_free_x( keys, op->o_tmpmemctx ); +- +- Debug( LDAP_DEBUG_TRACE, "<= bdb_substring_candidates: %ld, first=%ld, last=%ld\n", +- (long) ids[0], +- (long) BDB_IDL_FIRST(ids), +- (long) BDB_IDL_LAST(ids) ); +- return( rc ); +-} +- +-static int +-inequality_candidates( +- Operation *op, +- DB_TXN *rtxn, +- AttributeAssertion *ava, +- ID *ids, +- ID *tmp, +- int gtorlt ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- DB *db; +- int rc; +- slap_mask_t mask; +- struct berval prefix = {0, NULL}; +- struct berval *keys = NULL; +- MatchingRule *mr; +- DBC * cursor = NULL; +- +- Debug( LDAP_DEBUG_TRACE, "=> bdb_inequality_candidates (%s)\n", +- ava->aa_desc->ad_cname.bv_val, 0, 0 ); +- +- BDB_IDL_ALL( bdb, ids ); +- +- rc = bdb_index_param( op->o_bd, ava->aa_desc, LDAP_FILTER_EQUALITY, +- &db, &mask, &prefix ); +- +- if ( rc == LDAP_INAPPROPRIATE_MATCHING ) { +- Debug( LDAP_DEBUG_ANY, +- "<= bdb_inequality_candidates: (%s) not indexed\n", +- ava->aa_desc->ad_cname.bv_val, 0, 0 ); +- return 0; +- } +- +- if( rc != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_ANY, +- "<= bdb_inequality_candidates: (%s) " +- "index_param failed (%d)\n", +- ava->aa_desc->ad_cname.bv_val, rc, 0 ); +- return 0; +- } +- +- mr = ava->aa_desc->ad_type->sat_equality; +- if( !mr ) { +- return 0; +- } +- +- if( !mr->smr_filter ) { +- return 0; +- } +- +- rc = (mr->smr_filter)( +- LDAP_FILTER_EQUALITY, +- mask, +- ava->aa_desc->ad_type->sat_syntax, +- mr, +- &prefix, +- &ava->aa_value, +- &keys, op->o_tmpmemctx ); +- +- if( rc != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_inequality_candidates: (%s, %s) " +- "MR filter failed (%d)\n", +- prefix.bv_val, ava->aa_desc->ad_cname.bv_val, rc ); +- return 0; +- } +- +- if( keys == NULL ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_inequality_candidates: (%s) no keys\n", +- ava->aa_desc->ad_cname.bv_val, 0, 0 ); +- return 0; +- } +- +- BDB_IDL_ZERO( ids ); +- while(1) { +- rc = bdb_key_read( op->o_bd, db, rtxn, &keys[0], tmp, &cursor, gtorlt ); +- +- if( rc == DB_NOTFOUND ) { +- rc = 0; +- break; +- } else if( rc != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_inequality_candidates: (%s) " +- "key read failed (%d)\n", +- ava->aa_desc->ad_cname.bv_val, rc, 0 ); +- break; +- } +- +- if( BDB_IDL_IS_ZERO( tmp ) ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_inequality_candidates: (%s) NULL\n", +- ava->aa_desc->ad_cname.bv_val, 0, 0 ); +- break; +- } +- +- bdb_idl_union( ids, tmp ); +- +- if( op->ors_limit && op->ors_limit->lms_s_unchecked != -1 && +- BDB_IDL_N( ids ) >= (unsigned) op->ors_limit->lms_s_unchecked ) { +- cursor->c_close( cursor ); +- break; +- } +- } +- ber_bvarray_free_x( keys, op->o_tmpmemctx ); +- +- Debug( LDAP_DEBUG_TRACE, +- "<= bdb_inequality_candidates: id=%ld, first=%ld, last=%ld\n", +- (long) ids[0], +- (long) BDB_IDL_FIRST(ids), +- (long) BDB_IDL_LAST(ids) ); +- return( rc ); +-} +diff --git a/servers/slapd/back-bdb/id2entry.c b/servers/slapd/back-bdb/id2entry.c +deleted file mode 100644 +index cc00098..0000000 +--- a/servers/slapd/back-bdb/id2entry.c ++++ /dev/null +@@ -1,446 +0,0 @@ +-/* id2entry.c - routines to deal with the id2entry database */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +-#include +-#include +- +-#include "back-bdb.h" +- +-static int bdb_id2entry_put( +- BackendDB *be, +- DB_TXN *tid, +- Entry *e, +- int flag ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) be->be_private; +- DB *db = bdb->bi_id2entry->bdi_db; +- DBT key, data; +- struct berval bv; +- int rc; +- ID nid; +-#ifdef BDB_HIER +- struct berval odn, ondn; +- +- /* We only store rdns, and they go in the dn2id database. */ +- +- odn = e->e_name; ondn = e->e_nname; +- +- e->e_name = slap_empty_bv; +- e->e_nname = slap_empty_bv; +-#endif +- DBTzero( &key ); +- +- /* Store ID in BigEndian format */ +- key.data = &nid; +- key.size = sizeof(ID); +- BDB_ID2DISK( e->e_id, &nid ); +- +- rc = entry_encode( e, &bv ); +-#ifdef BDB_HIER +- e->e_name = odn; e->e_nname = ondn; +-#endif +- if( rc != LDAP_SUCCESS ) { +- return -1; +- } +- +- DBTzero( &data ); +- bv2DBT( &bv, &data ); +- +- rc = db->put( db, tid, &key, &data, flag ); +- +- free( bv.bv_val ); +- return rc; +-} +- +-/* +- * This routine adds (or updates) an entry on disk. +- * The cache should be already be updated. +- */ +- +- +-int bdb_id2entry_add( +- BackendDB *be, +- DB_TXN *tid, +- Entry *e ) +-{ +- return bdb_id2entry_put(be, tid, e, DB_NOOVERWRITE); +-} +- +-int bdb_id2entry_update( +- BackendDB *be, +- DB_TXN *tid, +- Entry *e ) +-{ +- return bdb_id2entry_put(be, tid, e, 0); +-} +- +-int bdb_id2entry( +- BackendDB *be, +- DB_TXN *tid, +- ID id, +- Entry **e ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) be->be_private; +- DB *db = bdb->bi_id2entry->bdi_db; +- DBT key, data; +- DBC *cursor; +- EntryHeader eh; +- char buf[16]; +- int rc = 0, off; +- ID nid; +- +- *e = NULL; +- +- DBTzero( &key ); +- key.data = &nid; +- key.size = sizeof(ID); +- BDB_ID2DISK( id, &nid ); +- +- DBTzero( &data ); +- data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; +- +- /* fetch it */ +- rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags ); +- if ( rc ) return rc; +- +- /* Get the nattrs / nvals counts first */ +- data.ulen = data.dlen = sizeof(buf); +- data.data = buf; +- rc = cursor->c_get( cursor, &key, &data, DB_SET ); +- if ( rc ) goto finish; +- +- +- eh.bv.bv_val = buf; +- eh.bv.bv_len = data.size; +- rc = entry_header( &eh ); +- if ( rc ) goto finish; +- +- if ( eh.nvals ) { +- /* Get the size */ +- data.flags ^= DB_DBT_PARTIAL; +- data.ulen = 0; +- rc = cursor->c_get( cursor, &key, &data, DB_CURRENT ); +- if ( rc != DB_BUFFER_SMALL ) goto finish; +- +- /* Allocate a block and retrieve the data */ +- off = eh.data - eh.bv.bv_val; +- eh.bv.bv_len = eh.nvals * sizeof( struct berval ) + data.size; +- eh.bv.bv_val = ch_malloc( eh.bv.bv_len ); +- eh.data = eh.bv.bv_val + eh.nvals * sizeof( struct berval ); +- data.data = eh.data; +- data.ulen = data.size; +- +- /* skip past already parsed nattr/nvals */ +- eh.data += off; +- +- rc = cursor->c_get( cursor, &key, &data, DB_CURRENT ); +- } +- +-finish: +- cursor->c_close( cursor ); +- +- if( rc != 0 ) { +- return rc; +- } +- +- if ( eh.nvals ) { +-#ifdef SLAP_ZONE_ALLOC +- rc = entry_decode(&eh, e, bdb->bi_cache.c_zctx); +-#else +- rc = entry_decode(&eh, e); +-#endif +- } else { +- *e = entry_alloc(); +- } +- +- if( rc == 0 ) { +- (*e)->e_id = id; +- } else { +- /* only free on error. On success, the entry was +- * decoded in place. +- */ +-#ifndef SLAP_ZONE_ALLOC +- ch_free(eh.bv.bv_val); +-#endif +- } +-#ifdef SLAP_ZONE_ALLOC +- ch_free(eh.bv.bv_val); +-#endif +- +- return rc; +-} +- +-int bdb_id2entry_delete( +- BackendDB *be, +- DB_TXN *tid, +- Entry *e ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) be->be_private; +- DB *db = bdb->bi_id2entry->bdi_db; +- DBT key; +- int rc; +- ID nid; +- +- DBTzero( &key ); +- key.data = &nid; +- key.size = sizeof(ID); +- BDB_ID2DISK( e->e_id, &nid ); +- +- /* delete from database */ +- rc = db->del( db, tid, &key, 0 ); +- +- return rc; +-} +- +-int bdb_entry_return( +- Entry *e +-) +-{ +- /* Our entries are allocated in two blocks; the data comes from +- * the db itself and the Entry structure and associated pointers +- * are allocated in entry_decode. The db data pointer is saved +- * in e_bv. +- */ +- if ( e->e_bv.bv_val ) { +- /* See if the DNs were changed by modrdn */ +- if( e->e_nname.bv_val < e->e_bv.bv_val || e->e_nname.bv_val > +- e->e_bv.bv_val + e->e_bv.bv_len ) { +- ch_free(e->e_name.bv_val); +- ch_free(e->e_nname.bv_val); +- } +- e->e_name.bv_val = NULL; +- e->e_nname.bv_val = NULL; +- /* In tool mode the e_bv buffer is realloc'd, leave it alone */ +- if( !(slapMode & SLAP_TOOL_MODE) ) { +- free( e->e_bv.bv_val ); +- } +- BER_BVZERO( &e->e_bv ); +- } +- entry_free( e ); +- return 0; +-} +- +-int bdb_entry_release( +- Operation *op, +- Entry *e, +- int rw ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- struct bdb_op_info *boi; +- OpExtra *oex; +- +- /* slapMode : SLAP_SERVER_MODE, SLAP_TOOL_MODE, +- SLAP_TRUNCATE_MODE, SLAP_UNDEFINED_MODE */ +- +- if ( slapMode & SLAP_SERVER_MODE ) { +- /* If not in our cache, just free it */ +- if ( !e->e_private ) { +-#ifdef SLAP_ZONE_ALLOC +- return bdb_entry_return( bdb, e, -1 ); +-#else +- return bdb_entry_return( e ); +-#endif +- } +- /* free entry and reader or writer lock */ +- LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) { +- if ( oex->oe_key == bdb ) break; +- } +- boi = (struct bdb_op_info *)oex; +- +- /* lock is freed with txn */ +- if ( !boi || boi->boi_txn ) { +- bdb_unlocked_cache_return_entry_rw( bdb, e, rw ); +- } else { +- struct bdb_lock_info *bli, *prev; +- for ( prev=(struct bdb_lock_info *)&boi->boi_locks, +- bli = boi->boi_locks; bli; prev=bli, bli=bli->bli_next ) { +- if ( bli->bli_id == e->e_id ) { +- bdb_cache_return_entry_rw( bdb, e, rw, &bli->bli_lock ); +- prev->bli_next = bli->bli_next; +- /* Cleanup, or let caller know we unlocked */ +- if ( bli->bli_flag & BLI_DONTFREE ) +- bli->bli_flag = 0; +- else +- op->o_tmpfree( bli, op->o_tmpmemctx ); +- break; +- } +- } +- if ( !boi->boi_locks ) { +- LDAP_SLIST_REMOVE( &op->o_extra, &boi->boi_oe, OpExtra, oe_next ); +- if ( !(boi->boi_flag & BOI_DONTFREE)) +- op->o_tmpfree( boi, op->o_tmpmemctx ); +- } +- } +- } else { +-#ifdef SLAP_ZONE_ALLOC +- int zseq = -1; +- if (e->e_private != NULL) { +- BEI(e)->bei_e = NULL; +- zseq = BEI(e)->bei_zseq; +- } +-#else +- if (e->e_private != NULL) +- BEI(e)->bei_e = NULL; +-#endif +- e->e_private = NULL; +-#ifdef SLAP_ZONE_ALLOC +- bdb_entry_return ( bdb, e, zseq ); +-#else +- bdb_entry_return ( e ); +-#endif +- } +- +- return 0; +-} +- +-/* return LDAP_SUCCESS IFF we can retrieve the specified entry. +- */ +-int bdb_entry_get( +- Operation *op, +- struct berval *ndn, +- ObjectClass *oc, +- AttributeDescription *at, +- int rw, +- Entry **ent ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- struct bdb_op_info *boi = NULL; +- DB_TXN *txn = NULL; +- Entry *e = NULL; +- EntryInfo *ei; +- int rc; +- const char *at_name = at ? at->ad_cname.bv_val : "(null)"; +- +- DB_LOCK lock; +- +- Debug( LDAP_DEBUG_ARGS, +- "=> bdb_entry_get: ndn: \"%s\"\n", ndn->bv_val, 0, 0 ); +- Debug( LDAP_DEBUG_ARGS, +- "=> bdb_entry_get: oc: \"%s\", at: \"%s\"\n", +- oc ? oc->soc_cname.bv_val : "(null)", at_name, 0); +- +- if( op ) { +- OpExtra *oex; +- LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) { +- if ( oex->oe_key == bdb ) break; +- } +- boi = (struct bdb_op_info *)oex; +- if ( boi ) +- txn = boi->boi_txn; +- } +- +- if ( !txn ) { +- rc = bdb_reader_get( op, bdb->bi_dbenv, &txn ); +- switch(rc) { +- case 0: +- break; +- default: +- return LDAP_OTHER; +- } +- } +- +-dn2entry_retry: +- /* can we find entry */ +- rc = bdb_dn2entry( op, txn, ndn, &ei, 0, &lock ); +- switch( rc ) { +- case DB_NOTFOUND: +- case 0: +- break; +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- /* the txn must abort and retry */ +- if ( txn ) { +- if ( boi ) boi->boi_err = rc; +- return LDAP_BUSY; +- } +- ldap_pvt_thread_yield(); +- goto dn2entry_retry; +- default: +- if ( boi ) boi->boi_err = rc; +- return (rc != LDAP_BUSY) ? LDAP_OTHER : LDAP_BUSY; +- } +- if (ei) e = ei->bei_e; +- if (e == NULL) { +- Debug( LDAP_DEBUG_ACL, +- "=> bdb_entry_get: cannot find entry: \"%s\"\n", +- ndn->bv_val, 0, 0 ); +- return LDAP_NO_SUCH_OBJECT; +- } +- +- Debug( LDAP_DEBUG_ACL, +- "=> bdb_entry_get: found entry: \"%s\"\n", +- ndn->bv_val, 0, 0 ); +- +- if ( oc && !is_entry_objectclass( e, oc, 0 )) { +- Debug( LDAP_DEBUG_ACL, +- "<= bdb_entry_get: failed to find objectClass %s\n", +- oc->soc_cname.bv_val, 0, 0 ); +- rc = LDAP_NO_SUCH_ATTRIBUTE; +- goto return_results; +- } +- +- /* NOTE: attr_find() or attrs_find()? */ +- if ( at && attr_find( e->e_attrs, at ) == NULL ) { +- Debug( LDAP_DEBUG_ACL, +- "<= bdb_entry_get: failed to find attribute %s\n", +- at->ad_cname.bv_val, 0, 0 ); +- rc = LDAP_NO_SUCH_ATTRIBUTE; +- goto return_results; +- } +- +-return_results: +- if( rc != LDAP_SUCCESS ) { +- /* free entry */ +- bdb_cache_return_entry_rw(bdb, e, rw, &lock); +- +- } else { +- if ( slapMode & SLAP_SERVER_MODE ) { +- *ent = e; +- /* big drag. we need a place to store a read lock so we can +- * release it later?? If we're in a txn, nothing is needed +- * here because the locks will go away with the txn. +- */ +- if ( op ) { +- if ( !boi ) { +- boi = op->o_tmpcalloc(1,sizeof(struct bdb_op_info),op->o_tmpmemctx); +- boi->boi_oe.oe_key = bdb; +- LDAP_SLIST_INSERT_HEAD( &op->o_extra, &boi->boi_oe, oe_next ); +- } +- if ( !boi->boi_txn ) { +- struct bdb_lock_info *bli; +- bli = op->o_tmpalloc( sizeof(struct bdb_lock_info), +- op->o_tmpmemctx ); +- bli->bli_next = boi->boi_locks; +- bli->bli_id = e->e_id; +- bli->bli_flag = 0; +- bli->bli_lock = lock; +- boi->boi_locks = bli; +- } +- } +- } else { +- *ent = entry_dup( e ); +- bdb_cache_return_entry_rw(bdb, e, rw, &lock); +- } +- } +- +- Debug( LDAP_DEBUG_TRACE, +- "bdb_entry_get: rc=%d\n", +- rc, 0, 0 ); +- return(rc); +-} +diff --git a/servers/slapd/back-bdb/idl.c b/servers/slapd/back-bdb/idl.c +deleted file mode 100644 +index d0c13a6..0000000 +--- a/servers/slapd/back-bdb/idl.c ++++ /dev/null +@@ -1,1570 +0,0 @@ +-/* idl.c - ldap id list handling routines */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +-#include +- +-#include "back-bdb.h" +-#include "idl.h" +- +-#define IDL_MAX(x,y) ( (x) > (y) ? (x) : (y) ) +-#define IDL_MIN(x,y) ( (x) < (y) ? (x) : (y) ) +-#define IDL_CMP(x,y) ( (x) < (y) ? -1 : (x) > (y) ) +- +-#define IDL_LRU_DELETE( bdb, e ) do { \ +- if ( (e) == (bdb)->bi_idl_lru_head ) { \ +- if ( (e)->idl_lru_next == (bdb)->bi_idl_lru_head ) { \ +- (bdb)->bi_idl_lru_head = NULL; \ +- } else { \ +- (bdb)->bi_idl_lru_head = (e)->idl_lru_next; \ +- } \ +- } \ +- if ( (e) == (bdb)->bi_idl_lru_tail ) { \ +- if ( (e)->idl_lru_prev == (bdb)->bi_idl_lru_tail ) { \ +- assert( (bdb)->bi_idl_lru_head == NULL ); \ +- (bdb)->bi_idl_lru_tail = NULL; \ +- } else { \ +- (bdb)->bi_idl_lru_tail = (e)->idl_lru_prev; \ +- } \ +- } \ +- (e)->idl_lru_next->idl_lru_prev = (e)->idl_lru_prev; \ +- (e)->idl_lru_prev->idl_lru_next = (e)->idl_lru_next; \ +-} while ( 0 ) +- +-static int +-bdb_idl_entry_cmp( const void *v_idl1, const void *v_idl2 ) +-{ +- const bdb_idl_cache_entry_t *idl1 = v_idl1, *idl2 = v_idl2; +- int rc; +- +- if ((rc = SLAP_PTRCMP( idl1->db, idl2->db ))) return rc; +- if ((rc = idl1->kstr.bv_len - idl2->kstr.bv_len )) return rc; +- return ( memcmp ( idl1->kstr.bv_val, idl2->kstr.bv_val , idl1->kstr.bv_len ) ); +-} +- +-#if IDL_DEBUG > 0 +-static void idl_check( ID *ids ) +-{ +- if( BDB_IDL_IS_RANGE( ids ) ) { +- assert( BDB_IDL_RANGE_FIRST(ids) <= BDB_IDL_RANGE_LAST(ids) ); +- } else { +- ID i; +- for( i=1; i < ids[0]; i++ ) { +- assert( ids[i+1] > ids[i] ); +- } +- } +-} +- +-#if IDL_DEBUG > 1 +-static void idl_dump( ID *ids ) +-{ +- if( BDB_IDL_IS_RANGE( ids ) ) { +- Debug( LDAP_DEBUG_ANY, +- "IDL: range ( %ld - %ld )\n", +- (long) BDB_IDL_RANGE_FIRST( ids ), +- (long) BDB_IDL_RANGE_LAST( ids ) ); +- +- } else { +- ID i; +- Debug( LDAP_DEBUG_ANY, "IDL: size %ld", (long) ids[0], 0, 0 ); +- +- for( i=1; i<=ids[0]; i++ ) { +- if( i % 16 == 1 ) { +- Debug( LDAP_DEBUG_ANY, "\n", 0, 0, 0 ); +- } +- Debug( LDAP_DEBUG_ANY, " %02lx", (long) ids[i], 0, 0 ); +- } +- +- Debug( LDAP_DEBUG_ANY, "\n", 0, 0, 0 ); +- } +- +- idl_check( ids ); +-} +-#endif /* IDL_DEBUG > 1 */ +-#endif /* IDL_DEBUG > 0 */ +- +-unsigned bdb_idl_search( ID *ids, ID id ) +-{ +-#define IDL_BINARY_SEARCH 1 +-#ifdef IDL_BINARY_SEARCH +- /* +- * binary search of id in ids +- * if found, returns position of id +- * if not found, returns first postion greater than id +- */ +- unsigned base = 0; +- unsigned cursor = 1; +- int val = 0; +- unsigned n = ids[0]; +- +-#if IDL_DEBUG > 0 +- idl_check( ids ); +-#endif +- +- while( 0 < n ) { +- unsigned pivot = n >> 1; +- cursor = base + pivot + 1; +- val = IDL_CMP( id, ids[cursor] ); +- +- if( val < 0 ) { +- n = pivot; +- +- } else if ( val > 0 ) { +- base = cursor; +- n -= pivot + 1; +- +- } else { +- return cursor; +- } +- } +- +- if( val > 0 ) { +- ++cursor; +- } +- return cursor; +- +-#else +- /* (reverse) linear search */ +- int i; +- +-#if IDL_DEBUG > 0 +- idl_check( ids ); +-#endif +- +- for( i=ids[0]; i; i-- ) { +- if( id > ids[i] ) { +- break; +- } +- } +- +- return i+1; +-#endif +-} +- +-int bdb_idl_insert( ID *ids, ID id ) +-{ +- unsigned x; +- +-#if IDL_DEBUG > 1 +- Debug( LDAP_DEBUG_ANY, "insert: %04lx at %d\n", (long) id, x, 0 ); +- idl_dump( ids ); +-#elif IDL_DEBUG > 0 +- idl_check( ids ); +-#endif +- +- if (BDB_IDL_IS_RANGE( ids )) { +- /* if already in range, treat as a dup */ +- if (id >= BDB_IDL_RANGE_FIRST(ids) && id <= BDB_IDL_RANGE_LAST(ids)) +- return -1; +- if (id < BDB_IDL_RANGE_FIRST(ids)) +- ids[1] = id; +- else if (id > BDB_IDL_RANGE_LAST(ids)) +- ids[2] = id; +- return 0; +- } +- +- x = bdb_idl_search( ids, id ); +- assert( x > 0 ); +- +- if( x < 1 ) { +- /* internal error */ +- return -2; +- } +- +- if ( x <= ids[0] && ids[x] == id ) { +- /* duplicate */ +- return -1; +- } +- +- if ( ++ids[0] >= BDB_IDL_DB_MAX ) { +- if( id < ids[1] ) { +- ids[1] = id; +- ids[2] = ids[ids[0]-1]; +- } else if ( ids[ids[0]-1] < id ) { +- ids[2] = id; +- } else { +- ids[2] = ids[ids[0]-1]; +- } +- ids[0] = NOID; +- +- } else { +- /* insert id */ +- AC_MEMCPY( &ids[x+1], &ids[x], (ids[0]-x) * sizeof(ID) ); +- ids[x] = id; +- } +- +-#if IDL_DEBUG > 1 +- idl_dump( ids ); +-#elif IDL_DEBUG > 0 +- idl_check( ids ); +-#endif +- +- return 0; +-} +- +-int bdb_idl_delete( ID *ids, ID id ) +-{ +- unsigned x; +- +-#if IDL_DEBUG > 1 +- Debug( LDAP_DEBUG_ANY, "delete: %04lx at %d\n", (long) id, x, 0 ); +- idl_dump( ids ); +-#elif IDL_DEBUG > 0 +- idl_check( ids ); +-#endif +- +- if (BDB_IDL_IS_RANGE( ids )) { +- /* If deleting a range boundary, adjust */ +- if ( ids[1] == id ) +- ids[1]++; +- else if ( ids[2] == id ) +- ids[2]--; +- /* deleting from inside a range is a no-op */ +- +- /* If the range has collapsed, re-adjust */ +- if ( ids[1] > ids[2] ) +- ids[0] = 0; +- else if ( ids[1] == ids[2] ) +- ids[1] = 1; +- return 0; +- } +- +- x = bdb_idl_search( ids, id ); +- assert( x > 0 ); +- +- if( x <= 0 ) { +- /* internal error */ +- return -2; +- } +- +- if( x > ids[0] || ids[x] != id ) { +- /* not found */ +- return -1; +- +- } else if ( --ids[0] == 0 ) { +- if( x != 1 ) { +- return -3; +- } +- +- } else { +- AC_MEMCPY( &ids[x], &ids[x+1], (1+ids[0]-x) * sizeof(ID) ); +- } +- +-#if IDL_DEBUG > 1 +- idl_dump( ids ); +-#elif IDL_DEBUG > 0 +- idl_check( ids ); +-#endif +- +- return 0; +-} +- +-static char * +-bdb_show_key( +- DBT *key, +- char *buf ) +-{ +- if ( key->size == 4 /* LUTIL_HASH_BYTES */ ) { +- unsigned char *c = key->data; +- sprintf( buf, "[%02x%02x%02x%02x]", c[0], c[1], c[2], c[3] ); +- return buf; +- } else { +- return key->data; +- } +-} +- +-/* Find a db/key pair in the IDL cache. If ids is non-NULL, +- * copy the cached IDL into it, otherwise just return the status. +- */ +-int +-bdb_idl_cache_get( +- struct bdb_info *bdb, +- DB *db, +- DBT *key, +- ID *ids ) +-{ +- bdb_idl_cache_entry_t idl_tmp; +- bdb_idl_cache_entry_t *matched_idl_entry; +- int rc = LDAP_NO_SUCH_OBJECT; +- +- DBT2bv( key, &idl_tmp.kstr ); +- idl_tmp.db = db; +- ldap_pvt_thread_rdwr_rlock( &bdb->bi_idl_tree_rwlock ); +- matched_idl_entry = avl_find( bdb->bi_idl_tree, &idl_tmp, +- bdb_idl_entry_cmp ); +- if ( matched_idl_entry != NULL ) { +- if ( matched_idl_entry->idl && ids ) +- BDB_IDL_CPY( ids, matched_idl_entry->idl ); +- matched_idl_entry->idl_flags |= CACHE_ENTRY_REFERENCED; +- if ( matched_idl_entry->idl ) +- rc = LDAP_SUCCESS; +- else +- rc = DB_NOTFOUND; +- } +- ldap_pvt_thread_rdwr_runlock( &bdb->bi_idl_tree_rwlock ); +- +- return rc; +-} +- +-void +-bdb_idl_cache_put( +- struct bdb_info *bdb, +- DB *db, +- DBT *key, +- ID *ids, +- int rc ) +-{ +- bdb_idl_cache_entry_t idl_tmp; +- bdb_idl_cache_entry_t *ee, *eprev; +- +- if ( rc == DB_NOTFOUND || BDB_IDL_IS_ZERO( ids )) +- return; +- +- DBT2bv( key, &idl_tmp.kstr ); +- +- ee = (bdb_idl_cache_entry_t *) ch_malloc( +- sizeof( bdb_idl_cache_entry_t ) ); +- ee->db = db; +- ee->idl = (ID*) ch_malloc( BDB_IDL_SIZEOF ( ids ) ); +- BDB_IDL_CPY( ee->idl, ids ); +- +- ee->idl_lru_prev = NULL; +- ee->idl_lru_next = NULL; +- ee->idl_flags = 0; +- ber_dupbv( &ee->kstr, &idl_tmp.kstr ); +- ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock ); +- if ( avl_insert( &bdb->bi_idl_tree, (caddr_t) ee, +- bdb_idl_entry_cmp, avl_dup_error )) +- { +- ch_free( ee->kstr.bv_val ); +- ch_free( ee->idl ); +- ch_free( ee ); +- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock ); +- return; +- } +- ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock ); +- /* LRU_ADD */ +- if ( bdb->bi_idl_lru_head ) { +- assert( bdb->bi_idl_lru_tail != NULL ); +- assert( bdb->bi_idl_lru_head->idl_lru_prev != NULL ); +- assert( bdb->bi_idl_lru_head->idl_lru_next != NULL ); +- +- ee->idl_lru_next = bdb->bi_idl_lru_head; +- ee->idl_lru_prev = bdb->bi_idl_lru_head->idl_lru_prev; +- bdb->bi_idl_lru_head->idl_lru_prev->idl_lru_next = ee; +- bdb->bi_idl_lru_head->idl_lru_prev = ee; +- } else { +- ee->idl_lru_next = ee->idl_lru_prev = ee; +- bdb->bi_idl_lru_tail = ee; +- } +- bdb->bi_idl_lru_head = ee; +- +- if ( bdb->bi_idl_cache_size >= bdb->bi_idl_cache_max_size ) { +- int i; +- eprev = bdb->bi_idl_lru_tail; +- for ( i = 0; (ee = eprev) != NULL && i < 10; i++ ) { +- eprev = ee->idl_lru_prev; +- if ( eprev == ee ) { +- eprev = NULL; +- } +- if ( ee->idl_flags & CACHE_ENTRY_REFERENCED ) { +- ee->idl_flags ^= CACHE_ENTRY_REFERENCED; +- continue; +- } +- if ( avl_delete( &bdb->bi_idl_tree, (caddr_t) ee, +- bdb_idl_entry_cmp ) == NULL ) { +- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_cache_put: " +- "AVL delete failed\n", +- 0, 0, 0 ); +- } +- IDL_LRU_DELETE( bdb, ee ); +- i++; +- --bdb->bi_idl_cache_size; +- ch_free( ee->kstr.bv_val ); +- ch_free( ee->idl ); +- ch_free( ee ); +- } +- bdb->bi_idl_lru_tail = eprev; +- assert( bdb->bi_idl_lru_tail != NULL +- || bdb->bi_idl_lru_head == NULL ); +- } +- bdb->bi_idl_cache_size++; +- ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock ); +- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock ); +-} +- +-void +-bdb_idl_cache_del( +- struct bdb_info *bdb, +- DB *db, +- DBT *key ) +-{ +- bdb_idl_cache_entry_t *matched_idl_entry, idl_tmp; +- DBT2bv( key, &idl_tmp.kstr ); +- idl_tmp.db = db; +- ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock ); +- matched_idl_entry = avl_find( bdb->bi_idl_tree, &idl_tmp, +- bdb_idl_entry_cmp ); +- if ( matched_idl_entry != NULL ) { +- if ( avl_delete( &bdb->bi_idl_tree, (caddr_t) matched_idl_entry, +- bdb_idl_entry_cmp ) == NULL ) { +- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_cache_del: " +- "AVL delete failed\n", +- 0, 0, 0 ); +- } +- --bdb->bi_idl_cache_size; +- ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock ); +- IDL_LRU_DELETE( bdb, matched_idl_entry ); +- ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock ); +- free( matched_idl_entry->kstr.bv_val ); +- if ( matched_idl_entry->idl ) +- free( matched_idl_entry->idl ); +- free( matched_idl_entry ); +- } +- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock ); +-} +- +-void +-bdb_idl_cache_add_id( +- struct bdb_info *bdb, +- DB *db, +- DBT *key, +- ID id ) +-{ +- bdb_idl_cache_entry_t *cache_entry, idl_tmp; +- DBT2bv( key, &idl_tmp.kstr ); +- idl_tmp.db = db; +- ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock ); +- cache_entry = avl_find( bdb->bi_idl_tree, &idl_tmp, +- bdb_idl_entry_cmp ); +- if ( cache_entry != NULL ) { +- if ( !BDB_IDL_IS_RANGE( cache_entry->idl ) && +- cache_entry->idl[0] < BDB_IDL_DB_MAX ) { +- size_t s = BDB_IDL_SIZEOF( cache_entry->idl ) + sizeof(ID); +- cache_entry->idl = ch_realloc( cache_entry->idl, s ); +- } +- bdb_idl_insert( cache_entry->idl, id ); +- } +- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock ); +-} +- +-void +-bdb_idl_cache_del_id( +- struct bdb_info *bdb, +- DB *db, +- DBT *key, +- ID id ) +-{ +- bdb_idl_cache_entry_t *cache_entry, idl_tmp; +- DBT2bv( key, &idl_tmp.kstr ); +- idl_tmp.db = db; +- ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock ); +- cache_entry = avl_find( bdb->bi_idl_tree, &idl_tmp, +- bdb_idl_entry_cmp ); +- if ( cache_entry != NULL ) { +- bdb_idl_delete( cache_entry->idl, id ); +- if ( cache_entry->idl[0] == 0 ) { +- if ( avl_delete( &bdb->bi_idl_tree, (caddr_t) cache_entry, +- bdb_idl_entry_cmp ) == NULL ) { +- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_cache_del: " +- "AVL delete failed\n", +- 0, 0, 0 ); +- } +- --bdb->bi_idl_cache_size; +- ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock ); +- IDL_LRU_DELETE( bdb, cache_entry ); +- ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock ); +- free( cache_entry->kstr.bv_val ); +- free( cache_entry->idl ); +- free( cache_entry ); +- } +- } +- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock ); +-} +- +-int +-bdb_idl_fetch_key( +- BackendDB *be, +- DB *db, +- DB_TXN *txn, +- DBT *key, +- ID *ids, +- DBC **saved_cursor, +- int get_flag ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) be->be_private; +- int rc; +- DBT data, key2, *kptr; +- DBC *cursor; +- ID *i; +- void *ptr; +- size_t len; +- int rc2; +- int flags = bdb->bi_db_opflags | DB_MULTIPLE; +- int opflag; +- +- /* If using BerkeleyDB 4.0, the buf must be large enough to +- * grab the entire IDL in one get(), otherwise BDB will leak +- * resources on subsequent get's. We can safely call get() +- * twice - once for the data, and once to get the DB_NOTFOUND +- * result meaning there's no more data. See ITS#2040 for details. +- * This bug is fixed in BDB 4.1 so a smaller buffer will work if +- * stack space is too limited. +- * +- * configure now requires Berkeley DB 4.1. +- */ +-#if DB_VERSION_FULL < 0x04010000 +-# define BDB_ENOUGH 5 +-#else +- /* We sometimes test with tiny IDLs, and BDB always wants buffers +- * that are at least one page in size. +- */ +-# if BDB_IDL_DB_SIZE < 4096 +-# define BDB_ENOUGH 2048 +-# else +-# define BDB_ENOUGH 1 +-# endif +-#endif +- ID buf[BDB_IDL_DB_SIZE*BDB_ENOUGH]; +- +- char keybuf[16]; +- +- Debug( LDAP_DEBUG_ARGS, +- "bdb_idl_fetch_key: %s\n", +- bdb_show_key( key, keybuf ), 0, 0 ); +- +- assert( ids != NULL ); +- +- if ( saved_cursor && *saved_cursor ) { +- opflag = DB_NEXT; +- } else if ( get_flag == LDAP_FILTER_GE ) { +- opflag = DB_SET_RANGE; +- } else if ( get_flag == LDAP_FILTER_LE ) { +- opflag = DB_FIRST; +- } else { +- opflag = DB_SET; +- } +- +- /* only non-range lookups can use the IDL cache */ +- if ( bdb->bi_idl_cache_size && opflag == DB_SET ) { +- rc = bdb_idl_cache_get( bdb, db, key, ids ); +- if ( rc != LDAP_NO_SUCH_OBJECT ) return rc; +- } +- +- DBTzero( &data ); +- +- data.data = buf; +- data.ulen = sizeof(buf); +- data.flags = DB_DBT_USERMEM; +- +- /* If we're not reusing an existing cursor, get a new one */ +- if( opflag != DB_NEXT ) { +- rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags ); +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " +- "cursor failed: %s (%d)\n", db_strerror(rc), rc, 0 ); +- return rc; +- } +- } else { +- cursor = *saved_cursor; +- } +- +- /* If this is a LE lookup, save original key so we can determine +- * when to stop. If this is a GE lookup, save the key since it +- * will be overwritten. +- */ +- if ( get_flag == LDAP_FILTER_LE || get_flag == LDAP_FILTER_GE ) { +- DBTzero( &key2 ); +- key2.flags = DB_DBT_USERMEM; +- key2.ulen = sizeof(keybuf); +- key2.data = keybuf; +- key2.size = key->size; +- AC_MEMCPY( keybuf, key->data, key->size ); +- kptr = &key2; +- } else { +- kptr = key; +- } +- len = key->size; +- rc = cursor->c_get( cursor, kptr, &data, flags | opflag ); +- +- /* skip presence key on range inequality lookups */ +- while (rc == 0 && kptr->size != len) { +- rc = cursor->c_get( cursor, kptr, &data, flags | DB_NEXT_NODUP ); +- } +- /* If we're doing a LE compare and the new key is greater than +- * our search key, we're done +- */ +- if (rc == 0 && get_flag == LDAP_FILTER_LE && memcmp( kptr->data, +- key->data, key->size ) > 0 ) { +- rc = DB_NOTFOUND; +- } +- if (rc == 0) { +- i = ids; +- while (rc == 0) { +- u_int8_t *j; +- +- DB_MULTIPLE_INIT( ptr, &data ); +- while (ptr) { +- DB_MULTIPLE_NEXT(ptr, &data, j, len); +- if (j) { +- ++i; +- BDB_DISK2ID( j, i ); +- } +- } +- rc = cursor->c_get( cursor, key, &data, flags | DB_NEXT_DUP ); +- } +- if ( rc == DB_NOTFOUND ) rc = 0; +- ids[0] = i - ids; +- /* On disk, a range is denoted by 0 in the first element */ +- if (ids[1] == 0) { +- if (ids[0] != BDB_IDL_RANGE_SIZE) { +- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " +- "range size mismatch: expected %d, got %ld\n", +- BDB_IDL_RANGE_SIZE, ids[0], 0 ); +- cursor->c_close( cursor ); +- return -1; +- } +- BDB_IDL_RANGE( ids, ids[2], ids[3] ); +- } +- data.size = BDB_IDL_SIZEOF(ids); +- } +- +- if ( saved_cursor && rc == 0 ) { +- if ( !*saved_cursor ) +- *saved_cursor = cursor; +- rc2 = 0; +- } +- else +- rc2 = cursor->c_close( cursor ); +- if (rc2) { +- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " +- "close failed: %s (%d)\n", db_strerror(rc2), rc2, 0 ); +- return rc2; +- } +- +- if( rc == DB_NOTFOUND ) { +- return rc; +- +- } else if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " +- "get failed: %s (%d)\n", +- db_strerror(rc), rc, 0 ); +- return rc; +- +- } else if ( data.size == 0 || data.size % sizeof( ID ) ) { +- /* size not multiple of ID size */ +- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " +- "odd size: expected %ld multiple, got %ld\n", +- (long) sizeof( ID ), (long) data.size, 0 ); +- return -1; +- +- } else if ( data.size != BDB_IDL_SIZEOF(ids) ) { +- /* size mismatch */ +- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " +- "get size mismatch: expected %ld, got %ld\n", +- (long) ((1 + ids[0]) * sizeof( ID )), (long) data.size, 0 ); +- return -1; +- } +- +- if ( bdb->bi_idl_cache_max_size ) { +- bdb_idl_cache_put( bdb, db, key, ids, rc ); +- } +- +- return rc; +-} +- +- +-int +-bdb_idl_insert_key( +- BackendDB *be, +- DB *db, +- DB_TXN *tid, +- DBT *key, +- ID id ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) be->be_private; +- int rc; +- DBT data; +- DBC *cursor; +- ID lo, hi, nlo, nhi, nid; +- char *err; +- +- { +- char buf[16]; +- Debug( LDAP_DEBUG_ARGS, +- "bdb_idl_insert_key: %lx %s\n", +- (long) id, bdb_show_key( key, buf ), 0 ); +- } +- +- assert( id != NOID ); +- +- DBTzero( &data ); +- data.size = sizeof( ID ); +- data.ulen = data.size; +- data.flags = DB_DBT_USERMEM; +- +- BDB_ID2DISK( id, &nid ); +- +- rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags ); +- if ( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_insert_key: " +- "cursor failed: %s (%d)\n", db_strerror(rc), rc, 0 ); +- return rc; +- } +- data.data = &nlo; +- /* Fetch the first data item for this key, to see if it +- * exists and if it's a range. +- */ +- rc = cursor->c_get( cursor, key, &data, DB_SET ); +- err = "c_get"; +- if ( rc == 0 ) { +- if ( nlo != 0 ) { +- /* not a range, count the number of items */ +- db_recno_t count; +- rc = cursor->c_count( cursor, &count, 0 ); +- if ( rc != 0 ) { +- err = "c_count"; +- goto fail; +- } +- if ( count >= BDB_IDL_DB_MAX ) { +- /* No room, convert to a range */ +- DBT key2 = *key; +- db_recno_t i; +- +- key2.dlen = key2.ulen; +- key2.flags |= DB_DBT_PARTIAL; +- +- BDB_DISK2ID( &nlo, &lo ); +- data.data = &nhi; +- +- rc = cursor->c_get( cursor, &key2, &data, DB_NEXT_NODUP ); +- if ( rc != 0 && rc != DB_NOTFOUND ) { +- err = "c_get next_nodup"; +- goto fail; +- } +- if ( rc == DB_NOTFOUND ) { +- rc = cursor->c_get( cursor, key, &data, DB_LAST ); +- if ( rc != 0 ) { +- err = "c_get last"; +- goto fail; +- } +- } else { +- rc = cursor->c_get( cursor, key, &data, DB_PREV ); +- if ( rc != 0 ) { +- err = "c_get prev"; +- goto fail; +- } +- } +- BDB_DISK2ID( &nhi, &hi ); +- /* Update hi/lo if needed, then delete all the items +- * between lo and hi +- */ +- if ( id < lo ) { +- lo = id; +- nlo = nid; +- } else if ( id > hi ) { +- hi = id; +- nhi = nid; +- } +- data.data = &nid; +- /* Don't fetch anything, just position cursor */ +- data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; +- data.dlen = data.ulen = 0; +- rc = cursor->c_get( cursor, key, &data, DB_SET ); +- if ( rc != 0 ) { +- err = "c_get 2"; +- goto fail; +- } +- rc = cursor->c_del( cursor, 0 ); +- if ( rc != 0 ) { +- err = "c_del range1"; +- goto fail; +- } +- /* Delete all the records */ +- for ( i=1; ic_get( cursor, &key2, &data, DB_NEXT_DUP ); +- if ( rc != 0 ) { +- err = "c_get next_dup"; +- goto fail; +- } +- rc = cursor->c_del( cursor, 0 ); +- if ( rc != 0 ) { +- err = "c_del range"; +- goto fail; +- } +- } +- /* Store the range marker */ +- data.size = data.ulen = sizeof(ID); +- data.flags = DB_DBT_USERMEM; +- nid = 0; +- rc = cursor->c_put( cursor, key, &data, DB_KEYFIRST ); +- if ( rc != 0 ) { +- err = "c_put range"; +- goto fail; +- } +- nid = nlo; +- rc = cursor->c_put( cursor, key, &data, DB_KEYLAST ); +- if ( rc != 0 ) { +- err = "c_put lo"; +- goto fail; +- } +- nid = nhi; +- rc = cursor->c_put( cursor, key, &data, DB_KEYLAST ); +- if ( rc != 0 ) { +- err = "c_put hi"; +- goto fail; +- } +- } else { +- /* There's room, just store it */ +- goto put1; +- } +- } else { +- /* It's a range, see if we need to rewrite +- * the boundaries +- */ +- hi = id; +- data.data = &nlo; +- rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP ); +- if ( rc != 0 ) { +- err = "c_get lo"; +- goto fail; +- } +- BDB_DISK2ID( &nlo, &lo ); +- if ( id > lo ) { +- data.data = &nhi; +- rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP ); +- if ( rc != 0 ) { +- err = "c_get hi"; +- goto fail; +- } +- BDB_DISK2ID( &nhi, &hi ); +- } +- if ( id < lo || id > hi ) { +- /* Delete the current lo/hi */ +- rc = cursor->c_del( cursor, 0 ); +- if ( rc != 0 ) { +- err = "c_del"; +- goto fail; +- } +- data.data = &nid; +- rc = cursor->c_put( cursor, key, &data, DB_KEYFIRST ); +- if ( rc != 0 ) { +- err = "c_put lo/hi"; +- goto fail; +- } +- } +- } +- } else if ( rc == DB_NOTFOUND ) { +-put1: data.data = &nid; +- rc = cursor->c_put( cursor, key, &data, DB_NODUPDATA ); +- /* Don't worry if it's already there */ +- if ( rc != 0 && rc != DB_KEYEXIST ) { +- err = "c_put id"; +- goto fail; +- } +- } else { +- /* initial c_get failed, nothing was done */ +-fail: +- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_insert_key: " +- "%s failed: %s (%d)\n", err, db_strerror(rc), rc ); +- cursor->c_close( cursor ); +- return rc; +- } +- /* If key was added (didn't already exist) and using IDL cache, +- * update key in IDL cache. +- */ +- if ( !rc && bdb->bi_idl_cache_max_size ) { +- bdb_idl_cache_add_id( bdb, db, key, id ); +- } +- rc = cursor->c_close( cursor ); +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_insert_key: " +- "c_close failed: %s (%d)\n", +- db_strerror(rc), rc, 0 ); +- } +- return rc; +-} +- +-int +-bdb_idl_delete_key( +- BackendDB *be, +- DB *db, +- DB_TXN *tid, +- DBT *key, +- ID id ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) be->be_private; +- int rc; +- DBT data; +- DBC *cursor; +- ID lo, hi, tmp, nid, nlo, nhi; +- char *err; +- +- { +- char buf[16]; +- Debug( LDAP_DEBUG_ARGS, +- "bdb_idl_delete_key: %lx %s\n", +- (long) id, bdb_show_key( key, buf ), 0 ); +- } +- assert( id != NOID ); +- +- if ( bdb->bi_idl_cache_size ) { +- bdb_idl_cache_del( bdb, db, key ); +- } +- +- BDB_ID2DISK( id, &nid ); +- +- DBTzero( &data ); +- data.data = &tmp; +- data.size = sizeof( id ); +- data.ulen = data.size; +- data.flags = DB_DBT_USERMEM; +- +- rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags ); +- if ( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_delete_key: " +- "cursor failed: %s (%d)\n", db_strerror(rc), rc, 0 ); +- return rc; +- } +- /* Fetch the first data item for this key, to see if it +- * exists and if it's a range. +- */ +- rc = cursor->c_get( cursor, key, &data, DB_SET ); +- err = "c_get"; +- if ( rc == 0 ) { +- if ( tmp != 0 ) { +- /* Not a range, just delete it */ +- if (tmp != nid) { +- /* position to correct item */ +- tmp = nid; +- rc = cursor->c_get( cursor, key, &data, DB_GET_BOTH ); +- if ( rc != 0 ) { +- err = "c_get id"; +- goto fail; +- } +- } +- rc = cursor->c_del( cursor, 0 ); +- if ( rc != 0 ) { +- err = "c_del id"; +- goto fail; +- } +- } else { +- /* It's a range, see if we need to rewrite +- * the boundaries +- */ +- data.data = &nlo; +- rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP ); +- if ( rc != 0 ) { +- err = "c_get lo"; +- goto fail; +- } +- BDB_DISK2ID( &nlo, &lo ); +- data.data = &nhi; +- rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP ); +- if ( rc != 0 ) { +- err = "c_get hi"; +- goto fail; +- } +- BDB_DISK2ID( &nhi, &hi ); +- if ( id == lo || id == hi ) { +- if ( id == lo ) { +- id++; +- lo = id; +- } else if ( id == hi ) { +- id--; +- hi = id; +- } +- if ( lo >= hi ) { +- /* The range has collapsed... */ +- rc = db->del( db, tid, key, 0 ); +- if ( rc != 0 ) { +- err = "del"; +- goto fail; +- } +- } else { +- if ( id == lo ) { +- /* reposition on lo slot */ +- data.data = &nlo; +- cursor->c_get( cursor, key, &data, DB_PREV ); +- } +- rc = cursor->c_del( cursor, 0 ); +- if ( rc != 0 ) { +- err = "c_del"; +- goto fail; +- } +- } +- if ( lo <= hi ) { +- BDB_ID2DISK( id, &nid ); +- data.data = &nid; +- rc = cursor->c_put( cursor, key, &data, DB_KEYFIRST ); +- if ( rc != 0 ) { +- err = "c_put lo/hi"; +- goto fail; +- } +- } +- } +- } +- } else { +- /* initial c_get failed, nothing was done */ +-fail: +- if ( rc != DB_NOTFOUND ) { +- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_delete_key: " +- "%s failed: %s (%d)\n", err, db_strerror(rc), rc ); +- } +- cursor->c_close( cursor ); +- return rc; +- } +- rc = cursor->c_close( cursor ); +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, +- "=> bdb_idl_delete_key: c_close failed: %s (%d)\n", +- db_strerror(rc), rc, 0 ); +- } +- +- return rc; +-} +- +- +-/* +- * idl_intersection - return a = a intersection b +- */ +-int +-bdb_idl_intersection( +- ID *a, +- ID *b ) +-{ +- ID ida, idb; +- ID idmax, idmin; +- ID cursora = 0, cursorb = 0, cursorc; +- int swap = 0; +- +- if ( BDB_IDL_IS_ZERO( a ) || BDB_IDL_IS_ZERO( b ) ) { +- a[0] = 0; +- return 0; +- } +- +- idmin = IDL_MAX( BDB_IDL_FIRST(a), BDB_IDL_FIRST(b) ); +- idmax = IDL_MIN( BDB_IDL_LAST(a), BDB_IDL_LAST(b) ); +- if ( idmin > idmax ) { +- a[0] = 0; +- return 0; +- } else if ( idmin == idmax ) { +- a[0] = 1; +- a[1] = idmin; +- return 0; +- } +- +- if ( BDB_IDL_IS_RANGE( a ) ) { +- if ( BDB_IDL_IS_RANGE(b) ) { +- /* If both are ranges, just shrink the boundaries */ +- a[1] = idmin; +- a[2] = idmax; +- return 0; +- } else { +- /* Else swap so that b is the range, a is a list */ +- ID *tmp = a; +- a = b; +- b = tmp; +- swap = 1; +- } +- } +- +- /* If a range completely covers the list, the result is +- * just the list. +- */ +- if ( BDB_IDL_IS_RANGE( b ) +- && BDB_IDL_RANGE_FIRST( b ) <= BDB_IDL_FIRST( a ) +- && BDB_IDL_RANGE_LAST( b ) >= BDB_IDL_LLAST( a ) ) { +- goto done; +- } +- +- /* Fine, do the intersection one element at a time. +- * First advance to idmin in both IDLs. +- */ +- cursora = cursorb = idmin; +- ida = bdb_idl_first( a, &cursora ); +- idb = bdb_idl_first( b, &cursorb ); +- cursorc = 0; +- +- while( ida <= idmax || idb <= idmax ) { +- if( ida == idb ) { +- a[++cursorc] = ida; +- ida = bdb_idl_next( a, &cursora ); +- idb = bdb_idl_next( b, &cursorb ); +- } else if ( ida < idb ) { +- ida = bdb_idl_next( a, &cursora ); +- } else { +- idb = bdb_idl_next( b, &cursorb ); +- } +- } +- a[0] = cursorc; +-done: +- if (swap) +- BDB_IDL_CPY( b, a ); +- +- return 0; +-} +- +- +-/* +- * idl_union - return a = a union b +- */ +-int +-bdb_idl_union( +- ID *a, +- ID *b ) +-{ +- ID ida, idb; +- ID cursora = 0, cursorb = 0, cursorc; +- +- if ( BDB_IDL_IS_ZERO( b ) ) { +- return 0; +- } +- +- if ( BDB_IDL_IS_ZERO( a ) ) { +- BDB_IDL_CPY( a, b ); +- return 0; +- } +- +- if ( BDB_IDL_IS_RANGE( a ) || BDB_IDL_IS_RANGE(b) ) { +-over: ida = IDL_MIN( BDB_IDL_FIRST(a), BDB_IDL_FIRST(b) ); +- idb = IDL_MAX( BDB_IDL_LAST(a), BDB_IDL_LAST(b) ); +- a[0] = NOID; +- a[1] = ida; +- a[2] = idb; +- return 0; +- } +- +- ida = bdb_idl_first( a, &cursora ); +- idb = bdb_idl_first( b, &cursorb ); +- +- cursorc = b[0]; +- +- /* The distinct elements of a are cat'd to b */ +- while( ida != NOID || idb != NOID ) { +- if ( ida < idb ) { +- if( ++cursorc > BDB_IDL_UM_MAX ) { +- goto over; +- } +- b[cursorc] = ida; +- ida = bdb_idl_next( a, &cursora ); +- +- } else { +- if ( ida == idb ) +- ida = bdb_idl_next( a, &cursora ); +- idb = bdb_idl_next( b, &cursorb ); +- } +- } +- +- /* b is copied back to a in sorted order */ +- a[0] = cursorc; +- cursora = 1; +- cursorb = 1; +- cursorc = b[0]+1; +- while (cursorb <= b[0] || cursorc <= a[0]) { +- if (cursorc > a[0]) +- idb = NOID; +- else +- idb = b[cursorc]; +- if (cursorb <= b[0] && b[cursorb] < idb) +- a[cursora++] = b[cursorb++]; +- else { +- a[cursora++] = idb; +- cursorc++; +- } +- } +- +- return 0; +-} +- +- +-#if 0 +-/* +- * bdb_idl_notin - return a intersection ~b (or a minus b) +- */ +-int +-bdb_idl_notin( +- ID *a, +- ID *b, +- ID *ids ) +-{ +- ID ida, idb; +- ID cursora = 0, cursorb = 0; +- +- if( BDB_IDL_IS_ZERO( a ) || +- BDB_IDL_IS_ZERO( b ) || +- BDB_IDL_IS_RANGE( b ) ) +- { +- BDB_IDL_CPY( ids, a ); +- return 0; +- } +- +- if( BDB_IDL_IS_RANGE( a ) ) { +- BDB_IDL_CPY( ids, a ); +- return 0; +- } +- +- ida = bdb_idl_first( a, &cursora ), +- idb = bdb_idl_first( b, &cursorb ); +- +- ids[0] = 0; +- +- while( ida != NOID ) { +- if ( idb == NOID ) { +- /* we could shortcut this */ +- ids[++ids[0]] = ida; +- ida = bdb_idl_next( a, &cursora ); +- +- } else if ( ida < idb ) { +- ids[++ids[0]] = ida; +- ida = bdb_idl_next( a, &cursora ); +- +- } else if ( ida > idb ) { +- idb = bdb_idl_next( b, &cursorb ); +- +- } else { +- ida = bdb_idl_next( a, &cursora ); +- idb = bdb_idl_next( b, &cursorb ); +- } +- } +- +- return 0; +-} +-#endif +- +-ID bdb_idl_first( ID *ids, ID *cursor ) +-{ +- ID pos; +- +- if ( ids[0] == 0 ) { +- *cursor = NOID; +- return NOID; +- } +- +- if ( BDB_IDL_IS_RANGE( ids ) ) { +- if( *cursor < ids[1] ) { +- *cursor = ids[1]; +- } +- return *cursor; +- } +- +- if ( *cursor == 0 ) +- pos = 1; +- else +- pos = bdb_idl_search( ids, *cursor ); +- +- if( pos > ids[0] ) { +- return NOID; +- } +- +- *cursor = pos; +- return ids[pos]; +-} +- +-ID bdb_idl_next( ID *ids, ID *cursor ) +-{ +- if ( BDB_IDL_IS_RANGE( ids ) ) { +- if( ids[2] < ++(*cursor) ) { +- return NOID; +- } +- return *cursor; +- } +- +- if ( ++(*cursor) <= ids[0] ) { +- return ids[*cursor]; +- } +- +- return NOID; +-} +- +-#ifdef BDB_HIER +- +-/* Add one ID to an unsorted list. We ensure that the first element is the +- * minimum and the last element is the maximum, for fast range compaction. +- * this means IDLs up to length 3 are always sorted... +- */ +-int bdb_idl_append_one( ID *ids, ID id ) +-{ +- if (BDB_IDL_IS_RANGE( ids )) { +- /* if already in range, treat as a dup */ +- if (id >= BDB_IDL_RANGE_FIRST(ids) && id <= BDB_IDL_RANGE_LAST(ids)) +- return -1; +- if (id < BDB_IDL_RANGE_FIRST(ids)) +- ids[1] = id; +- else if (id > BDB_IDL_RANGE_LAST(ids)) +- ids[2] = id; +- return 0; +- } +- if ( ids[0] ) { +- ID tmp; +- +- if (id < ids[1]) { +- tmp = ids[1]; +- ids[1] = id; +- id = tmp; +- } +- if ( ids[0] > 1 && id < ids[ids[0]] ) { +- tmp = ids[ids[0]]; +- ids[ids[0]] = id; +- id = tmp; +- } +- } +- ids[0]++; +- if ( ids[0] >= BDB_IDL_UM_MAX ) { +- ids[0] = NOID; +- ids[2] = id; +- } else { +- ids[ids[0]] = id; +- } +- return 0; +-} +- +-/* Append sorted list b to sorted list a. The result is unsorted but +- * a[1] is the min of the result and a[a[0]] is the max. +- */ +-int bdb_idl_append( ID *a, ID *b ) +-{ +- ID ida, idb, tmp, swap = 0; +- +- if ( BDB_IDL_IS_ZERO( b ) ) { +- return 0; +- } +- +- if ( BDB_IDL_IS_ZERO( a ) ) { +- BDB_IDL_CPY( a, b ); +- return 0; +- } +- +- if ( b[0] == 1 ) { +- return bdb_idl_append_one( a, BDB_IDL_FIRST( b )); +- } +- +- ida = BDB_IDL_LAST( a ); +- idb = BDB_IDL_LAST( b ); +- if ( BDB_IDL_IS_RANGE( a ) || BDB_IDL_IS_RANGE(b) || +- a[0] + b[0] >= BDB_IDL_UM_MAX ) { +- a[2] = IDL_MAX( ida, idb ); +- a[1] = IDL_MIN( a[1], b[1] ); +- a[0] = NOID; +- return 0; +- } +- +- if ( ida > idb ) { +- swap = idb; +- a[a[0]] = idb; +- b[b[0]] = ida; +- } +- +- if ( b[1] < a[1] ) { +- tmp = a[1]; +- a[1] = b[1]; +- } else { +- tmp = b[1]; +- } +- a[0]++; +- a[a[0]] = tmp; +- +- { +- int i = b[0] - 1; +- AC_MEMCPY(a+a[0]+1, b+2, i * sizeof(ID)); +- a[0] += i; +- } +- if ( swap ) { +- b[b[0]] = swap; +- } +- return 0; +-} +- +-#if 1 +- +-/* Quicksort + Insertion sort for small arrays */ +- +-#define SMALL 8 +-#define SWAP(a,b) itmp=(a);(a)=(b);(b)=itmp +- +-void +-bdb_idl_sort( ID *ids, ID *tmp ) +-{ +- int *istack = (int *)tmp; +- int i,j,k,l,ir,jstack; +- ID a, itmp; +- +- if ( BDB_IDL_IS_RANGE( ids )) +- return; +- +- ir = ids[0]; +- l = 1; +- jstack = 0; +- for(;;) { +- if (ir - l < SMALL) { /* Insertion sort */ +- for (j=l+1;j<=ir;j++) { +- a = ids[j]; +- for (i=j-1;i>=1;i--) { +- if (ids[i] <= a) break; +- ids[i+1] = ids[i]; +- } +- ids[i+1] = a; +- } +- if (jstack == 0) break; +- ir = istack[jstack--]; +- l = istack[jstack--]; +- } else { +- k = (l + ir) >> 1; /* Choose median of left, center, right */ +- SWAP(ids[k], ids[l+1]); +- if (ids[l] > ids[ir]) { +- SWAP(ids[l], ids[ir]); +- } +- if (ids[l+1] > ids[ir]) { +- SWAP(ids[l+1], ids[ir]); +- } +- if (ids[l] > ids[l+1]) { +- SWAP(ids[l], ids[l+1]); +- } +- i = l+1; +- j = ir; +- a = ids[l+1]; +- for(;;) { +- do i++; while(ids[i] < a); +- do j--; while(ids[j] > a); +- if (j < i) break; +- SWAP(ids[i],ids[j]); +- } +- ids[l+1] = ids[j]; +- ids[j] = a; +- jstack += 2; +- if (ir-i+1 >= j-1) { +- istack[jstack] = ir; +- istack[jstack-1] = i; +- ir = j-1; +- } else { +- istack[jstack] = j-1; +- istack[jstack-1] = l; +- l = i; +- } +- } +- } +-} +- +-#else +- +-/* 8 bit Radix sort + insertion sort +- * +- * based on code from http://www.cubic.org/docs/radix.htm +- * with improvements by ebackes@symas.com and hyc@symas.com +- * +- * This code is O(n) but has a relatively high constant factor. For lists +- * up to ~50 Quicksort is slightly faster; up to ~100 they are even. +- * Much faster than quicksort for lists longer than ~100. Insertion +- * sort is actually superior for lists <50. +- */ +- +-#define BUCKETS (1<<8) +-#define SMALL 50 +- +-void +-bdb_idl_sort( ID *ids, ID *tmp ) +-{ +- int count, soft_limit, phase = 0, size = ids[0]; +- ID *idls[2]; +- unsigned char *maxv = (unsigned char *)&ids[size]; +- +- if ( BDB_IDL_IS_RANGE( ids )) +- return; +- +- /* Use insertion sort for small lists */ +- if ( size <= SMALL ) { +- int i,j; +- ID a; +- +- for (j=1;j<=size;j++) { +- a = ids[j]; +- for (i=j-1;i>=1;i--) { +- if (ids[i] <= a) break; +- ids[i+1] = ids[i]; +- } +- ids[i+1] = a; +- } +- return; +- } +- +- tmp[0] = size; +- idls[0] = ids; +- idls[1] = tmp; +- +-#if BYTE_ORDER == BIG_ENDIAN +- for (soft_limit = 0; !maxv[soft_limit]; soft_limit++); +-#else +- for (soft_limit = sizeof(ID)-1; !maxv[soft_limit]; soft_limit--); +-#endif +- +- for ( +-#if BYTE_ORDER == BIG_ENDIAN +- count = sizeof(ID)-1; count >= soft_limit; --count +-#else +- count = 0; count <= soft_limit; ++count +-#endif +- ) { +- unsigned int num[BUCKETS], * np, n, sum; +- int i; +- ID *sp, *source, *dest; +- unsigned char *bp, *source_start; +- +- source = idls[phase]+1; +- dest = idls[phase^1]+1; +- source_start = ((unsigned char *) source) + count; +- +- np = num; +- for ( i = BUCKETS; i > 0; --i ) *np++ = 0; +- +- /* count occurences of every byte value */ +- bp = source_start; +- for ( i = size; i > 0; --i, bp += sizeof(ID) ) +- num[*bp]++; +- +- /* transform count into index by summing elements and storing +- * into same array +- */ +- sum = 0; +- np = num; +- for ( i = BUCKETS; i > 0; --i ) { +- n = *np; +- *np++ = sum; +- sum += n; +- } +- +- /* fill dest with the right values in the right place */ +- bp = source_start; +- sp = source; +- for ( i = size; i > 0; --i, bp += sizeof(ID) ) { +- np = num + *bp; +- dest[*np] = *sp++; +- ++(*np); +- } +- phase ^= 1; +- } +- +- /* copy back from temp if needed */ +- if ( phase ) { +- ids++; tmp++; +- for ( count = 0; count < size; ++count ) +- *ids++ = *tmp++; +- } +-} +-#endif /* Quick vs Radix */ +- +-#endif /* BDB_HIER */ +diff --git a/servers/slapd/back-bdb/idl.h b/servers/slapd/back-bdb/idl.h +deleted file mode 100644 +index 909a43b..0000000 +--- a/servers/slapd/back-bdb/idl.h ++++ /dev/null +@@ -1,75 +0,0 @@ +-/* idl.h - ldap bdb back-end ID list header file */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#ifndef _BDB_IDL_H_ +-#define _BDB_IDL_H_ +- +-/* IDL sizes - likely should be even bigger +- * limiting factors: sizeof(ID), thread stack size +- */ +-#define BDB_IDL_LOGN 16 /* DB_SIZE is 2^16, UM_SIZE is 2^17 */ +-#define BDB_IDL_DB_SIZE (1<bi_lastid) ) +-#define BDB_IDL_ALL( bdb, ids ) BDB_IDL_RANGE( ids, 1, ((bdb)->bi_lastid) ) +- +-#define BDB_IDL_FIRST( ids ) ( (ids)[1] ) +-#define BDB_IDL_LLAST( ids ) ( (ids)[(ids)[0]] ) +-#define BDB_IDL_LAST( ids ) ( BDB_IDL_IS_RANGE(ids) \ +- ? (ids)[2] : (ids)[(ids)[0]] ) +- +-#define BDB_IDL_N( ids ) ( BDB_IDL_IS_RANGE(ids) \ +- ? ((ids)[2]-(ids)[1])+1 : (ids)[0] ) +- +-LDAP_BEGIN_DECL +-LDAP_END_DECL +- +-#endif +diff --git a/servers/slapd/back-bdb/index.c b/servers/slapd/back-bdb/index.c +deleted file mode 100644 +index c095641..0000000 +--- a/servers/slapd/back-bdb/index.c ++++ /dev/null +@@ -1,574 +0,0 @@ +-/* index.c - routines for dealing with attribute indexes */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +- +-#include +-#include +- +-#include "slap.h" +-#include "back-bdb.h" +-#include "lutil_hash.h" +- +-static char presence_keyval[] = {0,0}; +-static struct berval presence_key = BER_BVC(presence_keyval); +- +-AttrInfo *bdb_index_mask( +- Backend *be, +- AttributeDescription *desc, +- struct berval *atname ) +-{ +- AttributeType *at; +- AttrInfo *ai = bdb_attr_mask( be->be_private, desc ); +- +- if( ai ) { +- *atname = desc->ad_cname; +- return ai; +- } +- +- /* If there is a tagging option, did we ever index the base +- * type? If so, check for mask, otherwise it's not there. +- */ +- if( slap_ad_is_tagged( desc ) && desc != desc->ad_type->sat_ad ) { +- /* has tagging option */ +- ai = bdb_attr_mask( be->be_private, desc->ad_type->sat_ad ); +- +- if ( ai && !( ai->ai_indexmask & SLAP_INDEX_NOTAGS ) ) { +- *atname = desc->ad_type->sat_cname; +- return ai; +- } +- } +- +- /* see if supertype defined mask for its subtypes */ +- for( at = desc->ad_type; at != NULL ; at = at->sat_sup ) { +- /* If no AD, we've never indexed this type */ +- if ( !at->sat_ad ) continue; +- +- ai = bdb_attr_mask( be->be_private, at->sat_ad ); +- +- if ( ai && !( ai->ai_indexmask & SLAP_INDEX_NOSUBTYPES ) ) { +- *atname = at->sat_cname; +- return ai; +- } +- } +- +- return 0; +-} +- +-/* This function is only called when evaluating search filters. +- */ +-int bdb_index_param( +- Backend *be, +- AttributeDescription *desc, +- int ftype, +- DB **dbp, +- slap_mask_t *maskp, +- struct berval *prefixp ) +-{ +- AttrInfo *ai; +- int rc; +- slap_mask_t mask, type = 0; +- DB *db; +- +- ai = bdb_index_mask( be, desc, prefixp ); +- +- if ( !ai ) { +-#ifdef BDB_MONITOR_IDX +- switch ( ftype ) { +- case LDAP_FILTER_PRESENT: +- type = SLAP_INDEX_PRESENT; +- break; +- case LDAP_FILTER_APPROX: +- type = SLAP_INDEX_APPROX; +- break; +- case LDAP_FILTER_EQUALITY: +- type = SLAP_INDEX_EQUALITY; +- break; +- case LDAP_FILTER_SUBSTRINGS: +- type = SLAP_INDEX_SUBSTR; +- break; +- default: +- return LDAP_INAPPROPRIATE_MATCHING; +- } +- bdb_monitor_idx_add( be->be_private, desc, type ); +-#endif /* BDB_MONITOR_IDX */ +- +- return LDAP_INAPPROPRIATE_MATCHING; +- } +- mask = ai->ai_indexmask; +- +- rc = bdb_db_cache( be, prefixp, &db ); +- +- if( rc != LDAP_SUCCESS ) { +- return rc; +- } +- +- switch( ftype ) { +- case LDAP_FILTER_PRESENT: +- type = SLAP_INDEX_PRESENT; +- if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) { +- *prefixp = presence_key; +- goto done; +- } +- break; +- +- case LDAP_FILTER_APPROX: +- type = SLAP_INDEX_APPROX; +- if ( desc->ad_type->sat_approx ) { +- if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) { +- goto done; +- } +- break; +- } +- +- /* Use EQUALITY rule and index for approximate match */ +- /* fall thru */ +- +- case LDAP_FILTER_EQUALITY: +- type = SLAP_INDEX_EQUALITY; +- if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) { +- goto done; +- } +- break; +- +- case LDAP_FILTER_SUBSTRINGS: +- type = SLAP_INDEX_SUBSTR; +- if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) { +- goto done; +- } +- break; +- +- default: +- return LDAP_OTHER; +- } +- +-#ifdef BDB_MONITOR_IDX +- bdb_monitor_idx_add( be->be_private, desc, type ); +-#endif /* BDB_MONITOR_IDX */ +- +- return LDAP_INAPPROPRIATE_MATCHING; +- +-done: +- *dbp = db; +- *maskp = mask; +- return LDAP_SUCCESS; +-} +- +-static int indexer( +- Operation *op, +- DB_TXN *txn, +- AttributeDescription *ad, +- struct berval *atname, +- BerVarray vals, +- ID id, +- int opid, +- slap_mask_t mask ) +-{ +- int rc, i; +- DB *db; +- struct berval *keys; +- +- assert( mask != 0 ); +- +- rc = bdb_db_cache( op->o_bd, atname, &db ); +- +- if ( rc != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_ANY, +- "bdb_index_read: Could not open DB %s\n", +- atname->bv_val, 0, 0 ); +- return LDAP_OTHER; +- } +- +- if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) { +- rc = bdb_key_change( op->o_bd, db, txn, &presence_key, id, opid ); +- if( rc ) { +- goto done; +- } +- } +- +- if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) { +- rc = ad->ad_type->sat_equality->smr_indexer( +- LDAP_FILTER_EQUALITY, +- mask, +- ad->ad_type->sat_syntax, +- ad->ad_type->sat_equality, +- atname, vals, &keys, op->o_tmpmemctx ); +- +- if( rc == LDAP_SUCCESS && keys != NULL ) { +- for( i=0; keys[i].bv_val != NULL; i++ ) { +- rc = bdb_key_change( op->o_bd, db, txn, &keys[i], id, opid ); +- if( rc ) { +- ber_bvarray_free_x( keys, op->o_tmpmemctx ); +- goto done; +- } +- } +- ber_bvarray_free_x( keys, op->o_tmpmemctx ); +- } +- rc = LDAP_SUCCESS; +- } +- +- if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) { +- rc = ad->ad_type->sat_approx->smr_indexer( +- LDAP_FILTER_APPROX, +- mask, +- ad->ad_type->sat_syntax, +- ad->ad_type->sat_approx, +- atname, vals, &keys, op->o_tmpmemctx ); +- +- if( rc == LDAP_SUCCESS && keys != NULL ) { +- for( i=0; keys[i].bv_val != NULL; i++ ) { +- rc = bdb_key_change( op->o_bd, db, txn, &keys[i], id, opid ); +- if( rc ) { +- ber_bvarray_free_x( keys, op->o_tmpmemctx ); +- goto done; +- } +- } +- ber_bvarray_free_x( keys, op->o_tmpmemctx ); +- } +- +- rc = LDAP_SUCCESS; +- } +- +- if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) { +- rc = ad->ad_type->sat_substr->smr_indexer( +- LDAP_FILTER_SUBSTRINGS, +- mask, +- ad->ad_type->sat_syntax, +- ad->ad_type->sat_substr, +- atname, vals, &keys, op->o_tmpmemctx ); +- +- if( rc == LDAP_SUCCESS && keys != NULL ) { +- for( i=0; keys[i].bv_val != NULL; i++ ) { +- rc = bdb_key_change( op->o_bd, db, txn, &keys[i], id, opid ); +- if( rc ) { +- ber_bvarray_free_x( keys, op->o_tmpmemctx ); +- goto done; +- } +- } +- ber_bvarray_free_x( keys, op->o_tmpmemctx ); +- } +- +- rc = LDAP_SUCCESS; +- } +- +-done: +- switch( rc ) { +- /* The callers all know how to deal with these results */ +- case 0: +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- break; +- /* Anything else is bad news */ +- default: +- rc = LDAP_OTHER; +- } +- return rc; +-} +- +-static int index_at_values( +- Operation *op, +- DB_TXN *txn, +- AttributeDescription *ad, +- AttributeType *type, +- struct berval *tags, +- BerVarray vals, +- ID id, +- int opid ) +-{ +- int rc; +- slap_mask_t mask = 0; +- int ixop = opid; +- AttrInfo *ai = NULL; +- +- if ( opid == BDB_INDEX_UPDATE_OP ) +- ixop = SLAP_INDEX_ADD_OP; +- +- if( type->sat_sup ) { +- /* recurse */ +- rc = index_at_values( op, txn, NULL, +- type->sat_sup, tags, +- vals, id, opid ); +- +- if( rc ) return rc; +- } +- +- /* If this type has no AD, we've never used it before */ +- if( type->sat_ad ) { +- ai = bdb_attr_mask( op->o_bd->be_private, type->sat_ad ); +- if ( ai ) { +-#ifdef LDAP_COMP_MATCH +- /* component indexing */ +- if ( ai->ai_cr ) { +- ComponentReference *cr; +- for( cr = ai->ai_cr ; cr ; cr = cr->cr_next ) { +- rc = indexer( op, txn, cr->cr_ad, &type->sat_cname, +- cr->cr_nvals, id, ixop, +- cr->cr_indexmask ); +- } +- } +-#endif +- ad = type->sat_ad; +- /* If we're updating the index, just set the new bits that aren't +- * already in the old mask. +- */ +- if ( opid == BDB_INDEX_UPDATE_OP ) +- mask = ai->ai_newmask & ~ai->ai_indexmask; +- else +- /* For regular updates, if there is a newmask use it. Otherwise +- * just use the old mask. +- */ +- mask = ai->ai_newmask ? ai->ai_newmask : ai->ai_indexmask; +- if( mask ) { +- rc = indexer( op, txn, ad, &type->sat_cname, +- vals, id, ixop, mask ); +- +- if( rc ) return rc; +- } +- } +- } +- +- if( tags->bv_len ) { +- AttributeDescription *desc; +- +- desc = ad_find_tags( type, tags ); +- if( desc ) { +- ai = bdb_attr_mask( op->o_bd->be_private, desc ); +- +- if( ai ) { +- if ( opid == BDB_INDEX_UPDATE_OP ) +- mask = ai->ai_newmask & ~ai->ai_indexmask; +- else +- mask = ai->ai_newmask ? ai->ai_newmask : ai->ai_indexmask; +- if ( mask ) { +- rc = indexer( op, txn, desc, &desc->ad_cname, +- vals, id, ixop, mask ); +- +- if( rc ) { +- return rc; +- } +- } +- } +- } +- } +- +- return LDAP_SUCCESS; +-} +- +-int bdb_index_values( +- Operation *op, +- DB_TXN *txn, +- AttributeDescription *desc, +- BerVarray vals, +- ID id, +- int opid ) +-{ +- int rc; +- +- /* Never index ID 0 */ +- if ( id == 0 ) +- return 0; +- +- rc = index_at_values( op, txn, desc, +- desc->ad_type, &desc->ad_tags, +- vals, id, opid ); +- +- return rc; +-} +- +-/* Get the list of which indices apply to this attr */ +-int +-bdb_index_recset( +- struct bdb_info *bdb, +- Attribute *a, +- AttributeType *type, +- struct berval *tags, +- IndexRec *ir ) +-{ +- int rc, slot; +- AttrList *al; +- +- if( type->sat_sup ) { +- /* recurse */ +- rc = bdb_index_recset( bdb, a, type->sat_sup, tags, ir ); +- if( rc ) return rc; +- } +- /* If this type has no AD, we've never used it before */ +- if( type->sat_ad ) { +- slot = bdb_attr_slot( bdb, type->sat_ad, NULL ); +- if ( slot >= 0 ) { +- ir[slot].ai = bdb->bi_attrs[slot]; +- al = ch_malloc( sizeof( AttrList )); +- al->attr = a; +- al->next = ir[slot].attrs; +- ir[slot].attrs = al; +- } +- } +- if( tags->bv_len ) { +- AttributeDescription *desc; +- +- desc = ad_find_tags( type, tags ); +- if( desc ) { +- slot = bdb_attr_slot( bdb, desc, NULL ); +- if ( slot >= 0 ) { +- ir[slot].ai = bdb->bi_attrs[slot]; +- al = ch_malloc( sizeof( AttrList )); +- al->attr = a; +- al->next = ir[slot].attrs; +- ir[slot].attrs = al; +- } +- } +- } +- return LDAP_SUCCESS; +-} +- +-/* Apply the indices for the recset */ +-int bdb_index_recrun( +- Operation *op, +- struct bdb_info *bdb, +- IndexRec *ir0, +- ID id, +- int base ) +-{ +- IndexRec *ir; +- AttrList *al; +- int i, rc = 0; +- +- /* Never index ID 0 */ +- if ( id == 0 ) +- return 0; +- +- for (i=base; ibi_nattrs; i+=slap_tool_thread_max-1) { +- ir = ir0 + i; +- if ( !ir->ai ) continue; +- while (( al = ir->attrs )) { +- ir->attrs = al->next; +- rc = indexer( op, NULL, ir->ai->ai_desc, +- &ir->ai->ai_desc->ad_type->sat_cname, +- al->attr->a_nvals, id, SLAP_INDEX_ADD_OP, +- ir->ai->ai_indexmask ); +- free( al ); +- if ( rc ) break; +- } +- } +- return rc; +-} +- +-int +-bdb_index_entry( +- Operation *op, +- DB_TXN *txn, +- int opid, +- Entry *e ) +-{ +- int rc; +- Attribute *ap = e->e_attrs; +-#if 0 /* ifdef LDAP_COMP_MATCH */ +- ComponentReference *cr_list = NULL; +- ComponentReference *cr = NULL, *dupped_cr = NULL; +- void* decoded_comp; +- ComponentSyntaxInfo* csi_attr; +- Syntax* syn; +- AttributeType* at; +- int i, num_attr; +- void* mem_op; +- struct berval value = {0}; +-#endif +- +- /* Never index ID 0 */ +- if ( e->e_id == 0 ) +- return 0; +- +- Debug( LDAP_DEBUG_TRACE, "=> index_entry_%s( %ld, \"%s\" )\n", +- opid == SLAP_INDEX_DELETE_OP ? "del" : "add", +- (long) e->e_id, e->e_dn ); +- +- /* add each attribute to the indexes */ +- for ( ; ap != NULL; ap = ap->a_next ) { +-#if 0 /* ifdef LDAP_COMP_MATCH */ +- AttrInfo *ai; +- /* see if attribute has components to be indexed */ +- ai = bdb_attr_mask( op->o_bd->be_private, ap->a_desc->ad_type->sat_ad ); +- if ( !ai ) continue; +- cr_list = ai->ai_cr; +- if ( attr_converter && cr_list ) { +- syn = ap->a_desc->ad_type->sat_syntax; +- ap->a_comp_data = op->o_tmpalloc( sizeof( ComponentData ), op->o_tmpmemctx ); +- /* Memory chunk(nibble) pre-allocation for decoders */ +- mem_op = nibble_mem_allocator ( 1024*16, 1024*4 ); +- ap->a_comp_data->cd_mem_op = mem_op; +- for( cr = cr_list ; cr ; cr = cr->cr_next ) { +- /* count how many values in an attribute */ +- for( num_attr=0; ap->a_vals[num_attr].bv_val != NULL; num_attr++ ); +- num_attr++; +- cr->cr_nvals = (BerVarray)op->o_tmpalloc( sizeof( struct berval )*num_attr, op->o_tmpmemctx ); +- for( i=0; ap->a_vals[i].bv_val != NULL; i++ ) { +- /* decoding attribute value */ +- decoded_comp = attr_converter ( ap, syn, &ap->a_vals[i] ); +- if ( !decoded_comp ) +- return LDAP_DECODING_ERROR; +- /* extracting the referenced component */ +- dupped_cr = dup_comp_ref( op, cr ); +- csi_attr = ((ComponentSyntaxInfo*)decoded_comp)->csi_comp_desc->cd_extract_i( mem_op, dupped_cr, decoded_comp ); +- if ( !csi_attr ) +- return LDAP_DECODING_ERROR; +- cr->cr_asn_type_id = csi_attr->csi_comp_desc->cd_type_id; +- cr->cr_ad = (AttributeDescription*)get_component_description ( cr->cr_asn_type_id ); +- if ( !cr->cr_ad ) +- return LDAP_INVALID_SYNTAX; +- at = cr->cr_ad->ad_type; +- /* encoding the value of component in GSER */ +- rc = component_encoder( mem_op, csi_attr, &value ); +- if ( rc != LDAP_SUCCESS ) +- return LDAP_ENCODING_ERROR; +- /* Normalize the encoded component values */ +- if ( at->sat_equality && at->sat_equality->smr_normalize ) { +- rc = at->sat_equality->smr_normalize ( +- SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, +- at->sat_syntax, at->sat_equality, +- &value, &cr->cr_nvals[i], op->o_tmpmemctx ); +- } else { +- cr->cr_nvals[i] = value; +- } +- } +- /* The end of BerVarray */ +- cr->cr_nvals[num_attr-1].bv_val = NULL; +- cr->cr_nvals[num_attr-1].bv_len = 0; +- } +- op->o_tmpfree( ap->a_comp_data, op->o_tmpmemctx ); +- nibble_mem_free ( mem_op ); +- ap->a_comp_data = NULL; +- } +-#endif +- rc = bdb_index_values( op, txn, ap->a_desc, +- ap->a_nvals, e->e_id, opid ); +- +- if( rc != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_TRACE, +- "<= index_entry_%s( %ld, \"%s\" ) failure\n", +- opid == SLAP_INDEX_ADD_OP ? "add" : "del", +- (long) e->e_id, e->e_dn ); +- return rc; +- } +- } +- +- Debug( LDAP_DEBUG_TRACE, "<= index_entry_%s( %ld, \"%s\" ) success\n", +- opid == SLAP_INDEX_DELETE_OP ? "del" : "add", +- (long) e->e_id, e->e_dn ); +- +- return LDAP_SUCCESS; +-} +diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c +deleted file mode 100644 +index 6c42d54..0000000 +--- a/servers/slapd/back-bdb/init.c ++++ /dev/null +@@ -1,874 +0,0 @@ +-/* init.c - initialize bdb backend */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include "back-bdb.h" +-#include +-#include +-#include "alock.h" +-#include "config.h" +- +-static const struct bdbi_database { +- char *file; +- struct berval name; +- int type; +- int flags; +-} bdbi_databases[] = { +- { "id2entry" BDB_SUFFIX, BER_BVC("id2entry"), DB_BTREE, 0 }, +- { "dn2id" BDB_SUFFIX, BER_BVC("dn2id"), DB_BTREE, 0 }, +- { NULL, BER_BVNULL, 0, 0 } +-}; +- +-typedef void * db_malloc(size_t); +-typedef void * db_realloc(void *, size_t); +- +-#define bdb_db_init BDB_SYMBOL(db_init) +-#define bdb_db_open BDB_SYMBOL(db_open) +-#define bdb_db_close BDB_SYMBOL(db_close) +- +-static int +-bdb_db_init( BackendDB *be, ConfigReply *cr ) +-{ +- struct bdb_info *bdb; +- int rc; +- +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_db_init) ": Initializing " BDB_UCTYPE " database\n", +- 0, 0, 0 ); +- +- /* allocate backend-database-specific stuff */ +- bdb = (struct bdb_info *) ch_calloc( 1, sizeof(struct bdb_info) ); +- +- /* DBEnv parameters */ +- bdb->bi_dbenv_home = ch_strdup( SLAPD_DEFAULT_DB_DIR ); +- bdb->bi_dbenv_xflags = DB_TIME_NOTGRANTED; +- bdb->bi_dbenv_mode = SLAPD_DEFAULT_DB_MODE; +- +- bdb->bi_cache.c_maxsize = DEFAULT_CACHE_SIZE; +- bdb->bi_cache.c_minfree = 1; +- +- bdb->bi_lock_detect = DB_LOCK_DEFAULT; +- bdb->bi_search_stack_depth = DEFAULT_SEARCH_STACK_DEPTH; +- bdb->bi_search_stack = NULL; +- +- ldap_pvt_thread_mutex_init( &bdb->bi_database_mutex ); +- ldap_pvt_thread_mutex_init( &bdb->bi_lastid_mutex ); +-#ifdef BDB_HIER +- ldap_pvt_thread_mutex_init( &bdb->bi_modrdns_mutex ); +-#endif +- ldap_pvt_thread_mutex_init( &bdb->bi_cache.c_lru_mutex ); +- ldap_pvt_thread_mutex_init( &bdb->bi_cache.c_count_mutex ); +- ldap_pvt_thread_mutex_init( &bdb->bi_cache.c_eifree_mutex ); +- ldap_pvt_thread_mutex_init( &bdb->bi_cache.c_dntree.bei_kids_mutex ); +- ldap_pvt_thread_rdwr_init ( &bdb->bi_cache.c_rwlock ); +- ldap_pvt_thread_rdwr_init( &bdb->bi_idl_tree_rwlock ); +- ldap_pvt_thread_mutex_init( &bdb->bi_idl_tree_lrulock ); +- +- be->be_private = bdb; +- be->be_cf_ocs = be->bd_info->bi_cf_ocs; +- +-#ifndef BDB_MULTIPLE_SUFFIXES +- SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_ONE_SUFFIX; +-#endif +- +- rc = bdb_monitor_db_init( be ); +- +- return rc; +-} +- +-static int +-bdb_db_close( BackendDB *be, ConfigReply *cr ); +- +-static int +-bdb_db_open( BackendDB *be, ConfigReply *cr ) +-{ +- int rc, i; +- struct bdb_info *bdb = (struct bdb_info *) be->be_private; +- struct stat stat1, stat2; +- u_int32_t flags; +- char path[MAXPATHLEN]; +- char *dbhome; +- Entry *e = NULL; +- int do_recover = 0, do_alock_recover = 0; +- int alockt, quick = 0; +- int do_retry = 1; +- +- if ( be->be_suffix == NULL ) { +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": need suffix.\n", +- 1, 0, 0 ); +- return -1; +- } +- +- Debug( LDAP_DEBUG_ARGS, +- LDAP_XSTRING(bdb_db_open) ": \"%s\"\n", +- be->be_suffix[0].bv_val, 0, 0 ); +- +- /* Check existence of dbenv_home. Any error means trouble */ +- rc = stat( bdb->bi_dbenv_home, &stat1 ); +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " +- "cannot access database directory \"%s\" (%d).\n", +- be->be_suffix[0].bv_val, bdb->bi_dbenv_home, errno ); +- return -1; +- } +- +- /* Perform database use arbitration/recovery logic */ +- alockt = (slapMode & SLAP_TOOL_READONLY) ? ALOCK_LOCKED : ALOCK_UNIQUE; +- if ( slapMode & SLAP_TOOL_QUICK ) { +- alockt |= ALOCK_NOSAVE; +- quick = 1; +- } +- +- rc = alock_open( &bdb->bi_alock_info, +- "slapd", +- bdb->bi_dbenv_home, alockt ); +- +- /* alockt is TRUE if the existing environment was created in Quick mode */ +- alockt = (rc & ALOCK_NOSAVE) ? 1 : 0; +- rc &= ~ALOCK_NOSAVE; +- +- if( rc == ALOCK_RECOVER ) { +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " +- "unclean shutdown detected; attempting recovery.\n", +- be->be_suffix[0].bv_val, 0, 0 ); +- do_alock_recover = 1; +- do_recover = DB_RECOVER; +- } else if( rc == ALOCK_BUSY ) { +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " +- "database already in use.\n", +- be->be_suffix[0].bv_val, 0, 0 ); +- return -1; +- } else if( rc != ALOCK_CLEAN ) { +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " +- "alock package is unstable.\n", +- be->be_suffix[0].bv_val, 0, 0 ); +- return -1; +- } +- if ( rc == ALOCK_CLEAN ) +- be->be_flags |= SLAP_DBFLAG_CLEAN; +- +- /* +- * The DB_CONFIG file may have changed. If so, recover the +- * database so that new settings are put into effect. Also +- * note the possible absence of DB_CONFIG in the log. +- */ +- if( stat( bdb->bi_db_config_path, &stat1 ) == 0 ) { +- if ( !do_recover ) { +- char *ptr = lutil_strcopy(path, bdb->bi_dbenv_home); +- *ptr++ = LDAP_DIRSEP[0]; +- strcpy( ptr, "__db.001" ); +- if( stat( path, &stat2 ) == 0 ) { +- if( stat2.st_mtime < stat1.st_mtime ) { +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": DB_CONFIG for suffix \"%s\" has changed.\n", +- be->be_suffix[0].bv_val, 0, 0 ); +- if ( quick ) { +- Debug( LDAP_DEBUG_ANY, +- "Cannot use Quick mode; perform manual recovery first.\n", +- 0, 0, 0 ); +- slapMode ^= SLAP_TOOL_QUICK; +- rc = -1; +- goto fail; +- } else { +- Debug( LDAP_DEBUG_ANY, +- "Performing database recovery to activate new settings.\n", +- 0, 0, 0 ); +- } +- do_recover = DB_RECOVER; +- } +- } +- } +- } +- else { +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": warning - no DB_CONFIG file found " +- "in directory %s: (%d).\n" +- "Expect poor performance for suffix \"%s\".\n", +- bdb->bi_dbenv_home, errno, be->be_suffix[0].bv_val ); +- } +- +- /* Always let slapcat run, regardless of environment state. +- * This can be used to cause a cache flush after an unclean +- * shutdown. +- */ +- if ( do_recover && ( slapMode & SLAP_TOOL_READONLY )) { +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " +- "recovery skipped in read-only mode. " +- "Run manual recovery if errors are encountered.\n", +- be->be_suffix[0].bv_val, 0, 0 ); +- do_recover = 0; +- do_alock_recover = 0; +- quick = alockt; +- } +- +- /* An existing environment in Quick mode has nothing to recover. */ +- if ( alockt && do_recover ) { +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " +- "cannot recover, database must be reinitialized.\n", +- be->be_suffix[0].bv_val, 0, 0 ); +- rc = -1; +- goto fail; +- } +- +- rc = db_env_create( &bdb->bi_dbenv, 0 ); +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " +- "db_env_create failed: %s (%d).\n", +- be->be_suffix[0].bv_val, db_strerror(rc), rc ); +- goto fail; +- } +- +-#ifdef HAVE_EBCDIC +- strcpy( path, bdb->bi_dbenv_home ); +- __atoe( path ); +- dbhome = path; +-#else +- dbhome = bdb->bi_dbenv_home; +-#endif +- +- /* If existing environment is clean but doesn't support +- * currently requested modes, remove it. +- */ +- if ( !do_recover && ( alockt ^ quick )) { +-shm_retry: +- rc = bdb->bi_dbenv->remove( bdb->bi_dbenv, dbhome, DB_FORCE ); +- if ( rc ) { +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " +- "dbenv remove failed: %s (%d).\n", +- be->be_suffix[0].bv_val, db_strerror(rc), rc ); +- bdb->bi_dbenv = NULL; +- goto fail; +- } +- rc = db_env_create( &bdb->bi_dbenv, 0 ); +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " +- "db_env_create failed: %s (%d).\n", +- be->be_suffix[0].bv_val, db_strerror(rc), rc ); +- goto fail; +- } +- } +- +- bdb->bi_dbenv->set_errpfx( bdb->bi_dbenv, be->be_suffix[0].bv_val ); +- bdb->bi_dbenv->set_errcall( bdb->bi_dbenv, bdb_errcall ); +- +- bdb->bi_dbenv->set_lk_detect( bdb->bi_dbenv, bdb->bi_lock_detect ); +- +- if ( !BER_BVISNULL( &bdb->bi_db_crypt_key )) { +- rc = bdb->bi_dbenv->set_encrypt( bdb->bi_dbenv, bdb->bi_db_crypt_key.bv_val, +- DB_ENCRYPT_AES ); +- if ( rc ) { +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " +- "dbenv set_encrypt failed: %s (%d).\n", +- be->be_suffix[0].bv_val, db_strerror(rc), rc ); +- goto fail; +- } +- } +- +- /* One long-lived TXN per thread, two TXNs per write op */ +- bdb->bi_dbenv->set_tx_max( bdb->bi_dbenv, connection_pool_max * 3 ); +- +- if( bdb->bi_dbenv_xflags != 0 ) { +- rc = bdb->bi_dbenv->set_flags( bdb->bi_dbenv, +- bdb->bi_dbenv_xflags, 1); +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " +- "dbenv_set_flags failed: %s (%d).\n", +- be->be_suffix[0].bv_val, db_strerror(rc), rc ); +- goto fail; +- } +- } +- +-#define BDB_TXN_FLAGS (DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN) +- +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " +- "dbenv_open(%s).\n", +- be->be_suffix[0].bv_val, bdb->bi_dbenv_home, 0); +- +- flags = DB_INIT_MPOOL | DB_CREATE | DB_THREAD; +- +- if ( !quick ) +- flags |= BDB_TXN_FLAGS; +- +- /* If a key was set, use shared memory for the BDB environment */ +- if ( bdb->bi_shm_key ) { +- bdb->bi_dbenv->set_shm_key( bdb->bi_dbenv, bdb->bi_shm_key ); +- flags |= DB_SYSTEM_MEM; +- } +- rc = (bdb->bi_dbenv->open)( bdb->bi_dbenv, dbhome, +- flags | do_recover, bdb->bi_dbenv_mode ); +- +- if ( rc ) { +- /* Regular open failed, probably a missing shm environment. +- * Start over, do a recovery. +- */ +- if ( !do_recover && bdb->bi_shm_key && do_retry ) { +- bdb->bi_dbenv->close( bdb->bi_dbenv, 0 ); +- rc = db_env_create( &bdb->bi_dbenv, 0 ); +- if( rc == 0 ) { +- Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_db_open) +- ": database \"%s\": " +- "shared memory env open failed, assuming stale env.\n", +- be->be_suffix[0].bv_val, 0, 0 ); +- do_retry = 0; +- goto shm_retry; +- } +- } +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": database \"%s\" cannot be %s, err %d. " +- "Restore from backup!\n", +- be->be_suffix[0].bv_val, do_recover ? "recovered" : "opened", rc ); +- goto fail; +- } +- +- if ( do_alock_recover && alock_recover (&bdb->bi_alock_info) != 0 ) { +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": database \"%s\": alock_recover failed\n", +- be->be_suffix[0].bv_val, 0, 0 ); +- rc = -1; +- goto fail; +- } +- +-#ifdef SLAP_ZONE_ALLOC +- if ( bdb->bi_cache.c_maxsize ) { +- bdb->bi_cache.c_zctx = slap_zn_mem_create( +- SLAP_ZONE_INITSIZE, SLAP_ZONE_MAXSIZE, +- SLAP_ZONE_DELTA, SLAP_ZONE_SIZE); +- } +-#endif +- +- /* dncache defaults to 0 == unlimited +- * must be >= entrycache +- */ +- if ( bdb->bi_cache.c_eimax && bdb->bi_cache.c_eimax < bdb->bi_cache.c_maxsize ) { +- bdb->bi_cache.c_eimax = bdb->bi_cache.c_maxsize; +- } +- +- if ( bdb->bi_idl_cache_max_size ) { +- bdb->bi_idl_tree = NULL; +- bdb->bi_idl_cache_size = 0; +- } +- +- flags = DB_THREAD | bdb->bi_db_opflags; +- +-#ifdef DB_AUTO_COMMIT +- if ( !quick ) +- flags |= DB_AUTO_COMMIT; +-#endif +- +- bdb->bi_databases = (struct bdb_db_info **) ch_malloc( +- BDB_INDICES * sizeof(struct bdb_db_info *) ); +- +- /* open (and create) main database */ +- for( i = 0; bdbi_databases[i].name.bv_val; i++ ) { +- struct bdb_db_info *db; +- +- db = (struct bdb_db_info *) ch_calloc(1, sizeof(struct bdb_db_info)); +- +- rc = db_create( &db->bdi_db, bdb->bi_dbenv, 0 ); +- if( rc != 0 ) { +- snprintf(cr->msg, sizeof(cr->msg), +- "database \"%s\": db_create(%s) failed: %s (%d).", +- be->be_suffix[0].bv_val, +- bdb->bi_dbenv_home, db_strerror(rc), rc ); +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": %s\n", +- cr->msg, 0, 0 ); +- ch_free( db ); +- goto fail; +- } +- +- if( !BER_BVISNULL( &bdb->bi_db_crypt_key )) { +- rc = db->bdi_db->set_flags( db->bdi_db, DB_ENCRYPT ); +- if ( rc ) { +- snprintf(cr->msg, sizeof(cr->msg), +- "database \"%s\": db set_flags(DB_ENCRYPT)(%s) failed: %s (%d).", +- be->be_suffix[0].bv_val, +- bdb->bi_dbenv_home, db_strerror(rc), rc ); +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": %s\n", +- cr->msg, 0, 0 ); +- db->bdi_db->close( db->bdi_db, 0 ); +- ch_free( db ); +- goto fail; +- } +- } +- +- if( bdb->bi_flags & BDB_CHKSUM ) { +- rc = db->bdi_db->set_flags( db->bdi_db, DB_CHKSUM ); +- if ( rc ) { +- snprintf(cr->msg, sizeof(cr->msg), +- "database \"%s\": db set_flags(DB_CHKSUM)(%s) failed: %s (%d).", +- be->be_suffix[0].bv_val, +- bdb->bi_dbenv_home, db_strerror(rc), rc ); +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": %s\n", +- cr->msg, 0, 0 ); +- db->bdi_db->close( db->bdi_db, 0 ); +- ch_free( db ); +- goto fail; +- } +- } +- +- rc = bdb_db_findsize( bdb, (struct berval *)&bdbi_databases[i].name ); +- +- if( i == BDB_ID2ENTRY ) { +- if ( !rc ) rc = BDB_ID2ENTRY_PAGESIZE; +- rc = db->bdi_db->set_pagesize( db->bdi_db, rc ); +- +- if ( slapMode & SLAP_TOOL_MODE ) +- db->bdi_db->mpf->set_priority( db->bdi_db->mpf, +- DB_PRIORITY_VERY_LOW ); +- +- if ( slapMode & SLAP_TOOL_READMAIN ) { +- flags |= DB_RDONLY; +- } else { +- flags |= DB_CREATE; +- } +- } else { +- /* Use FS default size if not configured */ +- if ( rc ) +- rc = db->bdi_db->set_pagesize( db->bdi_db, rc ); +- +- rc = db->bdi_db->set_flags( db->bdi_db, +- DB_DUP | DB_DUPSORT ); +-#ifndef BDB_HIER +- if ( slapMode & SLAP_TOOL_READONLY ) { +- flags |= DB_RDONLY; +- } else { +- flags |= DB_CREATE; +- } +-#else +- rc = db->bdi_db->set_dup_compare( db->bdi_db, +- bdb_dup_compare ); +- if ( slapMode & (SLAP_TOOL_READONLY|SLAP_TOOL_READMAIN) ) { +- flags |= DB_RDONLY; +- } else { +- flags |= DB_CREATE; +- } +-#endif +- } +- +-#ifdef HAVE_EBCDIC +- strcpy( path, bdbi_databases[i].file ); +- __atoe( path ); +- rc = DB_OPEN( db->bdi_db, +- path, +- /* bdbi_databases[i].name, */ NULL, +- bdbi_databases[i].type, +- bdbi_databases[i].flags | flags, +- bdb->bi_dbenv_mode ); +-#else +- rc = DB_OPEN( db->bdi_db, +- bdbi_databases[i].file, +- /* bdbi_databases[i].name, */ NULL, +- bdbi_databases[i].type, +- bdbi_databases[i].flags | flags, +- bdb->bi_dbenv_mode ); +-#endif +- +- if ( rc != 0 ) { +- snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": " +- "db_open(%s/%s) failed: %s (%d).", +- be->be_suffix[0].bv_val, +- bdb->bi_dbenv_home, bdbi_databases[i].file, +- db_strerror(rc), rc ); +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": %s\n", +- cr->msg, 0, 0 ); +- db->bdi_db->close( db->bdi_db, 0 ); +- ch_free( db ); +- goto fail; +- } +- +- flags &= ~(DB_CREATE | DB_RDONLY); +- db->bdi_name = bdbi_databases[i].name; +- bdb->bi_databases[i] = db; +- } +- +- bdb->bi_databases[i] = NULL; +- bdb->bi_ndatabases = i; +- +- /* get nextid */ +- rc = bdb_last_id( be, NULL ); +- if( rc != 0 ) { +- snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": " +- "last_id(%s) failed: %s (%d).", +- be->be_suffix[0].bv_val, bdb->bi_dbenv_home, +- db_strerror(rc), rc ); +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_db_open) ": %s\n", +- cr->msg, 0, 0 ); +- goto fail; +- } +- +- if ( !quick ) { +- int txflag = DB_READ_COMMITTED; +- /* avoid deadlocks in server; tools should +- * wait since they have no deadlock retry mechanism. +- */ +- if ( slapMode & SLAP_SERVER_MODE ) +- txflag |= DB_TXN_NOWAIT; +- TXN_BEGIN(bdb->bi_dbenv, NULL, &bdb->bi_cache.c_txn, txflag); +- } +- +- entry_prealloc( bdb->bi_cache.c_maxsize ); +- attr_prealloc( bdb->bi_cache.c_maxsize * 20 ); +- +- /* setup for empty-DN contexts */ +- if ( BER_BVISEMPTY( &be->be_nsuffix[0] )) { +- rc = bdb_id2entry( be, NULL, 0, &e ); +- } +- if ( !e ) { +- struct berval gluebv = BER_BVC("glue"); +- Operation op = {0}; +- Opheader ohdr = {0}; +- e = entry_alloc(); +- e->e_id = 0; +- ber_dupbv( &e->e_name, (struct berval *)&slap_empty_bv ); +- ber_dupbv( &e->e_nname, (struct berval *)&slap_empty_bv ); +- attr_merge_one( e, slap_schema.si_ad_objectClass, +- &gluebv, NULL ); +- attr_merge_one( e, slap_schema.si_ad_structuralObjectClass, +- &gluebv, NULL ); +- op.o_hdr = &ohdr; +- op.o_bd = be; +- op.ora_e = e; +- op.o_dn = be->be_rootdn; +- op.o_ndn = be->be_rootndn; +- slap_add_opattrs( &op, NULL, NULL, 0, 0 ); +- } +- e->e_ocflags = SLAP_OC_GLUE|SLAP_OC__END; +- e->e_private = &bdb->bi_cache.c_dntree; +- bdb->bi_cache.c_dntree.bei_e = e; +- +- /* monitor setup */ +- rc = bdb_monitor_db_open( be ); +- if ( rc != 0 ) { +- goto fail; +- } +- +- bdb->bi_flags |= BDB_IS_OPEN; +- +- return 0; +- +-fail: +- bdb_db_close( be, NULL ); +- return rc; +-} +- +-static int +-bdb_db_close( BackendDB *be, ConfigReply *cr ) +-{ +- int rc; +- struct bdb_info *bdb = (struct bdb_info *) be->be_private; +- struct bdb_db_info *db; +- bdb_idl_cache_entry_t *entry, *next_entry; +- +- /* monitor handling */ +- (void)bdb_monitor_db_close( be ); +- +- { +- Entry *e = bdb->bi_cache.c_dntree.bei_e; +- if ( e ) { +- bdb->bi_cache.c_dntree.bei_e = NULL; +- e->e_private = NULL; +- bdb_entry_return( e ); +- } +- } +- +- bdb->bi_flags &= ~BDB_IS_OPEN; +- +- ber_bvarray_free( bdb->bi_db_config ); +- bdb->bi_db_config = NULL; +- +- if( bdb->bi_dbenv ) { +- /* Free cache locker if we enabled locking. +- * TXNs must all be closed before DBs... +- */ +- if ( !( slapMode & SLAP_TOOL_QUICK ) && bdb->bi_cache.c_txn ) { +- TXN_ABORT( bdb->bi_cache.c_txn ); +- bdb->bi_cache.c_txn = NULL; +- } +- bdb_reader_flush( bdb->bi_dbenv ); +- } +- +- while( bdb->bi_databases && bdb->bi_ndatabases-- ) { +- db = bdb->bi_databases[bdb->bi_ndatabases]; +- rc = db->bdi_db->close( db->bdi_db, 0 ); +- /* Lower numbered names are not strdup'd */ +- if( bdb->bi_ndatabases >= BDB_NDB ) +- free( db->bdi_name.bv_val ); +- free( db ); +- } +- free( bdb->bi_databases ); +- bdb->bi_databases = NULL; +- +- bdb_cache_release_all (&bdb->bi_cache); +- +- if ( bdb->bi_idl_cache_size ) { +- avl_free( bdb->bi_idl_tree, NULL ); +- bdb->bi_idl_tree = NULL; +- entry = bdb->bi_idl_lru_head; +- do { +- next_entry = entry->idl_lru_next; +- if ( entry->idl ) +- free( entry->idl ); +- free( entry->kstr.bv_val ); +- free( entry ); +- entry = next_entry; +- } while ( entry != bdb->bi_idl_lru_head ); +- bdb->bi_idl_lru_head = bdb->bi_idl_lru_tail = NULL; +- } +- +- /* close db environment */ +- if( bdb->bi_dbenv ) { +- /* force a checkpoint, but not if we were ReadOnly, +- * and not in Quick mode since there are no transactions there. +- */ +- if ( !( slapMode & ( SLAP_TOOL_QUICK|SLAP_TOOL_READONLY ))) { +- rc = TXN_CHECKPOINT( bdb->bi_dbenv, 0, 0, DB_FORCE ); +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, +- "bdb_db_close: database \"%s\": " +- "txn_checkpoint failed: %s (%d).\n", +- be->be_suffix[0].bv_val, db_strerror(rc), rc ); +- } +- } +- +- rc = bdb->bi_dbenv->close( bdb->bi_dbenv, 0 ); +- bdb->bi_dbenv = NULL; +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, +- "bdb_db_close: database \"%s\": " +- "close failed: %s (%d)\n", +- be->be_suffix[0].bv_val, db_strerror(rc), rc ); +- return rc; +- } +- } +- +- rc = alock_close( &bdb->bi_alock_info, slapMode & SLAP_TOOL_QUICK ); +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, +- "bdb_db_close: database \"%s\": alock_close failed\n", +- be->be_suffix[0].bv_val, 0, 0 ); +- return -1; +- } +- +- return 0; +-} +- +-static int +-bdb_db_destroy( BackendDB *be, ConfigReply *cr ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) be->be_private; +- +- /* stop and remove checkpoint task */ +- if ( bdb->bi_txn_cp_task ) { +- struct re_s *re = bdb->bi_txn_cp_task; +- bdb->bi_txn_cp_task = NULL; +- ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); +- if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ) ) +- ldap_pvt_runqueue_stoptask( &slapd_rq, re ); +- ldap_pvt_runqueue_remove( &slapd_rq, re ); +- ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); +- } +- +- /* monitor handling */ +- (void)bdb_monitor_db_destroy( be ); +- +- if( bdb->bi_dbenv_home ) ch_free( bdb->bi_dbenv_home ); +- if( bdb->bi_db_config_path ) ch_free( bdb->bi_db_config_path ); +- +- bdb_attr_index_destroy( bdb ); +- +- ldap_pvt_thread_rdwr_destroy ( &bdb->bi_cache.c_rwlock ); +- ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_lru_mutex ); +- ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_count_mutex ); +- ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_eifree_mutex ); +- ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_dntree.bei_kids_mutex ); +-#ifdef BDB_HIER +- ldap_pvt_thread_mutex_destroy( &bdb->bi_modrdns_mutex ); +-#endif +- ldap_pvt_thread_mutex_destroy( &bdb->bi_lastid_mutex ); +- ldap_pvt_thread_mutex_destroy( &bdb->bi_database_mutex ); +- ldap_pvt_thread_rdwr_destroy( &bdb->bi_idl_tree_rwlock ); +- ldap_pvt_thread_mutex_destroy( &bdb->bi_idl_tree_lrulock ); +- +- ch_free( bdb ); +- be->be_private = NULL; +- +- return 0; +-} +- +-int +-bdb_back_initialize( +- BackendInfo *bi ) +-{ +- int rc; +- +- static char *controls[] = { +- LDAP_CONTROL_ASSERT, +- LDAP_CONTROL_MANAGEDSAIT, +- LDAP_CONTROL_NOOP, +- LDAP_CONTROL_PAGEDRESULTS, +- LDAP_CONTROL_PRE_READ, +- LDAP_CONTROL_POST_READ, +- LDAP_CONTROL_SUBENTRIES, +- LDAP_CONTROL_X_PERMISSIVE_MODIFY, +-#ifdef LDAP_X_TXN +- LDAP_CONTROL_X_TXN_SPEC, +-#endif +- NULL +- }; +- +- /* initialize the underlying database system */ +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_back_initialize) ": initialize " +- BDB_UCTYPE " backend\n", 0, 0, 0 ); +- +- bi->bi_flags |= +- SLAP_BFLAG_INCREMENT | +- SLAP_BFLAG_SUBENTRIES | +- SLAP_BFLAG_ALIASES | +- SLAP_BFLAG_REFERRALS; +- +- bi->bi_controls = controls; +- +- { /* version check */ +- int major, minor, patch, ver; +- char *version = db_version( &major, &minor, &patch ); +-#ifdef HAVE_EBCDIC +- char v2[1024]; +- +- /* All our stdio does an ASCII to EBCDIC conversion on +- * the output. Strings from the BDB library are already +- * in EBCDIC; we have to go back and forth... +- */ +- strcpy( v2, version ); +- __etoa( v2 ); +- version = v2; +-#endif +- +- ver = (major << 24) | (minor << 16) | patch; +- if( ver != DB_VERSION_FULL ) { +- /* fail if a versions don't match */ +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_back_initialize) ": " +- "BDB library version mismatch:" +- " expected " DB_VERSION_STRING "," +- " got %s\n", version, 0, 0 ); +- return -1; +- } +- +- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_back_initialize) +- ": %s\n", version, 0, 0 ); +- } +- +- db_env_set_func_free( ber_memfree ); +- db_env_set_func_malloc( (db_malloc *)ber_memalloc ); +- db_env_set_func_realloc( (db_realloc *)ber_memrealloc ); +-#if !defined(NO_THREAD) && DB_VERSION_FULL <= 0x04070000 +- /* This is a no-op on a NO_THREAD build. Leave the default +- * alone so that BDB will sleep on interprocess conflicts. +- * Don't bother on BDB 4.7... +- */ +- db_env_set_func_yield( ldap_pvt_thread_yield ); +-#endif +- +- bi->bi_open = 0; +- bi->bi_close = 0; +- bi->bi_config = 0; +- bi->bi_destroy = 0; +- +- bi->bi_db_init = bdb_db_init; +- bi->bi_db_config = config_generic_wrapper; +- bi->bi_db_open = bdb_db_open; +- bi->bi_db_close = bdb_db_close; +- bi->bi_db_destroy = bdb_db_destroy; +- +- bi->bi_op_add = bdb_add; +- bi->bi_op_bind = bdb_bind; +- bi->bi_op_compare = bdb_compare; +- bi->bi_op_delete = bdb_delete; +- bi->bi_op_modify = bdb_modify; +- bi->bi_op_modrdn = bdb_modrdn; +- bi->bi_op_search = bdb_search; +- +- bi->bi_op_unbind = 0; +- +- bi->bi_extended = bdb_extended; +- +- bi->bi_chk_referrals = bdb_referrals; +- bi->bi_operational = bdb_operational; +- bi->bi_has_subordinates = bdb_hasSubordinates; +- bi->bi_entry_release_rw = bdb_entry_release; +- bi->bi_entry_get_rw = bdb_entry_get; +- +- /* +- * hooks for slap tools +- */ +- bi->bi_tool_entry_open = bdb_tool_entry_open; +- bi->bi_tool_entry_close = bdb_tool_entry_close; +- bi->bi_tool_entry_first = backend_tool_entry_first; +- bi->bi_tool_entry_first_x = bdb_tool_entry_first_x; +- bi->bi_tool_entry_next = bdb_tool_entry_next; +- bi->bi_tool_entry_get = bdb_tool_entry_get; +- bi->bi_tool_entry_put = bdb_tool_entry_put; +- bi->bi_tool_entry_reindex = bdb_tool_entry_reindex; +- bi->bi_tool_sync = 0; +- bi->bi_tool_dn2id_get = bdb_tool_dn2id_get; +- bi->bi_tool_entry_modify = bdb_tool_entry_modify; +- +- bi->bi_connection_init = 0; +- bi->bi_connection_destroy = 0; +- +- rc = bdb_back_init_cf( bi ); +- +- return rc; +-} +- +-#if (SLAPD_BDB == SLAPD_MOD_DYNAMIC && !defined(BDB_HIER)) || \ +- (SLAPD_HDB == SLAPD_MOD_DYNAMIC && defined(BDB_HIER)) +- +-/* conditionally define the init_module() function */ +-#ifdef BDB_HIER +-SLAP_BACKEND_INIT_MODULE( hdb ) +-#else /* !BDB_HIER */ +-SLAP_BACKEND_INIT_MODULE( bdb ) +-#endif /* !BDB_HIER */ +- +-#endif /* SLAPD_[BH]DB == SLAPD_MOD_DYNAMIC */ +- +diff --git a/servers/slapd/back-bdb/key.c b/servers/slapd/back-bdb/key.c +deleted file mode 100644 +index 417ad70..0000000 +--- a/servers/slapd/back-bdb/key.c ++++ /dev/null +@@ -1,104 +0,0 @@ +-/* index.c - routines for dealing with attribute indexes */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +- +-#include +-#include +- +-#include "slap.h" +-#include "back-bdb.h" +-#include "idl.h" +- +-/* read a key */ +-int +-bdb_key_read( +- Backend *be, +- DB *db, +- DB_TXN *txn, +- struct berval *k, +- ID *ids, +- DBC **saved_cursor, +- int get_flag +-) +-{ +- int rc; +- DBT key; +- +- Debug( LDAP_DEBUG_TRACE, "=> key_read\n", 0, 0, 0 ); +- +- DBTzero( &key ); +- bv2DBT(k,&key); +- key.ulen = key.size; +- key.flags = DB_DBT_USERMEM; +- +- rc = bdb_idl_fetch_key( be, db, txn, &key, ids, saved_cursor, get_flag ); +- +- if( rc != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_TRACE, "<= bdb_index_read: failed (%d)\n", +- rc, 0, 0 ); +- } else { +- Debug( LDAP_DEBUG_TRACE, "<= bdb_index_read %ld candidates\n", +- (long) BDB_IDL_N(ids), 0, 0 ); +- } +- +- return rc; +-} +- +-/* Add or remove stuff from index files */ +-int +-bdb_key_change( +- Backend *be, +- DB *db, +- DB_TXN *txn, +- struct berval *k, +- ID id, +- int op +-) +-{ +- int rc; +- DBT key; +- +- Debug( LDAP_DEBUG_TRACE, "=> key_change(%s,%lx)\n", +- op == SLAP_INDEX_ADD_OP ? "ADD":"DELETE", (long) id, 0 ); +- +- DBTzero( &key ); +- bv2DBT(k,&key); +- key.ulen = key.size; +- key.flags = DB_DBT_USERMEM; +- +- if (op == SLAP_INDEX_ADD_OP) { +- /* Add values */ +- +-#ifdef BDB_TOOL_IDL_CACHING +- if ( slapMode & SLAP_TOOL_QUICK ) +- rc = bdb_tool_idl_add( be, db, txn, &key, id ); +- else +-#endif +- rc = bdb_idl_insert_key( be, db, txn, &key, id ); +- if ( rc == DB_KEYEXIST ) rc = 0; +- } else { +- /* Delete values */ +- rc = bdb_idl_delete_key( be, db, txn, &key, id ); +- if ( rc == DB_NOTFOUND ) rc = 0; +- } +- +- Debug( LDAP_DEBUG_TRACE, "<= key_change %d\n", rc, 0, 0 ); +- +- return rc; +-} +diff --git a/servers/slapd/back-bdb/modify.c b/servers/slapd/back-bdb/modify.c +deleted file mode 100644 +index fb7dbe3..0000000 +--- a/servers/slapd/back-bdb/modify.c ++++ /dev/null +@@ -1,835 +0,0 @@ +-/* modify.c - bdb backend modify routine */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +-#include +-#include +- +-#include "back-bdb.h" +- +-static struct berval scbva[] = { +- BER_BVC("glue"), +- BER_BVNULL +-}; +- +-static void +-bdb_modify_idxflags( +- Operation *op, +- AttributeDescription *desc, +- int got_delete, +- Attribute *newattrs, +- Attribute *oldattrs ) +-{ +- struct berval ix_at; +- AttrInfo *ai; +- +- /* check if modified attribute was indexed +- * but not in case of NOOP... */ +- ai = bdb_index_mask( op->o_bd, desc, &ix_at ); +- if ( ai ) { +- if ( got_delete ) { +- Attribute *ap; +- struct berval ix2; +- +- ap = attr_find( oldattrs, desc ); +- if ( ap ) ap->a_flags |= SLAP_ATTR_IXDEL; +- +- /* Find all other attrs that index to same slot */ +- for ( ap = newattrs; ap; ap = ap->a_next ) { +- ai = bdb_index_mask( op->o_bd, ap->a_desc, &ix2 ); +- if ( ai && ix2.bv_val == ix_at.bv_val ) +- ap->a_flags |= SLAP_ATTR_IXADD; +- } +- +- } else { +- Attribute *ap; +- +- ap = attr_find( newattrs, desc ); +- if ( ap ) ap->a_flags |= SLAP_ATTR_IXADD; +- } +- } +-} +- +-int bdb_modify_internal( +- Operation *op, +- DB_TXN *tid, +- Modifications *modlist, +- Entry *e, +- const char **text, +- char *textbuf, +- size_t textlen ) +-{ +- int rc, err; +- Modification *mod; +- Modifications *ml; +- Attribute *save_attrs; +- Attribute *ap; +- int glue_attr_delete = 0; +- int got_delete; +- +- Debug( LDAP_DEBUG_TRACE, "bdb_modify_internal: 0x%08lx: %s\n", +- e->e_id, e->e_dn, 0); +- +- if ( !acl_check_modlist( op, e, modlist )) { +- return LDAP_INSUFFICIENT_ACCESS; +- } +- +- /* save_attrs will be disposed of by bdb_cache_modify */ +- save_attrs = e->e_attrs; +- e->e_attrs = attrs_dup( e->e_attrs ); +- +- for ( ml = modlist; ml != NULL; ml = ml->sml_next ) { +- int match; +- mod = &ml->sml_mod; +- switch( mod->sm_op ) { +- case LDAP_MOD_ADD: +- case LDAP_MOD_REPLACE: +- if ( mod->sm_desc == slap_schema.si_ad_structuralObjectClass ) { +- value_match( &match, slap_schema.si_ad_structuralObjectClass, +- slap_schema.si_ad_structuralObjectClass-> +- ad_type->sat_equality, +- SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, +- &mod->sm_values[0], &scbva[0], text ); +- if ( !match ) glue_attr_delete = 1; +- } +- } +- if ( glue_attr_delete ) +- break; +- } +- +- if ( glue_attr_delete ) { +- Attribute **app = &e->e_attrs; +- while ( *app != NULL ) { +- if ( !is_at_operational( (*app)->a_desc->ad_type )) { +- Attribute *save = *app; +- *app = (*app)->a_next; +- attr_free( save ); +- continue; +- } +- app = &(*app)->a_next; +- } +- } +- +- for ( ml = modlist; ml != NULL; ml = ml->sml_next ) { +- mod = &ml->sml_mod; +- got_delete = 0; +- +- switch ( mod->sm_op ) { +- case LDAP_MOD_ADD: +- Debug(LDAP_DEBUG_ARGS, +- "bdb_modify_internal: add %s\n", +- mod->sm_desc->ad_cname.bv_val, 0, 0); +- err = modify_add_values( e, mod, get_permissiveModify(op), +- text, textbuf, textlen ); +- if( err != LDAP_SUCCESS ) { +- Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n", +- err, *text, 0); +- } +- break; +- +- case LDAP_MOD_DELETE: +- if ( glue_attr_delete ) { +- err = LDAP_SUCCESS; +- break; +- } +- +- Debug(LDAP_DEBUG_ARGS, +- "bdb_modify_internal: delete %s\n", +- mod->sm_desc->ad_cname.bv_val, 0, 0); +- err = modify_delete_values( e, mod, get_permissiveModify(op), +- text, textbuf, textlen ); +- if( err != LDAP_SUCCESS ) { +- Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n", +- err, *text, 0); +- } else { +- got_delete = 1; +- } +- break; +- +- case LDAP_MOD_REPLACE: +- Debug(LDAP_DEBUG_ARGS, +- "bdb_modify_internal: replace %s\n", +- mod->sm_desc->ad_cname.bv_val, 0, 0); +- err = modify_replace_values( e, mod, get_permissiveModify(op), +- text, textbuf, textlen ); +- if( err != LDAP_SUCCESS ) { +- Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n", +- err, *text, 0); +- } else { +- got_delete = 1; +- } +- break; +- +- case LDAP_MOD_INCREMENT: +- Debug(LDAP_DEBUG_ARGS, +- "bdb_modify_internal: increment %s\n", +- mod->sm_desc->ad_cname.bv_val, 0, 0); +- err = modify_increment_values( e, mod, get_permissiveModify(op), +- text, textbuf, textlen ); +- if( err != LDAP_SUCCESS ) { +- Debug(LDAP_DEBUG_ARGS, +- "bdb_modify_internal: %d %s\n", +- err, *text, 0); +- } else { +- got_delete = 1; +- } +- break; +- +- case SLAP_MOD_SOFTADD: +- Debug(LDAP_DEBUG_ARGS, +- "bdb_modify_internal: softadd %s\n", +- mod->sm_desc->ad_cname.bv_val, 0, 0); +- /* Avoid problems in index_add_mods() +- * We need to add index if necessary. +- */ +- mod->sm_op = LDAP_MOD_ADD; +- +- err = modify_add_values( e, mod, get_permissiveModify(op), +- text, textbuf, textlen ); +- +- mod->sm_op = SLAP_MOD_SOFTADD; +- +- if ( err == LDAP_TYPE_OR_VALUE_EXISTS ) { +- err = LDAP_SUCCESS; +- } +- +- if( err != LDAP_SUCCESS ) { +- Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n", +- err, *text, 0); +- } +- break; +- +- case SLAP_MOD_SOFTDEL: +- Debug(LDAP_DEBUG_ARGS, +- "bdb_modify_internal: softdel %s\n", +- mod->sm_desc->ad_cname.bv_val, 0, 0); +- /* Avoid problems in index_delete_mods() +- * We need to add index if necessary. +- */ +- mod->sm_op = LDAP_MOD_DELETE; +- +- err = modify_delete_values( e, mod, get_permissiveModify(op), +- text, textbuf, textlen ); +- +- mod->sm_op = SLAP_MOD_SOFTDEL; +- +- if ( err == LDAP_SUCCESS ) { +- got_delete = 1; +- } else if ( err == LDAP_NO_SUCH_ATTRIBUTE ) { +- err = LDAP_SUCCESS; +- } +- +- if( err != LDAP_SUCCESS ) { +- Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n", +- err, *text, 0); +- } +- break; +- +- case SLAP_MOD_ADD_IF_NOT_PRESENT: +- if ( attr_find( e->e_attrs, mod->sm_desc ) != NULL ) { +- /* skip */ +- err = LDAP_SUCCESS; +- break; +- } +- +- Debug(LDAP_DEBUG_ARGS, +- "bdb_modify_internal: add_if_not_present %s\n", +- mod->sm_desc->ad_cname.bv_val, 0, 0); +- /* Avoid problems in index_add_mods() +- * We need to add index if necessary. +- */ +- mod->sm_op = LDAP_MOD_ADD; +- +- err = modify_add_values( e, mod, get_permissiveModify(op), +- text, textbuf, textlen ); +- +- mod->sm_op = SLAP_MOD_ADD_IF_NOT_PRESENT; +- +- if( err != LDAP_SUCCESS ) { +- Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n", +- err, *text, 0); +- } +- break; +- +- default: +- Debug(LDAP_DEBUG_ANY, "bdb_modify_internal: invalid op %d\n", +- mod->sm_op, 0, 0); +- *text = "Invalid modify operation"; +- err = LDAP_OTHER; +- Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n", +- err, *text, 0); +- } +- +- if ( err != LDAP_SUCCESS ) { +- attrs_free( e->e_attrs ); +- e->e_attrs = save_attrs; +- /* unlock entry, delete from cache */ +- return err; +- } +- +- /* If objectClass was modified, reset the flags */ +- if ( mod->sm_desc == slap_schema.si_ad_objectClass ) { +- e->e_ocflags = 0; +- } +- +- if ( glue_attr_delete ) e->e_ocflags = 0; +- +- +- /* check if modified attribute was indexed +- * but not in case of NOOP... */ +- if ( !op->o_noop ) { +- bdb_modify_idxflags( op, mod->sm_desc, got_delete, e->e_attrs, save_attrs ); +- } +- } +- +- /* check that the entry still obeys the schema */ +- ap = NULL; +- rc = entry_schema_check( op, e, save_attrs, get_relax(op), 0, &ap, +- text, textbuf, textlen ); +- if ( rc != LDAP_SUCCESS || op->o_noop ) { +- attrs_free( e->e_attrs ); +- /* clear the indexing flags */ +- for ( ap = save_attrs; ap != NULL; ap = ap->a_next ) { +- ap->a_flags &= ~(SLAP_ATTR_IXADD|SLAP_ATTR_IXDEL); +- } +- e->e_attrs = save_attrs; +- +- if ( rc != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_ANY, +- "entry failed schema check: %s\n", +- *text, 0, 0 ); +- } +- +- /* if NOOP then silently revert to saved attrs */ +- return rc; +- } +- +- /* structuralObjectClass modified! */ +- if ( ap ) { +- assert( ap->a_desc == slap_schema.si_ad_structuralObjectClass ); +- if ( !op->o_noop ) { +- bdb_modify_idxflags( op, slap_schema.si_ad_structuralObjectClass, +- 1, e->e_attrs, save_attrs ); +- } +- } +- +- /* update the indices of the modified attributes */ +- +- /* start with deleting the old index entries */ +- for ( ap = save_attrs; ap != NULL; ap = ap->a_next ) { +- if ( ap->a_flags & SLAP_ATTR_IXDEL ) { +- struct berval *vals; +- Attribute *a2; +- ap->a_flags &= ~SLAP_ATTR_IXDEL; +- a2 = attr_find( e->e_attrs, ap->a_desc ); +- if ( a2 ) { +- /* need to detect which values were deleted */ +- int i, j; +- /* let add know there were deletes */ +- if ( a2->a_flags & SLAP_ATTR_IXADD ) +- a2->a_flags |= SLAP_ATTR_IXDEL; +- vals = op->o_tmpalloc( (ap->a_numvals + 1) * +- sizeof(struct berval), op->o_tmpmemctx ); +- j = 0; +- for ( i=0; i < ap->a_numvals; i++ ) { +- rc = attr_valfind( a2, SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH, +- &ap->a_nvals[i], NULL, op->o_tmpmemctx ); +- /* Save deleted values */ +- if ( rc == LDAP_NO_SUCH_ATTRIBUTE ) +- vals[j++] = ap->a_nvals[i]; +- } +- BER_BVZERO(vals+j); +- } else { +- /* attribute was completely deleted */ +- vals = ap->a_nvals; +- } +- rc = 0; +- if ( !BER_BVISNULL( vals )) { +- rc = bdb_index_values( op, tid, ap->a_desc, +- vals, e->e_id, SLAP_INDEX_DELETE_OP ); +- if ( rc != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_ANY, +- "%s: attribute \"%s\" index delete failure\n", +- op->o_log_prefix, ap->a_desc->ad_cname.bv_val, 0 ); +- attrs_free( e->e_attrs ); +- e->e_attrs = save_attrs; +- } +- } +- if ( vals != ap->a_nvals ) +- op->o_tmpfree( vals, op->o_tmpmemctx ); +- if ( rc ) return rc; +- } +- } +- +- /* add the new index entries */ +- for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) { +- if (ap->a_flags & SLAP_ATTR_IXADD) { +- ap->a_flags &= ~SLAP_ATTR_IXADD; +- if ( ap->a_flags & SLAP_ATTR_IXDEL ) { +- /* if any values were deleted, we must readd index +- * for all remaining values. +- */ +- ap->a_flags &= ~SLAP_ATTR_IXDEL; +- rc = bdb_index_values( op, tid, ap->a_desc, +- ap->a_nvals, +- e->e_id, SLAP_INDEX_ADD_OP ); +- } else { +- int found = 0; +- /* if this was only an add, we only need to index +- * the added values. +- */ +- for ( ml = modlist; ml != NULL; ml = ml->sml_next ) { +- struct berval *vals; +- if ( ml->sml_desc != ap->a_desc || !ml->sml_numvals ) +- continue; +- found = 1; +- switch( ml->sml_op ) { +- case LDAP_MOD_ADD: +- case LDAP_MOD_REPLACE: +- case LDAP_MOD_INCREMENT: +- case SLAP_MOD_SOFTADD: +- case SLAP_MOD_ADD_IF_NOT_PRESENT: +- if ( ml->sml_op == LDAP_MOD_INCREMENT ) +- vals = ap->a_nvals; +- else if ( ml->sml_nvalues ) +- vals = ml->sml_nvalues; +- else +- vals = ml->sml_values; +- rc = bdb_index_values( op, tid, ap->a_desc, +- vals, e->e_id, SLAP_INDEX_ADD_OP ); +- break; +- } +- if ( rc ) +- break; +- } +- /* This attr was affected by a modify of a subtype, so +- * there was no direct match in the modlist. Just readd +- * all of its values. +- */ +- if ( !found ) { +- rc = bdb_index_values( op, tid, ap->a_desc, +- ap->a_nvals, +- e->e_id, SLAP_INDEX_ADD_OP ); +- } +- } +- if ( rc != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_ANY, +- "%s: attribute \"%s\" index add failure\n", +- op->o_log_prefix, ap->a_desc->ad_cname.bv_val, 0 ); +- attrs_free( e->e_attrs ); +- e->e_attrs = save_attrs; +- return rc; +- } +- } +- } +- +- return rc; +-} +- +- +-int +-bdb_modify( Operation *op, SlapReply *rs ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- Entry *e = NULL; +- EntryInfo *ei = NULL; +- int manageDSAit = get_manageDSAit( op ); +- char textbuf[SLAP_TEXT_BUFLEN]; +- size_t textlen = sizeof textbuf; +- DB_TXN *ltid = NULL, *lt2; +- struct bdb_op_info opinfo = {{{ 0 }}}; +- Entry dummy = {0}; +- +- DB_LOCK lock; +- +- int num_retries = 0; +- +- LDAPControl **preread_ctrl = NULL; +- LDAPControl **postread_ctrl = NULL; +- LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS]; +- int num_ctrls = 0; +- +- int rc; +- +-#ifdef LDAP_X_TXN +- int settle = 0; +-#endif +- +- Debug( LDAP_DEBUG_ARGS, LDAP_XSTRING(bdb_modify) ": %s\n", +- op->o_req_dn.bv_val, 0, 0 ); +- +-#ifdef LDAP_X_TXN +- if( op->o_txnSpec ) { +- /* acquire connection lock */ +- ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); +- if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) { +- rs->sr_text = "invalid transaction identifier"; +- rs->sr_err = LDAP_X_TXN_ID_INVALID; +- goto txnReturn; +- } else if( op->o_conn->c_txn == CONN_TXN_SETTLE ) { +- settle=1; +- goto txnReturn; +- } +- +- if( op->o_conn->c_txn_backend == NULL ) { +- op->o_conn->c_txn_backend = op->o_bd; +- +- } else if( op->o_conn->c_txn_backend != op->o_bd ) { +- rs->sr_text = "transaction cannot span multiple database contexts"; +- rs->sr_err = LDAP_AFFECTS_MULTIPLE_DSAS; +- goto txnReturn; +- } +- +- /* insert operation into transaction */ +- +- rs->sr_text = "transaction specified"; +- rs->sr_err = LDAP_X_TXN_SPECIFY_OKAY; +- +-txnReturn: +- /* release connection lock */ +- ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); +- +- if( !settle ) { +- send_ldap_result( op, rs ); +- return rs->sr_err; +- } +- } +-#endif +- +- ctrls[num_ctrls] = NULL; +- +- /* Don't touch the opattrs, if this is a contextCSN update +- * initiated from updatedn */ +- if ( !be_isupdate(op) || !op->orm_modlist || op->orm_modlist->sml_next || +- op->orm_modlist->sml_desc != slap_schema.si_ad_contextCSN ) { +- +- slap_mods_opattrs( op, &op->orm_modlist, 1 ); +- } +- +- if( 0 ) { +-retry: /* transaction retry */ +- if ( dummy.e_attrs ) { +- attrs_free( dummy.e_attrs ); +- dummy.e_attrs = NULL; +- } +- if( e != NULL ) { +- bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e); +- e = NULL; +- } +- Debug(LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modify) ": retrying...\n", 0, 0, 0); +- +- rs->sr_err = TXN_ABORT( ltid ); +- ltid = NULL; +- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); +- opinfo.boi_oe.oe_key = NULL; +- op->o_do_not_cache = opinfo.boi_acl_cache; +- if( rs->sr_err != 0 ) { +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- if ( op->o_abandon ) { +- rs->sr_err = SLAPD_ABANDON; +- goto return_results; +- } +- bdb_trans_backoff( ++num_retries ); +- } +- +- /* begin transaction */ +- rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, <id, +- bdb->bi_db_opflags ); +- rs->sr_text = NULL; +- if( rs->sr_err != 0 ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modify) ": txn_begin failed: " +- "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 ); +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modify) ": txn1 id: %x\n", +- ltid->id(ltid), 0, 0 ); +- +- opinfo.boi_oe.oe_key = bdb; +- opinfo.boi_txn = ltid; +- opinfo.boi_err = 0; +- opinfo.boi_acl_cache = op->o_do_not_cache; +- LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.boi_oe, oe_next ); +- +- /* get entry or ancestor */ +- rs->sr_err = bdb_dn2entry( op, ltid, &op->o_req_ndn, &ei, 1, +- &lock ); +- +- if ( rs->sr_err != 0 ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modify) ": dn2entry failed (%d)\n", +- rs->sr_err, 0, 0 ); +- switch( rs->sr_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- case DB_NOTFOUND: +- break; +- case LDAP_BUSY: +- rs->sr_text = "ldap server busy"; +- goto return_results; +- default: +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- } +- +- e = ei->bei_e; +- +- /* acquire and lock entry */ +- /* FIXME: dn2entry() should return non-glue entry */ +- if (( rs->sr_err == DB_NOTFOUND ) || +- ( !manageDSAit && e && is_entry_glue( e ))) +- { +- if ( e != NULL ) { +- rs->sr_matched = ch_strdup( e->e_dn ); +- rs->sr_ref = is_entry_referral( e ) +- ? get_entry_referrals( op, e ) +- : NULL; +- bdb_unlocked_cache_return_entry_r (&bdb->bi_cache, e); +- e = NULL; +- +- } else { +- rs->sr_ref = referral_rewrite( default_referral, NULL, +- &op->o_req_dn, LDAP_SCOPE_DEFAULT ); +- } +- +- rs->sr_err = LDAP_REFERRAL; +- send_ldap_result( op, rs ); +- +- if ( rs->sr_ref != default_referral ) { +- ber_bvarray_free( rs->sr_ref ); +- } +- free( (char *)rs->sr_matched ); +- rs->sr_ref = NULL; +- rs->sr_matched = NULL; +- +- goto done; +- } +- +- if ( !manageDSAit && is_entry_referral( e ) ) { +- /* entry is a referral, don't allow modify */ +- rs->sr_ref = get_entry_referrals( op, e ); +- +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modify) ": entry is referral\n", +- 0, 0, 0 ); +- +- rs->sr_err = LDAP_REFERRAL; +- rs->sr_matched = e->e_name.bv_val; +- send_ldap_result( op, rs ); +- +- ber_bvarray_free( rs->sr_ref ); +- rs->sr_ref = NULL; +- rs->sr_matched = NULL; +- goto done; +- } +- +- if ( get_assert( op ) && +- ( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE )) +- { +- rs->sr_err = LDAP_ASSERTION_FAILED; +- goto return_results; +- } +- +- if( op->o_preread ) { +- if( preread_ctrl == NULL ) { +- preread_ctrl = &ctrls[num_ctrls++]; +- ctrls[num_ctrls] = NULL; +- } +- if ( slap_read_controls( op, rs, e, +- &slap_pre_read_bv, preread_ctrl ) ) +- { +- Debug( LDAP_DEBUG_TRACE, +- "<=- " LDAP_XSTRING(bdb_modify) ": pre-read " +- "failed!\n", 0, 0, 0 ); +- if ( op->o_preread & SLAP_CONTROL_CRITICAL ) { +- /* FIXME: is it correct to abort +- * operation if control fails? */ +- goto return_results; +- } +- } +- } +- +- /* nested transaction */ +- rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, <2, bdb->bi_db_opflags ); +- rs->sr_text = NULL; +- if( rs->sr_err != 0 ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modify) ": txn_begin(2) failed: " "%s (%d)\n", +- db_strerror(rs->sr_err), rs->sr_err, 0 ); +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modify) ": txn2 id: %x\n", +- lt2->id(lt2), 0, 0 ); +- /* Modify the entry */ +- dummy = *e; +- rs->sr_err = bdb_modify_internal( op, lt2, op->orm_modlist, +- &dummy, &rs->sr_text, textbuf, textlen ); +- +- if( rs->sr_err != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modify) ": modify failed (%d)\n", +- rs->sr_err, 0, 0 ); +- if ( (rs->sr_err == LDAP_INSUFFICIENT_ACCESS) && opinfo.boi_err ) { +- rs->sr_err = opinfo.boi_err; +- } +- /* Only free attrs if they were dup'd. */ +- if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL; +- switch( rs->sr_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- goto return_results; +- } +- +- /* change the entry itself */ +- rs->sr_err = bdb_id2entry_update( op->o_bd, lt2, &dummy ); +- if ( rs->sr_err != 0 ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modify) ": id2entry update failed " "(%d)\n", +- rs->sr_err, 0, 0 ); +- switch( rs->sr_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- rs->sr_text = "entry update failed"; +- goto return_results; +- } +- +- if ( TXN_COMMIT( lt2, 0 ) != 0 ) { +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "txn_commit(2) failed"; +- goto return_results; +- } +- +- if( op->o_postread ) { +- if( postread_ctrl == NULL ) { +- postread_ctrl = &ctrls[num_ctrls++]; +- ctrls[num_ctrls] = NULL; +- } +- if( slap_read_controls( op, rs, &dummy, +- &slap_post_read_bv, postread_ctrl ) ) +- { +- Debug( LDAP_DEBUG_TRACE, +- "<=- " LDAP_XSTRING(bdb_modify) +- ": post-read failed!\n", 0, 0, 0 ); +- if ( op->o_postread & SLAP_CONTROL_CRITICAL ) { +- /* FIXME: is it correct to abort +- * operation if control fails? */ +- goto return_results; +- } +- } +- } +- +- if( op->o_noop ) { +- if ( ( rs->sr_err = TXN_ABORT( ltid ) ) != 0 ) { +- rs->sr_text = "txn_abort (no-op) failed"; +- } else { +- rs->sr_err = LDAP_X_NO_OPERATION; +- ltid = NULL; +- /* Only free attrs if they were dup'd. */ +- if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL; +- goto return_results; +- } +- } else { +- /* may have changed in bdb_modify_internal() */ +- e->e_ocflags = dummy.e_ocflags; +- rc = bdb_cache_modify( bdb, e, dummy.e_attrs, ltid, &lock ); +- switch( rc ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- dummy.e_attrs = NULL; +- +- rs->sr_err = TXN_COMMIT( ltid, 0 ); +- } +- ltid = NULL; +- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); +- opinfo.boi_oe.oe_key = NULL; +- +- if( rs->sr_err != 0 ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modify) ": txn_%s failed: %s (%d)\n", +- op->o_noop ? "abort (no-op)" : "commit", +- db_strerror(rs->sr_err), rs->sr_err ); +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "commit failed"; +- +- goto return_results; +- } +- +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modify) ": updated%s id=%08lx dn=\"%s\"\n", +- op->o_noop ? " (no-op)" : "", +- dummy.e_id, op->o_req_dn.bv_val ); +- +- rs->sr_err = LDAP_SUCCESS; +- rs->sr_text = NULL; +- if( num_ctrls ) rs->sr_ctrls = ctrls; +- +-return_results: +- if( dummy.e_attrs ) { +- attrs_free( dummy.e_attrs ); +- } +- send_ldap_result( op, rs ); +- +- if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp_kbyte ) { +- TXN_CHECKPOINT( bdb->bi_dbenv, +- bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 ); +- } +- +-done: +- slap_graduate_commit_csn( op ); +- +- if( ltid != NULL ) { +- TXN_ABORT( ltid ); +- } +- if ( opinfo.boi_oe.oe_key ) { +- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); +- } +- +- if( e != NULL ) { +- bdb_unlocked_cache_return_entry_w (&bdb->bi_cache, e); +- } +- +- if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) { +- slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx ); +- slap_sl_free( *preread_ctrl, op->o_tmpmemctx ); +- } +- if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) { +- slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx ); +- slap_sl_free( *postread_ctrl, op->o_tmpmemctx ); +- } +- +- rs->sr_text = NULL; +- +- return rs->sr_err; +-} +diff --git a/servers/slapd/back-bdb/modrdn.c b/servers/slapd/back-bdb/modrdn.c +deleted file mode 100644 +index f213b0f..0000000 +--- a/servers/slapd/back-bdb/modrdn.c ++++ /dev/null +@@ -1,842 +0,0 @@ +-/* modrdn.c - bdb backend modrdn routine */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +-#include +- +-#include "back-bdb.h" +- +-int +-bdb_modrdn( Operation *op, SlapReply *rs ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- AttributeDescription *children = slap_schema.si_ad_children; +- AttributeDescription *entry = slap_schema.si_ad_entry; +- struct berval p_dn, p_ndn; +- struct berval new_dn = {0, NULL}, new_ndn = {0, NULL}; +- Entry *e = NULL; +- Entry *p = NULL; +- EntryInfo *ei = NULL, *eip = NULL, *nei = NULL, *neip = NULL; +- /* LDAP v2 supporting correct attribute handling. */ +- char textbuf[SLAP_TEXT_BUFLEN]; +- size_t textlen = sizeof textbuf; +- DB_TXN *ltid = NULL, *lt2; +- struct bdb_op_info opinfo = {{{ 0 }}}; +- Entry dummy = {0}; +- +- Entry *np = NULL; /* newSuperior Entry */ +- struct berval *np_dn = NULL; /* newSuperior dn */ +- struct berval *np_ndn = NULL; /* newSuperior ndn */ +- struct berval *new_parent_dn = NULL; /* np_dn, p_dn, or NULL */ +- +- int manageDSAit = get_manageDSAit( op ); +- +- DB_LOCK lock, plock, nplock; +- +- int num_retries = 0; +- +- LDAPControl **preread_ctrl = NULL; +- LDAPControl **postread_ctrl = NULL; +- LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS]; +- int num_ctrls = 0; +- +- int rc; +- +- int parent_is_glue = 0; +- int parent_is_leaf = 0; +- +-#ifdef LDAP_X_TXN +- int settle = 0; +-#endif +- +- Debug( LDAP_DEBUG_TRACE, "==>" LDAP_XSTRING(bdb_modrdn) "(%s,%s,%s)\n", +- op->o_req_dn.bv_val,op->oq_modrdn.rs_newrdn.bv_val, +- op->oq_modrdn.rs_newSup ? op->oq_modrdn.rs_newSup->bv_val : "NULL" ); +- +-#ifdef LDAP_X_TXN +- if( op->o_txnSpec ) { +- /* acquire connection lock */ +- ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); +- if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) { +- rs->sr_text = "invalid transaction identifier"; +- rs->sr_err = LDAP_X_TXN_ID_INVALID; +- goto txnReturn; +- } else if( op->o_conn->c_txn == CONN_TXN_SETTLE ) { +- settle=1; +- goto txnReturn; +- } +- +- if( op->o_conn->c_txn_backend == NULL ) { +- op->o_conn->c_txn_backend = op->o_bd; +- +- } else if( op->o_conn->c_txn_backend != op->o_bd ) { +- rs->sr_text = "transaction cannot span multiple database contexts"; +- rs->sr_err = LDAP_AFFECTS_MULTIPLE_DSAS; +- goto txnReturn; +- } +- +- /* insert operation into transaction */ +- +- rs->sr_text = "transaction specified"; +- rs->sr_err = LDAP_X_TXN_SPECIFY_OKAY; +- +-txnReturn: +- /* release connection lock */ +- ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); +- +- if( !settle ) { +- send_ldap_result( op, rs ); +- return rs->sr_err; +- } +- } +-#endif +- +- ctrls[num_ctrls] = NULL; +- +- slap_mods_opattrs( op, &op->orr_modlist, 1 ); +- +- if( 0 ) { +-retry: /* transaction retry */ +- if ( dummy.e_attrs ) { +- attrs_free( dummy.e_attrs ); +- dummy.e_attrs = NULL; +- } +- if (e != NULL) { +- bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e); +- e = NULL; +- } +- if (p != NULL) { +- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p); +- p = NULL; +- } +- if (np != NULL) { +- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, np); +- np = NULL; +- } +- Debug( LDAP_DEBUG_TRACE, "==>" LDAP_XSTRING(bdb_modrdn) +- ": retrying...\n", 0, 0, 0 ); +- +- rs->sr_err = TXN_ABORT( ltid ); +- ltid = NULL; +- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); +- opinfo.boi_oe.oe_key = NULL; +- op->o_do_not_cache = opinfo.boi_acl_cache; +- if( rs->sr_err != 0 ) { +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- if ( op->o_abandon ) { +- rs->sr_err = SLAPD_ABANDON; +- goto return_results; +- } +- parent_is_glue = 0; +- parent_is_leaf = 0; +- bdb_trans_backoff( ++num_retries ); +- } +- +- /* begin transaction */ +- rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, <id, +- bdb->bi_db_opflags ); +- rs->sr_text = NULL; +- if( rs->sr_err != 0 ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modrdn) ": txn_begin failed: " +- "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 ); +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modrdn) ": txn1 id: %x\n", +- ltid->id(ltid), 0, 0 ); +- +- opinfo.boi_oe.oe_key = bdb; +- opinfo.boi_txn = ltid; +- opinfo.boi_err = 0; +- opinfo.boi_acl_cache = op->o_do_not_cache; +- LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.boi_oe, oe_next ); +- +- /* get entry */ +- rs->sr_err = bdb_dn2entry( op, ltid, &op->o_req_ndn, &ei, 1, +- &lock ); +- +- switch( rs->sr_err ) { +- case 0: +- case DB_NOTFOUND: +- break; +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- case LDAP_BUSY: +- rs->sr_text = "ldap server busy"; +- goto return_results; +- default: +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- +- e = ei->bei_e; +- /* FIXME: dn2entry() should return non-glue entry */ +- if (( rs->sr_err == DB_NOTFOUND ) || +- ( !manageDSAit && e && is_entry_glue( e ))) +- { +- if( e != NULL ) { +- rs->sr_matched = ch_strdup( e->e_dn ); +- rs->sr_ref = is_entry_referral( e ) +- ? get_entry_referrals( op, e ) +- : NULL; +- bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, e); +- e = NULL; +- +- } else { +- rs->sr_ref = referral_rewrite( default_referral, NULL, +- &op->o_req_dn, LDAP_SCOPE_DEFAULT ); +- } +- +- rs->sr_err = LDAP_REFERRAL; +- send_ldap_result( op, rs ); +- +- ber_bvarray_free( rs->sr_ref ); +- free( (char *)rs->sr_matched ); +- rs->sr_ref = NULL; +- rs->sr_matched = NULL; +- +- goto done; +- } +- +- if ( get_assert( op ) && +- ( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE )) +- { +- rs->sr_err = LDAP_ASSERTION_FAILED; +- goto return_results; +- } +- +- /* check write on old entry */ +- rs->sr_err = access_allowed( op, e, entry, NULL, ACL_WRITE, NULL ); +- if ( ! rs->sr_err ) { +- switch( opinfo.boi_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- +- Debug( LDAP_DEBUG_TRACE, "no access to entry\n", 0, +- 0, 0 ); +- rs->sr_text = "no write access to old entry"; +- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; +- goto return_results; +- } +- +-#ifndef BDB_HIER +- rs->sr_err = bdb_cache_children( op, ltid, e ); +- if ( rs->sr_err != DB_NOTFOUND ) { +- switch( rs->sr_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- case 0: +- Debug(LDAP_DEBUG_ARGS, +- "<=- " LDAP_XSTRING(bdb_modrdn) +- ": non-leaf %s\n", +- op->o_req_dn.bv_val, 0, 0); +- rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF; +- rs->sr_text = "subtree rename not supported"; +- break; +- default: +- Debug(LDAP_DEBUG_ARGS, +- "<=- " LDAP_XSTRING(bdb_modrdn) +- ": has_children failed: %s (%d)\n", +- db_strerror(rs->sr_err), rs->sr_err, 0 ); +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- } +- goto return_results; +- } +- ei->bei_state |= CACHE_ENTRY_NO_KIDS; +-#endif +- +- if (!manageDSAit && is_entry_referral( e ) ) { +- /* parent is a referral, don't allow add */ +- rs->sr_ref = get_entry_referrals( op, e ); +- +- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modrdn) +- ": entry %s is referral\n", e->e_dn, 0, 0 ); +- +- rs->sr_err = LDAP_REFERRAL, +- rs->sr_matched = e->e_name.bv_val; +- send_ldap_result( op, rs ); +- +- ber_bvarray_free( rs->sr_ref ); +- rs->sr_ref = NULL; +- rs->sr_matched = NULL; +- goto done; +- } +- +- if ( be_issuffix( op->o_bd, &e->e_nname ) ) { +-#ifdef BDB_MULTIPLE_SUFFIXES +- /* Allow renaming one suffix entry to another */ +- p_ndn = slap_empty_bv; +-#else +- /* There can only be one suffix entry */ +- rs->sr_err = LDAP_NAMING_VIOLATION; +- rs->sr_text = "cannot rename suffix entry"; +- goto return_results; +-#endif +- } else { +- dnParent( &e->e_nname, &p_ndn ); +- } +- np_ndn = &p_ndn; +- eip = ei->bei_parent; +- if ( eip && eip->bei_id ) { +- /* Make sure parent entry exist and we can write its +- * children. +- */ +- rs->sr_err = bdb_cache_find_id( op, ltid, +- eip->bei_id, &eip, 0, &plock ); +- +- switch( rs->sr_err ) { +- case 0: +- case DB_NOTFOUND: +- break; +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- case LDAP_BUSY: +- rs->sr_text = "ldap server busy"; +- goto return_results; +- default: +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- +- p = eip->bei_e; +- if( p == NULL) { +- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modrdn) +- ": parent does not exist\n", 0, 0, 0); +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "old entry's parent does not exist"; +- goto return_results; +- } +- } else { +- p = (Entry *)&slap_entry_root; +- } +- +- /* check parent for "children" acl */ +- rs->sr_err = access_allowed( op, p, +- children, NULL, +- op->oq_modrdn.rs_newSup == NULL ? +- ACL_WRITE : ACL_WDEL, +- NULL ); +- +- if ( !p_ndn.bv_len ) +- p = NULL; +- +- if ( ! rs->sr_err ) { +- switch( opinfo.boi_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- +- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; +- Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0, +- 0, 0 ); +- rs->sr_text = "no write access to old parent's children"; +- goto return_results; +- } +- +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modrdn) ": wr to children " +- "of entry %s OK\n", p_ndn.bv_val, 0, 0 ); +- +- if ( p_ndn.bv_val == slap_empty_bv.bv_val ) { +- p_dn = slap_empty_bv; +- } else { +- dnParent( &e->e_name, &p_dn ); +- } +- +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modrdn) ": parent dn=%s\n", +- p_dn.bv_val, 0, 0 ); +- +- new_parent_dn = &p_dn; /* New Parent unless newSuperior given */ +- +- if ( op->oq_modrdn.rs_newSup != NULL ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modrdn) +- ": new parent \"%s\" requested...\n", +- op->oq_modrdn.rs_newSup->bv_val, 0, 0 ); +- +- /* newSuperior == oldParent? */ +- if( dn_match( &p_ndn, op->oq_modrdn.rs_nnewSup ) ) { +- Debug( LDAP_DEBUG_TRACE, "bdb_back_modrdn: " +- "new parent \"%s\" same as the old parent \"%s\"\n", +- op->oq_modrdn.rs_newSup->bv_val, p_dn.bv_val, 0 ); +- op->oq_modrdn.rs_newSup = NULL; /* ignore newSuperior */ +- } +- } +- +- /* There's a BDB_MULTIPLE_SUFFIXES case here that this code doesn't +- * support. E.g., two suffixes dc=foo,dc=com and dc=bar,dc=net. +- * We do not allow modDN +- * dc=foo,dc=com +- * newrdn dc=bar +- * newsup dc=net +- * and we probably should. But since MULTIPLE_SUFFIXES is deprecated +- * I'm ignoring this problem for now. +- */ +- if ( op->oq_modrdn.rs_newSup != NULL ) { +- if ( op->oq_modrdn.rs_newSup->bv_len ) { +- np_dn = op->oq_modrdn.rs_newSup; +- np_ndn = op->oq_modrdn.rs_nnewSup; +- +- /* newSuperior == oldParent? - checked above */ +- /* newSuperior == entry being moved?, if so ==> ERROR */ +- if ( dnIsSuffix( np_ndn, &e->e_nname )) { +- rs->sr_err = LDAP_NO_SUCH_OBJECT; +- rs->sr_text = "new superior not found"; +- goto return_results; +- } +- /* Get Entry with dn=newSuperior. Does newSuperior exist? */ +- +- rs->sr_err = bdb_dn2entry( op, ltid, np_ndn, +- &neip, 0, &nplock ); +- +- switch( rs->sr_err ) { +- case 0: np = neip->bei_e; +- case DB_NOTFOUND: +- break; +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- case LDAP_BUSY: +- rs->sr_text = "ldap server busy"; +- goto return_results; +- default: +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- +- if( np == NULL) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modrdn) +- ": newSup(ndn=%s) not here!\n", +- np_ndn->bv_val, 0, 0); +- rs->sr_text = "new superior not found"; +- rs->sr_err = LDAP_NO_SUCH_OBJECT; +- goto return_results; +- } +- +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modrdn) +- ": wr to new parent OK np=%p, id=%ld\n", +- (void *) np, (long) np->e_id, 0 ); +- +- /* check newSuperior for "children" acl */ +- rs->sr_err = access_allowed( op, np, children, +- NULL, ACL_WADD, NULL ); +- +- if( ! rs->sr_err ) { +- switch( opinfo.boi_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modrdn) +- ": no wr to newSup children\n", +- 0, 0, 0 ); +- rs->sr_text = "no write access to new superior's children"; +- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; +- goto return_results; +- } +- +- if ( is_entry_alias( np ) ) { +- /* parent is an alias, don't allow add */ +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modrdn) +- ": entry is alias\n", +- 0, 0, 0 ); +- rs->sr_text = "new superior is an alias"; +- rs->sr_err = LDAP_ALIAS_PROBLEM; +- goto return_results; +- } +- +- if ( is_entry_referral( np ) ) { +- /* parent is a referral, don't allow add */ +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modrdn) +- ": entry is referral\n", +- 0, 0, 0 ); +- rs->sr_text = "new superior is a referral"; +- rs->sr_err = LDAP_OTHER; +- goto return_results; +- } +- +- } else { +- np_dn = NULL; +- +- /* no parent, modrdn entry directly under root */ +- if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv ) +- || be_isupdate( op ) ) { +- np = (Entry *)&slap_entry_root; +- +- /* check parent for "children" acl */ +- rs->sr_err = access_allowed( op, np, +- children, NULL, ACL_WADD, NULL ); +- +- np = NULL; +- +- if ( ! rs->sr_err ) { +- switch( opinfo.boi_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- +- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; +- Debug( LDAP_DEBUG_TRACE, +- "no access to new superior\n", +- 0, 0, 0 ); +- rs->sr_text = +- "no write access to new superior's children"; +- goto return_results; +- } +- } +- } +- +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_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. */ +- if (!new_dn.bv_val) { +- build_new_dn( &new_dn, new_parent_dn, &op->oq_modrdn.rs_newrdn, NULL ); +- } +- +- if (!new_ndn.bv_val) { +- struct berval bv = {0, NULL}; +- dnNormalize( 0, NULL, NULL, &new_dn, &bv, op->o_tmpmemctx ); +- ber_dupbv( &new_ndn, &bv ); +- /* FIXME: why not call dnNormalize() w/o ctx? */ +- op->o_tmpfree( bv.bv_val, op->o_tmpmemctx ); +- } +- +- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modrdn) ": new ndn=%s\n", +- new_ndn.bv_val, 0, 0 ); +- +- /* Shortcut the search */ +- nei = neip ? neip : eip; +- rs->sr_err = bdb_cache_find_ndn ( op, ltid, &new_ndn, &nei ); +- if ( nei ) bdb_cache_entryinfo_unlock( nei ); +- switch( rs->sr_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- case DB_NOTFOUND: +- break; +- case 0: +- /* Allow rename to same DN */ +- if ( nei == ei ) +- break; +- rs->sr_err = LDAP_ALREADY_EXISTS; +- goto return_results; +- default: +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- +- assert( op->orr_modlist != NULL ); +- +- if( op->o_preread ) { +- if( preread_ctrl == NULL ) { +- preread_ctrl = &ctrls[num_ctrls++]; +- ctrls[num_ctrls] = NULL; +- } +- if( slap_read_controls( op, rs, e, +- &slap_pre_read_bv, preread_ctrl ) ) +- { +- Debug( LDAP_DEBUG_TRACE, +- "<=- " LDAP_XSTRING(bdb_modrdn) +- ": pre-read failed!\n", 0, 0, 0 ); +- if ( op->o_preread & SLAP_CONTROL_CRITICAL ) { +- /* FIXME: is it correct to abort +- * operation if control fails? */ +- goto return_results; +- } +- } +- } +- +- /* nested transaction */ +- rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, <2, bdb->bi_db_opflags ); +- rs->sr_text = NULL; +- if( rs->sr_err != 0 ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modrdn) +- ": txn_begin(2) failed: %s (%d)\n", +- db_strerror(rs->sr_err), rs->sr_err, 0 ); +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modrdn) ": txn2 id: %x\n", +- lt2->id(lt2), 0, 0 ); +- +- /* delete old DN */ +- rs->sr_err = bdb_dn2id_delete( op, lt2, eip, e ); +- if ( rs->sr_err != 0 ) { +- Debug(LDAP_DEBUG_TRACE, +- "<=- " LDAP_XSTRING(bdb_modrdn) +- ": dn2id del failed: %s (%d)\n", +- db_strerror(rs->sr_err), rs->sr_err, 0 ); +- switch( rs->sr_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "DN index delete fail"; +- goto return_results; +- } +- +- /* copy the entry, then override some fields */ +- dummy = *e; +- dummy.e_name = new_dn; +- dummy.e_nname = new_ndn; +- dummy.e_attrs = NULL; +- +- /* add new DN */ +- rs->sr_err = bdb_dn2id_add( op, lt2, neip ? neip : eip, &dummy ); +- if ( rs->sr_err != 0 ) { +- Debug(LDAP_DEBUG_TRACE, +- "<=- " LDAP_XSTRING(bdb_modrdn) +- ": dn2id add failed: %s (%d)\n", +- db_strerror(rs->sr_err), rs->sr_err, 0 ); +- switch( rs->sr_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "DN index add failed"; +- goto return_results; +- } +- +- dummy.e_attrs = e->e_attrs; +- +- /* modify entry */ +- rs->sr_err = bdb_modify_internal( op, lt2, op->orr_modlist, &dummy, +- &rs->sr_text, textbuf, textlen ); +- if( rs->sr_err != LDAP_SUCCESS ) { +- Debug(LDAP_DEBUG_TRACE, +- "<=- " LDAP_XSTRING(bdb_modrdn) +- ": modify failed: %s (%d)\n", +- db_strerror(rs->sr_err), rs->sr_err, 0 ); +- if ( ( rs->sr_err == LDAP_INSUFFICIENT_ACCESS ) && opinfo.boi_err ) { +- rs->sr_err = opinfo.boi_err; +- } +- if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL; +- switch( rs->sr_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- goto return_results; +- } +- +- /* id2entry index */ +- rs->sr_err = bdb_id2entry_update( op->o_bd, lt2, &dummy ); +- if ( rs->sr_err != 0 ) { +- Debug(LDAP_DEBUG_TRACE, +- "<=- " LDAP_XSTRING(bdb_modrdn) +- ": id2entry failed: %s (%d)\n", +- db_strerror(rs->sr_err), rs->sr_err, 0 ); +- switch( rs->sr_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "entry update failed"; +- goto return_results; +- } +- +- if ( p_ndn.bv_len != 0 ) { +- parent_is_glue = is_entry_glue(p); +- rs->sr_err = bdb_cache_children( op, lt2, p ); +- if ( rs->sr_err != DB_NOTFOUND ) { +- switch( rs->sr_err ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- case 0: +- break; +- default: +- Debug(LDAP_DEBUG_ARGS, +- "<=- " LDAP_XSTRING(bdb_modrdn) +- ": has_children failed: %s (%d)\n", +- db_strerror(rs->sr_err), rs->sr_err, 0 ); +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error"; +- goto return_results; +- } +- parent_is_leaf = 1; +- } +- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p); +- p = NULL; +- } +- +- if ( TXN_COMMIT( lt2, 0 ) != 0 ) { +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "txn_commit(2) failed"; +- goto return_results; +- } +- +- if( op->o_postread ) { +- if( postread_ctrl == NULL ) { +- postread_ctrl = &ctrls[num_ctrls++]; +- ctrls[num_ctrls] = NULL; +- } +- if( slap_read_controls( op, rs, &dummy, +- &slap_post_read_bv, postread_ctrl ) ) +- { +- Debug( LDAP_DEBUG_TRACE, +- "<=- " LDAP_XSTRING(bdb_modrdn) +- ": post-read failed!\n", 0, 0, 0 ); +- if ( op->o_postread & SLAP_CONTROL_CRITICAL ) { +- /* FIXME: is it correct to abort +- * operation if control fails? */ +- goto return_results; +- } +- } +- } +- +- if( op->o_noop ) { +- if(( rs->sr_err=TXN_ABORT( ltid )) != 0 ) { +- rs->sr_text = "txn_abort (no-op) failed"; +- } else { +- rs->sr_err = LDAP_X_NO_OPERATION; +- ltid = NULL; +- /* Only free attrs if they were dup'd. */ +- if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL; +- goto return_results; +- } +- +- } else { +- rc = bdb_cache_modrdn( bdb, e, &op->orr_nnewrdn, &dummy, neip, +- ltid, &lock ); +- switch( rc ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- } +- dummy.e_attrs = NULL; +- new_dn.bv_val = NULL; +- new_ndn.bv_val = NULL; +- +- if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) { +- rs->sr_text = "txn_commit failed"; +- } else { +- rs->sr_err = LDAP_SUCCESS; +- } +- } +- +- ltid = NULL; +- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); +- opinfo.boi_oe.oe_key = NULL; +- +- if( rs->sr_err != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modrdn) ": %s : %s (%d)\n", +- rs->sr_text, db_strerror(rs->sr_err), rs->sr_err ); +- rs->sr_err = LDAP_OTHER; +- +- goto return_results; +- } +- +- Debug(LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_modrdn) +- ": rdn modified%s id=%08lx dn=\"%s\"\n", +- op->o_noop ? " (no-op)" : "", +- dummy.e_id, op->o_req_dn.bv_val ); +- rs->sr_text = NULL; +- if( num_ctrls ) rs->sr_ctrls = ctrls; +- +-return_results: +- if ( dummy.e_attrs ) { +- attrs_free( dummy.e_attrs ); +- } +- send_ldap_result( op, rs ); +- +- if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp_kbyte ) { +- TXN_CHECKPOINT( bdb->bi_dbenv, +- bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 ); +- } +- +- if ( rs->sr_err == LDAP_SUCCESS && parent_is_glue && parent_is_leaf ) { +- op->o_delete_glue_parent = 1; +- } +- +-done: +- slap_graduate_commit_csn( op ); +- +- if( new_dn.bv_val != NULL ) free( new_dn.bv_val ); +- if( new_ndn.bv_val != NULL ) free( new_ndn.bv_val ); +- +- /* LDAP v3 Support */ +- if( np != NULL ) { +- /* free new parent and reader lock */ +- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, np); +- } +- +- if( p != NULL ) { +- /* free parent and reader lock */ +- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p); +- } +- +- /* free entry */ +- if( e != NULL ) { +- bdb_unlocked_cache_return_entry_w( &bdb->bi_cache, e); +- } +- +- if( ltid != NULL ) { +- TXN_ABORT( ltid ); +- } +- if ( opinfo.boi_oe.oe_key ) { +- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); +- } +- +- if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) { +- slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx ); +- slap_sl_free( *preread_ctrl, op->o_tmpmemctx ); +- } +- if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) { +- slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx ); +- slap_sl_free( *postread_ctrl, op->o_tmpmemctx ); +- } +- return rs->sr_err; +-} +diff --git a/servers/slapd/back-bdb/monitor.c b/servers/slapd/back-bdb/monitor.c +deleted file mode 100644 +index 4afaf9d..0000000 +--- a/servers/slapd/back-bdb/monitor.c ++++ /dev/null +@@ -1,724 +0,0 @@ +-/* monitor.c - monitor bdb backend */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include "lutil.h" +-#include "back-bdb.h" +- +-#include "../back-monitor/back-monitor.h" +- +-#include "config.h" +- +-static ObjectClass *oc_olmBDBDatabase; +- +-static AttributeDescription *ad_olmBDBEntryCache, +- *ad_olmBDBDNCache, *ad_olmBDBIDLCache, +- *ad_olmDbDirectory; +- +-#ifdef BDB_MONITOR_IDX +-static int +-bdb_monitor_idx_entry_add( +- struct bdb_info *bdb, +- Entry *e ); +- +-static AttributeDescription *ad_olmDbNotIndexed; +-#endif /* BDB_MONITOR_IDX */ +- +-/* +- * NOTE: there's some confusion in monitor OID arc; +- * by now, let's consider: +- * +- * Subsystems monitor attributes 1.3.6.1.4.1.4203.666.1.55.0 +- * Databases monitor attributes 1.3.6.1.4.1.4203.666.1.55.0.1 +- * BDB database monitor attributes 1.3.6.1.4.1.4203.666.1.55.0.1.1 +- * +- * Subsystems monitor objectclasses 1.3.6.1.4.1.4203.666.3.16.0 +- * Databases monitor objectclasses 1.3.6.1.4.1.4203.666.3.16.0.1 +- * BDB database monitor objectclasses 1.3.6.1.4.1.4203.666.3.16.0.1.1 +- */ +- +-static struct { +- char *name; +- char *oid; +-} s_oid[] = { +- { "olmBDBAttributes", "olmDatabaseAttributes:1" }, +- { "olmBDBObjectClasses", "olmDatabaseObjectClasses:1" }, +- +- { NULL } +-}; +- +-static struct { +- char *desc; +- AttributeDescription **ad; +-} s_at[] = { +- { "( olmBDBAttributes:1 " +- "NAME ( 'olmBDBEntryCache' ) " +- "DESC 'Number of items in Entry Cache' " +- "SUP monitorCounter " +- "NO-USER-MODIFICATION " +- "USAGE dSAOperation )", +- &ad_olmBDBEntryCache }, +- +- { "( olmBDBAttributes:2 " +- "NAME ( 'olmBDBDNCache' ) " +- "DESC 'Number of items in DN Cache' " +- "SUP monitorCounter " +- "NO-USER-MODIFICATION " +- "USAGE dSAOperation )", +- &ad_olmBDBDNCache }, +- +- { "( olmBDBAttributes:3 " +- "NAME ( 'olmBDBIDLCache' ) " +- "DESC 'Number of items in IDL Cache' " +- "SUP monitorCounter " +- "NO-USER-MODIFICATION " +- "USAGE dSAOperation )", +- &ad_olmBDBIDLCache }, +- +- { "( olmDatabaseAttributes:1 " +- "NAME ( 'olmDbDirectory' ) " +- "DESC 'Path name of the directory " +- "where the database environment resides' " +- "SUP monitoredInfo " +- "NO-USER-MODIFICATION " +- "USAGE dSAOperation )", +- &ad_olmDbDirectory }, +- +-#ifdef BDB_MONITOR_IDX +- { "( olmDatabaseAttributes:2 " +- "NAME ( 'olmDbNotIndexed' ) " +- "DESC 'Missing indexes resulting from candidate selection' " +- "SUP monitoredInfo " +- "NO-USER-MODIFICATION " +- "USAGE dSAOperation )", +- &ad_olmDbNotIndexed }, +-#endif /* BDB_MONITOR_IDX */ +- +- { NULL } +-}; +- +-static struct { +- char *desc; +- ObjectClass **oc; +-} s_oc[] = { +- /* augments an existing object, so it must be AUXILIARY +- * FIXME: derive from some ABSTRACT "monitoredEntity"? */ +- { "( olmBDBObjectClasses:1 " +- "NAME ( 'olmBDBDatabase' ) " +- "SUP top AUXILIARY " +- "MAY ( " +- "olmBDBEntryCache " +- "$ olmBDBDNCache " +- "$ olmBDBIDLCache " +- "$ olmDbDirectory " +-#ifdef BDB_MONITOR_IDX +- "$ olmDbNotIndexed " +-#endif /* BDB_MONITOR_IDX */ +- ") )", +- &oc_olmBDBDatabase }, +- +- { NULL } +-}; +- +-static int +-bdb_monitor_update( +- Operation *op, +- SlapReply *rs, +- Entry *e, +- void *priv ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) priv; +- Attribute *a; +- +- char buf[ BUFSIZ ]; +- struct berval bv; +- +- assert( ad_olmBDBEntryCache != NULL ); +- +- a = attr_find( e->e_attrs, ad_olmBDBEntryCache ); +- assert( a != NULL ); +- bv.bv_val = buf; +- bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", bdb->bi_cache.c_cursize ); +- ber_bvreplace( &a->a_vals[ 0 ], &bv ); +- +- a = attr_find( e->e_attrs, ad_olmBDBDNCache ); +- assert( a != NULL ); +- bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", bdb->bi_cache.c_eiused ); +- ber_bvreplace( &a->a_vals[ 0 ], &bv ); +- +- a = attr_find( e->e_attrs, ad_olmBDBIDLCache ); +- assert( a != NULL ); +- bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", bdb->bi_idl_cache_size ); +- ber_bvreplace( &a->a_vals[ 0 ], &bv ); +- +-#ifdef BDB_MONITOR_IDX +- bdb_monitor_idx_entry_add( bdb, e ); +-#endif /* BDB_MONITOR_IDX */ +- +- return SLAP_CB_CONTINUE; +-} +- +-#if 0 /* uncomment if required */ +-static int +-bdb_monitor_modify( +- Operation *op, +- SlapReply *rs, +- Entry *e, +- void *priv ) +-{ +- return SLAP_CB_CONTINUE; +-} +-#endif +- +-static int +-bdb_monitor_free( +- Entry *e, +- void **priv ) +-{ +- struct berval values[ 2 ]; +- Modification mod = { 0 }; +- +- const char *text; +- char textbuf[ SLAP_TEXT_BUFLEN ]; +- +- int i, rc; +- +- /* NOTE: if slap_shutdown != 0, priv might have already been freed */ +- *priv = NULL; +- +- /* Remove objectClass */ +- mod.sm_op = LDAP_MOD_DELETE; +- mod.sm_desc = slap_schema.si_ad_objectClass; +- mod.sm_values = values; +- mod.sm_numvals = 1; +- values[ 0 ] = oc_olmBDBDatabase->soc_cname; +- BER_BVZERO( &values[ 1 ] ); +- +- rc = modify_delete_values( e, &mod, 1, &text, +- textbuf, sizeof( textbuf ) ); +- /* don't care too much about return code... */ +- +- /* remove attrs */ +- mod.sm_values = NULL; +- mod.sm_numvals = 0; +- for ( i = 0; s_at[ i ].desc != NULL; i++ ) { +- mod.sm_desc = *s_at[ i ].ad; +- rc = modify_delete_values( e, &mod, 1, &text, +- textbuf, sizeof( textbuf ) ); +- /* don't care too much about return code... */ +- } +- +- return SLAP_CB_CONTINUE; +-} +- +-#define bdb_monitor_initialize BDB_SYMBOL(monitor_initialize) +- +-/* +- * call from within bdb_initialize() +- */ +-static int +-bdb_monitor_initialize( void ) +-{ +- int i, code; +- ConfigArgs c; +- char *argv[ 3 ]; +- +- static int bdb_monitor_initialized = 0; +- +- /* set to 0 when successfully initialized; otherwise, remember failure */ +- static int bdb_monitor_initialized_failure = 1; +- +- if ( bdb_monitor_initialized++ ) { +- return bdb_monitor_initialized_failure; +- } +- +- if ( backend_info( "monitor" ) == NULL ) { +- return -1; +- } +- +- /* register schema here */ +- +- argv[ 0 ] = "back-bdb/back-hdb monitor"; +- c.argv = argv; +- c.argc = 3; +- c.fname = argv[0]; +- +- for ( i = 0; s_oid[ i ].name; i++ ) { +- c.lineno = i; +- argv[ 1 ] = s_oid[ i ].name; +- argv[ 2 ] = s_oid[ i ].oid; +- +- if ( parse_oidm( &c, 0, NULL ) != 0 ) { +- Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_monitor_initialize) +- ": unable to add " +- "objectIdentifier \"%s=%s\"\n", +- s_oid[ i ].name, s_oid[ i ].oid, 0 ); +- return 2; +- } +- } +- +- for ( i = 0; s_at[ i ].desc != NULL; i++ ) { +- code = register_at( s_at[ i ].desc, s_at[ i ].ad, 1 ); +- if ( code != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_monitor_initialize) +- ": register_at failed for attributeType (%s)\n", +- s_at[ i ].desc, 0, 0 ); +- return 3; +- +- } else { +- (*s_at[ i ].ad)->ad_type->sat_flags |= SLAP_AT_HIDE; +- } +- } +- +- for ( i = 0; s_oc[ i ].desc != NULL; i++ ) { +- code = register_oc( s_oc[ i ].desc, s_oc[ i ].oc, 1 ); +- if ( code != LDAP_SUCCESS ) { +- Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_monitor_initialize) +- ": register_oc failed for objectClass (%s)\n", +- s_oc[ i ].desc, 0, 0 ); +- return 4; +- +- } else { +- (*s_oc[ i ].oc)->soc_flags |= SLAP_OC_HIDE; +- } +- } +- +- return ( bdb_monitor_initialized_failure = LDAP_SUCCESS ); +-} +- +-/* +- * call from within bdb_db_init() +- */ +-int +-bdb_monitor_db_init( BackendDB *be ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) be->be_private; +- +- if ( bdb_monitor_initialize() == LDAP_SUCCESS ) { +- /* monitoring in back-bdb is on by default */ +- SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_MONITORING; +- } +- +-#ifdef BDB_MONITOR_IDX +- bdb->bi_idx = NULL; +- ldap_pvt_thread_mutex_init( &bdb->bi_idx_mutex ); +-#endif /* BDB_MONITOR_IDX */ +- +- return 0; +-} +- +-/* +- * call from within bdb_db_open() +- */ +-int +-bdb_monitor_db_open( BackendDB *be ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) be->be_private; +- Attribute *a, *next; +- monitor_callback_t *cb = NULL; +- int rc = 0; +- BackendInfo *mi; +- monitor_extra_t *mbe; +- +- if ( !SLAP_DBMONITORING( be ) ) { +- return 0; +- } +- +- mi = backend_info( "monitor" ); +- if ( !mi || !mi->bi_extra ) { +- SLAP_DBFLAGS( be ) ^= SLAP_DBFLAG_MONITORING; +- return 0; +- } +- mbe = mi->bi_extra; +- +- /* don't bother if monitor is not configured */ +- if ( !mbe->is_configured() ) { +- static int warning = 0; +- +- if ( warning++ == 0 ) { +- Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_monitor_db_open) +- ": monitoring disabled; " +- "configure monitor database to enable\n", +- 0, 0, 0 ); +- } +- +- return 0; +- } +- +- /* alloc as many as required (plus 1 for objectClass) */ +- a = attrs_alloc( 1 + 4 ); +- if ( a == NULL ) { +- rc = 1; +- goto cleanup; +- } +- +- a->a_desc = slap_schema.si_ad_objectClass; +- attr_valadd( a, &oc_olmBDBDatabase->soc_cname, NULL, 1 ); +- next = a->a_next; +- +- { +- struct berval bv = BER_BVC( "0" ); +- +- next->a_desc = ad_olmBDBEntryCache; +- attr_valadd( next, &bv, NULL, 1 ); +- next = next->a_next; +- +- next->a_desc = ad_olmBDBDNCache; +- attr_valadd( next, &bv, NULL, 1 ); +- next = next->a_next; +- +- next->a_desc = ad_olmBDBIDLCache; +- attr_valadd( next, &bv, NULL, 1 ); +- next = next->a_next; +- } +- +- { +- struct berval bv, nbv; +- ber_len_t pathlen = 0, len = 0; +- char path[ MAXPATHLEN ] = { '\0' }; +- char *fname = bdb->bi_dbenv_home, +- *ptr; +- +- len = strlen( fname ); +- if ( fname[ 0 ] != '/' ) { +- /* get full path name */ +- getcwd( path, sizeof( path ) ); +- pathlen = strlen( path ); +- +- if ( fname[ 0 ] == '.' && fname[ 1 ] == '/' ) { +- fname += 2; +- len -= 2; +- } +- } +- +- bv.bv_len = pathlen + STRLENOF( "/" ) + len; +- ptr = bv.bv_val = ch_malloc( bv.bv_len + STRLENOF( "/" ) + 1 ); +- if ( pathlen ) { +- ptr = lutil_strncopy( ptr, path, pathlen ); +- ptr[ 0 ] = '/'; +- ptr++; +- } +- ptr = lutil_strncopy( ptr, fname, len ); +- if ( ptr[ -1 ] != '/' ) { +- ptr[ 0 ] = '/'; +- ptr++; +- } +- ptr[ 0 ] = '\0'; +- +- attr_normalize_one( ad_olmDbDirectory, &bv, &nbv, NULL ); +- +- next->a_desc = ad_olmDbDirectory; +- next->a_vals = ch_calloc( sizeof( struct berval ), 2 ); +- next->a_vals[ 0 ] = bv; +- next->a_numvals = 1; +- +- if ( BER_BVISNULL( &nbv ) ) { +- next->a_nvals = next->a_vals; +- +- } else { +- next->a_nvals = ch_calloc( sizeof( struct berval ), 2 ); +- next->a_nvals[ 0 ] = nbv; +- } +- +- next = next->a_next; +- } +- +- cb = ch_calloc( sizeof( monitor_callback_t ), 1 ); +- cb->mc_update = bdb_monitor_update; +-#if 0 /* uncomment if required */ +- cb->mc_modify = bdb_monitor_modify; +-#endif +- cb->mc_free = bdb_monitor_free; +- cb->mc_private = (void *)bdb; +- +- /* make sure the database is registered; then add monitor attributes */ +- rc = mbe->register_database( be, &bdb->bi_monitor.bdm_ndn ); +- if ( rc == 0 ) { +- rc = mbe->register_entry_attrs( &bdb->bi_monitor.bdm_ndn, a, cb, +- NULL, 0, NULL ); +- } +- +-cleanup:; +- if ( rc != 0 ) { +- if ( cb != NULL ) { +- ch_free( cb ); +- cb = NULL; +- } +- +- if ( a != NULL ) { +- attrs_free( a ); +- a = NULL; +- } +- } +- +- /* store for cleanup */ +- bdb->bi_monitor.bdm_cb = (void *)cb; +- +- /* we don't need to keep track of the attributes, because +- * bdb_monitor_free() takes care of everything */ +- if ( a != NULL ) { +- attrs_free( a ); +- } +- +- return rc; +-} +- +-/* +- * call from within bdb_db_close() +- */ +-int +-bdb_monitor_db_close( BackendDB *be ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) be->be_private; +- +- if ( !BER_BVISNULL( &bdb->bi_monitor.bdm_ndn ) ) { +- BackendInfo *mi = backend_info( "monitor" ); +- monitor_extra_t *mbe; +- +- if ( mi && &mi->bi_extra ) { +- mbe = mi->bi_extra; +- mbe->unregister_entry_callback( &bdb->bi_monitor.bdm_ndn, +- (monitor_callback_t *)bdb->bi_monitor.bdm_cb, +- NULL, 0, NULL ); +- } +- +- memset( &bdb->bi_monitor, 0, sizeof( bdb->bi_monitor ) ); +- } +- +- return 0; +-} +- +-/* +- * call from within bdb_db_destroy() +- */ +-int +-bdb_monitor_db_destroy( BackendDB *be ) +-{ +-#ifdef BDB_MONITOR_IDX +- struct bdb_info *bdb = (struct bdb_info *) be->be_private; +- +- /* TODO: free tree */ +- ldap_pvt_thread_mutex_destroy( &bdb->bi_idx_mutex ); +- avl_free( bdb->bi_idx, ch_free ); +-#endif /* BDB_MONITOR_IDX */ +- +- return 0; +-} +- +-#ifdef BDB_MONITOR_IDX +- +-#define BDB_MONITOR_IDX_TYPES (4) +- +-typedef struct monitor_idx_t monitor_idx_t; +- +-struct monitor_idx_t { +- AttributeDescription *idx_ad; +- unsigned long idx_count[BDB_MONITOR_IDX_TYPES]; +-}; +- +-static int +-bdb_monitor_bitmask2key( slap_mask_t bitmask ) +-{ +- int key; +- +- for ( key = 0; key < 8 * (int)sizeof(slap_mask_t) && !( bitmask & 0x1U ); +- key++ ) +- bitmask >>= 1; +- +- return key; +-} +- +-static struct berval idxbv[] = { +- BER_BVC( "present=" ), +- BER_BVC( "equality=" ), +- BER_BVC( "approx=" ), +- BER_BVC( "substr=" ), +- BER_BVNULL +-}; +- +-static ber_len_t +-bdb_monitor_idx2len( monitor_idx_t *idx ) +-{ +- int i; +- ber_len_t len = 0; +- +- for ( i = 0; i < BDB_MONITOR_IDX_TYPES; i++ ) { +- if ( idx->idx_count[ i ] != 0 ) { +- len += idxbv[i].bv_len; +- } +- } +- +- return len; +-} +- +-static int +-monitor_idx_cmp( const void *p1, const void *p2 ) +-{ +- const monitor_idx_t *idx1 = (const monitor_idx_t *)p1; +- const monitor_idx_t *idx2 = (const monitor_idx_t *)p2; +- +- return SLAP_PTRCMP( idx1->idx_ad, idx2->idx_ad ); +-} +- +-static int +-monitor_idx_dup( void *p1, void *p2 ) +-{ +- monitor_idx_t *idx1 = (monitor_idx_t *)p1; +- monitor_idx_t *idx2 = (monitor_idx_t *)p2; +- +- return SLAP_PTRCMP( idx1->idx_ad, idx2->idx_ad ) == 0 ? -1 : 0; +-} +- +-int +-bdb_monitor_idx_add( +- struct bdb_info *bdb, +- AttributeDescription *desc, +- slap_mask_t type ) +-{ +- monitor_idx_t idx_dummy = { 0 }, +- *idx; +- int rc = 0, key; +- +- idx_dummy.idx_ad = desc; +- key = bdb_monitor_bitmask2key( type ) - 1; +- if ( key >= BDB_MONITOR_IDX_TYPES ) { +- /* invalid index type */ +- return -1; +- } +- +- ldap_pvt_thread_mutex_lock( &bdb->bi_idx_mutex ); +- +- idx = (monitor_idx_t *)avl_find( bdb->bi_idx, +- (caddr_t)&idx_dummy, monitor_idx_cmp ); +- if ( idx == NULL ) { +- idx = (monitor_idx_t *)ch_calloc( sizeof( monitor_idx_t ), 1 ); +- idx->idx_ad = desc; +- idx->idx_count[ key ] = 1; +- +- switch ( avl_insert( &bdb->bi_idx, (caddr_t)idx, +- monitor_idx_cmp, monitor_idx_dup ) ) +- { +- case 0: +- break; +- +- default: +- ch_free( idx ); +- rc = -1; +- } +- +- } else { +- idx->idx_count[ key ]++; +- } +- +- ldap_pvt_thread_mutex_unlock( &bdb->bi_idx_mutex ); +- +- return rc; +-} +- +-static int +-bdb_monitor_idx_apply( void *v_idx, void *v_valp ) +-{ +- monitor_idx_t *idx = (monitor_idx_t *)v_idx; +- BerVarray *valp = (BerVarray *)v_valp; +- +- struct berval bv; +- char *ptr; +- char count_buf[ BDB_MONITOR_IDX_TYPES ][ SLAP_TEXT_BUFLEN ]; +- ber_len_t count_len[ BDB_MONITOR_IDX_TYPES ], +- idx_len; +- int i, num = 0; +- +- idx_len = bdb_monitor_idx2len( idx ); +- +- bv.bv_len = 0; +- for ( i = 0; i < BDB_MONITOR_IDX_TYPES; i++ ) { +- if ( idx->idx_count[ i ] == 0 ) { +- continue; +- } +- +- count_len[ i ] = snprintf( count_buf[ i ], +- sizeof( count_buf[ i ] ), "%lu", idx->idx_count[ i ] ); +- bv.bv_len += count_len[ i ]; +- num++; +- } +- +- bv.bv_len += idx->idx_ad->ad_cname.bv_len +- + num +- + idx_len; +- ptr = bv.bv_val = ch_malloc( bv.bv_len + 1 ); +- ptr = lutil_strcopy( ptr, idx->idx_ad->ad_cname.bv_val ); +- for ( i = 0; i < BDB_MONITOR_IDX_TYPES; i++ ) { +- if ( idx->idx_count[ i ] == 0 ) { +- continue; +- } +- +- ptr[ 0 ] = '#'; +- ++ptr; +- ptr = lutil_strcopy( ptr, idxbv[ i ].bv_val ); +- ptr = lutil_strcopy( ptr, count_buf[ i ] ); +- } +- +- ber_bvarray_add( valp, &bv ); +- +- return 0; +-} +- +-static int +-bdb_monitor_idx_entry_add( +- struct bdb_info *bdb, +- Entry *e ) +-{ +- BerVarray vals = NULL; +- Attribute *a; +- +- a = attr_find( e->e_attrs, ad_olmDbNotIndexed ); +- +- ldap_pvt_thread_mutex_lock( &bdb->bi_idx_mutex ); +- +- avl_apply( bdb->bi_idx, bdb_monitor_idx_apply, +- &vals, -1, AVL_INORDER ); +- +- ldap_pvt_thread_mutex_unlock( &bdb->bi_idx_mutex ); +- +- if ( vals != NULL ) { +- if ( a != NULL ) { +- assert( a->a_nvals == a->a_vals ); +- +- ber_bvarray_free( a->a_vals ); +- +- } else { +- Attribute **ap; +- +- for ( ap = &e->e_attrs; *ap != NULL; ap = &(*ap)->a_next ) +- ; +- *ap = attr_alloc( ad_olmDbNotIndexed ); +- a = *ap; +- } +- a->a_vals = vals; +- a->a_nvals = a->a_vals; +- } +- +- return 0; +-} +- +-#endif /* BDB_MONITOR_IDX */ +diff --git a/servers/slapd/back-bdb/nextid.c b/servers/slapd/back-bdb/nextid.c +deleted file mode 100644 +index 480b80e..0000000 +--- a/servers/slapd/back-bdb/nextid.c ++++ /dev/null +@@ -1,80 +0,0 @@ +-/* init.c - initialize bdb backend */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +-#include +- +-#include "back-bdb.h" +- +-int bdb_next_id( BackendDB *be, ID *out ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) be->be_private; +- +- ldap_pvt_thread_mutex_lock( &bdb->bi_lastid_mutex ); +- *out = ++bdb->bi_lastid; +- ldap_pvt_thread_mutex_unlock( &bdb->bi_lastid_mutex ); +- +- return 0; +-} +- +-int bdb_last_id( BackendDB *be, DB_TXN *tid ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) be->be_private; +- int rc; +- ID id = 0; +- unsigned char idbuf[sizeof(ID)]; +- DBT key, data; +- DBC *cursor; +- +- DBTzero( &key ); +- key.flags = DB_DBT_USERMEM; +- key.data = (char *) idbuf; +- key.ulen = sizeof( idbuf ); +- +- DBTzero( &data ); +- data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; +- +- /* Get a read cursor */ +- rc = bdb->bi_id2entry->bdi_db->cursor( bdb->bi_id2entry->bdi_db, +- tid, &cursor, 0 ); +- +- if (rc == 0) { +- rc = cursor->c_get(cursor, &key, &data, DB_LAST); +- cursor->c_close(cursor); +- } +- +- switch(rc) { +- case DB_NOTFOUND: +- rc = 0; +- break; +- case 0: +- BDB_DISK2ID( idbuf, &id ); +- break; +- +- default: +- Debug( LDAP_DEBUG_ANY, +- "=> bdb_last_id: get failed: %s (%d)\n", +- db_strerror(rc), rc, 0 ); +- goto done; +- } +- +- bdb->bi_lastid = id; +- +-done: +- return rc; +-} +diff --git a/servers/slapd/back-bdb/operational.c b/servers/slapd/back-bdb/operational.c +deleted file mode 100644 +index 5f21abe..0000000 +--- a/servers/slapd/back-bdb/operational.c ++++ /dev/null +@@ -1,151 +0,0 @@ +-/* operational.c - bdb backend operational attributes function */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +- +-#include +-#include +- +-#include "slap.h" +-#include "back-bdb.h" +- +-/* +- * sets *hasSubordinates to LDAP_COMPARE_TRUE/LDAP_COMPARE_FALSE +- * if the entry has children or not. +- */ +-int +-bdb_hasSubordinates( +- Operation *op, +- Entry *e, +- int *hasSubordinates ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- struct bdb_op_info *opinfo; +- OpExtra *oex; +- DB_TXN *rtxn; +- int rc; +- int release = 0; +- +- assert( e != NULL ); +- +- /* NOTE: this should never happen, but it actually happens +- * when using back-relay; until we find a better way to +- * preserve entry's private information while rewriting it, +- * let's disable the hasSubordinate feature for back-relay. +- */ +- if ( BEI( e ) == NULL ) { +- Entry *ee = NULL; +- rc = be_entry_get_rw( op, &e->e_nname, NULL, NULL, 0, &ee ); +- if ( rc != LDAP_SUCCESS || ee == NULL ) { +- rc = LDAP_OTHER; +- goto done; +- } +- e = ee; +- release = 1; +- if ( BEI( ee ) == NULL ) { +- rc = LDAP_OTHER; +- goto done; +- } +- } +- +- /* Check for a txn in a parent op, otherwise use reader txn */ +- LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) { +- if ( oex->oe_key == bdb ) +- break; +- } +- opinfo = (struct bdb_op_info *) oex; +- if ( opinfo && opinfo->boi_txn ) { +- rtxn = opinfo->boi_txn; +- } else { +- rc = bdb_reader_get(op, bdb->bi_dbenv, &rtxn); +- if ( rc ) { +- rc = LDAP_OTHER; +- goto done; +- } +- } +- +-retry: +- /* FIXME: we can no longer assume the entry's e_private +- * field is correctly populated; so we need to reacquire +- * it with reader lock */ +- rc = bdb_cache_children( op, rtxn, e ); +- +- switch( rc ) { +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto retry; +- +- case 0: +- *hasSubordinates = LDAP_COMPARE_TRUE; +- break; +- +- case DB_NOTFOUND: +- *hasSubordinates = LDAP_COMPARE_FALSE; +- rc = LDAP_SUCCESS; +- break; +- +- default: +- Debug(LDAP_DEBUG_ARGS, +- "<=- " LDAP_XSTRING(bdb_hasSubordinates) +- ": has_children failed: %s (%d)\n", +- db_strerror(rc), rc, 0 ); +- rc = LDAP_OTHER; +- } +- +-done:; +- if ( release && e != NULL ) be_entry_release_r( op, e ); +- return rc; +-} +- +-/* +- * sets the supported operational attributes (if required) +- */ +-int +-bdb_operational( +- Operation *op, +- SlapReply *rs ) +-{ +- Attribute **ap; +- +- assert( rs->sr_entry != NULL ); +- +- for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next ) { +- if ( (*ap)->a_desc == slap_schema.si_ad_hasSubordinates ) { +- break; +- } +- } +- +- if ( *ap == NULL && +- attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_hasSubordinates ) == NULL && +- ( SLAP_OPATTRS( rs->sr_attr_flags ) || +- ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) ) ) +- { +- int hasSubordinates, rc; +- +- rc = bdb_hasSubordinates( op, rs->sr_entry, &hasSubordinates ); +- if ( rc == LDAP_SUCCESS ) { +- *ap = slap_operational_hasSubordinate( hasSubordinates == LDAP_COMPARE_TRUE ); +- assert( *ap != NULL ); +- +- ap = &(*ap)->a_next; +- } +- } +- +- return LDAP_SUCCESS; +-} +- +diff --git a/servers/slapd/back-bdb/proto-bdb.h b/servers/slapd/back-bdb/proto-bdb.h +deleted file mode 100644 +index 34b8ce0..0000000 +--- a/servers/slapd/back-bdb/proto-bdb.h ++++ /dev/null +@@ -1,678 +0,0 @@ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#ifndef _PROTO_BDB_H +-#define _PROTO_BDB_H +- +-LDAP_BEGIN_DECL +- +-#ifdef BDB_HIER +-#define BDB_SYMBOL(x) LDAP_CONCAT(hdb_,x) +-#define BDB_UCTYPE "HDB" +-#else +-#define BDB_SYMBOL(x) LDAP_CONCAT(bdb_,x) +-#define BDB_UCTYPE "BDB" +-#endif +- +-/* +- * attr.c +- */ +- +-#define bdb_attr_mask BDB_SYMBOL(attr_mask) +-#define bdb_attr_flush BDB_SYMBOL(attr_flush) +-#define bdb_attr_slot BDB_SYMBOL(attr_slot) +-#define bdb_attr_index_config BDB_SYMBOL(attr_index_config) +-#define bdb_attr_index_destroy BDB_SYMBOL(attr_index_destroy) +-#define bdb_attr_index_free BDB_SYMBOL(attr_index_free) +-#define bdb_attr_index_unparse BDB_SYMBOL(attr_index_unparse) +-#define bdb_attr_info_free BDB_SYMBOL(attr_info_free) +- +-AttrInfo *bdb_attr_mask( struct bdb_info *bdb, +- AttributeDescription *desc ); +- +-void bdb_attr_flush( struct bdb_info *bdb ); +- +-int bdb_attr_slot( struct bdb_info *bdb, +- AttributeDescription *desc, int *insert ); +- +-int bdb_attr_index_config LDAP_P(( struct bdb_info *bdb, +- const char *fname, int lineno, +- int argc, char **argv, struct config_reply_s *cr )); +- +-void bdb_attr_index_unparse LDAP_P(( struct bdb_info *bdb, BerVarray *bva )); +-void bdb_attr_index_destroy LDAP_P(( struct bdb_info *bdb )); +-void bdb_attr_index_free LDAP_P(( struct bdb_info *bdb, +- AttributeDescription *ad )); +- +-void bdb_attr_info_free( AttrInfo *ai ); +- +-/* +- * config.c +- */ +- +-#define bdb_back_init_cf BDB_SYMBOL(back_init_cf) +- +-int bdb_back_init_cf( BackendInfo *bi ); +- +-/* +- * dbcache.c +- */ +-#define bdb_db_cache BDB_SYMBOL(db_cache) +-#define bdb_db_findsize BDB_SYMBOL(db_findsize) +- +-int +-bdb_db_cache( +- Backend *be, +- struct berval *name, +- DB **db ); +- +-int +-bdb_db_findsize( +- struct bdb_info *bdb, +- struct berval *name ); +- +-/* +- * dn2entry.c +- */ +-#define bdb_dn2entry BDB_SYMBOL(dn2entry) +- +-int bdb_dn2entry LDAP_P(( Operation *op, DB_TXN *tid, +- struct berval *dn, EntryInfo **e, int matched, +- DB_LOCK *lock )); +- +-/* +- * dn2id.c +- */ +-#define bdb_dn2id BDB_SYMBOL(dn2id) +-#define bdb_dn2id_add BDB_SYMBOL(dn2id_add) +-#define bdb_dn2id_delete BDB_SYMBOL(dn2id_delete) +-#define bdb_dn2id_children BDB_SYMBOL(dn2id_children) +-#define bdb_dn2idl BDB_SYMBOL(dn2idl) +- +-int bdb_dn2id( +- Operation *op, +- struct berval *dn, +- EntryInfo *ei, +- DB_TXN *txn, +- DBC **cursor ); +- +-int bdb_dn2id_add( +- Operation *op, +- DB_TXN *tid, +- EntryInfo *eip, +- Entry *e ); +- +-int bdb_dn2id_delete( +- Operation *op, +- DB_TXN *tid, +- EntryInfo *eip, +- Entry *e ); +- +-int bdb_dn2id_children( +- Operation *op, +- DB_TXN *tid, +- Entry *e ); +- +-int bdb_dn2idl( +- Operation *op, +- DB_TXN *txn, +- struct berval *ndn, +- EntryInfo *ei, +- ID *ids, +- ID *stack ); +- +-#ifdef BDB_HIER +-#define bdb_dn2id_parent BDB_SYMBOL(dn2id_parent) +-#define bdb_dup_compare BDB_SYMBOL(dup_compare) +-#define bdb_fix_dn BDB_SYMBOL(fix_dn) +- +-int bdb_dn2id_parent( +- Operation *op, +- DB_TXN *txn, +- EntryInfo *ei, +- ID *idp ); +- +-int bdb_dup_compare( +- DB *db, +- const DBT *usrkey, +- const DBT *curkey ); +- +-int bdb_fix_dn( Entry *e, int checkit ); +-#endif +- +- +-/* +- * error.c +- */ +-#define bdb_errcall BDB_SYMBOL(errcall) +- +-#if DB_VERSION_FULL < 0x04030000 +-void bdb_errcall( const char *pfx, char * msg ); +-#else +-#define bdb_msgcall BDB_SYMBOL(msgcall) +-void bdb_errcall( const DB_ENV *env, const char *pfx, const char * msg ); +-void bdb_msgcall( const DB_ENV *env, const char * msg ); +-#endif +- +-#ifdef HAVE_EBCDIC +-#define ebcdic_dberror BDB_SYMBOL(ebcdic_dberror) +- +-char *ebcdic_dberror( int rc ); +-#define db_strerror(x) ebcdic_dberror(x) +-#endif +- +-/* +- * filterentry.c +- */ +-#define bdb_filter_candidates BDB_SYMBOL(filter_candidates) +- +-int bdb_filter_candidates( +- Operation *op, +- DB_TXN *txn, +- Filter *f, +- ID *ids, +- ID *tmp, +- ID *stack ); +- +-/* +- * id2entry.c +- */ +-#define bdb_id2entry BDB_SYMBOL(id2entry) +-#define bdb_id2entry_add BDB_SYMBOL(id2entry_add) +-#define bdb_id2entry_update BDB_SYMBOL(id2entry_update) +-#define bdb_id2entry_delete BDB_SYMBOL(id2entry_delete) +- +-int bdb_id2entry_add( +- BackendDB *be, +- DB_TXN *tid, +- Entry *e ); +- +-int bdb_id2entry_update( +- BackendDB *be, +- DB_TXN *tid, +- Entry *e ); +- +-int bdb_id2entry_delete( +- BackendDB *be, +- DB_TXN *tid, +- Entry *e); +- +-#ifdef SLAP_ZONE_ALLOC +-#else +-int bdb_id2entry( +- BackendDB *be, +- DB_TXN *tid, +- ID id, +- Entry **e); +-#endif +- +-#define bdb_entry_free BDB_SYMBOL(entry_free) +-#define bdb_entry_return BDB_SYMBOL(entry_return) +-#define bdb_entry_release BDB_SYMBOL(entry_release) +-#define bdb_entry_get BDB_SYMBOL(entry_get) +- +-void bdb_entry_free ( Entry *e ); +-#ifdef SLAP_ZONE_ALLOC +-int bdb_entry_return( struct bdb_info *bdb, Entry *e, int seqno ); +-#else +-int bdb_entry_return( Entry *e ); +-#endif +-BI_entry_release_rw bdb_entry_release; +-BI_entry_get_rw bdb_entry_get; +- +- +-/* +- * idl.c +- */ +- +-#define bdb_idl_cache_get BDB_SYMBOL(idl_cache_get) +-#define bdb_idl_cache_put BDB_SYMBOL(idl_cache_put) +-#define bdb_idl_cache_del BDB_SYMBOL(idl_cache_del) +-#define bdb_idl_cache_add_id BDB_SYMBOL(idl_cache_add_id) +-#define bdb_idl_cache_del_id BDB_SYMBOL(idl_cache_del_id) +- +-int bdb_idl_cache_get( +- struct bdb_info *bdb, +- DB *db, +- DBT *key, +- ID *ids ); +- +-void +-bdb_idl_cache_put( +- struct bdb_info *bdb, +- DB *db, +- DBT *key, +- ID *ids, +- int rc ); +- +-void +-bdb_idl_cache_del( +- struct bdb_info *bdb, +- DB *db, +- DBT *key ); +- +-void +-bdb_idl_cache_add_id( +- struct bdb_info *bdb, +- DB *db, +- DBT *key, +- ID id ); +- +-void +-bdb_idl_cache_del_id( +- struct bdb_info *bdb, +- DB *db, +- DBT *key, +- ID id ); +- +-#define bdb_idl_first BDB_SYMBOL(idl_first) +-#define bdb_idl_next BDB_SYMBOL(idl_next) +-#define bdb_idl_search BDB_SYMBOL(idl_search) +-#define bdb_idl_insert BDB_SYMBOL(idl_insert) +-#define bdb_idl_delete BDB_SYMBOL(idl_delete) +-#define bdb_idl_intersection BDB_SYMBOL(idl_intersection) +-#define bdb_idl_union BDB_SYMBOL(idl_union) +-#define bdb_idl_sort BDB_SYMBOL(idl_sort) +-#define bdb_idl_append BDB_SYMBOL(idl_append) +-#define bdb_idl_append_one BDB_SYMBOL(idl_append_one) +- +-#define bdb_idl_fetch_key BDB_SYMBOL(idl_fetch_key) +-#define bdb_idl_insert_key BDB_SYMBOL(idl_insert_key) +-#define bdb_idl_delete_key BDB_SYMBOL(idl_delete_key) +- +-unsigned bdb_idl_search( ID *ids, ID id ); +- +-int bdb_idl_fetch_key( +- BackendDB *be, +- DB *db, +- DB_TXN *txn, +- DBT *key, +- ID *ids, +- DBC **saved_cursor, +- int get_flag ); +- +-int bdb_idl_insert( ID *ids, ID id ); +-int bdb_idl_delete( ID *ids, ID id ); +- +-int bdb_idl_insert_key( +- BackendDB *be, +- DB *db, +- DB_TXN *txn, +- DBT *key, +- ID id ); +- +-int bdb_idl_delete_key( +- BackendDB *be, +- DB *db, +- DB_TXN *txn, +- DBT *key, +- ID id ); +- +-int +-bdb_idl_intersection( +- ID *a, +- ID *b ); +- +-int +-bdb_idl_union( +- ID *a, +- ID *b ); +- +-ID bdb_idl_first( ID *ids, ID *cursor ); +-ID bdb_idl_next( ID *ids, ID *cursor ); +- +-void bdb_idl_sort( ID *ids, ID *tmp ); +-int bdb_idl_append( ID *a, ID *b ); +-int bdb_idl_append_one( ID *ids, ID id ); +- +- +-/* +- * index.c +- */ +-#define bdb_index_mask BDB_SYMBOL(index_mask) +-#define bdb_index_param BDB_SYMBOL(index_param) +-#define bdb_index_values BDB_SYMBOL(index_values) +-#define bdb_index_entry BDB_SYMBOL(index_entry) +-#define bdb_index_recset BDB_SYMBOL(index_recset) +-#define bdb_index_recrun BDB_SYMBOL(index_recrun) +- +-extern AttrInfo * +-bdb_index_mask LDAP_P(( +- Backend *be, +- AttributeDescription *desc, +- struct berval *name )); +- +-extern int +-bdb_index_param LDAP_P(( +- Backend *be, +- AttributeDescription *desc, +- int ftype, +- DB **db, +- slap_mask_t *mask, +- struct berval *prefix )); +- +-extern int +-bdb_index_values LDAP_P(( +- Operation *op, +- DB_TXN *txn, +- AttributeDescription *desc, +- BerVarray vals, +- ID id, +- int opid )); +- +-extern int +-bdb_index_recset LDAP_P(( +- struct bdb_info *bdb, +- Attribute *a, +- AttributeType *type, +- struct berval *tags, +- IndexRec *ir )); +- +-extern int +-bdb_index_recrun LDAP_P(( +- Operation *op, +- struct bdb_info *bdb, +- IndexRec *ir, +- ID id, +- int base )); +- +-int bdb_index_entry LDAP_P(( Operation *op, DB_TXN *t, int r, Entry *e )); +- +-#define bdb_index_entry_add(op,t,e) \ +- bdb_index_entry((op),(t),SLAP_INDEX_ADD_OP,(e)) +-#define bdb_index_entry_del(op,t,e) \ +- bdb_index_entry((op),(t),SLAP_INDEX_DELETE_OP,(e)) +- +-/* +- * key.c +- */ +-#define bdb_key_read BDB_SYMBOL(key_read) +-#define bdb_key_change BDB_SYMBOL(key_change) +- +-extern int +-bdb_key_read( +- Backend *be, +- DB *db, +- DB_TXN *txn, +- struct berval *k, +- ID *ids, +- DBC **saved_cursor, +- int get_flags ); +- +-extern int +-bdb_key_change( +- Backend *be, +- DB *db, +- DB_TXN *txn, +- struct berval *k, +- ID id, +- int op ); +- +-/* +- * nextid.c +- */ +-#define bdb_next_id BDB_SYMBOL(next_id) +-#define bdb_last_id BDB_SYMBOL(last_id) +- +-int bdb_next_id( BackendDB *be, ID *id ); +-int bdb_last_id( BackendDB *be, DB_TXN *tid ); +- +-/* +- * modify.c +- */ +-#define bdb_modify_internal BDB_SYMBOL(modify_internal) +- +-int bdb_modify_internal( +- Operation *op, +- DB_TXN *tid, +- Modifications *modlist, +- Entry *e, +- const char **text, +- char *textbuf, +- size_t textlen ); +- +-/* +- * monitor.c +- */ +- +-#define bdb_monitor_db_init BDB_SYMBOL(monitor_db_init) +-#define bdb_monitor_db_open BDB_SYMBOL(monitor_db_open) +-#define bdb_monitor_db_close BDB_SYMBOL(monitor_db_close) +-#define bdb_monitor_db_destroy BDB_SYMBOL(monitor_db_destroy) +- +-int bdb_monitor_db_init( BackendDB *be ); +-int bdb_monitor_db_open( BackendDB *be ); +-int bdb_monitor_db_close( BackendDB *be ); +-int bdb_monitor_db_destroy( BackendDB *be ); +- +-#ifdef BDB_MONITOR_IDX +-#define bdb_monitor_idx_add BDB_SYMBOL(monitor_idx_add) +-int +-bdb_monitor_idx_add( +- struct bdb_info *bdb, +- AttributeDescription *desc, +- slap_mask_t type ); +-#endif /* BDB_MONITOR_IDX */ +- +-/* +- * cache.c +- */ +-#define bdb_cache_entry_db_unlock BDB_SYMBOL(cache_entry_db_unlock) +-#define bdb_cache_return_entry_rw BDB_SYMBOL(cache_return_entry_rw) +- +-#define bdb_cache_entryinfo_lock(e) \ +- ldap_pvt_thread_mutex_lock( &(e)->bei_kids_mutex ) +-#define bdb_cache_entryinfo_unlock(e) \ +- ldap_pvt_thread_mutex_unlock( &(e)->bei_kids_mutex ) +-#define bdb_cache_entryinfo_trylock(e) \ +- ldap_pvt_thread_mutex_trylock( &(e)->bei_kids_mutex ) +- +-/* What a mess. Hopefully the current cache scheme will stabilize +- * and we can trim out all of this stuff. +- */ +-void bdb_cache_return_entry_rw( struct bdb_info *bdb, Entry *e, +- int rw, DB_LOCK *lock ); +-#define bdb_cache_return_entry_r(bdb, e, l) \ +- bdb_cache_return_entry_rw((bdb), (e), 0, (l)) +-#define bdb_cache_return_entry_w(bdb, e, l) \ +- bdb_cache_return_entry_rw((bdb), (e), 1, (l)) +-#if 0 +-void bdb_unlocked_cache_return_entry_rw( struct bdb_info *bdb, Entry *e, int rw ); +-#else +-#define bdb_unlocked_cache_return_entry_rw( a, b, c ) ((void)0) +-#endif +-#define bdb_unlocked_cache_return_entry_r( c, e ) \ +- bdb_unlocked_cache_return_entry_rw((c), (e), 0) +-#define bdb_unlocked_cache_return_entry_w( c, e ) \ +- bdb_unlocked_cache_return_entry_rw((c), (e), 1) +- +-#define bdb_cache_add BDB_SYMBOL(cache_add) +-#define bdb_cache_children BDB_SYMBOL(cache_children) +-#define bdb_cache_delete BDB_SYMBOL(cache_delete) +-#define bdb_cache_delete_cleanup BDB_SYMBOL(cache_delete_cleanup) +-#define bdb_cache_find_id BDB_SYMBOL(cache_find_id) +-#define bdb_cache_find_ndn BDB_SYMBOL(cache_find_ndn) +-#define bdb_cache_find_parent BDB_SYMBOL(cache_find_parent) +-#define bdb_cache_modify BDB_SYMBOL(cache_modify) +-#define bdb_cache_modrdn BDB_SYMBOL(cache_modrdn) +-#define bdb_cache_release_all BDB_SYMBOL(cache_release_all) +-#define bdb_cache_delete_entry BDB_SYMBOL(cache_delete_entry) +-#define bdb_cache_deref BDB_SYMBOL(cache_deref) +- +-int bdb_cache_children( +- Operation *op, +- DB_TXN *txn, +- Entry *e +-); +-int bdb_cache_add( +- struct bdb_info *bdb, +- EntryInfo *pei, +- Entry *e, +- struct berval *nrdn, +- DB_TXN *txn, +- DB_LOCK *lock +-); +-int bdb_cache_modrdn( +- struct bdb_info *bdb, +- Entry *e, +- struct berval *nrdn, +- Entry *new, +- EntryInfo *ein, +- DB_TXN *txn, +- DB_LOCK *lock +-); +-int bdb_cache_modify( +- struct bdb_info *bdb, +- Entry *e, +- Attribute *newAttrs, +- DB_TXN *txn, +- DB_LOCK *lock +-); +-int bdb_cache_find_ndn( +- Operation *op, +- DB_TXN *txn, +- struct berval *ndn, +- EntryInfo **res +-); +- +-#define ID_LOCKED 1 +-#define ID_NOCACHE 2 +-#define ID_NOENTRY 4 +-#define ID_CHKPURGE 8 +-int bdb_cache_find_id( +- Operation *op, +- DB_TXN *tid, +- ID id, +- EntryInfo **eip, +- int flag, +- DB_LOCK *lock +-); +-int +-bdb_cache_find_parent( +- Operation *op, +- DB_TXN *txn, +- ID id, +- EntryInfo **res +-); +-int bdb_cache_delete( +- struct bdb_info *bdb, +- Entry *e, +- DB_TXN *txn, +- DB_LOCK *lock +-); +-void bdb_cache_delete_cleanup( +- Cache *cache, +- EntryInfo *ei +-); +-void bdb_cache_release_all( Cache *cache ); +-void bdb_cache_deref( EntryInfo *ei ); +- +-#ifdef BDB_HIER +-int hdb_cache_load( +- struct bdb_info *bdb, +- EntryInfo *ei, +- EntryInfo **res +-); +-#endif +- +-#define bdb_cache_entry_db_relock BDB_SYMBOL(cache_entry_db_relock) +-int bdb_cache_entry_db_relock( +- struct bdb_info *bdb, +- DB_TXN *txn, +- EntryInfo *ei, +- int rw, +- int tryOnly, +- DB_LOCK *lock ); +- +-int bdb_cache_entry_db_unlock( +- struct bdb_info *bdb, +- DB_LOCK *lock ); +- +-#define bdb_reader_get BDB_SYMBOL(reader_get) +-#define bdb_reader_flush BDB_SYMBOL(reader_flush) +-int bdb_reader_get( Operation *op, DB_ENV *env, DB_TXN **txn ); +-void bdb_reader_flush( DB_ENV *env ); +- +-/* +- * trans.c +- */ +-#define bdb_trans_backoff BDB_SYMBOL(trans_backoff) +- +-void +-bdb_trans_backoff( int num_retries ); +- +-/* +- * former external.h +- */ +- +-#define bdb_back_initialize BDB_SYMBOL(back_initialize) +-#define bdb_db_config BDB_SYMBOL(db_config) +-#define bdb_add BDB_SYMBOL(add) +-#define bdb_bind BDB_SYMBOL(bind) +-#define bdb_compare BDB_SYMBOL(compare) +-#define bdb_delete BDB_SYMBOL(delete) +-#define bdb_modify BDB_SYMBOL(modify) +-#define bdb_modrdn BDB_SYMBOL(modrdn) +-#define bdb_search BDB_SYMBOL(search) +-#define bdb_extended BDB_SYMBOL(extended) +-#define bdb_referrals BDB_SYMBOL(referrals) +-#define bdb_operational BDB_SYMBOL(operational) +-#define bdb_hasSubordinates BDB_SYMBOL(hasSubordinates) +-#define bdb_tool_entry_open BDB_SYMBOL(tool_entry_open) +-#define bdb_tool_entry_close BDB_SYMBOL(tool_entry_close) +-#define bdb_tool_entry_first_x BDB_SYMBOL(tool_entry_first_x) +-#define bdb_tool_entry_next BDB_SYMBOL(tool_entry_next) +-#define bdb_tool_entry_get BDB_SYMBOL(tool_entry_get) +-#define bdb_tool_entry_put BDB_SYMBOL(tool_entry_put) +-#define bdb_tool_entry_reindex BDB_SYMBOL(tool_entry_reindex) +-#define bdb_tool_dn2id_get BDB_SYMBOL(tool_dn2id_get) +-#define bdb_tool_entry_modify BDB_SYMBOL(tool_entry_modify) +-#define bdb_tool_idl_add BDB_SYMBOL(tool_idl_add) +- +-extern BI_init bdb_back_initialize; +- +-extern BI_db_config bdb_db_config; +- +-extern BI_op_add bdb_add; +-extern BI_op_bind bdb_bind; +-extern BI_op_compare bdb_compare; +-extern BI_op_delete bdb_delete; +-extern BI_op_modify bdb_modify; +-extern BI_op_modrdn bdb_modrdn; +-extern BI_op_search bdb_search; +-extern BI_op_extended bdb_extended; +- +-extern BI_chk_referrals bdb_referrals; +- +-extern BI_operational bdb_operational; +- +-extern BI_has_subordinates bdb_hasSubordinates; +- +-/* tools.c */ +-extern BI_tool_entry_open bdb_tool_entry_open; +-extern BI_tool_entry_close bdb_tool_entry_close; +-extern BI_tool_entry_first_x bdb_tool_entry_first_x; +-extern BI_tool_entry_next bdb_tool_entry_next; +-extern BI_tool_entry_get bdb_tool_entry_get; +-extern BI_tool_entry_put bdb_tool_entry_put; +-extern BI_tool_entry_reindex bdb_tool_entry_reindex; +-extern BI_tool_dn2id_get bdb_tool_dn2id_get; +-extern BI_tool_entry_modify bdb_tool_entry_modify; +- +-int bdb_tool_idl_add( BackendDB *be, DB *db, DB_TXN *txn, DBT *key, ID id ); +- +-LDAP_END_DECL +- +-#endif /* _PROTO_BDB_H */ +diff --git a/servers/slapd/back-bdb/referral.c b/servers/slapd/back-bdb/referral.c +deleted file mode 100644 +index d92ff5a..0000000 +--- a/servers/slapd/back-bdb/referral.c ++++ /dev/null +@@ -1,152 +0,0 @@ +-/* referral.c - BDB backend referral handler */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +-#include +-#include +- +-#include "back-bdb.h" +- +-int +-bdb_referrals( Operation *op, SlapReply *rs ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- Entry *e = NULL; +- EntryInfo *ei; +- int rc = LDAP_SUCCESS; +- +- DB_TXN *rtxn; +- DB_LOCK lock; +- +- if( op->o_tag == LDAP_REQ_SEARCH ) { +- /* let search take care of itself */ +- return rc; +- } +- +- if( get_manageDSAit( op ) ) { +- /* let op take care of DSA management */ +- return rc; +- } +- +- rc = bdb_reader_get(op, bdb->bi_dbenv, &rtxn); +- switch(rc) { +- case 0: +- break; +- default: +- return LDAP_OTHER; +- } +- +-dn2entry_retry: +- /* get entry */ +- rc = bdb_dn2entry( op, rtxn, &op->o_req_ndn, &ei, 1, &lock ); +- +- /* bdb_dn2entry() may legally leave ei == NULL +- * if rc != 0 and rc != DB_NOTFOUND +- */ +- if ( ei ) { +- e = ei->bei_e; +- } +- +- switch(rc) { +- case DB_NOTFOUND: +- case 0: +- break; +- case LDAP_BUSY: +- rs->sr_text = "ldap server busy"; +- return LDAP_BUSY; +- case DB_LOCK_DEADLOCK: +- case DB_LOCK_NOTGRANTED: +- goto dn2entry_retry; +- default: +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_referrals) +- ": dn2entry failed: %s (%d)\n", +- db_strerror(rc), rc, 0 ); +- rs->sr_text = "internal error"; +- return LDAP_OTHER; +- } +- +- if ( rc == DB_NOTFOUND ) { +- rc = LDAP_SUCCESS; +- rs->sr_matched = NULL; +- if ( e != NULL ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_referrals) +- ": tag=%lu target=\"%s\" matched=\"%s\"\n", +- (unsigned long)op->o_tag, op->o_req_dn.bv_val, e->e_name.bv_val ); +- +- if( is_entry_referral( e ) ) { +- BerVarray ref = get_entry_referrals( op, e ); +- rc = LDAP_OTHER; +- rs->sr_ref = referral_rewrite( ref, &e->e_name, +- &op->o_req_dn, LDAP_SCOPE_DEFAULT ); +- ber_bvarray_free( ref ); +- if ( rs->sr_ref ) { +- rs->sr_matched = ber_strdup_x( +- e->e_name.bv_val, op->o_tmpmemctx ); +- } +- } +- +- bdb_cache_return_entry_r (bdb, e, &lock); +- e = NULL; +- } +- +- if( rs->sr_ref != NULL ) { +- /* send referrals */ +- rc = rs->sr_err = LDAP_REFERRAL; +- send_ldap_result( op, rs ); +- ber_bvarray_free( rs->sr_ref ); +- rs->sr_ref = NULL; +- } else if ( rc != LDAP_SUCCESS ) { +- rs->sr_text = rs->sr_matched ? "bad referral object" : NULL; +- } +- +- if (rs->sr_matched) { +- op->o_tmpfree( (char *)rs->sr_matched, op->o_tmpmemctx ); +- rs->sr_matched = NULL; +- } +- return rc; +- } +- +- if ( is_entry_referral( e ) ) { +- /* entry is a referral */ +- BerVarray refs = get_entry_referrals( op, e ); +- rs->sr_ref = referral_rewrite( +- refs, &e->e_name, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); +- +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_referrals) +- ": tag=%lu target=\"%s\" matched=\"%s\"\n", +- (unsigned long)op->o_tag, op->o_req_dn.bv_val, e->e_name.bv_val ); +- +- rs->sr_matched = e->e_name.bv_val; +- if( rs->sr_ref != NULL ) { +- rc = rs->sr_err = LDAP_REFERRAL; +- send_ldap_result( op, rs ); +- ber_bvarray_free( rs->sr_ref ); +- rs->sr_ref = NULL; +- } else { +- rc = LDAP_OTHER; +- rs->sr_text = "bad referral object"; +- } +- +- rs->sr_matched = NULL; +- ber_bvarray_free( refs ); +- } +- +- bdb_cache_return_entry_r(bdb, e, &lock); +- return rc; +-} +diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c +deleted file mode 100644 +index dd67f21..0000000 +--- a/servers/slapd/back-bdb/search.c ++++ /dev/null +@@ -1,1388 +0,0 @@ +-/* search.c - search operation */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +-#include +- +-#include "back-bdb.h" +-#include "idl.h" +- +-static int base_candidate( +- BackendDB *be, +- Entry *e, +- ID *ids ); +- +-static int search_candidates( +- Operation *op, +- SlapReply *rs, +- Entry *e, +- DB_TXN *txn, +- ID *ids, +- ID *scopes ); +- +-static int parse_paged_cookie( Operation *op, SlapReply *rs ); +- +-static void send_paged_response( +- Operation *op, +- SlapReply *rs, +- ID *lastid, +- int tentries ); +- +-/* Dereference aliases for a single alias entry. Return the final +- * dereferenced entry on success, NULL on any failure. +- */ +-static Entry * deref_base ( +- Operation *op, +- SlapReply *rs, +- Entry *e, +- Entry **matched, +- DB_TXN *txn, +- DB_LOCK *lock, +- ID *tmp, +- ID *visited ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- struct berval ndn; +- EntryInfo *ei; +- DB_LOCK lockr; +- +- rs->sr_err = LDAP_ALIAS_DEREF_PROBLEM; +- rs->sr_text = "maximum deref depth exceeded"; +- +- for (;;) { +- /* Remember the last entry we looked at, so we can +- * report broken links +- */ +- *matched = e; +- +- if (BDB_IDL_N(tmp) >= op->o_bd->be_max_deref_depth) { +- e = NULL; +- break; +- } +- +- /* If this is part of a subtree or onelevel search, +- * have we seen this ID before? If so, quit. +- */ +- if ( visited && bdb_idl_insert( visited, e->e_id ) ) { +- e = NULL; +- break; +- } +- +- /* If we've seen this ID during this deref iteration, +- * we've hit a loop. +- */ +- if ( bdb_idl_insert( tmp, e->e_id ) ) { +- rs->sr_err = LDAP_ALIAS_PROBLEM; +- rs->sr_text = "circular alias"; +- e = NULL; +- break; +- } +- +- /* If there was a problem getting the aliasedObjectName, +- * get_alias_dn will have set the error status. +- */ +- if ( get_alias_dn(e, &ndn, &rs->sr_err, &rs->sr_text) ) { +- e = NULL; +- break; +- } +- +- rs->sr_err = bdb_dn2entry( op, txn, &ndn, &ei, +- 0, &lockr ); +- if ( rs->sr_err == DB_LOCK_DEADLOCK ) +- return NULL; +- +- if ( ei ) { +- e = ei->bei_e; +- } else { +- e = NULL; +- } +- +- if (!e) { +- rs->sr_err = LDAP_ALIAS_PROBLEM; +- rs->sr_text = "aliasedObject not found"; +- break; +- } +- +- /* Free the previous entry, continue to work with the +- * one we just retrieved. +- */ +- bdb_cache_return_entry_r( bdb, *matched, lock); +- *lock = lockr; +- +- /* We found a regular entry. Return this to the caller. The +- * entry is still locked for Read. +- */ +- if (!is_entry_alias(e)) { +- rs->sr_err = LDAP_SUCCESS; +- rs->sr_text = NULL; +- break; +- } +- } +- return e; +-} +- +-/* Look for and dereference all aliases within the search scope. Adds +- * the dereferenced entries to the "ids" list. Requires "stack" to be +- * able to hold 8 levels of DB_SIZE IDLs. Of course we're hardcoded to +- * require a minimum of 8 UM_SIZE IDLs so this is never a problem. +- */ +-static int search_aliases( +- Operation *op, +- SlapReply *rs, +- Entry *e, +- DB_TXN *txn, +- ID *ids, +- ID *scopes, +- ID *stack ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- ID *aliases, *curscop, *subscop, *visited, *newsubs, *oldsubs, *tmp; +- ID cursora, ida, cursoro, ido, *subscop2; +- Entry *matched, *a; +- EntryInfo *ei; +- struct berval bv_alias = BER_BVC( "alias" ); +- AttributeAssertion aa_alias = ATTRIBUTEASSERTION_INIT; +- Filter af; +- DB_LOCK locka, lockr; +- int first = 1; +- +- aliases = stack; /* IDL of all aliases in the database */ +- curscop = aliases + BDB_IDL_DB_SIZE; /* Aliases in the current scope */ +- subscop = curscop + BDB_IDL_DB_SIZE; /* The current scope */ +- visited = subscop + BDB_IDL_DB_SIZE; /* IDs we've seen in this search */ +- newsubs = visited + BDB_IDL_DB_SIZE; /* New subtrees we've added */ +- oldsubs = newsubs + BDB_IDL_DB_SIZE; /* Subtrees added previously */ +- tmp = oldsubs + BDB_IDL_DB_SIZE; /* Scratch space for deref_base() */ +- +- /* A copy of subscop, because subscop gets clobbered by +- * the bdb_idl_union/intersection routines +- */ +- subscop2 = tmp + BDB_IDL_DB_SIZE; +- +- af.f_choice = LDAP_FILTER_EQUALITY; +- af.f_ava = &aa_alias; +- af.f_av_desc = slap_schema.si_ad_objectClass; +- af.f_av_value = bv_alias; +- af.f_next = NULL; +- +- /* Find all aliases in database */ +- BDB_IDL_ZERO( aliases ); +- rs->sr_err = bdb_filter_candidates( op, txn, &af, aliases, +- curscop, visited ); +- if (rs->sr_err != LDAP_SUCCESS || BDB_IDL_IS_ZERO( aliases )) { +- return rs->sr_err; +- } +- oldsubs[0] = 1; +- oldsubs[1] = e->e_id; +- +- BDB_IDL_ZERO( ids ); +- BDB_IDL_ZERO( visited ); +- BDB_IDL_ZERO( newsubs ); +- +- cursoro = 0; +- ido = bdb_idl_first( oldsubs, &cursoro ); +- +- for (;;) { +- /* Set curscop to only the aliases in the current scope. Start with +- * all the aliases, obtain the IDL for the current scope, and then +- * get the intersection of these two IDLs. Add the current scope +- * to the cumulative list of candidates. +- */ +- BDB_IDL_CPY( curscop, aliases ); +- rs->sr_err = bdb_dn2idl( op, txn, &e->e_nname, BEI(e), subscop, +- subscop2+BDB_IDL_DB_SIZE ); +- +- if (first) { +- first = 0; +- } else { +- bdb_cache_return_entry_r (bdb, e, &locka); +- } +- if ( rs->sr_err == DB_LOCK_DEADLOCK ) +- return rs->sr_err; +- +- BDB_IDL_CPY(subscop2, subscop); +- rs->sr_err = bdb_idl_intersection(curscop, subscop); +- bdb_idl_union( ids, subscop2 ); +- +- /* Dereference all of the aliases in the current scope. */ +- cursora = 0; +- for (ida = bdb_idl_first(curscop, &cursora); ida != NOID; +- ida = bdb_idl_next(curscop, &cursora)) +- { +- ei = NULL; +-retry1: +- rs->sr_err = bdb_cache_find_id(op, txn, +- ida, &ei, 0, &lockr ); +- if (rs->sr_err != LDAP_SUCCESS) { +- if ( rs->sr_err == DB_LOCK_DEADLOCK ) +- return rs->sr_err; +- if ( rs->sr_err == DB_LOCK_NOTGRANTED ) +- goto retry1; +- continue; +- } +- a = ei->bei_e; +- +- /* This should only happen if the curscop IDL has maxed out and +- * turned into a range that spans IDs indiscriminately +- */ +- if (!is_entry_alias(a)) { +- bdb_cache_return_entry_r (bdb, a, &lockr); +- continue; +- } +- +- /* Actually dereference the alias */ +- BDB_IDL_ZERO(tmp); +- a = deref_base( op, rs, a, &matched, txn, &lockr, +- tmp, visited ); +- if (a) { +- /* If the target was not already in our current candidates, +- * make note of it in the newsubs list. Also +- * set it in the scopes list so that bdb_search +- * can check it. +- */ +- if (bdb_idl_insert(ids, a->e_id) == 0) { +- bdb_idl_insert(newsubs, a->e_id); +- bdb_idl_insert(scopes, a->e_id); +- } +- bdb_cache_return_entry_r( bdb, a, &lockr); +- +- } else if ( rs->sr_err == DB_LOCK_DEADLOCK ) { +- return rs->sr_err; +- } else if (matched) { +- /* Alias could not be dereferenced, or it deref'd to +- * an ID we've already seen. Ignore it. +- */ +- bdb_cache_return_entry_r( bdb, matched, &lockr ); +- rs->sr_text = NULL; +- } +- } +- /* If this is a OneLevel search, we're done; oldsubs only had one +- * ID in it. For a Subtree search, oldsubs may be a list of scope IDs. +- */ +- if ( op->ors_scope == LDAP_SCOPE_ONELEVEL ) break; +-nextido: +- ido = bdb_idl_next( oldsubs, &cursoro ); +- +- /* If we're done processing the old scopes, did we add any new +- * scopes in this iteration? If so, go back and do those now. +- */ +- if (ido == NOID) { +- if (BDB_IDL_IS_ZERO(newsubs)) break; +- BDB_IDL_CPY(oldsubs, newsubs); +- BDB_IDL_ZERO(newsubs); +- cursoro = 0; +- ido = bdb_idl_first( oldsubs, &cursoro ); +- } +- +- /* Find the entry corresponding to the next scope. If it can't +- * be found, ignore it and move on. This should never happen; +- * we should never see the ID of an entry that doesn't exist. +- * Set the name so that the scope's IDL can be retrieved. +- */ +- ei = NULL; +-sameido: +- rs->sr_err = bdb_cache_find_id(op, txn, ido, &ei, +- 0, &locka ); +- if ( rs->sr_err != LDAP_SUCCESS ) { +- if ( rs->sr_err == DB_LOCK_DEADLOCK ) +- return rs->sr_err; +- if ( rs->sr_err == DB_LOCK_NOTGRANTED ) +- goto sameido; +- goto nextido; +- } +- e = ei->bei_e; +- } +- return rs->sr_err; +-} +- +-/* Get the next ID from the DB. Used if the candidate list is +- * a range and simple iteration hits missing entryIDs +- */ +-static int +-bdb_get_nextid(struct bdb_info *bdb, DB_TXN *ltid, ID *cursor) +-{ +- DBC *curs; +- DBT key, data; +- ID id, nid; +- int rc; +- +- id = *cursor + 1; +- BDB_ID2DISK( id, &nid ); +- rc = bdb->bi_id2entry->bdi_db->cursor( +- bdb->bi_id2entry->bdi_db, ltid, &curs, bdb->bi_db_opflags ); +- if ( rc ) +- return rc; +- key.data = &nid; +- key.size = key.ulen = sizeof(ID); +- key.flags = DB_DBT_USERMEM; +- data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; +- data.dlen = data.ulen = 0; +- rc = curs->c_get( curs, &key, &data, DB_SET_RANGE ); +- curs->c_close( curs ); +- if ( rc ) +- return rc; +- BDB_DISK2ID( &nid, cursor ); +- return 0; +-} +- +-int +-bdb_search( Operation *op, SlapReply *rs ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- ID id, cursor; +- ID lastid = NOID; +- ID candidates[BDB_IDL_UM_SIZE]; +- ID scopes[BDB_IDL_DB_SIZE]; +- Entry *e = NULL, base, *e_root; +- Entry *matched = NULL; +- EntryInfo *ei; +- AttributeName *attrs; +- struct berval realbase = BER_BVNULL; +- slap_mask_t mask; +- time_t stoptime; +- int manageDSAit; +- int tentries = 0; +- unsigned nentries = 0; +- int idflag = 0; +- +- DB_LOCK lock; +- struct bdb_op_info *opinfo = NULL; +- DB_TXN *ltid = NULL; +- OpExtra *oex; +- +- Debug( LDAP_DEBUG_TRACE, "=> " LDAP_XSTRING(bdb_search) "\n", 0, 0, 0); +- attrs = op->oq_search.rs_attrs; +- +- LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) { +- if ( oex->oe_key == bdb ) +- break; +- } +- opinfo = (struct bdb_op_info *) oex; +- +- manageDSAit = get_manageDSAit( op ); +- +- if ( opinfo && opinfo->boi_txn ) { +- ltid = opinfo->boi_txn; +- } else { +- rs->sr_err = bdb_reader_get( op, bdb->bi_dbenv, <id ); +- +- switch(rs->sr_err) { +- case 0: +- break; +- default: +- send_ldap_error( op, rs, LDAP_OTHER, "internal error" ); +- return rs->sr_err; +- } +- } +- +- e_root = bdb->bi_cache.c_dntree.bei_e; +- if ( op->o_req_ndn.bv_len == 0 ) { +- /* DIT root special case */ +- ei = e_root->e_private; +- rs->sr_err = LDAP_SUCCESS; +- } else { +- if ( op->ors_deref & LDAP_DEREF_FINDING ) { +- BDB_IDL_ZERO(candidates); +- } +-dn2entry_retry: +- /* get entry with reader lock */ +- rs->sr_err = bdb_dn2entry( op, ltid, &op->o_req_ndn, &ei, +- 1, &lock ); +- } +- +- switch(rs->sr_err) { +- case DB_NOTFOUND: +- matched = ei->bei_e; +- break; +- case 0: +- e = ei->bei_e; +- break; +- case DB_LOCK_DEADLOCK: +- if ( !opinfo ) { +- ltid->flags &= ~TXN_DEADLOCK; +- goto dn2entry_retry; +- } +- opinfo->boi_err = rs->sr_err; +- /* FALLTHRU */ +- case LDAP_BUSY: +- send_ldap_error( op, rs, LDAP_BUSY, "ldap server busy" ); +- return LDAP_BUSY; +- case DB_LOCK_NOTGRANTED: +- goto dn2entry_retry; +- default: +- send_ldap_error( op, rs, LDAP_OTHER, "internal error" ); +- return rs->sr_err; +- } +- +- if ( op->ors_deref & LDAP_DEREF_FINDING ) { +- if ( matched && is_entry_alias( matched )) { +- struct berval stub; +- +- stub.bv_val = op->o_req_ndn.bv_val; +- stub.bv_len = op->o_req_ndn.bv_len - matched->e_nname.bv_len - 1; +- e = deref_base( op, rs, matched, &matched, ltid, &lock, +- candidates, NULL ); +- if ( e ) { +- build_new_dn( &op->o_req_ndn, &e->e_nname, &stub, +- op->o_tmpmemctx ); +- bdb_cache_return_entry_r (bdb, e, &lock); +- matched = NULL; +- goto dn2entry_retry; +- } +- } else if ( e && is_entry_alias( e )) { +- e = deref_base( op, rs, e, &matched, ltid, &lock, +- candidates, NULL ); +- } +- } +- +- if ( e == NULL ) { +- struct berval matched_dn = BER_BVNULL; +- +- if ( matched != NULL ) { +- BerVarray erefs = NULL; +- +- /* return referral only if "disclose" +- * is granted on the object */ +- if ( ! access_allowed( op, matched, +- slap_schema.si_ad_entry, +- NULL, ACL_DISCLOSE, NULL ) ) +- { +- rs->sr_err = LDAP_NO_SUCH_OBJECT; +- +- } else { +- ber_dupbv( &matched_dn, &matched->e_name ); +- +- erefs = is_entry_referral( matched ) +- ? get_entry_referrals( op, matched ) +- : NULL; +- if ( rs->sr_err == DB_NOTFOUND ) +- rs->sr_err = LDAP_REFERRAL; +- rs->sr_matched = matched_dn.bv_val; +- } +- +-#ifdef SLAP_ZONE_ALLOC +- slap_zn_runlock(bdb->bi_cache.c_zctx, matched); +-#endif +- bdb_cache_return_entry_r (bdb, matched, &lock); +- matched = NULL; +- +- if ( erefs ) { +- rs->sr_ref = referral_rewrite( erefs, &matched_dn, +- &op->o_req_dn, op->oq_search.rs_scope ); +- ber_bvarray_free( erefs ); +- } +- +- } else { +-#ifdef SLAP_ZONE_ALLOC +- slap_zn_runlock(bdb->bi_cache.c_zctx, matched); +-#endif +- rs->sr_ref = referral_rewrite( default_referral, +- NULL, &op->o_req_dn, op->oq_search.rs_scope ); +- rs->sr_err = rs->sr_ref != NULL ? LDAP_REFERRAL : LDAP_NO_SUCH_OBJECT; +- } +- +- send_ldap_result( op, rs ); +- +- if ( rs->sr_ref ) { +- ber_bvarray_free( rs->sr_ref ); +- rs->sr_ref = NULL; +- } +- if ( !BER_BVISNULL( &matched_dn ) ) { +- ber_memfree( matched_dn.bv_val ); +- rs->sr_matched = NULL; +- } +- return rs->sr_err; +- } +- +- /* NOTE: __NEW__ "search" access is required +- * on searchBase object */ +- if ( ! access_allowed_mask( op, e, slap_schema.si_ad_entry, +- NULL, ACL_SEARCH, NULL, &mask ) ) +- { +- if ( !ACL_GRANT( mask, ACL_DISCLOSE ) ) { +- rs->sr_err = LDAP_NO_SUCH_OBJECT; +- } else { +- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; +- } +- +-#ifdef SLAP_ZONE_ALLOC +- slap_zn_runlock(bdb->bi_cache.c_zctx, e); +-#endif +- if ( e != e_root ) { +- bdb_cache_return_entry_r(bdb, e, &lock); +- } +- send_ldap_result( op, rs ); +- return rs->sr_err; +- } +- +- if ( !manageDSAit && e != e_root && is_entry_referral( e ) ) { +- /* entry is a referral, don't allow add */ +- struct berval matched_dn = BER_BVNULL; +- BerVarray erefs = NULL; +- +- ber_dupbv( &matched_dn, &e->e_name ); +- erefs = get_entry_referrals( op, e ); +- +- rs->sr_err = LDAP_REFERRAL; +- +-#ifdef SLAP_ZONE_ALLOC +- slap_zn_runlock(bdb->bi_cache.c_zctx, e); +-#endif +- bdb_cache_return_entry_r( bdb, e, &lock ); +- e = NULL; +- +- if ( erefs ) { +- rs->sr_ref = referral_rewrite( erefs, &matched_dn, +- &op->o_req_dn, op->oq_search.rs_scope ); +- ber_bvarray_free( erefs ); +- +- if ( !rs->sr_ref ) { +- rs->sr_text = "bad_referral object"; +- } +- } +- +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_search) ": entry is referral\n", +- 0, 0, 0 ); +- +- rs->sr_matched = matched_dn.bv_val; +- send_ldap_result( op, rs ); +- +- ber_bvarray_free( rs->sr_ref ); +- rs->sr_ref = NULL; +- ber_memfree( matched_dn.bv_val ); +- rs->sr_matched = NULL; +- return 1; +- } +- +- if ( get_assert( op ) && +- ( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE )) +- { +- rs->sr_err = LDAP_ASSERTION_FAILED; +-#ifdef SLAP_ZONE_ALLOC +- slap_zn_runlock(bdb->bi_cache.c_zctx, e); +-#endif +- if ( e != e_root ) { +- bdb_cache_return_entry_r(bdb, e, &lock); +- } +- send_ldap_result( op, rs ); +- return 1; +- } +- +- /* compute it anyway; root does not use it */ +- stoptime = op->o_time + op->ors_tlimit; +- +- /* need normalized dn below */ +- ber_dupbv( &realbase, &e->e_nname ); +- +- /* Copy info to base, must free entry before accessing the database +- * in search_candidates, to avoid deadlocks. +- */ +- base.e_private = e->e_private; +- base.e_nname = realbase; +- base.e_id = e->e_id; +- +-#ifdef SLAP_ZONE_ALLOC +- slap_zn_runlock(bdb->bi_cache.c_zctx, e); +-#endif +- if ( e != e_root ) { +- bdb_cache_return_entry_r(bdb, e, &lock); +- } +- e = NULL; +- +- /* select candidates */ +- if ( op->oq_search.rs_scope == LDAP_SCOPE_BASE ) { +- rs->sr_err = base_candidate( op->o_bd, &base, candidates ); +- +- } else { +-cand_retry: +- BDB_IDL_ZERO( candidates ); +- BDB_IDL_ZERO( scopes ); +- rs->sr_err = search_candidates( op, rs, &base, +- ltid, candidates, scopes ); +- if ( rs->sr_err == DB_LOCK_DEADLOCK ) { +- if ( !opinfo ) { +- ltid->flags &= ~TXN_DEADLOCK; +- goto cand_retry; +- } +- opinfo->boi_err = rs->sr_err; +- send_ldap_error( op, rs, LDAP_BUSY, "ldap server busy" ); +- return LDAP_BUSY; +- } +- } +- +- /* start cursor at beginning of candidates. +- */ +- cursor = 0; +- +- if ( candidates[0] == 0 ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_search) ": no candidates\n", +- 0, 0, 0 ); +- +- goto nochange; +- } +- +- /* if not root and candidates exceed to-be-checked entries, abort */ +- if ( op->ors_limit /* isroot == FALSE */ && +- op->ors_limit->lms_s_unchecked != -1 && +- BDB_IDL_N(candidates) > (unsigned) op->ors_limit->lms_s_unchecked ) +- { +- rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; +- send_ldap_result( op, rs ); +- rs->sr_err = LDAP_SUCCESS; +- goto done; +- } +- +- if ( op->ors_limit == NULL /* isroot == TRUE */ || +- !op->ors_limit->lms_s_pr_hide ) +- { +- tentries = BDB_IDL_N(candidates); +- } +- +- if ( get_pagedresults( op ) > SLAP_CONTROL_IGNORED ) { +- PagedResultsState *ps = op->o_pagedresults_state; +- /* deferred cookie parsing */ +- rs->sr_err = parse_paged_cookie( op, rs ); +- if ( rs->sr_err != LDAP_SUCCESS ) { +- send_ldap_result( op, rs ); +- goto done; +- } +- +- cursor = (ID) ps->ps_cookie; +- if ( cursor && ps->ps_size == 0 ) { +- rs->sr_err = LDAP_SUCCESS; +- rs->sr_text = "search abandoned by pagedResult size=0"; +- send_ldap_result( op, rs ); +- goto done; +- } +- id = bdb_idl_first( candidates, &cursor ); +- if ( id == NOID ) { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_search) +- ": no paged results candidates\n", +- 0, 0, 0 ); +- send_paged_response( op, rs, &lastid, 0 ); +- +- rs->sr_err = LDAP_OTHER; +- goto done; +- } +- nentries = ps->ps_count; +- if ( id == (ID)ps->ps_cookie ) +- id = bdb_idl_next( candidates, &cursor ); +- goto loop_begin; +- } +- +- for ( id = bdb_idl_first( candidates, &cursor ); +- id != NOID ; id = bdb_idl_next( candidates, &cursor ) ) +- { +- int scopeok; +- +-loop_begin: +- +- /* check for abandon */ +- if ( op->o_abandon ) { +- rs->sr_err = SLAPD_ABANDON; +- send_ldap_result( op, rs ); +- goto done; +- } +- +- /* mostly needed by internal searches, +- * e.g. related to syncrepl, for whom +- * abandon does not get set... */ +- if ( slapd_shutdown ) { +- rs->sr_err = LDAP_UNAVAILABLE; +- send_ldap_disconnect( op, rs ); +- goto done; +- } +- +- /* check time limit */ +- if ( op->ors_tlimit != SLAP_NO_LIMIT +- && slap_get_time() > stoptime ) +- { +- rs->sr_err = LDAP_TIMELIMIT_EXCEEDED; +- rs->sr_ref = rs->sr_v2ref; +- send_ldap_result( op, rs ); +- rs->sr_err = LDAP_SUCCESS; +- goto done; +- } +- +- /* If we inspect more entries than will +- * fit into the entry cache, stop caching +- * any subsequent entries +- */ +- nentries++; +- if ( nentries > bdb->bi_cache.c_maxsize && !idflag ) { +- idflag = ID_NOCACHE; +- } +- +-fetch_entry_retry: +- /* get the entry with reader lock */ +- ei = NULL; +- rs->sr_err = bdb_cache_find_id( op, ltid, +- id, &ei, idflag, &lock ); +- +- if (rs->sr_err == LDAP_BUSY) { +- rs->sr_text = "ldap server busy"; +- send_ldap_result( op, rs ); +- goto done; +- +- } else if ( rs->sr_err == DB_LOCK_DEADLOCK ) { +- if ( !opinfo ) { +- ltid->flags &= ~TXN_DEADLOCK; +- goto fetch_entry_retry; +- } +-txnfail: +- opinfo->boi_err = rs->sr_err; +- send_ldap_error( op, rs, LDAP_BUSY, "ldap server busy" ); +- goto done; +- +- } else if ( rs->sr_err == DB_LOCK_NOTGRANTED ) +- { +- goto fetch_entry_retry; +- } else if ( rs->sr_err == LDAP_OTHER ) { +- rs->sr_text = "internal error"; +- send_ldap_result( op, rs ); +- goto done; +- } +- +- if ( ei && rs->sr_err == LDAP_SUCCESS ) { +- e = ei->bei_e; +- } else { +- e = NULL; +- } +- +- if ( e == NULL ) { +- if( !BDB_IDL_IS_RANGE(candidates) ) { +- /* only complain for non-range IDLs */ +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_search) +- ": candidate %ld not found\n", +- (long) id, 0, 0 ); +- } else { +- /* get the next ID from the DB */ +-id_retry: +- rs->sr_err = bdb_get_nextid( bdb, ltid, &cursor ); +- if ( rs->sr_err == DB_NOTFOUND ) { +- break; +- } else if ( rs->sr_err == DB_LOCK_DEADLOCK ) { +- if ( opinfo ) +- goto txnfail; +- ltid->flags &= ~TXN_DEADLOCK; +- goto id_retry; +- } else if ( rs->sr_err == DB_LOCK_NOTGRANTED ) { +- goto id_retry; +- } +- if ( rs->sr_err ) { +- rs->sr_err = LDAP_OTHER; +- rs->sr_text = "internal error in get_nextid"; +- send_ldap_result( op, rs ); +- goto done; +- } +- cursor--; +- } +- +- goto loop_continue; +- } +- +- if ( is_entry_subentry( e ) ) { +- if( op->oq_search.rs_scope != LDAP_SCOPE_BASE ) { +- if(!get_subentries_visibility( op )) { +- /* only subentries are visible */ +- goto loop_continue; +- } +- +- } else if ( get_subentries( op ) && +- !get_subentries_visibility( op )) +- { +- /* only subentries are visible */ +- goto loop_continue; +- } +- +- } else if ( get_subentries_visibility( op )) { +- /* only subentries are visible */ +- goto loop_continue; +- } +- +- /* Does this candidate actually satisfy the search scope? +- * +- * Note that we don't lock access to the bei_parent pointer. +- * Since only leaf nodes can be deleted, the parent of any +- * node will always be a valid node. Also since we have +- * a Read lock on the data, it cannot be renamed out of the +- * scope while we are looking at it, and unless we're using +- * BDB_HIER, its parents cannot be moved either. +- */ +- scopeok = 0; +- switch( op->ors_scope ) { +- case LDAP_SCOPE_BASE: +- /* This is always true, yes? */ +- if ( id == base.e_id ) scopeok = 1; +- break; +- +- case LDAP_SCOPE_ONELEVEL: +- if ( ei->bei_parent->bei_id == base.e_id ) scopeok = 1; +- break; +- +-#ifdef LDAP_SCOPE_CHILDREN +- case LDAP_SCOPE_CHILDREN: +- if ( id == base.e_id ) break; +- /* Fall-thru */ +-#endif +- case LDAP_SCOPE_SUBTREE: { +- EntryInfo *tmp; +- for ( tmp = BEI(e); tmp; tmp = tmp->bei_parent ) { +- if ( tmp->bei_id == base.e_id ) { +- scopeok = 1; +- break; +- } +- } +- } break; +- } +- +- /* aliases were already dereferenced in candidate list */ +- if ( op->ors_deref & LDAP_DEREF_SEARCHING ) { +- /* but if the search base is an alias, and we didn't +- * deref it when finding, return it. +- */ +- if ( is_entry_alias(e) && +- ((op->ors_deref & LDAP_DEREF_FINDING) || +- !bvmatch(&e->e_nname, &op->o_req_ndn))) +- { +- goto loop_continue; +- } +- +- /* scopes is only non-empty for onelevel or subtree */ +- if ( !scopeok && BDB_IDL_N(scopes) ) { +- unsigned x; +- if ( op->ors_scope == LDAP_SCOPE_ONELEVEL ) { +- x = bdb_idl_search( scopes, e->e_id ); +- if ( scopes[x] == e->e_id ) scopeok = 1; +- } else { +- /* subtree, walk up the tree */ +- EntryInfo *tmp = BEI(e); +- for (;tmp->bei_parent; tmp=tmp->bei_parent) { +- x = bdb_idl_search( scopes, tmp->bei_id ); +- if ( scopes[x] == tmp->bei_id ) { +- scopeok = 1; +- break; +- } +- } +- } +- } +- } +- +- /* Not in scope, ignore it */ +- if ( !scopeok ) +- { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_search) +- ": %ld scope not okay\n", +- (long) id, 0, 0 ); +- goto loop_continue; +- } +- +- /* +- * 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 && op->oq_search.rs_scope != LDAP_SCOPE_BASE +- && is_entry_referral( e ) ) +- { +- struct bdb_op_info bois; +- struct bdb_lock_info blis; +- BerVarray erefs = get_entry_referrals( op, e ); +- rs->sr_ref = referral_rewrite( erefs, &e->e_name, NULL, +- op->oq_search.rs_scope == LDAP_SCOPE_ONELEVEL +- ? LDAP_SCOPE_BASE : LDAP_SCOPE_SUBTREE ); +- +- /* Must set lockinfo so that entry_release will work */ +- if (!opinfo) { +- bois.boi_oe.oe_key = bdb; +- bois.boi_txn = NULL; +- bois.boi_err = 0; +- bois.boi_acl_cache = op->o_do_not_cache; +- bois.boi_flag = BOI_DONTFREE; +- bois.boi_locks = &blis; +- blis.bli_next = NULL; +- LDAP_SLIST_INSERT_HEAD( &op->o_extra, &bois.boi_oe, +- oe_next ); +- } else { +- blis.bli_next = opinfo->boi_locks; +- opinfo->boi_locks = &blis; +- } +- blis.bli_id = e->e_id; +- blis.bli_lock = lock; +- blis.bli_flag = BLI_DONTFREE; +- +- rs->sr_entry = e; +- rs->sr_flags = REP_ENTRY_MUSTRELEASE; +- +- send_search_reference( op, rs ); +- +- if ( blis.bli_flag ) { +-#ifdef SLAP_ZONE_ALLOC +- slap_zn_runlock(bdb->bi_cache.c_zctx, e); +-#endif +- bdb_cache_return_entry_r(bdb, e, &lock); +- if ( opinfo ) { +- opinfo->boi_locks = blis.bli_next; +- } else { +- LDAP_SLIST_REMOVE( &op->o_extra, &bois.boi_oe, +- OpExtra, oe_next ); +- } +- } +- rs->sr_entry = NULL; +- e = NULL; +- +- ber_bvarray_free( rs->sr_ref ); +- ber_bvarray_free( erefs ); +- rs->sr_ref = NULL; +- +- goto loop_continue; +- } +- +- if ( !manageDSAit && is_entry_glue( e )) { +- goto loop_continue; +- } +- +- /* if it matches the filter and scope, send it */ +- rs->sr_err = test_filter( op, e, op->oq_search.rs_filter ); +- +- if ( rs->sr_err == LDAP_COMPARE_TRUE ) { +- /* check size limit */ +- if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) { +- if ( rs->sr_nentries >= ((PagedResultsState *)op->o_pagedresults_state)->ps_size ) { +-#ifdef SLAP_ZONE_ALLOC +- slap_zn_runlock(bdb->bi_cache.c_zctx, e); +-#endif +- bdb_cache_return_entry_r( bdb, e, &lock ); +- e = NULL; +- send_paged_response( op, rs, &lastid, tentries ); +- goto done; +- } +- lastid = id; +- } +- +- if (e) { +- struct bdb_op_info bois; +- struct bdb_lock_info blis; +- +- /* Must set lockinfo so that entry_release will work */ +- if (!opinfo) { +- bois.boi_oe.oe_key = bdb; +- bois.boi_txn = NULL; +- bois.boi_err = 0; +- bois.boi_acl_cache = op->o_do_not_cache; +- bois.boi_flag = BOI_DONTFREE; +- bois.boi_locks = &blis; +- blis.bli_next = NULL; +- LDAP_SLIST_INSERT_HEAD( &op->o_extra, &bois.boi_oe, +- oe_next ); +- } else { +- blis.bli_next = opinfo->boi_locks; +- opinfo->boi_locks = &blis; +- } +- blis.bli_id = e->e_id; +- blis.bli_lock = lock; +- blis.bli_flag = BLI_DONTFREE; +- +- /* safe default */ +- rs->sr_attrs = op->oq_search.rs_attrs; +- rs->sr_operational_attrs = NULL; +- rs->sr_ctrls = NULL; +- rs->sr_entry = e; +- RS_ASSERT( e->e_private != NULL ); +- rs->sr_flags = REP_ENTRY_MUSTRELEASE; +- rs->sr_err = LDAP_SUCCESS; +- rs->sr_err = send_search_entry( op, rs ); +- rs->sr_attrs = NULL; +- rs->sr_entry = NULL; +- +- /* send_search_entry will usually free it. +- * an overlay might leave its own copy here; +- * bli_flag will be 0 if lock was already released. +- */ +- if ( blis.bli_flag ) { +-#ifdef SLAP_ZONE_ALLOC +- slap_zn_runlock(bdb->bi_cache.c_zctx, e); +-#endif +- bdb_cache_return_entry_r(bdb, e, &lock); +- if ( opinfo ) { +- opinfo->boi_locks = blis.bli_next; +- } else { +- LDAP_SLIST_REMOVE( &op->o_extra, &bois.boi_oe, +- OpExtra, oe_next ); +- } +- } +- e = NULL; +- +- switch ( rs->sr_err ) { +- case LDAP_SUCCESS: /* entry sent ok */ +- break; +- default: /* entry not sent */ +- break; +- case LDAP_BUSY: +- send_ldap_result( op, rs ); +- goto done; +- case LDAP_UNAVAILABLE: +- case LDAP_SIZELIMIT_EXCEEDED: +- if ( rs->sr_err == LDAP_SIZELIMIT_EXCEEDED ) { +- rs->sr_ref = rs->sr_v2ref; +- send_ldap_result( op, rs ); +- rs->sr_err = LDAP_SUCCESS; +- +- } else { +- rs->sr_err = LDAP_OTHER; +- } +- goto done; +- } +- } +- +- } else { +- Debug( LDAP_DEBUG_TRACE, +- LDAP_XSTRING(bdb_search) +- ": %ld does not match filter\n", +- (long) id, 0, 0 ); +- } +- +-loop_continue: +- if( e != NULL ) { +- /* free reader lock */ +-#ifdef SLAP_ZONE_ALLOC +- slap_zn_runlock(bdb->bi_cache.c_zctx, e); +-#endif +- bdb_cache_return_entry_r( bdb, e , &lock ); +- RS_ASSERT( rs->sr_entry == NULL ); +- e = NULL; +- rs->sr_entry = NULL; +- } +- } +- +-nochange: +- rs->sr_ctrls = NULL; +- rs->sr_ref = rs->sr_v2ref; +- rs->sr_err = (rs->sr_v2ref == NULL) ? LDAP_SUCCESS : LDAP_REFERRAL; +- rs->sr_rspoid = NULL; +- if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) { +- send_paged_response( op, rs, NULL, 0 ); +- } else { +- send_ldap_result( op, rs ); +- } +- +- rs->sr_err = LDAP_SUCCESS; +- +-done: +- if( rs->sr_v2ref ) { +- ber_bvarray_free( rs->sr_v2ref ); +- rs->sr_v2ref = NULL; +- } +- if( realbase.bv_val ) ch_free( realbase.bv_val ); +- +- return rs->sr_err; +-} +- +- +-static int base_candidate( +- BackendDB *be, +- Entry *e, +- ID *ids ) +-{ +- Debug(LDAP_DEBUG_ARGS, "base_candidates: base: \"%s\" (0x%08lx)\n", +- e->e_nname.bv_val, (long) e->e_id, 0); +- +- ids[0] = 1; +- ids[1] = e->e_id; +- return 0; +-} +- +-/* Look for "objectClass Present" in this filter. +- * Also count depth of filter tree while we're at it. +- */ +-static int oc_filter( +- Filter *f, +- int cur, +- int *max ) +-{ +- int rc = 0; +- +- assert( f != NULL ); +- +- if( cur > *max ) *max = cur; +- +- switch( f->f_choice ) { +- case LDAP_FILTER_PRESENT: +- if (f->f_desc == slap_schema.si_ad_objectClass) { +- rc = 1; +- } +- break; +- +- case LDAP_FILTER_AND: +- case LDAP_FILTER_OR: +- cur++; +- for ( f=f->f_and; f; f=f->f_next ) { +- (void) oc_filter(f, cur, max); +- } +- break; +- +- default: +- break; +- } +- return rc; +-} +- +-static void search_stack_free( void *key, void *data ) +-{ +- ber_memfree_x(data, NULL); +-} +- +-static void *search_stack( Operation *op ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- void *ret = NULL; +- +- if ( op->o_threadctx ) { +- ldap_pvt_thread_pool_getkey( op->o_threadctx, (void *)search_stack, +- &ret, NULL ); +- } else { +- ret = bdb->bi_search_stack; +- } +- +- if ( !ret ) { +- ret = ch_malloc( bdb->bi_search_stack_depth * BDB_IDL_UM_SIZE +- * sizeof( ID ) ); +- if ( op->o_threadctx ) { +- ldap_pvt_thread_pool_setkey( op->o_threadctx, (void *)search_stack, +- ret, search_stack_free, NULL, NULL ); +- } else { +- bdb->bi_search_stack = ret; +- } +- } +- return ret; +-} +- +-static int search_candidates( +- Operation *op, +- SlapReply *rs, +- Entry *e, +- DB_TXN *txn, +- ID *ids, +- ID *scopes ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- int rc, depth = 1; +- Filter f, rf, xf, nf; +- ID *stack; +- AttributeAssertion aa_ref = ATTRIBUTEASSERTION_INIT; +- Filter sf; +- AttributeAssertion aa_subentry = ATTRIBUTEASSERTION_INIT; +- +- /* +- * This routine takes as input a filter (user-filter) +- * and rewrites it as follows: +- * (&(scope=DN)[(objectClass=subentry)] +- * (|[(objectClass=referral)(objectClass=alias)](user-filter)) +- */ +- +- Debug(LDAP_DEBUG_TRACE, +- "search_candidates: base=\"%s\" (0x%08lx) scope=%d\n", +- e->e_nname.bv_val, (long) e->e_id, op->oq_search.rs_scope ); +- +- xf.f_or = op->oq_search.rs_filter; +- xf.f_choice = LDAP_FILTER_OR; +- xf.f_next = NULL; +- +- /* If the user's filter uses objectClass=*, +- * these clauses are redundant. +- */ +- if (!oc_filter(op->oq_search.rs_filter, 1, &depth) +- && !get_subentries_visibility(op)) { +- if( !get_manageDSAit(op) && !get_domainScope(op) ) { +- /* match referral objects */ +- struct berval bv_ref = BER_BVC( "referral" ); +- rf.f_choice = LDAP_FILTER_EQUALITY; +- rf.f_ava = &aa_ref; +- rf.f_av_desc = slap_schema.si_ad_objectClass; +- rf.f_av_value = bv_ref; +- rf.f_next = xf.f_or; +- xf.f_or = &rf; +- depth++; +- } +- } +- +- f.f_next = NULL; +- f.f_choice = LDAP_FILTER_AND; +- f.f_and = &nf; +- /* Dummy; we compute scope separately now */ +- nf.f_choice = SLAPD_FILTER_COMPUTED; +- nf.f_result = LDAP_SUCCESS; +- nf.f_next = ( xf.f_or == op->oq_search.rs_filter ) +- ? op->oq_search.rs_filter : &xf ; +- /* Filter depth increased again, adding dummy clause */ +- depth++; +- +- if( get_subentries_visibility( op ) ) { +- struct berval bv_subentry = BER_BVC( "subentry" ); +- sf.f_choice = LDAP_FILTER_EQUALITY; +- sf.f_ava = &aa_subentry; +- sf.f_av_desc = slap_schema.si_ad_objectClass; +- sf.f_av_value = bv_subentry; +- sf.f_next = nf.f_next; +- nf.f_next = &sf; +- } +- +- /* Allocate IDL stack, plus 1 more for former tmp */ +- if ( depth+1 > bdb->bi_search_stack_depth ) { +- stack = ch_malloc( (depth + 1) * BDB_IDL_UM_SIZE * sizeof( ID ) ); +- } else { +- stack = search_stack( op ); +- } +- +- if( op->ors_deref & LDAP_DEREF_SEARCHING ) { +- rc = search_aliases( op, rs, e, txn, ids, scopes, stack ); +- if ( BDB_IDL_IS_ZERO( ids ) && rc == LDAP_SUCCESS ) +- rc = bdb_dn2idl( op, txn, &e->e_nname, BEI(e), ids, stack ); +- } else { +- rc = bdb_dn2idl( op, txn, &e->e_nname, BEI(e), ids, stack ); +- } +- +- if ( rc == LDAP_SUCCESS ) { +- rc = bdb_filter_candidates( op, txn, &f, ids, +- stack, stack+BDB_IDL_UM_SIZE ); +- } +- +- if ( depth+1 > bdb->bi_search_stack_depth ) { +- ch_free( stack ); +- } +- +- if( rc ) { +- Debug(LDAP_DEBUG_TRACE, +- "bdb_search_candidates: failed (rc=%d)\n", +- rc, NULL, NULL ); +- +- } else { +- Debug(LDAP_DEBUG_TRACE, +- "bdb_search_candidates: id=%ld first=%ld last=%ld\n", +- (long) ids[0], +- (long) BDB_IDL_FIRST(ids), +- (long) BDB_IDL_LAST(ids) ); +- } +- +- return rc; +-} +- +-static int +-parse_paged_cookie( Operation *op, SlapReply *rs ) +-{ +- int rc = LDAP_SUCCESS; +- PagedResultsState *ps = op->o_pagedresults_state; +- +- /* this function must be invoked only if the pagedResults +- * control has been detected, parsed and partially checked +- * by the frontend */ +- assert( get_pagedresults( op ) > SLAP_CONTROL_IGNORED ); +- +- /* cookie decoding/checks deferred to backend... */ +- if ( ps->ps_cookieval.bv_len ) { +- PagedResultsCookie reqcookie; +- if( ps->ps_cookieval.bv_len != sizeof( reqcookie ) ) { +- /* bad cookie */ +- rs->sr_text = "paged results cookie is invalid"; +- rc = LDAP_PROTOCOL_ERROR; +- goto done; +- } +- +- AC_MEMCPY( &reqcookie, ps->ps_cookieval.bv_val, sizeof( reqcookie )); +- +- if ( reqcookie > ps->ps_cookie ) { +- /* bad cookie */ +- rs->sr_text = "paged results cookie is invalid"; +- rc = LDAP_PROTOCOL_ERROR; +- goto done; +- +- } else if ( reqcookie < ps->ps_cookie ) { +- rs->sr_text = "paged results cookie is invalid or old"; +- rc = LDAP_UNWILLING_TO_PERFORM; +- goto done; +- } +- +- } else { +- /* we're going to use ps_cookie */ +- op->o_conn->c_pagedresults_state.ps_cookie = 0; +- } +- +-done:; +- +- return rc; +-} +- +-static void +-send_paged_response( +- Operation *op, +- SlapReply *rs, +- ID *lastid, +- int tentries ) +-{ +- LDAPControl *ctrls[2]; +- BerElementBuffer berbuf; +- BerElement *ber = (BerElement *)&berbuf; +- PagedResultsCookie respcookie; +- struct berval cookie; +- +- Debug(LDAP_DEBUG_ARGS, +- "send_paged_response: lastid=0x%08lx nentries=%d\n", +- lastid ? *lastid : 0, rs->sr_nentries, NULL ); +- +- ctrls[1] = NULL; +- +- ber_init2( ber, NULL, LBER_USE_DER ); +- +- if ( lastid ) { +- respcookie = ( PagedResultsCookie )(*lastid); +- cookie.bv_len = sizeof( respcookie ); +- cookie.bv_val = (char *)&respcookie; +- +- } else { +- respcookie = ( PagedResultsCookie )0; +- BER_BVSTR( &cookie, "" ); +- } +- +- op->o_conn->c_pagedresults_state.ps_cookie = respcookie; +- op->o_conn->c_pagedresults_state.ps_count = +- ((PagedResultsState *)op->o_pagedresults_state)->ps_count + +- rs->sr_nentries; +- +- /* return size of 0 -- no estimate */ +- ber_printf( ber, "{iO}", 0, &cookie ); +- +- ctrls[0] = op->o_tmpalloc( sizeof(LDAPControl), op->o_tmpmemctx ); +- if ( ber_flatten2( ber, &ctrls[0]->ldctl_value, 0 ) == -1 ) { +- goto done; +- } +- +- ctrls[0]->ldctl_oid = LDAP_CONTROL_PAGEDRESULTS; +- ctrls[0]->ldctl_iscritical = 0; +- +- slap_add_ctrls( op, rs, ctrls ); +- rs->sr_err = LDAP_SUCCESS; +- send_ldap_result( op, rs ); +- +-done: +- (void) ber_free_buf( ber ); +-} +diff --git a/servers/slapd/back-bdb/tools.c b/servers/slapd/back-bdb/tools.c +deleted file mode 100644 +index 1882ef2..0000000 +--- a/servers/slapd/back-bdb/tools.c ++++ /dev/null +@@ -1,1327 +0,0 @@ +-/* tools.c - tools for slap tools */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +-#include +-#include +- +-#define AVL_INTERNAL +-#include "back-bdb.h" +-#include "idl.h" +- +-static DBC *cursor = NULL; +-static DBT key, data; +-static EntryHeader eh; +-static ID nid, previd = NOID; +-static char ehbuf[16]; +- +-typedef struct dn_id { +- ID id; +- struct berval dn; +-} dn_id; +- +-#define HOLE_SIZE 4096 +-static dn_id hbuf[HOLE_SIZE], *holes = hbuf; +-static unsigned nhmax = HOLE_SIZE; +-static unsigned nholes; +- +-static int index_nattrs; +- +-static struct berval *tool_base; +-static int tool_scope; +-static Filter *tool_filter; +-static Entry *tool_next_entry; +- +-#ifdef BDB_TOOL_IDL_CACHING +-#define bdb_tool_idl_cmp BDB_SYMBOL(tool_idl_cmp) +-#define bdb_tool_idl_flush_one BDB_SYMBOL(tool_idl_flush_one) +-#define bdb_tool_idl_flush BDB_SYMBOL(tool_idl_flush) +- +-static int bdb_tool_idl_flush( BackendDB *be ); +- +-#define IDBLOCK 1024 +- +-typedef struct bdb_tool_idl_cache_entry { +- struct bdb_tool_idl_cache_entry *next; +- ID ids[IDBLOCK]; +-} bdb_tool_idl_cache_entry; +- +-typedef struct bdb_tool_idl_cache { +- struct berval kstr; +- bdb_tool_idl_cache_entry *head, *tail; +- ID first, last; +- int count; +-} bdb_tool_idl_cache; +- +-static bdb_tool_idl_cache_entry *bdb_tool_idl_free_list; +-#endif /* BDB_TOOL_IDL_CACHING */ +- +-static ID bdb_tool_ix_id; +-static Operation *bdb_tool_ix_op; +-static int *bdb_tool_index_threads, bdb_tool_index_tcount; +-static void *bdb_tool_index_rec; +-static struct bdb_info *bdb_tool_info; +-static ldap_pvt_thread_mutex_t bdb_tool_index_mutex; +-static ldap_pvt_thread_cond_t bdb_tool_index_cond_main; +-static ldap_pvt_thread_cond_t bdb_tool_index_cond_work; +- +-#if DB_VERSION_FULL >= 0x04060000 +-#define USE_TRICKLE 1 +-#else +-/* Seems to slow things down too much in BDB 4.5 */ +-#undef USE_TRICKLE +-#endif +- +-#ifdef USE_TRICKLE +-static ldap_pvt_thread_mutex_t bdb_tool_trickle_mutex; +-static ldap_pvt_thread_cond_t bdb_tool_trickle_cond; +-static ldap_pvt_thread_cond_t bdb_tool_trickle_cond_end; +- +-static void * bdb_tool_trickle_task( void *ctx, void *ptr ); +-static int bdb_tool_trickle_active; +-#endif +- +-static void * bdb_tool_index_task( void *ctx, void *ptr ); +- +-static int +-bdb_tool_entry_get_int( BackendDB *be, ID id, Entry **ep ); +- +-static int bdb_tool_threads; +- +-int bdb_tool_entry_open( +- BackendDB *be, int mode ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) be->be_private; +- +- /* initialize key and data thangs */ +- DBTzero( &key ); +- DBTzero( &data ); +- key.flags = DB_DBT_USERMEM; +- key.data = &nid; +- key.size = key.ulen = sizeof( nid ); +- data.flags = DB_DBT_USERMEM; +- +- if (cursor == NULL) { +- int rc = bdb->bi_id2entry->bdi_db->cursor( +- bdb->bi_id2entry->bdi_db, bdb->bi_cache.c_txn, &cursor, +- bdb->bi_db_opflags ); +- if( rc != 0 ) { +- return -1; +- } +- } +- +- /* Set up for threaded slapindex */ +- if (( slapMode & (SLAP_TOOL_QUICK|SLAP_TOOL_READONLY)) == SLAP_TOOL_QUICK ) { +- if ( !bdb_tool_info ) { +-#ifdef USE_TRICKLE +- ldap_pvt_thread_mutex_init( &bdb_tool_trickle_mutex ); +- ldap_pvt_thread_cond_init( &bdb_tool_trickle_cond ); +- ldap_pvt_thread_cond_init( &bdb_tool_trickle_cond_end ); +- ldap_pvt_thread_pool_submit( &connection_pool, bdb_tool_trickle_task, bdb->bi_dbenv ); +-#endif +- +- ldap_pvt_thread_mutex_init( &bdb_tool_index_mutex ); +- ldap_pvt_thread_cond_init( &bdb_tool_index_cond_main ); +- ldap_pvt_thread_cond_init( &bdb_tool_index_cond_work ); +- if ( bdb->bi_nattrs ) { +- int i; +- bdb_tool_threads = slap_tool_thread_max - 1; +- if ( bdb_tool_threads > 1 ) { +- bdb_tool_index_threads = ch_malloc( bdb_tool_threads * sizeof( int )); +- bdb_tool_index_rec = ch_malloc( bdb->bi_nattrs * sizeof( IndexRec )); +- bdb_tool_index_tcount = bdb_tool_threads - 1; +- for (i=1; i 1 ) { +- ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex ); +- +- /* There might still be some threads starting */ +- while ( bdb_tool_index_tcount > 0 ) { +- ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main, +- &bdb_tool_index_mutex ); +- } +- +- bdb_tool_index_tcount = bdb_tool_threads - 1; +- ldap_pvt_thread_cond_broadcast( &bdb_tool_index_cond_work ); +- +- /* Make sure all threads are stopped */ +- while ( bdb_tool_index_tcount > 0 ) { +- ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main, +- &bdb_tool_index_mutex ); +- } +- ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex ); +- +- ch_free( bdb_tool_index_threads ); +- ch_free( bdb_tool_index_rec ); +- bdb_tool_index_tcount = bdb_tool_threads - 1; +- } +- bdb_tool_info = NULL; +- slapd_shutdown = 0; +- } +- +- if( eh.bv.bv_val ) { +- ch_free( eh.bv.bv_val ); +- eh.bv.bv_val = NULL; +- } +- +- if( cursor ) { +- cursor->c_close( cursor ); +- cursor = NULL; +- } +- +-#ifdef BDB_TOOL_IDL_CACHING +- bdb_tool_idl_flush( be ); +-#endif +- +- if( nholes ) { +- unsigned i; +- fprintf( stderr, "Error, entries missing!\n"); +- for (i=0; ibe_private; +- assert( bdb != NULL ); +- +-next:; +- /* Get the header */ +- data.ulen = data.dlen = sizeof( ehbuf ); +- data.data = ehbuf; +- data.flags |= DB_DBT_PARTIAL; +- rc = cursor->c_get( cursor, &key, &data, DB_NEXT ); +- +- if( rc ) { +- /* If we're doing linear indexing and there are more attrs to +- * index, and we're at the end of the database, start over. +- */ +- if ( index_nattrs && rc == DB_NOTFOUND ) { +- /* optional - do a checkpoint here? */ +- bdb_attr_info_free( bdb->bi_attrs[0] ); +- bdb->bi_attrs[0] = bdb->bi_attrs[index_nattrs]; +- index_nattrs--; +- rc = cursor->c_get( cursor, &key, &data, DB_FIRST ); +- if ( rc ) { +- return NOID; +- } +- } else { +- return NOID; +- } +- } +- +- BDB_DISK2ID( key.data, &id ); +- previd = id; +- +- if ( tool_filter || tool_base ) { +- static Operation op = {0}; +- static Opheader ohdr = {0}; +- +- op.o_hdr = &ohdr; +- op.o_bd = be; +- op.o_tmpmemctx = NULL; +- op.o_tmpmfuncs = &ch_mfuncs; +- +- if ( tool_next_entry ) { +- bdb_entry_release( &op, tool_next_entry, 0 ); +- tool_next_entry = NULL; +- } +- +- rc = bdb_tool_entry_get_int( be, id, &tool_next_entry ); +- if ( rc == LDAP_NO_SUCH_OBJECT ) { +- goto next; +- } +- +- assert( tool_next_entry != NULL ); +- +-#ifdef BDB_HIER +- /* TODO: needed until BDB_HIER is handled accordingly +- * in bdb_tool_entry_get_int() */ +- if ( tool_base && !dnIsSuffixScope( &tool_next_entry->e_nname, tool_base, tool_scope ) ) +- { +- bdb_entry_release( &op, tool_next_entry, 0 ); +- tool_next_entry = NULL; +- goto next; +- } +-#endif +- +- if ( tool_filter && test_filter( NULL, tool_next_entry, tool_filter ) != LDAP_COMPARE_TRUE ) +- { +- bdb_entry_release( &op, tool_next_entry, 0 ); +- tool_next_entry = NULL; +- goto next; +- } +- } +- +- return id; +-} +- +-ID bdb_tool_dn2id_get( +- Backend *be, +- struct berval *dn +-) +-{ +- Operation op = {0}; +- Opheader ohdr = {0}; +- EntryInfo *ei = NULL; +- int rc; +- +- if ( BER_BVISEMPTY(dn) ) +- return 0; +- +- op.o_hdr = &ohdr; +- op.o_bd = be; +- op.o_tmpmemctx = NULL; +- op.o_tmpmfuncs = &ch_mfuncs; +- +- rc = bdb_cache_find_ndn( &op, 0, dn, &ei ); +- if ( ei ) bdb_cache_entryinfo_unlock( ei ); +- if ( rc == DB_NOTFOUND ) +- return NOID; +- +- return ei->bei_id; +-} +- +-static int +-bdb_tool_entry_get_int( BackendDB *be, ID id, Entry **ep ) +-{ +- Entry *e = NULL; +- char *dptr; +- int rc, eoff; +- +- assert( be != NULL ); +- assert( slapMode & SLAP_TOOL_MODE ); +- +- if ( ( tool_filter || tool_base ) && id == previd && tool_next_entry != NULL ) { +- *ep = tool_next_entry; +- tool_next_entry = NULL; +- return LDAP_SUCCESS; +- } +- +- if ( id != previd ) { +- data.ulen = data.dlen = sizeof( ehbuf ); +- data.data = ehbuf; +- data.flags |= DB_DBT_PARTIAL; +- +- BDB_ID2DISK( id, &nid ); +- rc = cursor->c_get( cursor, &key, &data, DB_SET ); +- if ( rc ) { +- rc = LDAP_OTHER; +- goto done; +- } +- } +- +- /* Get the header */ +- dptr = eh.bv.bv_val; +- eh.bv.bv_val = ehbuf; +- eh.bv.bv_len = data.size; +- rc = entry_header( &eh ); +- eoff = eh.data - eh.bv.bv_val; +- eh.bv.bv_val = dptr; +- if ( rc ) { +- rc = LDAP_OTHER; +- goto done; +- } +- +- /* Get the size */ +- data.flags &= ~DB_DBT_PARTIAL; +- data.ulen = 0; +- rc = cursor->c_get( cursor, &key, &data, DB_CURRENT ); +- if ( rc != DB_BUFFER_SMALL ) { +- rc = LDAP_OTHER; +- goto done; +- } +- +- /* Allocate a block and retrieve the data */ +- eh.bv.bv_len = eh.nvals * sizeof( struct berval ) + data.size; +- eh.bv.bv_val = ch_realloc( eh.bv.bv_val, eh.bv.bv_len ); +- eh.data = eh.bv.bv_val + eh.nvals * sizeof( struct berval ); +- data.data = eh.data; +- data.ulen = data.size; +- +- /* Skip past already parsed nattr/nvals */ +- eh.data += eoff; +- +- rc = cursor->c_get( cursor, &key, &data, DB_CURRENT ); +- if ( rc ) { +- rc = LDAP_OTHER; +- goto done; +- } +- +-#ifndef BDB_HIER +- /* TODO: handle BDB_HIER accordingly */ +- if ( tool_base != NULL ) { +- struct berval ndn; +- entry_decode_dn( &eh, NULL, &ndn ); +- +- if ( !dnIsSuffixScope( &ndn, tool_base, tool_scope ) ) { +- return LDAP_NO_SUCH_OBJECT; +- } +- } +-#endif +- +-#ifdef SLAP_ZONE_ALLOC +- /* FIXME: will add ctx later */ +- rc = entry_decode( &eh, &e, NULL ); +-#else +- rc = entry_decode( &eh, &e ); +-#endif +- +- if( rc == LDAP_SUCCESS ) { +- e->e_id = id; +-#ifdef BDB_HIER +- if ( slapMode & SLAP_TOOL_READONLY ) { +- struct bdb_info *bdb = (struct bdb_info *) be->be_private; +- EntryInfo *ei = NULL; +- Operation op = {0}; +- Opheader ohdr = {0}; +- +- op.o_hdr = &ohdr; +- op.o_bd = be; +- op.o_tmpmemctx = NULL; +- op.o_tmpmfuncs = &ch_mfuncs; +- +- rc = bdb_cache_find_parent( &op, bdb->bi_cache.c_txn, id, &ei ); +- if ( rc == LDAP_SUCCESS ) { +- bdb_cache_entryinfo_unlock( ei ); +- e->e_private = ei; +- ei->bei_e = e; +- bdb_fix_dn( e, 0 ); +- ei->bei_e = NULL; +- e->e_private = NULL; +- } +- } +-#endif +- } +-done: +- if ( e != NULL ) { +- *ep = e; +- } +- +- return rc; +-} +- +-Entry* +-bdb_tool_entry_get( BackendDB *be, ID id ) +-{ +- Entry *e = NULL; +- +- (void)bdb_tool_entry_get_int( be, id, &e ); +- return e; +-} +- +-static int bdb_tool_next_id( +- Operation *op, +- DB_TXN *tid, +- Entry *e, +- struct berval *text, +- int hole ) +-{ +- struct berval dn = e->e_name; +- struct berval ndn = e->e_nname; +- struct berval pdn, npdn; +- EntryInfo *ei = NULL, eidummy; +- int rc; +- +- if (ndn.bv_len == 0) { +- e->e_id = 0; +- return 0; +- } +- +- rc = bdb_cache_find_ndn( op, tid, &ndn, &ei ); +- if ( ei ) bdb_cache_entryinfo_unlock( ei ); +- if ( rc == DB_NOTFOUND ) { +- if ( !be_issuffix( op->o_bd, &ndn ) ) { +- ID eid = e->e_id; +- dnParent( &dn, &pdn ); +- dnParent( &ndn, &npdn ); +- e->e_name = pdn; +- e->e_nname = npdn; +- rc = bdb_tool_next_id( op, tid, e, text, 1 ); +- e->e_name = dn; +- e->e_nname = ndn; +- if ( rc ) { +- return rc; +- } +- /* If parent didn't exist, it was created just now +- * and its ID is now in e->e_id. Make sure the current +- * entry gets added under the new parent ID. +- */ +- if ( eid != e->e_id ) { +- eidummy.bei_id = e->e_id; +- ei = &eidummy; +- } +- } +- rc = bdb_next_id( op->o_bd, &e->e_id ); +- if ( rc ) { +- snprintf( text->bv_val, text->bv_len, +- "next_id failed: %s (%d)", +- db_strerror(rc), rc ); +- Debug( LDAP_DEBUG_ANY, +- "=> bdb_tool_next_id: %s\n", text->bv_val, 0, 0 ); +- return rc; +- } +- rc = bdb_dn2id_add( op, tid, ei, e ); +- if ( rc ) { +- snprintf( text->bv_val, text->bv_len, +- "dn2id_add failed: %s (%d)", +- db_strerror(rc), rc ); +- Debug( LDAP_DEBUG_ANY, +- "=> bdb_tool_next_id: %s\n", text->bv_val, 0, 0 ); +- } else if ( hole ) { +- if ( nholes == nhmax - 1 ) { +- if ( holes == hbuf ) { +- holes = ch_malloc( nhmax * sizeof(dn_id) * 2 ); +- AC_MEMCPY( holes, hbuf, sizeof(hbuf) ); +- } else { +- holes = ch_realloc( holes, nhmax * sizeof(dn_id) * 2 ); +- } +- nhmax *= 2; +- } +- ber_dupbv( &holes[nholes].dn, &ndn ); +- holes[nholes++].id = e->e_id; +- } +- } else if ( !hole ) { +- unsigned i, j; +- +- e->e_id = ei->bei_id; +- +- for ( i=0; ie_id ) { +- free(holes[i].dn.bv_val); +- for (j=i;j e->e_id ) { +- break; +- } +- } +- } +- return rc; +-} +- +-static int +-bdb_tool_index_add( +- Operation *op, +- DB_TXN *txn, +- Entry *e ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; +- +- if ( !bdb->bi_nattrs ) +- return 0; +- +- if ( bdb_tool_threads > 1 ) { +- IndexRec *ir; +- int i, rc; +- Attribute *a; +- +- ir = bdb_tool_index_rec; +- memset(ir, 0, bdb->bi_nattrs * sizeof( IndexRec )); +- +- for ( a = e->e_attrs; a != NULL; a = a->a_next ) { +- rc = bdb_index_recset( bdb, a, a->a_desc->ad_type, +- &a->a_desc->ad_tags, ir ); +- if ( rc ) +- return rc; +- } +- bdb_tool_ix_id = e->e_id; +- bdb_tool_ix_op = op; +- ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex ); +- /* Wait for all threads to be ready */ +- while ( bdb_tool_index_tcount > 0 ) { +- ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main, +- &bdb_tool_index_mutex ); +- } +- for ( i=1; ie_id, 0 ); +- if ( rc ) +- return rc; +- ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex ); +- for ( i=1; ibv_val != NULL ); +- assert( text->bv_val[0] == '\0' ); /* overconservative? */ +- +- Debug( LDAP_DEBUG_TRACE, "=> " LDAP_XSTRING(bdb_tool_entry_put) +- "( %ld, \"%s\" )\n", (long) e->e_id, e->e_dn, 0 ); +- +- bdb = (struct bdb_info *) be->be_private; +- +- if (! (slapMode & SLAP_TOOL_QUICK)) { +- rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &tid, +- bdb->bi_db_opflags ); +- if( rc != 0 ) { +- snprintf( text->bv_val, text->bv_len, +- "txn_begin failed: %s (%d)", +- db_strerror(rc), rc ); +- Debug( LDAP_DEBUG_ANY, +- "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n", +- text->bv_val, 0, 0 ); +- return NOID; +- } +- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_tool_entry_put) ": txn id: %x\n", +- tid->id(tid), 0, 0 ); +- } +- +- op.o_hdr = &ohdr; +- op.o_bd = be; +- op.o_tmpmemctx = NULL; +- op.o_tmpmfuncs = &ch_mfuncs; +- +- /* add dn2id indices */ +- rc = bdb_tool_next_id( &op, tid, e, text, 0 ); +- if( rc != 0 ) { +- goto done; +- } +- +-#ifdef USE_TRICKLE +- if (( slapMode & SLAP_TOOL_QUICK ) && (( e->e_id & 0xfff ) == 0xfff )) { +- ldap_pvt_thread_cond_signal( &bdb_tool_trickle_cond ); +- } +-#endif +- +- if ( !bdb->bi_linear_index ) +- rc = bdb_tool_index_add( &op, tid, e ); +- if( rc != 0 ) { +- snprintf( text->bv_val, text->bv_len, +- "index_entry_add failed: %s (%d)", +- rc == LDAP_OTHER ? "Internal error" : +- db_strerror(rc), rc ); +- Debug( LDAP_DEBUG_ANY, +- "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n", +- text->bv_val, 0, 0 ); +- goto done; +- } +- +- /* id2entry index */ +- rc = bdb_id2entry_add( be, tid, e ); +- if( rc != 0 ) { +- snprintf( text->bv_val, text->bv_len, +- "id2entry_add failed: %s (%d)", +- db_strerror(rc), rc ); +- Debug( LDAP_DEBUG_ANY, +- "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n", +- text->bv_val, 0, 0 ); +- goto done; +- } +- +-done: +- if( rc == 0 ) { +- if ( !( slapMode & SLAP_TOOL_QUICK )) { +- rc = TXN_COMMIT( tid, 0 ); +- if( rc != 0 ) { +- snprintf( text->bv_val, text->bv_len, +- "txn_commit failed: %s (%d)", +- db_strerror(rc), rc ); +- Debug( LDAP_DEBUG_ANY, +- "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n", +- text->bv_val, 0, 0 ); +- e->e_id = NOID; +- } +- } +- +- } else { +- if ( !( slapMode & SLAP_TOOL_QUICK )) { +- TXN_ABORT( tid ); +- snprintf( text->bv_val, text->bv_len, +- "txn_aborted! %s (%d)", +- rc == LDAP_OTHER ? "Internal error" : +- db_strerror(rc), rc ); +- Debug( LDAP_DEBUG_ANY, +- "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n", +- text->bv_val, 0, 0 ); +- } +- e->e_id = NOID; +- } +- +- return e->e_id; +-} +- +-int bdb_tool_entry_reindex( +- BackendDB *be, +- ID id, +- AttributeDescription **adv ) +-{ +- struct bdb_info *bi = (struct bdb_info *) be->be_private; +- int rc; +- Entry *e; +- DB_TXN *tid = NULL; +- Operation op = {0}; +- Opheader ohdr = {0}; +- +- Debug( LDAP_DEBUG_ARGS, +- "=> " LDAP_XSTRING(bdb_tool_entry_reindex) "( %ld )\n", +- (long) id, 0, 0 ); +- assert( tool_base == NULL ); +- assert( tool_filter == NULL ); +- +- /* No indexes configured, nothing to do. Could return an +- * error here to shortcut things. +- */ +- if (!bi->bi_attrs) { +- return 0; +- } +- +- /* Check for explicit list of attrs to index */ +- if ( adv ) { +- int i, j, n; +- +- if ( bi->bi_attrs[0]->ai_desc != adv[0] ) { +- /* count */ +- for ( n = 0; adv[n]; n++ ) ; +- +- /* insertion sort */ +- for ( i = 0; i < n; i++ ) { +- AttributeDescription *ad = adv[i]; +- for ( j = i-1; j>=0; j--) { +- if ( SLAP_PTRCMP( adv[j], ad ) <= 0 ) break; +- adv[j+1] = adv[j]; +- } +- adv[j+1] = ad; +- } +- } +- +- for ( i = 0; adv[i]; i++ ) { +- if ( bi->bi_attrs[i]->ai_desc != adv[i] ) { +- for ( j = i+1; j < bi->bi_nattrs; j++ ) { +- if ( bi->bi_attrs[j]->ai_desc == adv[i] ) { +- AttrInfo *ai = bi->bi_attrs[i]; +- bi->bi_attrs[i] = bi->bi_attrs[j]; +- bi->bi_attrs[j] = ai; +- break; +- } +- } +- if ( j == bi->bi_nattrs ) { +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_tool_entry_reindex) +- ": no index configured for %s\n", +- adv[i]->ad_cname.bv_val, 0, 0 ); +- return -1; +- } +- } +- } +- bi->bi_nattrs = i; +- } +- +- /* Get the first attribute to index */ +- if (bi->bi_linear_index && !index_nattrs) { +- index_nattrs = bi->bi_nattrs - 1; +- bi->bi_nattrs = 1; +- } +- +- e = bdb_tool_entry_get( be, id ); +- +- if( e == NULL ) { +- Debug( LDAP_DEBUG_ANY, +- LDAP_XSTRING(bdb_tool_entry_reindex) +- ": could not locate id=%ld\n", +- (long) id, 0, 0 ); +- return -1; +- } +- +- op.o_hdr = &ohdr; +- op.o_bd = be; +- op.o_tmpmemctx = NULL; +- op.o_tmpmfuncs = &ch_mfuncs; +- +- if (! (slapMode & SLAP_TOOL_QUICK)) { +- rc = TXN_BEGIN( bi->bi_dbenv, NULL, &tid, bi->bi_db_opflags ); +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, +- "=> " LDAP_XSTRING(bdb_tool_entry_reindex) ": " +- "txn_begin failed: %s (%d)\n", +- db_strerror(rc), rc, 0 ); +- goto done; +- } +- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_tool_entry_reindex) ": txn id: %x\n", +- tid->id(tid), 0, 0 ); +- } +- +- /* +- * just (re)add them for now +- * assume that some other routine (not yet implemented) +- * will zap index databases +- * +- */ +- +- Debug( LDAP_DEBUG_TRACE, +- "=> " LDAP_XSTRING(bdb_tool_entry_reindex) "( %ld, \"%s\" )\n", +- (long) id, e->e_dn, 0 ); +- +- rc = bdb_tool_index_add( &op, tid, e ); +- +-done: +- if( rc == 0 ) { +- if (! (slapMode & SLAP_TOOL_QUICK)) { +- rc = TXN_COMMIT( tid, 0 ); +- if( rc != 0 ) { +- Debug( LDAP_DEBUG_ANY, +- "=> " LDAP_XSTRING(bdb_tool_entry_reindex) +- ": txn_commit failed: %s (%d)\n", +- db_strerror(rc), rc, 0 ); +- e->e_id = NOID; +- } +- } +- +- } else { +- if (! (slapMode & SLAP_TOOL_QUICK)) { +- TXN_ABORT( tid ); +- Debug( LDAP_DEBUG_ANY, +- "=> " LDAP_XSTRING(bdb_tool_entry_reindex) +- ": txn_aborted! %s (%d)\n", +- db_strerror(rc), rc, 0 ); +- } +- e->e_id = NOID; +- } +- bdb_entry_release( &op, e, 0 ); +- +- return rc; +-} +- +-ID bdb_tool_entry_modify( +- BackendDB *be, +- Entry *e, +- struct berval *text ) +-{ +- int rc; +- struct bdb_info *bdb; +- DB_TXN *tid = NULL; +- Operation op = {0}; +- Opheader ohdr = {0}; +- +- assert( be != NULL ); +- assert( slapMode & SLAP_TOOL_MODE ); +- +- assert( text != NULL ); +- assert( text->bv_val != NULL ); +- assert( text->bv_val[0] == '\0' ); /* overconservative? */ +- +- assert ( e->e_id != NOID ); +- +- Debug( LDAP_DEBUG_TRACE, +- "=> " LDAP_XSTRING(bdb_tool_entry_modify) "( %ld, \"%s\" )\n", +- (long) e->e_id, e->e_dn, 0 ); +- +- bdb = (struct bdb_info *) be->be_private; +- +- if (! (slapMode & SLAP_TOOL_QUICK)) { +- if( cursor ) { +- cursor->c_close( cursor ); +- cursor = NULL; +- } +- rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &tid, +- bdb->bi_db_opflags ); +- if( rc != 0 ) { +- snprintf( text->bv_val, text->bv_len, +- "txn_begin failed: %s (%d)", +- db_strerror(rc), rc ); +- Debug( LDAP_DEBUG_ANY, +- "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n", +- text->bv_val, 0, 0 ); +- return NOID; +- } +- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_tool_entry_modify) ": txn id: %x\n", +- tid->id(tid), 0, 0 ); +- } +- +- op.o_hdr = &ohdr; +- op.o_bd = be; +- op.o_tmpmemctx = NULL; +- op.o_tmpmfuncs = &ch_mfuncs; +- +- /* id2entry index */ +- rc = bdb_id2entry_update( be, tid, e ); +- if( rc != 0 ) { +- snprintf( text->bv_val, text->bv_len, +- "id2entry_add failed: %s (%d)", +- db_strerror(rc), rc ); +- Debug( LDAP_DEBUG_ANY, +- "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n", +- text->bv_val, 0, 0 ); +- goto done; +- } +- +-done: +- if( rc == 0 ) { +- if (! (slapMode & SLAP_TOOL_QUICK)) { +- rc = TXN_COMMIT( tid, 0 ); +- if( rc != 0 ) { +- snprintf( text->bv_val, text->bv_len, +- "txn_commit failed: %s (%d)", +- db_strerror(rc), rc ); +- Debug( LDAP_DEBUG_ANY, +- "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": " +- "%s\n", text->bv_val, 0, 0 ); +- e->e_id = NOID; +- } +- } +- +- } else { +- if (! (slapMode & SLAP_TOOL_QUICK)) { +- TXN_ABORT( tid ); +- snprintf( text->bv_val, text->bv_len, +- "txn_aborted! %s (%d)", +- db_strerror(rc), rc ); +- Debug( LDAP_DEBUG_ANY, +- "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n", +- text->bv_val, 0, 0 ); +- } +- e->e_id = NOID; +- } +- +- return e->e_id; +-} +- +-#ifdef BDB_TOOL_IDL_CACHING +-static int +-bdb_tool_idl_cmp( const void *v1, const void *v2 ) +-{ +- const bdb_tool_idl_cache *c1 = v1, *c2 = v2; +- int rc; +- +- if (( rc = c1->kstr.bv_len - c2->kstr.bv_len )) return rc; +- return memcmp( c1->kstr.bv_val, c2->kstr.bv_val, c1->kstr.bv_len ); +-} +- +-static int +-bdb_tool_idl_flush_one( void *v1, void *arg ) +-{ +- bdb_tool_idl_cache *ic = v1; +- DB *db = arg; +- struct bdb_info *bdb = bdb_tool_info; +- bdb_tool_idl_cache_entry *ice; +- DBC *curs; +- DBT key, data; +- int i, rc; +- ID id, nid; +- +- /* Freshly allocated, ignore it */ +- if ( !ic->head && ic->count <= BDB_IDL_DB_SIZE ) { +- return 0; +- } +- +- rc = db->cursor( db, NULL, &curs, 0 ); +- if ( rc ) +- return -1; +- +- DBTzero( &key ); +- DBTzero( &data ); +- +- bv2DBT( &ic->kstr, &key ); +- +- data.size = data.ulen = sizeof( ID ); +- data.flags = DB_DBT_USERMEM; +- data.data = &nid; +- +- rc = curs->c_get( curs, &key, &data, DB_SET ); +- /* If key already exists and we're writing a range... */ +- if ( rc == 0 && ic->count > BDB_IDL_DB_SIZE ) { +- /* If it's not currently a range, must delete old info */ +- if ( nid ) { +- /* Skip lo */ +- while ( curs->c_get( curs, &key, &data, DB_NEXT_DUP ) == 0 ) +- curs->c_del( curs, 0 ); +- +- nid = 0; +- /* Store range marker */ +- curs->c_put( curs, &key, &data, DB_KEYFIRST ); +- } else { +- +- /* Skip lo */ +- rc = curs->c_get( curs, &key, &data, DB_NEXT_DUP ); +- +- /* Get hi */ +- rc = curs->c_get( curs, &key, &data, DB_NEXT_DUP ); +- +- /* Delete hi */ +- curs->c_del( curs, 0 ); +- } +- BDB_ID2DISK( ic->last, &nid ); +- curs->c_put( curs, &key, &data, DB_KEYLAST ); +- rc = 0; +- } else if ( rc && rc != DB_NOTFOUND ) { +- rc = -1; +- } else if ( ic->count > BDB_IDL_DB_SIZE ) { +- /* range, didn't exist before */ +- nid = 0; +- rc = curs->c_put( curs, &key, &data, DB_KEYLAST ); +- if ( rc == 0 ) { +- BDB_ID2DISK( ic->first, &nid ); +- rc = curs->c_put( curs, &key, &data, DB_KEYLAST ); +- if ( rc == 0 ) { +- BDB_ID2DISK( ic->last, &nid ); +- rc = curs->c_put( curs, &key, &data, DB_KEYLAST ); +- } +- } +- if ( rc ) { +- rc = -1; +- } +- } else { +- int n; +- +- /* Just a normal write */ +- rc = 0; +- for ( ice = ic->head, n=0; ice; ice = ice->next, n++ ) { +- int end; +- if ( ice->next ) { +- end = IDBLOCK; +- } else { +- end = ic->count & (IDBLOCK-1); +- if ( !end ) +- end = IDBLOCK; +- } +- for ( i=0; iids[i] ) continue; +- BDB_ID2DISK( ice->ids[i], &nid ); +- rc = curs->c_put( curs, &key, &data, DB_NODUPDATA ); +- if ( rc ) { +- if ( rc == DB_KEYEXIST ) { +- rc = 0; +- continue; +- } +- rc = -1; +- break; +- } +- } +- if ( rc ) { +- rc = -1; +- break; +- } +- } +- if ( ic->head ) { +- ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock ); +- ic->tail->next = bdb_tool_idl_free_list; +- bdb_tool_idl_free_list = ic->head; +- bdb->bi_idl_cache_size -= n; +- ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock ); +- } +- } +- if ( ic != db->app_private ) { +- ch_free( ic ); +- } else { +- ic->head = ic->tail = NULL; +- } +- curs->c_close( curs ); +- return rc; +-} +- +-static int +-bdb_tool_idl_flush_db( DB *db, bdb_tool_idl_cache *ic ) +-{ +- Avlnode *root = db->app_private; +- int rc; +- +- db->app_private = ic; +- rc = avl_apply( root, bdb_tool_idl_flush_one, db, -1, AVL_INORDER ); +- avl_free( root, NULL ); +- db->app_private = NULL; +- if ( rc != -1 ) +- rc = 0; +- return rc; +-} +- +-static int +-bdb_tool_idl_flush( BackendDB *be ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) be->be_private; +- DB *db; +- Avlnode *root; +- int i, rc = 0; +- +- for ( i=BDB_NDB; i < bdb->bi_ndatabases; i++ ) { +- db = bdb->bi_databases[i]->bdi_db; +- if ( !db->app_private ) continue; +- rc = bdb_tool_idl_flush_db( db, NULL ); +- if ( rc ) +- break; +- } +- if ( !rc ) { +- bdb->bi_idl_cache_size = 0; +- } +- return rc; +-} +- +-int bdb_tool_idl_add( +- BackendDB *be, +- DB *db, +- DB_TXN *txn, +- DBT *key, +- ID id ) +-{ +- struct bdb_info *bdb = (struct bdb_info *) be->be_private; +- bdb_tool_idl_cache *ic, itmp; +- bdb_tool_idl_cache_entry *ice; +- int rc; +- +- if ( !bdb->bi_idl_cache_max_size ) +- return bdb_idl_insert_key( be, db, txn, key, id ); +- +- DBT2bv( key, &itmp.kstr ); +- +- ic = avl_find( (Avlnode *)db->app_private, &itmp, bdb_tool_idl_cmp ); +- +- /* No entry yet, create one */ +- if ( !ic ) { +- DBC *curs; +- DBT data; +- ID nid; +- int rc; +- +- ic = ch_malloc( sizeof( bdb_tool_idl_cache ) + itmp.kstr.bv_len ); +- ic->kstr.bv_len = itmp.kstr.bv_len; +- ic->kstr.bv_val = (char *)(ic+1); +- AC_MEMCPY( ic->kstr.bv_val, itmp.kstr.bv_val, ic->kstr.bv_len ); +- ic->head = ic->tail = NULL; +- ic->last = 0; +- ic->count = 0; +- avl_insert( (Avlnode **)&db->app_private, ic, bdb_tool_idl_cmp, +- avl_dup_error ); +- +- /* load existing key count here */ +- rc = db->cursor( db, NULL, &curs, 0 ); +- if ( rc ) return rc; +- +- data.ulen = sizeof( ID ); +- data.flags = DB_DBT_USERMEM; +- data.data = &nid; +- rc = curs->c_get( curs, key, &data, DB_SET ); +- if ( rc == 0 ) { +- if ( nid == 0 ) { +- ic->count = BDB_IDL_DB_SIZE+1; +- } else { +- db_recno_t count; +- +- curs->c_count( curs, &count, 0 ); +- ic->count = count; +- BDB_DISK2ID( &nid, &ic->first ); +- } +- } +- curs->c_close( curs ); +- } +- /* are we a range already? */ +- if ( ic->count > BDB_IDL_DB_SIZE ) { +- ic->last = id; +- return 0; +- /* Are we at the limit, and converting to a range? */ +- } else if ( ic->count == BDB_IDL_DB_SIZE ) { +- int n; +- for ( ice = ic->head, n=0; ice; ice = ice->next, n++ ) +- /* counting */ ; +- if ( n ) { +- ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock ); +- ic->tail->next = bdb_tool_idl_free_list; +- bdb_tool_idl_free_list = ic->head; +- bdb->bi_idl_cache_size -= n; +- ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock ); +- } +- ic->head = ic->tail = NULL; +- ic->last = id; +- ic->count++; +- return 0; +- } +- /* No free block, create that too */ +- if ( !ic->tail || ( ic->count & (IDBLOCK-1)) == 0) { +- ice = NULL; +- ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock ); +- if ( bdb->bi_idl_cache_size >= bdb->bi_idl_cache_max_size ) { +- ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock ); +- rc = bdb_tool_idl_flush_db( db, ic ); +- if ( rc ) +- return rc; +- avl_insert( (Avlnode **)&db->app_private, ic, bdb_tool_idl_cmp, +- avl_dup_error ); +- ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock ); +- } +- bdb->bi_idl_cache_size++; +- if ( bdb_tool_idl_free_list ) { +- ice = bdb_tool_idl_free_list; +- bdb_tool_idl_free_list = ice->next; +- } +- ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock ); +- if ( !ice ) { +- ice = ch_malloc( sizeof( bdb_tool_idl_cache_entry )); +- } +- memset( ice, 0, sizeof( *ice )); +- if ( !ic->head ) { +- ic->head = ice; +- } else { +- ic->tail->next = ice; +- } +- ic->tail = ice; +- if ( !ic->count ) +- ic->first = id; +- } +- ice = ic->tail; +- ice->ids[ ic->count & (IDBLOCK-1) ] = id; +- ic->count++; +- +- return 0; +-} +-#endif +- +-#ifdef USE_TRICKLE +-static void * +-bdb_tool_trickle_task( void *ctx, void *ptr ) +-{ +- DB_ENV *env = ptr; +- int wrote; +- +- ldap_pvt_thread_mutex_lock( &bdb_tool_trickle_mutex ); +- bdb_tool_trickle_active = 1; +- ldap_pvt_thread_cond_signal( &bdb_tool_trickle_cond_end ); +- while ( 1 ) { +- ldap_pvt_thread_cond_wait( &bdb_tool_trickle_cond, +- &bdb_tool_trickle_mutex ); +- if ( slapd_shutdown ) +- break; +- env->memp_trickle( env, 30, &wrote ); +- } +- bdb_tool_trickle_active = 0; +- ldap_pvt_thread_cond_signal( &bdb_tool_trickle_cond_end ); +- ldap_pvt_thread_mutex_unlock( &bdb_tool_trickle_mutex ); +- +- return NULL; +-} +-#endif +- +-static void * +-bdb_tool_index_task( void *ctx, void *ptr ) +-{ +- int base = *(int *)ptr; +- +- free( ptr ); +- while ( 1 ) { +- ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex ); +- bdb_tool_index_tcount--; +- if ( !bdb_tool_index_tcount ) +- ldap_pvt_thread_cond_signal( &bdb_tool_index_cond_main ); +- ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_work, +- &bdb_tool_index_mutex ); +- if ( slapd_shutdown ) { +- bdb_tool_index_tcount--; +- if ( !bdb_tool_index_tcount ) +- ldap_pvt_thread_cond_signal( &bdb_tool_index_cond_main ); +- ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex ); +- break; +- } +- ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex ); +- +- bdb_tool_index_threads[base] = bdb_index_recrun( bdb_tool_ix_op, +- bdb_tool_info, bdb_tool_index_rec, bdb_tool_ix_id, base ); +- } +- +- return NULL; +-} +diff --git a/servers/slapd/back-bdb/trans.c b/servers/slapd/back-bdb/trans.c +deleted file mode 100644 +index 1971d29..0000000 +--- a/servers/slapd/back-bdb/trans.c ++++ /dev/null +@@ -1,56 +0,0 @@ +-/* trans.c - bdb backend transaction routines */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +- +-#include "portable.h" +- +-#include +-#include +- +-#include "back-bdb.h" +-#include "lber_pvt.h" +-#include "lutil.h" +- +- +-/* Congestion avoidance code +- * for Deadlock Rollback +- */ +- +-void +-bdb_trans_backoff( int num_retries ) +-{ +- int i; +- int delay = 0; +- int pow_retries = 1; +- unsigned long key = 0; +- unsigned long max_key = -1; +- struct timeval timeout; +- +- lutil_entropy( (unsigned char *) &key, sizeof( unsigned long )); +- +- for ( i = 0; i < num_retries; i++ ) { +- if ( i >= 5 ) break; +- pow_retries *= 4; +- } +- +- delay = 16384 * (key * (double) pow_retries / (double) max_key); +- delay = delay ? delay : 1; +- +- Debug( LDAP_DEBUG_TRACE, "delay = %d, num_retries = %d\n", delay, num_retries, 0 ); +- +- timeout.tv_sec = delay / 1000000; +- timeout.tv_usec = delay % 1000000; +- select( 0, NULL, NULL, NULL, &timeout ); +-} +diff --git a/servers/slapd/back-hdb/Makefile.in b/servers/slapd/back-hdb/Makefile.in +deleted file mode 100644 +index 150cee5..0000000 +--- a/servers/slapd/back-hdb/Makefile.in ++++ /dev/null +@@ -1,70 +0,0 @@ +-# Makefile for back-hdb +-# $OpenLDAP$ +-## This work is part of OpenLDAP Software . +-## +-## Copyright 1998-2020 The OpenLDAP Foundation. +-## All rights reserved. +-## +-## Redistribution and use in source and binary forms, with or without +-## modification, are permitted only as authorized by the OpenLDAP +-## Public License. +-## +-## A copy of this license is available in the file LICENSE in the +-## top-level directory of the distribution or, alternatively, at +-## . +-# +-## Copyright 2003 Howard Chu @ Symas Corp. See master COPYRIGHT file for terms. +- +-XXDIR = $(srcdir)/../back-bdb +- +-XXSRCS = init.c tools.c config.c \ +- add.c bind.c compare.c delete.c modify.c modrdn.c search.c \ +- extended.c referral.c operational.c \ +- attr.c index.c key.c dbcache.c filterindex.c trans.c \ +- dn2entry.c dn2id.c error.c id2entry.c idl.c nextid.c cache.c \ +- monitor.c +-SRCS = $(XXSRCS) +-OBJS = init.lo tools.lo config.lo \ +- add.lo bind.lo compare.lo delete.lo modify.lo modrdn.lo search.lo \ +- extended.lo referral.lo operational.lo \ +- attr.lo index.lo key.lo dbcache.lo filterindex.lo trans.lo \ +- dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo nextid.lo cache.lo \ +- monitor.lo +- +-LDAP_INCDIR= ../../../include +-LDAP_LIBDIR= ../../../libraries +- +-BUILD_OPT = "--enable-hdb" +-BUILD_MOD = @BUILD_HDB@ +- +-mod_DEFS = -DSLAPD_IMPORT +-MOD_DEFS = $(@BUILD_HDB@_DEFS) +-MOD_LIBS = $(BDB_LIBS) +- +-shared_LDAP_LIBS = $(LDAP_LIBLDAP_R_LA) $(LDAP_LIBLBER_LA) +-NT_LINK_LIBS = -L.. -lslapd $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS) +-UNIX_LINK_LIBS = $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS) +- +-.links : Makefile +- @for i in $(XXSRCS); do \ +- $(RM) $$i; \ +- $(LN_S) $(XXDIR)/$$i . ; \ +- done +- touch .links +- +-$(XXSRCS) : .links +- +-LIBBASE = back_hdb +- +-XINCPATH = -I.. -I$(srcdir)/.. -I$(srcdir) -I$(XXDIR) +-XDEFS = $(MODULES_CPPFLAGS) +- +-depend-local-lib: .links +- +-all-local-lib: ../.backend +- +-../.backend: lib$(LIBBASE).a +- @touch $@ +- +-veryclean-local: FORCE +- $(RM) $(XXSRCS) .links +diff --git a/servers/slapd/back-hdb/back-bdb.h b/servers/slapd/back-hdb/back-bdb.h +deleted file mode 100644 +index 9f92d8b..0000000 +--- a/servers/slapd/back-hdb/back-bdb.h ++++ /dev/null +@@ -1,31 +0,0 @@ +-/* back-bdb.h - hdb back-end header file */ +-/* $OpenLDAP$ */ +-/* This work is part of OpenLDAP Software . +- * +- * Copyright 2000-2020 The OpenLDAP Foundation. +- * Portions Copyright 2003 Howard Chu @ Symas Corp. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted only as authorized by the OpenLDAP +- * Public License. +- * +- * A copy of this license is available in the file LICENSE in the +- * top-level directory of the distribution or, alternatively, at +- * . +- */ +-/* ACKNOWLEDGEMENTS: +- * This work was originally developed by Howard Chu for inclusion +- * in OpenLDAP Software. +- */ +- +-#ifndef _BACK_HDB_H_ +-#define _BACK_HDB_H_ +- +-#ifndef BDB_HIER +-#define BDB_HIER 1 +-#endif +- +-#include "../back-bdb/back-bdb.h" +- +-#endif /* _BACK_HDB_H_ */ +diff --git a/servers/slapd/back-monitor/init.c b/servers/slapd/back-monitor/init.c +index b264115..ce9a34a 100644 +--- a/servers/slapd/back-monitor/init.c ++++ b/servers/slapd/back-monitor/init.c +@@ -1991,8 +1991,8 @@ monitor_back_initialize( + { "olmGenericAttributes", "olmSubSystemAttributes:0" }, + { "olmDatabaseAttributes", "olmSubSystemAttributes:1" }, + +- /* for example, back-bdb specific attrs +- * are in "olmDatabaseAttributes:1" ++ /* for example, back-mdb specific attrs ++ * are in "olmDatabaseAttributes:12" + * + * NOTE: developers, please record here OID assignments + * for other modules */ +@@ -2002,8 +2002,8 @@ monitor_back_initialize( + { "olmGenericObjectClasses", "olmSubSystemObjectClasses:0" }, + { "olmDatabaseObjectClasses", "olmSubSystemObjectClasses:1" }, + +- /* for example, back-bdb specific objectClasses +- * are in "olmDatabaseObjectClasses:1" ++ /* for example, back-mdb specific objectClasses ++ * are in "olmDatabaseObjectClasses:12" + * + * NOTE: developers, please record here OID assignments + * for other modules */ +diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c +index 0c6a7f5..538eef1 100644 +--- a/servers/slapd/bconfig.c ++++ b/servers/slapd/bconfig.c +@@ -238,7 +238,7 @@ static OidRec OidMacros[] = { + * Backend/Database registry + * + * OLcfg{Bk|Db}{Oc|At}:0 -> common +- * OLcfg{Bk|Db}{Oc|At}:1 -> back-bdb(/back-hdb) ++ * OLcfg{Bk|Db}{Oc|At}:1 -> back-bdb(/back-hdb) (removed) + * OLcfg{Bk|Db}{Oc|At}:2 -> back-ldif + * OLcfg{Bk|Db}{Oc|At}:3 -> back-ldap/meta + * OLcfg{Bk|Db}{Oc|At}:4 -> back-monitor +diff --git a/servers/slapd/dn.c b/servers/slapd/dn.c +index 06698b0..89b80e3 100644 +--- a/servers/slapd/dn.c ++++ b/servers/slapd/dn.c +@@ -1131,8 +1131,7 @@ rdn_validate( struct berval *rdn ) + + /* build_new_dn: + * +- * Used by back-bdb back_modrdn to create the new dn of entries being +- * renamed. ++ * Used to create the new dn of entries being renamed. + * + * new_dn = parent (p_dn) + separator + rdn (newrdn) + null. + */ +diff --git a/servers/slapd/overlays/pcache.c b/servers/slapd/overlays/pcache.c +index f88ca09..0d7ff8c 100644 +--- a/servers/slapd/overlays/pcache.c ++++ b/servers/slapd/overlays/pcache.c +@@ -5616,7 +5616,7 @@ cleanup:; + cm->monitor_cb = (void *)cb; + + /* we don't need to keep track of the attributes, because +- * bdb_monitor_free() takes care of everything */ ++ * mdb_monitor_free() takes care of everything */ + if ( a != NULL ) { + attrs_free( a ); + } +@@ -5700,7 +5700,7 @@ pcache_initialize() + } + #endif /* PCACHE_EXOP_QUERY_DELETE */ + +- argv[ 0 ] = "back-bdb/back-hdb monitor"; ++ argv[ 0 ] = "back-mdb monitor"; + c.argv = argv; + c.argc = 3; + c.fname = argv[0]; +diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h +index f003bb9..591f49d 100644 +--- a/servers/slapd/slap.h ++++ b/servers/slapd/slap.h +@@ -1805,7 +1805,6 @@ struct BackendDB { + + /* + * define to honor hasSubordinates operational attribute in search filters +- * (in previous use there was a flaw with back-bdb; now it is fixed). + */ + #define be_has_subordinates bd_info->bi_has_subordinates + +diff --git a/servers/slapd/slapd.ldif b/servers/slapd/slapd.ldif +index 5aba54d..b2b38ea 100644 +--- a/servers/slapd/slapd.ldif ++++ b/servers/slapd/slapd.ldif +@@ -30,8 +30,7 @@ olcPidFile: %LOCALSTATEDIR%/run/slapd.pid + #objectClass: olcModuleList + #cn: module + #olcModulepath: %MODULEDIR% +-#olcModuleload: back_bdb.la +-#olcModuleload: back_hdb.la ++#olcModuleload: back_mdb.la + #olcModuleload: back_ldap.la + #olcModuleload: back_passwd.la + #olcModuleload: back_shell.la +diff --git a/tests/Makefile.in b/tests/Makefile.in +index d841846..ef98813 100644 +--- a/tests/Makefile.in ++++ b/tests/Makefile.in +@@ -16,15 +16,11 @@ + RUN=./run + SUBDIRS= progs + +-BUILD_BDB=@BUILD_BDB@ +-BUILD_HDB=@BUILD_HDB@ + BUILD_MDB=@BUILD_MDB@ + BUILD_SQL=@BUILD_SQL@ + + # test primary backends (default) + test tests: +- @$(MAKE) bdb +- @$(MAKE) hdb + @$(MAKE) mdb + + # test all backends +@@ -32,22 +28,6 @@ alltests: tests + @$(MAKE) sql + @$(MAKE) ldif + +-bdb test-bdb: bdb-$(BUILD_BDB) +-bdb-no: +- @echo "run configure with --enable-bdb to run BDB tests" +- +-bdb-yes bdb-mod: FORCE +- @echo "Initiating LDAP tests for BDB..." +- @$(RUN) -b bdb all +- +-hdb test-hdb: hdb-$(BUILD_HDB) +-hdb-no: +- @echo "run configure with --enable-hdb to run HDB tests" +- +-hdb-yes hdb-mod: FORCE +- @echo "Initiating LDAP tests for HDB..." +- @$(RUN) -b hdb all +- + mdb test-mdb: mdb-$(BUILD_MDB) + mdb-no: + @echo "run configure with --enable-mdb to run MDB tests" +@@ -70,26 +50,10 @@ ldif test-ldif: FORCE + + regressions: FORCE + @echo "Testing (available) ITS regressions" +- @$(MAKE) bdb-its +- @$(MAKE) hdb-its + @$(MAKE) mdb-its + + its: regressions + +-bdb-its: bdb-its-$(BUILD_BDB) +-bdb-its-no: +- @echo "run configure with --enable-bdb to run BDB ITS regressions" +- +-bdb-its-yes bdb-its-mod: FORCE +- @$(RUN) -b bdb its-all +- +-hdb-its: hdb-its-$(BUILD_HDB) +-hdb-its-no: +- @echo "run configure with --enable-hdb to run HDB ITS regressions" +- +-hdb-its-yes hdb-its-mod: FORCE +- @$(RUN) -b hdb its-all +- + mdb-its: mdb-its-$(BUILD_MDB) + mdb-its-no: + @echo "run configure with --enable-mdb to run MDB ITS regressions" +diff --git a/tests/README b/tests/README +index 1a25df8..a3b5d2f 100644 +--- a/tests/README ++++ b/tests/README +@@ -2,8 +2,6 @@ This directory contains a series of test scripts which are used to + verify basic functionality of the LDAP libraries and slapd. + + To run all of the tests, type "make test". +- To run BDB tests, type "make bdb". +- To run HDB tests, type "make hdb". + To run MDB tests, type "make mdb". + To run SQL tests, define SLAPD_USE_SQL= and type + "make sql"; define SLAPD_USE_SQLWRITE=yes +diff --git a/tests/data/regressions/its4184/its4184 b/tests/data/regressions/its4184/its4184 +index 08f9f1c..4170f05 100755 +--- a/tests/data/regressions/its4184/its4184 ++++ b/tests/data/regressions/its4184/its4184 +@@ -16,10 +16,6 @@ + echo "running defines.sh" + . $SRCDIR/scripts/defines.sh + +-if test "$BACKEND" != "bdb" && test "$BACKEND" != "hdb" ; then +- echo "Warning: this test is known to affect bdb and hdb, although it may impact other backends as well." +-fi +- + mkdir -p $DBDIR1A $DBDIR2A + + ITS=4184 +diff --git a/tests/data/regressions/its4448/its4448 b/tests/data/regressions/its4448/its4448 +index 7f50999..9319374 100755 +--- a/tests/data/regressions/its4448/its4448 ++++ b/tests/data/regressions/its4448/its4448 +@@ -47,22 +47,6 @@ ITS=4448 + ITSDIR=$DATADIR/regressions/its$ITS + ITSCONF=$ITSDIR/slapd-meta.conf + +-# NOTE: this could be added to all tests... +-if test "$BACKEND" = "bdb" || test "$BACKEND" = "hdb" ; then +- if test "x$DB_CONFIG" != "x" ; then \ +- if test -f $DB_CONFIG ; then +- echo "==> using DB_CONFIG \"$DB_CONFIG\"" +- cp $DB_CONFIG $DBDIR1 +- cp $DB_CONFIG $DBDIR2 +- else +- echo "==> DB_CONFIG must point to a valid file (ignored)" +- fi +- else +- echo "==> set \"DB_CONFIG\" to the DB_CONFIG file you want to use for the test." +- fi +- echo "" +-fi +- + echo "Starting slapd on TCP/IP port $PORT1..." + . $CONFFILTER $BACKEND $MONITORDB < $CONF > $CONF1 + $SLAPD -f $CONF1 -h $URI1 -d $LVL $TIMING > $LOG1 2>&1 & +diff --git a/tests/data/slapd-proxyauthz.conf b/tests/data/slapd-proxyauthz.conf +index 2ff6563..b28d60d 100644 +--- a/tests/data/slapd-proxyauthz.conf ++++ b/tests/data/slapd-proxyauthz.conf +@@ -64,10 +64,6 @@ pcachetemplate (cn=) 0 86400 86400 86400 180 + + pcachebind (cn=) 0 3600 sub ou=people,dc=example,dc=com + +-#bdb#cachesize 20 +-#hdb#cachesize 20 +-#bdb#dbnosync +-#hdb#dbnosync + #mdb#dbnosync + + #~null~#directory @TESTDIR@/db.2.a +diff --git a/tests/data/slapd-proxycache.conf b/tests/data/slapd-proxycache.conf +index b96d850..db3b60e 100644 +--- a/tests/data/slapd-proxycache.conf ++++ b/tests/data/slapd-proxycache.conf +@@ -54,10 +54,6 @@ pcachetemplate (mail=) 0 @TTL@ @NTTL@ @STTL@ + pcachetemplate (&(objectclass=)(uid=)) 1 @TTL@ @NTTL@ @STTL@ @TTR@ + pcachebind (&(objectclass=person)(uid=)) 1 @BTTR@ sub "ou=Alumni Association,ou=people,dc=example,dc=com" + +-#bdb#cachesize 20 +-#hdb#cachesize 20 +-#bdb#dbnosync +-#hdb#dbnosync + #mdb#dbnosync + + #~null~#directory @TESTDIR@/db.2.a +diff --git a/tests/data/slapd-ref-slave.conf b/tests/data/slapd-ref-slave.conf +index 3d30ca7..5d8d83f 100644 +--- a/tests/data/slapd-ref-slave.conf ++++ b/tests/data/slapd-ref-slave.conf +@@ -34,8 +34,6 @@ argsfile @TESTDIR@/slapd.2.args + referral "@URI1@" + + database @BACKEND@ +-#bdb#cachesize 0 +-#hdb#cachesize 0 + + suffix "o=University of Mich,c=US" + rootdn "cn=Manager,o=University of Mich,c=US" +diff --git a/tests/data/slapd.conf b/tests/data/slapd.conf +index 97c883b..309eb5a 100644 +--- a/tests/data/slapd.conf ++++ b/tests/data/slapd.conf +@@ -44,8 +44,6 @@ rootpw secret + #~null~#directory @TESTDIR@/db.1.a + #indexdb#index objectClass eq + #indexdb#index cn,sn,uid pres,eq,sub +-#bdb#checkpoint 1024 5 +-#hdb#checkpoint 1024 5 + #mdb#maxsize 33554432 + #ndb#dbname db_1 + #ndb#include @DATADIR@/ndb.conf +diff --git a/tests/run.in b/tests/run.in +index 8830dd4..6705265 100644 +--- a/tests/run.in ++++ b/tests/run.in +@@ -24,8 +24,6 @@ EGREP_CMD="@EGREP@" + export SRCDIR TOPSRCDIR LN_S EGREP_CMD + + # backends known to ./run -b (used to deduce $BACKENDTYPE) +-AC_bdb=@BUILD_BDB@ +-AC_hdb=@BUILD_HDB@ + AC_ldif=yes + AC_mdb=@BUILD_MDB@ + AC_null=@BUILD_NULL@ +@@ -69,7 +67,7 @@ if test "${AC_meta}" = "metamod" && test "${AC_LIBS_DYNAMIC}" = "static" ; then + AC_meta="metano" + fi + +-export AC_bdb AC_hdb AC_ldap AC_mdb AC_meta AC_monitor AC_null AC_relay AC_sql \ ++export AC_ldap AC_mdb AC_meta AC_monitor AC_null AC_relay AC_sql \ + AC_accesslog AC_constraint AC_dds AC_dynlist AC_memberof AC_pcache AC_ppolicy \ + AC_refint AC_retcode AC_rwm AC_unique AC_syncprov AC_translucent \ + AC_valsort \ +@@ -153,7 +151,7 @@ while test $# -gt 0 ; do + done + + if test -z "$BACKEND" ; then +- for b in bdb hdb mdb ; do ++ for b in mdb ; do + if eval "test \"\$AC_$b\" != no" ; then + BACKEND=$b + break +@@ -174,7 +172,7 @@ fi + # maindb: main storage backend. Currently index,limits,mode,paged results. + INDEXDB=noindexdb MAINDB=nomaindb + case $BACKEND in +- bdb|hdb|mdb) INDEXDB=indexdb MAINDB=maindb ;; ++ mdb) INDEXDB=indexdb MAINDB=maindb ;; + ndb) INDEXDB=indexdb ;; + esac + +diff --git a/tests/scripts/test023-refint b/tests/scripts/test023-refint +index 546b9c7..b51134d 100755 +--- a/tests/scripts/test023-refint ++++ b/tests/scripts/test023-refint +@@ -189,9 +189,8 @@ if test $RC != 0 ; then + exit $RC + fi + +-if test $BACKEND != "bdb" ; then +- $LDAPMODIFY -v -D "$REFINTDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \ +- $TESTOUT 2>&1 << EDEL ++$LDAPMODIFY -v -D "$REFINTDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \ ++ $TESTOUT 2>&1 << EDEL + version: 1 + dn: cn=group,o=refint + changetype: add +@@ -205,65 +204,65 @@ member: uid=theman,ou=users,o=refint + member: uid=richard,ou=users,o=refint + EDEL + +- RC=$? +- if test $RC != 0 ; then +- echo "ldapmodify failed ($RC)!" +- test $KILLSERVERS != no && kill -HUP $KILLPIDS +- exit $RC +- fi ++RC=$? ++if test $RC != 0 ; then ++ echo "ldapmodify failed ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi + +- sleep 1; ++sleep 1; + +- $LDAPSEARCH -S "" -b "o=refint" -h $LOCALHOST -p $PORT1 \ +- manager member secretary > $SEARCHOUT 2>&1 +- RC=$? +- if test $RC != 0 ; then +- echo "ldapsearch failed ($RC)!" +- test $KILLSERVERS != no && kill -HUP $KILLPIDS +- exit $RC +- fi ++$LDAPSEARCH -S "" -b "o=refint" -h $LOCALHOST -p $PORT1 \ ++ manager member secretary > $SEARCHOUT 2>&1 ++RC=$? ++if test $RC != 0 ; then ++ echo "ldapsearch failed ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi + +- $EGREP_CMD "(manager|member|secretary):" $SEARCHOUT \ +- | sed "s/ou=users/ou=people/g" | \ +- sort > $TESTOUT 2>&1 ++$EGREP_CMD "(manager|member|secretary):" $SEARCHOUT \ ++ | sed "s/ou=users/ou=people/g" | \ ++ sort > $TESTOUT 2>&1 + +- echo "testing subtree rename" +- $LDAPMODRDN -D "$REFINTDN" -r -h $LOCALHOST -p $PORT1 -w $PASSWD > \ +- /dev/null 2>&1 'ou=users,o=refint' 'ou=people' +- RC=$? +- if test $RC != 0 ; then +- echo "ldapmodrdn failed ($RC)!" +- test $KILLSERVERS != no && kill -HUP $KILLPIDS +- exit $RC +- fi ++echo "testing subtree rename" ++$LDAPMODRDN -D "$REFINTDN" -r -h $LOCALHOST -p $PORT1 -w $PASSWD > \ ++ /dev/null 2>&1 'ou=users,o=refint' 'ou=people' ++RC=$? ++if test $RC != 0 ; then ++ echo "ldapmodrdn failed ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi + +- sleep 1; ++sleep 1; + +- echo "Using ldapsearch to check dependents new rdn..." ++echo "Using ldapsearch to check dependents new rdn..." + +- $LDAPSEARCH -S "" -b "o=refint" -h $LOCALHOST -p $PORT1 \ +- manager member secretary > $SEARCHOUT 2>&1 ++$LDAPSEARCH -S "" -b "o=refint" -h $LOCALHOST -p $PORT1 \ ++ manager member secretary > $SEARCHOUT 2>&1 + +- RC=$? +- if test $RC != 0 ; then +- echo "ldapsearch failed ($RC)!" +- test $KILLSERVERS != no && kill -HUP $KILLPIDS +- exit $RC +- fi ++RC=$? ++if test $RC != 0 ; then ++ echo "ldapsearch failed ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi + +- $EGREP_CMD "(manager|member|secretary):" $SEARCHOUT \ +- | sort > $SEARCHFLT 2>&1 ++$EGREP_CMD "(manager|member|secretary):" $SEARCHOUT \ ++ | sort > $SEARCHFLT 2>&1 + +- echo "Comparing ldapsearch results against original..." +- $CMP $TESTOUT $SEARCHFLT > $CMPOUT ++echo "Comparing ldapsearch results against original..." ++$CMP $TESTOUT $SEARCHFLT > $CMPOUT + +- if test $? != 0 ; then +- echo "comparison failed - subtree rename operations did not complete correctly" +- test $KILLSERVERS != no && kill -HUP $KILLPIDS +- exit 1 +- fi ++if test $? != 0 ; then ++ echo "comparison failed - subtree rename operations did not complete correctly" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit 1 + fi + ++ + test $KILLSERVERS != no && kill -HUP $KILLPIDS + + echo ">>>>> Test succeeded" +diff --git a/tests/scripts/test025-limits b/tests/scripts/test025-limits +index 8d39c6b..551b969 100755 +--- a/tests/scripts/test025-limits ++++ b/tests/scripts/test025-limits +@@ -750,7 +750,7 @@ case $RC in + esac + + if test $MAINDB != maindb ; then +- # only bdb|hdb|mdb currently supports pagedResults control ++ # only mdb currently supports pagedResults control + test $KILLSERVERS != no && kill -HUP $KILLPIDS + + echo ">>>>> Test succeeded" +diff --git a/tests/scripts/test036-meta-concurrency b/tests/scripts/test036-meta-concurrency +index 2a4146c..3344f45 100755 +--- a/tests/scripts/test036-meta-concurrency ++++ b/tests/scripts/test036-meta-concurrency +@@ -40,22 +40,6 @@ rm -rf $TESTDIR + + mkdir -p $TESTDIR $DBDIR1 $DBDIR2 + +-# NOTE: this could be added to all tests... +-if test "$BACKEND" = "bdb" || test "$BACKEND" = "hdb" ; then +- if test "x$DB_CONFIG" != "x" ; then \ +- if test -f $DB_CONFIG ; then +- echo "==> using DB_CONFIG \"$DB_CONFIG\"" +- cp $DB_CONFIG $DBDIR1 +- cp $DB_CONFIG $DBDIR2 +- else +- echo "==> DB_CONFIG must point to a valid file (ignored)" +- fi +- else +- echo "==> set \"DB_CONFIG\" to the DB_CONFIG file you want to use for the test." +- fi +- echo "" +-fi +- + echo "Starting slapd on TCP/IP port $PORT1..." + . $CONFFILTER $BACKEND $MONITORDB < $METACONF1 > $CONF1 + $SLAPD -f $CONF1 -h $URI1 -d $LVL $TIMING > $LOG1 2>&1 & +diff --git a/tests/scripts/test040-subtree-rename b/tests/scripts/test040-subtree-rename +index 671d626..f1057d6 100755 +--- a/tests/scripts/test040-subtree-rename ++++ b/tests/scripts/test040-subtree-rename +@@ -16,11 +16,6 @@ + echo "running defines.sh" + . $SRCDIR/scripts/defines.sh + +-if test $BACKEND = bdb ; then +- echo "subtree rename not supported by back-$BACKEND" +- exit 0 +-fi +- + mkdir -p $TESTDIR $DBDIR1 + + echo "Starting slapd on TCP/IP port $PORT1..." +diff --git a/tests/scripts/test043-delta-syncrepl b/tests/scripts/test043-delta-syncrepl +index 3c7c629..686bf1c 100755 +--- a/tests/scripts/test043-delta-syncrepl ++++ b/tests/scripts/test043-delta-syncrepl +@@ -32,7 +32,7 @@ fi + + mkdir -p $TESTDIR $DBDIR1A $DBDIR1B $DBDIR2 + +-SPEC="mdb=a,bdb=a,hdb=a" ++SPEC="mdb=a" + + # + # Test replication: +diff --git a/tests/scripts/test052-memberof b/tests/scripts/test052-memberof +index 4b2a5d9..a73a929 100755 +--- a/tests/scripts/test052-memberof ++++ b/tests/scripts/test052-memberof +@@ -72,11 +72,10 @@ EOF + fi + fi + +-indexInclude="" mainInclude="" bdbInclude="# " nullExclude="" ++indexInclude="" mainInclude="" " nullExclude="" + test $INDEXDB = indexdb || indexInclude="# " + test $MAINDB = maindb || mainInclude="# " + case $BACKEND in +-bdb | hdb) bdbInclude="" ;; + null) nullExclude="# " ;; + esac + +@@ -114,7 +113,6 @@ olcRootDN: cn=Manager,$BASEDN + olcRootPW:: c2VjcmV0 + olcMonitoring: TRUE + ${nullExclude}olcDbDirectory: $TESTDIR/db.1.a/ +-${bdbInclude}olcDbCacheSize: 1000 + ${indexInclude}olcDbIndex: objectClass eq + ${indexInclude}olcDbIndex: cn pres,eq,sub + ${indexInclude}olcDbIndex: uid pres,eq,sub +diff --git a/tests/scripts/test056-monitor b/tests/scripts/test056-monitor +index 06713df..7a87eaa 100755 +--- a/tests/scripts/test056-monitor ++++ b/tests/scripts/test056-monitor +@@ -85,8 +85,7 @@ echo "Using ldapsearch to read database monitor entries..." + $LDAPSEARCH -S "" -b "$DATABASESMONITORDN" -h $LOCALHOST -p $PORT1 \ + 'objectclass=*' \ + structuralObjectClass entryDN namingContexts readOnly \ +- monitorIsShadow monitorContext \ +- olmBDBEntryCache olmBDBDNCache olmBDBIDLCache \ ++ monitorIsShadow monitorContext + > $SEARCHOUT 2>&1 + RC=$? + +@@ -101,11 +100,8 @@ $LDIFFILTER -b monitor < $SEARCHOUT > $SEARCHFLT + + TMPMONITOROUT2=$MONITOROUT2 + case $BACKEND in +-bdb|hdb) +- ;; + *) + TMPMONITOROUT2=$TESTDIR/monitor2.out +- grep -v "olmBDB" $MONITOROUT2 > $TMPMONITOROUT2 + ;; + esac + +diff --git a/tests/scripts/test057-memberof-refint b/tests/scripts/test057-memberof-refint +index 5f02a77..ba480f8 100755 +--- a/tests/scripts/test057-memberof-refint ++++ b/tests/scripts/test057-memberof-refint +@@ -27,11 +27,6 @@ if test $REFINT = refintno; then + exit 0 + fi + +-if test $BACKEND = bdb; then +- echo "$BACKEND backend does not support subtree rename, test skipped" +- exit 0 +-fi +- + mkdir -p $TESTDIR $DBDIR1 $TESTDIR/confdir + + $SLAPPASSWD -g -n >$CONFIGPWF +@@ -66,11 +61,10 @@ fi + + cat /dev/null > $TESTOUT + +-indexInclude="" mainInclude="" bdbInclude="# " nullExclude="" ++indexInclude="" mainInclude="" nullExclude="" + test $INDEXDB = indexdb || indexInclude="# " + test $MAINDB = maindb || mainInclude="# " + case $BACKEND in +-bdb | hdb) bdbInclude="" ;; + null) nullExclude="# " ;; + esac + +@@ -104,7 +98,6 @@ olcRootDN: cn=Manager,$BASEDN + olcRootPW:: c2VjcmV0 + olcMonitoring: TRUE + ${nullExclude}olcDbDirectory: $TESTDIR/db.1.a/ +-${bdbInclude}olcDbCacheSize: 1000 + ${indexInclude}olcDbIndex: objectClass eq + ${indexInclude}olcDbIndex: cn pres,eq,sub + ${indexInclude}olcDbIndex: uid pres,eq,sub +diff --git a/tests/scripts/test061-syncreplication-initiation b/tests/scripts/test061-syncreplication-initiation +index 5d27e52..fda7a1b 100755 +--- a/tests/scripts/test061-syncreplication-initiation ++++ b/tests/scripts/test061-syncreplication-initiation +@@ -63,7 +63,6 @@ KILLPIDS= + $SLAPPASSWD -g -n >$CONFIGPWF + + case "$BACKEND" in +- bdb|hdb) olcDbCheckpoint="olcDbCheckpoint";; + *) olcDbCheckpoint="# olcDbCheckpoint";; + esac + +-- +2.19.1 + diff --git a/openldap.spec b/openldap.spec index 965a3df..f7d6932 100644 --- a/openldap.spec +++ b/openldap.spec @@ -2,7 +2,7 @@ Name: openldap Version: 2.4.50 -Release: 5 +Release: 6 Summary: LDAP support libraries License: OpenLDAP URL: https://www.openldap.org/ @@ -57,6 +57,13 @@ Patch36: CVE-2020-36227.patch Patch37: CVE-2020-36228.patch Patch38: CVE-2020-36230.patch Patch39: CVE-2020-36229.patch +Patch40: backport-delete-back-bdb-back-hdb.patch +Patch41: backport-Fix-test-suite.patch +Patch42: backport-ITS-9010-regenerate-configure.patch +Patch43: backport-ITS-9010-More-BDB-HDB-cleanup.patch +Patch44: CVE-2021-27212.patch +Patch45: CVE-2020-25709.patch +Patch46: CVE-2020-25710.patch BuildRequires: cyrus-sasl-devel openssl-devel krb5-devel unixODBC-devel BuildRequires: glibc-devel libtool libtool-ltdl-devel groff perl-interpreter perl-devel perl-generators perl-ExtUtils-Embed @@ -443,6 +450,16 @@ popd %doc ltb-project-openldap-ppolicy-check-password-1.1/README.check_pwd %changelog +* Thu Oct 28 2021 zengweifeng - 2.4.50-6 +- Type:cves +- ID:NA +- SUG:restart +- DESC: fix CVE-2020-25709 CVE-2020-25710 CVE-2021-27212 + delete back-bdb and back-hdb + fix test-suite + cleanup ITS-9010-More-BDB-HDB + regenerate configure of ITS-9010 + * Thu Feb 18 2021 liulong - 2.4.50-5 - Type:cves - ID:NA -- Gitee From 5953fb4ed19861301ea1c98f53eb693aa33e5182 Mon Sep 17 00:00:00 2001 From: zengwefeng Date: Fri, 29 Oct 2021 11:28:23 +0800 Subject: [PATCH 2/3] fix CVE-2020-25709 CVE-2020-25710 CVE-2021-27212 --- backport-Fix-test-suite.patch | 71 - backport-ITS-9010-More-BDB-HDB-cleanup.patch | 406 - backport-ITS-9010-regenerate-configure.patch | 1783 -- backport-delete-back-bdb-back-hdb.patch | 22206 ----------------- openldap.spec | 18 +- 5 files changed, 6 insertions(+), 24478 deletions(-) delete mode 100644 backport-Fix-test-suite.patch delete mode 100644 backport-ITS-9010-More-BDB-HDB-cleanup.patch delete mode 100644 backport-ITS-9010-regenerate-configure.patch delete mode 100644 backport-delete-back-bdb-back-hdb.patch diff --git a/backport-Fix-test-suite.patch b/backport-Fix-test-suite.patch deleted file mode 100644 index cc8f72e..0000000 --- a/backport-Fix-test-suite.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 70f87370f99e78ac3874501bfe5124dbb86185a8 Mon Sep 17 00:00:00 2001 -From: zhangqiumiao -Date: Fri, 25 Sep 2020 21:56:43 +0800 -Subject: [PATCH] backport Fix test suite - ---- - tests/data/monitor2.out | 3 --- - tests/scripts/test052-memberof | 2 +- - tests/scripts/test056-monitor | 11 ++--------- - 3 files changed, 3 insertions(+), 13 deletions(-) - -diff --git a/tests/data/monitor2.out b/tests/data/monitor2.out -index 26e9ce9..20209d1 100644 ---- a/tests/data/monitor2.out -+++ b/tests/data/monitor2.out -@@ -10,9 +10,6 @@ structuralObjectClass: monitoredObject - monitorIsShadow: FALSE - namingContexts: o=OpenLDAP Project,l=Internet - readOnly: FALSE --olmBDBEntryCache: 0 --olmBDBDNCache: 0 --olmBDBIDLCache: 0 - entryDN: cn=Database 1,cn=Databases,cn=Monitor - - dn: cn=Database 2,cn=Databases,cn=Monitor -diff --git a/tests/scripts/test052-memberof b/tests/scripts/test052-memberof -index a73a929..1dba946 100755 ---- a/tests/scripts/test052-memberof -+++ b/tests/scripts/test052-memberof -@@ -72,7 +72,7 @@ EOF - fi - fi - --indexInclude="" mainInclude="" " nullExclude="" -+indexInclude="" mainInclude="" nullExclude="" - test $INDEXDB = indexdb || indexInclude="# " - test $MAINDB = maindb || mainInclude="# " - case $BACKEND in -diff --git a/tests/scripts/test056-monitor b/tests/scripts/test056-monitor -index 7a87eaa..0e1ba20 100755 ---- a/tests/scripts/test056-monitor -+++ b/tests/scripts/test056-monitor -@@ -85,7 +85,7 @@ echo "Using ldapsearch to read database monitor entries..." - $LDAPSEARCH -S "" -b "$DATABASESMONITORDN" -h $LOCALHOST -p $PORT1 \ - 'objectclass=*' \ - structuralObjectClass entryDN namingContexts readOnly \ -- monitorIsShadow monitorContext -+ monitorIsShadow monitorContext \ - > $SEARCHOUT 2>&1 - RC=$? - -@@ -98,15 +98,8 @@ fi - echo "Filtering ldapsearch results..." - $LDIFFILTER -b monitor < $SEARCHOUT > $SEARCHFLT - --TMPMONITOROUT2=$MONITOROUT2 --case $BACKEND in --*) -- TMPMONITOROUT2=$TESTDIR/monitor2.out -- ;; --esac -- - echo "Comparing filter output..." --$CMP $SEARCHFLT $TMPMONITOROUT2 > $CMPOUT -+$CMP $SEARCHFLT $MONITOROUT2 > $CMPOUT - - if test $? != 0 ; then - echo "comparison failed - database monitor output is not correct" --- -2.19.1 - diff --git a/backport-ITS-9010-More-BDB-HDB-cleanup.patch b/backport-ITS-9010-More-BDB-HDB-cleanup.patch deleted file mode 100644 index 9739b8c..0000000 --- a/backport-ITS-9010-More-BDB-HDB-cleanup.patch +++ /dev/null @@ -1,406 +0,0 @@ -From ac37a67536d37ae059ed120f00b540429be6b4e0 Mon Sep 17 00:00:00 2001 -From: zhangqiumiao -Date: Sun, 27 Sep 2020 15:01:05 +0800 -Subject: [PATCH] backport ITS#9010 More BDB/HDB cleanup - ---- - doc/guide/admin/aspell.en.pws | 7 - - tests/data/regressions/its4337/config.out | 129 ------------------ - tests/data/regressions/its4337/its4337 | 157 ---------------------- - tests/data/regressions/its4337/slapd.conf | 36 ----- - 4 files changed, 329 deletions(-) - delete mode 100644 tests/data/regressions/its4337/config.out - delete mode 100755 tests/data/regressions/its4337/its4337 - delete mode 100644 tests/data/regressions/its4337/slapd.conf - -diff --git a/doc/guide/admin/aspell.en.pws b/doc/guide/admin/aspell.en.pws -index ae777e2..ec24572 100644 ---- a/doc/guide/admin/aspell.en.pws -+++ b/doc/guide/admin/aspell.en.pws -@@ -220,8 +220,6 @@ AVAs - associatedDomain - organizationalRole - initgroups --olcDbCachesize --olcDbCacheSize - ETCDIR - colaligns - olcReadOnly -@@ -426,10 +424,8 @@ txt - UTR - XER - roomNumber --olcDbIDLcacheSize - namespace - LDAPControl --dbconfig - olcAttributeOptions - dsaparam - searchResult -@@ -965,7 +961,6 @@ unwillingToPerform - PhotoURI - MyCompany - mkdep --idlcachesize - irresponsive - PasswordModify - readOnly -@@ -1183,7 +1178,6 @@ monitorRuntimeConfig - olcAuditlogFile - namingContexts - referralAttrDN --idlecachesize - moddn - calloc - LDFLAGS -@@ -1375,7 +1369,6 @@ spasswd - sprintf - monitorCounterObject - Instanstantiation --olcDbConfig - olcLastMod - vals - param -diff --git a/tests/data/regressions/its4337/config.out b/tests/data/regressions/its4337/config.out -deleted file mode 100644 -index bdcbbe5..0000000 ---- a/tests/data/regressions/its4337/config.out -+++ /dev/null -@@ -1,129 +0,0 @@ --# Searching databases __before__ append... --dn: olcDatabase={-1}frontend,cn=config --objectClass: olcDatabaseConfig --objectClass: olcFrontendConfig --olcDatabase: {-1}frontend --olcAddContentAcl: FALSE --olcLastMod: TRUE --olcMaxDerefDepth: 0 --olcReadOnly: FALSE --olcSchemaDN: cn=Subschema --olcSyncUseSubentry: FALSE --olcMonitoring: FALSE -- --dn: olcDatabase={0}config,cn=config --objectClass: olcDatabaseConfig --olcDatabase: {0}config --olcAccess: {0}to * by * none --olcAddContentAcl: TRUE --olcLastMod: TRUE --olcMaxDerefDepth: 15 --olcReadOnly: FALSE --olcRootDN: cn=config --olcRootPW: config --olcSyncUseSubentry: FALSE --olcMonitoring: FALSE -- --dn: olcDatabase={1}monitor,cn=config --objectClass: olcDatabaseConfig --olcDatabase: {1}monitor --olcAddContentAcl: FALSE --olcLastMod: TRUE --olcMaxDerefDepth: 15 --olcReadOnly: FALSE --olcSyncUseSubentry: FALSE --olcMonitoring: FALSE -- --# Searching databases __after__ append... --dn: olcDatabase={-1}frontend,cn=config --objectClass: olcDatabaseConfig --objectClass: olcFrontendConfig --olcDatabase: {-1}frontend --olcAddContentAcl: FALSE --olcLastMod: TRUE --olcMaxDerefDepth: 0 --olcReadOnly: FALSE --olcSchemaDN: cn=Subschema --olcSyncUseSubentry: FALSE --olcMonitoring: FALSE -- --dn: olcDatabase={0}config,cn=config --objectClass: olcDatabaseConfig --olcDatabase: {0}config --olcAccess: {0}to * by * none --olcAddContentAcl: TRUE --olcLastMod: TRUE --olcMaxDerefDepth: 15 --olcReadOnly: FALSE --olcRootDN: cn=config --olcRootPW: config --olcSyncUseSubentry: FALSE --olcMonitoring: FALSE -- --dn: olcDatabase={1}monitor,cn=config --objectClass: olcDatabaseConfig --olcDatabase: {1}monitor --olcAddContentAcl: FALSE --olcLastMod: TRUE --olcMaxDerefDepth: 15 --olcReadOnly: FALSE --olcSyncUseSubentry: FALSE --olcMonitoring: FALSE -- --dn: olcDatabase={2}bdb,cn=config --objectClass: olcDatabaseConfig --objectClass: olcBdbConfig --olcDatabase: {2}bdb --olcDbDirectory: ./testrun/db.1.a --olcSuffix: dc=com -- --# Searching databases __after__ insert... --dn: olcDatabase={-1}frontend,cn=config --objectClass: olcDatabaseConfig --objectClass: olcFrontendConfig --olcDatabase: {-1}frontend --olcAddContentAcl: FALSE --olcLastMod: TRUE --olcMaxDerefDepth: 0 --olcReadOnly: FALSE --olcSchemaDN: cn=Subschema --olcSyncUseSubentry: FALSE --olcMonitoring: FALSE -- --dn: olcDatabase={0}config,cn=config --objectClass: olcDatabaseConfig --olcDatabase: {0}config --olcAccess: {0}to * by * none --olcAddContentAcl: TRUE --olcLastMod: TRUE --olcMaxDerefDepth: 15 --olcReadOnly: FALSE --olcRootDN: cn=config --olcRootPW: config --olcSyncUseSubentry: FALSE --olcMonitoring: FALSE -- --dn: olcDatabase={1}bdb,cn=config --objectClass: olcDatabaseConfig --objectClass: olcBdbConfig --olcDatabase: {1}bdb --olcDbDirectory: ./testrun/db.2.a --olcSuffix: dc=org -- --dn: olcDatabase={2}monitor,cn=config --objectClass: olcDatabaseConfig --olcDatabase: {2}monitor --olcAddContentAcl: FALSE --olcLastMod: TRUE --olcMaxDerefDepth: 15 --olcReadOnly: FALSE --olcSyncUseSubentry: FALSE --olcMonitoring: FALSE -- --dn: olcDatabase={3}bdb,cn=config --objectClass: olcDatabaseConfig --objectClass: olcBdbConfig --olcDatabase: {3}bdb --olcDbDirectory: ./testrun/db.1.a --olcSuffix: dc=com -- -diff --git a/tests/data/regressions/its4337/its4337 b/tests/data/regressions/its4337/its4337 -deleted file mode 100755 -index 66bc716..0000000 ---- a/tests/data/regressions/its4337/its4337 -+++ /dev/null -@@ -1,157 +0,0 @@ --#! /bin/sh --# $OpenLDAP$ --## This work is part of OpenLDAP Software . --## --## Copyright 1998-2020 The OpenLDAP Foundation. --## All rights reserved. --## --## Redistribution and use in source and binary forms, with or without --## modification, are permitted only as authorized by the OpenLDAP --## Public License. --## --## A copy of this license is available in the file LICENSE in the --## top-level directory of the distribution or, alternatively, at --## . -- --echo "running defines.sh" --. $SRCDIR/scripts/defines.sh -- --if test $BACKEND != "bdb" ; then -- echo "BDB backend not available, test skipped" -- exit 0 --fi -- --mkdir -p $TESTDIR $DBDIR1 $DBDIR2 $DBDIR3 $TESTDIR/slapd.d -- --ITS=4337 --ITSDIR=$DATADIR/regressions/its$ITS -- --echo "Starting slapd on TCP/IP port $PORT1..." --. $CONFFILTER $BACKEND $MONITORDB < $ITSDIR/slapd.conf > $CONF1 --#$SLAPD -f $CONF1 -F $TESTDIR/slapd.d -h $URI1 -d $LVL $TIMING > $LOG1 2>&1 & --$SLAPD -f $CONF1 -h $URI1 -d $LVL $TIMING > $LOG1 2>&1 & --PID=$! --if test $WAIT != 0 ; then -- echo PID $PID -- read foo --fi --KILLPIDS="$PID" -- --sleep 1 -- --echo "Using ldapsearch to check that slapd is running..." --for i in 0 1 2 3 4 5; do -- $LDAPSEARCH -s base -b "$MONITOR" -h $LOCALHOST -p $PORT1 \ -- 'objectclass=*' > /dev/null 2>&1 -- RC=$? -- if test $RC = 0 ; then -- break -- fi -- echo "Waiting 5 seconds for slapd to start..." -- sleep 5 --done -- --if test $RC != 0 ; then -- echo "ldapsearch failed ($RC)!" -- test $KILLSERVERS != no && kill -HUP $KILLPIDS -- exit $RC --fi -- --cat /dev/null > $TESTOUT --cat /dev/null > $SEARCHOUT -- --echo "Searching databases..." --echo "# Searching databases __before__ append..." >> $SEARCHOUT --$LDAPSEARCH -h $LOCALHOST -p $PORT1 \ -- -D "cn=config" -w "config" -b "cn=config" \ -- '(objectClass=olcDatabaseConfig)' >> $SEARCHOUT 2>> $TESTOUT --RC=$? --if test $RC != 0 ; then -- echo "ldapsearch failed ($RC)!" -- test $KILLSERVERS != no && kill -HUP $KILLPIDS -- exit $RC --fi -- --echo "Appending a database..." --$LDAPADD -v -D "cn=config" -w "config" -h $LOCALHOST -p $PORT1 \ -- >> $TESTOUT 2>&1 << EOMODS --dn: olcDatabase=bdb,cn=config --objectClass: olcDatabaseConfig --objectClass: olcBdbConfig --olcDatabase: bdb --olcSuffix: dc=com --olcDbDirectory: ./testrun/db.1.a --EOMODS --RC=$? --if test $RC != 0 ; then -- echo "ldapadd failed ($RC)!" -- test $KILLSERVERS != no && kill -HUP $KILLPIDS -- exit $RC --fi -- --echo "Searching databases..." --echo "# Searching databases __after__ append..." >> $SEARCHOUT --$LDAPSEARCH -h $LOCALHOST -p $PORT1 \ -- -D "cn=config" -w "config" -b "cn=config" \ -- '(objectClass=olcDatabaseConfig)' >> $SEARCHOUT 2>> $TESTOUT --RC=$? --if test $RC != 0 ; then -- echo "ldapsearch failed ($RC)!" -- test $KILLSERVERS != no && kill -HUP $KILLPIDS -- exit $RC --fi -- --echo "Inserting a database..." --$LDAPADD -v -D "cn=config" -w "config" -h $LOCALHOST -p $PORT1 \ -- >> $TESTOUT 2>&1 << EOMODS --dn: olcDatabase={1}bdb,cn=config --objectClass: olcDatabaseConfig --objectClass: olcBdbConfig --olcDatabase: {1}bdb --olcSuffix: dc=org --olcDbDirectory: ./testrun/db.2.a --EOMODS --RC=$? --if test $RC != 0 ; then -- echo "ldapadd failed ($RC)!" -- test $KILLSERVERS != no && kill -HUP $KILLPIDS -- if test $RC = 53 ; then -- echo "TODO" -- exit 0 -- fi -- exit $RC --fi -- --echo "Searching databases..." --echo "# Searching databases __after__ insert..." >> $SEARCHOUT --$LDAPSEARCH -h $LOCALHOST -p $PORT1 \ -- -D "cn=config" -w "config" -b "cn=config" \ -- '(objectClass=olcDatabaseConfig)' >> $SEARCHOUT 2>> $TESTOUT --RC=$? --if test $RC != 0 ; then -- echo "ldapsearch failed ($RC)!" -- test $KILLSERVERS != no && kill -HUP $KILLPIDS -- exit $RC --fi -- --test $KILLSERVERS != no && kill -HUP $KILLPIDS -- --LDIF=$ITSDIR/config.out -- --echo "Filtering ldapsearch results..." --$LDIFFILTER < $SEARCHOUT > $SEARCHFLT --echo "Filtering original ldif..." --$LDIFFILTER < $LDIF > $LDIFFLT --echo "Comparing filter output..." --$CMP $SEARCHFLT $LDIFFLT > $CMPOUT -- --if test $? != 0 ; then -- echo "Comparison failed" -- exit 1 --fi -- --echo ">>>>> Test succeeded" -- --test $KILLSERVERS != no && wait -- --exit 0 -diff --git a/tests/data/regressions/its4337/slapd.conf b/tests/data/regressions/its4337/slapd.conf -deleted file mode 100644 -index ee3108a..0000000 ---- a/tests/data/regressions/its4337/slapd.conf -+++ /dev/null -@@ -1,36 +0,0 @@ --# stand-alone slapd config -- for testing (with indexing) --# $OpenLDAP$ --## This work is part of OpenLDAP Software . --## --## Copyright 1998-2020 The OpenLDAP Foundation. --## All rights reserved. --## --## Redistribution and use in source and binary forms, with or without --## modification, are permitted only as authorized by the OpenLDAP --## Public License. --## --## A copy of this license is available in the file LICENSE in the --## top-level directory of the distribution or, alternatively, at --## . -- --include @SCHEMADIR@/core.schema --include @SCHEMADIR@/cosine.schema --include @SCHEMADIR@/inetorgperson.schema --include @SCHEMADIR@/openldap.schema --include @SCHEMADIR@/nis.schema --include @DATADIR@/test.schema -- --# --pidfile @TESTDIR@/slapd.2.pid --argsfile @TESTDIR@/slapd.2.args -- --#mod#modulepath ../servers/slapd/back-@BACKEND@/:../servers/slapd/overlays --#mod#moduleload back_@BACKEND@.la -- --#monitormod#modulepath ../servers/slapd/back-monitor/ --#monitormod#moduleload back_monitor.la -- --database config --rootpw config -- --#monitor#database monitor --- -2.19.1 - diff --git a/backport-ITS-9010-regenerate-configure.patch b/backport-ITS-9010-regenerate-configure.patch deleted file mode 100644 index 1ec1ee1..0000000 --- a/backport-ITS-9010-regenerate-configure.patch +++ /dev/null @@ -1,1783 +0,0 @@ -From 14c7c8f3579a8c0a802aaac72841efed3d01445f Mon Sep 17 00:00:00 2001 -From: zhangqiumiao -Date: Sun, 27 Sep 2020 14:25:21 +0800 -Subject: [PATCH] backport ITS#9010 regenerate configure - ---- - configure | 1565 +++++------------------------------------------------ - 1 file changed, 148 insertions(+), 1417 deletions(-) - -diff --git a/configure b/configure -index 5f05f1c..5c5097a 100755 ---- a/configure -+++ b/configure -@@ -667,7 +667,6 @@ LUTIL_LIBS - LTHREAD_LIBS - SLAPD_NDB_INCS - SLAPD_NDB_LIBS --BDB_LIBS - SLAPD_LIBS - LDAP_LIBS - BUILD_VALSORT -@@ -704,9 +703,7 @@ BUILD_MONITOR - BUILD_META - BUILD_MDB - BUILD_LDAP --BUILD_HDB - BUILD_DNSSRV --BUILD_BDB - SLAPD_SLAPI_DEPEND - BUILD_SLAPI - BUILD_SLAPD -@@ -764,6 +761,7 @@ DLLTOOL - AS - AR - CC -+moduledir - ldap_subdir - top_builddir - OPENLDAP_RELEASE_DATE -@@ -852,6 +850,7 @@ ac_user_opts=' - enable_option_checking - enable_silent_rules - with_subdir -+with_moduledir - enable_debug - enable_dynamic - enable_syslog -@@ -881,9 +880,7 @@ enable_slp - enable_wrappers - enable_xxslapbackends - enable_backends --enable_bdb - enable_dnssrv --enable_hdb - enable_ldap - enable_mdb - enable_meta -@@ -1583,9 +1580,7 @@ SLAPD (Standalone LDAP Daemon) Options: - - SLAPD Backend Options: - --enable-backends enable all available backends no|yes|mod -- --enable-bdb enable Berkeley DB backend no|yes|mod [yes] - --enable-dnssrv enable dnssrv backend no|yes|mod [no] -- --enable-hdb enable Hierarchical DB backend no|yes|mod [yes] - --enable-ldap enable ldap backend no|yes|mod [no] - --enable-mdb enable mdb database backend no|yes|mod [yes] - --enable-meta enable metadirectory backend no|yes|mod [no] -@@ -1637,6 +1632,7 @@ Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-subdir=DIR change default subdirectory used for installs -+ --with-moduledir=DIR change default module subdirectory used for installs - --with-cyrus-sasl with Cyrus SASL support [auto] - --with-fetch with fetch(3) URL support [auto] - --with-threads with threads [auto] -@@ -3570,6 +3566,24 @@ esac - fi - - -+ -+moduledir="openldap" -+ -+ -+# Check whether --with-moduledir was given. -+if test "${with_moduledir+set}" = set; then : -+ withval=$with_moduledir; case "$withval" in -+ no) moduledir="" -+ ;; -+ yes) -+ ;; -+ *) -+ moduledir="$withval" -+ ;; -+esac -+ -+fi -+ - # OpenLDAP --enable-debug - - # Check whether --enable-debug was given. -@@ -4126,9 +4140,7 @@ fi - - # end --enable-wrappers - --Backends="bdb \ -- dnssrv \ -- hdb \ -+Backends="dnssrv \ - ldap \ - mdb \ - meta \ -@@ -4167,27 +4179,6 @@ if test "${enable_backends+set}" = set; then : - fi - - # end --enable-backends --# OpenLDAP --enable-bdb -- -- # Check whether --enable-bdb was given. --if test "${enable_bdb+set}" = set; then : -- enableval=$enable_bdb; -- ol_arg=invalid -- for ol_val in no yes mod ; do -- if test "$enableval" = "$ol_val" ; then -- ol_arg="$ol_val" -- fi -- done -- if test "$ol_arg" = "invalid" ; then -- as_fn_error $? "bad value $enableval for --enable-bdb" "$LINENO" 5 -- fi -- ol_enable_bdb="$ol_arg" -- --else -- ol_enable_bdb=${ol_enable_backends:-yes} --fi -- --# end --enable-bdb - # OpenLDAP --enable-dnssrv - - # Check whether --enable-dnssrv was given. -@@ -4209,27 +4200,6 @@ else - fi - - # end --enable-dnssrv --# OpenLDAP --enable-hdb -- -- # Check whether --enable-hdb was given. --if test "${enable_hdb+set}" = set; then : -- enableval=$enable_hdb; -- ol_arg=invalid -- for ol_val in no yes mod ; do -- if test "$enableval" = "$ol_val" ; then -- ol_arg="$ol_val" -- fi -- done -- if test "$ol_arg" = "invalid" ; then -- as_fn_error $? "bad value $enableval for --enable-hdb" "$LINENO" 5 -- fi -- ol_enable_hdb="$ol_arg" -- --else -- ol_enable_hdb=${ol_enable_backends:-yes} --fi -- --# end --enable-hdb - # OpenLDAP --enable-ldap - - # Check whether --enable-ldap was given. -@@ -5108,9 +5078,7 @@ $as_echo "$as_me: WARNING: slapd disabled, ignoring --enable-$i argument" >&2;} - ol_enable_rewrite=no - - elif test $ol_enable_modules != yes && -- test $ol_enable_bdb = no && - test $ol_enable_dnssrv = no && -- test $ol_enable_hdb = no && - test $ol_enable_ldap = no && - test $ol_enable_mdb = no && - test $ol_enable_meta = no && -@@ -5150,11 +5118,22 @@ if test $ol_enable_spasswd = yes ; then - ol_with_cyrus_sasl=yes - fi - -+ - { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 - $as_echo "done" >&6; } - -+case $moduledir in -+ /*|\\*) -+ ;; -+ *) -+ moduledir=$libexecdir/$moduledir -+ ;; -+esac -+ -+ -+ -+ - LDAP_LIBS= --BDB_LIBS= - SLAPD_NDB_LIBS= - SLAPD_NDB_INCS= - LTHREAD_LIBS= -@@ -5169,9 +5148,7 @@ BUILD_THREAD=no - BUILD_SLAPI=no - SLAPD_SLAPI_DEPEND= - --BUILD_BDB=no - BUILD_DNSSRV=no --BUILD_HDB=no - BUILD_LDAP=no - BUILD_MDB=no - BUILD_META=no -@@ -22937,1388 +22914,178 @@ else - ol_cv_func_gethostbyaddr_r_nargs=0 - fi - --ol_link_bdb=no - --if test $ol_enable_bdb/$ol_enable_hdb != no/no; then -- ol_cv_berkeley_db=no --for ac_header in db.h --do : -- ac_fn_c_check_header_mongrel "$LINENO" "db.h" "ac_cv_header_db_h" "$ac_includes_default" --if test "x$ac_cv_header_db_h" = xyes; then : -- cat >>confdefs.h <<_ACEOF --#define HAVE_DB_H 1 --_ACEOF -- --fi -- --done -- --if test $ac_cv_header_db_h = yes; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB major version in db.h" >&5 --$as_echo_n "checking for Berkeley DB major version in db.h... " >&6; } --if ${ol_cv_bdb_major+:} false; then : -- $as_echo_n "(cached) " >&6 -+if test $ol_enable_dynamic = yes && test $enable_shared = yes ; then -+ BUILD_LIBS_DYNAMIC=shared -+ $as_echo "#define LDAP_LIBS_DYNAMIC 1" >>confdefs.h -+ LTSTATIC="" - else -- -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --#include --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif --__db_version DB_VERSION_MAJOR -- --_ACEOF -- set X `eval "$ac_cpp -P conftest.$ac_ext" | $EGREP __db_version` none none -- ol_cv_bdb_major=${3} -- -+ BUILD_LIBS_DYNAMIC=static -+ LTSTATIC="-static" - fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_bdb_major" >&5 --$as_echo "$ol_cv_bdb_major" >&6; } --case $ol_cv_bdb_major in [1-9]*) : ;; *) -- as_fn_error $? "Unknown Berkeley DB major version in db.h" "$LINENO" 5 ;; --esac -- --{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB minor version in db.h" >&5 --$as_echo_n "checking for Berkeley DB minor version in db.h... " >&6; } --if ${ol_cv_bdb_minor+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --#include --#ifndef DB_VERSION_MINOR --# define DB_VERSION_MINOR 0 --#endif --__db_version DB_VERSION_MINOR - -+if test $ol_enable_wrappers != no ; then -+ for ac_header in tcpd.h -+do : -+ ac_fn_c_check_header_mongrel "$LINENO" "tcpd.h" "ac_cv_header_tcpd_h" "$ac_includes_default" -+if test "x$ac_cv_header_tcpd_h" = x""yes; then : -+ cat >>confdefs.h <<_ACEOF -+#define HAVE_TCPD_H 1 - _ACEOF -- set X `eval "$ac_cpp -P conftest.$ac_ext" | $EGREP __db_version` none none -- ol_cv_bdb_minor=${3} -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_bdb_minor" >&5 --$as_echo "$ol_cv_bdb_minor" >&6; } --case $ol_cv_bdb_minor in [0-9]*) : ;; *) -- as_fn_error $? "Unknown Berkeley DB minor version in db.h" "$LINENO" 5 ;; --esac - -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Berkeley DB version supported by BDB/HDB backends" >&5 --$as_echo_n "checking if Berkeley DB version supported by BDB/HDB backends... " >&6; } --if ${ol_cv_bdb_compat+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TCP wrappers library" >&5 -+$as_echo_n "checking for TCP wrappers library... " >&6; } -+ save_LIBS="$LIBS" -+ LIBS="$LIBS -lwrap" -+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext - /* end confdefs.h. */ - --#include -+#include -+int allow_severity = 0; -+int deny_severity = 0; - -- /* this check could be improved */ --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif --#ifndef DB_VERSION_MINOR --# define DB_VERSION_MINOR 0 --#endif --#ifndef DB_VERSION_PATCH --# define DB_VERSION_PATCH 0 --#endif -+struct request_info *req; - --#define DB_VERSION_FULL ((DB_VERSION_MAJOR<<16)|(DB_VERSION_MINOR<<8)|DB_VERSION_PATCH) -+int -+main () -+{ - --/* require 4.4 or later, but less than 6.0.20 */ --#if DB_VERSION_FULL >= 0x040400 && DB_VERSION_FULL < 0x060014 -- __db_version_compat --#endif --#if DB_VERSION_FULL >= 0x060014 --#error "BerkeleyDB 6.0.20+ license is incompatible with LDAP" --#endif -+hosts_access(req) - -+ ; -+ return 0; -+} - _ACEOF --if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | -- $EGREP "__db_version_compat" >/dev/null 2>&1; then : -- ol_cv_bdb_compat=yes --else -- ol_cv_bdb_compat=no --fi --rm -f conftest* -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_bdb_compat" >&5 --$as_echo "$ol_cv_bdb_compat" >&6; } -- -- -- if test $ol_cv_bdb_compat != yes ; then -- as_fn_error $? "BerkeleyDB version incompatible with BDB/HDB backends" "$LINENO" 5 -- fi -- -- ol_cv_lib_db=no -- --if test $ol_cv_bdb_major = 5 ; then -- if test $ol_cv_lib_db = no ; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb-5.$ol_cv_bdb_minor)" >&5 --$as_echo_n "checking for Berkeley DB link (-ldb-5.$ol_cv_bdb_minor)... " >&6; } --if ${ol_cv_db_db_5_dot_m+:} false; then : -- $as_echo_n "(cached) " >&6 -+if ac_fn_c_try_link "$LINENO"; then : -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: -lwrap" >&5 -+$as_echo "-lwrap" >&6; } -+ have_wrappers=yes -+ LIBS="$save_LIBS" - else -- -- ol_DB_LIB=-ldb-5.$ol_cv_bdb_minor -- ol_LIBS=$LIBS -- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" -- -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+ LIBS="$LIBS -lnsl" -+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext - /* end confdefs.h. */ - --#ifdef HAVE_DB_185_H --# include --#else --# include --#endif -- --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif -+#include -+int allow_severity = 0; -+int deny_severity = 0; - --#ifndef NULL --#define NULL ((void*)0) --#endif -+struct request_info *req; - - int - main () - { - --#if DB_VERSION_MAJOR > 2 -- db_env_create( NULL, 0 ); --#elif DB_VERSION_MAJOR > 1 -- db_appexit( NULL ); --#else -- (void) dbopen( NULL, 0, 0, 0, NULL); --#endif -+hosts_access(req) - - ; - return 0; - } - _ACEOF - if ac_fn_c_try_link "$LINENO"; then : -- ol_cv_db_db_5_dot_m=yes -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: -lwrap -lnsl" >&5 -+$as_echo "-lwrap -lnsl" >&6; } -+ have_wrappers=yes -+ LIBS="$save_LIBS -lnsl" - else -- ol_cv_db_db_5_dot_m=no -+ -+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -+$as_echo "no" >&6; } -+ have_wrappers=no -+ LIBS=$save_LIBS - fi - rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -- -- LIBS="$ol_LIBS" -- - fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db_5_dot_m" >&5 --$as_echo "$ol_cv_db_db_5_dot_m" >&6; } -- -- if test $ol_cv_db_db_5_dot_m = yes ; then -- ol_cv_lib_db=-ldb-5.$ol_cv_bdb_minor -- fi -+rm -f core conftest.err conftest.$ac_objext \ -+ conftest$ac_exeext conftest.$ac_ext -+else -+ have_wrappers=no - fi - -- if test $ol_cv_lib_db = no ; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb5$ol_cv_bdb_minor)" >&5 --$as_echo_n "checking for Berkeley DB link (-ldb5$ol_cv_bdb_minor)... " >&6; } --if ${ol_cv_db_db5m+:} false; then : -- $as_echo_n "(cached) " >&6 --else -+done - -- ol_DB_LIB=-ldb5$ol_cv_bdb_minor -- ol_LIBS=$LIBS -- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" - -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -+ if test $have_wrappers = yes ; then - --#ifdef HAVE_DB_185_H --# include --#else --# include --#endif -+$as_echo "#define HAVE_TCPD 1" >>confdefs.h - --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif -+ WRAP_LIBS="-lwrap" -+ elif test $ol_enable_wrappers = yes ; then -+ as_fn_error "could not find TCP wrappers, select appropriate options or disable" "$LINENO" 5 -+ else -+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: could not find TCP wrappers, support disabled" >&5 -+$as_echo "$as_me: WARNING: could not find TCP wrappers, support disabled" >&2;} -+ WRAP_LIBS="" -+ fi -+fi - --#ifndef NULL --#define NULL ((void*)0) --#endif -+if test $ol_enable_syslog != no ; then -+ ac_fn_c_check_func "$LINENO" "openlog" "ac_cv_func_openlog" -+if test "x$ac_cv_func_openlog" = x""yes; then : - --int --main () --{ -+fi - --#if DB_VERSION_MAJOR > 2 -- db_env_create( NULL, 0 ); --#elif DB_VERSION_MAJOR > 1 -- db_appexit( NULL ); --#else -- (void) dbopen( NULL, 0, 0, 0, NULL); --#endif -+ if test $ac_cv_func_openlog = no && test $ol_enable_syslog = yes; then -+ { as_fn_set_status select appropriate options or disable -+as_fn_error "could not find syslog" "$LINENO" 5; } -+ fi -+ ol_enable_syslog=$ac_cv_func_openlog -+fi - -- ; -- return 0; --} -+ol_link_sql=no -+if test $ol_enable_sql != no ; then -+ for ac_header in sql.h sqlext.h -+do : -+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -+eval as_val=\$$as_ac_Header -+ if test "x$as_val" = x""yes; then : -+ cat >>confdefs.h <<_ACEOF -+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 - _ACEOF --if ac_fn_c_try_link "$LINENO"; then : -- ol_cv_db_db5m=yes -+ - else -- ol_cv_db_db5m=no --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext - -- LIBS="$ol_LIBS" -+ as_fn_error "could not locate SQL headers" "$LINENO" 5 - - fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db5m" >&5 --$as_echo "$ol_cv_db_db5m" >&6; } - -- if test $ol_cv_db_db5m = yes ; then -- ol_cv_lib_db=-ldb5$ol_cv_bdb_minor -+done -+ -+ -+ sql_LIBS="$LIBS" -+ LIBS="$LTHREAD_LIBS $LIBS" -+ -+ if test $ol_with_odbc = auto ; then -+ ol_with_odbc="iodbc unixodbc odbc32" - fi --fi - -- if test $ol_cv_lib_db = no ; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb-5$ol_cv_bdb_minor)" >&5 --$as_echo_n "checking for Berkeley DB link (-ldb-5$ol_cv_bdb_minor)... " >&6; } --if ${ol_cv_db_db_5m+:} false; then : -+ for odbc in $ol_with_odbc ; do -+ if test $ol_link_sql = no ; then -+ case $odbc in -+ iodbc) -+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SQLDriverConnect in -liodbc" >&5 -+$as_echo_n "checking for SQLDriverConnect in -liodbc... " >&6; } -+if test "${ac_cv_lib_iodbc_SQLDriverConnect+set}" = set; then : - $as_echo_n "(cached) " >&6 - else -- -- ol_DB_LIB=-ldb-5$ol_cv_bdb_minor -- ol_LIBS=$LIBS -- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" -- -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext -+ ac_check_lib_save_LIBS=$LIBS -+LIBS="-liodbc $LIBS" -+cat confdefs.h - <<_ACEOF >conftest.$ac_ext - /* end confdefs.h. */ - --#ifdef HAVE_DB_185_H --# include --#else --# include --#endif -- --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif -- --#ifndef NULL --#define NULL ((void*)0) -+/* Override any GCC internal prototype to avoid an error. -+ Use char because int might match the return type of a GCC -+ builtin and then its argument prototype would still apply. */ -+#ifdef __cplusplus -+extern "C" - #endif -- -+char SQLDriverConnect (); - int - main () - { -- --#if DB_VERSION_MAJOR > 2 -- db_env_create( NULL, 0 ); --#elif DB_VERSION_MAJOR > 1 -- db_appexit( NULL ); --#else -- (void) dbopen( NULL, 0, 0, 0, NULL); --#endif -- -- ; -- return 0; --} --_ACEOF --if ac_fn_c_try_link "$LINENO"; then : -- ol_cv_db_db_5m=yes --else -- ol_cv_db_db_5m=no --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext -- -- LIBS="$ol_LIBS" -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db_5m" >&5 --$as_echo "$ol_cv_db_db_5m" >&6; } -- -- if test $ol_cv_db_db_5m = yes ; then -- ol_cv_lib_db=-ldb-5$ol_cv_bdb_minor -- fi --fi -- -- if test $ol_cv_lib_db = no ; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb-5-$ol_cv_bdb_minor)" >&5 --$as_echo_n "checking for Berkeley DB link (-ldb-5-$ol_cv_bdb_minor)... " >&6; } --if ${ol_cv_db_db_5_m+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- -- ol_DB_LIB=-ldb-5-$ol_cv_bdb_minor -- ol_LIBS=$LIBS -- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" -- -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --#ifdef HAVE_DB_185_H --# include --#else --# include --#endif -- --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif -- --#ifndef NULL --#define NULL ((void*)0) --#endif -- --int --main () --{ -- --#if DB_VERSION_MAJOR > 2 -- db_env_create( NULL, 0 ); --#elif DB_VERSION_MAJOR > 1 -- db_appexit( NULL ); --#else -- (void) dbopen( NULL, 0, 0, 0, NULL); --#endif -- -- ; -- return 0; --} --_ACEOF --if ac_fn_c_try_link "$LINENO"; then : -- ol_cv_db_db_5_m=yes --else -- ol_cv_db_db_5_m=no --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext -- -- LIBS="$ol_LIBS" -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db_5_m" >&5 --$as_echo "$ol_cv_db_db_5_m" >&6; } -- -- if test $ol_cv_db_db_5_m = yes ; then -- ol_cv_lib_db=-ldb-5-$ol_cv_bdb_minor -- fi --fi -- -- if test $ol_cv_lib_db = no ; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb-5)" >&5 --$as_echo_n "checking for Berkeley DB link (-ldb-5)... " >&6; } --if ${ol_cv_db_db_5+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- -- ol_DB_LIB=-ldb-5 -- ol_LIBS=$LIBS -- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" -- -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --#ifdef HAVE_DB_185_H --# include --#else --# include --#endif -- --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif -- --#ifndef NULL --#define NULL ((void*)0) --#endif -- --int --main () --{ -- --#if DB_VERSION_MAJOR > 2 -- db_env_create( NULL, 0 ); --#elif DB_VERSION_MAJOR > 1 -- db_appexit( NULL ); --#else -- (void) dbopen( NULL, 0, 0, 0, NULL); --#endif -- -- ; -- return 0; --} --_ACEOF --if ac_fn_c_try_link "$LINENO"; then : -- ol_cv_db_db_5=yes --else -- ol_cv_db_db_5=no --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext -- -- LIBS="$ol_LIBS" -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db_5" >&5 --$as_echo "$ol_cv_db_db_5" >&6; } -- -- if test $ol_cv_db_db_5 = yes ; then -- ol_cv_lib_db=-ldb-5 -- fi --fi -- -- if test $ol_cv_lib_db = no ; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb5)" >&5 --$as_echo_n "checking for Berkeley DB link (-ldb5)... " >&6; } --if ${ol_cv_db_db5+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- -- ol_DB_LIB=-ldb5 -- ol_LIBS=$LIBS -- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" -- -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --#ifdef HAVE_DB_185_H --# include --#else --# include --#endif -- --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif -- --#ifndef NULL --#define NULL ((void*)0) --#endif -- --int --main () --{ -- --#if DB_VERSION_MAJOR > 2 -- db_env_create( NULL, 0 ); --#elif DB_VERSION_MAJOR > 1 -- db_appexit( NULL ); --#else -- (void) dbopen( NULL, 0, 0, 0, NULL); --#endif -- -- ; -- return 0; --} --_ACEOF --if ac_fn_c_try_link "$LINENO"; then : -- ol_cv_db_db5=yes --else -- ol_cv_db_db5=no --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext -- -- LIBS="$ol_LIBS" -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db5" >&5 --$as_echo "$ol_cv_db_db5" >&6; } -- -- if test $ol_cv_db_db5 = yes ; then -- ol_cv_lib_db=-ldb5 -- fi --fi -- --elif test $ol_cv_bdb_major = 4 ; then -- if test $ol_cv_lib_db = no ; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb-4.$ol_cv_bdb_minor)" >&5 --$as_echo_n "checking for Berkeley DB link (-ldb-4.$ol_cv_bdb_minor)... " >&6; } --if ${ol_cv_db_db_4_dot_m+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- -- ol_DB_LIB=-ldb-4.$ol_cv_bdb_minor -- ol_LIBS=$LIBS -- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" -- -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --#ifdef HAVE_DB_185_H --# include --#else --# include --#endif -- --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif -- --#ifndef NULL --#define NULL ((void*)0) --#endif -- --int --main () --{ -- --#if DB_VERSION_MAJOR > 2 -- db_env_create( NULL, 0 ); --#elif DB_VERSION_MAJOR > 1 -- db_appexit( NULL ); --#else -- (void) dbopen( NULL, 0, 0, 0, NULL); --#endif -- -- ; -- return 0; --} --_ACEOF --if ac_fn_c_try_link "$LINENO"; then : -- ol_cv_db_db_4_dot_m=yes --else -- ol_cv_db_db_4_dot_m=no --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext -- -- LIBS="$ol_LIBS" -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db_4_dot_m" >&5 --$as_echo "$ol_cv_db_db_4_dot_m" >&6; } -- -- if test $ol_cv_db_db_4_dot_m = yes ; then -- ol_cv_lib_db=-ldb-4.$ol_cv_bdb_minor -- fi --fi -- -- if test $ol_cv_lib_db = no ; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb4$ol_cv_bdb_minor)" >&5 --$as_echo_n "checking for Berkeley DB link (-ldb4$ol_cv_bdb_minor)... " >&6; } --if ${ol_cv_db_db4m+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- -- ol_DB_LIB=-ldb4$ol_cv_bdb_minor -- ol_LIBS=$LIBS -- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" -- -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --#ifdef HAVE_DB_185_H --# include --#else --# include --#endif -- --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif -- --#ifndef NULL --#define NULL ((void*)0) --#endif -- --int --main () --{ -- --#if DB_VERSION_MAJOR > 2 -- db_env_create( NULL, 0 ); --#elif DB_VERSION_MAJOR > 1 -- db_appexit( NULL ); --#else -- (void) dbopen( NULL, 0, 0, 0, NULL); --#endif -- -- ; -- return 0; --} --_ACEOF --if ac_fn_c_try_link "$LINENO"; then : -- ol_cv_db_db4m=yes --else -- ol_cv_db_db4m=no --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext -- -- LIBS="$ol_LIBS" -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db4m" >&5 --$as_echo "$ol_cv_db_db4m" >&6; } -- -- if test $ol_cv_db_db4m = yes ; then -- ol_cv_lib_db=-ldb4$ol_cv_bdb_minor -- fi --fi -- -- if test $ol_cv_lib_db = no ; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb-4$ol_cv_bdb_minor)" >&5 --$as_echo_n "checking for Berkeley DB link (-ldb-4$ol_cv_bdb_minor)... " >&6; } --if ${ol_cv_db_db_4m+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- -- ol_DB_LIB=-ldb-4$ol_cv_bdb_minor -- ol_LIBS=$LIBS -- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" -- -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --#ifdef HAVE_DB_185_H --# include --#else --# include --#endif -- --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif -- --#ifndef NULL --#define NULL ((void*)0) --#endif -- --int --main () --{ -- --#if DB_VERSION_MAJOR > 2 -- db_env_create( NULL, 0 ); --#elif DB_VERSION_MAJOR > 1 -- db_appexit( NULL ); --#else -- (void) dbopen( NULL, 0, 0, 0, NULL); --#endif -- -- ; -- return 0; --} --_ACEOF --if ac_fn_c_try_link "$LINENO"; then : -- ol_cv_db_db_4m=yes --else -- ol_cv_db_db_4m=no --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext -- -- LIBS="$ol_LIBS" -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db_4m" >&5 --$as_echo "$ol_cv_db_db_4m" >&6; } -- -- if test $ol_cv_db_db_4m = yes ; then -- ol_cv_lib_db=-ldb-4$ol_cv_bdb_minor -- fi --fi -- -- if test $ol_cv_lib_db = no ; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb-4-$ol_cv_bdb_minor)" >&5 --$as_echo_n "checking for Berkeley DB link (-ldb-4-$ol_cv_bdb_minor)... " >&6; } --if ${ol_cv_db_db_4_m+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- -- ol_DB_LIB=-ldb-4-$ol_cv_bdb_minor -- ol_LIBS=$LIBS -- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" -- -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --#ifdef HAVE_DB_185_H --# include --#else --# include --#endif -- --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif -- --#ifndef NULL --#define NULL ((void*)0) --#endif -- --int --main () --{ -- --#if DB_VERSION_MAJOR > 2 -- db_env_create( NULL, 0 ); --#elif DB_VERSION_MAJOR > 1 -- db_appexit( NULL ); --#else -- (void) dbopen( NULL, 0, 0, 0, NULL); --#endif -- -- ; -- return 0; --} --_ACEOF --if ac_fn_c_try_link "$LINENO"; then : -- ol_cv_db_db_4_m=yes --else -- ol_cv_db_db_4_m=no --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext -- -- LIBS="$ol_LIBS" -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db_4_m" >&5 --$as_echo "$ol_cv_db_db_4_m" >&6; } -- -- if test $ol_cv_db_db_4_m = yes ; then -- ol_cv_lib_db=-ldb-4-$ol_cv_bdb_minor -- fi --fi -- -- if test $ol_cv_lib_db = no ; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb-4)" >&5 --$as_echo_n "checking for Berkeley DB link (-ldb-4)... " >&6; } --if ${ol_cv_db_db_4+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- -- ol_DB_LIB=-ldb-4 -- ol_LIBS=$LIBS -- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" -- -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --#ifdef HAVE_DB_185_H --# include --#else --# include --#endif -- --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif -- --#ifndef NULL --#define NULL ((void*)0) --#endif -- --int --main () --{ -- --#if DB_VERSION_MAJOR > 2 -- db_env_create( NULL, 0 ); --#elif DB_VERSION_MAJOR > 1 -- db_appexit( NULL ); --#else -- (void) dbopen( NULL, 0, 0, 0, NULL); --#endif -- -- ; -- return 0; --} --_ACEOF --if ac_fn_c_try_link "$LINENO"; then : -- ol_cv_db_db_4=yes --else -- ol_cv_db_db_4=no --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext -- -- LIBS="$ol_LIBS" -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db_4" >&5 --$as_echo "$ol_cv_db_db_4" >&6; } -- -- if test $ol_cv_db_db_4 = yes ; then -- ol_cv_lib_db=-ldb-4 -- fi --fi -- -- if test $ol_cv_lib_db = no ; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb4)" >&5 --$as_echo_n "checking for Berkeley DB link (-ldb4)... " >&6; } --if ${ol_cv_db_db4+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- -- ol_DB_LIB=-ldb4 -- ol_LIBS=$LIBS -- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" -- -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --#ifdef HAVE_DB_185_H --# include --#else --# include --#endif -- --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif -- --#ifndef NULL --#define NULL ((void*)0) --#endif -- --int --main () --{ -- --#if DB_VERSION_MAJOR > 2 -- db_env_create( NULL, 0 ); --#elif DB_VERSION_MAJOR > 1 -- db_appexit( NULL ); --#else -- (void) dbopen( NULL, 0, 0, 0, NULL); --#endif -- -- ; -- return 0; --} --_ACEOF --if ac_fn_c_try_link "$LINENO"; then : -- ol_cv_db_db4=yes --else -- ol_cv_db_db4=no --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext -- -- LIBS="$ol_LIBS" -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db4" >&5 --$as_echo "$ol_cv_db_db4" >&6; } -- -- if test $ol_cv_db_db4 = yes ; then -- ol_cv_lib_db=-ldb4 -- fi --fi -- --fi --if test $ol_cv_lib_db = no ; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (-ldb)" >&5 --$as_echo_n "checking for Berkeley DB link (-ldb)... " >&6; } --if ${ol_cv_db_db+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- -- ol_DB_LIB=-ldb -- ol_LIBS=$LIBS -- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" -- -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --#ifdef HAVE_DB_185_H --# include --#else --# include --#endif -- --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif -- --#ifndef NULL --#define NULL ((void*)0) --#endif -- --int --main () --{ -- --#if DB_VERSION_MAJOR > 2 -- db_env_create( NULL, 0 ); --#elif DB_VERSION_MAJOR > 1 -- db_appexit( NULL ); --#else -- (void) dbopen( NULL, 0, 0, 0, NULL); --#endif -- -- ; -- return 0; --} --_ACEOF --if ac_fn_c_try_link "$LINENO"; then : -- ol_cv_db_db=yes --else -- ol_cv_db_db=no --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext -- -- LIBS="$ol_LIBS" -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_db" >&5 --$as_echo "$ol_cv_db_db" >&6; } -- -- if test $ol_cv_db_db = yes ; then -- ol_cv_lib_db=-ldb -- fi --fi -- --if test $ol_cv_lib_db = no ; then -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB link (default)" >&5 --$as_echo_n "checking for Berkeley DB link (default)... " >&6; } --if ${ol_cv_db_none+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- -- ol_DB_LIB= -- ol_LIBS=$LIBS -- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" -- -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --#ifdef HAVE_DB_185_H --# include --#else --# include --#endif -- --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif -- --#ifndef NULL --#define NULL ((void*)0) --#endif -- --int --main () --{ -- --#if DB_VERSION_MAJOR > 2 -- db_env_create( NULL, 0 ); --#elif DB_VERSION_MAJOR > 1 -- db_appexit( NULL ); --#else -- (void) dbopen( NULL, 0, 0, 0, NULL); --#endif -- -- ; -- return 0; --} --_ACEOF --if ac_fn_c_try_link "$LINENO"; then : -- ol_cv_db_none=yes --else -- ol_cv_db_none=no --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext -- -- LIBS="$ol_LIBS" -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_db_none" >&5 --$as_echo "$ol_cv_db_none" >&6; } -- -- if test $ol_cv_db_none = yes ; then -- ol_cv_lib_db=yes -- fi --fi -- -- -- if test "$ol_cv_lib_db" != no ; then -- ol_cv_berkeley_db=yes -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB library and header version match" >&5 --$as_echo_n "checking for Berkeley DB library and header version match... " >&6; } --if ${ol_cv_berkeley_db_version+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- -- ol_LIBS="$LIBS" -- LIBS="$LTHREAD_LIBS $LIBS" -- if test $ol_cv_lib_db != yes ; then -- LIBS="$ol_cv_lib_db $LIBS" -- fi -- -- if test "$cross_compiling" = yes; then : -- ol_cv_berkeley_db_version=cross --else -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --#ifdef HAVE_DB_185_H -- choke me; --#else --#include --#endif --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif --#ifndef NULL --#define NULL ((void *)0) --#endif --main() --{ --#if DB_VERSION_MAJOR > 1 -- char *version; -- int major, minor, patch; -- -- version = db_version( &major, &minor, &patch ); -- -- if( major != DB_VERSION_MAJOR || -- minor != DB_VERSION_MINOR || -- patch != DB_VERSION_PATCH ) -- { -- printf("Berkeley DB version mismatch\n" -- "\theader: %s\n\tlibrary: %s\n", -- DB_VERSION_STRING, version); -- return 1; -- } --#endif -- -- return 0; --} --_ACEOF --if ac_fn_c_try_run "$LINENO"; then : -- ol_cv_berkeley_db_version=yes --else -- ol_cv_berkeley_db_version=no --fi --rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ -- conftest.$ac_objext conftest.beam conftest.$ac_ext --fi -- -- -- LIBS="$ol_LIBS" -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_berkeley_db_version" >&5 --$as_echo "$ol_cv_berkeley_db_version" >&6; } -- -- if test $ol_cv_berkeley_db_version = no ; then -- as_fn_error $? "Berkeley DB version mismatch" "$LINENO" 5 -- fi -- -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Berkeley DB thread support" >&5 --$as_echo_n "checking for Berkeley DB thread support... " >&6; } --if ${ol_cv_berkeley_db_thread+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- -- ol_LIBS="$LIBS" -- LIBS="$LTHREAD_LIBS $LIBS" -- if test $ol_cv_lib_db != yes ; then -- LIBS="$ol_cv_lib_db $LIBS" -- fi -- -- if test "$cross_compiling" = yes; then : -- ol_cv_berkeley_db_thread=cross --else -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --#ifdef HAVE_DB_185_H -- choke me; --#else --#include --#endif --#ifndef NULL --#define NULL ((void *)0) --#endif --main() --{ -- int rc; -- u_int32_t flags = DB_CREATE | --#ifdef DB_PRIVATE -- DB_PRIVATE | --#endif -- DB_THREAD; -- --#if DB_VERSION_MAJOR > 2 -- DB_ENV *env = NULL; -- -- rc = db_env_create( &env, 0 ); -- -- flags |= DB_INIT_MPOOL; --#ifdef DB_MPOOL_PRIVATE -- flags |= DB_MPOOL_PRIVATE; --#endif -- -- if( rc ) { -- printf("BerkeleyDB: %s\n", db_strerror(rc) ); -- return rc; -- } -- --#if (DB_VERSION_MAJOR > 3) || (DB_VERSION_MINOR >= 1) -- rc = (env->open)( env, NULL, flags, 0 ); --#else -- rc = (env->open)( env, NULL, NULL, flags, 0 ); --#endif -- -- if ( rc == 0 ) { -- rc = env->close( env, 0 ); -- } -- -- if( rc ) { -- printf("BerkeleyDB: %s\n", db_strerror(rc) ); -- return rc; -- } -- --#else -- DB_ENV env; -- memset( &env, '\0', sizeof(env) ); -- -- rc = db_appinit( NULL, NULL, &env, flags ); -- -- if( rc == 0 ) { -- db_appexit( &env ); -- } -- -- unlink("__db_mpool.share"); -- unlink("__db_lock.share"); --#endif -- -- return rc; --} --_ACEOF --if ac_fn_c_try_run "$LINENO"; then : -- ol_cv_berkeley_db_thread=yes --else -- ol_cv_berkeley_db_thread=no --fi --rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ -- conftest.$ac_objext conftest.beam conftest.$ac_ext --fi -- -- -- LIBS="$ol_LIBS" -- --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ol_cv_berkeley_db_thread" >&5 --$as_echo "$ol_cv_berkeley_db_thread" >&6; } -- -- if test $ol_cv_berkeley_db_thread != no ; then -- --$as_echo "#define HAVE_BERKELEY_DB_THREAD 1" >>confdefs.h -- -- fi -- -- fi --fi -- -- -- if test $ol_cv_berkeley_db = no ; then -- as_fn_error $? "BDB/HDB: BerkeleyDB not available" "$LINENO" 5 -- fi -- -- --$as_echo "#define HAVE_BERKELEY_DB 1" >>confdefs.h -- -- -- if test $ol_cv_lib_db != yes ; then -- BDB_LIBS="$BDB_LIBS $ol_cv_lib_db" -- fi -- -- if test $ol_enable_bdb/$ol_enable_hdb != mod/mod ; then -- if test $ol_enable_bdb = yes -o $ol_enable_hdb = yes ; then -- SLAPD_LIBS="$SLAPD_LIBS \$(BDB_LIBS)" -- fi -- fi -- -- ol_link_bdb=yes --fi -- -- --if test $ol_enable_dynamic = yes && test $enable_shared = yes ; then -- BUILD_LIBS_DYNAMIC=shared -- --$as_echo "#define LDAP_LIBS_DYNAMIC 1" >>confdefs.h -- -- LTSTATIC="" --else -- BUILD_LIBS_DYNAMIC=static -- LTSTATIC="-static" --fi -- --if test $ol_enable_wrappers != no ; then -- for ac_header in tcpd.h --do : -- ac_fn_c_check_header_mongrel "$LINENO" "tcpd.h" "ac_cv_header_tcpd_h" "$ac_includes_default" --if test "x$ac_cv_header_tcpd_h" = xyes; then : -- cat >>confdefs.h <<_ACEOF --#define HAVE_TCPD_H 1 --_ACEOF -- -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TCP wrappers library" >&5 --$as_echo_n "checking for TCP wrappers library... " >&6; } -- save_LIBS="$LIBS" -- LIBS="$LIBS -lwrap" -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --#include --int allow_severity = 0; --int deny_severity = 0; -- --struct request_info *req; -- --int --main () --{ -- --hosts_access(req) -- -- ; -- return 0; --} --_ACEOF --if ac_fn_c_try_link "$LINENO"; then : -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: -lwrap" >&5 --$as_echo "-lwrap" >&6; } -- have_wrappers=yes -- LIBS="$save_LIBS" --else -- -- LIBS="$LIBS -lnsl" -- cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --#include --int allow_severity = 0; --int deny_severity = 0; -- --struct request_info *req; -- --int --main () --{ -- --hosts_access(req) -- -- ; -- return 0; --} --_ACEOF --if ac_fn_c_try_link "$LINENO"; then : -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: -lwrap -lnsl" >&5 --$as_echo "-lwrap -lnsl" >&6; } -- have_wrappers=yes -- LIBS="$save_LIBS -lnsl" --else -- -- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 --$as_echo "no" >&6; } -- have_wrappers=no -- LIBS=$save_LIBS --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext --else -- have_wrappers=no --fi -- --done -- -- -- if test $have_wrappers = yes ; then -- --$as_echo "#define HAVE_TCPD 1" >>confdefs.h -- -- WRAP_LIBS="-lwrap" -- elif test $ol_enable_wrappers = yes ; then -- as_fn_error $? "could not find TCP wrappers, select apppropriate options or disable" "$LINENO" 5 -- else -- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: could not find TCP wrappers, support disabled" >&5 --$as_echo "$as_me: WARNING: could not find TCP wrappers, support disabled" >&2;} -- WRAP_LIBS="" -- fi --fi -- --if test $ol_enable_syslog != no ; then -- ac_fn_c_check_func "$LINENO" "openlog" "ac_cv_func_openlog" --if test "x$ac_cv_func_openlog" = xyes; then : -- --fi -- -- if test $ac_cv_func_openlog = no && test $ol_enable_syslog = yes; then -- as_fn_error select appropriate options or disable "could not find syslog" "$LINENO" 5 -- fi -- ol_enable_syslog=$ac_cv_func_openlog --fi -- --ol_link_sql=no --if test $ol_enable_sql != no ; then -- for ac_header in sql.h sqlext.h --do : -- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` --ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" --if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : -- cat >>confdefs.h <<_ACEOF --#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 --_ACEOF -- --else -- -- as_fn_error $? "could not locate SQL headers" "$LINENO" 5 -- --fi -- --done -- -- -- sql_LIBS="$LIBS" -- LIBS="$LTHREAD_LIBS $LIBS" -- -- if test $ol_with_odbc = auto ; then -- ol_with_odbc="iodbc unixodbc odbc32" -- fi -- -- for odbc in $ol_with_odbc ; do -- if test $ol_link_sql = no ; then -- case $odbc in -- iodbc) -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SQLDriverConnect in -liodbc" >&5 --$as_echo_n "checking for SQLDriverConnect in -liodbc... " >&6; } --if ${ac_cv_lib_iodbc_SQLDriverConnect+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- ac_check_lib_save_LIBS=$LIBS --LIBS="-liodbc $LIBS" --cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -- --/* Override any GCC internal prototype to avoid an error. -- Use char because int might match the return type of a GCC -- builtin and then its argument prototype would still apply. */ --#ifdef __cplusplus --extern "C" --#endif --char SQLDriverConnect (); --int --main () --{ --return SQLDriverConnect (); -+return SQLDriverConnect (); - ; - return 0; - } -@@ -26763,23 +25530,6 @@ _ACEOF - - fi - --if test "$ol_enable_bdb" != no ; then -- BUILD_SLAPD=yes -- BUILD_BDB=$ol_enable_bdb -- if test "$ol_enable_bdb" = mod ; then -- SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-bdb" -- MFLAG=SLAPD_MOD_DYNAMIC -- else -- SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-bdb" -- MFLAG=SLAPD_MOD_STATIC -- fi -- --cat >>confdefs.h <<_ACEOF --#define SLAPD_BDB $MFLAG --_ACEOF -- --fi -- - if test "$ol_enable_dnssrv" != no ; then - BUILD_SLAPD=yes - BUILD_DNSSRV=$ol_enable_dnssrv -@@ -26797,23 +25547,6 @@ _ACEOF - - fi - --if test "$ol_enable_hdb" != no ; then -- BUILD_SLAPD=yes -- BUILD_HDB=$ol_enable_hdb -- if test "$ol_enable_hdb" = mod ; then -- SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-hdb" -- MFLAG=SLAPD_MOD_DYNAMIC -- else -- SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-hdb" -- MFLAG=SLAPD_MOD_STATIC -- fi -- --cat >>confdefs.h <<_ACEOF --#define SLAPD_HDB $MFLAG --_ACEOF -- --fi -- - if test "$ol_enable_ldap" != no ; then - BUILD_SLAPD=yes - BUILD_LDAP=$ol_enable_ldap -@@ -27447,7 +26180,7 @@ fi - - - --ac_config_files="$ac_config_files Makefile:build/top.mk:Makefile.in:build/dir.mk doc/Makefile:build/top.mk:doc/Makefile.in:build/dir.mk doc/man/Makefile:build/top.mk:doc/man/Makefile.in:build/dir.mk doc/man/man1/Makefile:build/top.mk:doc/man/man1/Makefile.in:build/man.mk doc/man/man3/Makefile:build/top.mk:doc/man/man3/Makefile.in:build/man.mk doc/man/man5/Makefile:build/top.mk:doc/man/man5/Makefile.in:build/man.mk doc/man/man8/Makefile:build/top.mk:doc/man/man8/Makefile.in:build/man.mk clients/Makefile:build/top.mk:clients/Makefile.in:build/dir.mk clients/tools/Makefile:build/top.mk:clients/tools/Makefile.in:build/rules.mk include/Makefile:build/top.mk:include/Makefile.in libraries/Makefile:build/top.mk:libraries/Makefile.in:build/dir.mk libraries/liblber/Makefile:build/top.mk:libraries/liblber/Makefile.in:build/lib.mk:build/lib-shared.mk libraries/libldap/Makefile:build/top.mk:libraries/libldap/Makefile.in:build/lib.mk:build/lib-shared.mk libraries/libldap_r/Makefile:build/top.mk:libraries/libldap_r/Makefile.in:build/lib.mk:build/lib-shared.mk libraries/liblunicode/Makefile:build/top.mk:libraries/liblunicode/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 libraries/librewrite/Makefile:build/top.mk:libraries/librewrite/Makefile.in:build/lib.mk:build/lib-static.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/back-bdb/Makefile:build/top.mk:servers/slapd/back-bdb/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-hdb/Makefile:build/top.mk:servers/slapd/back-hdb/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-ldif/Makefile:build/top.mk:servers/slapd/back-ldif/Makefile.in:build/mod.mk servers/slapd/back-mdb/Makefile:build/top.mk:servers/slapd/back-mdb/Makefile.in:build/mod.mk servers/slapd/back-meta/Makefile:build/top.mk:servers/slapd/back-meta/Makefile.in:build/mod.mk servers/slapd/back-monitor/Makefile:build/top.mk:servers/slapd/back-monitor/Makefile.in:build/mod.mk servers/slapd/back-ndb/Makefile:build/top.mk:servers/slapd/back-ndb/Makefile.in:build/mod.mk servers/slapd/back-null/Makefile:build/top.mk:servers/slapd/back-null/Makefile.in:build/mod.mk servers/slapd/back-passwd/Makefile:build/top.mk:servers/slapd/back-passwd/Makefile.in:build/mod.mk servers/slapd/back-perl/Makefile:build/top.mk:servers/slapd/back-perl/Makefile.in:build/mod.mk servers/slapd/back-relay/Makefile:build/top.mk:servers/slapd/back-relay/Makefile.in:build/mod.mk servers/slapd/back-shell/Makefile:build/top.mk:servers/slapd/back-shell/Makefile.in:build/mod.mk servers/slapd/back-sock/Makefile:build/top.mk:servers/slapd/back-sock/Makefile.in:build/mod.mk servers/slapd/back-sql/Makefile:build/top.mk:servers/slapd/back-sql/Makefile.in:build/mod.mk servers/slapd/shell-backends/Makefile:build/top.mk:servers/slapd/shell-backends/Makefile.in:build/srv.mk servers/slapd/slapi/Makefile:build/top.mk:servers/slapd/slapi/Makefile.in:build/lib.mk:build/lib-shared.mk servers/slapd/overlays/Makefile:build/top.mk:servers/slapd/overlays/Makefile.in:build/lib.mk tests/Makefile:build/top.mk:tests/Makefile.in:build/dir.mk tests/run tests/progs/Makefile:build/top.mk:tests/progs/Makefile.in:build/rules.mk" -+ac_config_files="$ac_config_files Makefile:build/top.mk:Makefile.in:build/dir.mk doc/Makefile:build/top.mk:doc/Makefile.in:build/dir.mk doc/man/Makefile:build/top.mk:doc/man/Makefile.in:build/dir.mk doc/man/man1/Makefile:build/top.mk:doc/man/man1/Makefile.in:build/man.mk doc/man/man3/Makefile:build/top.mk:doc/man/man3/Makefile.in:build/man.mk doc/man/man5/Makefile:build/top.mk:doc/man/man5/Makefile.in:build/man.mk doc/man/man8/Makefile:build/top.mk:doc/man/man8/Makefile.in:build/man.mk clients/Makefile:build/top.mk:clients/Makefile.in:build/dir.mk clients/tools/Makefile:build/top.mk:clients/tools/Makefile.in:build/rules.mk include/Makefile:build/top.mk:include/Makefile.in libraries/Makefile:build/top.mk:libraries/Makefile.in:build/dir.mk libraries/liblber/Makefile:build/top.mk:libraries/liblber/Makefile.in:build/lib.mk:build/lib-shared.mk libraries/libldap/Makefile:build/top.mk:libraries/libldap/Makefile.in:build/lib.mk:build/lib-shared.mk libraries/libldap_r/Makefile:build/top.mk:libraries/libldap_r/Makefile.in:build/lib.mk:build/lib-shared.mk libraries/liblunicode/Makefile:build/top.mk:libraries/liblunicode/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 libraries/librewrite/Makefile:build/top.mk:libraries/librewrite/Makefile.in:build/lib.mk:build/lib-static.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/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-ldif/Makefile:build/top.mk:servers/slapd/back-ldif/Makefile.in:build/mod.mk servers/slapd/back-mdb/Makefile:build/top.mk:servers/slapd/back-mdb/Makefile.in:build/mod.mk servers/slapd/back-meta/Makefile:build/top.mk:servers/slapd/back-meta/Makefile.in:build/mod.mk servers/slapd/back-monitor/Makefile:build/top.mk:servers/slapd/back-monitor/Makefile.in:build/mod.mk servers/slapd/back-ndb/Makefile:build/top.mk:servers/slapd/back-ndb/Makefile.in:build/mod.mk servers/slapd/back-null/Makefile:build/top.mk:servers/slapd/back-null/Makefile.in:build/mod.mk servers/slapd/back-passwd/Makefile:build/top.mk:servers/slapd/back-passwd/Makefile.in:build/mod.mk servers/slapd/back-perl/Makefile:build/top.mk:servers/slapd/back-perl/Makefile.in:build/mod.mk servers/slapd/back-relay/Makefile:build/top.mk:servers/slapd/back-relay/Makefile.in:build/mod.mk servers/slapd/back-shell/Makefile:build/top.mk:servers/slapd/back-shell/Makefile.in:build/mod.mk servers/slapd/back-sock/Makefile:build/top.mk:servers/slapd/back-sock/Makefile.in:build/mod.mk servers/slapd/back-sql/Makefile:build/top.mk:servers/slapd/back-sql/Makefile.in:build/mod.mk servers/slapd/shell-backends/Makefile:build/top.mk:servers/slapd/shell-backends/Makefile.in:build/srv.mk servers/slapd/slapi/Makefile:build/top.mk:servers/slapd/slapi/Makefile.in:build/lib.mk:build/lib-shared.mk servers/slapd/overlays/Makefile:build/top.mk:servers/slapd/overlays/Makefile.in:build/lib.mk tests/Makefile:build/top.mk:tests/Makefile.in:build/dir.mk tests/run tests/progs/Makefile:build/top.mk:tests/progs/Makefile.in:build/rules.mk" - - - ac_config_commands="$ac_config_commands default" -@@ -28411,9 +27144,7 @@ do - "libraries/librewrite/Makefile") CONFIG_FILES="$CONFIG_FILES libraries/librewrite/Makefile:build/top.mk:libraries/librewrite/Makefile.in:build/lib.mk:build/lib-static.mk" ;; - "servers/Makefile") CONFIG_FILES="$CONFIG_FILES servers/Makefile:build/top.mk:servers/Makefile.in:build/dir.mk" ;; - "servers/slapd/Makefile") CONFIG_FILES="$CONFIG_FILES servers/slapd/Makefile:build/top.mk:servers/slapd/Makefile.in:build/srv.mk" ;; -- "servers/slapd/back-bdb/Makefile") CONFIG_FILES="$CONFIG_FILES servers/slapd/back-bdb/Makefile:build/top.mk:servers/slapd/back-bdb/Makefile.in:build/mod.mk" ;; - "servers/slapd/back-dnssrv/Makefile") CONFIG_FILES="$CONFIG_FILES servers/slapd/back-dnssrv/Makefile:build/top.mk:servers/slapd/back-dnssrv/Makefile.in:build/mod.mk" ;; -- "servers/slapd/back-hdb/Makefile") CONFIG_FILES="$CONFIG_FILES servers/slapd/back-hdb/Makefile:build/top.mk:servers/slapd/back-hdb/Makefile.in:build/mod.mk" ;; - "servers/slapd/back-ldap/Makefile") CONFIG_FILES="$CONFIG_FILES servers/slapd/back-ldap/Makefile:build/top.mk:servers/slapd/back-ldap/Makefile.in:build/mod.mk" ;; - "servers/slapd/back-ldif/Makefile") CONFIG_FILES="$CONFIG_FILES servers/slapd/back-ldif/Makefile:build/top.mk:servers/slapd/back-ldif/Makefile.in:build/mod.mk" ;; - "servers/slapd/back-mdb/Makefile") CONFIG_FILES="$CONFIG_FILES servers/slapd/back-mdb/Makefile:build/top.mk:servers/slapd/back-mdb/Makefile.in:build/mod.mk" ;; --- -2.19.1 - diff --git a/backport-delete-back-bdb-back-hdb.patch b/backport-delete-back-bdb-back-hdb.patch deleted file mode 100644 index 6eb148b..0000000 --- a/backport-delete-back-bdb-back-hdb.patch +++ /dev/null @@ -1,22206 +0,0 @@ -From 8897fff4f352923b91e776bf9bc0bf8dbd636e85 Mon Sep 17 00:00:00 2001 -From: zhangqiumiao -Date: Fri, 25 Sep 2020 21:54:05 +0800 -Subject: [PATCH] backport delete back-bdb/back-hdb - ---- - INSTALL | 3 - - build/openldap.m4 | 292 --- - build/top.mk | 1 - - configure.in | 74 +- - contrib/slapd-modules/allowed/allowed.c | 2 +- - contrib/slapd-modules/nssov/README | 4 +- - contrib/slapd-modules/nssov/slapo-nssov.5 | 2 +- - doc/guide/admin/appendix-changes.sdf | 27 +- - doc/guide/admin/appendix-common-errors.sdf | 10 +- - doc/guide/admin/aspell.en.pws | 7 - - doc/guide/admin/backends.sdf | 47 +- - doc/guide/admin/install.sdf | 17 - - doc/guide/admin/intro.sdf | 12 +- - doc/guide/admin/maintenance.sdf | 86 +- - doc/guide/admin/monitoringslapd.sdf | 25 +- - doc/guide/admin/overlays.sdf | 6 +- - doc/guide/admin/replication.sdf | 12 +- - doc/guide/admin/slapdconf2.sdf | 237 +-- - doc/guide/admin/slapdconfig.sdf | 218 ++- - doc/guide/admin/tuning.sdf | 175 +- - doc/guide/preamble.sdf | 2 - - doc/guide/release/install.sdf | 2 +- - doc/man/man5/slapd-bdb.5 | 286 --- - doc/man/man5/slapd-bdb.5.links | 1 - - doc/man/man5/slapd-config.5 | 8 +- - doc/man/man5/slapd-mdb.5 | 7 +- - doc/man/man5/slapd-sql.5 | 2 +- - doc/man/man5/slapd.access.5 | 9 +- - doc/man/man5/slapd.backends.5 | 35 +- - doc/man/man5/slapd.conf.5 | 7 +- - doc/man/man5/slapd.overlays.5 | 6 +- - doc/man/man8/slapcat.8 | 2 - - doc/man/man8/slapschema.8 | 3 +- - include/portable.hin | 12 - - servers/slapd/DB_CONFIG | 28 - - servers/slapd/Makefile.in | 12 +- - servers/slapd/alock.c | 718 ------- - servers/slapd/alock.h | 74 - - servers/slapd/back-bdb/Makefile.in | 53 - - servers/slapd/back-bdb/add.c | 547 ------ - servers/slapd/back-bdb/attr.c | 441 ----- - servers/slapd/back-bdb/back-bdb.h | 377 ---- - servers/slapd/back-bdb/bind.c | 166 -- - servers/slapd/back-bdb/cache.c | 1692 ----------------- - servers/slapd/back-bdb/compare.c | 143 -- - servers/slapd/back-bdb/config.c | 951 --------- - servers/slapd/back-bdb/dbcache.c | 210 -- - servers/slapd/back-bdb/delete.c | 605 ------ - servers/slapd/back-bdb/dn2entry.c | 84 - - servers/slapd/back-bdb/dn2id.c | 1215 ------------ - servers/slapd/back-bdb/error.c | 62 - - servers/slapd/back-bdb/extended.c | 54 - - servers/slapd/back-bdb/filterindex.c | 1183 ------------ - servers/slapd/back-bdb/id2entry.c | 446 ----- - servers/slapd/back-bdb/idl.c | 1570 --------------- - servers/slapd/back-bdb/idl.h | 75 - - servers/slapd/back-bdb/index.c | 574 ------ - servers/slapd/back-bdb/init.c | 874 --------- - servers/slapd/back-bdb/key.c | 104 - - servers/slapd/back-bdb/modify.c | 835 -------- - servers/slapd/back-bdb/modrdn.c | 842 -------- - servers/slapd/back-bdb/monitor.c | 724 ------- - servers/slapd/back-bdb/nextid.c | 80 - - servers/slapd/back-bdb/operational.c | 151 -- - servers/slapd/back-bdb/proto-bdb.h | 678 ------- - servers/slapd/back-bdb/referral.c | 152 -- - servers/slapd/back-bdb/search.c | 1388 -------------- - servers/slapd/back-bdb/tools.c | 1327 ------------- - servers/slapd/back-bdb/trans.c | 56 - - servers/slapd/back-hdb/Makefile.in | 70 - - servers/slapd/back-hdb/back-bdb.h | 31 - - servers/slapd/back-monitor/init.c | 8 +- - servers/slapd/bconfig.c | 2 +- - servers/slapd/dn.c | 3 +- - servers/slapd/overlays/pcache.c | 4 +- - servers/slapd/slap.h | 1 - - servers/slapd/slapd.ldif | 3 +- - tests/Makefile.in | 36 - - tests/README | 2 - - tests/data/regressions/its4184/its4184 | 4 - - tests/data/regressions/its4448/its4448 | 16 - - tests/data/slapd-proxyauthz.conf | 4 - - tests/data/slapd-proxycache.conf | 4 - - tests/data/slapd-ref-slave.conf | 2 - - tests/data/slapd.conf | 2 - - tests/run.in | 8 +- - tests/scripts/test023-refint | 97 +- - tests/scripts/test025-limits | 2 +- - tests/scripts/test036-meta-concurrency | 16 - - tests/scripts/test040-subtree-rename | 5 - - tests/scripts/test043-delta-syncrepl | 2 +- - tests/scripts/test052-memberof | 4 +- - tests/scripts/test056-monitor | 6 +- - tests/scripts/test057-memberof-refint | 9 +- - .../test061-syncreplication-initiation | 1 - - 95 files changed, 418 insertions(+), 20054 deletions(-) - delete mode 100644 doc/man/man5/slapd-bdb.5 - delete mode 100644 doc/man/man5/slapd-bdb.5.links - delete mode 100644 servers/slapd/DB_CONFIG - delete mode 100644 servers/slapd/alock.c - delete mode 100644 servers/slapd/alock.h - delete mode 100644 servers/slapd/back-bdb/Makefile.in - delete mode 100644 servers/slapd/back-bdb/add.c - delete mode 100644 servers/slapd/back-bdb/attr.c - delete mode 100644 servers/slapd/back-bdb/back-bdb.h - delete mode 100644 servers/slapd/back-bdb/bind.c - delete mode 100644 servers/slapd/back-bdb/cache.c - delete mode 100644 servers/slapd/back-bdb/compare.c - delete mode 100644 servers/slapd/back-bdb/config.c - delete mode 100644 servers/slapd/back-bdb/dbcache.c - delete mode 100644 servers/slapd/back-bdb/delete.c - delete mode 100644 servers/slapd/back-bdb/dn2entry.c - delete mode 100644 servers/slapd/back-bdb/dn2id.c - delete mode 100644 servers/slapd/back-bdb/error.c - delete mode 100644 servers/slapd/back-bdb/extended.c - delete mode 100644 servers/slapd/back-bdb/filterindex.c - delete mode 100644 servers/slapd/back-bdb/id2entry.c - delete mode 100644 servers/slapd/back-bdb/idl.c - delete mode 100644 servers/slapd/back-bdb/idl.h - delete mode 100644 servers/slapd/back-bdb/index.c - delete mode 100644 servers/slapd/back-bdb/init.c - delete mode 100644 servers/slapd/back-bdb/key.c - delete mode 100644 servers/slapd/back-bdb/modify.c - delete mode 100644 servers/slapd/back-bdb/modrdn.c - delete mode 100644 servers/slapd/back-bdb/monitor.c - delete mode 100644 servers/slapd/back-bdb/nextid.c - delete mode 100644 servers/slapd/back-bdb/operational.c - delete mode 100644 servers/slapd/back-bdb/proto-bdb.h - delete mode 100644 servers/slapd/back-bdb/referral.c - delete mode 100644 servers/slapd/back-bdb/search.c - delete mode 100644 servers/slapd/back-bdb/tools.c - delete mode 100644 servers/slapd/back-bdb/trans.c - delete mode 100644 servers/slapd/back-hdb/Makefile.in - delete mode 100644 servers/slapd/back-hdb/back-bdb.h - -diff --git a/INSTALL b/INSTALL -index e8a4fb3..0805e1c 100644 ---- a/INSTALL -+++ b/INSTALL -@@ -73,9 +73,6 @@ Making and Installing the OpenLDAP Distribution - - 6. Test the standalone system: - -- This step requires the standalone LDAP server, slapd(8), with HDB -- and/or BDB support. -- - % make test - - If all goes well, the system has been built as configured. If -diff --git a/build/openldap.m4 b/build/openldap.m4 -index 80fda16..fd768aa 100644 ---- a/build/openldap.m4 -+++ b/build/openldap.m4 -@@ -243,298 +243,6 @@ OL_RESOLVER_TRY(ol_cv_resolver_none) - OL_RESOLVER_TRY(ol_cv_resolver_resolv,[-lresolv]) - OL_RESOLVER_TRY(ol_cv_resolver_bind,[-lbind]) - ]) --dnl --dnl ==================================================================== --dnl Berkeley DB macros --dnl --dnl -------------------------------------------------------------------- --dnl Try to link --AC_DEFUN([OL_BERKELEY_DB_TRY], --[if test $ol_cv_lib_db = no ; then -- AC_CACHE_CHECK([for Berkeley DB link (]ifelse($2,,default,$2)[)],[$1], --[ -- ol_DB_LIB=ifelse($2,,,$2) -- ol_LIBS=$LIBS -- LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" -- -- AC_LINK_IFELSE([AC_LANG_PROGRAM([[ --#ifdef HAVE_DB_185_H --# include --#else --# include --#endif -- --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif -- --#ifndef NULL --#define NULL ((void*)0) --#endif --]], [[ --#if DB_VERSION_MAJOR > 2 -- db_env_create( NULL, 0 ); --#elif DB_VERSION_MAJOR > 1 -- db_appexit( NULL ); --#else -- (void) dbopen( NULL, 0, 0, 0, NULL); --#endif --]])],[$1=yes],[$1=no]) -- -- LIBS="$ol_LIBS" --]) -- -- if test $$1 = yes ; then -- ol_cv_lib_db=ifelse($2,,yes,$2) -- fi --fi --]) --dnl --dnl -------------------------------------------------------------------- --dnl Get major and minor version from --AC_DEFUN([OL_BDB_HEADER_VERSION], --[AC_CACHE_CHECK([for Berkeley DB major version in db.h], [ol_cv_bdb_major],[ -- AC_LANG_CONFTEST([ --#include --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif --__db_version DB_VERSION_MAJOR --]) -- set X `eval "$ac_cpp -P conftest.$ac_ext" | $EGREP __db_version` none none -- ol_cv_bdb_major=${3} --]) --case $ol_cv_bdb_major in [[1-9]]*) : ;; *) -- AC_MSG_ERROR([Unknown Berkeley DB major version in db.h]) ;; --esac -- --dnl Determine minor version --AC_CACHE_CHECK([for Berkeley DB minor version in db.h], [ol_cv_bdb_minor],[ -- AC_LANG_CONFTEST([ --#include --#ifndef DB_VERSION_MINOR --# define DB_VERSION_MINOR 0 --#endif --__db_version DB_VERSION_MINOR --]) -- set X `eval "$ac_cpp -P conftest.$ac_ext" | $EGREP __db_version` none none -- ol_cv_bdb_minor=${3} --]) --case $ol_cv_bdb_minor in [[0-9]]*) : ;; *) -- AC_MSG_ERROR([Unknown Berkeley DB minor version in db.h]) ;; --esac --]) --dnl --dnl -------------------------------------------------------------------- --dnl Try to locate appropriate library --AC_DEFUN([OL_BERKELEY_DB_LINK], --[ol_cv_lib_db=no -- --if test $ol_cv_bdb_major = 5 ; then -- OL_BERKELEY_DB_TRY(ol_cv_db_db_5_dot_m,[-ldb-5.$ol_cv_bdb_minor]) -- OL_BERKELEY_DB_TRY(ol_cv_db_db5m,[-ldb5$ol_cv_bdb_minor]) -- OL_BERKELEY_DB_TRY(ol_cv_db_db_5m,[-ldb-5$ol_cv_bdb_minor]) -- OL_BERKELEY_DB_TRY(ol_cv_db_db_5_m,[-ldb-5-$ol_cv_bdb_minor]) -- OL_BERKELEY_DB_TRY(ol_cv_db_db_5,[-ldb-5]) -- OL_BERKELEY_DB_TRY(ol_cv_db_db5,[-ldb5]) --elif test $ol_cv_bdb_major = 4 ; then -- OL_BERKELEY_DB_TRY(ol_cv_db_db_4_dot_m,[-ldb-4.$ol_cv_bdb_minor]) -- OL_BERKELEY_DB_TRY(ol_cv_db_db4m,[-ldb4$ol_cv_bdb_minor]) -- OL_BERKELEY_DB_TRY(ol_cv_db_db_4m,[-ldb-4$ol_cv_bdb_minor]) -- OL_BERKELEY_DB_TRY(ol_cv_db_db_4_m,[-ldb-4-$ol_cv_bdb_minor]) -- OL_BERKELEY_DB_TRY(ol_cv_db_db_4,[-ldb-4]) -- OL_BERKELEY_DB_TRY(ol_cv_db_db4,[-ldb4]) --fi --OL_BERKELEY_DB_TRY(ol_cv_db_db,[-ldb]) --OL_BERKELEY_DB_TRY(ol_cv_db_none) --]) --dnl --dnl -------------------------------------------------------------------- --dnl Check if Berkeley DB version --AC_DEFUN([OL_BERKELEY_DB_VERSION], --[AC_CACHE_CHECK([for Berkeley DB library and header version match], [ol_cv_berkeley_db_version], [ -- ol_LIBS="$LIBS" -- LIBS="$LTHREAD_LIBS $LIBS" -- if test $ol_cv_lib_db != yes ; then -- LIBS="$ol_cv_lib_db $LIBS" -- fi -- -- AC_RUN_IFELSE([AC_LANG_SOURCE([[ --#ifdef HAVE_DB_185_H -- choke me; --#else --#include --#endif --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif --#ifndef NULL --#define NULL ((void *)0) --#endif --main() --{ --#if DB_VERSION_MAJOR > 1 -- char *version; -- int major, minor, patch; -- -- version = db_version( &major, &minor, &patch ); -- -- if( major != DB_VERSION_MAJOR || -- minor != DB_VERSION_MINOR || -- patch != DB_VERSION_PATCH ) -- { -- printf("Berkeley DB version mismatch\n" -- "\theader: %s\n\tlibrary: %s\n", -- DB_VERSION_STRING, version); -- return 1; -- } --#endif -- -- return 0; --}]])],[ol_cv_berkeley_db_version=yes],[ol_cv_berkeley_db_version=no],[ol_cv_berkeley_db_version=cross]) -- -- LIBS="$ol_LIBS" --]) -- -- if test $ol_cv_berkeley_db_version = no ; then -- AC_MSG_ERROR([Berkeley DB version mismatch]) -- fi --])dnl --dnl --dnl -------------------------------------------------------------------- --dnl Check if Berkeley DB supports DB_THREAD --AC_DEFUN([OL_BERKELEY_DB_THREAD], --[AC_CACHE_CHECK([for Berkeley DB thread support], [ol_cv_berkeley_db_thread], [ -- ol_LIBS="$LIBS" -- LIBS="$LTHREAD_LIBS $LIBS" -- if test $ol_cv_lib_db != yes ; then -- LIBS="$ol_cv_lib_db $LIBS" -- fi -- -- AC_RUN_IFELSE([AC_LANG_SOURCE([[ --#ifdef HAVE_DB_185_H -- choke me; --#else --#include --#endif --#ifndef NULL --#define NULL ((void *)0) --#endif --main() --{ -- int rc; -- u_int32_t flags = DB_CREATE | --#ifdef DB_PRIVATE -- DB_PRIVATE | --#endif -- DB_THREAD; -- --#if DB_VERSION_MAJOR > 2 -- DB_ENV *env = NULL; -- -- rc = db_env_create( &env, 0 ); -- -- flags |= DB_INIT_MPOOL; --#ifdef DB_MPOOL_PRIVATE -- flags |= DB_MPOOL_PRIVATE; --#endif -- -- if( rc ) { -- printf("BerkeleyDB: %s\n", db_strerror(rc) ); -- return rc; -- } -- --#if (DB_VERSION_MAJOR > 3) || (DB_VERSION_MINOR >= 1) -- rc = (env->open)( env, NULL, flags, 0 ); --#else -- rc = (env->open)( env, NULL, NULL, flags, 0 ); --#endif -- -- if ( rc == 0 ) { -- rc = env->close( env, 0 ); -- } -- -- if( rc ) { -- printf("BerkeleyDB: %s\n", db_strerror(rc) ); -- return rc; -- } -- --#else -- DB_ENV env; -- memset( &env, '\0', sizeof(env) ); -- -- rc = db_appinit( NULL, NULL, &env, flags ); -- -- if( rc == 0 ) { -- db_appexit( &env ); -- } -- -- unlink("__db_mpool.share"); -- unlink("__db_lock.share"); --#endif -- -- return rc; --}]])],[ol_cv_berkeley_db_thread=yes],[ol_cv_berkeley_db_thread=no],[ol_cv_berkeley_db_thread=cross]) -- -- LIBS="$ol_LIBS" --]) -- -- if test $ol_cv_berkeley_db_thread != no ; then -- AC_DEFINE(HAVE_BERKELEY_DB_THREAD, 1, -- [define if Berkeley DB has DB_THREAD support]) -- fi --])dnl --dnl --dnl -------------------------------------------------------------------- --dnl Find any DB --AC_DEFUN([OL_BERKELEY_DB], --[ol_cv_berkeley_db=no --AC_CHECK_HEADERS(db.h) --if test $ac_cv_header_db_h = yes; then -- OL_BDB_HEADER_VERSION -- OL_BDB_COMPAT -- -- if test $ol_cv_bdb_compat != yes ; then -- AC_MSG_ERROR([BerkeleyDB version incompatible with BDB/HDB backends]) -- fi -- -- OL_BERKELEY_DB_LINK -- if test "$ol_cv_lib_db" != no ; then -- ol_cv_berkeley_db=yes -- OL_BERKELEY_DB_VERSION -- OL_BERKELEY_DB_THREAD -- fi --fi --]) --dnl -------------------------------------------------------------------- --dnl Check for version compatility with back-bdb --AC_DEFUN([OL_BDB_COMPAT], --[AC_CACHE_CHECK([if Berkeley DB version supported by BDB/HDB backends], [ol_cv_bdb_compat],[ -- AC_EGREP_CPP(__db_version_compat,[ --#include -- -- /* this check could be improved */ --#ifndef DB_VERSION_MAJOR --# define DB_VERSION_MAJOR 1 --#endif --#ifndef DB_VERSION_MINOR --# define DB_VERSION_MINOR 0 --#endif --#ifndef DB_VERSION_PATCH --# define DB_VERSION_PATCH 0 --#endif -- --#define DB_VERSION_FULL ((DB_VERSION_MAJOR<<16)|(DB_VERSION_MINOR<<8)|DB_VERSION_PATCH) -- --/* require 4.4 or later, but less than 6.0.20 */ --#if DB_VERSION_FULL >= 0x040400 && DB_VERSION_FULL < 0x060014 -- __db_version_compat --#endif --#if DB_VERSION_FULL >= 0x060014 --#error "BerkeleyDB 6.0.20+ license is incompatible with LDAP" --#endif -- ], [ol_cv_bdb_compat=yes], [ol_cv_bdb_compat=no])]) --]) - - dnl - dnl ==================================================================== -diff --git a/build/top.mk b/build/top.mk -index 6850121..a25c5fc 100644 ---- a/build/top.mk -+++ b/build/top.mk -@@ -159,7 +159,6 @@ LDAP_LIBDIR= $(top_builddir)/libraries - LUTIL_LIBS = @LUTIL_LIBS@ - LTHREAD_LIBS = @LTHREAD_LIBS@ - --BDB_LIBS = @BDB_LIBS@ - SLAPD_NDB_LIBS = @SLAPD_NDB_LIBS@ - - LDAP_LIBLBER_LA = $(LDAP_LIBDIR)/liblber/liblber.la -diff --git a/configure.in b/configure.in -index c70241a..065eae3 100644 ---- a/configure.in -+++ b/configure.in -@@ -282,9 +282,7 @@ OL_ARG_ENABLE(wrappers,[ --enable-wrappers enable tcp wrapper support], no) - - dnl ---------------------------------------------------------------- - dnl SLAPD Backend Options --Backends="bdb \ -- dnssrv \ -- hdb \ -+Backends="dnssrv \ - ldap \ - mdb \ - meta \ -@@ -303,12 +301,8 @@ SLAPD Backend Options:]) - - OL_ARG_ENABLE(backends,[ --enable-backends enable all available backends], - --, [no yes mod])dnl --OL_ARG_ENABLE(bdb,[ --enable-bdb enable Berkeley DB backend], -- yes, [no yes mod], ol_enable_backends)dnl - OL_ARG_ENABLE(dnssrv,[ --enable-dnssrv enable dnssrv backend], - no, [no yes mod], ol_enable_backends)dnl --OL_ARG_ENABLE(hdb,[ --enable-hdb enable Hierarchical DB backend], -- yes, [no yes mod], ol_enable_backends)dnl - OL_ARG_ENABLE(ldap,[ --enable-ldap enable ldap backend], - no, [no yes mod], ol_enable_backends)dnl - OL_ARG_ENABLE(mdb,[ --enable-mdb enable mdb database backend], -@@ -471,9 +465,7 @@ if test $ol_enable_slapd = no ; then - ol_enable_rewrite=no - - elif test $ol_enable_modules != yes && -- test $ol_enable_bdb = no && - test $ol_enable_dnssrv = no && -- test $ol_enable_hdb = no && - test $ol_enable_ldap = no && - test $ol_enable_mdb = no && - test $ol_enable_meta = no && -@@ -518,7 +510,6 @@ AC_MSG_RESULT(done) - dnl ---------------------------------------------------------------- - dnl Initialize vars - LDAP_LIBS= --BDB_LIBS= - SLAPD_NDB_LIBS= - SLAPD_NDB_INCS= - LTHREAD_LIBS= -@@ -533,9 +524,7 @@ BUILD_THREAD=no - BUILD_SLAPI=no - SLAPD_SLAPI_DEPEND= - --BUILD_BDB=no - BUILD_DNSSRV=no --BUILD_HDB=no - BUILD_LDAP=no - BUILD_MDB=no - BUILD_META=no -@@ -1867,36 +1856,6 @@ else - ol_cv_func_gethostbyaddr_r_nargs=0 - fi - --dnl ---------------------------------------------------------------- --ol_link_bdb=no -- --if test $ol_enable_bdb/$ol_enable_hdb != no/no; then -- OL_BERKELEY_DB -- -- if test $ol_cv_berkeley_db = no ; then -- AC_MSG_ERROR(BDB/HDB: BerkeleyDB not available) -- fi -- -- AC_DEFINE(HAVE_BERKELEY_DB,1, -- [define this if Berkeley DB is available]) -- -- dnl $ol_cv_lib_db should be yes or -ldb -- dnl (it could be no, but that would be an error -- if test $ol_cv_lib_db != yes ; then -- BDB_LIBS="$BDB_LIBS $ol_cv_lib_db" -- fi -- -- dnl link BDB library to slapd when there is a -- dnl static BDB based backend in use -- if test $ol_enable_bdb/$ol_enable_hdb != mod/mod ; then -- if test $ol_enable_bdb = yes -o $ol_enable_hdb = yes ; then -- SLAPD_LIBS="$SLAPD_LIBS \$(BDB_LIBS)" -- fi -- fi -- -- ol_link_bdb=yes --fi -- - dnl ---------------------------------------------------------------- - - if test $ol_enable_dynamic = yes && test $enable_shared = yes ; then -@@ -2610,19 +2569,6 @@ if test "$ol_enable_monitor" != no ; then - AC_DEFINE_UNQUOTED(SLAPD_MONITOR,$MFLAG,[define to support cn=Monitor backend]) - fi - --if test "$ol_enable_bdb" != no ; then -- BUILD_SLAPD=yes -- BUILD_BDB=$ol_enable_bdb -- if test "$ol_enable_bdb" = mod ; then -- SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-bdb" -- MFLAG=SLAPD_MOD_DYNAMIC -- else -- SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-bdb" -- MFLAG=SLAPD_MOD_STATIC -- fi -- AC_DEFINE_UNQUOTED(SLAPD_BDB,$MFLAG,[define to support BDB backend]) --fi -- - if test "$ol_enable_dnssrv" != no ; then - BUILD_SLAPD=yes - BUILD_DNSSRV=$ol_enable_dnssrv -@@ -2636,19 +2582,6 @@ if test "$ol_enable_dnssrv" != no ; then - AC_DEFINE_UNQUOTED(SLAPD_DNSSRV,$MFLAG,[define to support DNS SRV backend]) - fi - --if test "$ol_enable_hdb" != no ; then -- BUILD_SLAPD=yes -- BUILD_HDB=$ol_enable_hdb -- if test "$ol_enable_hdb" = mod ; then -- SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-hdb" -- MFLAG=SLAPD_MOD_DYNAMIC -- else -- SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-hdb" -- MFLAG=SLAPD_MOD_STATIC -- fi -- AC_DEFINE_UNQUOTED(SLAPD_HDB,$MFLAG,[define to support HDB backend]) --fi -- - if test "$ol_enable_ldap" != no ; then - BUILD_SLAPD=yes - BUILD_LDAP=$ol_enable_ldap -@@ -3076,9 +3009,7 @@ dnl slapi - AC_SUBST(BUILD_SLAPI) - AC_SUBST(SLAPD_SLAPI_DEPEND) - dnl backends -- AC_SUBST(BUILD_BDB) - AC_SUBST(BUILD_DNSSRV) -- AC_SUBST(BUILD_HDB) - AC_SUBST(BUILD_LDAP) - AC_SUBST(BUILD_MDB) - AC_SUBST(BUILD_META) -@@ -3117,7 +3048,6 @@ dnl overlays - - AC_SUBST(LDAP_LIBS) - AC_SUBST(SLAPD_LIBS) --AC_SUBST(BDB_LIBS) - AC_SUBST(SLAPD_NDB_LIBS) - AC_SUBST(SLAPD_NDB_INCS) - AC_SUBST(LTHREAD_LIBS) -@@ -3181,9 +3111,7 @@ AC_CONFIG_FILES([Makefile:build/top.mk:Makefile.in:build/dir.mk] - [libraries/librewrite/Makefile:build/top.mk:libraries/librewrite/Makefile.in:build/lib.mk:build/lib-static.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/back-bdb/Makefile:build/top.mk:servers/slapd/back-bdb/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-hdb/Makefile:build/top.mk:servers/slapd/back-hdb/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-ldif/Makefile:build/top.mk:servers/slapd/back-ldif/Makefile.in:build/mod.mk] - [servers/slapd/back-mdb/Makefile:build/top.mk:servers/slapd/back-mdb/Makefile.in:build/mod.mk] -diff --git a/contrib/slapd-modules/allowed/allowed.c b/contrib/slapd-modules/allowed/allowed.c -index 5f2810f..8ca0889 100644 ---- a/contrib/slapd-modules/allowed/allowed.c -+++ b/contrib/slapd-modules/allowed/allowed.c -@@ -27,7 +27,7 @@ - * Caveats: - * - right now, the overlay assumes that all values of the objectClass - * attribute will be returned in rs->sr_entry; this may not be true -- * in general, but it usually is for back-bdb/back-hdb. To generalize, -+ * in general, but it usually is for back-mdb. To generalize, - * the search request should be analyzed, and if allowedAttributes or - * allowedAttributesEffective are requested, add objectClass to the - * requested attributes -diff --git a/contrib/slapd-modules/nssov/README b/contrib/slapd-modules/nssov/README -index ced3872..f8538f9 100644 ---- a/contrib/slapd-modules/nssov/README -+++ b/contrib/slapd-modules/nssov/README -@@ -21,7 +21,7 @@ To use the overlay, add: - moduleload nssov.so - ... - -- database hdb -+ database mdb - ... - overlay nssov - -@@ -65,7 +65,7 @@ See the nss-ldapd/README for the original attribute names used in this code. - The overlay also supports dynamic configuration in cn=config. The layout - of the config entry is - -- dn: olcOverlay={0}nssov,ocDatabase={1}hdb,cn=config -+ dn: olcOverlay={0}nssov,ocDatabase={1}mdb,cn=config - objectClass: olcOverlayConfig - objectClass: olcNssOvConfig - olcOverlay: {0}nssov -diff --git a/contrib/slapd-modules/nssov/slapo-nssov.5 b/contrib/slapd-modules/nssov/slapo-nssov.5 -index 816b661..83621bd 100644 ---- a/contrib/slapd-modules/nssov/slapo-nssov.5 -+++ b/contrib/slapd-modules/nssov/slapo-nssov.5 -@@ -278,7 +278,7 @@ of the config entry is - .LP - .RS - .nf -- dn: olcOverlay={0}nssov,ocDatabase={1}hdb,cn=config -+ dn: olcOverlay={0}nssov,ocDatabase={1}mdb,cn=config - objectClass: olcOverlayConfig - objectClass: olcNssOvConfig - olcOverlay: {0}nssov -diff --git a/doc/guide/admin/appendix-changes.sdf b/doc/guide/admin/appendix-changes.sdf -index 5006672..7fe91d1 100644 ---- a/doc/guide/admin/appendix-changes.sdf -+++ b/doc/guide/admin/appendix-changes.sdf -@@ -147,11 +147,6 @@ search over 500 thousand entries per second. The search was on an unindexed - attribute using a filter that would not match any entry, forcing slapd to examine - every entry in the DB, testing the filter for a match. - --Essentially the slapd entry cache in back-bdb/back-hdb is so efficient the search --processing time is almost invisible; the runtime is limited only by the memory --bandwidth of the machine. (The search data rate corresponds to about 3.5GB/sec; --the memory bandwidth on the machine is only about 4GB/sec due to ECC and register latency.) -- - H3: New overlays - - * slapo-constraint (Attribute value constraints) -@@ -199,21 +194,13 @@ H3: New build options - * Support for building against GnuTLS - - --H2: Obsolete Features Removed From 2.4 -- --These features were strongly deprecated in 2.3 and removed in 2.4. -- --H3: Slurpd -+H2: Obsolete Features Removed From 2.5 - --Please read the {{SECT:Replication}} section as to why this is no longer in --OpenLDAP -+These features were strongly deprecated in 2.4 and removed in 2.5. - --H3: back-ldbm -+H3: back-bdb and back-hdb - --back-ldbm was both slow and unreliable. Its byzantine indexing code was --prone to spontaneous corruption, as were the underlying database libraries --that were commonly used (e.g. GDBM or NDBM). back-bdb and back-hdb are --superior in every aspect, with simplified indexing to avoid index corruption, --fine-grained locking for greater concurrency, hierarchical caching for --greater performance, streamlined on-disk format for greater efficiency --and portability, and full transaction support for greater reliability. -+back-bdb and back-hdb were signficantly slower than back-mdb and -+required significant tuning of multiple parameters to maximize -+performance. back-mdb requires no tuning and provides all the -+functionality previously provided via back-bdb and back-hdb. -diff --git a/doc/guide/admin/appendix-common-errors.sdf b/doc/guide/admin/appendix-common-errors.sdf -index 23eef9b..5ead0e1 100644 ---- a/doc/guide/admin/appendix-common-errors.sdf -+++ b/doc/guide/admin/appendix-common-errors.sdf -@@ -636,7 +636,7 @@ values of . - - H3: ldap_*: Internal (implementation specific) error (80) - additional info: entry index delete failed - --This seems to be related with wrong ownership of the BDB's dir (/var/lib/ldap) -+This seems to be related with wrong ownership of the MDB's dir (/var/lib/ldap) - and files. The files must be owned by the user that slapd runs as. - - > chown -R ldap:ldap /var/lib/ldap -@@ -652,11 +652,3 @@ immediately and client gets an error : - > SASL/GSSAPI authentication started ldap_sasl_interactive_bind_s: Can't contact LDAP server (-1) - - Then check the slapd service, it stopped. -- --This may come from incompatible of using different versions of BerkeleyDB for --installing of SASL and installing of OpenLDAP. The problem arises in case of --using multiple version of BerkeleyDB. Solution: - Check which version of --BerkeleyDB when install Cyrus SASL. -- --Reinstall OpenLDAP with the version of BerkeleyDB above. -- -diff --git a/doc/guide/admin/aspell.en.pws b/doc/guide/admin/aspell.en.pws -index f486703..ae777e2 100644 ---- a/doc/guide/admin/aspell.en.pws -+++ b/doc/guide/admin/aspell.en.pws -@@ -102,7 +102,6 @@ NOSYNC - env - pagedResultsControl - dup --hdb - LDIFv - syslog - monitorTimestamp -@@ -887,7 +886,6 @@ proxyAttrSet - proxyAttrset - mary - crlcheck --olcBdbConfig - kadmin - mech - slapcat -@@ -1190,7 +1188,6 @@ moddn - calloc - LDFLAGS - attributeOrValueExists --olcHdbConfig - bsize - auditObject - dnssrv -@@ -1492,7 +1489,6 @@ ghenry - odbcinst - reqType - slapover --BerkeleyDB's - attributename - lwrap - reqStart -@@ -1628,7 +1624,6 @@ DSAIT - olcHidden - mySNMP - metainformation --BerkeleyDB - ldapuri - auditAbandon - RANDFILE -@@ -1662,7 +1657,6 @@ olcPasswordHash - ldapc - loopback - ldapi --BDB's - GETREALM - functionalities - noplain -@@ -1670,7 +1664,6 @@ NOECHOPROMPT - AES - ldaps - notoc --bdb - LDAPv - IPsec - olcServerID -diff --git a/doc/guide/admin/backends.sdf b/doc/guide/admin/backends.sdf -index 38e9ae2..6e005a6 100644 ---- a/doc/guide/admin/backends.sdf -+++ b/doc/guide/admin/backends.sdf -@@ -14,38 +14,9 @@ name of the module for a backend is usually of the form: - - > back_.la - --So for example, if you need to load the {{hdb}} backend, you would configure -+So for example, if you need to load the {{mdb}} backend, you would configure - --> moduleload back_hdb.la -- --H2: Berkeley DB Backends -- -- --H3: Overview -- --The {{hdb}} backend to {{slapd}}(8) is a backend for a --normal {{slapd}} database. It uses the Oracle Berkeley DB ({{TERM:BDB}}) --package to store data. It makes extensive use of indexing and caching --(see the {{SECT:Tuning}} section) to speed data access. -- --{{hdb}} is a variant of the original {{bdb}} backend which was first written for use with BDB. --{{hdb}} uses a hierarchical database layout which supports subtree renames. --It is otherwise identical to the {{bdb}} --behavior, and all the same configuration options apply. -- --Note: An {{hdb}} database needs a large {{idlcachesize}} for good search performance, --typically three times the {{cachesize}} (entry cache size) or larger. -- --Note: The {{hdb}} backend has superseded the {{bdb}} backend, and both will --soon be deprecated in favor of the new {{mdb}} backend. See below. -- --H3: back-bdb/back-hdb Configuration -- --MORE LATER -- --H3: Further Information -- --{{slapd-bdb}}(5) -+ moduleload back_mdb.la - - H2: LDAP - -@@ -199,16 +170,16 @@ H3: Overview - The {{mdb}} backend to {{slapd}}(8) is the recommended primary backend for a - normal {{slapd}} database. It uses OpenLDAP's own - Lightning Memory-Mapped Database ({{TERM:LMDB}}) --library to store data and is intended to replace the Berkeley DB backends. -+library to store data and replace the BerkeleyDB backends used in older -+OpenLDAP releases. - --It supports indexing like the BDB backends, but it uses no caching and requires --no tuning to deliver maximum search performance. Like {{hdb}}, it is also --fully hierarchical and supports subtree renames in constant time. -+It supports indexing, it uses no caching and requires no tuning to deliver -+maximum search performance. It is fully hierarchical and supports subtree -+renames in constant time. - - H3: back-mdb Configuration - --Unlike the BDB backends, the {{mdb}} backend can be instantiated with very few --configuration lines: -+The {{mdb}} backend can be instantiated with very few configuration lines: - - > include ./schema/core.schema - > -@@ -490,7 +461,7 @@ distribute information between different sites/applications that use RDBMSes - and/or LDAP. Or whatever else... - - It is {{B:NOT}} designed as a general-purpose backend that uses RDBMS instead of --BerkeleyDB (as the standard BDB backend does), though it can be used as such with -+LMDB (as the standard back-mdb backend does), though it can be used as such with - several limitations. Please see {{SECT: LDAP vs RDBMS}} for discussion. - - The idea is to use some meta-information to translate LDAP queries to SQL queries, -diff --git a/doc/guide/admin/install.sdf b/doc/guide/admin/install.sdf -index 9c47b24..4b4e85e 100644 ---- a/doc/guide/admin/install.sdf -+++ b/doc/guide/admin/install.sdf -@@ -118,23 +118,6 @@ OpenLDAP's {{slapd}}(8) {{TERM:MDB}} primary database backend uses the {{TERM:LM - software included with the OpenLDAP source. There is no need to download any - additional software to have {{MDB}} support. - --OpenLDAP's {{slapd}}(8) {{TERM:BDB}} and {{TERM:HDB}} deprecated database backends --require {{ORG[expand]Oracle}}'s Berkeley DB. --If not available at configure time, you will not be able to build --{{slapd}}(8) with these deprecated database backends. -- --Your operating system may provide a supported version of --Berkeley DB in the base system or as an optional --software component. If not, you'll have to obtain and --install it yourself. Berkeley DB is available from --{{ORG[expand]Oracle}}'s Berkeley DB download page if required. -- --There are several versions available from {{ORG[expand]Oracle}}. --Berkeley DB version 6.0.20 and later uses a software license that is --incompatible with LDAP technology and should not be used with OpenLDAP. -- --Note: Please see {{SECT:Recommended OpenLDAP Software Dependency Versions}} for --more information. - - - H3: Threads -diff --git a/doc/guide/admin/intro.sdf b/doc/guide/admin/intro.sdf -index c3dd92f..6aa2149 100644 ---- a/doc/guide/admin/intro.sdf -+++ b/doc/guide/admin/intro.sdf -@@ -346,7 +346,7 @@ really have a "directory". - - Existing commercial LDAP server implementations that use a relational database - are either from the first kind or the third. I don't know of any implementation --that uses a relational database to do inefficiently what BDB does efficiently. -+that uses a relational database to do inefficiently what LMDB does efficiently. - For those who are interested in "third way" (exposing EXISTING data from RDBMS - as LDAP tree, having some limitations compared to classic LDAP model, but making - it possible to interoperate between LDAP and SQL applications): -@@ -403,15 +403,9 @@ tags. - {{B:Choice of database backends}}: {{slapd}} comes with a variety - of different database backends you can choose from. They include - {{TERM:MDB}}, a hierarchical high-performance transactional database backend; --{{TERM:BDB}}, a high-performance transactional database backend (deprecated); --{{TERM:HDB}}, a hierarchical high-performance transactional --backend (deprecated); {{SHELL}}, a backend interface to arbitrary shell scripts; -+{{SHELL}}, a backend interface to arbitrary shell scripts; - and PASSWD, a simple backend interface to the {{passwd}}(5) file. --The MDB backend utilizes {{TERM:LMDB}}, a high performance replacement --for {{ORG[expand]Oracle}}'s Berkeley DB. --The BDB and HDB backends utilize {{ORG[expand]Oracle}} Berkeley DB. These --backends have been deprecated as LMDB provides significantly higher read --and write throughput and data reliability. -+The MDB backend utilizes {{TERM:LMDB}}. - - {{B:Multiple database instances}}: {{slapd}} can be configured to - serve multiple databases at the same time. This means that a single -diff --git a/doc/guide/admin/maintenance.sdf b/doc/guide/admin/maintenance.sdf -index deb14b9..3b7503f 100644 ---- a/doc/guide/admin/maintenance.sdf -+++ b/doc/guide/admin/maintenance.sdf -@@ -14,23 +14,7 @@ Backup strategies largely depend on the amount of change in the database - and how much of that change an administrator might be willing to lose in a - catastrophic failure. There are two basic methods that can be used: - --1. Backup the Berkeley database itself and periodically back up the transaction --log files: -- --Berkeley DB produces transaction logs that can be used to reconstruct --changes from a given point in time. For example, if an administrator were willing to only --lose one hour's worth of changes, they could take down the server in --the middle of the night, copy the Berkeley database files offsite, and bring --the server back online. Then, on an hourly basis, they could force a --database checkpoint, capture the log files that have been generated in the --past hour, and copy them offsite. The accumulated log files, in combination --with the previous database backup, could be used with db_recover to --reconstruct the database up to the time the last collection of log files was --copied offsite. This method affords good protection, with minimal space --overhead. -- -- --2. Periodically run slapcat and back up the LDIF file: -+1. Periodically run slapcat and back up the LDIF file: - - Slapcat can be run while slapd is active. However, one runs the risk of an - inconsistent database- not from the point of slapd, but from the point of -@@ -46,73 +30,11 @@ files can be rather large and the accumulation of the day's backups could - add up to a substantial amount of space. - - You can use {{slapcat}}(8) to generate an LDIF file for each of your {{slapd}}(8) --back-bdb or back-hdb databases. -+back-mdb databases. - - > slapcat -f slapd.conf -b "dc=example,dc=com" - --For back-bdb and back-hdb, this command may be ran while slapd(8) is running. -- --MORE on actual Berkeley DB backups later covering db_recover etc. -- --H2: Berkeley DB Logs -- --Berkeley DB log files grow, and the administrator has to deal with it. The --procedure is known as log file archival or log file rotation. -- --Note: The actual log file rotation is handled by the Berkeley DB engine. -- --Logs of current transactions need to be stored into files so that the database --can be recovered in the event of an application crash. Administrators can change --the size limit of a single log file (by default 10MB), and have old log files --removed automatically, by setting up DB environment (see below). The reason --Berkeley DB never deletes any log files by default is that the administrator --may wish to backup the log files before removal to make database recovery --possible even after a catastrophic failure, such as file system corruption. -- --Log file names are {{F:log.XXXXXXXXXX}} (X is a digit). By default the log files --are located in the BDB backend directory. The {{F:db_archive}} tool knows what --log files are used in current transactions, and what are not. Administrators can --move unused log files to a backup media, and delete them. To have them removed --automatically, place set_flags {{DB_LOG_AUTOREMOVE}} directive in {{F:DB_CONFIG}}. -- --Note: If the log files are removed automatically, recovery after a catastrophic --failure is likely to be impossible. -- --The files with names {{F:__db.001}}, {{F:__db.002}}, etc are just shared memory --regions (or whatever). These ARE NOT 'logs', they must be left alone. Don't be --afraid of them, they do not grow like logs do. -- --To understand the {{F:db_archive}} interface, the reader should refer to --chapter 9 of the Berkeley DB guide. In particular, the following chapters are --recommended: -- --* Database and log file archival - {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/ref/transapp/archival.html}} --* Log file removal - {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/ref/transapp/logfile.html}} --* Recovery procedures - {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/ref/transapp/recovery.html}} --* Hot failover - {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/ref/transapp/hotfail.html}} --* Complete list of Berkeley DB flags - {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/api_c/env_set_flags.html}} -- --Advanced installations can use special environment settings to fine-tune some --Berkeley DB options (change the log file limit, etc). This can be done by using --the {{F:DB_CONFIG}} file. This magic file can be created in BDB backend directory --set up by {{slapd.conf}}(5). More information on this file can be found in File --naming chapter. Specific directives can be found in C Interface, look for --{{DB_ENV->set_XXXX}} calls. -- --Note: options set in {{F:DB_CONFIG}} file override options set by OpenLDAP. --Use them with extreme caution. Do not use them unless You know what You are doing. -- --The advantages of {{F:DB_CONFIG}} usage can be the following: -- --* to keep data files and log files on different mediums (i.e. disks) to improve -- performance and/or reliability; --* to fine-tune some specific options (such as shared memory region sizes); --* to set the log file limit (please read Log file limits before doing this). -- --To figure out the best-practice BDB backup scenario, the reader is highly --recommended to read the whole Chapter 9: Berkeley DB Transactional Data Store Applications. --This chapter is a set of small pages with examples in C language. Non-programming --people can skip these examples without loss of knowledge. -+For back-mdb this command may be ran while slapd(8) is running. - - - H2: Checkpointing -@@ -148,7 +70,7 @@ type are: - +{{B: slapcat the current data out}} - - .{{S: }} --+{{B: Clear out the current data directory (/usr/local/var/openldap-data/) leaving DB_CONFIG in place}} -++{{B: Clear out the current data directory (/usr/local/var/openldap-data/)}} - - .{{S: }} - +{{B: Perform the software upgrades}} -diff --git a/doc/guide/admin/monitoringslapd.sdf b/doc/guide/admin/monitoringslapd.sdf -index 2781e47..bca2ec5 100644 ---- a/doc/guide/admin/monitoringslapd.sdf -+++ b/doc/guide/admin/monitoringslapd.sdf -@@ -214,11 +214,10 @@ backends, as well as backends loaded by modules. For example: - > monitoredInfo: config - > monitoredInfo: ldif - > monitoredInfo: monitor --> monitoredInfo: bdb --> monitoredInfo: hdb -+> monitoredInfo: mdb - --This indicates the {{config}}, {{ldif}}, {{monitor}}, {{bdb}}, --and {{hdb}} backends are available. -+This indicates the {{config}}, {{ldif}}, {{monitor}}, -+and {{mdb}} backends are available. - - The {{EX:cn=Backends,cn=Monitor}} object is also a container - for available backend objects. Each available backend object -@@ -242,21 +241,7 @@ contains information about a particular backend. For example: - > seeAlso: cn=Database 2,cn=Databases,cn=Monitor - > - > dn: cn=Backend 3,cn=Backends,cn=Monitor --> monitoredInfo: bdb --> monitorRuntimeConfig: TRUE --> supportedControl: 1.3.6.1.1.12 --> supportedControl: 2.16.840.1.113730.3.4.2 --> supportedControl: 1.3.6.1.4.1.4203.666.5.2 --> supportedControl: 1.2.840.113556.1.4.319 --> supportedControl: 1.3.6.1.1.13.1 --> supportedControl: 1.3.6.1.1.13.2 --> supportedControl: 1.3.6.1.4.1.4203.1.10.1 --> supportedControl: 1.2.840.113556.1.4.1413 --> supportedControl: 1.3.6.1.4.1.4203.666.11.7.2 --> seeAlso: cn=Database 1,cn=Databases,cn=Monitor --> --> dn: cn=Backend 4,cn=Backends,cn=Monitor --> monitoredInfo: hdb -+> monitoredInfo: mdb - > monitorRuntimeConfig: TRUE - > supportedControl: 1.3.6.1.1.12 - > supportedControl: 2.16.840.1.113730.3.4.2 -@@ -271,7 +256,7 @@ contains information about a particular backend. For example: - For each of these objects, monitorInfo indicates which backend the - information in the object is about. For instance, the {{EX:cn=Backend - 3,cn=Backends,cn=Monitor}} object contains (in the example) information --about the {{bdb}} backend. -+about the {{mdb}} backend. - - !block table - Attribute|Description -diff --git a/doc/guide/admin/overlays.sdf b/doc/guide/admin/overlays.sdf -index 2eb115b..712cd1b 100644 ---- a/doc/guide/admin/overlays.sdf -+++ b/doc/guide/admin/overlays.sdf -@@ -743,9 +743,9 @@ H4: Setting cache parameters - This directive enables proxy caching and sets general cache - parameters. The parameter specifies which underlying database - is to be used to hold cached entries. It should be set to --{{EX:mdb}}, {{EX:hdb}}, or {{EX:bdb}}. The parameter --specifies the total number of entries which may be held in the cache. --The parameter specifies the total number of attribute sets -+{{EX:mdb}}. The parameter specifies the -+total number of entries which may be held in the cache. The -+ parameter specifies the total number of attribute sets - (as specified by the {{EX:pcacheAttrset}} directive) that may be - defined. The parameter specifies the maximum number of - entries in a cacheable query. The specifies the consistency -diff --git a/doc/guide/admin/replication.sdf b/doc/guide/admin/replication.sdf -index 87139b5..bbc91e4 100644 ---- a/doc/guide/admin/replication.sdf -+++ b/doc/guide/admin/replication.sdf -@@ -225,8 +225,8 @@ in the replication context. - - The syncrepl engine, which is a consumer-side replication engine, - can work with any backends. The LDAP Sync provider can be configured --as an overlay on any backend, but works best with the {{back-bdb}}, --{{back-hdb}}, or {{back-mdb}} backends. -+as an overlay on any backend, but works best with the {{back-mdb}}, -+backends. - - The LDAP Sync provider maintains a {{EX:contextCSN}} for each - database as the current synchronization state indicator of the -@@ -423,9 +423,6 @@ writes have to go to just one of the mirror nodes at a time - server (slapd in proxy mode) or device (hardware load balancer) - is needed to manage which provider is currently active - * Backups are managed slightly differently --- If backing up the Berkeley database itself and periodically backing up the --transaction log files, then the same member of the mirror pair needs to be --used to collect logfiles until the next database backup is taken - - For configuration, please see the {{SECT:MirrorMode}} section below - -@@ -762,10 +759,7 @@ H4: Delta-syncrepl Consumer configuration - - - The above configuration assumes that you have a replicator identity defined --in your database that can be used to bind to the provider. In addition, --all of the databases (primary, replica, and the accesslog --storage database) should also have properly tuned {{DB_CONFIG}} files that meet --your needs. -+in your database that can be used to bind to the provider. - - Note: An accesslog database is unique to a given master. It should - never be replicated. -diff --git a/doc/guide/admin/slapdconf2.sdf b/doc/guide/admin/slapdconf2.sdf -index cb51d88..8a3e969 100644 ---- a/doc/guide/admin/slapdconf2.sdf -+++ b/doc/guide/admin/slapdconf2.sdf -@@ -69,7 +69,7 @@ used to configure the software. - the schema that is hard-coded in slapd). - .. Child entries of {{EX:cn=schema,cn=config}} contain user schema as - loaded from config files or added at runtime. --* Backend-specific configuration -+* Backend-specific configuration - * Database-specific configuration - .. Overlays are defined in children of the Database entry. - .. Databases and Overlays may also have other miscellaneous children. -@@ -207,7 +207,7 @@ Level Keyword Description - !endblock - - The desired log level can be input as a single integer that --combines the (ORed) desired levels, both in decimal or in hexadecimal -+combines the (ORed) desired levels, both in decimal or in hexadecimal - notation, as a list of integers (that are ORed internally), or as a list of the names that are shown between brackets, such that - - > olcLogLevel 129 -@@ -364,10 +364,8 @@ supported backend types listed in Table 5.2. - !block table; align=Center; coltags="EX,N"; \ - title="Table 5.2: Database Backends" - Types Description --bdb Berkeley DB transactional backend (deprecated) - config Slapd configuration backend - dnssrv DNS SRV backend --hdb Hierarchical variant of bdb backend (deprecated) - ldap Lightweight Directory Access Protocol (Proxy) backend - ldif Lightweight Data Interchange Format backend - mdb Memory-Mapped DB backend -@@ -381,7 +379,7 @@ sql SQL Programmable backend - - \Example: - --> olcBackend: bdb -+> olcBackend: mdb - - There are no other directives defined for this entry. Specific backend - types may define additional attributes for their particular use but so -@@ -391,9 +389,9 @@ not appear in any actual configurations. - - H4: Sample Entry - --> dn: olcBackend=bdb,cn=config -+> dn: olcBackend=mdb,cn=config - > objectClass: olcBackendConfig --> olcBackend: bdb -+> olcBackend: mdb - - - H3: Database-specific Directives -@@ -421,9 +419,9 @@ databases. - - \Example: - --> olcDatabase: bdb -+> olcDatabase: mdb - --This marks the beginning of a new {{TERM:BDB}} database instance. -+This marks the beginning of a new {{TERM:MDB}} database instance. - - - H4: olcAccess: to [ by [] [] ]+ -@@ -642,7 +640,7 @@ schema conformance. The default is off. - The {{EX:binddn}} parameter gives the DN to bind as for the - syncrepl searches to the provider slapd. It should be a DN - which has read access to the replication content in the --master database. -+master database. - - The {{EX:bindmethod}} is {{EX:simple}} or {{EX:sasl}}, - depending on whether simple password-based authentication or -@@ -683,8 +681,8 @@ conforms to the obsolete {{changelog}} format. If the {{EX:syncdata}} - parameter is omitted or set to {{EX:"default"}} then the log - parameters are ignored. - --The {{syncrepl}} replication mechanism is supported by the {{bdb}}, --{{hdb}}, and {{mdb}} backends. -+The {{syncrepl}} replication mechanism is supported by the {{mdb}} -+backend. - - See the {{SECT:LDAP Sync Replication}} chapter of this guide for - more information on how to use this directive. -@@ -731,21 +729,20 @@ H4: Sample Entries - >olcRootDN: cn=Manager,dc=example,dc=com - - --H3: BDB and HDB Database Directives -+H3: MDB Database Directives - --Directives in this category apply to both the {{TERM:BDB}} --and the {{TERM:HDB}} database. -+Directives in this category apply to the {{TERM:MDB}} -+database backend. - They are used in an olcDatabase entry in addition to the generic - database directives defined above. For a complete reference --of BDB/HDB configuration directives, see {{slapd-bdb}}(5). In --addition to the {{EX:olcDatabaseConfig}} objectClass, BDB and HDB --database entries must have the {{EX:olcBdbConfig}} and --{{EX:olcHdbConfig}} objectClass, respectively. -+of MDB configuration directives, see {{slapd-mdb}}(5). In -+addition to the {{EX:olcDatabaseConfig}} objectClass, MDB -+database entries must have the {{EX:olcMdbConfig}} objectClass. - - - H4: olcDbDirectory: - --This directive specifies the directory where the BDB files -+This directive specifies the directory where the MDB files - containing the database and associated indices live. - - \Default: -@@ -753,98 +750,48 @@ containing the database and associated indices live. - > olcDbDirectory: /usr/local/var/openldap-data - - --H4: olcDbCachesize: -- --This directive specifies the size in entries of the in-memory --cache maintained by the BDB backend database instance. -- --\Default: -- --> olcDbCachesize: 1000 -- -- - H4: olcDbCheckpoint: - --This directive specifies how often to checkpoint the BDB transaction log. --A checkpoint operation flushes the database buffers to disk and writes a --checkpoint record in the log. -+This directive specifies the frequency for flushing the database disk -+buffers. This directive is only needed if the {{olcDbNoSync}} option is -+{{EX:TRUE}}. - The checkpoint will occur if either data has been written or - minutes have passed since the last checkpoint. Both arguments default - to zero, in which case they are ignored. When the argument is - non-zero, an internal task will run every minutes to perform the --checkpoint. See the Berkeley DB reference guide for more details. -+checkpoint. Note: currently the _kbyte_ setting is unimplemented. - - \Example: - - > olcDbCheckpoint: 1024 10 - - --H4: olcDbConfig: -+H4: olcDbEnvFlags: {nosync,nometasync,writemap,mapasync,nordahead} - --This attribute specifies a configuration directive to be placed in the --{{EX:DB_CONFIG}} file of the database directory. At server startup time, if --no such file exists yet, the {{EX:DB_CONFIG}} file will be created and the --settings in this attribute will be written to it. If the file exists, --its contents will be read and displayed in this attribute. The attribute --is multi-valued, to accommodate multiple configuration directives. No default --is provided, but it is essential to use proper settings here to get the --best server performance. -+This option specifies flags for finer-grained control of the LMDB library's -+operation. - --Any changes made to this attribute will be written to the {{EX:DB_CONFIG}} --file and will cause the database environment to be reset so the changes --can take immediate effect. If the environment cache is large and has not --been recently checkpointed, this reset operation may take a long time. It --may be advisable to manually perform a single checkpoint using the Berkeley DB --{{db_checkpoint}} utility before using LDAP Modify to change this --attribute. -+* {{F:nosync}}: This is exactly the same as the dbnosync directive. - --\Example: -+* {{F:nometasync}}: Flush the data on a commit, but skip the sync of the meta -+page. This mode is slightly faster than doing a full sync, but can -+potentially lose the last committed transaction if the operating system -+crashes. If both nometasync and nosync are set, the nosync flag takes -+precedence. - --> olcDbConfig: set_cachesize 0 10485760 0 --> olcDbConfig: set_lg_bsize 2097512 --> olcDbConfig: set_lg_dir /var/tmp/bdb-log --> olcDbConfig: set_flags DB_LOG_AUTOREMOVE -- --In this example, the BDB cache is set to 10MB, the BDB transaction log --buffer size is set to 2MB, and the transaction log files are to be stored --in the /var/tmp/bdb-log directory. Also a flag is set to tell BDB to --delete transaction log files as soon as their contents have been --checkpointed and they are no longer needed. Without this setting the --transaction log files will continue to accumulate until some other --cleanup procedure removes them. See the Berkeley DB documentation for the --{{EX:db_archive}} command for details. For a complete list of Berkeley DB --flags please see - {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/api_c/env_set_flags.html}} -- --Ideally the BDB cache must be --at least as large as the working set of the database, the log buffer size --should be large enough to accommodate most transactions without overflowing, --and the log directory must be on a separate physical disk from the main --database files. And both the database directory and the log directory --should be separate from disks used for regular system activities such as --the root, boot, or swap filesystems. See the FAQ-o-Matic and the Berkeley DB --documentation for more details. -+* {{F:writemap}}: Use a writable memory map instead of just read-only. This -+speeds up write operations but makes the database vulnerable to corruption in -+case any bugs in slapd cause stray writes into the mmap region. - -+* {{F:mapasync}}: When using a writable memory map and performing flushes on -+each commit, use an asynchronous flush instead of a synchronous flush (the -+default). This option has no effect if writemap has not been set. It also has -+no effect if nosync is set. - --H4: olcDbNosync: { TRUE | FALSE } -- --This option causes on-disk database contents to not be immediately --synchronized with in memory changes upon change. Setting this option --to {{EX:TRUE}} may improve performance at the expense of data integrity. This --directive has the same effect as using --> olcDbConfig: set_flags DB_TXN_NOSYNC -- -- --H4: olcDbIDLcacheSize: -- --Specify the size of the in-memory index cache, in index slots. The --default is zero. A larger value will speed up frequent searches of --indexed entries. The optimal size will depend on the data and search --characteristics of the database, but using a number three times --the entry cache size is a good starting point. -- --\Example: -- --> olcDbIDLcacheSize: 3000 -+* {{F:nordahead}}: Turn off file readahead. Usually the OS performs readahead -+on every read request. This usually boosts read performance but can be -+harmful to random access read performance if the system's memory is full and -+the DB is larger than RAM. This option is not implemented on Windows. - - - H4: olcDbIndex: { | default} [pres,eq,approx,sub,none] -@@ -874,7 +821,7 @@ matches do not use an index. However, some attributes do support - indexing for inequality matches, based on the equality index. - - A substring index can be more explicitly specified as {{EX:subinitial}}, --{{EX:subany}}, or {{EX:subfinal}}, corresponding to the three -+{{EX:subany}}, or {{EX:subfinal}}, corresponding to the three - possible components - of a substring match filter. A subinitial index only indexes - substrings that appear at the beginning of an attribute value. -@@ -890,7 +837,7 @@ attribute that inherits from {{EX:name}} to be indexed. - By default, no indices are maintained. It is generally advised - that minimally an equality index upon objectClass be maintained. - --> olcDbindex: objectClass eq -+> olcDbIndex: objectClass eq - - Additional indices should be configured corresponding to the - most common searches that are used on the database. -@@ -907,18 +854,24 @@ stopped before the index task completes, indexing will have to be - manually completed using the slapindex tool. - - --H4: olcDbLinearIndex: { TRUE | FALSE } -+H4: olcDbMaxReaders: -+ -+This directive specifies the maximum number of threads that may have -+concurrent read access to the database. Tools such as slapcat count as a -+single thread, in addition to threads in any active slapd processes. The -+default is 126. -+ - --If this setting is {{EX:TRUE}} slapindex will index one attribute --at a time. The default settings is {{EX:FALSE}} in which case all --indexed attributes of an entry are processed at the same time. When --enabled, each indexed attribute is processed individually, using --multiple passes through the entire database. This option improves --slapindex performance when the database size exceeds the BDB cache --size. When the BDB cache is large enough, this option is not needed --and will decrease performance. Also by default, slapadd performs --full indexing and so a separate slapindex run is not needed. With --this option, slapadd does no indexing and slapindex must be used. -+H4: olcDbMaxSize: -+ -+This directive specifies the maximum size of the database in bytes. A memory -+map of this size is allocated at startup time and the database will not be -+allowed to grow beyond this size. The default is 10485760 bytes (10MB). This -+setting may be changed upward if the configured limit needs to be increased. -+ -+Note: It is important to set this to as large a value as possible, (relative -+to anticipated growth of the actual data over time) since growing the size -+later may not be practical when the system is under heavy load. - - - H4: olcDbMode: { | } -@@ -932,6 +885,18 @@ created database index files should have. This can be in the form - > olcDbMode: 0600 - - -+H4: olcDbRtxnsize: -+ -+This directive specifies the maximum number of entries to process in a single -+read transaction when executing a large search. Long-lived read transactions -+prevent old database pages from being reused in write transactions, and so -+can cause significant growth of the database file when there is heavy write -+traffic. This setting causes the read transaction in large searches to be -+released and reacquired after the given number of entries has been read, to -+give writers the opportunity to reclaim old database pages. The default is -+10000. -+ -+ - H4: olcDbSearchStack: - - Specify the depth of the stack used for search filter evaluation. -@@ -955,33 +920,21 @@ to take effect. - > olcDbSearchStack: 16 - - --H4: olcDbShmKey: -- --Specify a key for a shared memory BDB environment. By default the BDB --environment uses memory mapped files. If a non-zero value is specified, --it will be used as the key to identify a shared memory region that will --house the environment. -- --\Example: -+H4: olcDbNosync: { TRUE | FALSE } - --> olcDbShmKey: 42 -+This directive causes on-disk database contents to not be immediately -+synchronized with in memory changes upon change. Setting this option -+to {{EX:TRUE}} may improve performance at the expense of data integrity. - - - H4: Sample Entry - -->dn: olcDatabase=hdb,cn=config -+>dn: olcDatabase=mdb,cn=config - >objectClass: olcDatabaseConfig -->objectClass: olcHdbConfig -->olcDatabase: hdb -+>objectClass: olcMdbConfig -+>olcDatabase: mdb - >olcSuffix: dc=example,dc=com - >olcDbDirectory: /usr/local/var/openldap-data -->olcDbCacheSize: 1000 -->olcDbCheckpoint: 1024 10 -->olcDbConfig: set_cachesize 0 10485760 0 -->olcDbConfig: set_lg_bsize 2097152 -->olcDbConfig: set_lg_dir /var/tmp/bdb-log -->olcDbConfig: set_flags DB_LOG_AUTOREMOVE -->olcDbIDLcacheSize: 3000 - >olcDbIndex: objectClass eq - - -@@ -989,7 +942,7 @@ H2: Configuration Example - - The following is an example configuration, interspersed - with explanatory text. It defines two databases to handle --different parts of the {{TERM:X.500}} tree; both are {{TERM:BDB}} -+different parts of the {{TERM:X.500}} tree; both are {{TERM:MDB}} - database instances. The line numbers shown are provided for - reference only and are not included in the actual file. First, the - global configuration section: -@@ -999,7 +952,7 @@ E: 2. dn: cn=config - E: 3. objectClass: olcGlobal - E: 4. cn: config - E: 5. olcReferral: ldap://root.openldap.org --E: 6. -+E: 6. - - Line 1 is a comment. Lines 2-4 identify this as the global - configuration entry. -@@ -1013,7 +966,7 @@ E: 7. # internal schema - E: 8. dn: cn=schema,cn=config - E: 9. objectClass: olcSchemaConfig - E: 10. cn: schema --E: 11. -+E: 11. - - Line 7 is a comment. Lines 8-10 identify this as the root of - the schema subtree. The actual schema definitions in this entry -@@ -1022,7 +975,7 @@ Line 11 is a blank line, indicating the end of this entry. - - E: 12. # include the core schema - E: 13. include: file:///usr/local/etc/openldap/schema/core.ldif --E: 14. -+E: 14. - - Line 12 is a comment. Line 13 is an LDIF include directive which - accesses the {{core}} schema definitions in LDIF format. Line 14 -@@ -1037,7 +990,7 @@ E: 16. dn: olcDatabase=frontend,cn=config - E: 17. objectClass: olcDatabaseConfig - E: 18. olcDatabase: frontend - E: 19. olcAccess: to * by * read --E: 20. -+E: 20. - - Line 15 is a comment. Lines 16-18 identify this entry as the global - database entry. Line 19 is a global access control. It applies to all -@@ -1066,16 +1019,16 @@ inaccessible.) - - Line 28 is a blank line. - --The next entry defines a BDB backend that will handle queries for things -+The next entry defines an MDB backend that will handle queries for things - in the "dc=example,dc=com" portion of the tree. Indices are to be maintained - for several attributes, and the {{EX:userPassword}} attribute is to be - protected from unauthorized access. - --E: 29. # BDB definition for example.com --E: 30. dn: olcDatabase=bdb,cn=config -+E: 29. # MDB definition for example.com -+E: 30. dn: olcDatabase=mdb,cn=config - E: 31. objectClass: olcDatabaseConfig --E: 32. objectClass: olcBdbConfig --E: 33. olcDatabase: bdb -+E: 32. objectClass: olcMdbConfig -+E: 33. olcDatabase: mdb - E: 34. olcSuffix: dc=example,dc=com - E: 35. olcDbDirectory: /usr/local/var/openldap-data - E: 36. olcRootDN: cn=Manager,dc=example,dc=com -@@ -1092,7 +1045,7 @@ E: 46. olcAccess: to * - E: 47. by self write - E: 48. by dn.base="cn=Admin,dc=example,dc=com" write - E: 49. by * read --E: 50. -+E: 50. - - Line 29 is a comment. Lines 30-33 identify this entry as a BDB database - configuration entry. Line 34 specifies the DN suffix -@@ -1116,16 +1069,16 @@ entry, but may be read by all users (authenticated or not). - Line 50 is a blank line, indicating the end of this entry. - - The next entry defines another --BDB database. This one handles queries involving the -+MDB database. This one handles queries involving the - {{EX:dc=example,dc=net}} subtree but is managed by the same entity - as the first database. Note that without line 60, the read access - would be allowed due to the global access rule at line 19. - --E: 51. # BDB definition for example.net --E: 52. dn: olcDatabase=bdb,cn=config -+E: 51. # MDB definition for example.net -+E: 52. dn: olcDatabase=mdb,cn=config - E: 53. objectClass: olcDatabaseConfig --E: 54. objectClass: olcBdbConfig --E: 55. olcDatabase: bdb -+E: 54. objectClass: olcMdbConfig -+E: 55. olcDatabase: mdb - E: 56. olcSuffix: dc=example,dc=net - E: 57. olcDbDirectory: /usr/local/var/openldap-data-net - E: 58. olcRootDN: cn=Manager,dc=example,dc=com -diff --git a/doc/guide/admin/slapdconfig.sdf b/doc/guide/admin/slapdconfig.sdf -index d943eb9..8b1162c 100644 ---- a/doc/guide/admin/slapdconfig.sdf -+++ b/doc/guide/admin/slapdconfig.sdf -@@ -90,7 +90,7 @@ H4: access to [ by [] [] ]+ - - This directive grants access (specified by ) to a set - of entries and/or attributes (specified by ) by one or more --requestors (specified by ). See the {{SECT:Access Control}} section of -+requestors (specified by ). See the {{SECT:Access Control}} section of - this guide for basic usage. - - !if 0 -@@ -162,7 +162,7 @@ Level Keyword Description - !endblock - - The desired log level can be input as a single integer that --combines the (ORed) desired levels, both in decimal or in hexadecimal -+combines the (ORed) desired levels, both in decimal or in hexadecimal - notation, as a list of integers (that are ORed internally), or as a list of the names that are shown between brackets, such that - - > loglevel 129 -@@ -264,9 +264,7 @@ supported backend types listed in Table 6.2. - !block table; align=Center; coltags="EX,N"; \ - title="Table 6.2: Database Backends" - Types Description --bdb Berkeley DB transactional backend (deprecated) - dnssrv DNS SRV backend --hdb Hierarchical variant of bdb backend (deprecated) - ldap Lightweight Directory Access Protocol (Proxy) backend - mdb Memory-Mapped DB backend - meta Meta Directory backend -@@ -507,7 +505,7 @@ defaults for these parameters come from {{ldap.conf}}(5). - The {{EX:binddn}} parameter gives the DN to bind as for the - syncrepl searches to the provider slapd. It should be a DN - which has read access to the replication content in the --master database. -+master database. - - The {{EX:bindmethod}} is {{EX:simple}} or {{EX:sasl}}, - depending on whether simple password-based authentication or -@@ -564,8 +562,7 @@ conforms to the obsolete {{changelog}} format. If the {{EX:syncdata}} - parameter is omitted or set to {{EX:"default"}} then the log - parameters are ignored. - --The {{syncrepl}} replication mechanism is supported by the {{bdb}}, --{{hdb}}, and {{mdb}} backends. -+The {{syncrepl}} replication mechanism is supported by the {{mdb}} backends. - - See the {{SECT:LDAP Sync Replication}} chapter of this guide for - more information on how to use this directive. -@@ -584,19 +581,18 @@ If specified multiple times, each {{TERM:URL}} is provided. - > updateref ldap://master.example.net - - --H3: BDB and HDB Database Directives -+H3: MDB Database Directives - --Directives in this category only apply to both the {{TERM:BDB}} --and the {{TERM:HDB}} database. --That is, they must follow a "database bdb" or "database hdb" line --and come before any --subsequent "backend" or "database" line. For a complete reference --of BDB/HDB configuration directives, see {{slapd-bdb}}(5). -+Directives in this category only apply to the {{TERM:MDB}} -+database backend. -+That is, they must follow a "database mdb" line -+and come before any subsequent "backend" or "database" lines. -+For a complete reference of MDB configuration directives, see {{slapd-mdb}}(5). - - - H4: directory - --This directive specifies the directory where the BDB files -+This directive specifies the directory where the MDB files - containing the database and associated indices live. - - \Default: -@@ -604,11 +600,189 @@ containing the database and associated indices live. - > directory /usr/local/var/openldap-data - - -+H4: checkpoint -+ -+This directive specifies the frequency for flushing the database disk -+buffers. This directive is only needed if the {{dbnosync}} option is -+{{EX:TRUE}}. -+The checkpoint will occur if either data has been written or -+ minutes have passed since the last checkpoint. Both arguments default -+to zero, in which case they are ignored. When the argument is -+non-zero, an internal task will run every minutes to perform the -+checkpoint. Note: currently the _kbyte_ setting is unimplemented. -+ -+\Example: -+ -+> checkpoint: 1024 10 -+ -+H4: dbnosync: { TRUE | FALSE } -+ -+This directive causes on-disk database contents to not be immediately -+synchronized with in memory changes upon change. Setting this option -+to {{EX:TRUE}} may improve performance at the expense of data integrity. -+ -+ -+H4: envflags: {nosync,nometasync,writemap,mapasync,nordahead} -+ -+This option specifies flags for finer-grained control of the LMDB library's -+operation. -+ -+* {{F:nosync}}: This is exactly the same as the dbnosync directive. -+ -+* {{F:nometasync}}: Flush the data on a commit, but skip the sync of the meta -+page. This mode is slightly faster than doing a full sync, but can -+potentially lose the last committed transaction if the operating system -+crashes. If both nometasync and nosync are set, the nosync flag takes -+precedence. -+ -+* {{F:writemap}}: Use a writable memory map instead of just read-only. This -+speeds up write operations but makes the database vulnerable to corruption in -+case any bugs in slapd cause stray writes into the mmap region. -+ -+* {{F:mapasync}}: When using a writable memory map and performing flushes on -+each commit, use an asynchronous flush instead of a synchronous flush (the -+default). This option has no effect if writemap has not been set. It also has -+no effect if nosync is set. -+ -+* {{F:nordahead}}: Turn off file readahead. Usually the OS performs readahead -+on every read request. This usually boosts read performance but can be -+harmful to random access read performance if the system's memory is full and -+the DB is larger than RAM. This option is not implemented on Windows. -+ -+ -+H4: index: { | default} [pres,eq,approx,sub,none] -+ -+This directive specifies the indices to maintain for the given -+attribute. If only an {{EX:}} is given, the default -+indices are maintained. The index keywords correspond to the -+common types of matches that may be used in an LDAP search filter. -+ -+\Example: -+ -+> index: default pres,eq -+> index: uid -+> index: cn,sn pres,eq,sub -+> index: objectClass eq -+ -+The first line sets the default set of indices to maintain to -+present and equality. The second line causes the default (pres,eq) -+set of indices to be maintained for the {{EX:uid}} attribute type. -+The third line causes present, equality, and substring indices to -+be maintained for {{EX:cn}} and {{EX:sn}} attribute types. The -+fourth line causes an equality index for the {{EX:objectClass}} -+attribute type. -+ -+There is no index keyword for inequality matches. Generally these -+matches do not use an index. However, some attributes do support -+indexing for inequality matches, based on the equality index. -+ -+A substring index can be more explicitly specified as {{EX:subinitial}}, -+{{EX:subany}}, or {{EX:subfinal}}, corresponding to the three -+possible components -+of a substring match filter. A subinitial index only indexes -+substrings that appear at the beginning of an attribute value. -+A subfinal index only indexes substrings that appear at the end -+of an attribute value, while subany indexes substrings that occur -+anywhere in a value. -+ -+Note that by default, setting an index for an attribute also -+affects every subtype of that attribute. E.g., setting an equality -+index on the {{EX:name}} attribute causes {{EX:cn}}, {{EX:sn}}, and every other -+attribute that inherits from {{EX:name}} to be indexed. -+ -+By default, no indices are maintained. It is generally advised -+that minimally an equality index upon objectClass be maintained. -+ -+> index: objectClass eq -+ -+Additional indices should be configured corresponding to the -+most common searches that are used on the database. -+Presence indexing should not be configured for an attribute -+unless the attribute occurs very rarely in the database, and -+presence searches on the attribute occur very frequently during -+normal use of the directory. Most applications don't use presence -+searches, so usually presence indexing is not very useful. -+ -+ -+H4: maxreaders: -+ -+This directive specifies the maximum number of threads that may have -+concurrent read access to the database. Tools such as slapcat count as a -+single thread, in addition to threads in any active slapd processes. The -+default is 126. -+ -+ -+H4: maxsize: -+ -+This directive specifies the maximum size of the database in bytes. A memory -+map of this size is allocated at startup time and the database will not be -+allowed to grow beyond this size. The default is 10485760 bytes (10MB). This -+setting may be changed upward if the configured limit needs to be increased. -+ -+Note: It is important to set this to as large a value as possible, (relative -+to anticipated growth of the actual data over time) since growing the size -+later may not be practical when the system is under heavy load. -+ -+ -+H4: mode: { | } -+ -+This directive specifies the file protection mode that newly -+created database index files should have. This can be in the form -+{{EX:0600}} or {{EX:-rw-------}} -+ -+\Default: -+ -+> mode: 0600 -+ -+ -+H4: rtxnsize: -+ -+This directive specifies the maximum number of entries to process in a single -+read transaction when executing a large search. Long-lived read transactions -+prevent old database pages from being reused in write transactions, and so -+can cause significant growth of the database file when there is heavy write -+traffic. This setting causes the read transaction in large searches to be -+released and reacquired after the given number of entries has been read, to -+give writers the opportunity to reclaim old database pages. The default is -+10000. -+ -+ -+H4: searchstack: -+ -+Specify the depth of the stack used for search filter evaluation. -+Search filters are evaluated on a stack to accommodate nested {{EX:AND}} / -+{{EX:OR}} clauses. An individual stack is allocated for each server thread. -+The depth of the stack determines how complex a filter can be evaluated -+without requiring any additional memory allocation. Filters that are -+nested deeper than the search stack depth will cause a separate stack to -+be allocated for that particular search operation. These separate allocations -+can have a major negative impact on server performance, but specifying -+too much stack will also consume a great deal of memory. Each search -+uses 512K bytes per level on a 32-bit machine, or 1024K bytes per level -+on a 64-bit machine. The default stack depth is 16, thus 8MB or 16MB -+per thread is used on 32 and 64 bit machines, respectively. Also the -+512KB size of a single stack slot is set by a compile-time constant which -+may be changed if needed; the code must be recompiled for the change -+to take effect. -+ -+\Default: -+ -+> searchstack: 16 -+ -+ -+H4: Sample Entry -+ -+>database mdb -+>suffix: "dc=example,dc=com" -+>directory: /usr/local/var/openldap-data -+>index: objectClass eq -+ -+ - H2: Configuration File Example - - The following is an example configuration file, interspersed - with explanatory text. It defines two databases to handle --different parts of the {{TERM:X.500}} tree; both are {{TERM:BDB}} -+different parts of the {{TERM:X.500}} tree; both are {{TERM:MDB}} - database instances. The line numbers shown are provided for - reference only and are not included in the actual file. First, the - global configuration section: -@@ -617,7 +791,7 @@ E: 1. # example config file - global configuration section - E: 2. include /usr/local/etc/schema/core.schema - E: 3. referral ldap://root.openldap.org - E: 4. access to * by * read -- -+ - Line 1 is a comment. Line 2 includes another config file - which contains {{core}} schema definitions. - The {{EX:referral}} directive on line 3 -@@ -629,7 +803,7 @@ Line 4 is a global access control. It applies to all - entries (after any applicable database-specific access - controls). - --The next section of the configuration file defines a BDB -+The next section of the configuration file defines a MDB - backend that will handle queries for things in the - "dc=example,dc=com" portion of the tree. The - database is to be replicated to two slave slapds, one on -@@ -637,8 +811,8 @@ truelies, the other on judgmentday. Indices are to be - maintained for several attributes, and the {{EX:userPassword}} - attribute is to be protected from unauthorized access. - --E: 5. # BDB definition for the example.com --E: 6. database bdb -+E: 5. # MDB definition for the example.com -+E: 6. database mdb - E: 7. suffix "dc=example,dc=com" - E: 8. directory /usr/local/var/openldap-data - E: 9. rootdn "cn=Manager,dc=example,dc=com" -@@ -683,8 +857,8 @@ BDB database. This one handles queries involving the - as the first database. Note that without line 39, the read access - would be allowed due to the global access rule at line 4. - --E: 33. # BDB definition for example.net --E: 34. database bdb -+E: 33. # MDB definition for example.net -+E: 34. database mdb - E: 35. suffix "dc=example,dc=net" - E: 36. directory /usr/local/var/openldap-data-net - E: 37. rootdn "cn=Manager,dc=example,dc=com" -diff --git a/doc/guide/admin/tuning.sdf b/doc/guide/admin/tuning.sdf -index 7074561..795c5ce 100644 ---- a/doc/guide/admin/tuning.sdf -+++ b/doc/guide/admin/tuning.sdf -@@ -27,10 +27,6 @@ H3: Memory - - Scale your cache to use available memory and increase system memory if you can. - --See {{SECT:Caching}} for BDB cache tuning hints. --Note that LMDB uses no cache of its own and has no tuning options, so the Caching --section can be ignored when using LMDB. -- - - H3: Disks - -@@ -39,15 +35,7 @@ types perform best with your workload. (On our own Linux testing, EXT2 and JFS - tend to provide better write performance than everything else, including - newer filesystems like EXT4, BTRFS, etc.) - --Use fast subsystems. Put each database and logs on separate disks --(for BDB this is configurable via {{DB_CONFIG}}): -- --> # Data Directory --> set_data_dir /data/db --> --> # Transaction Log settings --> set_lg_dir /logs -- -+Use fast subsystems. Put each database on separate disks - - H3: Network Topology - -@@ -131,7 +119,7 @@ H3: What to watch out for - - The most common message you'll see that you should pay attention to is: - --> "<= bdb_equality_candidates: (foo) index_param failed (18)" -+> "<= mdb_equality_candidates: (foo) index_param failed (18)" - - That means that some application tried to use an equality filter ({{foo=}}) - and attribute {{foo}} does not have an equality index. If you see a lot of these -@@ -163,165 +151,6 @@ For syslog-ng, add or modify the following line in {{syslog-ng.conf}}: - where n is the number of lines which will be buffered before a write. - - --H2: Caching -- --We all know what caching is, don't we? -- --In brief, "A cache is a block of memory for temporary storage of data likely --to be used again" - {{URL:http://en.wikipedia.org/wiki/Cache}} -- --There are 3 types of caches, BerkeleyDB's own cache, {{slapd}}(8) --entry cache and {{TERM:IDL}} (IDL) cache. -- -- --H3: Berkeley DB Cache -- --There are two ways to tune for the BDB cachesize: -- --(a) BDB cache size necessary to load the database via slapadd in optimal time -- --(b) BDB cache size necessary to have a high performing running slapd once the data is loaded -- --For (a), the optimal cachesize is the size of the entire database. If you --already have the database loaded, this is simply a -- --> du -c -h *.bdb -- --in the directory containing the OpenLDAP ({{/usr/local/var/openldap-data}}) data. -- --For (b), the optimal cachesize is just the size of the {{id2entry.bdb}} file, --plus about 10% for growth. -- --The tuning of {{DB_CONFIG}} should be done for each BDB type database --instantiated (back-bdb, back-hdb). -- --Note that while the {{TERM:BDB}} cache is just raw chunks of memory and --configured as a memory size, the {{slapd}}(8) entry cache holds parsed entries, --and the size of each entry is variable. -- --There is also an IDL cache which is used for Index Data Lookups. --If you can fit all of your database into slapd's entry cache, and all of your --index lookups fit in the IDL cache, that will provide the maximum throughput. -- --If not, but you can fit the entire database into the BDB cache, then you --should do that and shrink the slapd entry cache as appropriate. -- --Failing that, you should balance the BDB cache against the entry cache. -- --It is worth noting that it is not absolutely necessary to configure a BerkeleyDB --cache equal in size to your entire database. All that you need is a cache --that's large enough for your "working set." -- --That means, large enough to hold all of the most frequently accessed data, --plus a few less-frequently accessed items. -- --For more information, please see: {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/ref/am_conf/cachesize.html}} -- --H4: Calculating Cachesize -- --The back-bdb database lives in two main files, {{F:dn2id.bdb}} and {{F:id2entry.bdb}}. --These are B-tree databases. We have never documented the back-bdb internal --layout before, because it didn't seem like something anyone should have to worry --about, nor was it necessarily cast in stone. But here's how it works today, --in OpenLDAP 2.4. -- --A B-tree is a balanced tree; it stores data in its leaf nodes and bookkeeping --data in its interior nodes (If you don't know what tree data structures look -- like in general, Google for some references, because that's getting far too --elementary for the purposes of this discussion). -- --For decent performance, you need enough cache memory to contain all the nodes --along the path from the root of the tree down to the particular data item --you're accessing. That's enough cache for a single search. For the general case, --you want enough cache to contain all the internal nodes in the database. -- --> db_stat -d -- --will tell you how many internal pages are present in a database. You should --check this number for both dn2id and id2entry. -- --Also note that {{id2entry}} always uses 16KB per "page", while {{dn2id}} uses whatever --the underlying filesystem uses, typically 4 or 8KB. To avoid thrashing, --your cache must be at least as large as the number of internal pages in both --the {{dn2id}} and {{id2entry}} databases, plus some extra space to accommodate --the actual leaf data pages. -- --For example, in my OpenLDAP 2.4 test database, I have an input LDIF file that's --about 360MB. With the back-hdb backend this creates a {{dn2id.bdb}} that's 68MB, --and an {{id2entry}} that's 800MB. db_stat tells me that {{dn2id}} uses 4KB pages, has --433 internal pages, and 6378 leaf pages. The id2entry uses 16KB pages, has 52 --internal pages, and 45912 leaf pages. In order to efficiently retrieve any --single entry in this database, the cache should be at least -- --> (433+1) * 4KB + (52+1) * 16KB in size: 1736KB + 848KB =~ 2.5MB. -- --This doesn't take into account other library overhead, so this is even lower --than the barest minimum. The default cache size, when nothing is configured, --is only 256KB. -- --This 2.5MB number also doesn't take indexing into account. Each indexed --attribute results in another database file. Earlier versions of OpenLDAP --kept these index databases in Hash format, but from OpenLDAP 2.2 onward --the index databases are in B-tree format so the same procedure can --be used to calculate the necessary amount of cache for each index database. -- --For example, if your only index is for the objectClass attribute and db_stat --reveals that {{objectClass.bdb}} has 339 internal pages and uses 4096 byte --pages, the additional cache needed for just this attribute index is -- --> (339+1) * 4KB =~ 1.3MB. -- --With only this index enabled, I'd figure at least a 4MB cache for this backend. --(Of course you're using a single cache shared among all of the database files, --so the cache pages will most likely get used for something other than what you --accounted for, but this gives you a fighting chance.) -- --With this 4MB cache I can slapcat this entire database on my 1.3GHz PIII in --1 minute, 40 seconds. With the cache doubled to 8MB, it still takes the same 1:40s. --Once you've got enough cache to fit the B-tree internal pages, increasing it --further won't have any effect until the cache really is large enough to hold --100% of the data pages. I don't have enough free RAM to hold all the 800MB --id2entry data, so 4MB is good enough. -- --With back-bdb and back-hdb you can use "db_stat -m" to check how well the --database cache is performing. -- --For more information on {{db_stat}}: {{URL:http://www.oracle.com/technology/documentation/berkeley-db/db/utility/db_stat.html}} -- --H3: {{slapd}}(8) Entry Cache (cachesize) -- --The {{slapd}}(8) entry cache operates on decoded entries. The rationale - entries --in the entry cache can be used directly, giving the fastest response. If an entry --isn't in the entry cache but can be extracted from the BDB page cache, that will --avoid an I/O but it will still require parsing, so this will be slower. -- --If the entry is in neither cache then BDB will have to flush some of its current --cached pages and bring in the needed pages, resulting in a couple of expensive --I/Os as well as parsing. -- --The most optimal value is of course, the entire number of entries in the database. --However, most directory servers don't consistently serve out their entire database, so setting this to a lesser number that more closely matches the believed working set of data is --sufficient. This is the second most important parameter for the DB. -- --As far as balancing the entry cache vs the BDB cache - parsed entries in memory --are generally about twice as large as they are on disk. -- --As we have already mentioned, not having a proper database cache size will --cause performance issues. These issues are not an indication of corruption --occurring in the database. It is merely the fact that the cache is thrashing --itself that causes performance/response time to slowdown. -- -- --H3: {{TERM:IDL}} Cache (idlcachesize) -- --Each IDL holds the search results from a given query, so the IDL cache will --end up holding the most frequently requested search results. For back-bdb, --it is generally recommended to match the "cachesize" setting. For back-hdb, --it is generally recommended to be 3x"cachesize". -- --{NOTE: The idlcachesize setting directly affects search performance} -- -- - H2: {{slapd}}(8) Threads - - {{slapd}}(8) can process requests via a configurable number of threads, which -diff --git a/doc/guide/preamble.sdf b/doc/guide/preamble.sdf -index b4cc0dd..aa84f9b 100644 ---- a/doc/guide/preamble.sdf -+++ b/doc/guide/preamble.sdf -@@ -167,7 +167,6 @@ AuthcId|Authentication Identity - AuthzDN|Authorization DN - AuthzId|Authorization Identity - BCP|Best Current Practice --BDB|Berkeley DB (Backend) - BER|Basic Encoding Rules - BNF|Backus-Naur Form - C|The C Programming Language -@@ -201,7 +200,6 @@ FYI|For Your Information - GSER|Generic String Encoding Rules - GSS-API|Generic Security Service Application Program Interface - GSSAPI|SASL Kerberos V GSS-API Authentication Mechanism --HDB|Hierarchical Database (Backend) - I-D|Internet-Draft - IA5|International Alphabet 5 - IDNA|Internationalized Domain Names in Applications -diff --git a/doc/guide/release/install.sdf b/doc/guide/release/install.sdf -index 6770e6a..83c95ae 100644 ---- a/doc/guide/release/install.sdf -+++ b/doc/guide/release/install.sdf -@@ -84,7 +84,7 @@ if you have not done so already. - + Test the standalone system: - - .This step requires the standalone LDAP server, {{slapd}}(8), --with {{HDB}} and/or {{BDB}} support. -+with {{MDB}} support. - - E: % make test - -diff --git a/doc/man/man5/slapd-bdb.5 b/doc/man/man5/slapd-bdb.5 -deleted file mode 100644 -index 3c8ad9c..0000000 ---- a/doc/man/man5/slapd-bdb.5 -+++ /dev/null -@@ -1,286 +0,0 @@ --.TH SLAPD-BDB 5 "RELEASEDATE" "OpenLDAP LDVERSION" --.\" Copyright 1998-2020 The OpenLDAP Foundation All Rights Reserved. --.\" Copying restrictions apply. See COPYRIGHT/LICENSE. --.\" $OpenLDAP$ --.SH NAME --slapd\-bdb, slapd\-hdb \- Berkeley DB backends to slapd --.SH SYNOPSIS --.B ETCDIR/slapd.conf --.SH DESCRIPTION --The \fBbdb\fP backend to --.BR slapd (8) --uses the Oracle Berkeley DB (BDB) package to store data. --It makes extensive use of indexing and caching to speed data access. --.LP --Note that BDB is deprecated and support will be dropped in future --OpenLDAP releases. Installations should use the \fBmdb\fP --backend instead. --.LP --\fBhdb\fP is a variant of --the \fBbdb\fP backend that uses a hierarchical database layout which --supports subtree renames. It is both more space-efficient and more --execution-efficient than the \fBbdb\fP backend. It is otherwise identical --to the \fBbdb\fP behavior, and all the same configuration options apply. --.LP --It is noted that these options are intended to complement --Berkeley DB configuration options set in the environment's --.B DB_CONFIG --file. See Berkeley DB documentation for details on --.B DB_CONFIG --configuration options. --Where there is overlap, settings in --.B DB_CONFIG --take precedence. --.SH CONFIGURATION --These --.B slapd.conf --options apply to the \fBbdb\fP and \fBhdb\fP backend database. --That is, they must follow a "database bdb" or "database hdb" line and --come before any subsequent "backend" or "database" lines. --Other database options are described in the --.BR slapd.conf (5) --manual page. --.TP --.BI cachesize \ --Specify the size in entries of the in-memory entry cache maintained --by the \fBbdb\fP or \fBhdb\fP backend database instance. --The default is 1000 entries. --.TP --.BI cachefree \ --Specify the number of entries to free from the entry cache when the --cache reaches the \fBcachesize\fP limit. --The default is 1 entry. --.TP --.BI checkpoint \ \ --Specify the frequency for checkpointing the database transaction log. --A checkpoint operation flushes the database buffers to disk and writes --a checkpoint record in the log. --The checkpoint will occur if either \fI\fP data has been written or --\fI\fP minutes have passed since the last checkpoint. --Both arguments default to zero, in which case they are ignored. When --the \fI\fP argument is non-zero, an internal task will run every --\fI\fP minutes to perform the checkpoint. --See the Berkeley DB reference guide for more details. --.TP --.B checksum --Enable checksum validation of DB pages whenever they are read from disk. --This setting can only be configured before any database files are created. --.TP --.BI cryptfile \ --Specify the pathname of a file containing an encryption key to use for --encrypting the database. Encryption is performed using Berkeley DB's --implementation of AES. Note that encryption can only be configured before --any database files are created, and changing the key can only be done --after destroying the current database and recreating it. Encryption is --not enabled by default, and some distributions of Berkeley DB do not --support encryption. --.TP --.BI cryptkey \ --Specify an encryption key to use for encrypting the database. This option --may be used when a separate --.I cryptfile --is not desired. Only one of --.B cryptkey --or --.B cryptfile --may be configured. --.TP --.BI dbconfig \ --Specify a configuration directive to be placed in the --.B DB_CONFIG --file of the database directory. The --.B dbconfig --directive is just a convenience --to allow all necessary configuration to be set in the --.B slapd.conf --file. --The options set using this directive will only be written to the --.B DB_CONFIG --file if no such file existed at server startup time, otherwise --they are completely ignored. This allows one --to set initial values without overwriting/destroying a --.B DB_CONFIG --file that was already customized through other means. --This directive may be specified multiple times, as needed. --For example: --.RS --.nf -- dbconfig set_cachesize 0 1048576 0 -- dbconfig set_lg_bsize 2097152 --.fi --.RE --.TP --.B dbnosync --Specify that on-disk database contents should not be immediately --synchronized with in memory changes. --Enabling this option may improve performance at the expense of data --security. --See the Berkeley DB reference guide for more details. --.TP --\fBdbpagesize \fR \fI \fR --Specify the page size to use for a particular database file, in units --of 1024 bytes. The default for the --.B id2entry --file is 16, the default for all other files depends on the size of the --underlying filesystem's block size (typically 4 or 8). --The maximum that BerkeleyDB supports is 64. This --setting usually should not need to be changed, but if BerkeleyDB's --"db_stat \-d" shows a large amount of overflow pages in use in a file, --setting a larger size may increase performance at the expense of --data integrity. This setting only takes effect when a database is --being newly created. See the Berkeley DB reference guide for more details. --.TP --.BI directory \ --Specify the directory where the BDB files containing this database and --associated indexes live. --A separate directory must be specified for each database. --The default is --.BR LOCALSTATEDIR/openldap\-data . --.TP --.B dirtyread --Allow reads of modified but not yet committed data. --Usually transactions are isolated to prevent other operations from --accessing uncommitted data. --This option may improve performance, but may also return inconsistent --results if the data comes from a transaction that is later aborted. --In this case, the modified data is discarded and a subsequent search --will return a different result. --.TP --.BI dncachesize \ --Specify the maximum number of DNs in the in-memory DN cache. --Ideally this cache should be --large enough to contain the DNs of every entry in the database. If --set to a smaller value than the \fBcachesize\fP it will be silently --increased to equal the \fBcachesize\fP. The default value is 0 which --means unlimited, i.e. the DN cache will grow without bound. -- --It should be noted that the \fBDN cache\fP is allowed to temporarily --grow beyond the configured size. It does this if many entries are --locked when it tries to do a purge, because that means they're --legitimately in use. Also, the \fBDN cache\fP never purges entries --that have cached children, so depending on the shape of the DIT, it --could have lots of cached DNs over the defined limit. --.TP --.BI idlcachesize \ --Specify the size of the in-memory index cache, in index slots. The --default is zero. A larger value will speed up frequent searches of --indexed entries. An \fBhdb\fP database needs a large \fBidlcachesize\fP --for good search performance, typically three times the --.B cachesize --(entry cache size) --or larger. --.TP --\fBindex \fR{\fI\fR|\fBdefault\fR} [\fBpres\fR,\fBeq\fR,\fBapprox\fR,\fBsub\fR,\fI\fR] --Specify the indexes to maintain for the given attribute (or --list of attributes). --Some attributes only support a subset of indexes. --If only an \fI\fP is given, the indices specified for \fBdefault\fR --are maintained. --Note that setting a default does not imply that all attributes will be --indexed. Also, for best performance, an --.B eq --index should always be configured for the --.B objectClass --attribute. -- --A number of special index parameters may be specified. --The index type --.B sub --can be decomposed into --.BR subinitial , --.BR subany ,\ and --.B subfinal --indices. --The special type --.B nolang --may be specified to disallow use of this index by language subtypes. --The special type --.B nosubtypes --may be specified to disallow use of this index by named subtypes. --Note: changing \fBindex\fP settings in --.BR slapd.conf (5) --requires rebuilding indices, see --.BR slapindex (8); --changing \fBindex\fP settings --dynamically by LDAPModifying "cn=config" automatically causes rebuilding --of the indices online in a background task. --.TP --.B linearindex --Tell --.B slapindex --to index one attribute at a time. By default, all indexed --attributes in an entry are processed at the same time. With this option, --each indexed attribute is processed individually, using multiple passes --through the entire database. This option improves --.B slapindex --performance --when the database size exceeds the \fBdbcache\fP size. When the \fBdbcache\fP is --large enough, this option is not needed and will decrease performance. --Also by default, --.B slapadd --performs full indexing and so a separate --.B slapindex --run is not needed. With this option, --.B slapadd --does no indexing and --.B slapindex --must be used. --.TP --.BR lockdetect \ { oldest | youngest | fewest | random | default } --Specify which transaction to abort when a deadlock is detected. --The default is --.BR random . --.TP --.BI mode \ --Specify the file protection mode that newly created database --index files should have. --The default is 0600. --.TP --.BI searchstack \ --Specify the depth of the stack used for search filter evaluation. --Search filters are evaluated on a stack to accommodate nested AND / OR --clauses. An individual stack is assigned to each server thread. --The depth of the stack determines how complex a filter can be --evaluated without requiring any additional memory allocation. Filters that --are nested deeper than the search stack depth will cause a separate --stack to be allocated for that particular search operation. These --allocations can have a major negative impact on server performance, --but specifying too much stack will also consume a great deal of memory. --Each search stack uses 512K bytes per level. The default stack depth --is 16, thus 8MB per thread is used. --.TP --.BI shm_key \ --Specify a key for a shared memory BDB environment. By default the --BDB environment uses memory mapped files. If a non-zero value is --specified, it will be used as the key to identify a shared memory --region that will house the environment. --.SH ACCESS CONTROL --The --.B bdb --and --.B hdb --backends honor access control semantics as indicated in --.BR slapd.access (5). --.SH FILES --.TP --.B ETCDIR/slapd.conf --default --.B slapd --configuration file --.TP --.B DB_CONFIG --Berkeley DB configuration file --.SH SEE ALSO --.BR slapd.conf (5), --.BR slapd\-config (5), --.BR slapd\-mdb (5), --.BR slapd (8), --.BR slapadd (8), --.BR slapcat (8), --.BR slapindex (8), --Berkeley DB documentation. --.SH ACKNOWLEDGEMENTS --.so ../Project --Originally begun by Kurt Zeilenga. Caching mechanisms originally designed --by Jong-Hyuk Choi. Completion and subsequent work, as well as --back-hdb, by Howard Chu. -diff --git a/doc/man/man5/slapd-bdb.5.links b/doc/man/man5/slapd-bdb.5.links -deleted file mode 100644 -index 3bc8c40..0000000 ---- a/doc/man/man5/slapd-bdb.5.links -+++ /dev/null -@@ -1 +0,0 @@ --slapd-hdb.5 -diff --git a/doc/man/man5/slapd-config.5 b/doc/man/man5/slapd-config.5 -index 5753292..3061dcf 100644 ---- a/doc/man/man5/slapd-config.5 -+++ b/doc/man/man5/slapd-config.5 -@@ -1123,10 +1123,8 @@ The entry must be named - and must have the olcBackendConfig objectClass. - - should be one of --.BR bdb , - .BR config , - .BR dnssrv , --.BR hdb , - .BR ldap , - .BR ldif , - .BR mdb , -@@ -2059,10 +2057,10 @@ olcDatabase: config - olcRootPW: {SSHA}XKYnrjvGT3wZFQrDD5040US592LxsdLy - olcAccess: to * by * none - --dn: olcDatabase=bdb,cn=config -+dn: olcDatabase=mdb,cn=config - objectClass: olcDatabaseConfig --objectClass: olcBdbConfig --olcDatabase: bdb -+objectClass: olcMdbConfig -+olcDatabase: mdb - olcSuffix: "dc=our\-domain,dc=com" - # The database directory MUST exist prior to - # running slapd AND should only be accessible -diff --git a/doc/man/man5/slapd-mdb.5 b/doc/man/man5/slapd-mdb.5 -index 62146b0..8955bbb 100644 ---- a/doc/man/man5/slapd-mdb.5 -+++ b/doc/man/man5/slapd-mdb.5 -@@ -14,11 +14,8 @@ It relies completely on the underlying operating system for memory - management and does no caching of its own. It is the recommended - primary database backend. - .LP --The \fBmdb\fP backend is similar to the \fBhdb\fP backend in that --it uses a hierarchical database layout which --supports subtree renames. It is both more space-efficient and more --execution-efficient than the \fBbdb\fP backend, while being overall --much simpler to manage. -+The \fBmdb\fP backend uses a hierarchical database layout which -+supports subtree renames. - .SH CONFIGURATION - These - .B slapd.conf -diff --git a/doc/man/man5/slapd-sql.5 b/doc/man/man5/slapd-sql.5 -index 8492553..ccfa3a4 100644 ---- a/doc/man/man5/slapd-sql.5 -+++ b/doc/man/man5/slapd-sql.5 -@@ -19,7 +19,7 @@ sites/applications that use RDBMSes and/or LDAP. - Or whatever else... - .LP - It is NOT designed as a general-purpose backend that uses RDBMS instead --of BerkeleyDB (as the standard BDB backend does), though it can be -+of MDB (as the standard MDB backend does), though it can be - used as such with several limitations. - You can take a look at - .B http://www.openldap.org/faq/index.cgi?file=378 -diff --git a/doc/man/man5/slapd.access.5 b/doc/man/man5/slapd.access.5 -index c62158b..ebad05a 100644 ---- a/doc/man/man5/slapd.access.5 -+++ b/doc/man/man5/slapd.access.5 -@@ -920,9 +920,8 @@ identity, control is passed straight to the subsequent rules. - - .SH OPERATION REQUIREMENTS - Operations require different privileges on different portions of entries. --The following summary applies to primary MDB database backend and the --deprecated BDB and HDB backends. Requirements for other backends may --(and often do) differ. -+The following summary applies to primary MDB database backend. Requirements -+for other backends may (and often do) differ. - - .LP - The -@@ -1085,9 +1084,7 @@ Access control to search entries is checked by the frontend, - so it is fully honored by all backends; for all other operations - and for the discovery phase of the search operation, - full ACL semantics is only supported by the primary backends, i.e. --.BR back\-bdb (5), --and --.BR back\-hdb (5). -+.BR back\-mdb (5). - - Some other backend, like - .BR back\-sql (5), -diff --git a/doc/man/man5/slapd.backends.5 b/doc/man/man5/slapd.backends.5 -index b9f9190..25a70e6 100644 ---- a/doc/man/man5/slapd.backends.5 -+++ b/doc/man/man5/slapd.backends.5 -@@ -19,14 +19,6 @@ corresponding - .BR slapd\- (5) - manual pages. - .TP --.B bdb --This was the recommended primary backend through OpenLDAP 2.3, but it has --since been superseded by the --.BR mdb --backend. It takes care to configure it properly. --It uses the transactional database interface of the Oracle Berkeley --DB (BDB) package to store data. --.TP - .B config - This backend is used to manage the configuration of slapd at run-time. - Unlike other backends, only a single instance of the -@@ -41,22 +33,6 @@ This backend is experimental. - It serves up referrals based upon SRV resource records held in the - Domain Name System. - .TP --.B hdb --This was the recommended primary backend through OpenLDAP 2.4.40 but it has --since been superseded by the --.BR mdb --backend. It takes care to configure it properly. --.B hdb --is a variant of the --.B bdb --backend that uses a hierarchical database --layout. --This layout stores entry DNs more efficiently than the --.B bdb --backend, --using less space and requiring less work to create, delete, and rename --entries. It is also one of the few backends to support subtree renames. --.TP - .B ldap - This backend acts as a proxy to forward incoming requests to another - LDAP server. -@@ -68,14 +44,9 @@ Its usage should be limited to very simple databases, where performance - is not a requirement. This backend also supports subtree renames. - .TP - .B mdb --This is the recommended primary backend, superseding --.BR hdb . -+This is the recommended primary backend. - This backend uses OpenLDAP's own MDB transactional database --library. It is extremely compact and extremely efficient, delivering --much higher performance than the Berkeley DB backends while using --significantly less memory. Also, unlike Berkeley DB, MDB is crash proof, --and requires no special tuning or maintenance. --This backend also supports subtree renames. -+library. This backend also supports subtree renames. - .TP - .B meta - This backend performs basic LDAP proxying with respect to a set of -@@ -138,10 +109,8 @@ ETCDIR/slapd.d - default slapd configuration directory - .SH SEE ALSO - .BR ldap (3), --.BR slapd\-bdb (5), - .BR slapd\-config (5), - .BR slapd\-dnssrv (5), --.BR slapd\-hdb (5), - .BR slapd\-ldap (5), - .BR slapd\-ldif (5), - .BR slapd\-mdb (5), -diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5 -index 78b2415..0fa62ce 100644 ---- a/doc/man/man5/slapd.conf.5 -+++ b/doc/man/man5/slapd.conf.5 -@@ -1250,10 +1250,8 @@ type of backend. - .B backend - Mark the beginning of a backend definition. - should be one of --.BR bdb , - .BR config , - .BR dnssrv , --.BR hdb , - .BR ldap , - .BR ldif , - .BR mdb , -@@ -1280,10 +1278,8 @@ option are mandatory for each database. - .B database - Mark the beginning of a new database instance definition. - should be one of --.BR bdb , - .BR config , - .BR dnssrv , --.BR hdb , - .BR ldap , - .BR ldif , - .BR mdb , -@@ -1593,8 +1589,7 @@ By default, mirrormode is off. - This option enables database-specific monitoring in the entry related - to the current database in the "cn=Databases,cn=Monitor" subtree - of the monitor database, if the monitor database is enabled. --Currently, only the BDB and the HDB databases provide database-specific --monitoring. -+Currently, only the MDB databases provide database-specific monitoring. - The default depends on the backend type. - .TP - .B overlay -diff --git a/doc/man/man5/slapd.overlays.5 b/doc/man/man5/slapd.overlays.5 -index 2345d81..8ca9783 100644 ---- a/doc/man/man5/slapd.overlays.5 -+++ b/doc/man/man5/slapd.overlays.5 -@@ -91,7 +91,7 @@ password resets, etc. - .B refint - Referential Integrity. - This overlay can be used with a backend database such as --.BR slapd\-bdb (5) -+.BR slapd\-mdb (5) - to maintain the cohesiveness of a schema which utilizes reference - attributes. - .TP -@@ -121,7 +121,7 @@ replication, including persistent search functionality. - .B translucent - Translucent Proxy. - This overlay can be used with a backend database such as --.BR slapd\-bdb (5) -+.BR slapd\-mdb (5) - to create a "translucent proxy". - Content of entries retrieved from a remote LDAP server can be partially - overridden by the database. -@@ -129,7 +129,7 @@ overridden by the database. - .B unique - Attribute Uniqueness. - This overlay can be used with a backend database such as --.BR slapd\-bdb (5) -+.BR slapd\-mdb (5) - to enforce the uniqueness of some or all attributes within a subtree. - .TP - .B valsort -diff --git a/doc/man/man8/slapcat.8 b/doc/man/man8/slapcat.8 -index bd22637..a80ad36 100644 ---- a/doc/man/man8/slapcat.8 -+++ b/doc/man/man8/slapcat.8 -@@ -177,8 +177,6 @@ mode) when you do this to ensure consistency of the database. It is - always safe to run - .B slapcat - with the --.BR slapd\-bdb (5), --.BR slapd\-hdb (5), - .BR slapd\-mdb (5), - and - .BR slapd\-null (5) -diff --git a/doc/man/man8/slapschema.8 b/doc/man/man8/slapschema.8 -index 704ab0c..f4ea0cd 100644 ---- a/doc/man/man8/slapschema.8 -+++ b/doc/man/man8/slapschema.8 -@@ -168,8 +168,7 @@ mode) when you do this to ensure consistency of the database. It is - always safe to run - .B slapschema - with the --.BR slapd\-bdb (5), --.BR slapd\-hdb (5), -+.BR slapd\-mdb (5), - and - .BR slapd\-null (5) - backends. -diff --git a/include/portable.hin b/include/portable.hin -index 3169f03..1b1be1a 100644 ---- a/include/portable.hin -+++ b/include/portable.hin -@@ -99,12 +99,6 @@ - /* Define to 1 if you have the `bcopy' function. */ - #undef HAVE_BCOPY - --/* define this if Berkeley DB is available */ --#undef HAVE_BERKELEY_DB -- --/* define if Berkeley DB has DB_THREAD support */ --#undef HAVE_BERKELEY_DB_THREAD -- - /* Define to 1 if you have the header file. */ - #undef HAVE_BITS_TYPES_H - -@@ -924,9 +918,6 @@ - /* define to support per-object ACIs */ - #undef SLAPD_ACI_ENABLED - --/* define to support BDB backend */ --#undef SLAPD_BDB -- - /* define to support cleartext passwords */ - #undef SLAPD_CLEARTEXT - -@@ -936,9 +927,6 @@ - /* define to support DNS SRV backend */ - #undef SLAPD_DNSSRV - --/* define to support HDB backend */ --#undef SLAPD_HDB -- - /* define to support LDAP backend */ - #undef SLAPD_LDAP - -diff --git a/servers/slapd/DB_CONFIG b/servers/slapd/DB_CONFIG -deleted file mode 100644 -index d0f2c68..0000000 ---- a/servers/slapd/DB_CONFIG -+++ /dev/null -@@ -1,28 +0,0 @@ --# $OpenLDAP$ --# Example DB_CONFIG file for use with slapd(8) BDB/HDB databases. --# --# See the Oracle Berkeley DB documentation --# --# for detail description of DB_CONFIG syntax and semantics. --# --# Hints can also be found in the OpenLDAP Software FAQ --# --# in particular: --# -- --# Note: most DB_CONFIG settings will take effect only upon rebuilding --# the DB environment. -- --# one 0.25 GB cache --set_cachesize 0 268435456 1 -- --# Data Directory --#set_data_dir db -- --# Transaction Log settings --set_lg_regionmax 262144 --set_lg_bsize 2097152 --#set_lg_dir logs -- --# Note: special DB_CONFIG flags are no longer needed for "quick" --# slapadd(8) or slapindex(8) access (see their -q option). -diff --git a/servers/slapd/Makefile.in b/servers/slapd/Makefile.in -index b20564d..9a9f589 100644 ---- a/servers/slapd/Makefile.in -+++ b/servers/slapd/Makefile.in -@@ -38,7 +38,7 @@ SRCS = main.c globals.c bconfig.c config.c daemon.c \ - backglue.c backover.c ctxcsn.c ldapsync.c frontend.c \ - slapadd.c slapcat.c slapcommon.c slapdn.c slapindex.c \ - slappasswd.c slaptest.c slapauth.c slapacl.c component.c \ -- aci.c alock.c txn.c slapschema.c \ -+ aci.c txn.c slapschema.c \ - $(@PLAT@_SRCS) - - OBJS = main.o globals.o bconfig.o config.o daemon.o \ -@@ -56,7 +56,7 @@ OBJS = main.o globals.o bconfig.o config.o daemon.o \ - backglue.o backover.o ctxcsn.o ldapsync.o frontend.o \ - slapadd.o slapcat.o slapcommon.o slapdn.o slapindex.o \ - slappasswd.o slaptest.o slapauth.o slapacl.o component.o \ -- aci.o alock.o txn.o slapschema.o \ -+ aci.o txn.o slapschema.o \ - $(@PLAT@_OBJS) - - LDAP_INCDIR= ../../include -I$(srcdir) -I$(srcdir)/slapi -I. -@@ -366,14 +366,8 @@ veryclean-local-srv: FORCE - fi; \ - done - --install-dbc-maybe: install-dbc-@BUILD_BDB@ install-dbc-@BUILD_HDB@ -- --install-dbc-yes: install-db-config --install-dbc-mod: install-db-config --install-dbc-no: -- - install-local-srv: install-slapd install-tools \ -- install-conf install-dbc-maybe install-schema install-tools -+ install-conf install-schema install-tools - - install-slapd: FORCE - -$(MKDIR) $(DESTDIR)$(libexecdir) -diff --git a/servers/slapd/alock.c b/servers/slapd/alock.c -deleted file mode 100644 -index 4e85fad..0000000 ---- a/servers/slapd/alock.c -+++ /dev/null -@@ -1,718 +0,0 @@ --/* alock.c - access lock library */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2005-2020 The OpenLDAP Foundation. -- * Portions Copyright 2004-2005 Symas Corporation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ --/* ACKNOWLEDGEMENTS: -- * This work was initially developed by Emily Backes at Symas -- * Corporation for inclusion in OpenLDAP Software. -- */ -- --#include "portable.h" -- --#if SLAPD_BDB || SLAPD_HDB -- --#include --#include "alock.h" --#include "lutil.h" -- --#include --#include --#include --#include --#include --#include --#include --#ifdef HAVE_SYS_FILE_H --#include --#endif --#include -- --#ifdef _WIN32 --#include --#include --#include --#endif -- -- --static int --alock_grab_lock ( int fd, int slot ) --{ -- int res; -- --#if defined( HAVE_LOCKF ) -- res = lseek (fd, (off_t) (ALOCK_SLOT_SIZE * slot), SEEK_SET); -- if (res == -1) return -1; -- res = lockf (fd, F_LOCK, (off_t) ALOCK_SLOT_SIZE); --#elif defined( HAVE_FCNTL ) -- struct flock lock_info; -- (void) memset ((void *) &lock_info, 0, sizeof (struct flock)); -- -- lock_info.l_type = F_WRLCK; -- lock_info.l_whence = SEEK_SET; -- lock_info.l_start = (off_t) (ALOCK_SLOT_SIZE * slot); -- lock_info.l_len = (off_t) ALOCK_SLOT_SIZE; -- -- res = fcntl (fd, F_SETLKW, &lock_info); --#elif defined( _WIN32 ) -- OVERLAPPED ov; -- HANDLE hh = _get_osfhandle ( fd ); -- ov.hEvent = 0; -- ov.Offset = ALOCK_SLOT_SIZE*slot; -- ov.OffsetHigh = 0; -- res = LockFileEx( hh, LOCKFILE_EXCLUSIVE_LOCK, 0, -- ALOCK_SLOT_SIZE, 0, &ov ) ? 0 : -1; --#else --# error alock needs lockf, fcntl, or LockFile[Ex] --#endif -- if (res == -1) { -- assert (errno != EDEADLK); -- return -1; -- } -- return 0; --} -- --static int --alock_release_lock ( int fd, int slot ) --{ -- int res; -- --#if defined( HAVE_LOCKF ) -- res = lseek (fd, (off_t) (ALOCK_SLOT_SIZE * slot), SEEK_SET); -- if (res == -1) return -1; -- res = lockf (fd, F_ULOCK, (off_t) ALOCK_SLOT_SIZE); -- if (res == -1) return -1; --#elif defined ( HAVE_FCNTL ) -- struct flock lock_info; -- (void) memset ((void *) &lock_info, 0, sizeof (struct flock)); -- -- lock_info.l_type = F_UNLCK; -- lock_info.l_whence = SEEK_SET; -- lock_info.l_start = (off_t) (ALOCK_SLOT_SIZE * slot); -- lock_info.l_len = (off_t) ALOCK_SLOT_SIZE; -- -- res = fcntl (fd, F_SETLKW, &lock_info); -- if (res == -1) return -1; --#elif defined( _WIN32 ) -- HANDLE hh = _get_osfhandle ( fd ); -- if ( !UnlockFile ( hh, ALOCK_SLOT_SIZE*slot, 0, -- ALOCK_SLOT_SIZE, 0 )) -- return -1; --#else --# error alock needs lockf, fcntl, or LockFile[Ex] --#endif -- -- return 0; --} -- --static int --alock_share_lock ( int fd, int slot ) --{ -- int res; -- --#if defined( HAVE_LOCKF ) -- res = 0; /* lockf has no shared locks */ --#elif defined ( HAVE_FCNTL ) -- struct flock lock_info; -- (void) memset ((void *) &lock_info, 0, sizeof (struct flock)); -- -- /* The shared lock replaces the existing lock */ -- lock_info.l_type = F_RDLCK; -- lock_info.l_whence = SEEK_SET; -- lock_info.l_start = (off_t) (ALOCK_SLOT_SIZE * slot); -- lock_info.l_len = (off_t) ALOCK_SLOT_SIZE; -- -- res = fcntl (fd, F_SETLK, &lock_info); -- if (res == -1) return -1; --#elif defined( _WIN32 ) -- OVERLAPPED ov; -- HANDLE hh = _get_osfhandle ( fd ); -- -- /* Windows locks are mandatory, not advisory. -- * We must downgrade the lock to allow future -- * callers to read the slot data. -- * -- * First acquire a shared lock. Unlock will -- * release the existing exclusive lock. -- */ -- ov.hEvent = 0; -- ov.Offset = ALOCK_SLOT_SIZE*slot; -- ov.OffsetHigh = 0; -- LockFileEx (hh, 0, 0, ALOCK_SLOT_SIZE, 0, &ov); -- UnlockFile (hh, ALOCK_SLOT_SIZE*slot, 0, ALOCK_SLOT_SIZE, 0); --#else --# error alock needs lockf, fcntl, or LockFile[Ex] --#endif -- -- return 0; --} -- --static int --alock_test_lock ( int fd, int slot ) --{ -- int res; -- --#if defined( HAVE_LOCKF ) -- res = lseek (fd, (off_t) (ALOCK_SLOT_SIZE * slot), SEEK_SET); -- if (res == -1) return -1; -- -- res = lockf (fd, F_TEST, (off_t) ALOCK_SLOT_SIZE); -- if (res == -1) { -- if (errno == EACCES || errno == EAGAIN) { -- return ALOCK_LOCKED; -- } else { -- return -1; -- } -- } --#elif defined( HAVE_FCNTL ) -- struct flock lock_info; -- (void) memset ((void *) &lock_info, 0, sizeof (struct flock)); -- -- lock_info.l_type = F_WRLCK; -- lock_info.l_whence = SEEK_SET; -- lock_info.l_start = (off_t) (ALOCK_SLOT_SIZE * slot); -- lock_info.l_len = (off_t) ALOCK_SLOT_SIZE; -- -- res = fcntl (fd, F_GETLK, &lock_info); -- if (res == -1) return -1; -- -- if (lock_info.l_type != F_UNLCK) return ALOCK_LOCKED; --#elif defined( _WIN32 ) -- OVERLAPPED ov; -- HANDLE hh = _get_osfhandle ( fd ); -- ov.hEvent = 0; -- ov.Offset = ALOCK_SLOT_SIZE*slot; -- ov.OffsetHigh = 0; -- if( !LockFileEx( hh, -- LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY, 0, -- ALOCK_SLOT_SIZE, 0, &ov )) { -- int err = GetLastError(); -- if ( err == ERROR_LOCK_VIOLATION ) -- return ALOCK_LOCKED; -- else -- return -1; -- } --#else --# error alock needs lockf, fcntl, or LockFile --#endif -- -- return 0; --} -- --/* Read a 64bit LE value */ --static unsigned long int --alock_read_iattr ( unsigned char * bufptr ) --{ -- unsigned long int val = 0; -- int count; -- -- assert (bufptr != NULL); -- -- bufptr += sizeof (unsigned long int); -- for (count=0; count <= (int) sizeof (unsigned long int); ++count) { -- val <<= 8; -- val += (unsigned long int) *bufptr--; -- } -- -- return val; --} -- --/* Write a 64bit LE value */ --static void --alock_write_iattr ( unsigned char * bufptr, -- unsigned long int val ) --{ -- int count; -- -- assert (bufptr != NULL); -- -- for (count=0; count < 8; ++count) { -- *bufptr++ = (unsigned char) (val & 0xff); -- val >>= 8; -- } --} -- --static int --alock_read_slot ( alock_info_t * info, -- alock_slot_t * slot_data ) --{ -- unsigned char slotbuf [ALOCK_SLOT_SIZE]; -- int res, size, size_total, err; -- -- assert (info != NULL); -- assert (slot_data != NULL); -- assert (info->al_slot > 0); -- -- res = lseek (info->al_fd, -- (off_t) (ALOCK_SLOT_SIZE * info->al_slot), -- SEEK_SET); -- if (res == -1) return -1; -- -- size_total = 0; -- while (size_total < ALOCK_SLOT_SIZE) { -- size = read (info->al_fd, -- slotbuf + size_total, -- ALOCK_SLOT_SIZE - size_total); -- if (size == 0) return -1; -- if (size < 0) { -- err = errno; -- if (err != EINTR && err != EAGAIN) return -1; -- } else { -- size_total += size; -- } -- } -- -- if (alock_read_iattr (slotbuf) != ALOCK_MAGIC) { -- return -1; -- } -- slot_data->al_lock = alock_read_iattr (slotbuf+8); -- slot_data->al_stamp = alock_read_iattr (slotbuf+16); -- slot_data->al_pid = alock_read_iattr (slotbuf+24); -- -- if (slot_data->al_appname) ber_memfree (slot_data->al_appname); -- slot_data->al_appname = ber_memcalloc (1, ALOCK_MAX_APPNAME); -- if (slot_data->al_appname == NULL) { -- return -1; -- } -- strncpy (slot_data->al_appname, (char *)slotbuf+32, ALOCK_MAX_APPNAME-1); -- (slot_data->al_appname) [ALOCK_MAX_APPNAME-1] = '\0'; -- -- return 0; --} -- --static int --alock_write_slot ( alock_info_t * info, -- alock_slot_t * slot_data ) --{ -- unsigned char slotbuf [ALOCK_SLOT_SIZE]; -- int res, size, size_total, err; -- -- assert (info != NULL); -- assert (slot_data != NULL); -- assert (info->al_slot > 0); -- -- (void) memset ((void *) slotbuf, 0, ALOCK_SLOT_SIZE); -- -- alock_write_iattr (slotbuf, ALOCK_MAGIC); -- assert (alock_read_iattr (slotbuf) == ALOCK_MAGIC); -- alock_write_iattr (slotbuf+8, slot_data->al_lock); -- alock_write_iattr (slotbuf+16, slot_data->al_stamp); -- alock_write_iattr (slotbuf+24, slot_data->al_pid); -- -- if (slot_data->al_appname) -- strncpy ((char *)slotbuf+32, slot_data->al_appname, ALOCK_MAX_APPNAME-1); -- slotbuf[ALOCK_SLOT_SIZE-1] = '\0'; -- -- res = lseek (info->al_fd, -- (off_t) (ALOCK_SLOT_SIZE * info->al_slot), -- SEEK_SET); -- if (res == -1) return -1; -- -- size_total = 0; -- while (size_total < ALOCK_SLOT_SIZE) { -- size = write (info->al_fd, -- slotbuf + size_total, -- ALOCK_SLOT_SIZE - size_total); -- if (size == 0) return -1; -- if (size < 0) { -- err = errno; -- if (err != EINTR && err != EAGAIN) return -1; -- } else { -- size_total += size; -- } -- } -- -- return 0; --} -- --static int --alock_query_slot ( alock_info_t * info ) --{ -- int res, nosave; -- alock_slot_t slot_data; -- -- assert (info != NULL); -- assert (info->al_slot > 0); -- -- (void) memset ((void *) &slot_data, 0, sizeof (alock_slot_t)); -- alock_read_slot (info, &slot_data); -- -- if (slot_data.al_appname != NULL) ber_memfree (slot_data.al_appname); -- slot_data.al_appname = NULL; -- -- nosave = slot_data.al_lock & ALOCK_NOSAVE; -- -- if ((slot_data.al_lock & ALOCK_SMASK) == ALOCK_UNLOCKED) -- return slot_data.al_lock; -- -- res = alock_test_lock (info->al_fd, info->al_slot); -- if (res < 0) return -1; -- if (res > 0) { -- if ((slot_data.al_lock & ALOCK_SMASK) == ALOCK_UNIQUE) { -- return slot_data.al_lock; -- } else { -- return ALOCK_LOCKED | nosave; -- } -- } -- -- return ALOCK_DIRTY | nosave; --} -- --int --alock_open ( alock_info_t * info, -- const char * appname, -- const char * envdir, -- int locktype ) --{ -- struct stat statbuf; -- alock_info_t scan_info; -- alock_slot_t slot_data; -- char * filename; -- int res, max_slot; -- int dirty_count, live_count, nosave; -- char *ptr; -- -- assert (info != NULL); -- assert (appname != NULL); -- assert (envdir != NULL); -- assert ((locktype & ALOCK_SMASK) >= 1 && (locktype & ALOCK_SMASK) <= 2); -- -- slot_data.al_lock = locktype; -- slot_data.al_stamp = time(NULL); -- slot_data.al_pid = getpid(); -- slot_data.al_appname = ber_memcalloc (1, ALOCK_MAX_APPNAME); -- if (slot_data.al_appname == NULL) { -- return ALOCK_UNSTABLE; -- } -- strncpy (slot_data.al_appname, appname, ALOCK_MAX_APPNAME-1); -- slot_data.al_appname [ALOCK_MAX_APPNAME-1] = '\0'; -- -- filename = ber_memcalloc (1, strlen (envdir) + strlen ("/alock") + 1); -- if (filename == NULL ) { -- ber_memfree (slot_data.al_appname); -- return ALOCK_UNSTABLE; -- } -- ptr = lutil_strcopy(filename, envdir); -- lutil_strcopy(ptr, "/alock"); --#ifdef _WIN32 -- { HANDLE handle = CreateFile (filename, GENERIC_READ|GENERIC_WRITE, -- FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, -- FILE_ATTRIBUTE_NORMAL, NULL); -- info->al_fd = _open_osfhandle (handle, 0); -- } --#else -- info->al_fd = open (filename, O_CREAT|O_RDWR, 0666); --#endif -- ber_memfree (filename); -- if (info->al_fd < 0) { -- ber_memfree (slot_data.al_appname); -- return ALOCK_UNSTABLE; -- } -- info->al_slot = 0; -- -- res = alock_grab_lock (info->al_fd, 0); -- if (res == -1) { -- close (info->al_fd); -- ber_memfree (slot_data.al_appname); -- return ALOCK_UNSTABLE; -- } -- -- res = fstat (info->al_fd, &statbuf); -- if (res == -1) { -- close (info->al_fd); -- ber_memfree (slot_data.al_appname); -- return ALOCK_UNSTABLE; -- } -- -- max_slot = (statbuf.st_size + ALOCK_SLOT_SIZE - 1) / ALOCK_SLOT_SIZE; -- dirty_count = 0; -- live_count = 0; -- nosave = 0; -- scan_info.al_fd = info->al_fd; -- for (scan_info.al_slot = 1; -- scan_info.al_slot < max_slot; -- ++ scan_info.al_slot) { -- if (scan_info.al_slot != info->al_slot) { -- res = alock_query_slot (&scan_info); -- -- if (res & ALOCK_NOSAVE) { -- nosave = ALOCK_NOSAVE; -- res ^= ALOCK_NOSAVE; -- } -- if (res == ALOCK_UNLOCKED -- && info->al_slot == 0) { -- info->al_slot = scan_info.al_slot; -- -- } else if (res == ALOCK_LOCKED) { -- ++live_count; -- -- } else if (res == ALOCK_UNIQUE -- && (( locktype & ALOCK_SMASK ) == ALOCK_UNIQUE -- || nosave )) { -- close (info->al_fd); -- ber_memfree (slot_data.al_appname); -- return ALOCK_BUSY; -- -- } else if (res == ALOCK_DIRTY) { -- ++dirty_count; -- -- } else if (res == -1) { -- close (info->al_fd); -- ber_memfree (slot_data.al_appname); -- return ALOCK_UNSTABLE; -- -- } -- } -- } -- -- if (dirty_count && live_count) { -- close (info->al_fd); -- ber_memfree (slot_data.al_appname); -- return ALOCK_UNSTABLE; -- } -- -- if (info->al_slot == 0) info->al_slot = max_slot + 1; -- res = alock_grab_lock (info->al_fd, -- info->al_slot); -- if (res == -1) { -- close (info->al_fd); -- ber_memfree (slot_data.al_appname); -- return ALOCK_UNSTABLE; -- } -- res = alock_write_slot (info, &slot_data); -- ber_memfree (slot_data.al_appname); -- if (res == -1) { -- close (info->al_fd); -- return ALOCK_UNSTABLE; -- } -- alock_share_lock (info->al_fd, info->al_slot); -- -- res = alock_release_lock (info->al_fd, 0); -- if (res == -1) { -- close (info->al_fd); -- return ALOCK_UNSTABLE; -- } -- -- if (dirty_count) return ALOCK_RECOVER | nosave; -- return ALOCK_CLEAN | nosave; --} -- --int --alock_scan ( alock_info_t * info ) --{ -- struct stat statbuf; -- alock_info_t scan_info; -- int res, max_slot; -- int dirty_count, live_count, nosave; -- -- assert (info != NULL); -- -- scan_info.al_fd = info->al_fd; -- -- res = alock_grab_lock (info->al_fd, 0); -- if (res == -1) { -- close (info->al_fd); -- return ALOCK_UNSTABLE; -- } -- -- res = fstat (info->al_fd, &statbuf); -- if (res == -1) { -- close (info->al_fd); -- return ALOCK_UNSTABLE; -- } -- -- max_slot = (statbuf.st_size + ALOCK_SLOT_SIZE - 1) / ALOCK_SLOT_SIZE; -- dirty_count = 0; -- live_count = 0; -- nosave = 0; -- for (scan_info.al_slot = 1; -- scan_info.al_slot < max_slot; -- ++ scan_info.al_slot) { -- if (scan_info.al_slot != info->al_slot) { -- res = alock_query_slot (&scan_info); -- -- if (res & ALOCK_NOSAVE) { -- nosave = ALOCK_NOSAVE; -- res ^= ALOCK_NOSAVE; -- } -- -- if (res == ALOCK_LOCKED) { -- ++live_count; -- -- } else if (res == ALOCK_DIRTY) { -- ++dirty_count; -- -- } else if (res == -1) { -- close (info->al_fd); -- return ALOCK_UNSTABLE; -- -- } -- } -- } -- -- res = alock_release_lock (info->al_fd, 0); -- if (res == -1) { -- close (info->al_fd); -- return ALOCK_UNSTABLE; -- } -- -- if (dirty_count) { -- if (live_count) { -- close (info->al_fd); -- return ALOCK_UNSTABLE; -- } else { -- return ALOCK_RECOVER | nosave; -- } -- } -- -- return ALOCK_CLEAN | nosave; --} -- --int --alock_close ( alock_info_t * info, int nosave ) --{ -- alock_slot_t slot_data; -- int res; -- -- if ( !info->al_slot ) -- return ALOCK_CLEAN; -- -- (void) memset ((void *) &slot_data, 0, sizeof(alock_slot_t)); -- -- res = alock_grab_lock (info->al_fd, 0); -- if (res == -1) { --fail: -- /* Windows doesn't clean up locks immediately when a process exits. -- * Make sure we release our locks, to prevent stale locks from -- * hanging around. -- */ -- alock_release_lock (info->al_fd, 0); -- close (info->al_fd); -- return ALOCK_UNSTABLE; -- } -- -- /* mark our slot as clean */ -- res = alock_read_slot (info, &slot_data); -- if (res == -1) { -- if (slot_data.al_appname != NULL) -- ber_memfree (slot_data.al_appname); -- goto fail; -- } -- slot_data.al_lock = ALOCK_UNLOCKED; -- if ( nosave ) -- slot_data.al_lock |= ALOCK_NOSAVE; -- /* since we have slot 0 locked, we don't need our slot lock */ -- res = alock_release_lock (info->al_fd, info->al_slot); -- if (res == -1) { -- goto fail; -- } -- res = alock_write_slot (info, &slot_data); -- if (res == -1) { -- if (slot_data.al_appname != NULL) -- ber_memfree (slot_data.al_appname); -- goto fail; -- } -- if (slot_data.al_appname != NULL) { -- ber_memfree (slot_data.al_appname); -- slot_data.al_appname = NULL; -- } -- -- res = alock_release_lock (info->al_fd, 0); -- if (res == -1) { -- close (info->al_fd); -- return ALOCK_UNSTABLE; -- } -- -- res = close (info->al_fd); -- if (res == -1) return ALOCK_UNSTABLE; -- -- return ALOCK_CLEAN; --} -- --int --alock_recover ( alock_info_t * info ) --{ -- struct stat statbuf; -- alock_slot_t slot_data; -- alock_info_t scan_info; -- int res, max_slot; -- -- assert (info != NULL); -- -- scan_info.al_fd = info->al_fd; -- -- (void) memset ((void *) &slot_data, 0, sizeof(alock_slot_t)); -- -- res = alock_grab_lock (info->al_fd, 0); -- if (res == -1) { -- goto fail; -- } -- -- res = fstat (info->al_fd, &statbuf); -- if (res == -1) { -- goto fail; -- } -- -- max_slot = (statbuf.st_size + ALOCK_SLOT_SIZE - 1) / ALOCK_SLOT_SIZE; -- for (scan_info.al_slot = 1; -- scan_info.al_slot < max_slot; -- ++ scan_info.al_slot) { -- if (scan_info.al_slot != info->al_slot) { -- res = alock_query_slot (&scan_info) & ~ALOCK_NOSAVE; -- -- if (res == ALOCK_LOCKED -- || res == ALOCK_UNIQUE) { -- /* recovery attempt on an active db? */ -- goto fail; -- -- } else if (res == ALOCK_DIRTY) { -- /* mark it clean */ -- res = alock_read_slot (&scan_info, &slot_data); -- if (res == -1) { -- goto fail; -- } -- slot_data.al_lock = ALOCK_UNLOCKED; -- res = alock_write_slot (&scan_info, &slot_data); -- if (res == -1) { -- if (slot_data.al_appname != NULL) -- ber_memfree (slot_data.al_appname); -- goto fail; -- } -- if (slot_data.al_appname != NULL) { -- ber_memfree (slot_data.al_appname); -- slot_data.al_appname = NULL; -- } -- -- } else if (res == -1) { -- goto fail; -- -- } -- } -- } -- -- res = alock_release_lock (info->al_fd, 0); -- if (res == -1) { -- close (info->al_fd); -- return ALOCK_UNSTABLE; -- } -- -- return ALOCK_CLEAN; -- --fail: -- alock_release_lock (info->al_fd, 0); -- close (info->al_fd); -- return ALOCK_UNSTABLE; --} -- --#endif /* SLAPD_BDB || SLAPD_HDB */ -diff --git a/servers/slapd/alock.h b/servers/slapd/alock.h -deleted file mode 100644 -index 56f03d8..0000000 ---- a/servers/slapd/alock.h -+++ /dev/null -@@ -1,74 +0,0 @@ --/* alock.h - access lock header */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2005-2020 The OpenLDAP Foundation. -- * Portions Copyright 2004-2005 Symas Corporation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ --/* ACKNOWLEDGEMENTS: -- * This work was initially developed by Emily Backes at Symas -- * Corporation for inclusion in OpenLDAP Software. -- */ -- --#ifndef _ALOCK_H_ --#define _ALOCK_H_ -- --#include "portable.h" --#include --#include -- --/* environment states (all the slots together) */ --#define ALOCK_CLEAN (0) --#define ALOCK_RECOVER (1) --#define ALOCK_BUSY (2) --#define ALOCK_UNSTABLE (3) -- --/* lock user types and states */ --#define ALOCK_UNLOCKED (0) --#define ALOCK_LOCKED (1) --#define ALOCK_UNIQUE (2) --#define ALOCK_DIRTY (3) -- --#define ALOCK_SMASK 3 -- --/* lock/state where recovery is not available */ --#define ALOCK_NOSAVE 4 -- --/* constants */ --#define ALOCK_SLOT_SIZE (1024) --#define ALOCK_SLOT_IATTRS (4) --#define ALOCK_MAX_APPNAME (ALOCK_SLOT_SIZE - 8 * ALOCK_SLOT_IATTRS) --#define ALOCK_MAGIC (0x12345678) -- --LDAP_BEGIN_DECL -- --typedef struct alock_info { -- int al_fd; -- int al_slot; --} alock_info_t; -- --typedef struct alock_slot { -- unsigned int al_lock; -- time_t al_stamp; -- pid_t al_pid; -- char * al_appname; --} alock_slot_t; -- --LDAP_SLAPD_F (int) alock_open LDAP_P(( alock_info_t * info, const char * appname, -- const char * envdir, int locktype )); --LDAP_SLAPD_F (int) alock_scan LDAP_P(( alock_info_t * info )); --LDAP_SLAPD_F (int) alock_close LDAP_P(( alock_info_t * info, int nosave )); --LDAP_SLAPD_F (int) alock_recover LDAP_P(( alock_info_t * info )); -- --LDAP_END_DECL -- --#endif -diff --git a/servers/slapd/back-bdb/Makefile.in b/servers/slapd/back-bdb/Makefile.in -deleted file mode 100644 -index 8529202..0000000 ---- a/servers/slapd/back-bdb/Makefile.in -+++ /dev/null -@@ -1,53 +0,0 @@ --# Makefile.in for back-bdb --# $OpenLDAP$ --## This work is part of OpenLDAP Software . --## --## Copyright 1998-2020 The OpenLDAP Foundation. --## All rights reserved. --## --## Redistribution and use in source and binary forms, with or without --## modification, are permitted only as authorized by the OpenLDAP --## Public License. --## --## A copy of this license is available in the file LICENSE in the --## top-level directory of the distribution or, alternatively, at --## . -- --SRCS = init.c tools.c config.c \ -- add.c bind.c compare.c delete.c modify.c modrdn.c search.c \ -- extended.c referral.c operational.c \ -- attr.c index.c key.c dbcache.c filterindex.c \ -- dn2entry.c dn2id.c error.c id2entry.c idl.c \ -- nextid.c cache.c trans.c monitor.c -- --OBJS = init.lo tools.lo config.lo \ -- add.lo bind.lo compare.lo delete.lo modify.lo modrdn.lo search.lo \ -- extended.lo referral.lo operational.lo \ -- attr.lo index.lo key.lo dbcache.lo filterindex.lo \ -- dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo \ -- nextid.lo cache.lo trans.lo monitor.lo -- --LDAP_INCDIR= ../../../include --LDAP_LIBDIR= ../../../libraries -- --BUILD_OPT = "--enable-bdb" --BUILD_MOD = @BUILD_BDB@ -- --mod_DEFS = -DSLAPD_IMPORT --MOD_DEFS = $(@BUILD_BDB@_DEFS) --MOD_LIBS = $(BDB_LIBS) -- --shared_LDAP_LIBS = $(LDAP_LIBLDAP_R_LA) $(LDAP_LIBLBER_LA) --NT_LINK_LIBS = -L.. -lslapd $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS) --UNIX_LINK_LIBS = $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS) -- --LIBBASE = back_bdb -- --XINCPATH = -I.. -I$(srcdir)/.. --XDEFS = $(MODULES_CPPFLAGS) -- --all-local-lib: ../.backend -- --../.backend: lib$(LIBBASE).a -- @touch $@ -- -diff --git a/servers/slapd/back-bdb/add.c b/servers/slapd/back-bdb/add.c -deleted file mode 100644 -index d842b55..0000000 ---- a/servers/slapd/back-bdb/add.c -+++ /dev/null -@@ -1,547 +0,0 @@ --/* add.c - ldap BerkeleyDB back-end add routine */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include --#include -- --#include "back-bdb.h" -- --int --bdb_add(Operation *op, SlapReply *rs ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- struct berval pdn; -- Entry *p = NULL, *oe = op->ora_e; -- EntryInfo *ei; -- char textbuf[SLAP_TEXT_BUFLEN]; -- size_t textlen = sizeof textbuf; -- AttributeDescription *children = slap_schema.si_ad_children; -- AttributeDescription *entry = slap_schema.si_ad_entry; -- DB_TXN *ltid = NULL, *lt2; -- ID eid = NOID; -- struct bdb_op_info opinfo = {{{ 0 }}}; -- int subentry; -- DB_LOCK lock; -- -- int num_retries = 0; -- int success; -- -- LDAPControl **postread_ctrl = NULL; -- LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS]; -- int num_ctrls = 0; -- --#ifdef LDAP_X_TXN -- int settle = 0; --#endif -- -- Debug(LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(bdb_add) ": %s\n", -- op->ora_e->e_name.bv_val, 0, 0); -- --#ifdef LDAP_X_TXN -- if( op->o_txnSpec ) { -- /* acquire connection lock */ -- ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); -- if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) { -- rs->sr_text = "invalid transaction identifier"; -- rs->sr_err = LDAP_X_TXN_ID_INVALID; -- goto txnReturn; -- } else if( op->o_conn->c_txn == CONN_TXN_SETTLE ) { -- settle=1; -- goto txnReturn; -- } -- -- if( op->o_conn->c_txn_backend == NULL ) { -- op->o_conn->c_txn_backend = op->o_bd; -- -- } else if( op->o_conn->c_txn_backend != op->o_bd ) { -- rs->sr_text = "transaction cannot span multiple database contexts"; -- rs->sr_err = LDAP_AFFECTS_MULTIPLE_DSAS; -- goto txnReturn; -- } -- -- /* insert operation into transaction */ -- -- rs->sr_text = "transaction specified"; -- rs->sr_err = LDAP_X_TXN_SPECIFY_OKAY; -- --txnReturn: -- /* release connection lock */ -- ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); -- -- if( !settle ) { -- send_ldap_result( op, rs ); -- return rs->sr_err; -- } -- } --#endif -- -- ctrls[num_ctrls] = 0; -- -- /* check entry's schema */ -- rs->sr_err = entry_schema_check( op, op->ora_e, NULL, -- get_relax(op), 1, NULL, &rs->sr_text, textbuf, textlen ); -- if ( rs->sr_err != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_add) ": entry failed schema check: " -- "%s (%d)\n", rs->sr_text, rs->sr_err, 0 ); -- goto return_results; -- } -- -- /* add opattrs to shadow as well, only missing attrs will actually -- * be added; helps compatibility with older OL versions */ -- rs->sr_err = slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 ); -- if ( rs->sr_err != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_add) ": entry failed op attrs add: " -- "%s (%d)\n", rs->sr_text, rs->sr_err, 0 ); -- goto return_results; -- } -- -- if ( get_assert( op ) && -- ( test_filter( op, op->ora_e, get_assertion( op )) != LDAP_COMPARE_TRUE )) -- { -- rs->sr_err = LDAP_ASSERTION_FAILED; -- goto return_results; -- } -- -- subentry = is_entry_subentry( op->ora_e ); -- -- if( 0 ) { --retry: /* transaction retry */ -- if( p ) { -- /* free parent and reader lock */ -- if ( p != (Entry *)&slap_entry_root ) { -- bdb_unlocked_cache_return_entry_r( bdb, p ); -- } -- p = NULL; -- } -- rs->sr_err = TXN_ABORT( ltid ); -- ltid = NULL; -- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); -- opinfo.boi_oe.oe_key = NULL; -- op->o_do_not_cache = opinfo.boi_acl_cache; -- if( rs->sr_err != 0 ) { -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- if ( op->o_abandon ) { -- rs->sr_err = SLAPD_ABANDON; -- goto return_results; -- } -- bdb_trans_backoff( ++num_retries ); -- } -- -- /* begin transaction */ -- rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, <id, -- bdb->bi_db_opflags ); -- rs->sr_text = NULL; -- if( rs->sr_err != 0 ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_add) ": txn_begin failed: %s (%d)\n", -- db_strerror(rs->sr_err), rs->sr_err, 0 ); -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": txn1 id: %x\n", -- ltid->id(ltid), 0, 0 ); -- -- opinfo.boi_oe.oe_key = bdb; -- opinfo.boi_txn = ltid; -- opinfo.boi_err = 0; -- opinfo.boi_acl_cache = op->o_do_not_cache; -- LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.boi_oe, oe_next ); -- -- /* -- * Get the parent dn and see if the corresponding entry exists. -- */ -- if ( be_issuffix( op->o_bd, &op->ora_e->e_nname ) ) { -- pdn = slap_empty_bv; -- } else { -- dnParent( &op->ora_e->e_nname, &pdn ); -- } -- -- /* get entry or parent */ -- rs->sr_err = bdb_dn2entry( op, ltid, &op->ora_e->e_nname, &ei, -- 1, &lock ); -- switch( rs->sr_err ) { -- case 0: -- rs->sr_err = LDAP_ALREADY_EXISTS; -- goto return_results; -- case DB_NOTFOUND: -- break; -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- case LDAP_BUSY: -- rs->sr_text = "ldap server busy"; -- goto return_results; -- default: -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- -- p = ei->bei_e; -- if ( !p ) -- p = (Entry *)&slap_entry_root; -- -- if ( !bvmatch( &pdn, &p->e_nname ) ) { -- rs->sr_matched = ber_strdup_x( p->e_name.bv_val, -- op->o_tmpmemctx ); -- rs->sr_ref = is_entry_referral( p ) -- ? get_entry_referrals( op, p ) -- : NULL; -- if ( p != (Entry *)&slap_entry_root ) -- bdb_unlocked_cache_return_entry_r( bdb, p ); -- p = NULL; -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_add) ": parent " -- "does not exist\n", 0, 0, 0 ); -- -- rs->sr_err = LDAP_REFERRAL; -- rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; -- goto return_results; -- } -- -- rs->sr_err = access_allowed( op, p, -- children, NULL, ACL_WADD, NULL ); -- -- if ( ! rs->sr_err ) { -- switch( opinfo.boi_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- -- if ( p != (Entry *)&slap_entry_root ) -- bdb_unlocked_cache_return_entry_r( bdb, p ); -- p = NULL; -- -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_add) ": no write access to parent\n", -- 0, 0, 0 ); -- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; -- rs->sr_text = "no write access to parent"; -- goto return_results;; -- } -- -- if ( p != (Entry *)&slap_entry_root ) { -- if ( is_entry_subentry( p ) ) { -- bdb_unlocked_cache_return_entry_r( bdb, p ); -- p = NULL; -- /* parent is a subentry, don't allow add */ -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_add) ": parent is subentry\n", -- 0, 0, 0 ); -- rs->sr_err = LDAP_OBJECT_CLASS_VIOLATION; -- rs->sr_text = "parent is a subentry"; -- goto return_results;; -- } -- -- if ( is_entry_alias( p ) ) { -- bdb_unlocked_cache_return_entry_r( bdb, p ); -- p = NULL; -- /* parent is an alias, don't allow add */ -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_add) ": parent is alias\n", -- 0, 0, 0 ); -- rs->sr_err = LDAP_ALIAS_PROBLEM; -- rs->sr_text = "parent is an alias"; -- goto return_results;; -- } -- -- if ( is_entry_referral( p ) ) { -- /* parent is a referral, don't allow add */ -- rs->sr_matched = ber_strdup_x( p->e_name.bv_val, -- op->o_tmpmemctx ); -- rs->sr_ref = get_entry_referrals( op, p ); -- bdb_unlocked_cache_return_entry_r( bdb, p ); -- p = NULL; -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_add) ": parent is referral\n", -- 0, 0, 0 ); -- -- rs->sr_err = LDAP_REFERRAL; -- rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; -- goto return_results; -- } -- -- } -- -- if ( subentry ) { -- /* FIXME: */ -- /* parent must be an administrative point of the required kind */ -- } -- -- /* free parent and reader lock */ -- if ( p != (Entry *)&slap_entry_root ) { -- if ( p->e_nname.bv_len ) { -- struct berval ppdn; -- -- /* ITS#5326: use parent's DN if differs from provided one */ -- dnParent( &op->ora_e->e_name, &ppdn ); -- if ( !dn_match( &p->e_name, &ppdn ) ) { -- struct berval rdn; -- struct berval newdn; -- -- dnRdn( &op->ora_e->e_name, &rdn ); -- -- build_new_dn( &newdn, &p->e_name, &rdn, NULL ); -- if ( op->ora_e->e_name.bv_val != op->o_req_dn.bv_val ) -- ber_memfree( op->ora_e->e_name.bv_val ); -- op->ora_e->e_name = newdn; -- -- /* FIXME: should check whether -- * dnNormalize(newdn) == e->e_nname ... */ -- } -- } -- -- bdb_unlocked_cache_return_entry_r( bdb, p ); -- } -- p = NULL; -- -- rs->sr_err = access_allowed( op, op->ora_e, -- entry, NULL, ACL_WADD, NULL ); -- -- if ( ! rs->sr_err ) { -- switch( opinfo.boi_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_add) ": no write access to entry\n", -- 0, 0, 0 ); -- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; -- rs->sr_text = "no write access to entry"; -- goto return_results;; -- } -- -- /* -- * Check ACL for attribute write access -- */ -- if (!acl_check_modlist(op, oe, op->ora_modlist)) { -- switch( opinfo.boi_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_add) ": no write access to attribute\n", -- 0, 0, 0 ); -- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; -- rs->sr_text = "no write access to attribute"; -- goto return_results;; -- } -- -- if ( eid == NOID ) { -- rs->sr_err = bdb_next_id( op->o_bd, &eid ); -- if( rs->sr_err != 0 ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_add) ": next_id failed (%d)\n", -- rs->sr_err, 0, 0 ); -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- op->ora_e->e_id = eid; -- } -- -- /* nested transaction */ -- rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, <2, -- bdb->bi_db_opflags ); -- rs->sr_text = NULL; -- if( rs->sr_err != 0 ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_add) ": txn_begin(2) failed: " -- "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 ); -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": txn2 id: %x\n", -- lt2->id(lt2), 0, 0 ); -- -- /* dn2id index */ -- rs->sr_err = bdb_dn2id_add( op, lt2, ei, op->ora_e ); -- if ( rs->sr_err != 0 ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_add) ": dn2id_add failed: %s (%d)\n", -- db_strerror(rs->sr_err), rs->sr_err, 0 ); -- -- switch( rs->sr_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- case DB_KEYEXIST: -- rs->sr_err = LDAP_ALREADY_EXISTS; -- break; -- default: -- rs->sr_err = LDAP_OTHER; -- } -- goto return_results; -- } -- -- /* attribute indexes */ -- rs->sr_err = bdb_index_entry_add( op, lt2, op->ora_e ); -- if ( rs->sr_err != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_add) ": index_entry_add failed\n", -- 0, 0, 0 ); -- switch( rs->sr_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- default: -- rs->sr_err = LDAP_OTHER; -- } -- rs->sr_text = "index generation failed"; -- goto return_results; -- } -- -- /* id2entry index */ -- rs->sr_err = bdb_id2entry_add( op->o_bd, lt2, op->ora_e ); -- if ( rs->sr_err != 0 ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_add) ": id2entry_add failed\n", -- 0, 0, 0 ); -- switch( rs->sr_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- default: -- rs->sr_err = LDAP_OTHER; -- } -- rs->sr_text = "entry store failed"; -- goto return_results; -- } -- -- if ( TXN_COMMIT( lt2, 0 ) != 0 ) { -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "txn_commit(2) failed"; -- goto return_results; -- } -- -- /* post-read */ -- if( op->o_postread ) { -- if( postread_ctrl == NULL ) { -- postread_ctrl = &ctrls[num_ctrls++]; -- ctrls[num_ctrls] = NULL; -- } -- if ( slap_read_controls( op, rs, op->ora_e, -- &slap_post_read_bv, postread_ctrl ) ) -- { -- Debug( LDAP_DEBUG_TRACE, -- "<=- " LDAP_XSTRING(bdb_add) ": post-read " -- "failed!\n", 0, 0, 0 ); -- if ( op->o_postread & SLAP_CONTROL_CRITICAL ) { -- /* FIXME: is it correct to abort -- * operation if control fails? */ -- goto return_results; -- } -- } -- } -- -- if ( op->o_noop ) { -- if (( rs->sr_err=TXN_ABORT( ltid )) != 0 ) { -- rs->sr_text = "txn_abort (no-op) failed"; -- } else { -- rs->sr_err = LDAP_X_NO_OPERATION; -- ltid = NULL; -- goto return_results; -- } -- -- } else { -- struct berval nrdn; -- -- /* pick the RDN if not suffix; otherwise pick the entire DN */ -- if (pdn.bv_len) { -- nrdn.bv_val = op->ora_e->e_nname.bv_val; -- nrdn.bv_len = pdn.bv_val - op->ora_e->e_nname.bv_val - 1; -- } else { -- nrdn = op->ora_e->e_nname; -- } -- -- bdb_cache_add( bdb, ei, op->ora_e, &nrdn, ltid, &lock ); -- -- if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) { -- rs->sr_text = "txn_commit failed"; -- } else { -- rs->sr_err = LDAP_SUCCESS; -- } -- } -- -- ltid = NULL; -- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); -- opinfo.boi_oe.oe_key = NULL; -- -- if ( rs->sr_err != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_add) ": %s : %s (%d)\n", -- rs->sr_text, db_strerror(rs->sr_err), rs->sr_err ); -- rs->sr_err = LDAP_OTHER; -- goto return_results; -- } -- -- Debug(LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_add) ": added%s id=%08lx dn=\"%s\"\n", -- op->o_noop ? " (no-op)" : "", -- op->ora_e->e_id, op->ora_e->e_dn ); -- -- rs->sr_text = NULL; -- if( num_ctrls ) rs->sr_ctrls = ctrls; -- --return_results: -- success = rs->sr_err; -- send_ldap_result( op, rs ); -- -- if( ltid != NULL ) { -- TXN_ABORT( ltid ); -- } -- if ( opinfo.boi_oe.oe_key ) { -- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); -- } -- -- if( success == LDAP_SUCCESS ) { -- /* We own the entry now, and it can be purged at will -- * Check to make sure it's the same entry we entered with. -- * Possibly a callback may have mucked with it, although -- * in general callbacks should treat the entry as read-only. -- */ -- bdb_cache_deref( oe->e_private ); -- if ( op->ora_e == oe ) -- op->ora_e = NULL; -- -- if ( bdb->bi_txn_cp_kbyte ) { -- TXN_CHECKPOINT( bdb->bi_dbenv, -- bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 ); -- } -- } -- -- slap_graduate_commit_csn( op ); -- -- if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) { -- slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx ); -- slap_sl_free( *postread_ctrl, op->o_tmpmemctx ); -- } -- return rs->sr_err; --} -diff --git a/servers/slapd/back-bdb/attr.c b/servers/slapd/back-bdb/attr.c -deleted file mode 100644 -index 5d9990d..0000000 ---- a/servers/slapd/back-bdb/attr.c -+++ /dev/null -@@ -1,441 +0,0 @@ --/* attr.c - backend routines for dealing with attributes */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include -- --#include --#include -- --#include "slap.h" --#include "back-bdb.h" --#include "config.h" --#include "lutil.h" -- --/* Find the ad, return -1 if not found, -- * set point for insertion if ins is non-NULL -- */ --int --bdb_attr_slot( struct bdb_info *bdb, AttributeDescription *ad, int *ins ) --{ -- unsigned base = 0, cursor = 0; -- unsigned n = bdb->bi_nattrs; -- int val = 0; -- -- while ( 0 < n ) { -- unsigned pivot = n >> 1; -- cursor = base + pivot; -- -- val = SLAP_PTRCMP( ad, bdb->bi_attrs[cursor]->ai_desc ); -- if ( val < 0 ) { -- n = pivot; -- } else if ( val > 0 ) { -- base = cursor + 1; -- n -= pivot + 1; -- } else { -- return cursor; -- } -- } -- if ( ins ) { -- if ( val > 0 ) -- ++cursor; -- *ins = cursor; -- } -- return -1; --} -- --static int --ainfo_insert( struct bdb_info *bdb, AttrInfo *a ) --{ -- int x; -- int i = bdb_attr_slot( bdb, a->ai_desc, &x ); -- -- /* Is it a dup? */ -- if ( i >= 0 ) -- return -1; -- -- bdb->bi_attrs = ch_realloc( bdb->bi_attrs, ( bdb->bi_nattrs+1 ) * -- sizeof( AttrInfo * )); -- if ( x < bdb->bi_nattrs ) -- AC_MEMCPY( &bdb->bi_attrs[x+1], &bdb->bi_attrs[x], -- ( bdb->bi_nattrs - x ) * sizeof( AttrInfo *)); -- bdb->bi_attrs[x] = a; -- bdb->bi_nattrs++; -- return 0; --} -- --AttrInfo * --bdb_attr_mask( -- struct bdb_info *bdb, -- AttributeDescription *desc ) --{ -- int i = bdb_attr_slot( bdb, desc, NULL ); -- return i < 0 ? NULL : bdb->bi_attrs[i]; --} -- --int --bdb_attr_index_config( -- struct bdb_info *bdb, -- const char *fname, -- int lineno, -- int argc, -- char **argv, -- struct config_reply_s *c_reply) --{ -- int rc = 0; -- int i; -- slap_mask_t mask; -- char **attrs; -- char **indexes = NULL; -- -- attrs = ldap_str2charray( argv[0], "," ); -- -- if( attrs == NULL ) { -- fprintf( stderr, "%s: line %d: " -- "no attributes specified: %s\n", -- fname, lineno, argv[0] ); -- return LDAP_PARAM_ERROR; -- } -- -- if ( argc > 1 ) { -- indexes = ldap_str2charray( argv[1], "," ); -- -- if( indexes == NULL ) { -- fprintf( stderr, "%s: line %d: " -- "no indexes specified: %s\n", -- fname, lineno, argv[1] ); -- rc = LDAP_PARAM_ERROR; -- goto done; -- } -- } -- -- if( indexes == NULL ) { -- mask = bdb->bi_defaultmask; -- -- } else { -- mask = 0; -- -- for ( i = 0; indexes[i] != NULL; i++ ) { -- slap_mask_t index; -- rc = slap_str2index( indexes[i], &index ); -- -- if( rc != LDAP_SUCCESS ) { -- if ( c_reply ) -- { -- snprintf(c_reply->msg, sizeof(c_reply->msg), -- "index type \"%s\" undefined", indexes[i] ); -- -- fprintf( stderr, "%s: line %d: %s\n", -- fname, lineno, c_reply->msg ); -- } -- rc = LDAP_PARAM_ERROR; -- goto done; -- } -- -- mask |= index; -- } -- } -- -- if( !mask ) { -- if ( c_reply ) -- { -- snprintf(c_reply->msg, sizeof(c_reply->msg), -- "no indexes selected" ); -- fprintf( stderr, "%s: line %d: %s\n", -- fname, lineno, c_reply->msg ); -- } -- rc = LDAP_PARAM_ERROR; -- goto done; -- } -- -- for ( i = 0; attrs[i] != NULL; i++ ) { -- AttrInfo *a; -- AttributeDescription *ad; -- const char *text; --#ifdef LDAP_COMP_MATCH -- ComponentReference* cr = NULL; -- AttrInfo *a_cr = NULL; --#endif -- -- if( strcasecmp( attrs[i], "default" ) == 0 ) { -- bdb->bi_defaultmask |= mask; -- continue; -- } -- --#ifdef LDAP_COMP_MATCH -- if ( is_component_reference( attrs[i] ) ) { -- rc = extract_component_reference( attrs[i], &cr ); -- if ( rc != LDAP_SUCCESS ) { -- if ( c_reply ) -- { -- snprintf(c_reply->msg, sizeof(c_reply->msg), -- "index component reference\"%s\" undefined", -- attrs[i] ); -- fprintf( stderr, "%s: line %d: %s\n", -- fname, lineno, c_reply->msg ); -- } -- goto done; -- } -- cr->cr_indexmask = mask; -- /* -- * After extracting a component reference -- * only the name of a attribute will be remaining -- */ -- } else { -- cr = NULL; -- } --#endif -- ad = NULL; -- rc = slap_str2ad( attrs[i], &ad, &text ); -- -- if( rc != LDAP_SUCCESS ) { -- if ( c_reply ) -- { -- snprintf(c_reply->msg, sizeof(c_reply->msg), -- "index attribute \"%s\" undefined", -- attrs[i] ); -- -- fprintf( stderr, "%s: line %d: %s\n", -- fname, lineno, c_reply->msg ); -- } -- goto done; -- } -- -- if( ad == slap_schema.si_ad_entryDN || slap_ad_is_binary( ad ) ) { -- if (c_reply) { -- snprintf(c_reply->msg, sizeof(c_reply->msg), -- "index of attribute \"%s\" disallowed", attrs[i] ); -- fprintf( stderr, "%s: line %d: %s\n", -- fname, lineno, c_reply->msg ); -- } -- rc = LDAP_UNWILLING_TO_PERFORM; -- goto done; -- } -- -- if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) && !( -- ad->ad_type->sat_approx -- && ad->ad_type->sat_approx->smr_indexer -- && ad->ad_type->sat_approx->smr_filter ) ) -- { -- if (c_reply) { -- snprintf(c_reply->msg, sizeof(c_reply->msg), -- "approx index of attribute \"%s\" disallowed", attrs[i] ); -- fprintf( stderr, "%s: line %d: %s\n", -- fname, lineno, c_reply->msg ); -- } -- rc = LDAP_INAPPROPRIATE_MATCHING; -- goto done; -- } -- -- if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) && !( -- ad->ad_type->sat_equality -- && ad->ad_type->sat_equality->smr_indexer -- && ad->ad_type->sat_equality->smr_filter ) ) -- { -- if (c_reply) { -- snprintf(c_reply->msg, sizeof(c_reply->msg), -- "equality index of attribute \"%s\" disallowed", attrs[i] ); -- fprintf( stderr, "%s: line %d: %s\n", -- fname, lineno, c_reply->msg ); -- } -- rc = LDAP_INAPPROPRIATE_MATCHING; -- goto done; -- } -- -- if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) && !( -- ad->ad_type->sat_substr -- && ad->ad_type->sat_substr->smr_indexer -- && ad->ad_type->sat_substr->smr_filter ) ) -- { -- if (c_reply) { -- snprintf(c_reply->msg, sizeof(c_reply->msg), -- "substr index of attribute \"%s\" disallowed", attrs[i] ); -- fprintf( stderr, "%s: line %d: %s\n", -- fname, lineno, c_reply->msg ); -- } -- rc = LDAP_INAPPROPRIATE_MATCHING; -- goto done; -- } -- -- Debug( LDAP_DEBUG_CONFIG, "index %s 0x%04lx\n", -- ad->ad_cname.bv_val, mask, 0 ); -- -- a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) ); -- --#ifdef LDAP_COMP_MATCH -- a->ai_cr = NULL; --#endif -- a->ai_desc = ad; -- -- if ( bdb->bi_flags & BDB_IS_OPEN ) { -- a->ai_indexmask = 0; -- a->ai_newmask = mask; -- } else { -- a->ai_indexmask = mask; -- a->ai_newmask = 0; -- } -- --#ifdef LDAP_COMP_MATCH -- if ( cr ) { -- a_cr = bdb_attr_mask( bdb, ad ); -- if ( a_cr ) { -- /* -- * AttrInfo is already in AVL -- * just add the extracted component reference -- * in the AttrInfo -- */ -- rc = insert_component_reference( cr, &a_cr->ai_cr ); -- if ( rc != LDAP_SUCCESS) { -- fprintf( stderr, " error during inserting component reference in %s ", attrs[i]); -- rc = LDAP_PARAM_ERROR; -- goto done; -- } -- continue; -- } else { -- rc = insert_component_reference( cr, &a->ai_cr ); -- if ( rc != LDAP_SUCCESS) { -- fprintf( stderr, " error during inserting component reference in %s ", attrs[i]); -- rc = LDAP_PARAM_ERROR; -- goto done; -- } -- } -- } --#endif -- rc = ainfo_insert( bdb, a ); -- if( rc ) { -- if ( bdb->bi_flags & BDB_IS_OPEN ) { -- AttrInfo *b = bdb_attr_mask( bdb, ad ); -- /* If there is already an index defined for this attribute -- * it must be replaced. Otherwise we end up with multiple -- * olcIndex values for the same attribute */ -- if ( b->ai_indexmask & BDB_INDEX_DELETING ) { -- /* If we were editing this attr, reset it */ -- b->ai_indexmask &= ~BDB_INDEX_DELETING; -- /* If this is leftover from a previous add, commit it */ -- if ( b->ai_newmask ) -- b->ai_indexmask = b->ai_newmask; -- b->ai_newmask = a->ai_newmask; -- ch_free( a ); -- rc = 0; -- continue; -- } -- } -- if (c_reply) { -- snprintf(c_reply->msg, sizeof(c_reply->msg), -- "duplicate index definition for attr \"%s\"", -- attrs[i] ); -- fprintf( stderr, "%s: line %d: %s\n", -- fname, lineno, c_reply->msg ); -- } -- -- rc = LDAP_PARAM_ERROR; -- goto done; -- } -- } -- --done: -- ldap_charray_free( attrs ); -- if ( indexes != NULL ) ldap_charray_free( indexes ); -- -- return rc; --} -- --static int --bdb_attr_index_unparser( void *v1, void *v2 ) --{ -- AttrInfo *ai = v1; -- BerVarray *bva = v2; -- struct berval bv; -- char *ptr; -- -- slap_index2bvlen( ai->ai_indexmask, &bv ); -- if ( bv.bv_len ) { -- bv.bv_len += ai->ai_desc->ad_cname.bv_len + 1; -- ptr = ch_malloc( bv.bv_len+1 ); -- bv.bv_val = lutil_strcopy( ptr, ai->ai_desc->ad_cname.bv_val ); -- *bv.bv_val++ = ' '; -- slap_index2bv( ai->ai_indexmask, &bv ); -- bv.bv_val = ptr; -- ber_bvarray_add( bva, &bv ); -- } -- return 0; --} -- --static AttributeDescription addef = { NULL, NULL, BER_BVC("default") }; --static AttrInfo aidef = { &addef }; -- --void --bdb_attr_index_unparse( struct bdb_info *bdb, BerVarray *bva ) --{ -- int i; -- -- if ( bdb->bi_defaultmask ) { -- aidef.ai_indexmask = bdb->bi_defaultmask; -- bdb_attr_index_unparser( &aidef, bva ); -- } -- for ( i=0; ibi_nattrs; i++ ) -- bdb_attr_index_unparser( bdb->bi_attrs[i], bva ); --} -- --void --bdb_attr_info_free( AttrInfo *ai ) --{ --#ifdef LDAP_COMP_MATCH -- free( ai->ai_cr ); --#endif -- free( ai ); --} -- --void --bdb_attr_index_destroy( struct bdb_info *bdb ) --{ -- int i; -- -- for ( i=0; ibi_nattrs; i++ ) -- bdb_attr_info_free( bdb->bi_attrs[i] ); -- -- free( bdb->bi_attrs ); --} -- --void bdb_attr_index_free( struct bdb_info *bdb, AttributeDescription *ad ) --{ -- int i; -- -- i = bdb_attr_slot( bdb, ad, NULL ); -- if ( i >= 0 ) { -- bdb_attr_info_free( bdb->bi_attrs[i] ); -- bdb->bi_nattrs--; -- for (; ibi_nattrs; i++) -- bdb->bi_attrs[i] = bdb->bi_attrs[i+1]; -- } --} -- --void bdb_attr_flush( struct bdb_info *bdb ) --{ -- int i; -- -- for ( i=0; ibi_nattrs; i++ ) { -- if ( bdb->bi_attrs[i]->ai_indexmask & BDB_INDEX_DELETING ) { -- int j; -- bdb_attr_info_free( bdb->bi_attrs[i] ); -- bdb->bi_nattrs--; -- for (j=i; jbi_nattrs; j++) -- bdb->bi_attrs[j] = bdb->bi_attrs[j+1]; -- i--; -- } -- } --} -diff --git a/servers/slapd/back-bdb/back-bdb.h b/servers/slapd/back-bdb/back-bdb.h -deleted file mode 100644 -index 84897cd..0000000 ---- a/servers/slapd/back-bdb/back-bdb.h -+++ /dev/null -@@ -1,377 +0,0 @@ --/* back-bdb.h - bdb back-end header file */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#ifndef _BACK_BDB_H_ --#define _BACK_BDB_H_ -- --#include --#include "slap.h" --#include --#include "alock.h" -- --LDAP_BEGIN_DECL -- --#define DB_VERSION_FULL ((DB_VERSION_MAJOR << 24) | (DB_VERSION_MINOR << 16) | DB_VERSION_PATCH) -- --#define DN_BASE_PREFIX SLAP_INDEX_EQUALITY_PREFIX --#define DN_ONE_PREFIX '%' --#define DN_SUBTREE_PREFIX '@' -- --#define DBTzero(t) (memset((t), 0, sizeof(DBT))) --#define DBT2bv(t,bv) ((bv)->bv_val = (t)->data, \ -- (bv)->bv_len = (t)->size) --#define bv2DBT(bv,t) ((t)->data = (bv)->bv_val, \ -- (t)->size = (bv)->bv_len ) -- --#define BDB_TXN_RETRIES 16 -- --#define BDB_MAX_ADD_LOOP 30 -- --#define BDB_SUFFIX ".bdb" --#define BDB_ID2ENTRY 0 --#define BDB_DN2ID 1 --#define BDB_NDB 2 -- --/* The bdb on-disk entry format is pretty space-inefficient. Average -- * sized user entries are 3-4K each. You need at least two entries to -- * fit into a single database page, more is better. 64K is BDB's -- * upper bound. Smaller pages are better for concurrency. -- */ --#ifndef BDB_ID2ENTRY_PAGESIZE --#define BDB_ID2ENTRY_PAGESIZE 16384 --#endif -- --#define DEFAULT_CACHE_SIZE 1000 -- --/* The default search IDL stack cache depth */ --#define DEFAULT_SEARCH_STACK_DEPTH 16 -- --/* The minimum we can function with */ --#define MINIMUM_SEARCH_STACK_DEPTH 8 -- --typedef struct bdb_idl_cache_entry_s { -- struct berval kstr; -- ID *idl; -- DB *db; -- int idl_flags; -- struct bdb_idl_cache_entry_s* idl_lru_prev; -- struct bdb_idl_cache_entry_s* idl_lru_next; --} bdb_idl_cache_entry_t; -- --/* BDB backend specific entry info */ --typedef struct bdb_entry_info { -- struct bdb_entry_info *bei_parent; -- ID bei_id; -- -- /* we use the bei_id as a lockobj, but we need to make the size != 4 -- * to avoid conflicting with BDB's internal locks. So add a byte here -- * that is always zero. -- */ -- short bei_lockpad; -- -- short bei_state; --#define CACHE_ENTRY_DELETED 1 --#define CACHE_ENTRY_NO_KIDS 2 --#define CACHE_ENTRY_NOT_LINKED 4 --#define CACHE_ENTRY_NO_GRANDKIDS 8 --#define CACHE_ENTRY_LOADING 0x10 --#define CACHE_ENTRY_WALKING 0x20 --#define CACHE_ENTRY_ONELEVEL 0x40 --#define CACHE_ENTRY_REFERENCED 0x80 --#define CACHE_ENTRY_NOT_CACHED 0x100 -- int bei_finders; -- -- /* -- * remaining fields require backend cache lock to access -- */ -- struct berval bei_nrdn; --#ifdef BDB_HIER -- struct berval bei_rdn; -- int bei_modrdns; /* track renames */ -- int bei_ckids; /* number of kids cached */ -- int bei_dkids; /* number of kids on-disk, plus 1 */ --#endif -- Entry *bei_e; -- Avlnode *bei_kids; --#ifdef SLAP_ZONE_ALLOC -- struct bdb_info *bei_bdb; -- int bei_zseq; --#endif -- ldap_pvt_thread_mutex_t bei_kids_mutex; -- -- struct bdb_entry_info *bei_lrunext; /* for cache lru list */ -- struct bdb_entry_info *bei_lruprev; --} EntryInfo; --#undef BEI --#define BEI(e) ((EntryInfo *) ((e)->e_private)) -- --/* for the in-core cache of entries */ --typedef struct bdb_cache { -- EntryInfo *c_eifree; /* free list */ -- Avlnode *c_idtree; -- EntryInfo *c_lruhead; /* lru - add accessed entries here */ -- EntryInfo *c_lrutail; /* lru - rem lru entries from here */ -- EntryInfo c_dntree; -- ID c_maxsize; -- ID c_cursize; -- ID c_minfree; -- ID c_eimax; -- ID c_eiused; /* EntryInfo's in use */ -- ID c_leaves; /* EntryInfo leaf nodes */ -- int c_purging; -- DB_TXN *c_txn; /* used by lru cleaner */ -- ldap_pvt_thread_rdwr_t c_rwlock; -- ldap_pvt_thread_mutex_t c_lru_mutex; -- ldap_pvt_thread_mutex_t c_count_mutex; -- ldap_pvt_thread_mutex_t c_eifree_mutex; --#ifdef SLAP_ZONE_ALLOC -- void *c_zctx; --#endif --} Cache; -- --#define CACHE_READ_LOCK 0 --#define CACHE_WRITE_LOCK 1 -- --#define BDB_INDICES 128 -- --struct bdb_db_info { -- struct berval bdi_name; -- DB *bdi_db; --}; -- --struct bdb_db_pgsize { -- struct bdb_db_pgsize *bdp_next; -- struct berval bdp_name; -- int bdp_size; --}; -- --#ifdef LDAP_DEVEL --#define BDB_MONITOR_IDX --#endif /* LDAP_DEVEL */ -- --typedef struct bdb_monitor_t { -- void *bdm_cb; -- struct berval bdm_ndn; --} bdb_monitor_t; -- --/* From ldap_rq.h */ --struct re_s; -- --struct bdb_info { -- DB_ENV *bi_dbenv; -- -- /* DB_ENV parameters */ -- /* The DB_ENV can be tuned via DB_CONFIG */ -- char *bi_dbenv_home; -- u_int32_t bi_dbenv_xflags; /* extra flags */ -- int bi_dbenv_mode; -- -- int bi_ndatabases; -- int bi_db_opflags; /* db-specific flags */ -- struct bdb_db_info **bi_databases; -- ldap_pvt_thread_mutex_t bi_database_mutex; -- struct bdb_db_pgsize *bi_pagesizes; -- -- slap_mask_t bi_defaultmask; -- Cache bi_cache; -- struct bdb_attrinfo **bi_attrs; -- int bi_nattrs; -- void *bi_search_stack; -- int bi_search_stack_depth; -- int bi_linear_index; -- -- int bi_txn_cp; -- u_int32_t bi_txn_cp_min; -- u_int32_t bi_txn_cp_kbyte; -- struct re_s *bi_txn_cp_task; -- struct re_s *bi_index_task; -- -- u_int32_t bi_lock_detect; -- long bi_shm_key; -- -- ID bi_lastid; -- ldap_pvt_thread_mutex_t bi_lastid_mutex; -- ID bi_idl_cache_max_size; -- ID bi_idl_cache_size; -- Avlnode *bi_idl_tree; -- bdb_idl_cache_entry_t *bi_idl_lru_head; -- bdb_idl_cache_entry_t *bi_idl_lru_tail; -- ldap_pvt_thread_rdwr_t bi_idl_tree_rwlock; -- ldap_pvt_thread_mutex_t bi_idl_tree_lrulock; -- alock_info_t bi_alock_info; -- char *bi_db_config_path; -- BerVarray bi_db_config; -- char *bi_db_crypt_file; -- struct berval bi_db_crypt_key; -- bdb_monitor_t bi_monitor; -- --#ifdef BDB_MONITOR_IDX -- ldap_pvt_thread_mutex_t bi_idx_mutex; -- Avlnode *bi_idx; --#endif /* BDB_MONITOR_IDX */ -- -- int bi_flags; --#define BDB_IS_OPEN 0x01 --#define BDB_HAS_CONFIG 0x02 --#define BDB_UPD_CONFIG 0x04 --#define BDB_DEL_INDEX 0x08 --#define BDB_RE_OPEN 0x10 --#define BDB_CHKSUM 0x20 --#ifdef BDB_HIER -- int bi_modrdns; /* number of modrdns completed */ -- ldap_pvt_thread_mutex_t bi_modrdns_mutex; --#endif --}; -- --#define bi_id2entry bi_databases[BDB_ID2ENTRY] --#define bi_dn2id bi_databases[BDB_DN2ID] -- -- --struct bdb_lock_info { -- struct bdb_lock_info *bli_next; -- DB_LOCK bli_lock; -- ID bli_id; -- int bli_flag; --}; --#define BLI_DONTFREE 1 -- --struct bdb_op_info { -- OpExtra boi_oe; -- DB_TXN* boi_txn; -- struct bdb_lock_info *boi_locks; /* used when no txn */ -- u_int32_t boi_err; -- char boi_acl_cache; -- char boi_flag; --}; --#define BOI_DONTFREE 1 -- --#define DB_OPEN(db, file, name, type, flags, mode) \ -- ((db)->open)(db, file, name, type, flags, mode) -- --#if DB_VERSION_MAJOR < 4 --#define LOCK_DETECT(env,f,t,a) lock_detect(env, f, t, a) --#define LOCK_GET(env,i,f,o,m,l) lock_get(env, i, f, o, m, l) --#define LOCK_PUT(env,l) lock_put(env, l) --#define TXN_CHECKPOINT(env,k,m,f) txn_checkpoint(env, k, m, f) --#define TXN_BEGIN(env,p,t,f) txn_begin((env), p, t, f) --#define TXN_PREPARE(txn,gid) txn_prepare((txn), (gid)) --#define TXN_COMMIT(txn,f) txn_commit((txn), (f)) --#define TXN_ABORT(txn) txn_abort((txn)) --#define TXN_ID(txn) txn_id(txn) --#define XLOCK_ID(env, locker) lock_id(env, locker) --#define XLOCK_ID_FREE(env, locker) lock_id_free(env, locker) --#else --#define LOCK_DETECT(env,f,t,a) (env)->lock_detect(env, f, t, a) --#define LOCK_GET(env,i,f,o,m,l) (env)->lock_get(env, i, f, o, m, l) --#define LOCK_PUT(env,l) (env)->lock_put(env, l) --#define TXN_CHECKPOINT(env,k,m,f) (env)->txn_checkpoint(env, k, m, f) --#define TXN_BEGIN(env,p,t,f) (env)->txn_begin((env), p, t, f) --#define TXN_PREPARE(txn,g) (txn)->prepare((txn), (g)) --#define TXN_COMMIT(txn,f) (txn)->commit((txn), (f)) --#define TXN_ABORT(txn) (txn)->abort((txn)) --#define TXN_ID(txn) (txn)->id(txn) --#define XLOCK_ID(env, locker) (env)->lock_id(env, locker) --#define XLOCK_ID_FREE(env, locker) (env)->lock_id_free(env, locker) -- --/* BDB 4.1.17 adds txn arg to db->open */ --#if DB_VERSION_FULL >= 0x04010011 --#undef DB_OPEN --#define DB_OPEN(db, file, name, type, flags, mode) \ -- ((db)->open)(db, NULL, file, name, type, flags, mode) --#endif -- --/* #undef BDB_LOG_DEBUG */ -- --#ifdef BDB_LOG_DEBUG -- --/* env->log_printf appeared in 4.4 */ --#if DB_VERSION_FULL >= 0x04040000 --#define BDB_LOG_PRINTF(env,txn,fmt,...) (env)->log_printf((env),(txn),(fmt),__VA_ARGS__) --#else --extern int __db_logmsg(const DB_ENV *env, DB_TXN *txn, const char *op, u_int32_t flags, -- const char *fmt,...); --#define BDB_LOG_PRINTF(env,txn,fmt,...) __db_logmsg((env),(txn),"DIAGNOSTIC",0,(fmt),__VA_ARGS__) --#endif -- --/* !BDB_LOG_DEBUG */ --#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ -- (defined(__GNUC__) && __GNUC__ >= 3 && !defined(__STRICT_ANSI__)) --#define BDB_LOG_PRINTF(a,b,c,...) --#else --#define BDB_LOG_PRINTF (void) /* will evaluate and discard the arguments */ -- --#endif /* BDB_LOG_DEBUG */ -- --#endif -- --#ifndef DB_BUFFER_SMALL --#define DB_BUFFER_SMALL ENOMEM --#endif -- --#define BDB_CSN_COMMIT 0 --#define BDB_CSN_ABORT 1 --#define BDB_CSN_RETRY 2 -- --/* Copy an ID "src" to pointer "dst" in big-endian byte order */ --#define BDB_ID2DISK( src, dst ) \ -- do { int i0; ID tmp; unsigned char *_p; \ -- tmp = (src); _p = (unsigned char *)(dst); \ -- for ( i0=sizeof(ID)-1; i0>=0; i0-- ) { \ -- _p[i0] = tmp & 0xff; tmp >>= 8; \ -- } \ -- } while(0) -- --/* Copy a pointer "src" to a pointer "dst" from big-endian to native order */ --#define BDB_DISK2ID( src, dst ) \ -- do { unsigned i0; ID tmp = 0; unsigned char *_p; \ -- _p = (unsigned char *)(src); \ -- for ( i0=0; i0. -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include --#include --#include -- --#include "back-bdb.h" -- --int --bdb_bind( Operation *op, SlapReply *rs ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- Entry *e; -- Attribute *a; -- EntryInfo *ei; -- -- AttributeDescription *password = slap_schema.si_ad_userPassword; -- -- DB_TXN *rtxn; -- DB_LOCK lock; -- -- Debug( LDAP_DEBUG_ARGS, -- "==> " LDAP_XSTRING(bdb_bind) ": dn: %s\n", -- op->o_req_dn.bv_val, 0, 0); -- -- /* allow noauth binds */ -- switch ( be_rootdn_bind( op, NULL ) ) { -- case LDAP_SUCCESS: -- /* frontend will send result */ -- return rs->sr_err = LDAP_SUCCESS; -- -- default: -- /* give the database a chance */ -- /* NOTE: this behavior departs from that of other backends, -- * since the others, in case of password checking failure -- * do not give the database a chance. If an entry with -- * rootdn's name does not exist in the database the result -- * will be the same. See ITS#4962 for discussion. */ -- break; -- } -- -- rs->sr_err = bdb_reader_get(op, bdb->bi_dbenv, &rtxn); -- switch(rs->sr_err) { -- case 0: -- break; -- default: -- rs->sr_text = "internal error"; -- send_ldap_result( op, rs ); -- return rs->sr_err; -- } -- --dn2entry_retry: -- /* get entry with reader lock */ -- rs->sr_err = bdb_dn2entry( op, rtxn, &op->o_req_ndn, &ei, 1, -- &lock ); -- -- switch(rs->sr_err) { -- case DB_NOTFOUND: -- case 0: -- break; -- case LDAP_BUSY: -- send_ldap_error( op, rs, LDAP_BUSY, "ldap_server_busy" ); -- return LDAP_BUSY; -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto dn2entry_retry; -- default: -- send_ldap_error( op, rs, LDAP_OTHER, "internal error" ); -- return rs->sr_err; -- } -- -- e = ei->bei_e; -- if ( rs->sr_err == DB_NOTFOUND ) { -- if( e != NULL ) { -- bdb_cache_return_entry_r( bdb, e, &lock ); -- e = NULL; -- } -- -- rs->sr_err = LDAP_INVALID_CREDENTIALS; -- send_ldap_result( op, rs ); -- -- return rs->sr_err; -- } -- -- ber_dupbv( &op->oq_bind.rb_edn, &e->e_name ); -- -- /* check for deleted */ -- if ( is_entry_subentry( e ) ) { -- /* entry is an subentry, don't allow bind */ -- Debug( LDAP_DEBUG_TRACE, "entry is subentry\n", 0, -- 0, 0 ); -- rs->sr_err = LDAP_INVALID_CREDENTIALS; -- goto done; -- } -- -- if ( is_entry_alias( e ) ) { -- /* entry is an alias, don't allow bind */ -- Debug( LDAP_DEBUG_TRACE, "entry is alias\n", 0, 0, 0 ); -- rs->sr_err = LDAP_INVALID_CREDENTIALS; -- goto done; -- } -- -- if ( is_entry_referral( e ) ) { -- Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0, -- 0, 0 ); -- rs->sr_err = LDAP_INVALID_CREDENTIALS; -- goto done; -- } -- -- switch ( op->oq_bind.rb_method ) { -- case LDAP_AUTH_SIMPLE: -- a = attr_find( e->e_attrs, password ); -- if ( a == NULL ) { -- rs->sr_err = LDAP_INVALID_CREDENTIALS; -- goto done; -- } -- -- if ( slap_passwd_check( op, e, a, &op->oq_bind.rb_cred, -- &rs->sr_text ) != 0 ) -- { -- /* failure; stop front end from sending result */ -- rs->sr_err = LDAP_INVALID_CREDENTIALS; -- goto done; -- } -- -- rs->sr_err = 0; -- break; -- -- default: -- assert( 0 ); /* should not be reachable */ -- rs->sr_err = LDAP_STRONG_AUTH_NOT_SUPPORTED; -- rs->sr_text = "authentication method not supported"; -- } -- --done: -- /* free entry and reader lock */ -- if( e != NULL ) { -- bdb_cache_return_entry_r( bdb, e, &lock ); -- } -- -- if ( rs->sr_err ) { -- send_ldap_result( op, rs ); -- if ( rs->sr_ref ) { -- ber_bvarray_free( rs->sr_ref ); -- rs->sr_ref = NULL; -- } -- } -- /* front end will send result on success (rs->sr_err==0) */ -- return rs->sr_err; --} -diff --git a/servers/slapd/back-bdb/cache.c b/servers/slapd/back-bdb/cache.c -deleted file mode 100644 -index 51161fe..0000000 ---- a/servers/slapd/back-bdb/cache.c -+++ /dev/null -@@ -1,1692 +0,0 @@ --/* cache.c - routines to maintain an in-core cache of entries */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include -- --#include --#include --#include -- --#include "slap.h" -- --#include "back-bdb.h" -- --#include "ldap_rq.h" -- --#ifdef BDB_HIER --#define bdb_cache_lru_purge hdb_cache_lru_purge --#endif --static void bdb_cache_lru_purge( struct bdb_info *bdb ); -- --static int bdb_cache_delete_internal(Cache *cache, EntryInfo *e, int decr); --#ifdef LDAP_DEBUG --#define SLAPD_UNUSED --#ifdef SLAPD_UNUSED --static void bdb_lru_print(Cache *cache); --static void bdb_idtree_print(Cache *cache); --#endif --#endif -- --/* For concurrency experiments only! */ --#if 0 --#define ldap_pvt_thread_rdwr_wlock(a) 0 --#define ldap_pvt_thread_rdwr_wunlock(a) 0 --#define ldap_pvt_thread_rdwr_rlock(a) 0 --#define ldap_pvt_thread_rdwr_runlock(a) 0 --#endif -- --#if 0 --#define ldap_pvt_thread_mutex_trylock(a) 0 --#endif -- --static EntryInfo * --bdb_cache_entryinfo_new( Cache *cache ) --{ -- EntryInfo *ei = NULL; -- -- if ( cache->c_eifree ) { -- ldap_pvt_thread_mutex_lock( &cache->c_eifree_mutex ); -- if ( cache->c_eifree ) { -- ei = cache->c_eifree; -- cache->c_eifree = ei->bei_lrunext; -- ei->bei_finders = 0; -- ei->bei_lrunext = NULL; -- } -- ldap_pvt_thread_mutex_unlock( &cache->c_eifree_mutex ); -- } -- if ( !ei ) { -- ei = ch_calloc(1, sizeof(EntryInfo)); -- ldap_pvt_thread_mutex_init( &ei->bei_kids_mutex ); -- } -- -- ei->bei_state = CACHE_ENTRY_REFERENCED; -- -- return ei; --} -- --static void --bdb_cache_entryinfo_free( Cache *cache, EntryInfo *ei ) --{ -- free( ei->bei_nrdn.bv_val ); -- BER_BVZERO( &ei->bei_nrdn ); --#ifdef BDB_HIER -- free( ei->bei_rdn.bv_val ); -- BER_BVZERO( &ei->bei_rdn ); -- ei->bei_modrdns = 0; -- ei->bei_ckids = 0; -- ei->bei_dkids = 0; --#endif -- ei->bei_parent = NULL; -- ei->bei_kids = NULL; -- ei->bei_lruprev = NULL; -- --#if 0 -- ldap_pvt_thread_mutex_lock( &cache->c_eifree_mutex ); -- ei->bei_lrunext = cache->c_eifree; -- cache->c_eifree = ei; -- ldap_pvt_thread_mutex_unlock( &cache->c_eifree_mutex ); --#else -- ldap_pvt_thread_mutex_destroy( &ei->bei_kids_mutex ); -- ch_free( ei ); --#endif --} -- --#define LRU_DEL( c, e ) do { \ -- if ( e == e->bei_lruprev ) { \ -- (c)->c_lruhead = (c)->c_lrutail = NULL; \ -- } else { \ -- if ( e == (c)->c_lruhead ) (c)->c_lruhead = e->bei_lruprev; \ -- if ( e == (c)->c_lrutail ) (c)->c_lrutail = e->bei_lruprev; \ -- e->bei_lrunext->bei_lruprev = e->bei_lruprev; \ -- e->bei_lruprev->bei_lrunext = e->bei_lrunext; \ -- } \ -- e->bei_lruprev = NULL; \ --} while ( 0 ) -- --/* Note - we now use a Second-Chance / Clock algorithm instead of -- * Least-Recently-Used. This tremendously improves concurrency -- * because we no longer need to manipulate the lists every time an -- * entry is touched. We only need to lock the lists when adding -- * or deleting an entry. It's now a circular doubly-linked list. -- * We always append to the tail, but the head traverses the circle -- * during a purge operation. -- */ --static void --bdb_cache_lru_link( struct bdb_info *bdb, EntryInfo *ei ) --{ -- -- /* Already linked, ignore */ -- if ( ei->bei_lruprev ) -- return; -- -- /* Insert into circular LRU list */ -- ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_lru_mutex ); -- -- ei->bei_lruprev = bdb->bi_cache.c_lrutail; -- if ( bdb->bi_cache.c_lrutail ) { -- ei->bei_lrunext = bdb->bi_cache.c_lrutail->bei_lrunext; -- bdb->bi_cache.c_lrutail->bei_lrunext = ei; -- if ( ei->bei_lrunext ) -- ei->bei_lrunext->bei_lruprev = ei; -- } else { -- ei->bei_lrunext = ei->bei_lruprev = ei; -- bdb->bi_cache.c_lruhead = ei; -- } -- bdb->bi_cache.c_lrutail = ei; -- ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_lru_mutex ); --} -- --#ifdef NO_THREADS --#define NO_DB_LOCK --#endif -- --/* #define NO_DB_LOCK 1 */ --/* Note: The BerkeleyDB locks are much slower than regular -- * mutexes or rdwr locks. But the BDB implementation has the -- * advantage of using a fixed size lock table, instead of -- * allocating a lock object per entry in the DB. That's a -- * key benefit for scaling. It also frees us from worrying -- * about undetectable deadlocks between BDB activity and our -- * own cache activity. It's still worth exploring faster -- * alternatives though. -- */ -- --/* Atomically release and reacquire a lock */ --int --bdb_cache_entry_db_relock( -- struct bdb_info *bdb, -- DB_TXN *txn, -- EntryInfo *ei, -- int rw, -- int tryOnly, -- DB_LOCK *lock ) --{ --#ifdef NO_DB_LOCK -- return 0; --#else -- int rc; -- DBT lockobj; -- DB_LOCKREQ list[2]; -- -- if ( !lock ) return 0; -- -- DBTzero( &lockobj ); -- lockobj.data = &ei->bei_id; -- lockobj.size = sizeof(ei->bei_id) + 1; -- -- list[0].op = DB_LOCK_PUT; -- list[0].lock = *lock; -- list[1].op = DB_LOCK_GET; -- list[1].lock = *lock; -- list[1].mode = rw ? DB_LOCK_WRITE : DB_LOCK_READ; -- list[1].obj = &lockobj; -- rc = bdb->bi_dbenv->lock_vec(bdb->bi_dbenv, TXN_ID(txn), tryOnly ? DB_LOCK_NOWAIT : 0, -- list, 2, NULL ); -- -- if (rc && !tryOnly) { -- Debug( LDAP_DEBUG_TRACE, -- "bdb_cache_entry_db_relock: entry %ld, rw %d, rc %d\n", -- ei->bei_id, rw, rc ); -- } else { -- *lock = list[1].lock; -- } -- return rc; --#endif --} -- --static int --bdb_cache_entry_db_lock( struct bdb_info *bdb, DB_TXN *txn, EntryInfo *ei, -- int rw, int tryOnly, DB_LOCK *lock ) --{ --#ifdef NO_DB_LOCK -- return 0; --#else -- int rc; -- DBT lockobj; -- int db_rw; -- -- if ( !lock ) return 0; -- -- if (rw) -- db_rw = DB_LOCK_WRITE; -- else -- db_rw = DB_LOCK_READ; -- -- DBTzero( &lockobj ); -- lockobj.data = &ei->bei_id; -- lockobj.size = sizeof(ei->bei_id) + 1; -- -- rc = LOCK_GET(bdb->bi_dbenv, TXN_ID(txn), tryOnly ? DB_LOCK_NOWAIT : 0, -- &lockobj, db_rw, lock); -- if (rc && !tryOnly) { -- Debug( LDAP_DEBUG_TRACE, -- "bdb_cache_entry_db_lock: entry %ld, rw %d, rc %d\n", -- ei->bei_id, rw, rc ); -- } -- return rc; --#endif /* NO_DB_LOCK */ --} -- --int --bdb_cache_entry_db_unlock ( struct bdb_info *bdb, DB_LOCK *lock ) --{ --#ifdef NO_DB_LOCK -- return 0; --#else -- int rc; -- -- if ( !lock || lock->mode == DB_LOCK_NG ) return 0; -- -- rc = LOCK_PUT ( bdb->bi_dbenv, lock ); -- return rc; --#endif --} -- --void --bdb_cache_return_entry_rw( struct bdb_info *bdb, Entry *e, -- int rw, DB_LOCK *lock ) --{ -- EntryInfo *ei; -- int free = 0; -- -- ei = e->e_private; -- if ( ei && ( ei->bei_state & CACHE_ENTRY_NOT_CACHED )) { -- bdb_cache_entryinfo_lock( ei ); -- if ( ei->bei_state & CACHE_ENTRY_NOT_CACHED ) { -- /* Releasing the entry can only be done when -- * we know that nobody else is using it, i.e we -- * should have an entry_db writelock. But the -- * flag is only set by the thread that loads the -- * entry, and only if no other threads has found -- * it while it was working. All other threads -- * clear the flag, which mean that we should be -- * the only thread using the entry if the flag -- * is set here. -- */ -- ei->bei_e = NULL; -- ei->bei_state ^= CACHE_ENTRY_NOT_CACHED; -- free = 1; -- } -- bdb_cache_entryinfo_unlock( ei ); -- } -- bdb_cache_entry_db_unlock( bdb, lock ); -- if ( free ) { -- e->e_private = NULL; -- bdb_entry_return( e ); -- } --} -- --static int --bdb_cache_entryinfo_destroy( EntryInfo *e ) --{ -- ldap_pvt_thread_mutex_destroy( &e->bei_kids_mutex ); -- free( e->bei_nrdn.bv_val ); --#ifdef BDB_HIER -- free( e->bei_rdn.bv_val ); --#endif -- free( e ); -- return 0; --} -- --/* Do a length-ordered sort on normalized RDNs */ --static int --bdb_rdn_cmp( const void *v_e1, const void *v_e2 ) --{ -- const EntryInfo *e1 = v_e1, *e2 = v_e2; -- int rc = e1->bei_nrdn.bv_len - e2->bei_nrdn.bv_len; -- if (rc == 0) { -- rc = strncmp( e1->bei_nrdn.bv_val, e2->bei_nrdn.bv_val, -- e1->bei_nrdn.bv_len ); -- } -- return rc; --} -- --static int --bdb_id_cmp( const void *v_e1, const void *v_e2 ) --{ -- const EntryInfo *e1 = v_e1, *e2 = v_e2; -- return e1->bei_id - e2->bei_id; --} -- --static int --bdb_id_dup_err( void *v1, void *v2 ) --{ -- EntryInfo *e2 = v2; -- e2->bei_lrunext = v1; -- return -1; --} -- --/* Create an entryinfo in the cache. Caller must release the locks later. -- */ --static int --bdb_entryinfo_add_internal( -- struct bdb_info *bdb, -- EntryInfo *ei, -- EntryInfo **res ) --{ -- EntryInfo *ei2 = NULL; -- -- *res = NULL; -- -- ei2 = bdb_cache_entryinfo_new( &bdb->bi_cache ); -- -- bdb_cache_entryinfo_lock( ei->bei_parent ); -- ldap_pvt_thread_rdwr_wlock( &bdb->bi_cache.c_rwlock ); -- -- ei2->bei_id = ei->bei_id; -- ei2->bei_parent = ei->bei_parent; --#ifdef BDB_HIER -- ei2->bei_rdn = ei->bei_rdn; --#endif --#ifdef SLAP_ZONE_ALLOC -- ei2->bei_bdb = bdb; --#endif -- -- /* Add to cache ID tree */ -- if (avl_insert( &bdb->bi_cache.c_idtree, ei2, bdb_id_cmp, -- bdb_id_dup_err )) { -- EntryInfo *eix = ei2->bei_lrunext; -- bdb_cache_entryinfo_free( &bdb->bi_cache, ei2 ); -- ei2 = eix; --#ifdef BDB_HIER -- /* It got freed above because its value was -- * assigned to ei2. -- */ -- ei->bei_rdn.bv_val = NULL; --#endif -- } else { -- int rc; -- -- bdb->bi_cache.c_eiused++; -- ber_dupbv( &ei2->bei_nrdn, &ei->bei_nrdn ); -- -- /* This is a new leaf node. But if parent had no kids, then it was -- * a leaf and we would be decrementing that. So, only increment if -- * the parent already has kids. -- */ -- if ( ei->bei_parent->bei_kids || !ei->bei_parent->bei_id ) -- bdb->bi_cache.c_leaves++; -- rc = avl_insert( &ei->bei_parent->bei_kids, ei2, bdb_rdn_cmp, -- avl_dup_error ); --#ifdef BDB_HIER -- /* it's possible for hdb_cache_find_parent to beat us to it */ -- if ( !rc ) { -- ei->bei_parent->bei_ckids++; -- } --#endif -- } -- -- *res = ei2; -- return 0; --} -- --/* Find the EntryInfo for the requested DN. If the DN cannot be found, return -- * the info for its closest ancestor. *res should be NULL to process a -- * complete DN starting from the tree root. Otherwise *res must be the -- * immediate parent of the requested DN, and only the RDN will be searched. -- * The EntryInfo is locked upon return and must be unlocked by the caller. -- */ --int --bdb_cache_find_ndn( -- Operation *op, -- DB_TXN *txn, -- struct berval *ndn, -- EntryInfo **res ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- EntryInfo ei, *eip, *ei2; -- int rc = 0; -- char *ptr; -- -- /* this function is always called with normalized DN */ -- if ( *res ) { -- /* we're doing a onelevel search for an RDN */ -- ei.bei_nrdn.bv_val = ndn->bv_val; -- ei.bei_nrdn.bv_len = dn_rdnlen( op->o_bd, ndn ); -- eip = *res; -- } else { -- /* we're searching a full DN from the root */ -- ptr = ndn->bv_val + ndn->bv_len - op->o_bd->be_nsuffix[0].bv_len; -- ei.bei_nrdn.bv_val = ptr; -- ei.bei_nrdn.bv_len = op->o_bd->be_nsuffix[0].bv_len; -- /* Skip to next rdn if suffix is empty */ -- if ( ei.bei_nrdn.bv_len == 0 ) { -- for (ptr = ei.bei_nrdn.bv_val - 2; ptr > ndn->bv_val -- && !DN_SEPARATOR(*ptr); ptr--) /* empty */; -- if ( ptr >= ndn->bv_val ) { -- if (DN_SEPARATOR(*ptr)) ptr++; -- ei.bei_nrdn.bv_len = ei.bei_nrdn.bv_val - ptr; -- ei.bei_nrdn.bv_val = ptr; -- } -- } -- eip = &bdb->bi_cache.c_dntree; -- } -- -- for ( bdb_cache_entryinfo_lock( eip ); eip; ) { -- eip->bei_state |= CACHE_ENTRY_REFERENCED; -- ei.bei_parent = eip; -- ei2 = (EntryInfo *)avl_find( eip->bei_kids, &ei, bdb_rdn_cmp ); -- if ( !ei2 ) { -- DBC *cursor; -- int len = ei.bei_nrdn.bv_len; -- -- if ( BER_BVISEMPTY( ndn )) { -- *res = eip; -- return LDAP_SUCCESS; -- } -- -- ei.bei_nrdn.bv_len = ndn->bv_len - -- (ei.bei_nrdn.bv_val - ndn->bv_val); -- eip->bei_finders++; -- bdb_cache_entryinfo_unlock( eip ); -- -- BDB_LOG_PRINTF( bdb->bi_dbenv, NULL, "slapd Reading %s", -- ei.bei_nrdn.bv_val ); -- -- cursor = NULL; -- rc = bdb_dn2id( op, &ei.bei_nrdn, &ei, txn, &cursor ); -- if (rc) { -- bdb_cache_entryinfo_lock( eip ); -- eip->bei_finders--; -- if ( cursor ) cursor->c_close( cursor ); -- *res = eip; -- return rc; -- } -- -- BDB_LOG_PRINTF( bdb->bi_dbenv, NULL, "slapd Read got %s(%d)", -- ei.bei_nrdn.bv_val, ei.bei_id ); -- -- /* DN exists but needs to be added to cache */ -- ei.bei_nrdn.bv_len = len; -- rc = bdb_entryinfo_add_internal( bdb, &ei, &ei2 ); -- /* add_internal left eip and c_rwlock locked */ -- eip->bei_finders--; -- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock ); -- if ( cursor ) cursor->c_close( cursor ); -- if ( rc ) { -- *res = eip; -- return rc; -- } -- } -- bdb_cache_entryinfo_lock( ei2 ); -- if ( ei2->bei_state & CACHE_ENTRY_DELETED ) { -- /* In the midst of deleting? Give it a chance to -- * complete. -- */ -- bdb_cache_entryinfo_unlock( ei2 ); -- bdb_cache_entryinfo_unlock( eip ); -- ldap_pvt_thread_yield(); -- bdb_cache_entryinfo_lock( eip ); -- *res = eip; -- return DB_NOTFOUND; -- } -- bdb_cache_entryinfo_unlock( eip ); -- -- eip = ei2; -- -- /* Advance to next lower RDN */ -- for (ptr = ei.bei_nrdn.bv_val - 2; ptr > ndn->bv_val -- && !DN_SEPARATOR(*ptr); ptr--) /* empty */; -- if ( ptr >= ndn->bv_val ) { -- if (DN_SEPARATOR(*ptr)) ptr++; -- ei.bei_nrdn.bv_len = ei.bei_nrdn.bv_val - ptr - 1; -- ei.bei_nrdn.bv_val = ptr; -- } -- if ( ptr < ndn->bv_val ) { -- *res = eip; -- break; -- } -- } -- -- return rc; --} -- --#ifdef BDB_HIER --/* Walk up the tree from a child node, looking for an ID that's already -- * been linked into the cache. -- */ --int --hdb_cache_find_parent( -- Operation *op, -- DB_TXN *txn, -- ID id, -- EntryInfo **res ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- EntryInfo ei, eip, *ei2 = NULL, *ein = NULL, *eir = NULL; -- int rc, add; -- -- ei.bei_id = id; -- ei.bei_kids = NULL; -- ei.bei_ckids = 0; -- -- for (;;) { -- rc = hdb_dn2id_parent( op, txn, &ei, &eip.bei_id ); -- if ( rc ) break; -- -- /* Save the previous node, if any */ -- ei2 = ein; -- -- /* Create a new node for the current ID */ -- ein = bdb_cache_entryinfo_new( &bdb->bi_cache ); -- ein->bei_id = ei.bei_id; -- ein->bei_kids = ei.bei_kids; -- ein->bei_nrdn = ei.bei_nrdn; -- ein->bei_rdn = ei.bei_rdn; -- ein->bei_ckids = ei.bei_ckids; --#ifdef SLAP_ZONE_ALLOC -- ein->bei_bdb = bdb; --#endif -- ei.bei_ckids = 0; -- add = 1; -- -- /* This node is not fully connected yet */ -- ein->bei_state |= CACHE_ENTRY_NOT_LINKED; -- -- /* If this is the first time, save this node -- * to be returned later. -- */ -- if ( eir == NULL ) { -- eir = ein; -- ein->bei_finders++; -- } -- --again: -- /* Insert this node into the ID tree */ -- ldap_pvt_thread_rdwr_wlock( &bdb->bi_cache.c_rwlock ); -- if ( avl_insert( &bdb->bi_cache.c_idtree, (caddr_t)ein, -- bdb_id_cmp, bdb_id_dup_err ) ) { -- EntryInfo *eix = ein->bei_lrunext; -- -- if ( bdb_cache_entryinfo_trylock( eix )) { -- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock ); -- ldap_pvt_thread_yield(); -- goto again; -- } -- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock ); -- -- /* Someone else created this node just before us. -- * Free our new copy and use the existing one. -- */ -- bdb_cache_entryinfo_free( &bdb->bi_cache, ein ); -- -- /* if it was the node we were looking for, just return it */ -- if ( eir == ein ) { -- *res = eix; -- rc = 0; -- break; -- } -- -- ein = ei2; -- ei2 = eix; -- add = 0; -- -- /* otherwise, link up what we have and return */ -- goto gotparent; -- } -- -- /* If there was a previous node, link it to this one */ -- if ( ei2 ) ei2->bei_parent = ein; -- -- /* Look for this node's parent */ --par2: -- if ( eip.bei_id ) { -- ei2 = (EntryInfo *) avl_find( bdb->bi_cache.c_idtree, -- (caddr_t) &eip, bdb_id_cmp ); -- } else { -- ei2 = &bdb->bi_cache.c_dntree; -- } -- if ( ei2 && bdb_cache_entryinfo_trylock( ei2 )) { -- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock ); -- ldap_pvt_thread_yield(); -- ldap_pvt_thread_rdwr_wlock( &bdb->bi_cache.c_rwlock ); -- goto par2; -- } -- if ( add ) -- bdb->bi_cache.c_eiused++; -- if ( ei2 && ( ei2->bei_kids || !ei2->bei_id )) -- bdb->bi_cache.c_leaves++; -- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock ); -- --gotparent: -- /* Got the parent, link in and we're done. */ -- if ( ei2 ) { -- bdb_cache_entryinfo_lock( eir ); -- ein->bei_parent = ei2; -- -- if ( avl_insert( &ei2->bei_kids, (caddr_t)ein, bdb_rdn_cmp, -- avl_dup_error) == 0 ) -- ei2->bei_ckids++; -- -- /* Reset all the state info */ -- for (ein = eir; ein != ei2; ein=ein->bei_parent) -- ein->bei_state &= ~CACHE_ENTRY_NOT_LINKED; -- -- bdb_cache_entryinfo_unlock( ei2 ); -- eir->bei_finders--; -- -- *res = eir; -- break; -- } -- ei.bei_kids = NULL; -- ei.bei_id = eip.bei_id; -- ei.bei_ckids = 1; -- avl_insert( &ei.bei_kids, (caddr_t)ein, bdb_rdn_cmp, -- avl_dup_error ); -- } -- return rc; --} -- --/* Used by hdb_dn2idl when loading the EntryInfo for all the children -- * of a given node -- */ --int hdb_cache_load( -- struct bdb_info *bdb, -- EntryInfo *ei, -- EntryInfo **res ) --{ -- EntryInfo *ei2; -- int rc; -- -- /* See if we already have this one */ -- bdb_cache_entryinfo_lock( ei->bei_parent ); -- ei2 = (EntryInfo *)avl_find( ei->bei_parent->bei_kids, ei, bdb_rdn_cmp ); -- bdb_cache_entryinfo_unlock( ei->bei_parent ); -- -- if ( !ei2 ) { -- /* Not found, add it */ -- struct berval bv; -- -- /* bei_rdn was not malloc'd before, do it now */ -- ber_dupbv( &bv, &ei->bei_rdn ); -- ei->bei_rdn = bv; -- -- rc = bdb_entryinfo_add_internal( bdb, ei, res ); -- bdb_cache_entryinfo_unlock( ei->bei_parent ); -- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock ); -- } else { -- /* Found, return it */ -- *res = ei2; -- return 0; -- } -- return rc; --} --#endif -- --/* This is best-effort only. If all entries in the cache are -- * busy, they will all be kept. This is unlikely to happen -- * unless the cache is very much smaller than the working set. -- */ --static void --bdb_cache_lru_purge( struct bdb_info *bdb ) --{ -- DB_LOCK lock, *lockp; -- EntryInfo *elru, *elnext = NULL; -- int islocked; -- ID eicount, ecount; -- ID count, efree, eifree = 0; --#ifdef LDAP_DEBUG -- int iter; --#endif -- -- /* Wait for the mutex; we're the only one trying to purge. */ -- ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_lru_mutex ); -- -- if ( bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize ) { -- efree = bdb->bi_cache.c_cursize - bdb->bi_cache.c_maxsize; -- efree += bdb->bi_cache.c_minfree; -- } else { -- efree = 0; -- } -- -- /* maximum number of EntryInfo leaves to cache. In slapcat -- * we always free all leaf nodes. -- */ -- -- if ( slapMode & SLAP_TOOL_READONLY ) { -- eifree = bdb->bi_cache.c_leaves; -- } else if ( bdb->bi_cache.c_eimax && -- bdb->bi_cache.c_leaves > bdb->bi_cache.c_eimax ) { -- eifree = bdb->bi_cache.c_minfree * 10; -- if ( eifree >= bdb->bi_cache.c_leaves ) -- eifree /= 2; -- } -- -- if ( !efree && !eifree ) { -- ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_lru_mutex ); -- bdb->bi_cache.c_purging = 0; -- return; -- } -- -- if ( bdb->bi_cache.c_txn ) { -- lockp = &lock; -- } else { -- lockp = NULL; -- } -- -- count = 0; -- eicount = 0; -- ecount = 0; --#ifdef LDAP_DEBUG -- iter = 0; --#endif -- -- /* Look for an unused entry to remove */ -- for ( elru = bdb->bi_cache.c_lruhead; elru; elru = elnext ) { -- elnext = elru->bei_lrunext; -- -- if ( bdb_cache_entryinfo_trylock( elru )) -- goto bottom; -- -- /* This flag implements the clock replacement behavior */ -- if ( elru->bei_state & ( CACHE_ENTRY_REFERENCED )) { -- elru->bei_state &= ~CACHE_ENTRY_REFERENCED; -- bdb_cache_entryinfo_unlock( elru ); -- goto bottom; -- } -- -- /* If this node is in the process of linking into the cache, -- * or this node is being deleted, skip it. -- */ -- if (( elru->bei_state & ( CACHE_ENTRY_NOT_LINKED | -- CACHE_ENTRY_DELETED | CACHE_ENTRY_LOADING | -- CACHE_ENTRY_ONELEVEL )) || -- elru->bei_finders > 0 ) { -- bdb_cache_entryinfo_unlock( elru ); -- goto bottom; -- } -- -- if ( bdb_cache_entryinfo_trylock( elru->bei_parent )) { -- bdb_cache_entryinfo_unlock( elru ); -- goto bottom; -- } -- -- /* entryinfo is locked */ -- islocked = 1; -- -- /* If we can successfully writelock it, then -- * the object is idle. -- */ -- if ( bdb_cache_entry_db_lock( bdb, -- bdb->bi_cache.c_txn, elru, 1, 1, lockp ) == 0 ) { -- -- /* Free entry for this node if it's present */ -- if ( elru->bei_e ) { -- ecount++; -- -- /* the cache may have gone over the limit while we -- * weren't looking, so double check. -- */ -- if ( !efree && ecount > bdb->bi_cache.c_maxsize ) -- efree = bdb->bi_cache.c_minfree; -- -- if ( count < efree ) { -- elru->bei_e->e_private = NULL; --#ifdef SLAP_ZONE_ALLOC -- bdb_entry_return( bdb, elru->bei_e, elru->bei_zseq ); --#else -- bdb_entry_return( elru->bei_e ); --#endif -- elru->bei_e = NULL; -- count++; -- } else { -- /* Keep this node cached, skip to next */ -- bdb_cache_entry_db_unlock( bdb, lockp ); -- goto next; -- } -- } -- bdb_cache_entry_db_unlock( bdb, lockp ); -- -- /* -- * If it is a leaf node, and we're over the limit, free it. -- */ -- if ( elru->bei_kids ) { -- /* Drop from list, we ignore it... */ -- LRU_DEL( &bdb->bi_cache, elru ); -- } else if ( eicount < eifree ) { -- /* Too many leaf nodes, free this one */ -- bdb_cache_delete_internal( &bdb->bi_cache, elru, 0 ); -- bdb_cache_delete_cleanup( &bdb->bi_cache, elru ); -- islocked = 0; -- eicount++; -- } /* Leave on list until we need to free it */ -- } -- --next: -- if ( islocked ) { -- bdb_cache_entryinfo_unlock( elru ); -- bdb_cache_entryinfo_unlock( elru->bei_parent ); -- } -- -- if ( count >= efree && eicount >= eifree ) -- break; --bottom: -- if ( elnext == bdb->bi_cache.c_lruhead ) -- break; --#ifdef LDAP_DEBUG -- iter++; --#endif -- } -- -- if ( count || ecount > bdb->bi_cache.c_cursize ) { -- ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_count_mutex ); -- /* HACK: we seem to be losing track, fix up now */ -- if ( ecount > bdb->bi_cache.c_cursize ) -- bdb->bi_cache.c_cursize = ecount; -- bdb->bi_cache.c_cursize -= count; -- ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex ); -- } -- bdb->bi_cache.c_lruhead = elnext; -- ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_lru_mutex ); -- bdb->bi_cache.c_purging = 0; --} -- --/* -- * cache_find_id - find an entry in the cache, given id. -- * The entry is locked for Read upon return. Call with flag ID_LOCKED if -- * the supplied *eip was already locked. -- */ -- --int --bdb_cache_find_id( -- Operation *op, -- DB_TXN *tid, -- ID id, -- EntryInfo **eip, -- int flag, -- DB_LOCK *lock ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- Entry *ep = NULL; -- int rc = 0, load = 0; -- EntryInfo ei = { 0 }; -- -- ei.bei_id = id; -- --#ifdef SLAP_ZONE_ALLOC -- slap_zh_rlock(bdb->bi_cache.c_zctx); --#endif -- /* If we weren't given any info, see if we have it already cached */ -- if ( !*eip ) { --again: ldap_pvt_thread_rdwr_rlock( &bdb->bi_cache.c_rwlock ); -- *eip = (EntryInfo *) avl_find( bdb->bi_cache.c_idtree, -- (caddr_t) &ei, bdb_id_cmp ); -- if ( *eip ) { -- /* If the lock attempt fails, the info is in use */ -- if ( bdb_cache_entryinfo_trylock( *eip )) { -- int del = (*eip)->bei_state & CACHE_ENTRY_DELETED; -- ldap_pvt_thread_rdwr_runlock( &bdb->bi_cache.c_rwlock ); -- /* If this node is being deleted, treat -- * as if the delete has already finished -- */ -- if ( del ) { -- return DB_NOTFOUND; -- } -- /* otherwise, wait for the info to free up */ -- ldap_pvt_thread_yield(); -- goto again; -- } -- /* If this info isn't hooked up to its parent yet, -- * unlock and wait for it to be fully initialized -- */ -- if ( (*eip)->bei_state & CACHE_ENTRY_NOT_LINKED ) { -- bdb_cache_entryinfo_unlock( *eip ); -- ldap_pvt_thread_rdwr_runlock( &bdb->bi_cache.c_rwlock ); -- ldap_pvt_thread_yield(); -- goto again; -- } -- flag |= ID_LOCKED; -- } -- ldap_pvt_thread_rdwr_runlock( &bdb->bi_cache.c_rwlock ); -- } -- -- /* See if the ID exists in the database; add it to the cache if so */ -- if ( !*eip ) { --#ifndef BDB_HIER -- rc = bdb_id2entry( op->o_bd, tid, id, &ep ); -- if ( rc == 0 ) { -- rc = bdb_cache_find_ndn( op, tid, -- &ep->e_nname, eip ); -- if ( *eip ) flag |= ID_LOCKED; -- if ( rc ) { -- ep->e_private = NULL; --#ifdef SLAP_ZONE_ALLOC -- bdb_entry_return( bdb, ep, (*eip)->bei_zseq ); --#else -- bdb_entry_return( ep ); --#endif -- ep = NULL; -- } -- } --#else -- rc = hdb_cache_find_parent(op, tid, id, eip ); -- if ( rc == 0 ) flag |= ID_LOCKED; --#endif -- } -- -- /* Ok, we found the info, do we have the entry? */ -- if ( rc == 0 ) { -- if ( !( flag & ID_LOCKED )) { -- bdb_cache_entryinfo_lock( *eip ); -- flag |= ID_LOCKED; -- } -- -- if ( (*eip)->bei_state & CACHE_ENTRY_DELETED ) { -- rc = DB_NOTFOUND; -- } else { -- (*eip)->bei_finders++; -- (*eip)->bei_state |= CACHE_ENTRY_REFERENCED; -- if ( flag & ID_NOENTRY ) { -- bdb_cache_entryinfo_unlock( *eip ); -- return 0; -- } -- /* Make sure only one thread tries to load the entry */ --load1: --#ifdef SLAP_ZONE_ALLOC -- if ((*eip)->bei_e && !slap_zn_validate( -- bdb->bi_cache.c_zctx, (*eip)->bei_e, (*eip)->bei_zseq)) { -- (*eip)->bei_e = NULL; -- (*eip)->bei_zseq = 0; -- } --#endif -- if ( !(*eip)->bei_e && !((*eip)->bei_state & CACHE_ENTRY_LOADING)) { -- load = 1; -- (*eip)->bei_state |= CACHE_ENTRY_LOADING; -- flag |= ID_CHKPURGE; -- } -- -- if ( !load ) { -- /* Clear the uncached state if we are not -- * loading it, i.e it is already cached or -- * another thread is currently loading it. -- */ -- if ( (*eip)->bei_state & CACHE_ENTRY_NOT_CACHED ) { -- (*eip)->bei_state ^= CACHE_ENTRY_NOT_CACHED; -- flag |= ID_CHKPURGE; -- } -- } -- -- if ( flag & ID_LOCKED ) { -- bdb_cache_entryinfo_unlock( *eip ); -- flag ^= ID_LOCKED; -- } -- rc = bdb_cache_entry_db_lock( bdb, tid, *eip, load, 0, lock ); -- if ( (*eip)->bei_state & CACHE_ENTRY_DELETED ) { -- rc = DB_NOTFOUND; -- bdb_cache_entry_db_unlock( bdb, lock ); -- bdb_cache_entryinfo_lock( *eip ); -- (*eip)->bei_finders--; -- bdb_cache_entryinfo_unlock( *eip ); -- } else if ( rc == 0 ) { -- if ( load ) { -- if ( !ep) { -- rc = bdb_id2entry( op->o_bd, tid, id, &ep ); -- } -- if ( rc == 0 ) { -- ep->e_private = *eip; --#ifdef BDB_HIER -- while ( (*eip)->bei_state & CACHE_ENTRY_NOT_LINKED ) -- ldap_pvt_thread_yield(); -- bdb_fix_dn( ep, 0 ); --#endif -- bdb_cache_entryinfo_lock( *eip ); -- -- (*eip)->bei_e = ep; --#ifdef SLAP_ZONE_ALLOC -- (*eip)->bei_zseq = *((ber_len_t *)ep - 2); --#endif -- ep = NULL; -- if ( flag & ID_NOCACHE ) { -- /* Set the cached state only if no other thread -- * found the info while we were loading the entry. -- */ -- if ( (*eip)->bei_finders == 1 ) { -- (*eip)->bei_state |= CACHE_ENTRY_NOT_CACHED; -- flag ^= ID_CHKPURGE; -- } -- } -- bdb_cache_entryinfo_unlock( *eip ); -- bdb_cache_lru_link( bdb, *eip ); -- } -- if ( rc == 0 ) { -- /* If we succeeded, downgrade back to a readlock. */ -- rc = bdb_cache_entry_db_relock( bdb, tid, -- *eip, 0, 0, lock ); -- } else { -- /* Otherwise, release the lock. */ -- bdb_cache_entry_db_unlock( bdb, lock ); -- } -- } else if ( !(*eip)->bei_e ) { -- /* Some other thread is trying to load the entry, -- * wait for it to finish. -- */ -- bdb_cache_entry_db_unlock( bdb, lock ); -- bdb_cache_entryinfo_lock( *eip ); -- flag |= ID_LOCKED; -- goto load1; --#ifdef BDB_HIER -- } else { -- /* Check for subtree renames -- */ -- rc = bdb_fix_dn( (*eip)->bei_e, 1 ); -- if ( rc ) { -- bdb_cache_entry_db_relock( bdb, -- tid, *eip, 1, 0, lock ); -- /* check again in case other modifier did it already */ -- if ( bdb_fix_dn( (*eip)->bei_e, 1 ) ) -- rc = bdb_fix_dn( (*eip)->bei_e, 2 ); -- bdb_cache_entry_db_relock( bdb, -- tid, *eip, 0, 0, lock ); -- } --#endif -- } -- bdb_cache_entryinfo_lock( *eip ); -- (*eip)->bei_finders--; -- if ( load ) -- (*eip)->bei_state ^= CACHE_ENTRY_LOADING; -- bdb_cache_entryinfo_unlock( *eip ); -- } -- } -- } -- if ( flag & ID_LOCKED ) { -- bdb_cache_entryinfo_unlock( *eip ); -- } -- if ( ep ) { -- ep->e_private = NULL; --#ifdef SLAP_ZONE_ALLOC -- bdb_entry_return( bdb, ep, (*eip)->bei_zseq ); --#else -- bdb_entry_return( ep ); --#endif -- } -- if ( rc == 0 ) { -- int purge = 0; -- -- if (( flag & ID_CHKPURGE ) || bdb->bi_cache.c_eimax ) { -- ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_count_mutex ); -- if ( flag & ID_CHKPURGE ) { -- bdb->bi_cache.c_cursize++; -- if ( !bdb->bi_cache.c_purging && bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize ) { -- purge = 1; -- bdb->bi_cache.c_purging = 1; -- } -- } else if ( !bdb->bi_cache.c_purging && bdb->bi_cache.c_eimax && bdb->bi_cache.c_leaves > bdb->bi_cache.c_eimax ) { -- purge = 1; -- bdb->bi_cache.c_purging = 1; -- } -- ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex ); -- } -- if ( purge ) -- bdb_cache_lru_purge( bdb ); -- } -- --#ifdef SLAP_ZONE_ALLOC -- if (rc == 0 && (*eip)->bei_e) { -- slap_zn_rlock(bdb->bi_cache.c_zctx, (*eip)->bei_e); -- } -- slap_zh_runlock(bdb->bi_cache.c_zctx); --#endif -- return rc; --} -- --int --bdb_cache_children( -- Operation *op, -- DB_TXN *txn, -- Entry *e ) --{ -- int rc; -- -- if ( BEI(e)->bei_kids ) { -- return 0; -- } -- if ( BEI(e)->bei_state & CACHE_ENTRY_NO_KIDS ) { -- return DB_NOTFOUND; -- } -- rc = bdb_dn2id_children( op, txn, e ); -- if ( rc == DB_NOTFOUND ) { -- BEI(e)->bei_state |= CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS; -- } -- return rc; --} -- --/* Update the cache after a successful database Add. */ --int --bdb_cache_add( -- struct bdb_info *bdb, -- EntryInfo *eip, -- Entry *e, -- struct berval *nrdn, -- DB_TXN *txn, -- DB_LOCK *lock ) --{ -- EntryInfo *new, ei; -- int rc, purge = 0; --#ifdef BDB_HIER -- struct berval rdn = e->e_name; --#endif -- -- ei.bei_id = e->e_id; -- ei.bei_parent = eip; -- ei.bei_nrdn = *nrdn; -- ei.bei_lockpad = 0; -- --#if 0 -- /* Lock this entry so that bdb_add can run to completion. -- * It can only fail if BDB has run out of lock resources. -- */ -- rc = bdb_cache_entry_db_lock( bdb, txn, &ei, 0, 0, lock ); -- if ( rc ) { -- bdb_cache_entryinfo_unlock( eip ); -- return rc; -- } --#endif -- --#ifdef BDB_HIER -- if ( nrdn->bv_len != e->e_nname.bv_len ) { -- char *ptr = ber_bvchr( &rdn, ',' ); -- assert( ptr != NULL ); -- rdn.bv_len = ptr - rdn.bv_val; -- } -- ber_dupbv( &ei.bei_rdn, &rdn ); -- if ( eip->bei_dkids ) eip->bei_dkids++; --#endif -- -- if (eip->bei_parent) { -- bdb_cache_entryinfo_lock( eip->bei_parent ); -- eip->bei_parent->bei_state &= ~CACHE_ENTRY_NO_GRANDKIDS; -- bdb_cache_entryinfo_unlock( eip->bei_parent ); -- } -- -- rc = bdb_entryinfo_add_internal( bdb, &ei, &new ); -- /* bdb_csn_commit can cause this when adding the database root entry */ -- if ( new->bei_e ) { -- new->bei_e->e_private = NULL; --#ifdef SLAP_ZONE_ALLOC -- bdb_entry_return( bdb, new->bei_e, new->bei_zseq ); --#else -- bdb_entry_return( new->bei_e ); --#endif -- } -- new->bei_e = e; -- e->e_private = new; -- new->bei_state |= CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS; -- eip->bei_state &= ~CACHE_ENTRY_NO_KIDS; -- bdb_cache_entryinfo_unlock( eip ); -- -- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock ); -- ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_count_mutex ); -- ++bdb->bi_cache.c_cursize; -- if ( bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize && -- !bdb->bi_cache.c_purging ) { -- purge = 1; -- bdb->bi_cache.c_purging = 1; -- } -- ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex ); -- -- new->bei_finders = 1; -- bdb_cache_lru_link( bdb, new ); -- -- if ( purge ) -- bdb_cache_lru_purge( bdb ); -- -- return rc; --} -- --void bdb_cache_deref( -- EntryInfo *ei -- ) --{ -- bdb_cache_entryinfo_lock( ei ); -- ei->bei_finders--; -- bdb_cache_entryinfo_unlock( ei ); --} -- --int --bdb_cache_modify( -- struct bdb_info *bdb, -- Entry *e, -- Attribute *newAttrs, -- DB_TXN *txn, -- DB_LOCK *lock ) --{ -- EntryInfo *ei = BEI(e); -- int rc; -- /* Get write lock on data */ -- rc = bdb_cache_entry_db_relock( bdb, txn, ei, 1, 0, lock ); -- -- /* If we've done repeated mods on a cached entry, then e_attrs -- * is no longer contiguous with the entry, and must be freed. -- */ -- if ( ! rc ) { -- if ( (void *)e->e_attrs != (void *)(e+1) ) { -- attrs_free( e->e_attrs ); -- } -- e->e_attrs = newAttrs; -- } -- return rc; --} -- --/* -- * Change the rdn in the entryinfo. Also move to a new parent if needed. -- */ --int --bdb_cache_modrdn( -- struct bdb_info *bdb, -- Entry *e, -- struct berval *nrdn, -- Entry *new, -- EntryInfo *ein, -- DB_TXN *txn, -- DB_LOCK *lock ) --{ -- EntryInfo *ei = BEI(e), *pei; -- int rc; --#ifdef BDB_HIER -- struct berval rdn; --#endif -- -- /* Get write lock on data */ -- rc = bdb_cache_entry_db_relock( bdb, txn, ei, 1, 0, lock ); -- if ( rc ) return rc; -- -- /* If we've done repeated mods on a cached entry, then e_attrs -- * is no longer contiguous with the entry, and must be freed. -- */ -- if ( (void *)e->e_attrs != (void *)(e+1) ) { -- attrs_free( e->e_attrs ); -- } -- e->e_attrs = new->e_attrs; -- if( e->e_nname.bv_val < e->e_bv.bv_val || -- e->e_nname.bv_val > e->e_bv.bv_val + e->e_bv.bv_len ) -- { -- ch_free(e->e_name.bv_val); -- ch_free(e->e_nname.bv_val); -- } -- e->e_name = new->e_name; -- e->e_nname = new->e_nname; -- -- /* Lock the parent's kids AVL tree */ -- pei = ei->bei_parent; -- bdb_cache_entryinfo_lock( pei ); -- avl_delete( &pei->bei_kids, (caddr_t) ei, bdb_rdn_cmp ); -- free( ei->bei_nrdn.bv_val ); -- ber_dupbv( &ei->bei_nrdn, nrdn ); -- --#ifdef BDB_HIER -- free( ei->bei_rdn.bv_val ); -- -- rdn = e->e_name; -- if ( nrdn->bv_len != e->e_nname.bv_len ) { -- char *ptr = ber_bvchr(&rdn, ','); -- assert( ptr != NULL ); -- rdn.bv_len = ptr - rdn.bv_val; -- } -- ber_dupbv( &ei->bei_rdn, &rdn ); -- -- /* If new parent, decrement kid counts */ -- if ( ein ) { -- pei->bei_ckids--; -- if ( pei->bei_dkids ) { -- pei->bei_dkids--; -- if ( pei->bei_dkids < 2 ) -- pei->bei_state |= CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS; -- } -- } --#endif -- -- if (!ein) { -- ein = ei->bei_parent; -- } else { -- ei->bei_parent = ein; -- bdb_cache_entryinfo_unlock( pei ); -- bdb_cache_entryinfo_lock( ein ); -- -- /* new parent now has kids */ -- if ( ein->bei_state & CACHE_ENTRY_NO_KIDS ) -- ein->bei_state ^= CACHE_ENTRY_NO_KIDS; -- /* grandparent has grandkids */ -- if ( ein->bei_parent ) -- ein->bei_parent->bei_state &= ~CACHE_ENTRY_NO_GRANDKIDS; --#ifdef BDB_HIER -- /* parent might now have grandkids */ -- if ( ein->bei_state & CACHE_ENTRY_NO_GRANDKIDS && -- !(ei->bei_state & CACHE_ENTRY_NO_KIDS)) -- ein->bei_state ^= CACHE_ENTRY_NO_GRANDKIDS; -- -- ein->bei_ckids++; -- if ( ein->bei_dkids ) ein->bei_dkids++; --#endif -- } -- --#ifdef BDB_HIER -- /* Record the generation number of this change */ -- ldap_pvt_thread_mutex_lock( &bdb->bi_modrdns_mutex ); -- bdb->bi_modrdns++; -- ei->bei_modrdns = bdb->bi_modrdns; -- ldap_pvt_thread_mutex_unlock( &bdb->bi_modrdns_mutex ); --#endif -- -- avl_insert( &ein->bei_kids, ei, bdb_rdn_cmp, avl_dup_error ); -- bdb_cache_entryinfo_unlock( ein ); -- return rc; --} --/* -- * cache_delete - delete the entry e from the cache. -- * -- * returns: 0 e was deleted ok -- * 1 e was not in the cache -- * -1 something bad happened -- */ --int --bdb_cache_delete( -- struct bdb_info *bdb, -- Entry *e, -- DB_TXN *txn, -- DB_LOCK *lock ) --{ -- EntryInfo *ei = BEI(e); -- int rc, busy = 0, counter = 0; -- -- assert( e->e_private != NULL ); -- -- /* Lock the entry's info */ -- bdb_cache_entryinfo_lock( ei ); -- -- /* Set this early, warn off any queriers */ -- ei->bei_state |= CACHE_ENTRY_DELETED; -- -- if (( ei->bei_state & ( CACHE_ENTRY_NOT_LINKED | -- CACHE_ENTRY_LOADING | CACHE_ENTRY_ONELEVEL )) || -- ei->bei_finders > 0 ) -- busy = 1; -- -- bdb_cache_entryinfo_unlock( ei ); -- -- while ( busy && counter < 1000) { -- ldap_pvt_thread_yield(); -- busy = 0; -- bdb_cache_entryinfo_lock( ei ); -- if (( ei->bei_state & ( CACHE_ENTRY_NOT_LINKED | -- CACHE_ENTRY_LOADING | CACHE_ENTRY_ONELEVEL )) || -- ei->bei_finders > 0 ) -- busy = 1; -- bdb_cache_entryinfo_unlock( ei ); -- counter ++; -- } -- if( busy ) { -- bdb_cache_entryinfo_lock( ei ); -- ei->bei_state ^= CACHE_ENTRY_DELETED; -- bdb_cache_entryinfo_unlock( ei ); -- return DB_LOCK_DEADLOCK; -- } -- -- /* Get write lock on the data */ -- rc = bdb_cache_entry_db_relock( bdb, txn, ei, 1, 0, lock ); -- if ( rc ) { -- bdb_cache_entryinfo_lock( ei ); -- /* couldn't lock, undo and give up */ -- ei->bei_state ^= CACHE_ENTRY_DELETED; -- bdb_cache_entryinfo_unlock( ei ); -- return rc; -- } -- -- Debug( LDAP_DEBUG_TRACE, "====> bdb_cache_delete( %ld )\n", -- e->e_id, 0, 0 ); -- -- /* set lru mutex */ -- ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_lru_mutex ); -- -- bdb_cache_entryinfo_lock( ei->bei_parent ); -- bdb_cache_entryinfo_lock( ei ); -- rc = bdb_cache_delete_internal( &bdb->bi_cache, e->e_private, 1 ); -- bdb_cache_entryinfo_unlock( ei ); -- -- /* free lru mutex */ -- ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_lru_mutex ); -- -- return( rc ); --} -- --void --bdb_cache_delete_cleanup( -- Cache *cache, -- EntryInfo *ei ) --{ -- /* Enter with ei locked */ -- -- /* already freed? */ -- if ( !ei->bei_parent ) return; -- -- if ( ei->bei_e ) { -- ei->bei_e->e_private = NULL; --#ifdef SLAP_ZONE_ALLOC -- bdb_entry_return( ei->bei_bdb, ei->bei_e, ei->bei_zseq ); --#else -- bdb_entry_return( ei->bei_e ); --#endif -- ei->bei_e = NULL; -- } -- -- bdb_cache_entryinfo_unlock( ei ); -- bdb_cache_entryinfo_free( cache, ei ); --} -- --static int --bdb_cache_delete_internal( -- Cache *cache, -- EntryInfo *e, -- int decr ) --{ -- int rc = 0; /* return code */ -- int decr_leaf = 0; -- -- /* already freed? */ -- if ( !e->bei_parent ) { -- assert(0); -- return -1; -- } -- --#ifdef BDB_HIER -- e->bei_parent->bei_ckids--; -- if ( decr && e->bei_parent->bei_dkids ) e->bei_parent->bei_dkids--; --#endif -- /* dn tree */ -- if ( avl_delete( &e->bei_parent->bei_kids, (caddr_t) e, bdb_rdn_cmp ) -- == NULL ) -- { -- rc = -1; -- assert(0); -- } -- if ( e->bei_parent->bei_kids ) -- decr_leaf = 1; -- -- ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock ); -- /* id tree */ -- if ( avl_delete( &cache->c_idtree, (caddr_t) e, bdb_id_cmp )) { -- cache->c_eiused--; -- if ( decr_leaf ) -- cache->c_leaves--; -- } else { -- rc = -1; -- assert(0); -- } -- ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock ); -- bdb_cache_entryinfo_unlock( e->bei_parent ); -- -- if ( rc == 0 ){ -- /* lru */ -- LRU_DEL( cache, e ); -- -- if ( e->bei_e ) { -- ldap_pvt_thread_mutex_lock( &cache->c_count_mutex ); -- cache->c_cursize--; -- ldap_pvt_thread_mutex_unlock( &cache->c_count_mutex ); -- } -- } -- -- return( rc ); --} -- --static void --bdb_entryinfo_release( void *data ) --{ -- EntryInfo *ei = (EntryInfo *)data; -- if ( ei->bei_kids ) { -- avl_free( ei->bei_kids, NULL ); -- } -- if ( ei->bei_e ) { -- ei->bei_e->e_private = NULL; --#ifdef SLAP_ZONE_ALLOC -- bdb_entry_return( ei->bei_bdb, ei->bei_e, ei->bei_zseq ); --#else -- bdb_entry_return( ei->bei_e ); --#endif -- } -- bdb_cache_entryinfo_destroy( ei ); --} -- --void --bdb_cache_release_all( Cache *cache ) --{ -- /* set cache write lock */ -- ldap_pvt_thread_rdwr_wlock( &cache->c_rwlock ); -- /* set lru mutex */ -- ldap_pvt_thread_mutex_lock( &cache->c_lru_mutex ); -- -- Debug( LDAP_DEBUG_TRACE, "====> bdb_cache_release_all\n", 0, 0, 0 ); -- -- avl_free( cache->c_dntree.bei_kids, NULL ); -- avl_free( cache->c_idtree, bdb_entryinfo_release ); -- for (;cache->c_eifree;cache->c_eifree = cache->c_lruhead) { -- cache->c_lruhead = cache->c_eifree->bei_lrunext; -- bdb_cache_entryinfo_destroy(cache->c_eifree); -- } -- cache->c_cursize = 0; -- cache->c_eiused = 0; -- cache->c_leaves = 0; -- cache->c_idtree = NULL; -- cache->c_lruhead = NULL; -- cache->c_lrutail = NULL; -- cache->c_dntree.bei_kids = NULL; -- -- /* free lru mutex */ -- ldap_pvt_thread_mutex_unlock( &cache->c_lru_mutex ); -- /* free cache write lock */ -- ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock ); --} -- --#ifdef LDAP_DEBUG --static void --bdb_lru_count( Cache *cache ) --{ -- EntryInfo *e; -- int ei = 0, ent = 0, nc = 0; -- -- for ( e = cache->c_lrutail; ; ) { -- ei++; -- if ( e->bei_e ) { -- ent++; -- if ( e->bei_state & CACHE_ENTRY_NOT_CACHED ) -- nc++; -- fprintf( stderr, "ei %d entry %p dn %s\n", ei, (void *) e->bei_e, e->bei_e->e_name.bv_val ); -- } -- e = e->bei_lrunext; -- if ( e == cache->c_lrutail ) -- break; -- } -- fprintf( stderr, "counted %d entryInfos and %d entries, %d notcached\n", -- ei, ent, nc ); -- ei = 0; -- for ( e = cache->c_lrutail; ; ) { -- ei++; -- e = e->bei_lruprev; -- if ( e == cache->c_lrutail ) -- break; -- } -- fprintf( stderr, "counted %d entryInfos (on lruprev)\n", ei ); --} -- --#ifdef SLAPD_UNUSED --static void --bdb_lru_print( Cache *cache ) --{ -- EntryInfo *e; -- -- fprintf( stderr, "LRU circle head: %p\n", (void *) cache->c_lruhead ); -- fprintf( stderr, "LRU circle (tail forward):\n" ); -- for ( e = cache->c_lrutail; ; ) { -- fprintf( stderr, "\t%p, %p id %ld rdn \"%s\"\n", -- (void *) e, (void *) e->bei_e, e->bei_id, e->bei_nrdn.bv_val ); -- e = e->bei_lrunext; -- if ( e == cache->c_lrutail ) -- break; -- } -- fprintf( stderr, "LRU circle (tail backward):\n" ); -- for ( e = cache->c_lrutail; ; ) { -- fprintf( stderr, "\t%p, %p id %ld rdn \"%s\"\n", -- (void *) e, (void *) e->bei_e, e->bei_id, e->bei_nrdn.bv_val ); -- e = e->bei_lruprev; -- if ( e == cache->c_lrutail ) -- break; -- } --} -- --static int --bdb_entryinfo_print(void *data, void *arg) --{ -- EntryInfo *e = data; -- fprintf( stderr, "\t%p, %p id %ld rdn \"%s\"\n", -- (void *) e, (void *) e->bei_e, e->bei_id, e->bei_nrdn.bv_val ); -- return 0; --} -- --static void --bdb_idtree_print(Cache *cache) --{ -- avl_apply( cache->c_idtree, bdb_entryinfo_print, NULL, -1, AVL_INORDER ); --} --#endif --#endif -- --static void --bdb_reader_free( void *key, void *data ) --{ -- /* DB_ENV *env = key; */ -- DB_TXN *txn = data; -- -- if ( txn ) TXN_ABORT( txn ); --} -- --/* free up any keys used by the main thread */ --void --bdb_reader_flush( DB_ENV *env ) --{ -- void *data; -- void *ctx = ldap_pvt_thread_pool_context(); -- -- if ( !ldap_pvt_thread_pool_getkey( ctx, env, &data, NULL ) ) { -- ldap_pvt_thread_pool_setkey( ctx, env, NULL, 0, NULL, NULL ); -- bdb_reader_free( env, data ); -- } --} -- --int --bdb_reader_get( Operation *op, DB_ENV *env, DB_TXN **txn ) --{ -- int i, rc; -- void *data; -- void *ctx; -- -- if ( !env || !txn ) return -1; -- -- /* If no op was provided, try to find the ctx anyway... */ -- if ( op ) { -- ctx = op->o_threadctx; -- } else { -- ctx = ldap_pvt_thread_pool_context(); -- } -- -- /* Shouldn't happen unless we're single-threaded */ -- if ( !ctx ) { -- *txn = NULL; -- return 0; -- } -- -- if ( ldap_pvt_thread_pool_getkey( ctx, env, &data, NULL ) ) { -- for ( i=0, rc=1; rc != 0 && i<4; i++ ) { -- rc = TXN_BEGIN( env, NULL, txn, DB_READ_COMMITTED ); -- if (rc) ldap_pvt_thread_yield(); -- } -- if ( rc != 0) { -- return rc; -- } -- data = *txn; -- if ( ( rc = ldap_pvt_thread_pool_setkey( ctx, env, -- data, bdb_reader_free, NULL, NULL ) ) ) { -- TXN_ABORT( *txn ); -- Debug( LDAP_DEBUG_ANY, "bdb_reader_get: err %s(%d)\n", -- db_strerror(rc), rc, 0 ); -- -- return rc; -- } -- } else { -- *txn = data; -- } -- return 0; --} -diff --git a/servers/slapd/back-bdb/compare.c b/servers/slapd/back-bdb/compare.c -deleted file mode 100644 -index 4d7d45f..0000000 ---- a/servers/slapd/back-bdb/compare.c -+++ /dev/null -@@ -1,143 +0,0 @@ --/* compare.c - bdb backend compare routine */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include --#include -- --#include "back-bdb.h" -- --int --bdb_compare( Operation *op, SlapReply *rs ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- Entry *e = NULL; -- EntryInfo *ei; -- int manageDSAit = get_manageDSAit( op ); -- -- DB_TXN *rtxn; -- DB_LOCK lock; -- -- rs->sr_err = bdb_reader_get(op, bdb->bi_dbenv, &rtxn); -- switch(rs->sr_err) { -- case 0: -- break; -- default: -- send_ldap_error( op, rs, LDAP_OTHER, "internal error" ); -- return rs->sr_err; -- } -- --dn2entry_retry: -- /* get entry */ -- rs->sr_err = bdb_dn2entry( op, rtxn, &op->o_req_ndn, &ei, 1, -- &lock ); -- -- switch( rs->sr_err ) { -- case DB_NOTFOUND: -- case 0: -- break; -- case LDAP_BUSY: -- rs->sr_text = "ldap server busy"; -- goto return_results; -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto dn2entry_retry; -- default: -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- -- e = ei->bei_e; -- if ( rs->sr_err == DB_NOTFOUND ) { -- if ( e != NULL ) { -- /* return referral only if "disclose" is granted on the object */ -- if ( ! access_allowed( op, e, slap_schema.si_ad_entry, -- NULL, ACL_DISCLOSE, NULL ) ) -- { -- rs->sr_err = LDAP_NO_SUCH_OBJECT; -- -- } else { -- rs->sr_matched = ch_strdup( e->e_dn ); -- rs->sr_ref = is_entry_referral( e ) -- ? get_entry_referrals( op, e ) -- : NULL; -- rs->sr_err = LDAP_REFERRAL; -- } -- -- bdb_cache_return_entry_r( bdb, e, &lock ); -- e = NULL; -- -- } else { -- rs->sr_ref = referral_rewrite( default_referral, -- NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); -- rs->sr_err = rs->sr_ref ? LDAP_REFERRAL : LDAP_NO_SUCH_OBJECT; -- } -- -- send_ldap_result( op, rs ); -- -- ber_bvarray_free( rs->sr_ref ); -- free( (char *)rs->sr_matched ); -- rs->sr_ref = NULL; -- rs->sr_matched = NULL; -- -- goto done; -- } -- -- if (!manageDSAit && is_entry_referral( e ) ) { -- /* return referral only if "disclose" is granted on the object */ -- if ( !access_allowed( op, e, slap_schema.si_ad_entry, -- NULL, ACL_DISCLOSE, NULL ) ) -- { -- rs->sr_err = LDAP_NO_SUCH_OBJECT; -- } else { -- /* entry is a referral, don't allow compare */ -- rs->sr_ref = get_entry_referrals( op, e ); -- rs->sr_err = LDAP_REFERRAL; -- rs->sr_matched = e->e_name.bv_val; -- } -- -- Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0, 0, 0 ); -- -- send_ldap_result( op, rs ); -- -- ber_bvarray_free( rs->sr_ref ); -- rs->sr_ref = NULL; -- rs->sr_matched = NULL; -- goto done; -- } -- -- rs->sr_err = slap_compare_entry( op, e, op->orc_ava ); -- --return_results: -- send_ldap_result( op, rs ); -- -- switch ( rs->sr_err ) { -- case LDAP_COMPARE_FALSE: -- case LDAP_COMPARE_TRUE: -- rs->sr_err = LDAP_SUCCESS; -- break; -- } -- --done: -- /* free entry */ -- if ( e != NULL ) { -- bdb_cache_return_entry_r( bdb, e, &lock ); -- } -- -- return rs->sr_err; --} -diff --git a/servers/slapd/back-bdb/config.c b/servers/slapd/back-bdb/config.c -deleted file mode 100644 -index c3c8315..0000000 ---- a/servers/slapd/back-bdb/config.c -+++ /dev/null -@@ -1,951 +0,0 @@ --/* config.c - bdb backend configuration file routine */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include --#include --#include --#include -- --#include "back-bdb.h" -- --#include "config.h" -- --#include "lutil.h" --#include "ldap_rq.h" -- --#ifdef DB_DIRTY_READ --# define SLAP_BDB_ALLOW_DIRTY_READ --#endif -- --#define bdb_cf_gen BDB_SYMBOL(cf_gen) --#define bdb_cf_cleanup BDB_SYMBOL(cf_cleanup) --#define bdb_checkpoint BDB_SYMBOL(checkpoint) --#define bdb_online_index BDB_SYMBOL(online_index) -- --static ConfigDriver bdb_cf_gen; -- --enum { -- BDB_CHKPT = 1, -- BDB_CONFIG, -- BDB_CRYPTFILE, -- BDB_CRYPTKEY, -- BDB_DIRECTORY, -- BDB_NOSYNC, -- BDB_DIRTYR, -- BDB_INDEX, -- BDB_LOCKD, -- BDB_SSTACK, -- BDB_MODE, -- BDB_PGSIZE, -- BDB_CHECKSUM --}; -- --static ConfigTable bdbcfg[] = { -- { "directory", "dir", 2, 2, 0, ARG_STRING|ARG_MAGIC|BDB_DIRECTORY, -- bdb_cf_gen, "( OLcfgDbAt:0.1 NAME 'olcDbDirectory' " -- "DESC 'Directory for database content' " -- "EQUALITY caseIgnoreMatch " -- "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, -- { "cachefree", "size", 2, 2, 0, ARG_ULONG|ARG_OFFSET, -- (void *)offsetof(struct bdb_info, bi_cache.c_minfree), -- "( OLcfgDbAt:1.11 NAME 'olcDbCacheFree' " -- "DESC 'Number of extra entries to free when max is reached' " -- "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, -- { "cachesize", "size", 2, 2, 0, ARG_ULONG|ARG_OFFSET, -- (void *)offsetof(struct bdb_info, bi_cache.c_maxsize), -- "( OLcfgDbAt:1.1 NAME 'olcDbCacheSize' " -- "DESC 'Entry cache size in entries' " -- "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, -- { "checkpoint", "kbyte> <[pres,eq,approx,sub]", 2, 3, 0, ARG_MAGIC|BDB_INDEX, -- bdb_cf_gen, "( OLcfgDbAt:0.2 NAME 'olcDbIndex' " -- "DESC 'Attribute index parameters' " -- "EQUALITY caseIgnoreMatch " -- "SYNTAX OMsDirectoryString )", NULL, NULL }, -- { "linearindex", NULL, 1, 2, 0, ARG_ON_OFF|ARG_OFFSET, -- (void *)offsetof(struct bdb_info, bi_linear_index), -- "( OLcfgDbAt:1.7 NAME 'olcDbLinearIndex' " -- "DESC 'Index attributes one at a time' " -- "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL }, -- { "lockdetect", "policy", 2, 2, 0, ARG_MAGIC|BDB_LOCKD, -- bdb_cf_gen, "( OLcfgDbAt:1.8 NAME 'olcDbLockDetect' " -- "DESC 'Deadlock detection algorithm' " -- "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, -- { "mode", "mode", 2, 2, 0, ARG_MAGIC|BDB_MODE, -- bdb_cf_gen, "( OLcfgDbAt:0.3 NAME 'olcDbMode' " -- "DESC 'Unix permissions of database files' " -- "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, -- { "searchstack", "depth", 2, 2, 0, ARG_INT|ARG_MAGIC|BDB_SSTACK, -- bdb_cf_gen, "( OLcfgDbAt:1.9 NAME 'olcDbSearchStack' " -- "DESC 'Depth of search stack in IDLs' " -- "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, -- { "shm_key", "key", 2, 2, 0, ARG_LONG|ARG_OFFSET, -- (void *)offsetof(struct bdb_info, bi_shm_key), -- "( OLcfgDbAt:1.10 NAME 'olcDbShmKey' " -- "DESC 'Key for shared memory region' " -- "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, -- { NULL, NULL, 0, 0, 0, ARG_IGNORED, -- NULL, NULL, NULL, NULL } --}; -- --static ConfigOCs bdbocs[] = { -- { --#ifdef BDB_HIER -- "( OLcfgDbOc:1.2 " -- "NAME 'olcHdbConfig' " -- "DESC 'HDB backend configuration' " --#else -- "( OLcfgDbOc:1.1 " -- "NAME 'olcBdbConfig' " -- "DESC 'BDB backend configuration' " --#endif -- "SUP olcDatabaseConfig " -- "MUST olcDbDirectory " -- "MAY ( olcDbCacheSize $ olcDbCheckpoint $ olcDbChecksum $ " -- "olcDbConfig $ olcDbCryptFile $ olcDbCryptKey $ " -- "olcDbNoSync $ olcDbDirtyRead $ olcDbIDLcacheSize $ " -- "olcDbIndex $ olcDbLinearIndex $ olcDbLockDetect $ " -- "olcDbMode $ olcDbSearchStack $ olcDbShmKey $ " -- "olcDbCacheFree $ olcDbDNcacheSize $ olcDbPageSize ) )", -- Cft_Database, bdbcfg }, -- { NULL, 0, NULL } --}; -- --static slap_verbmasks bdb_lockd[] = { -- { BER_BVC("default"), DB_LOCK_DEFAULT }, -- { BER_BVC("oldest"), DB_LOCK_OLDEST }, -- { BER_BVC("random"), DB_LOCK_RANDOM }, -- { BER_BVC("youngest"), DB_LOCK_YOUNGEST }, -- { BER_BVC("fewest"), DB_LOCK_MINLOCKS }, -- { BER_BVNULL, 0 } --}; -- --/* perform periodic checkpoints */ --static void * --bdb_checkpoint( void *ctx, void *arg ) --{ -- struct re_s *rtask = arg; -- struct bdb_info *bdb = rtask->arg; -- -- TXN_CHECKPOINT( bdb->bi_dbenv, bdb->bi_txn_cp_kbyte, -- bdb->bi_txn_cp_min, 0 ); -- ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); -- ldap_pvt_runqueue_stoptask( &slapd_rq, rtask ); -- ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); -- return NULL; --} -- --/* reindex entries on the fly */ --static void * --bdb_online_index( void *ctx, void *arg ) --{ -- struct re_s *rtask = arg; -- BackendDB *be = rtask->arg; -- struct bdb_info *bdb = be->be_private; -- -- Connection conn = {0}; -- OperationBuffer opbuf; -- Operation *op; -- -- DBC *curs; -- DBT key, data; -- DB_TXN *txn; -- DB_LOCK lock; -- ID id, nid; -- EntryInfo *ei; -- int rc, getnext = 1; -- int i; -- -- connection_fake_init( &conn, &opbuf, ctx ); -- op = &opbuf.ob_op; -- -- op->o_bd = be; -- -- DBTzero( &key ); -- DBTzero( &data ); -- -- id = 1; -- key.data = &nid; -- key.size = key.ulen = sizeof(ID); -- key.flags = DB_DBT_USERMEM; -- -- data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; -- data.dlen = data.ulen = 0; -- -- while ( 1 ) { -- if ( slapd_shutdown ) -- break; -- -- rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &txn, bdb->bi_db_opflags ); -- if ( rc ) -- break; -- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_online_index) ": txn id: %x\n", -- txn->id(txn), 0, 0 ); -- if ( getnext ) { -- getnext = 0; -- BDB_ID2DISK( id, &nid ); -- rc = bdb->bi_id2entry->bdi_db->cursor( -- bdb->bi_id2entry->bdi_db, txn, &curs, bdb->bi_db_opflags ); -- if ( rc ) { -- TXN_ABORT( txn ); -- break; -- } -- rc = curs->c_get( curs, &key, &data, DB_SET_RANGE ); -- curs->c_close( curs ); -- if ( rc ) { -- TXN_ABORT( txn ); -- if ( rc == DB_NOTFOUND ) -- rc = 0; -- if ( rc == DB_LOCK_DEADLOCK ) { -- ldap_pvt_thread_yield(); -- continue; -- } -- break; -- } -- BDB_DISK2ID( &nid, &id ); -- } -- -- ei = NULL; -- rc = bdb_cache_find_id( op, txn, id, &ei, 0, &lock ); -- if ( rc ) { -- TXN_ABORT( txn ); -- if ( rc == DB_LOCK_DEADLOCK ) { -- ldap_pvt_thread_yield(); -- continue; -- } -- if ( rc == DB_NOTFOUND ) { -- id++; -- getnext = 1; -- continue; -- } -- break; -- } -- if ( ei->bei_e ) { -- rc = bdb_index_entry( op, txn, BDB_INDEX_UPDATE_OP, ei->bei_e ); -- if ( rc ) { -- TXN_ABORT( txn ); -- if ( rc == DB_LOCK_DEADLOCK ) { -- ldap_pvt_thread_yield(); -- continue; -- } -- break; -- } -- rc = TXN_COMMIT( txn, 0 ); -- txn = NULL; -- } -- id++; -- getnext = 1; -- } -- -- for ( i = 0; i < bdb->bi_nattrs; i++ ) { -- if ( bdb->bi_attrs[ i ]->ai_indexmask & BDB_INDEX_DELETING -- || bdb->bi_attrs[ i ]->ai_newmask == 0 ) -- { -- continue; -- } -- bdb->bi_attrs[ i ]->ai_indexmask = bdb->bi_attrs[ i ]->ai_newmask; -- bdb->bi_attrs[ i ]->ai_newmask = 0; -- } -- -- ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); -- ldap_pvt_runqueue_stoptask( &slapd_rq, rtask ); -- bdb->bi_index_task = NULL; -- ldap_pvt_runqueue_remove( &slapd_rq, rtask ); -- ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); -- -- return NULL; --} -- --/* Cleanup loose ends after Modify completes */ --static int --bdb_cf_cleanup( ConfigArgs *c ) --{ -- struct bdb_info *bdb = c->be->be_private; -- int rc = 0; -- BerVarray bva; -- -- if ( bdb->bi_flags & BDB_DEL_INDEX ) { -- bdb_attr_flush( bdb ); -- bdb->bi_flags ^= BDB_DEL_INDEX; -- } -- -- if ( bdb->bi_flags & BDB_RE_OPEN ) { -- bdb->bi_flags ^= BDB_RE_OPEN; -- bva = bdb->bi_db_config; -- bdb->bi_db_config = NULL; -- rc = c->be->bd_info->bi_db_close( c->be, &c->reply ); -- if ( rc == 0 ) { -- if ( bdb->bi_flags & BDB_UPD_CONFIG ) { -- if ( bva ) { -- int i; -- FILE *f = fopen( bdb->bi_db_config_path, "w" ); -- if ( f ) { -- bdb->bi_db_config = bva; -- bva = NULL; -- for (i=0; bdb->bi_db_config[i].bv_val; i++) -- fprintf( f, "%s\n", bdb->bi_db_config[i].bv_val ); -- fclose( f ); -- } else { -- ber_bvarray_free( bva ); -- } -- } else { -- unlink( bdb->bi_db_config_path ); -- } -- bdb->bi_flags ^= BDB_UPD_CONFIG; -- } -- rc = c->be->bd_info->bi_db_open( c->be, &c->reply ); -- } -- /* If this fails, we need to restart */ -- if ( rc ) { -- slapd_shutdown = 2; -- snprintf( c->cr_msg, sizeof( c->cr_msg ), -- "failed to reopen database, rc=%d", rc ); -- Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_cf_cleanup) -- ": %s\n", c->cr_msg, 0, 0 ); -- rc = LDAP_OTHER; -- } -- } -- return rc; --} -- --static int --bdb_cf_gen( ConfigArgs *c ) --{ -- struct bdb_info *bdb = c->be->be_private; -- int rc; -- -- if ( c->op == SLAP_CONFIG_EMIT ) { -- rc = 0; -- switch( c->type ) { -- case BDB_MODE: { -- char buf[64]; -- struct berval bv; -- bv.bv_len = snprintf( buf, sizeof(buf), "0%o", bdb->bi_dbenv_mode ); -- if ( bv.bv_len > 0 && bv.bv_len < sizeof(buf) ) { -- bv.bv_val = buf; -- value_add_one( &c->rvalue_vals, &bv ); -- } else { -- rc = 1; -- } -- } break; -- -- case BDB_CHKPT: -- if ( bdb->bi_txn_cp ) { -- char buf[64]; -- struct berval bv; -- bv.bv_len = snprintf( buf, sizeof(buf), "%ld %ld", -- (long) bdb->bi_txn_cp_kbyte, (long) bdb->bi_txn_cp_min ); -- if ( bv.bv_len > 0 && bv.bv_len < sizeof(buf) ) { -- bv.bv_val = buf; -- value_add_one( &c->rvalue_vals, &bv ); -- } else { -- rc = 1; -- } -- } else { -- rc = 1; -- } -- break; -- -- case BDB_CRYPTFILE: -- if ( bdb->bi_db_crypt_file ) { -- c->value_string = ch_strdup( bdb->bi_db_crypt_file ); -- } else { -- rc = 1; -- } -- break; -- -- /* If a crypt file has been set, its contents are copied here. -- * But we don't want the key to be incorporated here. -- */ -- case BDB_CRYPTKEY: -- if ( !bdb->bi_db_crypt_file && !BER_BVISNULL( &bdb->bi_db_crypt_key )) { -- value_add_one( &c->rvalue_vals, &bdb->bi_db_crypt_key ); -- } else { -- rc = 1; -- } -- break; -- -- case BDB_DIRECTORY: -- if ( bdb->bi_dbenv_home ) { -- c->value_string = ch_strdup( bdb->bi_dbenv_home ); -- } else { -- rc = 1; -- } -- break; -- -- case BDB_CONFIG: -- if ( !( bdb->bi_flags & BDB_IS_OPEN ) -- && !bdb->bi_db_config ) -- { -- char buf[SLAP_TEXT_BUFLEN]; -- FILE *f = fopen( bdb->bi_db_config_path, "r" ); -- struct berval bv; -- -- if ( f ) { -- bdb->bi_flags |= BDB_HAS_CONFIG; -- while ( fgets( buf, sizeof(buf), f )) { -- ber_str2bv( buf, 0, 1, &bv ); -- if ( bv.bv_len > 0 && bv.bv_val[bv.bv_len-1] == '\n' ) { -- bv.bv_len--; -- bv.bv_val[bv.bv_len] = '\0'; -- } -- /* shouldn't need this, but ... */ -- if ( bv.bv_len > 0 && bv.bv_val[bv.bv_len-1] == '\r' ) { -- bv.bv_len--; -- bv.bv_val[bv.bv_len] = '\0'; -- } -- ber_bvarray_add( &bdb->bi_db_config, &bv ); -- } -- fclose( f ); -- } -- } -- if ( bdb->bi_db_config ) { -- int i; -- struct berval bv; -- -- bv.bv_val = c->log; -- for (i=0; !BER_BVISNULL(&bdb->bi_db_config[i]); i++) { -- bv.bv_len = sprintf( bv.bv_val, "{%d}%s", i, -- bdb->bi_db_config[i].bv_val ); -- value_add_one( &c->rvalue_vals, &bv ); -- } -- } -- if ( !c->rvalue_vals ) rc = 1; -- break; -- -- case BDB_NOSYNC: -- if ( bdb->bi_dbenv_xflags & DB_TXN_NOSYNC ) -- c->value_int = 1; -- break; -- -- case BDB_CHECKSUM: -- if ( bdb->bi_flags & BDB_CHKSUM ) -- c->value_int = 1; -- break; -- -- case BDB_INDEX: -- bdb_attr_index_unparse( bdb, &c->rvalue_vals ); -- if ( !c->rvalue_vals ) rc = 1; -- break; -- -- case BDB_LOCKD: -- rc = 1; -- if ( bdb->bi_lock_detect != DB_LOCK_DEFAULT ) { -- int i; -- for (i=0; !BER_BVISNULL(&bdb_lockd[i].word); i++) { -- if ( bdb->bi_lock_detect == (u_int32_t)bdb_lockd[i].mask ) { -- value_add_one( &c->rvalue_vals, &bdb_lockd[i].word ); -- rc = 0; -- break; -- } -- } -- } -- break; -- -- case BDB_SSTACK: -- c->value_int = bdb->bi_search_stack_depth; -- break; -- -- case BDB_PGSIZE: { -- struct bdb_db_pgsize *ps; -- char buf[SLAP_TEXT_BUFLEN]; -- struct berval bv; -- int rc = 1; -- -- bv.bv_val = buf; -- for ( ps = bdb->bi_pagesizes; ps; ps = ps->bdp_next ) { -- bv.bv_len = sprintf( buf, "%s %d", ps->bdp_name.bv_val, -- ps->bdp_size / 1024 ); -- value_add_one( &c->rvalue_vals, &bv ); -- rc = 0; -- -- } -- break; -- } -- } -- return rc; -- } else if ( c->op == LDAP_MOD_DELETE ) { -- rc = 0; -- switch( c->type ) { -- case BDB_MODE: --#if 0 -- /* FIXME: does it make any sense to change the mode, -- * if we don't exec a chmod()? */ -- bdb->bi_dbenv_mode = SLAPD_DEFAULT_DB_MODE; -- break; --#endif -- -- /* single-valued no-ops */ -- case BDB_LOCKD: -- case BDB_SSTACK: -- break; -- -- case BDB_CHKPT: -- if ( bdb->bi_txn_cp_task ) { -- struct re_s *re = bdb->bi_txn_cp_task; -- bdb->bi_txn_cp_task = NULL; -- ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); -- if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ) ) -- ldap_pvt_runqueue_stoptask( &slapd_rq, re ); -- ldap_pvt_runqueue_remove( &slapd_rq, re ); -- ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); -- } -- bdb->bi_txn_cp = 0; -- break; -- case BDB_CONFIG: -- if ( c->valx < 0 ) { -- ber_bvarray_free( bdb->bi_db_config ); -- bdb->bi_db_config = NULL; -- } else { -- int i = c->valx; -- ch_free( bdb->bi_db_config[i].bv_val ); -- for (; bdb->bi_db_config[i].bv_val; i++) -- bdb->bi_db_config[i] = bdb->bi_db_config[i+1]; -- } -- bdb->bi_flags |= BDB_UPD_CONFIG|BDB_RE_OPEN; -- c->cleanup = bdb_cf_cleanup; -- break; -- /* Doesn't really make sense to change these on the fly; -- * the entire DB must be dumped and reloaded -- */ -- case BDB_CRYPTFILE: -- if ( bdb->bi_db_crypt_file ) { -- ch_free( bdb->bi_db_crypt_file ); -- bdb->bi_db_crypt_file = NULL; -- } -- /* FALLTHRU */ -- case BDB_CRYPTKEY: -- if ( !BER_BVISNULL( &bdb->bi_db_crypt_key )) { -- ch_free( bdb->bi_db_crypt_key.bv_val ); -- BER_BVZERO( &bdb->bi_db_crypt_key ); -- } -- break; -- case BDB_DIRECTORY: -- bdb->bi_flags |= BDB_RE_OPEN; -- bdb->bi_flags ^= BDB_HAS_CONFIG; -- ch_free( bdb->bi_dbenv_home ); -- bdb->bi_dbenv_home = NULL; -- ch_free( bdb->bi_db_config_path ); -- bdb->bi_db_config_path = NULL; -- c->cleanup = bdb_cf_cleanup; -- ldap_pvt_thread_pool_purgekey( bdb->bi_dbenv ); -- break; -- case BDB_NOSYNC: -- bdb->bi_dbenv->set_flags( bdb->bi_dbenv, DB_TXN_NOSYNC, 0 ); -- break; -- case BDB_CHECKSUM: -- bdb->bi_flags &= ~BDB_CHKSUM; -- break; -- case BDB_INDEX: -- if ( c->valx == -1 ) { -- int i; -- -- /* delete all */ -- for ( i = 0; i < bdb->bi_nattrs; i++ ) { -- bdb->bi_attrs[i]->ai_indexmask |= BDB_INDEX_DELETING; -- } -- bdb->bi_defaultmask = 0; -- bdb->bi_flags |= BDB_DEL_INDEX; -- c->cleanup = bdb_cf_cleanup; -- -- } else { -- struct berval bv, def = BER_BVC("default"); -- char *ptr; -- -- for (ptr = c->line; !isspace( (unsigned char) *ptr ); ptr++); -- -- bv.bv_val = c->line; -- bv.bv_len = ptr - bv.bv_val; -- if ( bvmatch( &bv, &def )) { -- bdb->bi_defaultmask = 0; -- -- } else { -- int i; -- char **attrs; -- char sep; -- -- sep = bv.bv_val[ bv.bv_len ]; -- bv.bv_val[ bv.bv_len ] = '\0'; -- attrs = ldap_str2charray( bv.bv_val, "," ); -- -- for ( i = 0; attrs[ i ]; i++ ) { -- AttributeDescription *ad = NULL; -- const char *text; -- AttrInfo *ai; -- -- slap_str2ad( attrs[ i ], &ad, &text ); -- /* if we got here... */ -- assert( ad != NULL ); -- -- ai = bdb_attr_mask( bdb, ad ); -- /* if we got here... */ -- assert( ai != NULL ); -- -- ai->ai_indexmask |= BDB_INDEX_DELETING; -- bdb->bi_flags |= BDB_DEL_INDEX; -- c->cleanup = bdb_cf_cleanup; -- } -- -- bv.bv_val[ bv.bv_len ] = sep; -- ldap_charray_free( attrs ); -- } -- } -- break; -- /* doesn't make sense on the fly; the DB file must be -- * recreated -- */ -- case BDB_PGSIZE: { -- struct bdb_db_pgsize *ps, **prev; -- int i; -- -- for ( i = 0, prev = &bdb->bi_pagesizes, ps = *prev; ps; -- prev = &ps->bdp_next, ps = ps->bdp_next, i++ ) { -- if ( c->valx == -1 || i == c->valx ) { -- *prev = ps->bdp_next; -- ch_free( ps ); -- ps = *prev; -- if ( i == c->valx ) break; -- } -- } -- } -- break; -- } -- return rc; -- } -- -- switch( c->type ) { -- case BDB_MODE: -- if ( ASCII_DIGIT( c->argv[1][0] ) ) { -- long mode; -- char *next; -- errno = 0; -- mode = strtol( c->argv[1], &next, 0 ); -- if ( errno != 0 || next == c->argv[1] || next[0] != '\0' ) { -- fprintf( stderr, "%s: " -- "unable to parse mode=\"%s\".\n", -- c->log, c->argv[1] ); -- return 1; -- } -- bdb->bi_dbenv_mode = mode; -- -- } else { -- char *m = c->argv[1]; -- int who, what, mode = 0; -- -- if ( strlen( m ) != STRLENOF("-rwxrwxrwx") ) { -- return 1; -- } -- -- if ( m[0] != '-' ) { -- return 1; -- } -- -- m++; -- for ( who = 0; who < 3; who++ ) { -- for ( what = 0; what < 3; what++, m++ ) { -- if ( m[0] == '-' ) { -- continue; -- } else if ( m[0] != "rwx"[what] ) { -- return 1; -- } -- mode += ((1 << (2 - what)) << 3*(2 - who)); -- } -- } -- bdb->bi_dbenv_mode = mode; -- } -- break; -- case BDB_CHKPT: { -- long l; -- bdb->bi_txn_cp = 1; -- if ( lutil_atolx( &l, c->argv[1], 0 ) != 0 ) { -- fprintf( stderr, "%s: " -- "invalid kbyte \"%s\" in \"checkpoint\".\n", -- c->log, c->argv[1] ); -- return 1; -- } -- bdb->bi_txn_cp_kbyte = l; -- if ( lutil_atolx( &l, c->argv[2], 0 ) != 0 ) { -- fprintf( stderr, "%s: " -- "invalid minutes \"%s\" in \"checkpoint\".\n", -- c->log, c->argv[2] ); -- return 1; -- } -- bdb->bi_txn_cp_min = l; -- /* If we're in server mode and time-based checkpointing is enabled, -- * submit a task to perform periodic checkpoints. -- */ -- if ((slapMode & SLAP_SERVER_MODE) && bdb->bi_txn_cp_min ) { -- struct re_s *re = bdb->bi_txn_cp_task; -- if ( re ) { -- re->interval.tv_sec = bdb->bi_txn_cp_min * 60; -- } else { -- if ( c->be->be_suffix == NULL || BER_BVISNULL( &c->be->be_suffix[0] ) ) { -- fprintf( stderr, "%s: " -- "\"checkpoint\" must occur after \"suffix\".\n", -- c->log ); -- return 1; -- } -- ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); -- bdb->bi_txn_cp_task = ldap_pvt_runqueue_insert( &slapd_rq, -- bdb->bi_txn_cp_min * 60, bdb_checkpoint, bdb, -- LDAP_XSTRING(bdb_checkpoint), c->be->be_suffix[0].bv_val ); -- ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); -- } -- } -- } break; -- -- case BDB_CONFIG: { -- char *ptr = c->line; -- struct berval bv; -- -- if ( c->op == SLAP_CONFIG_ADD ) { -- ptr += STRLENOF("dbconfig"); -- while (!isspace((unsigned char)*ptr)) ptr++; -- while (isspace((unsigned char)*ptr)) ptr++; -- } -- -- if ( bdb->bi_flags & BDB_IS_OPEN ) { -- bdb->bi_flags |= BDB_UPD_CONFIG|BDB_RE_OPEN; -- c->cleanup = bdb_cf_cleanup; -- } else { -- /* If we're just starting up... -- */ -- FILE *f; -- /* If a DB_CONFIG file exists, or we don't know the path -- * to the DB_CONFIG file, ignore these directives -- */ -- if (( bdb->bi_flags & BDB_HAS_CONFIG ) || !bdb->bi_db_config_path ) -- break; -- f = fopen( bdb->bi_db_config_path, "a" ); -- if ( f ) { -- /* FIXME: EBCDIC probably needs special handling */ -- fprintf( f, "%s\n", ptr ); -- fclose( f ); -- } -- } -- ber_str2bv( ptr, 0, 1, &bv ); -- ber_bvarray_add( &bdb->bi_db_config, &bv ); -- } -- break; -- -- case BDB_CRYPTFILE: -- rc = lutil_get_filed_password( c->value_string, &bdb->bi_db_crypt_key ); -- if ( rc == 0 ) { -- bdb->bi_db_crypt_file = c->value_string; -- } -- break; -- -- /* Cannot set key if file was already set */ -- case BDB_CRYPTKEY: -- if ( bdb->bi_db_crypt_file ) { -- rc = 1; -- } else { -- bdb->bi_db_crypt_key = c->value_bv; -- } -- break; -- -- case BDB_DIRECTORY: { -- FILE *f; -- char *ptr, *testpath; -- int len; -- -- len = strlen( c->value_string ); -- testpath = ch_malloc( len + STRLENOF(LDAP_DIRSEP) + STRLENOF("DUMMY") + 1 ); -- ptr = lutil_strcopy( testpath, c->value_string ); -- *ptr++ = LDAP_DIRSEP[0]; -- strcpy( ptr, "DUMMY" ); -- f = fopen( testpath, "w" ); -- if ( f ) { -- fclose( f ); -- unlink( testpath ); -- } -- ch_free( testpath ); -- if ( !f ) { -- snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid path: %s", -- c->log, strerror( errno )); -- Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); -- return -1; -- } -- -- if ( bdb->bi_dbenv_home ) -- ch_free( bdb->bi_dbenv_home ); -- bdb->bi_dbenv_home = c->value_string; -- -- /* See if a DB_CONFIG file already exists here */ -- if ( bdb->bi_db_config_path ) -- ch_free( bdb->bi_db_config_path ); -- bdb->bi_db_config_path = ch_malloc( len + -- STRLENOF(LDAP_DIRSEP) + STRLENOF("DB_CONFIG") + 1 ); -- ptr = lutil_strcopy( bdb->bi_db_config_path, bdb->bi_dbenv_home ); -- *ptr++ = LDAP_DIRSEP[0]; -- strcpy( ptr, "DB_CONFIG" ); -- -- f = fopen( bdb->bi_db_config_path, "r" ); -- if ( f ) { -- bdb->bi_flags |= BDB_HAS_CONFIG; -- fclose(f); -- } -- } -- break; -- -- case BDB_NOSYNC: -- if ( c->value_int ) -- bdb->bi_dbenv_xflags |= DB_TXN_NOSYNC; -- else -- bdb->bi_dbenv_xflags &= ~DB_TXN_NOSYNC; -- if ( bdb->bi_flags & BDB_IS_OPEN ) { -- bdb->bi_dbenv->set_flags( bdb->bi_dbenv, DB_TXN_NOSYNC, -- c->value_int ); -- } -- break; -- -- case BDB_CHECKSUM: -- if ( c->value_int ) -- bdb->bi_flags |= BDB_CHKSUM; -- else -- bdb->bi_flags &= ~BDB_CHKSUM; -- break; -- -- case BDB_INDEX: -- rc = bdb_attr_index_config( bdb, c->fname, c->lineno, -- c->argc - 1, &c->argv[1], &c->reply); -- -- if( rc != LDAP_SUCCESS ) return 1; -- if (( bdb->bi_flags & BDB_IS_OPEN ) && !bdb->bi_index_task ) { -- /* Start the task as soon as we finish here. Set a long -- * interval (10 hours) so that it only gets scheduled once. -- */ -- if ( c->be->be_suffix == NULL || BER_BVISNULL( &c->be->be_suffix[0] ) ) { -- fprintf( stderr, "%s: " -- "\"index\" must occur after \"suffix\".\n", -- c->log ); -- return 1; -- } -- ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); -- bdb->bi_index_task = ldap_pvt_runqueue_insert( &slapd_rq, 36000, -- bdb_online_index, c->be, -- LDAP_XSTRING(bdb_online_index), c->be->be_suffix[0].bv_val ); -- ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); -- } -- break; -- -- case BDB_LOCKD: -- rc = verb_to_mask( c->argv[1], bdb_lockd ); -- if ( BER_BVISNULL(&bdb_lockd[rc].word) ) { -- fprintf( stderr, "%s: " -- "bad policy (%s) in \"lockDetect \" line\n", -- c->log, c->argv[1] ); -- return 1; -- } -- bdb->bi_lock_detect = (u_int32_t)rc; -- break; -- -- case BDB_SSTACK: -- if ( c->value_int < MINIMUM_SEARCH_STACK_DEPTH ) { -- fprintf( stderr, -- "%s: depth %d too small, using %d\n", -- c->log, c->value_int, MINIMUM_SEARCH_STACK_DEPTH ); -- c->value_int = MINIMUM_SEARCH_STACK_DEPTH; -- } -- bdb->bi_search_stack_depth = c->value_int; -- break; -- -- case BDB_PGSIZE: { -- struct bdb_db_pgsize *ps, **prev; -- int i, s; -- -- s = atoi(c->argv[2]); -- if ( s < 1 || s > 64 ) { -- snprintf( c->cr_msg, sizeof( c->cr_msg ), -- "%s: size must be > 0 and <= 64: %d", -- c->log, s ); -- Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); -- return -1; -- } -- i = strlen(c->argv[1]); -- ps = ch_malloc( sizeof(struct bdb_db_pgsize) + i + 1 ); -- ps->bdp_next = NULL; -- ps->bdp_name.bv_len = i; -- ps->bdp_name.bv_val = (char *)(ps+1); -- strcpy( ps->bdp_name.bv_val, c->argv[1] ); -- ps->bdp_size = s * 1024; -- for ( prev = &bdb->bi_pagesizes; *prev; prev = &(*prev)->bdp_next ) -- ; -- *prev = ps; -- } -- break; -- } -- return 0; --} -- --int bdb_back_init_cf( BackendInfo *bi ) --{ -- int rc; -- bi->bi_cf_ocs = bdbocs; -- -- rc = config_register_schema( bdbcfg, bdbocs ); -- if ( rc ) return rc; -- return 0; --} -diff --git a/servers/slapd/back-bdb/dbcache.c b/servers/slapd/back-bdb/dbcache.c -deleted file mode 100644 -index 9a35b71..0000000 ---- a/servers/slapd/back-bdb/dbcache.c -+++ /dev/null -@@ -1,210 +0,0 @@ --/* dbcache.c - manage cache of open databases */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include -- --#include --#include --#include --#include --#include -- --#include "slap.h" --#include "back-bdb.h" --#include "lutil_hash.h" -- --#ifdef BDB_INDEX_USE_HASH --/* Pass-thru hash function. Since the indexer is already giving us hash -- * values as keys, we don't need BDB to re-hash them. -- */ --static u_int32_t --bdb_db_hash( -- DB *db, -- const void *bytes, -- u_int32_t length --) --{ -- u_int32_t ret = 0; -- unsigned char *dst = (unsigned char *)&ret; -- const unsigned char *src = (const unsigned char *)bytes; -- -- if ( length > sizeof(u_int32_t) ) -- length = sizeof(u_int32_t); -- -- while ( length ) { -- *dst++ = *src++; -- length--; -- } -- return ret; --} --#define BDB_INDEXTYPE DB_HASH --#else --#define BDB_INDEXTYPE DB_BTREE --#endif -- --/* If a configured size is found, return it, otherwise return 0 */ --int --bdb_db_findsize( -- struct bdb_info *bdb, -- struct berval *name --) --{ -- struct bdb_db_pgsize *bp; -- int rc; -- -- for ( bp = bdb->bi_pagesizes; bp; bp=bp->bdp_next ) { -- rc = strncmp( name->bv_val, bp->bdp_name.bv_val, name->bv_len ); -- if ( !rc ) { -- if ( name->bv_len == bp->bdp_name.bv_len ) -- return bp->bdp_size; -- if ( name->bv_len < bp->bdp_name.bv_len && -- bp->bdp_name.bv_val[name->bv_len] == '.' ) -- return bp->bdp_size; -- } -- } -- return 0; --} -- --int --bdb_db_cache( -- Backend *be, -- struct berval *name, -- DB **dbout ) --{ -- int i, flags; -- int rc; -- struct bdb_info *bdb = (struct bdb_info *) be->be_private; -- struct bdb_db_info *db; -- char *file; -- -- *dbout = NULL; -- -- for( i=BDB_NDB; i < bdb->bi_ndatabases; i++ ) { -- if( !ber_bvcmp( &bdb->bi_databases[i]->bdi_name, name) ) { -- *dbout = bdb->bi_databases[i]->bdi_db; -- return 0; -- } -- } -- -- ldap_pvt_thread_mutex_lock( &bdb->bi_database_mutex ); -- -- /* check again! may have been added by another thread */ -- for( i=BDB_NDB; i < bdb->bi_ndatabases; i++ ) { -- if( !ber_bvcmp( &bdb->bi_databases[i]->bdi_name, name) ) { -- *dbout = bdb->bi_databases[i]->bdi_db; -- ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex ); -- return 0; -- } -- } -- -- if( i >= BDB_INDICES ) { -- ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex ); -- return -1; -- } -- -- db = (struct bdb_db_info *) ch_calloc(1, sizeof(struct bdb_db_info)); -- -- ber_dupbv( &db->bdi_name, name ); -- -- rc = db_create( &db->bdi_db, bdb->bi_dbenv, 0 ); -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, -- "bdb_db_cache: db_create(%s) failed: %s (%d)\n", -- bdb->bi_dbenv_home, db_strerror(rc), rc ); -- ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex ); -- ch_free( db ); -- return rc; -- } -- -- if( !BER_BVISNULL( &bdb->bi_db_crypt_key )) { -- rc = db->bdi_db->set_flags( db->bdi_db, DB_ENCRYPT ); -- if ( rc ) { -- Debug( LDAP_DEBUG_ANY, -- "bdb_db_cache: db set_flags(DB_ENCRYPT)(%s) failed: %s (%d)\n", -- bdb->bi_dbenv_home, db_strerror(rc), rc ); -- ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex ); -- db->bdi_db->close( db->bdi_db, 0 ); -- ch_free( db ); -- return rc; -- } -- } -- -- if( bdb->bi_flags & BDB_CHKSUM ) { -- rc = db->bdi_db->set_flags( db->bdi_db, DB_CHKSUM ); -- if ( rc ) { -- Debug( LDAP_DEBUG_ANY, -- "bdb_db_cache: db set_flags(DB_CHKSUM)(%s) failed: %s (%d)\n", -- bdb->bi_dbenv_home, db_strerror(rc), rc ); -- ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex ); -- db->bdi_db->close( db->bdi_db, 0 ); -- ch_free( db ); -- return rc; -- } -- } -- -- /* If no explicit size set, use the FS default */ -- flags = bdb_db_findsize( bdb, name ); -- if ( flags ) -- rc = db->bdi_db->set_pagesize( db->bdi_db, flags ); -- --#ifdef BDB_INDEX_USE_HASH -- rc = db->bdi_db->set_h_hash( db->bdi_db, bdb_db_hash ); --#endif -- rc = db->bdi_db->set_flags( db->bdi_db, DB_DUP | DB_DUPSORT ); -- -- file = ch_malloc( db->bdi_name.bv_len + sizeof(BDB_SUFFIX) ); -- strcpy( file, db->bdi_name.bv_val ); -- strcpy( file+db->bdi_name.bv_len, BDB_SUFFIX ); -- --#ifdef HAVE_EBCDIC -- __atoe( file ); --#endif -- flags = DB_CREATE | DB_THREAD; --#ifdef DB_AUTO_COMMIT -- if ( !( slapMode & SLAP_TOOL_QUICK )) -- flags |= DB_AUTO_COMMIT; --#endif -- /* Cannot Truncate when Transactions are in use */ -- if ( (slapMode & (SLAP_TOOL_QUICK|SLAP_TRUNCATE_MODE)) == -- (SLAP_TOOL_QUICK|SLAP_TRUNCATE_MODE)) -- flags |= DB_TRUNCATE; -- -- rc = DB_OPEN( db->bdi_db, -- file, NULL /* name */, -- BDB_INDEXTYPE, bdb->bi_db_opflags | flags, bdb->bi_dbenv_mode ); -- -- ch_free( file ); -- -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, -- "bdb_db_cache: db_open(%s) failed: %s (%d)\n", -- name->bv_val, db_strerror(rc), rc ); -- ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex ); -- db->bdi_db->close( db->bdi_db, 0 ); -- ch_free( db ); -- return rc; -- } -- -- bdb->bi_databases[i] = db; -- bdb->bi_ndatabases = i+1; -- -- *dbout = db->bdi_db; -- -- ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex ); -- return 0; --} -diff --git a/servers/slapd/back-bdb/delete.c b/servers/slapd/back-bdb/delete.c -deleted file mode 100644 -index f4f6e23..0000000 ---- a/servers/slapd/back-bdb/delete.c -+++ /dev/null -@@ -1,605 +0,0 @@ --/* delete.c - bdb backend delete routine */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include --#include -- --#include "lutil.h" --#include "back-bdb.h" -- --int --bdb_delete( Operation *op, SlapReply *rs ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- Entry *matched = NULL; -- struct berval pdn = {0, NULL}; -- Entry *e = NULL; -- Entry *p = NULL; -- EntryInfo *ei = NULL, *eip = NULL; -- int manageDSAit = get_manageDSAit( op ); -- AttributeDescription *children = slap_schema.si_ad_children; -- AttributeDescription *entry = slap_schema.si_ad_entry; -- DB_TXN *ltid = NULL, *lt2; -- struct bdb_op_info opinfo = {{{ 0 }}}; -- ID eid; -- -- DB_LOCK lock, plock; -- -- int num_retries = 0; -- -- int rc; -- -- LDAPControl **preread_ctrl = NULL; -- LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS]; -- int num_ctrls = 0; -- -- int parent_is_glue = 0; -- int parent_is_leaf = 0; -- --#ifdef LDAP_X_TXN -- int settle = 0; --#endif -- -- Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(bdb_delete) ": %s\n", -- op->o_req_dn.bv_val, 0, 0 ); -- --#ifdef LDAP_X_TXN -- if( op->o_txnSpec ) { -- /* acquire connection lock */ -- ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); -- if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) { -- rs->sr_text = "invalid transaction identifier"; -- rs->sr_err = LDAP_X_TXN_ID_INVALID; -- goto txnReturn; -- } else if( op->o_conn->c_txn == CONN_TXN_SETTLE ) { -- settle=1; -- goto txnReturn; -- } -- -- if( op->o_conn->c_txn_backend == NULL ) { -- op->o_conn->c_txn_backend = op->o_bd; -- -- } else if( op->o_conn->c_txn_backend != op->o_bd ) { -- rs->sr_text = "transaction cannot span multiple database contexts"; -- rs->sr_err = LDAP_AFFECTS_MULTIPLE_DSAS; -- goto txnReturn; -- } -- -- /* insert operation into transaction */ -- -- rs->sr_text = "transaction specified"; -- rs->sr_err = LDAP_X_TXN_SPECIFY_OKAY; -- --txnReturn: -- /* release connection lock */ -- ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); -- -- if( !settle ) { -- send_ldap_result( op, rs ); -- return rs->sr_err; -- } -- } --#endif -- -- ctrls[num_ctrls] = 0; -- -- /* allocate CSN */ -- if ( BER_BVISNULL( &op->o_csn ) ) { -- struct berval csn; -- char csnbuf[LDAP_PVT_CSNSTR_BUFSIZE]; -- -- csn.bv_val = csnbuf; -- csn.bv_len = sizeof(csnbuf); -- slap_get_csn( op, &csn, 1 ); -- } -- -- if( 0 ) { --retry: /* transaction retry */ -- if( e != NULL ) { -- bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e); -- e = NULL; -- } -- if( p != NULL ) { -- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p); -- p = NULL; -- } -- Debug( LDAP_DEBUG_TRACE, -- "==> " LDAP_XSTRING(bdb_delete) ": retrying...\n", -- 0, 0, 0 ); -- rs->sr_err = TXN_ABORT( ltid ); -- ltid = NULL; -- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); -- opinfo.boi_oe.oe_key = NULL; -- op->o_do_not_cache = opinfo.boi_acl_cache; -- if( rs->sr_err != 0 ) { -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- if ( op->o_abandon ) { -- rs->sr_err = SLAPD_ABANDON; -- goto return_results; -- } -- parent_is_glue = 0; -- parent_is_leaf = 0; -- bdb_trans_backoff( ++num_retries ); -- } -- -- /* begin transaction */ -- rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, <id, -- bdb->bi_db_opflags ); -- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_delete) ": txn1 id: %x\n", -- ltid->id(ltid), 0, 0 ); -- rs->sr_text = NULL; -- if( rs->sr_err != 0 ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_delete) ": txn_begin failed: " -- "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 ); -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- -- opinfo.boi_oe.oe_key = bdb; -- opinfo.boi_txn = ltid; -- opinfo.boi_err = 0; -- opinfo.boi_acl_cache = op->o_do_not_cache; -- LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.boi_oe, oe_next ); -- -- if ( !be_issuffix( op->o_bd, &op->o_req_ndn ) ) { -- dnParent( &op->o_req_ndn, &pdn ); -- } -- -- /* get entry */ -- rs->sr_err = bdb_dn2entry( op, ltid, &op->o_req_ndn, &ei, 1, -- &lock ); -- -- switch( rs->sr_err ) { -- case 0: -- case DB_NOTFOUND: -- break; -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- case LDAP_BUSY: -- rs->sr_text = "ldap server busy"; -- goto return_results; -- default: -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- -- if ( rs->sr_err == 0 ) { -- e = ei->bei_e; -- eip = ei->bei_parent; -- } else { -- matched = ei->bei_e; -- } -- -- /* FIXME : dn2entry() should return non-glue entry */ -- if ( e == NULL || ( !manageDSAit && is_entry_glue( e ))) { -- Debug( LDAP_DEBUG_ARGS, -- "<=- " LDAP_XSTRING(bdb_delete) ": no such object %s\n", -- op->o_req_dn.bv_val, 0, 0); -- -- if ( matched != NULL ) { -- rs->sr_matched = ch_strdup( matched->e_dn ); -- rs->sr_ref = is_entry_referral( matched ) -- ? get_entry_referrals( op, matched ) -- : NULL; -- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, matched); -- matched = NULL; -- -- } else { -- rs->sr_ref = referral_rewrite( default_referral, NULL, -- &op->o_req_dn, LDAP_SCOPE_DEFAULT ); -- } -- -- rs->sr_err = LDAP_REFERRAL; -- rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; -- goto return_results; -- } -- -- rc = bdb_cache_find_id( op, ltid, eip->bei_id, &eip, 0, &plock ); -- switch( rc ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- case 0: -- case DB_NOTFOUND: -- break; -- default: -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- if ( eip ) p = eip->bei_e; -- -- if ( pdn.bv_len != 0 ) { -- if( p == NULL || !bvmatch( &pdn, &p->e_nname )) { -- Debug( LDAP_DEBUG_TRACE, -- "<=- " LDAP_XSTRING(bdb_delete) ": parent " -- "does not exist\n", 0, 0, 0 ); -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "could not locate parent of entry"; -- goto return_results; -- } -- -- /* check parent for "children" acl */ -- rs->sr_err = access_allowed( op, p, -- children, NULL, ACL_WDEL, NULL ); -- -- if ( !rs->sr_err ) { -- switch( opinfo.boi_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- -- Debug( LDAP_DEBUG_TRACE, -- "<=- " LDAP_XSTRING(bdb_delete) ": no write " -- "access to parent\n", 0, 0, 0 ); -- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; -- rs->sr_text = "no write access to parent"; -- goto return_results; -- } -- -- } else { -- /* no parent, must be root to delete */ -- if( ! be_isroot( op ) ) { -- if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv ) -- || be_shadow_update( op ) ) { -- p = (Entry *)&slap_entry_root; -- -- /* check parent for "children" acl */ -- rs->sr_err = access_allowed( op, p, -- children, NULL, ACL_WDEL, NULL ); -- -- p = NULL; -- -- if ( !rs->sr_err ) { -- switch( opinfo.boi_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- -- Debug( LDAP_DEBUG_TRACE, -- "<=- " LDAP_XSTRING(bdb_delete) -- ": no access to parent\n", -- 0, 0, 0 ); -- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; -- rs->sr_text = "no write access to parent"; -- goto return_results; -- } -- -- } else { -- Debug( LDAP_DEBUG_TRACE, -- "<=- " LDAP_XSTRING(bdb_delete) -- ": no parent and not root\n", 0, 0, 0 ); -- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; -- goto return_results; -- } -- } -- } -- -- if ( get_assert( op ) && -- ( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE )) -- { -- rs->sr_err = LDAP_ASSERTION_FAILED; -- goto return_results; -- } -- -- rs->sr_err = access_allowed( op, e, -- entry, NULL, ACL_WDEL, NULL ); -- -- if ( !rs->sr_err ) { -- switch( opinfo.boi_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- -- Debug( LDAP_DEBUG_TRACE, -- "<=- " LDAP_XSTRING(bdb_delete) ": no write access " -- "to entry\n", 0, 0, 0 ); -- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; -- rs->sr_text = "no write access to entry"; -- goto return_results; -- } -- -- if ( !manageDSAit && is_entry_referral( e ) ) { -- /* entry is a referral, don't allow delete */ -- rs->sr_ref = get_entry_referrals( op, e ); -- -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_delete) ": entry is referral\n", -- 0, 0, 0 ); -- -- rs->sr_err = LDAP_REFERRAL; -- rs->sr_matched = ch_strdup( e->e_name.bv_val ); -- rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; -- goto return_results; -- } -- -- /* pre-read */ -- if( op->o_preread ) { -- if( preread_ctrl == NULL ) { -- preread_ctrl = &ctrls[num_ctrls++]; -- ctrls[num_ctrls] = NULL; -- } -- if( slap_read_controls( op, rs, e, -- &slap_pre_read_bv, preread_ctrl ) ) -- { -- Debug( LDAP_DEBUG_TRACE, -- "<=- " LDAP_XSTRING(bdb_delete) ": pre-read " -- "failed!\n", 0, 0, 0 ); -- if ( op->o_preread & SLAP_CONTROL_CRITICAL ) { -- /* FIXME: is it correct to abort -- * operation if control fails? */ -- goto return_results; -- } -- } -- } -- -- /* nested transaction */ -- rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, <2, -- bdb->bi_db_opflags ); -- rs->sr_text = NULL; -- if( rs->sr_err != 0 ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_delete) ": txn_begin(2) failed: " -- "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 ); -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_delete) ": txn2 id: %x\n", -- lt2->id(lt2), 0, 0 ); -- -- BDB_LOG_PRINTF( bdb->bi_dbenv, lt2, "slapd Starting delete %s(%d)", -- e->e_nname.bv_val, e->e_id ); -- -- /* Can't do it if we have kids */ -- rs->sr_err = bdb_cache_children( op, lt2, e ); -- if( rs->sr_err != DB_NOTFOUND ) { -- switch( rs->sr_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- case 0: -- Debug(LDAP_DEBUG_ARGS, -- "<=- " LDAP_XSTRING(bdb_delete) -- ": non-leaf %s\n", -- op->o_req_dn.bv_val, 0, 0); -- rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF; -- rs->sr_text = "subordinate objects must be deleted first"; -- break; -- default: -- Debug(LDAP_DEBUG_ARGS, -- "<=- " LDAP_XSTRING(bdb_delete) -- ": has_children failed: %s (%d)\n", -- db_strerror(rs->sr_err), rs->sr_err, 0 ); -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- } -- goto return_results; -- } -- -- /* delete from dn2id */ -- rs->sr_err = bdb_dn2id_delete( op, lt2, eip, e ); -- if ( rs->sr_err != 0 ) { -- Debug(LDAP_DEBUG_TRACE, -- "<=- " LDAP_XSTRING(bdb_delete) ": dn2id failed: " -- "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 ); -- switch( rs->sr_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- rs->sr_text = "DN index delete failed"; -- rs->sr_err = LDAP_OTHER; -- goto return_results; -- } -- -- /* delete indices for old attributes */ -- rs->sr_err = bdb_index_entry_del( op, lt2, e ); -- if ( rs->sr_err != LDAP_SUCCESS ) { -- Debug(LDAP_DEBUG_TRACE, -- "<=- " LDAP_XSTRING(bdb_delete) ": index failed: " -- "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 ); -- switch( rs->sr_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- rs->sr_text = "entry index delete failed"; -- rs->sr_err = LDAP_OTHER; -- goto return_results; -- } -- -- /* fixup delete CSN */ -- if ( !SLAP_SHADOW( op->o_bd )) { -- struct berval vals[2]; -- -- assert( !BER_BVISNULL( &op->o_csn ) ); -- vals[0] = op->o_csn; -- BER_BVZERO( &vals[1] ); -- rs->sr_err = bdb_index_values( op, lt2, slap_schema.si_ad_entryCSN, -- vals, 0, SLAP_INDEX_ADD_OP ); -- if ( rs->sr_err != LDAP_SUCCESS ) { -- switch( rs->sr_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- rs->sr_text = "entryCSN index update failed"; -- rs->sr_err = LDAP_OTHER; -- goto return_results; -- } -- } -- -- /* delete from id2entry */ -- rs->sr_err = bdb_id2entry_delete( op->o_bd, lt2, e ); -- if ( rs->sr_err != 0 ) { -- Debug( LDAP_DEBUG_TRACE, -- "<=- " LDAP_XSTRING(bdb_delete) ": id2entry failed: " -- "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 ); -- switch( rs->sr_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- rs->sr_text = "entry delete failed"; -- rs->sr_err = LDAP_OTHER; -- goto return_results; -- } -- -- if ( pdn.bv_len != 0 ) { -- parent_is_glue = is_entry_glue(p); -- rs->sr_err = bdb_cache_children( op, lt2, p ); -- if ( rs->sr_err != DB_NOTFOUND ) { -- switch( rs->sr_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- case 0: -- break; -- default: -- Debug(LDAP_DEBUG_ARGS, -- "<=- " LDAP_XSTRING(bdb_delete) -- ": has_children failed: %s (%d)\n", -- db_strerror(rs->sr_err), rs->sr_err, 0 ); -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- parent_is_leaf = 1; -- } -- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p); -- p = NULL; -- } -- -- BDB_LOG_PRINTF( bdb->bi_dbenv, lt2, "slapd Commit1 delete %s(%d)", -- e->e_nname.bv_val, e->e_id ); -- -- if ( TXN_COMMIT( lt2, 0 ) != 0 ) { -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "txn_commit(2) failed"; -- goto return_results; -- } -- -- eid = e->e_id; -- --#if 0 /* Do we want to reclaim deleted IDs? */ -- ldap_pvt_thread_mutex_lock( &bdb->bi_lastid_mutex ); -- if ( e->e_id == bdb->bi_lastid ) { -- bdb_last_id( op->o_bd, ltid ); -- } -- ldap_pvt_thread_mutex_unlock( &bdb->bi_lastid_mutex ); --#endif -- -- if( op->o_noop ) { -- if ( ( rs->sr_err = TXN_ABORT( ltid ) ) != 0 ) { -- rs->sr_text = "txn_abort (no-op) failed"; -- } else { -- rs->sr_err = LDAP_X_NO_OPERATION; -- ltid = NULL; -- goto return_results; -- } -- } else { -- -- BDB_LOG_PRINTF( bdb->bi_dbenv, ltid, "slapd Cache delete %s(%d)", -- e->e_nname.bv_val, e->e_id ); -- -- rc = bdb_cache_delete( bdb, e, ltid, &lock ); -- switch( rc ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- -- rs->sr_err = TXN_COMMIT( ltid, 0 ); -- } -- ltid = NULL; -- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); -- opinfo.boi_oe.oe_key = NULL; -- -- BDB_LOG_PRINTF( bdb->bi_dbenv, NULL, "slapd Committed delete %s(%d)", -- e->e_nname.bv_val, e->e_id ); -- -- if( rs->sr_err != 0 ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_delete) ": txn_%s failed: %s (%d)\n", -- op->o_noop ? "abort (no-op)" : "commit", -- db_strerror(rs->sr_err), rs->sr_err ); -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "commit failed"; -- -- goto return_results; -- } -- -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_delete) ": deleted%s id=%08lx dn=\"%s\"\n", -- op->o_noop ? " (no-op)" : "", -- eid, op->o_req_dn.bv_val ); -- rs->sr_err = LDAP_SUCCESS; -- rs->sr_text = NULL; -- if( num_ctrls ) rs->sr_ctrls = ctrls; -- --return_results: -- if ( rs->sr_err == LDAP_SUCCESS && parent_is_glue && parent_is_leaf ) { -- op->o_delete_glue_parent = 1; -- } -- -- if ( p ) -- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p); -- -- /* free entry */ -- if( e != NULL ) { -- if ( rs->sr_err == LDAP_SUCCESS ) { -- /* Free the EntryInfo and the Entry */ -- bdb_cache_entryinfo_lock( BEI(e) ); -- bdb_cache_delete_cleanup( &bdb->bi_cache, BEI(e) ); -- } else { -- bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e); -- } -- } -- -- if( ltid != NULL ) { -- TXN_ABORT( ltid ); -- } -- if ( opinfo.boi_oe.oe_key ) { -- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); -- } -- -- send_ldap_result( op, rs ); -- slap_graduate_commit_csn( op ); -- -- if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) { -- slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx ); -- slap_sl_free( *preread_ctrl, op->o_tmpmemctx ); -- } -- -- if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp_kbyte ) { -- TXN_CHECKPOINT( bdb->bi_dbenv, -- bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 ); -- } -- return rs->sr_err; --} -diff --git a/servers/slapd/back-bdb/dn2entry.c b/servers/slapd/back-bdb/dn2entry.c -deleted file mode 100644 -index 41d1dc9..0000000 ---- a/servers/slapd/back-bdb/dn2entry.c -+++ /dev/null -@@ -1,84 +0,0 @@ --/* dn2entry.c - routines to deal with the dn2id / id2entry glue */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include --#include -- --#include "back-bdb.h" -- --/* -- * dn2entry - look up dn in the cache/indexes and return the corresponding -- * entry. If the requested DN is not found and matched is TRUE, return info -- * for the closest ancestor of the DN. Otherwise e is NULL. -- */ -- --int --bdb_dn2entry( -- Operation *op, -- DB_TXN *tid, -- struct berval *dn, -- EntryInfo **e, -- int matched, -- DB_LOCK *lock ) --{ -- EntryInfo *ei = NULL; -- int rc, rc2; -- -- Debug(LDAP_DEBUG_TRACE, "bdb_dn2entry(\"%s\")\n", -- dn->bv_val, 0, 0 ); -- -- *e = NULL; -- -- rc = bdb_cache_find_ndn( op, tid, dn, &ei ); -- if ( rc ) { -- if ( matched && rc == DB_NOTFOUND ) { -- /* Set the return value, whether we have its entry -- * or not. -- */ -- *e = ei; -- if ( ei && ei->bei_id ) { -- rc2 = bdb_cache_find_id( op, tid, ei->bei_id, -- &ei, ID_LOCKED, lock ); -- if ( rc2 ) rc = rc2; -- } else if ( ei ) { -- bdb_cache_entryinfo_unlock( ei ); -- memset( lock, 0, sizeof( *lock )); -- lock->mode = DB_LOCK_NG; -- } -- } else if ( ei ) { -- bdb_cache_entryinfo_unlock( ei ); -- } -- } else { -- rc = bdb_cache_find_id( op, tid, ei->bei_id, &ei, ID_LOCKED, -- lock ); -- if ( rc == 0 ) { -- *e = ei; -- } else if ( matched && rc == DB_NOTFOUND ) { -- /* always return EntryInfo */ -- if ( ei->bei_parent ) { -- ei = ei->bei_parent; -- rc2 = bdb_cache_find_id( op, tid, ei->bei_id, &ei, 0, -- lock ); -- if ( rc2 ) rc = rc2; -- } -- *e = ei; -- } -- } -- -- return rc; --} -diff --git a/servers/slapd/back-bdb/dn2id.c b/servers/slapd/back-bdb/dn2id.c -deleted file mode 100644 -index 7b54024..0000000 ---- a/servers/slapd/back-bdb/dn2id.c -+++ /dev/null -@@ -1,1215 +0,0 @@ --/* dn2id.c - routines to deal with the dn2id index */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include --#include -- --#include "back-bdb.h" --#include "idl.h" --#include "lutil.h" -- --#ifndef BDB_HIER --int --bdb_dn2id_add( -- Operation *op, -- DB_TXN *txn, -- EntryInfo *eip, -- Entry *e ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- DB *db = bdb->bi_dn2id->bdi_db; -- int rc; -- DBT key, data; -- ID nid; -- char *buf; -- struct berval ptr, pdn; -- -- Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_add 0x%lx: \"%s\"\n", -- e->e_id, e->e_ndn, 0 ); -- assert( e->e_id != NOID ); -- -- DBTzero( &key ); -- key.size = e->e_nname.bv_len + 2; -- key.ulen = key.size; -- key.flags = DB_DBT_USERMEM; -- buf = op->o_tmpalloc( key.size, op->o_tmpmemctx ); -- key.data = buf; -- buf[0] = DN_BASE_PREFIX; -- ptr.bv_val = buf + 1; -- ptr.bv_len = e->e_nname.bv_len; -- AC_MEMCPY( ptr.bv_val, e->e_nname.bv_val, e->e_nname.bv_len ); -- ptr.bv_val[ptr.bv_len] = '\0'; -- -- DBTzero( &data ); -- data.data = &nid; -- data.size = sizeof( nid ); -- BDB_ID2DISK( e->e_id, &nid ); -- -- /* store it -- don't override */ -- rc = db->put( db, txn, &key, &data, DB_NOOVERWRITE ); -- if( rc != 0 ) { -- char buf[ SLAP_TEXT_BUFLEN ]; -- snprintf( buf, sizeof( buf ), "%s => bdb_dn2id_add dn=\"%s\" ID=0x%lx", -- op->o_log_prefix, e->e_name.bv_val, e->e_id ); -- Debug( LDAP_DEBUG_ANY, "%s: put failed: %s %d\n", -- buf, db_strerror(rc), rc ); -- goto done; -- } -- --#ifndef BDB_MULTIPLE_SUFFIXES -- if( !be_issuffix( op->o_bd, &ptr )) --#endif -- { -- buf[0] = DN_SUBTREE_PREFIX; -- rc = db->put( db, txn, &key, &data, DB_NOOVERWRITE ); -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, -- "=> bdb_dn2id_add 0x%lx: subtree (%s) put failed: %d\n", -- e->e_id, ptr.bv_val, rc ); -- goto done; -- } -- --#ifdef BDB_MULTIPLE_SUFFIXES -- if( !be_issuffix( op->o_bd, &ptr )) --#endif -- { -- dnParent( &ptr, &pdn ); -- -- key.size = pdn.bv_len + 2; -- key.ulen = key.size; -- pdn.bv_val[-1] = DN_ONE_PREFIX; -- key.data = pdn.bv_val-1; -- ptr = pdn; -- -- rc = bdb_idl_insert_key( op->o_bd, db, txn, &key, e->e_id ); -- -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, -- "=> bdb_dn2id_add 0x%lx: parent (%s) insert failed: %d\n", -- e->e_id, ptr.bv_val, rc ); -- goto done; -- } -- } -- --#ifndef BDB_MULTIPLE_SUFFIXES -- while( !be_issuffix( op->o_bd, &ptr )) --#else -- for (;;) --#endif -- { -- ptr.bv_val[-1] = DN_SUBTREE_PREFIX; -- -- rc = bdb_idl_insert_key( op->o_bd, db, txn, &key, e->e_id ); -- -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, -- "=> bdb_dn2id_add 0x%lx: subtree (%s) insert failed: %d\n", -- e->e_id, ptr.bv_val, rc ); -- break; -- } --#ifdef BDB_MULTIPLE_SUFFIXES -- if( be_issuffix( op->o_bd, &ptr )) break; --#endif -- dnParent( &ptr, &pdn ); -- -- key.size = pdn.bv_len + 2; -- key.ulen = key.size; -- key.data = pdn.bv_val - 1; -- ptr = pdn; -- } -- } -- --done: -- op->o_tmpfree( buf, op->o_tmpmemctx ); -- Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_add 0x%lx: %d\n", e->e_id, rc, 0 ); -- return rc; --} -- --int --bdb_dn2id_delete( -- Operation *op, -- DB_TXN *txn, -- EntryInfo *eip, -- Entry *e ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- DB *db = bdb->bi_dn2id->bdi_db; -- char *buf; -- DBT key; -- struct berval pdn, ptr; -- int rc; -- -- Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_delete 0x%lx: \"%s\"\n", -- e->e_id, e->e_ndn, 0 ); -- -- DBTzero( &key ); -- key.size = e->e_nname.bv_len + 2; -- buf = op->o_tmpalloc( key.size, op->o_tmpmemctx ); -- key.data = buf; -- key.flags = DB_DBT_USERMEM; -- buf[0] = DN_BASE_PREFIX; -- ptr.bv_val = buf+1; -- ptr.bv_len = e->e_nname.bv_len; -- AC_MEMCPY( ptr.bv_val, e->e_nname.bv_val, e->e_nname.bv_len ); -- ptr.bv_val[ptr.bv_len] = '\0'; -- -- /* delete it */ -- rc = db->del( db, txn, &key, 0 ); -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, "=> bdb_dn2id_delete 0x%lx: delete failed: %s %d\n", -- e->e_id, db_strerror(rc), rc ); -- goto done; -- } -- --#ifndef BDB_MULTIPLE_SUFFIXES -- if( !be_issuffix( op->o_bd, &ptr )) --#endif -- { -- buf[0] = DN_SUBTREE_PREFIX; -- rc = bdb_idl_delete_key( op->o_bd, db, txn, &key, e->e_id ); -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, -- "=> bdb_dn2id_delete 0x%lx: subtree (%s) delete failed: %d\n", -- e->e_id, ptr.bv_val, rc ); -- goto done; -- } -- --#ifdef BDB_MULTIPLE_SUFFIXES -- if( !be_issuffix( op->o_bd, &ptr )) --#endif -- { -- dnParent( &ptr, &pdn ); -- -- key.size = pdn.bv_len + 2; -- key.ulen = key.size; -- pdn.bv_val[-1] = DN_ONE_PREFIX; -- key.data = pdn.bv_val - 1; -- ptr = pdn; -- -- rc = bdb_idl_delete_key( op->o_bd, db, txn, &key, e->e_id ); -- -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, -- "=> bdb_dn2id_delete 0x%lx: parent (%s) delete failed: %d\n", -- e->e_id, ptr.bv_val, rc ); -- goto done; -- } -- } -- --#ifndef BDB_MULTIPLE_SUFFIXES -- while( !be_issuffix( op->o_bd, &ptr )) --#else -- for (;;) --#endif -- { -- ptr.bv_val[-1] = DN_SUBTREE_PREFIX; -- -- rc = bdb_idl_delete_key( op->o_bd, db, txn, &key, e->e_id ); -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, -- "=> bdb_dn2id_delete 0x%lx: subtree (%s) delete failed: %d\n", -- e->e_id, ptr.bv_val, rc ); -- goto done; -- } --#ifdef BDB_MULTIPLE_SUFFIXES -- if( be_issuffix( op->o_bd, &ptr )) break; --#endif -- dnParent( &ptr, &pdn ); -- -- key.size = pdn.bv_len + 2; -- key.ulen = key.size; -- key.data = pdn.bv_val - 1; -- ptr = pdn; -- } -- } -- --done: -- op->o_tmpfree( buf, op->o_tmpmemctx ); -- Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_delete 0x%lx: %d\n", e->e_id, rc, 0 ); -- return rc; --} -- --int --bdb_dn2id( -- Operation *op, -- struct berval *dn, -- EntryInfo *ei, -- DB_TXN *txn, -- DBC **cursor ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- DB *db = bdb->bi_dn2id->bdi_db; -- int rc; -- DBT key, data; -- ID nid; -- -- Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id(\"%s\")\n", dn->bv_val, 0, 0 ); -- -- DBTzero( &key ); -- key.size = dn->bv_len + 2; -- key.data = op->o_tmpalloc( key.size, op->o_tmpmemctx ); -- ((char *)key.data)[0] = DN_BASE_PREFIX; -- AC_MEMCPY( &((char *)key.data)[1], dn->bv_val, key.size - 1 ); -- -- /* store the ID */ -- DBTzero( &data ); -- data.data = &nid; -- data.ulen = sizeof(ID); -- data.flags = DB_DBT_USERMEM; -- -- rc = db->cursor( db, txn, cursor, bdb->bi_db_opflags ); -- -- /* fetch it */ -- if ( !rc ) -- rc = (*cursor)->c_get( *cursor, &key, &data, DB_SET ); -- -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id: get failed: %s (%d)\n", -- db_strerror( rc ), rc, 0 ); -- } else { -- BDB_DISK2ID( &nid, &ei->bei_id ); -- Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id: got id=0x%lx\n", -- ei->bei_id, 0, 0 ); -- } -- op->o_tmpfree( key.data, op->o_tmpmemctx ); -- return rc; --} -- --int --bdb_dn2id_children( -- Operation *op, -- DB_TXN *txn, -- Entry *e ) --{ -- DBT key, data; -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- DB *db = bdb->bi_dn2id->bdi_db; -- ID id; -- int rc; -- -- Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_children(\"%s\")\n", -- e->e_nname.bv_val, 0, 0 ); -- DBTzero( &key ); -- key.size = e->e_nname.bv_len + 2; -- key.data = op->o_tmpalloc( key.size, op->o_tmpmemctx ); -- ((char *)key.data)[0] = DN_ONE_PREFIX; -- AC_MEMCPY( &((char *)key.data)[1], e->e_nname.bv_val, key.size - 1 ); -- -- if ( bdb->bi_idl_cache_size ) { -- rc = bdb_idl_cache_get( bdb, db, &key, NULL ); -- if ( rc != LDAP_NO_SUCH_OBJECT ) { -- op->o_tmpfree( key.data, op->o_tmpmemctx ); -- return rc; -- } -- } -- /* we actually could do a empty get... */ -- DBTzero( &data ); -- data.data = &id; -- data.ulen = sizeof(id); -- data.flags = DB_DBT_USERMEM; -- data.doff = 0; -- data.dlen = sizeof(id); -- -- rc = db->get( db, txn, &key, &data, bdb->bi_db_opflags ); -- op->o_tmpfree( key.data, op->o_tmpmemctx ); -- -- Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_children(\"%s\"): %s (%d)\n", -- e->e_nname.bv_val, -- rc == 0 ? "" : ( rc == DB_NOTFOUND ? "no " : -- db_strerror(rc) ), rc ); -- -- return rc; --} -- --int --bdb_dn2idl( -- Operation *op, -- DB_TXN *txn, -- struct berval *ndn, -- EntryInfo *ei, -- ID *ids, -- ID *stack ) --{ -- int rc; -- DBT key; -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- DB *db = bdb->bi_dn2id->bdi_db; -- int prefix = ( op->ors_scope == LDAP_SCOPE_ONELEVEL ) -- ? DN_ONE_PREFIX : DN_SUBTREE_PREFIX; -- -- Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2idl(\"%s\")\n", -- ndn->bv_val, 0, 0 ); -- --#ifndef BDB_MULTIPLE_SUFFIXES -- if ( prefix == DN_SUBTREE_PREFIX -- && ( ei->bei_id == 0 || -- ( ei->bei_parent->bei_id == 0 && op->o_bd->be_suffix[0].bv_len ))) { -- BDB_IDL_ALL(bdb, ids); -- return 0; -- } --#endif -- -- DBTzero( &key ); -- key.size = ndn->bv_len + 2; -- key.ulen = key.size; -- key.flags = DB_DBT_USERMEM; -- key.data = op->o_tmpalloc( key.size, op->o_tmpmemctx ); -- ((char *)key.data)[0] = prefix; -- AC_MEMCPY( &((char *)key.data)[1], ndn->bv_val, key.size - 1 ); -- -- BDB_IDL_ZERO( ids ); -- rc = bdb_idl_fetch_key( op->o_bd, db, txn, &key, ids, NULL, 0 ); -- -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_dn2idl: get failed: %s (%d)\n", -- db_strerror( rc ), rc, 0 ); -- -- } else { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_dn2idl: id=%ld first=%ld last=%ld\n", -- (long) ids[0], -- (long) BDB_IDL_FIRST( ids ), (long) BDB_IDL_LAST( ids ) ); -- } -- -- op->o_tmpfree( key.data, op->o_tmpmemctx ); -- return rc; --} -- --#else /* BDB_HIER */ --/* Management routines for a hierarchically structured database. -- * -- * Instead of a ldbm-style dn2id database, we use a hierarchical one. Each -- * entry in this database is a struct diskNode, keyed by entryID and with -- * the data containing the RDN and entryID of the node's children. We use -- * a B-Tree with sorted duplicates to store all the children of a node under -- * the same key. Also, the first item under the key contains the entry's own -- * rdn and the ID of the node's parent, to allow bottom-up tree traversal as -- * well as top-down. To keep this info first in the list, the high bit of all -- * subsequent nrdnlen's is always set. This means we can only accomodate -- * RDNs up to length 32767, but that's fine since full DNs are already -- * restricted to 8192. -- * -- * The diskNode is a variable length structure. This definition is not -- * directly usable for in-memory manipulation. -- */ --typedef struct diskNode { -- unsigned char nrdnlen[2]; -- char nrdn[1]; -- char rdn[1]; /* variable placement */ -- unsigned char entryID[sizeof(ID)]; /* variable placement */ --} diskNode; -- --/* Sort function for the sorted duplicate data items of a dn2id key. -- * Sorts based on normalized RDN, in length order. -- */ --int --hdb_dup_compare( -- DB *db, -- const DBT *usrkey, -- const DBT *curkey --) --{ -- diskNode *un, *cn; -- int rc; -- -- un = (diskNode *)usrkey->data; -- cn = (diskNode *)curkey->data; -- -- /* data is not aligned, cannot compare directly */ -- rc = un->nrdnlen[0] - cn->nrdnlen[0]; -- if ( rc ) return rc; -- rc = un->nrdnlen[1] - cn->nrdnlen[1]; -- if ( rc ) return rc; -- -- return strcmp( un->nrdn, cn->nrdn ); --} -- --/* This function constructs a full DN for a given entry. -- */ --int hdb_fix_dn( -- Entry *e, -- int checkit ) --{ -- EntryInfo *ei; -- int rlen = 0, nrlen = 0; -- char *ptr, *nptr; -- int max = 0; -- -- if ( !e->e_id ) -- return 0; -- -- /* count length of all DN components */ -- for ( ei = BEI(e); ei && ei->bei_id; ei=ei->bei_parent ) { -- rlen += ei->bei_rdn.bv_len + 1; -- nrlen += ei->bei_nrdn.bv_len + 1; -- if (ei->bei_modrdns > max) max = ei->bei_modrdns; -- } -- -- /* See if the entry DN was invalidated by a subtree rename */ -- if ( checkit ) { -- if ( BEI(e)->bei_modrdns >= max ) { -- return 0; -- } -- /* We found a mismatch, tell the caller to lock it */ -- if ( checkit == 1 ) { -- return 1; -- } -- /* checkit == 2. do the fix. */ -- free( e->e_name.bv_val ); -- free( e->e_nname.bv_val ); -- } -- -- e->e_name.bv_len = rlen - 1; -- e->e_nname.bv_len = nrlen - 1; -- e->e_name.bv_val = ch_malloc(rlen); -- e->e_nname.bv_val = ch_malloc(nrlen); -- ptr = e->e_name.bv_val; -- nptr = e->e_nname.bv_val; -- for ( ei = BEI(e); ei && ei->bei_id; ei=ei->bei_parent ) { -- ptr = lutil_strcopy(ptr, ei->bei_rdn.bv_val); -- nptr = lutil_strcopy(nptr, ei->bei_nrdn.bv_val); -- if ( ei->bei_parent ) { -- *ptr++ = ','; -- *nptr++ = ','; -- } -- } -- BEI(e)->bei_modrdns = max; -- if ( ptr > e->e_name.bv_val ) ptr[-1] = '\0'; -- if ( nptr > e->e_nname.bv_val ) nptr[-1] = '\0'; -- -- return 0; --} -- --/* We add two elements to the DN2ID database - a data item under the parent's -- * entryID containing the child's RDN and entryID, and an item under the -- * child's entryID containing the parent's entryID. -- */ --int --hdb_dn2id_add( -- Operation *op, -- DB_TXN *txn, -- EntryInfo *eip, -- Entry *e ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- DB *db = bdb->bi_dn2id->bdi_db; -- DBT key, data; -- ID nid; -- int rc, rlen, nrlen; -- diskNode *d; -- char *ptr; -- -- Debug( LDAP_DEBUG_TRACE, "=> hdb_dn2id_add 0x%lx: \"%s\"\n", -- e->e_id, e->e_ndn, 0 ); -- -- nrlen = dn_rdnlen( op->o_bd, &e->e_nname ); -- if (nrlen) { -- rlen = dn_rdnlen( op->o_bd, &e->e_name ); -- } else { -- nrlen = e->e_nname.bv_len; -- rlen = e->e_name.bv_len; -- } -- -- d = op->o_tmpalloc(sizeof(diskNode) + rlen + nrlen, op->o_tmpmemctx); -- d->nrdnlen[1] = nrlen & 0xff; -- d->nrdnlen[0] = (nrlen >> 8) | 0x80; -- ptr = lutil_strncopy( d->nrdn, e->e_nname.bv_val, nrlen ); -- *ptr++ = '\0'; -- ptr = lutil_strncopy( ptr, e->e_name.bv_val, rlen ); -- *ptr++ = '\0'; -- BDB_ID2DISK( e->e_id, ptr ); -- -- DBTzero(&key); -- DBTzero(&data); -- key.size = sizeof(ID); -- key.flags = DB_DBT_USERMEM; -- BDB_ID2DISK( eip->bei_id, &nid ); -- -- key.data = &nid; -- -- /* Need to make dummy root node once. Subsequent attempts -- * will fail harmlessly. -- */ -- if ( eip->bei_id == 0 ) { -- diskNode dummy = {{0, 0}, "", "", ""}; -- data.data = &dummy; -- data.size = sizeof(diskNode); -- data.flags = DB_DBT_USERMEM; -- -- db->put( db, txn, &key, &data, DB_NODUPDATA ); -- } -- -- data.data = d; -- data.size = sizeof(diskNode) + rlen + nrlen; -- data.flags = DB_DBT_USERMEM; -- -- rc = db->put( db, txn, &key, &data, DB_NODUPDATA ); -- -- if (rc == 0) { -- BDB_ID2DISK( e->e_id, &nid ); -- BDB_ID2DISK( eip->bei_id, ptr ); -- d->nrdnlen[0] ^= 0x80; -- -- rc = db->put( db, txn, &key, &data, DB_NODUPDATA ); -- } -- -- /* Update all parents' IDL cache entries */ -- if ( rc == 0 && bdb->bi_idl_cache_size ) { -- ID tmp[2]; -- char *ptr = ((char *)&tmp[1])-1; -- key.data = ptr; -- key.size = sizeof(ID)+1; -- tmp[1] = eip->bei_id; -- *ptr = DN_ONE_PREFIX; -- bdb_idl_cache_add_id( bdb, db, &key, e->e_id ); -- if ( eip->bei_parent ) { -- *ptr = DN_SUBTREE_PREFIX; -- for (; eip && eip->bei_parent->bei_id; eip = eip->bei_parent) { -- tmp[1] = eip->bei_id; -- bdb_idl_cache_add_id( bdb, db, &key, e->e_id ); -- } -- /* Handle DB with empty suffix */ -- if ( !op->o_bd->be_suffix[0].bv_len && eip ) { -- tmp[1] = eip->bei_id; -- bdb_idl_cache_add_id( bdb, db, &key, e->e_id ); -- } -- } -- } -- -- op->o_tmpfree( d, op->o_tmpmemctx ); -- Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id_add 0x%lx: %d\n", e->e_id, rc, 0 ); -- -- return rc; --} -- --int --hdb_dn2id_delete( -- Operation *op, -- DB_TXN *txn, -- EntryInfo *eip, -- Entry *e ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- DB *db = bdb->bi_dn2id->bdi_db; -- DBT key, data; -- DBC *cursor; -- diskNode *d; -- int rc; -- ID nid; -- unsigned char dlen[2]; -- -- Debug( LDAP_DEBUG_TRACE, "=> hdb_dn2id_delete 0x%lx: \"%s\"\n", -- e->e_id, e->e_ndn, 0 ); -- -- DBTzero(&key); -- key.size = sizeof(ID); -- key.ulen = key.size; -- key.flags = DB_DBT_USERMEM; -- BDB_ID2DISK( eip->bei_id, &nid ); -- -- DBTzero(&data); -- data.size = sizeof(diskNode) + BEI(e)->bei_nrdn.bv_len - sizeof(ID) - 1; -- data.ulen = data.size; -- data.dlen = data.size; -- data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; -- -- key.data = &nid; -- -- d = op->o_tmpalloc( data.size, op->o_tmpmemctx ); -- d->nrdnlen[1] = BEI(e)->bei_nrdn.bv_len & 0xff; -- d->nrdnlen[0] = (BEI(e)->bei_nrdn.bv_len >> 8) | 0x80; -- dlen[0] = d->nrdnlen[0]; -- dlen[1] = d->nrdnlen[1]; -- memcpy( d->nrdn, BEI(e)->bei_nrdn.bv_val, BEI(e)->bei_nrdn.bv_len+1 ); -- data.data = d; -- -- rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags ); -- if ( rc ) goto func_leave; -- -- /* Delete our ID from the parent's list */ -- rc = cursor->c_get( cursor, &key, &data, DB_GET_BOTH_RANGE ); -- if ( rc == 0 ) { -- if ( dlen[1] == d->nrdnlen[1] && dlen[0] == d->nrdnlen[0] && -- !strcmp( d->nrdn, BEI(e)->bei_nrdn.bv_val )) -- rc = cursor->c_del( cursor, 0 ); -- else -- rc = DB_NOTFOUND; -- } -- -- /* Delete our ID from the tree. With sorted duplicates, this -- * will leave any child nodes still hanging around. This is OK -- * for modrdn, which will add our info back in later. -- */ -- if ( rc == 0 ) { -- BDB_ID2DISK( e->e_id, &nid ); -- rc = cursor->c_get( cursor, &key, &data, DB_SET ); -- if ( rc == 0 ) -- rc = cursor->c_del( cursor, 0 ); -- } -- -- cursor->c_close( cursor ); --func_leave: -- op->o_tmpfree( d, op->o_tmpmemctx ); -- -- /* Delete IDL cache entries */ -- if ( rc == 0 && bdb->bi_idl_cache_size ) { -- ID tmp[2]; -- char *ptr = ((char *)&tmp[1])-1; -- key.data = ptr; -- key.size = sizeof(ID)+1; -- tmp[1] = eip->bei_id; -- *ptr = DN_ONE_PREFIX; -- bdb_idl_cache_del_id( bdb, db, &key, e->e_id ); -- if ( eip ->bei_parent ) { -- *ptr = DN_SUBTREE_PREFIX; -- for (; eip && eip->bei_parent->bei_id; eip = eip->bei_parent) { -- tmp[1] = eip->bei_id; -- bdb_idl_cache_del_id( bdb, db, &key, e->e_id ); -- } -- /* Handle DB with empty suffix */ -- if ( !op->o_bd->be_suffix[0].bv_len && eip ) { -- tmp[1] = eip->bei_id; -- bdb_idl_cache_del_id( bdb, db, &key, e->e_id ); -- } -- } -- } -- Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id_delete 0x%lx: %d\n", e->e_id, rc, 0 ); -- return rc; --} -- -- --int --hdb_dn2id( -- Operation *op, -- struct berval *in, -- EntryInfo *ei, -- DB_TXN *txn, -- DBC **cursor ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- DB *db = bdb->bi_dn2id->bdi_db; -- DBT key, data; -- int rc = 0, nrlen; -- diskNode *d; -- char *ptr; -- unsigned char dlen[2]; -- ID idp, parentID; -- -- Debug( LDAP_DEBUG_TRACE, "=> hdb_dn2id(\"%s\")\n", in->bv_val, 0, 0 ); -- -- nrlen = dn_rdnlen( op->o_bd, in ); -- if (!nrlen) nrlen = in->bv_len; -- -- DBTzero(&key); -- key.size = sizeof(ID); -- key.data = &idp; -- key.ulen = sizeof(ID); -- key.flags = DB_DBT_USERMEM; -- parentID = ( ei->bei_parent != NULL ) ? ei->bei_parent->bei_id : 0; -- BDB_ID2DISK( parentID, &idp ); -- -- DBTzero(&data); -- data.size = sizeof(diskNode) + nrlen - sizeof(ID) - 1; -- data.ulen = data.size * 3; -- data.dlen = data.ulen; -- data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; -- -- rc = db->cursor( db, txn, cursor, bdb->bi_db_opflags ); -- if ( rc ) return rc; -- -- d = op->o_tmpalloc( data.size * 3, op->o_tmpmemctx ); -- d->nrdnlen[1] = nrlen & 0xff; -- d->nrdnlen[0] = (nrlen >> 8) | 0x80; -- dlen[0] = d->nrdnlen[0]; -- dlen[1] = d->nrdnlen[1]; -- ptr = lutil_strncopy( d->nrdn, in->bv_val, nrlen ); -- *ptr = '\0'; -- data.data = d; -- -- rc = (*cursor)->c_get( *cursor, &key, &data, DB_GET_BOTH_RANGE ); -- if ( rc == 0 && (dlen[1] != d->nrdnlen[1] || dlen[0] != d->nrdnlen[0] || -- strncmp( d->nrdn, in->bv_val, nrlen ))) { -- rc = DB_NOTFOUND; -- } -- if ( rc == 0 ) { -- ptr = (char *) data.data + data.size - sizeof(ID); -- BDB_DISK2ID( ptr, &ei->bei_id ); -- ei->bei_rdn.bv_len = data.size - sizeof(diskNode) - nrlen; -- ptr = d->nrdn + nrlen + 1; -- ber_str2bv( ptr, ei->bei_rdn.bv_len, 1, &ei->bei_rdn ); -- if ( ei->bei_parent != NULL && !ei->bei_parent->bei_dkids ) { -- db_recno_t dkids; -- /* How many children does the parent have? */ -- /* FIXME: do we need to lock the parent -- * entryinfo? Seems safe... -- */ -- (*cursor)->c_count( *cursor, &dkids, 0 ); -- ei->bei_parent->bei_dkids = dkids; -- } -- } -- -- op->o_tmpfree( d, op->o_tmpmemctx ); -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id: get failed: %s (%d)\n", -- db_strerror( rc ), rc, 0 ); -- } else { -- Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id: got id=0x%lx\n", -- ei->bei_id, 0, 0 ); -- } -- -- return rc; --} -- --int --hdb_dn2id_parent( -- Operation *op, -- DB_TXN *txn, -- EntryInfo *ei, -- ID *idp ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- DB *db = bdb->bi_dn2id->bdi_db; -- DBT key, data; -- DBC *cursor; -- int rc = 0; -- diskNode *d; -- char *ptr; -- ID nid; -- -- DBTzero(&key); -- key.size = sizeof(ID); -- key.data = &nid; -- key.ulen = sizeof(ID); -- key.flags = DB_DBT_USERMEM; -- BDB_ID2DISK( ei->bei_id, &nid ); -- -- DBTzero(&data); -- data.flags = DB_DBT_USERMEM; -- -- rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags ); -- if ( rc ) return rc; -- -- data.ulen = sizeof(diskNode) + (SLAP_LDAPDN_MAXLEN * 2); -- d = op->o_tmpalloc( data.ulen, op->o_tmpmemctx ); -- data.data = d; -- -- rc = cursor->c_get( cursor, &key, &data, DB_SET ); -- if ( rc == 0 ) { -- if (d->nrdnlen[0] & 0x80) { -- rc = LDAP_OTHER; -- } else { -- db_recno_t dkids; -- ptr = (char *) data.data + data.size - sizeof(ID); -- BDB_DISK2ID( ptr, idp ); -- ei->bei_nrdn.bv_len = (d->nrdnlen[0] << 8) | d->nrdnlen[1]; -- ber_str2bv( d->nrdn, ei->bei_nrdn.bv_len, 1, &ei->bei_nrdn ); -- ei->bei_rdn.bv_len = data.size - sizeof(diskNode) - -- ei->bei_nrdn.bv_len; -- ptr = d->nrdn + ei->bei_nrdn.bv_len + 1; -- ber_str2bv( ptr, ei->bei_rdn.bv_len, 1, &ei->bei_rdn ); -- /* How many children does this node have? */ -- cursor->c_count( cursor, &dkids, 0 ); -- ei->bei_dkids = dkids; -- } -- } -- cursor->c_close( cursor ); -- op->o_tmpfree( d, op->o_tmpmemctx ); -- return rc; --} -- --int --hdb_dn2id_children( -- Operation *op, -- DB_TXN *txn, -- Entry *e ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- DB *db = bdb->bi_dn2id->bdi_db; -- DBT key, data; -- DBC *cursor; -- int rc; -- ID id; -- diskNode d; -- -- DBTzero(&key); -- key.size = sizeof(ID); -- key.data = &e->e_id; -- key.flags = DB_DBT_USERMEM; -- BDB_ID2DISK( e->e_id, &id ); -- -- /* IDL cache is in host byte order */ -- if ( bdb->bi_idl_cache_size ) { -- rc = bdb_idl_cache_get( bdb, db, &key, NULL ); -- if ( rc != LDAP_NO_SUCH_OBJECT ) { -- return rc; -- } -- } -- -- key.data = &id; -- DBTzero(&data); -- data.data = &d; -- data.ulen = sizeof(d); -- data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; -- data.dlen = sizeof(d); -- -- rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags ); -- if ( rc ) return rc; -- -- rc = cursor->c_get( cursor, &key, &data, DB_SET ); -- if ( rc == 0 ) { -- db_recno_t dkids; -- rc = cursor->c_count( cursor, &dkids, 0 ); -- if ( rc == 0 ) { -- BEI(e)->bei_dkids = dkids; -- if ( dkids < 2 ) rc = DB_NOTFOUND; -- } -- } -- cursor->c_close( cursor ); -- return rc; --} -- --/* bdb_dn2idl: -- * We can't just use bdb_idl_fetch_key because -- * 1 - our data items are longer than just an entry ID -- * 2 - our data items are sorted alphabetically by nrdn, not by ID. -- * -- * We descend the tree recursively, so we define this cookie -- * to hold our necessary state information. The bdb_dn2idl_internal -- * function uses this cookie when calling itself. -- */ -- --struct dn2id_cookie { -- struct bdb_info *bdb; -- Operation *op; -- DB_TXN *txn; -- EntryInfo *ei; -- ID *ids; -- ID *tmp; -- ID *buf; -- DB *db; -- DBC *dbc; -- DBT key; -- DBT data; -- ID dbuf; -- ID id; -- ID nid; -- int rc; -- int depth; -- char need_sort; -- char prefix; --}; -- --static int --apply_func( -- void *data, -- void *arg ) --{ -- EntryInfo *ei = data; -- ID *idl = arg; -- -- bdb_idl_append_one( idl, ei->bei_id ); -- return 0; --} -- --static int --hdb_dn2idl_internal( -- struct dn2id_cookie *cx --) --{ -- BDB_IDL_ZERO( cx->tmp ); -- -- if ( cx->bdb->bi_idl_cache_size ) { -- char *ptr = ((char *)&cx->id)-1; -- -- cx->key.data = ptr; -- cx->key.size = sizeof(ID)+1; -- if ( cx->prefix == DN_SUBTREE_PREFIX ) { -- ID *ids = cx->depth ? cx->tmp : cx->ids; -- *ptr = cx->prefix; -- cx->rc = bdb_idl_cache_get(cx->bdb, cx->db, &cx->key, ids); -- if ( cx->rc == LDAP_SUCCESS ) { -- if ( cx->depth ) { -- bdb_idl_delete( cx->tmp, cx->id ); /* ITS#6983, drop our own ID */ -- bdb_idl_append( cx->ids, cx->tmp ); -- cx->need_sort = 1; -- } -- return cx->rc; -- } -- } -- *ptr = DN_ONE_PREFIX; -- cx->rc = bdb_idl_cache_get(cx->bdb, cx->db, &cx->key, cx->tmp); -- if ( cx->rc == LDAP_SUCCESS ) { -- goto gotit; -- } -- if ( cx->rc == DB_NOTFOUND ) { -- return cx->rc; -- } -- } -- -- bdb_cache_entryinfo_lock( cx->ei ); -- -- /* If number of kids in the cache differs from on-disk, load -- * up all the kids from the database -- */ -- if ( cx->ei->bei_ckids+1 != cx->ei->bei_dkids ) { -- EntryInfo ei; -- db_recno_t dkids = cx->ei->bei_dkids; -- ei.bei_parent = cx->ei; -- -- /* Only one thread should load the cache */ -- while ( cx->ei->bei_state & CACHE_ENTRY_ONELEVEL ) { -- bdb_cache_entryinfo_unlock( cx->ei ); -- ldap_pvt_thread_yield(); -- bdb_cache_entryinfo_lock( cx->ei ); -- if ( cx->ei->bei_ckids+1 == cx->ei->bei_dkids ) { -- goto synced; -- } -- } -- -- cx->ei->bei_state |= CACHE_ENTRY_ONELEVEL; -- -- bdb_cache_entryinfo_unlock( cx->ei ); -- -- cx->rc = cx->db->cursor( cx->db, NULL, &cx->dbc, -- cx->bdb->bi_db_opflags ); -- if ( cx->rc ) -- goto done_one; -- -- cx->data.data = &cx->dbuf; -- cx->data.ulen = sizeof(ID); -- cx->data.dlen = sizeof(ID); -- cx->data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; -- -- /* The first item holds the parent ID. Ignore it. */ -- cx->key.data = &cx->nid; -- cx->key.size = sizeof(ID); -- cx->rc = cx->dbc->c_get( cx->dbc, &cx->key, &cx->data, DB_SET ); -- if ( cx->rc ) { -- cx->dbc->c_close( cx->dbc ); -- goto done_one; -- } -- -- /* If the on-disk count is zero we've never checked it. -- * Count it now. -- */ -- if ( !dkids ) { -- cx->dbc->c_count( cx->dbc, &dkids, 0 ); -- cx->ei->bei_dkids = dkids; -- } -- -- cx->data.data = cx->buf; -- cx->data.ulen = BDB_IDL_UM_SIZE * sizeof(ID); -- cx->data.flags = DB_DBT_USERMEM; -- -- if ( dkids > 1 ) { -- /* Fetch the rest of the IDs in a loop... */ -- while ( (cx->rc = cx->dbc->c_get( cx->dbc, &cx->key, &cx->data, -- DB_MULTIPLE | DB_NEXT_DUP )) == 0 ) { -- u_int8_t *j; -- size_t len; -- void *ptr; -- DB_MULTIPLE_INIT( ptr, &cx->data ); -- while (ptr) { -- DB_MULTIPLE_NEXT( ptr, &cx->data, j, len ); -- if (j) { -- EntryInfo *ei2; -- diskNode *d = (diskNode *)j; -- short nrlen; -- -- BDB_DISK2ID( j + len - sizeof(ID), &ei.bei_id ); -- nrlen = ((d->nrdnlen[0] ^ 0x80) << 8) | d->nrdnlen[1]; -- ei.bei_nrdn.bv_len = nrlen; -- /* nrdn/rdn are set in-place. -- * hdb_cache_load will copy them as needed -- */ -- ei.bei_nrdn.bv_val = d->nrdn; -- ei.bei_rdn.bv_len = len - sizeof(diskNode) -- - ei.bei_nrdn.bv_len; -- ei.bei_rdn.bv_val = d->nrdn + ei.bei_nrdn.bv_len + 1; -- bdb_idl_append_one( cx->tmp, ei.bei_id ); -- hdb_cache_load( cx->bdb, &ei, &ei2 ); -- } -- } -- } -- } -- -- cx->rc = cx->dbc->c_close( cx->dbc ); --done_one: -- bdb_cache_entryinfo_lock( cx->ei ); -- cx->ei->bei_state &= ~CACHE_ENTRY_ONELEVEL; -- bdb_cache_entryinfo_unlock( cx->ei ); -- if ( cx->rc ) -- return cx->rc; -- -- } else { -- /* The in-memory cache is in sync with the on-disk data. -- * do we have any kids? -- */ --synced: -- cx->rc = 0; -- if ( cx->ei->bei_ckids > 0 ) { -- /* Walk the kids tree; order is irrelevant since bdb_idl_sort -- * will sort it later. -- */ -- avl_apply( cx->ei->bei_kids, apply_func, -- cx->tmp, -1, AVL_POSTORDER ); -- } -- bdb_cache_entryinfo_unlock( cx->ei ); -- } -- -- if ( !BDB_IDL_IS_RANGE( cx->tmp ) && cx->tmp[0] > 3 ) -- bdb_idl_sort( cx->tmp, cx->buf ); -- if ( cx->bdb->bi_idl_cache_max_size && !BDB_IDL_IS_ZERO( cx->tmp )) { -- char *ptr = ((char *)&cx->id)-1; -- cx->key.data = ptr; -- cx->key.size = sizeof(ID)+1; -- *ptr = DN_ONE_PREFIX; -- bdb_idl_cache_put( cx->bdb, cx->db, &cx->key, cx->tmp, cx->rc ); -- } -- --gotit: -- if ( !BDB_IDL_IS_ZERO( cx->tmp )) { -- if ( cx->prefix == DN_SUBTREE_PREFIX ) { -- bdb_idl_append( cx->ids, cx->tmp ); -- cx->need_sort = 1; -- if ( !(cx->ei->bei_state & CACHE_ENTRY_NO_GRANDKIDS)) { -- ID *save, idcurs; -- EntryInfo *ei = cx->ei; -- int nokids = 1; -- save = cx->op->o_tmpalloc( BDB_IDL_SIZEOF( cx->tmp ), -- cx->op->o_tmpmemctx ); -- BDB_IDL_CPY( save, cx->tmp ); -- -- idcurs = 0; -- cx->depth++; -- for ( cx->id = bdb_idl_first( save, &idcurs ); -- cx->id != NOID; -- cx->id = bdb_idl_next( save, &idcurs )) { -- EntryInfo *ei2; -- cx->ei = NULL; -- if ( bdb_cache_find_id( cx->op, cx->txn, cx->id, &cx->ei, -- ID_NOENTRY, NULL )) -- continue; -- if ( cx->ei ) { -- ei2 = cx->ei; -- if ( !( ei2->bei_state & CACHE_ENTRY_NO_KIDS )) { -- BDB_ID2DISK( cx->id, &cx->nid ); -- hdb_dn2idl_internal( cx ); -- if ( !BDB_IDL_IS_ZERO( cx->tmp )) -- nokids = 0; -- } -- bdb_cache_entryinfo_lock( ei2 ); -- ei2->bei_finders--; -- bdb_cache_entryinfo_unlock( ei2 ); -- } -- } -- cx->depth--; -- cx->op->o_tmpfree( save, cx->op->o_tmpmemctx ); -- if ( nokids ) { -- bdb_cache_entryinfo_lock( ei ); -- ei->bei_state |= CACHE_ENTRY_NO_GRANDKIDS; -- bdb_cache_entryinfo_unlock( ei ); -- } -- } -- /* Make sure caller knows it had kids! */ -- cx->tmp[0]=1; -- -- cx->rc = 0; -- } else { -- BDB_IDL_CPY( cx->ids, cx->tmp ); -- } -- } -- return cx->rc; --} -- --int --hdb_dn2idl( -- Operation *op, -- DB_TXN *txn, -- struct berval *ndn, -- EntryInfo *ei, -- ID *ids, -- ID *stack ) --{ -- struct bdb_info *bdb = (struct bdb_info *)op->o_bd->be_private; -- struct dn2id_cookie cx; -- -- Debug( LDAP_DEBUG_TRACE, "=> hdb_dn2idl(\"%s\")\n", -- ndn->bv_val, 0, 0 ); -- --#ifndef BDB_MULTIPLE_SUFFIXES -- if ( op->ors_scope != LDAP_SCOPE_ONELEVEL && -- ( ei->bei_id == 0 || -- ( ei->bei_parent->bei_id == 0 && op->o_bd->be_suffix[0].bv_len ))) -- { -- BDB_IDL_ALL( bdb, ids ); -- return 0; -- } --#endif -- -- cx.id = ei->bei_id; -- BDB_ID2DISK( cx.id, &cx.nid ); -- cx.ei = ei; -- cx.bdb = bdb; -- cx.db = cx.bdb->bi_dn2id->bdi_db; -- cx.prefix = (op->ors_scope == LDAP_SCOPE_ONELEVEL) ? -- DN_ONE_PREFIX : DN_SUBTREE_PREFIX; -- cx.ids = ids; -- cx.tmp = stack; -- cx.buf = stack + BDB_IDL_UM_SIZE; -- cx.op = op; -- cx.txn = txn; -- cx.need_sort = 0; -- cx.depth = 0; -- -- if ( cx.prefix == DN_SUBTREE_PREFIX ) { -- ids[0] = 1; -- ids[1] = cx.id; -- } else { -- BDB_IDL_ZERO( ids ); -- } -- if ( cx.ei->bei_state & CACHE_ENTRY_NO_KIDS ) -- return LDAP_SUCCESS; -- -- DBTzero(&cx.key); -- cx.key.ulen = sizeof(ID); -- cx.key.size = sizeof(ID); -- cx.key.flags = DB_DBT_USERMEM; -- -- DBTzero(&cx.data); -- -- hdb_dn2idl_internal(&cx); -- if ( cx.need_sort ) { -- char *ptr = ((char *)&cx.id)-1; -- if ( !BDB_IDL_IS_RANGE( cx.ids ) && cx.ids[0] > 3 ) -- bdb_idl_sort( cx.ids, cx.tmp ); -- cx.key.data = ptr; -- cx.key.size = sizeof(ID)+1; -- *ptr = cx.prefix; -- cx.id = ei->bei_id; -- if ( cx.bdb->bi_idl_cache_max_size ) -- bdb_idl_cache_put( cx.bdb, cx.db, &cx.key, cx.ids, cx.rc ); -- } -- -- if ( cx.rc == DB_NOTFOUND ) -- cx.rc = LDAP_SUCCESS; -- -- return cx.rc; --} --#endif /* BDB_HIER */ -diff --git a/servers/slapd/back-bdb/error.c b/servers/slapd/back-bdb/error.c -deleted file mode 100644 -index cf823ec..0000000 ---- a/servers/slapd/back-bdb/error.c -+++ /dev/null -@@ -1,62 +0,0 @@ --/* error.c - BDB errcall routine */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include --#include -- --#include "slap.h" --#include "back-bdb.h" -- --#if DB_VERSION_FULL < 0x04030000 --void bdb_errcall( const char *pfx, char * msg ) --#else --void bdb_errcall( const DB_ENV *env, const char *pfx, const char * msg ) --#endif --{ --#ifdef HAVE_EBCDIC -- if ( msg[0] > 0x7f ) -- __etoa( msg ); --#endif -- Debug( LDAP_DEBUG_ANY, "bdb(%s): %s\n", pfx, msg, 0 ); --} -- --#if DB_VERSION_FULL >= 0x04030000 --void bdb_msgcall( const DB_ENV *env, const char *msg ) --{ --#ifdef HAVE_EBCDIC -- if ( msg[0] > 0x7f ) -- __etoa( msg ); --#endif -- Debug( LDAP_DEBUG_TRACE, "bdb: %s\n", msg, 0, 0 ); --} --#endif -- --#ifdef HAVE_EBCDIC -- --#undef db_strerror -- --/* Not re-entrant! */ --char *ebcdic_dberror( int rc ) --{ -- static char msg[1024]; -- -- strcpy( msg, db_strerror( rc ) ); -- __etoa( msg ); -- return msg; --} --#endif -diff --git a/servers/slapd/back-bdb/extended.c b/servers/slapd/back-bdb/extended.c -deleted file mode 100644 -index 74d85df..0000000 ---- a/servers/slapd/back-bdb/extended.c -+++ /dev/null -@@ -1,54 +0,0 @@ --/* extended.c - bdb backend extended routines */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include --#include -- --#include "back-bdb.h" --#include "lber_pvt.h" -- --static struct exop { -- struct berval *oid; -- BI_op_extended *extended; --} exop_table[] = { -- { NULL, NULL } --}; -- --int --bdb_extended( Operation *op, SlapReply *rs ) --/* struct berval *reqoid, -- struct berval *reqdata, -- char **rspoid, -- struct berval **rspdata, -- LDAPControl *** rspctrls, -- const char** text, -- BerVarray *refs --) */ --{ -- int i; -- -- for( i=0; exop_table[i].extended != NULL; i++ ) { -- if( ber_bvcmp( exop_table[i].oid, &op->oq_extended.rs_reqoid ) == 0 ) { -- return (exop_table[i].extended)( op, rs ); -- } -- } -- -- rs->sr_text = "not supported within naming context"; -- return rs->sr_err = LDAP_UNWILLING_TO_PERFORM; --} -- -diff --git a/servers/slapd/back-bdb/filterindex.c b/servers/slapd/back-bdb/filterindex.c -deleted file mode 100644 -index c04c68c..0000000 ---- a/servers/slapd/back-bdb/filterindex.c -+++ /dev/null -@@ -1,1183 +0,0 @@ --/* filterindex.c - generate the list of candidate entries from a filter */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include --#include -- --#include "back-bdb.h" --#include "idl.h" --#ifdef LDAP_COMP_MATCH --#include --#endif -- --static int presence_candidates( -- Operation *op, -- DB_TXN *rtxn, -- AttributeDescription *desc, -- ID *ids ); -- --static int equality_candidates( -- Operation *op, -- DB_TXN *rtxn, -- AttributeAssertion *ava, -- ID *ids, -- ID *tmp ); --static int inequality_candidates( -- Operation *op, -- DB_TXN *rtxn, -- AttributeAssertion *ava, -- ID *ids, -- ID *tmp, -- int gtorlt ); --static int approx_candidates( -- Operation *op, -- DB_TXN *rtxn, -- AttributeAssertion *ava, -- ID *ids, -- ID *tmp ); --static int substring_candidates( -- Operation *op, -- DB_TXN *rtxn, -- SubstringsAssertion *sub, -- ID *ids, -- ID *tmp ); -- --static int list_candidates( -- Operation *op, -- DB_TXN *rtxn, -- Filter *flist, -- int ftype, -- ID *ids, -- ID *tmp, -- ID *stack ); -- --static int --ext_candidates( -- Operation *op, -- DB_TXN *rtxn, -- MatchingRuleAssertion *mra, -- ID *ids, -- ID *tmp, -- ID *stack); -- --#ifdef LDAP_COMP_MATCH --static int --comp_candidates ( -- Operation *op, -- DB_TXN *rtxn, -- MatchingRuleAssertion *mra, -- ComponentFilter *f, -- ID *ids, -- ID *tmp, -- ID *stack); -- --static int --ava_comp_candidates ( -- Operation *op, -- DB_TXN *rtxn, -- AttributeAssertion *ava, -- AttributeAliasing *aa, -- ID *ids, -- ID *tmp, -- ID *stack); --#endif -- --int --bdb_filter_candidates( -- Operation *op, -- DB_TXN *rtxn, -- Filter *f, -- ID *ids, -- ID *tmp, -- ID *stack ) --{ -- int rc = 0; --#ifdef LDAP_COMP_MATCH -- AttributeAliasing *aa; --#endif -- Debug( LDAP_DEBUG_FILTER, "=> bdb_filter_candidates\n", 0, 0, 0 ); -- -- if ( f->f_choice & SLAPD_FILTER_UNDEFINED ) { -- BDB_IDL_ZERO( ids ); -- goto out; -- } -- -- switch ( f->f_choice ) { -- case SLAPD_FILTER_COMPUTED: -- switch( f->f_result ) { -- case SLAPD_COMPARE_UNDEFINED: -- /* This technically is not the same as FALSE, but it -- * certainly will produce no matches. -- */ -- /* FALL THRU */ -- case LDAP_COMPARE_FALSE: -- BDB_IDL_ZERO( ids ); -- break; -- case LDAP_COMPARE_TRUE: { -- struct bdb_info *bdb = (struct bdb_info *)op->o_bd->be_private; -- BDB_IDL_ALL( bdb, ids ); -- } break; -- case LDAP_SUCCESS: -- /* this is a pre-computed scope, leave it alone */ -- break; -- } -- break; -- case LDAP_FILTER_PRESENT: -- Debug( LDAP_DEBUG_FILTER, "\tPRESENT\n", 0, 0, 0 ); -- rc = presence_candidates( op, rtxn, f->f_desc, ids ); -- break; -- -- case LDAP_FILTER_EQUALITY: -- Debug( LDAP_DEBUG_FILTER, "\tEQUALITY\n", 0, 0, 0 ); --#ifdef LDAP_COMP_MATCH -- if ( is_aliased_attribute && ( aa = is_aliased_attribute ( f->f_ava->aa_desc ) ) ) { -- rc = ava_comp_candidates ( op, rtxn, f->f_ava, aa, ids, tmp, stack ); -- } -- else --#endif -- { -- rc = equality_candidates( op, rtxn, f->f_ava, ids, tmp ); -- } -- break; -- -- case LDAP_FILTER_APPROX: -- Debug( LDAP_DEBUG_FILTER, "\tAPPROX\n", 0, 0, 0 ); -- rc = approx_candidates( op, rtxn, f->f_ava, ids, tmp ); -- break; -- -- case LDAP_FILTER_SUBSTRINGS: -- Debug( LDAP_DEBUG_FILTER, "\tSUBSTRINGS\n", 0, 0, 0 ); -- rc = substring_candidates( op, rtxn, f->f_sub, ids, tmp ); -- break; -- -- case LDAP_FILTER_GE: -- /* if no GE index, use pres */ -- Debug( LDAP_DEBUG_FILTER, "\tGE\n", 0, 0, 0 ); -- if( f->f_ava->aa_desc->ad_type->sat_ordering && -- ( f->f_ava->aa_desc->ad_type->sat_ordering->smr_usage & SLAP_MR_ORDERED_INDEX ) ) -- rc = inequality_candidates( op, rtxn, f->f_ava, ids, tmp, LDAP_FILTER_GE ); -- else -- rc = presence_candidates( op, rtxn, f->f_ava->aa_desc, ids ); -- break; -- -- case LDAP_FILTER_LE: -- /* if no LE index, use pres */ -- Debug( LDAP_DEBUG_FILTER, "\tLE\n", 0, 0, 0 ); -- if( f->f_ava->aa_desc->ad_type->sat_ordering && -- ( f->f_ava->aa_desc->ad_type->sat_ordering->smr_usage & SLAP_MR_ORDERED_INDEX ) ) -- rc = inequality_candidates( op, rtxn, f->f_ava, ids, tmp, LDAP_FILTER_LE ); -- else -- rc = presence_candidates( op, rtxn, f->f_ava->aa_desc, ids ); -- break; -- -- case LDAP_FILTER_NOT: -- /* no indexing to support NOT filters */ -- Debug( LDAP_DEBUG_FILTER, "\tNOT\n", 0, 0, 0 ); -- { struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- BDB_IDL_ALL( bdb, ids ); -- } -- break; -- -- case LDAP_FILTER_AND: -- Debug( LDAP_DEBUG_FILTER, "\tAND\n", 0, 0, 0 ); -- rc = list_candidates( op, rtxn, -- f->f_and, LDAP_FILTER_AND, ids, tmp, stack ); -- break; -- -- case LDAP_FILTER_OR: -- Debug( LDAP_DEBUG_FILTER, "\tOR\n", 0, 0, 0 ); -- rc = list_candidates( op, rtxn, -- f->f_or, LDAP_FILTER_OR, ids, tmp, stack ); -- break; -- case LDAP_FILTER_EXT: -- Debug( LDAP_DEBUG_FILTER, "\tEXT\n", 0, 0, 0 ); -- rc = ext_candidates( op, rtxn, f->f_mra, ids, tmp, stack ); -- break; -- default: -- Debug( LDAP_DEBUG_FILTER, "\tUNKNOWN %lu\n", -- (unsigned long) f->f_choice, 0, 0 ); -- /* Must not return NULL, otherwise extended filters break */ -- { struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- BDB_IDL_ALL( bdb, ids ); -- } -- } -- --out: -- Debug( LDAP_DEBUG_FILTER, -- "<= bdb_filter_candidates: id=%ld first=%ld last=%ld\n", -- (long) ids[0], -- (long) BDB_IDL_FIRST( ids ), -- (long) BDB_IDL_LAST( ids ) ); -- -- return rc; --} -- --#ifdef LDAP_COMP_MATCH --static int --comp_list_candidates( -- Operation *op, -- DB_TXN *rtxn, -- MatchingRuleAssertion* mra, -- ComponentFilter *flist, -- int ftype, -- ID *ids, -- ID *tmp, -- ID *save ) --{ -- int rc = 0; -- ComponentFilter *f; -- -- Debug( LDAP_DEBUG_FILTER, "=> comp_list_candidates 0x%x\n", ftype, 0, 0 ); -- for ( f = flist; f != NULL; f = f->cf_next ) { -- /* ignore precomputed scopes */ -- if ( f->cf_choice == SLAPD_FILTER_COMPUTED && -- f->cf_result == LDAP_SUCCESS ) { -- continue; -- } -- BDB_IDL_ZERO( save ); -- rc = comp_candidates( op, rtxn, mra, f, save, tmp, save+BDB_IDL_UM_SIZE ); -- -- if ( rc != 0 ) { -- if ( ftype == LDAP_COMP_FILTER_AND ) { -- rc = 0; -- continue; -- } -- break; -- } -- -- if ( ftype == LDAP_COMP_FILTER_AND ) { -- if ( f == flist ) { -- BDB_IDL_CPY( ids, save ); -- } else { -- bdb_idl_intersection( ids, save ); -- } -- if( BDB_IDL_IS_ZERO( ids ) ) -- break; -- } else { -- if ( f == flist ) { -- BDB_IDL_CPY( ids, save ); -- } else { -- bdb_idl_union( ids, save ); -- } -- } -- } -- -- if( rc == LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_FILTER, -- "<= comp_list_candidates: id=%ld first=%ld last=%ld\n", -- (long) ids[0], -- (long) BDB_IDL_FIRST(ids), -- (long) BDB_IDL_LAST(ids) ); -- -- } else { -- Debug( LDAP_DEBUG_FILTER, -- "<= comp_list_candidates: undefined rc=%d\n", -- rc, 0, 0 ); -- } -- -- return rc; --} -- --static int --comp_equality_candidates ( -- Operation *op, -- DB_TXN *rtxn, -- MatchingRuleAssertion *mra, -- ComponentAssertion *ca, -- ID *ids, -- ID *tmp, -- ID *stack) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- DB *db; -- int i; -- int rc; -- slap_mask_t mask; -- struct berval prefix = {0, NULL}; -- struct berval *keys = NULL; -- MatchingRule *mr = mra->ma_rule; -- Syntax *sat_syntax; -- ComponentReference* cr_list, *cr; -- AttrInfo *ai; -- -- BDB_IDL_ALL( bdb, ids ); -- -- if ( !ca->ca_comp_ref ) -- return 0; -- -- ai = bdb_attr_mask( op->o_bd->be_private, mra->ma_desc ); -- if( ai ) { -- cr_list = ai->ai_cr; -- } -- else { -- return 0; -- } -- /* find a component reference to be indexed */ -- sat_syntax = ca->ca_ma_rule->smr_syntax; -- for ( cr = cr_list ; cr ; cr = cr->cr_next ) { -- if ( cr->cr_string.bv_len == ca->ca_comp_ref->cr_string.bv_len && -- strncmp( cr->cr_string.bv_val, ca->ca_comp_ref->cr_string.bv_val,cr->cr_string.bv_len ) == 0 ) -- break; -- } -- -- if ( !cr ) -- return 0; -- -- rc = bdb_index_param( op->o_bd, mra->ma_desc, LDAP_FILTER_EQUALITY, -- &db, &mask, &prefix ); -- -- if( rc != LDAP_SUCCESS ) { -- return 0; -- } -- -- if( !mr ) { -- return 0; -- } -- -- if( !mr->smr_filter ) { -- return 0; -- } -- -- rc = (ca->ca_ma_rule->smr_filter)( -- LDAP_FILTER_EQUALITY, -- cr->cr_indexmask, -- sat_syntax, -- ca->ca_ma_rule, -- &prefix, -- &ca->ca_ma_value, -- &keys, op->o_tmpmemctx ); -- -- if( rc != LDAP_SUCCESS ) { -- return 0; -- } -- -- if( keys == NULL ) { -- return 0; -- } -- for ( i= 0; keys[i].bv_val != NULL; i++ ) { -- rc = bdb_key_read( op->o_bd, db, rtxn, &keys[i], tmp, NULL, 0 ); -- -- if( rc == DB_NOTFOUND ) { -- BDB_IDL_ZERO( ids ); -- rc = 0; -- break; -- } else if( rc != LDAP_SUCCESS ) { -- break; -- } -- -- if( BDB_IDL_IS_ZERO( tmp ) ) { -- BDB_IDL_ZERO( ids ); -- break; -- } -- -- if ( i == 0 ) { -- BDB_IDL_CPY( ids, tmp ); -- } else { -- bdb_idl_intersection( ids, tmp ); -- } -- -- if( BDB_IDL_IS_ZERO( ids ) ) -- break; -- } -- ber_bvarray_free_x( keys, op->o_tmpmemctx ); -- -- Debug( LDAP_DEBUG_TRACE, -- "<= comp_equality_candidates: id=%ld, first=%ld, last=%ld\n", -- (long) ids[0], -- (long) BDB_IDL_FIRST(ids), -- (long) BDB_IDL_LAST(ids) ); -- return( rc ); --} -- --static int --ava_comp_candidates ( -- Operation *op, -- DB_TXN *rtxn, -- AttributeAssertion *ava, -- AttributeAliasing *aa, -- ID *ids, -- ID *tmp, -- ID *stack ) --{ -- MatchingRuleAssertion mra; -- -- mra.ma_rule = ava->aa_desc->ad_type->sat_equality; -- if ( !mra.ma_rule ) { -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- BDB_IDL_ALL( bdb, ids ); -- return 0; -- } -- mra.ma_desc = aa->aa_aliased_ad; -- mra.ma_rule = ava->aa_desc->ad_type->sat_equality; -- -- return comp_candidates ( op, rtxn, &mra, ava->aa_cf, ids, tmp, stack ); --} -- --static int --comp_candidates ( -- Operation *op, -- DB_TXN *rtxn, -- MatchingRuleAssertion *mra, -- ComponentFilter *f, -- ID *ids, -- ID *tmp, -- ID *stack) --{ -- int rc; -- -- if ( !f ) return LDAP_PROTOCOL_ERROR; -- -- Debug( LDAP_DEBUG_FILTER, "comp_candidates\n", 0, 0, 0 ); -- switch ( f->cf_choice ) { -- case SLAPD_FILTER_COMPUTED: -- rc = f->cf_result; -- break; -- case LDAP_COMP_FILTER_AND: -- rc = comp_list_candidates( op, rtxn, mra, f->cf_and, LDAP_COMP_FILTER_AND, ids, tmp, stack ); -- break; -- case LDAP_COMP_FILTER_OR: -- rc = comp_list_candidates( op, rtxn, mra, f->cf_or, LDAP_COMP_FILTER_OR, ids, tmp, stack ); -- break; -- case LDAP_COMP_FILTER_NOT: -- /* No component indexing supported for NOT filter */ -- Debug( LDAP_DEBUG_FILTER, "\tComponent NOT\n", 0, 0, 0 ); -- { -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- BDB_IDL_ALL( bdb, ids ); -- } -- rc = LDAP_PROTOCOL_ERROR; -- break; -- case LDAP_COMP_FILTER_ITEM: -- rc = comp_equality_candidates( op, rtxn, mra, f->cf_ca, ids, tmp, stack ); -- break; -- default: -- { -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- BDB_IDL_ALL( bdb, ids ); -- } -- rc = LDAP_PROTOCOL_ERROR; -- } -- -- return( rc ); --} --#endif -- --static int --ext_candidates( -- Operation *op, -- DB_TXN *rtxn, -- MatchingRuleAssertion *mra, -- ID *ids, -- ID *tmp, -- ID *stack) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- --#ifdef LDAP_COMP_MATCH -- /* -- * Currently Only Component Indexing for componentFilterMatch is supported -- * Indexing for an extensible filter is not supported yet -- */ -- if ( mra->ma_cf ) { -- return comp_candidates ( op, rtxn, mra, mra->ma_cf, ids, tmp, stack); -- } --#endif -- if ( mra->ma_desc == slap_schema.si_ad_entryDN ) { -- int rc; -- EntryInfo *ei; -- -- BDB_IDL_ZERO( ids ); -- if ( mra->ma_rule == slap_schema.si_mr_distinguishedNameMatch ) { -- ei = NULL; -- rc = bdb_cache_find_ndn( op, rtxn, &mra->ma_value, &ei ); -- if ( rc == LDAP_SUCCESS ) -- bdb_idl_insert( ids, ei->bei_id ); -- if ( ei ) -- bdb_cache_entryinfo_unlock( ei ); -- return 0; -- } else if ( mra->ma_rule && mra->ma_rule->smr_match == -- dnRelativeMatch && dnIsSuffix( &mra->ma_value, -- op->o_bd->be_nsuffix )) { -- int scope; -- if ( mra->ma_rule == slap_schema.si_mr_dnSuperiorMatch ) { -- struct berval pdn; -- ei = NULL; -- dnParent( &mra->ma_value, &pdn ); -- bdb_cache_find_ndn( op, rtxn, &pdn, &ei ); -- if ( ei ) { -- bdb_cache_entryinfo_unlock( ei ); -- while ( ei && ei->bei_id ) { -- bdb_idl_insert( ids, ei->bei_id ); -- ei = ei->bei_parent; -- } -- } -- return 0; -- } -- if ( mra->ma_rule == slap_schema.si_mr_dnSubtreeMatch ) -- scope = LDAP_SCOPE_SUBTREE; -- else if ( mra->ma_rule == slap_schema.si_mr_dnOneLevelMatch ) -- scope = LDAP_SCOPE_ONELEVEL; -- else if ( mra->ma_rule == slap_schema.si_mr_dnSubordinateMatch ) -- scope = LDAP_SCOPE_SUBORDINATE; -- else -- scope = LDAP_SCOPE_BASE; -- if ( scope > LDAP_SCOPE_BASE ) { -- ei = NULL; -- rc = bdb_cache_find_ndn( op, rtxn, &mra->ma_value, &ei ); -- if ( ei ) -- bdb_cache_entryinfo_unlock( ei ); -- if ( rc == LDAP_SUCCESS ) { -- int sc = op->ors_scope; -- op->ors_scope = scope; -- rc = bdb_dn2idl( op, rtxn, &mra->ma_value, ei, ids, -- stack ); -- op->ors_scope = sc; -- } -- return 0; -- } -- } -- } -- -- BDB_IDL_ALL( bdb, ids ); -- return 0; --} -- --static int --list_candidates( -- Operation *op, -- DB_TXN *rtxn, -- Filter *flist, -- int ftype, -- ID *ids, -- ID *tmp, -- ID *save ) --{ -- int rc = 0; -- Filter *f; -- -- Debug( LDAP_DEBUG_FILTER, "=> bdb_list_candidates 0x%x\n", ftype, 0, 0 ); -- for ( f = flist; f != NULL; f = f->f_next ) { -- /* ignore precomputed scopes */ -- if ( f->f_choice == SLAPD_FILTER_COMPUTED && -- f->f_result == LDAP_SUCCESS ) { -- continue; -- } -- BDB_IDL_ZERO( save ); -- rc = bdb_filter_candidates( op, rtxn, f, save, tmp, -- save+BDB_IDL_UM_SIZE ); -- -- if ( rc != 0 ) { -- if ( rc == DB_LOCK_DEADLOCK ) -- return rc; -- -- if ( ftype == LDAP_FILTER_AND ) { -- rc = 0; -- continue; -- } -- break; -- } -- -- -- if ( ftype == LDAP_FILTER_AND ) { -- if ( f == flist ) { -- BDB_IDL_CPY( ids, save ); -- } else { -- bdb_idl_intersection( ids, save ); -- } -- if( BDB_IDL_IS_ZERO( ids ) ) -- break; -- } else { -- if ( f == flist ) { -- BDB_IDL_CPY( ids, save ); -- } else { -- bdb_idl_union( ids, save ); -- } -- } -- } -- -- if( rc == LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_FILTER, -- "<= bdb_list_candidates: id=%ld first=%ld last=%ld\n", -- (long) ids[0], -- (long) BDB_IDL_FIRST(ids), -- (long) BDB_IDL_LAST(ids) ); -- -- } else { -- Debug( LDAP_DEBUG_FILTER, -- "<= bdb_list_candidates: undefined rc=%d\n", -- rc, 0, 0 ); -- } -- -- return rc; --} -- --static int --presence_candidates( -- Operation *op, -- DB_TXN *rtxn, -- AttributeDescription *desc, -- ID *ids ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- DB *db; -- int rc; -- slap_mask_t mask; -- struct berval prefix = {0, NULL}; -- -- Debug( LDAP_DEBUG_TRACE, "=> bdb_presence_candidates (%s)\n", -- desc->ad_cname.bv_val, 0, 0 ); -- -- BDB_IDL_ALL( bdb, ids ); -- -- if( desc == slap_schema.si_ad_objectClass ) { -- return 0; -- } -- -- rc = bdb_index_param( op->o_bd, desc, LDAP_FILTER_PRESENT, -- &db, &mask, &prefix ); -- -- if( rc == LDAP_INAPPROPRIATE_MATCHING ) { -- /* not indexed */ -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_presence_candidates: (%s) not indexed\n", -- desc->ad_cname.bv_val, 0, 0 ); -- return 0; -- } -- -- if( rc != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_presence_candidates: (%s) index_param " -- "returned=%d\n", -- desc->ad_cname.bv_val, rc, 0 ); -- return 0; -- } -- -- if( prefix.bv_val == NULL ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_presence_candidates: (%s) no prefix\n", -- desc->ad_cname.bv_val, 0, 0 ); -- return -1; -- } -- -- rc = bdb_key_read( op->o_bd, db, rtxn, &prefix, ids, NULL, 0 ); -- -- if( rc == DB_NOTFOUND ) { -- BDB_IDL_ZERO( ids ); -- rc = 0; -- } else if( rc != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_presense_candidates: (%s) " -- "key read failed (%d)\n", -- desc->ad_cname.bv_val, rc, 0 ); -- goto done; -- } -- -- Debug(LDAP_DEBUG_TRACE, -- "<= bdb_presence_candidates: id=%ld first=%ld last=%ld\n", -- (long) ids[0], -- (long) BDB_IDL_FIRST(ids), -- (long) BDB_IDL_LAST(ids) ); -- --done: -- return rc; --} -- --static int --equality_candidates( -- Operation *op, -- DB_TXN *rtxn, -- AttributeAssertion *ava, -- ID *ids, -- ID *tmp ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- DB *db; -- int i; -- int rc; -- slap_mask_t mask; -- struct berval prefix = {0, NULL}; -- struct berval *keys = NULL; -- MatchingRule *mr; -- -- Debug( LDAP_DEBUG_TRACE, "=> bdb_equality_candidates (%s)\n", -- ava->aa_desc->ad_cname.bv_val, 0, 0 ); -- -- if ( ava->aa_desc == slap_schema.si_ad_entryDN ) { -- EntryInfo *ei = NULL; -- rc = bdb_cache_find_ndn( op, rtxn, &ava->aa_value, &ei ); -- if ( rc == LDAP_SUCCESS ) { -- /* exactly one ID can match */ -- ids[0] = 1; -- ids[1] = ei->bei_id; -- } -- if ( ei ) { -- bdb_cache_entryinfo_unlock( ei ); -- } -- if ( rc == DB_NOTFOUND ) { -- BDB_IDL_ZERO( ids ); -- rc = 0; -- } -- return rc; -- } -- -- BDB_IDL_ALL( bdb, ids ); -- -- rc = bdb_index_param( op->o_bd, ava->aa_desc, LDAP_FILTER_EQUALITY, -- &db, &mask, &prefix ); -- -- if ( rc == LDAP_INAPPROPRIATE_MATCHING ) { -- Debug( LDAP_DEBUG_ANY, -- "<= bdb_equality_candidates: (%s) not indexed\n", -- ava->aa_desc->ad_cname.bv_val, 0, 0 ); -- return 0; -- } -- -- if( rc != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_ANY, -- "<= bdb_equality_candidates: (%s) " -- "index_param failed (%d)\n", -- ava->aa_desc->ad_cname.bv_val, rc, 0 ); -- return 0; -- } -- -- mr = ava->aa_desc->ad_type->sat_equality; -- if( !mr ) { -- return 0; -- } -- -- if( !mr->smr_filter ) { -- return 0; -- } -- -- rc = (mr->smr_filter)( -- LDAP_FILTER_EQUALITY, -- mask, -- ava->aa_desc->ad_type->sat_syntax, -- mr, -- &prefix, -- &ava->aa_value, -- &keys, op->o_tmpmemctx ); -- -- if( rc != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_equality_candidates: (%s, %s) " -- "MR filter failed (%d)\n", -- prefix.bv_val, ava->aa_desc->ad_cname.bv_val, rc ); -- return 0; -- } -- -- if( keys == NULL ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_equality_candidates: (%s) no keys\n", -- ava->aa_desc->ad_cname.bv_val, 0, 0 ); -- return 0; -- } -- -- for ( i= 0; keys[i].bv_val != NULL; i++ ) { -- rc = bdb_key_read( op->o_bd, db, rtxn, &keys[i], tmp, NULL, 0 ); -- -- if( rc == DB_NOTFOUND ) { -- BDB_IDL_ZERO( ids ); -- rc = 0; -- break; -- } else if( rc != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_equality_candidates: (%s) " -- "key read failed (%d)\n", -- ava->aa_desc->ad_cname.bv_val, rc, 0 ); -- break; -- } -- -- if( BDB_IDL_IS_ZERO( tmp ) ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_equality_candidates: (%s) NULL\n", -- ava->aa_desc->ad_cname.bv_val, 0, 0 ); -- BDB_IDL_ZERO( ids ); -- break; -- } -- -- if ( i == 0 ) { -- BDB_IDL_CPY( ids, tmp ); -- } else { -- bdb_idl_intersection( ids, tmp ); -- } -- -- if( BDB_IDL_IS_ZERO( ids ) ) -- break; -- } -- -- ber_bvarray_free_x( keys, op->o_tmpmemctx ); -- -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_equality_candidates: id=%ld, first=%ld, last=%ld\n", -- (long) ids[0], -- (long) BDB_IDL_FIRST(ids), -- (long) BDB_IDL_LAST(ids) ); -- return( rc ); --} -- -- --static int --approx_candidates( -- Operation *op, -- DB_TXN *rtxn, -- AttributeAssertion *ava, -- ID *ids, -- ID *tmp ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- DB *db; -- int i; -- int rc; -- slap_mask_t mask; -- struct berval prefix = {0, NULL}; -- struct berval *keys = NULL; -- MatchingRule *mr; -- -- Debug( LDAP_DEBUG_TRACE, "=> bdb_approx_candidates (%s)\n", -- ava->aa_desc->ad_cname.bv_val, 0, 0 ); -- -- BDB_IDL_ALL( bdb, ids ); -- -- rc = bdb_index_param( op->o_bd, ava->aa_desc, LDAP_FILTER_APPROX, -- &db, &mask, &prefix ); -- -- if ( rc == LDAP_INAPPROPRIATE_MATCHING ) { -- Debug( LDAP_DEBUG_ANY, -- "<= bdb_approx_candidates: (%s) not indexed\n", -- ava->aa_desc->ad_cname.bv_val, 0, 0 ); -- return 0; -- } -- -- if( rc != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_ANY, -- "<= bdb_approx_candidates: (%s) " -- "index_param failed (%d)\n", -- ava->aa_desc->ad_cname.bv_val, rc, 0 ); -- return 0; -- } -- -- mr = ava->aa_desc->ad_type->sat_approx; -- if( !mr ) { -- /* no approx matching rule, try equality matching rule */ -- mr = ava->aa_desc->ad_type->sat_equality; -- } -- -- if( !mr ) { -- return 0; -- } -- -- if( !mr->smr_filter ) { -- return 0; -- } -- -- rc = (mr->smr_filter)( -- LDAP_FILTER_APPROX, -- mask, -- ava->aa_desc->ad_type->sat_syntax, -- mr, -- &prefix, -- &ava->aa_value, -- &keys, op->o_tmpmemctx ); -- -- if( rc != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_approx_candidates: (%s, %s) " -- "MR filter failed (%d)\n", -- prefix.bv_val, ava->aa_desc->ad_cname.bv_val, rc ); -- return 0; -- } -- -- if( keys == NULL ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_approx_candidates: (%s) no keys (%s)\n", -- prefix.bv_val, ava->aa_desc->ad_cname.bv_val, 0 ); -- return 0; -- } -- -- for ( i= 0; keys[i].bv_val != NULL; i++ ) { -- rc = bdb_key_read( op->o_bd, db, rtxn, &keys[i], tmp, NULL, 0 ); -- -- if( rc == DB_NOTFOUND ) { -- BDB_IDL_ZERO( ids ); -- rc = 0; -- break; -- } else if( rc != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_approx_candidates: (%s) " -- "key read failed (%d)\n", -- ava->aa_desc->ad_cname.bv_val, rc, 0 ); -- break; -- } -- -- if( BDB_IDL_IS_ZERO( tmp ) ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_approx_candidates: (%s) NULL\n", -- ava->aa_desc->ad_cname.bv_val, 0, 0 ); -- BDB_IDL_ZERO( ids ); -- break; -- } -- -- if ( i == 0 ) { -- BDB_IDL_CPY( ids, tmp ); -- } else { -- bdb_idl_intersection( ids, tmp ); -- } -- -- if( BDB_IDL_IS_ZERO( ids ) ) -- break; -- } -- -- ber_bvarray_free_x( keys, op->o_tmpmemctx ); -- -- Debug( LDAP_DEBUG_TRACE, "<= bdb_approx_candidates %ld, first=%ld, last=%ld\n", -- (long) ids[0], -- (long) BDB_IDL_FIRST(ids), -- (long) BDB_IDL_LAST(ids) ); -- return( rc ); --} -- --static int --substring_candidates( -- Operation *op, -- DB_TXN *rtxn, -- SubstringsAssertion *sub, -- ID *ids, -- ID *tmp ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- DB *db; -- int i; -- int rc; -- slap_mask_t mask; -- struct berval prefix = {0, NULL}; -- struct berval *keys = NULL; -- MatchingRule *mr; -- -- Debug( LDAP_DEBUG_TRACE, "=> bdb_substring_candidates (%s)\n", -- sub->sa_desc->ad_cname.bv_val, 0, 0 ); -- -- BDB_IDL_ALL( bdb, ids ); -- -- rc = bdb_index_param( op->o_bd, sub->sa_desc, LDAP_FILTER_SUBSTRINGS, -- &db, &mask, &prefix ); -- -- if ( rc == LDAP_INAPPROPRIATE_MATCHING ) { -- Debug( LDAP_DEBUG_ANY, -- "<= bdb_substring_candidates: (%s) not indexed\n", -- sub->sa_desc->ad_cname.bv_val, 0, 0 ); -- return 0; -- } -- -- if( rc != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_ANY, -- "<= bdb_substring_candidates: (%s) " -- "index_param failed (%d)\n", -- sub->sa_desc->ad_cname.bv_val, rc, 0 ); -- return 0; -- } -- -- mr = sub->sa_desc->ad_type->sat_substr; -- -- if( !mr ) { -- return 0; -- } -- -- if( !mr->smr_filter ) { -- return 0; -- } -- -- rc = (mr->smr_filter)( -- LDAP_FILTER_SUBSTRINGS, -- mask, -- sub->sa_desc->ad_type->sat_syntax, -- mr, -- &prefix, -- sub, -- &keys, op->o_tmpmemctx ); -- -- if( rc != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_substring_candidates: (%s) " -- "MR filter failed (%d)\n", -- sub->sa_desc->ad_cname.bv_val, rc, 0 ); -- return 0; -- } -- -- if( keys == NULL ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_substring_candidates: (0x%04lx) no keys (%s)\n", -- mask, sub->sa_desc->ad_cname.bv_val, 0 ); -- return 0; -- } -- -- for ( i= 0; keys[i].bv_val != NULL; i++ ) { -- rc = bdb_key_read( op->o_bd, db, rtxn, &keys[i], tmp, NULL, 0 ); -- -- if( rc == DB_NOTFOUND ) { -- BDB_IDL_ZERO( ids ); -- rc = 0; -- break; -- } else if( rc != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_substring_candidates: (%s) " -- "key read failed (%d)\n", -- sub->sa_desc->ad_cname.bv_val, rc, 0 ); -- break; -- } -- -- if( BDB_IDL_IS_ZERO( tmp ) ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_substring_candidates: (%s) NULL\n", -- sub->sa_desc->ad_cname.bv_val, 0, 0 ); -- BDB_IDL_ZERO( ids ); -- break; -- } -- -- if ( i == 0 ) { -- BDB_IDL_CPY( ids, tmp ); -- } else { -- bdb_idl_intersection( ids, tmp ); -- } -- -- if( BDB_IDL_IS_ZERO( ids ) ) -- break; -- } -- -- ber_bvarray_free_x( keys, op->o_tmpmemctx ); -- -- Debug( LDAP_DEBUG_TRACE, "<= bdb_substring_candidates: %ld, first=%ld, last=%ld\n", -- (long) ids[0], -- (long) BDB_IDL_FIRST(ids), -- (long) BDB_IDL_LAST(ids) ); -- return( rc ); --} -- --static int --inequality_candidates( -- Operation *op, -- DB_TXN *rtxn, -- AttributeAssertion *ava, -- ID *ids, -- ID *tmp, -- int gtorlt ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- DB *db; -- int rc; -- slap_mask_t mask; -- struct berval prefix = {0, NULL}; -- struct berval *keys = NULL; -- MatchingRule *mr; -- DBC * cursor = NULL; -- -- Debug( LDAP_DEBUG_TRACE, "=> bdb_inequality_candidates (%s)\n", -- ava->aa_desc->ad_cname.bv_val, 0, 0 ); -- -- BDB_IDL_ALL( bdb, ids ); -- -- rc = bdb_index_param( op->o_bd, ava->aa_desc, LDAP_FILTER_EQUALITY, -- &db, &mask, &prefix ); -- -- if ( rc == LDAP_INAPPROPRIATE_MATCHING ) { -- Debug( LDAP_DEBUG_ANY, -- "<= bdb_inequality_candidates: (%s) not indexed\n", -- ava->aa_desc->ad_cname.bv_val, 0, 0 ); -- return 0; -- } -- -- if( rc != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_ANY, -- "<= bdb_inequality_candidates: (%s) " -- "index_param failed (%d)\n", -- ava->aa_desc->ad_cname.bv_val, rc, 0 ); -- return 0; -- } -- -- mr = ava->aa_desc->ad_type->sat_equality; -- if( !mr ) { -- return 0; -- } -- -- if( !mr->smr_filter ) { -- return 0; -- } -- -- rc = (mr->smr_filter)( -- LDAP_FILTER_EQUALITY, -- mask, -- ava->aa_desc->ad_type->sat_syntax, -- mr, -- &prefix, -- &ava->aa_value, -- &keys, op->o_tmpmemctx ); -- -- if( rc != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_inequality_candidates: (%s, %s) " -- "MR filter failed (%d)\n", -- prefix.bv_val, ava->aa_desc->ad_cname.bv_val, rc ); -- return 0; -- } -- -- if( keys == NULL ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_inequality_candidates: (%s) no keys\n", -- ava->aa_desc->ad_cname.bv_val, 0, 0 ); -- return 0; -- } -- -- BDB_IDL_ZERO( ids ); -- while(1) { -- rc = bdb_key_read( op->o_bd, db, rtxn, &keys[0], tmp, &cursor, gtorlt ); -- -- if( rc == DB_NOTFOUND ) { -- rc = 0; -- break; -- } else if( rc != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_inequality_candidates: (%s) " -- "key read failed (%d)\n", -- ava->aa_desc->ad_cname.bv_val, rc, 0 ); -- break; -- } -- -- if( BDB_IDL_IS_ZERO( tmp ) ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_inequality_candidates: (%s) NULL\n", -- ava->aa_desc->ad_cname.bv_val, 0, 0 ); -- break; -- } -- -- bdb_idl_union( ids, tmp ); -- -- if( op->ors_limit && op->ors_limit->lms_s_unchecked != -1 && -- BDB_IDL_N( ids ) >= (unsigned) op->ors_limit->lms_s_unchecked ) { -- cursor->c_close( cursor ); -- break; -- } -- } -- ber_bvarray_free_x( keys, op->o_tmpmemctx ); -- -- Debug( LDAP_DEBUG_TRACE, -- "<= bdb_inequality_candidates: id=%ld, first=%ld, last=%ld\n", -- (long) ids[0], -- (long) BDB_IDL_FIRST(ids), -- (long) BDB_IDL_LAST(ids) ); -- return( rc ); --} -diff --git a/servers/slapd/back-bdb/id2entry.c b/servers/slapd/back-bdb/id2entry.c -deleted file mode 100644 -index cc00098..0000000 ---- a/servers/slapd/back-bdb/id2entry.c -+++ /dev/null -@@ -1,446 +0,0 @@ --/* id2entry.c - routines to deal with the id2entry database */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include --#include --#include -- --#include "back-bdb.h" -- --static int bdb_id2entry_put( -- BackendDB *be, -- DB_TXN *tid, -- Entry *e, -- int flag ) --{ -- struct bdb_info *bdb = (struct bdb_info *) be->be_private; -- DB *db = bdb->bi_id2entry->bdi_db; -- DBT key, data; -- struct berval bv; -- int rc; -- ID nid; --#ifdef BDB_HIER -- struct berval odn, ondn; -- -- /* We only store rdns, and they go in the dn2id database. */ -- -- odn = e->e_name; ondn = e->e_nname; -- -- e->e_name = slap_empty_bv; -- e->e_nname = slap_empty_bv; --#endif -- DBTzero( &key ); -- -- /* Store ID in BigEndian format */ -- key.data = &nid; -- key.size = sizeof(ID); -- BDB_ID2DISK( e->e_id, &nid ); -- -- rc = entry_encode( e, &bv ); --#ifdef BDB_HIER -- e->e_name = odn; e->e_nname = ondn; --#endif -- if( rc != LDAP_SUCCESS ) { -- return -1; -- } -- -- DBTzero( &data ); -- bv2DBT( &bv, &data ); -- -- rc = db->put( db, tid, &key, &data, flag ); -- -- free( bv.bv_val ); -- return rc; --} -- --/* -- * This routine adds (or updates) an entry on disk. -- * The cache should be already be updated. -- */ -- -- --int bdb_id2entry_add( -- BackendDB *be, -- DB_TXN *tid, -- Entry *e ) --{ -- return bdb_id2entry_put(be, tid, e, DB_NOOVERWRITE); --} -- --int bdb_id2entry_update( -- BackendDB *be, -- DB_TXN *tid, -- Entry *e ) --{ -- return bdb_id2entry_put(be, tid, e, 0); --} -- --int bdb_id2entry( -- BackendDB *be, -- DB_TXN *tid, -- ID id, -- Entry **e ) --{ -- struct bdb_info *bdb = (struct bdb_info *) be->be_private; -- DB *db = bdb->bi_id2entry->bdi_db; -- DBT key, data; -- DBC *cursor; -- EntryHeader eh; -- char buf[16]; -- int rc = 0, off; -- ID nid; -- -- *e = NULL; -- -- DBTzero( &key ); -- key.data = &nid; -- key.size = sizeof(ID); -- BDB_ID2DISK( id, &nid ); -- -- DBTzero( &data ); -- data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; -- -- /* fetch it */ -- rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags ); -- if ( rc ) return rc; -- -- /* Get the nattrs / nvals counts first */ -- data.ulen = data.dlen = sizeof(buf); -- data.data = buf; -- rc = cursor->c_get( cursor, &key, &data, DB_SET ); -- if ( rc ) goto finish; -- -- -- eh.bv.bv_val = buf; -- eh.bv.bv_len = data.size; -- rc = entry_header( &eh ); -- if ( rc ) goto finish; -- -- if ( eh.nvals ) { -- /* Get the size */ -- data.flags ^= DB_DBT_PARTIAL; -- data.ulen = 0; -- rc = cursor->c_get( cursor, &key, &data, DB_CURRENT ); -- if ( rc != DB_BUFFER_SMALL ) goto finish; -- -- /* Allocate a block and retrieve the data */ -- off = eh.data - eh.bv.bv_val; -- eh.bv.bv_len = eh.nvals * sizeof( struct berval ) + data.size; -- eh.bv.bv_val = ch_malloc( eh.bv.bv_len ); -- eh.data = eh.bv.bv_val + eh.nvals * sizeof( struct berval ); -- data.data = eh.data; -- data.ulen = data.size; -- -- /* skip past already parsed nattr/nvals */ -- eh.data += off; -- -- rc = cursor->c_get( cursor, &key, &data, DB_CURRENT ); -- } -- --finish: -- cursor->c_close( cursor ); -- -- if( rc != 0 ) { -- return rc; -- } -- -- if ( eh.nvals ) { --#ifdef SLAP_ZONE_ALLOC -- rc = entry_decode(&eh, e, bdb->bi_cache.c_zctx); --#else -- rc = entry_decode(&eh, e); --#endif -- } else { -- *e = entry_alloc(); -- } -- -- if( rc == 0 ) { -- (*e)->e_id = id; -- } else { -- /* only free on error. On success, the entry was -- * decoded in place. -- */ --#ifndef SLAP_ZONE_ALLOC -- ch_free(eh.bv.bv_val); --#endif -- } --#ifdef SLAP_ZONE_ALLOC -- ch_free(eh.bv.bv_val); --#endif -- -- return rc; --} -- --int bdb_id2entry_delete( -- BackendDB *be, -- DB_TXN *tid, -- Entry *e ) --{ -- struct bdb_info *bdb = (struct bdb_info *) be->be_private; -- DB *db = bdb->bi_id2entry->bdi_db; -- DBT key; -- int rc; -- ID nid; -- -- DBTzero( &key ); -- key.data = &nid; -- key.size = sizeof(ID); -- BDB_ID2DISK( e->e_id, &nid ); -- -- /* delete from database */ -- rc = db->del( db, tid, &key, 0 ); -- -- return rc; --} -- --int bdb_entry_return( -- Entry *e --) --{ -- /* Our entries are allocated in two blocks; the data comes from -- * the db itself and the Entry structure and associated pointers -- * are allocated in entry_decode. The db data pointer is saved -- * in e_bv. -- */ -- if ( e->e_bv.bv_val ) { -- /* See if the DNs were changed by modrdn */ -- if( e->e_nname.bv_val < e->e_bv.bv_val || e->e_nname.bv_val > -- e->e_bv.bv_val + e->e_bv.bv_len ) { -- ch_free(e->e_name.bv_val); -- ch_free(e->e_nname.bv_val); -- } -- e->e_name.bv_val = NULL; -- e->e_nname.bv_val = NULL; -- /* In tool mode the e_bv buffer is realloc'd, leave it alone */ -- if( !(slapMode & SLAP_TOOL_MODE) ) { -- free( e->e_bv.bv_val ); -- } -- BER_BVZERO( &e->e_bv ); -- } -- entry_free( e ); -- return 0; --} -- --int bdb_entry_release( -- Operation *op, -- Entry *e, -- int rw ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- struct bdb_op_info *boi; -- OpExtra *oex; -- -- /* slapMode : SLAP_SERVER_MODE, SLAP_TOOL_MODE, -- SLAP_TRUNCATE_MODE, SLAP_UNDEFINED_MODE */ -- -- if ( slapMode & SLAP_SERVER_MODE ) { -- /* If not in our cache, just free it */ -- if ( !e->e_private ) { --#ifdef SLAP_ZONE_ALLOC -- return bdb_entry_return( bdb, e, -1 ); --#else -- return bdb_entry_return( e ); --#endif -- } -- /* free entry and reader or writer lock */ -- LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) { -- if ( oex->oe_key == bdb ) break; -- } -- boi = (struct bdb_op_info *)oex; -- -- /* lock is freed with txn */ -- if ( !boi || boi->boi_txn ) { -- bdb_unlocked_cache_return_entry_rw( bdb, e, rw ); -- } else { -- struct bdb_lock_info *bli, *prev; -- for ( prev=(struct bdb_lock_info *)&boi->boi_locks, -- bli = boi->boi_locks; bli; prev=bli, bli=bli->bli_next ) { -- if ( bli->bli_id == e->e_id ) { -- bdb_cache_return_entry_rw( bdb, e, rw, &bli->bli_lock ); -- prev->bli_next = bli->bli_next; -- /* Cleanup, or let caller know we unlocked */ -- if ( bli->bli_flag & BLI_DONTFREE ) -- bli->bli_flag = 0; -- else -- op->o_tmpfree( bli, op->o_tmpmemctx ); -- break; -- } -- } -- if ( !boi->boi_locks ) { -- LDAP_SLIST_REMOVE( &op->o_extra, &boi->boi_oe, OpExtra, oe_next ); -- if ( !(boi->boi_flag & BOI_DONTFREE)) -- op->o_tmpfree( boi, op->o_tmpmemctx ); -- } -- } -- } else { --#ifdef SLAP_ZONE_ALLOC -- int zseq = -1; -- if (e->e_private != NULL) { -- BEI(e)->bei_e = NULL; -- zseq = BEI(e)->bei_zseq; -- } --#else -- if (e->e_private != NULL) -- BEI(e)->bei_e = NULL; --#endif -- e->e_private = NULL; --#ifdef SLAP_ZONE_ALLOC -- bdb_entry_return ( bdb, e, zseq ); --#else -- bdb_entry_return ( e ); --#endif -- } -- -- return 0; --} -- --/* return LDAP_SUCCESS IFF we can retrieve the specified entry. -- */ --int bdb_entry_get( -- Operation *op, -- struct berval *ndn, -- ObjectClass *oc, -- AttributeDescription *at, -- int rw, -- Entry **ent ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- struct bdb_op_info *boi = NULL; -- DB_TXN *txn = NULL; -- Entry *e = NULL; -- EntryInfo *ei; -- int rc; -- const char *at_name = at ? at->ad_cname.bv_val : "(null)"; -- -- DB_LOCK lock; -- -- Debug( LDAP_DEBUG_ARGS, -- "=> bdb_entry_get: ndn: \"%s\"\n", ndn->bv_val, 0, 0 ); -- Debug( LDAP_DEBUG_ARGS, -- "=> bdb_entry_get: oc: \"%s\", at: \"%s\"\n", -- oc ? oc->soc_cname.bv_val : "(null)", at_name, 0); -- -- if( op ) { -- OpExtra *oex; -- LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) { -- if ( oex->oe_key == bdb ) break; -- } -- boi = (struct bdb_op_info *)oex; -- if ( boi ) -- txn = boi->boi_txn; -- } -- -- if ( !txn ) { -- rc = bdb_reader_get( op, bdb->bi_dbenv, &txn ); -- switch(rc) { -- case 0: -- break; -- default: -- return LDAP_OTHER; -- } -- } -- --dn2entry_retry: -- /* can we find entry */ -- rc = bdb_dn2entry( op, txn, ndn, &ei, 0, &lock ); -- switch( rc ) { -- case DB_NOTFOUND: -- case 0: -- break; -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- /* the txn must abort and retry */ -- if ( txn ) { -- if ( boi ) boi->boi_err = rc; -- return LDAP_BUSY; -- } -- ldap_pvt_thread_yield(); -- goto dn2entry_retry; -- default: -- if ( boi ) boi->boi_err = rc; -- return (rc != LDAP_BUSY) ? LDAP_OTHER : LDAP_BUSY; -- } -- if (ei) e = ei->bei_e; -- if (e == NULL) { -- Debug( LDAP_DEBUG_ACL, -- "=> bdb_entry_get: cannot find entry: \"%s\"\n", -- ndn->bv_val, 0, 0 ); -- return LDAP_NO_SUCH_OBJECT; -- } -- -- Debug( LDAP_DEBUG_ACL, -- "=> bdb_entry_get: found entry: \"%s\"\n", -- ndn->bv_val, 0, 0 ); -- -- if ( oc && !is_entry_objectclass( e, oc, 0 )) { -- Debug( LDAP_DEBUG_ACL, -- "<= bdb_entry_get: failed to find objectClass %s\n", -- oc->soc_cname.bv_val, 0, 0 ); -- rc = LDAP_NO_SUCH_ATTRIBUTE; -- goto return_results; -- } -- -- /* NOTE: attr_find() or attrs_find()? */ -- if ( at && attr_find( e->e_attrs, at ) == NULL ) { -- Debug( LDAP_DEBUG_ACL, -- "<= bdb_entry_get: failed to find attribute %s\n", -- at->ad_cname.bv_val, 0, 0 ); -- rc = LDAP_NO_SUCH_ATTRIBUTE; -- goto return_results; -- } -- --return_results: -- if( rc != LDAP_SUCCESS ) { -- /* free entry */ -- bdb_cache_return_entry_rw(bdb, e, rw, &lock); -- -- } else { -- if ( slapMode & SLAP_SERVER_MODE ) { -- *ent = e; -- /* big drag. we need a place to store a read lock so we can -- * release it later?? If we're in a txn, nothing is needed -- * here because the locks will go away with the txn. -- */ -- if ( op ) { -- if ( !boi ) { -- boi = op->o_tmpcalloc(1,sizeof(struct bdb_op_info),op->o_tmpmemctx); -- boi->boi_oe.oe_key = bdb; -- LDAP_SLIST_INSERT_HEAD( &op->o_extra, &boi->boi_oe, oe_next ); -- } -- if ( !boi->boi_txn ) { -- struct bdb_lock_info *bli; -- bli = op->o_tmpalloc( sizeof(struct bdb_lock_info), -- op->o_tmpmemctx ); -- bli->bli_next = boi->boi_locks; -- bli->bli_id = e->e_id; -- bli->bli_flag = 0; -- bli->bli_lock = lock; -- boi->boi_locks = bli; -- } -- } -- } else { -- *ent = entry_dup( e ); -- bdb_cache_return_entry_rw(bdb, e, rw, &lock); -- } -- } -- -- Debug( LDAP_DEBUG_TRACE, -- "bdb_entry_get: rc=%d\n", -- rc, 0, 0 ); -- return(rc); --} -diff --git a/servers/slapd/back-bdb/idl.c b/servers/slapd/back-bdb/idl.c -deleted file mode 100644 -index d0c13a6..0000000 ---- a/servers/slapd/back-bdb/idl.c -+++ /dev/null -@@ -1,1570 +0,0 @@ --/* idl.c - ldap id list handling routines */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include --#include -- --#include "back-bdb.h" --#include "idl.h" -- --#define IDL_MAX(x,y) ( (x) > (y) ? (x) : (y) ) --#define IDL_MIN(x,y) ( (x) < (y) ? (x) : (y) ) --#define IDL_CMP(x,y) ( (x) < (y) ? -1 : (x) > (y) ) -- --#define IDL_LRU_DELETE( bdb, e ) do { \ -- if ( (e) == (bdb)->bi_idl_lru_head ) { \ -- if ( (e)->idl_lru_next == (bdb)->bi_idl_lru_head ) { \ -- (bdb)->bi_idl_lru_head = NULL; \ -- } else { \ -- (bdb)->bi_idl_lru_head = (e)->idl_lru_next; \ -- } \ -- } \ -- if ( (e) == (bdb)->bi_idl_lru_tail ) { \ -- if ( (e)->idl_lru_prev == (bdb)->bi_idl_lru_tail ) { \ -- assert( (bdb)->bi_idl_lru_head == NULL ); \ -- (bdb)->bi_idl_lru_tail = NULL; \ -- } else { \ -- (bdb)->bi_idl_lru_tail = (e)->idl_lru_prev; \ -- } \ -- } \ -- (e)->idl_lru_next->idl_lru_prev = (e)->idl_lru_prev; \ -- (e)->idl_lru_prev->idl_lru_next = (e)->idl_lru_next; \ --} while ( 0 ) -- --static int --bdb_idl_entry_cmp( const void *v_idl1, const void *v_idl2 ) --{ -- const bdb_idl_cache_entry_t *idl1 = v_idl1, *idl2 = v_idl2; -- int rc; -- -- if ((rc = SLAP_PTRCMP( idl1->db, idl2->db ))) return rc; -- if ((rc = idl1->kstr.bv_len - idl2->kstr.bv_len )) return rc; -- return ( memcmp ( idl1->kstr.bv_val, idl2->kstr.bv_val , idl1->kstr.bv_len ) ); --} -- --#if IDL_DEBUG > 0 --static void idl_check( ID *ids ) --{ -- if( BDB_IDL_IS_RANGE( ids ) ) { -- assert( BDB_IDL_RANGE_FIRST(ids) <= BDB_IDL_RANGE_LAST(ids) ); -- } else { -- ID i; -- for( i=1; i < ids[0]; i++ ) { -- assert( ids[i+1] > ids[i] ); -- } -- } --} -- --#if IDL_DEBUG > 1 --static void idl_dump( ID *ids ) --{ -- if( BDB_IDL_IS_RANGE( ids ) ) { -- Debug( LDAP_DEBUG_ANY, -- "IDL: range ( %ld - %ld )\n", -- (long) BDB_IDL_RANGE_FIRST( ids ), -- (long) BDB_IDL_RANGE_LAST( ids ) ); -- -- } else { -- ID i; -- Debug( LDAP_DEBUG_ANY, "IDL: size %ld", (long) ids[0], 0, 0 ); -- -- for( i=1; i<=ids[0]; i++ ) { -- if( i % 16 == 1 ) { -- Debug( LDAP_DEBUG_ANY, "\n", 0, 0, 0 ); -- } -- Debug( LDAP_DEBUG_ANY, " %02lx", (long) ids[i], 0, 0 ); -- } -- -- Debug( LDAP_DEBUG_ANY, "\n", 0, 0, 0 ); -- } -- -- idl_check( ids ); --} --#endif /* IDL_DEBUG > 1 */ --#endif /* IDL_DEBUG > 0 */ -- --unsigned bdb_idl_search( ID *ids, ID id ) --{ --#define IDL_BINARY_SEARCH 1 --#ifdef IDL_BINARY_SEARCH -- /* -- * binary search of id in ids -- * if found, returns position of id -- * if not found, returns first postion greater than id -- */ -- unsigned base = 0; -- unsigned cursor = 1; -- int val = 0; -- unsigned n = ids[0]; -- --#if IDL_DEBUG > 0 -- idl_check( ids ); --#endif -- -- while( 0 < n ) { -- unsigned pivot = n >> 1; -- cursor = base + pivot + 1; -- val = IDL_CMP( id, ids[cursor] ); -- -- if( val < 0 ) { -- n = pivot; -- -- } else if ( val > 0 ) { -- base = cursor; -- n -= pivot + 1; -- -- } else { -- return cursor; -- } -- } -- -- if( val > 0 ) { -- ++cursor; -- } -- return cursor; -- --#else -- /* (reverse) linear search */ -- int i; -- --#if IDL_DEBUG > 0 -- idl_check( ids ); --#endif -- -- for( i=ids[0]; i; i-- ) { -- if( id > ids[i] ) { -- break; -- } -- } -- -- return i+1; --#endif --} -- --int bdb_idl_insert( ID *ids, ID id ) --{ -- unsigned x; -- --#if IDL_DEBUG > 1 -- Debug( LDAP_DEBUG_ANY, "insert: %04lx at %d\n", (long) id, x, 0 ); -- idl_dump( ids ); --#elif IDL_DEBUG > 0 -- idl_check( ids ); --#endif -- -- if (BDB_IDL_IS_RANGE( ids )) { -- /* if already in range, treat as a dup */ -- if (id >= BDB_IDL_RANGE_FIRST(ids) && id <= BDB_IDL_RANGE_LAST(ids)) -- return -1; -- if (id < BDB_IDL_RANGE_FIRST(ids)) -- ids[1] = id; -- else if (id > BDB_IDL_RANGE_LAST(ids)) -- ids[2] = id; -- return 0; -- } -- -- x = bdb_idl_search( ids, id ); -- assert( x > 0 ); -- -- if( x < 1 ) { -- /* internal error */ -- return -2; -- } -- -- if ( x <= ids[0] && ids[x] == id ) { -- /* duplicate */ -- return -1; -- } -- -- if ( ++ids[0] >= BDB_IDL_DB_MAX ) { -- if( id < ids[1] ) { -- ids[1] = id; -- ids[2] = ids[ids[0]-1]; -- } else if ( ids[ids[0]-1] < id ) { -- ids[2] = id; -- } else { -- ids[2] = ids[ids[0]-1]; -- } -- ids[0] = NOID; -- -- } else { -- /* insert id */ -- AC_MEMCPY( &ids[x+1], &ids[x], (ids[0]-x) * sizeof(ID) ); -- ids[x] = id; -- } -- --#if IDL_DEBUG > 1 -- idl_dump( ids ); --#elif IDL_DEBUG > 0 -- idl_check( ids ); --#endif -- -- return 0; --} -- --int bdb_idl_delete( ID *ids, ID id ) --{ -- unsigned x; -- --#if IDL_DEBUG > 1 -- Debug( LDAP_DEBUG_ANY, "delete: %04lx at %d\n", (long) id, x, 0 ); -- idl_dump( ids ); --#elif IDL_DEBUG > 0 -- idl_check( ids ); --#endif -- -- if (BDB_IDL_IS_RANGE( ids )) { -- /* If deleting a range boundary, adjust */ -- if ( ids[1] == id ) -- ids[1]++; -- else if ( ids[2] == id ) -- ids[2]--; -- /* deleting from inside a range is a no-op */ -- -- /* If the range has collapsed, re-adjust */ -- if ( ids[1] > ids[2] ) -- ids[0] = 0; -- else if ( ids[1] == ids[2] ) -- ids[1] = 1; -- return 0; -- } -- -- x = bdb_idl_search( ids, id ); -- assert( x > 0 ); -- -- if( x <= 0 ) { -- /* internal error */ -- return -2; -- } -- -- if( x > ids[0] || ids[x] != id ) { -- /* not found */ -- return -1; -- -- } else if ( --ids[0] == 0 ) { -- if( x != 1 ) { -- return -3; -- } -- -- } else { -- AC_MEMCPY( &ids[x], &ids[x+1], (1+ids[0]-x) * sizeof(ID) ); -- } -- --#if IDL_DEBUG > 1 -- idl_dump( ids ); --#elif IDL_DEBUG > 0 -- idl_check( ids ); --#endif -- -- return 0; --} -- --static char * --bdb_show_key( -- DBT *key, -- char *buf ) --{ -- if ( key->size == 4 /* LUTIL_HASH_BYTES */ ) { -- unsigned char *c = key->data; -- sprintf( buf, "[%02x%02x%02x%02x]", c[0], c[1], c[2], c[3] ); -- return buf; -- } else { -- return key->data; -- } --} -- --/* Find a db/key pair in the IDL cache. If ids is non-NULL, -- * copy the cached IDL into it, otherwise just return the status. -- */ --int --bdb_idl_cache_get( -- struct bdb_info *bdb, -- DB *db, -- DBT *key, -- ID *ids ) --{ -- bdb_idl_cache_entry_t idl_tmp; -- bdb_idl_cache_entry_t *matched_idl_entry; -- int rc = LDAP_NO_SUCH_OBJECT; -- -- DBT2bv( key, &idl_tmp.kstr ); -- idl_tmp.db = db; -- ldap_pvt_thread_rdwr_rlock( &bdb->bi_idl_tree_rwlock ); -- matched_idl_entry = avl_find( bdb->bi_idl_tree, &idl_tmp, -- bdb_idl_entry_cmp ); -- if ( matched_idl_entry != NULL ) { -- if ( matched_idl_entry->idl && ids ) -- BDB_IDL_CPY( ids, matched_idl_entry->idl ); -- matched_idl_entry->idl_flags |= CACHE_ENTRY_REFERENCED; -- if ( matched_idl_entry->idl ) -- rc = LDAP_SUCCESS; -- else -- rc = DB_NOTFOUND; -- } -- ldap_pvt_thread_rdwr_runlock( &bdb->bi_idl_tree_rwlock ); -- -- return rc; --} -- --void --bdb_idl_cache_put( -- struct bdb_info *bdb, -- DB *db, -- DBT *key, -- ID *ids, -- int rc ) --{ -- bdb_idl_cache_entry_t idl_tmp; -- bdb_idl_cache_entry_t *ee, *eprev; -- -- if ( rc == DB_NOTFOUND || BDB_IDL_IS_ZERO( ids )) -- return; -- -- DBT2bv( key, &idl_tmp.kstr ); -- -- ee = (bdb_idl_cache_entry_t *) ch_malloc( -- sizeof( bdb_idl_cache_entry_t ) ); -- ee->db = db; -- ee->idl = (ID*) ch_malloc( BDB_IDL_SIZEOF ( ids ) ); -- BDB_IDL_CPY( ee->idl, ids ); -- -- ee->idl_lru_prev = NULL; -- ee->idl_lru_next = NULL; -- ee->idl_flags = 0; -- ber_dupbv( &ee->kstr, &idl_tmp.kstr ); -- ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock ); -- if ( avl_insert( &bdb->bi_idl_tree, (caddr_t) ee, -- bdb_idl_entry_cmp, avl_dup_error )) -- { -- ch_free( ee->kstr.bv_val ); -- ch_free( ee->idl ); -- ch_free( ee ); -- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock ); -- return; -- } -- ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock ); -- /* LRU_ADD */ -- if ( bdb->bi_idl_lru_head ) { -- assert( bdb->bi_idl_lru_tail != NULL ); -- assert( bdb->bi_idl_lru_head->idl_lru_prev != NULL ); -- assert( bdb->bi_idl_lru_head->idl_lru_next != NULL ); -- -- ee->idl_lru_next = bdb->bi_idl_lru_head; -- ee->idl_lru_prev = bdb->bi_idl_lru_head->idl_lru_prev; -- bdb->bi_idl_lru_head->idl_lru_prev->idl_lru_next = ee; -- bdb->bi_idl_lru_head->idl_lru_prev = ee; -- } else { -- ee->idl_lru_next = ee->idl_lru_prev = ee; -- bdb->bi_idl_lru_tail = ee; -- } -- bdb->bi_idl_lru_head = ee; -- -- if ( bdb->bi_idl_cache_size >= bdb->bi_idl_cache_max_size ) { -- int i; -- eprev = bdb->bi_idl_lru_tail; -- for ( i = 0; (ee = eprev) != NULL && i < 10; i++ ) { -- eprev = ee->idl_lru_prev; -- if ( eprev == ee ) { -- eprev = NULL; -- } -- if ( ee->idl_flags & CACHE_ENTRY_REFERENCED ) { -- ee->idl_flags ^= CACHE_ENTRY_REFERENCED; -- continue; -- } -- if ( avl_delete( &bdb->bi_idl_tree, (caddr_t) ee, -- bdb_idl_entry_cmp ) == NULL ) { -- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_cache_put: " -- "AVL delete failed\n", -- 0, 0, 0 ); -- } -- IDL_LRU_DELETE( bdb, ee ); -- i++; -- --bdb->bi_idl_cache_size; -- ch_free( ee->kstr.bv_val ); -- ch_free( ee->idl ); -- ch_free( ee ); -- } -- bdb->bi_idl_lru_tail = eprev; -- assert( bdb->bi_idl_lru_tail != NULL -- || bdb->bi_idl_lru_head == NULL ); -- } -- bdb->bi_idl_cache_size++; -- ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock ); -- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock ); --} -- --void --bdb_idl_cache_del( -- struct bdb_info *bdb, -- DB *db, -- DBT *key ) --{ -- bdb_idl_cache_entry_t *matched_idl_entry, idl_tmp; -- DBT2bv( key, &idl_tmp.kstr ); -- idl_tmp.db = db; -- ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock ); -- matched_idl_entry = avl_find( bdb->bi_idl_tree, &idl_tmp, -- bdb_idl_entry_cmp ); -- if ( matched_idl_entry != NULL ) { -- if ( avl_delete( &bdb->bi_idl_tree, (caddr_t) matched_idl_entry, -- bdb_idl_entry_cmp ) == NULL ) { -- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_cache_del: " -- "AVL delete failed\n", -- 0, 0, 0 ); -- } -- --bdb->bi_idl_cache_size; -- ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock ); -- IDL_LRU_DELETE( bdb, matched_idl_entry ); -- ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock ); -- free( matched_idl_entry->kstr.bv_val ); -- if ( matched_idl_entry->idl ) -- free( matched_idl_entry->idl ); -- free( matched_idl_entry ); -- } -- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock ); --} -- --void --bdb_idl_cache_add_id( -- struct bdb_info *bdb, -- DB *db, -- DBT *key, -- ID id ) --{ -- bdb_idl_cache_entry_t *cache_entry, idl_tmp; -- DBT2bv( key, &idl_tmp.kstr ); -- idl_tmp.db = db; -- ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock ); -- cache_entry = avl_find( bdb->bi_idl_tree, &idl_tmp, -- bdb_idl_entry_cmp ); -- if ( cache_entry != NULL ) { -- if ( !BDB_IDL_IS_RANGE( cache_entry->idl ) && -- cache_entry->idl[0] < BDB_IDL_DB_MAX ) { -- size_t s = BDB_IDL_SIZEOF( cache_entry->idl ) + sizeof(ID); -- cache_entry->idl = ch_realloc( cache_entry->idl, s ); -- } -- bdb_idl_insert( cache_entry->idl, id ); -- } -- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock ); --} -- --void --bdb_idl_cache_del_id( -- struct bdb_info *bdb, -- DB *db, -- DBT *key, -- ID id ) --{ -- bdb_idl_cache_entry_t *cache_entry, idl_tmp; -- DBT2bv( key, &idl_tmp.kstr ); -- idl_tmp.db = db; -- ldap_pvt_thread_rdwr_wlock( &bdb->bi_idl_tree_rwlock ); -- cache_entry = avl_find( bdb->bi_idl_tree, &idl_tmp, -- bdb_idl_entry_cmp ); -- if ( cache_entry != NULL ) { -- bdb_idl_delete( cache_entry->idl, id ); -- if ( cache_entry->idl[0] == 0 ) { -- if ( avl_delete( &bdb->bi_idl_tree, (caddr_t) cache_entry, -- bdb_idl_entry_cmp ) == NULL ) { -- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_cache_del: " -- "AVL delete failed\n", -- 0, 0, 0 ); -- } -- --bdb->bi_idl_cache_size; -- ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock ); -- IDL_LRU_DELETE( bdb, cache_entry ); -- ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock ); -- free( cache_entry->kstr.bv_val ); -- free( cache_entry->idl ); -- free( cache_entry ); -- } -- } -- ldap_pvt_thread_rdwr_wunlock( &bdb->bi_idl_tree_rwlock ); --} -- --int --bdb_idl_fetch_key( -- BackendDB *be, -- DB *db, -- DB_TXN *txn, -- DBT *key, -- ID *ids, -- DBC **saved_cursor, -- int get_flag ) --{ -- struct bdb_info *bdb = (struct bdb_info *) be->be_private; -- int rc; -- DBT data, key2, *kptr; -- DBC *cursor; -- ID *i; -- void *ptr; -- size_t len; -- int rc2; -- int flags = bdb->bi_db_opflags | DB_MULTIPLE; -- int opflag; -- -- /* If using BerkeleyDB 4.0, the buf must be large enough to -- * grab the entire IDL in one get(), otherwise BDB will leak -- * resources on subsequent get's. We can safely call get() -- * twice - once for the data, and once to get the DB_NOTFOUND -- * result meaning there's no more data. See ITS#2040 for details. -- * This bug is fixed in BDB 4.1 so a smaller buffer will work if -- * stack space is too limited. -- * -- * configure now requires Berkeley DB 4.1. -- */ --#if DB_VERSION_FULL < 0x04010000 --# define BDB_ENOUGH 5 --#else -- /* We sometimes test with tiny IDLs, and BDB always wants buffers -- * that are at least one page in size. -- */ --# if BDB_IDL_DB_SIZE < 4096 --# define BDB_ENOUGH 2048 --# else --# define BDB_ENOUGH 1 --# endif --#endif -- ID buf[BDB_IDL_DB_SIZE*BDB_ENOUGH]; -- -- char keybuf[16]; -- -- Debug( LDAP_DEBUG_ARGS, -- "bdb_idl_fetch_key: %s\n", -- bdb_show_key( key, keybuf ), 0, 0 ); -- -- assert( ids != NULL ); -- -- if ( saved_cursor && *saved_cursor ) { -- opflag = DB_NEXT; -- } else if ( get_flag == LDAP_FILTER_GE ) { -- opflag = DB_SET_RANGE; -- } else if ( get_flag == LDAP_FILTER_LE ) { -- opflag = DB_FIRST; -- } else { -- opflag = DB_SET; -- } -- -- /* only non-range lookups can use the IDL cache */ -- if ( bdb->bi_idl_cache_size && opflag == DB_SET ) { -- rc = bdb_idl_cache_get( bdb, db, key, ids ); -- if ( rc != LDAP_NO_SUCH_OBJECT ) return rc; -- } -- -- DBTzero( &data ); -- -- data.data = buf; -- data.ulen = sizeof(buf); -- data.flags = DB_DBT_USERMEM; -- -- /* If we're not reusing an existing cursor, get a new one */ -- if( opflag != DB_NEXT ) { -- rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags ); -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " -- "cursor failed: %s (%d)\n", db_strerror(rc), rc, 0 ); -- return rc; -- } -- } else { -- cursor = *saved_cursor; -- } -- -- /* If this is a LE lookup, save original key so we can determine -- * when to stop. If this is a GE lookup, save the key since it -- * will be overwritten. -- */ -- if ( get_flag == LDAP_FILTER_LE || get_flag == LDAP_FILTER_GE ) { -- DBTzero( &key2 ); -- key2.flags = DB_DBT_USERMEM; -- key2.ulen = sizeof(keybuf); -- key2.data = keybuf; -- key2.size = key->size; -- AC_MEMCPY( keybuf, key->data, key->size ); -- kptr = &key2; -- } else { -- kptr = key; -- } -- len = key->size; -- rc = cursor->c_get( cursor, kptr, &data, flags | opflag ); -- -- /* skip presence key on range inequality lookups */ -- while (rc == 0 && kptr->size != len) { -- rc = cursor->c_get( cursor, kptr, &data, flags | DB_NEXT_NODUP ); -- } -- /* If we're doing a LE compare and the new key is greater than -- * our search key, we're done -- */ -- if (rc == 0 && get_flag == LDAP_FILTER_LE && memcmp( kptr->data, -- key->data, key->size ) > 0 ) { -- rc = DB_NOTFOUND; -- } -- if (rc == 0) { -- i = ids; -- while (rc == 0) { -- u_int8_t *j; -- -- DB_MULTIPLE_INIT( ptr, &data ); -- while (ptr) { -- DB_MULTIPLE_NEXT(ptr, &data, j, len); -- if (j) { -- ++i; -- BDB_DISK2ID( j, i ); -- } -- } -- rc = cursor->c_get( cursor, key, &data, flags | DB_NEXT_DUP ); -- } -- if ( rc == DB_NOTFOUND ) rc = 0; -- ids[0] = i - ids; -- /* On disk, a range is denoted by 0 in the first element */ -- if (ids[1] == 0) { -- if (ids[0] != BDB_IDL_RANGE_SIZE) { -- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " -- "range size mismatch: expected %d, got %ld\n", -- BDB_IDL_RANGE_SIZE, ids[0], 0 ); -- cursor->c_close( cursor ); -- return -1; -- } -- BDB_IDL_RANGE( ids, ids[2], ids[3] ); -- } -- data.size = BDB_IDL_SIZEOF(ids); -- } -- -- if ( saved_cursor && rc == 0 ) { -- if ( !*saved_cursor ) -- *saved_cursor = cursor; -- rc2 = 0; -- } -- else -- rc2 = cursor->c_close( cursor ); -- if (rc2) { -- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " -- "close failed: %s (%d)\n", db_strerror(rc2), rc2, 0 ); -- return rc2; -- } -- -- if( rc == DB_NOTFOUND ) { -- return rc; -- -- } else if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " -- "get failed: %s (%d)\n", -- db_strerror(rc), rc, 0 ); -- return rc; -- -- } else if ( data.size == 0 || data.size % sizeof( ID ) ) { -- /* size not multiple of ID size */ -- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " -- "odd size: expected %ld multiple, got %ld\n", -- (long) sizeof( ID ), (long) data.size, 0 ); -- return -1; -- -- } else if ( data.size != BDB_IDL_SIZEOF(ids) ) { -- /* size mismatch */ -- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: " -- "get size mismatch: expected %ld, got %ld\n", -- (long) ((1 + ids[0]) * sizeof( ID )), (long) data.size, 0 ); -- return -1; -- } -- -- if ( bdb->bi_idl_cache_max_size ) { -- bdb_idl_cache_put( bdb, db, key, ids, rc ); -- } -- -- return rc; --} -- -- --int --bdb_idl_insert_key( -- BackendDB *be, -- DB *db, -- DB_TXN *tid, -- DBT *key, -- ID id ) --{ -- struct bdb_info *bdb = (struct bdb_info *) be->be_private; -- int rc; -- DBT data; -- DBC *cursor; -- ID lo, hi, nlo, nhi, nid; -- char *err; -- -- { -- char buf[16]; -- Debug( LDAP_DEBUG_ARGS, -- "bdb_idl_insert_key: %lx %s\n", -- (long) id, bdb_show_key( key, buf ), 0 ); -- } -- -- assert( id != NOID ); -- -- DBTzero( &data ); -- data.size = sizeof( ID ); -- data.ulen = data.size; -- data.flags = DB_DBT_USERMEM; -- -- BDB_ID2DISK( id, &nid ); -- -- rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags ); -- if ( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_insert_key: " -- "cursor failed: %s (%d)\n", db_strerror(rc), rc, 0 ); -- return rc; -- } -- data.data = &nlo; -- /* Fetch the first data item for this key, to see if it -- * exists and if it's a range. -- */ -- rc = cursor->c_get( cursor, key, &data, DB_SET ); -- err = "c_get"; -- if ( rc == 0 ) { -- if ( nlo != 0 ) { -- /* not a range, count the number of items */ -- db_recno_t count; -- rc = cursor->c_count( cursor, &count, 0 ); -- if ( rc != 0 ) { -- err = "c_count"; -- goto fail; -- } -- if ( count >= BDB_IDL_DB_MAX ) { -- /* No room, convert to a range */ -- DBT key2 = *key; -- db_recno_t i; -- -- key2.dlen = key2.ulen; -- key2.flags |= DB_DBT_PARTIAL; -- -- BDB_DISK2ID( &nlo, &lo ); -- data.data = &nhi; -- -- rc = cursor->c_get( cursor, &key2, &data, DB_NEXT_NODUP ); -- if ( rc != 0 && rc != DB_NOTFOUND ) { -- err = "c_get next_nodup"; -- goto fail; -- } -- if ( rc == DB_NOTFOUND ) { -- rc = cursor->c_get( cursor, key, &data, DB_LAST ); -- if ( rc != 0 ) { -- err = "c_get last"; -- goto fail; -- } -- } else { -- rc = cursor->c_get( cursor, key, &data, DB_PREV ); -- if ( rc != 0 ) { -- err = "c_get prev"; -- goto fail; -- } -- } -- BDB_DISK2ID( &nhi, &hi ); -- /* Update hi/lo if needed, then delete all the items -- * between lo and hi -- */ -- if ( id < lo ) { -- lo = id; -- nlo = nid; -- } else if ( id > hi ) { -- hi = id; -- nhi = nid; -- } -- data.data = &nid; -- /* Don't fetch anything, just position cursor */ -- data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; -- data.dlen = data.ulen = 0; -- rc = cursor->c_get( cursor, key, &data, DB_SET ); -- if ( rc != 0 ) { -- err = "c_get 2"; -- goto fail; -- } -- rc = cursor->c_del( cursor, 0 ); -- if ( rc != 0 ) { -- err = "c_del range1"; -- goto fail; -- } -- /* Delete all the records */ -- for ( i=1; ic_get( cursor, &key2, &data, DB_NEXT_DUP ); -- if ( rc != 0 ) { -- err = "c_get next_dup"; -- goto fail; -- } -- rc = cursor->c_del( cursor, 0 ); -- if ( rc != 0 ) { -- err = "c_del range"; -- goto fail; -- } -- } -- /* Store the range marker */ -- data.size = data.ulen = sizeof(ID); -- data.flags = DB_DBT_USERMEM; -- nid = 0; -- rc = cursor->c_put( cursor, key, &data, DB_KEYFIRST ); -- if ( rc != 0 ) { -- err = "c_put range"; -- goto fail; -- } -- nid = nlo; -- rc = cursor->c_put( cursor, key, &data, DB_KEYLAST ); -- if ( rc != 0 ) { -- err = "c_put lo"; -- goto fail; -- } -- nid = nhi; -- rc = cursor->c_put( cursor, key, &data, DB_KEYLAST ); -- if ( rc != 0 ) { -- err = "c_put hi"; -- goto fail; -- } -- } else { -- /* There's room, just store it */ -- goto put1; -- } -- } else { -- /* It's a range, see if we need to rewrite -- * the boundaries -- */ -- hi = id; -- data.data = &nlo; -- rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP ); -- if ( rc != 0 ) { -- err = "c_get lo"; -- goto fail; -- } -- BDB_DISK2ID( &nlo, &lo ); -- if ( id > lo ) { -- data.data = &nhi; -- rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP ); -- if ( rc != 0 ) { -- err = "c_get hi"; -- goto fail; -- } -- BDB_DISK2ID( &nhi, &hi ); -- } -- if ( id < lo || id > hi ) { -- /* Delete the current lo/hi */ -- rc = cursor->c_del( cursor, 0 ); -- if ( rc != 0 ) { -- err = "c_del"; -- goto fail; -- } -- data.data = &nid; -- rc = cursor->c_put( cursor, key, &data, DB_KEYFIRST ); -- if ( rc != 0 ) { -- err = "c_put lo/hi"; -- goto fail; -- } -- } -- } -- } else if ( rc == DB_NOTFOUND ) { --put1: data.data = &nid; -- rc = cursor->c_put( cursor, key, &data, DB_NODUPDATA ); -- /* Don't worry if it's already there */ -- if ( rc != 0 && rc != DB_KEYEXIST ) { -- err = "c_put id"; -- goto fail; -- } -- } else { -- /* initial c_get failed, nothing was done */ --fail: -- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_insert_key: " -- "%s failed: %s (%d)\n", err, db_strerror(rc), rc ); -- cursor->c_close( cursor ); -- return rc; -- } -- /* If key was added (didn't already exist) and using IDL cache, -- * update key in IDL cache. -- */ -- if ( !rc && bdb->bi_idl_cache_max_size ) { -- bdb_idl_cache_add_id( bdb, db, key, id ); -- } -- rc = cursor->c_close( cursor ); -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_insert_key: " -- "c_close failed: %s (%d)\n", -- db_strerror(rc), rc, 0 ); -- } -- return rc; --} -- --int --bdb_idl_delete_key( -- BackendDB *be, -- DB *db, -- DB_TXN *tid, -- DBT *key, -- ID id ) --{ -- struct bdb_info *bdb = (struct bdb_info *) be->be_private; -- int rc; -- DBT data; -- DBC *cursor; -- ID lo, hi, tmp, nid, nlo, nhi; -- char *err; -- -- { -- char buf[16]; -- Debug( LDAP_DEBUG_ARGS, -- "bdb_idl_delete_key: %lx %s\n", -- (long) id, bdb_show_key( key, buf ), 0 ); -- } -- assert( id != NOID ); -- -- if ( bdb->bi_idl_cache_size ) { -- bdb_idl_cache_del( bdb, db, key ); -- } -- -- BDB_ID2DISK( id, &nid ); -- -- DBTzero( &data ); -- data.data = &tmp; -- data.size = sizeof( id ); -- data.ulen = data.size; -- data.flags = DB_DBT_USERMEM; -- -- rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags ); -- if ( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_delete_key: " -- "cursor failed: %s (%d)\n", db_strerror(rc), rc, 0 ); -- return rc; -- } -- /* Fetch the first data item for this key, to see if it -- * exists and if it's a range. -- */ -- rc = cursor->c_get( cursor, key, &data, DB_SET ); -- err = "c_get"; -- if ( rc == 0 ) { -- if ( tmp != 0 ) { -- /* Not a range, just delete it */ -- if (tmp != nid) { -- /* position to correct item */ -- tmp = nid; -- rc = cursor->c_get( cursor, key, &data, DB_GET_BOTH ); -- if ( rc != 0 ) { -- err = "c_get id"; -- goto fail; -- } -- } -- rc = cursor->c_del( cursor, 0 ); -- if ( rc != 0 ) { -- err = "c_del id"; -- goto fail; -- } -- } else { -- /* It's a range, see if we need to rewrite -- * the boundaries -- */ -- data.data = &nlo; -- rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP ); -- if ( rc != 0 ) { -- err = "c_get lo"; -- goto fail; -- } -- BDB_DISK2ID( &nlo, &lo ); -- data.data = &nhi; -- rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP ); -- if ( rc != 0 ) { -- err = "c_get hi"; -- goto fail; -- } -- BDB_DISK2ID( &nhi, &hi ); -- if ( id == lo || id == hi ) { -- if ( id == lo ) { -- id++; -- lo = id; -- } else if ( id == hi ) { -- id--; -- hi = id; -- } -- if ( lo >= hi ) { -- /* The range has collapsed... */ -- rc = db->del( db, tid, key, 0 ); -- if ( rc != 0 ) { -- err = "del"; -- goto fail; -- } -- } else { -- if ( id == lo ) { -- /* reposition on lo slot */ -- data.data = &nlo; -- cursor->c_get( cursor, key, &data, DB_PREV ); -- } -- rc = cursor->c_del( cursor, 0 ); -- if ( rc != 0 ) { -- err = "c_del"; -- goto fail; -- } -- } -- if ( lo <= hi ) { -- BDB_ID2DISK( id, &nid ); -- data.data = &nid; -- rc = cursor->c_put( cursor, key, &data, DB_KEYFIRST ); -- if ( rc != 0 ) { -- err = "c_put lo/hi"; -- goto fail; -- } -- } -- } -- } -- } else { -- /* initial c_get failed, nothing was done */ --fail: -- if ( rc != DB_NOTFOUND ) { -- Debug( LDAP_DEBUG_ANY, "=> bdb_idl_delete_key: " -- "%s failed: %s (%d)\n", err, db_strerror(rc), rc ); -- } -- cursor->c_close( cursor ); -- return rc; -- } -- rc = cursor->c_close( cursor ); -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, -- "=> bdb_idl_delete_key: c_close failed: %s (%d)\n", -- db_strerror(rc), rc, 0 ); -- } -- -- return rc; --} -- -- --/* -- * idl_intersection - return a = a intersection b -- */ --int --bdb_idl_intersection( -- ID *a, -- ID *b ) --{ -- ID ida, idb; -- ID idmax, idmin; -- ID cursora = 0, cursorb = 0, cursorc; -- int swap = 0; -- -- if ( BDB_IDL_IS_ZERO( a ) || BDB_IDL_IS_ZERO( b ) ) { -- a[0] = 0; -- return 0; -- } -- -- idmin = IDL_MAX( BDB_IDL_FIRST(a), BDB_IDL_FIRST(b) ); -- idmax = IDL_MIN( BDB_IDL_LAST(a), BDB_IDL_LAST(b) ); -- if ( idmin > idmax ) { -- a[0] = 0; -- return 0; -- } else if ( idmin == idmax ) { -- a[0] = 1; -- a[1] = idmin; -- return 0; -- } -- -- if ( BDB_IDL_IS_RANGE( a ) ) { -- if ( BDB_IDL_IS_RANGE(b) ) { -- /* If both are ranges, just shrink the boundaries */ -- a[1] = idmin; -- a[2] = idmax; -- return 0; -- } else { -- /* Else swap so that b is the range, a is a list */ -- ID *tmp = a; -- a = b; -- b = tmp; -- swap = 1; -- } -- } -- -- /* If a range completely covers the list, the result is -- * just the list. -- */ -- if ( BDB_IDL_IS_RANGE( b ) -- && BDB_IDL_RANGE_FIRST( b ) <= BDB_IDL_FIRST( a ) -- && BDB_IDL_RANGE_LAST( b ) >= BDB_IDL_LLAST( a ) ) { -- goto done; -- } -- -- /* Fine, do the intersection one element at a time. -- * First advance to idmin in both IDLs. -- */ -- cursora = cursorb = idmin; -- ida = bdb_idl_first( a, &cursora ); -- idb = bdb_idl_first( b, &cursorb ); -- cursorc = 0; -- -- while( ida <= idmax || idb <= idmax ) { -- if( ida == idb ) { -- a[++cursorc] = ida; -- ida = bdb_idl_next( a, &cursora ); -- idb = bdb_idl_next( b, &cursorb ); -- } else if ( ida < idb ) { -- ida = bdb_idl_next( a, &cursora ); -- } else { -- idb = bdb_idl_next( b, &cursorb ); -- } -- } -- a[0] = cursorc; --done: -- if (swap) -- BDB_IDL_CPY( b, a ); -- -- return 0; --} -- -- --/* -- * idl_union - return a = a union b -- */ --int --bdb_idl_union( -- ID *a, -- ID *b ) --{ -- ID ida, idb; -- ID cursora = 0, cursorb = 0, cursorc; -- -- if ( BDB_IDL_IS_ZERO( b ) ) { -- return 0; -- } -- -- if ( BDB_IDL_IS_ZERO( a ) ) { -- BDB_IDL_CPY( a, b ); -- return 0; -- } -- -- if ( BDB_IDL_IS_RANGE( a ) || BDB_IDL_IS_RANGE(b) ) { --over: ida = IDL_MIN( BDB_IDL_FIRST(a), BDB_IDL_FIRST(b) ); -- idb = IDL_MAX( BDB_IDL_LAST(a), BDB_IDL_LAST(b) ); -- a[0] = NOID; -- a[1] = ida; -- a[2] = idb; -- return 0; -- } -- -- ida = bdb_idl_first( a, &cursora ); -- idb = bdb_idl_first( b, &cursorb ); -- -- cursorc = b[0]; -- -- /* The distinct elements of a are cat'd to b */ -- while( ida != NOID || idb != NOID ) { -- if ( ida < idb ) { -- if( ++cursorc > BDB_IDL_UM_MAX ) { -- goto over; -- } -- b[cursorc] = ida; -- ida = bdb_idl_next( a, &cursora ); -- -- } else { -- if ( ida == idb ) -- ida = bdb_idl_next( a, &cursora ); -- idb = bdb_idl_next( b, &cursorb ); -- } -- } -- -- /* b is copied back to a in sorted order */ -- a[0] = cursorc; -- cursora = 1; -- cursorb = 1; -- cursorc = b[0]+1; -- while (cursorb <= b[0] || cursorc <= a[0]) { -- if (cursorc > a[0]) -- idb = NOID; -- else -- idb = b[cursorc]; -- if (cursorb <= b[0] && b[cursorb] < idb) -- a[cursora++] = b[cursorb++]; -- else { -- a[cursora++] = idb; -- cursorc++; -- } -- } -- -- return 0; --} -- -- --#if 0 --/* -- * bdb_idl_notin - return a intersection ~b (or a minus b) -- */ --int --bdb_idl_notin( -- ID *a, -- ID *b, -- ID *ids ) --{ -- ID ida, idb; -- ID cursora = 0, cursorb = 0; -- -- if( BDB_IDL_IS_ZERO( a ) || -- BDB_IDL_IS_ZERO( b ) || -- BDB_IDL_IS_RANGE( b ) ) -- { -- BDB_IDL_CPY( ids, a ); -- return 0; -- } -- -- if( BDB_IDL_IS_RANGE( a ) ) { -- BDB_IDL_CPY( ids, a ); -- return 0; -- } -- -- ida = bdb_idl_first( a, &cursora ), -- idb = bdb_idl_first( b, &cursorb ); -- -- ids[0] = 0; -- -- while( ida != NOID ) { -- if ( idb == NOID ) { -- /* we could shortcut this */ -- ids[++ids[0]] = ida; -- ida = bdb_idl_next( a, &cursora ); -- -- } else if ( ida < idb ) { -- ids[++ids[0]] = ida; -- ida = bdb_idl_next( a, &cursora ); -- -- } else if ( ida > idb ) { -- idb = bdb_idl_next( b, &cursorb ); -- -- } else { -- ida = bdb_idl_next( a, &cursora ); -- idb = bdb_idl_next( b, &cursorb ); -- } -- } -- -- return 0; --} --#endif -- --ID bdb_idl_first( ID *ids, ID *cursor ) --{ -- ID pos; -- -- if ( ids[0] == 0 ) { -- *cursor = NOID; -- return NOID; -- } -- -- if ( BDB_IDL_IS_RANGE( ids ) ) { -- if( *cursor < ids[1] ) { -- *cursor = ids[1]; -- } -- return *cursor; -- } -- -- if ( *cursor == 0 ) -- pos = 1; -- else -- pos = bdb_idl_search( ids, *cursor ); -- -- if( pos > ids[0] ) { -- return NOID; -- } -- -- *cursor = pos; -- return ids[pos]; --} -- --ID bdb_idl_next( ID *ids, ID *cursor ) --{ -- if ( BDB_IDL_IS_RANGE( ids ) ) { -- if( ids[2] < ++(*cursor) ) { -- return NOID; -- } -- return *cursor; -- } -- -- if ( ++(*cursor) <= ids[0] ) { -- return ids[*cursor]; -- } -- -- return NOID; --} -- --#ifdef BDB_HIER -- --/* Add one ID to an unsorted list. We ensure that the first element is the -- * minimum and the last element is the maximum, for fast range compaction. -- * this means IDLs up to length 3 are always sorted... -- */ --int bdb_idl_append_one( ID *ids, ID id ) --{ -- if (BDB_IDL_IS_RANGE( ids )) { -- /* if already in range, treat as a dup */ -- if (id >= BDB_IDL_RANGE_FIRST(ids) && id <= BDB_IDL_RANGE_LAST(ids)) -- return -1; -- if (id < BDB_IDL_RANGE_FIRST(ids)) -- ids[1] = id; -- else if (id > BDB_IDL_RANGE_LAST(ids)) -- ids[2] = id; -- return 0; -- } -- if ( ids[0] ) { -- ID tmp; -- -- if (id < ids[1]) { -- tmp = ids[1]; -- ids[1] = id; -- id = tmp; -- } -- if ( ids[0] > 1 && id < ids[ids[0]] ) { -- tmp = ids[ids[0]]; -- ids[ids[0]] = id; -- id = tmp; -- } -- } -- ids[0]++; -- if ( ids[0] >= BDB_IDL_UM_MAX ) { -- ids[0] = NOID; -- ids[2] = id; -- } else { -- ids[ids[0]] = id; -- } -- return 0; --} -- --/* Append sorted list b to sorted list a. The result is unsorted but -- * a[1] is the min of the result and a[a[0]] is the max. -- */ --int bdb_idl_append( ID *a, ID *b ) --{ -- ID ida, idb, tmp, swap = 0; -- -- if ( BDB_IDL_IS_ZERO( b ) ) { -- return 0; -- } -- -- if ( BDB_IDL_IS_ZERO( a ) ) { -- BDB_IDL_CPY( a, b ); -- return 0; -- } -- -- if ( b[0] == 1 ) { -- return bdb_idl_append_one( a, BDB_IDL_FIRST( b )); -- } -- -- ida = BDB_IDL_LAST( a ); -- idb = BDB_IDL_LAST( b ); -- if ( BDB_IDL_IS_RANGE( a ) || BDB_IDL_IS_RANGE(b) || -- a[0] + b[0] >= BDB_IDL_UM_MAX ) { -- a[2] = IDL_MAX( ida, idb ); -- a[1] = IDL_MIN( a[1], b[1] ); -- a[0] = NOID; -- return 0; -- } -- -- if ( ida > idb ) { -- swap = idb; -- a[a[0]] = idb; -- b[b[0]] = ida; -- } -- -- if ( b[1] < a[1] ) { -- tmp = a[1]; -- a[1] = b[1]; -- } else { -- tmp = b[1]; -- } -- a[0]++; -- a[a[0]] = tmp; -- -- { -- int i = b[0] - 1; -- AC_MEMCPY(a+a[0]+1, b+2, i * sizeof(ID)); -- a[0] += i; -- } -- if ( swap ) { -- b[b[0]] = swap; -- } -- return 0; --} -- --#if 1 -- --/* Quicksort + Insertion sort for small arrays */ -- --#define SMALL 8 --#define SWAP(a,b) itmp=(a);(a)=(b);(b)=itmp -- --void --bdb_idl_sort( ID *ids, ID *tmp ) --{ -- int *istack = (int *)tmp; -- int i,j,k,l,ir,jstack; -- ID a, itmp; -- -- if ( BDB_IDL_IS_RANGE( ids )) -- return; -- -- ir = ids[0]; -- l = 1; -- jstack = 0; -- for(;;) { -- if (ir - l < SMALL) { /* Insertion sort */ -- for (j=l+1;j<=ir;j++) { -- a = ids[j]; -- for (i=j-1;i>=1;i--) { -- if (ids[i] <= a) break; -- ids[i+1] = ids[i]; -- } -- ids[i+1] = a; -- } -- if (jstack == 0) break; -- ir = istack[jstack--]; -- l = istack[jstack--]; -- } else { -- k = (l + ir) >> 1; /* Choose median of left, center, right */ -- SWAP(ids[k], ids[l+1]); -- if (ids[l] > ids[ir]) { -- SWAP(ids[l], ids[ir]); -- } -- if (ids[l+1] > ids[ir]) { -- SWAP(ids[l+1], ids[ir]); -- } -- if (ids[l] > ids[l+1]) { -- SWAP(ids[l], ids[l+1]); -- } -- i = l+1; -- j = ir; -- a = ids[l+1]; -- for(;;) { -- do i++; while(ids[i] < a); -- do j--; while(ids[j] > a); -- if (j < i) break; -- SWAP(ids[i],ids[j]); -- } -- ids[l+1] = ids[j]; -- ids[j] = a; -- jstack += 2; -- if (ir-i+1 >= j-1) { -- istack[jstack] = ir; -- istack[jstack-1] = i; -- ir = j-1; -- } else { -- istack[jstack] = j-1; -- istack[jstack-1] = l; -- l = i; -- } -- } -- } --} -- --#else -- --/* 8 bit Radix sort + insertion sort -- * -- * based on code from http://www.cubic.org/docs/radix.htm -- * with improvements by ebackes@symas.com and hyc@symas.com -- * -- * This code is O(n) but has a relatively high constant factor. For lists -- * up to ~50 Quicksort is slightly faster; up to ~100 they are even. -- * Much faster than quicksort for lists longer than ~100. Insertion -- * sort is actually superior for lists <50. -- */ -- --#define BUCKETS (1<<8) --#define SMALL 50 -- --void --bdb_idl_sort( ID *ids, ID *tmp ) --{ -- int count, soft_limit, phase = 0, size = ids[0]; -- ID *idls[2]; -- unsigned char *maxv = (unsigned char *)&ids[size]; -- -- if ( BDB_IDL_IS_RANGE( ids )) -- return; -- -- /* Use insertion sort for small lists */ -- if ( size <= SMALL ) { -- int i,j; -- ID a; -- -- for (j=1;j<=size;j++) { -- a = ids[j]; -- for (i=j-1;i>=1;i--) { -- if (ids[i] <= a) break; -- ids[i+1] = ids[i]; -- } -- ids[i+1] = a; -- } -- return; -- } -- -- tmp[0] = size; -- idls[0] = ids; -- idls[1] = tmp; -- --#if BYTE_ORDER == BIG_ENDIAN -- for (soft_limit = 0; !maxv[soft_limit]; soft_limit++); --#else -- for (soft_limit = sizeof(ID)-1; !maxv[soft_limit]; soft_limit--); --#endif -- -- for ( --#if BYTE_ORDER == BIG_ENDIAN -- count = sizeof(ID)-1; count >= soft_limit; --count --#else -- count = 0; count <= soft_limit; ++count --#endif -- ) { -- unsigned int num[BUCKETS], * np, n, sum; -- int i; -- ID *sp, *source, *dest; -- unsigned char *bp, *source_start; -- -- source = idls[phase]+1; -- dest = idls[phase^1]+1; -- source_start = ((unsigned char *) source) + count; -- -- np = num; -- for ( i = BUCKETS; i > 0; --i ) *np++ = 0; -- -- /* count occurences of every byte value */ -- bp = source_start; -- for ( i = size; i > 0; --i, bp += sizeof(ID) ) -- num[*bp]++; -- -- /* transform count into index by summing elements and storing -- * into same array -- */ -- sum = 0; -- np = num; -- for ( i = BUCKETS; i > 0; --i ) { -- n = *np; -- *np++ = sum; -- sum += n; -- } -- -- /* fill dest with the right values in the right place */ -- bp = source_start; -- sp = source; -- for ( i = size; i > 0; --i, bp += sizeof(ID) ) { -- np = num + *bp; -- dest[*np] = *sp++; -- ++(*np); -- } -- phase ^= 1; -- } -- -- /* copy back from temp if needed */ -- if ( phase ) { -- ids++; tmp++; -- for ( count = 0; count < size; ++count ) -- *ids++ = *tmp++; -- } --} --#endif /* Quick vs Radix */ -- --#endif /* BDB_HIER */ -diff --git a/servers/slapd/back-bdb/idl.h b/servers/slapd/back-bdb/idl.h -deleted file mode 100644 -index 909a43b..0000000 ---- a/servers/slapd/back-bdb/idl.h -+++ /dev/null -@@ -1,75 +0,0 @@ --/* idl.h - ldap bdb back-end ID list header file */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#ifndef _BDB_IDL_H_ --#define _BDB_IDL_H_ -- --/* IDL sizes - likely should be even bigger -- * limiting factors: sizeof(ID), thread stack size -- */ --#define BDB_IDL_LOGN 16 /* DB_SIZE is 2^16, UM_SIZE is 2^17 */ --#define BDB_IDL_DB_SIZE (1<bi_lastid) ) --#define BDB_IDL_ALL( bdb, ids ) BDB_IDL_RANGE( ids, 1, ((bdb)->bi_lastid) ) -- --#define BDB_IDL_FIRST( ids ) ( (ids)[1] ) --#define BDB_IDL_LLAST( ids ) ( (ids)[(ids)[0]] ) --#define BDB_IDL_LAST( ids ) ( BDB_IDL_IS_RANGE(ids) \ -- ? (ids)[2] : (ids)[(ids)[0]] ) -- --#define BDB_IDL_N( ids ) ( BDB_IDL_IS_RANGE(ids) \ -- ? ((ids)[2]-(ids)[1])+1 : (ids)[0] ) -- --LDAP_BEGIN_DECL --LDAP_END_DECL -- --#endif -diff --git a/servers/slapd/back-bdb/index.c b/servers/slapd/back-bdb/index.c -deleted file mode 100644 -index c095641..0000000 ---- a/servers/slapd/back-bdb/index.c -+++ /dev/null -@@ -1,574 +0,0 @@ --/* index.c - routines for dealing with attribute indexes */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include -- --#include --#include -- --#include "slap.h" --#include "back-bdb.h" --#include "lutil_hash.h" -- --static char presence_keyval[] = {0,0}; --static struct berval presence_key = BER_BVC(presence_keyval); -- --AttrInfo *bdb_index_mask( -- Backend *be, -- AttributeDescription *desc, -- struct berval *atname ) --{ -- AttributeType *at; -- AttrInfo *ai = bdb_attr_mask( be->be_private, desc ); -- -- if( ai ) { -- *atname = desc->ad_cname; -- return ai; -- } -- -- /* If there is a tagging option, did we ever index the base -- * type? If so, check for mask, otherwise it's not there. -- */ -- if( slap_ad_is_tagged( desc ) && desc != desc->ad_type->sat_ad ) { -- /* has tagging option */ -- ai = bdb_attr_mask( be->be_private, desc->ad_type->sat_ad ); -- -- if ( ai && !( ai->ai_indexmask & SLAP_INDEX_NOTAGS ) ) { -- *atname = desc->ad_type->sat_cname; -- return ai; -- } -- } -- -- /* see if supertype defined mask for its subtypes */ -- for( at = desc->ad_type; at != NULL ; at = at->sat_sup ) { -- /* If no AD, we've never indexed this type */ -- if ( !at->sat_ad ) continue; -- -- ai = bdb_attr_mask( be->be_private, at->sat_ad ); -- -- if ( ai && !( ai->ai_indexmask & SLAP_INDEX_NOSUBTYPES ) ) { -- *atname = at->sat_cname; -- return ai; -- } -- } -- -- return 0; --} -- --/* This function is only called when evaluating search filters. -- */ --int bdb_index_param( -- Backend *be, -- AttributeDescription *desc, -- int ftype, -- DB **dbp, -- slap_mask_t *maskp, -- struct berval *prefixp ) --{ -- AttrInfo *ai; -- int rc; -- slap_mask_t mask, type = 0; -- DB *db; -- -- ai = bdb_index_mask( be, desc, prefixp ); -- -- if ( !ai ) { --#ifdef BDB_MONITOR_IDX -- switch ( ftype ) { -- case LDAP_FILTER_PRESENT: -- type = SLAP_INDEX_PRESENT; -- break; -- case LDAP_FILTER_APPROX: -- type = SLAP_INDEX_APPROX; -- break; -- case LDAP_FILTER_EQUALITY: -- type = SLAP_INDEX_EQUALITY; -- break; -- case LDAP_FILTER_SUBSTRINGS: -- type = SLAP_INDEX_SUBSTR; -- break; -- default: -- return LDAP_INAPPROPRIATE_MATCHING; -- } -- bdb_monitor_idx_add( be->be_private, desc, type ); --#endif /* BDB_MONITOR_IDX */ -- -- return LDAP_INAPPROPRIATE_MATCHING; -- } -- mask = ai->ai_indexmask; -- -- rc = bdb_db_cache( be, prefixp, &db ); -- -- if( rc != LDAP_SUCCESS ) { -- return rc; -- } -- -- switch( ftype ) { -- case LDAP_FILTER_PRESENT: -- type = SLAP_INDEX_PRESENT; -- if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) { -- *prefixp = presence_key; -- goto done; -- } -- break; -- -- case LDAP_FILTER_APPROX: -- type = SLAP_INDEX_APPROX; -- if ( desc->ad_type->sat_approx ) { -- if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) { -- goto done; -- } -- break; -- } -- -- /* Use EQUALITY rule and index for approximate match */ -- /* fall thru */ -- -- case LDAP_FILTER_EQUALITY: -- type = SLAP_INDEX_EQUALITY; -- if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) { -- goto done; -- } -- break; -- -- case LDAP_FILTER_SUBSTRINGS: -- type = SLAP_INDEX_SUBSTR; -- if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) { -- goto done; -- } -- break; -- -- default: -- return LDAP_OTHER; -- } -- --#ifdef BDB_MONITOR_IDX -- bdb_monitor_idx_add( be->be_private, desc, type ); --#endif /* BDB_MONITOR_IDX */ -- -- return LDAP_INAPPROPRIATE_MATCHING; -- --done: -- *dbp = db; -- *maskp = mask; -- return LDAP_SUCCESS; --} -- --static int indexer( -- Operation *op, -- DB_TXN *txn, -- AttributeDescription *ad, -- struct berval *atname, -- BerVarray vals, -- ID id, -- int opid, -- slap_mask_t mask ) --{ -- int rc, i; -- DB *db; -- struct berval *keys; -- -- assert( mask != 0 ); -- -- rc = bdb_db_cache( op->o_bd, atname, &db ); -- -- if ( rc != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_ANY, -- "bdb_index_read: Could not open DB %s\n", -- atname->bv_val, 0, 0 ); -- return LDAP_OTHER; -- } -- -- if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) { -- rc = bdb_key_change( op->o_bd, db, txn, &presence_key, id, opid ); -- if( rc ) { -- goto done; -- } -- } -- -- if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) { -- rc = ad->ad_type->sat_equality->smr_indexer( -- LDAP_FILTER_EQUALITY, -- mask, -- ad->ad_type->sat_syntax, -- ad->ad_type->sat_equality, -- atname, vals, &keys, op->o_tmpmemctx ); -- -- if( rc == LDAP_SUCCESS && keys != NULL ) { -- for( i=0; keys[i].bv_val != NULL; i++ ) { -- rc = bdb_key_change( op->o_bd, db, txn, &keys[i], id, opid ); -- if( rc ) { -- ber_bvarray_free_x( keys, op->o_tmpmemctx ); -- goto done; -- } -- } -- ber_bvarray_free_x( keys, op->o_tmpmemctx ); -- } -- rc = LDAP_SUCCESS; -- } -- -- if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) { -- rc = ad->ad_type->sat_approx->smr_indexer( -- LDAP_FILTER_APPROX, -- mask, -- ad->ad_type->sat_syntax, -- ad->ad_type->sat_approx, -- atname, vals, &keys, op->o_tmpmemctx ); -- -- if( rc == LDAP_SUCCESS && keys != NULL ) { -- for( i=0; keys[i].bv_val != NULL; i++ ) { -- rc = bdb_key_change( op->o_bd, db, txn, &keys[i], id, opid ); -- if( rc ) { -- ber_bvarray_free_x( keys, op->o_tmpmemctx ); -- goto done; -- } -- } -- ber_bvarray_free_x( keys, op->o_tmpmemctx ); -- } -- -- rc = LDAP_SUCCESS; -- } -- -- if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) { -- rc = ad->ad_type->sat_substr->smr_indexer( -- LDAP_FILTER_SUBSTRINGS, -- mask, -- ad->ad_type->sat_syntax, -- ad->ad_type->sat_substr, -- atname, vals, &keys, op->o_tmpmemctx ); -- -- if( rc == LDAP_SUCCESS && keys != NULL ) { -- for( i=0; keys[i].bv_val != NULL; i++ ) { -- rc = bdb_key_change( op->o_bd, db, txn, &keys[i], id, opid ); -- if( rc ) { -- ber_bvarray_free_x( keys, op->o_tmpmemctx ); -- goto done; -- } -- } -- ber_bvarray_free_x( keys, op->o_tmpmemctx ); -- } -- -- rc = LDAP_SUCCESS; -- } -- --done: -- switch( rc ) { -- /* The callers all know how to deal with these results */ -- case 0: -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- break; -- /* Anything else is bad news */ -- default: -- rc = LDAP_OTHER; -- } -- return rc; --} -- --static int index_at_values( -- Operation *op, -- DB_TXN *txn, -- AttributeDescription *ad, -- AttributeType *type, -- struct berval *tags, -- BerVarray vals, -- ID id, -- int opid ) --{ -- int rc; -- slap_mask_t mask = 0; -- int ixop = opid; -- AttrInfo *ai = NULL; -- -- if ( opid == BDB_INDEX_UPDATE_OP ) -- ixop = SLAP_INDEX_ADD_OP; -- -- if( type->sat_sup ) { -- /* recurse */ -- rc = index_at_values( op, txn, NULL, -- type->sat_sup, tags, -- vals, id, opid ); -- -- if( rc ) return rc; -- } -- -- /* If this type has no AD, we've never used it before */ -- if( type->sat_ad ) { -- ai = bdb_attr_mask( op->o_bd->be_private, type->sat_ad ); -- if ( ai ) { --#ifdef LDAP_COMP_MATCH -- /* component indexing */ -- if ( ai->ai_cr ) { -- ComponentReference *cr; -- for( cr = ai->ai_cr ; cr ; cr = cr->cr_next ) { -- rc = indexer( op, txn, cr->cr_ad, &type->sat_cname, -- cr->cr_nvals, id, ixop, -- cr->cr_indexmask ); -- } -- } --#endif -- ad = type->sat_ad; -- /* If we're updating the index, just set the new bits that aren't -- * already in the old mask. -- */ -- if ( opid == BDB_INDEX_UPDATE_OP ) -- mask = ai->ai_newmask & ~ai->ai_indexmask; -- else -- /* For regular updates, if there is a newmask use it. Otherwise -- * just use the old mask. -- */ -- mask = ai->ai_newmask ? ai->ai_newmask : ai->ai_indexmask; -- if( mask ) { -- rc = indexer( op, txn, ad, &type->sat_cname, -- vals, id, ixop, mask ); -- -- if( rc ) return rc; -- } -- } -- } -- -- if( tags->bv_len ) { -- AttributeDescription *desc; -- -- desc = ad_find_tags( type, tags ); -- if( desc ) { -- ai = bdb_attr_mask( op->o_bd->be_private, desc ); -- -- if( ai ) { -- if ( opid == BDB_INDEX_UPDATE_OP ) -- mask = ai->ai_newmask & ~ai->ai_indexmask; -- else -- mask = ai->ai_newmask ? ai->ai_newmask : ai->ai_indexmask; -- if ( mask ) { -- rc = indexer( op, txn, desc, &desc->ad_cname, -- vals, id, ixop, mask ); -- -- if( rc ) { -- return rc; -- } -- } -- } -- } -- } -- -- return LDAP_SUCCESS; --} -- --int bdb_index_values( -- Operation *op, -- DB_TXN *txn, -- AttributeDescription *desc, -- BerVarray vals, -- ID id, -- int opid ) --{ -- int rc; -- -- /* Never index ID 0 */ -- if ( id == 0 ) -- return 0; -- -- rc = index_at_values( op, txn, desc, -- desc->ad_type, &desc->ad_tags, -- vals, id, opid ); -- -- return rc; --} -- --/* Get the list of which indices apply to this attr */ --int --bdb_index_recset( -- struct bdb_info *bdb, -- Attribute *a, -- AttributeType *type, -- struct berval *tags, -- IndexRec *ir ) --{ -- int rc, slot; -- AttrList *al; -- -- if( type->sat_sup ) { -- /* recurse */ -- rc = bdb_index_recset( bdb, a, type->sat_sup, tags, ir ); -- if( rc ) return rc; -- } -- /* If this type has no AD, we've never used it before */ -- if( type->sat_ad ) { -- slot = bdb_attr_slot( bdb, type->sat_ad, NULL ); -- if ( slot >= 0 ) { -- ir[slot].ai = bdb->bi_attrs[slot]; -- al = ch_malloc( sizeof( AttrList )); -- al->attr = a; -- al->next = ir[slot].attrs; -- ir[slot].attrs = al; -- } -- } -- if( tags->bv_len ) { -- AttributeDescription *desc; -- -- desc = ad_find_tags( type, tags ); -- if( desc ) { -- slot = bdb_attr_slot( bdb, desc, NULL ); -- if ( slot >= 0 ) { -- ir[slot].ai = bdb->bi_attrs[slot]; -- al = ch_malloc( sizeof( AttrList )); -- al->attr = a; -- al->next = ir[slot].attrs; -- ir[slot].attrs = al; -- } -- } -- } -- return LDAP_SUCCESS; --} -- --/* Apply the indices for the recset */ --int bdb_index_recrun( -- Operation *op, -- struct bdb_info *bdb, -- IndexRec *ir0, -- ID id, -- int base ) --{ -- IndexRec *ir; -- AttrList *al; -- int i, rc = 0; -- -- /* Never index ID 0 */ -- if ( id == 0 ) -- return 0; -- -- for (i=base; ibi_nattrs; i+=slap_tool_thread_max-1) { -- ir = ir0 + i; -- if ( !ir->ai ) continue; -- while (( al = ir->attrs )) { -- ir->attrs = al->next; -- rc = indexer( op, NULL, ir->ai->ai_desc, -- &ir->ai->ai_desc->ad_type->sat_cname, -- al->attr->a_nvals, id, SLAP_INDEX_ADD_OP, -- ir->ai->ai_indexmask ); -- free( al ); -- if ( rc ) break; -- } -- } -- return rc; --} -- --int --bdb_index_entry( -- Operation *op, -- DB_TXN *txn, -- int opid, -- Entry *e ) --{ -- int rc; -- Attribute *ap = e->e_attrs; --#if 0 /* ifdef LDAP_COMP_MATCH */ -- ComponentReference *cr_list = NULL; -- ComponentReference *cr = NULL, *dupped_cr = NULL; -- void* decoded_comp; -- ComponentSyntaxInfo* csi_attr; -- Syntax* syn; -- AttributeType* at; -- int i, num_attr; -- void* mem_op; -- struct berval value = {0}; --#endif -- -- /* Never index ID 0 */ -- if ( e->e_id == 0 ) -- return 0; -- -- Debug( LDAP_DEBUG_TRACE, "=> index_entry_%s( %ld, \"%s\" )\n", -- opid == SLAP_INDEX_DELETE_OP ? "del" : "add", -- (long) e->e_id, e->e_dn ); -- -- /* add each attribute to the indexes */ -- for ( ; ap != NULL; ap = ap->a_next ) { --#if 0 /* ifdef LDAP_COMP_MATCH */ -- AttrInfo *ai; -- /* see if attribute has components to be indexed */ -- ai = bdb_attr_mask( op->o_bd->be_private, ap->a_desc->ad_type->sat_ad ); -- if ( !ai ) continue; -- cr_list = ai->ai_cr; -- if ( attr_converter && cr_list ) { -- syn = ap->a_desc->ad_type->sat_syntax; -- ap->a_comp_data = op->o_tmpalloc( sizeof( ComponentData ), op->o_tmpmemctx ); -- /* Memory chunk(nibble) pre-allocation for decoders */ -- mem_op = nibble_mem_allocator ( 1024*16, 1024*4 ); -- ap->a_comp_data->cd_mem_op = mem_op; -- for( cr = cr_list ; cr ; cr = cr->cr_next ) { -- /* count how many values in an attribute */ -- for( num_attr=0; ap->a_vals[num_attr].bv_val != NULL; num_attr++ ); -- num_attr++; -- cr->cr_nvals = (BerVarray)op->o_tmpalloc( sizeof( struct berval )*num_attr, op->o_tmpmemctx ); -- for( i=0; ap->a_vals[i].bv_val != NULL; i++ ) { -- /* decoding attribute value */ -- decoded_comp = attr_converter ( ap, syn, &ap->a_vals[i] ); -- if ( !decoded_comp ) -- return LDAP_DECODING_ERROR; -- /* extracting the referenced component */ -- dupped_cr = dup_comp_ref( op, cr ); -- csi_attr = ((ComponentSyntaxInfo*)decoded_comp)->csi_comp_desc->cd_extract_i( mem_op, dupped_cr, decoded_comp ); -- if ( !csi_attr ) -- return LDAP_DECODING_ERROR; -- cr->cr_asn_type_id = csi_attr->csi_comp_desc->cd_type_id; -- cr->cr_ad = (AttributeDescription*)get_component_description ( cr->cr_asn_type_id ); -- if ( !cr->cr_ad ) -- return LDAP_INVALID_SYNTAX; -- at = cr->cr_ad->ad_type; -- /* encoding the value of component in GSER */ -- rc = component_encoder( mem_op, csi_attr, &value ); -- if ( rc != LDAP_SUCCESS ) -- return LDAP_ENCODING_ERROR; -- /* Normalize the encoded component values */ -- if ( at->sat_equality && at->sat_equality->smr_normalize ) { -- rc = at->sat_equality->smr_normalize ( -- SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, -- at->sat_syntax, at->sat_equality, -- &value, &cr->cr_nvals[i], op->o_tmpmemctx ); -- } else { -- cr->cr_nvals[i] = value; -- } -- } -- /* The end of BerVarray */ -- cr->cr_nvals[num_attr-1].bv_val = NULL; -- cr->cr_nvals[num_attr-1].bv_len = 0; -- } -- op->o_tmpfree( ap->a_comp_data, op->o_tmpmemctx ); -- nibble_mem_free ( mem_op ); -- ap->a_comp_data = NULL; -- } --#endif -- rc = bdb_index_values( op, txn, ap->a_desc, -- ap->a_nvals, e->e_id, opid ); -- -- if( rc != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_TRACE, -- "<= index_entry_%s( %ld, \"%s\" ) failure\n", -- opid == SLAP_INDEX_ADD_OP ? "add" : "del", -- (long) e->e_id, e->e_dn ); -- return rc; -- } -- } -- -- Debug( LDAP_DEBUG_TRACE, "<= index_entry_%s( %ld, \"%s\" ) success\n", -- opid == SLAP_INDEX_DELETE_OP ? "del" : "add", -- (long) e->e_id, e->e_dn ); -- -- return LDAP_SUCCESS; --} -diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c -deleted file mode 100644 -index 6c42d54..0000000 ---- a/servers/slapd/back-bdb/init.c -+++ /dev/null -@@ -1,874 +0,0 @@ --/* init.c - initialize bdb backend */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include --#include --#include --#include --#include --#include --#include "back-bdb.h" --#include --#include --#include "alock.h" --#include "config.h" -- --static const struct bdbi_database { -- char *file; -- struct berval name; -- int type; -- int flags; --} bdbi_databases[] = { -- { "id2entry" BDB_SUFFIX, BER_BVC("id2entry"), DB_BTREE, 0 }, -- { "dn2id" BDB_SUFFIX, BER_BVC("dn2id"), DB_BTREE, 0 }, -- { NULL, BER_BVNULL, 0, 0 } --}; -- --typedef void * db_malloc(size_t); --typedef void * db_realloc(void *, size_t); -- --#define bdb_db_init BDB_SYMBOL(db_init) --#define bdb_db_open BDB_SYMBOL(db_open) --#define bdb_db_close BDB_SYMBOL(db_close) -- --static int --bdb_db_init( BackendDB *be, ConfigReply *cr ) --{ -- struct bdb_info *bdb; -- int rc; -- -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_db_init) ": Initializing " BDB_UCTYPE " database\n", -- 0, 0, 0 ); -- -- /* allocate backend-database-specific stuff */ -- bdb = (struct bdb_info *) ch_calloc( 1, sizeof(struct bdb_info) ); -- -- /* DBEnv parameters */ -- bdb->bi_dbenv_home = ch_strdup( SLAPD_DEFAULT_DB_DIR ); -- bdb->bi_dbenv_xflags = DB_TIME_NOTGRANTED; -- bdb->bi_dbenv_mode = SLAPD_DEFAULT_DB_MODE; -- -- bdb->bi_cache.c_maxsize = DEFAULT_CACHE_SIZE; -- bdb->bi_cache.c_minfree = 1; -- -- bdb->bi_lock_detect = DB_LOCK_DEFAULT; -- bdb->bi_search_stack_depth = DEFAULT_SEARCH_STACK_DEPTH; -- bdb->bi_search_stack = NULL; -- -- ldap_pvt_thread_mutex_init( &bdb->bi_database_mutex ); -- ldap_pvt_thread_mutex_init( &bdb->bi_lastid_mutex ); --#ifdef BDB_HIER -- ldap_pvt_thread_mutex_init( &bdb->bi_modrdns_mutex ); --#endif -- ldap_pvt_thread_mutex_init( &bdb->bi_cache.c_lru_mutex ); -- ldap_pvt_thread_mutex_init( &bdb->bi_cache.c_count_mutex ); -- ldap_pvt_thread_mutex_init( &bdb->bi_cache.c_eifree_mutex ); -- ldap_pvt_thread_mutex_init( &bdb->bi_cache.c_dntree.bei_kids_mutex ); -- ldap_pvt_thread_rdwr_init ( &bdb->bi_cache.c_rwlock ); -- ldap_pvt_thread_rdwr_init( &bdb->bi_idl_tree_rwlock ); -- ldap_pvt_thread_mutex_init( &bdb->bi_idl_tree_lrulock ); -- -- be->be_private = bdb; -- be->be_cf_ocs = be->bd_info->bi_cf_ocs; -- --#ifndef BDB_MULTIPLE_SUFFIXES -- SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_ONE_SUFFIX; --#endif -- -- rc = bdb_monitor_db_init( be ); -- -- return rc; --} -- --static int --bdb_db_close( BackendDB *be, ConfigReply *cr ); -- --static int --bdb_db_open( BackendDB *be, ConfigReply *cr ) --{ -- int rc, i; -- struct bdb_info *bdb = (struct bdb_info *) be->be_private; -- struct stat stat1, stat2; -- u_int32_t flags; -- char path[MAXPATHLEN]; -- char *dbhome; -- Entry *e = NULL; -- int do_recover = 0, do_alock_recover = 0; -- int alockt, quick = 0; -- int do_retry = 1; -- -- if ( be->be_suffix == NULL ) { -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": need suffix.\n", -- 1, 0, 0 ); -- return -1; -- } -- -- Debug( LDAP_DEBUG_ARGS, -- LDAP_XSTRING(bdb_db_open) ": \"%s\"\n", -- be->be_suffix[0].bv_val, 0, 0 ); -- -- /* Check existence of dbenv_home. Any error means trouble */ -- rc = stat( bdb->bi_dbenv_home, &stat1 ); -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " -- "cannot access database directory \"%s\" (%d).\n", -- be->be_suffix[0].bv_val, bdb->bi_dbenv_home, errno ); -- return -1; -- } -- -- /* Perform database use arbitration/recovery logic */ -- alockt = (slapMode & SLAP_TOOL_READONLY) ? ALOCK_LOCKED : ALOCK_UNIQUE; -- if ( slapMode & SLAP_TOOL_QUICK ) { -- alockt |= ALOCK_NOSAVE; -- quick = 1; -- } -- -- rc = alock_open( &bdb->bi_alock_info, -- "slapd", -- bdb->bi_dbenv_home, alockt ); -- -- /* alockt is TRUE if the existing environment was created in Quick mode */ -- alockt = (rc & ALOCK_NOSAVE) ? 1 : 0; -- rc &= ~ALOCK_NOSAVE; -- -- if( rc == ALOCK_RECOVER ) { -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " -- "unclean shutdown detected; attempting recovery.\n", -- be->be_suffix[0].bv_val, 0, 0 ); -- do_alock_recover = 1; -- do_recover = DB_RECOVER; -- } else if( rc == ALOCK_BUSY ) { -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " -- "database already in use.\n", -- be->be_suffix[0].bv_val, 0, 0 ); -- return -1; -- } else if( rc != ALOCK_CLEAN ) { -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " -- "alock package is unstable.\n", -- be->be_suffix[0].bv_val, 0, 0 ); -- return -1; -- } -- if ( rc == ALOCK_CLEAN ) -- be->be_flags |= SLAP_DBFLAG_CLEAN; -- -- /* -- * The DB_CONFIG file may have changed. If so, recover the -- * database so that new settings are put into effect. Also -- * note the possible absence of DB_CONFIG in the log. -- */ -- if( stat( bdb->bi_db_config_path, &stat1 ) == 0 ) { -- if ( !do_recover ) { -- char *ptr = lutil_strcopy(path, bdb->bi_dbenv_home); -- *ptr++ = LDAP_DIRSEP[0]; -- strcpy( ptr, "__db.001" ); -- if( stat( path, &stat2 ) == 0 ) { -- if( stat2.st_mtime < stat1.st_mtime ) { -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": DB_CONFIG for suffix \"%s\" has changed.\n", -- be->be_suffix[0].bv_val, 0, 0 ); -- if ( quick ) { -- Debug( LDAP_DEBUG_ANY, -- "Cannot use Quick mode; perform manual recovery first.\n", -- 0, 0, 0 ); -- slapMode ^= SLAP_TOOL_QUICK; -- rc = -1; -- goto fail; -- } else { -- Debug( LDAP_DEBUG_ANY, -- "Performing database recovery to activate new settings.\n", -- 0, 0, 0 ); -- } -- do_recover = DB_RECOVER; -- } -- } -- } -- } -- else { -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": warning - no DB_CONFIG file found " -- "in directory %s: (%d).\n" -- "Expect poor performance for suffix \"%s\".\n", -- bdb->bi_dbenv_home, errno, be->be_suffix[0].bv_val ); -- } -- -- /* Always let slapcat run, regardless of environment state. -- * This can be used to cause a cache flush after an unclean -- * shutdown. -- */ -- if ( do_recover && ( slapMode & SLAP_TOOL_READONLY )) { -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " -- "recovery skipped in read-only mode. " -- "Run manual recovery if errors are encountered.\n", -- be->be_suffix[0].bv_val, 0, 0 ); -- do_recover = 0; -- do_alock_recover = 0; -- quick = alockt; -- } -- -- /* An existing environment in Quick mode has nothing to recover. */ -- if ( alockt && do_recover ) { -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " -- "cannot recover, database must be reinitialized.\n", -- be->be_suffix[0].bv_val, 0, 0 ); -- rc = -1; -- goto fail; -- } -- -- rc = db_env_create( &bdb->bi_dbenv, 0 ); -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " -- "db_env_create failed: %s (%d).\n", -- be->be_suffix[0].bv_val, db_strerror(rc), rc ); -- goto fail; -- } -- --#ifdef HAVE_EBCDIC -- strcpy( path, bdb->bi_dbenv_home ); -- __atoe( path ); -- dbhome = path; --#else -- dbhome = bdb->bi_dbenv_home; --#endif -- -- /* If existing environment is clean but doesn't support -- * currently requested modes, remove it. -- */ -- if ( !do_recover && ( alockt ^ quick )) { --shm_retry: -- rc = bdb->bi_dbenv->remove( bdb->bi_dbenv, dbhome, DB_FORCE ); -- if ( rc ) { -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " -- "dbenv remove failed: %s (%d).\n", -- be->be_suffix[0].bv_val, db_strerror(rc), rc ); -- bdb->bi_dbenv = NULL; -- goto fail; -- } -- rc = db_env_create( &bdb->bi_dbenv, 0 ); -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " -- "db_env_create failed: %s (%d).\n", -- be->be_suffix[0].bv_val, db_strerror(rc), rc ); -- goto fail; -- } -- } -- -- bdb->bi_dbenv->set_errpfx( bdb->bi_dbenv, be->be_suffix[0].bv_val ); -- bdb->bi_dbenv->set_errcall( bdb->bi_dbenv, bdb_errcall ); -- -- bdb->bi_dbenv->set_lk_detect( bdb->bi_dbenv, bdb->bi_lock_detect ); -- -- if ( !BER_BVISNULL( &bdb->bi_db_crypt_key )) { -- rc = bdb->bi_dbenv->set_encrypt( bdb->bi_dbenv, bdb->bi_db_crypt_key.bv_val, -- DB_ENCRYPT_AES ); -- if ( rc ) { -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " -- "dbenv set_encrypt failed: %s (%d).\n", -- be->be_suffix[0].bv_val, db_strerror(rc), rc ); -- goto fail; -- } -- } -- -- /* One long-lived TXN per thread, two TXNs per write op */ -- bdb->bi_dbenv->set_tx_max( bdb->bi_dbenv, connection_pool_max * 3 ); -- -- if( bdb->bi_dbenv_xflags != 0 ) { -- rc = bdb->bi_dbenv->set_flags( bdb->bi_dbenv, -- bdb->bi_dbenv_xflags, 1); -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " -- "dbenv_set_flags failed: %s (%d).\n", -- be->be_suffix[0].bv_val, db_strerror(rc), rc ); -- goto fail; -- } -- } -- --#define BDB_TXN_FLAGS (DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN) -- -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_db_open) ": database \"%s\": " -- "dbenv_open(%s).\n", -- be->be_suffix[0].bv_val, bdb->bi_dbenv_home, 0); -- -- flags = DB_INIT_MPOOL | DB_CREATE | DB_THREAD; -- -- if ( !quick ) -- flags |= BDB_TXN_FLAGS; -- -- /* If a key was set, use shared memory for the BDB environment */ -- if ( bdb->bi_shm_key ) { -- bdb->bi_dbenv->set_shm_key( bdb->bi_dbenv, bdb->bi_shm_key ); -- flags |= DB_SYSTEM_MEM; -- } -- rc = (bdb->bi_dbenv->open)( bdb->bi_dbenv, dbhome, -- flags | do_recover, bdb->bi_dbenv_mode ); -- -- if ( rc ) { -- /* Regular open failed, probably a missing shm environment. -- * Start over, do a recovery. -- */ -- if ( !do_recover && bdb->bi_shm_key && do_retry ) { -- bdb->bi_dbenv->close( bdb->bi_dbenv, 0 ); -- rc = db_env_create( &bdb->bi_dbenv, 0 ); -- if( rc == 0 ) { -- Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_db_open) -- ": database \"%s\": " -- "shared memory env open failed, assuming stale env.\n", -- be->be_suffix[0].bv_val, 0, 0 ); -- do_retry = 0; -- goto shm_retry; -- } -- } -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": database \"%s\" cannot be %s, err %d. " -- "Restore from backup!\n", -- be->be_suffix[0].bv_val, do_recover ? "recovered" : "opened", rc ); -- goto fail; -- } -- -- if ( do_alock_recover && alock_recover (&bdb->bi_alock_info) != 0 ) { -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": database \"%s\": alock_recover failed\n", -- be->be_suffix[0].bv_val, 0, 0 ); -- rc = -1; -- goto fail; -- } -- --#ifdef SLAP_ZONE_ALLOC -- if ( bdb->bi_cache.c_maxsize ) { -- bdb->bi_cache.c_zctx = slap_zn_mem_create( -- SLAP_ZONE_INITSIZE, SLAP_ZONE_MAXSIZE, -- SLAP_ZONE_DELTA, SLAP_ZONE_SIZE); -- } --#endif -- -- /* dncache defaults to 0 == unlimited -- * must be >= entrycache -- */ -- if ( bdb->bi_cache.c_eimax && bdb->bi_cache.c_eimax < bdb->bi_cache.c_maxsize ) { -- bdb->bi_cache.c_eimax = bdb->bi_cache.c_maxsize; -- } -- -- if ( bdb->bi_idl_cache_max_size ) { -- bdb->bi_idl_tree = NULL; -- bdb->bi_idl_cache_size = 0; -- } -- -- flags = DB_THREAD | bdb->bi_db_opflags; -- --#ifdef DB_AUTO_COMMIT -- if ( !quick ) -- flags |= DB_AUTO_COMMIT; --#endif -- -- bdb->bi_databases = (struct bdb_db_info **) ch_malloc( -- BDB_INDICES * sizeof(struct bdb_db_info *) ); -- -- /* open (and create) main database */ -- for( i = 0; bdbi_databases[i].name.bv_val; i++ ) { -- struct bdb_db_info *db; -- -- db = (struct bdb_db_info *) ch_calloc(1, sizeof(struct bdb_db_info)); -- -- rc = db_create( &db->bdi_db, bdb->bi_dbenv, 0 ); -- if( rc != 0 ) { -- snprintf(cr->msg, sizeof(cr->msg), -- "database \"%s\": db_create(%s) failed: %s (%d).", -- be->be_suffix[0].bv_val, -- bdb->bi_dbenv_home, db_strerror(rc), rc ); -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": %s\n", -- cr->msg, 0, 0 ); -- ch_free( db ); -- goto fail; -- } -- -- if( !BER_BVISNULL( &bdb->bi_db_crypt_key )) { -- rc = db->bdi_db->set_flags( db->bdi_db, DB_ENCRYPT ); -- if ( rc ) { -- snprintf(cr->msg, sizeof(cr->msg), -- "database \"%s\": db set_flags(DB_ENCRYPT)(%s) failed: %s (%d).", -- be->be_suffix[0].bv_val, -- bdb->bi_dbenv_home, db_strerror(rc), rc ); -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": %s\n", -- cr->msg, 0, 0 ); -- db->bdi_db->close( db->bdi_db, 0 ); -- ch_free( db ); -- goto fail; -- } -- } -- -- if( bdb->bi_flags & BDB_CHKSUM ) { -- rc = db->bdi_db->set_flags( db->bdi_db, DB_CHKSUM ); -- if ( rc ) { -- snprintf(cr->msg, sizeof(cr->msg), -- "database \"%s\": db set_flags(DB_CHKSUM)(%s) failed: %s (%d).", -- be->be_suffix[0].bv_val, -- bdb->bi_dbenv_home, db_strerror(rc), rc ); -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": %s\n", -- cr->msg, 0, 0 ); -- db->bdi_db->close( db->bdi_db, 0 ); -- ch_free( db ); -- goto fail; -- } -- } -- -- rc = bdb_db_findsize( bdb, (struct berval *)&bdbi_databases[i].name ); -- -- if( i == BDB_ID2ENTRY ) { -- if ( !rc ) rc = BDB_ID2ENTRY_PAGESIZE; -- rc = db->bdi_db->set_pagesize( db->bdi_db, rc ); -- -- if ( slapMode & SLAP_TOOL_MODE ) -- db->bdi_db->mpf->set_priority( db->bdi_db->mpf, -- DB_PRIORITY_VERY_LOW ); -- -- if ( slapMode & SLAP_TOOL_READMAIN ) { -- flags |= DB_RDONLY; -- } else { -- flags |= DB_CREATE; -- } -- } else { -- /* Use FS default size if not configured */ -- if ( rc ) -- rc = db->bdi_db->set_pagesize( db->bdi_db, rc ); -- -- rc = db->bdi_db->set_flags( db->bdi_db, -- DB_DUP | DB_DUPSORT ); --#ifndef BDB_HIER -- if ( slapMode & SLAP_TOOL_READONLY ) { -- flags |= DB_RDONLY; -- } else { -- flags |= DB_CREATE; -- } --#else -- rc = db->bdi_db->set_dup_compare( db->bdi_db, -- bdb_dup_compare ); -- if ( slapMode & (SLAP_TOOL_READONLY|SLAP_TOOL_READMAIN) ) { -- flags |= DB_RDONLY; -- } else { -- flags |= DB_CREATE; -- } --#endif -- } -- --#ifdef HAVE_EBCDIC -- strcpy( path, bdbi_databases[i].file ); -- __atoe( path ); -- rc = DB_OPEN( db->bdi_db, -- path, -- /* bdbi_databases[i].name, */ NULL, -- bdbi_databases[i].type, -- bdbi_databases[i].flags | flags, -- bdb->bi_dbenv_mode ); --#else -- rc = DB_OPEN( db->bdi_db, -- bdbi_databases[i].file, -- /* bdbi_databases[i].name, */ NULL, -- bdbi_databases[i].type, -- bdbi_databases[i].flags | flags, -- bdb->bi_dbenv_mode ); --#endif -- -- if ( rc != 0 ) { -- snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": " -- "db_open(%s/%s) failed: %s (%d).", -- be->be_suffix[0].bv_val, -- bdb->bi_dbenv_home, bdbi_databases[i].file, -- db_strerror(rc), rc ); -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": %s\n", -- cr->msg, 0, 0 ); -- db->bdi_db->close( db->bdi_db, 0 ); -- ch_free( db ); -- goto fail; -- } -- -- flags &= ~(DB_CREATE | DB_RDONLY); -- db->bdi_name = bdbi_databases[i].name; -- bdb->bi_databases[i] = db; -- } -- -- bdb->bi_databases[i] = NULL; -- bdb->bi_ndatabases = i; -- -- /* get nextid */ -- rc = bdb_last_id( be, NULL ); -- if( rc != 0 ) { -- snprintf( cr->msg, sizeof(cr->msg), "database \"%s\": " -- "last_id(%s) failed: %s (%d).", -- be->be_suffix[0].bv_val, bdb->bi_dbenv_home, -- db_strerror(rc), rc ); -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_db_open) ": %s\n", -- cr->msg, 0, 0 ); -- goto fail; -- } -- -- if ( !quick ) { -- int txflag = DB_READ_COMMITTED; -- /* avoid deadlocks in server; tools should -- * wait since they have no deadlock retry mechanism. -- */ -- if ( slapMode & SLAP_SERVER_MODE ) -- txflag |= DB_TXN_NOWAIT; -- TXN_BEGIN(bdb->bi_dbenv, NULL, &bdb->bi_cache.c_txn, txflag); -- } -- -- entry_prealloc( bdb->bi_cache.c_maxsize ); -- attr_prealloc( bdb->bi_cache.c_maxsize * 20 ); -- -- /* setup for empty-DN contexts */ -- if ( BER_BVISEMPTY( &be->be_nsuffix[0] )) { -- rc = bdb_id2entry( be, NULL, 0, &e ); -- } -- if ( !e ) { -- struct berval gluebv = BER_BVC("glue"); -- Operation op = {0}; -- Opheader ohdr = {0}; -- e = entry_alloc(); -- e->e_id = 0; -- ber_dupbv( &e->e_name, (struct berval *)&slap_empty_bv ); -- ber_dupbv( &e->e_nname, (struct berval *)&slap_empty_bv ); -- attr_merge_one( e, slap_schema.si_ad_objectClass, -- &gluebv, NULL ); -- attr_merge_one( e, slap_schema.si_ad_structuralObjectClass, -- &gluebv, NULL ); -- op.o_hdr = &ohdr; -- op.o_bd = be; -- op.ora_e = e; -- op.o_dn = be->be_rootdn; -- op.o_ndn = be->be_rootndn; -- slap_add_opattrs( &op, NULL, NULL, 0, 0 ); -- } -- e->e_ocflags = SLAP_OC_GLUE|SLAP_OC__END; -- e->e_private = &bdb->bi_cache.c_dntree; -- bdb->bi_cache.c_dntree.bei_e = e; -- -- /* monitor setup */ -- rc = bdb_monitor_db_open( be ); -- if ( rc != 0 ) { -- goto fail; -- } -- -- bdb->bi_flags |= BDB_IS_OPEN; -- -- return 0; -- --fail: -- bdb_db_close( be, NULL ); -- return rc; --} -- --static int --bdb_db_close( BackendDB *be, ConfigReply *cr ) --{ -- int rc; -- struct bdb_info *bdb = (struct bdb_info *) be->be_private; -- struct bdb_db_info *db; -- bdb_idl_cache_entry_t *entry, *next_entry; -- -- /* monitor handling */ -- (void)bdb_monitor_db_close( be ); -- -- { -- Entry *e = bdb->bi_cache.c_dntree.bei_e; -- if ( e ) { -- bdb->bi_cache.c_dntree.bei_e = NULL; -- e->e_private = NULL; -- bdb_entry_return( e ); -- } -- } -- -- bdb->bi_flags &= ~BDB_IS_OPEN; -- -- ber_bvarray_free( bdb->bi_db_config ); -- bdb->bi_db_config = NULL; -- -- if( bdb->bi_dbenv ) { -- /* Free cache locker if we enabled locking. -- * TXNs must all be closed before DBs... -- */ -- if ( !( slapMode & SLAP_TOOL_QUICK ) && bdb->bi_cache.c_txn ) { -- TXN_ABORT( bdb->bi_cache.c_txn ); -- bdb->bi_cache.c_txn = NULL; -- } -- bdb_reader_flush( bdb->bi_dbenv ); -- } -- -- while( bdb->bi_databases && bdb->bi_ndatabases-- ) { -- db = bdb->bi_databases[bdb->bi_ndatabases]; -- rc = db->bdi_db->close( db->bdi_db, 0 ); -- /* Lower numbered names are not strdup'd */ -- if( bdb->bi_ndatabases >= BDB_NDB ) -- free( db->bdi_name.bv_val ); -- free( db ); -- } -- free( bdb->bi_databases ); -- bdb->bi_databases = NULL; -- -- bdb_cache_release_all (&bdb->bi_cache); -- -- if ( bdb->bi_idl_cache_size ) { -- avl_free( bdb->bi_idl_tree, NULL ); -- bdb->bi_idl_tree = NULL; -- entry = bdb->bi_idl_lru_head; -- do { -- next_entry = entry->idl_lru_next; -- if ( entry->idl ) -- free( entry->idl ); -- free( entry->kstr.bv_val ); -- free( entry ); -- entry = next_entry; -- } while ( entry != bdb->bi_idl_lru_head ); -- bdb->bi_idl_lru_head = bdb->bi_idl_lru_tail = NULL; -- } -- -- /* close db environment */ -- if( bdb->bi_dbenv ) { -- /* force a checkpoint, but not if we were ReadOnly, -- * and not in Quick mode since there are no transactions there. -- */ -- if ( !( slapMode & ( SLAP_TOOL_QUICK|SLAP_TOOL_READONLY ))) { -- rc = TXN_CHECKPOINT( bdb->bi_dbenv, 0, 0, DB_FORCE ); -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, -- "bdb_db_close: database \"%s\": " -- "txn_checkpoint failed: %s (%d).\n", -- be->be_suffix[0].bv_val, db_strerror(rc), rc ); -- } -- } -- -- rc = bdb->bi_dbenv->close( bdb->bi_dbenv, 0 ); -- bdb->bi_dbenv = NULL; -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, -- "bdb_db_close: database \"%s\": " -- "close failed: %s (%d)\n", -- be->be_suffix[0].bv_val, db_strerror(rc), rc ); -- return rc; -- } -- } -- -- rc = alock_close( &bdb->bi_alock_info, slapMode & SLAP_TOOL_QUICK ); -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, -- "bdb_db_close: database \"%s\": alock_close failed\n", -- be->be_suffix[0].bv_val, 0, 0 ); -- return -1; -- } -- -- return 0; --} -- --static int --bdb_db_destroy( BackendDB *be, ConfigReply *cr ) --{ -- struct bdb_info *bdb = (struct bdb_info *) be->be_private; -- -- /* stop and remove checkpoint task */ -- if ( bdb->bi_txn_cp_task ) { -- struct re_s *re = bdb->bi_txn_cp_task; -- bdb->bi_txn_cp_task = NULL; -- ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); -- if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ) ) -- ldap_pvt_runqueue_stoptask( &slapd_rq, re ); -- ldap_pvt_runqueue_remove( &slapd_rq, re ); -- ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); -- } -- -- /* monitor handling */ -- (void)bdb_monitor_db_destroy( be ); -- -- if( bdb->bi_dbenv_home ) ch_free( bdb->bi_dbenv_home ); -- if( bdb->bi_db_config_path ) ch_free( bdb->bi_db_config_path ); -- -- bdb_attr_index_destroy( bdb ); -- -- ldap_pvt_thread_rdwr_destroy ( &bdb->bi_cache.c_rwlock ); -- ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_lru_mutex ); -- ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_count_mutex ); -- ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_eifree_mutex ); -- ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_dntree.bei_kids_mutex ); --#ifdef BDB_HIER -- ldap_pvt_thread_mutex_destroy( &bdb->bi_modrdns_mutex ); --#endif -- ldap_pvt_thread_mutex_destroy( &bdb->bi_lastid_mutex ); -- ldap_pvt_thread_mutex_destroy( &bdb->bi_database_mutex ); -- ldap_pvt_thread_rdwr_destroy( &bdb->bi_idl_tree_rwlock ); -- ldap_pvt_thread_mutex_destroy( &bdb->bi_idl_tree_lrulock ); -- -- ch_free( bdb ); -- be->be_private = NULL; -- -- return 0; --} -- --int --bdb_back_initialize( -- BackendInfo *bi ) --{ -- int rc; -- -- static char *controls[] = { -- LDAP_CONTROL_ASSERT, -- LDAP_CONTROL_MANAGEDSAIT, -- LDAP_CONTROL_NOOP, -- LDAP_CONTROL_PAGEDRESULTS, -- LDAP_CONTROL_PRE_READ, -- LDAP_CONTROL_POST_READ, -- LDAP_CONTROL_SUBENTRIES, -- LDAP_CONTROL_X_PERMISSIVE_MODIFY, --#ifdef LDAP_X_TXN -- LDAP_CONTROL_X_TXN_SPEC, --#endif -- NULL -- }; -- -- /* initialize the underlying database system */ -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_back_initialize) ": initialize " -- BDB_UCTYPE " backend\n", 0, 0, 0 ); -- -- bi->bi_flags |= -- SLAP_BFLAG_INCREMENT | -- SLAP_BFLAG_SUBENTRIES | -- SLAP_BFLAG_ALIASES | -- SLAP_BFLAG_REFERRALS; -- -- bi->bi_controls = controls; -- -- { /* version check */ -- int major, minor, patch, ver; -- char *version = db_version( &major, &minor, &patch ); --#ifdef HAVE_EBCDIC -- char v2[1024]; -- -- /* All our stdio does an ASCII to EBCDIC conversion on -- * the output. Strings from the BDB library are already -- * in EBCDIC; we have to go back and forth... -- */ -- strcpy( v2, version ); -- __etoa( v2 ); -- version = v2; --#endif -- -- ver = (major << 24) | (minor << 16) | patch; -- if( ver != DB_VERSION_FULL ) { -- /* fail if a versions don't match */ -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_back_initialize) ": " -- "BDB library version mismatch:" -- " expected " DB_VERSION_STRING "," -- " got %s\n", version, 0, 0 ); -- return -1; -- } -- -- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_back_initialize) -- ": %s\n", version, 0, 0 ); -- } -- -- db_env_set_func_free( ber_memfree ); -- db_env_set_func_malloc( (db_malloc *)ber_memalloc ); -- db_env_set_func_realloc( (db_realloc *)ber_memrealloc ); --#if !defined(NO_THREAD) && DB_VERSION_FULL <= 0x04070000 -- /* This is a no-op on a NO_THREAD build. Leave the default -- * alone so that BDB will sleep on interprocess conflicts. -- * Don't bother on BDB 4.7... -- */ -- db_env_set_func_yield( ldap_pvt_thread_yield ); --#endif -- -- bi->bi_open = 0; -- bi->bi_close = 0; -- bi->bi_config = 0; -- bi->bi_destroy = 0; -- -- bi->bi_db_init = bdb_db_init; -- bi->bi_db_config = config_generic_wrapper; -- bi->bi_db_open = bdb_db_open; -- bi->bi_db_close = bdb_db_close; -- bi->bi_db_destroy = bdb_db_destroy; -- -- bi->bi_op_add = bdb_add; -- bi->bi_op_bind = bdb_bind; -- bi->bi_op_compare = bdb_compare; -- bi->bi_op_delete = bdb_delete; -- bi->bi_op_modify = bdb_modify; -- bi->bi_op_modrdn = bdb_modrdn; -- bi->bi_op_search = bdb_search; -- -- bi->bi_op_unbind = 0; -- -- bi->bi_extended = bdb_extended; -- -- bi->bi_chk_referrals = bdb_referrals; -- bi->bi_operational = bdb_operational; -- bi->bi_has_subordinates = bdb_hasSubordinates; -- bi->bi_entry_release_rw = bdb_entry_release; -- bi->bi_entry_get_rw = bdb_entry_get; -- -- /* -- * hooks for slap tools -- */ -- bi->bi_tool_entry_open = bdb_tool_entry_open; -- bi->bi_tool_entry_close = bdb_tool_entry_close; -- bi->bi_tool_entry_first = backend_tool_entry_first; -- bi->bi_tool_entry_first_x = bdb_tool_entry_first_x; -- bi->bi_tool_entry_next = bdb_tool_entry_next; -- bi->bi_tool_entry_get = bdb_tool_entry_get; -- bi->bi_tool_entry_put = bdb_tool_entry_put; -- bi->bi_tool_entry_reindex = bdb_tool_entry_reindex; -- bi->bi_tool_sync = 0; -- bi->bi_tool_dn2id_get = bdb_tool_dn2id_get; -- bi->bi_tool_entry_modify = bdb_tool_entry_modify; -- -- bi->bi_connection_init = 0; -- bi->bi_connection_destroy = 0; -- -- rc = bdb_back_init_cf( bi ); -- -- return rc; --} -- --#if (SLAPD_BDB == SLAPD_MOD_DYNAMIC && !defined(BDB_HIER)) || \ -- (SLAPD_HDB == SLAPD_MOD_DYNAMIC && defined(BDB_HIER)) -- --/* conditionally define the init_module() function */ --#ifdef BDB_HIER --SLAP_BACKEND_INIT_MODULE( hdb ) --#else /* !BDB_HIER */ --SLAP_BACKEND_INIT_MODULE( bdb ) --#endif /* !BDB_HIER */ -- --#endif /* SLAPD_[BH]DB == SLAPD_MOD_DYNAMIC */ -- -diff --git a/servers/slapd/back-bdb/key.c b/servers/slapd/back-bdb/key.c -deleted file mode 100644 -index 417ad70..0000000 ---- a/servers/slapd/back-bdb/key.c -+++ /dev/null -@@ -1,104 +0,0 @@ --/* index.c - routines for dealing with attribute indexes */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include -- --#include --#include -- --#include "slap.h" --#include "back-bdb.h" --#include "idl.h" -- --/* read a key */ --int --bdb_key_read( -- Backend *be, -- DB *db, -- DB_TXN *txn, -- struct berval *k, -- ID *ids, -- DBC **saved_cursor, -- int get_flag --) --{ -- int rc; -- DBT key; -- -- Debug( LDAP_DEBUG_TRACE, "=> key_read\n", 0, 0, 0 ); -- -- DBTzero( &key ); -- bv2DBT(k,&key); -- key.ulen = key.size; -- key.flags = DB_DBT_USERMEM; -- -- rc = bdb_idl_fetch_key( be, db, txn, &key, ids, saved_cursor, get_flag ); -- -- if( rc != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_TRACE, "<= bdb_index_read: failed (%d)\n", -- rc, 0, 0 ); -- } else { -- Debug( LDAP_DEBUG_TRACE, "<= bdb_index_read %ld candidates\n", -- (long) BDB_IDL_N(ids), 0, 0 ); -- } -- -- return rc; --} -- --/* Add or remove stuff from index files */ --int --bdb_key_change( -- Backend *be, -- DB *db, -- DB_TXN *txn, -- struct berval *k, -- ID id, -- int op --) --{ -- int rc; -- DBT key; -- -- Debug( LDAP_DEBUG_TRACE, "=> key_change(%s,%lx)\n", -- op == SLAP_INDEX_ADD_OP ? "ADD":"DELETE", (long) id, 0 ); -- -- DBTzero( &key ); -- bv2DBT(k,&key); -- key.ulen = key.size; -- key.flags = DB_DBT_USERMEM; -- -- if (op == SLAP_INDEX_ADD_OP) { -- /* Add values */ -- --#ifdef BDB_TOOL_IDL_CACHING -- if ( slapMode & SLAP_TOOL_QUICK ) -- rc = bdb_tool_idl_add( be, db, txn, &key, id ); -- else --#endif -- rc = bdb_idl_insert_key( be, db, txn, &key, id ); -- if ( rc == DB_KEYEXIST ) rc = 0; -- } else { -- /* Delete values */ -- rc = bdb_idl_delete_key( be, db, txn, &key, id ); -- if ( rc == DB_NOTFOUND ) rc = 0; -- } -- -- Debug( LDAP_DEBUG_TRACE, "<= key_change %d\n", rc, 0, 0 ); -- -- return rc; --} -diff --git a/servers/slapd/back-bdb/modify.c b/servers/slapd/back-bdb/modify.c -deleted file mode 100644 -index fb7dbe3..0000000 ---- a/servers/slapd/back-bdb/modify.c -+++ /dev/null -@@ -1,835 +0,0 @@ --/* modify.c - bdb backend modify routine */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include --#include --#include -- --#include "back-bdb.h" -- --static struct berval scbva[] = { -- BER_BVC("glue"), -- BER_BVNULL --}; -- --static void --bdb_modify_idxflags( -- Operation *op, -- AttributeDescription *desc, -- int got_delete, -- Attribute *newattrs, -- Attribute *oldattrs ) --{ -- struct berval ix_at; -- AttrInfo *ai; -- -- /* check if modified attribute was indexed -- * but not in case of NOOP... */ -- ai = bdb_index_mask( op->o_bd, desc, &ix_at ); -- if ( ai ) { -- if ( got_delete ) { -- Attribute *ap; -- struct berval ix2; -- -- ap = attr_find( oldattrs, desc ); -- if ( ap ) ap->a_flags |= SLAP_ATTR_IXDEL; -- -- /* Find all other attrs that index to same slot */ -- for ( ap = newattrs; ap; ap = ap->a_next ) { -- ai = bdb_index_mask( op->o_bd, ap->a_desc, &ix2 ); -- if ( ai && ix2.bv_val == ix_at.bv_val ) -- ap->a_flags |= SLAP_ATTR_IXADD; -- } -- -- } else { -- Attribute *ap; -- -- ap = attr_find( newattrs, desc ); -- if ( ap ) ap->a_flags |= SLAP_ATTR_IXADD; -- } -- } --} -- --int bdb_modify_internal( -- Operation *op, -- DB_TXN *tid, -- Modifications *modlist, -- Entry *e, -- const char **text, -- char *textbuf, -- size_t textlen ) --{ -- int rc, err; -- Modification *mod; -- Modifications *ml; -- Attribute *save_attrs; -- Attribute *ap; -- int glue_attr_delete = 0; -- int got_delete; -- -- Debug( LDAP_DEBUG_TRACE, "bdb_modify_internal: 0x%08lx: %s\n", -- e->e_id, e->e_dn, 0); -- -- if ( !acl_check_modlist( op, e, modlist )) { -- return LDAP_INSUFFICIENT_ACCESS; -- } -- -- /* save_attrs will be disposed of by bdb_cache_modify */ -- save_attrs = e->e_attrs; -- e->e_attrs = attrs_dup( e->e_attrs ); -- -- for ( ml = modlist; ml != NULL; ml = ml->sml_next ) { -- int match; -- mod = &ml->sml_mod; -- switch( mod->sm_op ) { -- case LDAP_MOD_ADD: -- case LDAP_MOD_REPLACE: -- if ( mod->sm_desc == slap_schema.si_ad_structuralObjectClass ) { -- value_match( &match, slap_schema.si_ad_structuralObjectClass, -- slap_schema.si_ad_structuralObjectClass-> -- ad_type->sat_equality, -- SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, -- &mod->sm_values[0], &scbva[0], text ); -- if ( !match ) glue_attr_delete = 1; -- } -- } -- if ( glue_attr_delete ) -- break; -- } -- -- if ( glue_attr_delete ) { -- Attribute **app = &e->e_attrs; -- while ( *app != NULL ) { -- if ( !is_at_operational( (*app)->a_desc->ad_type )) { -- Attribute *save = *app; -- *app = (*app)->a_next; -- attr_free( save ); -- continue; -- } -- app = &(*app)->a_next; -- } -- } -- -- for ( ml = modlist; ml != NULL; ml = ml->sml_next ) { -- mod = &ml->sml_mod; -- got_delete = 0; -- -- switch ( mod->sm_op ) { -- case LDAP_MOD_ADD: -- Debug(LDAP_DEBUG_ARGS, -- "bdb_modify_internal: add %s\n", -- mod->sm_desc->ad_cname.bv_val, 0, 0); -- err = modify_add_values( e, mod, get_permissiveModify(op), -- text, textbuf, textlen ); -- if( err != LDAP_SUCCESS ) { -- Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n", -- err, *text, 0); -- } -- break; -- -- case LDAP_MOD_DELETE: -- if ( glue_attr_delete ) { -- err = LDAP_SUCCESS; -- break; -- } -- -- Debug(LDAP_DEBUG_ARGS, -- "bdb_modify_internal: delete %s\n", -- mod->sm_desc->ad_cname.bv_val, 0, 0); -- err = modify_delete_values( e, mod, get_permissiveModify(op), -- text, textbuf, textlen ); -- if( err != LDAP_SUCCESS ) { -- Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n", -- err, *text, 0); -- } else { -- got_delete = 1; -- } -- break; -- -- case LDAP_MOD_REPLACE: -- Debug(LDAP_DEBUG_ARGS, -- "bdb_modify_internal: replace %s\n", -- mod->sm_desc->ad_cname.bv_val, 0, 0); -- err = modify_replace_values( e, mod, get_permissiveModify(op), -- text, textbuf, textlen ); -- if( err != LDAP_SUCCESS ) { -- Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n", -- err, *text, 0); -- } else { -- got_delete = 1; -- } -- break; -- -- case LDAP_MOD_INCREMENT: -- Debug(LDAP_DEBUG_ARGS, -- "bdb_modify_internal: increment %s\n", -- mod->sm_desc->ad_cname.bv_val, 0, 0); -- err = modify_increment_values( e, mod, get_permissiveModify(op), -- text, textbuf, textlen ); -- if( err != LDAP_SUCCESS ) { -- Debug(LDAP_DEBUG_ARGS, -- "bdb_modify_internal: %d %s\n", -- err, *text, 0); -- } else { -- got_delete = 1; -- } -- break; -- -- case SLAP_MOD_SOFTADD: -- Debug(LDAP_DEBUG_ARGS, -- "bdb_modify_internal: softadd %s\n", -- mod->sm_desc->ad_cname.bv_val, 0, 0); -- /* Avoid problems in index_add_mods() -- * We need to add index if necessary. -- */ -- mod->sm_op = LDAP_MOD_ADD; -- -- err = modify_add_values( e, mod, get_permissiveModify(op), -- text, textbuf, textlen ); -- -- mod->sm_op = SLAP_MOD_SOFTADD; -- -- if ( err == LDAP_TYPE_OR_VALUE_EXISTS ) { -- err = LDAP_SUCCESS; -- } -- -- if( err != LDAP_SUCCESS ) { -- Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n", -- err, *text, 0); -- } -- break; -- -- case SLAP_MOD_SOFTDEL: -- Debug(LDAP_DEBUG_ARGS, -- "bdb_modify_internal: softdel %s\n", -- mod->sm_desc->ad_cname.bv_val, 0, 0); -- /* Avoid problems in index_delete_mods() -- * We need to add index if necessary. -- */ -- mod->sm_op = LDAP_MOD_DELETE; -- -- err = modify_delete_values( e, mod, get_permissiveModify(op), -- text, textbuf, textlen ); -- -- mod->sm_op = SLAP_MOD_SOFTDEL; -- -- if ( err == LDAP_SUCCESS ) { -- got_delete = 1; -- } else if ( err == LDAP_NO_SUCH_ATTRIBUTE ) { -- err = LDAP_SUCCESS; -- } -- -- if( err != LDAP_SUCCESS ) { -- Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n", -- err, *text, 0); -- } -- break; -- -- case SLAP_MOD_ADD_IF_NOT_PRESENT: -- if ( attr_find( e->e_attrs, mod->sm_desc ) != NULL ) { -- /* skip */ -- err = LDAP_SUCCESS; -- break; -- } -- -- Debug(LDAP_DEBUG_ARGS, -- "bdb_modify_internal: add_if_not_present %s\n", -- mod->sm_desc->ad_cname.bv_val, 0, 0); -- /* Avoid problems in index_add_mods() -- * We need to add index if necessary. -- */ -- mod->sm_op = LDAP_MOD_ADD; -- -- err = modify_add_values( e, mod, get_permissiveModify(op), -- text, textbuf, textlen ); -- -- mod->sm_op = SLAP_MOD_ADD_IF_NOT_PRESENT; -- -- if( err != LDAP_SUCCESS ) { -- Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n", -- err, *text, 0); -- } -- break; -- -- default: -- Debug(LDAP_DEBUG_ANY, "bdb_modify_internal: invalid op %d\n", -- mod->sm_op, 0, 0); -- *text = "Invalid modify operation"; -- err = LDAP_OTHER; -- Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: %d %s\n", -- err, *text, 0); -- } -- -- if ( err != LDAP_SUCCESS ) { -- attrs_free( e->e_attrs ); -- e->e_attrs = save_attrs; -- /* unlock entry, delete from cache */ -- return err; -- } -- -- /* If objectClass was modified, reset the flags */ -- if ( mod->sm_desc == slap_schema.si_ad_objectClass ) { -- e->e_ocflags = 0; -- } -- -- if ( glue_attr_delete ) e->e_ocflags = 0; -- -- -- /* check if modified attribute was indexed -- * but not in case of NOOP... */ -- if ( !op->o_noop ) { -- bdb_modify_idxflags( op, mod->sm_desc, got_delete, e->e_attrs, save_attrs ); -- } -- } -- -- /* check that the entry still obeys the schema */ -- ap = NULL; -- rc = entry_schema_check( op, e, save_attrs, get_relax(op), 0, &ap, -- text, textbuf, textlen ); -- if ( rc != LDAP_SUCCESS || op->o_noop ) { -- attrs_free( e->e_attrs ); -- /* clear the indexing flags */ -- for ( ap = save_attrs; ap != NULL; ap = ap->a_next ) { -- ap->a_flags &= ~(SLAP_ATTR_IXADD|SLAP_ATTR_IXDEL); -- } -- e->e_attrs = save_attrs; -- -- if ( rc != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_ANY, -- "entry failed schema check: %s\n", -- *text, 0, 0 ); -- } -- -- /* if NOOP then silently revert to saved attrs */ -- return rc; -- } -- -- /* structuralObjectClass modified! */ -- if ( ap ) { -- assert( ap->a_desc == slap_schema.si_ad_structuralObjectClass ); -- if ( !op->o_noop ) { -- bdb_modify_idxflags( op, slap_schema.si_ad_structuralObjectClass, -- 1, e->e_attrs, save_attrs ); -- } -- } -- -- /* update the indices of the modified attributes */ -- -- /* start with deleting the old index entries */ -- for ( ap = save_attrs; ap != NULL; ap = ap->a_next ) { -- if ( ap->a_flags & SLAP_ATTR_IXDEL ) { -- struct berval *vals; -- Attribute *a2; -- ap->a_flags &= ~SLAP_ATTR_IXDEL; -- a2 = attr_find( e->e_attrs, ap->a_desc ); -- if ( a2 ) { -- /* need to detect which values were deleted */ -- int i, j; -- /* let add know there were deletes */ -- if ( a2->a_flags & SLAP_ATTR_IXADD ) -- a2->a_flags |= SLAP_ATTR_IXDEL; -- vals = op->o_tmpalloc( (ap->a_numvals + 1) * -- sizeof(struct berval), op->o_tmpmemctx ); -- j = 0; -- for ( i=0; i < ap->a_numvals; i++ ) { -- rc = attr_valfind( a2, SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH, -- &ap->a_nvals[i], NULL, op->o_tmpmemctx ); -- /* Save deleted values */ -- if ( rc == LDAP_NO_SUCH_ATTRIBUTE ) -- vals[j++] = ap->a_nvals[i]; -- } -- BER_BVZERO(vals+j); -- } else { -- /* attribute was completely deleted */ -- vals = ap->a_nvals; -- } -- rc = 0; -- if ( !BER_BVISNULL( vals )) { -- rc = bdb_index_values( op, tid, ap->a_desc, -- vals, e->e_id, SLAP_INDEX_DELETE_OP ); -- if ( rc != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_ANY, -- "%s: attribute \"%s\" index delete failure\n", -- op->o_log_prefix, ap->a_desc->ad_cname.bv_val, 0 ); -- attrs_free( e->e_attrs ); -- e->e_attrs = save_attrs; -- } -- } -- if ( vals != ap->a_nvals ) -- op->o_tmpfree( vals, op->o_tmpmemctx ); -- if ( rc ) return rc; -- } -- } -- -- /* add the new index entries */ -- for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) { -- if (ap->a_flags & SLAP_ATTR_IXADD) { -- ap->a_flags &= ~SLAP_ATTR_IXADD; -- if ( ap->a_flags & SLAP_ATTR_IXDEL ) { -- /* if any values were deleted, we must readd index -- * for all remaining values. -- */ -- ap->a_flags &= ~SLAP_ATTR_IXDEL; -- rc = bdb_index_values( op, tid, ap->a_desc, -- ap->a_nvals, -- e->e_id, SLAP_INDEX_ADD_OP ); -- } else { -- int found = 0; -- /* if this was only an add, we only need to index -- * the added values. -- */ -- for ( ml = modlist; ml != NULL; ml = ml->sml_next ) { -- struct berval *vals; -- if ( ml->sml_desc != ap->a_desc || !ml->sml_numvals ) -- continue; -- found = 1; -- switch( ml->sml_op ) { -- case LDAP_MOD_ADD: -- case LDAP_MOD_REPLACE: -- case LDAP_MOD_INCREMENT: -- case SLAP_MOD_SOFTADD: -- case SLAP_MOD_ADD_IF_NOT_PRESENT: -- if ( ml->sml_op == LDAP_MOD_INCREMENT ) -- vals = ap->a_nvals; -- else if ( ml->sml_nvalues ) -- vals = ml->sml_nvalues; -- else -- vals = ml->sml_values; -- rc = bdb_index_values( op, tid, ap->a_desc, -- vals, e->e_id, SLAP_INDEX_ADD_OP ); -- break; -- } -- if ( rc ) -- break; -- } -- /* This attr was affected by a modify of a subtype, so -- * there was no direct match in the modlist. Just readd -- * all of its values. -- */ -- if ( !found ) { -- rc = bdb_index_values( op, tid, ap->a_desc, -- ap->a_nvals, -- e->e_id, SLAP_INDEX_ADD_OP ); -- } -- } -- if ( rc != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_ANY, -- "%s: attribute \"%s\" index add failure\n", -- op->o_log_prefix, ap->a_desc->ad_cname.bv_val, 0 ); -- attrs_free( e->e_attrs ); -- e->e_attrs = save_attrs; -- return rc; -- } -- } -- } -- -- return rc; --} -- -- --int --bdb_modify( Operation *op, SlapReply *rs ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- Entry *e = NULL; -- EntryInfo *ei = NULL; -- int manageDSAit = get_manageDSAit( op ); -- char textbuf[SLAP_TEXT_BUFLEN]; -- size_t textlen = sizeof textbuf; -- DB_TXN *ltid = NULL, *lt2; -- struct bdb_op_info opinfo = {{{ 0 }}}; -- Entry dummy = {0}; -- -- DB_LOCK lock; -- -- int num_retries = 0; -- -- LDAPControl **preread_ctrl = NULL; -- LDAPControl **postread_ctrl = NULL; -- LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS]; -- int num_ctrls = 0; -- -- int rc; -- --#ifdef LDAP_X_TXN -- int settle = 0; --#endif -- -- Debug( LDAP_DEBUG_ARGS, LDAP_XSTRING(bdb_modify) ": %s\n", -- op->o_req_dn.bv_val, 0, 0 ); -- --#ifdef LDAP_X_TXN -- if( op->o_txnSpec ) { -- /* acquire connection lock */ -- ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); -- if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) { -- rs->sr_text = "invalid transaction identifier"; -- rs->sr_err = LDAP_X_TXN_ID_INVALID; -- goto txnReturn; -- } else if( op->o_conn->c_txn == CONN_TXN_SETTLE ) { -- settle=1; -- goto txnReturn; -- } -- -- if( op->o_conn->c_txn_backend == NULL ) { -- op->o_conn->c_txn_backend = op->o_bd; -- -- } else if( op->o_conn->c_txn_backend != op->o_bd ) { -- rs->sr_text = "transaction cannot span multiple database contexts"; -- rs->sr_err = LDAP_AFFECTS_MULTIPLE_DSAS; -- goto txnReturn; -- } -- -- /* insert operation into transaction */ -- -- rs->sr_text = "transaction specified"; -- rs->sr_err = LDAP_X_TXN_SPECIFY_OKAY; -- --txnReturn: -- /* release connection lock */ -- ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); -- -- if( !settle ) { -- send_ldap_result( op, rs ); -- return rs->sr_err; -- } -- } --#endif -- -- ctrls[num_ctrls] = NULL; -- -- /* Don't touch the opattrs, if this is a contextCSN update -- * initiated from updatedn */ -- if ( !be_isupdate(op) || !op->orm_modlist || op->orm_modlist->sml_next || -- op->orm_modlist->sml_desc != slap_schema.si_ad_contextCSN ) { -- -- slap_mods_opattrs( op, &op->orm_modlist, 1 ); -- } -- -- if( 0 ) { --retry: /* transaction retry */ -- if ( dummy.e_attrs ) { -- attrs_free( dummy.e_attrs ); -- dummy.e_attrs = NULL; -- } -- if( e != NULL ) { -- bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e); -- e = NULL; -- } -- Debug(LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modify) ": retrying...\n", 0, 0, 0); -- -- rs->sr_err = TXN_ABORT( ltid ); -- ltid = NULL; -- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); -- opinfo.boi_oe.oe_key = NULL; -- op->o_do_not_cache = opinfo.boi_acl_cache; -- if( rs->sr_err != 0 ) { -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- if ( op->o_abandon ) { -- rs->sr_err = SLAPD_ABANDON; -- goto return_results; -- } -- bdb_trans_backoff( ++num_retries ); -- } -- -- /* begin transaction */ -- rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, <id, -- bdb->bi_db_opflags ); -- rs->sr_text = NULL; -- if( rs->sr_err != 0 ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modify) ": txn_begin failed: " -- "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 ); -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modify) ": txn1 id: %x\n", -- ltid->id(ltid), 0, 0 ); -- -- opinfo.boi_oe.oe_key = bdb; -- opinfo.boi_txn = ltid; -- opinfo.boi_err = 0; -- opinfo.boi_acl_cache = op->o_do_not_cache; -- LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.boi_oe, oe_next ); -- -- /* get entry or ancestor */ -- rs->sr_err = bdb_dn2entry( op, ltid, &op->o_req_ndn, &ei, 1, -- &lock ); -- -- if ( rs->sr_err != 0 ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modify) ": dn2entry failed (%d)\n", -- rs->sr_err, 0, 0 ); -- switch( rs->sr_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- case DB_NOTFOUND: -- break; -- case LDAP_BUSY: -- rs->sr_text = "ldap server busy"; -- goto return_results; -- default: -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- } -- -- e = ei->bei_e; -- -- /* acquire and lock entry */ -- /* FIXME: dn2entry() should return non-glue entry */ -- if (( rs->sr_err == DB_NOTFOUND ) || -- ( !manageDSAit && e && is_entry_glue( e ))) -- { -- if ( e != NULL ) { -- rs->sr_matched = ch_strdup( e->e_dn ); -- rs->sr_ref = is_entry_referral( e ) -- ? get_entry_referrals( op, e ) -- : NULL; -- bdb_unlocked_cache_return_entry_r (&bdb->bi_cache, e); -- e = NULL; -- -- } else { -- rs->sr_ref = referral_rewrite( default_referral, NULL, -- &op->o_req_dn, LDAP_SCOPE_DEFAULT ); -- } -- -- rs->sr_err = LDAP_REFERRAL; -- send_ldap_result( op, rs ); -- -- if ( rs->sr_ref != default_referral ) { -- ber_bvarray_free( rs->sr_ref ); -- } -- free( (char *)rs->sr_matched ); -- rs->sr_ref = NULL; -- rs->sr_matched = NULL; -- -- goto done; -- } -- -- if ( !manageDSAit && is_entry_referral( e ) ) { -- /* entry is a referral, don't allow modify */ -- rs->sr_ref = get_entry_referrals( op, e ); -- -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modify) ": entry is referral\n", -- 0, 0, 0 ); -- -- rs->sr_err = LDAP_REFERRAL; -- rs->sr_matched = e->e_name.bv_val; -- send_ldap_result( op, rs ); -- -- ber_bvarray_free( rs->sr_ref ); -- rs->sr_ref = NULL; -- rs->sr_matched = NULL; -- goto done; -- } -- -- if ( get_assert( op ) && -- ( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE )) -- { -- rs->sr_err = LDAP_ASSERTION_FAILED; -- goto return_results; -- } -- -- if( op->o_preread ) { -- if( preread_ctrl == NULL ) { -- preread_ctrl = &ctrls[num_ctrls++]; -- ctrls[num_ctrls] = NULL; -- } -- if ( slap_read_controls( op, rs, e, -- &slap_pre_read_bv, preread_ctrl ) ) -- { -- Debug( LDAP_DEBUG_TRACE, -- "<=- " LDAP_XSTRING(bdb_modify) ": pre-read " -- "failed!\n", 0, 0, 0 ); -- if ( op->o_preread & SLAP_CONTROL_CRITICAL ) { -- /* FIXME: is it correct to abort -- * operation if control fails? */ -- goto return_results; -- } -- } -- } -- -- /* nested transaction */ -- rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, <2, bdb->bi_db_opflags ); -- rs->sr_text = NULL; -- if( rs->sr_err != 0 ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modify) ": txn_begin(2) failed: " "%s (%d)\n", -- db_strerror(rs->sr_err), rs->sr_err, 0 ); -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modify) ": txn2 id: %x\n", -- lt2->id(lt2), 0, 0 ); -- /* Modify the entry */ -- dummy = *e; -- rs->sr_err = bdb_modify_internal( op, lt2, op->orm_modlist, -- &dummy, &rs->sr_text, textbuf, textlen ); -- -- if( rs->sr_err != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modify) ": modify failed (%d)\n", -- rs->sr_err, 0, 0 ); -- if ( (rs->sr_err == LDAP_INSUFFICIENT_ACCESS) && opinfo.boi_err ) { -- rs->sr_err = opinfo.boi_err; -- } -- /* Only free attrs if they were dup'd. */ -- if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL; -- switch( rs->sr_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- goto return_results; -- } -- -- /* change the entry itself */ -- rs->sr_err = bdb_id2entry_update( op->o_bd, lt2, &dummy ); -- if ( rs->sr_err != 0 ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modify) ": id2entry update failed " "(%d)\n", -- rs->sr_err, 0, 0 ); -- switch( rs->sr_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- rs->sr_text = "entry update failed"; -- goto return_results; -- } -- -- if ( TXN_COMMIT( lt2, 0 ) != 0 ) { -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "txn_commit(2) failed"; -- goto return_results; -- } -- -- if( op->o_postread ) { -- if( postread_ctrl == NULL ) { -- postread_ctrl = &ctrls[num_ctrls++]; -- ctrls[num_ctrls] = NULL; -- } -- if( slap_read_controls( op, rs, &dummy, -- &slap_post_read_bv, postread_ctrl ) ) -- { -- Debug( LDAP_DEBUG_TRACE, -- "<=- " LDAP_XSTRING(bdb_modify) -- ": post-read failed!\n", 0, 0, 0 ); -- if ( op->o_postread & SLAP_CONTROL_CRITICAL ) { -- /* FIXME: is it correct to abort -- * operation if control fails? */ -- goto return_results; -- } -- } -- } -- -- if( op->o_noop ) { -- if ( ( rs->sr_err = TXN_ABORT( ltid ) ) != 0 ) { -- rs->sr_text = "txn_abort (no-op) failed"; -- } else { -- rs->sr_err = LDAP_X_NO_OPERATION; -- ltid = NULL; -- /* Only free attrs if they were dup'd. */ -- if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL; -- goto return_results; -- } -- } else { -- /* may have changed in bdb_modify_internal() */ -- e->e_ocflags = dummy.e_ocflags; -- rc = bdb_cache_modify( bdb, e, dummy.e_attrs, ltid, &lock ); -- switch( rc ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- dummy.e_attrs = NULL; -- -- rs->sr_err = TXN_COMMIT( ltid, 0 ); -- } -- ltid = NULL; -- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); -- opinfo.boi_oe.oe_key = NULL; -- -- if( rs->sr_err != 0 ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modify) ": txn_%s failed: %s (%d)\n", -- op->o_noop ? "abort (no-op)" : "commit", -- db_strerror(rs->sr_err), rs->sr_err ); -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "commit failed"; -- -- goto return_results; -- } -- -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modify) ": updated%s id=%08lx dn=\"%s\"\n", -- op->o_noop ? " (no-op)" : "", -- dummy.e_id, op->o_req_dn.bv_val ); -- -- rs->sr_err = LDAP_SUCCESS; -- rs->sr_text = NULL; -- if( num_ctrls ) rs->sr_ctrls = ctrls; -- --return_results: -- if( dummy.e_attrs ) { -- attrs_free( dummy.e_attrs ); -- } -- send_ldap_result( op, rs ); -- -- if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp_kbyte ) { -- TXN_CHECKPOINT( bdb->bi_dbenv, -- bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 ); -- } -- --done: -- slap_graduate_commit_csn( op ); -- -- if( ltid != NULL ) { -- TXN_ABORT( ltid ); -- } -- if ( opinfo.boi_oe.oe_key ) { -- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); -- } -- -- if( e != NULL ) { -- bdb_unlocked_cache_return_entry_w (&bdb->bi_cache, e); -- } -- -- if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) { -- slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx ); -- slap_sl_free( *preread_ctrl, op->o_tmpmemctx ); -- } -- if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) { -- slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx ); -- slap_sl_free( *postread_ctrl, op->o_tmpmemctx ); -- } -- -- rs->sr_text = NULL; -- -- return rs->sr_err; --} -diff --git a/servers/slapd/back-bdb/modrdn.c b/servers/slapd/back-bdb/modrdn.c -deleted file mode 100644 -index f213b0f..0000000 ---- a/servers/slapd/back-bdb/modrdn.c -+++ /dev/null -@@ -1,842 +0,0 @@ --/* modrdn.c - bdb backend modrdn routine */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include --#include -- --#include "back-bdb.h" -- --int --bdb_modrdn( Operation *op, SlapReply *rs ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- AttributeDescription *children = slap_schema.si_ad_children; -- AttributeDescription *entry = slap_schema.si_ad_entry; -- struct berval p_dn, p_ndn; -- struct berval new_dn = {0, NULL}, new_ndn = {0, NULL}; -- Entry *e = NULL; -- Entry *p = NULL; -- EntryInfo *ei = NULL, *eip = NULL, *nei = NULL, *neip = NULL; -- /* LDAP v2 supporting correct attribute handling. */ -- char textbuf[SLAP_TEXT_BUFLEN]; -- size_t textlen = sizeof textbuf; -- DB_TXN *ltid = NULL, *lt2; -- struct bdb_op_info opinfo = {{{ 0 }}}; -- Entry dummy = {0}; -- -- Entry *np = NULL; /* newSuperior Entry */ -- struct berval *np_dn = NULL; /* newSuperior dn */ -- struct berval *np_ndn = NULL; /* newSuperior ndn */ -- struct berval *new_parent_dn = NULL; /* np_dn, p_dn, or NULL */ -- -- int manageDSAit = get_manageDSAit( op ); -- -- DB_LOCK lock, plock, nplock; -- -- int num_retries = 0; -- -- LDAPControl **preread_ctrl = NULL; -- LDAPControl **postread_ctrl = NULL; -- LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS]; -- int num_ctrls = 0; -- -- int rc; -- -- int parent_is_glue = 0; -- int parent_is_leaf = 0; -- --#ifdef LDAP_X_TXN -- int settle = 0; --#endif -- -- Debug( LDAP_DEBUG_TRACE, "==>" LDAP_XSTRING(bdb_modrdn) "(%s,%s,%s)\n", -- op->o_req_dn.bv_val,op->oq_modrdn.rs_newrdn.bv_val, -- op->oq_modrdn.rs_newSup ? op->oq_modrdn.rs_newSup->bv_val : "NULL" ); -- --#ifdef LDAP_X_TXN -- if( op->o_txnSpec ) { -- /* acquire connection lock */ -- ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); -- if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) { -- rs->sr_text = "invalid transaction identifier"; -- rs->sr_err = LDAP_X_TXN_ID_INVALID; -- goto txnReturn; -- } else if( op->o_conn->c_txn == CONN_TXN_SETTLE ) { -- settle=1; -- goto txnReturn; -- } -- -- if( op->o_conn->c_txn_backend == NULL ) { -- op->o_conn->c_txn_backend = op->o_bd; -- -- } else if( op->o_conn->c_txn_backend != op->o_bd ) { -- rs->sr_text = "transaction cannot span multiple database contexts"; -- rs->sr_err = LDAP_AFFECTS_MULTIPLE_DSAS; -- goto txnReturn; -- } -- -- /* insert operation into transaction */ -- -- rs->sr_text = "transaction specified"; -- rs->sr_err = LDAP_X_TXN_SPECIFY_OKAY; -- --txnReturn: -- /* release connection lock */ -- ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); -- -- if( !settle ) { -- send_ldap_result( op, rs ); -- return rs->sr_err; -- } -- } --#endif -- -- ctrls[num_ctrls] = NULL; -- -- slap_mods_opattrs( op, &op->orr_modlist, 1 ); -- -- if( 0 ) { --retry: /* transaction retry */ -- if ( dummy.e_attrs ) { -- attrs_free( dummy.e_attrs ); -- dummy.e_attrs = NULL; -- } -- if (e != NULL) { -- bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e); -- e = NULL; -- } -- if (p != NULL) { -- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p); -- p = NULL; -- } -- if (np != NULL) { -- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, np); -- np = NULL; -- } -- Debug( LDAP_DEBUG_TRACE, "==>" LDAP_XSTRING(bdb_modrdn) -- ": retrying...\n", 0, 0, 0 ); -- -- rs->sr_err = TXN_ABORT( ltid ); -- ltid = NULL; -- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); -- opinfo.boi_oe.oe_key = NULL; -- op->o_do_not_cache = opinfo.boi_acl_cache; -- if( rs->sr_err != 0 ) { -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- if ( op->o_abandon ) { -- rs->sr_err = SLAPD_ABANDON; -- goto return_results; -- } -- parent_is_glue = 0; -- parent_is_leaf = 0; -- bdb_trans_backoff( ++num_retries ); -- } -- -- /* begin transaction */ -- rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, NULL, <id, -- bdb->bi_db_opflags ); -- rs->sr_text = NULL; -- if( rs->sr_err != 0 ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modrdn) ": txn_begin failed: " -- "%s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 ); -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modrdn) ": txn1 id: %x\n", -- ltid->id(ltid), 0, 0 ); -- -- opinfo.boi_oe.oe_key = bdb; -- opinfo.boi_txn = ltid; -- opinfo.boi_err = 0; -- opinfo.boi_acl_cache = op->o_do_not_cache; -- LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.boi_oe, oe_next ); -- -- /* get entry */ -- rs->sr_err = bdb_dn2entry( op, ltid, &op->o_req_ndn, &ei, 1, -- &lock ); -- -- switch( rs->sr_err ) { -- case 0: -- case DB_NOTFOUND: -- break; -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- case LDAP_BUSY: -- rs->sr_text = "ldap server busy"; -- goto return_results; -- default: -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- -- e = ei->bei_e; -- /* FIXME: dn2entry() should return non-glue entry */ -- if (( rs->sr_err == DB_NOTFOUND ) || -- ( !manageDSAit && e && is_entry_glue( e ))) -- { -- if( e != NULL ) { -- rs->sr_matched = ch_strdup( e->e_dn ); -- rs->sr_ref = is_entry_referral( e ) -- ? get_entry_referrals( op, e ) -- : NULL; -- bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, e); -- e = NULL; -- -- } else { -- rs->sr_ref = referral_rewrite( default_referral, NULL, -- &op->o_req_dn, LDAP_SCOPE_DEFAULT ); -- } -- -- rs->sr_err = LDAP_REFERRAL; -- send_ldap_result( op, rs ); -- -- ber_bvarray_free( rs->sr_ref ); -- free( (char *)rs->sr_matched ); -- rs->sr_ref = NULL; -- rs->sr_matched = NULL; -- -- goto done; -- } -- -- if ( get_assert( op ) && -- ( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE )) -- { -- rs->sr_err = LDAP_ASSERTION_FAILED; -- goto return_results; -- } -- -- /* check write on old entry */ -- rs->sr_err = access_allowed( op, e, entry, NULL, ACL_WRITE, NULL ); -- if ( ! rs->sr_err ) { -- switch( opinfo.boi_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- -- Debug( LDAP_DEBUG_TRACE, "no access to entry\n", 0, -- 0, 0 ); -- rs->sr_text = "no write access to old entry"; -- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; -- goto return_results; -- } -- --#ifndef BDB_HIER -- rs->sr_err = bdb_cache_children( op, ltid, e ); -- if ( rs->sr_err != DB_NOTFOUND ) { -- switch( rs->sr_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- case 0: -- Debug(LDAP_DEBUG_ARGS, -- "<=- " LDAP_XSTRING(bdb_modrdn) -- ": non-leaf %s\n", -- op->o_req_dn.bv_val, 0, 0); -- rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF; -- rs->sr_text = "subtree rename not supported"; -- break; -- default: -- Debug(LDAP_DEBUG_ARGS, -- "<=- " LDAP_XSTRING(bdb_modrdn) -- ": has_children failed: %s (%d)\n", -- db_strerror(rs->sr_err), rs->sr_err, 0 ); -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- } -- goto return_results; -- } -- ei->bei_state |= CACHE_ENTRY_NO_KIDS; --#endif -- -- if (!manageDSAit && is_entry_referral( e ) ) { -- /* parent is a referral, don't allow add */ -- rs->sr_ref = get_entry_referrals( op, e ); -- -- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modrdn) -- ": entry %s is referral\n", e->e_dn, 0, 0 ); -- -- rs->sr_err = LDAP_REFERRAL, -- rs->sr_matched = e->e_name.bv_val; -- send_ldap_result( op, rs ); -- -- ber_bvarray_free( rs->sr_ref ); -- rs->sr_ref = NULL; -- rs->sr_matched = NULL; -- goto done; -- } -- -- if ( be_issuffix( op->o_bd, &e->e_nname ) ) { --#ifdef BDB_MULTIPLE_SUFFIXES -- /* Allow renaming one suffix entry to another */ -- p_ndn = slap_empty_bv; --#else -- /* There can only be one suffix entry */ -- rs->sr_err = LDAP_NAMING_VIOLATION; -- rs->sr_text = "cannot rename suffix entry"; -- goto return_results; --#endif -- } else { -- dnParent( &e->e_nname, &p_ndn ); -- } -- np_ndn = &p_ndn; -- eip = ei->bei_parent; -- if ( eip && eip->bei_id ) { -- /* Make sure parent entry exist and we can write its -- * children. -- */ -- rs->sr_err = bdb_cache_find_id( op, ltid, -- eip->bei_id, &eip, 0, &plock ); -- -- switch( rs->sr_err ) { -- case 0: -- case DB_NOTFOUND: -- break; -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- case LDAP_BUSY: -- rs->sr_text = "ldap server busy"; -- goto return_results; -- default: -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- -- p = eip->bei_e; -- if( p == NULL) { -- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modrdn) -- ": parent does not exist\n", 0, 0, 0); -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "old entry's parent does not exist"; -- goto return_results; -- } -- } else { -- p = (Entry *)&slap_entry_root; -- } -- -- /* check parent for "children" acl */ -- rs->sr_err = access_allowed( op, p, -- children, NULL, -- op->oq_modrdn.rs_newSup == NULL ? -- ACL_WRITE : ACL_WDEL, -- NULL ); -- -- if ( !p_ndn.bv_len ) -- p = NULL; -- -- if ( ! rs->sr_err ) { -- switch( opinfo.boi_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- -- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; -- Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0, -- 0, 0 ); -- rs->sr_text = "no write access to old parent's children"; -- goto return_results; -- } -- -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modrdn) ": wr to children " -- "of entry %s OK\n", p_ndn.bv_val, 0, 0 ); -- -- if ( p_ndn.bv_val == slap_empty_bv.bv_val ) { -- p_dn = slap_empty_bv; -- } else { -- dnParent( &e->e_name, &p_dn ); -- } -- -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modrdn) ": parent dn=%s\n", -- p_dn.bv_val, 0, 0 ); -- -- new_parent_dn = &p_dn; /* New Parent unless newSuperior given */ -- -- if ( op->oq_modrdn.rs_newSup != NULL ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modrdn) -- ": new parent \"%s\" requested...\n", -- op->oq_modrdn.rs_newSup->bv_val, 0, 0 ); -- -- /* newSuperior == oldParent? */ -- if( dn_match( &p_ndn, op->oq_modrdn.rs_nnewSup ) ) { -- Debug( LDAP_DEBUG_TRACE, "bdb_back_modrdn: " -- "new parent \"%s\" same as the old parent \"%s\"\n", -- op->oq_modrdn.rs_newSup->bv_val, p_dn.bv_val, 0 ); -- op->oq_modrdn.rs_newSup = NULL; /* ignore newSuperior */ -- } -- } -- -- /* There's a BDB_MULTIPLE_SUFFIXES case here that this code doesn't -- * support. E.g., two suffixes dc=foo,dc=com and dc=bar,dc=net. -- * We do not allow modDN -- * dc=foo,dc=com -- * newrdn dc=bar -- * newsup dc=net -- * and we probably should. But since MULTIPLE_SUFFIXES is deprecated -- * I'm ignoring this problem for now. -- */ -- if ( op->oq_modrdn.rs_newSup != NULL ) { -- if ( op->oq_modrdn.rs_newSup->bv_len ) { -- np_dn = op->oq_modrdn.rs_newSup; -- np_ndn = op->oq_modrdn.rs_nnewSup; -- -- /* newSuperior == oldParent? - checked above */ -- /* newSuperior == entry being moved?, if so ==> ERROR */ -- if ( dnIsSuffix( np_ndn, &e->e_nname )) { -- rs->sr_err = LDAP_NO_SUCH_OBJECT; -- rs->sr_text = "new superior not found"; -- goto return_results; -- } -- /* Get Entry with dn=newSuperior. Does newSuperior exist? */ -- -- rs->sr_err = bdb_dn2entry( op, ltid, np_ndn, -- &neip, 0, &nplock ); -- -- switch( rs->sr_err ) { -- case 0: np = neip->bei_e; -- case DB_NOTFOUND: -- break; -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- case LDAP_BUSY: -- rs->sr_text = "ldap server busy"; -- goto return_results; -- default: -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- -- if( np == NULL) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modrdn) -- ": newSup(ndn=%s) not here!\n", -- np_ndn->bv_val, 0, 0); -- rs->sr_text = "new superior not found"; -- rs->sr_err = LDAP_NO_SUCH_OBJECT; -- goto return_results; -- } -- -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modrdn) -- ": wr to new parent OK np=%p, id=%ld\n", -- (void *) np, (long) np->e_id, 0 ); -- -- /* check newSuperior for "children" acl */ -- rs->sr_err = access_allowed( op, np, children, -- NULL, ACL_WADD, NULL ); -- -- if( ! rs->sr_err ) { -- switch( opinfo.boi_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modrdn) -- ": no wr to newSup children\n", -- 0, 0, 0 ); -- rs->sr_text = "no write access to new superior's children"; -- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; -- goto return_results; -- } -- -- if ( is_entry_alias( np ) ) { -- /* parent is an alias, don't allow add */ -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modrdn) -- ": entry is alias\n", -- 0, 0, 0 ); -- rs->sr_text = "new superior is an alias"; -- rs->sr_err = LDAP_ALIAS_PROBLEM; -- goto return_results; -- } -- -- if ( is_entry_referral( np ) ) { -- /* parent is a referral, don't allow add */ -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modrdn) -- ": entry is referral\n", -- 0, 0, 0 ); -- rs->sr_text = "new superior is a referral"; -- rs->sr_err = LDAP_OTHER; -- goto return_results; -- } -- -- } else { -- np_dn = NULL; -- -- /* no parent, modrdn entry directly under root */ -- if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv ) -- || be_isupdate( op ) ) { -- np = (Entry *)&slap_entry_root; -- -- /* check parent for "children" acl */ -- rs->sr_err = access_allowed( op, np, -- children, NULL, ACL_WADD, NULL ); -- -- np = NULL; -- -- if ( ! rs->sr_err ) { -- switch( opinfo.boi_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- -- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; -- Debug( LDAP_DEBUG_TRACE, -- "no access to new superior\n", -- 0, 0, 0 ); -- rs->sr_text = -- "no write access to new superior's children"; -- goto return_results; -- } -- } -- } -- -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_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. */ -- if (!new_dn.bv_val) { -- build_new_dn( &new_dn, new_parent_dn, &op->oq_modrdn.rs_newrdn, NULL ); -- } -- -- if (!new_ndn.bv_val) { -- struct berval bv = {0, NULL}; -- dnNormalize( 0, NULL, NULL, &new_dn, &bv, op->o_tmpmemctx ); -- ber_dupbv( &new_ndn, &bv ); -- /* FIXME: why not call dnNormalize() w/o ctx? */ -- op->o_tmpfree( bv.bv_val, op->o_tmpmemctx ); -- } -- -- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modrdn) ": new ndn=%s\n", -- new_ndn.bv_val, 0, 0 ); -- -- /* Shortcut the search */ -- nei = neip ? neip : eip; -- rs->sr_err = bdb_cache_find_ndn ( op, ltid, &new_ndn, &nei ); -- if ( nei ) bdb_cache_entryinfo_unlock( nei ); -- switch( rs->sr_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- case DB_NOTFOUND: -- break; -- case 0: -- /* Allow rename to same DN */ -- if ( nei == ei ) -- break; -- rs->sr_err = LDAP_ALREADY_EXISTS; -- goto return_results; -- default: -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- -- assert( op->orr_modlist != NULL ); -- -- if( op->o_preread ) { -- if( preread_ctrl == NULL ) { -- preread_ctrl = &ctrls[num_ctrls++]; -- ctrls[num_ctrls] = NULL; -- } -- if( slap_read_controls( op, rs, e, -- &slap_pre_read_bv, preread_ctrl ) ) -- { -- Debug( LDAP_DEBUG_TRACE, -- "<=- " LDAP_XSTRING(bdb_modrdn) -- ": pre-read failed!\n", 0, 0, 0 ); -- if ( op->o_preread & SLAP_CONTROL_CRITICAL ) { -- /* FIXME: is it correct to abort -- * operation if control fails? */ -- goto return_results; -- } -- } -- } -- -- /* nested transaction */ -- rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, <2, bdb->bi_db_opflags ); -- rs->sr_text = NULL; -- if( rs->sr_err != 0 ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modrdn) -- ": txn_begin(2) failed: %s (%d)\n", -- db_strerror(rs->sr_err), rs->sr_err, 0 ); -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modrdn) ": txn2 id: %x\n", -- lt2->id(lt2), 0, 0 ); -- -- /* delete old DN */ -- rs->sr_err = bdb_dn2id_delete( op, lt2, eip, e ); -- if ( rs->sr_err != 0 ) { -- Debug(LDAP_DEBUG_TRACE, -- "<=- " LDAP_XSTRING(bdb_modrdn) -- ": dn2id del failed: %s (%d)\n", -- db_strerror(rs->sr_err), rs->sr_err, 0 ); -- switch( rs->sr_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "DN index delete fail"; -- goto return_results; -- } -- -- /* copy the entry, then override some fields */ -- dummy = *e; -- dummy.e_name = new_dn; -- dummy.e_nname = new_ndn; -- dummy.e_attrs = NULL; -- -- /* add new DN */ -- rs->sr_err = bdb_dn2id_add( op, lt2, neip ? neip : eip, &dummy ); -- if ( rs->sr_err != 0 ) { -- Debug(LDAP_DEBUG_TRACE, -- "<=- " LDAP_XSTRING(bdb_modrdn) -- ": dn2id add failed: %s (%d)\n", -- db_strerror(rs->sr_err), rs->sr_err, 0 ); -- switch( rs->sr_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "DN index add failed"; -- goto return_results; -- } -- -- dummy.e_attrs = e->e_attrs; -- -- /* modify entry */ -- rs->sr_err = bdb_modify_internal( op, lt2, op->orr_modlist, &dummy, -- &rs->sr_text, textbuf, textlen ); -- if( rs->sr_err != LDAP_SUCCESS ) { -- Debug(LDAP_DEBUG_TRACE, -- "<=- " LDAP_XSTRING(bdb_modrdn) -- ": modify failed: %s (%d)\n", -- db_strerror(rs->sr_err), rs->sr_err, 0 ); -- if ( ( rs->sr_err == LDAP_INSUFFICIENT_ACCESS ) && opinfo.boi_err ) { -- rs->sr_err = opinfo.boi_err; -- } -- if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL; -- switch( rs->sr_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- goto return_results; -- } -- -- /* id2entry index */ -- rs->sr_err = bdb_id2entry_update( op->o_bd, lt2, &dummy ); -- if ( rs->sr_err != 0 ) { -- Debug(LDAP_DEBUG_TRACE, -- "<=- " LDAP_XSTRING(bdb_modrdn) -- ": id2entry failed: %s (%d)\n", -- db_strerror(rs->sr_err), rs->sr_err, 0 ); -- switch( rs->sr_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "entry update failed"; -- goto return_results; -- } -- -- if ( p_ndn.bv_len != 0 ) { -- parent_is_glue = is_entry_glue(p); -- rs->sr_err = bdb_cache_children( op, lt2, p ); -- if ( rs->sr_err != DB_NOTFOUND ) { -- switch( rs->sr_err ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- case 0: -- break; -- default: -- Debug(LDAP_DEBUG_ARGS, -- "<=- " LDAP_XSTRING(bdb_modrdn) -- ": has_children failed: %s (%d)\n", -- db_strerror(rs->sr_err), rs->sr_err, 0 ); -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error"; -- goto return_results; -- } -- parent_is_leaf = 1; -- } -- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p); -- p = NULL; -- } -- -- if ( TXN_COMMIT( lt2, 0 ) != 0 ) { -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "txn_commit(2) failed"; -- goto return_results; -- } -- -- if( op->o_postread ) { -- if( postread_ctrl == NULL ) { -- postread_ctrl = &ctrls[num_ctrls++]; -- ctrls[num_ctrls] = NULL; -- } -- if( slap_read_controls( op, rs, &dummy, -- &slap_post_read_bv, postread_ctrl ) ) -- { -- Debug( LDAP_DEBUG_TRACE, -- "<=- " LDAP_XSTRING(bdb_modrdn) -- ": post-read failed!\n", 0, 0, 0 ); -- if ( op->o_postread & SLAP_CONTROL_CRITICAL ) { -- /* FIXME: is it correct to abort -- * operation if control fails? */ -- goto return_results; -- } -- } -- } -- -- if( op->o_noop ) { -- if(( rs->sr_err=TXN_ABORT( ltid )) != 0 ) { -- rs->sr_text = "txn_abort (no-op) failed"; -- } else { -- rs->sr_err = LDAP_X_NO_OPERATION; -- ltid = NULL; -- /* Only free attrs if they were dup'd. */ -- if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL; -- goto return_results; -- } -- -- } else { -- rc = bdb_cache_modrdn( bdb, e, &op->orr_nnewrdn, &dummy, neip, -- ltid, &lock ); -- switch( rc ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- } -- dummy.e_attrs = NULL; -- new_dn.bv_val = NULL; -- new_ndn.bv_val = NULL; -- -- if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) { -- rs->sr_text = "txn_commit failed"; -- } else { -- rs->sr_err = LDAP_SUCCESS; -- } -- } -- -- ltid = NULL; -- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); -- opinfo.boi_oe.oe_key = NULL; -- -- if( rs->sr_err != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modrdn) ": %s : %s (%d)\n", -- rs->sr_text, db_strerror(rs->sr_err), rs->sr_err ); -- rs->sr_err = LDAP_OTHER; -- -- goto return_results; -- } -- -- Debug(LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_modrdn) -- ": rdn modified%s id=%08lx dn=\"%s\"\n", -- op->o_noop ? " (no-op)" : "", -- dummy.e_id, op->o_req_dn.bv_val ); -- rs->sr_text = NULL; -- if( num_ctrls ) rs->sr_ctrls = ctrls; -- --return_results: -- if ( dummy.e_attrs ) { -- attrs_free( dummy.e_attrs ); -- } -- send_ldap_result( op, rs ); -- -- if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp_kbyte ) { -- TXN_CHECKPOINT( bdb->bi_dbenv, -- bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 ); -- } -- -- if ( rs->sr_err == LDAP_SUCCESS && parent_is_glue && parent_is_leaf ) { -- op->o_delete_glue_parent = 1; -- } -- --done: -- slap_graduate_commit_csn( op ); -- -- if( new_dn.bv_val != NULL ) free( new_dn.bv_val ); -- if( new_ndn.bv_val != NULL ) free( new_ndn.bv_val ); -- -- /* LDAP v3 Support */ -- if( np != NULL ) { -- /* free new parent and reader lock */ -- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, np); -- } -- -- if( p != NULL ) { -- /* free parent and reader lock */ -- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p); -- } -- -- /* free entry */ -- if( e != NULL ) { -- bdb_unlocked_cache_return_entry_w( &bdb->bi_cache, e); -- } -- -- if( ltid != NULL ) { -- TXN_ABORT( ltid ); -- } -- if ( opinfo.boi_oe.oe_key ) { -- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); -- } -- -- if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) { -- slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx ); -- slap_sl_free( *preread_ctrl, op->o_tmpmemctx ); -- } -- if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) { -- slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx ); -- slap_sl_free( *postread_ctrl, op->o_tmpmemctx ); -- } -- return rs->sr_err; --} -diff --git a/servers/slapd/back-bdb/monitor.c b/servers/slapd/back-bdb/monitor.c -deleted file mode 100644 -index 4afaf9d..0000000 ---- a/servers/slapd/back-bdb/monitor.c -+++ /dev/null -@@ -1,724 +0,0 @@ --/* monitor.c - monitor bdb backend */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include --#include --#include --#include --#include --#include --#include "lutil.h" --#include "back-bdb.h" -- --#include "../back-monitor/back-monitor.h" -- --#include "config.h" -- --static ObjectClass *oc_olmBDBDatabase; -- --static AttributeDescription *ad_olmBDBEntryCache, -- *ad_olmBDBDNCache, *ad_olmBDBIDLCache, -- *ad_olmDbDirectory; -- --#ifdef BDB_MONITOR_IDX --static int --bdb_monitor_idx_entry_add( -- struct bdb_info *bdb, -- Entry *e ); -- --static AttributeDescription *ad_olmDbNotIndexed; --#endif /* BDB_MONITOR_IDX */ -- --/* -- * NOTE: there's some confusion in monitor OID arc; -- * by now, let's consider: -- * -- * Subsystems monitor attributes 1.3.6.1.4.1.4203.666.1.55.0 -- * Databases monitor attributes 1.3.6.1.4.1.4203.666.1.55.0.1 -- * BDB database monitor attributes 1.3.6.1.4.1.4203.666.1.55.0.1.1 -- * -- * Subsystems monitor objectclasses 1.3.6.1.4.1.4203.666.3.16.0 -- * Databases monitor objectclasses 1.3.6.1.4.1.4203.666.3.16.0.1 -- * BDB database monitor objectclasses 1.3.6.1.4.1.4203.666.3.16.0.1.1 -- */ -- --static struct { -- char *name; -- char *oid; --} s_oid[] = { -- { "olmBDBAttributes", "olmDatabaseAttributes:1" }, -- { "olmBDBObjectClasses", "olmDatabaseObjectClasses:1" }, -- -- { NULL } --}; -- --static struct { -- char *desc; -- AttributeDescription **ad; --} s_at[] = { -- { "( olmBDBAttributes:1 " -- "NAME ( 'olmBDBEntryCache' ) " -- "DESC 'Number of items in Entry Cache' " -- "SUP monitorCounter " -- "NO-USER-MODIFICATION " -- "USAGE dSAOperation )", -- &ad_olmBDBEntryCache }, -- -- { "( olmBDBAttributes:2 " -- "NAME ( 'olmBDBDNCache' ) " -- "DESC 'Number of items in DN Cache' " -- "SUP monitorCounter " -- "NO-USER-MODIFICATION " -- "USAGE dSAOperation )", -- &ad_olmBDBDNCache }, -- -- { "( olmBDBAttributes:3 " -- "NAME ( 'olmBDBIDLCache' ) " -- "DESC 'Number of items in IDL Cache' " -- "SUP monitorCounter " -- "NO-USER-MODIFICATION " -- "USAGE dSAOperation )", -- &ad_olmBDBIDLCache }, -- -- { "( olmDatabaseAttributes:1 " -- "NAME ( 'olmDbDirectory' ) " -- "DESC 'Path name of the directory " -- "where the database environment resides' " -- "SUP monitoredInfo " -- "NO-USER-MODIFICATION " -- "USAGE dSAOperation )", -- &ad_olmDbDirectory }, -- --#ifdef BDB_MONITOR_IDX -- { "( olmDatabaseAttributes:2 " -- "NAME ( 'olmDbNotIndexed' ) " -- "DESC 'Missing indexes resulting from candidate selection' " -- "SUP monitoredInfo " -- "NO-USER-MODIFICATION " -- "USAGE dSAOperation )", -- &ad_olmDbNotIndexed }, --#endif /* BDB_MONITOR_IDX */ -- -- { NULL } --}; -- --static struct { -- char *desc; -- ObjectClass **oc; --} s_oc[] = { -- /* augments an existing object, so it must be AUXILIARY -- * FIXME: derive from some ABSTRACT "monitoredEntity"? */ -- { "( olmBDBObjectClasses:1 " -- "NAME ( 'olmBDBDatabase' ) " -- "SUP top AUXILIARY " -- "MAY ( " -- "olmBDBEntryCache " -- "$ olmBDBDNCache " -- "$ olmBDBIDLCache " -- "$ olmDbDirectory " --#ifdef BDB_MONITOR_IDX -- "$ olmDbNotIndexed " --#endif /* BDB_MONITOR_IDX */ -- ") )", -- &oc_olmBDBDatabase }, -- -- { NULL } --}; -- --static int --bdb_monitor_update( -- Operation *op, -- SlapReply *rs, -- Entry *e, -- void *priv ) --{ -- struct bdb_info *bdb = (struct bdb_info *) priv; -- Attribute *a; -- -- char buf[ BUFSIZ ]; -- struct berval bv; -- -- assert( ad_olmBDBEntryCache != NULL ); -- -- a = attr_find( e->e_attrs, ad_olmBDBEntryCache ); -- assert( a != NULL ); -- bv.bv_val = buf; -- bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", bdb->bi_cache.c_cursize ); -- ber_bvreplace( &a->a_vals[ 0 ], &bv ); -- -- a = attr_find( e->e_attrs, ad_olmBDBDNCache ); -- assert( a != NULL ); -- bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", bdb->bi_cache.c_eiused ); -- ber_bvreplace( &a->a_vals[ 0 ], &bv ); -- -- a = attr_find( e->e_attrs, ad_olmBDBIDLCache ); -- assert( a != NULL ); -- bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", bdb->bi_idl_cache_size ); -- ber_bvreplace( &a->a_vals[ 0 ], &bv ); -- --#ifdef BDB_MONITOR_IDX -- bdb_monitor_idx_entry_add( bdb, e ); --#endif /* BDB_MONITOR_IDX */ -- -- return SLAP_CB_CONTINUE; --} -- --#if 0 /* uncomment if required */ --static int --bdb_monitor_modify( -- Operation *op, -- SlapReply *rs, -- Entry *e, -- void *priv ) --{ -- return SLAP_CB_CONTINUE; --} --#endif -- --static int --bdb_monitor_free( -- Entry *e, -- void **priv ) --{ -- struct berval values[ 2 ]; -- Modification mod = { 0 }; -- -- const char *text; -- char textbuf[ SLAP_TEXT_BUFLEN ]; -- -- int i, rc; -- -- /* NOTE: if slap_shutdown != 0, priv might have already been freed */ -- *priv = NULL; -- -- /* Remove objectClass */ -- mod.sm_op = LDAP_MOD_DELETE; -- mod.sm_desc = slap_schema.si_ad_objectClass; -- mod.sm_values = values; -- mod.sm_numvals = 1; -- values[ 0 ] = oc_olmBDBDatabase->soc_cname; -- BER_BVZERO( &values[ 1 ] ); -- -- rc = modify_delete_values( e, &mod, 1, &text, -- textbuf, sizeof( textbuf ) ); -- /* don't care too much about return code... */ -- -- /* remove attrs */ -- mod.sm_values = NULL; -- mod.sm_numvals = 0; -- for ( i = 0; s_at[ i ].desc != NULL; i++ ) { -- mod.sm_desc = *s_at[ i ].ad; -- rc = modify_delete_values( e, &mod, 1, &text, -- textbuf, sizeof( textbuf ) ); -- /* don't care too much about return code... */ -- } -- -- return SLAP_CB_CONTINUE; --} -- --#define bdb_monitor_initialize BDB_SYMBOL(monitor_initialize) -- --/* -- * call from within bdb_initialize() -- */ --static int --bdb_monitor_initialize( void ) --{ -- int i, code; -- ConfigArgs c; -- char *argv[ 3 ]; -- -- static int bdb_monitor_initialized = 0; -- -- /* set to 0 when successfully initialized; otherwise, remember failure */ -- static int bdb_monitor_initialized_failure = 1; -- -- if ( bdb_monitor_initialized++ ) { -- return bdb_monitor_initialized_failure; -- } -- -- if ( backend_info( "monitor" ) == NULL ) { -- return -1; -- } -- -- /* register schema here */ -- -- argv[ 0 ] = "back-bdb/back-hdb monitor"; -- c.argv = argv; -- c.argc = 3; -- c.fname = argv[0]; -- -- for ( i = 0; s_oid[ i ].name; i++ ) { -- c.lineno = i; -- argv[ 1 ] = s_oid[ i ].name; -- argv[ 2 ] = s_oid[ i ].oid; -- -- if ( parse_oidm( &c, 0, NULL ) != 0 ) { -- Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_monitor_initialize) -- ": unable to add " -- "objectIdentifier \"%s=%s\"\n", -- s_oid[ i ].name, s_oid[ i ].oid, 0 ); -- return 2; -- } -- } -- -- for ( i = 0; s_at[ i ].desc != NULL; i++ ) { -- code = register_at( s_at[ i ].desc, s_at[ i ].ad, 1 ); -- if ( code != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_monitor_initialize) -- ": register_at failed for attributeType (%s)\n", -- s_at[ i ].desc, 0, 0 ); -- return 3; -- -- } else { -- (*s_at[ i ].ad)->ad_type->sat_flags |= SLAP_AT_HIDE; -- } -- } -- -- for ( i = 0; s_oc[ i ].desc != NULL; i++ ) { -- code = register_oc( s_oc[ i ].desc, s_oc[ i ].oc, 1 ); -- if ( code != LDAP_SUCCESS ) { -- Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_monitor_initialize) -- ": register_oc failed for objectClass (%s)\n", -- s_oc[ i ].desc, 0, 0 ); -- return 4; -- -- } else { -- (*s_oc[ i ].oc)->soc_flags |= SLAP_OC_HIDE; -- } -- } -- -- return ( bdb_monitor_initialized_failure = LDAP_SUCCESS ); --} -- --/* -- * call from within bdb_db_init() -- */ --int --bdb_monitor_db_init( BackendDB *be ) --{ -- struct bdb_info *bdb = (struct bdb_info *) be->be_private; -- -- if ( bdb_monitor_initialize() == LDAP_SUCCESS ) { -- /* monitoring in back-bdb is on by default */ -- SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_MONITORING; -- } -- --#ifdef BDB_MONITOR_IDX -- bdb->bi_idx = NULL; -- ldap_pvt_thread_mutex_init( &bdb->bi_idx_mutex ); --#endif /* BDB_MONITOR_IDX */ -- -- return 0; --} -- --/* -- * call from within bdb_db_open() -- */ --int --bdb_monitor_db_open( BackendDB *be ) --{ -- struct bdb_info *bdb = (struct bdb_info *) be->be_private; -- Attribute *a, *next; -- monitor_callback_t *cb = NULL; -- int rc = 0; -- BackendInfo *mi; -- monitor_extra_t *mbe; -- -- if ( !SLAP_DBMONITORING( be ) ) { -- return 0; -- } -- -- mi = backend_info( "monitor" ); -- if ( !mi || !mi->bi_extra ) { -- SLAP_DBFLAGS( be ) ^= SLAP_DBFLAG_MONITORING; -- return 0; -- } -- mbe = mi->bi_extra; -- -- /* don't bother if monitor is not configured */ -- if ( !mbe->is_configured() ) { -- static int warning = 0; -- -- if ( warning++ == 0 ) { -- Debug( LDAP_DEBUG_ANY, LDAP_XSTRING(bdb_monitor_db_open) -- ": monitoring disabled; " -- "configure monitor database to enable\n", -- 0, 0, 0 ); -- } -- -- return 0; -- } -- -- /* alloc as many as required (plus 1 for objectClass) */ -- a = attrs_alloc( 1 + 4 ); -- if ( a == NULL ) { -- rc = 1; -- goto cleanup; -- } -- -- a->a_desc = slap_schema.si_ad_objectClass; -- attr_valadd( a, &oc_olmBDBDatabase->soc_cname, NULL, 1 ); -- next = a->a_next; -- -- { -- struct berval bv = BER_BVC( "0" ); -- -- next->a_desc = ad_olmBDBEntryCache; -- attr_valadd( next, &bv, NULL, 1 ); -- next = next->a_next; -- -- next->a_desc = ad_olmBDBDNCache; -- attr_valadd( next, &bv, NULL, 1 ); -- next = next->a_next; -- -- next->a_desc = ad_olmBDBIDLCache; -- attr_valadd( next, &bv, NULL, 1 ); -- next = next->a_next; -- } -- -- { -- struct berval bv, nbv; -- ber_len_t pathlen = 0, len = 0; -- char path[ MAXPATHLEN ] = { '\0' }; -- char *fname = bdb->bi_dbenv_home, -- *ptr; -- -- len = strlen( fname ); -- if ( fname[ 0 ] != '/' ) { -- /* get full path name */ -- getcwd( path, sizeof( path ) ); -- pathlen = strlen( path ); -- -- if ( fname[ 0 ] == '.' && fname[ 1 ] == '/' ) { -- fname += 2; -- len -= 2; -- } -- } -- -- bv.bv_len = pathlen + STRLENOF( "/" ) + len; -- ptr = bv.bv_val = ch_malloc( bv.bv_len + STRLENOF( "/" ) + 1 ); -- if ( pathlen ) { -- ptr = lutil_strncopy( ptr, path, pathlen ); -- ptr[ 0 ] = '/'; -- ptr++; -- } -- ptr = lutil_strncopy( ptr, fname, len ); -- if ( ptr[ -1 ] != '/' ) { -- ptr[ 0 ] = '/'; -- ptr++; -- } -- ptr[ 0 ] = '\0'; -- -- attr_normalize_one( ad_olmDbDirectory, &bv, &nbv, NULL ); -- -- next->a_desc = ad_olmDbDirectory; -- next->a_vals = ch_calloc( sizeof( struct berval ), 2 ); -- next->a_vals[ 0 ] = bv; -- next->a_numvals = 1; -- -- if ( BER_BVISNULL( &nbv ) ) { -- next->a_nvals = next->a_vals; -- -- } else { -- next->a_nvals = ch_calloc( sizeof( struct berval ), 2 ); -- next->a_nvals[ 0 ] = nbv; -- } -- -- next = next->a_next; -- } -- -- cb = ch_calloc( sizeof( monitor_callback_t ), 1 ); -- cb->mc_update = bdb_monitor_update; --#if 0 /* uncomment if required */ -- cb->mc_modify = bdb_monitor_modify; --#endif -- cb->mc_free = bdb_monitor_free; -- cb->mc_private = (void *)bdb; -- -- /* make sure the database is registered; then add monitor attributes */ -- rc = mbe->register_database( be, &bdb->bi_monitor.bdm_ndn ); -- if ( rc == 0 ) { -- rc = mbe->register_entry_attrs( &bdb->bi_monitor.bdm_ndn, a, cb, -- NULL, 0, NULL ); -- } -- --cleanup:; -- if ( rc != 0 ) { -- if ( cb != NULL ) { -- ch_free( cb ); -- cb = NULL; -- } -- -- if ( a != NULL ) { -- attrs_free( a ); -- a = NULL; -- } -- } -- -- /* store for cleanup */ -- bdb->bi_monitor.bdm_cb = (void *)cb; -- -- /* we don't need to keep track of the attributes, because -- * bdb_monitor_free() takes care of everything */ -- if ( a != NULL ) { -- attrs_free( a ); -- } -- -- return rc; --} -- --/* -- * call from within bdb_db_close() -- */ --int --bdb_monitor_db_close( BackendDB *be ) --{ -- struct bdb_info *bdb = (struct bdb_info *) be->be_private; -- -- if ( !BER_BVISNULL( &bdb->bi_monitor.bdm_ndn ) ) { -- BackendInfo *mi = backend_info( "monitor" ); -- monitor_extra_t *mbe; -- -- if ( mi && &mi->bi_extra ) { -- mbe = mi->bi_extra; -- mbe->unregister_entry_callback( &bdb->bi_monitor.bdm_ndn, -- (monitor_callback_t *)bdb->bi_monitor.bdm_cb, -- NULL, 0, NULL ); -- } -- -- memset( &bdb->bi_monitor, 0, sizeof( bdb->bi_monitor ) ); -- } -- -- return 0; --} -- --/* -- * call from within bdb_db_destroy() -- */ --int --bdb_monitor_db_destroy( BackendDB *be ) --{ --#ifdef BDB_MONITOR_IDX -- struct bdb_info *bdb = (struct bdb_info *) be->be_private; -- -- /* TODO: free tree */ -- ldap_pvt_thread_mutex_destroy( &bdb->bi_idx_mutex ); -- avl_free( bdb->bi_idx, ch_free ); --#endif /* BDB_MONITOR_IDX */ -- -- return 0; --} -- --#ifdef BDB_MONITOR_IDX -- --#define BDB_MONITOR_IDX_TYPES (4) -- --typedef struct monitor_idx_t monitor_idx_t; -- --struct monitor_idx_t { -- AttributeDescription *idx_ad; -- unsigned long idx_count[BDB_MONITOR_IDX_TYPES]; --}; -- --static int --bdb_monitor_bitmask2key( slap_mask_t bitmask ) --{ -- int key; -- -- for ( key = 0; key < 8 * (int)sizeof(slap_mask_t) && !( bitmask & 0x1U ); -- key++ ) -- bitmask >>= 1; -- -- return key; --} -- --static struct berval idxbv[] = { -- BER_BVC( "present=" ), -- BER_BVC( "equality=" ), -- BER_BVC( "approx=" ), -- BER_BVC( "substr=" ), -- BER_BVNULL --}; -- --static ber_len_t --bdb_monitor_idx2len( monitor_idx_t *idx ) --{ -- int i; -- ber_len_t len = 0; -- -- for ( i = 0; i < BDB_MONITOR_IDX_TYPES; i++ ) { -- if ( idx->idx_count[ i ] != 0 ) { -- len += idxbv[i].bv_len; -- } -- } -- -- return len; --} -- --static int --monitor_idx_cmp( const void *p1, const void *p2 ) --{ -- const monitor_idx_t *idx1 = (const monitor_idx_t *)p1; -- const monitor_idx_t *idx2 = (const monitor_idx_t *)p2; -- -- return SLAP_PTRCMP( idx1->idx_ad, idx2->idx_ad ); --} -- --static int --monitor_idx_dup( void *p1, void *p2 ) --{ -- monitor_idx_t *idx1 = (monitor_idx_t *)p1; -- monitor_idx_t *idx2 = (monitor_idx_t *)p2; -- -- return SLAP_PTRCMP( idx1->idx_ad, idx2->idx_ad ) == 0 ? -1 : 0; --} -- --int --bdb_monitor_idx_add( -- struct bdb_info *bdb, -- AttributeDescription *desc, -- slap_mask_t type ) --{ -- monitor_idx_t idx_dummy = { 0 }, -- *idx; -- int rc = 0, key; -- -- idx_dummy.idx_ad = desc; -- key = bdb_monitor_bitmask2key( type ) - 1; -- if ( key >= BDB_MONITOR_IDX_TYPES ) { -- /* invalid index type */ -- return -1; -- } -- -- ldap_pvt_thread_mutex_lock( &bdb->bi_idx_mutex ); -- -- idx = (monitor_idx_t *)avl_find( bdb->bi_idx, -- (caddr_t)&idx_dummy, monitor_idx_cmp ); -- if ( idx == NULL ) { -- idx = (monitor_idx_t *)ch_calloc( sizeof( monitor_idx_t ), 1 ); -- idx->idx_ad = desc; -- idx->idx_count[ key ] = 1; -- -- switch ( avl_insert( &bdb->bi_idx, (caddr_t)idx, -- monitor_idx_cmp, monitor_idx_dup ) ) -- { -- case 0: -- break; -- -- default: -- ch_free( idx ); -- rc = -1; -- } -- -- } else { -- idx->idx_count[ key ]++; -- } -- -- ldap_pvt_thread_mutex_unlock( &bdb->bi_idx_mutex ); -- -- return rc; --} -- --static int --bdb_monitor_idx_apply( void *v_idx, void *v_valp ) --{ -- monitor_idx_t *idx = (monitor_idx_t *)v_idx; -- BerVarray *valp = (BerVarray *)v_valp; -- -- struct berval bv; -- char *ptr; -- char count_buf[ BDB_MONITOR_IDX_TYPES ][ SLAP_TEXT_BUFLEN ]; -- ber_len_t count_len[ BDB_MONITOR_IDX_TYPES ], -- idx_len; -- int i, num = 0; -- -- idx_len = bdb_monitor_idx2len( idx ); -- -- bv.bv_len = 0; -- for ( i = 0; i < BDB_MONITOR_IDX_TYPES; i++ ) { -- if ( idx->idx_count[ i ] == 0 ) { -- continue; -- } -- -- count_len[ i ] = snprintf( count_buf[ i ], -- sizeof( count_buf[ i ] ), "%lu", idx->idx_count[ i ] ); -- bv.bv_len += count_len[ i ]; -- num++; -- } -- -- bv.bv_len += idx->idx_ad->ad_cname.bv_len -- + num -- + idx_len; -- ptr = bv.bv_val = ch_malloc( bv.bv_len + 1 ); -- ptr = lutil_strcopy( ptr, idx->idx_ad->ad_cname.bv_val ); -- for ( i = 0; i < BDB_MONITOR_IDX_TYPES; i++ ) { -- if ( idx->idx_count[ i ] == 0 ) { -- continue; -- } -- -- ptr[ 0 ] = '#'; -- ++ptr; -- ptr = lutil_strcopy( ptr, idxbv[ i ].bv_val ); -- ptr = lutil_strcopy( ptr, count_buf[ i ] ); -- } -- -- ber_bvarray_add( valp, &bv ); -- -- return 0; --} -- --static int --bdb_monitor_idx_entry_add( -- struct bdb_info *bdb, -- Entry *e ) --{ -- BerVarray vals = NULL; -- Attribute *a; -- -- a = attr_find( e->e_attrs, ad_olmDbNotIndexed ); -- -- ldap_pvt_thread_mutex_lock( &bdb->bi_idx_mutex ); -- -- avl_apply( bdb->bi_idx, bdb_monitor_idx_apply, -- &vals, -1, AVL_INORDER ); -- -- ldap_pvt_thread_mutex_unlock( &bdb->bi_idx_mutex ); -- -- if ( vals != NULL ) { -- if ( a != NULL ) { -- assert( a->a_nvals == a->a_vals ); -- -- ber_bvarray_free( a->a_vals ); -- -- } else { -- Attribute **ap; -- -- for ( ap = &e->e_attrs; *ap != NULL; ap = &(*ap)->a_next ) -- ; -- *ap = attr_alloc( ad_olmDbNotIndexed ); -- a = *ap; -- } -- a->a_vals = vals; -- a->a_nvals = a->a_vals; -- } -- -- return 0; --} -- --#endif /* BDB_MONITOR_IDX */ -diff --git a/servers/slapd/back-bdb/nextid.c b/servers/slapd/back-bdb/nextid.c -deleted file mode 100644 -index 480b80e..0000000 ---- a/servers/slapd/back-bdb/nextid.c -+++ /dev/null -@@ -1,80 +0,0 @@ --/* init.c - initialize bdb backend */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include --#include -- --#include "back-bdb.h" -- --int bdb_next_id( BackendDB *be, ID *out ) --{ -- struct bdb_info *bdb = (struct bdb_info *) be->be_private; -- -- ldap_pvt_thread_mutex_lock( &bdb->bi_lastid_mutex ); -- *out = ++bdb->bi_lastid; -- ldap_pvt_thread_mutex_unlock( &bdb->bi_lastid_mutex ); -- -- return 0; --} -- --int bdb_last_id( BackendDB *be, DB_TXN *tid ) --{ -- struct bdb_info *bdb = (struct bdb_info *) be->be_private; -- int rc; -- ID id = 0; -- unsigned char idbuf[sizeof(ID)]; -- DBT key, data; -- DBC *cursor; -- -- DBTzero( &key ); -- key.flags = DB_DBT_USERMEM; -- key.data = (char *) idbuf; -- key.ulen = sizeof( idbuf ); -- -- DBTzero( &data ); -- data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; -- -- /* Get a read cursor */ -- rc = bdb->bi_id2entry->bdi_db->cursor( bdb->bi_id2entry->bdi_db, -- tid, &cursor, 0 ); -- -- if (rc == 0) { -- rc = cursor->c_get(cursor, &key, &data, DB_LAST); -- cursor->c_close(cursor); -- } -- -- switch(rc) { -- case DB_NOTFOUND: -- rc = 0; -- break; -- case 0: -- BDB_DISK2ID( idbuf, &id ); -- break; -- -- default: -- Debug( LDAP_DEBUG_ANY, -- "=> bdb_last_id: get failed: %s (%d)\n", -- db_strerror(rc), rc, 0 ); -- goto done; -- } -- -- bdb->bi_lastid = id; -- --done: -- return rc; --} -diff --git a/servers/slapd/back-bdb/operational.c b/servers/slapd/back-bdb/operational.c -deleted file mode 100644 -index 5f21abe..0000000 ---- a/servers/slapd/back-bdb/operational.c -+++ /dev/null -@@ -1,151 +0,0 @@ --/* operational.c - bdb backend operational attributes function */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include -- --#include --#include -- --#include "slap.h" --#include "back-bdb.h" -- --/* -- * sets *hasSubordinates to LDAP_COMPARE_TRUE/LDAP_COMPARE_FALSE -- * if the entry has children or not. -- */ --int --bdb_hasSubordinates( -- Operation *op, -- Entry *e, -- int *hasSubordinates ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- struct bdb_op_info *opinfo; -- OpExtra *oex; -- DB_TXN *rtxn; -- int rc; -- int release = 0; -- -- assert( e != NULL ); -- -- /* NOTE: this should never happen, but it actually happens -- * when using back-relay; until we find a better way to -- * preserve entry's private information while rewriting it, -- * let's disable the hasSubordinate feature for back-relay. -- */ -- if ( BEI( e ) == NULL ) { -- Entry *ee = NULL; -- rc = be_entry_get_rw( op, &e->e_nname, NULL, NULL, 0, &ee ); -- if ( rc != LDAP_SUCCESS || ee == NULL ) { -- rc = LDAP_OTHER; -- goto done; -- } -- e = ee; -- release = 1; -- if ( BEI( ee ) == NULL ) { -- rc = LDAP_OTHER; -- goto done; -- } -- } -- -- /* Check for a txn in a parent op, otherwise use reader txn */ -- LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) { -- if ( oex->oe_key == bdb ) -- break; -- } -- opinfo = (struct bdb_op_info *) oex; -- if ( opinfo && opinfo->boi_txn ) { -- rtxn = opinfo->boi_txn; -- } else { -- rc = bdb_reader_get(op, bdb->bi_dbenv, &rtxn); -- if ( rc ) { -- rc = LDAP_OTHER; -- goto done; -- } -- } -- --retry: -- /* FIXME: we can no longer assume the entry's e_private -- * field is correctly populated; so we need to reacquire -- * it with reader lock */ -- rc = bdb_cache_children( op, rtxn, e ); -- -- switch( rc ) { -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto retry; -- -- case 0: -- *hasSubordinates = LDAP_COMPARE_TRUE; -- break; -- -- case DB_NOTFOUND: -- *hasSubordinates = LDAP_COMPARE_FALSE; -- rc = LDAP_SUCCESS; -- break; -- -- default: -- Debug(LDAP_DEBUG_ARGS, -- "<=- " LDAP_XSTRING(bdb_hasSubordinates) -- ": has_children failed: %s (%d)\n", -- db_strerror(rc), rc, 0 ); -- rc = LDAP_OTHER; -- } -- --done:; -- if ( release && e != NULL ) be_entry_release_r( op, e ); -- return rc; --} -- --/* -- * sets the supported operational attributes (if required) -- */ --int --bdb_operational( -- Operation *op, -- SlapReply *rs ) --{ -- Attribute **ap; -- -- assert( rs->sr_entry != NULL ); -- -- for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next ) { -- if ( (*ap)->a_desc == slap_schema.si_ad_hasSubordinates ) { -- break; -- } -- } -- -- if ( *ap == NULL && -- attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_hasSubordinates ) == NULL && -- ( SLAP_OPATTRS( rs->sr_attr_flags ) || -- ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) ) ) -- { -- int hasSubordinates, rc; -- -- rc = bdb_hasSubordinates( op, rs->sr_entry, &hasSubordinates ); -- if ( rc == LDAP_SUCCESS ) { -- *ap = slap_operational_hasSubordinate( hasSubordinates == LDAP_COMPARE_TRUE ); -- assert( *ap != NULL ); -- -- ap = &(*ap)->a_next; -- } -- } -- -- return LDAP_SUCCESS; --} -- -diff --git a/servers/slapd/back-bdb/proto-bdb.h b/servers/slapd/back-bdb/proto-bdb.h -deleted file mode 100644 -index 34b8ce0..0000000 ---- a/servers/slapd/back-bdb/proto-bdb.h -+++ /dev/null -@@ -1,678 +0,0 @@ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#ifndef _PROTO_BDB_H --#define _PROTO_BDB_H -- --LDAP_BEGIN_DECL -- --#ifdef BDB_HIER --#define BDB_SYMBOL(x) LDAP_CONCAT(hdb_,x) --#define BDB_UCTYPE "HDB" --#else --#define BDB_SYMBOL(x) LDAP_CONCAT(bdb_,x) --#define BDB_UCTYPE "BDB" --#endif -- --/* -- * attr.c -- */ -- --#define bdb_attr_mask BDB_SYMBOL(attr_mask) --#define bdb_attr_flush BDB_SYMBOL(attr_flush) --#define bdb_attr_slot BDB_SYMBOL(attr_slot) --#define bdb_attr_index_config BDB_SYMBOL(attr_index_config) --#define bdb_attr_index_destroy BDB_SYMBOL(attr_index_destroy) --#define bdb_attr_index_free BDB_SYMBOL(attr_index_free) --#define bdb_attr_index_unparse BDB_SYMBOL(attr_index_unparse) --#define bdb_attr_info_free BDB_SYMBOL(attr_info_free) -- --AttrInfo *bdb_attr_mask( struct bdb_info *bdb, -- AttributeDescription *desc ); -- --void bdb_attr_flush( struct bdb_info *bdb ); -- --int bdb_attr_slot( struct bdb_info *bdb, -- AttributeDescription *desc, int *insert ); -- --int bdb_attr_index_config LDAP_P(( struct bdb_info *bdb, -- const char *fname, int lineno, -- int argc, char **argv, struct config_reply_s *cr )); -- --void bdb_attr_index_unparse LDAP_P(( struct bdb_info *bdb, BerVarray *bva )); --void bdb_attr_index_destroy LDAP_P(( struct bdb_info *bdb )); --void bdb_attr_index_free LDAP_P(( struct bdb_info *bdb, -- AttributeDescription *ad )); -- --void bdb_attr_info_free( AttrInfo *ai ); -- --/* -- * config.c -- */ -- --#define bdb_back_init_cf BDB_SYMBOL(back_init_cf) -- --int bdb_back_init_cf( BackendInfo *bi ); -- --/* -- * dbcache.c -- */ --#define bdb_db_cache BDB_SYMBOL(db_cache) --#define bdb_db_findsize BDB_SYMBOL(db_findsize) -- --int --bdb_db_cache( -- Backend *be, -- struct berval *name, -- DB **db ); -- --int --bdb_db_findsize( -- struct bdb_info *bdb, -- struct berval *name ); -- --/* -- * dn2entry.c -- */ --#define bdb_dn2entry BDB_SYMBOL(dn2entry) -- --int bdb_dn2entry LDAP_P(( Operation *op, DB_TXN *tid, -- struct berval *dn, EntryInfo **e, int matched, -- DB_LOCK *lock )); -- --/* -- * dn2id.c -- */ --#define bdb_dn2id BDB_SYMBOL(dn2id) --#define bdb_dn2id_add BDB_SYMBOL(dn2id_add) --#define bdb_dn2id_delete BDB_SYMBOL(dn2id_delete) --#define bdb_dn2id_children BDB_SYMBOL(dn2id_children) --#define bdb_dn2idl BDB_SYMBOL(dn2idl) -- --int bdb_dn2id( -- Operation *op, -- struct berval *dn, -- EntryInfo *ei, -- DB_TXN *txn, -- DBC **cursor ); -- --int bdb_dn2id_add( -- Operation *op, -- DB_TXN *tid, -- EntryInfo *eip, -- Entry *e ); -- --int bdb_dn2id_delete( -- Operation *op, -- DB_TXN *tid, -- EntryInfo *eip, -- Entry *e ); -- --int bdb_dn2id_children( -- Operation *op, -- DB_TXN *tid, -- Entry *e ); -- --int bdb_dn2idl( -- Operation *op, -- DB_TXN *txn, -- struct berval *ndn, -- EntryInfo *ei, -- ID *ids, -- ID *stack ); -- --#ifdef BDB_HIER --#define bdb_dn2id_parent BDB_SYMBOL(dn2id_parent) --#define bdb_dup_compare BDB_SYMBOL(dup_compare) --#define bdb_fix_dn BDB_SYMBOL(fix_dn) -- --int bdb_dn2id_parent( -- Operation *op, -- DB_TXN *txn, -- EntryInfo *ei, -- ID *idp ); -- --int bdb_dup_compare( -- DB *db, -- const DBT *usrkey, -- const DBT *curkey ); -- --int bdb_fix_dn( Entry *e, int checkit ); --#endif -- -- --/* -- * error.c -- */ --#define bdb_errcall BDB_SYMBOL(errcall) -- --#if DB_VERSION_FULL < 0x04030000 --void bdb_errcall( const char *pfx, char * msg ); --#else --#define bdb_msgcall BDB_SYMBOL(msgcall) --void bdb_errcall( const DB_ENV *env, const char *pfx, const char * msg ); --void bdb_msgcall( const DB_ENV *env, const char * msg ); --#endif -- --#ifdef HAVE_EBCDIC --#define ebcdic_dberror BDB_SYMBOL(ebcdic_dberror) -- --char *ebcdic_dberror( int rc ); --#define db_strerror(x) ebcdic_dberror(x) --#endif -- --/* -- * filterentry.c -- */ --#define bdb_filter_candidates BDB_SYMBOL(filter_candidates) -- --int bdb_filter_candidates( -- Operation *op, -- DB_TXN *txn, -- Filter *f, -- ID *ids, -- ID *tmp, -- ID *stack ); -- --/* -- * id2entry.c -- */ --#define bdb_id2entry BDB_SYMBOL(id2entry) --#define bdb_id2entry_add BDB_SYMBOL(id2entry_add) --#define bdb_id2entry_update BDB_SYMBOL(id2entry_update) --#define bdb_id2entry_delete BDB_SYMBOL(id2entry_delete) -- --int bdb_id2entry_add( -- BackendDB *be, -- DB_TXN *tid, -- Entry *e ); -- --int bdb_id2entry_update( -- BackendDB *be, -- DB_TXN *tid, -- Entry *e ); -- --int bdb_id2entry_delete( -- BackendDB *be, -- DB_TXN *tid, -- Entry *e); -- --#ifdef SLAP_ZONE_ALLOC --#else --int bdb_id2entry( -- BackendDB *be, -- DB_TXN *tid, -- ID id, -- Entry **e); --#endif -- --#define bdb_entry_free BDB_SYMBOL(entry_free) --#define bdb_entry_return BDB_SYMBOL(entry_return) --#define bdb_entry_release BDB_SYMBOL(entry_release) --#define bdb_entry_get BDB_SYMBOL(entry_get) -- --void bdb_entry_free ( Entry *e ); --#ifdef SLAP_ZONE_ALLOC --int bdb_entry_return( struct bdb_info *bdb, Entry *e, int seqno ); --#else --int bdb_entry_return( Entry *e ); --#endif --BI_entry_release_rw bdb_entry_release; --BI_entry_get_rw bdb_entry_get; -- -- --/* -- * idl.c -- */ -- --#define bdb_idl_cache_get BDB_SYMBOL(idl_cache_get) --#define bdb_idl_cache_put BDB_SYMBOL(idl_cache_put) --#define bdb_idl_cache_del BDB_SYMBOL(idl_cache_del) --#define bdb_idl_cache_add_id BDB_SYMBOL(idl_cache_add_id) --#define bdb_idl_cache_del_id BDB_SYMBOL(idl_cache_del_id) -- --int bdb_idl_cache_get( -- struct bdb_info *bdb, -- DB *db, -- DBT *key, -- ID *ids ); -- --void --bdb_idl_cache_put( -- struct bdb_info *bdb, -- DB *db, -- DBT *key, -- ID *ids, -- int rc ); -- --void --bdb_idl_cache_del( -- struct bdb_info *bdb, -- DB *db, -- DBT *key ); -- --void --bdb_idl_cache_add_id( -- struct bdb_info *bdb, -- DB *db, -- DBT *key, -- ID id ); -- --void --bdb_idl_cache_del_id( -- struct bdb_info *bdb, -- DB *db, -- DBT *key, -- ID id ); -- --#define bdb_idl_first BDB_SYMBOL(idl_first) --#define bdb_idl_next BDB_SYMBOL(idl_next) --#define bdb_idl_search BDB_SYMBOL(idl_search) --#define bdb_idl_insert BDB_SYMBOL(idl_insert) --#define bdb_idl_delete BDB_SYMBOL(idl_delete) --#define bdb_idl_intersection BDB_SYMBOL(idl_intersection) --#define bdb_idl_union BDB_SYMBOL(idl_union) --#define bdb_idl_sort BDB_SYMBOL(idl_sort) --#define bdb_idl_append BDB_SYMBOL(idl_append) --#define bdb_idl_append_one BDB_SYMBOL(idl_append_one) -- --#define bdb_idl_fetch_key BDB_SYMBOL(idl_fetch_key) --#define bdb_idl_insert_key BDB_SYMBOL(idl_insert_key) --#define bdb_idl_delete_key BDB_SYMBOL(idl_delete_key) -- --unsigned bdb_idl_search( ID *ids, ID id ); -- --int bdb_idl_fetch_key( -- BackendDB *be, -- DB *db, -- DB_TXN *txn, -- DBT *key, -- ID *ids, -- DBC **saved_cursor, -- int get_flag ); -- --int bdb_idl_insert( ID *ids, ID id ); --int bdb_idl_delete( ID *ids, ID id ); -- --int bdb_idl_insert_key( -- BackendDB *be, -- DB *db, -- DB_TXN *txn, -- DBT *key, -- ID id ); -- --int bdb_idl_delete_key( -- BackendDB *be, -- DB *db, -- DB_TXN *txn, -- DBT *key, -- ID id ); -- --int --bdb_idl_intersection( -- ID *a, -- ID *b ); -- --int --bdb_idl_union( -- ID *a, -- ID *b ); -- --ID bdb_idl_first( ID *ids, ID *cursor ); --ID bdb_idl_next( ID *ids, ID *cursor ); -- --void bdb_idl_sort( ID *ids, ID *tmp ); --int bdb_idl_append( ID *a, ID *b ); --int bdb_idl_append_one( ID *ids, ID id ); -- -- --/* -- * index.c -- */ --#define bdb_index_mask BDB_SYMBOL(index_mask) --#define bdb_index_param BDB_SYMBOL(index_param) --#define bdb_index_values BDB_SYMBOL(index_values) --#define bdb_index_entry BDB_SYMBOL(index_entry) --#define bdb_index_recset BDB_SYMBOL(index_recset) --#define bdb_index_recrun BDB_SYMBOL(index_recrun) -- --extern AttrInfo * --bdb_index_mask LDAP_P(( -- Backend *be, -- AttributeDescription *desc, -- struct berval *name )); -- --extern int --bdb_index_param LDAP_P(( -- Backend *be, -- AttributeDescription *desc, -- int ftype, -- DB **db, -- slap_mask_t *mask, -- struct berval *prefix )); -- --extern int --bdb_index_values LDAP_P(( -- Operation *op, -- DB_TXN *txn, -- AttributeDescription *desc, -- BerVarray vals, -- ID id, -- int opid )); -- --extern int --bdb_index_recset LDAP_P(( -- struct bdb_info *bdb, -- Attribute *a, -- AttributeType *type, -- struct berval *tags, -- IndexRec *ir )); -- --extern int --bdb_index_recrun LDAP_P(( -- Operation *op, -- struct bdb_info *bdb, -- IndexRec *ir, -- ID id, -- int base )); -- --int bdb_index_entry LDAP_P(( Operation *op, DB_TXN *t, int r, Entry *e )); -- --#define bdb_index_entry_add(op,t,e) \ -- bdb_index_entry((op),(t),SLAP_INDEX_ADD_OP,(e)) --#define bdb_index_entry_del(op,t,e) \ -- bdb_index_entry((op),(t),SLAP_INDEX_DELETE_OP,(e)) -- --/* -- * key.c -- */ --#define bdb_key_read BDB_SYMBOL(key_read) --#define bdb_key_change BDB_SYMBOL(key_change) -- --extern int --bdb_key_read( -- Backend *be, -- DB *db, -- DB_TXN *txn, -- struct berval *k, -- ID *ids, -- DBC **saved_cursor, -- int get_flags ); -- --extern int --bdb_key_change( -- Backend *be, -- DB *db, -- DB_TXN *txn, -- struct berval *k, -- ID id, -- int op ); -- --/* -- * nextid.c -- */ --#define bdb_next_id BDB_SYMBOL(next_id) --#define bdb_last_id BDB_SYMBOL(last_id) -- --int bdb_next_id( BackendDB *be, ID *id ); --int bdb_last_id( BackendDB *be, DB_TXN *tid ); -- --/* -- * modify.c -- */ --#define bdb_modify_internal BDB_SYMBOL(modify_internal) -- --int bdb_modify_internal( -- Operation *op, -- DB_TXN *tid, -- Modifications *modlist, -- Entry *e, -- const char **text, -- char *textbuf, -- size_t textlen ); -- --/* -- * monitor.c -- */ -- --#define bdb_monitor_db_init BDB_SYMBOL(monitor_db_init) --#define bdb_monitor_db_open BDB_SYMBOL(monitor_db_open) --#define bdb_monitor_db_close BDB_SYMBOL(monitor_db_close) --#define bdb_monitor_db_destroy BDB_SYMBOL(monitor_db_destroy) -- --int bdb_monitor_db_init( BackendDB *be ); --int bdb_monitor_db_open( BackendDB *be ); --int bdb_monitor_db_close( BackendDB *be ); --int bdb_monitor_db_destroy( BackendDB *be ); -- --#ifdef BDB_MONITOR_IDX --#define bdb_monitor_idx_add BDB_SYMBOL(monitor_idx_add) --int --bdb_monitor_idx_add( -- struct bdb_info *bdb, -- AttributeDescription *desc, -- slap_mask_t type ); --#endif /* BDB_MONITOR_IDX */ -- --/* -- * cache.c -- */ --#define bdb_cache_entry_db_unlock BDB_SYMBOL(cache_entry_db_unlock) --#define bdb_cache_return_entry_rw BDB_SYMBOL(cache_return_entry_rw) -- --#define bdb_cache_entryinfo_lock(e) \ -- ldap_pvt_thread_mutex_lock( &(e)->bei_kids_mutex ) --#define bdb_cache_entryinfo_unlock(e) \ -- ldap_pvt_thread_mutex_unlock( &(e)->bei_kids_mutex ) --#define bdb_cache_entryinfo_trylock(e) \ -- ldap_pvt_thread_mutex_trylock( &(e)->bei_kids_mutex ) -- --/* What a mess. Hopefully the current cache scheme will stabilize -- * and we can trim out all of this stuff. -- */ --void bdb_cache_return_entry_rw( struct bdb_info *bdb, Entry *e, -- int rw, DB_LOCK *lock ); --#define bdb_cache_return_entry_r(bdb, e, l) \ -- bdb_cache_return_entry_rw((bdb), (e), 0, (l)) --#define bdb_cache_return_entry_w(bdb, e, l) \ -- bdb_cache_return_entry_rw((bdb), (e), 1, (l)) --#if 0 --void bdb_unlocked_cache_return_entry_rw( struct bdb_info *bdb, Entry *e, int rw ); --#else --#define bdb_unlocked_cache_return_entry_rw( a, b, c ) ((void)0) --#endif --#define bdb_unlocked_cache_return_entry_r( c, e ) \ -- bdb_unlocked_cache_return_entry_rw((c), (e), 0) --#define bdb_unlocked_cache_return_entry_w( c, e ) \ -- bdb_unlocked_cache_return_entry_rw((c), (e), 1) -- --#define bdb_cache_add BDB_SYMBOL(cache_add) --#define bdb_cache_children BDB_SYMBOL(cache_children) --#define bdb_cache_delete BDB_SYMBOL(cache_delete) --#define bdb_cache_delete_cleanup BDB_SYMBOL(cache_delete_cleanup) --#define bdb_cache_find_id BDB_SYMBOL(cache_find_id) --#define bdb_cache_find_ndn BDB_SYMBOL(cache_find_ndn) --#define bdb_cache_find_parent BDB_SYMBOL(cache_find_parent) --#define bdb_cache_modify BDB_SYMBOL(cache_modify) --#define bdb_cache_modrdn BDB_SYMBOL(cache_modrdn) --#define bdb_cache_release_all BDB_SYMBOL(cache_release_all) --#define bdb_cache_delete_entry BDB_SYMBOL(cache_delete_entry) --#define bdb_cache_deref BDB_SYMBOL(cache_deref) -- --int bdb_cache_children( -- Operation *op, -- DB_TXN *txn, -- Entry *e --); --int bdb_cache_add( -- struct bdb_info *bdb, -- EntryInfo *pei, -- Entry *e, -- struct berval *nrdn, -- DB_TXN *txn, -- DB_LOCK *lock --); --int bdb_cache_modrdn( -- struct bdb_info *bdb, -- Entry *e, -- struct berval *nrdn, -- Entry *new, -- EntryInfo *ein, -- DB_TXN *txn, -- DB_LOCK *lock --); --int bdb_cache_modify( -- struct bdb_info *bdb, -- Entry *e, -- Attribute *newAttrs, -- DB_TXN *txn, -- DB_LOCK *lock --); --int bdb_cache_find_ndn( -- Operation *op, -- DB_TXN *txn, -- struct berval *ndn, -- EntryInfo **res --); -- --#define ID_LOCKED 1 --#define ID_NOCACHE 2 --#define ID_NOENTRY 4 --#define ID_CHKPURGE 8 --int bdb_cache_find_id( -- Operation *op, -- DB_TXN *tid, -- ID id, -- EntryInfo **eip, -- int flag, -- DB_LOCK *lock --); --int --bdb_cache_find_parent( -- Operation *op, -- DB_TXN *txn, -- ID id, -- EntryInfo **res --); --int bdb_cache_delete( -- struct bdb_info *bdb, -- Entry *e, -- DB_TXN *txn, -- DB_LOCK *lock --); --void bdb_cache_delete_cleanup( -- Cache *cache, -- EntryInfo *ei --); --void bdb_cache_release_all( Cache *cache ); --void bdb_cache_deref( EntryInfo *ei ); -- --#ifdef BDB_HIER --int hdb_cache_load( -- struct bdb_info *bdb, -- EntryInfo *ei, -- EntryInfo **res --); --#endif -- --#define bdb_cache_entry_db_relock BDB_SYMBOL(cache_entry_db_relock) --int bdb_cache_entry_db_relock( -- struct bdb_info *bdb, -- DB_TXN *txn, -- EntryInfo *ei, -- int rw, -- int tryOnly, -- DB_LOCK *lock ); -- --int bdb_cache_entry_db_unlock( -- struct bdb_info *bdb, -- DB_LOCK *lock ); -- --#define bdb_reader_get BDB_SYMBOL(reader_get) --#define bdb_reader_flush BDB_SYMBOL(reader_flush) --int bdb_reader_get( Operation *op, DB_ENV *env, DB_TXN **txn ); --void bdb_reader_flush( DB_ENV *env ); -- --/* -- * trans.c -- */ --#define bdb_trans_backoff BDB_SYMBOL(trans_backoff) -- --void --bdb_trans_backoff( int num_retries ); -- --/* -- * former external.h -- */ -- --#define bdb_back_initialize BDB_SYMBOL(back_initialize) --#define bdb_db_config BDB_SYMBOL(db_config) --#define bdb_add BDB_SYMBOL(add) --#define bdb_bind BDB_SYMBOL(bind) --#define bdb_compare BDB_SYMBOL(compare) --#define bdb_delete BDB_SYMBOL(delete) --#define bdb_modify BDB_SYMBOL(modify) --#define bdb_modrdn BDB_SYMBOL(modrdn) --#define bdb_search BDB_SYMBOL(search) --#define bdb_extended BDB_SYMBOL(extended) --#define bdb_referrals BDB_SYMBOL(referrals) --#define bdb_operational BDB_SYMBOL(operational) --#define bdb_hasSubordinates BDB_SYMBOL(hasSubordinates) --#define bdb_tool_entry_open BDB_SYMBOL(tool_entry_open) --#define bdb_tool_entry_close BDB_SYMBOL(tool_entry_close) --#define bdb_tool_entry_first_x BDB_SYMBOL(tool_entry_first_x) --#define bdb_tool_entry_next BDB_SYMBOL(tool_entry_next) --#define bdb_tool_entry_get BDB_SYMBOL(tool_entry_get) --#define bdb_tool_entry_put BDB_SYMBOL(tool_entry_put) --#define bdb_tool_entry_reindex BDB_SYMBOL(tool_entry_reindex) --#define bdb_tool_dn2id_get BDB_SYMBOL(tool_dn2id_get) --#define bdb_tool_entry_modify BDB_SYMBOL(tool_entry_modify) --#define bdb_tool_idl_add BDB_SYMBOL(tool_idl_add) -- --extern BI_init bdb_back_initialize; -- --extern BI_db_config bdb_db_config; -- --extern BI_op_add bdb_add; --extern BI_op_bind bdb_bind; --extern BI_op_compare bdb_compare; --extern BI_op_delete bdb_delete; --extern BI_op_modify bdb_modify; --extern BI_op_modrdn bdb_modrdn; --extern BI_op_search bdb_search; --extern BI_op_extended bdb_extended; -- --extern BI_chk_referrals bdb_referrals; -- --extern BI_operational bdb_operational; -- --extern BI_has_subordinates bdb_hasSubordinates; -- --/* tools.c */ --extern BI_tool_entry_open bdb_tool_entry_open; --extern BI_tool_entry_close bdb_tool_entry_close; --extern BI_tool_entry_first_x bdb_tool_entry_first_x; --extern BI_tool_entry_next bdb_tool_entry_next; --extern BI_tool_entry_get bdb_tool_entry_get; --extern BI_tool_entry_put bdb_tool_entry_put; --extern BI_tool_entry_reindex bdb_tool_entry_reindex; --extern BI_tool_dn2id_get bdb_tool_dn2id_get; --extern BI_tool_entry_modify bdb_tool_entry_modify; -- --int bdb_tool_idl_add( BackendDB *be, DB *db, DB_TXN *txn, DBT *key, ID id ); -- --LDAP_END_DECL -- --#endif /* _PROTO_BDB_H */ -diff --git a/servers/slapd/back-bdb/referral.c b/servers/slapd/back-bdb/referral.c -deleted file mode 100644 -index d92ff5a..0000000 ---- a/servers/slapd/back-bdb/referral.c -+++ /dev/null -@@ -1,152 +0,0 @@ --/* referral.c - BDB backend referral handler */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" --#include --#include -- --#include "back-bdb.h" -- --int --bdb_referrals( Operation *op, SlapReply *rs ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- Entry *e = NULL; -- EntryInfo *ei; -- int rc = LDAP_SUCCESS; -- -- DB_TXN *rtxn; -- DB_LOCK lock; -- -- if( op->o_tag == LDAP_REQ_SEARCH ) { -- /* let search take care of itself */ -- return rc; -- } -- -- if( get_manageDSAit( op ) ) { -- /* let op take care of DSA management */ -- return rc; -- } -- -- rc = bdb_reader_get(op, bdb->bi_dbenv, &rtxn); -- switch(rc) { -- case 0: -- break; -- default: -- return LDAP_OTHER; -- } -- --dn2entry_retry: -- /* get entry */ -- rc = bdb_dn2entry( op, rtxn, &op->o_req_ndn, &ei, 1, &lock ); -- -- /* bdb_dn2entry() may legally leave ei == NULL -- * if rc != 0 and rc != DB_NOTFOUND -- */ -- if ( ei ) { -- e = ei->bei_e; -- } -- -- switch(rc) { -- case DB_NOTFOUND: -- case 0: -- break; -- case LDAP_BUSY: -- rs->sr_text = "ldap server busy"; -- return LDAP_BUSY; -- case DB_LOCK_DEADLOCK: -- case DB_LOCK_NOTGRANTED: -- goto dn2entry_retry; -- default: -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_referrals) -- ": dn2entry failed: %s (%d)\n", -- db_strerror(rc), rc, 0 ); -- rs->sr_text = "internal error"; -- return LDAP_OTHER; -- } -- -- if ( rc == DB_NOTFOUND ) { -- rc = LDAP_SUCCESS; -- rs->sr_matched = NULL; -- if ( e != NULL ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_referrals) -- ": tag=%lu target=\"%s\" matched=\"%s\"\n", -- (unsigned long)op->o_tag, op->o_req_dn.bv_val, e->e_name.bv_val ); -- -- if( is_entry_referral( e ) ) { -- BerVarray ref = get_entry_referrals( op, e ); -- rc = LDAP_OTHER; -- rs->sr_ref = referral_rewrite( ref, &e->e_name, -- &op->o_req_dn, LDAP_SCOPE_DEFAULT ); -- ber_bvarray_free( ref ); -- if ( rs->sr_ref ) { -- rs->sr_matched = ber_strdup_x( -- e->e_name.bv_val, op->o_tmpmemctx ); -- } -- } -- -- bdb_cache_return_entry_r (bdb, e, &lock); -- e = NULL; -- } -- -- if( rs->sr_ref != NULL ) { -- /* send referrals */ -- rc = rs->sr_err = LDAP_REFERRAL; -- send_ldap_result( op, rs ); -- ber_bvarray_free( rs->sr_ref ); -- rs->sr_ref = NULL; -- } else if ( rc != LDAP_SUCCESS ) { -- rs->sr_text = rs->sr_matched ? "bad referral object" : NULL; -- } -- -- if (rs->sr_matched) { -- op->o_tmpfree( (char *)rs->sr_matched, op->o_tmpmemctx ); -- rs->sr_matched = NULL; -- } -- return rc; -- } -- -- if ( is_entry_referral( e ) ) { -- /* entry is a referral */ -- BerVarray refs = get_entry_referrals( op, e ); -- rs->sr_ref = referral_rewrite( -- refs, &e->e_name, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); -- -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_referrals) -- ": tag=%lu target=\"%s\" matched=\"%s\"\n", -- (unsigned long)op->o_tag, op->o_req_dn.bv_val, e->e_name.bv_val ); -- -- rs->sr_matched = e->e_name.bv_val; -- if( rs->sr_ref != NULL ) { -- rc = rs->sr_err = LDAP_REFERRAL; -- send_ldap_result( op, rs ); -- ber_bvarray_free( rs->sr_ref ); -- rs->sr_ref = NULL; -- } else { -- rc = LDAP_OTHER; -- rs->sr_text = "bad referral object"; -- } -- -- rs->sr_matched = NULL; -- ber_bvarray_free( refs ); -- } -- -- bdb_cache_return_entry_r(bdb, e, &lock); -- return rc; --} -diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c -deleted file mode 100644 -index dd67f21..0000000 ---- a/servers/slapd/back-bdb/search.c -+++ /dev/null -@@ -1,1388 +0,0 @@ --/* search.c - search operation */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include --#include -- --#include "back-bdb.h" --#include "idl.h" -- --static int base_candidate( -- BackendDB *be, -- Entry *e, -- ID *ids ); -- --static int search_candidates( -- Operation *op, -- SlapReply *rs, -- Entry *e, -- DB_TXN *txn, -- ID *ids, -- ID *scopes ); -- --static int parse_paged_cookie( Operation *op, SlapReply *rs ); -- --static void send_paged_response( -- Operation *op, -- SlapReply *rs, -- ID *lastid, -- int tentries ); -- --/* Dereference aliases for a single alias entry. Return the final -- * dereferenced entry on success, NULL on any failure. -- */ --static Entry * deref_base ( -- Operation *op, -- SlapReply *rs, -- Entry *e, -- Entry **matched, -- DB_TXN *txn, -- DB_LOCK *lock, -- ID *tmp, -- ID *visited ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- struct berval ndn; -- EntryInfo *ei; -- DB_LOCK lockr; -- -- rs->sr_err = LDAP_ALIAS_DEREF_PROBLEM; -- rs->sr_text = "maximum deref depth exceeded"; -- -- for (;;) { -- /* Remember the last entry we looked at, so we can -- * report broken links -- */ -- *matched = e; -- -- if (BDB_IDL_N(tmp) >= op->o_bd->be_max_deref_depth) { -- e = NULL; -- break; -- } -- -- /* If this is part of a subtree or onelevel search, -- * have we seen this ID before? If so, quit. -- */ -- if ( visited && bdb_idl_insert( visited, e->e_id ) ) { -- e = NULL; -- break; -- } -- -- /* If we've seen this ID during this deref iteration, -- * we've hit a loop. -- */ -- if ( bdb_idl_insert( tmp, e->e_id ) ) { -- rs->sr_err = LDAP_ALIAS_PROBLEM; -- rs->sr_text = "circular alias"; -- e = NULL; -- break; -- } -- -- /* If there was a problem getting the aliasedObjectName, -- * get_alias_dn will have set the error status. -- */ -- if ( get_alias_dn(e, &ndn, &rs->sr_err, &rs->sr_text) ) { -- e = NULL; -- break; -- } -- -- rs->sr_err = bdb_dn2entry( op, txn, &ndn, &ei, -- 0, &lockr ); -- if ( rs->sr_err == DB_LOCK_DEADLOCK ) -- return NULL; -- -- if ( ei ) { -- e = ei->bei_e; -- } else { -- e = NULL; -- } -- -- if (!e) { -- rs->sr_err = LDAP_ALIAS_PROBLEM; -- rs->sr_text = "aliasedObject not found"; -- break; -- } -- -- /* Free the previous entry, continue to work with the -- * one we just retrieved. -- */ -- bdb_cache_return_entry_r( bdb, *matched, lock); -- *lock = lockr; -- -- /* We found a regular entry. Return this to the caller. The -- * entry is still locked for Read. -- */ -- if (!is_entry_alias(e)) { -- rs->sr_err = LDAP_SUCCESS; -- rs->sr_text = NULL; -- break; -- } -- } -- return e; --} -- --/* Look for and dereference all aliases within the search scope. Adds -- * the dereferenced entries to the "ids" list. Requires "stack" to be -- * able to hold 8 levels of DB_SIZE IDLs. Of course we're hardcoded to -- * require a minimum of 8 UM_SIZE IDLs so this is never a problem. -- */ --static int search_aliases( -- Operation *op, -- SlapReply *rs, -- Entry *e, -- DB_TXN *txn, -- ID *ids, -- ID *scopes, -- ID *stack ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- ID *aliases, *curscop, *subscop, *visited, *newsubs, *oldsubs, *tmp; -- ID cursora, ida, cursoro, ido, *subscop2; -- Entry *matched, *a; -- EntryInfo *ei; -- struct berval bv_alias = BER_BVC( "alias" ); -- AttributeAssertion aa_alias = ATTRIBUTEASSERTION_INIT; -- Filter af; -- DB_LOCK locka, lockr; -- int first = 1; -- -- aliases = stack; /* IDL of all aliases in the database */ -- curscop = aliases + BDB_IDL_DB_SIZE; /* Aliases in the current scope */ -- subscop = curscop + BDB_IDL_DB_SIZE; /* The current scope */ -- visited = subscop + BDB_IDL_DB_SIZE; /* IDs we've seen in this search */ -- newsubs = visited + BDB_IDL_DB_SIZE; /* New subtrees we've added */ -- oldsubs = newsubs + BDB_IDL_DB_SIZE; /* Subtrees added previously */ -- tmp = oldsubs + BDB_IDL_DB_SIZE; /* Scratch space for deref_base() */ -- -- /* A copy of subscop, because subscop gets clobbered by -- * the bdb_idl_union/intersection routines -- */ -- subscop2 = tmp + BDB_IDL_DB_SIZE; -- -- af.f_choice = LDAP_FILTER_EQUALITY; -- af.f_ava = &aa_alias; -- af.f_av_desc = slap_schema.si_ad_objectClass; -- af.f_av_value = bv_alias; -- af.f_next = NULL; -- -- /* Find all aliases in database */ -- BDB_IDL_ZERO( aliases ); -- rs->sr_err = bdb_filter_candidates( op, txn, &af, aliases, -- curscop, visited ); -- if (rs->sr_err != LDAP_SUCCESS || BDB_IDL_IS_ZERO( aliases )) { -- return rs->sr_err; -- } -- oldsubs[0] = 1; -- oldsubs[1] = e->e_id; -- -- BDB_IDL_ZERO( ids ); -- BDB_IDL_ZERO( visited ); -- BDB_IDL_ZERO( newsubs ); -- -- cursoro = 0; -- ido = bdb_idl_first( oldsubs, &cursoro ); -- -- for (;;) { -- /* Set curscop to only the aliases in the current scope. Start with -- * all the aliases, obtain the IDL for the current scope, and then -- * get the intersection of these two IDLs. Add the current scope -- * to the cumulative list of candidates. -- */ -- BDB_IDL_CPY( curscop, aliases ); -- rs->sr_err = bdb_dn2idl( op, txn, &e->e_nname, BEI(e), subscop, -- subscop2+BDB_IDL_DB_SIZE ); -- -- if (first) { -- first = 0; -- } else { -- bdb_cache_return_entry_r (bdb, e, &locka); -- } -- if ( rs->sr_err == DB_LOCK_DEADLOCK ) -- return rs->sr_err; -- -- BDB_IDL_CPY(subscop2, subscop); -- rs->sr_err = bdb_idl_intersection(curscop, subscop); -- bdb_idl_union( ids, subscop2 ); -- -- /* Dereference all of the aliases in the current scope. */ -- cursora = 0; -- for (ida = bdb_idl_first(curscop, &cursora); ida != NOID; -- ida = bdb_idl_next(curscop, &cursora)) -- { -- ei = NULL; --retry1: -- rs->sr_err = bdb_cache_find_id(op, txn, -- ida, &ei, 0, &lockr ); -- if (rs->sr_err != LDAP_SUCCESS) { -- if ( rs->sr_err == DB_LOCK_DEADLOCK ) -- return rs->sr_err; -- if ( rs->sr_err == DB_LOCK_NOTGRANTED ) -- goto retry1; -- continue; -- } -- a = ei->bei_e; -- -- /* This should only happen if the curscop IDL has maxed out and -- * turned into a range that spans IDs indiscriminately -- */ -- if (!is_entry_alias(a)) { -- bdb_cache_return_entry_r (bdb, a, &lockr); -- continue; -- } -- -- /* Actually dereference the alias */ -- BDB_IDL_ZERO(tmp); -- a = deref_base( op, rs, a, &matched, txn, &lockr, -- tmp, visited ); -- if (a) { -- /* If the target was not already in our current candidates, -- * make note of it in the newsubs list. Also -- * set it in the scopes list so that bdb_search -- * can check it. -- */ -- if (bdb_idl_insert(ids, a->e_id) == 0) { -- bdb_idl_insert(newsubs, a->e_id); -- bdb_idl_insert(scopes, a->e_id); -- } -- bdb_cache_return_entry_r( bdb, a, &lockr); -- -- } else if ( rs->sr_err == DB_LOCK_DEADLOCK ) { -- return rs->sr_err; -- } else if (matched) { -- /* Alias could not be dereferenced, or it deref'd to -- * an ID we've already seen. Ignore it. -- */ -- bdb_cache_return_entry_r( bdb, matched, &lockr ); -- rs->sr_text = NULL; -- } -- } -- /* If this is a OneLevel search, we're done; oldsubs only had one -- * ID in it. For a Subtree search, oldsubs may be a list of scope IDs. -- */ -- if ( op->ors_scope == LDAP_SCOPE_ONELEVEL ) break; --nextido: -- ido = bdb_idl_next( oldsubs, &cursoro ); -- -- /* If we're done processing the old scopes, did we add any new -- * scopes in this iteration? If so, go back and do those now. -- */ -- if (ido == NOID) { -- if (BDB_IDL_IS_ZERO(newsubs)) break; -- BDB_IDL_CPY(oldsubs, newsubs); -- BDB_IDL_ZERO(newsubs); -- cursoro = 0; -- ido = bdb_idl_first( oldsubs, &cursoro ); -- } -- -- /* Find the entry corresponding to the next scope. If it can't -- * be found, ignore it and move on. This should never happen; -- * we should never see the ID of an entry that doesn't exist. -- * Set the name so that the scope's IDL can be retrieved. -- */ -- ei = NULL; --sameido: -- rs->sr_err = bdb_cache_find_id(op, txn, ido, &ei, -- 0, &locka ); -- if ( rs->sr_err != LDAP_SUCCESS ) { -- if ( rs->sr_err == DB_LOCK_DEADLOCK ) -- return rs->sr_err; -- if ( rs->sr_err == DB_LOCK_NOTGRANTED ) -- goto sameido; -- goto nextido; -- } -- e = ei->bei_e; -- } -- return rs->sr_err; --} -- --/* Get the next ID from the DB. Used if the candidate list is -- * a range and simple iteration hits missing entryIDs -- */ --static int --bdb_get_nextid(struct bdb_info *bdb, DB_TXN *ltid, ID *cursor) --{ -- DBC *curs; -- DBT key, data; -- ID id, nid; -- int rc; -- -- id = *cursor + 1; -- BDB_ID2DISK( id, &nid ); -- rc = bdb->bi_id2entry->bdi_db->cursor( -- bdb->bi_id2entry->bdi_db, ltid, &curs, bdb->bi_db_opflags ); -- if ( rc ) -- return rc; -- key.data = &nid; -- key.size = key.ulen = sizeof(ID); -- key.flags = DB_DBT_USERMEM; -- data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; -- data.dlen = data.ulen = 0; -- rc = curs->c_get( curs, &key, &data, DB_SET_RANGE ); -- curs->c_close( curs ); -- if ( rc ) -- return rc; -- BDB_DISK2ID( &nid, cursor ); -- return 0; --} -- --int --bdb_search( Operation *op, SlapReply *rs ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- ID id, cursor; -- ID lastid = NOID; -- ID candidates[BDB_IDL_UM_SIZE]; -- ID scopes[BDB_IDL_DB_SIZE]; -- Entry *e = NULL, base, *e_root; -- Entry *matched = NULL; -- EntryInfo *ei; -- AttributeName *attrs; -- struct berval realbase = BER_BVNULL; -- slap_mask_t mask; -- time_t stoptime; -- int manageDSAit; -- int tentries = 0; -- unsigned nentries = 0; -- int idflag = 0; -- -- DB_LOCK lock; -- struct bdb_op_info *opinfo = NULL; -- DB_TXN *ltid = NULL; -- OpExtra *oex; -- -- Debug( LDAP_DEBUG_TRACE, "=> " LDAP_XSTRING(bdb_search) "\n", 0, 0, 0); -- attrs = op->oq_search.rs_attrs; -- -- LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) { -- if ( oex->oe_key == bdb ) -- break; -- } -- opinfo = (struct bdb_op_info *) oex; -- -- manageDSAit = get_manageDSAit( op ); -- -- if ( opinfo && opinfo->boi_txn ) { -- ltid = opinfo->boi_txn; -- } else { -- rs->sr_err = bdb_reader_get( op, bdb->bi_dbenv, <id ); -- -- switch(rs->sr_err) { -- case 0: -- break; -- default: -- send_ldap_error( op, rs, LDAP_OTHER, "internal error" ); -- return rs->sr_err; -- } -- } -- -- e_root = bdb->bi_cache.c_dntree.bei_e; -- if ( op->o_req_ndn.bv_len == 0 ) { -- /* DIT root special case */ -- ei = e_root->e_private; -- rs->sr_err = LDAP_SUCCESS; -- } else { -- if ( op->ors_deref & LDAP_DEREF_FINDING ) { -- BDB_IDL_ZERO(candidates); -- } --dn2entry_retry: -- /* get entry with reader lock */ -- rs->sr_err = bdb_dn2entry( op, ltid, &op->o_req_ndn, &ei, -- 1, &lock ); -- } -- -- switch(rs->sr_err) { -- case DB_NOTFOUND: -- matched = ei->bei_e; -- break; -- case 0: -- e = ei->bei_e; -- break; -- case DB_LOCK_DEADLOCK: -- if ( !opinfo ) { -- ltid->flags &= ~TXN_DEADLOCK; -- goto dn2entry_retry; -- } -- opinfo->boi_err = rs->sr_err; -- /* FALLTHRU */ -- case LDAP_BUSY: -- send_ldap_error( op, rs, LDAP_BUSY, "ldap server busy" ); -- return LDAP_BUSY; -- case DB_LOCK_NOTGRANTED: -- goto dn2entry_retry; -- default: -- send_ldap_error( op, rs, LDAP_OTHER, "internal error" ); -- return rs->sr_err; -- } -- -- if ( op->ors_deref & LDAP_DEREF_FINDING ) { -- if ( matched && is_entry_alias( matched )) { -- struct berval stub; -- -- stub.bv_val = op->o_req_ndn.bv_val; -- stub.bv_len = op->o_req_ndn.bv_len - matched->e_nname.bv_len - 1; -- e = deref_base( op, rs, matched, &matched, ltid, &lock, -- candidates, NULL ); -- if ( e ) { -- build_new_dn( &op->o_req_ndn, &e->e_nname, &stub, -- op->o_tmpmemctx ); -- bdb_cache_return_entry_r (bdb, e, &lock); -- matched = NULL; -- goto dn2entry_retry; -- } -- } else if ( e && is_entry_alias( e )) { -- e = deref_base( op, rs, e, &matched, ltid, &lock, -- candidates, NULL ); -- } -- } -- -- if ( e == NULL ) { -- struct berval matched_dn = BER_BVNULL; -- -- if ( matched != NULL ) { -- BerVarray erefs = NULL; -- -- /* return referral only if "disclose" -- * is granted on the object */ -- if ( ! access_allowed( op, matched, -- slap_schema.si_ad_entry, -- NULL, ACL_DISCLOSE, NULL ) ) -- { -- rs->sr_err = LDAP_NO_SUCH_OBJECT; -- -- } else { -- ber_dupbv( &matched_dn, &matched->e_name ); -- -- erefs = is_entry_referral( matched ) -- ? get_entry_referrals( op, matched ) -- : NULL; -- if ( rs->sr_err == DB_NOTFOUND ) -- rs->sr_err = LDAP_REFERRAL; -- rs->sr_matched = matched_dn.bv_val; -- } -- --#ifdef SLAP_ZONE_ALLOC -- slap_zn_runlock(bdb->bi_cache.c_zctx, matched); --#endif -- bdb_cache_return_entry_r (bdb, matched, &lock); -- matched = NULL; -- -- if ( erefs ) { -- rs->sr_ref = referral_rewrite( erefs, &matched_dn, -- &op->o_req_dn, op->oq_search.rs_scope ); -- ber_bvarray_free( erefs ); -- } -- -- } else { --#ifdef SLAP_ZONE_ALLOC -- slap_zn_runlock(bdb->bi_cache.c_zctx, matched); --#endif -- rs->sr_ref = referral_rewrite( default_referral, -- NULL, &op->o_req_dn, op->oq_search.rs_scope ); -- rs->sr_err = rs->sr_ref != NULL ? LDAP_REFERRAL : LDAP_NO_SUCH_OBJECT; -- } -- -- send_ldap_result( op, rs ); -- -- if ( rs->sr_ref ) { -- ber_bvarray_free( rs->sr_ref ); -- rs->sr_ref = NULL; -- } -- if ( !BER_BVISNULL( &matched_dn ) ) { -- ber_memfree( matched_dn.bv_val ); -- rs->sr_matched = NULL; -- } -- return rs->sr_err; -- } -- -- /* NOTE: __NEW__ "search" access is required -- * on searchBase object */ -- if ( ! access_allowed_mask( op, e, slap_schema.si_ad_entry, -- NULL, ACL_SEARCH, NULL, &mask ) ) -- { -- if ( !ACL_GRANT( mask, ACL_DISCLOSE ) ) { -- rs->sr_err = LDAP_NO_SUCH_OBJECT; -- } else { -- rs->sr_err = LDAP_INSUFFICIENT_ACCESS; -- } -- --#ifdef SLAP_ZONE_ALLOC -- slap_zn_runlock(bdb->bi_cache.c_zctx, e); --#endif -- if ( e != e_root ) { -- bdb_cache_return_entry_r(bdb, e, &lock); -- } -- send_ldap_result( op, rs ); -- return rs->sr_err; -- } -- -- if ( !manageDSAit && e != e_root && is_entry_referral( e ) ) { -- /* entry is a referral, don't allow add */ -- struct berval matched_dn = BER_BVNULL; -- BerVarray erefs = NULL; -- -- ber_dupbv( &matched_dn, &e->e_name ); -- erefs = get_entry_referrals( op, e ); -- -- rs->sr_err = LDAP_REFERRAL; -- --#ifdef SLAP_ZONE_ALLOC -- slap_zn_runlock(bdb->bi_cache.c_zctx, e); --#endif -- bdb_cache_return_entry_r( bdb, e, &lock ); -- e = NULL; -- -- if ( erefs ) { -- rs->sr_ref = referral_rewrite( erefs, &matched_dn, -- &op->o_req_dn, op->oq_search.rs_scope ); -- ber_bvarray_free( erefs ); -- -- if ( !rs->sr_ref ) { -- rs->sr_text = "bad_referral object"; -- } -- } -- -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_search) ": entry is referral\n", -- 0, 0, 0 ); -- -- rs->sr_matched = matched_dn.bv_val; -- send_ldap_result( op, rs ); -- -- ber_bvarray_free( rs->sr_ref ); -- rs->sr_ref = NULL; -- ber_memfree( matched_dn.bv_val ); -- rs->sr_matched = NULL; -- return 1; -- } -- -- if ( get_assert( op ) && -- ( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE )) -- { -- rs->sr_err = LDAP_ASSERTION_FAILED; --#ifdef SLAP_ZONE_ALLOC -- slap_zn_runlock(bdb->bi_cache.c_zctx, e); --#endif -- if ( e != e_root ) { -- bdb_cache_return_entry_r(bdb, e, &lock); -- } -- send_ldap_result( op, rs ); -- return 1; -- } -- -- /* compute it anyway; root does not use it */ -- stoptime = op->o_time + op->ors_tlimit; -- -- /* need normalized dn below */ -- ber_dupbv( &realbase, &e->e_nname ); -- -- /* Copy info to base, must free entry before accessing the database -- * in search_candidates, to avoid deadlocks. -- */ -- base.e_private = e->e_private; -- base.e_nname = realbase; -- base.e_id = e->e_id; -- --#ifdef SLAP_ZONE_ALLOC -- slap_zn_runlock(bdb->bi_cache.c_zctx, e); --#endif -- if ( e != e_root ) { -- bdb_cache_return_entry_r(bdb, e, &lock); -- } -- e = NULL; -- -- /* select candidates */ -- if ( op->oq_search.rs_scope == LDAP_SCOPE_BASE ) { -- rs->sr_err = base_candidate( op->o_bd, &base, candidates ); -- -- } else { --cand_retry: -- BDB_IDL_ZERO( candidates ); -- BDB_IDL_ZERO( scopes ); -- rs->sr_err = search_candidates( op, rs, &base, -- ltid, candidates, scopes ); -- if ( rs->sr_err == DB_LOCK_DEADLOCK ) { -- if ( !opinfo ) { -- ltid->flags &= ~TXN_DEADLOCK; -- goto cand_retry; -- } -- opinfo->boi_err = rs->sr_err; -- send_ldap_error( op, rs, LDAP_BUSY, "ldap server busy" ); -- return LDAP_BUSY; -- } -- } -- -- /* start cursor at beginning of candidates. -- */ -- cursor = 0; -- -- if ( candidates[0] == 0 ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_search) ": no candidates\n", -- 0, 0, 0 ); -- -- goto nochange; -- } -- -- /* if not root and candidates exceed to-be-checked entries, abort */ -- if ( op->ors_limit /* isroot == FALSE */ && -- op->ors_limit->lms_s_unchecked != -1 && -- BDB_IDL_N(candidates) > (unsigned) op->ors_limit->lms_s_unchecked ) -- { -- rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; -- send_ldap_result( op, rs ); -- rs->sr_err = LDAP_SUCCESS; -- goto done; -- } -- -- if ( op->ors_limit == NULL /* isroot == TRUE */ || -- !op->ors_limit->lms_s_pr_hide ) -- { -- tentries = BDB_IDL_N(candidates); -- } -- -- if ( get_pagedresults( op ) > SLAP_CONTROL_IGNORED ) { -- PagedResultsState *ps = op->o_pagedresults_state; -- /* deferred cookie parsing */ -- rs->sr_err = parse_paged_cookie( op, rs ); -- if ( rs->sr_err != LDAP_SUCCESS ) { -- send_ldap_result( op, rs ); -- goto done; -- } -- -- cursor = (ID) ps->ps_cookie; -- if ( cursor && ps->ps_size == 0 ) { -- rs->sr_err = LDAP_SUCCESS; -- rs->sr_text = "search abandoned by pagedResult size=0"; -- send_ldap_result( op, rs ); -- goto done; -- } -- id = bdb_idl_first( candidates, &cursor ); -- if ( id == NOID ) { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_search) -- ": no paged results candidates\n", -- 0, 0, 0 ); -- send_paged_response( op, rs, &lastid, 0 ); -- -- rs->sr_err = LDAP_OTHER; -- goto done; -- } -- nentries = ps->ps_count; -- if ( id == (ID)ps->ps_cookie ) -- id = bdb_idl_next( candidates, &cursor ); -- goto loop_begin; -- } -- -- for ( id = bdb_idl_first( candidates, &cursor ); -- id != NOID ; id = bdb_idl_next( candidates, &cursor ) ) -- { -- int scopeok; -- --loop_begin: -- -- /* check for abandon */ -- if ( op->o_abandon ) { -- rs->sr_err = SLAPD_ABANDON; -- send_ldap_result( op, rs ); -- goto done; -- } -- -- /* mostly needed by internal searches, -- * e.g. related to syncrepl, for whom -- * abandon does not get set... */ -- if ( slapd_shutdown ) { -- rs->sr_err = LDAP_UNAVAILABLE; -- send_ldap_disconnect( op, rs ); -- goto done; -- } -- -- /* check time limit */ -- if ( op->ors_tlimit != SLAP_NO_LIMIT -- && slap_get_time() > stoptime ) -- { -- rs->sr_err = LDAP_TIMELIMIT_EXCEEDED; -- rs->sr_ref = rs->sr_v2ref; -- send_ldap_result( op, rs ); -- rs->sr_err = LDAP_SUCCESS; -- goto done; -- } -- -- /* If we inspect more entries than will -- * fit into the entry cache, stop caching -- * any subsequent entries -- */ -- nentries++; -- if ( nentries > bdb->bi_cache.c_maxsize && !idflag ) { -- idflag = ID_NOCACHE; -- } -- --fetch_entry_retry: -- /* get the entry with reader lock */ -- ei = NULL; -- rs->sr_err = bdb_cache_find_id( op, ltid, -- id, &ei, idflag, &lock ); -- -- if (rs->sr_err == LDAP_BUSY) { -- rs->sr_text = "ldap server busy"; -- send_ldap_result( op, rs ); -- goto done; -- -- } else if ( rs->sr_err == DB_LOCK_DEADLOCK ) { -- if ( !opinfo ) { -- ltid->flags &= ~TXN_DEADLOCK; -- goto fetch_entry_retry; -- } --txnfail: -- opinfo->boi_err = rs->sr_err; -- send_ldap_error( op, rs, LDAP_BUSY, "ldap server busy" ); -- goto done; -- -- } else if ( rs->sr_err == DB_LOCK_NOTGRANTED ) -- { -- goto fetch_entry_retry; -- } else if ( rs->sr_err == LDAP_OTHER ) { -- rs->sr_text = "internal error"; -- send_ldap_result( op, rs ); -- goto done; -- } -- -- if ( ei && rs->sr_err == LDAP_SUCCESS ) { -- e = ei->bei_e; -- } else { -- e = NULL; -- } -- -- if ( e == NULL ) { -- if( !BDB_IDL_IS_RANGE(candidates) ) { -- /* only complain for non-range IDLs */ -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_search) -- ": candidate %ld not found\n", -- (long) id, 0, 0 ); -- } else { -- /* get the next ID from the DB */ --id_retry: -- rs->sr_err = bdb_get_nextid( bdb, ltid, &cursor ); -- if ( rs->sr_err == DB_NOTFOUND ) { -- break; -- } else if ( rs->sr_err == DB_LOCK_DEADLOCK ) { -- if ( opinfo ) -- goto txnfail; -- ltid->flags &= ~TXN_DEADLOCK; -- goto id_retry; -- } else if ( rs->sr_err == DB_LOCK_NOTGRANTED ) { -- goto id_retry; -- } -- if ( rs->sr_err ) { -- rs->sr_err = LDAP_OTHER; -- rs->sr_text = "internal error in get_nextid"; -- send_ldap_result( op, rs ); -- goto done; -- } -- cursor--; -- } -- -- goto loop_continue; -- } -- -- if ( is_entry_subentry( e ) ) { -- if( op->oq_search.rs_scope != LDAP_SCOPE_BASE ) { -- if(!get_subentries_visibility( op )) { -- /* only subentries are visible */ -- goto loop_continue; -- } -- -- } else if ( get_subentries( op ) && -- !get_subentries_visibility( op )) -- { -- /* only subentries are visible */ -- goto loop_continue; -- } -- -- } else if ( get_subentries_visibility( op )) { -- /* only subentries are visible */ -- goto loop_continue; -- } -- -- /* Does this candidate actually satisfy the search scope? -- * -- * Note that we don't lock access to the bei_parent pointer. -- * Since only leaf nodes can be deleted, the parent of any -- * node will always be a valid node. Also since we have -- * a Read lock on the data, it cannot be renamed out of the -- * scope while we are looking at it, and unless we're using -- * BDB_HIER, its parents cannot be moved either. -- */ -- scopeok = 0; -- switch( op->ors_scope ) { -- case LDAP_SCOPE_BASE: -- /* This is always true, yes? */ -- if ( id == base.e_id ) scopeok = 1; -- break; -- -- case LDAP_SCOPE_ONELEVEL: -- if ( ei->bei_parent->bei_id == base.e_id ) scopeok = 1; -- break; -- --#ifdef LDAP_SCOPE_CHILDREN -- case LDAP_SCOPE_CHILDREN: -- if ( id == base.e_id ) break; -- /* Fall-thru */ --#endif -- case LDAP_SCOPE_SUBTREE: { -- EntryInfo *tmp; -- for ( tmp = BEI(e); tmp; tmp = tmp->bei_parent ) { -- if ( tmp->bei_id == base.e_id ) { -- scopeok = 1; -- break; -- } -- } -- } break; -- } -- -- /* aliases were already dereferenced in candidate list */ -- if ( op->ors_deref & LDAP_DEREF_SEARCHING ) { -- /* but if the search base is an alias, and we didn't -- * deref it when finding, return it. -- */ -- if ( is_entry_alias(e) && -- ((op->ors_deref & LDAP_DEREF_FINDING) || -- !bvmatch(&e->e_nname, &op->o_req_ndn))) -- { -- goto loop_continue; -- } -- -- /* scopes is only non-empty for onelevel or subtree */ -- if ( !scopeok && BDB_IDL_N(scopes) ) { -- unsigned x; -- if ( op->ors_scope == LDAP_SCOPE_ONELEVEL ) { -- x = bdb_idl_search( scopes, e->e_id ); -- if ( scopes[x] == e->e_id ) scopeok = 1; -- } else { -- /* subtree, walk up the tree */ -- EntryInfo *tmp = BEI(e); -- for (;tmp->bei_parent; tmp=tmp->bei_parent) { -- x = bdb_idl_search( scopes, tmp->bei_id ); -- if ( scopes[x] == tmp->bei_id ) { -- scopeok = 1; -- break; -- } -- } -- } -- } -- } -- -- /* Not in scope, ignore it */ -- if ( !scopeok ) -- { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_search) -- ": %ld scope not okay\n", -- (long) id, 0, 0 ); -- goto loop_continue; -- } -- -- /* -- * 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 && op->oq_search.rs_scope != LDAP_SCOPE_BASE -- && is_entry_referral( e ) ) -- { -- struct bdb_op_info bois; -- struct bdb_lock_info blis; -- BerVarray erefs = get_entry_referrals( op, e ); -- rs->sr_ref = referral_rewrite( erefs, &e->e_name, NULL, -- op->oq_search.rs_scope == LDAP_SCOPE_ONELEVEL -- ? LDAP_SCOPE_BASE : LDAP_SCOPE_SUBTREE ); -- -- /* Must set lockinfo so that entry_release will work */ -- if (!opinfo) { -- bois.boi_oe.oe_key = bdb; -- bois.boi_txn = NULL; -- bois.boi_err = 0; -- bois.boi_acl_cache = op->o_do_not_cache; -- bois.boi_flag = BOI_DONTFREE; -- bois.boi_locks = &blis; -- blis.bli_next = NULL; -- LDAP_SLIST_INSERT_HEAD( &op->o_extra, &bois.boi_oe, -- oe_next ); -- } else { -- blis.bli_next = opinfo->boi_locks; -- opinfo->boi_locks = &blis; -- } -- blis.bli_id = e->e_id; -- blis.bli_lock = lock; -- blis.bli_flag = BLI_DONTFREE; -- -- rs->sr_entry = e; -- rs->sr_flags = REP_ENTRY_MUSTRELEASE; -- -- send_search_reference( op, rs ); -- -- if ( blis.bli_flag ) { --#ifdef SLAP_ZONE_ALLOC -- slap_zn_runlock(bdb->bi_cache.c_zctx, e); --#endif -- bdb_cache_return_entry_r(bdb, e, &lock); -- if ( opinfo ) { -- opinfo->boi_locks = blis.bli_next; -- } else { -- LDAP_SLIST_REMOVE( &op->o_extra, &bois.boi_oe, -- OpExtra, oe_next ); -- } -- } -- rs->sr_entry = NULL; -- e = NULL; -- -- ber_bvarray_free( rs->sr_ref ); -- ber_bvarray_free( erefs ); -- rs->sr_ref = NULL; -- -- goto loop_continue; -- } -- -- if ( !manageDSAit && is_entry_glue( e )) { -- goto loop_continue; -- } -- -- /* if it matches the filter and scope, send it */ -- rs->sr_err = test_filter( op, e, op->oq_search.rs_filter ); -- -- if ( rs->sr_err == LDAP_COMPARE_TRUE ) { -- /* check size limit */ -- if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) { -- if ( rs->sr_nentries >= ((PagedResultsState *)op->o_pagedresults_state)->ps_size ) { --#ifdef SLAP_ZONE_ALLOC -- slap_zn_runlock(bdb->bi_cache.c_zctx, e); --#endif -- bdb_cache_return_entry_r( bdb, e, &lock ); -- e = NULL; -- send_paged_response( op, rs, &lastid, tentries ); -- goto done; -- } -- lastid = id; -- } -- -- if (e) { -- struct bdb_op_info bois; -- struct bdb_lock_info blis; -- -- /* Must set lockinfo so that entry_release will work */ -- if (!opinfo) { -- bois.boi_oe.oe_key = bdb; -- bois.boi_txn = NULL; -- bois.boi_err = 0; -- bois.boi_acl_cache = op->o_do_not_cache; -- bois.boi_flag = BOI_DONTFREE; -- bois.boi_locks = &blis; -- blis.bli_next = NULL; -- LDAP_SLIST_INSERT_HEAD( &op->o_extra, &bois.boi_oe, -- oe_next ); -- } else { -- blis.bli_next = opinfo->boi_locks; -- opinfo->boi_locks = &blis; -- } -- blis.bli_id = e->e_id; -- blis.bli_lock = lock; -- blis.bli_flag = BLI_DONTFREE; -- -- /* safe default */ -- rs->sr_attrs = op->oq_search.rs_attrs; -- rs->sr_operational_attrs = NULL; -- rs->sr_ctrls = NULL; -- rs->sr_entry = e; -- RS_ASSERT( e->e_private != NULL ); -- rs->sr_flags = REP_ENTRY_MUSTRELEASE; -- rs->sr_err = LDAP_SUCCESS; -- rs->sr_err = send_search_entry( op, rs ); -- rs->sr_attrs = NULL; -- rs->sr_entry = NULL; -- -- /* send_search_entry will usually free it. -- * an overlay might leave its own copy here; -- * bli_flag will be 0 if lock was already released. -- */ -- if ( blis.bli_flag ) { --#ifdef SLAP_ZONE_ALLOC -- slap_zn_runlock(bdb->bi_cache.c_zctx, e); --#endif -- bdb_cache_return_entry_r(bdb, e, &lock); -- if ( opinfo ) { -- opinfo->boi_locks = blis.bli_next; -- } else { -- LDAP_SLIST_REMOVE( &op->o_extra, &bois.boi_oe, -- OpExtra, oe_next ); -- } -- } -- e = NULL; -- -- switch ( rs->sr_err ) { -- case LDAP_SUCCESS: /* entry sent ok */ -- break; -- default: /* entry not sent */ -- break; -- case LDAP_BUSY: -- send_ldap_result( op, rs ); -- goto done; -- case LDAP_UNAVAILABLE: -- case LDAP_SIZELIMIT_EXCEEDED: -- if ( rs->sr_err == LDAP_SIZELIMIT_EXCEEDED ) { -- rs->sr_ref = rs->sr_v2ref; -- send_ldap_result( op, rs ); -- rs->sr_err = LDAP_SUCCESS; -- -- } else { -- rs->sr_err = LDAP_OTHER; -- } -- goto done; -- } -- } -- -- } else { -- Debug( LDAP_DEBUG_TRACE, -- LDAP_XSTRING(bdb_search) -- ": %ld does not match filter\n", -- (long) id, 0, 0 ); -- } -- --loop_continue: -- if( e != NULL ) { -- /* free reader lock */ --#ifdef SLAP_ZONE_ALLOC -- slap_zn_runlock(bdb->bi_cache.c_zctx, e); --#endif -- bdb_cache_return_entry_r( bdb, e , &lock ); -- RS_ASSERT( rs->sr_entry == NULL ); -- e = NULL; -- rs->sr_entry = NULL; -- } -- } -- --nochange: -- rs->sr_ctrls = NULL; -- rs->sr_ref = rs->sr_v2ref; -- rs->sr_err = (rs->sr_v2ref == NULL) ? LDAP_SUCCESS : LDAP_REFERRAL; -- rs->sr_rspoid = NULL; -- if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) { -- send_paged_response( op, rs, NULL, 0 ); -- } else { -- send_ldap_result( op, rs ); -- } -- -- rs->sr_err = LDAP_SUCCESS; -- --done: -- if( rs->sr_v2ref ) { -- ber_bvarray_free( rs->sr_v2ref ); -- rs->sr_v2ref = NULL; -- } -- if( realbase.bv_val ) ch_free( realbase.bv_val ); -- -- return rs->sr_err; --} -- -- --static int base_candidate( -- BackendDB *be, -- Entry *e, -- ID *ids ) --{ -- Debug(LDAP_DEBUG_ARGS, "base_candidates: base: \"%s\" (0x%08lx)\n", -- e->e_nname.bv_val, (long) e->e_id, 0); -- -- ids[0] = 1; -- ids[1] = e->e_id; -- return 0; --} -- --/* Look for "objectClass Present" in this filter. -- * Also count depth of filter tree while we're at it. -- */ --static int oc_filter( -- Filter *f, -- int cur, -- int *max ) --{ -- int rc = 0; -- -- assert( f != NULL ); -- -- if( cur > *max ) *max = cur; -- -- switch( f->f_choice ) { -- case LDAP_FILTER_PRESENT: -- if (f->f_desc == slap_schema.si_ad_objectClass) { -- rc = 1; -- } -- break; -- -- case LDAP_FILTER_AND: -- case LDAP_FILTER_OR: -- cur++; -- for ( f=f->f_and; f; f=f->f_next ) { -- (void) oc_filter(f, cur, max); -- } -- break; -- -- default: -- break; -- } -- return rc; --} -- --static void search_stack_free( void *key, void *data ) --{ -- ber_memfree_x(data, NULL); --} -- --static void *search_stack( Operation *op ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- void *ret = NULL; -- -- if ( op->o_threadctx ) { -- ldap_pvt_thread_pool_getkey( op->o_threadctx, (void *)search_stack, -- &ret, NULL ); -- } else { -- ret = bdb->bi_search_stack; -- } -- -- if ( !ret ) { -- ret = ch_malloc( bdb->bi_search_stack_depth * BDB_IDL_UM_SIZE -- * sizeof( ID ) ); -- if ( op->o_threadctx ) { -- ldap_pvt_thread_pool_setkey( op->o_threadctx, (void *)search_stack, -- ret, search_stack_free, NULL, NULL ); -- } else { -- bdb->bi_search_stack = ret; -- } -- } -- return ret; --} -- --static int search_candidates( -- Operation *op, -- SlapReply *rs, -- Entry *e, -- DB_TXN *txn, -- ID *ids, -- ID *scopes ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- int rc, depth = 1; -- Filter f, rf, xf, nf; -- ID *stack; -- AttributeAssertion aa_ref = ATTRIBUTEASSERTION_INIT; -- Filter sf; -- AttributeAssertion aa_subentry = ATTRIBUTEASSERTION_INIT; -- -- /* -- * This routine takes as input a filter (user-filter) -- * and rewrites it as follows: -- * (&(scope=DN)[(objectClass=subentry)] -- * (|[(objectClass=referral)(objectClass=alias)](user-filter)) -- */ -- -- Debug(LDAP_DEBUG_TRACE, -- "search_candidates: base=\"%s\" (0x%08lx) scope=%d\n", -- e->e_nname.bv_val, (long) e->e_id, op->oq_search.rs_scope ); -- -- xf.f_or = op->oq_search.rs_filter; -- xf.f_choice = LDAP_FILTER_OR; -- xf.f_next = NULL; -- -- /* If the user's filter uses objectClass=*, -- * these clauses are redundant. -- */ -- if (!oc_filter(op->oq_search.rs_filter, 1, &depth) -- && !get_subentries_visibility(op)) { -- if( !get_manageDSAit(op) && !get_domainScope(op) ) { -- /* match referral objects */ -- struct berval bv_ref = BER_BVC( "referral" ); -- rf.f_choice = LDAP_FILTER_EQUALITY; -- rf.f_ava = &aa_ref; -- rf.f_av_desc = slap_schema.si_ad_objectClass; -- rf.f_av_value = bv_ref; -- rf.f_next = xf.f_or; -- xf.f_or = &rf; -- depth++; -- } -- } -- -- f.f_next = NULL; -- f.f_choice = LDAP_FILTER_AND; -- f.f_and = &nf; -- /* Dummy; we compute scope separately now */ -- nf.f_choice = SLAPD_FILTER_COMPUTED; -- nf.f_result = LDAP_SUCCESS; -- nf.f_next = ( xf.f_or == op->oq_search.rs_filter ) -- ? op->oq_search.rs_filter : &xf ; -- /* Filter depth increased again, adding dummy clause */ -- depth++; -- -- if( get_subentries_visibility( op ) ) { -- struct berval bv_subentry = BER_BVC( "subentry" ); -- sf.f_choice = LDAP_FILTER_EQUALITY; -- sf.f_ava = &aa_subentry; -- sf.f_av_desc = slap_schema.si_ad_objectClass; -- sf.f_av_value = bv_subentry; -- sf.f_next = nf.f_next; -- nf.f_next = &sf; -- } -- -- /* Allocate IDL stack, plus 1 more for former tmp */ -- if ( depth+1 > bdb->bi_search_stack_depth ) { -- stack = ch_malloc( (depth + 1) * BDB_IDL_UM_SIZE * sizeof( ID ) ); -- } else { -- stack = search_stack( op ); -- } -- -- if( op->ors_deref & LDAP_DEREF_SEARCHING ) { -- rc = search_aliases( op, rs, e, txn, ids, scopes, stack ); -- if ( BDB_IDL_IS_ZERO( ids ) && rc == LDAP_SUCCESS ) -- rc = bdb_dn2idl( op, txn, &e->e_nname, BEI(e), ids, stack ); -- } else { -- rc = bdb_dn2idl( op, txn, &e->e_nname, BEI(e), ids, stack ); -- } -- -- if ( rc == LDAP_SUCCESS ) { -- rc = bdb_filter_candidates( op, txn, &f, ids, -- stack, stack+BDB_IDL_UM_SIZE ); -- } -- -- if ( depth+1 > bdb->bi_search_stack_depth ) { -- ch_free( stack ); -- } -- -- if( rc ) { -- Debug(LDAP_DEBUG_TRACE, -- "bdb_search_candidates: failed (rc=%d)\n", -- rc, NULL, NULL ); -- -- } else { -- Debug(LDAP_DEBUG_TRACE, -- "bdb_search_candidates: id=%ld first=%ld last=%ld\n", -- (long) ids[0], -- (long) BDB_IDL_FIRST(ids), -- (long) BDB_IDL_LAST(ids) ); -- } -- -- return rc; --} -- --static int --parse_paged_cookie( Operation *op, SlapReply *rs ) --{ -- int rc = LDAP_SUCCESS; -- PagedResultsState *ps = op->o_pagedresults_state; -- -- /* this function must be invoked only if the pagedResults -- * control has been detected, parsed and partially checked -- * by the frontend */ -- assert( get_pagedresults( op ) > SLAP_CONTROL_IGNORED ); -- -- /* cookie decoding/checks deferred to backend... */ -- if ( ps->ps_cookieval.bv_len ) { -- PagedResultsCookie reqcookie; -- if( ps->ps_cookieval.bv_len != sizeof( reqcookie ) ) { -- /* bad cookie */ -- rs->sr_text = "paged results cookie is invalid"; -- rc = LDAP_PROTOCOL_ERROR; -- goto done; -- } -- -- AC_MEMCPY( &reqcookie, ps->ps_cookieval.bv_val, sizeof( reqcookie )); -- -- if ( reqcookie > ps->ps_cookie ) { -- /* bad cookie */ -- rs->sr_text = "paged results cookie is invalid"; -- rc = LDAP_PROTOCOL_ERROR; -- goto done; -- -- } else if ( reqcookie < ps->ps_cookie ) { -- rs->sr_text = "paged results cookie is invalid or old"; -- rc = LDAP_UNWILLING_TO_PERFORM; -- goto done; -- } -- -- } else { -- /* we're going to use ps_cookie */ -- op->o_conn->c_pagedresults_state.ps_cookie = 0; -- } -- --done:; -- -- return rc; --} -- --static void --send_paged_response( -- Operation *op, -- SlapReply *rs, -- ID *lastid, -- int tentries ) --{ -- LDAPControl *ctrls[2]; -- BerElementBuffer berbuf; -- BerElement *ber = (BerElement *)&berbuf; -- PagedResultsCookie respcookie; -- struct berval cookie; -- -- Debug(LDAP_DEBUG_ARGS, -- "send_paged_response: lastid=0x%08lx nentries=%d\n", -- lastid ? *lastid : 0, rs->sr_nentries, NULL ); -- -- ctrls[1] = NULL; -- -- ber_init2( ber, NULL, LBER_USE_DER ); -- -- if ( lastid ) { -- respcookie = ( PagedResultsCookie )(*lastid); -- cookie.bv_len = sizeof( respcookie ); -- cookie.bv_val = (char *)&respcookie; -- -- } else { -- respcookie = ( PagedResultsCookie )0; -- BER_BVSTR( &cookie, "" ); -- } -- -- op->o_conn->c_pagedresults_state.ps_cookie = respcookie; -- op->o_conn->c_pagedresults_state.ps_count = -- ((PagedResultsState *)op->o_pagedresults_state)->ps_count + -- rs->sr_nentries; -- -- /* return size of 0 -- no estimate */ -- ber_printf( ber, "{iO}", 0, &cookie ); -- -- ctrls[0] = op->o_tmpalloc( sizeof(LDAPControl), op->o_tmpmemctx ); -- if ( ber_flatten2( ber, &ctrls[0]->ldctl_value, 0 ) == -1 ) { -- goto done; -- } -- -- ctrls[0]->ldctl_oid = LDAP_CONTROL_PAGEDRESULTS; -- ctrls[0]->ldctl_iscritical = 0; -- -- slap_add_ctrls( op, rs, ctrls ); -- rs->sr_err = LDAP_SUCCESS; -- send_ldap_result( op, rs ); -- --done: -- (void) ber_free_buf( ber ); --} -diff --git a/servers/slapd/back-bdb/tools.c b/servers/slapd/back-bdb/tools.c -deleted file mode 100644 -index 1882ef2..0000000 ---- a/servers/slapd/back-bdb/tools.c -+++ /dev/null -@@ -1,1327 +0,0 @@ --/* tools.c - tools for slap tools */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include --#include --#include -- --#define AVL_INTERNAL --#include "back-bdb.h" --#include "idl.h" -- --static DBC *cursor = NULL; --static DBT key, data; --static EntryHeader eh; --static ID nid, previd = NOID; --static char ehbuf[16]; -- --typedef struct dn_id { -- ID id; -- struct berval dn; --} dn_id; -- --#define HOLE_SIZE 4096 --static dn_id hbuf[HOLE_SIZE], *holes = hbuf; --static unsigned nhmax = HOLE_SIZE; --static unsigned nholes; -- --static int index_nattrs; -- --static struct berval *tool_base; --static int tool_scope; --static Filter *tool_filter; --static Entry *tool_next_entry; -- --#ifdef BDB_TOOL_IDL_CACHING --#define bdb_tool_idl_cmp BDB_SYMBOL(tool_idl_cmp) --#define bdb_tool_idl_flush_one BDB_SYMBOL(tool_idl_flush_one) --#define bdb_tool_idl_flush BDB_SYMBOL(tool_idl_flush) -- --static int bdb_tool_idl_flush( BackendDB *be ); -- --#define IDBLOCK 1024 -- --typedef struct bdb_tool_idl_cache_entry { -- struct bdb_tool_idl_cache_entry *next; -- ID ids[IDBLOCK]; --} bdb_tool_idl_cache_entry; -- --typedef struct bdb_tool_idl_cache { -- struct berval kstr; -- bdb_tool_idl_cache_entry *head, *tail; -- ID first, last; -- int count; --} bdb_tool_idl_cache; -- --static bdb_tool_idl_cache_entry *bdb_tool_idl_free_list; --#endif /* BDB_TOOL_IDL_CACHING */ -- --static ID bdb_tool_ix_id; --static Operation *bdb_tool_ix_op; --static int *bdb_tool_index_threads, bdb_tool_index_tcount; --static void *bdb_tool_index_rec; --static struct bdb_info *bdb_tool_info; --static ldap_pvt_thread_mutex_t bdb_tool_index_mutex; --static ldap_pvt_thread_cond_t bdb_tool_index_cond_main; --static ldap_pvt_thread_cond_t bdb_tool_index_cond_work; -- --#if DB_VERSION_FULL >= 0x04060000 --#define USE_TRICKLE 1 --#else --/* Seems to slow things down too much in BDB 4.5 */ --#undef USE_TRICKLE --#endif -- --#ifdef USE_TRICKLE --static ldap_pvt_thread_mutex_t bdb_tool_trickle_mutex; --static ldap_pvt_thread_cond_t bdb_tool_trickle_cond; --static ldap_pvt_thread_cond_t bdb_tool_trickle_cond_end; -- --static void * bdb_tool_trickle_task( void *ctx, void *ptr ); --static int bdb_tool_trickle_active; --#endif -- --static void * bdb_tool_index_task( void *ctx, void *ptr ); -- --static int --bdb_tool_entry_get_int( BackendDB *be, ID id, Entry **ep ); -- --static int bdb_tool_threads; -- --int bdb_tool_entry_open( -- BackendDB *be, int mode ) --{ -- struct bdb_info *bdb = (struct bdb_info *) be->be_private; -- -- /* initialize key and data thangs */ -- DBTzero( &key ); -- DBTzero( &data ); -- key.flags = DB_DBT_USERMEM; -- key.data = &nid; -- key.size = key.ulen = sizeof( nid ); -- data.flags = DB_DBT_USERMEM; -- -- if (cursor == NULL) { -- int rc = bdb->bi_id2entry->bdi_db->cursor( -- bdb->bi_id2entry->bdi_db, bdb->bi_cache.c_txn, &cursor, -- bdb->bi_db_opflags ); -- if( rc != 0 ) { -- return -1; -- } -- } -- -- /* Set up for threaded slapindex */ -- if (( slapMode & (SLAP_TOOL_QUICK|SLAP_TOOL_READONLY)) == SLAP_TOOL_QUICK ) { -- if ( !bdb_tool_info ) { --#ifdef USE_TRICKLE -- ldap_pvt_thread_mutex_init( &bdb_tool_trickle_mutex ); -- ldap_pvt_thread_cond_init( &bdb_tool_trickle_cond ); -- ldap_pvt_thread_cond_init( &bdb_tool_trickle_cond_end ); -- ldap_pvt_thread_pool_submit( &connection_pool, bdb_tool_trickle_task, bdb->bi_dbenv ); --#endif -- -- ldap_pvt_thread_mutex_init( &bdb_tool_index_mutex ); -- ldap_pvt_thread_cond_init( &bdb_tool_index_cond_main ); -- ldap_pvt_thread_cond_init( &bdb_tool_index_cond_work ); -- if ( bdb->bi_nattrs ) { -- int i; -- bdb_tool_threads = slap_tool_thread_max - 1; -- if ( bdb_tool_threads > 1 ) { -- bdb_tool_index_threads = ch_malloc( bdb_tool_threads * sizeof( int )); -- bdb_tool_index_rec = ch_malloc( bdb->bi_nattrs * sizeof( IndexRec )); -- bdb_tool_index_tcount = bdb_tool_threads - 1; -- for (i=1; i 1 ) { -- ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex ); -- -- /* There might still be some threads starting */ -- while ( bdb_tool_index_tcount > 0 ) { -- ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main, -- &bdb_tool_index_mutex ); -- } -- -- bdb_tool_index_tcount = bdb_tool_threads - 1; -- ldap_pvt_thread_cond_broadcast( &bdb_tool_index_cond_work ); -- -- /* Make sure all threads are stopped */ -- while ( bdb_tool_index_tcount > 0 ) { -- ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main, -- &bdb_tool_index_mutex ); -- } -- ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex ); -- -- ch_free( bdb_tool_index_threads ); -- ch_free( bdb_tool_index_rec ); -- bdb_tool_index_tcount = bdb_tool_threads - 1; -- } -- bdb_tool_info = NULL; -- slapd_shutdown = 0; -- } -- -- if( eh.bv.bv_val ) { -- ch_free( eh.bv.bv_val ); -- eh.bv.bv_val = NULL; -- } -- -- if( cursor ) { -- cursor->c_close( cursor ); -- cursor = NULL; -- } -- --#ifdef BDB_TOOL_IDL_CACHING -- bdb_tool_idl_flush( be ); --#endif -- -- if( nholes ) { -- unsigned i; -- fprintf( stderr, "Error, entries missing!\n"); -- for (i=0; ibe_private; -- assert( bdb != NULL ); -- --next:; -- /* Get the header */ -- data.ulen = data.dlen = sizeof( ehbuf ); -- data.data = ehbuf; -- data.flags |= DB_DBT_PARTIAL; -- rc = cursor->c_get( cursor, &key, &data, DB_NEXT ); -- -- if( rc ) { -- /* If we're doing linear indexing and there are more attrs to -- * index, and we're at the end of the database, start over. -- */ -- if ( index_nattrs && rc == DB_NOTFOUND ) { -- /* optional - do a checkpoint here? */ -- bdb_attr_info_free( bdb->bi_attrs[0] ); -- bdb->bi_attrs[0] = bdb->bi_attrs[index_nattrs]; -- index_nattrs--; -- rc = cursor->c_get( cursor, &key, &data, DB_FIRST ); -- if ( rc ) { -- return NOID; -- } -- } else { -- return NOID; -- } -- } -- -- BDB_DISK2ID( key.data, &id ); -- previd = id; -- -- if ( tool_filter || tool_base ) { -- static Operation op = {0}; -- static Opheader ohdr = {0}; -- -- op.o_hdr = &ohdr; -- op.o_bd = be; -- op.o_tmpmemctx = NULL; -- op.o_tmpmfuncs = &ch_mfuncs; -- -- if ( tool_next_entry ) { -- bdb_entry_release( &op, tool_next_entry, 0 ); -- tool_next_entry = NULL; -- } -- -- rc = bdb_tool_entry_get_int( be, id, &tool_next_entry ); -- if ( rc == LDAP_NO_SUCH_OBJECT ) { -- goto next; -- } -- -- assert( tool_next_entry != NULL ); -- --#ifdef BDB_HIER -- /* TODO: needed until BDB_HIER is handled accordingly -- * in bdb_tool_entry_get_int() */ -- if ( tool_base && !dnIsSuffixScope( &tool_next_entry->e_nname, tool_base, tool_scope ) ) -- { -- bdb_entry_release( &op, tool_next_entry, 0 ); -- tool_next_entry = NULL; -- goto next; -- } --#endif -- -- if ( tool_filter && test_filter( NULL, tool_next_entry, tool_filter ) != LDAP_COMPARE_TRUE ) -- { -- bdb_entry_release( &op, tool_next_entry, 0 ); -- tool_next_entry = NULL; -- goto next; -- } -- } -- -- return id; --} -- --ID bdb_tool_dn2id_get( -- Backend *be, -- struct berval *dn --) --{ -- Operation op = {0}; -- Opheader ohdr = {0}; -- EntryInfo *ei = NULL; -- int rc; -- -- if ( BER_BVISEMPTY(dn) ) -- return 0; -- -- op.o_hdr = &ohdr; -- op.o_bd = be; -- op.o_tmpmemctx = NULL; -- op.o_tmpmfuncs = &ch_mfuncs; -- -- rc = bdb_cache_find_ndn( &op, 0, dn, &ei ); -- if ( ei ) bdb_cache_entryinfo_unlock( ei ); -- if ( rc == DB_NOTFOUND ) -- return NOID; -- -- return ei->bei_id; --} -- --static int --bdb_tool_entry_get_int( BackendDB *be, ID id, Entry **ep ) --{ -- Entry *e = NULL; -- char *dptr; -- int rc, eoff; -- -- assert( be != NULL ); -- assert( slapMode & SLAP_TOOL_MODE ); -- -- if ( ( tool_filter || tool_base ) && id == previd && tool_next_entry != NULL ) { -- *ep = tool_next_entry; -- tool_next_entry = NULL; -- return LDAP_SUCCESS; -- } -- -- if ( id != previd ) { -- data.ulen = data.dlen = sizeof( ehbuf ); -- data.data = ehbuf; -- data.flags |= DB_DBT_PARTIAL; -- -- BDB_ID2DISK( id, &nid ); -- rc = cursor->c_get( cursor, &key, &data, DB_SET ); -- if ( rc ) { -- rc = LDAP_OTHER; -- goto done; -- } -- } -- -- /* Get the header */ -- dptr = eh.bv.bv_val; -- eh.bv.bv_val = ehbuf; -- eh.bv.bv_len = data.size; -- rc = entry_header( &eh ); -- eoff = eh.data - eh.bv.bv_val; -- eh.bv.bv_val = dptr; -- if ( rc ) { -- rc = LDAP_OTHER; -- goto done; -- } -- -- /* Get the size */ -- data.flags &= ~DB_DBT_PARTIAL; -- data.ulen = 0; -- rc = cursor->c_get( cursor, &key, &data, DB_CURRENT ); -- if ( rc != DB_BUFFER_SMALL ) { -- rc = LDAP_OTHER; -- goto done; -- } -- -- /* Allocate a block and retrieve the data */ -- eh.bv.bv_len = eh.nvals * sizeof( struct berval ) + data.size; -- eh.bv.bv_val = ch_realloc( eh.bv.bv_val, eh.bv.bv_len ); -- eh.data = eh.bv.bv_val + eh.nvals * sizeof( struct berval ); -- data.data = eh.data; -- data.ulen = data.size; -- -- /* Skip past already parsed nattr/nvals */ -- eh.data += eoff; -- -- rc = cursor->c_get( cursor, &key, &data, DB_CURRENT ); -- if ( rc ) { -- rc = LDAP_OTHER; -- goto done; -- } -- --#ifndef BDB_HIER -- /* TODO: handle BDB_HIER accordingly */ -- if ( tool_base != NULL ) { -- struct berval ndn; -- entry_decode_dn( &eh, NULL, &ndn ); -- -- if ( !dnIsSuffixScope( &ndn, tool_base, tool_scope ) ) { -- return LDAP_NO_SUCH_OBJECT; -- } -- } --#endif -- --#ifdef SLAP_ZONE_ALLOC -- /* FIXME: will add ctx later */ -- rc = entry_decode( &eh, &e, NULL ); --#else -- rc = entry_decode( &eh, &e ); --#endif -- -- if( rc == LDAP_SUCCESS ) { -- e->e_id = id; --#ifdef BDB_HIER -- if ( slapMode & SLAP_TOOL_READONLY ) { -- struct bdb_info *bdb = (struct bdb_info *) be->be_private; -- EntryInfo *ei = NULL; -- Operation op = {0}; -- Opheader ohdr = {0}; -- -- op.o_hdr = &ohdr; -- op.o_bd = be; -- op.o_tmpmemctx = NULL; -- op.o_tmpmfuncs = &ch_mfuncs; -- -- rc = bdb_cache_find_parent( &op, bdb->bi_cache.c_txn, id, &ei ); -- if ( rc == LDAP_SUCCESS ) { -- bdb_cache_entryinfo_unlock( ei ); -- e->e_private = ei; -- ei->bei_e = e; -- bdb_fix_dn( e, 0 ); -- ei->bei_e = NULL; -- e->e_private = NULL; -- } -- } --#endif -- } --done: -- if ( e != NULL ) { -- *ep = e; -- } -- -- return rc; --} -- --Entry* --bdb_tool_entry_get( BackendDB *be, ID id ) --{ -- Entry *e = NULL; -- -- (void)bdb_tool_entry_get_int( be, id, &e ); -- return e; --} -- --static int bdb_tool_next_id( -- Operation *op, -- DB_TXN *tid, -- Entry *e, -- struct berval *text, -- int hole ) --{ -- struct berval dn = e->e_name; -- struct berval ndn = e->e_nname; -- struct berval pdn, npdn; -- EntryInfo *ei = NULL, eidummy; -- int rc; -- -- if (ndn.bv_len == 0) { -- e->e_id = 0; -- return 0; -- } -- -- rc = bdb_cache_find_ndn( op, tid, &ndn, &ei ); -- if ( ei ) bdb_cache_entryinfo_unlock( ei ); -- if ( rc == DB_NOTFOUND ) { -- if ( !be_issuffix( op->o_bd, &ndn ) ) { -- ID eid = e->e_id; -- dnParent( &dn, &pdn ); -- dnParent( &ndn, &npdn ); -- e->e_name = pdn; -- e->e_nname = npdn; -- rc = bdb_tool_next_id( op, tid, e, text, 1 ); -- e->e_name = dn; -- e->e_nname = ndn; -- if ( rc ) { -- return rc; -- } -- /* If parent didn't exist, it was created just now -- * and its ID is now in e->e_id. Make sure the current -- * entry gets added under the new parent ID. -- */ -- if ( eid != e->e_id ) { -- eidummy.bei_id = e->e_id; -- ei = &eidummy; -- } -- } -- rc = bdb_next_id( op->o_bd, &e->e_id ); -- if ( rc ) { -- snprintf( text->bv_val, text->bv_len, -- "next_id failed: %s (%d)", -- db_strerror(rc), rc ); -- Debug( LDAP_DEBUG_ANY, -- "=> bdb_tool_next_id: %s\n", text->bv_val, 0, 0 ); -- return rc; -- } -- rc = bdb_dn2id_add( op, tid, ei, e ); -- if ( rc ) { -- snprintf( text->bv_val, text->bv_len, -- "dn2id_add failed: %s (%d)", -- db_strerror(rc), rc ); -- Debug( LDAP_DEBUG_ANY, -- "=> bdb_tool_next_id: %s\n", text->bv_val, 0, 0 ); -- } else if ( hole ) { -- if ( nholes == nhmax - 1 ) { -- if ( holes == hbuf ) { -- holes = ch_malloc( nhmax * sizeof(dn_id) * 2 ); -- AC_MEMCPY( holes, hbuf, sizeof(hbuf) ); -- } else { -- holes = ch_realloc( holes, nhmax * sizeof(dn_id) * 2 ); -- } -- nhmax *= 2; -- } -- ber_dupbv( &holes[nholes].dn, &ndn ); -- holes[nholes++].id = e->e_id; -- } -- } else if ( !hole ) { -- unsigned i, j; -- -- e->e_id = ei->bei_id; -- -- for ( i=0; ie_id ) { -- free(holes[i].dn.bv_val); -- for (j=i;j e->e_id ) { -- break; -- } -- } -- } -- return rc; --} -- --static int --bdb_tool_index_add( -- Operation *op, -- DB_TXN *txn, -- Entry *e ) --{ -- struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; -- -- if ( !bdb->bi_nattrs ) -- return 0; -- -- if ( bdb_tool_threads > 1 ) { -- IndexRec *ir; -- int i, rc; -- Attribute *a; -- -- ir = bdb_tool_index_rec; -- memset(ir, 0, bdb->bi_nattrs * sizeof( IndexRec )); -- -- for ( a = e->e_attrs; a != NULL; a = a->a_next ) { -- rc = bdb_index_recset( bdb, a, a->a_desc->ad_type, -- &a->a_desc->ad_tags, ir ); -- if ( rc ) -- return rc; -- } -- bdb_tool_ix_id = e->e_id; -- bdb_tool_ix_op = op; -- ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex ); -- /* Wait for all threads to be ready */ -- while ( bdb_tool_index_tcount > 0 ) { -- ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main, -- &bdb_tool_index_mutex ); -- } -- for ( i=1; ie_id, 0 ); -- if ( rc ) -- return rc; -- ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex ); -- for ( i=1; ibv_val != NULL ); -- assert( text->bv_val[0] == '\0' ); /* overconservative? */ -- -- Debug( LDAP_DEBUG_TRACE, "=> " LDAP_XSTRING(bdb_tool_entry_put) -- "( %ld, \"%s\" )\n", (long) e->e_id, e->e_dn, 0 ); -- -- bdb = (struct bdb_info *) be->be_private; -- -- if (! (slapMode & SLAP_TOOL_QUICK)) { -- rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &tid, -- bdb->bi_db_opflags ); -- if( rc != 0 ) { -- snprintf( text->bv_val, text->bv_len, -- "txn_begin failed: %s (%d)", -- db_strerror(rc), rc ); -- Debug( LDAP_DEBUG_ANY, -- "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n", -- text->bv_val, 0, 0 ); -- return NOID; -- } -- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_tool_entry_put) ": txn id: %x\n", -- tid->id(tid), 0, 0 ); -- } -- -- op.o_hdr = &ohdr; -- op.o_bd = be; -- op.o_tmpmemctx = NULL; -- op.o_tmpmfuncs = &ch_mfuncs; -- -- /* add dn2id indices */ -- rc = bdb_tool_next_id( &op, tid, e, text, 0 ); -- if( rc != 0 ) { -- goto done; -- } -- --#ifdef USE_TRICKLE -- if (( slapMode & SLAP_TOOL_QUICK ) && (( e->e_id & 0xfff ) == 0xfff )) { -- ldap_pvt_thread_cond_signal( &bdb_tool_trickle_cond ); -- } --#endif -- -- if ( !bdb->bi_linear_index ) -- rc = bdb_tool_index_add( &op, tid, e ); -- if( rc != 0 ) { -- snprintf( text->bv_val, text->bv_len, -- "index_entry_add failed: %s (%d)", -- rc == LDAP_OTHER ? "Internal error" : -- db_strerror(rc), rc ); -- Debug( LDAP_DEBUG_ANY, -- "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n", -- text->bv_val, 0, 0 ); -- goto done; -- } -- -- /* id2entry index */ -- rc = bdb_id2entry_add( be, tid, e ); -- if( rc != 0 ) { -- snprintf( text->bv_val, text->bv_len, -- "id2entry_add failed: %s (%d)", -- db_strerror(rc), rc ); -- Debug( LDAP_DEBUG_ANY, -- "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n", -- text->bv_val, 0, 0 ); -- goto done; -- } -- --done: -- if( rc == 0 ) { -- if ( !( slapMode & SLAP_TOOL_QUICK )) { -- rc = TXN_COMMIT( tid, 0 ); -- if( rc != 0 ) { -- snprintf( text->bv_val, text->bv_len, -- "txn_commit failed: %s (%d)", -- db_strerror(rc), rc ); -- Debug( LDAP_DEBUG_ANY, -- "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n", -- text->bv_val, 0, 0 ); -- e->e_id = NOID; -- } -- } -- -- } else { -- if ( !( slapMode & SLAP_TOOL_QUICK )) { -- TXN_ABORT( tid ); -- snprintf( text->bv_val, text->bv_len, -- "txn_aborted! %s (%d)", -- rc == LDAP_OTHER ? "Internal error" : -- db_strerror(rc), rc ); -- Debug( LDAP_DEBUG_ANY, -- "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n", -- text->bv_val, 0, 0 ); -- } -- e->e_id = NOID; -- } -- -- return e->e_id; --} -- --int bdb_tool_entry_reindex( -- BackendDB *be, -- ID id, -- AttributeDescription **adv ) --{ -- struct bdb_info *bi = (struct bdb_info *) be->be_private; -- int rc; -- Entry *e; -- DB_TXN *tid = NULL; -- Operation op = {0}; -- Opheader ohdr = {0}; -- -- Debug( LDAP_DEBUG_ARGS, -- "=> " LDAP_XSTRING(bdb_tool_entry_reindex) "( %ld )\n", -- (long) id, 0, 0 ); -- assert( tool_base == NULL ); -- assert( tool_filter == NULL ); -- -- /* No indexes configured, nothing to do. Could return an -- * error here to shortcut things. -- */ -- if (!bi->bi_attrs) { -- return 0; -- } -- -- /* Check for explicit list of attrs to index */ -- if ( adv ) { -- int i, j, n; -- -- if ( bi->bi_attrs[0]->ai_desc != adv[0] ) { -- /* count */ -- for ( n = 0; adv[n]; n++ ) ; -- -- /* insertion sort */ -- for ( i = 0; i < n; i++ ) { -- AttributeDescription *ad = adv[i]; -- for ( j = i-1; j>=0; j--) { -- if ( SLAP_PTRCMP( adv[j], ad ) <= 0 ) break; -- adv[j+1] = adv[j]; -- } -- adv[j+1] = ad; -- } -- } -- -- for ( i = 0; adv[i]; i++ ) { -- if ( bi->bi_attrs[i]->ai_desc != adv[i] ) { -- for ( j = i+1; j < bi->bi_nattrs; j++ ) { -- if ( bi->bi_attrs[j]->ai_desc == adv[i] ) { -- AttrInfo *ai = bi->bi_attrs[i]; -- bi->bi_attrs[i] = bi->bi_attrs[j]; -- bi->bi_attrs[j] = ai; -- break; -- } -- } -- if ( j == bi->bi_nattrs ) { -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_tool_entry_reindex) -- ": no index configured for %s\n", -- adv[i]->ad_cname.bv_val, 0, 0 ); -- return -1; -- } -- } -- } -- bi->bi_nattrs = i; -- } -- -- /* Get the first attribute to index */ -- if (bi->bi_linear_index && !index_nattrs) { -- index_nattrs = bi->bi_nattrs - 1; -- bi->bi_nattrs = 1; -- } -- -- e = bdb_tool_entry_get( be, id ); -- -- if( e == NULL ) { -- Debug( LDAP_DEBUG_ANY, -- LDAP_XSTRING(bdb_tool_entry_reindex) -- ": could not locate id=%ld\n", -- (long) id, 0, 0 ); -- return -1; -- } -- -- op.o_hdr = &ohdr; -- op.o_bd = be; -- op.o_tmpmemctx = NULL; -- op.o_tmpmfuncs = &ch_mfuncs; -- -- if (! (slapMode & SLAP_TOOL_QUICK)) { -- rc = TXN_BEGIN( bi->bi_dbenv, NULL, &tid, bi->bi_db_opflags ); -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, -- "=> " LDAP_XSTRING(bdb_tool_entry_reindex) ": " -- "txn_begin failed: %s (%d)\n", -- db_strerror(rc), rc, 0 ); -- goto done; -- } -- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_tool_entry_reindex) ": txn id: %x\n", -- tid->id(tid), 0, 0 ); -- } -- -- /* -- * just (re)add them for now -- * assume that some other routine (not yet implemented) -- * will zap index databases -- * -- */ -- -- Debug( LDAP_DEBUG_TRACE, -- "=> " LDAP_XSTRING(bdb_tool_entry_reindex) "( %ld, \"%s\" )\n", -- (long) id, e->e_dn, 0 ); -- -- rc = bdb_tool_index_add( &op, tid, e ); -- --done: -- if( rc == 0 ) { -- if (! (slapMode & SLAP_TOOL_QUICK)) { -- rc = TXN_COMMIT( tid, 0 ); -- if( rc != 0 ) { -- Debug( LDAP_DEBUG_ANY, -- "=> " LDAP_XSTRING(bdb_tool_entry_reindex) -- ": txn_commit failed: %s (%d)\n", -- db_strerror(rc), rc, 0 ); -- e->e_id = NOID; -- } -- } -- -- } else { -- if (! (slapMode & SLAP_TOOL_QUICK)) { -- TXN_ABORT( tid ); -- Debug( LDAP_DEBUG_ANY, -- "=> " LDAP_XSTRING(bdb_tool_entry_reindex) -- ": txn_aborted! %s (%d)\n", -- db_strerror(rc), rc, 0 ); -- } -- e->e_id = NOID; -- } -- bdb_entry_release( &op, e, 0 ); -- -- return rc; --} -- --ID bdb_tool_entry_modify( -- BackendDB *be, -- Entry *e, -- struct berval *text ) --{ -- int rc; -- struct bdb_info *bdb; -- DB_TXN *tid = NULL; -- Operation op = {0}; -- Opheader ohdr = {0}; -- -- assert( be != NULL ); -- assert( slapMode & SLAP_TOOL_MODE ); -- -- assert( text != NULL ); -- assert( text->bv_val != NULL ); -- assert( text->bv_val[0] == '\0' ); /* overconservative? */ -- -- assert ( e->e_id != NOID ); -- -- Debug( LDAP_DEBUG_TRACE, -- "=> " LDAP_XSTRING(bdb_tool_entry_modify) "( %ld, \"%s\" )\n", -- (long) e->e_id, e->e_dn, 0 ); -- -- bdb = (struct bdb_info *) be->be_private; -- -- if (! (slapMode & SLAP_TOOL_QUICK)) { -- if( cursor ) { -- cursor->c_close( cursor ); -- cursor = NULL; -- } -- rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &tid, -- bdb->bi_db_opflags ); -- if( rc != 0 ) { -- snprintf( text->bv_val, text->bv_len, -- "txn_begin failed: %s (%d)", -- db_strerror(rc), rc ); -- Debug( LDAP_DEBUG_ANY, -- "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n", -- text->bv_val, 0, 0 ); -- return NOID; -- } -- Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_tool_entry_modify) ": txn id: %x\n", -- tid->id(tid), 0, 0 ); -- } -- -- op.o_hdr = &ohdr; -- op.o_bd = be; -- op.o_tmpmemctx = NULL; -- op.o_tmpmfuncs = &ch_mfuncs; -- -- /* id2entry index */ -- rc = bdb_id2entry_update( be, tid, e ); -- if( rc != 0 ) { -- snprintf( text->bv_val, text->bv_len, -- "id2entry_add failed: %s (%d)", -- db_strerror(rc), rc ); -- Debug( LDAP_DEBUG_ANY, -- "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n", -- text->bv_val, 0, 0 ); -- goto done; -- } -- --done: -- if( rc == 0 ) { -- if (! (slapMode & SLAP_TOOL_QUICK)) { -- rc = TXN_COMMIT( tid, 0 ); -- if( rc != 0 ) { -- snprintf( text->bv_val, text->bv_len, -- "txn_commit failed: %s (%d)", -- db_strerror(rc), rc ); -- Debug( LDAP_DEBUG_ANY, -- "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": " -- "%s\n", text->bv_val, 0, 0 ); -- e->e_id = NOID; -- } -- } -- -- } else { -- if (! (slapMode & SLAP_TOOL_QUICK)) { -- TXN_ABORT( tid ); -- snprintf( text->bv_val, text->bv_len, -- "txn_aborted! %s (%d)", -- db_strerror(rc), rc ); -- Debug( LDAP_DEBUG_ANY, -- "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n", -- text->bv_val, 0, 0 ); -- } -- e->e_id = NOID; -- } -- -- return e->e_id; --} -- --#ifdef BDB_TOOL_IDL_CACHING --static int --bdb_tool_idl_cmp( const void *v1, const void *v2 ) --{ -- const bdb_tool_idl_cache *c1 = v1, *c2 = v2; -- int rc; -- -- if (( rc = c1->kstr.bv_len - c2->kstr.bv_len )) return rc; -- return memcmp( c1->kstr.bv_val, c2->kstr.bv_val, c1->kstr.bv_len ); --} -- --static int --bdb_tool_idl_flush_one( void *v1, void *arg ) --{ -- bdb_tool_idl_cache *ic = v1; -- DB *db = arg; -- struct bdb_info *bdb = bdb_tool_info; -- bdb_tool_idl_cache_entry *ice; -- DBC *curs; -- DBT key, data; -- int i, rc; -- ID id, nid; -- -- /* Freshly allocated, ignore it */ -- if ( !ic->head && ic->count <= BDB_IDL_DB_SIZE ) { -- return 0; -- } -- -- rc = db->cursor( db, NULL, &curs, 0 ); -- if ( rc ) -- return -1; -- -- DBTzero( &key ); -- DBTzero( &data ); -- -- bv2DBT( &ic->kstr, &key ); -- -- data.size = data.ulen = sizeof( ID ); -- data.flags = DB_DBT_USERMEM; -- data.data = &nid; -- -- rc = curs->c_get( curs, &key, &data, DB_SET ); -- /* If key already exists and we're writing a range... */ -- if ( rc == 0 && ic->count > BDB_IDL_DB_SIZE ) { -- /* If it's not currently a range, must delete old info */ -- if ( nid ) { -- /* Skip lo */ -- while ( curs->c_get( curs, &key, &data, DB_NEXT_DUP ) == 0 ) -- curs->c_del( curs, 0 ); -- -- nid = 0; -- /* Store range marker */ -- curs->c_put( curs, &key, &data, DB_KEYFIRST ); -- } else { -- -- /* Skip lo */ -- rc = curs->c_get( curs, &key, &data, DB_NEXT_DUP ); -- -- /* Get hi */ -- rc = curs->c_get( curs, &key, &data, DB_NEXT_DUP ); -- -- /* Delete hi */ -- curs->c_del( curs, 0 ); -- } -- BDB_ID2DISK( ic->last, &nid ); -- curs->c_put( curs, &key, &data, DB_KEYLAST ); -- rc = 0; -- } else if ( rc && rc != DB_NOTFOUND ) { -- rc = -1; -- } else if ( ic->count > BDB_IDL_DB_SIZE ) { -- /* range, didn't exist before */ -- nid = 0; -- rc = curs->c_put( curs, &key, &data, DB_KEYLAST ); -- if ( rc == 0 ) { -- BDB_ID2DISK( ic->first, &nid ); -- rc = curs->c_put( curs, &key, &data, DB_KEYLAST ); -- if ( rc == 0 ) { -- BDB_ID2DISK( ic->last, &nid ); -- rc = curs->c_put( curs, &key, &data, DB_KEYLAST ); -- } -- } -- if ( rc ) { -- rc = -1; -- } -- } else { -- int n; -- -- /* Just a normal write */ -- rc = 0; -- for ( ice = ic->head, n=0; ice; ice = ice->next, n++ ) { -- int end; -- if ( ice->next ) { -- end = IDBLOCK; -- } else { -- end = ic->count & (IDBLOCK-1); -- if ( !end ) -- end = IDBLOCK; -- } -- for ( i=0; iids[i] ) continue; -- BDB_ID2DISK( ice->ids[i], &nid ); -- rc = curs->c_put( curs, &key, &data, DB_NODUPDATA ); -- if ( rc ) { -- if ( rc == DB_KEYEXIST ) { -- rc = 0; -- continue; -- } -- rc = -1; -- break; -- } -- } -- if ( rc ) { -- rc = -1; -- break; -- } -- } -- if ( ic->head ) { -- ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock ); -- ic->tail->next = bdb_tool_idl_free_list; -- bdb_tool_idl_free_list = ic->head; -- bdb->bi_idl_cache_size -= n; -- ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock ); -- } -- } -- if ( ic != db->app_private ) { -- ch_free( ic ); -- } else { -- ic->head = ic->tail = NULL; -- } -- curs->c_close( curs ); -- return rc; --} -- --static int --bdb_tool_idl_flush_db( DB *db, bdb_tool_idl_cache *ic ) --{ -- Avlnode *root = db->app_private; -- int rc; -- -- db->app_private = ic; -- rc = avl_apply( root, bdb_tool_idl_flush_one, db, -1, AVL_INORDER ); -- avl_free( root, NULL ); -- db->app_private = NULL; -- if ( rc != -1 ) -- rc = 0; -- return rc; --} -- --static int --bdb_tool_idl_flush( BackendDB *be ) --{ -- struct bdb_info *bdb = (struct bdb_info *) be->be_private; -- DB *db; -- Avlnode *root; -- int i, rc = 0; -- -- for ( i=BDB_NDB; i < bdb->bi_ndatabases; i++ ) { -- db = bdb->bi_databases[i]->bdi_db; -- if ( !db->app_private ) continue; -- rc = bdb_tool_idl_flush_db( db, NULL ); -- if ( rc ) -- break; -- } -- if ( !rc ) { -- bdb->bi_idl_cache_size = 0; -- } -- return rc; --} -- --int bdb_tool_idl_add( -- BackendDB *be, -- DB *db, -- DB_TXN *txn, -- DBT *key, -- ID id ) --{ -- struct bdb_info *bdb = (struct bdb_info *) be->be_private; -- bdb_tool_idl_cache *ic, itmp; -- bdb_tool_idl_cache_entry *ice; -- int rc; -- -- if ( !bdb->bi_idl_cache_max_size ) -- return bdb_idl_insert_key( be, db, txn, key, id ); -- -- DBT2bv( key, &itmp.kstr ); -- -- ic = avl_find( (Avlnode *)db->app_private, &itmp, bdb_tool_idl_cmp ); -- -- /* No entry yet, create one */ -- if ( !ic ) { -- DBC *curs; -- DBT data; -- ID nid; -- int rc; -- -- ic = ch_malloc( sizeof( bdb_tool_idl_cache ) + itmp.kstr.bv_len ); -- ic->kstr.bv_len = itmp.kstr.bv_len; -- ic->kstr.bv_val = (char *)(ic+1); -- AC_MEMCPY( ic->kstr.bv_val, itmp.kstr.bv_val, ic->kstr.bv_len ); -- ic->head = ic->tail = NULL; -- ic->last = 0; -- ic->count = 0; -- avl_insert( (Avlnode **)&db->app_private, ic, bdb_tool_idl_cmp, -- avl_dup_error ); -- -- /* load existing key count here */ -- rc = db->cursor( db, NULL, &curs, 0 ); -- if ( rc ) return rc; -- -- data.ulen = sizeof( ID ); -- data.flags = DB_DBT_USERMEM; -- data.data = &nid; -- rc = curs->c_get( curs, key, &data, DB_SET ); -- if ( rc == 0 ) { -- if ( nid == 0 ) { -- ic->count = BDB_IDL_DB_SIZE+1; -- } else { -- db_recno_t count; -- -- curs->c_count( curs, &count, 0 ); -- ic->count = count; -- BDB_DISK2ID( &nid, &ic->first ); -- } -- } -- curs->c_close( curs ); -- } -- /* are we a range already? */ -- if ( ic->count > BDB_IDL_DB_SIZE ) { -- ic->last = id; -- return 0; -- /* Are we at the limit, and converting to a range? */ -- } else if ( ic->count == BDB_IDL_DB_SIZE ) { -- int n; -- for ( ice = ic->head, n=0; ice; ice = ice->next, n++ ) -- /* counting */ ; -- if ( n ) { -- ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock ); -- ic->tail->next = bdb_tool_idl_free_list; -- bdb_tool_idl_free_list = ic->head; -- bdb->bi_idl_cache_size -= n; -- ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock ); -- } -- ic->head = ic->tail = NULL; -- ic->last = id; -- ic->count++; -- return 0; -- } -- /* No free block, create that too */ -- if ( !ic->tail || ( ic->count & (IDBLOCK-1)) == 0) { -- ice = NULL; -- ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock ); -- if ( bdb->bi_idl_cache_size >= bdb->bi_idl_cache_max_size ) { -- ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock ); -- rc = bdb_tool_idl_flush_db( db, ic ); -- if ( rc ) -- return rc; -- avl_insert( (Avlnode **)&db->app_private, ic, bdb_tool_idl_cmp, -- avl_dup_error ); -- ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock ); -- } -- bdb->bi_idl_cache_size++; -- if ( bdb_tool_idl_free_list ) { -- ice = bdb_tool_idl_free_list; -- bdb_tool_idl_free_list = ice->next; -- } -- ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock ); -- if ( !ice ) { -- ice = ch_malloc( sizeof( bdb_tool_idl_cache_entry )); -- } -- memset( ice, 0, sizeof( *ice )); -- if ( !ic->head ) { -- ic->head = ice; -- } else { -- ic->tail->next = ice; -- } -- ic->tail = ice; -- if ( !ic->count ) -- ic->first = id; -- } -- ice = ic->tail; -- ice->ids[ ic->count & (IDBLOCK-1) ] = id; -- ic->count++; -- -- return 0; --} --#endif -- --#ifdef USE_TRICKLE --static void * --bdb_tool_trickle_task( void *ctx, void *ptr ) --{ -- DB_ENV *env = ptr; -- int wrote; -- -- ldap_pvt_thread_mutex_lock( &bdb_tool_trickle_mutex ); -- bdb_tool_trickle_active = 1; -- ldap_pvt_thread_cond_signal( &bdb_tool_trickle_cond_end ); -- while ( 1 ) { -- ldap_pvt_thread_cond_wait( &bdb_tool_trickle_cond, -- &bdb_tool_trickle_mutex ); -- if ( slapd_shutdown ) -- break; -- env->memp_trickle( env, 30, &wrote ); -- } -- bdb_tool_trickle_active = 0; -- ldap_pvt_thread_cond_signal( &bdb_tool_trickle_cond_end ); -- ldap_pvt_thread_mutex_unlock( &bdb_tool_trickle_mutex ); -- -- return NULL; --} --#endif -- --static void * --bdb_tool_index_task( void *ctx, void *ptr ) --{ -- int base = *(int *)ptr; -- -- free( ptr ); -- while ( 1 ) { -- ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex ); -- bdb_tool_index_tcount--; -- if ( !bdb_tool_index_tcount ) -- ldap_pvt_thread_cond_signal( &bdb_tool_index_cond_main ); -- ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_work, -- &bdb_tool_index_mutex ); -- if ( slapd_shutdown ) { -- bdb_tool_index_tcount--; -- if ( !bdb_tool_index_tcount ) -- ldap_pvt_thread_cond_signal( &bdb_tool_index_cond_main ); -- ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex ); -- break; -- } -- ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex ); -- -- bdb_tool_index_threads[base] = bdb_index_recrun( bdb_tool_ix_op, -- bdb_tool_info, bdb_tool_index_rec, bdb_tool_ix_id, base ); -- } -- -- return NULL; --} -diff --git a/servers/slapd/back-bdb/trans.c b/servers/slapd/back-bdb/trans.c -deleted file mode 100644 -index 1971d29..0000000 ---- a/servers/slapd/back-bdb/trans.c -+++ /dev/null -@@ -1,56 +0,0 @@ --/* trans.c - bdb backend transaction routines */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ -- --#include "portable.h" -- --#include --#include -- --#include "back-bdb.h" --#include "lber_pvt.h" --#include "lutil.h" -- -- --/* Congestion avoidance code -- * for Deadlock Rollback -- */ -- --void --bdb_trans_backoff( int num_retries ) --{ -- int i; -- int delay = 0; -- int pow_retries = 1; -- unsigned long key = 0; -- unsigned long max_key = -1; -- struct timeval timeout; -- -- lutil_entropy( (unsigned char *) &key, sizeof( unsigned long )); -- -- for ( i = 0; i < num_retries; i++ ) { -- if ( i >= 5 ) break; -- pow_retries *= 4; -- } -- -- delay = 16384 * (key * (double) pow_retries / (double) max_key); -- delay = delay ? delay : 1; -- -- Debug( LDAP_DEBUG_TRACE, "delay = %d, num_retries = %d\n", delay, num_retries, 0 ); -- -- timeout.tv_sec = delay / 1000000; -- timeout.tv_usec = delay % 1000000; -- select( 0, NULL, NULL, NULL, &timeout ); --} -diff --git a/servers/slapd/back-hdb/Makefile.in b/servers/slapd/back-hdb/Makefile.in -deleted file mode 100644 -index 150cee5..0000000 ---- a/servers/slapd/back-hdb/Makefile.in -+++ /dev/null -@@ -1,70 +0,0 @@ --# Makefile for back-hdb --# $OpenLDAP$ --## This work is part of OpenLDAP Software . --## --## Copyright 1998-2020 The OpenLDAP Foundation. --## All rights reserved. --## --## Redistribution and use in source and binary forms, with or without --## modification, are permitted only as authorized by the OpenLDAP --## Public License. --## --## A copy of this license is available in the file LICENSE in the --## top-level directory of the distribution or, alternatively, at --## . --# --## Copyright 2003 Howard Chu @ Symas Corp. See master COPYRIGHT file for terms. -- --XXDIR = $(srcdir)/../back-bdb -- --XXSRCS = init.c tools.c config.c \ -- add.c bind.c compare.c delete.c modify.c modrdn.c search.c \ -- extended.c referral.c operational.c \ -- attr.c index.c key.c dbcache.c filterindex.c trans.c \ -- dn2entry.c dn2id.c error.c id2entry.c idl.c nextid.c cache.c \ -- monitor.c --SRCS = $(XXSRCS) --OBJS = init.lo tools.lo config.lo \ -- add.lo bind.lo compare.lo delete.lo modify.lo modrdn.lo search.lo \ -- extended.lo referral.lo operational.lo \ -- attr.lo index.lo key.lo dbcache.lo filterindex.lo trans.lo \ -- dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo nextid.lo cache.lo \ -- monitor.lo -- --LDAP_INCDIR= ../../../include --LDAP_LIBDIR= ../../../libraries -- --BUILD_OPT = "--enable-hdb" --BUILD_MOD = @BUILD_HDB@ -- --mod_DEFS = -DSLAPD_IMPORT --MOD_DEFS = $(@BUILD_HDB@_DEFS) --MOD_LIBS = $(BDB_LIBS) -- --shared_LDAP_LIBS = $(LDAP_LIBLDAP_R_LA) $(LDAP_LIBLBER_LA) --NT_LINK_LIBS = -L.. -lslapd $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS) --UNIX_LINK_LIBS = $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS) -- --.links : Makefile -- @for i in $(XXSRCS); do \ -- $(RM) $$i; \ -- $(LN_S) $(XXDIR)/$$i . ; \ -- done -- touch .links -- --$(XXSRCS) : .links -- --LIBBASE = back_hdb -- --XINCPATH = -I.. -I$(srcdir)/.. -I$(srcdir) -I$(XXDIR) --XDEFS = $(MODULES_CPPFLAGS) -- --depend-local-lib: .links -- --all-local-lib: ../.backend -- --../.backend: lib$(LIBBASE).a -- @touch $@ -- --veryclean-local: FORCE -- $(RM) $(XXSRCS) .links -diff --git a/servers/slapd/back-hdb/back-bdb.h b/servers/slapd/back-hdb/back-bdb.h -deleted file mode 100644 -index 9f92d8b..0000000 ---- a/servers/slapd/back-hdb/back-bdb.h -+++ /dev/null -@@ -1,31 +0,0 @@ --/* back-bdb.h - hdb back-end header file */ --/* $OpenLDAP$ */ --/* This work is part of OpenLDAP Software . -- * -- * Copyright 2000-2020 The OpenLDAP Foundation. -- * Portions Copyright 2003 Howard Chu @ Symas Corp. -- * All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted only as authorized by the OpenLDAP -- * Public License. -- * -- * A copy of this license is available in the file LICENSE in the -- * top-level directory of the distribution or, alternatively, at -- * . -- */ --/* ACKNOWLEDGEMENTS: -- * This work was originally developed by Howard Chu for inclusion -- * in OpenLDAP Software. -- */ -- --#ifndef _BACK_HDB_H_ --#define _BACK_HDB_H_ -- --#ifndef BDB_HIER --#define BDB_HIER 1 --#endif -- --#include "../back-bdb/back-bdb.h" -- --#endif /* _BACK_HDB_H_ */ -diff --git a/servers/slapd/back-monitor/init.c b/servers/slapd/back-monitor/init.c -index b264115..ce9a34a 100644 ---- a/servers/slapd/back-monitor/init.c -+++ b/servers/slapd/back-monitor/init.c -@@ -1991,8 +1991,8 @@ monitor_back_initialize( - { "olmGenericAttributes", "olmSubSystemAttributes:0" }, - { "olmDatabaseAttributes", "olmSubSystemAttributes:1" }, - -- /* for example, back-bdb specific attrs -- * are in "olmDatabaseAttributes:1" -+ /* for example, back-mdb specific attrs -+ * are in "olmDatabaseAttributes:12" - * - * NOTE: developers, please record here OID assignments - * for other modules */ -@@ -2002,8 +2002,8 @@ monitor_back_initialize( - { "olmGenericObjectClasses", "olmSubSystemObjectClasses:0" }, - { "olmDatabaseObjectClasses", "olmSubSystemObjectClasses:1" }, - -- /* for example, back-bdb specific objectClasses -- * are in "olmDatabaseObjectClasses:1" -+ /* for example, back-mdb specific objectClasses -+ * are in "olmDatabaseObjectClasses:12" - * - * NOTE: developers, please record here OID assignments - * for other modules */ -diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c -index 0c6a7f5..538eef1 100644 ---- a/servers/slapd/bconfig.c -+++ b/servers/slapd/bconfig.c -@@ -238,7 +238,7 @@ static OidRec OidMacros[] = { - * Backend/Database registry - * - * OLcfg{Bk|Db}{Oc|At}:0 -> common -- * OLcfg{Bk|Db}{Oc|At}:1 -> back-bdb(/back-hdb) -+ * OLcfg{Bk|Db}{Oc|At}:1 -> back-bdb(/back-hdb) (removed) - * OLcfg{Bk|Db}{Oc|At}:2 -> back-ldif - * OLcfg{Bk|Db}{Oc|At}:3 -> back-ldap/meta - * OLcfg{Bk|Db}{Oc|At}:4 -> back-monitor -diff --git a/servers/slapd/dn.c b/servers/slapd/dn.c -index 06698b0..89b80e3 100644 ---- a/servers/slapd/dn.c -+++ b/servers/slapd/dn.c -@@ -1131,8 +1131,7 @@ rdn_validate( struct berval *rdn ) - - /* build_new_dn: - * -- * Used by back-bdb back_modrdn to create the new dn of entries being -- * renamed. -+ * Used to create the new dn of entries being renamed. - * - * new_dn = parent (p_dn) + separator + rdn (newrdn) + null. - */ -diff --git a/servers/slapd/overlays/pcache.c b/servers/slapd/overlays/pcache.c -index f88ca09..0d7ff8c 100644 ---- a/servers/slapd/overlays/pcache.c -+++ b/servers/slapd/overlays/pcache.c -@@ -5616,7 +5616,7 @@ cleanup:; - cm->monitor_cb = (void *)cb; - - /* we don't need to keep track of the attributes, because -- * bdb_monitor_free() takes care of everything */ -+ * mdb_monitor_free() takes care of everything */ - if ( a != NULL ) { - attrs_free( a ); - } -@@ -5700,7 +5700,7 @@ pcache_initialize() - } - #endif /* PCACHE_EXOP_QUERY_DELETE */ - -- argv[ 0 ] = "back-bdb/back-hdb monitor"; -+ argv[ 0 ] = "back-mdb monitor"; - c.argv = argv; - c.argc = 3; - c.fname = argv[0]; -diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h -index f003bb9..591f49d 100644 ---- a/servers/slapd/slap.h -+++ b/servers/slapd/slap.h -@@ -1805,7 +1805,6 @@ struct BackendDB { - - /* - * define to honor hasSubordinates operational attribute in search filters -- * (in previous use there was a flaw with back-bdb; now it is fixed). - */ - #define be_has_subordinates bd_info->bi_has_subordinates - -diff --git a/servers/slapd/slapd.ldif b/servers/slapd/slapd.ldif -index 5aba54d..b2b38ea 100644 ---- a/servers/slapd/slapd.ldif -+++ b/servers/slapd/slapd.ldif -@@ -30,8 +30,7 @@ olcPidFile: %LOCALSTATEDIR%/run/slapd.pid - #objectClass: olcModuleList - #cn: module - #olcModulepath: %MODULEDIR% --#olcModuleload: back_bdb.la --#olcModuleload: back_hdb.la -+#olcModuleload: back_mdb.la - #olcModuleload: back_ldap.la - #olcModuleload: back_passwd.la - #olcModuleload: back_shell.la -diff --git a/tests/Makefile.in b/tests/Makefile.in -index d841846..ef98813 100644 ---- a/tests/Makefile.in -+++ b/tests/Makefile.in -@@ -16,15 +16,11 @@ - RUN=./run - SUBDIRS= progs - --BUILD_BDB=@BUILD_BDB@ --BUILD_HDB=@BUILD_HDB@ - BUILD_MDB=@BUILD_MDB@ - BUILD_SQL=@BUILD_SQL@ - - # test primary backends (default) - test tests: -- @$(MAKE) bdb -- @$(MAKE) hdb - @$(MAKE) mdb - - # test all backends -@@ -32,22 +28,6 @@ alltests: tests - @$(MAKE) sql - @$(MAKE) ldif - --bdb test-bdb: bdb-$(BUILD_BDB) --bdb-no: -- @echo "run configure with --enable-bdb to run BDB tests" -- --bdb-yes bdb-mod: FORCE -- @echo "Initiating LDAP tests for BDB..." -- @$(RUN) -b bdb all -- --hdb test-hdb: hdb-$(BUILD_HDB) --hdb-no: -- @echo "run configure with --enable-hdb to run HDB tests" -- --hdb-yes hdb-mod: FORCE -- @echo "Initiating LDAP tests for HDB..." -- @$(RUN) -b hdb all -- - mdb test-mdb: mdb-$(BUILD_MDB) - mdb-no: - @echo "run configure with --enable-mdb to run MDB tests" -@@ -70,26 +50,10 @@ ldif test-ldif: FORCE - - regressions: FORCE - @echo "Testing (available) ITS regressions" -- @$(MAKE) bdb-its -- @$(MAKE) hdb-its - @$(MAKE) mdb-its - - its: regressions - --bdb-its: bdb-its-$(BUILD_BDB) --bdb-its-no: -- @echo "run configure with --enable-bdb to run BDB ITS regressions" -- --bdb-its-yes bdb-its-mod: FORCE -- @$(RUN) -b bdb its-all -- --hdb-its: hdb-its-$(BUILD_HDB) --hdb-its-no: -- @echo "run configure with --enable-hdb to run HDB ITS regressions" -- --hdb-its-yes hdb-its-mod: FORCE -- @$(RUN) -b hdb its-all -- - mdb-its: mdb-its-$(BUILD_MDB) - mdb-its-no: - @echo "run configure with --enable-mdb to run MDB ITS regressions" -diff --git a/tests/README b/tests/README -index 1a25df8..a3b5d2f 100644 ---- a/tests/README -+++ b/tests/README -@@ -2,8 +2,6 @@ This directory contains a series of test scripts which are used to - verify basic functionality of the LDAP libraries and slapd. - - To run all of the tests, type "make test". -- To run BDB tests, type "make bdb". -- To run HDB tests, type "make hdb". - To run MDB tests, type "make mdb". - To run SQL tests, define SLAPD_USE_SQL= and type - "make sql"; define SLAPD_USE_SQLWRITE=yes -diff --git a/tests/data/regressions/its4184/its4184 b/tests/data/regressions/its4184/its4184 -index 08f9f1c..4170f05 100755 ---- a/tests/data/regressions/its4184/its4184 -+++ b/tests/data/regressions/its4184/its4184 -@@ -16,10 +16,6 @@ - echo "running defines.sh" - . $SRCDIR/scripts/defines.sh - --if test "$BACKEND" != "bdb" && test "$BACKEND" != "hdb" ; then -- echo "Warning: this test is known to affect bdb and hdb, although it may impact other backends as well." --fi -- - mkdir -p $DBDIR1A $DBDIR2A - - ITS=4184 -diff --git a/tests/data/regressions/its4448/its4448 b/tests/data/regressions/its4448/its4448 -index 7f50999..9319374 100755 ---- a/tests/data/regressions/its4448/its4448 -+++ b/tests/data/regressions/its4448/its4448 -@@ -47,22 +47,6 @@ ITS=4448 - ITSDIR=$DATADIR/regressions/its$ITS - ITSCONF=$ITSDIR/slapd-meta.conf - --# NOTE: this could be added to all tests... --if test "$BACKEND" = "bdb" || test "$BACKEND" = "hdb" ; then -- if test "x$DB_CONFIG" != "x" ; then \ -- if test -f $DB_CONFIG ; then -- echo "==> using DB_CONFIG \"$DB_CONFIG\"" -- cp $DB_CONFIG $DBDIR1 -- cp $DB_CONFIG $DBDIR2 -- else -- echo "==> DB_CONFIG must point to a valid file (ignored)" -- fi -- else -- echo "==> set \"DB_CONFIG\" to the DB_CONFIG file you want to use for the test." -- fi -- echo "" --fi -- - echo "Starting slapd on TCP/IP port $PORT1..." - . $CONFFILTER $BACKEND $MONITORDB < $CONF > $CONF1 - $SLAPD -f $CONF1 -h $URI1 -d $LVL $TIMING > $LOG1 2>&1 & -diff --git a/tests/data/slapd-proxyauthz.conf b/tests/data/slapd-proxyauthz.conf -index 2ff6563..b28d60d 100644 ---- a/tests/data/slapd-proxyauthz.conf -+++ b/tests/data/slapd-proxyauthz.conf -@@ -64,10 +64,6 @@ pcachetemplate (cn=) 0 86400 86400 86400 180 - - pcachebind (cn=) 0 3600 sub ou=people,dc=example,dc=com - --#bdb#cachesize 20 --#hdb#cachesize 20 --#bdb#dbnosync --#hdb#dbnosync - #mdb#dbnosync - - #~null~#directory @TESTDIR@/db.2.a -diff --git a/tests/data/slapd-proxycache.conf b/tests/data/slapd-proxycache.conf -index b96d850..db3b60e 100644 ---- a/tests/data/slapd-proxycache.conf -+++ b/tests/data/slapd-proxycache.conf -@@ -54,10 +54,6 @@ pcachetemplate (mail=) 0 @TTL@ @NTTL@ @STTL@ - pcachetemplate (&(objectclass=)(uid=)) 1 @TTL@ @NTTL@ @STTL@ @TTR@ - pcachebind (&(objectclass=person)(uid=)) 1 @BTTR@ sub "ou=Alumni Association,ou=people,dc=example,dc=com" - --#bdb#cachesize 20 --#hdb#cachesize 20 --#bdb#dbnosync --#hdb#dbnosync - #mdb#dbnosync - - #~null~#directory @TESTDIR@/db.2.a -diff --git a/tests/data/slapd-ref-slave.conf b/tests/data/slapd-ref-slave.conf -index 3d30ca7..5d8d83f 100644 ---- a/tests/data/slapd-ref-slave.conf -+++ b/tests/data/slapd-ref-slave.conf -@@ -34,8 +34,6 @@ argsfile @TESTDIR@/slapd.2.args - referral "@URI1@" - - database @BACKEND@ --#bdb#cachesize 0 --#hdb#cachesize 0 - - suffix "o=University of Mich,c=US" - rootdn "cn=Manager,o=University of Mich,c=US" -diff --git a/tests/data/slapd.conf b/tests/data/slapd.conf -index 97c883b..309eb5a 100644 ---- a/tests/data/slapd.conf -+++ b/tests/data/slapd.conf -@@ -44,8 +44,6 @@ rootpw secret - #~null~#directory @TESTDIR@/db.1.a - #indexdb#index objectClass eq - #indexdb#index cn,sn,uid pres,eq,sub --#bdb#checkpoint 1024 5 --#hdb#checkpoint 1024 5 - #mdb#maxsize 33554432 - #ndb#dbname db_1 - #ndb#include @DATADIR@/ndb.conf -diff --git a/tests/run.in b/tests/run.in -index 8830dd4..6705265 100644 ---- a/tests/run.in -+++ b/tests/run.in -@@ -24,8 +24,6 @@ EGREP_CMD="@EGREP@" - export SRCDIR TOPSRCDIR LN_S EGREP_CMD - - # backends known to ./run -b (used to deduce $BACKENDTYPE) --AC_bdb=@BUILD_BDB@ --AC_hdb=@BUILD_HDB@ - AC_ldif=yes - AC_mdb=@BUILD_MDB@ - AC_null=@BUILD_NULL@ -@@ -69,7 +67,7 @@ if test "${AC_meta}" = "metamod" && test "${AC_LIBS_DYNAMIC}" = "static" ; then - AC_meta="metano" - fi - --export AC_bdb AC_hdb AC_ldap AC_mdb AC_meta AC_monitor AC_null AC_relay AC_sql \ -+export AC_ldap AC_mdb AC_meta AC_monitor AC_null AC_relay AC_sql \ - AC_accesslog AC_constraint AC_dds AC_dynlist AC_memberof AC_pcache AC_ppolicy \ - AC_refint AC_retcode AC_rwm AC_unique AC_syncprov AC_translucent \ - AC_valsort \ -@@ -153,7 +151,7 @@ while test $# -gt 0 ; do - done - - if test -z "$BACKEND" ; then -- for b in bdb hdb mdb ; do -+ for b in mdb ; do - if eval "test \"\$AC_$b\" != no" ; then - BACKEND=$b - break -@@ -174,7 +172,7 @@ fi - # maindb: main storage backend. Currently index,limits,mode,paged results. - INDEXDB=noindexdb MAINDB=nomaindb - case $BACKEND in -- bdb|hdb|mdb) INDEXDB=indexdb MAINDB=maindb ;; -+ mdb) INDEXDB=indexdb MAINDB=maindb ;; - ndb) INDEXDB=indexdb ;; - esac - -diff --git a/tests/scripts/test023-refint b/tests/scripts/test023-refint -index 546b9c7..b51134d 100755 ---- a/tests/scripts/test023-refint -+++ b/tests/scripts/test023-refint -@@ -189,9 +189,8 @@ if test $RC != 0 ; then - exit $RC - fi - --if test $BACKEND != "bdb" ; then -- $LDAPMODIFY -v -D "$REFINTDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \ -- $TESTOUT 2>&1 << EDEL -+$LDAPMODIFY -v -D "$REFINTDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \ -+ $TESTOUT 2>&1 << EDEL - version: 1 - dn: cn=group,o=refint - changetype: add -@@ -205,65 +204,65 @@ member: uid=theman,ou=users,o=refint - member: uid=richard,ou=users,o=refint - EDEL - -- RC=$? -- if test $RC != 0 ; then -- echo "ldapmodify failed ($RC)!" -- test $KILLSERVERS != no && kill -HUP $KILLPIDS -- exit $RC -- fi -+RC=$? -+if test $RC != 0 ; then -+ echo "ldapmodify failed ($RC)!" -+ test $KILLSERVERS != no && kill -HUP $KILLPIDS -+ exit $RC -+fi - -- sleep 1; -+sleep 1; - -- $LDAPSEARCH -S "" -b "o=refint" -h $LOCALHOST -p $PORT1 \ -- manager member secretary > $SEARCHOUT 2>&1 -- RC=$? -- if test $RC != 0 ; then -- echo "ldapsearch failed ($RC)!" -- test $KILLSERVERS != no && kill -HUP $KILLPIDS -- exit $RC -- fi -+$LDAPSEARCH -S "" -b "o=refint" -h $LOCALHOST -p $PORT1 \ -+ manager member secretary > $SEARCHOUT 2>&1 -+RC=$? -+if test $RC != 0 ; then -+ echo "ldapsearch failed ($RC)!" -+ test $KILLSERVERS != no && kill -HUP $KILLPIDS -+ exit $RC -+fi - -- $EGREP_CMD "(manager|member|secretary):" $SEARCHOUT \ -- | sed "s/ou=users/ou=people/g" | \ -- sort > $TESTOUT 2>&1 -+$EGREP_CMD "(manager|member|secretary):" $SEARCHOUT \ -+ | sed "s/ou=users/ou=people/g" | \ -+ sort > $TESTOUT 2>&1 - -- echo "testing subtree rename" -- $LDAPMODRDN -D "$REFINTDN" -r -h $LOCALHOST -p $PORT1 -w $PASSWD > \ -- /dev/null 2>&1 'ou=users,o=refint' 'ou=people' -- RC=$? -- if test $RC != 0 ; then -- echo "ldapmodrdn failed ($RC)!" -- test $KILLSERVERS != no && kill -HUP $KILLPIDS -- exit $RC -- fi -+echo "testing subtree rename" -+$LDAPMODRDN -D "$REFINTDN" -r -h $LOCALHOST -p $PORT1 -w $PASSWD > \ -+ /dev/null 2>&1 'ou=users,o=refint' 'ou=people' -+RC=$? -+if test $RC != 0 ; then -+ echo "ldapmodrdn failed ($RC)!" -+ test $KILLSERVERS != no && kill -HUP $KILLPIDS -+ exit $RC -+fi - -- sleep 1; -+sleep 1; - -- echo "Using ldapsearch to check dependents new rdn..." -+echo "Using ldapsearch to check dependents new rdn..." - -- $LDAPSEARCH -S "" -b "o=refint" -h $LOCALHOST -p $PORT1 \ -- manager member secretary > $SEARCHOUT 2>&1 -+$LDAPSEARCH -S "" -b "o=refint" -h $LOCALHOST -p $PORT1 \ -+ manager member secretary > $SEARCHOUT 2>&1 - -- RC=$? -- if test $RC != 0 ; then -- echo "ldapsearch failed ($RC)!" -- test $KILLSERVERS != no && kill -HUP $KILLPIDS -- exit $RC -- fi -+RC=$? -+if test $RC != 0 ; then -+ echo "ldapsearch failed ($RC)!" -+ test $KILLSERVERS != no && kill -HUP $KILLPIDS -+ exit $RC -+fi - -- $EGREP_CMD "(manager|member|secretary):" $SEARCHOUT \ -- | sort > $SEARCHFLT 2>&1 -+$EGREP_CMD "(manager|member|secretary):" $SEARCHOUT \ -+ | sort > $SEARCHFLT 2>&1 - -- echo "Comparing ldapsearch results against original..." -- $CMP $TESTOUT $SEARCHFLT > $CMPOUT -+echo "Comparing ldapsearch results against original..." -+$CMP $TESTOUT $SEARCHFLT > $CMPOUT - -- if test $? != 0 ; then -- echo "comparison failed - subtree rename operations did not complete correctly" -- test $KILLSERVERS != no && kill -HUP $KILLPIDS -- exit 1 -- fi -+if test $? != 0 ; then -+ echo "comparison failed - subtree rename operations did not complete correctly" -+ test $KILLSERVERS != no && kill -HUP $KILLPIDS -+ exit 1 - fi - -+ - test $KILLSERVERS != no && kill -HUP $KILLPIDS - - echo ">>>>> Test succeeded" -diff --git a/tests/scripts/test025-limits b/tests/scripts/test025-limits -index 8d39c6b..551b969 100755 ---- a/tests/scripts/test025-limits -+++ b/tests/scripts/test025-limits -@@ -750,7 +750,7 @@ case $RC in - esac - - if test $MAINDB != maindb ; then -- # only bdb|hdb|mdb currently supports pagedResults control -+ # only mdb currently supports pagedResults control - test $KILLSERVERS != no && kill -HUP $KILLPIDS - - echo ">>>>> Test succeeded" -diff --git a/tests/scripts/test036-meta-concurrency b/tests/scripts/test036-meta-concurrency -index 2a4146c..3344f45 100755 ---- a/tests/scripts/test036-meta-concurrency -+++ b/tests/scripts/test036-meta-concurrency -@@ -40,22 +40,6 @@ rm -rf $TESTDIR - - mkdir -p $TESTDIR $DBDIR1 $DBDIR2 - --# NOTE: this could be added to all tests... --if test "$BACKEND" = "bdb" || test "$BACKEND" = "hdb" ; then -- if test "x$DB_CONFIG" != "x" ; then \ -- if test -f $DB_CONFIG ; then -- echo "==> using DB_CONFIG \"$DB_CONFIG\"" -- cp $DB_CONFIG $DBDIR1 -- cp $DB_CONFIG $DBDIR2 -- else -- echo "==> DB_CONFIG must point to a valid file (ignored)" -- fi -- else -- echo "==> set \"DB_CONFIG\" to the DB_CONFIG file you want to use for the test." -- fi -- echo "" --fi -- - echo "Starting slapd on TCP/IP port $PORT1..." - . $CONFFILTER $BACKEND $MONITORDB < $METACONF1 > $CONF1 - $SLAPD -f $CONF1 -h $URI1 -d $LVL $TIMING > $LOG1 2>&1 & -diff --git a/tests/scripts/test040-subtree-rename b/tests/scripts/test040-subtree-rename -index 671d626..f1057d6 100755 ---- a/tests/scripts/test040-subtree-rename -+++ b/tests/scripts/test040-subtree-rename -@@ -16,11 +16,6 @@ - echo "running defines.sh" - . $SRCDIR/scripts/defines.sh - --if test $BACKEND = bdb ; then -- echo "subtree rename not supported by back-$BACKEND" -- exit 0 --fi -- - mkdir -p $TESTDIR $DBDIR1 - - echo "Starting slapd on TCP/IP port $PORT1..." -diff --git a/tests/scripts/test043-delta-syncrepl b/tests/scripts/test043-delta-syncrepl -index 3c7c629..686bf1c 100755 ---- a/tests/scripts/test043-delta-syncrepl -+++ b/tests/scripts/test043-delta-syncrepl -@@ -32,7 +32,7 @@ fi - - mkdir -p $TESTDIR $DBDIR1A $DBDIR1B $DBDIR2 - --SPEC="mdb=a,bdb=a,hdb=a" -+SPEC="mdb=a" - - # - # Test replication: -diff --git a/tests/scripts/test052-memberof b/tests/scripts/test052-memberof -index 4b2a5d9..a73a929 100755 ---- a/tests/scripts/test052-memberof -+++ b/tests/scripts/test052-memberof -@@ -72,11 +72,10 @@ EOF - fi - fi - --indexInclude="" mainInclude="" bdbInclude="# " nullExclude="" -+indexInclude="" mainInclude="" " nullExclude="" - test $INDEXDB = indexdb || indexInclude="# " - test $MAINDB = maindb || mainInclude="# " - case $BACKEND in --bdb | hdb) bdbInclude="" ;; - null) nullExclude="# " ;; - esac - -@@ -114,7 +113,6 @@ olcRootDN: cn=Manager,$BASEDN - olcRootPW:: c2VjcmV0 - olcMonitoring: TRUE - ${nullExclude}olcDbDirectory: $TESTDIR/db.1.a/ --${bdbInclude}olcDbCacheSize: 1000 - ${indexInclude}olcDbIndex: objectClass eq - ${indexInclude}olcDbIndex: cn pres,eq,sub - ${indexInclude}olcDbIndex: uid pres,eq,sub -diff --git a/tests/scripts/test056-monitor b/tests/scripts/test056-monitor -index 06713df..7a87eaa 100755 ---- a/tests/scripts/test056-monitor -+++ b/tests/scripts/test056-monitor -@@ -85,8 +85,7 @@ echo "Using ldapsearch to read database monitor entries..." - $LDAPSEARCH -S "" -b "$DATABASESMONITORDN" -h $LOCALHOST -p $PORT1 \ - 'objectclass=*' \ - structuralObjectClass entryDN namingContexts readOnly \ -- monitorIsShadow monitorContext \ -- olmBDBEntryCache olmBDBDNCache olmBDBIDLCache \ -+ monitorIsShadow monitorContext - > $SEARCHOUT 2>&1 - RC=$? - -@@ -101,11 +100,8 @@ $LDIFFILTER -b monitor < $SEARCHOUT > $SEARCHFLT - - TMPMONITOROUT2=$MONITOROUT2 - case $BACKEND in --bdb|hdb) -- ;; - *) - TMPMONITOROUT2=$TESTDIR/monitor2.out -- grep -v "olmBDB" $MONITOROUT2 > $TMPMONITOROUT2 - ;; - esac - -diff --git a/tests/scripts/test057-memberof-refint b/tests/scripts/test057-memberof-refint -index 5f02a77..ba480f8 100755 ---- a/tests/scripts/test057-memberof-refint -+++ b/tests/scripts/test057-memberof-refint -@@ -27,11 +27,6 @@ if test $REFINT = refintno; then - exit 0 - fi - --if test $BACKEND = bdb; then -- echo "$BACKEND backend does not support subtree rename, test skipped" -- exit 0 --fi -- - mkdir -p $TESTDIR $DBDIR1 $TESTDIR/confdir - - $SLAPPASSWD -g -n >$CONFIGPWF -@@ -66,11 +61,10 @@ fi - - cat /dev/null > $TESTOUT - --indexInclude="" mainInclude="" bdbInclude="# " nullExclude="" -+indexInclude="" mainInclude="" nullExclude="" - test $INDEXDB = indexdb || indexInclude="# " - test $MAINDB = maindb || mainInclude="# " - case $BACKEND in --bdb | hdb) bdbInclude="" ;; - null) nullExclude="# " ;; - esac - -@@ -104,7 +98,6 @@ olcRootDN: cn=Manager,$BASEDN - olcRootPW:: c2VjcmV0 - olcMonitoring: TRUE - ${nullExclude}olcDbDirectory: $TESTDIR/db.1.a/ --${bdbInclude}olcDbCacheSize: 1000 - ${indexInclude}olcDbIndex: objectClass eq - ${indexInclude}olcDbIndex: cn pres,eq,sub - ${indexInclude}olcDbIndex: uid pres,eq,sub -diff --git a/tests/scripts/test061-syncreplication-initiation b/tests/scripts/test061-syncreplication-initiation -index 5d27e52..fda7a1b 100755 ---- a/tests/scripts/test061-syncreplication-initiation -+++ b/tests/scripts/test061-syncreplication-initiation -@@ -63,7 +63,6 @@ KILLPIDS= - $SLAPPASSWD -g -n >$CONFIGPWF - - case "$BACKEND" in -- bdb|hdb) olcDbCheckpoint="olcDbCheckpoint";; - *) olcDbCheckpoint="# olcDbCheckpoint";; - esac - --- -2.19.1 - diff --git a/openldap.spec b/openldap.spec index f7d6932..1356ad2 100644 --- a/openldap.spec +++ b/openldap.spec @@ -57,13 +57,9 @@ Patch36: CVE-2020-36227.patch Patch37: CVE-2020-36228.patch Patch38: CVE-2020-36230.patch Patch39: CVE-2020-36229.patch -Patch40: backport-delete-back-bdb-back-hdb.patch -Patch41: backport-Fix-test-suite.patch -Patch42: backport-ITS-9010-regenerate-configure.patch -Patch43: backport-ITS-9010-More-BDB-HDB-cleanup.patch -Patch44: CVE-2021-27212.patch -Patch45: CVE-2020-25709.patch -Patch46: CVE-2020-25710.patch +Patch40: CVE-2021-27212.patch +Patch41: CVE-2020-25709.patch +Patch42: CVE-2020-25710.patch BuildRequires: cyrus-sasl-devel openssl-devel krb5-devel unixODBC-devel BuildRequires: glibc-devel libtool libtool-ltdl-devel groff perl-interpreter perl-devel perl-generators perl-ExtUtils-Embed @@ -168,7 +164,9 @@ AUTOMAKE=%{_bindir}/true autoreconf -fi %patch37 -p1 %patch38 -p1 %patch39 -p1 - +%patch40 -p1 +%patch41 -p1 +%patch42 -p1 ln -s ../../../contrib/slapd-modules/smbk5pwd/smbk5pwd.c servers/slapd/overlays mv contrib/slapd-modules/smbk5pwd/README contrib/slapd-modules/smbk5pwd/README.smbk5pwd ln -s ../../../contrib/slapd-modules/allop/allop.c servers/slapd/overlays @@ -455,10 +453,6 @@ popd - ID:NA - SUG:restart - DESC: fix CVE-2020-25709 CVE-2020-25710 CVE-2021-27212 - delete back-bdb and back-hdb - fix test-suite - cleanup ITS-9010-More-BDB-HDB - regenerate configure of ITS-9010 * Thu Feb 18 2021 liulong - 2.4.50-5 - Type:cves -- Gitee From aaaaf1dcaa9df9c9ad272d35265f711af9bd0d93 Mon Sep 17 00:00:00 2001 From: zengwefeng Date: Fri, 29 Oct 2021 15:08:27 +0800 Subject: [PATCH 3/3] fix test-suite --- backport-Fix-test-suite.patch | 71 +++++++++++++++++++++++++++++++++++ openldap.spec | 3 ++ 2 files changed, 74 insertions(+) create mode 100644 backport-Fix-test-suite.patch diff --git a/backport-Fix-test-suite.patch b/backport-Fix-test-suite.patch new file mode 100644 index 0000000..cc8f72e --- /dev/null +++ b/backport-Fix-test-suite.patch @@ -0,0 +1,71 @@ +From 70f87370f99e78ac3874501bfe5124dbb86185a8 Mon Sep 17 00:00:00 2001 +From: zhangqiumiao +Date: Fri, 25 Sep 2020 21:56:43 +0800 +Subject: [PATCH] backport Fix test suite + +--- + tests/data/monitor2.out | 3 --- + tests/scripts/test052-memberof | 2 +- + tests/scripts/test056-monitor | 11 ++--------- + 3 files changed, 3 insertions(+), 13 deletions(-) + +diff --git a/tests/data/monitor2.out b/tests/data/monitor2.out +index 26e9ce9..20209d1 100644 +--- a/tests/data/monitor2.out ++++ b/tests/data/monitor2.out +@@ -10,9 +10,6 @@ structuralObjectClass: monitoredObject + monitorIsShadow: FALSE + namingContexts: o=OpenLDAP Project,l=Internet + readOnly: FALSE +-olmBDBEntryCache: 0 +-olmBDBDNCache: 0 +-olmBDBIDLCache: 0 + entryDN: cn=Database 1,cn=Databases,cn=Monitor + + dn: cn=Database 2,cn=Databases,cn=Monitor +diff --git a/tests/scripts/test052-memberof b/tests/scripts/test052-memberof +index a73a929..1dba946 100755 +--- a/tests/scripts/test052-memberof ++++ b/tests/scripts/test052-memberof +@@ -72,7 +72,7 @@ EOF + fi + fi + +-indexInclude="" mainInclude="" " nullExclude="" ++indexInclude="" mainInclude="" nullExclude="" + test $INDEXDB = indexdb || indexInclude="# " + test $MAINDB = maindb || mainInclude="# " + case $BACKEND in +diff --git a/tests/scripts/test056-monitor b/tests/scripts/test056-monitor +index 7a87eaa..0e1ba20 100755 +--- a/tests/scripts/test056-monitor ++++ b/tests/scripts/test056-monitor +@@ -85,7 +85,7 @@ echo "Using ldapsearch to read database monitor entries..." + $LDAPSEARCH -S "" -b "$DATABASESMONITORDN" -h $LOCALHOST -p $PORT1 \ + 'objectclass=*' \ + structuralObjectClass entryDN namingContexts readOnly \ +- monitorIsShadow monitorContext ++ monitorIsShadow monitorContext \ + > $SEARCHOUT 2>&1 + RC=$? + +@@ -98,15 +98,8 @@ fi + echo "Filtering ldapsearch results..." + $LDIFFILTER -b monitor < $SEARCHOUT > $SEARCHFLT + +-TMPMONITOROUT2=$MONITOROUT2 +-case $BACKEND in +-*) +- TMPMONITOROUT2=$TESTDIR/monitor2.out +- ;; +-esac +- + echo "Comparing filter output..." +-$CMP $SEARCHFLT $TMPMONITOROUT2 > $CMPOUT ++$CMP $SEARCHFLT $MONITOROUT2 > $CMPOUT + + if test $? != 0 ; then + echo "comparison failed - database monitor output is not correct" +-- +2.19.1 + diff --git a/openldap.spec b/openldap.spec index 1356ad2..78b7791 100644 --- a/openldap.spec +++ b/openldap.spec @@ -60,6 +60,7 @@ Patch39: CVE-2020-36229.patch Patch40: CVE-2021-27212.patch Patch41: CVE-2020-25709.patch Patch42: CVE-2020-25710.patch +Patch43: backport-Fix-test-suite.patch BuildRequires: cyrus-sasl-devel openssl-devel krb5-devel unixODBC-devel BuildRequires: glibc-devel libtool libtool-ltdl-devel groff perl-interpreter perl-devel perl-generators perl-ExtUtils-Embed @@ -167,6 +168,8 @@ AUTOMAKE=%{_bindir}/true autoreconf -fi %patch40 -p1 %patch41 -p1 %patch42 -p1 +%patch43 -p1 + ln -s ../../../contrib/slapd-modules/smbk5pwd/smbk5pwd.c servers/slapd/overlays mv contrib/slapd-modules/smbk5pwd/README contrib/slapd-modules/smbk5pwd/README.smbk5pwd ln -s ../../../contrib/slapd-modules/allop/allop.c servers/slapd/overlays -- Gitee