Merge ~sergiodj/ubuntu/+source/openldap:mre-2.5.13-jammy into ubuntu/+source/openldap:ubuntu/jammy-devel

Proposed by Sergio Durigan Junior
Status: Merged
Approved by: git-ubuntu bot
Approved revision: not available
Merged at revision: fa9256815f981289f4c9a7a27e0baadce250b561
Proposed branch: ~sergiodj/ubuntu/+source/openldap:mre-2.5.13-jammy
Merge into: ubuntu/+source/openldap:ubuntu/jammy-devel
Diff against target: 2629 lines (+1610/-143)
50 files modified
CHANGES (+25/-0)
build/version.var (+4/-4)
clients/tools/ldapsearch.c (+4/-3)
configure (+8/-1)
configure.ac (+9/-2)
contrib/slapd-modules/autogroup/autogroup.c (+1/-1)
contrib/slapd-modules/autogroup/slapo-autogroup.5 (+5/-0)
contrib/slapd-modules/emptyds/Makefile (+78/-0)
contrib/slapd-modules/emptyds/README (+66/-0)
contrib/slapd-modules/emptyds/emptyds.c (+325/-0)
contrib/slapd-modules/emptyds/slapo-emptyds.5 (+68/-0)
contrib/slapd-modules/emptyds/tests/Rules.mk (+23/-0)
contrib/slapd-modules/emptyds/tests/data/emptyds.conf (+54/-0)
contrib/slapd-modules/emptyds/tests/data/test001.ldif (+71/-0)
contrib/slapd-modules/emptyds/tests/data/test001.out (+54/-0)
contrib/slapd-modules/emptyds/tests/run (+218/-0)
contrib/slapd-modules/emptyds/tests/scripts/all (+92/-0)
contrib/slapd-modules/emptyds/tests/scripts/test001-emptyds (+137/-0)
debian/changelog (+8/-0)
doc/guide/admin/guide.html (+1/-1)
doc/man/man3/ldap_get_option.3 (+2/-2)
doc/man/man5/slapd-ldap.5 (+3/-1)
doc/man/man5/slapd-meta.5 (+3/-1)
libraries/Makefile.in (+1/-1)
libraries/libldap/deref.c (+4/-10)
libraries/libldap/ldif.c (+2/-1)
libraries/libldap/turn.c (+6/-6)
libraries/libldap/txn.c (+6/-6)
libraries/librewrite/rewrite-int.h (+5/-5)
servers/lloadd/operation.c (+4/-3)
servers/slapd/back-mdb/id2entry.c (+10/-0)
servers/slapd/backend.c (+13/-18)
servers/slapd/backglue.c (+6/-0)
servers/slapd/bind.c (+1/-1)
servers/slapd/ctxcsn.c (+14/-14)
servers/slapd/daemon.c (+2/-3)
servers/slapd/frontend.c (+1/-1)
servers/slapd/overlays/accesslog.c (+2/-0)
servers/slapd/overlays/pcache.c (+0/-1)
servers/slapd/overlays/ppolicy.c (+13/-11)
servers/slapd/overlays/syncprov.c (+60/-10)
servers/slapd/overlays/translucent.c (+1/-1)
servers/slapd/overlays/unique.c (+18/-14)
servers/slapd/slap.h (+9/-3)
servers/slapd/syncrepl.c (+6/-9)
tests/data/slapd-deltasync-provider.conf (+4/-0)
tests/progs/Makefile.in (+1/-1)
tests/progs/slapd-watcher.c (+14/-7)
tests/scripts/test020-proxycache (+5/-0)
tests/scripts/test043-delta-syncrepl (+143/-1)
Reviewer Review Type Date Requested Status
git-ubuntu bot Approve
Bryce Harrington (community) Approve
Canonical Server Reporter Pending
Review via email: mp+427967@code.launchpad.net

Description of the change

This is the MRE for OpenLDAP 2.5.13.

The MRE bug with all the relevant details is bug #1983618.

You can see the bileto ticket here: https://bileto.ubuntu.com/#/ticket/4887

Unfortunately, the "automated test results" link is not working for this ticket. You will need to resort to lp-test-ppa in order to check the results.

As usual with MREs, the review should probably be performed locally instead of via LP's web interface, due to the amount of changes being proposed.

To post a comment you must log in.
Revision history for this message
Sergio Durigan Junior (sergiodj) wrote :

It looks like bileto's "automated test results" link is working again, so I've created another ticket:

https://bileto.ubuntu.com/#/ticket/4895

Revision history for this message
Bryce Harrington (bryce) wrote :
Download full text (3.4 KiB)

The lp-test-ppa results for openldap itself look good:

