From 72461ef5f4fe2da4179bc80a8523913367b0a303 Mon Sep 17 00:00:00 2001 From: zyppe <210hcl@gmail.com> Date: Wed, 28 Feb 2024 21:00:53 +0800 Subject: [PATCH] Initialize for openldap2 --- .gitignore | 3 + .openldap2.metadata | 3 + ...nique-to-return-filter-used-in-diagn.patch | 66 + 0003-LDAPI-socket-location.dif | 22 + 0005-pie-compile.dif | 131 ++ 0006-No-Build-date-and-time-in-binaries.dif | 33 + 0007-Recover-on-DB-version-change.dif | 29 + ...nd-do-not-return-Connection0-entries.patch | 29 + 0009-Fix-ldap-host-lookup-ipv6.patch | 73 + 0011-openldap-re24-its7796.patch | 80 + 0012-ITS8051-sockdnpat.patch | 128 ++ ...DED-operation-message-from-back-sock.patch | 241 ++ ...ar-shared-key-only-in-close-function.patch | 16 + 0017-Fix-segfault-in-nops.patch | 35 + ...lculation-of-consecutive-number-of-c.patch | 130 ++ ...zero-out-sasl_ssf-in-connection_init.patch | 25 + ...ict-rootDN-proxyauthz-to-its-own-DBs.patch | 36 + ...ate-test028-to-test-this-is-enforced.patch | 102 + 0204-ITS-9038-Another-test028-typo.patch | 25 + ...170771-limit-depth-of-nested-filters.patch | 128 ++ ...-tlso-use-openssl-api-to-verify-host.patch | 224 ++ ...0-check-for-equality-rule-on-old_rdn.patch | 27 + 0208-ITS-9400-back-ldap-fix-retry-binds.patch | 252 ++ ...ve-assert-in-certificateListValidate.patch | 26 + ...ve-assert-in-obsolete-csnNormalize23.patch | 27 + ...TS-9454-fix-issuerAndThisUpdateCheck.patch | 25 + ...-9404-fix-serialNumberAndIssuerCheck.patch | 58 + ...S-9406-9407-remove-saslauthz-asserts.patch | 69 + 0214-ITS-9406-fix-debug-msg.patch | 33 + 0215-ITS-9408-fix-vrfilter-double-free.patch | 28 + ...slauthz-use-ch_free-on-normalized-DN.patch | 25 + ...uthz-use-slap_sl_free-in-prev-commit.patch | 25 + ...ITS-9412-fix-AVA_Sort-on-invalid-RDN.patch | 42 + 0219-ITS-9413-fix-slap_parse_user.patch | 38 + ...09dn2bv-check-for-invalid-BER-after-.patch | 48 + ...fix-serialNumberAndIssuerSerialCheck.patch | 25 + ...25-add-more-checks-to-ldap_X509dn2bv.patch | 45 + ...TS-9427-fix-issuerAndThisUpdateCheck.patch | 25 + 0224-ITS-9428-fix-cancel-exop.patch | 28 + ...-Separate-Avlnode-and-TAvlnode-types.patch | 417 ++++ ...ap-added-task-that-prunes-expired-co.patch | 1460 ++++++++++++ ...e-timeouts-in-test-case-due-to-spora.patch | 166 ++ 0228-ITS-9197-fix-typo-in-prev-commit.patch | 25 + 0229-ITS-9197-Fix-test-script.patch | 66 + ...TS-9197-fix-info-msg-for-slapd-check.patch | 34 + ...est-case-for-proxy-re-binding-anonym.patch | 591 +++++ ...ap-Return-disconect-if-rebind-cannot.patch | 52 + ...emoved-accidental-unicode-characters.patch | 39 + ...ted-that-re-connecting-does-not-happ.patch | 58 + ...rize-discussion-about-rebind-as-user.patch | 58 + 0236-ITS-9468-fixed-typos.patch | 27 + ...ways-init-lc_time-and-lc_create_time.patch | 59 + ...arm-expire-timer-for-connections-tha.patch | 91 + 0239-ITS-9422-Update-for-TLS-v1.3.patch | 43 + ...d-LDAP_OPT_X_TLS_PROTOCOL_MAX-option.patch | 216 ++ 0241-TLS-set-protocol-version.patch | 47 + ...-9815-slapd-sql-escape-filter-values.patch | 273 +++ ...-use-calloc-to-prevent-memory-reuse-.patch | 77 + ...pen_url-check-for-ber_strdup-failure.patch | 26 + ...nnection-when-receiving-non-LDAP-dat.patch | 44 + DB_CONFIG | 7 + README.module-loading | 25 + SuSEfirewall2.openldap | 17 + baselibs.conf | 6 + fixup-modulepath.sh | 42 + openldap-r-only.dif | 24 + openldap2-rpmlintrc | 3 + openldap2.changes | 2034 +++++++++++++++++ openldap2.conf | 3 + openldap2.spec | 731 ++++++ ppolicy-check-password.5 | 182 ++ ppolicy-check-password.Makefile | 43 + ppolicy-check-password.conf | 7 + sasl-slapd.conf | 1 + schema2ldif | 53 + slapd-ldif-update-crc.sh | 33 + slapd.conf | 89 + slapd.conf.example | 354 +++ slapd.conf.olctemplate | 46 + slapd.service | 11 + start | 178 ++ sysconfig.openldap | 160 ++ update-crc.sh | 67 + 83 files changed, 10390 insertions(+) create mode 100644 .gitignore create mode 100644 .openldap2.metadata create mode 100644 0001-ITS-8866-slapo-unique-to-return-filter-used-in-diagn.patch create mode 100644 0003-LDAPI-socket-location.dif create mode 100644 0005-pie-compile.dif create mode 100644 0006-No-Build-date-and-time-in-binaries.dif create mode 100644 0007-Recover-on-DB-version-change.dif create mode 100644 0008-In-monitor-backend-do-not-return-Connection0-entries.patch create mode 100644 0009-Fix-ldap-host-lookup-ipv6.patch create mode 100644 0011-openldap-re24-its7796.patch create mode 100644 0012-ITS8051-sockdnpat.patch create mode 100644 0014-ITS-8714-Send-out-EXTENDED-operation-message-from-back-sock.patch create mode 100644 0016-Clear-shared-key-only-in-close-function.patch create mode 100644 0017-Fix-segfault-in-nops.patch create mode 100644 0200-Fix-incorrect-calculation-of-consecutive-number-of-c.patch create mode 100644 0201-ITS-9052-zero-out-sasl_ssf-in-connection_init.patch create mode 100644 0202-ITS-9038-restrict-rootDN-proxyauthz-to-its-own-DBs.patch create mode 100644 0203-ITS-9038-Update-test028-to-test-this-is-enforced.patch create mode 100644 0204-ITS-9038-Another-test028-typo.patch create mode 100644 0205-bsc-1170771-limit-depth-of-nested-filters.patch create mode 100644 0206-openldap-tlso-use-openssl-api-to-verify-host.patch create mode 100644 0207-ITS-9370-check-for-equality-rule-on-old_rdn.patch create mode 100644 0208-ITS-9400-back-ldap-fix-retry-binds.patch create mode 100644 0209-ITS-9383-remove-assert-in-certificateListValidate.patch create mode 100644 0210-ITS-9384-remove-assert-in-obsolete-csnNormalize23.patch create mode 100644 0211-ITS-9454-fix-issuerAndThisUpdateCheck.patch create mode 100644 0212-ITS-9404-fix-serialNumberAndIssuerCheck.patch create mode 100644 0213-ITS-9406-9407-remove-saslauthz-asserts.patch create mode 100644 0214-ITS-9406-fix-debug-msg.patch create mode 100644 0215-ITS-9408-fix-vrfilter-double-free.patch create mode 100644 0216-ITS-9409-saslauthz-use-ch_free-on-normalized-DN.patch create mode 100644 0217-ITS-9409-saslauthz-use-slap_sl_free-in-prev-commit.patch create mode 100644 0218-ITS-9412-fix-AVA_Sort-on-invalid-RDN.patch create mode 100644 0219-ITS-9413-fix-slap_parse_user.patch create mode 100644 0220-ITS-9423-ldap_X509dn2bv-check-for-invalid-BER-after-.patch create mode 100644 0221-ITS-9424-fix-serialNumberAndIssuerSerialCheck.patch create mode 100644 0222-ITS-9425-add-more-checks-to-ldap_X509dn2bv.patch create mode 100644 0223-ITS-9427-fix-issuerAndThisUpdateCheck.patch create mode 100644 0224-ITS-9428-fix-cancel-exop.patch create mode 100644 0225-ITS-8625-Separate-Avlnode-and-TAvlnode-types.patch create mode 100644 0226-ITS-9197-back-ldap-added-task-that-prunes-expired-co.patch create mode 100644 0227-ITS-9197-Increase-timeouts-in-test-case-due-to-spora.patch create mode 100644 0228-ITS-9197-fix-typo-in-prev-commit.patch create mode 100644 0229-ITS-9197-Fix-test-script.patch create mode 100644 0230-ITS-9197-fix-info-msg-for-slapd-check.patch create mode 100644 0231-ITS-9468-Added-test-case-for-proxy-re-binding-anonym.patch create mode 100644 0232-ITS-9468-back-ldap-Return-disconect-if-rebind-cannot.patch create mode 100644 0233-ITS-9468-removed-accidental-unicode-characters.patch create mode 100644 0234-ITS-9468-documented-that-re-connecting-does-not-happ.patch create mode 100644 0235-ITS-9468-summarize-discussion-about-rebind-as-user.patch create mode 100644 0236-ITS-9468-fixed-typos.patch create mode 100644 0237-ITS-9468-always-init-lc_time-and-lc_create_time.patch create mode 100644 0238-ITS-9468-do-not-arm-expire-timer-for-connections-tha.patch create mode 100644 0239-ITS-9422-Update-for-TLS-v1.3.patch create mode 100644 0240-ITS-9518-add-LDAP_OPT_X_TLS_PROTOCOL_MAX-option.patch create mode 100644 0241-TLS-set-protocol-version.patch create mode 100644 0242-ITS-9815-slapd-sql-escape-filter-values.patch create mode 100644 0243-Change-malloc-to-use-calloc-to-prevent-memory-reuse-.patch create mode 100644 0244-ITS-9904-ldif_open_url-check-for-ber_strdup-failure.patch create mode 100644 0245-ITS-9803-Drop-connection-when-receiving-non-LDAP-dat.patch create mode 100644 DB_CONFIG create mode 100644 README.module-loading create mode 100644 SuSEfirewall2.openldap create mode 100644 baselibs.conf create mode 100644 fixup-modulepath.sh create mode 100644 openldap-r-only.dif create mode 100644 openldap2-rpmlintrc create mode 100644 openldap2.changes create mode 100644 openldap2.conf create mode 100644 openldap2.spec create mode 100644 ppolicy-check-password.5 create mode 100644 ppolicy-check-password.Makefile create mode 100644 ppolicy-check-password.conf create mode 100644 sasl-slapd.conf create mode 100644 schema2ldif create mode 100644 slapd-ldif-update-crc.sh create mode 100644 slapd.conf create mode 100644 slapd.conf.example create mode 100644 slapd.conf.olctemplate create mode 100644 slapd.service create mode 100644 start create mode 100644 sysconfig.openldap create mode 100644 update-crc.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a1d5e3c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +addonschema.tar.gz +openldap-2.4.46.tgz +ppolicy-check-password-1.2.tar.gz diff --git a/.openldap2.metadata b/.openldap2.metadata new file mode 100644 index 0000000..8ce3e6d --- /dev/null +++ b/.openldap2.metadata @@ -0,0 +1,3 @@ +7320568eb209542bd27b48795b56e6bf8c23f9861eb63fb275faf212753317d7 addonschema.tar.gz +22ebe3866d65a361ec8b57a137e92e62b330945a2378428d93caaf62cbb26866 openldap-2.4.46.tgz +b34809e6c98826fd0812eef18dfe8b97067238b0f9e68cb8448e65822028a6e8 ppolicy-check-password-1.2.tar.gz diff --git a/0001-ITS-8866-slapo-unique-to-return-filter-used-in-diagn.patch b/0001-ITS-8866-slapo-unique-to-return-filter-used-in-diagn.patch new file mode 100644 index 0000000..00b7426 --- /dev/null +++ b/0001-ITS-8866-slapo-unique-to-return-filter-used-in-diagn.patch @@ -0,0 +1,66 @@ +From 348588561c694784a8106871b0d5fe578007ea4e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20Str=C3=B6der?= +Date: Fri, 26 Oct 2018 16:40:23 +0200 +Subject: [PATCH] ITS#8866 slapo-unique to return filter used in diagnostic + message + +--- + servers/slapd/overlays/unique.c | 27 +++++++++++++++++---------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +diff --git a/servers/slapd/overlays/unique.c b/servers/slapd/overlays/unique.c +index ed62d03b8..a7723cf5d 100644 +--- a/servers/slapd/overlays/unique.c ++++ b/servers/slapd/overlays/unique.c +@@ -965,6 +965,8 @@ unique_search( + slap_callback cb = { NULL, NULL, NULL, NULL }; /* XXX */ + unique_counter uq = { NULL, 0 }; + int rc; ++ char *errmsg; ++ int errmsgsize; + + Debug(LDAP_DEBUG_TRACE, "==> unique_search %s\n", key->bv_val, 0, 0); + +@@ -998,24 +1000,29 @@ unique_search( + nop->o_bd = on->on_info->oi_origdb; + rc = nop->o_bd->be_search(nop, &nrs); + filter_free_x(nop, nop->ors_filter, 1); +- op->o_tmpfree( key->bv_val, op->o_tmpmemctx ); + + if(rc != LDAP_SUCCESS && rc != LDAP_NO_SUCH_OBJECT) { + op->o_bd->bd_info = (BackendInfo *) on->on_info; + send_ldap_error(op, rs, rc, "unique_search failed"); +- return(rs->sr_err); +- } +- +- Debug(LDAP_DEBUG_TRACE, "=> unique_search found %d records\n", uq.count, 0, 0); ++ rc = rs->sr_err; ++ } else if(uq.count) { ++ Debug(LDAP_DEBUG_TRACE, "=> unique_search found %d records\n", uq.count, 0, 0); + +- if(uq.count) { ++ errmsgsize = sizeof("non-unique attributes found with ") + key->bv_len; ++ errmsg = op->o_tmpalloc(errmsgsize, op->o_tmpmemctx); ++ snprintf( errmsg, errmsgsize, "non-unique attributes found with %s", key->bv_val ); + op->o_bd->bd_info = (BackendInfo *) on->on_info; +- send_ldap_error(op, rs, LDAP_CONSTRAINT_VIOLATION, +- "some attributes not unique"); +- return(rs->sr_err); ++ send_ldap_error(op, rs, LDAP_CONSTRAINT_VIOLATION, errmsg); ++ op->o_tmpfree(errmsg, op->o_tmpmemctx); ++ rc = rs->sr_err; ++ } else { ++ Debug(LDAP_DEBUG_TRACE, "=> unique_search found no records\n", 0, 0, 0); ++ rc = SLAP_CB_CONTINUE; + } + +- return(SLAP_CB_CONTINUE); ++ op->o_tmpfree( key->bv_val, op->o_tmpmemctx ); ++ ++ return(rc); + } + + static int +-- +2.19.1 + diff --git a/0003-LDAPI-socket-location.dif b/0003-LDAPI-socket-location.dif new file mode 100644 index 0000000..0aa76ad --- /dev/null +++ b/0003-LDAPI-socket-location.dif @@ -0,0 +1,22 @@ +From 73f1a31ec1d90872ac6f09ffac5adfb199eba963 Mon Sep 17 00:00:00 2001 +From: Ralf Haferkamp +Date: Wed, 16 Jun 2010 14:06:42 +0200 +Subject: LDAPI socket location + + +diff --git a/include/ldap_defaults.h b/include/ldap_defaults.h +index 9dba666..b9780bc 100644 +--- a/include/ldap_defaults.h ++++ b/include/ldap_defaults.h +@@ -39,7 +39,7 @@ + #define LDAP_ENV_PREFIX "LDAP" + + /* default ldapi:// socket */ +-#define LDAPI_SOCK LDAP_RUNDIR LDAP_DIRSEP "run" LDAP_DIRSEP "ldapi" ++#define LDAPI_SOCK LDAP_RUNDIR LDAP_DIRSEP "ldapi" + + /* + * SLAPD DEFINITIONS +-- +1.7.10.4 + diff --git a/0005-pie-compile.dif b/0005-pie-compile.dif new file mode 100644 index 0000000..091a778 --- /dev/null +++ b/0005-pie-compile.dif @@ -0,0 +1,131 @@ +From 60edf86023da15db7be5935c85826e16d2b78648 Mon Sep 17 00:00:00 2001 +From: Ralf Haferkamp +Date: Fri, 12 Nov 2010 09:39:11 +0100 +Subject: pie compile + + +diff --git a/build/top.mk b/build/top.mk +index 633c9a4..c67289d 100644 +--- a/build/top.mk ++++ b/build/top.mk +@@ -107,7 +107,7 @@ LINK_LIBS = $(MOD_LIBS) $(@PLAT@_LINK_LIBS) + LTSTATIC = @LTSTATIC@ + + LTLINK = $(LIBTOOL) --mode=link \ +- $(CC) $(LTSTATIC) $(LT_CFLAGS) $(LDFLAGS) $(LTFLAGS) ++ $(CC) -pie $(LTSTATIC) $(LT_CFLAGS) $(LDFLAGS) $(LTFLAGS) + + LTCOMPILE_LIB = $(LIBTOOL) $(LTONLY_LIB) --mode=compile \ + $(CC) $(LT_CFLAGS) $(LT_CPPFLAGS) $(LIB_DEFS) -c +@@ -116,7 +116,7 @@ LTLINK_LIB = $(LIBTOOL) $(LTONLY_LIB) --mode=link \ + $(CC) $(LT_CFLAGS) $(LDFLAGS) $(LTFLAGS_LIB) + + LTCOMPILE_MOD = $(LIBTOOL) $(LTONLY_MOD) --mode=compile \ +- $(CC) $(LT_CFLAGS) $(LT_CPPFLAGS) $(MOD_DEFS) -c ++ $(CC) $(LT_CFLAGS) $(PIE_CFLAGS) $(LT_CPPFLAGS) $(MOD_DEFS) -c + + LTLINK_MOD = $(LIBTOOL) $(LTONLY_MOD) --mode=link \ + $(CC) $(LT_CFLAGS) $(LDFLAGS) $(LTFLAGS_MOD) +@@ -206,7 +206,7 @@ SLAPD_LIBS = @SLAPD_LIBS@ @SLAPD_PERL_LDFLAGS@ @SLAPD_SQL_LDFLAGS@ @SLAPD_SQL_LI + # Our Defaults + CC = $(AC_CC) + DEFS = $(LDAP_INCPATH) $(XINCPATH) $(XDEFS) $(AC_DEFS) $(DEFINES) +-CFLAGS = $(AC_CFLAGS) $(DEFS) ++CFLAGS = -fPIE $(AC_CFLAGS) $(DEFS) + LDFLAGS = $(LDAP_LIBPATH) $(AC_LDFLAGS) $(XLDFLAGS) + LIBS = $(XLIBS) $(XXLIBS) $(AC_LIBS) $(XXXLIBS) + +diff --git a/servers/slapd/back-bdb/Makefile.in b/servers/slapd/back-bdb/Makefile.in +index da7da0c..dcb6d92 100644 +--- a/servers/slapd/back-bdb/Makefile.in ++++ b/servers/slapd/back-bdb/Makefile.in +@@ -33,6 +33,8 @@ LDAP_LIBDIR= ../../../libraries + BUILD_OPT = "--enable-bdb" + BUILD_MOD = @BUILD_BDB@ + ++PIE_CFLAGS="-fPIE" ++ + mod_DEFS = -DSLAPD_IMPORT + MOD_DEFS = $(@BUILD_BDB@_DEFS) + MOD_LIBS = $(BDB_LIBS) +diff --git a/servers/slapd/back-hdb/Makefile.in b/servers/slapd/back-hdb/Makefile.in +index 5af828f..6f43f7b 100644 +--- a/servers/slapd/back-hdb/Makefile.in ++++ b/servers/slapd/back-hdb/Makefile.in +@@ -37,6 +37,8 @@ LDAP_LIBDIR= ../../../libraries + BUILD_OPT = "--enable-hdb" + BUILD_MOD = @BUILD_HDB@ + ++PIE_CFLAGS="-fPIE" ++ + mod_DEFS = -DSLAPD_IMPORT + MOD_DEFS = $(@BUILD_HDB@_DEFS) + MOD_LIBS = $(BDB_LIBS) +diff --git a/servers/slapd/back-ldap/Makefile.in b/servers/slapd/back-ldap/Makefile.in +index 392d92e..3a0663d 100644 +--- a/servers/slapd/back-ldap/Makefile.in ++++ b/servers/slapd/back-ldap/Makefile.in +@@ -26,6 +26,8 @@ LDAP_LIBDIR= ../../../libraries + BUILD_OPT = "--enable-ldap" + BUILD_MOD = @BUILD_LDAP@ + ++PIE_CFLAGS="-fPIE" ++ + mod_DEFS = -DSLAPD_IMPORT + MOD_DEFS = $(@BUILD_LDAP@_DEFS) + +diff --git a/servers/slapd/back-ldif/Makefile.in b/servers/slapd/back-ldif/Makefile.in +index 5e4abc1..1e8c454 100644 +--- a/servers/slapd/back-ldif/Makefile.in ++++ b/servers/slapd/back-ldif/Makefile.in +@@ -22,6 +22,8 @@ LDAP_LIBDIR= ../../../libraries + BUILD_OPT = "--enable-ldif" + BUILD_MOD = yes + ++PIE_CFLAGS="-fPIE" ++ + mod_DEFS = -DSLAPD_IMPORT + MOD_DEFS = $(yes_DEFS) + +diff --git a/servers/slapd/back-mdb/Makefile.in b/servers/slapd/back-mdb/Makefile.in +index 9b01d2a..e37520a 100644 +--- a/servers/slapd/back-mdb/Makefile.in ++++ b/servers/slapd/back-mdb/Makefile.in +@@ -34,6 +34,8 @@ MDB_SUBDIR = $(srcdir)/$(LDAP_LIBDIR)/libmdb + BUILD_OPT = "--enable-mdb" + BUILD_MOD = @BUILD_MDB@ + ++PIE_CFLAGS="-fPIE" ++ + mod_DEFS = -DSLAPD_IMPORT + MOD_DEFS = $(@BUILD_MDB@_DEFS) + MOD_LIBS = $(MDB_LIBS) +diff --git a/servers/slapd/back-monitor/Makefile.in b/servers/slapd/back-monitor/Makefile.in +index 9aecdbc..11c962c 100644 +--- a/servers/slapd/back-monitor/Makefile.in ++++ b/servers/slapd/back-monitor/Makefile.in +@@ -30,6 +30,8 @@ LDAP_LIBDIR= ../../../libraries + BUILD_OPT = "--enable-monitor" + BUILD_MOD = @BUILD_MONITOR@ + ++PIE_CFLAGS="-fPIE" ++ + mod_DEFS = -DSLAPD_IMPORT + MOD_DEFS = $(@BUILD_MONITOR@_DEFS) + +diff --git a/servers/slapd/back-relay/Makefile.in b/servers/slapd/back-relay/Makefile.in +index 90ea4b3..ff2f429 100644 +--- a/servers/slapd/back-relay/Makefile.in ++++ b/servers/slapd/back-relay/Makefile.in +@@ -22,6 +22,8 @@ LDAP_LIBDIR= ../../../libraries + BUILD_OPT = "--enable-relay" + BUILD_MOD = @BUILD_RELAY@ + ++PIE_CFLAGS="-fPIE" ++ + mod_DEFS = -DSLAPD_IMPORT + MOD_DEFS = $(@BUILD_RELAY@_DEFS) + +-- +1.7.10.4 + diff --git a/0006-No-Build-date-and-time-in-binaries.dif b/0006-No-Build-date-and-time-in-binaries.dif new file mode 100644 index 0000000..c26a367 --- /dev/null +++ b/0006-No-Build-date-and-time-in-binaries.dif @@ -0,0 +1,33 @@ +From a7a37111026ccb9fddfeedc22606b80d8d75557f Mon Sep 17 00:00:00 2001 +From: Cristian Rodriguez +Date: Tue, 5 Oct 2010 13:59:40 +0200 +Subject: No Build date and time in binaries + +This avoids build-compare failures and unhelpful rebuilds/republishes in +the openSUSE buildservice. + +diff --git a/build/mkversion b/build/mkversion +index 3fd9565..dd9a998 100755 +--- a/build/mkversion ++++ b/build/mkversion +@@ -50,7 +50,7 @@ if test $# != 1 ; then + fi + + APPLICATION=$1 +-WHOWHERE="$USER@`uname -n`:`pwd`" ++WHOWHERE="opensuse-buildservice@opensuse.org" + + cat << __EOF__ + /* This work is part of OpenLDAP Software . +@@ -72,7 +72,7 @@ static const char copyright[] = + "COPYING RESTRICTIONS APPLY\n"; + + $static $const char $SYMBOL[] = +-"@(#) \$$PACKAGE: $APPLICATION $VERSION (" __DATE__ " " __TIME__ ") \$\n" ++"@(#) \$$PACKAGE: $APPLICATION $VERSION \$\n" + "\t$WHOWHERE\n"; + + __EOF__ +-- +1.7.10.4 + diff --git a/0007-Recover-on-DB-version-change.dif b/0007-Recover-on-DB-version-change.dif new file mode 100644 index 0000000..06b7028 --- /dev/null +++ b/0007-Recover-on-DB-version-change.dif @@ -0,0 +1,29 @@ +From 895fa6d9b49344e1a92f7df3ed65458519e22f98 Mon Sep 17 00:00:00 2001 +From: Ralf Haferkamp +Date: Tue, 5 Oct 2010 14:20:22 +0200 +Subject: Recover on DB version change + +If the libdb Version changed try to recover the database. Note: This will +only succeed if only the format of transaction logs changed. + +diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c +index ac5a6d5..fea5cb4 100644 +--- a/servers/slapd/back-bdb/init.c ++++ b/servers/slapd/back-bdb/init.c +@@ -330,6 +330,13 @@ shm_retry: + rc = (bdb->bi_dbenv->open)( bdb->bi_dbenv, dbhome, + flags | do_recover, bdb->bi_dbenv_mode ); + ++ if ( rc == DB_VERSION_MISMATCH ) { ++ Debug( LDAP_DEBUG_ANY, ++ LDAP_XSTRING(bdb_db_open) ": bdb version change detected " ++ "trying to recover\n", 0, 0, 0 ); ++ rc = (bdb->bi_dbenv->open)( bdb->bi_dbenv, dbhome, ++ flags | DB_RECOVER, bdb->bi_dbenv_mode ); ++ } + if ( rc ) { + /* Regular open failed, probably a missing shm environment. + * Start over, do a recovery. +-- +1.7.10.4 + diff --git a/0008-In-monitor-backend-do-not-return-Connection0-entries.patch b/0008-In-monitor-backend-do-not-return-Connection0-entries.patch new file mode 100644 index 0000000..84fd4c9 --- /dev/null +++ b/0008-In-monitor-backend-do-not-return-Connection0-entries.patch @@ -0,0 +1,29 @@ +From d4b247e43fe1ea1b3713f3d8f493422d5adcc537 Mon Sep 17 00:00:00 2001 +From: HouzuoGuo +Date: Fri, 13 Mar 2015 16:14:10 +0100 +Subject: [PATCH] In monitor backend, do not return Connection0 entries as they + are created for internal use only. + +--- + servers/slapd/back-monitor/conn.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/servers/slapd/back-monitor/conn.c b/servers/slapd/back-monitor/conn.c +index c1995b0..2d27738 100644 +--- a/servers/slapd/back-monitor/conn.c ++++ b/servers/slapd/back-monitor/conn.c +@@ -454,6 +454,11 @@ monitor_subsys_conn_create( + c != NULL; + c = connection_next( c, &connindex ) ) + { ++ /* Connection 0 is created by connection_client_setup for internal use only */ ++ if (c->c_connid == 0) { ++ continue; ++ } ++ + monitor_entry_t *mp; + + if ( conn_create( mi, c, &e, ms ) != SLAP_CB_CONTINUE +-- +2.1.4 + diff --git a/0009-Fix-ldap-host-lookup-ipv6.patch b/0009-Fix-ldap-host-lookup-ipv6.patch new file mode 100644 index 0000000..bbcc043 --- /dev/null +++ b/0009-Fix-ldap-host-lookup-ipv6.patch @@ -0,0 +1,73 @@ +The patch was written by Christian Kornacker on 2014-01-08 to fix an issue with unresponsive +LDAP host lookups in IPv6 environment. + +--- + libraries/libldap/util-int.c | 39 +++++++++++++++++++++++++++++++++++++-- + 1 file changed, 37 insertions(+), 2 deletions(-) + +Index: openldap-2.4.41/libraries/libldap/util-int.c +=================================================================== +--- openldap-2.4.41.orig/libraries/libldap/util-int.c ++++ openldap-2.4.41/libraries/libldap/util-int.c +@@ -731,10 +731,16 @@ static char *safe_realloc( char **buf, i + + char * ldap_pvt_get_fqdn( char *name ) + { +- char *fqdn, *ha_buf; ++ int rc; ++ char *fqdn; + char hostbuf[MAXHOSTNAMELEN+1]; ++#ifdef HAVE_GETADDRINFO ++ struct addrinfo hints, *res; ++#else ++ char *ha_buf; + struct hostent *hp, he_buf; +- int rc, local_h_errno; ++ int local_h_errno; ++#endif + + if( name == NULL ) { + if( gethostname( hostbuf, MAXHOSTNAMELEN ) == 0 ) { +@@ -745,6 +751,33 @@ char * ldap_pvt_get_fqdn( char *name ) + } + } + ++#ifdef HAVE_GETADDRINFO ++ memset( &hints, '\0', sizeof( hints ) ); ++ hints.ai_family = AF_UNSPEC; ++ hints.ai_socktype = SOCK_STREAM; ++ hints.ai_flags |= AI_CANONNAME; ++ ++ /* most getaddrinfo(3) use non-threadsafe resolver libraries */ ++ LDAP_MUTEX_LOCK(&ldap_int_resolv_mutex); ++ ++ rc = getaddrinfo( name, NULL, &hints, &res ); ++ ++ LDAP_MUTEX_UNLOCK(&ldap_int_resolv_mutex); ++ ++ if ( rc != 0 ) { ++ fqdn = LDAP_STRDUP( name ); ++ } else { ++ while ( res ) { ++ if ( res->ai_canonname ) { ++ fqdn = LDAP_STRDUP ( res->ai_canonname ); ++ break; ++ } ++ res = res->ai_next; ++ } ++ freeaddrinfo( res ); ++ } ++#else ++ + rc = ldap_pvt_gethostbyname_a( name, + &he_buf, &ha_buf, &hp, &local_h_errno ); + +@@ -755,6 +788,8 @@ char * ldap_pvt_get_fqdn( char *name ) + } + + LDAP_FREE( ha_buf ); ++#endif ++ + return fqdn; + } + diff --git a/0011-openldap-re24-its7796.patch b/0011-openldap-re24-its7796.patch new file mode 100644 index 0000000..d5fe3dd --- /dev/null +++ b/0011-openldap-re24-its7796.patch @@ -0,0 +1,80 @@ +diff --git a/servers/slapd/back-bdb/filterindex.c b/servers/slapd/back-bdb/filterindex.c +index 71e3ea4..bafef72 100644 +--- a/servers/slapd/back-bdb/filterindex.c ++++ b/servers/slapd/back-bdb/filterindex.c +@@ -741,7 +741,7 @@ equality_candidates( + &db, &mask, &prefix ); + + if ( rc == LDAP_INAPPROPRIATE_MATCHING ) { +- Debug( LDAP_DEBUG_ANY, ++ Debug( LDAP_DEBUG_TRACE, + "<= bdb_equality_candidates: (%s) not indexed\n", + ava->aa_desc->ad_cname.bv_val, 0, 0 ); + return 0; +@@ -858,7 +858,7 @@ approx_candidates( + &db, &mask, &prefix ); + + if ( rc == LDAP_INAPPROPRIATE_MATCHING ) { +- Debug( LDAP_DEBUG_ANY, ++ Debug( LDAP_DEBUG_TRACE, + "<= bdb_approx_candidates: (%s) not indexed\n", + ava->aa_desc->ad_cname.bv_val, 0, 0 ); + return 0; +@@ -978,7 +978,7 @@ substring_candidates( + &db, &mask, &prefix ); + + if ( rc == LDAP_INAPPROPRIATE_MATCHING ) { +- Debug( LDAP_DEBUG_ANY, ++ Debug( LDAP_DEBUG_TRACE, + "<= bdb_substring_candidates: (%s) not indexed\n", + sub->sa_desc->ad_cname.bv_val, 0, 0 ); + return 0; +@@ -1095,7 +1095,7 @@ inequality_candidates( + &db, &mask, &prefix ); + + if ( rc == LDAP_INAPPROPRIATE_MATCHING ) { +- Debug( LDAP_DEBUG_ANY, ++ Debug( LDAP_DEBUG_TRACE, + "<= bdb_inequality_candidates: (%s) not indexed\n", + ava->aa_desc->ad_cname.bv_val, 0, 0 ); + return 0; +diff --git a/servers/slapd/back-mdb/filterindex.c b/servers/slapd/back-mdb/filterindex.c +index 58c1cc8..20c58b7 100644 +--- a/servers/slapd/back-mdb/filterindex.c ++++ b/servers/slapd/back-mdb/filterindex.c +@@ -709,7 +709,7 @@ equality_candidates( + &dbi, &mask, &prefix ); + + if ( rc == LDAP_INAPPROPRIATE_MATCHING ) { +- Debug( LDAP_DEBUG_ANY, ++ Debug( LDAP_DEBUG_TRACE, + "<= mdb_equality_candidates: (%s) not indexed\n", + ava->aa_desc->ad_cname.bv_val, 0, 0 ); + return 0; +@@ -825,7 +825,7 @@ approx_candidates( + &dbi, &mask, &prefix ); + + if ( rc == LDAP_INAPPROPRIATE_MATCHING ) { +- Debug( LDAP_DEBUG_ANY, ++ Debug( LDAP_DEBUG_TRACE, + "<= mdb_approx_candidates: (%s) not indexed\n", + ava->aa_desc->ad_cname.bv_val, 0, 0 ); + return 0; +@@ -944,7 +944,7 @@ substring_candidates( + &dbi, &mask, &prefix ); + + if ( rc == LDAP_INAPPROPRIATE_MATCHING ) { +- Debug( LDAP_DEBUG_ANY, ++ Debug( LDAP_DEBUG_TRACE, + "<= mdb_substring_candidates: (%s) not indexed\n", + sub->sa_desc->ad_cname.bv_val, 0, 0 ); + return 0; +@@ -1060,7 +1060,7 @@ inequality_candidates( + &dbi, &mask, &prefix ); + + if ( rc == LDAP_INAPPROPRIATE_MATCHING ) { +- Debug( LDAP_DEBUG_ANY, ++ Debug( LDAP_DEBUG_TRACE, + "<= mdb_inequality_candidates: (%s) not indexed\n", + ava->aa_desc->ad_cname.bv_val, 0, 0 ); + return 0; diff --git a/0012-ITS8051-sockdnpat.patch b/0012-ITS8051-sockdnpat.patch new file mode 100644 index 0000000..9e682b4 --- /dev/null +++ b/0012-ITS8051-sockdnpat.patch @@ -0,0 +1,128 @@ +From 328612d3370290c7f42ad835e1b0e3189eadef7b Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Wed, 4 Feb 2015 03:53:13 +0000 +Subject: [PATCH] ITS#8051 add DN qualifier + +--- + doc/man/man5/slapd-sock.5 | 5 +++++ + servers/slapd/back-sock/back-sock.h | 2 ++ + servers/slapd/back-sock/config.c | 32 +++++++++++++++++++++++++++++--- + 3 files changed, 36 insertions(+), 3 deletions(-) + +diff --git a/doc/man/man5/slapd-sock.5 b/doc/man/man5/slapd-sock.5 +index ee8cc919f..1ac4f7fdd 100644 +--- a/doc/man/man5/slapd-sock.5 ++++ b/doc/man/man5/slapd-sock.5 +@@ -58,6 +58,11 @@ Specify which response types to send to the external program. "result" + sends just the results of an operation. "search" sends all entries that + the database returned for a search request. The default is empty + (no responses are sent). ++.TP ++.B sockdnpat ++Specify DN patterns for which the overlay will act. Only operations on ++DNs matching the specified regular expression will be processed. The default ++is empty (all DNs are processed). + + .SH PROTOCOL + The protocol is essentially the same as +diff --git a/servers/slapd/back-sock/back-sock.h b/servers/slapd/back-sock/back-sock.h +index 15495a6bc..7a083a8df 100644 +--- a/servers/slapd/back-sock/back-sock.h ++++ b/servers/slapd/back-sock/back-sock.h +@@ -30,6 +30,8 @@ struct sockinfo { + slap_mask_t si_extensions; + slap_mask_t si_ops; /* overlay: operations to act on */ + slap_mask_t si_resps; /* overlay: responses to forward */ ++ regex_t si_dnpat; /* overlay: DN pattern to match */ ++ struct berval si_dnpatstr; + }; + + #define SOCK_EXT_BINDDN 1 +diff --git a/servers/slapd/back-sock/config.c b/servers/slapd/back-sock/config.c +index d8ff95ceb..dc3f1365c 100644 +--- a/servers/slapd/back-sock/config.c ++++ b/servers/slapd/back-sock/config.c +@@ -36,11 +36,12 @@ static slap_response sock_over_response; + enum { + BS_EXT = 1, + BS_OPS, +- BS_RESP ++ BS_RESP, ++ BS_DNPAT + }; + + /* The number of overlay-only config attrs */ +-#define NUM_OV_ATTRS 2 ++#define NUM_OV_ATTRS 3 + + static ConfigTable bscfg[] = { + { "sockops", "ops", 2, 0, 0, ARG_MAGIC|BS_OPS, +@@ -53,6 +54,11 @@ static ConfigTable bscfg[] = { + "DESC 'Response types to forward' " + "EQUALITY caseIgnoreMatch " + "SYNTAX OMsDirectoryString )", NULL, NULL }, ++ { "sockdnpat", "regexp", 2, 2, 0, ARG_MAGIC|BS_DNPAT, ++ bs_cf_gen, "( OLcfgDbAt:7.5 NAME 'olcOvSocketDNpat' " ++ "DESC 'DN pattern to match' " ++ "EQUALITY caseIgnoreMatch " ++ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, + + { "socketpath", "pathname", 2, 2, 0, ARG_STRING|ARG_OFFSET, + (void *)offsetof(struct sockinfo, si_sockpath), +@@ -86,7 +92,8 @@ static ConfigOCs osocs[] = { + "SUP olcOverlayConfig " + "MUST olcDbSocketPath " + "MAY ( olcDbSocketExtensions $ " +- " olcOvSocketOps $ olcOvSocketResps ) )", ++ " olcOvSocketOps $ olcOvSocketResps $ " ++ " olcOvSocketDNpat ) )", + Cft_Overlay, bscfg }, + { NULL, 0, NULL } + }; +@@ -150,6 +157,9 @@ bs_cf_gen( ConfigArgs *c ) + return mask_to_verbs( ov_ops, si->si_ops, &c->rvalue_vals ); + case BS_RESP: + return mask_to_verbs( ov_resps, si->si_resps, &c->rvalue_vals ); ++ case BS_DNPAT: ++ value_add_one( &c->rvalue_vals, &si->si_dnpatstr ); ++ return 0; + } + } else if ( c->op == LDAP_MOD_DELETE ) { + switch( c->type ) { +@@ -186,6 +196,11 @@ bs_cf_gen( ConfigArgs *c ) + si->si_resps ^= dels; + } + return rc; ++ case BS_DNPAT: ++ regfree( &si->si_dnpat ); ++ ch_free( si->si_dnpatstr.bv_val ); ++ BER_BVZERO( &si->si_dnpatstr ); ++ return 0; + } + + } else { +@@ -196,6 +211,13 @@ bs_cf_gen( ConfigArgs *c ) + return verbs_to_mask( c->argc, c->argv, ov_ops, &si->si_ops ); + case BS_RESP: + return verbs_to_mask( c->argc, c->argv, ov_resps, &si->si_resps ); ++ case BS_DNPAT: ++ if ( !regcomp( &si->si_dnpat, c->argv[1], REG_EXTENDED|REG_ICASE|REG_NOSUB )) { ++ ber_str2bv( c->argv[1], 0, 1, &si->si_dnpatstr ); ++ return 0; ++ } else { ++ return 1; ++ } + } + } + return 1; +@@ -268,6 +290,10 @@ static int sock_over_op( + if ( !(si->si_ops & sockopflags[which])) + return SLAP_CB_CONTINUE; + ++ if ( !BER_BVISEMPTY( &si->si_dnpatstr ) && ++ regexec( &si->si_dnpat, op->o_req_ndn.bv_val, 0, NULL, 0 )) ++ return SLAP_CB_CONTINUE; ++ + op->o_bd->be_private = si; + sc = op->o_callback; + op->o_callback = NULL; diff --git a/0014-ITS-8714-Send-out-EXTENDED-operation-message-from-back-sock.patch b/0014-ITS-8714-Send-out-EXTENDED-operation-message-from-back-sock.patch new file mode 100644 index 0000000..5702e94 --- /dev/null +++ b/0014-ITS-8714-Send-out-EXTENDED-operation-message-from-back-sock.patch @@ -0,0 +1,241 @@ +diff --git a/doc/man/man5/slapd-sock.5 b/doc/man/man5/slapd-sock.5 +index 1ac4f7fdd..903155fa4 100644 +--- a/doc/man/man5/slapd-sock.5 ++++ b/doc/man/man5/slapd-sock.5 +@@ -49,7 +49,7 @@ be sent and from which replies are received. + + When used as an overlay, these additional directives are defined: + .TP +-.B sockops [ bind | unbind | search | compare | modify | modrdn | add | delete ]* ++.B sockops [ bind | unbind | search | compare | modify | modrdn | add | delete | extended ]* + Specify which request types to send to the external program. The default is + empty (no requests are sent). + .TP +@@ -115,6 +115,17 @@ dn: + .PP + .RS + .nf ++EXTENDED ++msgid: ++ }> ++oid: ++value: ++ ++.fi ++.RE ++.PP ++.RS ++.nf + MODIFY + msgid: + }> +@@ -213,6 +224,11 @@ msgid: + .fi + .RE + ++.SH KNOWN LIMITATIONS ++The ++.B sock ++backend does not process extended operation results from an external program. ++ + .SH ACCESS CONTROL + The + .B sock +@@ -292,6 +308,11 @@ access to the + pseudo_attribute of the searchBase; + .B search (=s) + access to the attributes and values used in the filter is not checked. ++.LP ++The ++.B extended ++operation does not require any access special rights. ++The external program has to implement any sort of access control. + + .SH EXAMPLE + There is an example script in the slapd/back\-sock/ directory +diff --git a/servers/slapd/back-sock/Makefile.in b/servers/slapd/back-sock/Makefile.in +index 3e527e545..efb916246 100644 +--- a/servers/slapd/back-sock/Makefile.in ++++ b/servers/slapd/back-sock/Makefile.in +@@ -18,9 +18,9 @@ + ## in OpenLDAP Software. + + SRCS = init.c config.c opensock.c search.c bind.c unbind.c add.c \ +- delete.c modify.c modrdn.c compare.c result.c ++ delete.c modify.c modrdn.c compare.c result.c extended.c + OBJS = init.lo config.lo opensock.lo search.lo bind.lo unbind.lo add.lo \ +- delete.lo modify.lo modrdn.lo compare.lo result.lo ++ delete.lo modify.lo modrdn.lo compare.lo result.lo extended.lo + + LDAP_INCDIR= ../../../include + LDAP_LIBDIR= ../../../libraries +diff --git a/servers/slapd/back-sock/config.c b/servers/slapd/back-sock/config.c +index dc3f1365c..2dcf68bf6 100644 +--- a/servers/slapd/back-sock/config.c ++++ b/servers/slapd/back-sock/config.c +@@ -106,6 +106,7 @@ static ConfigOCs osocs[] = { + #define SOCK_OP_MODRDN 0x020 + #define SOCK_OP_ADD 0x040 + #define SOCK_OP_DELETE 0x080 ++#define SOCK_OP_EXTENDED 0x100 + + #define SOCK_REP_RESULT 0x001 + #define SOCK_REP_SEARCH 0x002 +@@ -127,6 +128,7 @@ static slap_verbmasks ov_ops[] = { + { BER_BVC("modrdn"), SOCK_OP_MODRDN }, + { BER_BVC("add"), SOCK_OP_ADD }, + { BER_BVC("delete"), SOCK_OP_DELETE }, ++ { BER_BVC("extended"), SOCK_OP_EXTENDED }, + { BER_BVNULL, 0 } + }; + +@@ -249,7 +251,9 @@ static BI_op_bind *sockfuncs[] = { + sock_back_modify, + sock_back_modrdn, + sock_back_add, +- sock_back_delete ++ sock_back_delete, ++ 0, /* abandon not supported */ ++ sock_back_extended + }; + + static const int sockopflags[] = { +@@ -260,7 +264,9 @@ static const int sockopflags[] = { + SOCK_OP_MODIFY, + SOCK_OP_MODRDN, + SOCK_OP_ADD, +- SOCK_OP_DELETE ++ SOCK_OP_DELETE, ++ 0, /* abandon not supported */ ++ SOCK_OP_EXTENDED + }; + + static int sock_over_op( +@@ -283,6 +289,7 @@ static int sock_over_op( + case LDAP_REQ_MODRDN: which = op_modrdn; break; + case LDAP_REQ_ADD: which = op_add; break; + case LDAP_REQ_DELETE: which = op_delete; break; ++ case LDAP_REQ_EXTENDED: which = op_extended; break; + default: + return SLAP_CB_CONTINUE; + } +@@ -365,6 +372,7 @@ sock_over_setup() + sockover.on_bi.bi_op_modrdn = sock_over_op; + sockover.on_bi.bi_op_add = sock_over_op; + sockover.on_bi.bi_op_delete = sock_over_op; ++ sockover.on_bi.bi_extended = sock_over_op; + sockover.on_response = sock_over_response; + + sockover.on_bi.bi_cf_ocs = osocs; +diff --git a/servers/slapd/back-sock/extended.c b/servers/slapd/back-sock/extended.c +new file mode 100644 +index 000000000..dfe56b32b +--- /dev/null ++++ b/servers/slapd/back-sock/extended.c +@@ -0,0 +1,80 @@ ++/* extended.c - sock backend extended routines */ ++/* $OpenLDAP$ */ ++/* This work is part of OpenLDAP Software . ++ * ++ * Copyright 2000-2017 The OpenLDAP Foundation. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted only as authorized by the OpenLDAP ++ * Public License. ++ * ++ * A copy of this license is available in the file LICENSE in the ++ * top-level directory of the distribution or, alternatively, at ++ * . ++ */ ++ ++#include "portable.h" ++ ++#include ++#include ++ ++#include "slap.h" ++#include "back-sock.h" ++ ++#include "lutil.h" ++ ++int ++sock_back_extended( Operation *op, SlapReply *rs ) ++{ ++ int rc; ++ struct sockinfo *si = (struct sockinfo *) op->o_bd->be_private; ++ FILE *fp; ++ struct berval b64; ++ ++ Debug( LDAP_DEBUG_ARGS, "==> sock_back_extended(%s)\n", ++ op->ore_reqoid.bv_val, op->o_req_dn.bv_val, 0 ); ++ ++ if ( (fp = opensock( si->si_sockpath )) == NULL ) { ++ send_ldap_error( op, rs, LDAP_OTHER, ++ "could not open socket" ); ++ return( -1 ); ++ } ++ ++ /* write out the request to the extended process */ ++ fprintf( fp, "EXTENDED\n" ); ++ fprintf( fp, "msgid: %ld\n", (long) op->o_msgid ); ++ sock_print_conn( fp, op->o_conn, si ); ++ sock_print_suffixes( fp, op->o_bd ); ++ fprintf( fp, "oid: %s\n", op->ore_reqoid.bv_val ); ++ ++ if (op->ore_reqdata) { ++ ++ b64.bv_len = LUTIL_BASE64_ENCODE_LEN( op->ore_reqdata->bv_len ) + 1; ++ b64.bv_val = ber_memalloc( b64.bv_len + 1 ); ++ ++ if( b64.bv_val == NULL ) { ++ return LUTIL_PASSWD_ERR; ++ } ++ ++ rc = lutil_b64_ntop( ++ (unsigned char *) op->ore_reqdata->bv_val, op->ore_reqdata->bv_len, ++ b64.bv_val, b64.bv_len ); ++ ++ b64.bv_len = rc; ++ assert( strlen(b64.bv_val) == b64.bv_len ); ++ ++ fprintf( fp, "value: %s\n", b64.bv_val ); ++ ++ ber_memfree( b64.bv_val ); ++ ++ } ++ ++ fprintf( fp, "\n" ); ++ ++ /* read in the results and send them along */ ++ rc = sock_read_and_send_results( op, rs, fp ); ++ fclose( fp ); ++ ++ return( rc ); ++} +diff --git a/servers/slapd/back-sock/init.c b/servers/slapd/back-sock/init.c +index dcfe61a44..92e68782f 100644 +--- a/servers/slapd/back-sock/init.c ++++ b/servers/slapd/back-sock/init.c +@@ -53,7 +53,7 @@ sock_back_initialize( + bi->bi_op_delete = sock_back_delete; + bi->bi_op_abandon = 0; + +- bi->bi_extended = 0; ++ bi->bi_extended = sock_back_extended; + + bi->bi_chk_referrals = 0; + +diff --git a/servers/slapd/back-sock/proto-sock.h b/servers/slapd/back-sock/proto-sock.h +index fa02ab896..8b3b5f3ef 100644 +--- a/servers/slapd/back-sock/proto-sock.h ++++ b/servers/slapd/back-sock/proto-sock.h +@@ -40,6 +40,8 @@ extern BI_op_modrdn sock_back_modrdn; + extern BI_op_add sock_back_add; + extern BI_op_delete sock_back_delete; + ++extern BI_op_extended sock_back_extended; ++ + extern int sock_back_init_cf( BackendInfo *bi ); + + LDAP_END_DECL diff --git a/0016-Clear-shared-key-only-in-close-function.patch b/0016-Clear-shared-key-only-in-close-function.patch new file mode 100644 index 0000000..e6ea5e9 --- /dev/null +++ b/0016-Clear-shared-key-only-in-close-function.patch @@ -0,0 +1,16 @@ +diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c +index 6bdf3151d..56212151b 100644 +--- a/libraries/liblmdb/mdb.c ++++ b/libraries/liblmdb/mdb.c +@@ -4692,6 +4692,11 @@ mdb_env_close0(MDB_env *env, int excl) + + if (env->me_flags & MDB_ENV_TXKEY) { + pthread_key_delete(env->me_txkey); ++ ++ // No need to call desctructor anymore, as all pid ++ // values are cleared below. ++ env->me_txkey = NULL; ++ + #ifdef _WIN32 + /* Delete our key from the global list */ + for (i=0; io_opid; + SlapReply rs2 = { REP_RESULT }; + slap_callback cb = { NULL, slap_null_cb, NULL, NULL }; +- Modifications mod[ 2 ] = { { { 0 } } }, *ml; +- struct berval values[ 4 ], nvalues[ 4 ]; ++ Modifications *mod, *ml; ++ struct berval *values, *nvalues; + int mcnt = 0; + ++ mod = (Modifications*)malloc(2 * sizeof(Modifications)); ++ memset(mod, 0, 2 * sizeof(Modifications)); ++ ++ values = (struct berval*)malloc(4 * sizeof(struct berval)); ++ nvalues = (struct berval*)malloc(4 * sizeof(struct berval)); ++ + op2.o_tag = LDAP_REQ_MODIFY; + + op2.o_req_dn = *ndn; +@@ -493,6 +499,11 @@ memberof_value_modify( + /* restore original opid */ + op->o_opid = opid; + ++ ++ slap_mods_free( mod, 0 ); ++ free(values); ++ free(nvalues); ++ + /* FIXME: if old_group_ndn doesn't exist, both delete __and__ + * add will fail; better split in two operations, although + * not optimal in terms of performance. At least it would diff --git a/0200-Fix-incorrect-calculation-of-consecutive-number-of-c.patch b/0200-Fix-incorrect-calculation-of-consecutive-number-of-c.patch new file mode 100644 index 0000000..0f52a02 --- /dev/null +++ b/0200-Fix-incorrect-calculation-of-consecutive-number-of-c.patch @@ -0,0 +1,130 @@ +From b026c9236e6b11c158e69572a28eb0efb174234b Mon Sep 17 00:00:00 2001 +From: HouzuoGuo +Date: Wed, 17 Feb 2016 16:10:05 +0100 +Subject: [PATCH] Fix incorrect calculation of consecutive number of characters + in a class, when the input is shorter than 6 chars or consecutive chars + appear at the beginning of input + + +diff --git a/check_password.c b/check_password.c +index 0d9f901..acf8eda 100644 +--- a/check_password.c ++++ b/check_password.c +@@ -355,18 +355,7 @@ check_password (char *pPasswd, char **ppErrStr, Entry *pEntry) + int min_quality = DEFAULT_QUALITY; + int use_cracklib = DEFAULT_CRACKLIB; + +- /** bail out early as cracklib will reject passwords shorter +- * than 6 characters +- */ +- + nLen = strlen (pPasswd); +- if ( nLen < 6) { +- mem_len = realloc_error_message(&szErrStr, mem_len, +- strlen(PASSWORD_TOO_SHORT_SZ) + +- strlen(pEntry->e_name.bv_val) + 1); +- sprintf (szErrStr, PASSWORD_TOO_SHORT_SZ, pEntry->e_name.bv_val, nLen); +- goto fail; +- } + + if (read_config_file() == -1) { + syslog(LOG_ERR, "Warning: Could not read values from config file %s. Using defaults.", CONFIG_FILE); +@@ -392,46 +381,38 @@ check_password (char *pPasswd, char **ppErrStr, Entry *pEntry) + */ + + if ( max_consecutive_per_class != 0 ) { +- int consec_chars = 1; +- char type[10] = "unkown"; +- char prev_type[10] = "unknown"; ++ char prev_type = '\0'; ++ char this_type = ' '; ++ i = 0; ++ int consec_chars = 0; + for ( i = 0; i < nLen; i++ ) { +- + if ( islower(pPasswd[i]) ) { +- strncpy(type,"lower",10); ++ this_type = 'l'; + } + else if ( isupper(pPasswd[i]) ) { +- strncpy(type,"upper",10); ++ this_type = 'u'; + } + else if ( isdigit(pPasswd[i]) ) { +- strncpy(type,"digit",10); ++ this_type = 'd'; + } + else if ( ispunct(pPasswd[i]) ) { +- strncpy(type,"punct",10); ++ this_type = 'p'; + } + else { +- strncpy(type,"unknown",10); +- } +- +- if ( consec_chars > max_consecutive_per_class ) { +- mem_len = realloc_error_message(&szErrStr, mem_len, +- strlen(CONSEC_FAIL_SZ) + +- strlen(pEntry->e_name.bv_val)); +- sprintf (szErrStr, CONSEC_FAIL_SZ, pEntry->e_name.bv_val); +- goto fail; ++ this_type = ' '; + } +- +- if ( strncmp(type,prev_type,10) == 0 ) { +- consec_chars++; ++ if (this_type == prev_type) { ++ ++consec_chars; ++ } else if (i > 0) { ++ consec_chars = 0; + } +- else { +- if (strncmp("unknown",prev_type,8) != 0) { +- consec_chars = 1; +- } +- else { +- consec_chars++; +- } +- strncpy(prev_type,type,10); ++ prev_type = this_type; ++ if ( consec_chars >= max_consecutive_per_class ) { ++ mem_len = realloc_error_message(&szErrStr, mem_len, ++ strlen(CONSEC_FAIL_SZ) + ++ strlen(pEntry->e_name.bv_val)); ++ sprintf (szErrStr, CONSEC_FAIL_SZ, pEntry->e_name.bv_val); ++ goto fail; + } + } + } +diff --git a/check_password_test.c b/check_password_test.c +index 626d719..d33bd80 100644 +--- a/check_password_test.c ++++ b/check_password_test.c +@@ -90,7 +90,6 @@ void setconf( + } + + int main(void) { +- + // Empty Config, equiv to: + // 5,3,1,0,0,0,0 + setconf(-1,-1,-1,-1,-1,-1,-1); +@@ -109,5 +108,16 @@ int main(void) { + testpass("Test 2.1", "Simp1e", 1); + testpass("Test 2.2", "SimPle", 1); + testpass("Test 2.1", "Simp1e!", 0); ++ ++ setconf(1,0,0,0,0,0,0); ++ testpass("a", "Ab1,", 0); ++ testpass("a", "AAb1,", 1); ++ testpass("a", "Abb1,", 1); ++ ++ setconf(3,0,0,0,0,0,0); ++ testpass("a", "AAAbbb111,,,", 0); ++ testpass("a", "AAAAbbb111,,,,", 1); ++ testpass("a", "AAAbbbb111,,,", 1); ++ + return 0; + } +-- +2.7.1 + diff --git a/0201-ITS-9052-zero-out-sasl_ssf-in-connection_init.patch b/0201-ITS-9052-zero-out-sasl_ssf-in-connection_init.patch new file mode 100644 index 0000000..1fe8045 --- /dev/null +++ b/0201-ITS-9052-zero-out-sasl_ssf-in-connection_init.patch @@ -0,0 +1,25 @@ +From 0fa0f8ff078a3a49a19574eecaea797b7a55a665 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Wed, 10 Jul 2019 21:29:39 +0100 +Subject: [PATCH] ITS#9052 zero out sasl_ssf in connection_init + +--- + servers/slapd/connection.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c +index 34ecaa85a..a9a8d119f 100644 +--- a/servers/slapd/connection.c ++++ b/servers/slapd/connection.c +@@ -535,7 +535,7 @@ Connection * connection_init( + c->c_close_reason = "?"; /* should never be needed */ + + c->c_ssf = c->c_transport_ssf = ssf; +- c->c_tls_ssf = 0; ++ c->c_tls_ssf = c->c_sasl_ssf = 0; + + #ifdef HAVE_TLS + if ( flags & CONN_IS_TLS ) { +-- +2.20.1 (Apple Git-117) + diff --git a/0202-ITS-9038-restrict-rootDN-proxyauthz-to-its-own-DBs.patch b/0202-ITS-9038-restrict-rootDN-proxyauthz-to-its-own-DBs.patch new file mode 100644 index 0000000..a45fdc3 --- /dev/null +++ b/0202-ITS-9038-restrict-rootDN-proxyauthz-to-its-own-DBs.patch @@ -0,0 +1,36 @@ +From fbe5611e606e80e56e158cc42f0c7289975836a8 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Wed, 19 Jun 2019 12:29:02 +0100 +Subject: [PATCH] ITS#9038 restrict rootDN proxyauthz to its own DBs. + +Treat as normal user for any other DB. +--- + servers/slapd/saslauthz.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c +index 541c21344..de34c0b10 100644 +--- a/servers/slapd/saslauthz.c ++++ b/servers/slapd/saslauthz.c +@@ -2062,12 +2062,13 @@ int slap_sasl_authorized( Operation *op, + goto DONE; + } + +- /* Allow the manager to authorize as any DN. */ +- if( op->o_conn->c_authz_backend && +- be_isroot_dn( op->o_conn->c_authz_backend, authcDN )) ++ /* Allow the manager to authorize as any DN in its own DBs. */ + { +- rc = LDAP_SUCCESS; +- goto DONE; ++ Backend *zbe = select_backend( authzDN, 1 ); ++ if ( zbe && be_isroot_dn( zbe, authcDN )) { ++ rc = LDAP_SUCCESS; ++ goto DONE; ++ } + } + + /* Check source rules */ +-- +2.20.1 (Apple Git-117) + diff --git a/0203-ITS-9038-Update-test028-to-test-this-is-enforced.patch b/0203-ITS-9038-Update-test028-to-test-this-is-enforced.patch new file mode 100644 index 0000000..cf218c8 --- /dev/null +++ b/0203-ITS-9038-Update-test028-to-test-this-is-enforced.patch @@ -0,0 +1,102 @@ +From eb5a58487b293358887a2b7f41ea1873abf55fa0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= +Date: Wed, 19 Jun 2019 18:47:32 +0200 +Subject: [PATCH] ITS#9038 Update test028 to test this is enforced + +--- + tests/data/idassert.out | 5 +++++ + tests/data/slapd-idassert.conf | 1 + + tests/data/test-idassert1.ldif | 6 ++++++ + tests/scripts/test028-idassert | 24 ++++++++++++++++++++++++ + 4 files changed, 36 insertions(+) + +diff --git a/tests/data/idassert.out b/tests/data/idassert.out +index 53d76bb2e..fa51c25d6 100644 +--- a/tests/data/idassert.out ++++ b/tests/data/idassert.out +@@ -4,6 +4,11 @@ objectClass: dcObject + o: Example, Inc. + dc: example + ++dn: cn=Manager,o=Example,c=US ++objectClass: inetOrgPerson ++cn: Manager ++sn: Parson ++ + dn: ou=People,o=Example,c=US + objectClass: organizationalUnit + ou: People +diff --git a/tests/data/slapd-idassert.conf b/tests/data/slapd-idassert.conf +index 88d66a36f..561c5ccc4 100644 +--- a/tests/data/slapd-idassert.conf ++++ b/tests/data/slapd-idassert.conf +@@ -36,6 +36,7 @@ argsfile @TESTDIR@/slapd.1.args + ####################################################################### + + authz-policy both ++authz-regexp "^uid=manager,.+" "cn=Manager,dc=example,dc=com" + authz-regexp "^uid=admin/([^,]+),.+" "ldap:///ou=Admin,dc=example,dc=com??sub?(cn=$1)" + authz-regexp "^uid=it/([^,]+),.+" "ldap:///ou=People,dc=example,dc=it??sub?(uid=$1)" + authz-regexp "^uid=(us/)?([^,]+),.+" "ldap:///ou=People,dc=example,dc=com??sub?(uid=$2)" +diff --git a/tests/data/test-idassert1.ldif b/tests/data/test-idassert1.ldif +index 063d6ec45..3ccbd1a22 100644 +--- a/tests/data/test-idassert1.ldif ++++ b/tests/data/test-idassert1.ldif +@@ -4,6 +4,12 @@ objectClass: dcObject + o: Example, Inc. + dc: example + ++dn: cn=Manager,dc=example,dc=com ++objectClass: inetOrgPerson ++cn: Manager ++sn: Parson ++userPassword: secret ++ + dn: ou=People,dc=example,dc=com + objectClass: organizationalUnit + ou: People +diff --git a/tests/scripts/test028-idassert b/tests/scripts/test028-idassert +index b1e16744a..9e5e10724 100755 +--- a/tests/scripts/test028-idassert ++++ b/tests/scripts/test028-idassert +@@ -191,6 +191,17 @@ if test $RC != 0 ; then + exit $RC + fi + ++AUTHZID="u:it/jaj" ++echo "Checking another DB's rootdn can't assert identity from another DB..." ++$LDAPWHOAMI -h $LOCALHOST -p $PORT1 -D "$MANAGERDN" -w $PASSWD -e\!"authzid=$AUTHZID" ++ ++RC=$? ++if test $RC != 1 ; then ++ echo "ldapwhoami should have failed ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi ++ + ID="uid=jaj,ou=People,dc=example,dc=it" + BASE="o=Example,c=US" + echo "Testing ldapsearch as $ID for \"$BASE\"..." +@@ -231,6 +242,19 @@ if test $USE_SASL != "no" ; then + exit $RC + fi + ++ ID="manager" ++ AUTHZID="u:it/jaj" ++ echo "Checking another DB's rootdn can't assert in another (with SASL bind this time)..." ++ $LDAPSASLWHOAMI -h $LOCALHOST -p $PORT1 \ ++ -Q -U "$ID" -w $PASSWD -Y $MECH -X $AUTHZID ++ ++ RC=$? ++ if test $RC != 50 ; then ++ echo "ldapwhoami should have failed ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++ fi ++ + echo "Filtering ldapsearch results..." + $LDIFFILTER < $SEARCHOUT > $SEARCHFLT + echo "Filtering original ldif used to create database..." +-- +2.20.1 (Apple Git-117) + diff --git a/0204-ITS-9038-Another-test028-typo.patch b/0204-ITS-9038-Another-test028-typo.patch new file mode 100644 index 0000000..4878988 --- /dev/null +++ b/0204-ITS-9038-Another-test028-typo.patch @@ -0,0 +1,25 @@ +From 15137bf76fc68f3c97c92ec0d2354d4dd0906348 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= +Date: Thu, 27 Jun 2019 00:45:29 +0200 +Subject: [PATCH] ITS#9038 Another test028 typo + +--- + tests/scripts/test028-idassert | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/scripts/test028-idassert b/tests/scripts/test028-idassert +index 564a615d2..dacd68d8f 100755 +--- a/tests/scripts/test028-idassert ++++ b/tests/scripts/test028-idassert +@@ -252,7 +252,7 @@ if test $USE_SASL != "no" ; then + if test $RC != 50 ; then + echo "ldapwhoami should have failed ($RC)!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS +- exit $RC ++ exit 1 + fi + + echo "Filtering ldapsearch results..." +-- +2.20.1 (Apple Git-117) + diff --git a/0205-bsc-1170771-limit-depth-of-nested-filters.patch b/0205-bsc-1170771-limit-depth-of-nested-filters.patch new file mode 100644 index 0000000..fc0cc7a --- /dev/null +++ b/0205-bsc-1170771-limit-depth-of-nested-filters.patch @@ -0,0 +1,128 @@ +From 7a96c04e0f8bd325a00bd846ea3d244465474e2a Mon Sep 17 00:00:00 2001 +From: William Brown +Date: Thu, 30 Apr 2020 08:57:57 +1000 +Subject: [PATCH] bsc#1170771 - limit depth of nested filters + +Original Commit Message: +d38d48fc8f572dedfb67b9da61a2ba3b125ced91 +[PATCH] ITS#9202 limit depth of nested filters + +Using a hardcoded limit for now; no reasonable apps +should ever run into it. +--- + servers/slapd/filter.c | 40 +++++++++++++++++++++++++++++++--------- + 1 file changed, 31 insertions(+), 9 deletions(-) + +diff --git a/servers/slapd/filter.c b/servers/slapd/filter.c +index e76dc08..95a20fe 100644 +--- a/servers/slapd/filter.c ++++ b/servers/slapd/filter.c +@@ -37,11 +37,16 @@ + const Filter *slap_filter_objectClass_pres; + const struct berval *slap_filterstr_objectClass_pres; + ++#ifndef SLAPD_MAX_FILTER_DEPTH ++#define SLAPD_MAX_FILTER_DEPTH 5000 ++#endif ++ + static int get_filter_list( + Operation *op, + BerElement *ber, + Filter **f, +- const char **text ); ++ const char **text, ++ int depth ); + + static int get_ssa( + Operation *op, +@@ -80,12 +85,13 @@ filter_destroy( void ) + return; + } + +-int +-get_filter( ++static int ++get_filter0( + Operation *op, + BerElement *ber, + Filter **filt, +- const char **text ) ++ const char **text, ++ int depth ) + { + ber_tag_t tag; + ber_len_t len; +@@ -126,6 +132,11 @@ get_filter( + * + */ + ++ if( depth > SLAPD_MAX_FILTER_DEPTH ) { ++ *text = "filter nested too deeply"; ++ return SLAPD_DISCONNECT; ++ } ++ + tag = ber_peek_tag( ber, &len ); + + if( tag == LBER_ERROR ) { +@@ -221,7 +232,7 @@ get_filter( + + case LDAP_FILTER_AND: + Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 ); +- err = get_filter_list( op, ber, &f.f_and, text ); ++ err = get_filter_list( op, ber, &f.f_and, text, depth+1 ); + if ( err != LDAP_SUCCESS ) { + break; + } +@@ -234,7 +245,7 @@ get_filter( + + case LDAP_FILTER_OR: + Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 ); +- err = get_filter_list( op, ber, &f.f_or, text ); ++ err = get_filter_list( op, ber, &f.f_or, text, depth+1 ); + if ( err != LDAP_SUCCESS ) { + break; + } +@@ -248,7 +259,7 @@ get_filter( + case LDAP_FILTER_NOT: + Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 ); + (void) ber_skip_tag( ber, &len ); +- err = get_filter( op, ber, &f.f_not, text ); ++ err = get_filter0( op, ber, &f.f_not, text, depth+1 ); + if ( err != LDAP_SUCCESS ) { + break; + } +@@ -311,10 +322,21 @@ get_filter( + return( err ); + } + ++int ++get_filter( ++ Operation *op, ++ BerElement *ber, ++ Filter **filt, ++ const char **text ) ++{ ++ return get_filter0( op, ber, filt, text, 0 ); ++} ++ + static int + get_filter_list( Operation *op, BerElement *ber, + Filter **f, +- const char **text ) ++ const char **text, ++ int depth ) + { + Filter **new; + int err; +@@ -328,7 +350,7 @@ get_filter_list( Operation *op, BerElement *ber, + tag != LBER_DEFAULT; + tag = ber_next_element( ber, &len, last ) ) + { +- err = get_filter( op, ber, new, text ); ++ err = get_filter0( op, ber, new, text, depth ); + if ( err != LDAP_SUCCESS ) + return( err ); + new = &(*new)->f_next; +-- +2.26.2 + diff --git a/0206-openldap-tlso-use-openssl-api-to-verify-host.patch b/0206-openldap-tlso-use-openssl-api-to-verify-host.patch new file mode 100644 index 0000000..f7a1259 --- /dev/null +++ b/0206-openldap-tlso-use-openssl-api-to-verify-host.patch @@ -0,0 +1,224 @@ +From f2978fefa13eb92b73922e49d2f6c12b4f92ea85 Mon Sep 17 00:00:00 2001 +From: Christian Heimes +Date: Fri, 10 Jan 2020 18:35:02 +0100 +Subject: [PATCH] Use OpenSSL API to verify host + +Replace custom hostname and IP address verification with OpenSSL 1.0.2 +APIs. +--- + libraries/libldap/tls_o.c | 184 ++++++-------------------------------- + 1 file changed, 28 insertions(+), 156 deletions(-) + +diff --git a/libraries/libldap/tls_o.c b/libraries/libldap/tls_o.c +index e52c5507c..5adf7b74f 100644 +--- a/libraries/libldap/tls_o.c ++++ b/libraries/libldap/tls_o.c +@@ -660,25 +660,15 @@ tlso_session_peer_dn( tls_session *sess, struct berval *der_dn ) + return 0; + } + +-/* what kind of hostname were we given? */ +-#define IS_DNS 0 +-#define IS_IP4 1 +-#define IS_IP6 2 +- + static int + tlso_session_chkhost( LDAP *ld, tls_session *sess, const char *name_in ) + { + tlso_session *s = (tlso_session *)sess; +- int i, ret = LDAP_LOCAL_ERROR; ++ int ret = LDAP_LOCAL_ERROR; + X509 *x; + const char *name; +- char *ptr; +- int ntype = IS_DNS, nlen; +-#ifdef LDAP_PF_INET6 +- struct in6_addr addr; +-#else +- struct in_addr addr; +-#endif ++ int flags = X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS; ++ ASN1_OCTET_STRING *ip; + + if( ldap_int_hostname && + ( !name_in || !strcasecmp( name_in, "localhost" ) ) ) +@@ -687,7 +677,6 @@ tlso_session_chkhost( LDAP *ld, tls_session *sess, const char *name_in ) + } else { + name = name_in; + } +- nlen = strlen(name); + + x = tlso_get_cert(s); + if (!x) { +@@ -619,150 +619,32 @@ tlso_session_chkhost( LDAP *ld, tls_session *sess, const char *name_in ) + return LDAP_SUCCESS; + } + +-#ifdef LDAP_PF_INET6 +- if (inet_pton(AF_INET6, name, &addr)) { +- ntype = IS_IP6; +- } else +-#endif +- if ((ptr = strrchr(name, '.')) && isdigit((unsigned char)ptr[1])) { +- if (inet_aton(name, (struct in_addr *)&addr)) ntype = IS_IP4; +- } +- +- i = X509_get_ext_by_NID(x, NID_subject_alt_name, -1); +- if (i >= 0) { +- X509_EXTENSION *ex; +- STACK_OF(GENERAL_NAME) *alt; +- +- ex = X509_get_ext(x, i); +- alt = X509V3_EXT_d2i(ex); +- if (alt) { +- int n, len2 = 0; +- char *domain = NULL; +- GENERAL_NAME *gn; +- +- if (ntype == IS_DNS) { +- domain = strchr(name, '.'); +- if (domain) { +- len2 = nlen - (domain-name); +- } +- } +- n = sk_GENERAL_NAME_num(alt); +- for (i=0; itype == GEN_DNS) { +- if (ntype != IS_DNS) continue; +- +- sn = (char *) ASN1_STRING_data(gn->d.ia5); +- sl = ASN1_STRING_length(gn->d.ia5); +- +- /* ignore empty */ +- if (sl == 0) continue; +- +- /* Is this an exact match? */ +- if ((nlen == sl) && !strncasecmp(name, sn, nlen)) { +- break; +- } +- +- /* Is this a wildcard match? */ +- if (domain && (sn[0] == '*') && (sn[1] == '.') && +- (len2 == sl-1) && !strncasecmp(domain, &sn[1], len2)) +- { +- break; +- } +- +- } else if (gn->type == GEN_IPADD) { +- if (ntype == IS_DNS) continue; +- +- sn = (char *) ASN1_STRING_data(gn->d.ia5); +- sl = ASN1_STRING_length(gn->d.ia5); +- +-#ifdef LDAP_PF_INET6 +- if (ntype == IS_IP6 && sl != sizeof(struct in6_addr)) { +- continue; +- } else +-#endif +- if (ntype == IS_IP4 && sl != sizeof(struct in_addr)) { +- continue; +- } +- if (!memcmp(sn, &addr, sl)) { +- break; +- } +- } +- } +- +- GENERAL_NAMES_free(alt); +- if (i < n) { /* Found a match */ +- ret = LDAP_SUCCESS; +- } +- } +- } +- +- if (ret != LDAP_SUCCESS) { +- X509_NAME *xn; +- X509_NAME_ENTRY *ne; +- ASN1_OBJECT *obj; +- ASN1_STRING *cn = NULL; +- int navas; +- +- /* find the last CN */ +- obj = OBJ_nid2obj( NID_commonName ); +- if ( !obj ) goto no_cn; /* should never happen */ +- +- xn = X509_get_subject_name(x); +- navas = X509_NAME_entry_count( xn ); +- for ( i=navas-1; i>=0; i-- ) { +- ne = X509_NAME_get_entry( xn, i ); +- if ( !OBJ_cmp( X509_NAME_ENTRY_get_object(ne), obj )) { +- cn = X509_NAME_ENTRY_get_data( ne ); +- break; +- } ++ /* attempt to encode name as IP address */ ++ ip = a2i_IPADDRESS(name); ++ if (ip == NULL) { ++ ERR_clear_error(); ++ /* it's a hostname */ ++ if (X509_check_host(x, name, strlen(name), flags, NULL) == 1) { ++ ret = LDAP_SUCCESS; + } +- +- if( !cn ) +- { +-no_cn: +- Debug( LDAP_DEBUG_ANY, +- "TLS: unable to get common name from peer certificate.\n", +- 0, 0, 0 ); +- ret = LDAP_CONNECT_ERROR; +- if ( ld->ld_error ) { +- LDAP_FREE( ld->ld_error ); +- } +- ld->ld_error = LDAP_STRDUP( +- _("TLS: unable to get CN from peer certificate")); +- +- } else if ( cn->length == nlen && +- strncasecmp( name, (char *) cn->data, nlen ) == 0 ) { ++ } else { ++ /* It's an IPv4 or IPv6 address */ ++ if (X509_check_ip(x, ASN1_STRING_data(ip), ++ ASN1_STRING_length(ip), 0) == 1) { + ret = LDAP_SUCCESS; +- +- } else if (( cn->data[0] == '*' ) && ( cn->data[1] == '.' )) { +- char *domain = strchr(name, '.'); +- if( domain ) { +- int dlen; +- +- dlen = nlen - (domain-name); +- +- /* Is this a wildcard match? */ +- if ((dlen == cn->length-1) && +- !strncasecmp(domain, (char *) &cn->data[1], dlen)) { +- ret = LDAP_SUCCESS; +- } +- } + } ++ ASN1_OCTET_STRING_free(ip); ++ } + +- if( ret == LDAP_LOCAL_ERROR ) { +- Debug( LDAP_DEBUG_ANY, "TLS: hostname (%s) does not match " +- "common name in certificate (%.*s).\n", +- name, cn->length, cn->data ); +- ret = LDAP_CONNECT_ERROR; +- if ( ld->ld_error ) { +- LDAP_FREE( ld->ld_error ); +- } +- ld->ld_error = LDAP_STRDUP( +- _("TLS: hostname does not match CN in peer certificate")); ++ if( ret == LDAP_LOCAL_ERROR ) { ++ Debug( LDAP_DEBUG_ANY, "TLS: hostname (%s) does not match " ++ "peer certificate.\n", name, 0, 0); ++ ret = LDAP_CONNECT_ERROR; ++ if ( ld->ld_error ) { ++ LDAP_FREE( ld->ld_error ); + } ++ ld->ld_error = LDAP_STRDUP( ++ _("TLS: hostname does not match peer certificate")); + } + X509_free(x); + return ret; diff --git a/0207-ITS-9370-check-for-equality-rule-on-old_rdn.patch b/0207-ITS-9370-check-for-equality-rule-on-old_rdn.patch new file mode 100644 index 0000000..d64e3fe --- /dev/null +++ b/0207-ITS-9370-check-for-equality-rule-on-old_rdn.patch @@ -0,0 +1,27 @@ +From e26672d296d67457d77a49c482e900f416b15dfd Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Mon, 19 Oct 2020 14:03:41 +0100 +Subject: [PATCH] ITS#9370 check for equality rule on old_rdn + +Just skip normalization if there's no equality rule. We accept +DNs without equality rules already. +--- + servers/slapd/modrdn.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c +index 77eaa68..6f176e8 100644 +--- a/servers/slapd/modrdn.c ++++ b/servers/slapd/modrdn.c +@@ -494,7 +494,7 @@ slap_modrdn2mods( + mod_tmp->sml_values = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) ); + ber_dupbv( &mod_tmp->sml_values[0], &old_rdn[d_cnt]->la_value ); + mod_tmp->sml_values[1].bv_val = NULL; +- if( desc->ad_type->sat_equality->smr_normalize) { ++ if( desc->ad_type->sat_equality && desc->ad_type->sat_equality->smr_normalize) { + mod_tmp->sml_nvalues = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) ); + (void) (*desc->ad_type->sat_equality->smr_normalize)( + SLAP_MR_EQUALITY|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX, +-- +2.29.2 + diff --git a/0208-ITS-9400-back-ldap-fix-retry-binds.patch b/0208-ITS-9400-back-ldap-fix-retry-binds.patch new file mode 100644 index 0000000..db51d4e --- /dev/null +++ b/0208-ITS-9400-back-ldap-fix-retry-binds.patch @@ -0,0 +1,252 @@ +From 76fea1fa8f4fe3b546596a6b63831cacb33c73aa Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Mon, 23 Nov 2020 05:14:30 +0000 +Subject: [PATCH] ITS#9400 back-ldap: fix retry binds + +Regression from fix for ITS#7403 + +ITS#9400 back-ldap: fix prev commit + +ITS#9400 Added test case for back-ldap retry failure +--- + servers/slapd/back-ldap/bind.c | 2 +- + tests/data/regressions/its9400/its9400 | 161 ++++++++++++++++++ + .../its9400/slapd-proxy-idassert.conf | 45 +++++ + 3 files changed, 207 insertions(+), 1 deletion(-) + create mode 100755 tests/data/regressions/its9400/its9400 + create mode 100644 tests/data/regressions/its9400/slapd-proxy-idassert.conf + +diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c +index 621cd2c8c..e6a3db144 100644 +--- a/servers/slapd/back-ldap/bind.c ++++ b/servers/slapd/back-ldap/bind.c +@@ -2102,7 +2102,7 @@ ldap_back_is_proxy_authz( Operation *op, SlapReply *rs, ldap_back_send_t sendok, + } + + if ( !( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE )) { +- if ( op->o_tag == LDAP_REQ_BIND ) { ++ if ( op->o_tag == LDAP_REQ_BIND && ( sendok & LDAP_BACK_SENDERR )) { + if ( !BER_BVISEMPTY( &ndn )) { + dobind = 0; + goto done; +diff --git a/tests/data/regressions/its9400/its9400 b/tests/data/regressions/its9400/its9400 +new file mode 100755 +index 000000000..ae0c5258b +--- /dev/null ++++ b/tests/data/regressions/its9400/its9400 +@@ -0,0 +1,161 @@ ++#! /bin/sh ++# $OpenLDAP$ ++## This work is part of OpenLDAP Software . ++## ++## Copyright 1998-2020 The OpenLDAP Foundation. ++## All rights reserved. ++## ++## Redistribution and use in source and binary forms, with or without ++## modification, are permitted only as authorized by the OpenLDAP ++## Public License. ++## ++## A copy of this license is available in the file LICENSE in the ++## top-level directory of the distribution or, alternatively, at ++## . ++ ++echo "running defines.sh" ++. $SRCDIR/scripts/defines.sh ++ ++ITS=9400 ++ITSDIR=$DATADIR/regressions/its$ITS ++ ++if test $BACKLDAP = "ldapno" ; then ++ echo "LDAP backend not available, test skipped" ++ exit 0 ++fi ++ ++mkdir -p $TESTDIR $DBDIR1 $DBDIR2 ++cp -r $DATADIR/tls $TESTDIR ++ ++echo "This test checks that back-ldap does retry binds after the remote LDAP server" ++echo "has abruptly disconnected the (idle) LDAP connection." ++ ++# ++# Start slapd that acts as a remote LDAP server that will be proxied ++# ++echo "Running slapadd to build database for the remote slapd server..." ++. $CONFFILTER $BACKEND < $CONF > $CONF1 ++$SLAPADD -f $CONF1 -l $LDIFORDERED ++ ++RC=$? ++if test $RC != 0 ; then ++ echo "slapadd failed ($RC)!" ++ exit $RC ++fi ++ ++ ++echo "Starting remote slapd server on TCP/IP port $PORT1..." ++$SLAPD -f $CONF1 -h "$URI1" -d $LVL > $LOG1 2>&1 & ++SERVERPID=$! ++if test $WAIT != 0 ; then ++ echo SERVERPID $SERVERPID ++ read foo ++fi ++ ++ ++# ++# Start ldapd that will proxy for the remote server ++# ++echo "Starting slapd proxy on TCP/IP port $PORT2..." ++. $CONFFILTER $BACKEND < $ITSDIR/slapd-proxy-idassert.conf > $CONF2 ++$SLAPD -f $CONF2 -h $URI2 -d $LVL > $LOG2 2>&1 & ++PROXYPID=$! ++if test $WAIT != 0 ; then ++ echo PROXYPID $PROXYPID ++ read foo ++fi ++KILLPIDS="$KILLPIDS $PROXYPID" ++ ++sleep 1 ++ ++ ++# ++# Successful searches ++# ++ ++echo "Using ldapsearch with bind that will be passed through to remote server..." ++$LDAPSEARCH -S "" -b "$BASEDN" \ ++ -D "cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com" \ ++ -H $URI2 \ ++ -w "bjensen" \ ++ 'objectclass=*' > $TESTOUT 2>&1 ++RC=$? ++if test $RC != 0 ; then ++ echo "ldapsearch failed at proxy ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi ++ ++ ++echo "Using ldapsearch with idassert-bind..." ++$LDAPSEARCH -S "" -b "$BASEDN" -D "cn=Manager,dc=local,dc=com" -H $URI2 -w "secret" \ ++ 'objectclass=*' >> $TESTOUT 2>&1 ++RC=$? ++if test $RC != 0 ; then ++ echo "ldapsearch failed at proxy ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi ++ ++ ++# ++# Now kill the remote slapd that is being proxied for. ++# This will invalidate the current TCP connections that proxy has to remote. ++# ++echo "Killing remote server" ++kill $SERVERPID ++sleep 1 ++ ++echo "Re-starting remote slapd server on TCP/IP port $PORT1..." ++$SLAPD -f $CONF1 -h "$URI1" -d $LVL >> $LOG1 2>&1 & ++SERVERPID=$! ++if test $WAIT != 0 ; then ++ echo SERVERPID $SERVERPID ++ read foo ++fi ++KILLPIDS="$KILLPIDS $SERVERPID" ++ ++sleep 2 ++ ++ ++echo "-------------------------------------------------" >> $TESTOUT ++echo "Searches after remote slapd server has restarted:" >> $TESTOUT ++echo "-------------------------------------------------" >> $TESTOUT ++ ++# ++# Successful search ++# ++echo "Using ldapsearch with bind that will be passed through to remote server..." ++$LDAPSEARCH -S "" -b "$BASEDN" \ ++ -D "cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com" \ ++ -H $URI2 \ ++ -w "bjensen" \ ++ 'objectclass=*' >> $TESTOUT 2>&1 ++RC=$? ++if test $RC != 0 ; then ++ echo "ldapsearch failed at proxy ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi ++ ++# ++# UNSUCCESFUL SEARCH ++# ++echo "Using ldapsearch with idassert-bind..." ++$LDAPSEARCH -S "" -b "$BASEDN" -D "cn=Manager,dc=local,dc=com" -H $URI2 -w "secret" \ ++ 'objectclass=*' >> $TESTOUT 2>&1 ++RC=$? ++if test $RC != 0 ; then ++ echo "ldapsearch failed at proxy ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi ++ ++ ++test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ ++echo ">>>>> Test succeeded" ++ ++test $KILLSERVERS != no && wait ++ ++exit 0 +diff --git a/tests/data/regressions/its9400/slapd-proxy-idassert.conf b/tests/data/regressions/its9400/slapd-proxy-idassert.conf +new file mode 100644 +index 000000000..b1f3c6626 +--- /dev/null ++++ b/tests/data/regressions/its9400/slapd-proxy-idassert.conf +@@ -0,0 +1,45 @@ ++# provider slapd config -- for testing ++# $OpenLDAP$ ++## This work is part of OpenLDAP Software . ++## ++## Copyright 1998-2020 The OpenLDAP Foundation. ++## All rights reserved. ++## ++## Redistribution and use in source and binary forms, with or without ++## modification, are permitted only as authorized by the OpenLDAP ++## Public License. ++## ++## A copy of this license is available in the file LICENSE in the ++## top-level directory of the distribution or, alternatively, at ++## . ++ ++include @SCHEMADIR@/core.schema ++include @SCHEMADIR@/cosine.schema ++include @SCHEMADIR@/inetorgperson.schema ++include @SCHEMADIR@/openldap.schema ++include @SCHEMADIR@/nis.schema ++pidfile @TESTDIR@/slapd.m.pid ++argsfile @TESTDIR@/slapd.m.args ++ ++####################################################################### ++# database definitions ++####################################################################### ++ ++# here the proxy is not only acting as a proxy, but it also has a local database dc=local,dc=com" ++database @BACKEND@ ++suffix "dc=local,dc=com" ++rootdn "cn=Manager,dc=local,dc=com" ++rootpw "secret" ++#~null~#directory @TESTDIR@/db.2.a ++ ++# Configure proxy ++# - normal user binds to "*,dc=example,dc=com" are proxied through to the remote slapd ++# - admin bind to local "cn=Manager,dc=local,dc=com" is overwritten by using idassert-bind ++database ldap ++uri "@URI1@" ++suffix "dc=example,dc=com" ++idassert-bind bindmethod=simple binddn="cn=Manager,dc=example,dc=com" credentials="secret" ++idassert-authzFrom "dn.exact:cn=Manager,dc=local,dc=com" ++rebind-as-user yes ++ ++database monitor +-- +2.24.3 (Apple Git-128) + diff --git a/0209-ITS-9383-remove-assert-in-certificateListValidate.patch b/0209-ITS-9383-remove-assert-in-certificateListValidate.patch new file mode 100644 index 0000000..b8cec35 --- /dev/null +++ b/0209-ITS-9383-remove-assert-in-certificateListValidate.patch @@ -0,0 +1,26 @@ +From 0b4c1bbb77a75e6139e9d9e7c84c90fb650408e3 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Mon, 2 Nov 2020 13:12:10 +0000 +Subject: [PATCH 1/2] ITS#9383 remove assert in certificateListValidate + +--- + servers/slapd/schema_init.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c +index 6a512a286..cd979cc5a 100644 +--- a/servers/slapd/schema_init.c ++++ b/servers/slapd/schema_init.c +@@ -371,8 +371,7 @@ certificateListValidate( Syntax *syntax, struct berval *in ) + /* Optional version */ + if ( tag == LBER_INTEGER ) { + tag = ber_get_int( ber, &version ); +- assert( tag == LBER_INTEGER ); +- if ( version != SLAP_X509_V2 ) return LDAP_INVALID_SYNTAX; ++ if ( tag != LBER_INTEGER || version != SLAP_X509_V2 ) return LDAP_INVALID_SYNTAX; + } + tag = ber_skip_tag( ber, &len ); /* Signature Algorithm */ + if ( tag != LBER_SEQUENCE ) return LDAP_INVALID_SYNTAX; +-- +2.29.2 + diff --git a/0210-ITS-9384-remove-assert-in-obsolete-csnNormalize23.patch b/0210-ITS-9384-remove-assert-in-obsolete-csnNormalize23.patch new file mode 100644 index 0000000..fb902b4 --- /dev/null +++ b/0210-ITS-9384-remove-assert-in-obsolete-csnNormalize23.patch @@ -0,0 +1,27 @@ +From 5482b878d90a9ee163a823ccc17b537bdb70aae7 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Mon, 2 Nov 2020 16:01:14 +0000 +Subject: [PATCH 2/2] ITS#9384 remove assert in obsolete csnNormalize23() + +--- + servers/slapd/schema_init.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c +index cd979cc5a..d6a54ad0b 100644 +--- a/servers/slapd/schema_init.c ++++ b/servers/slapd/schema_init.c +@@ -5315,8 +5315,8 @@ csnNormalize23( + } + *ptr = '\0'; + +- assert( ptr == &bv.bv_val[bv.bv_len] ); +- if ( csnValidate( syntax, &bv ) != LDAP_SUCCESS ) { ++ if ( ptr != &bv.bv_val[bv.bv_len] || ++ csnValidate( syntax, &bv ) != LDAP_SUCCESS ) { + return LDAP_INVALID_SYNTAX; + } + +-- +2.29.2 + diff --git a/0211-ITS-9454-fix-issuerAndThisUpdateCheck.patch b/0211-ITS-9454-fix-issuerAndThisUpdateCheck.patch new file mode 100644 index 0000000..6282664 --- /dev/null +++ b/0211-ITS-9454-fix-issuerAndThisUpdateCheck.patch @@ -0,0 +1,25 @@ +From 49dd15ba74283e40ec296237af45862d795c75ad Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Sat, 6 Feb 2021 20:52:06 +0000 +Subject: [PATCH] ITS#9454 fix issuerAndThisUpdateCheck + +--- + servers/slapd/schema_init.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c +index d6a54ad0b..3c5ee3dad 100644 +--- a/servers/slapd/schema_init.c ++++ b/servers/slapd/schema_init.c +@@ -3887,6 +3887,8 @@ issuerAndThisUpdateCheck( + break; + } + } ++ if ( tu->bv_len < STRLENOF("YYYYmmddHHmmssZ") ) return LDAP_INVALID_SYNTAX; ++ + x.bv_val += tu->bv_len + 1; + x.bv_len -= tu->bv_len + 1; + +-- +2.30.0 + diff --git a/0212-ITS-9404-fix-serialNumberAndIssuerCheck.patch b/0212-ITS-9404-fix-serialNumberAndIssuerCheck.patch new file mode 100644 index 0000000..c2f5777 --- /dev/null +++ b/0212-ITS-9404-fix-serialNumberAndIssuerCheck.patch @@ -0,0 +1,58 @@ +From 02e18c2f80eb89ef9dbab323a1c4301e713c8b79 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Mon, 23 Nov 2020 17:14:00 +0000 +Subject: [PATCH 212/224] ITS#9404 fix serialNumberAndIssuerCheck + +Tighten validity checks +--- + servers/slapd/schema_init.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c +index 3c5ee3dad..f9200d362 100644 +--- a/servers/slapd/schema_init.c ++++ b/servers/slapd/schema_init.c +@@ -3189,7 +3189,7 @@ serialNumberAndIssuerCheck( + + if( in->bv_len < 3 ) return LDAP_INVALID_SYNTAX; + +- if( in->bv_val[0] != '{' && in->bv_val[in->bv_len-1] != '}' ) { ++ if( in->bv_val[0] != '{' || in->bv_val[in->bv_len-1] != '}' ) { + /* Parse old format */ + is->bv_val = ber_bvchr( in, '$' ); + if( BER_BVISNULL( is ) ) return LDAP_INVALID_SYNTAX; +@@ -3220,7 +3220,7 @@ serialNumberAndIssuerCheck( + HAVE_ALL = ( HAVE_ISSUER | HAVE_SN ) + } have = HAVE_NONE; + +- int numdquotes = 0; ++ int numdquotes = 0, gotquote; + struct berval x = *in; + struct berval ni; + x.bv_val++; +@@ -3262,11 +3262,12 @@ serialNumberAndIssuerCheck( + is->bv_val = x.bv_val; + is->bv_len = 0; + +- for ( ; is->bv_len < x.bv_len; ) { ++ for ( gotquote=0; is->bv_len < x.bv_len; ) { + if ( is->bv_val[is->bv_len] != '"' ) { + is->bv_len++; + continue; + } ++ gotquote = 1; + if ( is->bv_val[is->bv_len+1] == '"' ) { + /* double dquote */ + numdquotes++; +@@ -3275,6 +3276,8 @@ serialNumberAndIssuerCheck( + } + break; + } ++ if ( !gotquote ) return LDAP_INVALID_SYNTAX; ++ + x.bv_val += is->bv_len + 1; + x.bv_len -= is->bv_len + 1; + +-- +2.30.0 + diff --git a/0213-ITS-9406-9407-remove-saslauthz-asserts.patch b/0213-ITS-9406-9407-remove-saslauthz-asserts.patch new file mode 100644 index 0000000..01f9477 --- /dev/null +++ b/0213-ITS-9406-9407-remove-saslauthz-asserts.patch @@ -0,0 +1,69 @@ +From f691c1bc5e7a3166a8c371974f8d920a99bae298 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Fri, 27 Nov 2020 14:37:10 +0000 +Subject: [PATCH 213/224] ITS#9406, #9407 remove saslauthz asserts + +--- + servers/slapd/saslauthz.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c +index 1245efc6c..bb99f5283 100644 +--- a/servers/slapd/saslauthz.c ++++ b/servers/slapd/saslauthz.c +@@ -180,14 +180,16 @@ int slap_parse_user( struct berval *id, struct berval *user, + } + + if ( !BER_BVISNULL( mech ) ) { +- assert( mech->bv_val == id->bv_val + 2 ); ++ if ( mech->bv_val != id->bv_val + 2 ) ++ return LDAP_PROTOCOL_ERROR; + + AC_MEMCPY( mech->bv_val - 2, mech->bv_val, mech->bv_len + 1 ); + mech->bv_val -= 2; + } + + if ( !BER_BVISNULL( realm ) ) { +- assert( realm->bv_val >= id->bv_val + 2 ); ++ if ( realm->bv_val < id->bv_val + 2 ) ++ return LDAP_PROTOCOL_ERROR; + + AC_MEMCPY( realm->bv_val - 2, realm->bv_val, realm->bv_len + 1 ); + realm->bv_val -= 2; +@@ -449,9 +451,12 @@ is_dn: bv.bv_len = in->bv_len - ( bv.bv_val - in->bv_val ); + } + + /* Grab the searchbase */ +- assert( ludp->lud_dn != NULL ); +- ber_str2bv( ludp->lud_dn, 0, 0, &bv ); +- rc = dnValidate( NULL, &bv ); ++ if ( ludp->lud_dn != NULL ) { ++ ber_str2bv( ludp->lud_dn, 0, 0, &bv ); ++ rc = dnValidate( NULL, &bv ); ++ } else { ++ rc = LDAP_INVALID_SYNTAX; ++ } + + done: + ldap_free_urldesc( ludp ); +@@ -813,7 +818,6 @@ is_dn: bv.bv_len = val->bv_len - ( bv.bv_val - val->bv_val ); + } + + /* Grab the searchbase */ +- assert( ludp->lud_dn != NULL ); + if ( ludp->lud_dn ) { + struct berval out = BER_BVNULL; + +@@ -831,6 +835,9 @@ is_dn: bv.bv_len = val->bv_len - ( bv.bv_val - val->bv_val ); + } + + ludp->lud_dn = out.bv_val; ++ } else { ++ rc = LDAP_INVALID_SYNTAX; ++ goto done; + } + + ludp->lud_port = 0; +-- +2.30.0 + diff --git a/0214-ITS-9406-fix-debug-msg.patch b/0214-ITS-9406-fix-debug-msg.patch new file mode 100644 index 0000000..2b088b2 --- /dev/null +++ b/0214-ITS-9406-fix-debug-msg.patch @@ -0,0 +1,33 @@ +From 6f896a9db19cd48df25fddc3bec4ab358f3a82f7 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Fri, 27 Nov 2020 14:48:26 +0000 +Subject: [PATCH 214/224] ITS#9406 fix debug msg + +--- + servers/slapd/saslauthz.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c +index bb99f5283..f424028ff 100644 +--- a/servers/slapd/saslauthz.c ++++ b/servers/slapd/saslauthz.c +@@ -488,6 +488,7 @@ authzPrettyNormal( + + assert( val != NULL ); + assert( !BER_BVISNULL( val ) ); ++ BER_BVZERO( normalized ); + + /* + * 2) dn[.{exact|children|subtree|onelevel}]:{*|} +@@ -906,7 +907,7 @@ authzPretty( + rc = authzPrettyNormal( val, out, ctx, 0 ); + + Debug( LDAP_DEBUG_TRACE, "<<< authzPretty: <%s> (%d)\n", +- out->bv_val, rc, 0 ); ++ out->bv_val ? out->bv_val : "(null)" , rc, 0 ); + + return rc; + } +-- +2.30.0 + diff --git a/0215-ITS-9408-fix-vrfilter-double-free.patch b/0215-ITS-9408-fix-vrfilter-double-free.patch new file mode 100644 index 0000000..3a230af --- /dev/null +++ b/0215-ITS-9408-fix-vrfilter-double-free.patch @@ -0,0 +1,28 @@ +From b4f0b6d88fa165de73e2418894038c2d24cee0a8 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Sat, 28 Nov 2020 15:54:17 +0000 +Subject: [PATCH 215/224] ITS#9408 fix vrfilter double-free + +--- + servers/slapd/controls.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c +index b8edd39bc..50a358b07 100644 +--- a/servers/slapd/controls.c ++++ b/servers/slapd/controls.c +@@ -1578,7 +1578,10 @@ static int parseValuesReturnFilter ( + } else { + send_ldap_result( op, rs ); + } +- if( op->o_vrFilter != NULL) vrFilter_free( op, op->o_vrFilter ); ++ if( op->o_vrFilter != NULL) { ++ vrFilter_free( op, op->o_vrFilter ); ++ op->o_vrFilter = NULL; ++ } + } + #ifdef LDAP_DEBUG + else { +-- +2.30.0 + diff --git a/0216-ITS-9409-saslauthz-use-ch_free-on-normalized-DN.patch b/0216-ITS-9409-saslauthz-use-ch_free-on-normalized-DN.patch new file mode 100644 index 0000000..d0cb150 --- /dev/null +++ b/0216-ITS-9409-saslauthz-use-ch_free-on-normalized-DN.patch @@ -0,0 +1,25 @@ +From 6eda12deab86a523a0eee8d395a83adacfe35d28 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Mon, 30 Nov 2020 11:45:46 +0000 +Subject: [PATCH 216/224] ITS#9409 saslauthz: use ch_free on normalized DN + +--- + servers/slapd/saslauthz.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c +index f424028ff..6001a5cbe 100644 +--- a/servers/slapd/saslauthz.c ++++ b/servers/slapd/saslauthz.c +@@ -860,7 +860,7 @@ done: + + if ( lud_dn ) { + if ( ludp->lud_dn != lud_dn ) { +- ber_memfree( ludp->lud_dn ); ++ ch_free( ludp->lud_dn ); + } + ludp->lud_dn = lud_dn; + } +-- +2.30.0 + diff --git a/0217-ITS-9409-saslauthz-use-slap_sl_free-in-prev-commit.patch b/0217-ITS-9409-saslauthz-use-slap_sl_free-in-prev-commit.patch new file mode 100644 index 0000000..062b43d --- /dev/null +++ b/0217-ITS-9409-saslauthz-use-slap_sl_free-in-prev-commit.patch @@ -0,0 +1,25 @@ +From 5d7ac6942c4e42a330b8874b71338b11a79c7051 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Mon, 30 Nov 2020 16:20:18 +0000 +Subject: [PATCH 217/224] ITS#9409 saslauthz: use slap_sl_free in prev commit + +--- + servers/slapd/saslauthz.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c +index 6001a5cbe..19c058cbf 100644 +--- a/servers/slapd/saslauthz.c ++++ b/servers/slapd/saslauthz.c +@@ -860,7 +860,7 @@ done: + + if ( lud_dn ) { + if ( ludp->lud_dn != lud_dn ) { +- ch_free( ludp->lud_dn ); ++ slap_sl_free( ludp->lud_dn, ctx ); + } + ludp->lud_dn = lud_dn; + } +-- +2.30.0 + diff --git a/0218-ITS-9412-fix-AVA_Sort-on-invalid-RDN.patch b/0218-ITS-9412-fix-AVA_Sort-on-invalid-RDN.patch new file mode 100644 index 0000000..263afeb --- /dev/null +++ b/0218-ITS-9412-fix-AVA_Sort-on-invalid-RDN.patch @@ -0,0 +1,42 @@ +From ef319e3bfd3c092a6a64d43a1f4a5a86a9aa1b58 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Tue, 1 Dec 2020 18:32:35 +0000 +Subject: [PATCH 218/224] ITS#9412 fix AVA_Sort on invalid RDN + +--- + servers/slapd/dn.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/servers/slapd/dn.c b/servers/slapd/dn.c +index c3465498d..4ac6cf313 100644 +--- a/servers/slapd/dn.c ++++ b/servers/slapd/dn.c +@@ -233,6 +233,7 @@ AVA_Sort( LDAPRDN rdn, int nAVAs ) + { + LDAPAVA *ava_i; + int i; ++ int rc = LDAP_SUCCESS; + + assert( rdn != NULL ); + +@@ -250,7 +251,7 @@ AVA_Sort( LDAPRDN rdn, int nAVAs ) + /* RFC4512 does not allow multiple AVAs + * with the same attribute type in RDN (ITS#5968) */ + if ( a == 0 ) +- return LDAP_INVALID_DN_SYNTAX; ++ rc = LDAP_INVALID_DN_SYNTAX; + + if ( a > 0 ) + break; +@@ -259,7 +260,7 @@ AVA_Sort( LDAPRDN rdn, int nAVAs ) + } + rdn[ j+1 ] = ava_i; + } +- return LDAP_SUCCESS; ++ return rc; + } + + static int +-- +2.30.0 + diff --git a/0219-ITS-9413-fix-slap_parse_user.patch b/0219-ITS-9413-fix-slap_parse_user.patch new file mode 100644 index 0000000..90b5f3e --- /dev/null +++ b/0219-ITS-9413-fix-slap_parse_user.patch @@ -0,0 +1,38 @@ +From b4248eeda7ebb2c62266c34128caba5c14e4bc67 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Tue, 1 Dec 2020 19:03:24 +0000 +Subject: [PATCH 219/224] ITS#9413 fix slap_parse_user + +--- + servers/slapd/saslauthz.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c +index 19c058cbf..629280efe 100644 +--- a/servers/slapd/saslauthz.c ++++ b/servers/slapd/saslauthz.c +@@ -156,10 +156,9 @@ int slap_parse_user( struct berval *id, struct berval *user, + user->bv_val++; + user->bv_len = id->bv_len - ( user->bv_val - id->bv_val ); + +- mech->bv_val = ber_bvchr( id, '.' ); +- if ( !BER_BVISNULL( mech ) ) { +- mech->bv_val[ 0 ] = '\0'; +- mech->bv_val++; ++ if ( id->bv_val[1] == '.' ) { ++ id->bv_val[1] = '\0'; ++ mech->bv_val = id->bv_val + 2; + mech->bv_len = user->bv_val - mech->bv_val - 1; + + realm->bv_val = ber_bvchr( mech, '/' ); +@@ -172,6 +171,7 @@ int slap_parse_user( struct berval *id, struct berval *user, + } + + } else { ++ BER_BVZERO( mech ); + BER_BVZERO( realm ); + } + +-- +2.30.0 + diff --git a/0220-ITS-9423-ldap_X509dn2bv-check-for-invalid-BER-after-.patch b/0220-ITS-9423-ldap_X509dn2bv-check-for-invalid-BER-after-.patch new file mode 100644 index 0000000..0149ae1 --- /dev/null +++ b/0220-ITS-9423-ldap_X509dn2bv-check-for-invalid-BER-after-.patch @@ -0,0 +1,48 @@ +From bd843f03d4137756b1d1ba0695cb583fbe91d905 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Sun, 13 Dec 2020 21:48:45 +0000 +Subject: [PATCH 220/224] ITS#9423 ldap_X509dn2bv: check for invalid BER after + RDN count + +--- + libraries/libldap/tls2.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c +index d25c190ea..c642469d9 100644 +--- a/libraries/libldap/tls2.c ++++ b/libraries/libldap/tls2.c +@@ -1220,6 +1220,12 @@ ldap_X509dn2bv( void *x509_name, struct berval *bv, LDAPDN_rewrite_func *func, + } + } + ++ /* Rewind and prepare to extract */ ++ ber_rewind( ber ); ++ tag = ber_first_element( ber, &len, &dn_end ); ++ if ( tag == LBER_DEFAULT ) ++ return LDAP_DECODING_ERROR; ++ + /* Allocate the DN/RDN/AVA stuff as a single block */ + dnsize = sizeof(LDAPRDN) * (nrdns+1); + dnsize += sizeof(LDAPAVA *) * (navas+nrdns); +@@ -1231,16 +1237,12 @@ ldap_X509dn2bv( void *x509_name, struct berval *bv, LDAPDN_rewrite_func *func, + } else { + newDN = (LDAPDN)(char *)ptrs; + } +- ++ + newDN[nrdns] = NULL; + newRDN = (LDAPRDN)(newDN + nrdns+1); + newAVA = (LDAPAVA *)(newRDN + navas + nrdns); + baseAVA = newAVA; + +- /* Rewind and start extracting */ +- ber_rewind( ber ); +- +- tag = ber_first_element( ber, &len, &dn_end ); + for ( i = nrdns - 1; i >= 0; i-- ) { + newDN[i] = newRDN; + +-- +2.30.0 + diff --git a/0221-ITS-9424-fix-serialNumberAndIssuerSerialCheck.patch b/0221-ITS-9424-fix-serialNumberAndIssuerSerialCheck.patch new file mode 100644 index 0000000..89e036d --- /dev/null +++ b/0221-ITS-9424-fix-serialNumberAndIssuerSerialCheck.patch @@ -0,0 +1,25 @@ +From a1b3d529c7cb26ca94ee4450a55773130c6ed9a4 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Mon, 14 Dec 2020 19:03:27 +0000 +Subject: [PATCH 221/224] ITS#9424 fix serialNumberAndIssuerSerialCheck + +--- + servers/slapd/schema_init.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c +index f9200d362..00f0d3b8c 100644 +--- a/servers/slapd/schema_init.c ++++ b/servers/slapd/schema_init.c +@@ -4291,7 +4291,7 @@ serialNumberAndIssuerSerialCheck( + if ( in->bv_len < 3 ) return LDAP_INVALID_SYNTAX; + + /* no old format */ +- if ( in->bv_val[0] != '{' && in->bv_val[in->bv_len-1] != '}' ) return LDAP_INVALID_SYNTAX; ++ if ( in->bv_val[0] != '{' || in->bv_val[in->bv_len-1] != '}' ) return LDAP_INVALID_SYNTAX; + + x.bv_val++; + x.bv_len -= 2; +-- +2.30.0 + diff --git a/0222-ITS-9425-add-more-checks-to-ldap_X509dn2bv.patch b/0222-ITS-9425-add-more-checks-to-ldap_X509dn2bv.patch new file mode 100644 index 0000000..672fa1e --- /dev/null +++ b/0222-ITS-9425-add-more-checks-to-ldap_X509dn2bv.patch @@ -0,0 +1,45 @@ +From 959971b245f1676a2aa4d25d3a1d1898eda5b0a7 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Mon, 14 Dec 2020 20:05:44 +0000 +Subject: [PATCH 222/224] ITS#9425 add more checks to ldap_X509dn2bv + +--- + libraries/libldap/tls2.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c +index c642469d9..16c9d0487 100644 +--- a/libraries/libldap/tls2.c ++++ b/libraries/libldap/tls2.c +@@ -1214,6 +1214,8 @@ ldap_X509dn2bv( void *x509_name, struct berval *bv, LDAPDN_rewrite_func *func, + for ( tag = ber_first_element( ber, &len, &rdn_end ); + tag == LBER_SEQUENCE; + tag = ber_next_element( ber, &len, rdn_end )) { ++ if ( rdn_end > dn_end ) ++ return LDAP_DECODING_ERROR; + tag = ber_skip_tag( ber, &len ); + ber_skip_data( ber, len ); + navas++; +@@ -1223,7 +1225,7 @@ ldap_X509dn2bv( void *x509_name, struct berval *bv, LDAPDN_rewrite_func *func, + /* Rewind and prepare to extract */ + ber_rewind( ber ); + tag = ber_first_element( ber, &len, &dn_end ); +- if ( tag == LBER_DEFAULT ) ++ if ( tag != LBER_SET ) + return LDAP_DECODING_ERROR; + + /* Allocate the DN/RDN/AVA stuff as a single block */ +@@ -1336,6 +1338,10 @@ allocd: + /* X.690 bitString value converted to RFC4517 Bit String */ + rc = der_to_ldap_BitString( &Val, &newAVA->la_value ); + goto allocd; ++ case LBER_DEFAULT: ++ /* decode error */ ++ rc = LDAP_DECODING_ERROR; ++ goto nomem; + default: + /* Not a string type at all */ + newAVA->la_flags = 0; +-- +2.30.0 + diff --git a/0223-ITS-9427-fix-issuerAndThisUpdateCheck.patch b/0223-ITS-9427-fix-issuerAndThisUpdateCheck.patch new file mode 100644 index 0000000..b675182 --- /dev/null +++ b/0223-ITS-9427-fix-issuerAndThisUpdateCheck.patch @@ -0,0 +1,25 @@ +From 4b2578c5b2cdb4563c53bda3479839a255261750 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Wed, 16 Dec 2020 18:52:42 +0000 +Subject: [PATCH 223/224] ITS#9427 fix issuerAndThisUpdateCheck + +--- + servers/slapd/schema_init.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c +index 00f0d3b8c..d0a2ebd3d 100644 +--- a/servers/slapd/schema_init.c ++++ b/servers/slapd/schema_init.c +@@ -3799,7 +3799,7 @@ issuerAndThisUpdateCheck( + + if ( in->bv_len < STRLENOF( "{issuer \"\",thisUpdate \"YYMMDDhhmmssZ\"}" ) ) return LDAP_INVALID_SYNTAX; + +- if ( in->bv_val[0] != '{' && in->bv_val[in->bv_len-1] != '}' ) { ++ if ( in->bv_val[0] != '{' || in->bv_val[in->bv_len-1] != '}' ) { + return LDAP_INVALID_SYNTAX; + } + +-- +2.30.0 + diff --git a/0224-ITS-9428-fix-cancel-exop.patch b/0224-ITS-9428-fix-cancel-exop.patch new file mode 100644 index 0000000..5b23fa4 --- /dev/null +++ b/0224-ITS-9428-fix-cancel-exop.patch @@ -0,0 +1,28 @@ +From 94ec55f8ad7f71d820906b9a2b18f42c06980fb3 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Sun, 20 Dec 2020 21:31:15 +0000 +Subject: [PATCH 224/224] ITS#9428 fix cancel exop + +--- + servers/slapd/cancel.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/servers/slapd/cancel.c b/servers/slapd/cancel.c +index a7bbb5350..822c00965 100644 +--- a/servers/slapd/cancel.c ++++ b/servers/slapd/cancel.c +@@ -64,6 +64,11 @@ int cancel_extop( Operation *op, SlapReply *rs ) + return LDAP_PROTOCOL_ERROR; + } + ++ if ( opid == op->o_msgid ) { ++ op->o_cancel = SLAP_CANCEL_DONE; ++ return LDAP_SUCCESS; ++ } ++ + ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); + + if ( op->o_abandon ) { +-- +2.30.0 + diff --git a/0225-ITS-8625-Separate-Avlnode-and-TAvlnode-types.patch b/0225-ITS-8625-Separate-Avlnode-and-TAvlnode-types.patch new file mode 100644 index 0000000..396c063 --- /dev/null +++ b/0225-ITS-8625-Separate-Avlnode-and-TAvlnode-types.patch @@ -0,0 +1,417 @@ +From 60e0f25d7c0b09023118577acb973d664c8469b0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= +Date: Tue, 28 Mar 2017 15:32:27 +0100 +Subject: [PATCH 225/230] ITS#8625 Separate Avlnode and TAvlnode types + +Switch AVL_CHILD/AVL_THREAD values and set Avlnode bits to AVL_CHILD for +better compatibility between avl and tavl as suggested by Howard. +--- + include/avl.h | 39 ++++++++++++++++----------- + libraries/liblutil/avl.c | 2 ++ + libraries/liblutil/tavl.c | 40 ++++++++++++++-------------- + libraries/liblutil/testtavl.c | 10 +++---- + servers/slapd/back-mdb/back-mdb.h | 2 +- + servers/slapd/back-mdb/tools.c | 4 +-- + servers/slapd/overlays/pcache.c | 6 ++--- + servers/slapd/overlays/sssvlv.c | 12 ++++----- + servers/slapd/overlays/translucent.c | 4 +-- + 9 files changed, 64 insertions(+), 55 deletions(-) + +diff --git a/include/avl.h b/include/avl.h +index 4c9efecb6..e811648a7 100644 +--- a/include/avl.h ++++ b/include/avl.h +@@ -50,9 +50,16 @@ struct avlnode { + #define avl_lbit avl_bits[0] + #define avl_rbit avl_bits[1] + +-#ifdef AVL_INTERNAL ++typedef struct tavlnode TAvlnode; + +-#define NULLAVL ((Avlnode *) NULL) ++struct tavlnode { ++ void* avl_data; ++ struct tavlnode *avl_link[2]; ++ char avl_bits[2]; ++ signed char avl_bf; ++}; ++ ++#ifdef AVL_INTERNAL + + /* balance factor values */ + #define LH (-1) +@@ -62,8 +69,8 @@ struct avlnode { + #define avl_bf2str(bf) ((bf) == -1 ? "LH" : (bf) == 0 ? "EH" : (bf) == 1 ? "RH" : "(unknown)" ) + + /* thread bits */ +-#define AVL_THREAD 0 +-#define AVL_CHILD 1 ++#define AVL_CHILD 0 ++#define AVL_THREAD 1 + + /* avl routines */ + #define avl_getone(x) ((x) == 0 ? 0 : (x)->avl_data) +@@ -120,31 +127,31 @@ LDAP_AVL_F( int ) + avl_prefixapply LDAP_P((Avlnode *, void*, AVL_CMP, void*, AVL_CMP, void*, int)); + + LDAP_AVL_F( int ) +-tavl_free LDAP_P(( Avlnode *root, AVL_FREE dfree )); ++tavl_free LDAP_P(( TAvlnode *root, AVL_FREE dfree )); + + LDAP_AVL_F( int ) +-tavl_insert LDAP_P((Avlnode **, void*, AVL_CMP, AVL_DUP)); ++tavl_insert LDAP_P((TAvlnode **, void*, AVL_CMP, AVL_DUP)); + + LDAP_AVL_F( void* ) +-tavl_delete LDAP_P((Avlnode **, void*, AVL_CMP)); ++tavl_delete LDAP_P((TAvlnode **, void*, AVL_CMP)); + + LDAP_AVL_F( void* ) +-tavl_find LDAP_P((Avlnode *, const void*, AVL_CMP)); ++tavl_find LDAP_P((TAvlnode *, const void*, AVL_CMP)); + +-LDAP_AVL_F( Avlnode* ) +-tavl_find2 LDAP_P((Avlnode *, const void*, AVL_CMP)); ++LDAP_AVL_F( TAvlnode* ) ++tavl_find2 LDAP_P((TAvlnode *, const void*, AVL_CMP)); + +-LDAP_AVL_F( Avlnode* ) +-tavl_find3 LDAP_P((Avlnode *, const void*, AVL_CMP, int *ret)); ++LDAP_AVL_F( TAvlnode* ) ++tavl_find3 LDAP_P((TAvlnode *, const void*, AVL_CMP, int *ret)); + + #define TAVL_DIR_LEFT 0 + #define TAVL_DIR_RIGHT 1 + +-LDAP_AVL_F( Avlnode* ) +-tavl_end LDAP_P((Avlnode *, int direction )); ++LDAP_AVL_F( TAvlnode* ) ++tavl_end LDAP_P((TAvlnode *, int direction)); + +-LDAP_AVL_F( Avlnode* ) +-tavl_next LDAP_P((Avlnode *, int direction )); ++LDAP_AVL_F( TAvlnode* ) ++tavl_next LDAP_P((TAvlnode *, int direction)); + + /* apply traversal types */ + #define AVL_PREORDER 1 +diff --git a/libraries/liblutil/avl.c b/libraries/liblutil/avl.c +index 8cd88b132..62747a2d4 100644 +--- a/libraries/liblutil/avl.c ++++ b/libraries/liblutil/avl.c +@@ -81,6 +81,7 @@ avl_insert( Avlnode ** root, void *data, AVL_CMP fcmp, AVL_DUP fdup ) + } + r->avl_link[0] = r->avl_link[1] = NULL; + r->avl_data = data; ++ r->avl_bits[0] = r->avl_bits[1] = AVL_CHILD; + r->avl_bf = EH; + *root = r; + +@@ -105,6 +106,7 @@ avl_insert( Avlnode ** root, void *data, AVL_CMP fcmp, AVL_DUP fdup ) + } + q->avl_link[0] = q->avl_link[1] = NULL; + q->avl_data = data; ++ q->avl_bits[0] = q->avl_bits[1] = AVL_CHILD; + q->avl_bf = EH; + + p->avl_link[cmp] = q; +diff --git a/libraries/liblutil/tavl.c b/libraries/liblutil/tavl.c +index 320ffaa26..0a9e49bc7 100644 +--- a/libraries/liblutil/tavl.c ++++ b/libraries/liblutil/tavl.c +@@ -60,13 +60,13 @@ static const int avl_bfs[] = {LH, RH}; + * NOTE: this routine may malloc memory + */ + int +-tavl_insert( Avlnode ** root, void *data, AVL_CMP fcmp, AVL_DUP fdup ) ++tavl_insert( TAvlnode ** root, void *data, AVL_CMP fcmp, AVL_DUP fdup ) + { +- Avlnode *t, *p, *s, *q, *r; ++ TAvlnode *t, *p, *s, *q, *r; + int a, cmp, ncmp; + + if ( *root == NULL ) { +- if (( r = (Avlnode *) ber_memalloc( sizeof( Avlnode ))) == NULL ) { ++ if (( r = (TAvlnode *) ber_memalloc( sizeof( TAvlnode ))) == NULL ) { + return( -1 ); + } + r->avl_link[0] = r->avl_link[1] = NULL; +@@ -91,7 +91,7 @@ tavl_insert( Avlnode ** root, void *data, AVL_CMP fcmp, AVL_DUP fdup ) + q = avl_child( p, cmp ); + if (q == NULL) { + /* insert */ +- if (( q = (Avlnode *) ber_memalloc( sizeof( Avlnode ))) == NULL ) { ++ if (( q = (TAvlnode *) ber_memalloc( sizeof( TAvlnode ))) == NULL ) { + return( -1 ); + } + q->avl_link[cmp] = p->avl_link[cmp]; +@@ -187,13 +187,13 @@ tavl_insert( Avlnode ** root, void *data, AVL_CMP fcmp, AVL_DUP fdup ) + } + + void* +-tavl_delete( Avlnode **root, void* data, AVL_CMP fcmp ) ++tavl_delete( TAvlnode **root, void* data, AVL_CMP fcmp ) + { +- Avlnode *p, *q, *r, *top; ++ TAvlnode *p, *q, *r, *top; + int side, side_bf, shorter, nside = -1; + + /* parent stack */ +- Avlnode *pptr[MAX_TREE_DEPTH]; ++ TAvlnode *pptr[MAX_TREE_DEPTH]; + unsigned char pdir[MAX_TREE_DEPTH]; + int depth = 0; + +@@ -424,7 +424,7 @@ tavl_delete( Avlnode **root, void* data, AVL_CMP fcmp ) + */ + + int +-tavl_free( Avlnode *root, AVL_FREE dfree ) ++tavl_free( TAvlnode *root, AVL_FREE dfree ) + { + int nleft, nright; + +@@ -450,15 +450,15 @@ tavl_free( Avlnode *root, AVL_FREE dfree ) + */ + + /* +- * tavl_find2 - returns Avlnode instead of data pointer. +- * tavl_find3 - as above, but returns Avlnode even if no match is found. ++ * tavl_find2 - returns TAvlnode instead of data pointer. ++ * tavl_find3 - as above, but returns TAvlnode even if no match is found. + * also set *ret = last comparison result, or -1 if root == NULL. + */ +-Avlnode * +-tavl_find3( Avlnode *root, const void *data, AVL_CMP fcmp, int *ret ) ++TAvlnode * ++tavl_find3( TAvlnode *root, const void *data, AVL_CMP fcmp, int *ret ) + { + int cmp = -1, dir; +- Avlnode *prev = root; ++ TAvlnode *prev = root; + + while ( root != 0 && (cmp = (*fcmp)( data, root->avl_data )) != 0 ) { + prev = root; +@@ -469,8 +469,8 @@ tavl_find3( Avlnode *root, const void *data, AVL_CMP fcmp, int *ret ) + return root ? root : prev; + } + +-Avlnode * +-tavl_find2( Avlnode *root, const void *data, AVL_CMP fcmp ) ++TAvlnode * ++tavl_find2( TAvlnode *root, const void *data, AVL_CMP fcmp ) + { + int cmp; + +@@ -482,7 +482,7 @@ tavl_find2( Avlnode *root, const void *data, AVL_CMP fcmp ) + } + + void* +-tavl_find( Avlnode *root, const void* data, AVL_CMP fcmp ) ++tavl_find( TAvlnode *root, const void* data, AVL_CMP fcmp ) + { + int cmp; + +@@ -495,8 +495,8 @@ tavl_find( Avlnode *root, const void* data, AVL_CMP fcmp ) + } + + /* Return the leftmost or rightmost node in the tree */ +-Avlnode * +-tavl_end( Avlnode *root, int dir ) ++TAvlnode * ++tavl_end( TAvlnode *root, int dir ) + { + if ( root ) { + while ( root->avl_bits[dir] == AVL_CHILD ) +@@ -506,8 +506,8 @@ tavl_end( Avlnode *root, int dir ) + } + + /* Return the next node in the given direction */ +-Avlnode * +-tavl_next( Avlnode *root, int dir ) ++TAvlnode * ++tavl_next( TAvlnode *root, int dir ) + { + if ( root ) { + int c = root->avl_bits[dir]; +diff --git a/libraries/liblutil/testtavl.c b/libraries/liblutil/testtavl.c +index 8374f3ec7..9bd621c0e 100644 +--- a/libraries/liblutil/testtavl.c ++++ b/libraries/liblutil/testtavl.c +@@ -39,14 +39,14 @@ + #define AVL_INTERNAL + #include "avl.h" + +-static void ravl_print LDAP_P(( Avlnode *root, int depth, int thread )); +-static void myprint LDAP_P(( Avlnode *root )); ++static void ravl_print LDAP_P(( TAvlnode *root, int depth, int thread )); ++static void myprint LDAP_P(( TAvlnode *root )); + static int avl_strcmp LDAP_P(( const void *s, const void *t )); + + int + main( int argc, char **argv ) + { +- Avlnode *tree = NULL, *n; ++ TAvlnode *tree = NULL, *n; + char command[ 10 ]; + char name[ 80 ]; + char *p; +@@ -115,7 +115,7 @@ main( int argc, char **argv ) + static const char bfc_array[] = "\\-/"; + static const char *bfcs = bfc_array+1; + +-static void ravl_print( Avlnode *root, int depth, int thread ) ++static void ravl_print( TAvlnode *root, int depth, int thread ) + { + int i; + +@@ -140,7 +140,7 @@ static void ravl_print( Avlnode *root, int depth, int thread ) + ravl_print( root->avl_link[0], depth+1, root->avl_bits[0] == AVL_THREAD ); + } + +-static void myprint( Avlnode *root ) ++static void myprint( TAvlnode *root ) + { + printf( "********\n" ); + +diff --git a/servers/slapd/back-mdb/back-mdb.h b/servers/slapd/back-mdb/back-mdb.h +index b27106977..578c7e7f3 100644 +--- a/servers/slapd/back-mdb/back-mdb.h ++++ b/servers/slapd/back-mdb/back-mdb.h +@@ -150,7 +150,7 @@ typedef struct mdb_attrinfo { + #ifdef LDAP_COMP_MATCH + ComponentReference* ai_cr; /*component indexing*/ + #endif +- Avlnode *ai_root; /* for tools */ ++ TAvlnode *ai_root; /* for tools */ + void *ai_flist; /* for tools */ + void *ai_clist; /* for tools */ + MDB_cursor *ai_cursor; /* for tools */ +diff --git a/servers/slapd/back-mdb/tools.c b/servers/slapd/back-mdb/tools.c +index bb56e65e0..baa3ab289 100644 +--- a/servers/slapd/back-mdb/tools.c ++++ b/servers/slapd/back-mdb/tools.c +@@ -1208,7 +1208,7 @@ int mdb_tool_idl_add( + dbi = ai->ai_dbi; + for (i=0; keys[i].bv_val; i++) { + itmp.kstr = keys[i]; +- ic = tavl_find( (Avlnode *)ai->ai_root, &itmp, mdb_tool_idl_cmp ); ++ ic = tavl_find( ai->ai_root, &itmp, mdb_tool_idl_cmp ); + + /* No entry yet, create one */ + if ( !ic ) { +@@ -1230,7 +1230,7 @@ int mdb_tool_idl_add( + ic->count = 0; + ic->offset = 0; + ic->flags = 0; +- tavl_insert( (Avlnode **)&ai->ai_root, ic, mdb_tool_idl_cmp, ++ tavl_insert( &ai->ai_root, ic, mdb_tool_idl_cmp, + avl_dup_error ); + + /* load existing key count here */ +diff --git a/servers/slapd/overlays/pcache.c b/servers/slapd/overlays/pcache.c +index 166ca48a2..36c26af58 100644 +--- a/servers/slapd/overlays/pcache.c ++++ b/servers/slapd/overlays/pcache.c +@@ -67,7 +67,7 @@ typedef struct Query_s { + struct query_template_s; + + typedef struct Qbase_s { +- Avlnode *scopes[4]; /* threaded AVL trees of cached queries */ ++ TAvlnode *scopes[4]; /* threaded AVL trees of cached queries */ + struct berval base; + int queries; + } Qbase; +@@ -1274,14 +1274,14 @@ typedef struct fstack { + } fstack; + + static CachedQuery * +-find_filter( Operation *op, Avlnode *root, Filter *inputf, Filter *first ) ++find_filter( Operation *op, TAvlnode *root, Filter *inputf, Filter *first ) + { + Filter* fs; + Filter* fi; + MatchingRule* mrule = NULL; + int res=0, eqpass= 0; + int ret, rc, dir; +- Avlnode *ptr; ++ TAvlnode *ptr; + CachedQuery cq, *qc; + fstack *stack = NULL, *fsp; + +diff --git a/servers/slapd/overlays/sssvlv.c b/servers/slapd/overlays/sssvlv.c +index dff2929a0..97d3b99f5 100644 +--- a/servers/slapd/overlays/sssvlv.c ++++ b/servers/slapd/overlays/sssvlv.c +@@ -105,7 +105,7 @@ typedef struct sssvlv_info + + typedef struct sort_op + { +- Avlnode *so_tree; ++ TAvlnode *so_tree; + sort_ctrl *so_ctrl; + sssvlv_info *so_info; + int so_paged; +@@ -409,7 +409,7 @@ static void free_sort_op( Connection *conn, sort_op *so ) + if ( sess_id > -1 ){ + if ( so->so_tree ) { + if ( so->so_paged > SLAP_CONTROL_IGNORED ) { +- Avlnode *cur_node, *next_node; ++ TAvlnode *cur_node, *next_node; + cur_node = so->so_tree; + while ( cur_node ) { + next_node = tavl_next( cur_node, TAVL_DIR_RIGHT ); +@@ -447,7 +447,7 @@ static void send_list( + SlapReply *rs, + sort_op *so) + { +- Avlnode *cur_node, *tmp_node; ++ TAvlnode *cur_node, *tmp_node; + vlv_ctrl *vc = op->o_controls[vlv_cid]; + int i, j, dir, rc; + BackendDB *be; +@@ -600,8 +600,8 @@ range_err: + + static void send_page( Operation *op, SlapReply *rs, sort_op *so ) + { +- Avlnode *cur_node = so->so_tree; +- Avlnode *next_node = NULL; ++ TAvlnode *cur_node = so->so_tree; ++ TAvlnode *next_node = NULL; + BackendDB *be = op->o_bd; + Entry *e; + int rc; +@@ -665,7 +665,7 @@ static void send_entry( + send_list( op, rs, so ); + } else { + /* Get the first node to send */ +- Avlnode *start_node = tavl_end(so->so_tree, TAVL_DIR_LEFT); ++ TAvlnode *start_node = tavl_end(so->so_tree, TAVL_DIR_LEFT); + so->so_tree = start_node; + + if ( so->so_paged <= SLAP_CONTROL_IGNORED ) { +diff --git a/servers/slapd/overlays/translucent.c b/servers/slapd/overlays/translucent.c +index 959917039..372f05383 100644 +--- a/servers/slapd/overlays/translucent.c ++++ b/servers/slapd/overlays/translucent.c +@@ -766,7 +766,7 @@ typedef struct trans_ctx { + BackendDB *db; + slap_overinst *on; + Filter *orig; +- Avlnode *list; ++ TAvlnode *list; + int step; + int slimit; + AttributeName *attrs; +@@ -1135,7 +1135,7 @@ static int translucent_search(Operation *op, SlapReply *rs) { + /* Send out anything remaining on the list and finish */ + if ( tc.step & USE_LIST ) { + if ( tc.list ) { +- Avlnode *av; ++ TAvlnode *av; + + av = tavl_end( tc.list, TAVL_DIR_LEFT ); + while ( av ) { +-- +2.30.1 + diff --git a/0226-ITS-9197-back-ldap-added-task-that-prunes-expired-co.patch b/0226-ITS-9197-back-ldap-added-task-that-prunes-expired-co.patch new file mode 100644 index 0000000..635f266 --- /dev/null +++ b/0226-ITS-9197-back-ldap-added-task-that-prunes-expired-co.patch @@ -0,0 +1,1460 @@ +From 8ee47ce0fdb1e6796fdf46c3eb7bd453933c3a6b Mon Sep 17 00:00:00 2001 +From: Tero Saarni +Date: Wed, 24 Feb 2021 22:07:48 +0000 +Subject: [PATCH 226/230] ITS#9197 back-ldap: added task that prunes expired + connections + +--- + servers/slapd/back-ldap/back-ldap.h | 3 +- + servers/slapd/back-ldap/bind.c | 206 +++++++++++++++--- + servers/slapd/back-ldap/chain.c | 141 +++++------- + servers/slapd/back-ldap/config.c | 2 +- + servers/slapd/back-ldap/distproc.c | 114 +++++----- + servers/slapd/back-ldap/init.c | 16 +- + servers/slapd/back-ldap/monitor.c | 10 +- + servers/slapd/back-ldap/unbind.c | 2 +- + servers/slapd/back-meta/bind.c | 4 +- + servers/slapd/back-meta/conn.c | 14 +- + servers/slapd/back-meta/init.c | 2 +- + servers/slapd/back-meta/unbind.c | 2 +- + tests/data/slapd-proxytimeout.conf | 71 ++++++ + tests/scripts/conf.sh | 1 + + tests/scripts/defines.sh | 1 + + tests/scripts/test079-proxy-timeout | 324 ++++++++++++++++++++++++++++ + 16 files changed, 716 insertions(+), 197 deletions(-) + create mode 100644 tests/data/slapd-proxytimeout.conf + create mode 100644 tests/scripts/test079-proxy-timeout + +diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h +index c4639e4f4..1f5054cf3 100644 +--- a/servers/slapd/back-ldap/back-ldap.h ++++ b/servers/slapd/back-ldap/back-ldap.h +@@ -180,7 +180,7 @@ typedef struct ldapconn_t { + + typedef struct ldap_avl_info_t { + ldap_pvt_thread_mutex_t lai_mutex; +- Avlnode *lai_tree; ++ TAvlnode *lai_tree; + } ldap_avl_info_t; + + typedef struct slap_retry_info_t { +@@ -414,6 +414,7 @@ typedef struct ldapinfo_t { + + ldap_pvt_thread_mutex_t li_counter_mutex; + ldap_pvt_mp_t li_ops_completed[SLAP_OP_LAST]; ++ struct re_s* li_conn_expire_task; + } ldapinfo_t; + + #define LDAP_ERR_OK(err) ((err) == LDAP_SUCCESS || (err) == LDAP_COMPARE_FALSE || (err) == LDAP_COMPARE_TRUE) +diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c +index 998b2c796..1f9cbf185 100644 +--- a/servers/slapd/back-ldap/bind.c ++++ b/servers/slapd/back-ldap/bind.c +@@ -34,6 +34,7 @@ + #include "back-ldap.h" + #include "lutil.h" + #include "lutil_ldap.h" ++#include "ldap_rq.h" + + #define LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ "2.16.840.1.113730.3.4.12" + +@@ -60,7 +61,7 @@ static const struct { + }; + + static void +-ldap_back_conn_print( ldapconn_t *lc, const char *avlstr ) ++ldap_back_conn_print( ldapconn_t *lc ) + { + char buf[ SLAP_TEXT_BUFLEN ]; + char fbuf[ sizeof("BAPTIENSC") ]; +@@ -77,31 +78,10 @@ ldap_back_conn_print( ldapconn_t *lc, const char *avlstr ) + } + fbuf[i] = '\0'; + +- fprintf( stderr, "lc=%p %s %s flags=0x%08x (%s)\n", +- (void *)lc, buf, avlstr, lc->lc_lcflags, fbuf ); ++ fprintf( stderr, "lc=%p %s flags=0x%08x (%s)\n", ++ (void *)lc, buf, lc->lc_lcflags, fbuf ); + } + +-static void +-ldap_back_ravl_print( Avlnode *root, int depth ) +-{ +- int i; +- ldapconn_t *lc; +- +- if ( root == 0 ) { +- return; +- } +- +- ldap_back_ravl_print( root->avl_right, depth+1 ); +- +- for ( i = 0; i < depth; i++ ) { +- fprintf( stderr, "-" ); +- } +- +- lc = root->avl_data; +- ldap_back_conn_print( lc, avl_bf2str( root->avl_bf ) ); +- +- ldap_back_ravl_print( root->avl_left, depth + 1 ); +-} + + static char* priv2str[] = { + "privileged", +@@ -129,7 +109,7 @@ ldap_back_print_conntree( ldapinfo_t *li, char *msg ) + LDAP_TAILQ_FOREACH( lc, &li->li_conn_priv[ c ].lic_priv, lc_q ) + { + fprintf( stderr, " [%d] ", i ); +- ldap_back_conn_print( lc, "" ); ++ ldap_back_conn_print( lc ); + i++; + } + } +@@ -138,7 +118,11 @@ ldap_back_print_conntree( ldapinfo_t *li, char *msg ) + fprintf( stderr, "\t(empty)\n" ); + + } else { +- ldap_back_ravl_print( li->li_conninfo.lai_tree, 0 ); ++ TAvlnode *edge = tavl_end( li->li_conninfo.lai_tree, TAVL_DIR_LEFT ); ++ while ( edge ) { ++ ldap_back_conn_print( (ldapconn_t *)edge->avl_data ); ++ edge = tavl_next( edge, TAVL_DIR_RIGHT ); ++ } + } + + fprintf( stderr, "<======== %s\n", msg ); +@@ -167,6 +151,12 @@ ldap_back_prepare_conn( ldapconn_t *lc, Operation *op, SlapReply *rs, + static int + ldap_back_conndnlc_cmp( const void *c1, const void *c2 ); + ++static void ++ldap_back_conn_prune( ldapinfo_t *li ); ++ ++static void ++ldap_back_schedule_conn_expiry( ldapinfo_t *li, ldapconn_t *lc ); ++ + ldapconn_t * + ldap_back_conn_delete( ldapinfo_t *li, ldapconn_t *lc ) + { +@@ -189,7 +179,7 @@ ldap_back_conn_delete( ldapinfo_t *li, ldapconn_t *lc ) + + if ( LDAP_BACK_CONN_CACHED( lc ) ) { + assert( !LDAP_BACK_CONN_TAINTED( lc ) ); +- tmplc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc, ++ tmplc = tavl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc, + ldap_back_conndnlc_cmp ); + assert( tmplc == lc ); + LDAP_BACK_CONN_CACHED_CLEAR( lc ); +@@ -343,7 +333,7 @@ retry_lock:; + + /* delete all cached connections with the current connection */ + if ( LDAP_BACK_SINGLECONN( li ) ) { +- while ( ( tmplc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc, ldap_back_conn_cmp ) ) != NULL ) ++ while ( ( tmplc = tavl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc, ldap_back_conn_cmp ) ) != NULL ) + { + assert( !LDAP_BACK_PCONN_ISPRIV( lc ) ); + Debug( LDAP_DEBUG_TRACE, +@@ -371,7 +361,7 @@ retry_lock:; + if ( be_isroot_dn( op->o_bd, &op->o_req_ndn ) ) { + LDAP_BACK_PCONN_ROOTDN_SET( lc, op ); + } +- lerr = avl_insert( &li->li_conninfo.lai_tree, (caddr_t)lc, ++ lerr = tavl_insert( &li->li_conninfo.lai_tree, (caddr_t)lc, + ldap_back_conndn_cmp, ldap_back_conndn_dup ); + } + +@@ -938,7 +928,7 @@ retry_lock: + } else { + + /* Searches for a ldapconn in the avl tree */ +- lc = (ldapconn_t *)avl_find( li->li_conninfo.lai_tree, ++ lc = (ldapconn_t *)tavl_find( li->li_conninfo.lai_tree, + (caddr_t)&lc_curr, ldap_back_conndn_cmp ); + } + +@@ -1084,7 +1074,7 @@ retry_lock: + rs->sr_err = 0; + + } else { +- rs->sr_err = avl_insert( &li->li_conninfo.lai_tree, (caddr_t)lc, ++ rs->sr_err = tavl_insert( &li->li_conninfo.lai_tree, (caddr_t)lc, + ldap_back_conndn_cmp, ldap_back_conndn_dup ); + LDAP_BACK_CONN_CACHED_SET( lc ); + } +@@ -1137,6 +1127,7 @@ retry_lock: + return NULL; + } + } ++ ldap_back_schedule_conn_expiry( li, lc ); + + } else { + int expiring = 0; +@@ -3066,3 +3057,156 @@ ldap_back_connid2str( const ldapconn_base_t *lc, char *buf, ber_len_t buflen ) + + return len; + } ++ ++void * ++ldap_back_conn_expire_fn( void *ctx, void *arg ) ++{ ++ struct re_s *rtask = arg; ++ ldapinfo_t *li = (ldapinfo_t *)rtask->arg; ++ ldap_back_conn_prune( li ); ++ ++ return NULL; ++} ++ ++/* Pick which expires first: connection TTL or idle timeout */ ++static time_t ++ldap_back_conn_expire_time( ldapinfo_t *li, ldapconn_t *lc) { ++ if ( li->li_conn_ttl != 0 && li->li_idle_timeout != 0 ) { ++ return ( lc->lc_create_time + li->li_conn_ttl ) < ( lc->lc_time + li->li_idle_timeout ) ? ++ ( lc->lc_create_time + li->li_conn_ttl ) : ( lc->lc_time + li->li_idle_timeout ); ++ } else if ( li->li_conn_ttl != 0 ) { ++ return lc->lc_create_time + li->li_conn_ttl; ++ } else if ( li->li_idle_timeout != 0 ) { ++ return lc->lc_time + li->li_idle_timeout; ++ } ++ return -1; ++} ++ ++static void ++ldap_back_conn_prune( ldapinfo_t *li ) ++{ ++ time_t now = slap_get_time(); ++ time_t next_timeout = -1; /* -1 means uninitialized */ ++ TAvlnode *edge; ++ int c; ++ ++ /* ++ * Iterate though connections and close those that are pass the expiry time. ++ * Also calculate the time for next connection to to expire. ++ */ ++ ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); ++ ++ for ( c = LDAP_BACK_PCONN_FIRST; c < LDAP_BACK_PCONN_LAST; c++ ) { ++ ldapconn_t *lc = LDAP_TAILQ_FIRST( &li->li_conn_priv[ c ].lic_priv ); ++ ++ while ( lc ) { ++ ldapconn_t *next = LDAP_TAILQ_NEXT( lc, lc_q ); ++ time_t conn_expires = ldap_back_conn_expire_time( li, lc ); ++ ++ if ( now >= conn_expires ) { ++ if ( lc->lc_refcnt == 0 ) { ++ Debug( LDAP_DEBUG_TRACE, ++ "ldap_back_conn_prune: closing expired connection lc=%p\n", ++ lc, 0, 0 ); ++ ldap_back_freeconn( li, lc, 0 ); ++ } else { ++ Debug( LDAP_DEBUG_TRACE, ++ "ldap_back_conn_prune: tainting expired connection lc=%p\n", ++ lc, 0, 0 ); ++ LDAP_BACK_CONN_TAINTED_SET( lc ); ++ } ++ } else if ( next_timeout == -1 || conn_expires < next_timeout ) { ++ /* next_timeout was not yet initialized or current connection expires sooner */ ++ next_timeout = conn_expires; ++ } ++ ++ lc = next; ++ } ++ } ++ ++ edge = tavl_end( li->li_conninfo.lai_tree, TAVL_DIR_LEFT ); ++ while ( edge ) { ++ TAvlnode *next = tavl_next( edge, TAVL_DIR_RIGHT ); ++ ldapconn_t *lc = (ldapconn_t *)edge->avl_data; ++ time_t conn_expires = ldap_back_conn_expire_time( li, lc ); ++ ++ if ( now >= conn_expires ) { ++ if ( lc->lc_refcnt == 0 ) { ++ Debug( LDAP_DEBUG_TRACE, ++ "ldap_back_conn_prune: closing expired connection lc=%p\n", ++ lc, 0, 0 ); ++ ldap_back_freeconn( li, lc, 0 ); ++ } else { ++ Debug( LDAP_DEBUG_TRACE, ++ "ldap_back_conn_prune: tainting expired connection lc=%p\n", ++ lc, 0, 0 ); ++ LDAP_BACK_CONN_TAINTED_SET( lc ); ++ } ++ } else if ( next_timeout == -1 || conn_expires < next_timeout ) { ++ next_timeout = conn_expires; ++ } ++ ++ edge = next; ++ } ++ ++ ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); ++ ++ /* Reschedule for next timeout or cancel the task */ ++ ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); ++ if ( next_timeout > 0 ) { ++ if ( ldap_pvt_runqueue_isrunning( &slapd_rq, li->li_conn_expire_task ) ) { ++ ldap_pvt_runqueue_stoptask( &slapd_rq, li->li_conn_expire_task ); ++ } ++ li->li_conn_expire_task->interval.tv_sec = next_timeout - now; ++ ldap_pvt_runqueue_resched( &slapd_rq, li->li_conn_expire_task, 0 ); ++ ++ /* ++ * The thread that handles runqueue might have already processed all tasks ++ * before we insertered new task or rescheduled the existing task with new ++ * timeout period. Wake it up to ensure that the task will be picked up. ++ */ ++ slap_wake_listener(); ++ Debug( LDAP_DEBUG_TRACE, ++ "ldap_back_conn_prune: scheduled connection expiry timer to %ld sec\n", ++ li->li_conn_expire_task->interval.tv_sec, 0, 0 ); ++ } else if ( next_timeout == -1 && li->li_conn_expire_task != NULL ) { ++ if ( ldap_pvt_runqueue_isrunning( &slapd_rq, li->li_conn_expire_task ) ) { ++ ldap_pvt_runqueue_stoptask( &slapd_rq, li->li_conn_expire_task ); ++ } ++ ldap_pvt_runqueue_remove( &slapd_rq, li->li_conn_expire_task ); ++ li->li_conn_expire_task = NULL; ++ } ++ ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); ++ ++ return; ++} ++ ++static void ++ldap_back_schedule_conn_expiry( ldapinfo_t *li, ldapconn_t *lc ) { ++ /* Do nothing if timeouts are not set. */ ++ if ( li->li_conn_ttl == 0 && li->li_idle_timeout == 0 ) { ++ return; ++ } ++ ++ /* ++ * If connection expire task is not running, create it and schedule for ++ * timeout of this connection. ++ * ++ * If the task is already running, this connection cannot be next one ++ * to expire and therefore timeout does not need to be re-calculated. ++ */ ++ ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); ++ if ( li->li_conn_expire_task == NULL ) { ++ li->li_conn_expire_task = ldap_pvt_runqueue_insert( &slapd_rq, ++ ldap_back_conn_expire_time( li, lc ) - slap_get_time(), ++ ldap_back_conn_expire_fn, li, "ldap_back_conn_expire_fn", ++ "ldap_back_conn_expire_timer" ); ++ slap_wake_listener(); ++ Debug( LDAP_DEBUG_TRACE, ++ "ldap_back_conn_prune: scheduled connection expiry timer to %ld sec\n", ++ li->li_conn_expire_task->interval.tv_sec, 0, 0 ); ++ } ++ ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); ++ ++ return; ++} +\ No newline at end of file +diff --git a/servers/slapd/back-ldap/chain.c b/servers/slapd/back-ldap/chain.c +index eeceb4c66..643fce9cf 100644 +--- a/servers/slapd/back-ldap/chain.c ++++ b/servers/slapd/back-ldap/chain.c +@@ -556,7 +556,7 @@ Document: RFC 4511 + + /* Searches for a ldapinfo in the avl tree */ + ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex ); +- lip = (ldapinfo_t *)avl_find( lc->lc_lai.lai_tree, ++ lip = (ldapinfo_t *)tavl_find( lc->lc_lai.lai_tree, + (caddr_t)&li, ldap_chain_uri_cmp ); + ldap_pvt_thread_mutex_unlock( &lc->lc_lai.lai_mutex ); + +@@ -588,7 +588,7 @@ Document: RFC 4511 + + if ( LDAP_CHAIN_CACHE_URI( lc ) ) { + ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex ); +- if ( avl_insert( &lc->lc_lai.lai_tree, ++ if ( tavl_insert( &lc->lc_lai.lai_tree, + (caddr_t)lip, ldap_chain_uri_cmp, ldap_chain_uri_dup ) ) + { + /* someone just inserted another; +@@ -828,7 +828,7 @@ ldap_chain_search( + + /* Searches for a ldapinfo in the avl tree */ + ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex ); +- lip = (ldapinfo_t *)avl_find( lc->lc_lai.lai_tree, ++ lip = (ldapinfo_t *)tavl_find( lc->lc_lai.lai_tree, + (caddr_t)&li, ldap_chain_uri_cmp ); + ldap_pvt_thread_mutex_unlock( &lc->lc_lai.lai_mutex ); + +@@ -861,7 +861,7 @@ ldap_chain_search( + + if ( LDAP_CHAIN_CACHE_URI( lc ) ) { + ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex ); +- if ( avl_insert( &lc->lc_lai.lai_tree, ++ if ( tavl_insert( &lc->lc_lai.lai_tree, + (caddr_t)lip, ldap_chain_uri_cmp, ldap_chain_uri_dup ) ) + { + /* someone just inserted another; +@@ -1366,7 +1366,7 @@ fail: + if ( at ) { + li->li_uri = ch_strdup( at->a_vals[ 0 ].bv_val ); + value_add_one( &li->li_bvuri, &at->a_vals[ 0 ] ); +- if ( avl_insert( &lc->lc_lai.lai_tree, (caddr_t)li, ++ if ( tavl_insert( &lc->lc_lai.lai_tree, (caddr_t)li, + ldap_chain_uri_cmp, ldap_chain_uri_dup ) ) + { + Debug( LDAP_DEBUG_ANY, "slapd-chain: " +@@ -1389,34 +1389,27 @@ done:; + return rc; + } + +-typedef struct ldap_chain_cfadd_apply_t { +- Operation *op; +- SlapReply *rs; +- Entry *p; +- ConfigArgs *ca; +- int count; +-} ldap_chain_cfadd_apply_t; +- +-static int +-ldap_chain_cfadd_apply( void *datum, void *arg ) ++static void ++ldap_chain_cfadd_apply( ++ ldapinfo_t *li, ++ Operation *op, ++ SlapReply *rs, ++ Entry *p, ++ ConfigArgs *ca, ++ int count ) + { +- ldapinfo_t *li = (ldapinfo_t *)datum; +- ldap_chain_cfadd_apply_t *lca = (ldap_chain_cfadd_apply_t *)arg; +- + struct berval bv; + + /* FIXME: should not hardcode "olcDatabase" here */ +- bv.bv_len = snprintf( lca->ca->cr_msg, sizeof( lca->ca->cr_msg ), +- "olcDatabase={%d}%s", lca->count, lback->bi_type ); +- bv.bv_val = lca->ca->cr_msg; ++ bv.bv_len = snprintf( ca->cr_msg, sizeof( ca->cr_msg ), ++ "olcDatabase={%d}%s", count, lback->bi_type ); ++ bv.bv_val = ca->cr_msg; + +- lca->ca->be->be_private = (void *)li; +- config_build_entry( lca->op, lca->rs, lca->p->e_private, lca->ca, ++ ca->be->be_private = (void *)li; ++ config_build_entry( op, rs, p->e_private, ca, + &bv, lback->bi_cf_ocs, &chainocs[1] ); + +- lca->count++; +- +- return 0; ++ return; + } + + static int +@@ -1426,20 +1419,20 @@ chain_cfadd( Operation *op, SlapReply *rs, Entry *p, ConfigArgs *ca ) + slap_overinst *on = (slap_overinst *)pe->ce_bi; + ldap_chain_t *lc = (ldap_chain_t *)on->on_bi.bi_private; + void *priv = (void *)ca->be->be_private; ++ TAvlnode *edge; ++ int count = 0; + + if ( lback->bi_cf_ocs ) { +- ldap_chain_cfadd_apply_t lca = { 0 }; +- +- lca.op = op; +- lca.rs = rs; +- lca.p = p; +- lca.ca = ca; +- lca.count = 0; + +- (void)ldap_chain_cfadd_apply( (void *)lc->lc_common_li, (void *)&lca ); ++ ldap_chain_cfadd_apply( lc->lc_common_li, op, rs, p, ca, count++ ); + +- (void)avl_apply( lc->lc_lai.lai_tree, ldap_chain_cfadd_apply, +- &lca, 1, AVL_INORDER ); ++ edge = tavl_end( lc->lc_lai.lai_tree, TAVL_DIR_LEFT ); ++ while ( edge ) { ++ TAvlnode *next = tavl_next( edge, TAVL_DIR_RIGHT ); ++ ldapinfo_t *li = (ldapinfo_t *)edge->avl_data; ++ ldap_chain_cfadd_apply( li, op, rs, p, ca, count++ ); ++ edge = next; ++ } + + ca->be->be_private = priv; + } +@@ -1457,7 +1450,7 @@ chain_lddel( CfEntryInfo *ce, Operation *op ) + ldapinfo_t *li = (ldapinfo_t *) ce->ce_be->be_private; + + if ( li != lc->lc_common_li ) { +- if (! avl_delete( &lc->lc_lai.lai_tree, li, ldap_chain_uri_cmp ) ) { ++ if (! tavl_delete( &lc->lc_lai.lai_tree, li, ldap_chain_uri_cmp ) ) { + Debug( LDAP_DEBUG_ANY, "slapd-chain: avl_delete failed. " + "\"%s\" not found.\n", li->li_uri, 0, 0 ); + return -1; +@@ -1866,7 +1859,7 @@ private_destroy:; + goto private_destroy; + } + +- if ( avl_insert( &lc->lc_lai.lai_tree, ++ if ( tavl_insert( &lc->lc_lai.lai_tree, + (caddr_t)lc->lc_cfg_li, + ldap_chain_uri_cmp, ldap_chain_uri_dup ) ) + { +@@ -1891,22 +1884,6 @@ enum db_which { + db_last + }; + +-typedef struct ldap_chain_db_apply_t { +- BackendDB *be; +- BI_db_func *func; +-} ldap_chain_db_apply_t; +- +-static int +-ldap_chain_db_apply( void *datum, void *arg ) +-{ +- ldapinfo_t *li = (ldapinfo_t *)datum; +- ldap_chain_db_apply_t *lca = (ldap_chain_db_apply_t *)arg; +- +- lca->be->be_private = (void *)li; +- +- return lca->func( lca->be, NULL ); +-} +- + static int + ldap_chain_db_func( + BackendDB *be, +@@ -1934,14 +1911,17 @@ ldap_chain_db_func( + } + + if ( lc->lc_lai.lai_tree != NULL ) { +- ldap_chain_db_apply_t lca; +- +- lca.be = &db; +- lca.func = func; +- +- rc = avl_apply( lc->lc_lai.lai_tree, +- ldap_chain_db_apply, (void *)&lca, +- 1, AVL_INORDER ) != AVL_NOMORE; ++ TAvlnode *edge = tavl_end( lc->lc_lai.lai_tree, TAVL_DIR_LEFT ); ++ while ( edge ) { ++ TAvlnode *next = tavl_next( edge, TAVL_DIR_RIGHT ); ++ ldapinfo_t *li = (ldapinfo_t *)edge->avl_data; ++ db.be_private = (void *)li; ++ rc = func( &db, NULL ); ++ if ( rc == 1 ) { ++ break; ++ } ++ edge = next; ++ } + } + } + } +@@ -2008,7 +1988,7 @@ ldap_chain_db_destroy( + rc = ldap_chain_db_func( be, db_destroy ); + + if ( lc ) { +- avl_free( lc->lc_lai.lai_tree, NULL ); ++ tavl_free( lc->lc_lai.lai_tree, NULL ); + ldap_pvt_thread_mutex_destroy( &lc->lc_lai.lai_mutex ); + ch_free( lc ); + } +@@ -2122,22 +2102,6 @@ ldap_chain_db_open_one( + return lback->bi_db_open( be, NULL ); + } + +-typedef struct ldap_chain_conn_apply_t { +- BackendDB *be; +- Connection *conn; +-} ldap_chain_conn_apply_t; +- +-static int +-ldap_chain_conn_apply( void *datum, void *arg ) +-{ +- ldapinfo_t *li = (ldapinfo_t *)datum; +- ldap_chain_conn_apply_t *lca = (ldap_chain_conn_apply_t *)arg; +- +- lca->be->be_private = (void *)li; +- +- return lback->bi_connection_destroy( lca->be, lca->conn ); +-} +- + static int + ldap_chain_connection_destroy( + BackendDB *be, +@@ -2147,15 +2111,24 @@ ldap_chain_connection_destroy( + slap_overinst *on = (slap_overinst *) be->bd_info; + ldap_chain_t *lc = (ldap_chain_t *)on->on_bi.bi_private; + void *private = be->be_private; +- ldap_chain_conn_apply_t lca; ++ TAvlnode *edge; + int rc; + + be->be_private = NULL; +- lca.be = be; +- lca.conn = conn; + ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex ); +- rc = avl_apply( lc->lc_lai.lai_tree, ldap_chain_conn_apply, +- (void *)&lca, 1, AVL_INORDER ) != AVL_NOMORE; ++ edge = tavl_end( lc->lc_lai.lai_tree, TAVL_DIR_LEFT ); ++ while ( edge ) { ++ TAvlnode *next = tavl_next( edge, TAVL_DIR_RIGHT ); ++ ldapinfo_t *li = (ldapinfo_t *)edge->avl_data; ++ be->be_private = (void *)li; ++ rc = lback->bi_connection_destroy( be, conn ); ++ if ( rc == 1 ) { ++ break; ++ } ++ edge = next; ++ } ++ ++ + ldap_pvt_thread_mutex_unlock( &lc->lc_lai.lai_mutex ); + be->be_private = private; + +diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c +index 38da178d1..cff5cd289 100644 +--- a/servers/slapd/back-ldap/config.c ++++ b/servers/slapd/back-ldap/config.c +@@ -1424,7 +1424,7 @@ ldap_back_cf_gen( ConfigArgs *c ) + /* NOTE: don't worry about locking: if we got here, + * other threads are suspended. */ + if ( li->li_conninfo.lai_tree != NULL ) { +- avl_free( li->li_conninfo.lai_tree, ldap_back_conn_free ); ++ tavl_free( li->li_conninfo.lai_tree, ldap_back_conn_free ); + li->li_conninfo.lai_tree = NULL; + } + +diff --git a/servers/slapd/back-ldap/distproc.c b/servers/slapd/back-ldap/distproc.c +index ed978728a..a8ea803b0 100644 +--- a/servers/slapd/back-ldap/distproc.c ++++ b/servers/slapd/back-ldap/distproc.c +@@ -435,7 +435,7 @@ distproc_ldadd( CfEntryInfo *p, Entry *e, ConfigArgs *ca ) + if ( lc->lc_common_li == NULL ) { + lc->lc_common_li = li; + +- } else if ( avl_insert( &lc->lc_lai.lai_tree, (caddr_t)li, ++ } else if ( tavl_insert( &lc->lc_lai.lai_tree, (caddr_t)li, + ldap_distproc_uri_cmp, ldap_distproc_uri_dup ) ) + { + Debug( LDAP_DEBUG_ANY, "slapd-distproc: " +@@ -463,26 +463,27 @@ typedef struct ldap_distproc_cfadd_apply_t { + int count; + } ldap_distproc_cfadd_apply_t; + +-static int +-ldap_distproc_cfadd_apply( void *datum, void *arg ) ++static void ++ldap_distproc_cfadd_apply( ++ ldapinfo_t *li, ++ Operation *op, ++ SlapReply *rs, ++ Entry *p, ++ ConfigArgs *ca, ++ int count ) + { +- ldapinfo_t *li = (ldapinfo_t *)datum; +- ldap_distproc_cfadd_apply_t *lca = (ldap_distproc_cfadd_apply_t *)arg; +- + struct berval bv; + + /* FIXME: should not hardcode "olcDatabase" here */ +- bv.bv_len = snprintf( lca->ca->cr_msg, sizeof( lca->ca->cr_msg ), +- "olcDatabase={%d}%s", lca->count, lback->bi_type ); +- bv.bv_val = lca->ca->cr_msg; ++ bv.bv_len = snprintf( ca->cr_msg, sizeof( ca->cr_msg ), ++ "olcDatabase={%d}%s", count, lback->bi_type ); ++ bv.bv_val = ca->cr_msg; + +- lca->ca->be->be_private = (void *)li; +- config_build_entry( lca->op, lca->rs, lca->p->e_private, lca->ca, ++ ca->be->be_private = (void *)li; ++ config_build_entry( op, rs, p->e_private, ca, + &bv, lback->bi_cf_ocs, &distproc_ocs[ 1 ] ); + +- lca->count++; +- +- return 0; ++ return; + } + + static int +@@ -492,6 +493,8 @@ distproc_cfadd( Operation *op, SlapReply *rs, Entry *p, ConfigArgs *ca ) + slap_overinst *on = (slap_overinst *)pe->ce_bi; + ldap_distproc_t *lc = (ldap_distproc_t *)on->on_bi.bi_private; + void *priv = (void *)ca->be->be_private; ++ TAvlnode *edge; ++ int count = 0; + + if ( lback->bi_cf_ocs ) { + ldap_distproc_cfadd_apply_t lca = { 0 }; +@@ -502,10 +505,15 @@ distproc_cfadd( Operation *op, SlapReply *rs, Entry *p, ConfigArgs *ca ) + lca.ca = ca; + lca.count = 0; + +- (void)ldap_distproc_cfadd_apply( (void *)lc->lc_common_li, (void *)&lca ); ++ ldap_distproc_cfadd_apply( lc->lc_common_li, op, rs, p, ca, count++ ); + +- (void)avl_apply( lc->lc_lai.lai_tree, ldap_distproc_cfadd_apply, +- &lca, 1, AVL_INORDER ); ++ edge = tavl_end( lc->lc_lai.lai_tree, TAVL_DIR_LEFT ); ++ while ( edge ) { ++ TAvlnode *next = tavl_next( edge, TAVL_DIR_RIGHT ); ++ ldapinfo_t *li = (ldapinfo_t *)edge->avl_data; ++ ldap_distproc_cfadd_apply( li, op, rs, p, ca, count++ ); ++ edge = next; ++ } + + ca->be->be_private = priv; + } +@@ -675,7 +683,7 @@ private_destroy:; + goto private_destroy; + } + +- if ( avl_insert( &lc->lc_lai.lai_tree, ++ if ( tavl_insert( &lc->lc_lai.lai_tree, + (caddr_t)lc->lc_cfg_li, + ldap_distproc_uri_cmp, ldap_distproc_uri_dup ) ) + { +@@ -700,22 +708,6 @@ enum db_which { + db_last + }; + +-typedef struct ldap_distproc_db_apply_t { +- BackendDB *be; +- BI_db_func *func; +-} ldap_distproc_db_apply_t; +- +-static int +-ldap_distproc_db_apply( void *datum, void *arg ) +-{ +- ldapinfo_t *li = (ldapinfo_t *)datum; +- ldap_distproc_db_apply_t *lca = (ldap_distproc_db_apply_t *)arg; +- +- lca->be->be_private = (void *)li; +- +- return lca->func( lca->be, NULL ); +-} +- + static int + ldap_distproc_db_func( + BackendDB *be, +@@ -743,14 +735,17 @@ ldap_distproc_db_func( + } + + if ( lc->lc_lai.lai_tree != NULL ) { +- ldap_distproc_db_apply_t lca; +- +- lca.be = &db; +- lca.func = func; +- +- rc = avl_apply( lc->lc_lai.lai_tree, +- ldap_distproc_db_apply, (void *)&lca, +- 1, AVL_INORDER ) != AVL_NOMORE; ++ TAvlnode *edge = tavl_end( lc->lc_lai.lai_tree, TAVL_DIR_LEFT ); ++ while ( edge ) { ++ TAvlnode *next = tavl_next( edge, TAVL_DIR_RIGHT ); ++ ldapinfo_t *li = (ldapinfo_t *)edge->avl_data; ++ be->be_private = (void *)li; ++ rc = func( &db, NULL ); ++ if ( rc == 1 ) { ++ break; ++ } ++ edge = next; ++ } + } + } + } +@@ -787,7 +782,7 @@ ldap_distproc_db_destroy( + rc = ldap_distproc_db_func( be, db_destroy ); + + if ( lc ) { +- avl_free( lc->lc_lai.lai_tree, NULL ); ++ tavl_free( lc->lc_lai.lai_tree, NULL ); + ldap_pvt_thread_mutex_destroy( &lc->lc_lai.lai_mutex ); + ch_free( lc ); + } +@@ -857,22 +852,6 @@ ldap_distproc_db_init_one( + return 0; + } + +-typedef struct ldap_distproc_conn_apply_t { +- BackendDB *be; +- Connection *conn; +-} ldap_distproc_conn_apply_t; +- +-static int +-ldap_distproc_conn_apply( void *datum, void *arg ) +-{ +- ldapinfo_t *li = (ldapinfo_t *)datum; +- ldap_distproc_conn_apply_t *lca = (ldap_distproc_conn_apply_t *)arg; +- +- lca->be->be_private = (void *)li; +- +- return lback->bi_connection_destroy( lca->be, lca->conn ); +-} +- + static int + ldap_distproc_connection_destroy( + BackendDB *be, +@@ -882,15 +861,22 @@ ldap_distproc_connection_destroy( + slap_overinst *on = (slap_overinst *) be->bd_info; + ldap_distproc_t *lc = (ldap_distproc_t *)on->on_bi.bi_private; + void *private = be->be_private; +- ldap_distproc_conn_apply_t lca; + int rc; ++ TAvlnode *edge; + + be->be_private = NULL; +- lca.be = be; +- lca.conn = conn; + ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex ); +- rc = avl_apply( lc->lc_lai.lai_tree, ldap_distproc_conn_apply, +- (void *)&lca, 1, AVL_INORDER ) != AVL_NOMORE; ++ edge = tavl_end( lc->lc_lai.lai_tree, TAVL_DIR_LEFT ); ++ while ( edge ) { ++ TAvlnode *next = tavl_next( edge, TAVL_DIR_RIGHT ); ++ ldapinfo_t *li = (ldapinfo_t *)edge->avl_data; ++ be->be_private = (void *)li; ++ rc = lback->bi_connection_destroy( be, conn ); ++ if ( rc == 1 ) { ++ break; ++ } ++ edge = next; ++ } + ldap_pvt_thread_mutex_unlock( &lc->lc_lai.lai_mutex ); + be->be_private = private; + +diff --git a/servers/slapd/back-ldap/init.c b/servers/slapd/back-ldap/init.c +index f73344c99..8b801ff67 100644 +--- a/servers/slapd/back-ldap/init.c ++++ b/servers/slapd/back-ldap/init.c +@@ -31,6 +31,7 @@ + #include "slap.h" + #include "config.h" + #include "back-ldap.h" ++#include "ldap_rq.h" + + static const ldap_extra_t ldap_extra = { + ldap_back_proxy_authz_ctrl, +@@ -185,6 +186,8 @@ ldap_back_db_init( Backend *be, ConfigReply *cr ) + ldap_pvt_mp_init( li->li_ops_completed[ i ] ); + } + ++ li->li_conn_expire_task = NULL; ++ + be->be_private = li; + SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_NOLASTMOD; + +@@ -303,6 +306,16 @@ ldap_back_db_destroy( Backend *be, ConfigReply *cr ) + + (void)ldap_back_monitor_db_destroy( be ); + ++ /* Stop and remove the task that prunes expired connections */ ++ if ( li->li_conn_expire_task != NULL ) { ++ ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); ++ if ( ldap_pvt_runqueue_isrunning( &slapd_rq, li->li_conn_expire_task ) ) { ++ ldap_pvt_runqueue_stoptask( &slapd_rq, li->li_conn_expire_task ); ++ } ++ ldap_pvt_runqueue_remove( &slapd_rq, li->li_conn_expire_task ); ++ ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); ++ } ++ + ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); + + if ( li->li_uri != NULL ) { +@@ -323,7 +336,7 @@ ldap_back_db_destroy( Backend *be, ConfigReply *cr ) + li->li_idassert_authz = NULL; + } + if ( li->li_conninfo.lai_tree ) { +- avl_free( li->li_conninfo.lai_tree, ldap_back_conn_free ); ++ tavl_free( li->li_conninfo.lai_tree, ldap_back_conn_free ); + } + for ( i = LDAP_BACK_PCONN_FIRST; i < LDAP_BACK_PCONN_LAST; i++ ) { + while ( !LDAP_TAILQ_EMPTY( &li->li_conn_priv[ i ].lic_priv ) ) { +@@ -359,4 +372,3 @@ ldap_back_db_destroy( Backend *be, ConfigReply *cr ) + SLAP_BACKEND_INIT_MODULE( ldap ) + + #endif /* SLAPD_LDAP == SLAPD_MOD_DYNAMIC */ +- +diff --git a/servers/slapd/back-ldap/monitor.c b/servers/slapd/back-ldap/monitor.c +index e12de8e4e..77f11ccb5 100644 +--- a/servers/slapd/back-ldap/monitor.c ++++ b/servers/slapd/back-ldap/monitor.c +@@ -540,6 +540,7 @@ ldap_back_monitor_conn_create( + + struct ldap_back_monitor_conn_arg *arg; + int conn_type; ++ TAvlnode *edge; + + assert( e_parent->e_private != NULL ); + +@@ -564,8 +565,13 @@ ldap_back_monitor_conn_create( + } + } + +- avl_apply( li->li_conninfo.lai_tree, (AVL_APPLY)ldap_back_monitor_conn_entry, +- arg, -1, AVL_INORDER ); ++ edge = tavl_end( li->li_conninfo.lai_tree, TAVL_DIR_LEFT ); ++ while ( edge ) { ++ TAvlnode *next = tavl_next( edge, TAVL_DIR_RIGHT ); ++ ldapconn_t *lc = (ldapconn_t *)edge->avl_data; ++ ldap_back_monitor_conn_entry( lc, arg ); ++ edge = next; ++ } + + ch_free( arg ); + +diff --git a/servers/slapd/back-ldap/unbind.c b/servers/slapd/back-ldap/unbind.c +index d8121f72d..6768baf16 100644 +--- a/servers/slapd/back-ldap/unbind.c ++++ b/servers/slapd/back-ldap/unbind.c +@@ -51,7 +51,7 @@ ldap_back_conn_destroy( + #if LDAP_BACK_PRINT_CONNTREE > 0 + ldap_back_print_conntree( li, ">>> ldap_back_conn_destroy" ); + #endif /* LDAP_BACK_PRINT_CONNTREE */ +- while ( ( lc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)&lc_curr, ldap_back_conn_cmp ) ) != NULL ) ++ while ( ( lc = tavl_delete( &li->li_conninfo.lai_tree, (caddr_t)&lc_curr, ldap_back_conn_cmp ) ) != NULL ) + { + assert( !LDAP_BACK_PCONN_ISPRIV( lc ) ); + Debug( LDAP_DEBUG_TRACE, +diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c +index f5d4df4e8..0e5e8853b 100644 +--- a/servers/slapd/back-meta/bind.c ++++ b/servers/slapd/back-meta/bind.c +@@ -220,7 +220,7 @@ meta_back_bind( Operation *op, SlapReply *rs ) + if ( LDAP_BACK_SINGLECONN( mi ) ) { + metaconn_t *tmpmc; + +- while ( ( tmpmc = avl_delete( &mi->mi_conninfo.lai_tree, (caddr_t)mc, meta_back_conn_cmp ) ) != NULL ) ++ while ( ( tmpmc = tavl_delete( &mi->mi_conninfo.lai_tree, (caddr_t)mc, meta_back_conn_cmp ) ) != NULL ) + { + assert( !LDAP_BACK_PCONN_ISPRIV( mc ) ); + Debug( LDAP_DEBUG_TRACE, +@@ -243,7 +243,7 @@ meta_back_bind( Operation *op, SlapReply *rs ) + } + + ber_bvreplace( &mc->mc_local_ndn, &op->o_req_ndn ); +- lerr = avl_insert( &mi->mi_conninfo.lai_tree, (caddr_t)mc, ++ lerr = tavl_insert( &mi->mi_conninfo.lai_tree, (caddr_t)mc, + meta_back_conndn_cmp, meta_back_conndn_dup ); + #if META_BACK_PRINT_CONNTREE > 0 + meta_back_print_conntree( mi, "<<< meta_back_bind" ); +diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c +index 8a781e573..239c86e5e 100644 +--- a/servers/slapd/back-meta/conn.c ++++ b/servers/slapd/back-meta/conn.c +@@ -160,7 +160,7 @@ meta_back_print( metaconn_t *mc, char *avlstr ) + } + + static void +-meta_back_ravl_print( Avlnode *root, int depth ) ++meta_back_ravl_print( TAvlnode *root, int depth ) + { + int i; + +@@ -849,7 +849,7 @@ meta_back_retry( + + } else { + /* FIXME: check if in tree, for consistency? */ +- (void)avl_delete( &mi->mi_conninfo.lai_tree, ++ (void)tavl_delete( &mi->mi_conninfo.lai_tree, + ( caddr_t )mc, meta_back_conndnmc_cmp ); + } + LDAP_BACK_CONN_CACHED_CLEAR( mc ); +@@ -1174,7 +1174,7 @@ retry_lock:; + + + } else { +- mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree, ++ mc = (metaconn_t *)tavl_find( mi->mi_conninfo.lai_tree, + (caddr_t)&mc_curr, meta_back_conndn_cmp ); + } + +@@ -1219,7 +1219,7 @@ retry_lock:; + } + + } else { +- (void)avl_delete( &mi->mi_conninfo.lai_tree, ++ (void)tavl_delete( &mi->mi_conninfo.lai_tree, + (caddr_t)mc, meta_back_conndnmc_cmp ); + } + +@@ -1439,7 +1439,7 @@ retry_lock:; + if ( !( sendok & LDAP_BACK_BINDING ) ) { + retry_lock2:; + ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); +- mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree, ++ mc = (metaconn_t *)tavl_find( mi->mi_conninfo.lai_tree, + (caddr_t)&mc_curr, meta_back_conndn_cmp ); + if ( mc != NULL ) { + /* catch taint errors */ +@@ -1688,7 +1688,7 @@ done:; + rs->sr_err = 0; + + } else if ( !( sendok & LDAP_BACK_BINDING ) ) { +- err = avl_insert( &mi->mi_conninfo.lai_tree, ( caddr_t )mc, ++ err = tavl_insert( &mi->mi_conninfo.lai_tree, ( caddr_t )mc, + meta_back_conndn_cmp, meta_back_conndn_dup ); + LDAP_BACK_CONN_CACHED_SET( mc ); + } +@@ -1805,7 +1805,7 @@ meta_back_release_conn_lock( + } else if ( LDAP_BACK_CONN_CACHED( mc ) ) { + metaconn_t *tmpmc; + +- tmpmc = avl_delete( &mi->mi_conninfo.lai_tree, ++ tmpmc = tavl_delete( &mi->mi_conninfo.lai_tree, + ( caddr_t )mc, meta_back_conndnmc_cmp ); + + /* Overparanoid, but useful... */ +diff --git a/servers/slapd/back-meta/init.c b/servers/slapd/back-meta/init.c +index fefdba812..d98fe3625 100644 +--- a/servers/slapd/back-meta/init.c ++++ b/servers/slapd/back-meta/init.c +@@ -407,7 +407,7 @@ meta_back_db_destroy( + ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex ); + + if ( mi->mi_conninfo.lai_tree ) { +- avl_free( mi->mi_conninfo.lai_tree, meta_back_conn_free ); ++ tavl_free( mi->mi_conninfo.lai_tree, meta_back_conn_free ); + } + for ( i = LDAP_BACK_PCONN_FIRST; i < LDAP_BACK_PCONN_LAST; i++ ) { + while ( !LDAP_TAILQ_EMPTY( &mi->mi_conn_priv[ i ].mic_priv ) ) { +diff --git a/servers/slapd/back-meta/unbind.c b/servers/slapd/back-meta/unbind.c +index 2a866a6c7..8589262e6 100644 +--- a/servers/slapd/back-meta/unbind.c ++++ b/servers/slapd/back-meta/unbind.c +@@ -54,7 +54,7 @@ meta_back_conn_destroy( + #if META_BACK_PRINT_CONNTREE > 0 + meta_back_print_conntree( mi, ">>> meta_back_conn_destroy" ); + #endif /* META_BACK_PRINT_CONNTREE */ +- while ( ( mc = avl_delete( &mi->mi_conninfo.lai_tree, ( caddr_t )&mc_curr, meta_back_conn_cmp ) ) != NULL ) ++ while ( ( mc = tavl_delete( &mi->mi_conninfo.lai_tree, ( caddr_t )&mc_curr, meta_back_conn_cmp ) ) != NULL ) + { + assert( !LDAP_BACK_PCONN_ISPRIV( mc ) ); + Debug( LDAP_DEBUG_TRACE, +diff --git a/tests/data/slapd-proxytimeout.conf b/tests/data/slapd-proxytimeout.conf +new file mode 100644 +index 000000000..2fb7c6dfa +--- /dev/null ++++ b/tests/data/slapd-proxytimeout.conf +@@ -0,0 +1,71 @@ ++# provider slapd config -- for testing ++# $OpenLDAP$ ++## This work is part of OpenLDAP Software . ++## ++## Copyright 1998-2021 The OpenLDAP Foundation. ++## All rights reserved. ++## ++## Redistribution and use in source and binary forms, with or without ++## modification, are permitted only as authorized by the OpenLDAP ++## Public License. ++## ++## A copy of this license is available in the file LICENSE in the ++## top-level directory of the distribution or, alternatively, at ++## . ++ ++include @SCHEMADIR@/core.schema ++include @SCHEMADIR@/cosine.schema ++include @SCHEMADIR@/inetorgperson.schema ++include @SCHEMADIR@/openldap.schema ++include @SCHEMADIR@/nis.schema ++pidfile @TESTDIR@/slapd.m.pid ++argsfile @TESTDIR@/slapd.m.args ++ ++####################################################################### ++# database definitions ++####################################################################### ++ ++#mod#modulepath ../servers/slapd/back-@BACKEND@/:../servers/slapd/overlays ++#mod#moduleload back_@BACKEND@.la ++#ldapmod#modulepath ../servers/slapd/back-ldap/ ++#ldapmod#moduleload back_ldap.la ++#rwmmod#modulepath ../servers/slapd/overlays/ ++#rwmmod#moduleload rwm.la ++#monitormod#modulepath ../servers/slapd/back-monitor/ ++#monitormod#moduleload back_monitor.la ++ ++# here the proxy is not only acting as a proxy, but it also has a local database dc=local,dc=com" ++database @BACKEND@ ++suffix "dc=local,dc=com" ++rootdn "cn=Manager,dc=local,dc=com" ++rootpw "secret" ++#~null~#directory @TESTDIR@/db.2.a ++ ++ ++# Configure proxy ++# - normal user binds to "*,dc=example,dc=com" are proxied through to the remote slapd ++# - admin bind to local "cn=Manager,dc=local,dc=com" is overwritten by using idassert-bind ++database ldap ++uri "@URI1@" ++suffix "dc=idle-timeout,dc=example,dc=com" ++idassert-bind bindmethod=simple binddn="cn=Manager,dc=example,dc=com" credentials="secret" ++idassert-authzFrom "dn.exact:cn=Manager,dc=local,dc=com" ++rebind-as-user yes ++monitoring on ++idle-timeout @TIMEOUT@ ++overlay rwm ++rwm-suffixmassage "dc=idle-timeout,dc=example,dc=com" "ou=People,dc=example,dc=com" ++ ++database ldap ++uri "@URI1@" ++suffix "dc=conn-ttl,dc=example,dc=com" ++idassert-bind bindmethod=simple binddn="cn=Manager,dc=example,dc=com" credentials="secret" ++idassert-authzFrom "dn.exact:cn=Manager,dc=local,dc=com" ++rebind-as-user yes ++monitoring on ++conn-ttl @TIMEOUT@ ++overlay rwm ++rwm-suffixmassage "dc=conn-ttl,dc=example,dc=com" "ou=People,dc=example,dc=com" ++ ++database monitor ++ +diff --git a/tests/scripts/conf.sh b/tests/scripts/conf.sh +index 98bfb5194..6200880c4 100755 +--- a/tests/scripts/conf.sh ++++ b/tests/scripts/conf.sh +@@ -79,4 +79,5 @@ sed -e "s/@BACKEND@/${BACKEND}/" \ + -e "s;@TESTWD@;${TESTWD};" \ + -e "s;@DATADIR@;${DATADIR};" \ + -e "s;@SCHEMADIR@;${SCHEMADIR};" \ ++ -e "s;@TIMEOUT@;${TIMEOUT};" \ + -e "/^#/d" +diff --git a/tests/scripts/defines.sh b/tests/scripts/defines.sh +index 97cf08fd7..273f039cf 100755 +--- a/tests/scripts/defines.sh ++++ b/tests/scripts/defines.sh +@@ -50,6 +50,7 @@ THREADS=${AC_THREADS-threadsno} + SLEEP0=${SLEEP0-1} + SLEEP1=${SLEEP1-7} + SLEEP2=${SLEEP2-15} ++TIMEOUT=${TIMEOUT-4} + + # dirs + PROGDIR=./progs +diff --git a/tests/scripts/test079-proxy-timeout b/tests/scripts/test079-proxy-timeout +new file mode 100644 +index 000000000..e097c0739 +--- /dev/null ++++ b/tests/scripts/test079-proxy-timeout +@@ -0,0 +1,324 @@ ++#! /bin/sh ++# $OpenLDAP$ ++## This work is part of OpenLDAP Software . ++## ++## Copyright 1998-2021 The OpenLDAP Foundation. ++## All rights reserved. ++## ++## Redistribution and use in source and binary forms, with or without ++## modification, are permitted only as authorized by the OpenLDAP ++## Public License. ++## ++## A copy of this license is available in the file LICENSE in the ++## top-level directory of the distribution or, alternatively, at ++## . ++ ++echo "running defines.sh" ++. $SRCDIR/scripts/defines.sh ++ ++if test $BACKLDAP = "ldapno" ; then ++ echo "LDAP backend not available, test skipped" ++ exit 0 ++fi ++if test $RWM = "rwmno" ; then ++ echo "rwm (rewrite/remap) overlay not available, test skipped" ++ exit 0 ++fi ++ ++mkdir -p $TESTDIR $DBDIR1 $DBDIR2 ++$SLAPPASSWD -g -n >$CONFIGPWF ++ ++# ++# Start slapd that acts as a remote LDAP server that will be proxied ++# ++echo "Running slapadd to build database for the remote slapd server..." ++. $CONFFILTER $BACKEND < $CONF > $CONF1 ++$SLAPADD -f $CONF1 -l $LDIFORDERED ++RC=$? ++if test $RC != 0 ; then ++ echo "slapadd failed ($RC)!" ++ exit $RC ++fi ++ ++echo "Starting remote slapd server on TCP/IP port $PORT1..." ++$SLAPD -f $CONF1 -h $URI1 -d $LVL > $LOG1 2>&1 & ++SERVERPID=$! ++if test $WAIT != 0 ; then ++ echo SERVERPID $SERVERPID ++ read foo ++fi ++ ++# ++# Start ldapd that will proxy for the remote server ++# ++# Proxy is configured with two slapd-ldap backends: ++# - one with idle timeout set: dc=idle-timeout,$BASED ++# - one with connection TTL set: dc=conn-ttl,$BASEDN ++# ++echo "Starting slapd proxy on TCP/IP port $PORT2..." ++. $CONFFILTER $BACKEND < $DATADIR/slapd-proxytimeout.conf > $CONF2 ++$SLAPD -f $CONF2 -h $URI2 -d $LVL > $LOG2 2>&1 & ++PROXYPID=$! ++if test $WAIT != 0 ; then ++ echo PROXYPID $PROXYPID ++ read foo ++fi ++ ++KILLPIDS="$SERVERPID $PROXYPID" ++ ++sleep $SLEEP0 ++ ++############################################################################## ++# ++# Test 1: Test that shared connections are timed out ++# ++ ++NOW=`date +%s` ++echo "Create shared connection towards remote LDAP (time_t now=$NOW timeout=`expr $NOW + $TIMEOUT`)" ++ ++$LDAPSEARCH -b "dc=idle-timeout,$BASEDN" \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -H $URI2 \ ++ -w $PASSWD \ ++ 'objectclass=*' > $TESTOUT 2>&1 ++RC=$? ++if test $RC != 0 ; then ++ echo "ldapsearch failed for base: dc=idle-timeout,$BASEDN ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi ++ ++$LDAPSEARCH -b "dc=conn-ttl,$BASEDN" \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -H $URI2 \ ++ -w $PASSWD \ ++ 'objectclass=*' >> $TESTOUT 2>&1 ++RC=$? ++if test $RC != 0 ; then ++ echo "ldapsearch failed for base: dc=conn-ttl,$BASEDN ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi ++ ++# Check that connections are established by searching for olmDbConnURI from Monitor ++ ++echo "Checking that proxy has created connections towards backend" ++ ++$LDAPSEARCH -b "cn=Connections,cn=database 2,cn=databases,cn=monitor" -s one -LLL olmDbConnURI \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -H $URI2 \ ++ -w $PASSWD 2>&1 | tee -a $TESTOUT | grep ldap://${LOCALHOST}:$PORT1 >/dev/null ++RC=$? ++if test $RC != 0 ; then ++ echo "Error: LDAP connection to remote LDAP server is not found ($RC)" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi ++ ++$LDAPSEARCH -b "cn=Connections,cn=database 3,cn=databases,cn=monitor" -s one -LLL olmDbConnURI \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -H $URI2 \ ++ -w $PASSWD 2>&1 | tee -a $TESTOUT | grep ldap://${LOCALHOST}:$PORT1 >/dev/null ++RC=$? ++if test $RC != 0 ; then ++ echo "Error: LDAP connection to remote LDAP server is not found ($RC)" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi ++ ++# Wait for connections to be closed, either due to ++# - idle-timeout and ++# - conn-ttl ++ ++echo "Sleeping until idle-timeout and conn-ttl have passed" ++sleep `expr $TIMEOUT + 1` ++ ++echo "Checking that proxy has closed expired connections towards the remote LDAP server (time_t now=`date +%s`)" ++ ++$LDAPSEARCH -b "cn=Connections,cn=database 2,cn=databases,cn=monitor" -s one -LLL olmDbConnURI \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -H $URI2 \ ++ -w $PASSWD 2>&1 | tee -a $TESTOUT | grep ldap://${LOCALHOST}:$PORT1 >/dev/null ++RC=$? ++if test $RC != 1 ; then ++ echo "Error: LDAP connection to remote LDAP server was not closed" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi ++ ++$LDAPSEARCH -b "cn=Connections,cn=database 3,cn=databases,cn=monitor" -s one -LLL olmDbConnURI \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -H $URI2 \ ++ -w $PASSWD 2>&1 | tee -a $TESTOUT | grep ldap://${LOCALHOST}:$PORT1 >/dev/null ++RC=$? ++if test $RC != 1 ; then ++ echo "Error: LDAP connection to remote LDAP server was not closed" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi ++ ++ ++############################################################################## ++# ++# Test 2: Test that private connections are timed out ++# ++ ++NOW=`date +%s` ++echo "Create private connection towards remote LDAP (time_t now=$NOW timeout=`expr $NOW + $TIMEOUT`)" ++ ++# Create fifos that are used to pass searches from the test case to ldapsearch ++rm -f $TESTDIR/ldapsearch1.fifo $TESTDIR/ldapsearch2.fifo ++mkfifo $TESTDIR/ldapsearch1.fifo $TESTDIR/ldapsearch2.fifo ++ ++# Execute ldapsearch on background and have it read searches from the fifo ++$LDAPSEARCH -b "dc=idle-timeout,$BASEDN" \ ++ -D "cn=Barbara Jensen,ou=Information Technology Division,dc=idle-timeout,$BASEDN" \ ++ -H $URI2 \ ++ -w "bjensen" \ ++ -f $TESTDIR/ldapsearch1.fifo >> $TESTOUT 2>&1 & ++LDAPSEARCHPIDS=$! ++ ++$LDAPSEARCH -b "dc=conn-ttl,$BASEDN" \ ++ -D "cn=Barbara Jensen,ou=Information Technology Division,dc=conn-ttl,$BASEDN" \ ++ -H $URI2 \ ++ -w "bjensen" \ ++ -f $TESTDIR/ldapsearch2.fifo >> $TESTOUT 2>&1 & ++LDAPSEARCHPIDS="$LDAPSEARCHPIDS $!" ++ ++# Open fifos as file descriptor ++exec 3>$TESTDIR/ldapsearch1.fifo ++exec 4>$TESTDIR/ldapsearch2.fifo ++ ++# Trigger LDAP connections towards the proxy by executing a search ++echo 'objectclass=*' >&3 ++echo 'objectclass=*' >&4 ++sleep 1 ++ ++echo "Checking that proxy has created connections towards backend" ++ ++$LDAPSEARCH -b "cn=Connections,cn=database 2,cn=databases,cn=monitor" -s one -LLL olmDbConnURI \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -H $URI2 \ ++ -w $PASSWD 2>&1 | tee -a $TESTOUT | grep ldap://${LOCALHOST}:$PORT1 >/dev/null ++RC=$? ++if test $RC != 0 ; then ++ echo "Error: LDAP connection to remote LDAP server is not found ($RC)" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS $LDAPSEARCHPIDS ++ exit $RC ++fi ++ ++$LDAPSEARCH -b "cn=Connections,cn=database 3,cn=databases,cn=monitor" -s one -LLL olmDbConnURI \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -H $URI2 \ ++ -w $PASSWD 2>&1 | tee -a $TESTOUT | grep ldap://${LOCALHOST}:$PORT1 >/dev/null ++RC=$? ++if test $RC != 0 ; then ++ echo "Error: LDAP connection to remote LDAP server is not found ($RC)" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS $LDAPSEARCHPIDS ++ exit $RC ++fi ++ ++ ++echo "Sleeping until idle-timeout and conn-ttl have passed" ++sleep `expr $TIMEOUT + 1` ++ ++echo "Checking that proxy has closed expired connections towards the remote LDAP server (time_t now=`date +%s`)" ++ ++$LDAPSEARCH -b "cn=Connections,cn=database 2,cn=databases,cn=monitor" -s one -LLL olmDbConnURI \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -H $URI2 \ ++ -w $PASSWD 2>&1 | tee -a $TESTOUT | grep ldap://${LOCALHOST}:$PORT1 >/dev/null ++RC=$? ++if test $RC != 1 ; then ++ echo "Error: LDAP connection to remote LDAP server was not closed" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS $LDAPSEARCHPIDS ++ exit $RC ++fi ++ ++$LDAPSEARCH -b "cn=Connections,cn=database 3,cn=databases,cn=monitor" -s one -LLL olmDbConnURI \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -H $URI2 \ ++ -w $PASSWD 2>&1 | tee -a $TESTOUT | grep ldap://${LOCALHOST}:$PORT1 >/dev/null ++RC=$? ++if test $RC != 1 ; then ++ echo "Error: LDAP connection to remote LDAP server was not closed" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS $LDAPSEARCHPIDS ++ exit $RC ++fi ++ ++# Close the file descriptors associated with the fifos. ++# This will trigger EOF to ldapsearch which will cause it to exit. ++exec 3>&- ++exec 4>&- ++ ++ ++############################################################################## ++# ++# Test 3: Check that idle-timeout is reset on activity ++# ++ ++echo "Checking that idle-timeout is reset on activity" ++NOW=`date +%s` ++echo "Create cached connection: idle-timeout timeout starts (time_t now=$NOW, original_timeout=`expr $NOW + $TIMEOUT`)" ++$LDAPSEARCH -b "dc=idle-timeout,$BASEDN" \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -H $URI2 \ ++ -w $PASSWD \ ++ 'objectclass=*' >> $TESTOUT 2>&1 ++RC=$? ++if test $RC != 0 ; then ++ echo "ldapsearch failed for base: dc=idle-timeout,$BASEDN ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi ++ ++# sleep second less than idle-timeout to extend the timeout ++sleep `expr $TIMEOUT - 1` ++NOW=`date +%s` ++echo "Do another search to reset the timeout (time_t now=$NOW, new_timeout=`expr $NOW + $TIMEOUT`)" ++$LDAPSEARCH -b "dc=idle-timeout,$BASEDN" \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -H $URI2 \ ++ -w $PASSWD \ ++ 'objectclass=*' >> $TESTOUT 2>&1 ++RC=$? ++if test $RC != 0 ; then ++ echo "ldapsearch failed for base: dc=idle-timeout,$BASEDN ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi ++ ++sleep `expr $TIMEOUT - 1` ++echo "Check that connection is still alive due to idle-timeout reset (time_t now=`date +%s`)" ++$LDAPSEARCH -b "cn=Connections,cn=database 2,cn=databases,cn=monitor" -s one -LLL olmDbConnURI \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -H $URI2 \ ++ -w $PASSWD 2>&1 | tee -a $TESTOUT | grep ldap://${LOCALHOST}:$PORT1 >/dev/null ++RC=$? ++if test $RC != 0 ; then ++ echo "Error: LDAP connection to remote LDAP server is not found ($RC)" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi ++ ++sleep 2 ++echo "Check that connection is closed after extended idle-timeout has passed (time_t now=`date +%s`)" ++$LDAPSEARCH -b "cn=Connections,cn=database 2,cn=databases,cn=monitor" -s one -LLL olmDbConnURI \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -H $URI2 \ ++ -w $PASSWD 2>&1 | tee -a $TESTOUT | grep ldap://${LOCALHOST}:$PORT1 >/dev/null ++RC=$? ++if test $RC != 1 ; then ++ echo "Error: LDAP connection to remote LDAP server was not closed" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi ++ ++ ++test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ ++echo ">>>>> Test succeeded" ++ ++test $KILLSERVERS != no && wait ++ ++exit 0 +-- +2.30.1 + diff --git a/0227-ITS-9197-Increase-timeouts-in-test-case-due-to-spora.patch b/0227-ITS-9197-Increase-timeouts-in-test-case-due-to-spora.patch new file mode 100644 index 0000000..0023dd0 --- /dev/null +++ b/0227-ITS-9197-Increase-timeouts-in-test-case-due-to-spora.patch @@ -0,0 +1,166 @@ +From 67f7f7eecbac11bc0040a4034ef2ea1cd99e617d Mon Sep 17 00:00:00 2001 +From: Tero Saarni +Date: Thu, 25 Feb 2021 14:38:45 +0200 +Subject: [PATCH 227/230] ITS#9197 Increase timeouts in test case due to + sporadic failures + +--- + tests/scripts/defines.sh | 2 +- + tests/scripts/test079-proxy-timeout | 54 +++++++++++++++++++---------- + 2 files changed, 36 insertions(+), 20 deletions(-) + +diff --git a/tests/scripts/defines.sh b/tests/scripts/defines.sh +index 273f039cf..fe8bd47c3 100755 +--- a/tests/scripts/defines.sh ++++ b/tests/scripts/defines.sh +@@ -50,7 +50,7 @@ THREADS=${AC_THREADS-threadsno} + SLEEP0=${SLEEP0-1} + SLEEP1=${SLEEP1-7} + SLEEP2=${SLEEP2-15} +-TIMEOUT=${TIMEOUT-4} ++TIMEOUT=${TIMEOUT-8} + + # dirs + PROGDIR=./progs +diff --git a/tests/scripts/test079-proxy-timeout b/tests/scripts/test079-proxy-timeout +index e097c0739..79f19d937 100644 +--- a/tests/scripts/test079-proxy-timeout ++++ b/tests/scripts/test079-proxy-timeout +@@ -73,8 +73,9 @@ sleep $SLEEP0 + # Test 1: Test that shared connections are timed out + # + +-NOW=`date +%s` +-echo "Create shared connection towards remote LDAP (time_t now=$NOW timeout=`expr $NOW + $TIMEOUT`)" ++CONN_BEGINS=`date +%s` ++CONN_EXPIRES=`expr $CONN_BEGINS + $TIMEOUT` ++echo "Create shared connection towards remote LDAP (time_t now=$CONN_BEGINS timeout=$CONN_EXPIRES)" + + $LDAPSEARCH -b "dc=idle-timeout,$BASEDN" \ + -D "cn=Manager,dc=local,dc=com" \ +@@ -102,7 +103,7 @@ fi + + # Check that connections are established by searching for olmDbConnURI from Monitor + +-echo "Checking that proxy has created connections towards backend" ++echo "Checking that proxy has created connections towards backend (time_t now=`date +%s`)" + + $LDAPSEARCH -b "cn=Connections,cn=database 2,cn=databases,cn=monitor" -s one -LLL olmDbConnURI \ + -D "cn=Manager,dc=local,dc=com" \ +@@ -129,9 +130,10 @@ fi + # Wait for connections to be closed, either due to + # - idle-timeout and + # - conn-ttl +- ++# sleep 2 second overtime for robustness of the test case + echo "Sleeping until idle-timeout and conn-ttl have passed" +-sleep `expr $TIMEOUT + 1` ++NOW=`date +%s` ++sleep `expr $CONN_EXPIRES - $NOW + 2` + + echo "Checking that proxy has closed expired connections towards the remote LDAP server (time_t now=`date +%s`)" + +@@ -163,8 +165,9 @@ fi + # Test 2: Test that private connections are timed out + # + +-NOW=`date +%s` +-echo "Create private connection towards remote LDAP (time_t now=$NOW timeout=`expr $NOW + $TIMEOUT`)" ++CONN_BEGINS=`date +%s` ++CONN_EXPIRES=`expr $CONN_BEGINS + $TIMEOUT` ++echo "Create private connection towards remote LDAP (time_t now=$CONN_BEGINS timeout=$CONN_EXPIRES)" + + # Create fifos that are used to pass searches from the test case to ldapsearch + rm -f $TESTDIR/ldapsearch1.fifo $TESTDIR/ldapsearch2.fifo +@@ -192,9 +195,11 @@ exec 4>$TESTDIR/ldapsearch2.fifo + # Trigger LDAP connections towards the proxy by executing a search + echo 'objectclass=*' >&3 + echo 'objectclass=*' >&4 +-sleep 1 + +-echo "Checking that proxy has created connections towards backend" ++# wait for ldapsearches (running as background processes) to execute search operations ++sleep 2 ++ ++echo "Checking that proxy has created connections towards backend (time_t now=`date +%s`)" + + $LDAPSEARCH -b "cn=Connections,cn=database 2,cn=databases,cn=monitor" -s one -LLL olmDbConnURI \ + -D "cn=Manager,dc=local,dc=com" \ +@@ -218,9 +223,13 @@ if test $RC != 0 ; then + exit $RC + fi + +- ++# Wait for connections to be closed, either due to ++# - idle-timeout and ++# - conn-ttl ++# sleep 2 second overtime for robustness of the test case + echo "Sleeping until idle-timeout and conn-ttl have passed" +-sleep `expr $TIMEOUT + 1` ++NOW=`date +%s` ++sleep `expr $CONN_EXPIRES - $NOW + 2` + + echo "Checking that proxy has closed expired connections towards the remote LDAP server (time_t now=`date +%s`)" + +@@ -258,8 +267,9 @@ exec 4>&- + # + + echo "Checking that idle-timeout is reset on activity" +-NOW=`date +%s` +-echo "Create cached connection: idle-timeout timeout starts (time_t now=$NOW, original_timeout=`expr $NOW + $TIMEOUT`)" ++CONN_BEGINS=`date +%s` ++CONN_EXPIRES=`expr $CONN_BEGINS + $TIMEOUT` ++echo "Create cached connection: idle-timeout timeout starts (time_t now=$CONN_BEGINS, original_timeout=$CONN_EXPIRES)" + $LDAPSEARCH -b "dc=idle-timeout,$BASEDN" \ + -D "cn=Manager,dc=local,dc=com" \ + -H $URI2 \ +@@ -272,10 +282,13 @@ if test $RC != 0 ; then + exit $RC + fi + +-# sleep second less than idle-timeout to extend the timeout +-sleep `expr $TIMEOUT - 1` ++# sleep until 2 seconds before idle-timeout, then extend the timeout by executing another search operation + NOW=`date +%s` +-echo "Do another search to reset the timeout (time_t now=$NOW, new_timeout=`expr $NOW + $TIMEOUT`)" ++sleep `expr $CONN_EXPIRES - $NOW - 2` ++ ++CONN_BEGINS=`date +%s` ++CONN_EXPIRES=`expr $CONN_BEGINS + $TIMEOUT` ++echo "Do another search to reset the timeout (time_t now=$CONN_BEGINS, new_timeout=$CONN_EXPIRES)" + $LDAPSEARCH -b "dc=idle-timeout,$BASEDN" \ + -D "cn=Manager,dc=local,dc=com" \ + -H $URI2 \ +@@ -288,7 +301,9 @@ if test $RC != 0 ; then + exit $RC + fi + +-sleep `expr $TIMEOUT - 1` ++# sleep until 2 seconds before new exteneded idle-timeout, check that connection still exist ++NOW=`date +%s` ++sleep `expr $CONN_EXPIRES - $NOW - 2` + echo "Check that connection is still alive due to idle-timeout reset (time_t now=`date +%s`)" + $LDAPSEARCH -b "cn=Connections,cn=database 2,cn=databases,cn=monitor" -s one -LLL olmDbConnURI \ + -D "cn=Manager,dc=local,dc=com" \ +@@ -301,7 +316,9 @@ if test $RC != 0 ; then + exit $RC + fi + +-sleep 2 ++# sleep until 2 seconds after timeout, check that connection does not exist ++NOW=`date +%s` ++sleep `expr $CONN_EXPIRES - $NOW + 2` + echo "Check that connection is closed after extended idle-timeout has passed (time_t now=`date +%s`)" + $LDAPSEARCH -b "cn=Connections,cn=database 2,cn=databases,cn=monitor" -s one -LLL olmDbConnURI \ + -D "cn=Manager,dc=local,dc=com" \ +@@ -314,7 +331,6 @@ if test $RC != 1 ; then + exit $RC + fi + +- + test $KILLSERVERS != no && kill -HUP $KILLPIDS + + echo ">>>>> Test succeeded" +-- +2.30.1 + diff --git a/0228-ITS-9197-fix-typo-in-prev-commit.patch b/0228-ITS-9197-fix-typo-in-prev-commit.patch new file mode 100644 index 0000000..2d3a19d --- /dev/null +++ b/0228-ITS-9197-fix-typo-in-prev-commit.patch @@ -0,0 +1,25 @@ +From 0db68d0983e21eee17c135402c7d603c6415ae65 Mon Sep 17 00:00:00 2001 +From: Quanah Gibson-Mount +Date: Thu, 25 Feb 2021 17:05:17 +0000 +Subject: [PATCH 228/230] ITS#9197 - fix typo in prev commit + +--- + tests/scripts/test079-proxy-timeout | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/scripts/test079-proxy-timeout b/tests/scripts/test079-proxy-timeout +index 79f19d937..39a6d36ce 100644 +--- a/tests/scripts/test079-proxy-timeout ++++ b/tests/scripts/test079-proxy-timeout +@@ -301,7 +301,7 @@ if test $RC != 0 ; then + exit $RC + fi + +-# sleep until 2 seconds before new exteneded idle-timeout, check that connection still exist ++# sleep until 2 seconds before new extended idle-timeout, check that connection still exist + NOW=`date +%s` + sleep `expr $CONN_EXPIRES - $NOW - 2` + echo "Check that connection is still alive due to idle-timeout reset (time_t now=`date +%s`)" +-- +2.30.1 + diff --git a/0229-ITS-9197-Fix-test-script.patch b/0229-ITS-9197-Fix-test-script.patch new file mode 100644 index 0000000..71aa0c7 --- /dev/null +++ b/0229-ITS-9197-Fix-test-script.patch @@ -0,0 +1,66 @@ +From 089fb5f9fe662324368f928a37b5b0e09655b4f1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= +Date: Fri, 26 Feb 2021 09:13:54 +0000 +Subject: [PATCH 229/230] ITS#9197 Fix test script + +--- + tests/scripts/test079-proxy-timeout | 36 ++++++++++++++++++++++++++++- + 1 file changed, 35 insertions(+), 1 deletion(-) + +diff --git a/tests/scripts/test079-proxy-timeout b/tests/scripts/test079-proxy-timeout +index 39a6d36ce..514bcfacc 100644 +--- a/tests/scripts/test079-proxy-timeout ++++ b/tests/scripts/test079-proxy-timeout +@@ -48,6 +48,24 @@ if test $WAIT != 0 ; then + read foo + fi + ++echo "Testing slapd modify operations..." ++for i in 0 1 2 3 4 5; do ++ $LDAPSEARCH -s base -b "$MONITOR" -H $URI1 \ ++ 'objectclass=*' > /dev/null 2>&1 ++ RC=$? ++ if test $RC = 0 ; then ++ break ++ fi ++ echo "Waiting $SLEEP1 seconds for slapd to start..." ++ sleep $SLEEP1 ++done ++ ++if test $RC != 0 ; then ++ echo "ldapsearch failed ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi ++ + # + # Start ldapd that will proxy for the remote server + # +@@ -66,7 +84,23 @@ fi + + KILLPIDS="$SERVERPID $PROXYPID" + +-sleep $SLEEP0 ++echo "Testing slapd modify operations..." ++for i in 0 1 2 3 4 5; do ++ $LDAPSEARCH -s base -b "$MONITOR" -H $URI2 \ ++ 'objectclass=*' > /dev/null 2>&1 ++ RC=$? ++ if test $RC = 0 ; then ++ break ++ fi ++ echo "Waiting $SLEEP1 seconds for slapd to start..." ++ sleep $SLEEP1 ++done ++ ++if test $RC != 0 ; then ++ echo "ldapsearch failed ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi + + ############################################################################## + # +-- +2.30.1 + diff --git a/0230-ITS-9197-fix-info-msg-for-slapd-check.patch b/0230-ITS-9197-fix-info-msg-for-slapd-check.patch new file mode 100644 index 0000000..7541b45 --- /dev/null +++ b/0230-ITS-9197-fix-info-msg-for-slapd-check.patch @@ -0,0 +1,34 @@ +From c621153dc7dc86caab09a0afd546f5ef19904db9 Mon Sep 17 00:00:00 2001 +From: Howard Chu +Date: Fri, 26 Feb 2021 14:47:18 +0000 +Subject: [PATCH 230/230] ITS#9197 fix info msg for slapd check + +--- + tests/scripts/test079-proxy-timeout | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tests/scripts/test079-proxy-timeout b/tests/scripts/test079-proxy-timeout +index 514bcfacc..075d64659 100644 +--- a/tests/scripts/test079-proxy-timeout ++++ b/tests/scripts/test079-proxy-timeout +@@ -48,7 +48,7 @@ if test $WAIT != 0 ; then + read foo + fi + +-echo "Testing slapd modify operations..." ++echo "Using ldapsearch to check that slapd is running..." + for i in 0 1 2 3 4 5; do + $LDAPSEARCH -s base -b "$MONITOR" -H $URI1 \ + 'objectclass=*' > /dev/null 2>&1 +@@ -84,7 +84,7 @@ fi + + KILLPIDS="$SERVERPID $PROXYPID" + +-echo "Testing slapd modify operations..." ++echo "Using ldapsearch to check that slapd is running..." + for i in 0 1 2 3 4 5; do + $LDAPSEARCH -s base -b "$MONITOR" -H $URI2 \ + 'objectclass=*' > /dev/null 2>&1 +-- +2.30.1 + diff --git a/0231-ITS-9468-Added-test-case-for-proxy-re-binding-anonym.patch b/0231-ITS-9468-Added-test-case-for-proxy-re-binding-anonym.patch new file mode 100644 index 0000000..2d8b635 --- /dev/null +++ b/0231-ITS-9468-Added-test-case-for-proxy-re-binding-anonym.patch @@ -0,0 +1,591 @@ +From 430ca1b323d92a4ec02bbeda0acb556467751ae6 Mon Sep 17 00:00:00 2001 +From: Tero Saarni +Date: Wed, 24 Feb 2021 18:24:31 +0200 +Subject: [PATCH 231/238] ITS#9468 Added test case for proxy re-binding + anonymously + +--- + tests/data/regressions/its9468/its9468 | 421 ++++++++++++++++++ + .../data/regressions/its9468/slapd-proxy.conf | 81 ++++ + .../regressions/its9468/slapd-remote.conf | 50 +++ + 3 files changed, 552 insertions(+) + create mode 100755 tests/data/regressions/its9468/its9468 + create mode 100644 tests/data/regressions/its9468/slapd-proxy.conf + create mode 100644 tests/data/regressions/its9468/slapd-remote.conf + +diff --git a/tests/data/regressions/its9468/its9468 b/tests/data/regressions/its9468/its9468 +new file mode 100755 +index 000000000..f79b48687 +--- /dev/null ++++ b/tests/data/regressions/its9468/its9468 +@@ -0,0 +1,421 @@ ++#! /bin/sh ++# $OpenLDAP$ ++## This work is part of OpenLDAP Software . ++## ++## Copyright 1998-2021 The OpenLDAP Foundation. ++## All rights reserved. ++## ++## Redistribution and use in source and binary forms, with or without ++## modification, are permitted only as authorized by the OpenLDAP ++## Public License. ++## ++## A copy of this license is available in the file LICENSE in the ++## top-level directory of the distribution or, alternatively, at ++## . ++ ++echo "running defines.sh" ++. $SRCDIR/scripts/defines.sh ++ ++ITS=9468 ++ITSDIR=$DATADIR/regressions/its$ITS ++ ++if test $BACKLDAP = "ldapno" ; then ++ echo "LDAP backend not available, test skipped" ++ exit 0 ++fi ++if test $RWM = "rwmno" ; then ++ echo "rwm (rewrite/remap) overlay not available, test skipped" ++ exit 0 ++fi ++ ++mkdir -p $TESTDIR $DBDIR1 $DBDIR2 ++ ++echo "This test checks back-ldap connection retry behavior when the connection" ++echo "to remote LDAP server is disconnected due to:" ++echo " - remote server disconnecting the proxy connection" ++echo " - proxy disconnecting the remote server connection due to timeout/ttl" ++ ++# ++# Start slapd that acts as a remote LDAP server that will be proxied ++# ++echo "Running slapadd to build database for the remote slapd server..." ++. $CONFFILTER $BACKEND < $ITSDIR/slapd-remote.conf > $CONF1 ++$SLAPADD -f $CONF1 -l $LDIFORDERED ++RC=$? ++if test $RC != 0 ; then ++ echo "slapadd failed ($RC)!" ++ exit $RC ++fi ++ ++echo "Starting remote slapd server on TCP/IP port $PORT1..." ++$SLAPD -f $CONF1 -h "$URI1" -d $LVL > $LOG1 2>&1 & ++SERVERPID=$! ++if test $WAIT != 0 ; then ++ echo SERVERPID $SERVERPID ++ read foo ++fi ++ ++echo "Using ldapsearch to check that slapd is running..." ++for i in 0 1 2 3 4 5; do ++ $LDAPSEARCH -s base -b "$MONITORDN" -H $URI1 \ ++ -D $MANAGERDN \ ++ -w $PASSWD \ ++ 'objectclass=*' > /dev/null 2>&1 ++ RC=$? ++ if test $RC = 0 ; then ++ break ++ fi ++ echo "Waiting $SLEEP0 seconds for slapd to start..." ++ sleep $SLEEP0 ++done ++ ++if test $RC != 0 ; then ++ echo "ldapsearch failed ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $SERVERPID ++ exit $RC ++fi ++ ++# ++# Start slapd that will proxy for the remote server ++# ++echo "Starting slapd proxy on TCP/IP port $PORT2..." ++. $CONFFILTER $BACKEND < $ITSDIR/slapd-proxy.conf > $CONF2 ++$SLAPD -f $CONF2 -h $URI2 -d $LVL > $LOG2 2>&1 & ++PROXYPID=$! ++if test $WAIT != 0 ; then ++ echo PROXYPID $PROXYPID ++ read foo ++fi ++KILLPIDS="$KILLPIDS $PROXYPID" ++ ++echo "Using ldapsearch to check that slapd is running..." ++for i in 0 1 2 3 4 5; do ++ $LDAPSEARCH -s base -b "$MONITORDN" -H $URI2 \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -w $PASSWD \ ++ 'objectclass=*' > /dev/null 2>&1 ++ RC=$? ++ if test $RC = 0 ; then ++ break ++ fi ++ echo "Waiting $SLEEP0 seconds for slapd to start..." ++ sleep $SLEEP0 ++done ++ ++if test $RC != 0 ; then ++ echo "ldapsearch failed ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS ++ exit $RC ++fi ++ ++# Create fifo that is used to pass searches from the test case to ldapsearch without ++# disconnecting the client -> proxy connection ++rm -f $TESTDIR/ldapsearch.fifo ++mkfifo $TESTDIR/ldapsearch.fifo ++ ++############################################################################# ++# ++# Test 1: Check that proxy WILL NOT try to re-establish connection and rebind ++# after server has disconnected the connection towards proxy. ++# ++# Proxy config is ++# - rebind-as-user no ++# - no idle-timeout of conn-ttl set ++# ++ ++echo "Test 1" ++ ++# Start ldapsearch on background and have it read search filters from fifo, ++# so that single client connection will persist over many searches ++echo "Make the proxy to connect the remote LDAP server..." ++$LDAPSEARCH -b "dc=no-rebind,dc=no-timeout,$BASEDN" \ ++ -D "cn=Barbara Jensen,dc=no-rebind,dc=no-timeout,$BASEDN" \ ++ -w "bjensen" \ ++ -H $URI2 \ ++ -f $TESTDIR/ldapsearch.fifo > $TESTOUT 2>&1 & ++LDAPSEARCHPID=$! ++KILLPIDS="$KILLPIDS $LDAPSEARCHPID" ++ ++# Open fifo as file descriptor ++exec 3>$TESTDIR/ldapsearch.fifo ++ ++# Trigger LDAP connections towards the proxy by executing a search ++echo 'objectclass=*' >&3 ++# Wait for ldapsearch process on the background to catch up reading the fifo ++sleep 2 ++ ++# Check the number of bind operations that proxy has executed so far ++NUM_PROXY_BINDS_BEFORE=`$LDAPSEARCH -LLL \ ++ -H $URI2 \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -w $PASSWD \ ++ -b "cn=Bind,cn=Operations,cn=database 2,cn=databases,cn=monitor" olmDbOperation | \ ++ tee -a $TESTOUT | \ ++ sed -n 's/^olmDbOperation: \(.*\)/\1/p'` ++ ++# Restart the remote server to invalidate TCP connection between proxy and remote ++echo "Killing and re-starting remote slapd server on TCP/IP port $PORT1..." ++kill -HUP $SERVERPID ++sleep 2 ++ ++# When forking slapd on background, close filehandle 3 to avoid leaving fifo hanging uncloseable ++$SLAPD -f $CONF1 -h "$URI1" -d $LVL >> $LOG1 2>&1 3>&- & ++SERVERPID=$! ++KILLPIDS="$KILLPIDS $SERVERPID" ++ ++echo "Using ldapsearch to check that remote slapd is running..." ++for i in 0 1 2 3 4 5; do ++ $LDAPSEARCH -s base -b "$MONITORDN" -H $URI1 \ ++ -D $MANAGERDN \ ++ -w $PASSWD \ ++ 'objectclass=*' > /dev/null 2>&1 ++ RC=$? ++ if test $RC = 0 ; then ++ break ++ fi ++ echo "Waiting $SLEEP0 seconds for slapd to start..." ++ sleep $SLEEP0 ++done ++ ++if test $RC != 0 ; then ++ echo "ldapsearch failed ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS 2>/dev/null ++ exit $RC ++fi ++ ++echo "Use ldapsearch to trigger proxy retry logic" ++echo 'objectclass=*' >&3 ++# Wait for ldapsearch process on the background to catch up reading the fifo ++sleep 2 ++ ++# Check how many binds have been executed after retry ++NUM_PROXY_BINDS_AFTER=`$LDAPSEARCH -LLL \ ++ -H $URI2 \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -w $PASSWD \ ++ -b "cn=Bind,cn=Operations,cn=database 2,cn=databases,cn=monitor" olmDbOperation | \ ++ tee -a $TESTOUT | \ ++ sed -n 's/^olmDbOperation: \(.*\)/\1/p'` ++ ++echo "Checking if proxy tried to re-bind to the remote server" ++if test $NUM_PROXY_BINDS_BEFORE != $NUM_PROXY_BINDS_AFTER ; then ++ echo "Failure: expected proxy bind operation count not to increase ($NUM_PROXY_BINDS_BEFORE != $NUM_PROXY_BINDS_AFTER)" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS 2>/dev/null ++ exit 1 ++fi ++ ++echo "Checking ldapsearch status" ++exec 3>&- ++wait $LDAPSEARCHPID ++RC=$? ++if test $RC != 52 ; then ++ echo "Failure: expected ldapsearch to return error unavailable (52) from proxy but got $RC" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS 2>/dev/null ++ exit 1 ++fi ++ ++############################################################################# ++# ++# Test 2: Check that proxy WILL re-establish connection and rebind after ++# remote server has disconnected the connection towards proxy. ++# ++# Proxy config is ++# - rebind-as-user yes ++# - no idle-timeout or conn-ttl set ++# ++ ++echo "Test 2" ++ ++echo "Make the proxy to connect the remote LDAP server..." ++$LDAPSEARCH -b "dc=rebind,dc=no-timeout,$BASEDN" \ ++ -D "cn=Barbara Jensen,dc=rebind,dc=no-timeout,$BASEDN" \ ++ -w "bjensen" \ ++ -H $URI2 \ ++ -f $TESTDIR/ldapsearch.fifo >> $TESTOUT 2>&1 & ++LDAPSEARCHPID=$! ++KILLPIDS="$SERVERPID $PROXYPID $LDAPSEARCHPID" ++ ++exec 3>$TESTDIR/ldapsearch.fifo ++ ++echo 'objectclass=*' >&3 ++sleep 2 ++ ++echo "Killing and re-starting remote slapd server on TCP/IP port $PORT1..." ++kill -HUP $SERVERPID ++sleep 2 ++ ++$SLAPD -f $CONF1 -h "$URI1" -d $LVL >> $LOG1 2>&1 3>&- & ++SERVERPID=$! ++KILLPIDS="$KILLPIDS $SERVERPID" ++ ++echo "Using ldapsearch to check that remote slapd is running..." ++for i in 0 1 2 3 4 5; do ++ $LDAPSEARCH -s base -b "$MONITORDN" -H $URI1 \ ++ -D $MANAGERDN \ ++ -w $PASSWD \ ++ 'objectclass=*' > /dev/null 2>&1 ++ RC=$? ++ if test $RC = 0 ; then ++ break ++ fi ++ echo "Waiting $SLEEP0 seconds for slapd to start..." ++ sleep $SLEEP0 ++done ++ ++if test $RC != 0 ; then ++ echo "ldapsearch failed ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS 2>/dev/null ++ exit $RC ++fi ++ ++echo "Use ldapsearch to trigger proxy retry logic" ++echo 'objectclass=*' >&3 ++sleep 2 ++ ++echo "Checking ldapsearch status" ++exec 3>&- ++wait $LDAPSEARCHPID ++RC=$? ++ ++if test $RC != 0 ; then ++ echo "ldapsearch failed ($RC)!" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS 2>/dev/null ++ exit $RC ++fi ++ ++############################################################################# ++# ++# Test 3: Check that proxy WILL NOT re-establish connection and rebind after ++# it disconnected the connection after idle-timeout or conn-ttl ++# ++# Proxy config is ++# - rebind-as-user no ++# - no idle-timeout or conn-ttl set ++# ++ ++echo "Test 3" ++ ++echo "Make the proxy to connect the remote LDAP server..." ++$LDAPSEARCH -b "dc=no-rebind,dc=timeout,$BASEDN" \ ++ -D "cn=Barbara Jensen,dc=no-rebind,dc=timeout,$BASEDN" \ ++ -w "bjensen" \ ++ -H $URI2 \ ++ -f $TESTDIR/ldapsearch.fifo >> $TESTOUT 2>&1 & ++LDAPSEARCHPID=$! ++KILLPIDS="$SERVERPID $PROXYPID $LDAPSEARCHPID" ++ ++exec 3>$TESTDIR/ldapsearch.fifo ++ ++echo 'objectclass=*' >&3 ++# Wait for proxy->remote server timeout to expire ++sleep 4 ++ ++NUM_PROXY_BINDS_BEFORE=`$LDAPSEARCH -LLL \ ++ -H $URI2 \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -w $PASSWD \ ++ -b "cn=Bind,cn=Operations,cn=database 2,cn=databases,cn=monitor" olmDbOperation | \ ++ tee -a $TESTOUT | \ ++ sed -n 's/^olmDbOperation: \(.*\)/\1/p'` ++ ++echo "Use ldapsearch to trigger proxy retry logic" ++echo 'objectclass=*' >&3 ++sleep 2 ++ ++NUM_PROXY_BINDS_AFTER=`$LDAPSEARCH -LLL \ ++ -H $URI2 \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -w $PASSWD \ ++ -b "cn=Bind,cn=Operations,cn=database 2,cn=databases,cn=monitor" olmDbOperation | \ ++ tee -a $TESTOUT | \ ++ sed -n 's/^olmDbOperation: \(.*\)/\1/p'` ++ ++echo "Checking if proxy tried to re-bind to the remote server" ++if test $NUM_PROXY_BINDS_BEFORE != $NUM_PROXY_BINDS_AFTER ; then ++ echo "Failure: expected proxy bind operation count not to increase ($NUM_PROXY_BINDS_BEFORE != $NUM_PROXY_BINDS_AFTER)" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS 2>/dev/null ++ exit 1 ++fi ++ ++echo "Checking ldapsearch status" ++exec 3>&- ++wait $LDAPSEARCHPID ++RC=$? ++if test $RC != 52 ; then ++ echo "Failure: expected ldapsearch to return error unavailable (52) from proxy but got $RC" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS 2>/dev/null ++ exit 1 ++fi ++ ++############################################################################# ++# ++# Test 4: Check that proxy WILL NOT re-establish connection and rebind after ++# it disconnected the connection after idle-timeout or conn-ttl ++# ++# Proxy config is ++# - rebind-as-user yes ++# - no idle-timeout or conn-ttl set ++# ++ ++echo "Test 4" ++ ++echo "Make the proxy to connect the remote LDAP server..." ++$LDAPSEARCH -b "dc=rebind,dc=timeout,$BASEDN" \ ++ -D "cn=Barbara Jensen,dc=rebind,dc=timeout,$BASEDN" \ ++ -w "bjensen" \ ++ -H $URI2 \ ++ -f $TESTDIR/ldapsearch.fifo >> $TESTOUT 2>&1 & ++LDAPSEARCHPID=$! ++KILLPIDS="$SERVERPID $PROXYPID $LDAPSEARCHPID" ++ ++exec 3>$TESTDIR/ldapsearch.fifo ++ ++echo 'objectclass=*' >&3 ++# Wait for proxy->remote server timeout to expire ++sleep 4 ++ ++NUM_PROXY_BINDS_BEFORE=`$LDAPSEARCH -LLL \ ++ -H $URI2 \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -w $PASSWD \ ++ -b "cn=Bind,cn=Operations,cn=database 2,cn=databases,cn=monitor" olmDbOperation | \ ++ tee -a $TESTOUT | \ ++ sed -n 's/^olmDbOperation: \(.*\)/\1/p'` ++ ++echo "Use ldapsearch to trigger proxy retry logic" ++echo 'objectclass=*' >&3 ++sleep 2 ++ ++NUM_PROXY_BINDS_AFTER=`$LDAPSEARCH -LLL \ ++ -H $URI2 \ ++ -D "cn=Manager,dc=local,dc=com" \ ++ -w $PASSWD \ ++ -b "cn=Bind,cn=Operations,cn=database 2,cn=databases,cn=monitor" olmDbOperation | \ ++ tee -a $TESTOUT | \ ++ sed -n 's/^olmDbOperation: \(.*\)/\1/p'` ++ ++echo "Checking if proxy tried to re-bind to the remote server" ++if test $NUM_PROXY_BINDS_BEFORE != $NUM_PROXY_BINDS_AFTER ; then ++ echo "Failure: expected proxy bind operation count not to increase ($NUM_PROXY_BINDS_BEFORE != $NUM_PROXY_BINDS_AFTER)" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS 2>/dev/null ++ exit 1 ++fi ++ ++echo "Checking ldapsearch status" ++exec 3>&- ++wait $LDAPSEARCHPID ++RC=$? ++if test $RC != 52 ; then ++ echo "Failure: expected ldapsearch to return error unavailable (52) from proxy but got $RC" ++ test $KILLSERVERS != no && kill -HUP $KILLPIDS 2>/dev/null ++ exit 1 ++fi ++ ++ ++test $KILLSERVERS != no && kill -HUP $KILLPIDS 2>/dev/null ++ ++echo ">>>>> Test succeeded" ++ ++test $KILLSERVERS != no && wait ++ ++exit 0 +\ No newline at end of file +diff --git a/tests/data/regressions/its9468/slapd-proxy.conf b/tests/data/regressions/its9468/slapd-proxy.conf +new file mode 100644 +index 000000000..a2bd893c8 +--- /dev/null ++++ b/tests/data/regressions/its9468/slapd-proxy.conf +@@ -0,0 +1,81 @@ ++# provider slapd config -- for testing ++# $OpenLDAP$ ++## This work is part of OpenLDAP Software . ++## ++## Copyright 1998-2021 The OpenLDAP Foundation. ++## All rights reserved. ++## ++## Redistribution and use in source and binary forms, with or without ++## modification, are permitted only as authorized by the OpenLDAP ++## Public License. ++## ++## A copy of this license is available in the file LICENSE in the ++## top-level directory of the distribution or, alternatively, at ++## . ++ ++include @SCHEMADIR@/core.schema ++include @SCHEMADIR@/cosine.schema ++include @SCHEMADIR@/inetorgperson.schema ++include @SCHEMADIR@/openldap.schema ++include @SCHEMADIR@/nis.schema ++pidfile @TESTDIR@/slapd.m.pid ++argsfile @TESTDIR@/slapd.m.args ++ ++####################################################################### ++# database definitions ++####################################################################### ++ ++#mod#modulepath ../servers/slapd/back-@BACKEND@/:../servers/slapd/overlays ++#mod#moduleload back_@BACKEND@.la ++#ldapmod#modulepath ../servers/slapd/back-ldap/ ++#ldapmod#moduleload back_ldap.la ++#rwmmod#modulepath ../servers/slapd/overlays/ ++#rwmmod#moduleload rwm.la ++#monitormod#modulepath ../servers/slapd/back-monitor/ ++#monitormod#moduleload back_monitor.la ++ ++database @BACKEND@ ++suffix "dc=local,dc=com" ++rootdn "cn=Manager,dc=local,dc=com" ++rootpw "secret" ++#~null~#directory @TESTDIR@/db.2.a ++ ++# proxy with default settings, used for test where remote server will disconnect the proxy connection ++database ldap ++uri "@URI1@" ++suffix "dc=no-rebind,dc=no-timeout,dc=example,dc=com" ++monitoring yes ++rebind-as-user no ++overlay rwm ++rwm-suffixmassage "dc=no-rebind,dc=no-timeout,dc=example,dc=com" "ou=Information Technology Division,ou=People,dc=example,dc=com" ++ ++# proxy with rebind-as-user set, used for test where remote server will disconnect the proxy connection ++database ldap ++uri "@URI1@" ++suffix "dc=rebind,dc=no-timeout,dc=example,dc=com" ++monitoring yes ++rebind-as-user yes ++overlay rwm ++rwm-suffixmassage "dc=rebind,dc=no-timeout,dc=example,dc=com" "ou=Information Technology Division,ou=People,dc=example,dc=com" ++ ++# proxy with idle-timeout, used for test where proxy will disconnect the remote server connection ++database ldap ++uri "@URI1@" ++suffix "dc=no-rebind,dc=timeout,dc=example,dc=com" ++monitoring yes ++rebind-as-user no ++idle-timeout 1 ++overlay rwm ++rwm-suffixmassage "dc=no-rebind,dc=timeout,dc=example,dc=com" "ou=Information Technology Division,ou=People,dc=example,dc=com" ++ ++# proxy with rebind-as-user and idle-timeout, used for test where proxy will disconnect the remote server connection ++database ldap ++uri "@URI1@" ++suffix "dc=rebind,dc=timeout,dc=example,dc=com" ++monitoring yes ++rebind-as-user yes ++idle-timeout 1 ++overlay rwm ++rwm-suffixmassage "dc=rebind,dc=timeout,dc=example,dc=com" "ou=Information Technology Division,ou=People,dc=example,dc=com" ++ ++database monitor +\ No newline at end of file +diff --git a/tests/data/regressions/its9468/slapd-remote.conf b/tests/data/regressions/its9468/slapd-remote.conf +new file mode 100644 +index 000000000..71fb1cb36 +--- /dev/null ++++ b/tests/data/regressions/its9468/slapd-remote.conf +@@ -0,0 +1,50 @@ ++# stand-alone slapd config -- for testing (with indexing) ++# $OpenLDAP$ ++## This work is part of OpenLDAP Software . ++## ++## Copyright 1998-2021 The OpenLDAP Foundation. ++## All rights reserved. ++## ++## Redistribution and use in source and binary forms, with or without ++## modification, are permitted only as authorized by the OpenLDAP ++## Public License. ++## ++## A copy of this license is available in the file LICENSE in the ++## top-level directory of the distribution or, alternatively, at ++## . ++ ++include @SCHEMADIR@/core.schema ++include @SCHEMADIR@/cosine.schema ++include @SCHEMADIR@/inetorgperson.schema ++include @SCHEMADIR@/openldap.schema ++include @SCHEMADIR@/nis.schema ++include @DATADIR@/test.schema ++ ++# ++pidfile @TESTDIR@/slapd.1.pid ++argsfile @TESTDIR@/slapd.1.args ++ ++# disable anonymous bind in order to catch ITS#9468 ++disallow bind_anon ++ ++#mod#modulepath ../servers/slapd/back-@BACKEND@/ ++#mod#moduleload back_@BACKEND@.la ++ ++####################################################################### ++# database definitions ++####################################################################### ++ ++database @BACKEND@ ++suffix "dc=example,dc=com" ++rootdn "cn=Manager,dc=example,dc=com" ++rootpw secret ++monitoring on ++#null#bind on ++#~null~#directory @TESTDIR@/db.1.a ++#indexdb#index objectClass eq ++#indexdb#index cn,sn,uid pres,eq,sub ++#mdb#maxsize 33554432 ++#ndb#dbname db_1 ++#ndb#include @DATADIR@/ndb.conf ++ ++database monitor +\ No newline at end of file +-- +2.32.0 + diff --git a/0232-ITS-9468-back-ldap-Return-disconect-if-rebind-cannot.patch b/0232-ITS-9468-back-ldap-Return-disconect-if-rebind-cannot.patch new file mode 100644 index 0000000..6842e45 --- /dev/null +++ b/0232-ITS-9468-back-ldap-Return-disconect-if-rebind-cannot.patch @@ -0,0 +1,52 @@ +From 9724cc7dc24dbbc17c356f100262a7999db3f88b Mon Sep 17 00:00:00 2001 +From: Tero Saarni +Date: Fri, 5 Mar 2021 10:51:28 +0200 +Subject: [PATCH 232/238] ITS#9468 back-ldap: Return disconect if rebind cannot + be done + +--- + servers/slapd/back-ldap/bind.c | 22 +++++++++++++++++++--- + 1 file changed, 19 insertions(+), 3 deletions(-) + +diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c +index 1f9cbf185..3b46caaa7 100644 +--- a/servers/slapd/back-ldap/bind.c ++++ b/servers/slapd/back-ldap/bind.c +@@ -1495,9 +1495,25 @@ retry_lock:; + retry:; + if ( BER_BVISNULL( &lc->lc_cred ) ) { + tmp_dn = ""; ++ /* ++ * Bind is requested with DN but without credentials. ++ * This can happen when connection to remote server has been ++ * lost either due to remote server disconnecting it or due to ++ * proxy disconnecting it by itself (idle-timeout, conn-ttl). ++ */ + if ( !BER_BVISNULL( &lc->lc_bound_ndn ) && !BER_BVISEMPTY( &lc->lc_bound_ndn ) ) { +- Debug( LDAP_DEBUG_ANY, "%s ldap_back_dobind_int: DN=\"%s\" without creds, binding anonymously", +- op->o_log_prefix, lc->lc_bound_ndn.bv_val, 0 ); ++ Debug( LDAP_DEBUG_ANY, ++ "%s ldap_back_dobind_int: DN=\"%s\" connection " ++ "was re-established but cannot rebind without creds\n", ++ op->o_log_prefix, lc->lc_bound_ndn.bv_val, 0 ); ++ rs->sr_text = "Proxy lost connection to remote server"; ++ rs->sr_err = LDAP_UNAVAILABLE; ++ if ( sendok & LDAP_BACK_SENDERR ) { ++ send_ldap_result( op, rs ); ++ } ++ rs->sr_err = SLAPD_DISCONNECT; ++ rc = 0; ++ goto done; + } + + } else { +@@ -3209,4 +3225,4 @@ ldap_back_schedule_conn_expiry( ldapinfo_t *li, ldapconn_t *lc ) { + ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); + + return; +-} +\ No newline at end of file ++} +-- +2.32.0 + diff --git a/0233-ITS-9468-removed-accidental-unicode-characters.patch b/0233-ITS-9468-removed-accidental-unicode-characters.patch new file mode 100644 index 0000000..9f3ece2 --- /dev/null +++ b/0233-ITS-9468-removed-accidental-unicode-characters.patch @@ -0,0 +1,39 @@ +From d144e881694555fc63169b069bfd4ba217fb0b78 Mon Sep 17 00:00:00 2001 +From: Tero Saarni +Date: Mon, 15 Mar 2021 20:29:01 +0200 +Subject: [PATCH 233/238] ITS#9468 removed accidental unicode characters + +--- + tests/data/regressions/its9468/its9468 | 2 +- + tests/data/regressions/its9468/slapd-proxy.conf | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tests/data/regressions/its9468/its9468 b/tests/data/regressions/its9468/its9468 +index f79b48687..96247ca51 100755 +--- a/tests/data/regressions/its9468/its9468 ++++ b/tests/data/regressions/its9468/its9468 +@@ -139,7 +139,7 @@ KILLPIDS="$KILLPIDS $LDAPSEARCHPID" + # Open fifo as file descriptor + exec 3>$TESTDIR/ldapsearch.fifo + +-# Trigger LDAP connections towards the proxy by executing a search ++# Trigger LDAP connections towards the proxy by executing a search + echo 'objectclass=*' >&3 + # Wait for ldapsearch process on the background to catch up reading the fifo + sleep 2 +diff --git a/tests/data/regressions/its9468/slapd-proxy.conf b/tests/data/regressions/its9468/slapd-proxy.conf +index a2bd893c8..e19ee91de 100644 +--- a/tests/data/regressions/its9468/slapd-proxy.conf ++++ b/tests/data/regressions/its9468/slapd-proxy.conf +@@ -29,7 +29,7 @@ argsfile @TESTDIR@/slapd.m.args + #mod#moduleload back_@BACKEND@.la + #ldapmod#modulepath ../servers/slapd/back-ldap/ + #ldapmod#moduleload back_ldap.la +-#rwmmod#modulepath ../servers/slapd/overlays/ ++#rwmmod#modulepath ../servers/slapd/overlays/ + #rwmmod#moduleload rwm.la + #monitormod#modulepath ../servers/slapd/back-monitor/ + #monitormod#moduleload back_monitor.la +-- +2.32.0 + diff --git a/0234-ITS-9468-documented-that-re-connecting-does-not-happ.patch b/0234-ITS-9468-documented-that-re-connecting-does-not-happ.patch new file mode 100644 index 0000000..42901ed --- /dev/null +++ b/0234-ITS-9468-documented-that-re-connecting-does-not-happ.patch @@ -0,0 +1,58 @@ +From e969f9b508ed06984da48f61c7816a9b9b40409b Mon Sep 17 00:00:00 2001 +From: Tero Saarni +Date: Mon, 29 Mar 2021 18:57:53 +0300 +Subject: [PATCH 234/238] ITS#9468 documented that re-connecting does not + happen after idle-timeout or conn-ttl + +--- + doc/man/man5/slapd-ldap.5 | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/doc/man/man5/slapd-ldap.5 b/doc/man/man5/slapd-ldap.5 +index 1c509542f..6088b049b 100644 +--- a/doc/man/man5/slapd-ldap.5 ++++ b/doc/man/man5/slapd-ldap.5 +@@ -193,8 +193,12 @@ underlying libldap, with rebinding eventually performed if the + + .TP + .B conn\-ttl