Results: (from http://autopkgtest.ubuntu.com/results/autopkgtest-jammy-ci-train-ppa-service-4895/?format=plain)
  openldap @ amd64:
    09.08.22 19:47:31 Log 🗒️ ✅ Triggers: openldap/2.5.13+dfsg-0ubuntu0.22.04.1~ppa1, django-ldapdb/1.5.1-3, krb5/1.19.2-2, nss-pam-ldapd/0.9.12-2, nsscache/0.42-2, openvpn-auth-ldap/2.0.4-1ubuntu4, python-bonsai/1.3.0+ds-3build1, sssd/2.6.3-1ubuntu3.1, sudo/1.9.9-1ubuntu2, volatildap/1.3.0-2ubuntu4
  openldap @ arm64:
    09.08.22 20:03:51 Log 🗒️ ✅ Triggers: openldap/2.5.13+dfsg-0ubuntu0.22.04.1~ppa1, django-ldapdb/1.5.1-3, krb5/1.19.2-2, nss-pam-ldapd/0.9.12-2, nsscache/0.42-2, openvpn-auth-ldap/2.0.4-1ubuntu4, python-bonsai/1.3.0+ds-3build1, sssd/2.6.3-1ubuntu3.1, sudo/1.9.9-1ubuntu2, volatildap/1.3.0-2ubuntu4
  openldap @ armhf:
    09.08.22 20:03:30 Log 🗒️ ✅ Triggers: openldap/2.5.13+dfsg-0ubuntu0.22.04.1~ppa1, django-ldapdb/1.5.1-3, krb5/1.19.2-2, nss-pam-ldapd/0.9.12-2, nsscache/0.42-2, openvpn-auth-ldap/2.0.4-1ubuntu4, python-bonsai/1.3.0+ds-3build1, sssd/2.6.3-1ubuntu3.1, sudo/1.9.9-1ubuntu2, volatildap/1.3.0-2ubuntu4
  openldap @ ppc64el:
    09.08.22 19:59:53 Log 🗒️ ✅ Triggers: openldap/2.5.13+dfsg-0ubuntu0.22.04.1~ppa1, django-ldapdb/1.5.1-3, krb5/1.19.2-2, nss-pam-ldapd/0.9.12-2, nsscache/0.42-2, openvpn-auth-ldap/2.0.4-1ubuntu4, python-bonsai/1.3.0+ds-3build1, sssd/2.6.3-1ubuntu3.1, sudo/1.9.9-1ubuntu2, volatildap/1.3.0-2ubuntu4
  openldap @ s390x:
    09.08.22 19:58:54 Log 🗒️ ✅ Triggers: openldap/2.5.13+dfsg-0ubuntu0.22.04.1~ppa1, django-ldapdb/1.5.1-3, krb5/1.19.2-2, nss-pam-ldapd/0.9.12-2, nsscache/0.42-2, openvpn-auth-ldap/2.0.4-1ubuntu4, python-bonsai/1.3.0+ds-3build1, sssd/2.6.3-1ubuntu3.1, sudo/1.9.9-1ubuntu2, volatildap/1.3.0-2ubuntu4

For the broader test dependencies, at least some of the failures (apache2, e.g.) are likely going to be flaky issues. I don't know if a clean bileto run is required for MREs, although certainly sounds like it should be a best practice. In any case, will be some time before those are processed so will leave those to your discretion for any followup.

I did a cursory skim type code review. As documented, there are various bug fixes but most substantial code changes are to slapd, and most of that is the emptyds additions. The emptyds overlay feels like it may be considered more a new feature than a bug fix? If so, may be worth special highlight in the changelog and SRU bug report. It might also be helpful for reviewers to copy and paste in the list of fixes from the release note, into the SRU, i.e.:

    Fixed librewrite declaration of calloc (ITS#9841)
    Fixed libldap memory leaks (ITS#9876)
    Fixed slapd kqueue support (ITS#9847)
    Fixed slapd delta-sync DN leak on ADD ops (ITS#9866)
    Fixed slapd replication with back-glue (ITS#9868)
    Fixed slapd-mdb to check for stale readers on MDB_READERS_FULL (ITS#7165)
    Fixed slapo-accesslog onetime memory leak (ITS#9864)
    Fixed slapo-ppolicy interaction with slapo-rwm (ITS#9871)
    Fixed slapo-syncprov memory leaks (ITS#9867)
    Fixed slapo-syncprov fallback in delta-sync mode (ITS#9823)
    Fixed slapo-uniq...

Read more...

review: Approve
Revision history for this message
git-ubuntu bot (git-ubuntu-bot) wrote :

Approvers: sergiodj, bryce
Uploaders: sergiodj, bryce
MP auto-approved

review: Approve
Revision history for this message
Sergio Durigan Junior (sergiodj) wrote :
Download full text (4.4 KiB)

On Tuesday, August 09 2022, Bryce Harrington wrote:

> The lp-test-ppa results for openldap itself look good:
>
> Results: (from http://autopkgtest.ubuntu.com/results/autopkgtest-jammy-ci-train-ppa-service-4895/?format=plain)
> openldap @ amd64:
> 09.08.22 19:47:31 Log 🗒️ ✅ Triggers: openldap/2.5.13+dfsg-0ubuntu0.22.04.1~ppa1, django-ldapdb/1.5.1-3, krb5/1.19.2-2, nss-pam-ldapd/0.9.12-2, nsscache/0.42-2, openvpn-auth-ldap/2.0.4-1ubuntu4, python-bonsai/1.3.0+ds-3build1, sssd/2.6.3-1ubuntu3.1, sudo/1.9.9-1ubuntu2, volatildap/1.3.0-2ubuntu4
> openldap @ arm64:
> 09.08.22 20:03:51 Log 🗒️ ✅ Triggers: openldap/2.5.13+dfsg-0ubuntu0.22.04.1~ppa1, django-ldapdb/1.5.1-3, krb5/1.19.2-2, nss-pam-ldapd/0.9.12-2, nsscache/0.42-2, openvpn-auth-ldap/2.0.4-1ubuntu4, python-bonsai/1.3.0+ds-3build1, sssd/2.6.3-1ubuntu3.1, sudo/1.9.9-1ubuntu2, volatildap/1.3.0-2ubuntu4
> openldap @ armhf:
> 09.08.22 20:03:30 Log 🗒️ ✅ Triggers: openldap/2.5.13+dfsg-0ubuntu0.22.04.1~ppa1, django-ldapdb/1.5.1-3, krb5/1.19.2-2, nss-pam-ldapd/0.9.12-2, nsscache/0.42-2, openvpn-auth-ldap/2.0.4-1ubuntu4, python-bonsai/1.3.0+ds-3build1, sssd/2.6.3-1ubuntu3.1, sudo/1.9.9-1ubuntu2, volatildap/1.3.0-2ubuntu4
> openldap @ ppc64el:
> 09.08.22 19:59:53 Log 🗒️ ✅ Triggers: openldap/2.5.13+dfsg-0ubuntu0.22.04.1~ppa1, django-ldapdb/1.5.1-3, krb5/1.19.2-2, nss-pam-ldapd/0.9.12-2, nsscache/0.42-2, openvpn-auth-ldap/2.0.4-1ubuntu4, python-bonsai/1.3.0+ds-3build1, sssd/2.6.3-1ubuntu3.1, sudo/1.9.9-1ubuntu2, volatildap/1.3.0-2ubuntu4
> openldap @ s390x:
> 09.08.22 19:58:54 Log 🗒️ ✅ Triggers: openldap/2.5.13+dfsg-0ubuntu0.22.04.1~ppa1, django-ldapdb/1.5.1-3, krb5/1.19.2-2, nss-pam-ldapd/0.9.12-2, nsscache/0.42-2, openvpn-auth-ldap/2.0.4-1ubuntu4, python-bonsai/1.3.0+ds-3build1, sssd/2.6.3-1ubuntu3.1, sudo/1.9.9-1ubuntu2, volatildap/1.3.0-2ubuntu4
>
> For the broader test dependencies, at least some of the failures (apache2, e.g.) are likely going to be flaky issues. I don't know if a clean bileto run is required for MREs, although certainly sounds like it should be a best practice. In any case, will be some time before those are processed so will leave those to your discretion for any followup.

Thank you for the review, Bryce.

I always strive to have a clean bileto run, but it's currently
impossible to achieve it because of some pre-existing failures (apache2
is indeed one of them). There are a lot of tests still happening on
https://bileto.ubuntu.com/excuses/4895/jammy.html, so I will make sure
to wait for them to finish before I upload.

> I did a cursory skim type code review. As documented, there are various bug fixes but most substantial code changes are to slapd, and most of that is the emptyds additions. The emptyds overlay feels like it may be considered more a new feature than a bug fix? If so, may be worth special highlight in the changelog and SRU bug report. It might also be helpful for reviewers to copy and paste in the list of fixes from the release note, into the SRU, i.e.:
>
> Fixed librewrite declaration of calloc (ITS#9841)
> Fixed libldap memory leaks (ITS#9876)
> Fixed slapd kqueue support (ITS#984...

Read more...

Revision history for this message
Sergio Durigan Junior (sergiodj) wrote :
Download full text (4.4 KiB)

On Tuesday, August 09 2022, Bryce Harrington wrote:

> The lp-test-ppa results for openldap itself look good:
>
> Results: (from http://autopkgtest.ubuntu.com/results/autopkgtest-jammy-ci-train-ppa-service-4895/?format=plain)
> openldap @ amd64:
> 09.08.22 19:47:31 Log 🗒️ ✅ Triggers: openldap/2.5.13+dfsg-0ubuntu0.22.04.1~ppa1, django-ldapdb/1.5.1-3, krb5/1.19.2-2, nss-pam-ldapd/0.9.12-2, nsscache/0.42-2, openvpn-auth-ldap/2.0.4-1ubuntu4, python-bonsai/1.3.0+ds-3build1, sssd/2.6.3-1ubuntu3.1, sudo/1.9.9-1ubuntu2, volatildap/1.3.0-2ubuntu4
> openldap @ arm64:
> 09.08.22 20:03:51 Log 🗒️ ✅ Triggers: openldap/2.5.13+dfsg-0ubuntu0.22.04.1~ppa1, django-ldapdb/1.5.1-3, krb5/1.19.2-2, nss-pam-ldapd/0.9.12-2, nsscache/0.42-2, openvpn-auth-ldap/2.0.4-1ubuntu4, python-bonsai/1.3.0+ds-3build1, sssd/2.6.3-1ubuntu3.1, sudo/1.9.9-1ubuntu2, volatildap/1.3.0-2ubuntu4
> openldap @ armhf:
> 09.08.22 20:03:30 Log 🗒️ ✅ Triggers: openldap/2.5.13+dfsg-0ubuntu0.22.04.1~ppa1, django-ldapdb/1.5.1-3, krb5/1.19.2-2, nss-pam-ldapd/0.9.12-2, nsscache/0.42-2, openvpn-auth-ldap/2.0.4-1ubuntu4, python-bonsai/1.3.0+ds-3build1, sssd/2.6.3-1ubuntu3.1, sudo/1.9.9-1ubuntu2, volatildap/1.3.0-2ubuntu4
> openldap @ ppc64el:
> 09.08.22 19:59:53 Log 🗒️ ✅ Triggers: openldap/2.5.13+dfsg-0ubuntu0.22.04.1~ppa1, django-ldapdb/1.5.1-3, krb5/1.19.2-2, nss-pam-ldapd/0.9.12-2, nsscache/0.42-2, openvpn-auth-ldap/2.0.4-1ubuntu4, python-bonsai/1.3.0+ds-3build1, sssd/2.6.3-1ubuntu3.1, sudo/1.9.9-1ubuntu2, volatildap/1.3.0-2ubuntu4
> openldap @ s390x:
> 09.08.22 19:58:54 Log 🗒️ ✅ Triggers: openldap/2.5.13+dfsg-0ubuntu0.22.04.1~ppa1, django-ldapdb/1.5.1-3, krb5/1.19.2-2, nss-pam-ldapd/0.9.12-2, nsscache/0.42-2, openvpn-auth-ldap/2.0.4-1ubuntu4, python-bonsai/1.3.0+ds-3build1, sssd/2.6.3-1ubuntu3.1, sudo/1.9.9-1ubuntu2, volatildap/1.3.0-2ubuntu4
>
> For the broader test dependencies, at least some of the failures (apache2, e.g.) are likely going to be flaky issues. I don't know if a clean bileto run is required for MREs, although certainly sounds like it should be a best practice. In any case, will be some time before those are processed so will leave those to your discretion for any followup.

Thank you for the review, Bryce.

I always strive to have a clean bileto run, but it's currently
impossible to achieve it because of some pre-existing failures (apache2
is indeed one of them). There are a lot of tests still happening on
https://bileto.ubuntu.com/excuses/4895/jammy.html, so I will make sure
to wait for them to finish before I upload.

> I did a cursory skim type code review. As documented, there are various bug fixes but most substantial code changes are to slapd, and most of that is the emptyds additions. The emptyds overlay feels like it may be considered more a new feature than a bug fix? If so, may be worth special highlight in the changelog and SRU bug report. It might also be helpful for reviewers to copy and paste in the list of fixes from the release note, into the SRU, i.e.:
>
> Fixed librewrite declaration of calloc (ITS#9841)
> Fixed libldap memory leaks (ITS#9876)
> Fixed slapd kqueue support (ITS#984...

Read more...

Revision history for this message
Sergio Durigan Junior (sergiodj) wrote :

I have the results for the dep8 tests now. Everything seems fine; the few failures I see are all accounted for.

Uploaded:

$ dput openldap_2.5.13+dfsg-0ubuntu0.22.04.1_source.changes
Trying to upload package to ubuntu
Checking signature on .changes
gpg: /home/sergio/work/openldap/openldap_2.5.13+dfsg-0ubuntu0.22.04.1_source.changes: Valid signature from 106DA1C8C3CBBF14
Checking signature on .dsc
gpg: /home/sergio/work/openldap/openldap_2.5.13+dfsg-0ubuntu0.22.04.1.dsc: Valid signature from 106DA1C8C3CBBF14
Package includes an .orig.tar.gz file although the debian revision suggests
that it might not be required. Multiple uploads of the .orig.tar.gz may be
rejected by the upload queue management software.
Uploading to ubuntu (via ftp to upload.ubuntu.com):
  Uploading openldap_2.5.13+dfsg-0ubuntu0.22.04.1.dsc: done.
  Uploading openldap_2.5.13+dfsg.orig.tar.gz: done.
  Uploading openldap_2.5.13+dfsg-0ubuntu0.22.04.1.debian.tar.xz: done.
  Uploading openldap_2.5.13+dfsg-0ubuntu0.22.04.1_source.buildinfo: done.
  Uploading openldap_2.5.13+dfsg-0ubuntu0.22.04.1_source.changes: done.
Successfully uploaded packages.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/CHANGES b/CHANGES
2index d8092be..736656d 100644
3--- a/CHANGES
4+++ b/CHANGES
5@@ -1,5 +1,30 @@
6 OpenLDAP 2.5 Change Log
7
8+OpenLDAP 2.5.13 Release (2022/07/14)
9+ Fixed librewrite declaration of calloc (ITS#9841)
10+ Fixed libldap memory leaks (ITS#9876)
11+ Fixed slapd kqueue support (ITS#9847)
12+ Fixed slapd delta-sync DN leak on ADD ops (ITS#9866)
13+ Fixed slapd replication with back-glue (ITS#9868)
14+ Fixed slapd-mdb to check for stale readers on MDB_READERS_FULL (ITS#7165)
15+ Fixed slapo-accesslog onetime memory leak (ITS#9864)
16+ Fixed slapo-ppolicy interaction with slapo-rwm (ITS#9871)
17+ Fixed slapo-syncprov memory leaks (ITS#9867)
18+ Fixed slapo-syncprov fallback in delta-sync mode (ITS#9823)
19+ Fixed slapo-unique to not release NULL entry (ITS#8245)
20+ Build Environment
21+ Added slapd-watcher -c contextDN option (ITS#9865)
22+ Fixed parallel builds (ITS#9840)
23+ Fixed test020 to skip back-wt (ITS#9859)
24+ Fixed slapd-watcher SID handling with single URI (ITS#9850)
25+ Fixed test043 with workaround for ITS#9878
26+ Contrib
27+ Added slapo-emptyds contrib module (ITS#8882)
28+ Fixed slapo-autogroup backwards compat (ITS#9020)
29+ Documentation
30+ Fixed ldap_get_option(3) to clarify ldap_get/set_option restrictions (ITS#9824)
31+ Fixed slapd-ldap(5),slapd-meta(5) missing bold tag on authz parameter (ITS#9872)
32+
33 OpenLDAP 2.5.12 Release (2022/05/04)
34 Fixed libldap to drop connection when non-LDAP data is received (ITS#9803)
35 Fixed libldap to allow newlines at end of included file (ITS#9811)
36diff --git a/build/version.var b/build/version.var
37index df94973..64ac2df 100644
38--- a/build/version.var
39+++ b/build/version.var
40@@ -15,9 +15,9 @@
41 ol_package=OpenLDAP
42 ol_major=2
43 ol_minor=5
44-ol_patch=12
45-ol_api_inc=20512
46+ol_patch=13
47+ol_api_inc=20513
48 ol_api_current=1
49-ol_api_revision=7
50+ol_api_revision=8
51 ol_api_age=1
52-ol_release_date="2022/05/04"
53+ol_release_date="2022/07/14"
54diff --git a/clients/tools/ldapsearch.c b/clients/tools/ldapsearch.c
55index a0ca0d7..02b49bd 100644
56--- a/clients/tools/ldapsearch.c
57+++ b/clients/tools/ldapsearch.c
58@@ -1866,12 +1866,13 @@ again:
59 if ( ldapsync && sync_slimit != -1 &&
60 nresponses_psearch >= sync_slimit ) {
61 BerElement *msgidber = NULL;
62- struct berval *msgidvalp = NULL;
63+ struct berval msgidval;
64 msgidber = ber_alloc_t(LBER_USE_DER);
65 ber_printf(msgidber, "{i}", msgid);
66- ber_flatten(msgidber, &msgidvalp);
67+ ber_flatten2( msgidber, &msgidval, 0 );
68 ldap_extended_operation(ld, LDAP_EXOP_CANCEL,
69- msgidvalp, NULL, NULL, &cancel_msgid);
70+ &msgidval, NULL, NULL, &cancel_msgid);
71+ ber_free( msgidber, 1 );
72 nresponses_psearch = -1;
73 }
74 }
75diff --git a/configure b/configure
76index bea23a1..f0513cb 100755
77--- a/configure
78+++ b/configure
79@@ -1,5 +1,5 @@
80 #! /bin/sh
81-# From configure.ac Id: 1c372d9fe8d80795909df859a01abd486462d0a2 .
82+# From configure.ac Id: 15bca89511fc428731cf9ab71a9b46e37511be67 .
83 # Guess values for system-dependent variables and create Makefiles.
84 # Generated by GNU Autoconf 2.69.
85 #
86@@ -16316,6 +16316,13 @@ $as_echo "no" >&6; }
87 else
88 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
89 /* end confdefs.h. */
90+$ac_includes_default
91+#ifdef HAVE_SYS_EVENT_H
92+#include <sys/event.h>
93+#endif
94+#ifdef HAVE_SYS_TIME_H
95+#include <sys/time.h>
96+#endif
97 int main(int argc, char **argv)
98 {
99 int kqfd = kqueue();
100diff --git a/configure.ac b/configure.ac
101index 0978eeb..626d024 100644
102--- a/configure.ac
103+++ b/configure.ac
104@@ -25,7 +25,7 @@ dnl ================================================================
105 dnl Configure.in for OpenLDAP
106 AC_COPYRIGHT([[Copyright 1998-2022 The OpenLDAP Foundation. All rights reserved.
107 Restrictions apply, see COPYRIGHT and LICENSE files.]])
108-AC_REVISION([$Id: 63b192fdc3ddaf2eabc322c60cd7066c9252e1d8 $])
109+AC_REVISION([$Id: 15bca89511fc428731cf9ab71a9b46e37511be67 $])
110 AC_INIT([OpenLDAP],,[https://bugs.openldap.org],,[https://www.openldap.org])
111 AC_CONFIG_SRCDIR(build/version.sh)dnl
112 dnl ----------------------------------------------------------------
113@@ -1022,7 +1022,14 @@ dnl ----------------------------------------------------------------
114 AC_CHECK_HEADERS( sys/event.h )
115 if test "${ac_cv_header_sys_event_h}" = yes; then
116 AC_MSG_CHECKING(for kqueue system call)
117-AC_RUN_IFELSE([AC_LANG_SOURCE([[int main(int argc, char **argv)
118+AC_RUN_IFELSE([AC_LANG_SOURCE([[$ac_includes_default
119+#ifdef HAVE_SYS_EVENT_H
120+#include <sys/event.h>
121+#endif
122+#ifdef HAVE_SYS_TIME_H
123+#include <sys/time.h>
124+#endif
125+int main(int argc, char **argv)
126 {
127 int kqfd = kqueue();
128 exit (kqfd == -1 ? 1 : 0);
129diff --git a/contrib/slapd-modules/autogroup/autogroup.c b/contrib/slapd-modules/autogroup/autogroup.c
130index 926703f..cbcedfe 100644
131--- a/contrib/slapd-modules/autogroup/autogroup.c
132+++ b/contrib/slapd-modules/autogroup/autogroup.c
133@@ -1733,7 +1733,7 @@ static ConfigTable agcfg[] = {
134
135 static ConfigOCs agocs[] = {
136 { "( OLcfgCtOc:2.1 "
137- "NAME 'olcAutoGroupConfig' "
138+ "NAME ( 'olcAutoGroupConfig' 'olcAutomaticGroups' ) "
139 "DESC 'Automatic groups configuration' "
140 "SUP olcOverlayConfig "
141 "MAY ( "
142diff --git a/contrib/slapd-modules/autogroup/slapo-autogroup.5 b/contrib/slapd-modules/autogroup/slapo-autogroup.5
143index 86fa1a1..4c6414d 100644
144--- a/contrib/slapd-modules/autogroup/slapo-autogroup.5
145+++ b/contrib/slapd-modules/autogroup/slapo-autogroup.5
146@@ -93,10 +93,15 @@ The autogroup overlay has been reworked with the 2.5 release to use
147 a consistent namespace as with other overlays. As a side-effect the
148 following cn=config parameters are deprecated and will be removed in
149 a future release:
150+.IP \[bu] 2
151 .B olcAGattrSet
152 is replaced with olcAutoGroupAttrSet
153+.IP \[bu]
154 .B olcAGmemberOfAd
155 is replaced with olcAutoGroupMemberOfAd
156+.IP \[bu]
157+.B olcAutomaticGroups
158+is replaced with olcAutoGroupConfig
159 .SH ACKNOWLEDGEMENTS
160 This module was originally written in 2007 by Michał
161 Szulczyński. Further enhancements were contributed by Howard
162diff --git a/contrib/slapd-modules/emptyds/Makefile b/contrib/slapd-modules/emptyds/Makefile
163new file mode 100644
164index 0000000..654f856
165--- /dev/null
166+++ b/contrib/slapd-modules/emptyds/Makefile
167@@ -0,0 +1,78 @@
168+# $OpenLDAP$
169+# This work is part of OpenLDAP Software <http://www.openldap.org/>.
170+#
171+# Copyright 1998-2022 The OpenLDAP Foundation.
172+#
173+# Redistribution and use in source and binary forms, with or without
174+# modification, are permitted only as authorized by the OpenLDAP
175+# Public License.
176+#
177+# A copy of this license is available in the file LICENSE in the
178+# top-level directory of the distribution or, alternatively, at
179+# <http://www.OpenLDAP.org/license.html>.
180+
181+LDAP_SRC = ../../..
182+LDAP_BUILD = $(LDAP_SRC)
183+SRCDIR = ./
184+LDAP_INC = -I$(LDAP_BUILD)/include -I$(LDAP_SRC)/include -I$(LDAP_SRC)/servers/slapd
185+LDAP_LIB = $(LDAP_BUILD)/libraries/libldap/libldap.la \
186+ $(LDAP_BUILD)/libraries/liblber/liblber.la
187+
188+LIBTOOL = $(LDAP_BUILD)/libtool
189+INSTALL = /usr/bin/install
190+CC = gcc
191+OPT = -g -O2
192+DEFS = -DSLAPD_OVER_EDS=SLAPD_MOD_DYNAMIC
193+INCS = $(LDAP_INC)
194+LIBS = $(LDAP_LIB)
195+
196+PROGRAMS = emptyds.la
197+MANPAGES = slapo-emptyds.5
198+CLEAN = *.o *.lo *.la .libs
199+LTVER = 0:0:0
200+
201+prefix=/usr/local
202+exec_prefix=$(prefix)
203+ldap_subdir=/openldap
204+
205+libdir=$(exec_prefix)/lib
206+libexecdir=$(exec_prefix)/libexec
207+moduledir = $(libexecdir)$(ldap_subdir)
208+mandir = $(exec_prefix)/share/man
209+man5dir = $(mandir)/man5
210+
211+all: $(PROGRAMS)
212+
213+d :=
214+sp :=
215+dir := tests
216+include $(dir)/Rules.mk
217+
218+.SUFFIXES: .c .o .lo
219+
220+.c.lo:
221+ $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) $(OPT) $(CPPFLAGS) $(DEFS) $(INCS) -c $<
222+
223+all: $(PROGRAMS)
224+
225+emptyds.la: emptyds.lo
226+ $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -version-info $(LTVER) \
227+ -rpath $(moduledir) -module -o $@ $? $(LIBS)
228+
229+clean:
230+ rm -rf $(CLEAN)
231+
232+install: install-lib install-man FORCE
233+
234+install-lib: $(PROGRAMS)
235+ mkdir -p $(DESTDIR)$(moduledir)
236+ for p in $(PROGRAMS) ; do \
237+ $(LIBTOOL) --mode=install cp $$p $(DESTDIR)$(moduledir) ; \
238+ done
239+
240+install-man: $(MANPAGES)
241+ mkdir -p $(DESTDIR)$(man5dir)
242+ $(INSTALL) -m 644 $(MANPAGES) $(DESTDIR)$(man5dir)
243+
244+FORCE:
245+
246diff --git a/contrib/slapd-modules/emptyds/README b/contrib/slapd-modules/emptyds/README
247new file mode 100644
248index 0000000..914d4e7
249--- /dev/null
250+++ b/contrib/slapd-modules/emptyds/README
251@@ -0,0 +1,66 @@
252+emptyds Overlay README
253+
254+DESCRIPTION
255+ This package contains an OpenLDAP overlay called "emptyds" (empty
256+ directory string) that eliminates empty values of type directory string
257+ (OID 1.3.6.1.4.1.1466.115.121.1.15) from the list of the values in the
258+ following manner:
259+
260+ - add: All empty attribute values will be removed before the add request
261+ is executed
262+ - mod-replace: A replace with empty values will be modified to a replace
263+ without values. As result the attribute will be deleted
264+ - mod-add: All empty attribute values will be removed before the mod-add
265+ request is executed
266+ - mod-delete: All empty attribute values will be removed before the
267+ mod-delete request is executed
268+
269+ If removing all empty values from a modification makes it a no-op, that
270+ modification is removed from the list.
271+
272+ At module load time the emptyds overlay manipulates the syntax checking
273+ so that it intercepts the syntax check and allows empty values for
274+ attributes of type directory string only. Non-empty values continue to
275+ go through the normal check routines. It is therefore very important to
276+ configure the overlays in a way that ensures that the emptyds overlay gets
277+ the control over the operation before any other overlay. Otherwise it
278+ could come to the situation with empty attribute values in the data base.
279+
280+ David Hawes' addpartial overlay has been used as starting point for this
281+ overlay.
282+
283+BUILDING
284+ A Makefile is included, please set your LDAP_SRC directory properly.
285+
286+INSTALLATION
287+ After compiling the emptyds overlay, add the following to your
288+ slapd.conf:
289+
290+ ### slapd.conf
291+ ...
292+ moduleload emptyds.la
293+ ...
294+ overlay emptyds
295+ ...
296+ # before database directive...
297+ # this overlay must be the last overlay in the config file to ensure that
298+ # requests are modified before other overlays get them.
299+ ...
300+ ### end slapd.conf
301+
302+CAVEATS
303+ - In order to ensure that emptyds does what it needs to do, it must be
304+ the last overlay configured so it will run before the other overlays.
305+
306+---
307+Copyright 2014-2022 The OpenLDAP Foundation.
308+Portions Copyright (C) DAASI International GmbH, Tamim Ziai.
309+All rights reserved.
310+
311+Redistribution and use in source and binary forms, with or without
312+modification, are permitted only as authorized by the OpenLDAP
313+Public License.
314+
315+A copy of this license is available in file LICENSE in the
316+top-level directory of the distribution or, alternatively, at
317+http://www.OpenLDAP.org/license.html.
318diff --git a/contrib/slapd-modules/emptyds/emptyds.c b/contrib/slapd-modules/emptyds/emptyds.c
319new file mode 100644
320index 0000000..bb3202e
321--- /dev/null
322+++ b/contrib/slapd-modules/emptyds/emptyds.c
323@@ -0,0 +1,325 @@
324+/* emptyds.c */
325+/* $OpenLDAP$ */
326+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
327+ *
328+ * Copyright 2014-2022 The OpenLDAP Foundation.
329+ * Portions Copyright (C) 2014 DAASI International GmbH, Tamim Ziai.
330+ * Portions Copyright (C) 2022 Ondřej Kuzník, Symas Corporation.
331+ * All rights reserved.
332+ *
333+ * Redistribution and use in source and binary forms, with or without
334+ * modification, are permitted only as authorized by the OpenLDAP
335+ * Public License.
336+ *
337+ * A copy of this license is available in file LICENSE in the
338+ * top-level directory of the distribution or, alternatively, at
339+ * http://www.OpenLDAP.org/license.html.
340+ */
341+/* ACKNOLEDGEDMENTS:
342+ * This work was initially developed by Tamim Ziai of DAASI International GmbH
343+ * for inclusion in OpenLDAP Software.
344+ */
345+/* slapo-emptyds
346+ *
347+ * This is an OpenLDAP overlay that accepts empty strings as attribute values
348+ * without syntax violation but never actually stores them. This allows
349+ * applications that used to work with LDAP implementations allowing empty
350+ * strings (such as Novel eDirectory) to continue to work with OpenLDAP without
351+ * any modifications. Add and modify change types will be proceeded as follows,
352+ * other operations will be forwarded without modifications:
353+ *
354+ * changeType: add changeType: add
355+ * sn: <empty> --> sn: blah
356+ * sn: blah
357+ *
358+ * changeType: modify changeType: modify
359+ * add: sn --> add: sn
360+ * sn: <empty> sn: blah
361+ * sn: blah
362+ *
363+ * changeType: modify changeType: modify
364+ * delete: sn --> delete: sn
365+ * sn: <empty> sn: blah
366+ * sn: blah
367+ *
368+ * changeType: modify changeType: modify
369+ * replace: sn --> replace: sn
370+ * sn: <empty>
371+ *
372+ */
373+
374+#include "portable.h"
375+#include "slap.h"
376+
377+static slap_overinst emptyds;
378+
379+static const char ds_oid[] = "1.3.6.1.4.1.1466.115.121.1.15";
380+
381+static slap_syntax_validate_func *ssyn_validate_original = NULL;
382+static slap_syntax_transform_func *ssyn_pretty_original = NULL;
383+static int emptyds_instances = 0;
384+
385+static unsigned int
386+remove_empty_values( Modification *m, Attribute *a )
387+{
388+ BerVarray vals = m ? m->sm_values : a->a_vals,
389+ nvals = m ? m->sm_nvalues : a->a_nvals;
390+ unsigned int i, j, numvals = m ? m->sm_numvals : a->a_numvals;
391+
392+ for ( i = 0; i < numvals && !BER_BVISEMPTY( &vals[i] ); i++ )
393+ /* Find first empty */;
394+
395+ if ( i == numvals ) return i;
396+
397+ /*
398+ * We have an empty value at index i, move all of them to the end of the
399+ * list, preserving the order of non-empty values.
400+ */
401+ j = i + 1;
402+ for ( j = i + 1; j < numvals; j++ ) {
403+ struct berval tmp;
404+
405+ if ( BER_BVISEMPTY( &vals[j] ) ) continue;
406+
407+ tmp = vals[i];
408+ vals[i] = vals[j];
409+ vals[j] = tmp;
410+
411+ if ( nvals && vals != nvals ) {
412+ tmp = nvals[i];
413+ nvals[i] = nvals[j];
414+ nvals[j] = tmp;
415+ }
416+
417+ if ( m && a && m->sm_values != a->a_vals ) {
418+ tmp = a->a_vals[i];
419+ a->a_vals[i] = a->a_vals[j];
420+ a->a_vals[j] = tmp;
421+
422+ if ( a->a_nvals && a->a_vals != a->a_nvals ) {
423+ tmp = a->a_nvals[i];
424+ a->a_nvals[i] = a->a_nvals[j];
425+ a->a_nvals[j] = tmp;
426+ }
427+ }
428+ i++;
429+ }
430+
431+ /* Free empty vals */
432+ for ( ; j && i < j--; ) {
433+ ber_memfree( vals[j].bv_val );
434+ if ( nvals && vals != nvals ) {
435+ ber_memfree( nvals[j].bv_val );
436+ BER_BVZERO( &nvals[j] );
437+ }
438+
439+ if ( m && a && m->sm_values != a->a_vals ) {
440+ if ( m->sm_values[j].bv_val != a->a_vals[j].bv_val ) {
441+ ber_memfree( a->a_vals[j].bv_val );
442+ BER_BVZERO( &a->a_vals[j] );
443+
444+ if ( a->a_nvals && a->a_vals != a->a_nvals ) {
445+ ber_memfree( a->a_nvals[j].bv_val );
446+ BER_BVZERO( &a->a_nvals[j] );
447+ }
448+ }
449+ }
450+ BER_BVZERO( &vals[j] );
451+ }
452+
453+ return i;
454+}
455+
456+/**
457+ * Remove all operations with empty strings.
458+ */
459+static int
460+emptyds_op_add( Operation *op, SlapReply *rs )
461+{
462+ Attribute **ap, **nexta, *a;
463+ Modifications **mlp, **nextp = NULL, *ml;
464+ Entry *e = op->ora_e;
465+
466+ /*
467+ * op->ora_modlist can be NULL, at least accesslog doesn't always populate
468+ * it on an add.
469+ */
470+ for ( ap = &e->e_attrs, a = e->e_attrs, mlp = &op->ora_modlist,
471+ ml = op->ora_modlist;
472+ a != NULL;
473+ ap = nexta, a = *ap, mlp = nextp, ml = ml ? *mlp : NULL ) {
474+ AttributeType *at = a->a_desc->ad_type;
475+ unsigned int remaining;
476+
477+ nexta = &a->a_next;
478+ if ( ml ) {
479+ nextp = &ml->sml_next;
480+ }
481+
482+ if ( at->sat_syntax != slap_schema.si_syn_directoryString ||
483+ at->sat_atype.at_usage != LDAP_SCHEMA_USER_APPLICATIONS )
484+ continue;
485+
486+ remaining = remove_empty_values( &ml->sml_mod, a );
487+ if ( remaining == a->a_numvals ) continue;
488+ /* Empty values found */
489+
490+ if ( !remaining ) {
491+ /* All values are empty */
492+ *ap = a->a_next;
493+ a->a_next = NULL;
494+ nexta = ap;
495+
496+ if ( ml ) {
497+ *mlp = ml->sml_next;
498+ ml->sml_next = NULL;
499+ nextp = mlp;
500+ /* Values are generally shared with attribute */
501+ slap_mods_free( ml, ml->sml_values != a->a_vals );
502+ }
503+ attr_free( a );
504+ } else {
505+ a->a_numvals = remaining;
506+ if ( ml ) {
507+ ml->sml_mod.sm_numvals = remaining;
508+ }
509+ }
510+ }
511+
512+ return SLAP_CB_CONTINUE;
513+}
514+
515+static int
516+emptyds_op_modify( Operation *op, SlapReply *rs )
517+{
518+ Modifications **mlp, **nextp, *ml;
519+
520+ for ( mlp = &op->orm_modlist, ml = op->orm_modlist; ml != NULL;
521+ mlp = nextp, ml = *mlp ) {
522+ AttributeType *at = ml->sml_desc->ad_type;
523+ unsigned int remaining;
524+
525+ nextp = &ml->sml_next;
526+
527+ if ( at->sat_syntax != slap_schema.si_syn_directoryString ||
528+ at->sat_atype.at_usage != LDAP_SCHEMA_USER_APPLICATIONS )
529+ continue;
530+
531+ remaining = remove_empty_values( &ml->sml_mod, NULL );
532+ if ( remaining == ml->sml_numvals ) continue;
533+
534+ if ( !remaining ) {
535+ /* All values are empty */
536+ if ( ml->sml_op == LDAP_MOD_REPLACE ) {
537+ /* Replace is kept */
538+ if ( ml->sml_nvalues && ml->sml_nvalues != ml->sml_values ) {
539+ ber_bvarray_free( ml->sml_nvalues );
540+ }
541+ if ( ml->sml_values ) {
542+ ber_bvarray_free( ml->sml_values );
543+ }
544+
545+ ml->sml_numvals = 0;
546+ ml->sml_values = NULL;
547+ ml->sml_nvalues = NULL;
548+ } else {
549+ /* Remove modification */
550+ *mlp = ml->sml_next;
551+ ml->sml_next = NULL;
552+ nextp = mlp;
553+ slap_mods_free( ml, 1 );
554+ }
555+ } else {
556+ ml->sml_numvals = remaining;
557+ }
558+ }
559+
560+ return SLAP_CB_CONTINUE;
561+}
562+
563+static int
564+emptyds_ssyn_validate( Syntax *syntax, struct berval *in )
565+{
566+ if ( BER_BVISEMPTY( in ) && syntax == slap_schema.si_syn_directoryString ) {
567+ return LDAP_SUCCESS;
568+ }
569+ return ssyn_validate_original( syntax, in );
570+}
571+
572+static int
573+emptyds_ssyn_pretty( Syntax *syntax,
574+ struct berval *in,
575+ struct berval *out,
576+ void *memctx )
577+{
578+ if ( BER_BVISEMPTY( in ) && syntax == slap_schema.si_syn_directoryString ) {
579+ return LDAP_SUCCESS;
580+ }
581+ return ssyn_pretty_original( syntax, in, out, memctx );
582+}
583+
584+static int
585+emptyds_db_init( BackendDB *be, ConfigReply *cr )
586+{
587+ Syntax *syntax = syn_find( ds_oid );
588+
589+ if ( syntax == NULL ) {
590+ Debug( LDAP_DEBUG_TRACE, "emptyds_db_init: "
591+ "Syntax %s not found\n",
592+ ds_oid );
593+ } else {
594+ Debug( LDAP_DEBUG_TRACE, "emptyds_db_init: "
595+ "Found syntax: %s\n",
596+ syntax->ssyn_bvoid.bv_val );
597+ if ( ssyn_validate_original == NULL && syntax->ssyn_validate != NULL ) {
598+ ssyn_validate_original = syntax->ssyn_validate;
599+ syntax->ssyn_validate = emptyds_ssyn_validate;
600+ }
601+ if ( ssyn_pretty_original == NULL && syntax->ssyn_pretty != NULL ) {
602+ ssyn_pretty_original = syntax->ssyn_pretty;
603+ syntax->ssyn_pretty = &emptyds_ssyn_pretty;
604+ }
605+ }
606+
607+ emptyds_instances++;
608+ return LDAP_SUCCESS;
609+}
610+
611+static int
612+emptyds_db_destroy( BackendDB *be, ConfigReply *cr )
613+{
614+ Syntax *syntax = syn_find( ds_oid );
615+
616+ if ( --emptyds_instances == 0 && syntax != NULL ) {
617+ if ( syntax->ssyn_validate == emptyds_ssyn_validate ) {
618+ syntax->ssyn_validate = ssyn_validate_original;
619+ }
620+ ssyn_validate_original = NULL;
621+
622+ if ( syntax->ssyn_pretty == emptyds_ssyn_pretty ) {
623+ syntax->ssyn_pretty = ssyn_pretty_original;
624+ }
625+ ssyn_pretty_original = NULL;
626+ }
627+
628+ assert( emptyds_instances >= 0 );
629+ return LDAP_SUCCESS;
630+}
631+
632+int
633+emptyds_init()
634+{
635+ emptyds.on_bi.bi_type = "emptyds";
636+ emptyds.on_bi.bi_op_add = emptyds_op_add;
637+ emptyds.on_bi.bi_op_modify = emptyds_op_modify;
638+ emptyds.on_bi.bi_db_init = emptyds_db_init;
639+ emptyds.on_bi.bi_db_destroy = emptyds_db_destroy;
640+
641+ return overlay_register( &emptyds );
642+}
643+
644+int
645+init_module( int argc, char *argv[] )
646+{
647+ return emptyds_init();
648+}
649diff --git a/contrib/slapd-modules/emptyds/slapo-emptyds.5 b/contrib/slapd-modules/emptyds/slapo-emptyds.5
650new file mode 100644
651index 0000000..75b1059
652--- /dev/null
653+++ b/contrib/slapd-modules/emptyds/slapo-emptyds.5
654@@ -0,0 +1,68 @@
655+.TH SLAPO-EDS 5 "RELEASEDATE" "OpenLDAP LDVERSION"
656+.\" Copyright 2022 The OpenLDAP Foundation, All Rights Reserved.
657+.\" Copyright 2018 Tamim Ziai
658+.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
659+.\" $OpenLDAP$
660+.SH NAME
661+slapo-emptyds \- Remove Empty values from Directory String attributes
662+Overlay to slapd
663+.SH SYNOPSIS
664+ETCDIR/slapd.conf
665+.SH DESCRIPTION
666+Some non-conformant clients will provide empty values for Directory String
667+attributes with certain operations. This overlay makes empty values acceptable
668+for the Directory String syntax and will adjust all operations to make sure
669+these values are never actually stored in the database.
670+.LP
671+.nf
672+.ft tt
673+ dn: cn=alex,cn=people,dc=example,dc=org
674+ changeType: add changeType: add
675+ sn: <empty> --> sn: blah
676+ sn: blah
677+
678+ dn: cn=alex,cn=people,dc=example,dc=org
679+ changeType: modify changeType: modify
680+ add: sn --> add: sn
681+ sn: <empty> sn: blah
682+ sn: blah
683+
684+ dn: cn=alex,cn=people,dc=example,dc=org
685+ changeType: modify changeType: modify
686+ delete: sn --> delete: sn
687+ sn: <empty> sn: blah
688+ sn: blah
689+
690+ dn: cn=alex,cn=people,dc=example,dc=org
691+ changeType: modify changeType: modify
692+ replace: sn --> replace: sn
693+ sn: <empty>
694+
695+ dn: cn=alex,cn=people,dc=example,dc=org
696+ changeType: modify changeType: modify
697+ replace: sn --> replace: sn
698+ sn: <empty> sn: blah
699+ sn: blah
700+.ft
701+.fi
702+.LP
703+.SH CONFIGURATION
704+This overlay has no specific configuration, however in order to ensure that it
705+does what it needs to do, it should be the last overlay configured so it will
706+run before the other overlays.
707+.SH EXAMPLES
708+.LP
709+.RS
710+.nf
711+overlay emptyds
712+.RE
713+.SH FILES
714+.TP
715+ETCDIR/slapd.conf
716+default slapd configuration file
717+.SH SEE ALSO
718+.BR slapd.conf (5).
719+.SH ACKNOWLEDGEMENTS
720+This module was written in 2014 by Tamim Ziai for DAASI International and
721+updated in 2022 by Ondřej Kuzník for inclusion in the OpenLDAP project.
722+.so ../Project
723diff --git a/contrib/slapd-modules/emptyds/tests/Rules.mk b/contrib/slapd-modules/emptyds/tests/Rules.mk
724new file mode 100644
725index 0000000..c25c1d2
726--- /dev/null
727+++ b/contrib/slapd-modules/emptyds/tests/Rules.mk
728@@ -0,0 +1,23 @@
729+sp := $(sp).x
730+dirstack_$(sp) := $(d)
731+d := $(dir)
732+
733+.PHONY: test
734+
735+CLEAN += clients servers tests/progs tests/schema tests/testdata tests/testrun
736+
737+test: all clients servers tests/progs
738+
739+test:
740+ cd tests; \
741+ SRCDIR=$(abspath $(LDAP_SRC)) \
742+ LDAP_BUILD=$(abspath $(LDAP_BUILD)) \
743+ TOPDIR=$(abspath $(SRCDIR)) \
744+ LIBTOOL=$(abspath $(LIBTOOL)) \
745+ $(abspath $(SRCDIR))/tests/run all
746+
747+servers clients tests/progs:
748+ ln -s $(abspath $(LDAP_BUILD))/$@ $@
749+
750+d := $(dirstack_$(sp))
751+sp := $(basename $(sp))
752diff --git a/contrib/slapd-modules/emptyds/tests/data/emptyds.conf b/contrib/slapd-modules/emptyds/tests/data/emptyds.conf
753new file mode 100644
754index 0000000..221fe81
755--- /dev/null
756+++ b/contrib/slapd-modules/emptyds/tests/data/emptyds.conf
757@@ -0,0 +1,54 @@
758+# basic slapd config -- for testing of slapo-emptyds
759+# $OpenLDAP$
760+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
761+##
762+## Copyright 1998-2022 The OpenLDAP Foundation.
763+## All rights reserved.
764+##
765+## Redistribution and use in source and binary forms, with or without
766+## modification, are permitted only as authorized by the OpenLDAP
767+## Public License.
768+##
769+## A copy of this license is available in the file LICENSE in the
770+## top-level directory of the distribution or, alternatively, at
771+## <http://www.OpenLDAP.org/license.html>.
772+
773+include @SCHEMADIR@/core.schema
774+include @SCHEMADIR@/cosine.schema
775+include @SCHEMADIR@/inetorgperson.schema
776+include @SCHEMADIR@/openldap.schema
777+include @SCHEMADIR@/nis.schema
778+include @DATADIR@/test.schema
779+#
780+pidfile @TESTDIR@/slapd.1.pid
781+argsfile @TESTDIR@/slapd.1.args
782+
783+#mod#modulepath ../servers/slapd/back-@BACKEND@/
784+#mod#moduleload back_@BACKEND@.la
785+#accesslogmod#modulepath ../servers/slapd/overlays/
786+#accesslogmod#moduleload accesslog.la
787+moduleload ../emptyds.la
788+
789+database @BACKEND@
790+suffix "dc=example,dc=com"
791+rootdn "cn=Manager,dc=example,dc=com"
792+rootpw secret
793+#~null~#directory @TESTDIR@/db.1.a
794+
795+overlay accesslog
796+logdb cn=log
797+logops writes
798+logsuccess true
799+
800+overlay emptyds
801+
802+database @BACKEND@
803+suffix "cn=log"
804+rootdn "cn=Manager,dc=example,dc=com"
805+#~null~#directory @TESTDIR@/db.1.b
806+
807+## This one makes no difference except we want to make sure we can
808+## safely instantiate the overlay on multiple databases
809+overlay emptyds
810+
811+database monitor
812diff --git a/contrib/slapd-modules/emptyds/tests/data/test001.ldif b/contrib/slapd-modules/emptyds/tests/data/test001.ldif
813new file mode 100644
814index 0000000..b7f289a
815--- /dev/null
816+++ b/contrib/slapd-modules/emptyds/tests/data/test001.ldif
817@@ -0,0 +1,71 @@
818+# slapd prevents us from adding the same value multiple times
819+dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
820+changetype: modify
821+add: description
822+description: one
823+description:
824+description: two
825+description: three
826+description: four
827+# a space is distinct from an empty value
828+description:: ICAg
829+-
830+replace: drink
831+drink: Earl Grey, hot
832+-
833+delete: description
834+description:
835+-
836+replace: drink
837+drink: Earl Grey, hot
838+
839+# there is no such restriction on deletes, so we exercise this part of the overlay here
840+dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
841+changetype: modify
842+delete: description
843+description:
844+description: four
845+description:
846+description: three
847+description: two
848+description:
849+description:
850+description: one
851+description:
852+-
853+add: description
854+description:
855+
856+dn: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
857+changetype: modify
858+replace: drink
859+drink:
860+
861+dn: cn=All Staff,ou=Groups,dc=example,dc=com
862+changetype: modify
863+delete: member
864+-
865+add: member
866+# an empty DN should not be stripped
867+member:
868+member: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
869+
870+dn: cn=Gern Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com
871+changetype: add
872+objectclass: testPerson
873+cn: Gern Jensen
874+sn: Jensen
875+uid: gjensen
876+title:
877+postaladdress: ITD $ 535 W. William St $ Anytown, MI 48103
878+seealso: cn=All Staff,ou=Groups,dc=example,dc=com
879+drink: Coffee
880+homepostaladdress: 844 Brown St. Apt. 4 $ Anytown, MI 48104
881+description: Very odd
882+description:
883+description: More than you think
884+facsimiletelephonenumber: +1 313 555 7557
885+telephonenumber: +1 313 555 8343
886+mail: gjensen@mailgw.example.com
887+homephone: +1 313 555 8844
888+testTime: 20050304001801.234Z
889diff --git a/contrib/slapd-modules/emptyds/tests/data/test001.out b/contrib/slapd-modules/emptyds/tests/data/test001.out
890new file mode 100644
891index 0000000..6f41247
892--- /dev/null
893+++ b/contrib/slapd-modules/emptyds/tests/data/test001.out
894@@ -0,0 +1,54 @@
895+dn: reqStart=timestamp,cn=log
896+reqDN: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
897+reqMod: description:+ one
898+reqMod: description:+ two
899+reqMod: description:+ three
900+reqMod: description:+ four
901+# "description:+ " that's a space, then 3 spaces for value
902+reqMod:: ZGVzY3JpcHRpb246KyAgICA=
903+reqMod: drink:= Earl Grey, hot
904+# second mod was removed, so we have two replaces in succession now and need
905+# to separate them (":")
906+reqMod:: Og==
907+reqMod: drink:= Earl Grey, hot
908+
909+dn: reqStart=timestamp,cn=log
910+reqDN: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
911+reqMod: description:- four
912+reqMod: description:- three
913+reqMod: description:- two
914+reqMod: description:- one
915+# second mod is removed
916+
917+dn: reqStart=timestamp,cn=log
918+reqDN: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
919+reqMod: drink:=
920+
921+dn: reqStart=timestamp,cn=log
922+reqDN: cn=All Staff,ou=Groups,dc=example,dc=com
923+reqMod: member:-
924+# "member:+ " adding an empty DN
925+reqMod:: bWVtYmVyOisg
926+reqMod: member:+ cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example
927+ ,dc=com
928+
929+dn: reqStart=timestamp,cn=log
930+reqDN: cn=Gern Jensen,ou=Information Technology Division,ou=People,dc=example,
931+ dc=com
932+reqMod: objectClass:+ testPerson
933+reqMod: cn:+ Gern Jensen
934+reqMod: sn:+ Jensen
935+reqMod: uid:+ gjensen
936+reqMod: postalAddress:+ ITD $ 535 W. William St $ Anytown, MI 48103
937+reqMod: seeAlso:+ cn=All Staff,ou=Groups,dc=example,dc=com
938+reqMod: drink:+ Coffee
939+reqMod: homePostalAddress:+ 844 Brown St. Apt. 4 $ Anytown, MI 48104
940+reqMod: description:+ Very odd
941+reqMod: description:+ More than you think
942+reqMod: facsimileTelephoneNumber:+ +1 313 555 7557
943+reqMod: telephoneNumber:+ +1 313 555 8343
944+reqMod: mail:+ gjensen@mailgw.example.com
945+reqMod: homePhone:+ +1 313 555 8844
946+reqMod: testTime:+ 20050304001801.234Z
947+reqMod: structuralObjectClass:+ testPerson
948+
949diff --git a/contrib/slapd-modules/emptyds/tests/run b/contrib/slapd-modules/emptyds/tests/run
950new file mode 100755
951index 0000000..e28820c
952--- /dev/null
953+++ b/contrib/slapd-modules/emptyds/tests/run
954@@ -0,0 +1,218 @@
955+#!/bin/sh
956+## $OpenLDAP$
957+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
958+##
959+## Copyright 1998-2022 The OpenLDAP Foundation.
960+## All rights reserved.
961+##
962+## Redistribution and use in source and binary forms, with or without
963+## modification, are permitted only as authorized by the OpenLDAP
964+## Public License.
965+##
966+## A copy of this license is available in the file LICENSE in the
967+## top-level directory of the distribution or, alternatively, at
968+## <http://www.OpenLDAP.org/license.html>.
969+##
970+## ACKNOWLEDGEMENTS:
971+## This module was written in 2016 by Ondřej Kuzník for Symas Corp.
972+
973+USAGE="$0 [-b <backend>] [-c] [-k] [-l #] [-p] [-s {ro|rp}] [-u] [-w] <script>"
974+
975+TOPSRCDIR="${SRCDIR-$LDAP_SRC}"
976+SRCDIR="${TOPSRCDIR}/tests"
977+eval `grep EGREP_CMD= ${LDAP_BUILD}/tests/run`
978+eval `$EGREP_CMD -e '^LN_S=' ${LDAP_BUILD}/tests/run`
979+
980+export SRCDIR TOPSRCDIR LN_S EGREP_CMD
981+
982+. "${SRCDIR}/scripts/defines.sh"
983+
984+BACKEND=
985+CLEAN=no
986+WAIT=0
987+KILLSERVERS=yes
988+PRESERVE=${PRESERVE-no}
989+SYNCMODE=${SYNCMODE-rp}
990+USERDATA=no
991+LOOP=1
992+COUNTER=1
993+
994+while test $# -gt 0 ; do
995+ case "$1" in
996+ -b | -backend)
997+ BACKEND="$2"
998+ shift; shift ;;
999+
1000+ -c | -clean)
1001+ CLEAN=yes
1002+ shift ;;
1003+
1004+ -k | -kill)
1005+ KILLSERVERS=no
1006+ shift ;;
1007+ -l | -loop)
1008+ NUM="`echo $2 | sed 's/[0-9]//g'`"
1009+ if [ -z "$NUM" ]; then
1010+ LOOP=$2
1011+ else
1012+ echo "Loop variable not an int: $2"
1013+ echo "$USAGE"; exit 1
1014+ fi
1015+ shift ;
1016+ shift ;;
1017+
1018+ -p | -preserve)
1019+ PRESERVE=yes
1020+ shift ;;
1021+
1022+ -s | -syncmode)
1023+ case "$2" in
1024+ ro | rp)
1025+ SYNCMODE="$2"
1026+ ;;
1027+ *)
1028+ echo "unknown sync mode $2"
1029+ echo "$USAGE"; exit 1
1030+ ;;
1031+ esac
1032+ shift; shift ;;
1033+
1034+ -u | -userdata)
1035+ USERDATA=yes
1036+ shift ;;
1037+
1038+ -w | -wait)
1039+ WAIT=1
1040+ shift ;;
1041+
1042+ -)
1043+ shift
1044+ break ;;
1045+
1046+ -*)
1047+ echo "$USAGE"; exit 1
1048+ ;;
1049+
1050+ *)
1051+ break ;;
1052+ esac
1053+done
1054+
1055+eval `$EGREP_CMD -e '^AC' ${LDAP_BUILD}/tests/run`
1056+export `$EGREP_CMD -e '^AC' ${LDAP_BUILD}/tests/run | sed 's/=.*//'`
1057+
1058+if test -z "$BACKEND" ; then
1059+ for b in mdb ; do
1060+ if eval "test \"\$AC_$b\" != no" ; then
1061+ BACKEND=$b
1062+ break
1063+ fi
1064+ done
1065+ if test -z "$BACKEND" ; then
1066+ echo "No suitable default database backend configured" >&2
1067+ exit 1
1068+ fi
1069+fi
1070+
1071+BACKENDTYPE=`eval 'echo $AC_'$BACKEND`
1072+if test "x$BACKENDTYPE" = "x" ; then
1073+ BACKENDTYPE="unknown"
1074+fi
1075+
1076+# Backend features. indexdb: indexing and unchecked limit.
1077+# maindb: main storage backend. Currently index,limits,mode,paged results.
1078+INDEXDB=noindexdb MAINDB=nomaindb
1079+case $BACKEND in
1080+ mdb) INDEXDB=indexdb MAINDB=maindb ;;
1081+esac
1082+
1083+export BACKEND BACKENDTYPE INDEXDB MAINDB \
1084+ WAIT KILLSERVERS PRESERVE SYNCMODE USERDATA \
1085+ SRCDIR
1086+
1087+if test $# = 0 ; then
1088+ echo "$USAGE"; exit 1
1089+fi
1090+
1091+# need defines.sh for the definitions of the directories
1092+. $SRCDIR/scripts/defines.sh
1093+
1094+SCRIPTDIR="${TOPDIR}/tests/scripts"
1095+
1096+export SCRIPTDIR
1097+
1098+SCRIPTNAME="$1"
1099+shift
1100+
1101+if test -x "${SCRIPTDIR}/${SCRIPTNAME}" ; then
1102+ SCRIPT="${SCRIPTDIR}/${SCRIPTNAME}"
1103+elif test -x "`echo ${SCRIPTDIR}/test*-${SCRIPTNAME}`"; then
1104+ SCRIPT="`echo ${SCRIPTDIR}/test*-${SCRIPTNAME}`"
1105+elif test -x "`echo ${SCRIPTDIR}/${SCRIPTNAME}-*`"; then
1106+ SCRIPT="`echo ${SCRIPTDIR}/${SCRIPTNAME}-*`"
1107+else
1108+ echo "run: ${SCRIPTNAME} not found (or not executable)"
1109+ exit 1;
1110+fi
1111+
1112+if test ! -r ${DATADIR}/test.ldif ; then
1113+ ${LN_S} ${SRCDIR}/data ${DATADIR}
1114+fi
1115+if test ! -r ${SCHEMADIR}/core.schema ; then
1116+ ${LN_S} ${TOPSRCDIR}/servers/slapd/schema ${SCHEMADIR}
1117+fi
1118+if test ! -r ./data; then
1119+ ${LN_S} ${TOPDIR}/tests/data ./
1120+fi
1121+
1122+if test -d ${TESTDIR} ; then
1123+ if test $PRESERVE = no ; then
1124+ echo "Cleaning up test run directory leftover from previous run."
1125+ /bin/rm -rf ${TESTDIR}
1126+ elif test $PRESERVE = yes ; then
1127+ echo "Cleaning up only database directories leftover from previous run."
1128+ /bin/rm -rf ${TESTDIR}/db.*
1129+ fi
1130+fi
1131+mkdir -p ${TESTDIR}
1132+
1133+if test $USERDATA = yes ; then
1134+ if test ! -d userdata ; then
1135+ echo "User data directory (userdata) does not exist."
1136+ exit 1
1137+ fi
1138+ cp -R userdata/* ${TESTDIR}
1139+fi
1140+
1141+# disable LDAP initialization
1142+LDAPNOINIT=true; export LDAPNOINIT
1143+
1144+echo "Running ${SCRIPT} for ${BACKEND}..."
1145+while [ $COUNTER -le $LOOP ]; do
1146+ if [ $LOOP -gt 1 ]; then
1147+ echo "Running $COUNTER of $LOOP iterations"
1148+ fi
1149+ $SCRIPT $*
1150+ RC=$?
1151+
1152+ if test $CLEAN = yes ; then
1153+ echo "Cleaning up test run directory from this run."
1154+ /bin/rm -rf ${TESTDIR}
1155+ echo "Cleaning up symlinks."
1156+ /bin/rm -f ${DATADIR} ${SCHEMADIR}
1157+ fi
1158+
1159+ if [ $RC -ne 0 ]; then
1160+ if [ $LOOP -gt 1 ]; then
1161+ echo "Failed after $COUNTER of $LOOP iterations"
1162+ fi
1163+ exit $RC
1164+ else
1165+ COUNTER=`expr $COUNTER + 1`
1166+ if [ $COUNTER -le $LOOP ]; then
1167+ echo "Cleaning up test run directory from this run."
1168+ /bin/rm -rf ${TESTDIR}
1169+ fi
1170+ fi
1171+done
1172+exit $RC
1173diff --git a/contrib/slapd-modules/emptyds/tests/scripts/all b/contrib/slapd-modules/emptyds/tests/scripts/all
1174new file mode 100755
1175index 0000000..a5c1774
1176--- /dev/null
1177+++ b/contrib/slapd-modules/emptyds/tests/scripts/all
1178@@ -0,0 +1,92 @@
1179+#! /bin/sh
1180+# $OpenLDAP$
1181+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
1182+##
1183+## Copyright 1998-2022 The OpenLDAP Foundation.
1184+## All rights reserved.
1185+##
1186+## Redistribution and use in source and binary forms, with or without
1187+## modification, are permitted only as authorized by the OpenLDAP
1188+## Public License.
1189+##
1190+## A copy of this license is available in the file LICENSE in the
1191+## top-level directory of the distribution or, alternatively, at
1192+## <http://www.OpenLDAP.org/license.html>.
1193+
1194+. $SRCDIR/scripts/defines.sh
1195+
1196+TB="" TN=""
1197+if test -t 1 ; then
1198+ TB=`$SHTOOL echo -e "%B" 2>/dev/null`
1199+ TN=`$SHTOOL echo -e "%b" 2>/dev/null`
1200+fi
1201+
1202+FAILCOUNT=0
1203+SKIPCOUNT=0
1204+SLEEPTIME=10
1205+
1206+echo ">>>>> Executing all LDAP tests for $BACKEND"
1207+
1208+if [ -n "$NOEXIT" ]; then
1209+ echo "Result Test" > $TESTWD/results
1210+fi
1211+
1212+for CMD in ${SCRIPTDIR}/test*; do
1213+ case "$CMD" in
1214+ *~) continue;;
1215+ *.bak) continue;;
1216+ *.orig) continue;;
1217+ *.sav) continue;;
1218+ *) test -f "$CMD" || continue;;
1219+ esac
1220+
1221+ # remove cruft from prior test
1222+ if test $PRESERVE = yes ; then
1223+ /bin/rm -rf $TESTDIR/db.*
1224+ else
1225+ /bin/rm -rf $TESTDIR
1226+ fi
1227+
1228+ BCMD=`basename $CMD`
1229+ if [ -x "$CMD" ]; then
1230+ echo ">>>>> Starting ${TB}$BCMD${TN} for $BACKEND..."
1231+ $CMD
1232+ RC=$?
1233+ if test $RC -eq 0 ; then
1234+ echo ">>>>> $BCMD completed ${TB}OK${TN} for $BACKEND."
1235+ else
1236+ echo ">>>>> $BCMD ${TB}failed${TN} for $BACKEND"
1237+ FAILCOUNT=`expr $FAILCOUNT + 1`
1238+
1239+ if [ -n "$NOEXIT" ]; then
1240+ echo "Continuing."
1241+ else
1242+ echo "(exit $RC)"
1243+ exit $RC
1244+ fi
1245+ fi
1246+ else
1247+ echo ">>>>> Skipping ${TB}$BCMD${TN} for $BACKEND."
1248+ SKIPCOUNT=`expr $SKIPCOUNT + 1`
1249+ RC="-"
1250+ fi
1251+
1252+ if [ -n "$NOEXIT" ]; then
1253+ echo "$RC $BCMD" >> $TESTWD/results
1254+ fi
1255+
1256+# echo ">>>>> waiting $SLEEPTIME seconds for things to exit"
1257+# sleep $SLEEPTIME
1258+ echo ""
1259+done
1260+
1261+if [ -n "$NOEXIT" ]; then
1262+ if [ "$FAILCOUNT" -gt 0 ]; then
1263+ cat $TESTWD/results
1264+ echo "$FAILCOUNT tests for $BACKEND ${TB}failed${TN}. Please review the test log."
1265+ else
1266+ echo "All executed tests for $BACKEND ${TB}succeeded${TN}."
1267+ fi
1268+fi
1269+
1270+echo "$SKIPCOUNT tests for $BACKEND were ${TB}skipped${TN}."
1271diff --git a/contrib/slapd-modules/emptyds/tests/scripts/test001-emptyds b/contrib/slapd-modules/emptyds/tests/scripts/test001-emptyds
1272new file mode 100755
1273index 0000000..b8d715a
1274--- /dev/null
1275+++ b/contrib/slapd-modules/emptyds/tests/scripts/test001-emptyds
1276@@ -0,0 +1,137 @@
1277+#! /bin/sh
1278+# $OpenLDAP$
1279+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
1280+##
1281+## Copyright 2022 The OpenLDAP Foundation.
1282+## All rights reserved.
1283+##
1284+## Redistribution and use in source and binary forms, with or without
1285+## modification, are permitted only as authorized by the OpenLDAP
1286+## Public License.
1287+##
1288+## A copy of this license is available in the file LICENSE in the
1289+## top-level directory of the distribution or, alternatively, at
1290+## <http://www.OpenLDAP.org/license.html>.
1291+##
1292+## ACKNOWLEDGEMENTS:
1293+## This module was written in 2019 by Tamim Ziai for DAASI International
1294+
1295+echo "running defines.sh"
1296+. $SRCDIR/scripts/defines.sh
1297+
1298+LDIF=${TOPDIR}/tests/data/test001.out
1299+
1300+if test $ACCESSLOG = accesslogno; then
1301+ echo "Accesslog overlay not available, test skipped"
1302+ exit 0
1303+fi
1304+
1305+mkdir -p $TESTDIR $DBDIR1A $DBDIR1B
1306+
1307+. $CONFFILTER $BACKEND < "${TOPDIR}/tests/data/emptyds.conf" > $CONF1
1308+
1309+echo "Running slapadd to build slapd database... "
1310+$SLAPADD -f $CONF1 -l $LDIFORDERED
1311+RC=$?
1312+if test $RC != 0 ; then
1313+ echo "slapadd failed ($RC)!"
1314+ exit $RC
1315+fi
1316+
1317+echo "Starting slapd on TCP/IP port $PORT1..."
1318+$SLAPD -f $CONF1 -h $URI1 -d $LVL >> $LOG1 2>&1 &
1319+PID=$!
1320+if test $WAIT != 0 ; then
1321+ echo PID $PID
1322+ read foo
1323+fi
1324+KILLPIDS="$PID"
1325+
1326+sleep $SLEEP0
1327+
1328+for i in 0 1 2 3 4 5; do
1329+ $LDAPSEARCH -s base -b "$MONITOR" -H $URI1 \
1330+ 'objectclass=*' > /dev/null 2>&1
1331+ RC=$?
1332+ if test $RC = 0 ; then
1333+ break
1334+ fi
1335+ echo "Waiting ${SLEEP1} seconds for slapd to start..."
1336+ sleep ${SLEEP1}
1337+done
1338+
1339+echo "Checking add/modify handling... "
1340+
1341+$LDAPMODIFY -D "$MANAGERDN" -H $URI1 -w $PASSWD \
1342+ > $TESTOUT -f "${TOPDIR}/tests/data/test001.ldif"
1343+RC=$?
1344+if test $RC != 0 ; then
1345+ echo "ldapmodify failed ($RC)!"
1346+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
1347+ exit $RC
1348+fi
1349+
1350+echo "Checking modrdn handling (should still fail with invalidDNSyntax)... "
1351+
1352+$LDAPMODIFY -D "$MANAGERDN" -H $URI1 -w $PASSWD \
1353+ >> $TESTOUT 2>&1 <<EOMOD
1354+dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com
1355+changetype: modrdn
1356+newrdn: cn=
1357+deleteoldrdn: 0
1358+EOMOD
1359+RC=$?
1360+case $RC in
1361+34)
1362+ echo " ldapmodify failed ($RC)"
1363+ ;;
1364+0)
1365+ echo " ldapmodify should have failed ($RC)!"
1366+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
1367+ exit 1
1368+ ;;
1369+*)
1370+ echo " ldapmodify failed ($RC)!"
1371+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
1372+ exit $RC
1373+ ;;
1374+esac
1375+
1376+echo "Dumping accesslog..."
1377+
1378+$LDAPSEARCH -b "cn=log" -H $URI1 \
1379+ 'objectClass=auditWriteObject' reqDN reqMod | \
1380+ grep -v -e 'entryCSN' -e '\(create\|modify\)Timestamp' \
1381+ -e '\(modifier\|creator\)sName' -e 'entryUUID' | \
1382+ sed -e 's/reqStart=[^,]*,/reqStart=timestamp,/' \
1383+ > $SEARCHOUT 2>&1
1384+RC=$?
1385+if test $RC != 0 ; then
1386+ echo "ldapsearch failed ($RC)!"
1387+ exit $RC
1388+fi
1389+
1390+test $KILLSERVERS != no && kill -HUP $KILLPIDS
1391+
1392+# Expectations:
1393+# - all empty values for directoryString pruned
1394+# - empty adds/deletes removed, empty replaces kept
1395+# - remaining values keep the same order as submitted
1396+# - other syntaxes (especially DNs) are kept intact
1397+echo "Filtering ldapsearch results..."
1398+$LDIFFILTER < $SEARCHOUT > $SEARCHFLT
1399+$LDIFFILTER < $LDIF > $LDIFFLT
1400+
1401+echo "Comparing filter output..."
1402+$CMP $LDIFFLT $SEARCHFLT > $CMPOUT
1403+
1404+if test $? != 0 ; then
1405+ echo "Comparison failed"
1406+ exit 1
1407+fi
1408+
1409+echo ">>>>> Test succeeded"
1410+
1411+test $KILLSERVERS != no && wait
1412+
1413+exit 0
1414diff --git a/debian/changelog b/debian/changelog
1415index 4c4b66d..c228ce0 100644
1416--- a/debian/changelog
1417+++ b/debian/changelog
1418@@ -1,3 +1,11 @@
1419+openldap (2.5.13+dfsg-0ubuntu0.22.04.1) jammy; urgency=medium
1420+
1421+ * New upstream version (LP: #1983618).
1422+ - Several fixes, including memory leaks that affected libldap.
1423+ - Added slapo-emptyds contrib module (ITS#8882).
1424+
1425+ -- Sergio Durigan Junior <sergio.durigan@canonical.com> Fri, 05 Aug 2022 10:51:52 -0400
1426+
1427 openldap (2.5.12+dfsg-0ubuntu0.22.04.1) jammy; urgency=medium
1428
1429 * New upstream version (LP: #1977627).
1430diff --git a/doc/guide/admin/guide.html b/doc/guide/admin/guide.html
1431index 7415912..7e924c8 100644
1432--- a/doc/guide/admin/guide.html
1433+++ b/doc/guide/admin/guide.html
1434@@ -23,7 +23,7 @@
1435 <DIV CLASS="title">
1436 <H1 CLASS="doc-title">OpenLDAP Software 2.5 Administrator's Guide</H1>
1437 <ADDRESS CLASS="doc-author">The OpenLDAP Project &lt;<A HREF="https://www.openldap.org/">https://www.openldap.org/</A>&gt;</ADDRESS>
1438-<ADDRESS CLASS="doc-modified">4 May 2022</ADDRESS>
1439+<ADDRESS CLASS="doc-modified">14 July 2022</ADDRESS>
1440 <BR CLEAR="All">
1441 </DIV>
1442 <DIV CLASS="contents">
1443diff --git a/doc/man/man3/ldap_get_option.3 b/doc/man/man3/ldap_get_option.3
1444index 3477f02..b98ad60 100644
1445--- a/doc/man/man3/ldap_get_option.3
1446+++ b/doc/man/man3/ldap_get_option.3
1447@@ -463,7 +463,7 @@ must be an
1448 .BR "unsigned int *" .
1449
1450 .SH SASL OPTIONS
1451-The SASL options are OpenLDAP specific.
1452+The SASL options are OpenLDAP specific and unless otherwise noted, require an LDAP handle to be passed.
1453 .TP
1454 .B LDAP_OPT_X_SASL_AUTHCID
1455 Gets the SASL authentication identity;
1456@@ -507,7 +507,7 @@ in form of a NULL-terminated array of strings;
1457 .BR outvalue
1458 must be
1459 .BR "char ***" .
1460-The caller must not free or otherwise muck with it.
1461+The caller must not free or otherwise muck with it. This option can be used globally.
1462 .TP
1463 .B LDAP_OPT_X_SASL_NOCANON
1464 Sets/gets the NOCANON flag.
1465diff --git a/doc/man/man5/slapd-ldap.5 b/doc/man/man5/slapd-ldap.5
1466index 8a4fa2e..ffcbe81 100644
1467--- a/doc/man/man5/slapd-ldap.5
1468+++ b/doc/man/man5/slapd-ldap.5
1469@@ -268,7 +268,9 @@ where
1470 .B none
1471 is the default, i.e. no \fIidentity assertion\fP is performed.
1472
1473-The authz parameter is used to instruct the SASL bind to exploit
1474+The
1475+.B authz
1476+parameter is used to instruct the SASL bind to exploit
1477 .B native
1478 SASL authorization, if available; since connections are cached,
1479 this should only be used when authorizing with a fixed identity
1480diff --git a/doc/man/man5/slapd-meta.5 b/doc/man/man5/slapd-meta.5
1481index e3d8089..2134ff6 100644
1482--- a/doc/man/man5/slapd-meta.5
1483+++ b/doc/man/man5/slapd-meta.5
1484@@ -417,7 +417,9 @@ where
1485 .B none
1486 is the default, i.e. no \fIidentity assertion\fP is performed.
1487
1488-The authz parameter is used to instruct the SASL bind to exploit
1489+The
1490+.B authz
1491+parameter is used to instruct the SASL bind to exploit
1492 .B native
1493 SASL authorization, if available; since connections are cached,
1494 this should only be used when authorizing with a fixed identity
1495diff --git a/libraries/Makefile.in b/libraries/Makefile.in
1496index 5d05889..b3a9127 100644
1497--- a/libraries/Makefile.in
1498+++ b/libraries/Makefile.in
1499@@ -24,7 +24,7 @@ PKGCONFIG_DIR=$(DESTDIR)$(libdir)/pkgconfig
1500 PKGCONFIG_SRCDIRS=liblber libldap
1501
1502 install-local:
1503- @$(MKDIR) $(PKGCONFIG_DIR)
1504+ @-$(MKDIR) $(PKGCONFIG_DIR)
1505 @for i in $(PKGCONFIG_SRCDIRS); do \
1506 $(INSTALL_DATA) $$i/*.pc $(PKGCONFIG_DIR); \
1507 done
1508diff --git a/libraries/libldap/deref.c b/libraries/libldap/deref.c
1509index 801954e..f187a9f 100644
1510--- a/libraries/libldap/deref.c
1511+++ b/libraries/libldap/deref.c
1512@@ -160,7 +160,8 @@ ldap_parse_derefresponse_control(
1513 LDAPControl *ctrl,
1514 LDAPDerefRes **drp2 )
1515 {
1516- BerElement *ber;
1517+ BerElementBuffer berbuf;
1518+ BerElement *ber = (BerElement *)&berbuf;
1519 ber_tag_t tag;
1520 ber_len_t len;
1521 char *last;
1522@@ -172,13 +173,8 @@ ldap_parse_derefresponse_control(
1523 return LDAP_PARAM_ERROR;
1524 }
1525
1526- /* Create a BerElement from the berval returned in the control. */
1527- ber = ber_init( &ctrl->ldctl_value );
1528-
1529- if ( ber == NULL ) {
1530- ld->ld_errno = LDAP_NO_MEMORY;
1531- return ld->ld_errno;
1532- }
1533+ /* Set up a BerElement from the berval returned in the control. */
1534+ ber_init2( ber, &ctrl->ldctl_value, 0 );
1535
1536 /* Extract the count and cookie from the control. */
1537 drp = &drhead;
1538@@ -243,8 +239,6 @@ ldap_parse_derefresponse_control(
1539 tag = 0;
1540
1541 done:;
1542- ber_free( ber, 1 );
1543-
1544 if ( tag == LBER_ERROR ) {
1545 if ( drhead != NULL ) {
1546 ldap_derefresponse_free( drhead );
1547diff --git a/libraries/libldap/ldif.c b/libraries/libldap/ldif.c
1548index 900a979..57e44f8 100644
1549--- a/libraries/libldap/ldif.c
1550+++ b/libraries/libldap/ldif.c
1551@@ -729,7 +729,8 @@ ldif_open(
1552 if ( fp ) {
1553 lfp = ber_memalloc( sizeof( LDIFFP ));
1554 if ( lfp == NULL ) {
1555- return NULL;
1556+ fclose( fp );
1557+ return NULL;
1558 }
1559 lfp->fp = fp;
1560 lfp->prev = NULL;
1561diff --git a/libraries/libldap/turn.c b/libraries/libldap/turn.c
1562index 565b449..7725f01 100644
1563--- a/libraries/libldap/turn.c
1564+++ b/libraries/libldap/turn.c
1565@@ -44,7 +44,7 @@ ldap_turn(
1566 {
1567 #ifdef LDAP_EXOP_X_TURN
1568 BerElement *turnvalber = NULL;
1569- struct berval *turnvalp = NULL;
1570+ struct berval turnval;
1571 int rc;
1572
1573 turnvalber = ber_alloc_t( LBER_USE_DER );
1574@@ -53,10 +53,10 @@ ldap_turn(
1575 } else {
1576 ber_printf( turnvalber, "{s}", identifier );
1577 }
1578- ber_flatten( turnvalber, &turnvalp );
1579+ ber_flatten2( turnvalber, &turnval, 0 );
1580
1581 rc = ldap_extended_operation( ld, LDAP_EXOP_X_TURN,
1582- turnvalp, sctrls, cctrls, msgidp );
1583+ &turnval, sctrls, cctrls, msgidp );
1584 ber_free( turnvalber, 1 );
1585 return rc;
1586 #else
1587@@ -74,7 +74,7 @@ ldap_turn_s(
1588 {
1589 #ifdef LDAP_EXOP_X_TURN
1590 BerElement *turnvalber = NULL;
1591- struct berval *turnvalp = NULL;
1592+ struct berval turnval;
1593 int rc;
1594
1595 turnvalber = ber_alloc_t( LBER_USE_DER );
1596@@ -83,10 +83,10 @@ ldap_turn_s(
1597 } else {
1598 ber_printf( turnvalber, "{s}", identifier );
1599 }
1600- ber_flatten( turnvalber, &turnvalp );
1601+ ber_flatten2( turnvalber, &turnval, 0 );
1602
1603 rc = ldap_extended_operation_s( ld, LDAP_EXOP_X_TURN,
1604- turnvalp, sctrls, cctrls, NULL, NULL );
1605+ &turnval, sctrls, cctrls, NULL, NULL );
1606 ber_free( turnvalber, 1 );
1607 return rc;
1608 #else
1609diff --git a/libraries/libldap/txn.c b/libraries/libldap/txn.c
1610index 66b22e8..6409002 100644
1611--- a/libraries/libldap/txn.c
1612+++ b/libraries/libldap/txn.c
1613@@ -68,7 +68,7 @@ ldap_txn_end(
1614 {
1615 int rc;
1616 BerElement *txnber = NULL;
1617- struct berval *txnval = NULL;
1618+ struct berval txnval;
1619
1620 assert( txnid != NULL );
1621
1622@@ -80,10 +80,10 @@ ldap_txn_end(
1623 ber_printf( txnber, "{bON}", commit, txnid );
1624 }
1625
1626- ber_flatten( txnber, &txnval );
1627+ ber_flatten2( txnber, &txnval, 0 );
1628
1629 rc = ldap_extended_operation( ld, LDAP_EXOP_TXN_END,
1630- txnval, sctrls, cctrls, msgidp );
1631+ &txnval, sctrls, cctrls, msgidp );
1632
1633 ber_free( txnber, 1 );
1634 return rc;
1635@@ -100,7 +100,7 @@ ldap_txn_end_s(
1636 {
1637 int rc;
1638 BerElement *txnber = NULL;
1639- struct berval *txnval = NULL;
1640+ struct berval txnval;
1641 struct berval *retdata = NULL;
1642
1643 if ( retidp != NULL ) *retidp = -1;
1644@@ -113,10 +113,10 @@ ldap_txn_end_s(
1645 ber_printf( txnber, "{bON}", commit, txnid );
1646 }
1647
1648- ber_flatten( txnber, &txnval );
1649+ ber_flatten2( txnber, &txnval, 0 );
1650
1651 rc = ldap_extended_operation_s( ld, LDAP_EXOP_TXN_END,
1652- txnval, sctrls, cctrls, NULL, &retdata );
1653+ &txnval, sctrls, cctrls, NULL, &retdata );
1654
1655 ber_free( txnber, 1 );
1656
1657diff --git a/libraries/librewrite/rewrite-int.h b/libraries/librewrite/rewrite-int.h
1658index 0deb72b..441db51 100644
1659--- a/libraries/librewrite/rewrite-int.h
1660+++ b/libraries/librewrite/rewrite-int.h
1661@@ -40,6 +40,11 @@
1662
1663 #include <rewrite.h>
1664
1665+#ifndef NO_THREADS
1666+#define USE_REWRITE_LDAP_PVT_THREADS
1667+#include <ldap_pvt_thread.h>
1668+#endif
1669+
1670 #define malloc(x) ber_memalloc(x)
1671 #define calloc(x,y) ber_memcalloc(x,y)
1672 #define realloc(x,y) ber_memrealloc(x,y)
1673@@ -47,11 +52,6 @@
1674 #undef strdup
1675 #define strdup(x) ber_strdup(x)
1676
1677-#ifndef NO_THREADS
1678-#define USE_REWRITE_LDAP_PVT_THREADS
1679-#include <ldap_pvt_thread.h>
1680-#endif
1681-
1682 /*
1683 * For details, see RATIONALE.
1684 */
1685diff --git a/servers/lloadd/operation.c b/servers/lloadd/operation.c
1686index 4fdc190..9074404 100644
1687--- a/servers/lloadd/operation.c
1688+++ b/servers/lloadd/operation.c
1689@@ -589,19 +589,20 @@ connection_timeout( LloadConnection *upstream, void *arg )
1690 LDAP_ADMINLIMIT_EXCEEDED,
1691 "upstream did not respond in time", 0 );
1692
1693- if ( rc == LDAP_SUCCESS ) {
1694+ if ( upstream->c_type != LLOAD_C_BIND && rc == LDAP_SUCCESS ) {
1695 rc = operation_send_abandon( op, upstream );
1696 }
1697 operation_unlink( op );
1698 }
1699
1700- /* TODO: if operation_send_abandon failed, we need to kill the upstream */
1701 if ( rc == LDAP_SUCCESS ) {
1702 connection_write_cb( -1, 0, upstream );
1703 }
1704
1705 CONNECTION_LOCK(upstream);
1706- if ( upstream->c_state == LLOAD_C_CLOSING && !upstream->c_ops ) {
1707+ /* ITS#9799: If a Bind timed out, connection is in an unknown state */
1708+ if ( upstream->c_type == LLOAD_C_BIND || rc != LDAP_SUCCESS ||
1709+ ( upstream->c_state == LLOAD_C_CLOSING && !upstream->c_ops ) ) {
1710 CONNECTION_DESTROY(upstream);
1711 } else {
1712 CONNECTION_UNLOCK(upstream);
1713diff --git a/servers/slapd/back-mdb/id2entry.c b/servers/slapd/back-mdb/id2entry.c
1714index a7ba23a..aa6067a 100644
1715--- a/servers/slapd/back-mdb/id2entry.c
1716+++ b/servers/slapd/back-mdb/id2entry.c
1717@@ -779,7 +779,17 @@ mdb_opinfo_get( Operation *op, struct mdb_info *mdb, int rdonly, mdb_op_info **m
1718 return rc;
1719 }
1720 if ( ldap_pvt_thread_pool_getkey( ctx, mdb->mi_dbenv, &data, NULL ) ) {
1721+ int retried = 0;
1722+retry:
1723 rc = mdb_txn_begin( mdb->mi_dbenv, NULL, MDB_RDONLY, &moi->moi_txn );
1724+ if (rc == MDB_READERS_FULL && !retried) {
1725+ int dead;
1726+ /* if any stale readers were cleared, a slot should be available */
1727+ if (!mdb_reader_check( mdb->mi_dbenv, &dead ) && dead) {
1728+ retried = 1;
1729+ goto retry;
1730+ }
1731+ }
1732 if (rc) {
1733 Debug( LDAP_DEBUG_ANY, "mdb_opinfo_get: err %s(%d)\n",
1734 mdb_strerror(rc), rc );
1735diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c
1736index 42f9039..cfe35aa 100644
1737--- a/servers/slapd/backend.c
1738+++ b/servers/slapd/backend.c
1739@@ -199,10 +199,7 @@ int backend_startup_one(Backend *be, ConfigReply *cr)
1740
1741 assert( be != NULL );
1742
1743- be->be_pending_csn_list = (struct be_pcl *)
1744- ch_calloc( 1, sizeof( struct be_pcl ) );
1745-
1746- LDAP_TAILQ_INIT( be->be_pending_csn_list );
1747+ LDAP_TAILQ_INIT( &be->be_pcsn_st.be_pcsn_list );
1748
1749 Debug( LDAP_DEBUG_TRACE,
1750 "backend_startup_one: starting \"%s\"\n",
1751@@ -433,18 +430,15 @@ int backend_shutdown( Backend *be )
1752 void
1753 backend_stopdown_one( BackendDB *bd )
1754 {
1755- if ( bd->be_pending_csn_list ) {
1756- struct slap_csn_entry *csne;
1757- csne = LDAP_TAILQ_FIRST( bd->be_pending_csn_list );
1758- while ( csne ) {
1759- struct slap_csn_entry *tmp_csne = csne;
1760+ struct slap_csn_entry *csne;
1761+ csne = LDAP_TAILQ_FIRST( &bd->be_pcsn_st.be_pcsn_list );
1762+ while ( csne ) {
1763+ struct slap_csn_entry *tmp_csne = csne;
1764
1765- LDAP_TAILQ_REMOVE( bd->be_pending_csn_list, csne, ce_csn_link );
1766- ch_free( csne->ce_csn.bv_val );
1767- csne = LDAP_TAILQ_NEXT( csne, ce_csn_link );
1768- ch_free( tmp_csne );
1769- }
1770- ch_free( bd->be_pending_csn_list );
1771+ LDAP_TAILQ_REMOVE( &bd->be_pcsn_st.be_pcsn_list, csne, ce_csn_link );
1772+ ch_free( csne->ce_csn.bv_val );
1773+ csne = LDAP_TAILQ_NEXT( csne, ce_csn_link );
1774+ ch_free( tmp_csne );
1775 }
1776
1777 if ( bd->bd_info->bi_db_destroy ) {
1778@@ -487,7 +481,7 @@ void backend_destroy_one( BackendDB *bd, int dynamic )
1779 ber_bvarray_free( bd->be_update_refs );
1780 }
1781
1782- ldap_pvt_thread_mutex_destroy( &bd->be_pcl_mutex );
1783+ ldap_pvt_thread_mutex_destroy( &bd->be_pcsn_st.be_pcsn_mutex );
1784
1785 if ( dynamic ) {
1786 free( bd );
1787@@ -624,7 +618,8 @@ backend_db_init(
1788 be->be_requires = frontendDB->be_requires;
1789 be->be_ssf_set = frontendDB->be_ssf_set;
1790
1791- ldap_pvt_thread_mutex_init( &be->be_pcl_mutex );
1792+ ldap_pvt_thread_mutex_init( &be->be_pcsn_st.be_pcsn_mutex );
1793+ be->be_pcsn_p = &be->be_pcsn_st;
1794
1795 /* assign a default depth limit for alias deref */
1796 be->be_max_deref_depth = SLAPD_DEFAULT_MAXDEREFDEPTH;
1797@@ -638,7 +633,7 @@ backend_db_init(
1798 /* If we created and linked this be, remove it and free it */
1799 if ( !b0 ) {
1800 LDAP_STAILQ_REMOVE(&backendDB, be, BackendDB, be_next);
1801- ldap_pvt_thread_mutex_destroy( &be->be_pcl_mutex );
1802+ ldap_pvt_thread_mutex_destroy( &be->be_pcsn_st.be_pcsn_mutex );
1803 ch_free( be );
1804 be = NULL;
1805 nbackends--;
1806diff --git a/servers/slapd/backglue.c b/servers/slapd/backglue.c
1807index e7db4ff..3183f2f 100644
1808--- a/servers/slapd/backglue.c
1809+++ b/servers/slapd/backglue.c
1810@@ -1381,6 +1381,11 @@ glue_sub_del( BackendDB *b0 )
1811 gi->gi_nodes--;
1812 }
1813 }
1814+ /* Mark as no longer linked/sub */
1815+ b0->be_flags &= ~(SLAP_DBFLAG_GLUE_SUBORDINATE|SLAP_DBFLAG_GLUE_LINKED|
1816+ SLAP_DBFLAG_GLUE_ADVERTISE);
1817+ b0->be_pcsn_p = &b0->be_pcsn_st;
1818+ break;
1819 }
1820 if ( be == NULL )
1821 rc = LDAP_NO_SUCH_OBJECT;
1822@@ -1440,6 +1445,7 @@ glue_sub_attach( int online )
1823 &gi->gi_n[gi->gi_nodes].gn_pdn );
1824 gi->gi_nodes++;
1825 on->on_bi.bi_private = gi;
1826+ ga->ga_be->be_pcsn_p = be->be_pcsn_p;
1827 ga->ga_be->be_flags |= SLAP_DBFLAG_GLUE_LINKED;
1828 break;
1829 }
1830diff --git a/servers/slapd/bind.c b/servers/slapd/bind.c
1831index 5159461..de602c9 100644
1832--- a/servers/slapd/bind.c
1833+++ b/servers/slapd/bind.c
1834@@ -500,7 +500,7 @@ fe_op_lastbind( Operation *op )
1835 }
1836 }
1837
1838- rc = op->o_bd->be_modify( &op2, &r2 );
1839+ rc = op2.o_bd->be_modify( &op2, &r2 );
1840 slap_mods_free( m, 1 );
1841
1842 done:
1843diff --git a/servers/slapd/ctxcsn.c b/servers/slapd/ctxcsn.c
1844index 55da649..a8f73c3 100644
1845--- a/servers/slapd/ctxcsn.c
1846+++ b/servers/slapd/ctxcsn.c
1847@@ -54,9 +54,9 @@ slap_get_commit_csn(
1848 sid = slap_parse_csn_sid( &op->o_csn );
1849 }
1850
1851- ldap_pvt_thread_mutex_lock( &be->be_pcl_mutex );
1852+ ldap_pvt_thread_mutex_lock( &be->be_pcsn_p->be_pcsn_mutex );
1853
1854- LDAP_TAILQ_FOREACH( csne, be->be_pending_csn_list, ce_csn_link ) {
1855+ LDAP_TAILQ_FOREACH( csne, &be->be_pcsn_p->be_pcsn_list, ce_csn_link ) {
1856 if ( csne->ce_op == op ) {
1857 csne->ce_state = SLAP_CSN_COMMIT;
1858 if ( foundit ) *foundit = 1;
1859@@ -64,7 +64,7 @@ slap_get_commit_csn(
1860 }
1861 }
1862
1863- LDAP_TAILQ_FOREACH( csne, be->be_pending_csn_list, ce_csn_link ) {
1864+ LDAP_TAILQ_FOREACH( csne, &be->be_pcsn_p->be_pcsn_list, ce_csn_link ) {
1865 if ( sid != -1 && sid == csne->ce_sid ) {
1866 if ( csne->ce_state == SLAP_CSN_COMMIT ) committed_csne = csne;
1867 if ( csne->ce_state == SLAP_CSN_PENDING ) break;
1868@@ -82,7 +82,7 @@ slap_get_commit_csn(
1869 maxcsn->bv_val[0] = 0;
1870 }
1871 }
1872- ldap_pvt_thread_mutex_unlock( &be->be_pcl_mutex );
1873+ ldap_pvt_thread_mutex_unlock( &be->be_pcsn_p->be_pcsn_mutex );
1874 }
1875
1876 void
1877@@ -91,16 +91,16 @@ slap_rewind_commit_csn( Operation *op )
1878 struct slap_csn_entry *csne;
1879 BackendDB *be = op->o_bd->bd_self;
1880
1881- ldap_pvt_thread_mutex_lock( &be->be_pcl_mutex );
1882+ ldap_pvt_thread_mutex_lock( &be->be_pcsn_p->be_pcsn_mutex );
1883
1884- LDAP_TAILQ_FOREACH( csne, be->be_pending_csn_list, ce_csn_link ) {
1885+ LDAP_TAILQ_FOREACH( csne, &be->be_pcsn_p->be_pcsn_list, ce_csn_link ) {
1886 if ( csne->ce_op == op ) {
1887 csne->ce_state = SLAP_CSN_PENDING;
1888 break;
1889 }
1890 }
1891
1892- ldap_pvt_thread_mutex_unlock( &be->be_pcl_mutex );
1893+ ldap_pvt_thread_mutex_unlock( &be->be_pcsn_p->be_pcsn_mutex );
1894 }
1895
1896 void
1897@@ -113,11 +113,11 @@ slap_graduate_commit_csn( Operation *op )
1898 if ( op->o_bd == NULL ) return;
1899 be = op->o_bd->bd_self;
1900
1901- ldap_pvt_thread_mutex_lock( &be->be_pcl_mutex );
1902+ ldap_pvt_thread_mutex_lock( &be->be_pcsn_p->be_pcsn_mutex );
1903
1904- LDAP_TAILQ_FOREACH( csne, be->be_pending_csn_list, ce_csn_link ) {
1905+ LDAP_TAILQ_FOREACH( csne, &be->be_pcsn_p->be_pcsn_list, ce_csn_link ) {
1906 if ( csne->ce_op == op ) {
1907- LDAP_TAILQ_REMOVE( be->be_pending_csn_list,
1908+ LDAP_TAILQ_REMOVE( &be->be_pcsn_p->be_pcsn_list,
1909 csne, ce_csn_link );
1910 Debug( LDAP_DEBUG_SYNC, "slap_graduate_commit_csn: removing %p %s\n",
1911 csne, csne->ce_csn.bv_val );
1912@@ -130,7 +130,7 @@ slap_graduate_commit_csn( Operation *op )
1913 }
1914 }
1915
1916- ldap_pvt_thread_mutex_unlock( &be->be_pcl_mutex );
1917+ ldap_pvt_thread_mutex_unlock( &be->be_pcsn_p->be_pcsn_mutex );
1918
1919 return;
1920 }
1921@@ -194,10 +194,10 @@ slap_queue_csn(
1922 pending->ce_op = op;
1923 pending->ce_state = SLAP_CSN_PENDING;
1924
1925- ldap_pvt_thread_mutex_lock( &be->be_pcl_mutex );
1926- LDAP_TAILQ_INSERT_TAIL( be->be_pending_csn_list,
1927+ ldap_pvt_thread_mutex_lock( &be->be_pcsn_p->be_pcsn_mutex );
1928+ LDAP_TAILQ_INSERT_TAIL( &be->be_pcsn_p->be_pcsn_list,
1929 pending, ce_csn_link );
1930- ldap_pvt_thread_mutex_unlock( &be->be_pcl_mutex );
1931+ ldap_pvt_thread_mutex_unlock( &be->be_pcsn_p->be_pcsn_mutex );
1932 }
1933
1934 int
1935diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c
1936index 2f78b77..18db97a 100644
1937--- a/servers/slapd/daemon.c
1938+++ b/servers/slapd/daemon.c
1939@@ -227,11 +227,10 @@ static slap_daemon_st *slap_daemon;
1940 slap_daemon[t].sd_kq = kqueue(); \
1941 } while (0)
1942
1943-/* a kqueue fd obtained before a fork can't be used in child process.
1944- * close it and reacquire it.
1945+/* a kqueue fd obtained before a fork isn't inherited by child process.
1946+ * reacquire it.
1947 */
1948 # define SLAP_SOCK_INIT2() do { \
1949- close(slap_daemon[0].sd_kq); \
1950 slap_daemon[0].sd_kq = kqueue(); \
1951 } while (0)
1952
1953diff --git a/servers/slapd/frontend.c b/servers/slapd/frontend.c
1954index c773f49..d0ca419 100644
1955--- a/servers/slapd/frontend.c
1956+++ b/servers/slapd/frontend.c
1957@@ -108,7 +108,7 @@ frontend_init( void )
1958 frontendDB->be_def_limit.lms_s_pr_hide = 0; /* don't hide number of entries left */
1959 frontendDB->be_def_limit.lms_s_pr_total = 0; /* number of total entries returned by pagedResults equal to hard limit */
1960
1961- ldap_pvt_thread_mutex_init( &frontendDB->be_pcl_mutex );
1962+ ldap_pvt_thread_mutex_init( &frontendDB->be_pcsn_st.be_pcsn_mutex );
1963
1964 /* suffix */
1965 frontendDB->be_suffix = ch_calloc( 2, sizeof( struct berval ) );
1966diff --git a/servers/slapd/overlays/accesslog.c b/servers/slapd/overlays/accesslog.c
1967index ed62c21..cbdaa53 100644
1968--- a/servers/slapd/overlays/accesslog.c
1969+++ b/servers/slapd/overlays/accesslog.c
1970@@ -2283,6 +2283,8 @@ accesslog_db_destroy(
1971 ch_free( li->li_sids );
1972 if ( li->li_mincsn )
1973 ber_bvarray_free( li->li_mincsn );
1974+ if ( li->li_db_suffix.bv_val )
1975+ ch_free( li->li_db_suffix.bv_val );
1976 ldap_pvt_thread_mutex_destroy( &li->li_log_mutex );
1977 ldap_pvt_thread_mutex_destroy( &li->li_op_rmutex );
1978 free( li );
1979diff --git a/servers/slapd/overlays/pcache.c b/servers/slapd/overlays/pcache.c
1980index fcf29c6..423c196 100644
1981--- a/servers/slapd/overlays/pcache.c
1982+++ b/servers/slapd/overlays/pcache.c
1983@@ -4540,7 +4540,6 @@ pcache_db_init(
1984 SLAP_DBFLAGS(&cm->db) |= SLAP_DBFLAG_NO_SCHEMA_CHECK;
1985 cm->db.be_private = NULL;
1986 cm->db.bd_self = &cm->db;
1987- cm->db.be_pending_csn_list = NULL;
1988 cm->qm = qm;
1989 cm->numattrsets = 0;
1990 cm->num_entries_limit = 5;
1991diff --git a/servers/slapd/overlays/ppolicy.c b/servers/slapd/overlays/ppolicy.c
1992index a2c86f6..a3f2e70 100644
1993--- a/servers/slapd/overlays/ppolicy.c
1994+++ b/servers/slapd/overlays/ppolicy.c
1995@@ -1405,7 +1405,8 @@ free_pwd_history_list( pw_hist **l )
1996 }
1997
1998 typedef struct ppbind {
1999- slap_overinst *on;
2000+ pp_info *pi;
2001+ BackendDB *be;
2002 int send_ctrl;
2003 int set_restrict;
2004 LDAPControl **oldctrls;
2005@@ -1455,8 +1456,7 @@ static int
2006 ppolicy_bind_response( Operation *op, SlapReply *rs )
2007 {
2008 ppbind *ppb = op->o_callback->sc_private;
2009- slap_overinst *on = ppb->on;
2010- pp_info *pi = on->on_bi.bi_private;
2011+ pp_info *pi = ppb->pi;
2012 Modifications *mod = ppb->mod, *m;
2013 int pwExpired = 0;
2014 int ngut = -1, warn = -1, fc = 0, age, rc;
2015@@ -1467,7 +1467,7 @@ ppolicy_bind_response( Operation *op, SlapReply *rs )
2016 char nowstr[ LDAP_LUTIL_GENTIME_BUFSIZE ];
2017 char nowstr_usec[ LDAP_LUTIL_GENTIME_BUFSIZE+8 ];
2018 struct berval timestamp, timestamp_usec;
2019- BackendInfo *bi = op->o_bd->bd_info;
2020+ BackendDB *be = op->o_bd;
2021 LDAPControl *ctrl = NULL;
2022 Entry *e;
2023
2024@@ -1477,9 +1477,9 @@ ppolicy_bind_response( Operation *op, SlapReply *rs )
2025 goto locked;
2026 }
2027
2028- op->o_bd->bd_info = (BackendInfo *)on->on_info;
2029+ op->o_bd = ppb->be;
2030 rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &e );
2031- op->o_bd->bd_info = bi;
2032+ op->o_bd = be;
2033
2034 if ( rc != LDAP_SUCCESS ) {
2035 ldap_pvt_thread_mutex_unlock( &pi->pwdFailureTime_mutex );
2036@@ -1781,8 +1781,9 @@ check_expiring_password:
2037 }
2038
2039 done:
2040- op->o_bd->bd_info = (BackendInfo *)on->on_info;
2041+ op->o_bd = ppb->be;
2042 be_entry_release_r( op, e );
2043+ op->o_bd = be;
2044
2045 locked:
2046 if ( mod && !pi->disable_write ) {
2047@@ -1821,7 +1822,7 @@ locked:
2048 op2.orm_no_opattrs = 1;
2049 op2.o_dont_replicate = 1;
2050 }
2051- op2.o_bd->bd_info = (BackendInfo *)on->on_info;
2052+ op2.o_bd = ppb->be;
2053 }
2054 rc = op2.o_bd->be_modify( &op2, &r2 );
2055 if ( rc != LDAP_SUCCESS ) {
2056@@ -1852,7 +1853,6 @@ locked:
2057 ppb->oldctrls = add_passcontrol( op, rs, ctrl );
2058 op->o_callback->sc_cleanup = ppolicy_ctrls_cleanup;
2059 }
2060- op->o_bd->bd_info = bi;
2061 ldap_pvt_thread_mutex_unlock( &pi->pwdFailureTime_mutex );
2062 return SLAP_CB_CONTINUE;
2063 }
2064@@ -1885,7 +1885,8 @@ ppolicy_bind( Operation *op, SlapReply *rs )
2065 cb = op->o_tmpcalloc( sizeof(ppbind)+sizeof(slap_callback),
2066 1, op->o_tmpmemctx );
2067 ppb = (ppbind *)(cb+1);
2068- ppb->on = on;
2069+ ppb->pi = on->on_bi.bi_private;
2070+ ppb->be = op->o_bd->bd_self;
2071 ppb->pErr = PP_noError;
2072 ppb->set_restrict = 1;
2073
2074@@ -2175,7 +2176,8 @@ ppolicy_compare(
2075 cb = op->o_tmpcalloc( sizeof(ppbind)+sizeof(slap_callback),
2076 1, op->o_tmpmemctx );
2077 ppb = (ppbind *)(cb+1);
2078- ppb->on = on;
2079+ ppb->pi = on->on_bi.bi_private;
2080+ ppb->be = op->o_bd->bd_self;
2081 ppb->pErr = PP_noError;
2082 ppb->send_ctrl = 1;
2083 /* failures here don't lockout the connection */
2084diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c
2085index 36978d6..6d749a5 100644
2086--- a/servers/slapd/overlays/syncprov.c
2087+++ b/servers/slapd/overlays/syncprov.c
2088@@ -3163,6 +3163,8 @@ syncprov_op_search( Operation *op, SlapReply *rs )
2089 */
2090 ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
2091 if ( slapd_shutdown ) {
2092+aband:
2093+ ch_free( sop->s_base.bv_val );
2094 ch_free( sop );
2095 return SLAPD_ABANDON;
2096 }
2097@@ -3172,8 +3174,7 @@ syncprov_op_search( Operation *op, SlapReply *rs )
2098 }
2099 if ( op->o_abandon ) {
2100 ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
2101- ch_free( sop );
2102- return SLAPD_ABANDON;
2103+ goto aband;
2104 }
2105 ldap_pvt_thread_mutex_init( &sop->s_mutex );
2106 sop->s_next = si->si_ops;
2107@@ -3242,14 +3243,8 @@ syncprov_op_search( Operation *op, SlapReply *rs )
2108 if (srs->sr_state.numcsns != numcsns) {
2109 /* consumer doesn't have the right number of CSNs */
2110 Debug( LDAP_DEBUG_SYNC, "%s syncprov_op_search: "
2111- "consumer cookie is missing a csn we track%s\n",
2112- op->o_log_prefix, si->si_nopres ? ", rejecting" : "" );
2113-
2114- if ( si->si_nopres ) {
2115- rs->sr_err = LDAP_SYNC_REFRESH_REQUIRED;
2116- rs->sr_text = "not enough information to resync, please use other means";
2117- goto bailout;
2118- }
2119+ "consumer cookie is missing a csn we track\n",
2120+ op->o_log_prefix );
2121
2122 changed = SS_CHANGED;
2123 if ( srs->sr_state.ctxcsn ) {
2124@@ -3302,6 +3297,7 @@ bailout:
2125 sp = &(*sp)->s_next;
2126 *sp = sop->s_next;
2127 ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
2128+ ch_free( sop->s_base.bv_val );
2129 ch_free( sop );
2130 }
2131 rs->sr_ctrls = NULL;
2132@@ -3348,7 +3344,55 @@ no_change: if ( !(op->o_sync_mode & SLAP_SYNC_PERSIST) ) {
2133 numcsns, sids, &mincsn, minsid ) ) {
2134 do_present = SS_PRESENT;
2135 }
2136+ } else if ( ad_minCSN != NULL && si->si_nopres && si->si_usehint ) {
2137+ /* We are instructed to trust minCSN if it exists. */
2138+ Entry *e;
2139+ Attribute *a = NULL;
2140+ int rc;
2141+
2142+ /*
2143+ * ITS#9580 FIXME: when we've figured out and split the
2144+ * sessionlog/deltalog tracking, use the appropriate attribute
2145+ */
2146+ rc = overlay_entry_get_ov( op, &op->o_bd->be_nsuffix[0], NULL,
2147+ ad_minCSN, 0, &e, on );
2148+ if ( rc == LDAP_SUCCESS && e != NULL ) {
2149+ a = attr_find( e->e_attrs, ad_minCSN );
2150+ }
2151+
2152+ if ( a != NULL ) {
2153+ int *minsids;
2154+
2155+ minsids = slap_parse_csn_sids( a->a_vals, a->a_numvals, op->o_tmpmemctx );
2156+ slap_sort_csn_sids( a->a_vals, minsids, a->a_numvals, op->o_tmpmemctx );
2157+
2158+ for ( i=0, j=0; i < a->a_numvals; i++ ) {
2159+ while ( j < numcsns && minsids[i] > sids[j] ) j++;
2160+ if ( j < numcsns && minsids[i] == sids[j] &&
2161+ ber_bvcmp( &a->a_vals[i], &srs->sr_state.ctxcsn[j] ) <= 0 ) {
2162+ /* minCSN for this serverID is contained, keep going */
2163+ continue;
2164+ }
2165+ /*
2166+ * Log DB's minCSN claims we can only replay from a certain
2167+ * CSN for this serverID, but consumer's cookie hasn't met that
2168+ * threshold: they need to refresh
2169+ */
2170+ Debug( LDAP_DEBUG_SYNC, "%s syncprov_op_search: "
2171+ "consumer not within recorded mincsn for DB's mincsn=%s\n",
2172+ op->o_log_prefix, a->a_vals[i].bv_val );
2173+ rs->sr_err = LDAP_SYNC_REFRESH_REQUIRED;
2174+ rs->sr_text = "sync cookie is stale";
2175+ slap_sl_free( minsids, op->o_tmpmemctx );
2176+ overlay_entry_release_ov( op, e, 0, on );
2177+ goto bailout;
2178+ }
2179+ slap_sl_free( minsids, op->o_tmpmemctx );
2180+ }
2181+ if ( e != NULL )
2182+ overlay_entry_release_ov( op, e, 0, on );
2183 }
2184+
2185 /*
2186 * If sessionlog wasn't useful, see if we can find at least one entry
2187 * that hasn't changed based on the cookie.
2188@@ -3793,6 +3837,10 @@ sp_cf_gen(ConfigArgs *c)
2189 break;
2190 case SP_USEHINT:
2191 si->si_usehint = c->value_int;
2192+ if ( si->si_usehint ) {
2193+ /* Consider we might be a delta provider, but it's ok if not */
2194+ (void)syncprov_setup_accesslog();
2195+ }
2196 break;
2197 case SP_LOGDB:
2198 if ( si->si_logs ) {
2199@@ -4137,6 +4185,8 @@ syncprov_db_destroy(
2200 ber_bvarray_free( si->si_ctxcsn );
2201 if ( si->si_sids )
2202 ch_free( si->si_sids );
2203+ if ( si->si_logbase.bv_val )
2204+ ch_free( si->si_logbase.bv_val );
2205 ldap_pvt_thread_mutex_destroy( &si->si_resp_mutex );
2206 ldap_pvt_thread_mutex_destroy( &si->si_mods_mutex );
2207 ldap_pvt_thread_mutex_destroy( &si->si_ops_mutex );
2208diff --git a/servers/slapd/overlays/translucent.c b/servers/slapd/overlays/translucent.c
2209index a034a58..2d31bb0 100644
2210--- a/servers/slapd/overlays/translucent.c
2211+++ b/servers/slapd/overlays/translucent.c
2212@@ -1439,7 +1439,7 @@ translucent_db_destroy( BackendDB *be, ConfigReply *cr )
2213 backend_stopdown_one( &ov->db );
2214 }
2215
2216- ldap_pvt_thread_mutex_destroy( &ov->db.be_pcl_mutex );
2217+ ldap_pvt_thread_mutex_destroy( &ov->db.be_pcsn_st.be_pcsn_mutex );
2218 ch_free(ov);
2219 on->on_bi.bi_private = NULL;
2220 }
2221diff --git a/servers/slapd/overlays/unique.c b/servers/slapd/overlays/unique.c
2222index 952c1ed..7a7c8fb 100644
2223--- a/servers/slapd/overlays/unique.c
2224+++ b/servers/slapd/overlays/unique.c
2225@@ -1225,13 +1225,15 @@ unique_modify(
2226 return rc;
2227 }
2228
2229- if ( SLAPD_SYNC_IS_SYNCCONN( op->o_connid ) || (
2230- get_relax(op) > SLAP_CONTROL_IGNORED
2231- && overlay_entry_get_ov(op, &op->o_req_ndn, NULL, NULL, 0, &e, on) == LDAP_SUCCESS
2232- && e
2233- && access_allowed( op, e,
2234- slap_schema.si_ad_entry, NULL,
2235- ACL_MANAGE, NULL ) ) ) {
2236+ if ( SLAPD_SYNC_IS_SYNCCONN( op->o_connid ) ) {
2237+ return rc;
2238+ }
2239+ if ( get_relax(op) > SLAP_CONTROL_IGNORED
2240+ && overlay_entry_get_ov( op, &op->o_req_ndn, NULL, NULL, 0, &e, on ) == LDAP_SUCCESS
2241+ && e
2242+ && access_allowed( op, e,
2243+ slap_schema.si_ad_entry, NULL,
2244+ ACL_MANAGE, NULL ) ) {
2245 overlay_entry_release_ov( op, e, 0, on );
2246 return rc;
2247 }
2248@@ -1363,13 +1365,15 @@ unique_modrdn(
2249 Debug(LDAP_DEBUG_TRACE, "==> unique_modrdn <%s> <%s>\n",
2250 op->o_req_dn.bv_val, op->orr_newrdn.bv_val );
2251
2252- if ( SLAPD_SYNC_IS_SYNCCONN( op->o_connid ) || (
2253- get_relax(op) > SLAP_CONTROL_IGNORED
2254- && overlay_entry_get_ov(op, &op->o_req_ndn, NULL, NULL, 0, &e, on) == LDAP_SUCCESS
2255- && e
2256- && access_allowed( op, e,
2257- slap_schema.si_ad_entry, NULL,
2258- ACL_MANAGE, NULL ) ) ) {
2259+ if ( SLAPD_SYNC_IS_SYNCCONN( op->o_connid ) ) {
2260+ return rc;
2261+ }
2262+ if ( get_relax(op) > SLAP_CONTROL_IGNORED
2263+ && overlay_entry_get_ov( op, &op->o_req_ndn, NULL, NULL, 0, &e, on ) == LDAP_SUCCESS
2264+ && e
2265+ && access_allowed( op, e,
2266+ slap_schema.si_ad_entry, NULL,
2267+ ACL_MANAGE, NULL ) ) {
2268 overlay_entry_release_ov( op, e, 0, on );
2269 return rc;
2270 }
2271diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h
2272index 0fc78d7..5cf2f46 100644
2273--- a/servers/slapd/slap.h
2274+++ b/servers/slapd/slap.h
2275@@ -1786,7 +1786,13 @@ struct sync_cookie {
2276
2277 LDAP_STAILQ_HEAD( slap_sync_cookie_s, sync_cookie );
2278
2279-LDAP_TAILQ_HEAD( be_pcl, slap_csn_entry );
2280+/* Defs for pending_csn_list */
2281+LDAP_TAILQ_HEAD( be_pclh, slap_csn_entry );
2282+
2283+typedef struct be_pcsn {
2284+ struct be_pclh be_pcsn_list;
2285+ ldap_pvt_thread_mutex_t be_pcsn_mutex;
2286+} be_pcsn;
2287
2288 #ifndef SLAP_MAX_CIDS
2289 #define SLAP_MAX_CIDS 32 /* Maximum number of supported controls */
2290@@ -1990,8 +1996,8 @@ struct BackendDB {
2291 /* Consumer Information */
2292 struct berval be_update_ndn; /* allowed to make changes (in replicas) */
2293 BerVarray be_update_refs; /* where to refer modifying clients to */
2294- struct be_pcl *be_pending_csn_list;
2295- ldap_pvt_thread_mutex_t be_pcl_mutex;
2296+ be_pcsn be_pcsn_st; /* be_pending_csn_list now inside this */
2297+ be_pcsn *be_pcsn_p;
2298 struct syncinfo_s *be_syncinfo; /* For syncrepl */
2299
2300 void *be_pb; /* Netscape plugin */
2301diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c
2302index 6ed5580..52e67e4 100644
2303--- a/servers/slapd/syncrepl.c
2304+++ b/servers/slapd/syncrepl.c
2305@@ -3107,10 +3107,8 @@ syncrepl_message_to_op(
2306 ch_free( bvals );
2307 goto done;
2308 }
2309- ber_dupbv( &op->o_req_dn, &dn );
2310- ber_dupbv( &op->o_req_ndn, &ndn );
2311- slap_sl_free( ndn.bv_val, op->o_tmpmemctx );
2312- slap_sl_free( dn.bv_val, op->o_tmpmemctx );
2313+ op->o_req_dn = dn;
2314+ op->o_req_ndn = ndn;
2315 freeReqDn = 1;
2316 } else if ( !ber_bvstrcasecmp( &bv, &ls->ls_req ) ) {
2317 int i = verb_to_mask( bvals[0].bv_val, modops );
2318@@ -3220,9 +3218,8 @@ syncrepl_message_to_op(
2319 if ( op->o_tag == LDAP_REQ_ADD ) {
2320 Entry *e = entry_alloc();
2321 op->ora_e = e;
2322- op->ora_e->e_name = op->o_req_dn;
2323- op->ora_e->e_nname = op->o_req_ndn;
2324- freeReqDn = 0;
2325+ ber_dupbv( &op->ora_e->e_name, &op->o_req_dn );
2326+ ber_dupbv( &op->ora_e->e_nname, &op->o_req_ndn );
2327 rc = slap_mods2entry( modlist, &op->ora_e, 1, 0, &text, txtbuf, textlen);
2328 if( rc != LDAP_SUCCESS ) {
2329 Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_op: %s "
2330@@ -3353,8 +3350,8 @@ done:
2331 }
2332 }
2333 if ( freeReqDn ) {
2334- ch_free( op->o_req_ndn.bv_val );
2335- ch_free( op->o_req_dn.bv_val );
2336+ op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
2337+ op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
2338 }
2339 ber_free( ber, 0 );
2340 return rc;
2341diff --git a/tests/data/slapd-deltasync-provider.conf b/tests/data/slapd-deltasync-provider.conf
2342index 03fd714..14327d1 100644
2343--- a/tests/data/slapd-deltasync-provider.conf
2344+++ b/tests/data/slapd-deltasync-provider.conf
2345@@ -29,6 +29,10 @@ argsfile @TESTDIR@/slapd.1.args
2346 #accesslogmod#modulepath ../servers/slapd/overlays/
2347 #accesslogmod#moduleload accesslog.la
2348
2349+database config
2350+include @TESTDIR@/configpw.conf
2351+
2352+
2353 #######################################################################
2354 # provider database definitions
2355 #######################################################################
2356diff --git a/tests/progs/Makefile.in b/tests/progs/Makefile.in
2357index 0421982..5e7a2a2 100644
2358--- a/tests/progs/Makefile.in
2359+++ b/tests/progs/Makefile.in
2360@@ -56,7 +56,7 @@ slapd-modify: slapd-modify.o $(OBJS) $(XLIBS)
2361 slapd-bind: slapd-bind.o $(OBJS) $(XLIBS)
2362 $(LTLINK) -o $@ slapd-bind.o $(OBJS) $(LIBS)
2363
2364-ldif-filter: ldif-filter.o $(XLIBS)
2365+ldif-filter: ldif-filter.o $(OBJS) $(XLIBS)
2366 $(LTLINK) -o $@ ldif-filter.o $(OBJS) $(LIBS)
2367
2368 slapd-mtread: slapd-mtread.o $(OBJS) $(XLIBS)
2369diff --git a/tests/progs/slapd-watcher.c b/tests/progs/slapd-watcher.c
2370index 116d63f..0fed11f 100644
2371--- a/tests/progs/slapd-watcher.c
2372+++ b/tests/progs/slapd-watcher.c
2373@@ -139,12 +139,13 @@ usage( char *name, char opt )
2374 "[-x | -Y <SASL mech>] "
2375 "[-i <interval>] "
2376 "[-s <sids>] "
2377+ "[-c <contextDN>] "
2378 "[-b <baseDN> ] URI[...]\n",
2379 name );
2380 exit( EXIT_FAILURE );
2381 }
2382
2383-struct berval base;
2384+struct berval base, cbase;
2385 int interval = 10;
2386 int numservers;
2387 server *servers;
2388@@ -509,9 +510,9 @@ setup_server( struct tester_conn_args *config, server *sv, int first )
2389 }
2390 ldap_msgfree( res );
2391
2392- if ( base.bv_val ) {
2393+ if ( cbase.bv_val ) {
2394 char *attr2[] = { at_contextCSN.bv_val, NULL };
2395- rc = ldap_search_ext_s( ld, base.bv_val, LDAP_SCOPE_BASE, "(objectClass=*)",
2396+ rc = ldap_search_ext_s( ld, cbase.bv_val, LDAP_SCOPE_BASE, "(objectClass=*)",
2397 attr2, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &res );
2398 switch(rc) {
2399 case LDAP_SUCCESS:
2400@@ -573,11 +574,17 @@ main( int argc, char **argv )
2401 config = tester_init( "slapd-watcher", TESTER_TESTER );
2402 config->authmethod = LDAP_AUTH_SIMPLE;
2403
2404- while ( ( i = getopt( argc, argv, "D:O:R:U:X:Y:b:d:i:s:w:x" ) ) != EOF )
2405+ while ( ( i = getopt( argc, argv, "D:O:R:U:X:Y:b:c:d:i:s:w:x" ) ) != EOF )
2406 {
2407 switch ( i ) {
2408- case 'b': /* base DN for contextCSN lookups */
2409+ case 'b': /* base DN for DB entrycount lookups */
2410 ber_str2bv( optarg, 0, 0, &base );
2411+ if ( !cbase.bv_val )
2412+ cbase = base;
2413+ break;
2414+
2415+ case 'c': /* base DN for contextCSN lookups */
2416+ ber_str2bv( optarg, 0, 0, &cbase );
2417 break;
2418
2419 case 'i':
2420@@ -628,7 +635,7 @@ main( int argc, char **argv )
2421 monfilter = MONFILTER;
2422 }
2423
2424- if ( numservers > 1 ) {
2425+ if ( sids || numservers > 1 ) {
2426 for ( i=0; i<numservers; i++ )
2427 if ( sids )
2428 servers[i].sid = atoi(sids[i]);
2429@@ -693,7 +700,7 @@ server_down1:
2430 }
2431 if (( servers[i].flags & HAS_BASE ) && !msg2[i] ) {
2432 char *attrs[2] = { at_contextCSN.bv_val };
2433- rc = ldap_search_ext( ld, base.bv_val,
2434+ rc = ldap_search_ext( ld, cbase.bv_val,
2435 LDAP_SCOPE_BASE, "(objectClass=*)",
2436 attrs, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &msg2[i] );
2437 if ( rc != LDAP_SUCCESS ) {
2438diff --git a/tests/scripts/test020-proxycache b/tests/scripts/test020-proxycache
2439index 8b38a7b..af4cc9e 100755
2440--- a/tests/scripts/test020-proxycache
2441+++ b/tests/scripts/test020-proxycache
2442@@ -40,6 +40,11 @@ if test $BACKEND = ldif ; then
2443 exit 0
2444 fi
2445
2446+if test $BACKEND = wt ; then
2447+ echo "Test does not support $BACKEND backend, test skipped"
2448+ exit 0
2449+fi
2450+
2451 mkdir -p $TESTDIR $DBDIR1 $DBDIR2
2452
2453 # Test proxy caching:
2454diff --git a/tests/scripts/test043-delta-syncrepl b/tests/scripts/test043-delta-syncrepl
2455index c919478..0d30e72 100755
2456--- a/tests/scripts/test043-delta-syncrepl
2457+++ b/tests/scripts/test043-delta-syncrepl
2458@@ -34,6 +34,8 @@ mkdir -p $TESTDIR $DBDIR1A $DBDIR1B $DBDIR2
2459
2460 SPEC="mdb=a"
2461
2462+$SLAPPASSWD -g -n >$CONFIGPWF
2463+echo "rootpw `$SLAPPASSWD -T $CONFIGPWF`" >$TESTDIR/configpw.conf
2464 #
2465 # Test replication:
2466 # - start provider
2467@@ -129,6 +131,7 @@ sleep $SLEEP1
2468
2469 echo "Stopping the provider, sleeping 10 seconds and restarting it..."
2470 kill -HUP "$PID"
2471+wait $PID
2472 sleep 10
2473 echo "RESTART" >> $LOG1
2474 $SLAPD -f $CONF1 -h $URI1 -d $LVL >> $LOG1 2>&1 &
2475@@ -296,7 +299,8 @@ fi
2476
2477 echo "Stopping consumer to test recovery..."
2478 kill -HUP $CONSUMERPID
2479-sleep 10
2480+wait $CONSUMERPID
2481+KILLPIDS="$PID"
2482
2483 echo "Modifying more entries on the provider..."
2484 $LDAPMODIFY -v -D "$BJORNSDN" -H $URI1 -w bjorn >> \
2485@@ -388,6 +392,144 @@ if test $RC != 0 ; then
2486 exit $RC
2487 fi
2488
2489+echo "Filtering provider results..."
2490+$LDIFFILTER -b $BACKEND -s $SPEC < $PROVIDEROUT | grep -iv "^auditcontext:" > $PROVIDERFLT
2491+echo "Filtering consumer results..."
2492+$LDIFFILTER -b $BACKEND -s $SPEC < $CONSUMEROUT | grep -iv "^auditcontext:" > $CONSUMERFLT
2493+
2494+echo "Comparing retrieved entries from provider and consumer..."
2495+$CMP $PROVIDERFLT $CONSUMERFLT > $CMPOUT
2496+
2497+if test $? != 0 ; then
2498+ echo "test failed - provider and consumer databases differ"
2499+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
2500+ exit 1
2501+fi
2502+
2503+echo "Stopping consumer to test recovery after logpurge expired..."
2504+kill -HUP $CONSUMERPID
2505+wait $CONSUMERPID
2506+KILLPIDS="$PID"
2507+
2508+echo "Modifying even more entries on the provider..."
2509+$LDAPMODIFY -v -D "$BJORNSDN" -H $URI1 -w bjorn >> \
2510+ $TESTOUT 2>&1 << EOMODS
2511+dn: cn=Dorothy Stevens,ou=Alumni Association,ou=People,dc=example,dc=com
2512+changetype: delete
2513+
2514+dn: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, dc=example,dc=com
2515+changetype: modify
2516+add: drink
2517+drink: Sangria
2518+
2519+dn: cn=George D. Stevens, ou=Retired, ou=People, dc=example,dc=com
2520+changetype: add
2521+objectclass: OpenLDAPperson
2522+sn: Stevens
2523+uid: gstevens
2524+cn: George D. Stevens
2525+
2526+dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example,
2527+ dc=com
2528+changetype: modify
2529+replace: drink
2530+drink: cold water
2531+
2532+dn: cn=Some Staff,ou=Groups,dc=example,dc=com
2533+changetype: modrdn
2534+newrdn: cn=More Staff
2535+deleteoldrdn: 1
2536+
2537+EOMODS
2538+
2539+echo "Configuring logpurge of 1 second..."
2540+$LDAPMODIFY -v -D cn=config -H $URI1 -y $CONFIGPWF >> \
2541+ $TESTOUT 2>&1 << EOMODS
2542+
2543+dn: olcOverlay={1}accesslog,olcDatabase={2}$BACKEND,cn=config
2544+changetype: modify
2545+replace: olcAccessLogPurge
2546+olcAccessLogPurge: 0+00:00:02 0+00:00:01
2547+-
2548+
2549+EOMODS
2550+RC=$?
2551+if test $RC != 0 ; then
2552+ echo "ldapmodify failed ($RC)!"
2553+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
2554+ exit $RC
2555+fi
2556+
2557+echo "Waiting 4 seconds for accesslog to be purged..."
2558+sleep 4
2559+
2560+echo "Using ldapsearch to check if accesslog is empty..."
2561+for i in 0 1 2 3 4 5; do
2562+ $LDAPSEARCH -b "cn=log" -H $URI1 -z 1 \
2563+ > $SEARCHOUT 2>&1
2564+ RC=$?
2565+ if test $RC = 0 ; then
2566+ break
2567+ fi
2568+ echo "Waiting 3 seconds for accesslog to be purged..."
2569+ sleep 3
2570+done
2571+
2572+if test $RC != 0; then
2573+ echo "Accesslog did not purge in time"
2574+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
2575+ exit 1
2576+fi
2577+
2578+
2579+echo "Restarting consumer..."
2580+echo "RESTART" >> $LOG2
2581+$SLAPD -f $CONF2 -h $URI2 -d $LVL >> $LOG2 2>&1 &
2582+CONSUMERPID=$!
2583+if test $WAIT != 0 ; then
2584+ echo CONSUMERPID $CONSUMERPID
2585+ read foo
2586+fi
2587+KILLPIDS="$PID $CONSUMERPID"
2588+
2589+echo "Waiting $SLEEP1 seconds for syncrepl to reschedule (ITS#9878) and poking it..."
2590+sleep $SLEEP1
2591+
2592+$LDAPSEARCH -s base -b "$MONITOR" -H $URI2 \
2593+ 'objectclass=*' > /dev/null 2>&1
2594+RC=$?
2595+
2596+if test $RC != 0; then
2597+ echo "ldapsearch failed at consumer ($RC)!"
2598+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
2599+ exit 1
2600+fi
2601+
2602+echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..."
2603+sleep $SLEEP1
2604+
2605+echo "Using ldapsearch to read all the entries from the provider..."
2606+$LDAPSEARCH -S "" -b "$BASEDN" -H $URI1 \
2607+ 'objectclass=*' \* + > $PROVIDEROUT 2>&1
2608+RC=$?
2609+
2610+if test $RC != 0 ; then
2611+ echo "ldapsearch failed at provider ($RC)!"
2612+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
2613+ exit $RC
2614+fi
2615+
2616+echo "Using ldapsearch to read all the entries from the consumer..."
2617+$LDAPSEARCH -S "" -b "$BASEDN" -H $URI2 \
2618+ 'objectclass=*' \* + > $CONSUMEROUT 2>&1
2619+RC=$?
2620+
2621+if test $RC != 0 ; then
2622+ echo "ldapsearch failed at consumer ($RC)!"
2623+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
2624+ exit $RC
2625+fi
2626+
2627 test $KILLSERVERS != no && kill -HUP $KILLPIDS
2628
2629 echo "Filtering provider results..."

Subscribers

People subscribed via source and target branches